blob: 5aa5df24f4dc19749dfacf79b716c2020479ae96 [file] [log] [blame]
Kalle Valo5e3dd152013-06-12 20:52:10 +03001/*
2 * Copyright (c) 2005-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include "mac.h"
19
20#include <net/mac80211.h>
21#include <linux/etherdevice.h>
22
Michal Kazior8cd13ca2013-07-16 09:38:54 +020023#include "hif.h"
Kalle Valo5e3dd152013-06-12 20:52:10 +030024#include "core.h"
25#include "debug.h"
26#include "wmi.h"
27#include "htt.h"
28#include "txrx.h"
Kalle Valo43d2a302014-09-10 18:23:30 +030029#include "testmode.h"
Michal Kaziord7579d12014-12-03 10:10:54 +020030#include "wmi.h"
Michal Kaziorb4aa5392015-03-31 10:26:24 +000031#include "wmi-tlv.h"
Michal Kaziord7579d12014-12-03 10:10:54 +020032#include "wmi-ops.h"
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +020033#include "wow.h"
Kalle Valo5e3dd152013-06-12 20:52:10 +030034
Michal Kaziordcc33092015-03-30 09:51:54 +030035/*********/
36/* Rates */
37/*********/
38
Michal Kaziordcc33092015-03-30 09:51:54 +030039static struct ieee80211_rate ath10k_rates[] = {
Michal Kazior5528e032015-03-30 09:51:56 +030040 { .bitrate = 10,
41 .hw_value = ATH10K_HW_RATE_CCK_LP_1M },
42 { .bitrate = 20,
43 .hw_value = ATH10K_HW_RATE_CCK_LP_2M,
44 .hw_value_short = ATH10K_HW_RATE_CCK_SP_2M,
45 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
46 { .bitrate = 55,
47 .hw_value = ATH10K_HW_RATE_CCK_LP_5_5M,
48 .hw_value_short = ATH10K_HW_RATE_CCK_SP_5_5M,
49 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
50 { .bitrate = 110,
51 .hw_value = ATH10K_HW_RATE_CCK_LP_11M,
52 .hw_value_short = ATH10K_HW_RATE_CCK_SP_11M,
53 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
Michal Kazior5653b392015-03-30 09:51:54 +030054
Michal Kazioraf001482015-03-30 09:51:56 +030055 { .bitrate = 60, .hw_value = ATH10K_HW_RATE_OFDM_6M },
56 { .bitrate = 90, .hw_value = ATH10K_HW_RATE_OFDM_9M },
57 { .bitrate = 120, .hw_value = ATH10K_HW_RATE_OFDM_12M },
58 { .bitrate = 180, .hw_value = ATH10K_HW_RATE_OFDM_18M },
59 { .bitrate = 240, .hw_value = ATH10K_HW_RATE_OFDM_24M },
60 { .bitrate = 360, .hw_value = ATH10K_HW_RATE_OFDM_36M },
61 { .bitrate = 480, .hw_value = ATH10K_HW_RATE_OFDM_48M },
62 { .bitrate = 540, .hw_value = ATH10K_HW_RATE_OFDM_54M },
Michal Kaziordcc33092015-03-30 09:51:54 +030063};
64
Mohammed Shafi Shajakhan5269c652016-06-07 15:47:04 +030065static struct ieee80211_rate ath10k_rates_rev2[] = {
66 { .bitrate = 10,
67 .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_1M },
68 { .bitrate = 20,
69 .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_2M,
70 .hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_2M,
71 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
72 { .bitrate = 55,
73 .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_5_5M,
74 .hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_5_5M,
75 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
76 { .bitrate = 110,
77 .hw_value = ATH10K_HW_RATE_REV2_CCK_LP_11M,
78 .hw_value_short = ATH10K_HW_RATE_REV2_CCK_SP_11M,
79 .flags = IEEE80211_RATE_SHORT_PREAMBLE },
80
81 { .bitrate = 60, .hw_value = ATH10K_HW_RATE_OFDM_6M },
82 { .bitrate = 90, .hw_value = ATH10K_HW_RATE_OFDM_9M },
83 { .bitrate = 120, .hw_value = ATH10K_HW_RATE_OFDM_12M },
84 { .bitrate = 180, .hw_value = ATH10K_HW_RATE_OFDM_18M },
85 { .bitrate = 240, .hw_value = ATH10K_HW_RATE_OFDM_24M },
86 { .bitrate = 360, .hw_value = ATH10K_HW_RATE_OFDM_36M },
87 { .bitrate = 480, .hw_value = ATH10K_HW_RATE_OFDM_48M },
88 { .bitrate = 540, .hw_value = ATH10K_HW_RATE_OFDM_54M },
89};
90
Michal Kazior8d7aa6b2015-03-30 09:51:57 +030091#define ATH10K_MAC_FIRST_OFDM_RATE_IDX 4
92
93#define ath10k_a_rates (ath10k_rates + ATH10K_MAC_FIRST_OFDM_RATE_IDX)
94#define ath10k_a_rates_size (ARRAY_SIZE(ath10k_rates) - \
95 ATH10K_MAC_FIRST_OFDM_RATE_IDX)
Michal Kaziordcc33092015-03-30 09:51:54 +030096#define ath10k_g_rates (ath10k_rates + 0)
97#define ath10k_g_rates_size (ARRAY_SIZE(ath10k_rates))
98
Mohammed Shafi Shajakhan5269c652016-06-07 15:47:04 +030099#define ath10k_g_rates_rev2 (ath10k_rates_rev2 + 0)
100#define ath10k_g_rates_rev2_size (ARRAY_SIZE(ath10k_rates_rev2))
101
Michal Kazior486017c2015-03-30 09:51:54 +0300102static bool ath10k_mac_bitrate_is_cck(int bitrate)
103{
104 switch (bitrate) {
105 case 10:
106 case 20:
107 case 55:
108 case 110:
109 return true;
110 }
111
112 return false;
113}
114
115static u8 ath10k_mac_bitrate_to_rate(int bitrate)
116{
117 return DIV_ROUND_UP(bitrate, 5) |
118 (ath10k_mac_bitrate_is_cck(bitrate) ? BIT(7) : 0);
119}
120
Michal Kazior5528e032015-03-30 09:51:56 +0300121u8 ath10k_mac_hw_rate_to_idx(const struct ieee80211_supported_band *sband,
Yanbo Li4b7f3532015-11-12 10:36:10 -0800122 u8 hw_rate, bool cck)
Michal Kazior5528e032015-03-30 09:51:56 +0300123{
124 const struct ieee80211_rate *rate;
125 int i;
126
127 for (i = 0; i < sband->n_bitrates; i++) {
128 rate = &sband->bitrates[i];
129
Yanbo Li4b7f3532015-11-12 10:36:10 -0800130 if (ath10k_mac_bitrate_is_cck(rate->bitrate) != cck)
131 continue;
132
Michal Kazior5528e032015-03-30 09:51:56 +0300133 if (rate->hw_value == hw_rate)
134 return i;
135 else if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE &&
136 rate->hw_value_short == hw_rate)
137 return i;
138 }
139
140 return 0;
141}
142
Michal Kazior01cebe12015-03-30 09:51:56 +0300143u8 ath10k_mac_bitrate_to_idx(const struct ieee80211_supported_band *sband,
144 u32 bitrate)
145{
146 int i;
147
148 for (i = 0; i < sband->n_bitrates; i++)
149 if (sband->bitrates[i].bitrate == bitrate)
150 return i;
151
152 return 0;
153}
154
Michal Kazior3ae54222015-03-31 10:49:20 +0000155static int ath10k_mac_get_max_vht_mcs_map(u16 mcs_map, int nss)
156{
157 switch ((mcs_map >> (2 * nss)) & 0x3) {
158 case IEEE80211_VHT_MCS_SUPPORT_0_7: return BIT(8) - 1;
159 case IEEE80211_VHT_MCS_SUPPORT_0_8: return BIT(9) - 1;
160 case IEEE80211_VHT_MCS_SUPPORT_0_9: return BIT(10) - 1;
161 }
162 return 0;
163}
164
Michal Kazior45c9abc2015-04-21 20:42:58 +0300165static u32
166ath10k_mac_max_ht_nss(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
167{
168 int nss;
169
170 for (nss = IEEE80211_HT_MCS_MASK_LEN - 1; nss >= 0; nss--)
171 if (ht_mcs_mask[nss])
172 return nss + 1;
173
174 return 1;
175}
176
177static u32
178ath10k_mac_max_vht_nss(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
179{
180 int nss;
181
182 for (nss = NL80211_VHT_NSS_MAX - 1; nss >= 0; nss--)
183 if (vht_mcs_mask[nss])
184 return nss + 1;
185
186 return 1;
187}
Kalle Valo5e3dd152013-06-12 20:52:10 +0300188
Raja Mani7e247a92016-04-12 20:15:53 +0530189int ath10k_mac_ext_resource_config(struct ath10k *ar, u32 val)
190{
191 enum wmi_host_platform_type platform_type;
192 int ret;
193
194 if (test_bit(WMI_SERVICE_TX_MODE_DYNAMIC, ar->wmi.svc_map))
195 platform_type = WMI_HOST_PLATFORM_LOW_PERF;
196 else
197 platform_type = WMI_HOST_PLATFORM_HIGH_PERF;
198
199 ret = ath10k_wmi_ext_resource_config(ar, platform_type, val);
200
201 if (ret && ret != -EOPNOTSUPP) {
202 ath10k_warn(ar, "failed to configure ext resource: %d\n", ret);
203 return ret;
204 }
205
206 return 0;
207}
208
Kalle Valo5e3dd152013-06-12 20:52:10 +0300209/**********/
210/* Crypto */
211/**********/
212
213static int ath10k_send_key(struct ath10k_vif *arvif,
214 struct ieee80211_key_conf *key,
215 enum set_key_cmd cmd,
Michal Kazior370e5672015-02-18 14:02:26 +0100216 const u8 *macaddr, u32 flags)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300217{
Michal Kazior7aa7a722014-08-25 12:09:38 +0200218 struct ath10k *ar = arvif->ar;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300219 struct wmi_vdev_install_key_arg arg = {
220 .vdev_id = arvif->vdev_id,
221 .key_idx = key->keyidx,
222 .key_len = key->keylen,
223 .key_data = key->key,
Michal Kazior370e5672015-02-18 14:02:26 +0100224 .key_flags = flags,
Kalle Valo5e3dd152013-06-12 20:52:10 +0300225 .macaddr = macaddr,
226 };
227
Michal Kazior548db542013-07-05 16:15:15 +0300228 lockdep_assert_held(&arvif->ar->conf_mutex);
229
Kalle Valo5e3dd152013-06-12 20:52:10 +0300230 switch (key->cipher) {
231 case WLAN_CIPHER_SUITE_CCMP:
232 arg.key_cipher = WMI_CIPHER_AES_CCM;
Marek Kwaczynskie4e82e92015-01-24 12:14:53 +0200233 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300234 break;
235 case WLAN_CIPHER_SUITE_TKIP:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300236 arg.key_cipher = WMI_CIPHER_TKIP;
237 arg.key_txmic_len = 8;
238 arg.key_rxmic_len = 8;
239 break;
240 case WLAN_CIPHER_SUITE_WEP40:
241 case WLAN_CIPHER_SUITE_WEP104:
242 arg.key_cipher = WMI_CIPHER_WEP;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300243 break;
Johannes Berg3cb10942015-01-22 21:38:45 +0100244 case WLAN_CIPHER_SUITE_AES_CMAC:
Bartosz Markowskid7131c02015-03-10 14:32:19 +0100245 WARN_ON(1);
246 return -EINVAL;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300247 default:
Michal Kazior7aa7a722014-08-25 12:09:38 +0200248 ath10k_warn(ar, "cipher %d is not supported\n", key->cipher);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300249 return -EOPNOTSUPP;
250 }
251
Kalle Valob9e284e2015-10-05 17:56:35 +0300252 if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
David Liuccec9032015-07-24 20:25:32 +0300253 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
David Liuccec9032015-07-24 20:25:32 +0300254
Kalle Valo5e3dd152013-06-12 20:52:10 +0300255 if (cmd == DISABLE_KEY) {
256 arg.key_cipher = WMI_CIPHER_NONE;
257 arg.key_data = NULL;
258 }
259
260 return ath10k_wmi_vdev_install_key(arvif->ar, &arg);
261}
262
263static int ath10k_install_key(struct ath10k_vif *arvif,
264 struct ieee80211_key_conf *key,
265 enum set_key_cmd cmd,
Michal Kazior370e5672015-02-18 14:02:26 +0100266 const u8 *macaddr, u32 flags)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300267{
268 struct ath10k *ar = arvif->ar;
269 int ret;
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300270 unsigned long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300271
Michal Kazior548db542013-07-05 16:15:15 +0300272 lockdep_assert_held(&ar->conf_mutex);
273
Wolfram Sang16735d02013-11-14 14:32:02 -0800274 reinit_completion(&ar->install_key_done);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300275
David Liuccec9032015-07-24 20:25:32 +0300276 if (arvif->nohwcrypt)
277 return 1;
278
Michal Kazior370e5672015-02-18 14:02:26 +0100279 ret = ath10k_send_key(arvif, key, cmd, macaddr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300280 if (ret)
281 return ret;
282
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300283 time_left = wait_for_completion_timeout(&ar->install_key_done, 3 * HZ);
284 if (time_left == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300285 return -ETIMEDOUT;
286
287 return 0;
288}
289
290static int ath10k_install_peer_wep_keys(struct ath10k_vif *arvif,
291 const u8 *addr)
292{
293 struct ath10k *ar = arvif->ar;
294 struct ath10k_peer *peer;
295 int ret;
296 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100297 u32 flags;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300298
299 lockdep_assert_held(&ar->conf_mutex);
300
Michal Kazior8674d902015-08-13 14:10:46 +0200301 if (WARN_ON(arvif->vif->type != NL80211_IFTYPE_AP &&
Peter Oh7c97b722015-12-03 09:50:55 -0800302 arvif->vif->type != NL80211_IFTYPE_ADHOC &&
303 arvif->vif->type != NL80211_IFTYPE_MESH_POINT))
Michal Kazior8674d902015-08-13 14:10:46 +0200304 return -EINVAL;
305
Kalle Valo5e3dd152013-06-12 20:52:10 +0300306 spin_lock_bh(&ar->data_lock);
307 peer = ath10k_peer_find(ar, arvif->vdev_id, addr);
308 spin_unlock_bh(&ar->data_lock);
309
310 if (!peer)
311 return -ENOENT;
312
313 for (i = 0; i < ARRAY_SIZE(arvif->wep_keys); i++) {
314 if (arvif->wep_keys[i] == NULL)
315 continue;
Michal Kazior370e5672015-02-18 14:02:26 +0100316
Michal Kazior8674d902015-08-13 14:10:46 +0200317 switch (arvif->vif->type) {
318 case NL80211_IFTYPE_AP:
319 flags = WMI_KEY_PAIRWISE;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300320
Michal Kazior8674d902015-08-13 14:10:46 +0200321 if (arvif->def_wep_key_idx == i)
322 flags |= WMI_KEY_TX_USAGE;
Michal Kaziorce90b272015-04-10 13:23:21 +0000323
Michal Kazior8674d902015-08-13 14:10:46 +0200324 ret = ath10k_install_key(arvif, arvif->wep_keys[i],
325 SET_KEY, addr, flags);
326 if (ret < 0)
327 return ret;
328 break;
329 case NL80211_IFTYPE_ADHOC:
330 ret = ath10k_install_key(arvif, arvif->wep_keys[i],
331 SET_KEY, addr,
332 WMI_KEY_PAIRWISE);
333 if (ret < 0)
334 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300335
Michal Kazior8674d902015-08-13 14:10:46 +0200336 ret = ath10k_install_key(arvif, arvif->wep_keys[i],
337 SET_KEY, addr, WMI_KEY_GROUP);
338 if (ret < 0)
339 return ret;
340 break;
341 default:
342 WARN_ON(1);
343 return -EINVAL;
344 }
Kalle Valo5e3dd152013-06-12 20:52:10 +0300345
Sujith Manoharanae167132014-11-25 11:46:59 +0530346 spin_lock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300347 peer->keys[i] = arvif->wep_keys[i];
Sujith Manoharanae167132014-11-25 11:46:59 +0530348 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300349 }
350
Michal Kaziorce90b272015-04-10 13:23:21 +0000351 /* In some cases (notably with static WEP IBSS with multiple keys)
352 * multicast Tx becomes broken. Both pairwise and groupwise keys are
353 * installed already. Using WMI_KEY_TX_USAGE in different combinations
354 * didn't seem help. Using def_keyid vdev parameter seems to be
355 * effective so use that.
356 *
357 * FIXME: Revisit. Perhaps this can be done in a less hacky way.
358 */
Michal Kazior8674d902015-08-13 14:10:46 +0200359 if (arvif->vif->type != NL80211_IFTYPE_ADHOC)
360 return 0;
361
Michal Kaziorce90b272015-04-10 13:23:21 +0000362 if (arvif->def_wep_key_idx == -1)
363 return 0;
364
365 ret = ath10k_wmi_vdev_set_param(arvif->ar,
366 arvif->vdev_id,
367 arvif->ar->wmi.vdev_param->def_keyid,
368 arvif->def_wep_key_idx);
369 if (ret) {
370 ath10k_warn(ar, "failed to re-set def wpa key idxon vdev %i: %d\n",
371 arvif->vdev_id, ret);
372 return ret;
373 }
374
Kalle Valo5e3dd152013-06-12 20:52:10 +0300375 return 0;
376}
377
378static int ath10k_clear_peer_keys(struct ath10k_vif *arvif,
379 const u8 *addr)
380{
381 struct ath10k *ar = arvif->ar;
382 struct ath10k_peer *peer;
383 int first_errno = 0;
384 int ret;
385 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100386 u32 flags = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300387
388 lockdep_assert_held(&ar->conf_mutex);
389
390 spin_lock_bh(&ar->data_lock);
391 peer = ath10k_peer_find(ar, arvif->vdev_id, addr);
392 spin_unlock_bh(&ar->data_lock);
393
394 if (!peer)
395 return -ENOENT;
396
397 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
398 if (peer->keys[i] == NULL)
399 continue;
400
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +0200401 /* key flags are not required to delete the key */
Kalle Valo5e3dd152013-06-12 20:52:10 +0300402 ret = ath10k_install_key(arvif, peer->keys[i],
Michal Kazior370e5672015-02-18 14:02:26 +0100403 DISABLE_KEY, addr, flags);
David Liuccec9032015-07-24 20:25:32 +0300404 if (ret < 0 && first_errno == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300405 first_errno = ret;
406
David Liuccec9032015-07-24 20:25:32 +0300407 if (ret < 0)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200408 ath10k_warn(ar, "failed to remove peer wep key %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300409 i, ret);
410
Sujith Manoharanae167132014-11-25 11:46:59 +0530411 spin_lock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300412 peer->keys[i] = NULL;
Sujith Manoharanae167132014-11-25 11:46:59 +0530413 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300414 }
415
416 return first_errno;
417}
418
Sujith Manoharan504f6cd2014-11-25 11:46:58 +0530419bool ath10k_mac_is_peer_wep_key_set(struct ath10k *ar, const u8 *addr,
420 u8 keyidx)
421{
422 struct ath10k_peer *peer;
423 int i;
424
425 lockdep_assert_held(&ar->data_lock);
426
427 /* We don't know which vdev this peer belongs to,
428 * since WMI doesn't give us that information.
429 *
430 * FIXME: multi-bss needs to be handled.
431 */
432 peer = ath10k_peer_find(ar, 0, addr);
433 if (!peer)
434 return false;
435
436 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
437 if (peer->keys[i] && peer->keys[i]->keyidx == keyidx)
438 return true;
439 }
440
441 return false;
442}
443
Kalle Valo5e3dd152013-06-12 20:52:10 +0300444static int ath10k_clear_vdev_key(struct ath10k_vif *arvif,
445 struct ieee80211_key_conf *key)
446{
447 struct ath10k *ar = arvif->ar;
448 struct ath10k_peer *peer;
449 u8 addr[ETH_ALEN];
450 int first_errno = 0;
451 int ret;
452 int i;
Michal Kazior370e5672015-02-18 14:02:26 +0100453 u32 flags = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300454
455 lockdep_assert_held(&ar->conf_mutex);
456
457 for (;;) {
458 /* since ath10k_install_key we can't hold data_lock all the
459 * time, so we try to remove the keys incrementally */
460 spin_lock_bh(&ar->data_lock);
461 i = 0;
462 list_for_each_entry(peer, &ar->peers, list) {
463 for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
464 if (peer->keys[i] == key) {
Kalle Valob25f32c2014-09-14 12:50:49 +0300465 ether_addr_copy(addr, peer->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300466 peer->keys[i] = NULL;
467 break;
468 }
469 }
470
471 if (i < ARRAY_SIZE(peer->keys))
472 break;
473 }
474 spin_unlock_bh(&ar->data_lock);
475
476 if (i == ARRAY_SIZE(peer->keys))
477 break;
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +0200478 /* key flags are not required to delete the key */
Michal Kazior370e5672015-02-18 14:02:26 +0100479 ret = ath10k_install_key(arvif, key, DISABLE_KEY, addr, flags);
David Liuccec9032015-07-24 20:25:32 +0300480 if (ret < 0 && first_errno == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300481 first_errno = ret;
482
483 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +0200484 ath10k_warn(ar, "failed to remove key for %pM: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +0200485 addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300486 }
487
488 return first_errno;
489}
490
Michal Kaziorad325cb2015-02-18 14:02:27 +0100491static int ath10k_mac_vif_update_wep_key(struct ath10k_vif *arvif,
492 struct ieee80211_key_conf *key)
493{
494 struct ath10k *ar = arvif->ar;
495 struct ath10k_peer *peer;
496 int ret;
497
498 lockdep_assert_held(&ar->conf_mutex);
499
500 list_for_each_entry(peer, &ar->peers, list) {
Kalle Valoc178da52016-04-13 14:13:49 +0300501 if (ether_addr_equal(peer->addr, arvif->vif->addr))
Michal Kaziorad325cb2015-02-18 14:02:27 +0100502 continue;
503
Kalle Valoc178da52016-04-13 14:13:49 +0300504 if (ether_addr_equal(peer->addr, arvif->bssid))
Michal Kaziorad325cb2015-02-18 14:02:27 +0100505 continue;
506
507 if (peer->keys[key->keyidx] == key)
508 continue;
509
510 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vif vdev %i update key %i needs update\n",
511 arvif->vdev_id, key->keyidx);
512
513 ret = ath10k_install_peer_wep_keys(arvif, peer->addr);
514 if (ret) {
515 ath10k_warn(ar, "failed to update wep keys on vdev %i for peer %pM: %d\n",
516 arvif->vdev_id, peer->addr, ret);
517 return ret;
518 }
519 }
520
521 return 0;
522}
523
Kalle Valo5e3dd152013-06-12 20:52:10 +0300524/*********************/
525/* General utilities */
526/*********************/
527
528static inline enum wmi_phy_mode
529chan_to_phymode(const struct cfg80211_chan_def *chandef)
530{
531 enum wmi_phy_mode phymode = MODE_UNKNOWN;
532
533 switch (chandef->chan->band) {
Johannes Berg57fbcce2016-04-12 15:56:15 +0200534 case NL80211_BAND_2GHZ:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300535 switch (chandef->width) {
536 case NL80211_CHAN_WIDTH_20_NOHT:
Peter Oh6faab122014-12-18 10:13:00 -0800537 if (chandef->chan->flags & IEEE80211_CHAN_NO_OFDM)
538 phymode = MODE_11B;
539 else
540 phymode = MODE_11G;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300541 break;
542 case NL80211_CHAN_WIDTH_20:
543 phymode = MODE_11NG_HT20;
544 break;
545 case NL80211_CHAN_WIDTH_40:
546 phymode = MODE_11NG_HT40;
547 break;
John W. Linville0f817ed2013-06-27 13:50:09 -0400548 case NL80211_CHAN_WIDTH_5:
549 case NL80211_CHAN_WIDTH_10:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300550 case NL80211_CHAN_WIDTH_80:
551 case NL80211_CHAN_WIDTH_80P80:
552 case NL80211_CHAN_WIDTH_160:
553 phymode = MODE_UNKNOWN;
554 break;
555 }
556 break;
Johannes Berg57fbcce2016-04-12 15:56:15 +0200557 case NL80211_BAND_5GHZ:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300558 switch (chandef->width) {
559 case NL80211_CHAN_WIDTH_20_NOHT:
560 phymode = MODE_11A;
561 break;
562 case NL80211_CHAN_WIDTH_20:
563 phymode = MODE_11NA_HT20;
564 break;
565 case NL80211_CHAN_WIDTH_40:
566 phymode = MODE_11NA_HT40;
567 break;
568 case NL80211_CHAN_WIDTH_80:
569 phymode = MODE_11AC_VHT80;
570 break;
John W. Linville0f817ed2013-06-27 13:50:09 -0400571 case NL80211_CHAN_WIDTH_5:
572 case NL80211_CHAN_WIDTH_10:
Kalle Valo5e3dd152013-06-12 20:52:10 +0300573 case NL80211_CHAN_WIDTH_80P80:
574 case NL80211_CHAN_WIDTH_160:
575 phymode = MODE_UNKNOWN;
576 break;
577 }
578 break;
579 default:
580 break;
581 }
582
583 WARN_ON(phymode == MODE_UNKNOWN);
584 return phymode;
585}
586
587static u8 ath10k_parse_mpdudensity(u8 mpdudensity)
588{
589/*
590 * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
591 * 0 for no restriction
592 * 1 for 1/4 us
593 * 2 for 1/2 us
594 * 3 for 1 us
595 * 4 for 2 us
596 * 5 for 4 us
597 * 6 for 8 us
598 * 7 for 16 us
599 */
600 switch (mpdudensity) {
601 case 0:
602 return 0;
603 case 1:
604 case 2:
605 case 3:
606 /* Our lower layer calculations limit our precision to
607 1 microsecond */
608 return 1;
609 case 4:
610 return 2;
611 case 5:
612 return 4;
613 case 6:
614 return 8;
615 case 7:
616 return 16;
617 default:
618 return 0;
619 }
620}
621
Michal Kazior500ff9f2015-03-31 10:26:21 +0000622int ath10k_mac_vif_chan(struct ieee80211_vif *vif,
623 struct cfg80211_chan_def *def)
624{
625 struct ieee80211_chanctx_conf *conf;
626
627 rcu_read_lock();
628 conf = rcu_dereference(vif->chanctx_conf);
629 if (!conf) {
630 rcu_read_unlock();
631 return -ENOENT;
632 }
633
634 *def = conf->def;
635 rcu_read_unlock();
636
637 return 0;
638}
639
640static void ath10k_mac_num_chanctxs_iter(struct ieee80211_hw *hw,
641 struct ieee80211_chanctx_conf *conf,
642 void *data)
643{
644 int *num = data;
645
646 (*num)++;
647}
648
649static int ath10k_mac_num_chanctxs(struct ath10k *ar)
650{
651 int num = 0;
652
653 ieee80211_iter_chan_contexts_atomic(ar->hw,
654 ath10k_mac_num_chanctxs_iter,
655 &num);
656
657 return num;
658}
659
660static void
661ath10k_mac_get_any_chandef_iter(struct ieee80211_hw *hw,
662 struct ieee80211_chanctx_conf *conf,
663 void *data)
664{
665 struct cfg80211_chan_def **def = data;
666
667 *def = &conf->def;
668}
669
Michal Kazior69427262016-03-06 16:14:30 +0200670static int ath10k_peer_create(struct ath10k *ar,
671 struct ieee80211_vif *vif,
672 struct ieee80211_sta *sta,
673 u32 vdev_id,
674 const u8 *addr,
Marek Puzyniak7390ed32015-03-30 09:51:52 +0300675 enum wmi_peer_type peer_type)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300676{
Michal Kaziore04cafb2015-08-05 12:15:24 +0200677 struct ath10k_vif *arvif;
Michal Kazior69427262016-03-06 16:14:30 +0200678 struct ath10k_peer *peer;
Michal Kaziore04cafb2015-08-05 12:15:24 +0200679 int num_peers = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300680 int ret;
681
682 lockdep_assert_held(&ar->conf_mutex);
683
Michal Kaziore04cafb2015-08-05 12:15:24 +0200684 num_peers = ar->num_peers;
685
686 /* Each vdev consumes a peer entry as well */
687 list_for_each_entry(arvif, &ar->arvifs, list)
688 num_peers++;
689
690 if (num_peers >= ar->max_num_peers)
Michal Kaziorcfd10612014-11-25 15:16:05 +0100691 return -ENOBUFS;
692
Marek Puzyniak7390ed32015-03-30 09:51:52 +0300693 ret = ath10k_wmi_peer_create(ar, vdev_id, addr, peer_type);
Ben Greear479398b2013-11-04 09:19:34 -0800694 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200695 ath10k_warn(ar, "failed to create wmi peer %pM on vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +0200696 addr, vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300697 return ret;
Ben Greear479398b2013-11-04 09:19:34 -0800698 }
Kalle Valo5e3dd152013-06-12 20:52:10 +0300699
700 ret = ath10k_wait_for_peer_created(ar, vdev_id, addr);
Ben Greear479398b2013-11-04 09:19:34 -0800701 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200702 ath10k_warn(ar, "failed to wait for created wmi peer %pM on vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +0200703 addr, vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300704 return ret;
Ben Greear479398b2013-11-04 09:19:34 -0800705 }
Michal Kazior292a7532014-11-25 15:16:04 +0100706
Michal Kazior69427262016-03-06 16:14:30 +0200707 spin_lock_bh(&ar->data_lock);
708
709 peer = ath10k_peer_find(ar, vdev_id, addr);
710 if (!peer) {
Ben Greearfee48cf2016-04-01 14:12:12 -0700711 spin_unlock_bh(&ar->data_lock);
Michal Kazior69427262016-03-06 16:14:30 +0200712 ath10k_warn(ar, "failed to find peer %pM on vdev %i after creation\n",
713 addr, vdev_id);
714 ath10k_wmi_peer_delete(ar, vdev_id, addr);
Michal Kazior69427262016-03-06 16:14:30 +0200715 return -ENOENT;
716 }
717
718 peer->vif = vif;
719 peer->sta = sta;
720
721 spin_unlock_bh(&ar->data_lock);
722
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100723 ar->num_peers++;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300724
725 return 0;
726}
727
Kalle Valo5a13e762014-01-20 11:01:46 +0200728static int ath10k_mac_set_kickout(struct ath10k_vif *arvif)
729{
730 struct ath10k *ar = arvif->ar;
731 u32 param;
732 int ret;
733
734 param = ar->wmi.pdev_param->sta_kickout_th;
735 ret = ath10k_wmi_pdev_set_param(ar, param,
736 ATH10K_KICKOUT_THRESHOLD);
737 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200738 ath10k_warn(ar, "failed to set kickout threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200739 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200740 return ret;
741 }
742
743 param = ar->wmi.vdev_param->ap_keepalive_min_idle_inactive_time_secs;
744 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
745 ATH10K_KEEPALIVE_MIN_IDLE);
746 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200747 ath10k_warn(ar, "failed to set keepalive minimum idle time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200748 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200749 return ret;
750 }
751
752 param = ar->wmi.vdev_param->ap_keepalive_max_idle_inactive_time_secs;
753 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
754 ATH10K_KEEPALIVE_MAX_IDLE);
755 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200756 ath10k_warn(ar, "failed to set keepalive maximum idle time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200757 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200758 return ret;
759 }
760
761 param = ar->wmi.vdev_param->ap_keepalive_max_unresponsive_time_secs;
762 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
763 ATH10K_KEEPALIVE_MAX_UNRESPONSIVE);
764 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200765 ath10k_warn(ar, "failed to set keepalive maximum unresponsive time on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200766 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +0200767 return ret;
768 }
769
770 return 0;
771}
772
Vivek Natarajanacab6402014-11-26 09:06:12 +0200773static int ath10k_mac_set_rts(struct ath10k_vif *arvif, u32 value)
Michal Kazior424121c2013-07-22 14:13:31 +0200774{
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200775 struct ath10k *ar = arvif->ar;
776 u32 vdev_param;
777
Bartosz Markowski6d1506e2013-09-26 17:47:15 +0200778 vdev_param = ar->wmi.vdev_param->rts_threshold;
779 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, value);
Michal Kazior424121c2013-07-22 14:13:31 +0200780}
781
Kalle Valo5e3dd152013-06-12 20:52:10 +0300782static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr)
783{
784 int ret;
785
786 lockdep_assert_held(&ar->conf_mutex);
787
788 ret = ath10k_wmi_peer_delete(ar, vdev_id, addr);
789 if (ret)
790 return ret;
791
792 ret = ath10k_wait_for_peer_deleted(ar, vdev_id, addr);
793 if (ret)
794 return ret;
795
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100796 ar->num_peers--;
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100797
Kalle Valo5e3dd152013-06-12 20:52:10 +0300798 return 0;
799}
800
801static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
802{
803 struct ath10k_peer *peer, *tmp;
Michal Kazior69427262016-03-06 16:14:30 +0200804 int peer_id;
Ben Greear6d68f792016-06-30 15:23:53 +0300805 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300806
807 lockdep_assert_held(&ar->conf_mutex);
808
809 spin_lock_bh(&ar->data_lock);
810 list_for_each_entry_safe(peer, tmp, &ar->peers, list) {
811 if (peer->vdev_id != vdev_id)
812 continue;
813
Michal Kazior7aa7a722014-08-25 12:09:38 +0200814 ath10k_warn(ar, "removing stale peer %pM from vdev_id %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +0300815 peer->addr, vdev_id);
816
Michal Kazior69427262016-03-06 16:14:30 +0200817 for_each_set_bit(peer_id, peer->peer_ids,
818 ATH10K_MAX_NUM_PEER_IDS) {
819 ar->peer_map[peer_id] = NULL;
820 }
821
Ben Greear6d68f792016-06-30 15:23:53 +0300822 /* Double check that peer is properly un-referenced from
823 * the peer_map
824 */
825 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
826 if (ar->peer_map[i] == peer) {
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +0530827 ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %pK idx %d)\n",
Ben Greear6d68f792016-06-30 15:23:53 +0300828 peer->addr, peer, i);
829 ar->peer_map[i] = NULL;
830 }
831 }
832
Kalle Valo5e3dd152013-06-12 20:52:10 +0300833 list_del(&peer->list);
834 kfree(peer);
Bartosz Markowski0e759f32014-01-02 14:38:33 +0100835 ar->num_peers--;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300836 }
837 spin_unlock_bh(&ar->data_lock);
838}
839
Michal Kaziora96d7742013-07-16 09:38:56 +0200840static void ath10k_peer_cleanup_all(struct ath10k *ar)
841{
842 struct ath10k_peer *peer, *tmp;
Ben Greear6d68f792016-06-30 15:23:53 +0300843 int i;
Michal Kaziora96d7742013-07-16 09:38:56 +0200844
845 lockdep_assert_held(&ar->conf_mutex);
846
847 spin_lock_bh(&ar->data_lock);
848 list_for_each_entry_safe(peer, tmp, &ar->peers, list) {
849 list_del(&peer->list);
850 kfree(peer);
851 }
Ben Greear6d68f792016-06-30 15:23:53 +0300852
853 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++)
854 ar->peer_map[i] = NULL;
855
Michal Kaziora96d7742013-07-16 09:38:56 +0200856 spin_unlock_bh(&ar->data_lock);
Michal Kazior292a7532014-11-25 15:16:04 +0100857
858 ar->num_peers = 0;
Michal Kaziorcfd10612014-11-25 15:16:05 +0100859 ar->num_stations = 0;
Michal Kaziora96d7742013-07-16 09:38:56 +0200860}
861
Marek Puzyniak75d85fd2015-03-30 09:51:53 +0300862static int ath10k_mac_tdls_peer_update(struct ath10k *ar, u32 vdev_id,
863 struct ieee80211_sta *sta,
864 enum wmi_tdls_peer_state state)
865{
866 int ret;
867 struct wmi_tdls_peer_update_cmd_arg arg = {};
868 struct wmi_tdls_peer_capab_arg cap = {};
869 struct wmi_channel_arg chan_arg = {};
870
871 lockdep_assert_held(&ar->conf_mutex);
872
873 arg.vdev_id = vdev_id;
874 arg.peer_state = state;
875 ether_addr_copy(arg.addr, sta->addr);
876
877 cap.peer_max_sp = sta->max_sp;
878 cap.peer_uapsd_queues = sta->uapsd_queues;
879
880 if (state == WMI_TDLS_PEER_STATE_CONNECTED &&
881 !sta->tdls_initiator)
882 cap.is_peer_responder = 1;
883
884 ret = ath10k_wmi_tdls_peer_update(ar, &arg, &cap, &chan_arg);
885 if (ret) {
886 ath10k_warn(ar, "failed to update tdls peer %pM on vdev %i: %i\n",
887 arg.addr, vdev_id, ret);
888 return ret;
889 }
890
891 return 0;
892}
893
Kalle Valo5e3dd152013-06-12 20:52:10 +0300894/************************/
895/* Interface management */
896/************************/
897
Michal Kazior64badcb2014-09-18 11:18:02 +0300898void ath10k_mac_vif_beacon_free(struct ath10k_vif *arvif)
899{
900 struct ath10k *ar = arvif->ar;
901
902 lockdep_assert_held(&ar->data_lock);
903
904 if (!arvif->beacon)
905 return;
906
907 if (!arvif->beacon_buf)
908 dma_unmap_single(ar->dev, ATH10K_SKB_CB(arvif->beacon)->paddr,
909 arvif->beacon->len, DMA_TO_DEVICE);
910
Michal Kazioraf213192015-01-29 14:29:52 +0200911 if (WARN_ON(arvif->beacon_state != ATH10K_BEACON_SCHEDULED &&
912 arvif->beacon_state != ATH10K_BEACON_SENT))
913 return;
914
Michal Kazior64badcb2014-09-18 11:18:02 +0300915 dev_kfree_skb_any(arvif->beacon);
916
917 arvif->beacon = NULL;
Michal Kazioraf213192015-01-29 14:29:52 +0200918 arvif->beacon_state = ATH10K_BEACON_SCHEDULED;
Michal Kazior64badcb2014-09-18 11:18:02 +0300919}
920
921static void ath10k_mac_vif_beacon_cleanup(struct ath10k_vif *arvif)
922{
923 struct ath10k *ar = arvif->ar;
924
925 lockdep_assert_held(&ar->data_lock);
926
927 ath10k_mac_vif_beacon_free(arvif);
928
929 if (arvif->beacon_buf) {
930 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
931 arvif->beacon_buf, arvif->beacon_paddr);
932 arvif->beacon_buf = NULL;
933 }
934}
935
Kalle Valo5e3dd152013-06-12 20:52:10 +0300936static inline int ath10k_vdev_setup_sync(struct ath10k *ar)
937{
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300938 unsigned long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300939
Michal Kazior548db542013-07-05 16:15:15 +0300940 lockdep_assert_held(&ar->conf_mutex);
941
Michal Kazior7962b0d2014-10-28 10:34:38 +0100942 if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags))
943 return -ESHUTDOWN;
944
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +0300945 time_left = wait_for_completion_timeout(&ar->vdev_setup_done,
946 ATH10K_VDEV_SETUP_TIMEOUT_HZ);
947 if (time_left == 0)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300948 return -ETIMEDOUT;
949
950 return 0;
951}
952
Michal Kazior1bbc0972014-04-08 09:45:47 +0300953static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
Kalle Valo5e3dd152013-06-12 20:52:10 +0300954{
Michal Kazior500ff9f2015-03-31 10:26:21 +0000955 struct cfg80211_chan_def *chandef = NULL;
Maninder Singh19be9e92015-07-16 09:25:33 +0530956 struct ieee80211_channel *channel = NULL;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300957 struct wmi_vdev_start_request_arg arg = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +0300958 int ret = 0;
959
960 lockdep_assert_held(&ar->conf_mutex);
961
Michal Kazior500ff9f2015-03-31 10:26:21 +0000962 ieee80211_iter_chan_contexts_atomic(ar->hw,
963 ath10k_mac_get_any_chandef_iter,
964 &chandef);
965 if (WARN_ON_ONCE(!chandef))
966 return -ENOENT;
967
968 channel = chandef->chan;
969
Kalle Valo5e3dd152013-06-12 20:52:10 +0300970 arg.vdev_id = vdev_id;
971 arg.channel.freq = channel->center_freq;
Michal Kaziorc930f742014-01-23 11:38:25 +0100972 arg.channel.band_center_freq1 = chandef->center_freq1;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300973
974 /* TODO setup this dynamically, what in case we
975 don't have any vifs? */
Michal Kaziorc930f742014-01-23 11:38:25 +0100976 arg.channel.mode = chan_to_phymode(chandef);
Marek Puzyniake8a50f82013-11-20 09:59:47 +0200977 arg.channel.chan_radar =
978 !!(channel->flags & IEEE80211_CHAN_RADAR);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300979
Michal Kazior89c5c842013-10-23 04:02:13 -0700980 arg.channel.min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -0700981 arg.channel.max_power = channel->max_power * 2;
982 arg.channel.max_reg_power = channel->max_reg_power * 2;
983 arg.channel.max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +0300984
Michal Kazior7962b0d2014-10-28 10:34:38 +0100985 reinit_completion(&ar->vdev_setup_done);
986
Kalle Valo5e3dd152013-06-12 20:52:10 +0300987 ret = ath10k_wmi_vdev_start(ar, &arg);
988 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +0200989 ath10k_warn(ar, "failed to request monitor vdev %i start: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200990 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300991 return ret;
992 }
993
994 ret = ath10k_vdev_setup_sync(ar);
995 if (ret) {
Ben Greear60028a82015-02-15 16:50:39 +0200996 ath10k_warn(ar, "failed to synchronize setup for monitor vdev %i start: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +0200997 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +0300998 return ret;
999 }
1000
1001 ret = ath10k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr);
1002 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001003 ath10k_warn(ar, "failed to put up monitor vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001004 vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001005 goto vdev_stop;
1006 }
1007
1008 ar->monitor_vdev_id = vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001009
Michal Kazior7aa7a722014-08-25 12:09:38 +02001010 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i started\n",
Michal Kazior1bbc0972014-04-08 09:45:47 +03001011 ar->monitor_vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001012 return 0;
1013
1014vdev_stop:
1015 ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
1016 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001017 ath10k_warn(ar, "failed to stop monitor vdev %i after start failure: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001018 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001019
1020 return ret;
1021}
1022
Michal Kazior1bbc0972014-04-08 09:45:47 +03001023static int ath10k_monitor_vdev_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001024{
1025 int ret = 0;
1026
1027 lockdep_assert_held(&ar->conf_mutex);
1028
Marek Puzyniak52fa0192013-09-24 14:06:24 +02001029 ret = ath10k_wmi_vdev_down(ar, ar->monitor_vdev_id);
1030 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001031 ath10k_warn(ar, "failed to put down monitor vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001032 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001033
Michal Kazior7962b0d2014-10-28 10:34:38 +01001034 reinit_completion(&ar->vdev_setup_done);
1035
Kalle Valo5e3dd152013-06-12 20:52:10 +03001036 ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
1037 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001038 ath10k_warn(ar, "failed to to request monitor vdev %i stop: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001039 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001040
1041 ret = ath10k_vdev_setup_sync(ar);
1042 if (ret)
Ben Greear60028a82015-02-15 16:50:39 +02001043 ath10k_warn(ar, "failed to synchronize monitor vdev %i stop: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001044 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001045
Michal Kazior7aa7a722014-08-25 12:09:38 +02001046 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n",
Michal Kazior1bbc0972014-04-08 09:45:47 +03001047 ar->monitor_vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001048 return ret;
1049}
1050
Michal Kazior1bbc0972014-04-08 09:45:47 +03001051static int ath10k_monitor_vdev_create(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001052{
1053 int bit, ret = 0;
1054
1055 lockdep_assert_held(&ar->conf_mutex);
1056
Ben Greeara9aefb32014-08-12 11:02:19 +03001057 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001058 ath10k_warn(ar, "failed to find free vdev id for monitor vdev\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03001059 return -ENOMEM;
1060 }
1061
Ben Greear16c11172014-09-23 14:17:16 -07001062 bit = __ffs64(ar->free_vdev_map);
Ben Greeara9aefb32014-08-12 11:02:19 +03001063
Ben Greear16c11172014-09-23 14:17:16 -07001064 ar->monitor_vdev_id = bit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001065
1066 ret = ath10k_wmi_vdev_create(ar, ar->monitor_vdev_id,
1067 WMI_VDEV_TYPE_MONITOR,
1068 0, ar->mac_addr);
1069 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001070 ath10k_warn(ar, "failed to request monitor vdev %i creation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001071 ar->monitor_vdev_id, ret);
Ben Greeara9aefb32014-08-12 11:02:19 +03001072 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001073 }
1074
Ben Greear16c11172014-09-23 14:17:16 -07001075 ar->free_vdev_map &= ~(1LL << ar->monitor_vdev_id);
Michal Kazior7aa7a722014-08-25 12:09:38 +02001076 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d created\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001077 ar->monitor_vdev_id);
1078
Kalle Valo5e3dd152013-06-12 20:52:10 +03001079 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001080}
1081
Michal Kazior1bbc0972014-04-08 09:45:47 +03001082static int ath10k_monitor_vdev_delete(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001083{
1084 int ret = 0;
1085
1086 lockdep_assert_held(&ar->conf_mutex);
1087
Kalle Valo5e3dd152013-06-12 20:52:10 +03001088 ret = ath10k_wmi_vdev_delete(ar, ar->monitor_vdev_id);
1089 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001090 ath10k_warn(ar, "failed to request wmi monitor vdev %i removal: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02001091 ar->monitor_vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001092 return ret;
1093 }
1094
Ben Greear16c11172014-09-23 14:17:16 -07001095 ar->free_vdev_map |= 1LL << ar->monitor_vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001096
Michal Kazior7aa7a722014-08-25 12:09:38 +02001097 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d deleted\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001098 ar->monitor_vdev_id);
1099 return ret;
1100}
1101
Michal Kazior1bbc0972014-04-08 09:45:47 +03001102static int ath10k_monitor_start(struct ath10k *ar)
1103{
1104 int ret;
1105
1106 lockdep_assert_held(&ar->conf_mutex);
1107
Michal Kazior1bbc0972014-04-08 09:45:47 +03001108 ret = ath10k_monitor_vdev_create(ar);
1109 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001110 ath10k_warn(ar, "failed to create monitor vdev: %d\n", ret);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001111 return ret;
1112 }
1113
1114 ret = ath10k_monitor_vdev_start(ar, ar->monitor_vdev_id);
1115 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001116 ath10k_warn(ar, "failed to start monitor vdev: %d\n", ret);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001117 ath10k_monitor_vdev_delete(ar);
1118 return ret;
1119 }
1120
1121 ar->monitor_started = true;
Michal Kazior7aa7a722014-08-25 12:09:38 +02001122 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor started\n");
Michal Kazior1bbc0972014-04-08 09:45:47 +03001123
1124 return 0;
1125}
1126
Michal Kazior19337472014-08-28 12:58:16 +02001127static int ath10k_monitor_stop(struct ath10k *ar)
Michal Kazior1bbc0972014-04-08 09:45:47 +03001128{
1129 int ret;
1130
1131 lockdep_assert_held(&ar->conf_mutex);
1132
Michal Kazior1bbc0972014-04-08 09:45:47 +03001133 ret = ath10k_monitor_vdev_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001134 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001135 ath10k_warn(ar, "failed to stop monitor vdev: %d\n", ret);
Michal Kazior19337472014-08-28 12:58:16 +02001136 return ret;
1137 }
Michal Kazior1bbc0972014-04-08 09:45:47 +03001138
1139 ret = ath10k_monitor_vdev_delete(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001140 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001141 ath10k_warn(ar, "failed to delete monitor vdev: %d\n", ret);
Michal Kazior19337472014-08-28 12:58:16 +02001142 return ret;
1143 }
Michal Kazior1bbc0972014-04-08 09:45:47 +03001144
1145 ar->monitor_started = false;
Michal Kazior7aa7a722014-08-25 12:09:38 +02001146 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopped\n");
Michal Kazior19337472014-08-28 12:58:16 +02001147
1148 return 0;
1149}
1150
Michal Kazior500ff9f2015-03-31 10:26:21 +00001151static bool ath10k_mac_monitor_vdev_is_needed(struct ath10k *ar)
1152{
1153 int num_ctx;
1154
1155 /* At least one chanctx is required to derive a channel to start
1156 * monitor vdev on.
1157 */
1158 num_ctx = ath10k_mac_num_chanctxs(ar);
1159 if (num_ctx == 0)
1160 return false;
1161
1162 /* If there's already an existing special monitor interface then don't
1163 * bother creating another monitor vdev.
1164 */
1165 if (ar->monitor_arvif)
1166 return false;
1167
1168 return ar->monitor ||
Bob Copeland0d031c82015-09-09 12:47:34 -04001169 ar->filter_flags & FIF_OTHER_BSS ||
Michal Kazior500ff9f2015-03-31 10:26:21 +00001170 test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1171}
1172
1173static bool ath10k_mac_monitor_vdev_is_allowed(struct ath10k *ar)
1174{
1175 int num_ctx;
1176
1177 num_ctx = ath10k_mac_num_chanctxs(ar);
1178
1179 /* FIXME: Current interface combinations and cfg80211/mac80211 code
1180 * shouldn't allow this but make sure to prevent handling the following
1181 * case anyway since multi-channel DFS hasn't been tested at all.
1182 */
1183 if (test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags) && num_ctx > 1)
1184 return false;
1185
1186 return true;
1187}
1188
Michal Kazior19337472014-08-28 12:58:16 +02001189static int ath10k_monitor_recalc(struct ath10k *ar)
1190{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001191 bool needed;
1192 bool allowed;
1193 int ret;
Michal Kazior19337472014-08-28 12:58:16 +02001194
1195 lockdep_assert_held(&ar->conf_mutex);
1196
Michal Kazior500ff9f2015-03-31 10:26:21 +00001197 needed = ath10k_mac_monitor_vdev_is_needed(ar);
1198 allowed = ath10k_mac_monitor_vdev_is_allowed(ar);
Michal Kazior19337472014-08-28 12:58:16 +02001199
1200 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior500ff9f2015-03-31 10:26:21 +00001201 "mac monitor recalc started? %d needed? %d allowed? %d\n",
1202 ar->monitor_started, needed, allowed);
Michal Kazior19337472014-08-28 12:58:16 +02001203
Michal Kazior500ff9f2015-03-31 10:26:21 +00001204 if (WARN_ON(needed && !allowed)) {
1205 if (ar->monitor_started) {
1206 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopping disallowed monitor\n");
1207
1208 ret = ath10k_monitor_stop(ar);
1209 if (ret)
Kalle Valo2a995082015-10-05 17:56:37 +03001210 ath10k_warn(ar, "failed to stop disallowed monitor: %d\n",
1211 ret);
Michal Kazior500ff9f2015-03-31 10:26:21 +00001212 /* not serious */
1213 }
1214
1215 return -EPERM;
1216 }
1217
1218 if (needed == ar->monitor_started)
Michal Kazior19337472014-08-28 12:58:16 +02001219 return 0;
1220
Michal Kazior500ff9f2015-03-31 10:26:21 +00001221 if (needed)
Michal Kazior19337472014-08-28 12:58:16 +02001222 return ath10k_monitor_start(ar);
Michal Kazior500ff9f2015-03-31 10:26:21 +00001223 else
1224 return ath10k_monitor_stop(ar);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001225}
1226
Bartosz Markowski83e48fc2016-12-15 11:23:24 +02001227static bool ath10k_mac_can_set_cts_prot(struct ath10k_vif *arvif)
1228{
1229 struct ath10k *ar = arvif->ar;
1230
1231 lockdep_assert_held(&ar->conf_mutex);
1232
1233 if (!arvif->is_started) {
1234 ath10k_dbg(ar, ATH10K_DBG_MAC, "defer cts setup, vdev is not ready yet\n");
1235 return false;
1236 }
1237
1238 return true;
1239}
1240
1241static int ath10k_mac_set_cts_prot(struct ath10k_vif *arvif)
1242{
1243 struct ath10k *ar = arvif->ar;
1244 u32 vdev_param;
1245
1246 lockdep_assert_held(&ar->conf_mutex);
1247
1248 vdev_param = ar->wmi.vdev_param->protection_mode;
1249
1250 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d cts_protection %d\n",
1251 arvif->vdev_id, arvif->use_cts_prot);
1252
1253 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
1254 arvif->use_cts_prot ? 1 : 0);
1255}
1256
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001257static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif)
1258{
1259 struct ath10k *ar = arvif->ar;
1260 u32 vdev_param, rts_cts = 0;
1261
1262 lockdep_assert_held(&ar->conf_mutex);
1263
1264 vdev_param = ar->wmi.vdev_param->enable_rtscts;
1265
Rajkumar Manoharan9a5ab0f2015-03-19 16:03:29 +02001266 rts_cts |= SM(WMI_RTSCTS_ENABLED, WMI_RTSCTS_SET);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001267
1268 if (arvif->num_legacy_stations > 0)
1269 rts_cts |= SM(WMI_RTSCTS_ACROSS_SW_RETRIES,
1270 WMI_RTSCTS_PROFILE);
Rajkumar Manoharan9a5ab0f2015-03-19 16:03:29 +02001271 else
1272 rts_cts |= SM(WMI_RTSCTS_FOR_SECOND_RATESERIES,
1273 WMI_RTSCTS_PROFILE);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02001274
1275 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
1276 rts_cts);
1277}
1278
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001279static int ath10k_start_cac(struct ath10k *ar)
1280{
1281 int ret;
1282
1283 lockdep_assert_held(&ar->conf_mutex);
1284
1285 set_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1286
Michal Kazior19337472014-08-28 12:58:16 +02001287 ret = ath10k_monitor_recalc(ar);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001288 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001289 ath10k_warn(ar, "failed to start monitor (cac): %d\n", ret);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001290 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
1291 return ret;
1292 }
1293
Michal Kazior7aa7a722014-08-25 12:09:38 +02001294 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac start monitor vdev %d\n",
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001295 ar->monitor_vdev_id);
1296
1297 return 0;
1298}
1299
1300static int ath10k_stop_cac(struct ath10k *ar)
1301{
1302 lockdep_assert_held(&ar->conf_mutex);
1303
1304 /* CAC is not running - do nothing */
1305 if (!test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags))
1306 return 0;
1307
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001308 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
Michal Kazior1bbc0972014-04-08 09:45:47 +03001309 ath10k_monitor_stop(ar);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001310
Michal Kazior7aa7a722014-08-25 12:09:38 +02001311 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac finished\n");
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001312
1313 return 0;
1314}
1315
Michal Kazior500ff9f2015-03-31 10:26:21 +00001316static void ath10k_mac_has_radar_iter(struct ieee80211_hw *hw,
1317 struct ieee80211_chanctx_conf *conf,
1318 void *data)
1319{
1320 bool *ret = data;
1321
1322 if (!*ret && conf->radar_enabled)
1323 *ret = true;
1324}
1325
1326static bool ath10k_mac_has_radar_enabled(struct ath10k *ar)
1327{
1328 bool has_radar = false;
1329
1330 ieee80211_iter_chan_contexts_atomic(ar->hw,
1331 ath10k_mac_has_radar_iter,
1332 &has_radar);
1333
1334 return has_radar;
1335}
1336
Michal Kaziord6500972014-04-08 09:56:09 +03001337static void ath10k_recalc_radar_detection(struct ath10k *ar)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001338{
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001339 int ret;
1340
1341 lockdep_assert_held(&ar->conf_mutex);
1342
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001343 ath10k_stop_cac(ar);
1344
Michal Kazior500ff9f2015-03-31 10:26:21 +00001345 if (!ath10k_mac_has_radar_enabled(ar))
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001346 return;
1347
Michal Kaziord6500972014-04-08 09:56:09 +03001348 if (ar->num_started_vdevs > 0)
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001349 return;
1350
1351 ret = ath10k_start_cac(ar);
1352 if (ret) {
1353 /*
1354 * Not possible to start CAC on current channel so starting
1355 * radiation is not allowed, make this channel DFS_UNAVAILABLE
1356 * by indicating that radar was detected.
1357 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02001358 ath10k_warn(ar, "failed to start CAC: %d\n", ret);
Marek Puzyniake8a50f82013-11-20 09:59:47 +02001359 ieee80211_radar_detected(ar->hw);
1360 }
1361}
1362
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301363static int ath10k_vdev_stop(struct ath10k_vif *arvif)
Michal Kazior72654fa2014-04-08 09:56:09 +03001364{
1365 struct ath10k *ar = arvif->ar;
Vasanthakumar Thiagarajan822b7e02015-03-02 17:45:27 +05301366 int ret;
1367
1368 lockdep_assert_held(&ar->conf_mutex);
1369
1370 reinit_completion(&ar->vdev_setup_done);
1371
1372 ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id);
1373 if (ret) {
1374 ath10k_warn(ar, "failed to stop WMI vdev %i: %d\n",
1375 arvif->vdev_id, ret);
1376 return ret;
1377 }
1378
1379 ret = ath10k_vdev_setup_sync(ar);
1380 if (ret) {
1381 ath10k_warn(ar, "failed to syncronise setup for vdev %i: %d\n",
1382 arvif->vdev_id, ret);
1383 return ret;
1384 }
1385
1386 WARN_ON(ar->num_started_vdevs == 0);
1387
1388 if (ar->num_started_vdevs != 0) {
1389 ar->num_started_vdevs--;
1390 ath10k_recalc_radar_detection(ar);
1391 }
1392
1393 return ret;
1394}
1395
Michal Kazior500ff9f2015-03-31 10:26:21 +00001396static int ath10k_vdev_start_restart(struct ath10k_vif *arvif,
1397 const struct cfg80211_chan_def *chandef,
1398 bool restart)
Michal Kazior72654fa2014-04-08 09:56:09 +03001399{
1400 struct ath10k *ar = arvif->ar;
Michal Kazior72654fa2014-04-08 09:56:09 +03001401 struct wmi_vdev_start_request_arg arg = {};
1402 int ret = 0;
1403
1404 lockdep_assert_held(&ar->conf_mutex);
1405
1406 reinit_completion(&ar->vdev_setup_done);
1407
1408 arg.vdev_id = arvif->vdev_id;
1409 arg.dtim_period = arvif->dtim_period;
1410 arg.bcn_intval = arvif->beacon_interval;
1411
1412 arg.channel.freq = chandef->chan->center_freq;
1413 arg.channel.band_center_freq1 = chandef->center_freq1;
1414 arg.channel.mode = chan_to_phymode(chandef);
1415
1416 arg.channel.min_power = 0;
1417 arg.channel.max_power = chandef->chan->max_power * 2;
1418 arg.channel.max_reg_power = chandef->chan->max_reg_power * 2;
1419 arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain * 2;
1420
1421 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
1422 arg.ssid = arvif->u.ap.ssid;
1423 arg.ssid_len = arvif->u.ap.ssid_len;
1424 arg.hidden_ssid = arvif->u.ap.hidden_ssid;
1425
1426 /* For now allow DFS for AP mode */
1427 arg.channel.chan_radar =
1428 !!(chandef->chan->flags & IEEE80211_CHAN_RADAR);
1429 } else if (arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
1430 arg.ssid = arvif->vif->bss_conf.ssid;
1431 arg.ssid_len = arvif->vif->bss_conf.ssid_len;
1432 }
1433
Michal Kazior7aa7a722014-08-25 12:09:38 +02001434 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior72654fa2014-04-08 09:56:09 +03001435 "mac vdev %d start center_freq %d phymode %s\n",
1436 arg.vdev_id, arg.channel.freq,
1437 ath10k_wmi_phymode_str(arg.channel.mode));
1438
Michal Kaziordc55e302014-07-29 12:53:36 +03001439 if (restart)
1440 ret = ath10k_wmi_vdev_restart(ar, &arg);
1441 else
1442 ret = ath10k_wmi_vdev_start(ar, &arg);
1443
Michal Kazior72654fa2014-04-08 09:56:09 +03001444 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001445 ath10k_warn(ar, "failed to start WMI vdev %i: %d\n",
Michal Kazior72654fa2014-04-08 09:56:09 +03001446 arg.vdev_id, ret);
1447 return ret;
1448 }
1449
1450 ret = ath10k_vdev_setup_sync(ar);
1451 if (ret) {
Ben Greear60028a82015-02-15 16:50:39 +02001452 ath10k_warn(ar,
1453 "failed to synchronize setup for vdev %i restart %d: %d\n",
1454 arg.vdev_id, restart, ret);
Michal Kazior72654fa2014-04-08 09:56:09 +03001455 return ret;
1456 }
1457
Michal Kaziord6500972014-04-08 09:56:09 +03001458 ar->num_started_vdevs++;
1459 ath10k_recalc_radar_detection(ar);
1460
Michal Kazior72654fa2014-04-08 09:56:09 +03001461 return ret;
1462}
1463
Michal Kazior500ff9f2015-03-31 10:26:21 +00001464static int ath10k_vdev_start(struct ath10k_vif *arvif,
1465 const struct cfg80211_chan_def *def)
Michal Kaziordc55e302014-07-29 12:53:36 +03001466{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001467 return ath10k_vdev_start_restart(arvif, def, false);
Michal Kaziordc55e302014-07-29 12:53:36 +03001468}
1469
Michal Kazior500ff9f2015-03-31 10:26:21 +00001470static int ath10k_vdev_restart(struct ath10k_vif *arvif,
1471 const struct cfg80211_chan_def *def)
Michal Kaziordc55e302014-07-29 12:53:36 +03001472{
Michal Kazior500ff9f2015-03-31 10:26:21 +00001473 return ath10k_vdev_start_restart(arvif, def, true);
Michal Kazior72654fa2014-04-08 09:56:09 +03001474}
1475
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001476static int ath10k_mac_setup_bcn_p2p_ie(struct ath10k_vif *arvif,
1477 struct sk_buff *bcn)
1478{
1479 struct ath10k *ar = arvif->ar;
1480 struct ieee80211_mgmt *mgmt;
1481 const u8 *p2p_ie;
1482 int ret;
1483
Peter Oh08c27be2016-01-28 13:54:09 -08001484 if (arvif->vif->type != NL80211_IFTYPE_AP || !arvif->vif->p2p)
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001485 return 0;
1486
1487 mgmt = (void *)bcn->data;
1488 p2p_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1489 mgmt->u.beacon.variable,
1490 bcn->len - (mgmt->u.beacon.variable -
1491 bcn->data));
1492 if (!p2p_ie)
1493 return -ENOENT;
1494
1495 ret = ath10k_wmi_p2p_go_bcn_ie(ar, arvif->vdev_id, p2p_ie);
1496 if (ret) {
1497 ath10k_warn(ar, "failed to submit p2p go bcn ie for vdev %i: %d\n",
1498 arvif->vdev_id, ret);
1499 return ret;
1500 }
1501
1502 return 0;
1503}
1504
1505static int ath10k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui,
1506 u8 oui_type, size_t ie_offset)
1507{
1508 size_t len;
1509 const u8 *next;
1510 const u8 *end;
1511 u8 *ie;
1512
1513 if (WARN_ON(skb->len < ie_offset))
1514 return -EINVAL;
1515
1516 ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type,
1517 skb->data + ie_offset,
1518 skb->len - ie_offset);
1519 if (!ie)
1520 return -ENOENT;
1521
1522 len = ie[1] + 2;
1523 end = skb->data + skb->len;
1524 next = ie + len;
1525
1526 if (WARN_ON(next > end))
1527 return -EINVAL;
1528
1529 memmove(ie, next, end - next);
1530 skb_trim(skb, skb->len - len);
1531
1532 return 0;
1533}
1534
1535static int ath10k_mac_setup_bcn_tmpl(struct ath10k_vif *arvif)
1536{
1537 struct ath10k *ar = arvif->ar;
1538 struct ieee80211_hw *hw = ar->hw;
1539 struct ieee80211_vif *vif = arvif->vif;
1540 struct ieee80211_mutable_offsets offs = {};
1541 struct sk_buff *bcn;
1542 int ret;
1543
1544 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1545 return 0;
1546
Michal Kazior81a9a172015-03-05 16:02:17 +02001547 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
1548 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
1549 return 0;
1550
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001551 bcn = ieee80211_beacon_get_template(hw, vif, &offs);
1552 if (!bcn) {
1553 ath10k_warn(ar, "failed to get beacon template from mac80211\n");
1554 return -EPERM;
1555 }
1556
1557 ret = ath10k_mac_setup_bcn_p2p_ie(arvif, bcn);
1558 if (ret) {
1559 ath10k_warn(ar, "failed to setup p2p go bcn ie: %d\n", ret);
1560 kfree_skb(bcn);
1561 return ret;
1562 }
1563
1564 /* P2P IE is inserted by firmware automatically (as configured above)
1565 * so remove it from the base beacon template to avoid duplicate P2P
1566 * IEs in beacon frames.
1567 */
1568 ath10k_mac_remove_vendor_ie(bcn, WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1569 offsetof(struct ieee80211_mgmt,
1570 u.beacon.variable));
1571
1572 ret = ath10k_wmi_bcn_tmpl(ar, arvif->vdev_id, offs.tim_offset, bcn, 0,
1573 0, NULL, 0);
1574 kfree_skb(bcn);
1575
1576 if (ret) {
1577 ath10k_warn(ar, "failed to submit beacon template command: %d\n",
1578 ret);
1579 return ret;
1580 }
1581
1582 return 0;
1583}
1584
1585static int ath10k_mac_setup_prb_tmpl(struct ath10k_vif *arvif)
1586{
1587 struct ath10k *ar = arvif->ar;
1588 struct ieee80211_hw *hw = ar->hw;
1589 struct ieee80211_vif *vif = arvif->vif;
1590 struct sk_buff *prb;
1591 int ret;
1592
1593 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1594 return 0;
1595
Michal Kazior81a9a172015-03-05 16:02:17 +02001596 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1597 return 0;
1598
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001599 prb = ieee80211_proberesp_get(hw, vif);
1600 if (!prb) {
1601 ath10k_warn(ar, "failed to get probe resp template from mac80211\n");
1602 return -EPERM;
1603 }
1604
1605 ret = ath10k_wmi_prb_tmpl(ar, arvif->vdev_id, prb);
1606 kfree_skb(prb);
1607
1608 if (ret) {
1609 ath10k_warn(ar, "failed to submit probe resp template command: %d\n",
1610 ret);
1611 return ret;
1612 }
1613
1614 return 0;
1615}
1616
Michal Kazior500ff9f2015-03-31 10:26:21 +00001617static int ath10k_mac_vif_fix_hidden_ssid(struct ath10k_vif *arvif)
1618{
1619 struct ath10k *ar = arvif->ar;
1620 struct cfg80211_chan_def def;
1621 int ret;
1622
1623 /* When originally vdev is started during assign_vif_chanctx() some
1624 * information is missing, notably SSID. Firmware revisions with beacon
1625 * offloading require the SSID to be provided during vdev (re)start to
1626 * handle hidden SSID properly.
1627 *
1628 * Vdev restart must be done after vdev has been both started and
1629 * upped. Otherwise some firmware revisions (at least 10.2) fail to
1630 * deliver vdev restart response event causing timeouts during vdev
1631 * syncing in ath10k.
1632 *
1633 * Note: The vdev down/up and template reinstallation could be skipped
1634 * since only wmi-tlv firmware are known to have beacon offload and
1635 * wmi-tlv doesn't seem to misbehave like 10.2 wrt vdev restart
1636 * response delivery. It's probably more robust to keep it as is.
1637 */
1638 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1639 return 0;
1640
1641 if (WARN_ON(!arvif->is_started))
1642 return -EINVAL;
1643
1644 if (WARN_ON(!arvif->is_up))
1645 return -EINVAL;
1646
1647 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
1648 return -EINVAL;
1649
1650 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1651 if (ret) {
1652 ath10k_warn(ar, "failed to bring down ap vdev %i: %d\n",
1653 arvif->vdev_id, ret);
1654 return ret;
1655 }
1656
1657 /* Vdev down reset beacon & presp templates. Reinstall them. Otherwise
1658 * firmware will crash upon vdev up.
1659 */
1660
1661 ret = ath10k_mac_setup_bcn_tmpl(arvif);
1662 if (ret) {
1663 ath10k_warn(ar, "failed to update beacon template: %d\n", ret);
1664 return ret;
1665 }
1666
1667 ret = ath10k_mac_setup_prb_tmpl(arvif);
1668 if (ret) {
1669 ath10k_warn(ar, "failed to update presp template: %d\n", ret);
1670 return ret;
1671 }
1672
1673 ret = ath10k_vdev_restart(arvif, &def);
1674 if (ret) {
1675 ath10k_warn(ar, "failed to restart ap vdev %i: %d\n",
1676 arvif->vdev_id, ret);
1677 return ret;
1678 }
1679
1680 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1681 arvif->bssid);
1682 if (ret) {
1683 ath10k_warn(ar, "failed to bring up ap vdev %i: %d\n",
1684 arvif->vdev_id, ret);
1685 return ret;
1686 }
1687
1688 return 0;
1689}
1690
Kalle Valo5e3dd152013-06-12 20:52:10 +03001691static void ath10k_control_beaconing(struct ath10k_vif *arvif,
Kalle Valo5b07e072014-09-14 12:50:06 +03001692 struct ieee80211_bss_conf *info)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001693{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001694 struct ath10k *ar = arvif->ar;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001695 int ret = 0;
1696
Michal Kazior548db542013-07-05 16:15:15 +03001697 lockdep_assert_held(&arvif->ar->conf_mutex);
1698
Kalle Valo5e3dd152013-06-12 20:52:10 +03001699 if (!info->enable_beacon) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00001700 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1701 if (ret)
1702 ath10k_warn(ar, "failed to down vdev_id %i: %d\n",
1703 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01001704
Michal Kaziorc930f742014-01-23 11:38:25 +01001705 arvif->is_up = false;
1706
Michal Kazior748afc42014-01-23 12:48:21 +01001707 spin_lock_bh(&arvif->ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03001708 ath10k_mac_vif_beacon_free(arvif);
Michal Kazior748afc42014-01-23 12:48:21 +01001709 spin_unlock_bh(&arvif->ar->data_lock);
1710
Kalle Valo5e3dd152013-06-12 20:52:10 +03001711 return;
1712 }
1713
1714 arvif->tx_seq_no = 0x1000;
1715
Michal Kaziorc930f742014-01-23 11:38:25 +01001716 arvif->aid = 0;
Kalle Valob25f32c2014-09-14 12:50:49 +03001717 ether_addr_copy(arvif->bssid, info->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01001718
1719 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1720 arvif->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001721 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001722 ath10k_warn(ar, "failed to bring up vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001723 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001724 return;
1725 }
Michal Kaziorc930f742014-01-23 11:38:25 +01001726
Michal Kaziorc930f742014-01-23 11:38:25 +01001727 arvif->is_up = true;
1728
Michal Kazior500ff9f2015-03-31 10:26:21 +00001729 ret = ath10k_mac_vif_fix_hidden_ssid(arvif);
1730 if (ret) {
1731 ath10k_warn(ar, "failed to fix hidden ssid for vdev %i, expect trouble: %d\n",
1732 arvif->vdev_id, ret);
1733 return;
1734 }
1735
Michal Kazior7aa7a722014-08-25 12:09:38 +02001736 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d up\n", arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001737}
1738
1739static void ath10k_control_ibss(struct ath10k_vif *arvif,
1740 struct ieee80211_bss_conf *info,
1741 const u8 self_peer[ETH_ALEN])
1742{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001743 struct ath10k *ar = arvif->ar;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001744 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001745 int ret = 0;
1746
Michal Kazior548db542013-07-05 16:15:15 +03001747 lockdep_assert_held(&arvif->ar->conf_mutex);
1748
Kalle Valo5e3dd152013-06-12 20:52:10 +03001749 if (!info->ibss_joined) {
Michal Kaziorc930f742014-01-23 11:38:25 +01001750 if (is_zero_ether_addr(arvif->bssid))
Kalle Valo5e3dd152013-06-12 20:52:10 +03001751 return;
1752
Joe Perches93803b32015-03-02 19:54:49 -08001753 eth_zero_addr(arvif->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001754
1755 return;
1756 }
1757
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001758 vdev_param = arvif->ar->wmi.vdev_param->atim_window;
1759 ret = ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001760 ATH10K_DEFAULT_ATIM);
1761 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001762 ath10k_warn(ar, "failed to set IBSS ATIM for vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001763 arvif->vdev_id, ret);
1764}
1765
Michal Kazior9f9b5742014-12-12 12:41:36 +01001766static int ath10k_mac_vif_recalc_ps_wake_threshold(struct ath10k_vif *arvif)
1767{
1768 struct ath10k *ar = arvif->ar;
1769 u32 param;
1770 u32 value;
1771 int ret;
1772
1773 lockdep_assert_held(&arvif->ar->conf_mutex);
1774
1775 if (arvif->u.sta.uapsd)
1776 value = WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER;
1777 else
1778 value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS;
1779
1780 param = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD;
1781 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, value);
1782 if (ret) {
1783 ath10k_warn(ar, "failed to submit ps wake threshold %u on vdev %i: %d\n",
1784 value, arvif->vdev_id, ret);
1785 return ret;
1786 }
1787
1788 return 0;
1789}
1790
1791static int ath10k_mac_vif_recalc_ps_poll_count(struct ath10k_vif *arvif)
1792{
1793 struct ath10k *ar = arvif->ar;
1794 u32 param;
1795 u32 value;
1796 int ret;
1797
1798 lockdep_assert_held(&arvif->ar->conf_mutex);
1799
1800 if (arvif->u.sta.uapsd)
1801 value = WMI_STA_PS_PSPOLL_COUNT_UAPSD;
1802 else
1803 value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX;
1804
1805 param = WMI_STA_PS_PARAM_PSPOLL_COUNT;
1806 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
1807 param, value);
1808 if (ret) {
1809 ath10k_warn(ar, "failed to submit ps poll count %u on vdev %i: %d\n",
1810 value, arvif->vdev_id, ret);
1811 return ret;
1812 }
1813
1814 return 0;
1815}
1816
Michal Kazior424f2632015-07-09 13:08:35 +02001817static int ath10k_mac_num_vifs_started(struct ath10k *ar)
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001818{
1819 struct ath10k_vif *arvif;
1820 int num = 0;
1821
1822 lockdep_assert_held(&ar->conf_mutex);
1823
1824 list_for_each_entry(arvif, &ar->arvifs, list)
Michal Kazior424f2632015-07-09 13:08:35 +02001825 if (arvif->is_started)
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001826 num++;
1827
1828 return num;
1829}
1830
Michal Kaziorad088bf2013-10-16 15:44:46 +03001831static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001832{
Michal Kaziorad088bf2013-10-16 15:44:46 +03001833 struct ath10k *ar = arvif->ar;
Michal Kazior526549a2014-12-12 12:41:37 +01001834 struct ieee80211_vif *vif = arvif->vif;
Michal Kaziorad088bf2013-10-16 15:44:46 +03001835 struct ieee80211_conf *conf = &ar->hw->conf;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001836 enum wmi_sta_powersave_param param;
1837 enum wmi_sta_ps_mode psmode;
1838 int ret;
Michal Kazior526549a2014-12-12 12:41:37 +01001839 int ps_timeout;
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001840 bool enable_ps;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001841
Michal Kazior548db542013-07-05 16:15:15 +03001842 lockdep_assert_held(&arvif->ar->conf_mutex);
1843
Michal Kaziorad088bf2013-10-16 15:44:46 +03001844 if (arvif->vif->type != NL80211_IFTYPE_STATION)
1845 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001846
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001847 enable_ps = arvif->ps;
1848
Michal Kazior424f2632015-07-09 13:08:35 +02001849 if (enable_ps && ath10k_mac_num_vifs_started(ar) > 1 &&
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001850 !test_bit(ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT,
Kalle Valoc4cdf752016-04-20 19:45:18 +03001851 ar->running_fw->fw_file.fw_features)) {
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001852 ath10k_warn(ar, "refusing to enable ps on vdev %i: not supported by fw\n",
1853 arvif->vdev_id);
1854 enable_ps = false;
1855 }
1856
Janusz Dziedzic917826b2015-05-18 09:38:17 +00001857 if (!arvif->is_started) {
1858 /* mac80211 can update vif powersave state while disconnected.
1859 * Firmware doesn't behave nicely and consumes more power than
1860 * necessary if PS is disabled on a non-started vdev. Hence
1861 * force-enable PS for non-running vdevs.
1862 */
1863 psmode = WMI_STA_PS_MODE_ENABLED;
1864 } else if (enable_ps) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03001865 psmode = WMI_STA_PS_MODE_ENABLED;
1866 param = WMI_STA_PS_PARAM_INACTIVITY_TIME;
1867
Michal Kazior526549a2014-12-12 12:41:37 +01001868 ps_timeout = conf->dynamic_ps_timeout;
1869 if (ps_timeout == 0) {
1870 /* Firmware doesn't like 0 */
1871 ps_timeout = ieee80211_tu_to_usec(
1872 vif->bss_conf.beacon_int) / 1000;
1873 }
1874
Michal Kaziorad088bf2013-10-16 15:44:46 +03001875 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param,
Michal Kazior526549a2014-12-12 12:41:37 +01001876 ps_timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001877 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001878 ath10k_warn(ar, "failed to set inactivity time for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001879 arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001880 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001881 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001882 } else {
1883 psmode = WMI_STA_PS_MODE_DISABLED;
1884 }
1885
Michal Kazior7aa7a722014-08-25 12:09:38 +02001886 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d psmode %s\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03001887 arvif->vdev_id, psmode ? "enable" : "disable");
1888
Michal Kaziorad088bf2013-10-16 15:44:46 +03001889 ret = ath10k_wmi_set_psmode(ar, arvif->vdev_id, psmode);
1890 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001891 ath10k_warn(ar, "failed to set PS Mode %d for vdev %d: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02001892 psmode, arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001893 return ret;
1894 }
1895
1896 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001897}
1898
Michal Kazior46725b12015-01-28 09:57:49 +02001899static int ath10k_mac_vif_disable_keepalive(struct ath10k_vif *arvif)
1900{
1901 struct ath10k *ar = arvif->ar;
1902 struct wmi_sta_keepalive_arg arg = {};
1903 int ret;
1904
1905 lockdep_assert_held(&arvif->ar->conf_mutex);
1906
1907 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
1908 return 0;
1909
1910 if (!test_bit(WMI_SERVICE_STA_KEEP_ALIVE, ar->wmi.svc_map))
1911 return 0;
1912
1913 /* Some firmware revisions have a bug and ignore the `enabled` field.
1914 * Instead use the interval to disable the keepalive.
1915 */
1916 arg.vdev_id = arvif->vdev_id;
1917 arg.enabled = 1;
1918 arg.method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME;
1919 arg.interval = WMI_STA_KEEPALIVE_INTERVAL_DISABLE;
1920
1921 ret = ath10k_wmi_sta_keepalive(ar, &arg);
1922 if (ret) {
1923 ath10k_warn(ar, "failed to submit keepalive on vdev %i: %d\n",
1924 arvif->vdev_id, ret);
1925 return ret;
1926 }
1927
1928 return 0;
1929}
1930
Michal Kazior81a9a172015-03-05 16:02:17 +02001931static void ath10k_mac_vif_ap_csa_count_down(struct ath10k_vif *arvif)
1932{
1933 struct ath10k *ar = arvif->ar;
1934 struct ieee80211_vif *vif = arvif->vif;
1935 int ret;
1936
Michal Kazior8513d952015-03-09 14:19:24 +01001937 lockdep_assert_held(&arvif->ar->conf_mutex);
1938
1939 if (WARN_ON(!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)))
1940 return;
1941
Michal Kazior81a9a172015-03-05 16:02:17 +02001942 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1943 return;
1944
1945 if (!vif->csa_active)
1946 return;
1947
1948 if (!arvif->is_up)
1949 return;
1950
1951 if (!ieee80211_csa_is_complete(vif)) {
1952 ieee80211_csa_update_counter(vif);
1953
1954 ret = ath10k_mac_setup_bcn_tmpl(arvif);
1955 if (ret)
1956 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
1957 ret);
1958
1959 ret = ath10k_mac_setup_prb_tmpl(arvif);
1960 if (ret)
1961 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
1962 ret);
1963 } else {
1964 ieee80211_csa_finish(vif);
1965 }
1966}
1967
1968static void ath10k_mac_vif_ap_csa_work(struct work_struct *work)
1969{
1970 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
1971 ap_csa_work);
1972 struct ath10k *ar = arvif->ar;
1973
1974 mutex_lock(&ar->conf_mutex);
1975 ath10k_mac_vif_ap_csa_count_down(arvif);
1976 mutex_unlock(&ar->conf_mutex);
1977}
1978
Michal Kaziorcc9904e2015-03-10 16:22:01 +02001979static void ath10k_mac_handle_beacon_iter(void *data, u8 *mac,
1980 struct ieee80211_vif *vif)
1981{
1982 struct sk_buff *skb = data;
1983 struct ieee80211_mgmt *mgmt = (void *)skb->data;
1984 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1985
1986 if (vif->type != NL80211_IFTYPE_STATION)
1987 return;
1988
1989 if (!ether_addr_equal(mgmt->bssid, vif->bss_conf.bssid))
1990 return;
1991
1992 cancel_delayed_work(&arvif->connection_loss_work);
1993}
1994
1995void ath10k_mac_handle_beacon(struct ath10k *ar, struct sk_buff *skb)
1996{
1997 ieee80211_iterate_active_interfaces_atomic(ar->hw,
1998 IEEE80211_IFACE_ITER_NORMAL,
1999 ath10k_mac_handle_beacon_iter,
2000 skb);
2001}
2002
2003static void ath10k_mac_handle_beacon_miss_iter(void *data, u8 *mac,
2004 struct ieee80211_vif *vif)
2005{
2006 u32 *vdev_id = data;
2007 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2008 struct ath10k *ar = arvif->ar;
2009 struct ieee80211_hw *hw = ar->hw;
2010
2011 if (arvif->vdev_id != *vdev_id)
2012 return;
2013
2014 if (!arvif->is_up)
2015 return;
2016
2017 ieee80211_beacon_loss(vif);
2018
2019 /* Firmware doesn't report beacon loss events repeatedly. If AP probe
2020 * (done by mac80211) succeeds but beacons do not resume then it
2021 * doesn't make sense to continue operation. Queue connection loss work
2022 * which can be cancelled when beacon is received.
2023 */
2024 ieee80211_queue_delayed_work(hw, &arvif->connection_loss_work,
2025 ATH10K_CONNECTION_LOSS_HZ);
2026}
2027
2028void ath10k_mac_handle_beacon_miss(struct ath10k *ar, u32 vdev_id)
2029{
2030 ieee80211_iterate_active_interfaces_atomic(ar->hw,
2031 IEEE80211_IFACE_ITER_NORMAL,
2032 ath10k_mac_handle_beacon_miss_iter,
2033 &vdev_id);
2034}
2035
2036static void ath10k_mac_vif_sta_connection_loss_work(struct work_struct *work)
2037{
2038 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
2039 connection_loss_work.work);
2040 struct ieee80211_vif *vif = arvif->vif;
2041
2042 if (!arvif->is_up)
2043 return;
2044
2045 ieee80211_connection_loss(vif);
2046}
2047
Kalle Valo5e3dd152013-06-12 20:52:10 +03002048/**********************/
2049/* Station management */
2050/**********************/
2051
Michal Kazior590922a2014-10-21 10:10:29 +03002052static u32 ath10k_peer_assoc_h_listen_intval(struct ath10k *ar,
2053 struct ieee80211_vif *vif)
2054{
2055 /* Some firmware revisions have unstable STA powersave when listen
2056 * interval is set too high (e.g. 5). The symptoms are firmware doesn't
2057 * generate NullFunc frames properly even if buffered frames have been
2058 * indicated in Beacon TIM. Firmware would seldom wake up to pull
2059 * buffered frames. Often pinging the device from AP would simply fail.
2060 *
2061 * As a workaround set it to 1.
2062 */
2063 if (vif->type == NL80211_IFTYPE_STATION)
2064 return 1;
2065
2066 return ar->hw->conf.listen_interval;
2067}
2068
Kalle Valo5e3dd152013-06-12 20:52:10 +03002069static void ath10k_peer_assoc_h_basic(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002070 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002071 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002072 struct wmi_peer_assoc_complete_arg *arg)
2073{
Michal Kazior590922a2014-10-21 10:10:29 +03002074 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorc51880e2015-03-30 09:51:57 +03002075 u32 aid;
Michal Kazior590922a2014-10-21 10:10:29 +03002076
Michal Kazior548db542013-07-05 16:15:15 +03002077 lockdep_assert_held(&ar->conf_mutex);
2078
Michal Kaziorc51880e2015-03-30 09:51:57 +03002079 if (vif->type == NL80211_IFTYPE_STATION)
2080 aid = vif->bss_conf.aid;
2081 else
2082 aid = sta->aid;
2083
Kalle Valob25f32c2014-09-14 12:50:49 +03002084 ether_addr_copy(arg->addr, sta->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002085 arg->vdev_id = arvif->vdev_id;
Michal Kaziorc51880e2015-03-30 09:51:57 +03002086 arg->peer_aid = aid;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002087 arg->peer_flags |= arvif->ar->wmi.peer_flags->auth;
Michal Kazior590922a2014-10-21 10:10:29 +03002088 arg->peer_listen_intval = ath10k_peer_assoc_h_listen_intval(ar, vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002089 arg->peer_num_spatial_streams = 1;
Michal Kazior590922a2014-10-21 10:10:29 +03002090 arg->peer_caps = vif->bss_conf.assoc_capability;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002091}
2092
2093static void ath10k_peer_assoc_h_crypto(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002094 struct ieee80211_vif *vif,
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002095 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002096 struct wmi_peer_assoc_complete_arg *arg)
2097{
Kalle Valo5e3dd152013-06-12 20:52:10 +03002098 struct ieee80211_bss_conf *info = &vif->bss_conf;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002099 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002100 struct cfg80211_bss *bss;
2101 const u8 *rsnie = NULL;
2102 const u8 *wpaie = NULL;
2103
Michal Kazior548db542013-07-05 16:15:15 +03002104 lockdep_assert_held(&ar->conf_mutex);
2105
Michal Kazior500ff9f2015-03-31 10:26:21 +00002106 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2107 return;
2108
2109 bss = cfg80211_get_bss(ar->hw->wiphy, def.chan, info->bssid, NULL, 0,
2110 IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002111 if (bss) {
2112 const struct cfg80211_bss_ies *ies;
2113
2114 rcu_read_lock();
2115 rsnie = ieee80211_bss_get_ie(bss, WLAN_EID_RSN);
2116
2117 ies = rcu_dereference(bss->ies);
2118
2119 wpaie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
Kalle Valo5b07e072014-09-14 12:50:06 +03002120 WLAN_OUI_TYPE_MICROSOFT_WPA,
2121 ies->data,
2122 ies->len);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002123 rcu_read_unlock();
2124 cfg80211_put_bss(ar->hw->wiphy, bss);
2125 }
2126
2127 /* FIXME: base on RSN IE/WPA IE is a correct idea? */
2128 if (rsnie || wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002129 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: rsn ie found\n", __func__);
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002130 arg->peer_flags |= ar->wmi.peer_flags->need_ptk_4_way;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002131 }
2132
2133 if (wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002134 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: wpa ie found\n", __func__);
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002135 arg->peer_flags |= ar->wmi.peer_flags->need_gtk_2_way;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002136 }
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002137
2138 if (sta->mfp &&
Kalle Valoc4cdf752016-04-20 19:45:18 +03002139 test_bit(ATH10K_FW_FEATURE_MFP_SUPPORT,
2140 ar->running_fw->fw_file.fw_features)) {
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002141 arg->peer_flags |= ar->wmi.peer_flags->pmf;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002142 }
2143}
2144
2145static void ath10k_peer_assoc_h_rates(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002146 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002147 struct ieee80211_sta *sta,
2148 struct wmi_peer_assoc_complete_arg *arg)
2149{
Michal Kazior45c9abc2015-04-21 20:42:58 +03002150 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002151 struct wmi_rate_set_arg *rateset = &arg->peer_legacy_rates;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002152 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002153 const struct ieee80211_supported_band *sband;
2154 const struct ieee80211_rate *rates;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002155 enum nl80211_band band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002156 u32 ratemask;
Michal Kazior486017c2015-03-30 09:51:54 +03002157 u8 rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002158 int i;
2159
Michal Kazior548db542013-07-05 16:15:15 +03002160 lockdep_assert_held(&ar->conf_mutex);
2161
Michal Kazior500ff9f2015-03-31 10:26:21 +00002162 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2163 return;
2164
Michal Kazior45c9abc2015-04-21 20:42:58 +03002165 band = def.chan->band;
2166 sband = ar->hw->wiphy->bands[band];
2167 ratemask = sta->supp_rates[band];
2168 ratemask &= arvif->bitrate_mask.control[band].legacy;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002169 rates = sband->bitrates;
2170
2171 rateset->num_rates = 0;
2172
2173 for (i = 0; i < 32; i++, ratemask >>= 1, rates++) {
2174 if (!(ratemask & 1))
2175 continue;
2176
Michal Kazior486017c2015-03-30 09:51:54 +03002177 rate = ath10k_mac_bitrate_to_rate(rates->bitrate);
2178 rateset->rates[rateset->num_rates] = rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002179 rateset->num_rates++;
2180 }
2181}
2182
Michal Kazior45c9abc2015-04-21 20:42:58 +03002183static bool
2184ath10k_peer_assoc_h_ht_masked(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
2185{
2186 int nss;
2187
2188 for (nss = 0; nss < IEEE80211_HT_MCS_MASK_LEN; nss++)
2189 if (ht_mcs_mask[nss])
2190 return false;
2191
2192 return true;
2193}
2194
2195static bool
2196ath10k_peer_assoc_h_vht_masked(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
2197{
2198 int nss;
2199
2200 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++)
2201 if (vht_mcs_mask[nss])
2202 return false;
2203
2204 return true;
2205}
2206
Kalle Valo5e3dd152013-06-12 20:52:10 +03002207static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
Michal Kazior45c9abc2015-04-21 20:42:58 +03002208 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002209 struct ieee80211_sta *sta,
2210 struct wmi_peer_assoc_complete_arg *arg)
2211{
2212 const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002213 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2214 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002215 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002216 const u8 *ht_mcs_mask;
2217 const u16 *vht_mcs_mask;
Vivek Natarajan72f8cef2015-10-06 15:19:34 +03002218 int i, n;
2219 u8 max_nss;
Kalle Valoaf762c02014-09-14 12:50:17 +03002220 u32 stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002221
Michal Kazior548db542013-07-05 16:15:15 +03002222 lockdep_assert_held(&ar->conf_mutex);
2223
Michal Kazior45c9abc2015-04-21 20:42:58 +03002224 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2225 return;
2226
Kalle Valo5e3dd152013-06-12 20:52:10 +03002227 if (!ht_cap->ht_supported)
2228 return;
2229
Michal Kazior45c9abc2015-04-21 20:42:58 +03002230 band = def.chan->band;
2231 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
2232 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2233
2234 if (ath10k_peer_assoc_h_ht_masked(ht_mcs_mask) &&
2235 ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
2236 return;
2237
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002238 arg->peer_flags |= ar->wmi.peer_flags->ht;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002239 arg->peer_max_mpdu = (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2240 ht_cap->ampdu_factor)) - 1;
2241
2242 arg->peer_mpdu_density =
2243 ath10k_parse_mpdudensity(ht_cap->ampdu_density);
2244
2245 arg->peer_ht_caps = ht_cap->cap;
2246 arg->peer_rate_caps |= WMI_RC_HT_FLAG;
2247
2248 if (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002249 arg->peer_flags |= ar->wmi.peer_flags->ldbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002250
2251 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) {
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002252 arg->peer_flags |= ar->wmi.peer_flags->bw40;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002253 arg->peer_rate_caps |= WMI_RC_CW40_FLAG;
2254 }
2255
Michal Kazior45c9abc2015-04-21 20:42:58 +03002256 if (arvif->bitrate_mask.control[band].gi != NL80211_TXRATE_FORCE_LGI) {
2257 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
2258 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002259
Michal Kazior45c9abc2015-04-21 20:42:58 +03002260 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40)
2261 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
2262 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002263
2264 if (ht_cap->cap & IEEE80211_HT_CAP_TX_STBC) {
2265 arg->peer_rate_caps |= WMI_RC_TX_STBC_FLAG;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002266 arg->peer_flags |= ar->wmi.peer_flags->stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002267 }
2268
2269 if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002270 stbc = ht_cap->cap & IEEE80211_HT_CAP_RX_STBC;
2271 stbc = stbc >> IEEE80211_HT_CAP_RX_STBC_SHIFT;
2272 stbc = stbc << WMI_RC_RX_STBC_FLAG_S;
2273 arg->peer_rate_caps |= stbc;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002274 arg->peer_flags |= ar->wmi.peer_flags->stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002275 }
2276
Kalle Valo5e3dd152013-06-12 20:52:10 +03002277 if (ht_cap->mcs.rx_mask[1] && ht_cap->mcs.rx_mask[2])
2278 arg->peer_rate_caps |= WMI_RC_TS_FLAG;
2279 else if (ht_cap->mcs.rx_mask[1])
2280 arg->peer_rate_caps |= WMI_RC_DS_FLAG;
2281
Michal Kazior45c9abc2015-04-21 20:42:58 +03002282 for (i = 0, n = 0, max_nss = 0; i < IEEE80211_HT_MCS_MASK_LEN * 8; i++)
2283 if ((ht_cap->mcs.rx_mask[i / 8] & BIT(i % 8)) &&
2284 (ht_mcs_mask[i / 8] & BIT(i % 8))) {
2285 max_nss = (i / 8) + 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002286 arg->peer_ht_rates.rates[n++] = i;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002287 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002288
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002289 /*
2290 * This is a workaround for HT-enabled STAs which break the spec
2291 * and have no HT capabilities RX mask (no HT RX MCS map).
2292 *
2293 * As per spec, in section 20.3.5 Modulation and coding scheme (MCS),
2294 * MCS 0 through 7 are mandatory in 20MHz with 800 ns GI at all STAs.
2295 *
2296 * Firmware asserts if such situation occurs.
2297 */
2298 if (n == 0) {
2299 arg->peer_ht_rates.num_rates = 8;
2300 for (i = 0; i < arg->peer_ht_rates.num_rates; i++)
2301 arg->peer_ht_rates.rates[i] = i;
2302 } else {
2303 arg->peer_ht_rates.num_rates = n;
Vivek Natarajan72f8cef2015-10-06 15:19:34 +03002304 arg->peer_num_spatial_streams = min(sta->rx_nss, max_nss);
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002305 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002306
Michal Kazior7aa7a722014-08-25 12:09:38 +02002307 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002308 arg->addr,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002309 arg->peer_ht_rates.num_rates,
2310 arg->peer_num_spatial_streams);
2311}
2312
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002313static int ath10k_peer_assoc_qos_ap(struct ath10k *ar,
2314 struct ath10k_vif *arvif,
2315 struct ieee80211_sta *sta)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002316{
2317 u32 uapsd = 0;
2318 u32 max_sp = 0;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002319 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002320
Michal Kazior548db542013-07-05 16:15:15 +03002321 lockdep_assert_held(&ar->conf_mutex);
2322
Kalle Valo5e3dd152013-06-12 20:52:10 +03002323 if (sta->wme && sta->uapsd_queues) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002324 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac uapsd_queues 0x%x max_sp %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002325 sta->uapsd_queues, sta->max_sp);
2326
Kalle Valo5e3dd152013-06-12 20:52:10 +03002327 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
2328 uapsd |= WMI_AP_PS_UAPSD_AC3_DELIVERY_EN |
2329 WMI_AP_PS_UAPSD_AC3_TRIGGER_EN;
2330 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
2331 uapsd |= WMI_AP_PS_UAPSD_AC2_DELIVERY_EN |
2332 WMI_AP_PS_UAPSD_AC2_TRIGGER_EN;
2333 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
2334 uapsd |= WMI_AP_PS_UAPSD_AC1_DELIVERY_EN |
2335 WMI_AP_PS_UAPSD_AC1_TRIGGER_EN;
2336 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
2337 uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN |
2338 WMI_AP_PS_UAPSD_AC0_TRIGGER_EN;
2339
Kalle Valo5e3dd152013-06-12 20:52:10 +03002340 if (sta->max_sp < MAX_WMI_AP_PS_PEER_PARAM_MAX_SP)
2341 max_sp = sta->max_sp;
2342
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002343 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2344 sta->addr,
2345 WMI_AP_PS_PEER_PARAM_UAPSD,
2346 uapsd);
2347 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002348 ath10k_warn(ar, "failed to set ap ps peer param uapsd for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002349 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002350 return ret;
2351 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002352
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002353 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2354 sta->addr,
2355 WMI_AP_PS_PEER_PARAM_MAX_SP,
2356 max_sp);
2357 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002358 ath10k_warn(ar, "failed to set ap ps peer param max sp for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002359 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002360 return ret;
2361 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002362
2363 /* TODO setup this based on STA listen interval and
2364 beacon interval. Currently we don't know
2365 sta->listen_interval - mac80211 patch required.
2366 Currently use 10 seconds */
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002367 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, sta->addr,
Kalle Valo5b07e072014-09-14 12:50:06 +03002368 WMI_AP_PS_PEER_PARAM_AGEOUT_TIME,
2369 10);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002370 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002371 ath10k_warn(ar, "failed to set ap ps peer param ageout time for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002372 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002373 return ret;
2374 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002375 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002376
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002377 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002378}
2379
Michal Kazior45c9abc2015-04-21 20:42:58 +03002380static u16
2381ath10k_peer_assoc_h_vht_limit(u16 tx_mcs_set,
2382 const u16 vht_mcs_limit[NL80211_VHT_NSS_MAX])
2383{
2384 int idx_limit;
2385 int nss;
2386 u16 mcs_map;
2387 u16 mcs;
2388
2389 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {
2390 mcs_map = ath10k_mac_get_max_vht_mcs_map(tx_mcs_set, nss) &
2391 vht_mcs_limit[nss];
2392
2393 if (mcs_map)
2394 idx_limit = fls(mcs_map) - 1;
2395 else
2396 idx_limit = -1;
2397
2398 switch (idx_limit) {
2399 case 0: /* fall through */
2400 case 1: /* fall through */
2401 case 2: /* fall through */
2402 case 3: /* fall through */
2403 case 4: /* fall through */
2404 case 5: /* fall through */
2405 case 6: /* fall through */
2406 default:
2407 /* see ath10k_mac_can_set_bitrate_mask() */
2408 WARN_ON(1);
2409 /* fall through */
2410 case -1:
2411 mcs = IEEE80211_VHT_MCS_NOT_SUPPORTED;
2412 break;
2413 case 7:
2414 mcs = IEEE80211_VHT_MCS_SUPPORT_0_7;
2415 break;
2416 case 8:
2417 mcs = IEEE80211_VHT_MCS_SUPPORT_0_8;
2418 break;
2419 case 9:
2420 mcs = IEEE80211_VHT_MCS_SUPPORT_0_9;
2421 break;
2422 }
2423
2424 tx_mcs_set &= ~(0x3 << (nss * 2));
2425 tx_mcs_set |= mcs << (nss * 2);
2426 }
2427
2428 return tx_mcs_set;
2429}
2430
Kalle Valo5e3dd152013-06-12 20:52:10 +03002431static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002432 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002433 struct ieee80211_sta *sta,
2434 struct wmi_peer_assoc_complete_arg *arg)
2435{
2436 const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002437 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002438 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002439 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002440 const u16 *vht_mcs_mask;
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002441 u8 ampdu_factor;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002442
Michal Kazior500ff9f2015-03-31 10:26:21 +00002443 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2444 return;
2445
Kalle Valo5e3dd152013-06-12 20:52:10 +03002446 if (!vht_cap->vht_supported)
2447 return;
2448
Michal Kazior45c9abc2015-04-21 20:42:58 +03002449 band = def.chan->band;
2450 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2451
2452 if (ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
2453 return;
2454
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002455 arg->peer_flags |= ar->wmi.peer_flags->vht;
Yanbo Lid68bb122015-01-23 08:18:20 +08002456
Johannes Berg57fbcce2016-04-12 15:56:15 +02002457 if (def.chan->band == NL80211_BAND_2GHZ)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002458 arg->peer_flags |= ar->wmi.peer_flags->vht_2g;
Yanbo Lid68bb122015-01-23 08:18:20 +08002459
Kalle Valo5e3dd152013-06-12 20:52:10 +03002460 arg->peer_vht_caps = vht_cap->cap;
2461
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002462 ampdu_factor = (vht_cap->cap &
2463 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) >>
2464 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
2465
2466 /* Workaround: Some Netgear/Linksys 11ac APs set Rx A-MPDU factor to
2467 * zero in VHT IE. Using it would result in degraded throughput.
2468 * arg->peer_max_mpdu at this point contains HT max_mpdu so keep
2469 * it if VHT max_mpdu is smaller. */
2470 arg->peer_max_mpdu = max(arg->peer_max_mpdu,
2471 (1U << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2472 ampdu_factor)) - 1);
2473
Kalle Valo5e3dd152013-06-12 20:52:10 +03002474 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002475 arg->peer_flags |= ar->wmi.peer_flags->bw80;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002476
2477 arg->peer_vht_rates.rx_max_rate =
2478 __le16_to_cpu(vht_cap->vht_mcs.rx_highest);
2479 arg->peer_vht_rates.rx_mcs_set =
2480 __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map);
2481 arg->peer_vht_rates.tx_max_rate =
2482 __le16_to_cpu(vht_cap->vht_mcs.tx_highest);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002483 arg->peer_vht_rates.tx_mcs_set = ath10k_peer_assoc_h_vht_limit(
2484 __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002485
Michal Kazior7aa7a722014-08-25 12:09:38 +02002486 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002487 sta->addr, arg->peer_max_mpdu, arg->peer_flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002488}
2489
2490static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002491 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002492 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002493 struct wmi_peer_assoc_complete_arg *arg)
2494{
Michal Kazior590922a2014-10-21 10:10:29 +03002495 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2496
Kalle Valo5e3dd152013-06-12 20:52:10 +03002497 switch (arvif->vdev_type) {
2498 case WMI_VDEV_TYPE_AP:
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002499 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002500 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002501
2502 if (sta->wme && sta->uapsd_queues) {
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002503 arg->peer_flags |= arvif->ar->wmi.peer_flags->apsd;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002504 arg->peer_rate_caps |= WMI_RC_UAPSD_FLAG;
2505 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002506 break;
2507 case WMI_VDEV_TYPE_STA:
Balaji Pothunooribb327722017-12-07 16:58:04 +02002508 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002509 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002510 break;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002511 case WMI_VDEV_TYPE_IBSS:
2512 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002513 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002514 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002515 default:
2516 break;
2517 }
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002518
2519 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM qos %d\n",
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002520 sta->addr, !!(arg->peer_flags &
2521 arvif->ar->wmi.peer_flags->qos));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002522}
2523
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002524static bool ath10k_mac_sta_has_ofdm_only(struct ieee80211_sta *sta)
Michal Kazior91b12082014-12-12 12:41:35 +01002525{
Johannes Berg57fbcce2016-04-12 15:56:15 +02002526 return sta->supp_rates[NL80211_BAND_2GHZ] >>
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002527 ATH10K_MAC_FIRST_OFDM_RATE_IDX;
Michal Kazior91b12082014-12-12 12:41:35 +01002528}
2529
Kalle Valo5e3dd152013-06-12 20:52:10 +03002530static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002531 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002532 struct ieee80211_sta *sta,
2533 struct wmi_peer_assoc_complete_arg *arg)
2534{
Michal Kazior45c9abc2015-04-21 20:42:58 +03002535 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002536 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002537 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002538 const u8 *ht_mcs_mask;
2539 const u16 *vht_mcs_mask;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002540 enum wmi_phy_mode phymode = MODE_UNKNOWN;
2541
Michal Kazior500ff9f2015-03-31 10:26:21 +00002542 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2543 return;
2544
Michal Kazior45c9abc2015-04-21 20:42:58 +03002545 band = def.chan->band;
2546 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
2547 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2548
2549 switch (band) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02002550 case NL80211_BAND_2GHZ:
Michal Kazior45c9abc2015-04-21 20:42:58 +03002551 if (sta->vht_cap.vht_supported &&
2552 !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
Yanbo Lid68bb122015-01-23 08:18:20 +08002553 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2554 phymode = MODE_11AC_VHT40;
2555 else
2556 phymode = MODE_11AC_VHT20;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002557 } else if (sta->ht_cap.ht_supported &&
2558 !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002559 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2560 phymode = MODE_11NG_HT40;
2561 else
2562 phymode = MODE_11NG_HT20;
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002563 } else if (ath10k_mac_sta_has_ofdm_only(sta)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002564 phymode = MODE_11G;
Michal Kazior91b12082014-12-12 12:41:35 +01002565 } else {
2566 phymode = MODE_11B;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002567 }
2568
2569 break;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002570 case NL80211_BAND_5GHZ:
Sujith Manoharan7cc45e92013-09-08 18:19:55 +03002571 /*
2572 * Check VHT first.
2573 */
Michal Kazior45c9abc2015-04-21 20:42:58 +03002574 if (sta->vht_cap.vht_supported &&
2575 !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
Sujith Manoharan7cc45e92013-09-08 18:19:55 +03002576 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
2577 phymode = MODE_11AC_VHT80;
2578 else if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2579 phymode = MODE_11AC_VHT40;
2580 else if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
2581 phymode = MODE_11AC_VHT20;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002582 } else if (sta->ht_cap.ht_supported &&
2583 !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
2584 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002585 phymode = MODE_11NA_HT40;
2586 else
2587 phymode = MODE_11NA_HT20;
2588 } else {
2589 phymode = MODE_11A;
2590 }
2591
2592 break;
2593 default:
2594 break;
2595 }
2596
Michal Kazior7aa7a722014-08-25 12:09:38 +02002597 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM phymode %s\n",
Kalle Valo38a1d472013-09-08 17:56:14 +03002598 sta->addr, ath10k_wmi_phymode_str(phymode));
Kalle Valo60c3daa2013-09-08 17:56:07 +03002599
Kalle Valo5e3dd152013-06-12 20:52:10 +03002600 arg->peer_phymode = phymode;
2601 WARN_ON(phymode == MODE_UNKNOWN);
2602}
2603
Kalle Valob9ada652013-10-16 15:44:46 +03002604static int ath10k_peer_assoc_prepare(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002605 struct ieee80211_vif *vif,
Kalle Valob9ada652013-10-16 15:44:46 +03002606 struct ieee80211_sta *sta,
Kalle Valob9ada652013-10-16 15:44:46 +03002607 struct wmi_peer_assoc_complete_arg *arg)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002608{
Michal Kazior548db542013-07-05 16:15:15 +03002609 lockdep_assert_held(&ar->conf_mutex);
2610
Kalle Valob9ada652013-10-16 15:44:46 +03002611 memset(arg, 0, sizeof(*arg));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002612
Michal Kazior590922a2014-10-21 10:10:29 +03002613 ath10k_peer_assoc_h_basic(ar, vif, sta, arg);
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002614 ath10k_peer_assoc_h_crypto(ar, vif, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002615 ath10k_peer_assoc_h_rates(ar, vif, sta, arg);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002616 ath10k_peer_assoc_h_ht(ar, vif, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002617 ath10k_peer_assoc_h_vht(ar, vif, sta, arg);
Michal Kazior590922a2014-10-21 10:10:29 +03002618 ath10k_peer_assoc_h_qos(ar, vif, sta, arg);
2619 ath10k_peer_assoc_h_phymode(ar, vif, sta, arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002620
Kalle Valob9ada652013-10-16 15:44:46 +03002621 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002622}
2623
Michal Kazior90046f52014-02-14 14:45:51 +01002624static const u32 ath10k_smps_map[] = {
2625 [WLAN_HT_CAP_SM_PS_STATIC] = WMI_PEER_SMPS_STATIC,
2626 [WLAN_HT_CAP_SM_PS_DYNAMIC] = WMI_PEER_SMPS_DYNAMIC,
2627 [WLAN_HT_CAP_SM_PS_INVALID] = WMI_PEER_SMPS_PS_NONE,
2628 [WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE,
2629};
2630
2631static int ath10k_setup_peer_smps(struct ath10k *ar, struct ath10k_vif *arvif,
2632 const u8 *addr,
2633 const struct ieee80211_sta_ht_cap *ht_cap)
2634{
2635 int smps;
2636
2637 if (!ht_cap->ht_supported)
2638 return 0;
2639
2640 smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;
2641 smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;
2642
2643 if (smps >= ARRAY_SIZE(ath10k_smps_map))
2644 return -EINVAL;
2645
2646 return ath10k_wmi_peer_set_param(ar, arvif->vdev_id, addr,
2647 WMI_PEER_SMPS_STATE,
2648 ath10k_smps_map[smps]);
2649}
2650
Michal Kazior139e1702015-02-15 16:50:42 +02002651static int ath10k_mac_vif_recalc_txbf(struct ath10k *ar,
2652 struct ieee80211_vif *vif,
2653 struct ieee80211_sta_vht_cap vht_cap)
2654{
2655 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2656 int ret;
2657 u32 param;
2658 u32 value;
2659
Vivek Natarajan08e75ea2015-08-04 10:45:11 +05302660 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_AFTER_ASSOC)
2661 return 0;
2662
Michal Kazior139e1702015-02-15 16:50:42 +02002663 if (!(ar->vht_cap_info &
2664 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2665 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
2666 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2667 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)))
2668 return 0;
2669
2670 param = ar->wmi.vdev_param->txbf;
2671 value = 0;
2672
2673 if (WARN_ON(param == WMI_VDEV_PARAM_UNSUPPORTED))
2674 return 0;
2675
2676 /* The following logic is correct. If a remote STA advertises support
2677 * for being a beamformer then we should enable us being a beamformee.
2678 */
2679
2680 if (ar->vht_cap_info &
2681 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2682 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
2683 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
2684 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2685
2686 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
2687 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFEE;
2688 }
2689
2690 if (ar->vht_cap_info &
2691 (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2692 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
2693 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
2694 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2695
2696 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
2697 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFER;
2698 }
2699
2700 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFEE)
2701 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2702
2703 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFER)
2704 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2705
2706 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, value);
2707 if (ret) {
2708 ath10k_warn(ar, "failed to submit vdev param txbf 0x%x: %d\n",
2709 value, ret);
2710 return ret;
2711 }
2712
2713 return 0;
2714}
2715
Kalle Valo5e3dd152013-06-12 20:52:10 +03002716/* can be called only in mac80211 callbacks due to `key_count` usage */
2717static void ath10k_bss_assoc(struct ieee80211_hw *hw,
2718 struct ieee80211_vif *vif,
2719 struct ieee80211_bss_conf *bss_conf)
2720{
2721 struct ath10k *ar = hw->priv;
2722 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior90046f52014-02-14 14:45:51 +01002723 struct ieee80211_sta_ht_cap ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002724 struct ieee80211_sta_vht_cap vht_cap;
Kalle Valob9ada652013-10-16 15:44:46 +03002725 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002726 struct ieee80211_sta *ap_sta;
2727 int ret;
2728
Michal Kazior548db542013-07-05 16:15:15 +03002729 lockdep_assert_held(&ar->conf_mutex);
2730
Michal Kazior077efc82014-10-21 10:10:29 +03002731 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i assoc bssid %pM aid %d\n",
2732 arvif->vdev_id, arvif->bssid, arvif->aid);
2733
Kalle Valo5e3dd152013-06-12 20:52:10 +03002734 rcu_read_lock();
2735
2736 ap_sta = ieee80211_find_sta(vif, bss_conf->bssid);
2737 if (!ap_sta) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002738 ath10k_warn(ar, "failed to find station entry for bss %pM vdev %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002739 bss_conf->bssid, arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002740 rcu_read_unlock();
2741 return;
2742 }
2743
Michal Kazior90046f52014-02-14 14:45:51 +01002744 /* ap_sta must be accessed only within rcu section which must be left
2745 * before calling ath10k_setup_peer_smps() which might sleep. */
2746 ht_cap = ap_sta->ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002747 vht_cap = ap_sta->vht_cap;
Michal Kazior90046f52014-02-14 14:45:51 +01002748
Michal Kazior590922a2014-10-21 10:10:29 +03002749 ret = ath10k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002750 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002751 ath10k_warn(ar, "failed to prepare peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002752 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002753 rcu_read_unlock();
2754 return;
2755 }
2756
2757 rcu_read_unlock();
2758
Kalle Valob9ada652013-10-16 15:44:46 +03002759 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2760 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002761 ath10k_warn(ar, "failed to run peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002762 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002763 return;
2764 }
2765
Michal Kazior90046f52014-02-14 14:45:51 +01002766 ret = ath10k_setup_peer_smps(ar, arvif, bss_conf->bssid, &ht_cap);
2767 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002768 ath10k_warn(ar, "failed to setup peer SMPS for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002769 arvif->vdev_id, ret);
Michal Kazior90046f52014-02-14 14:45:51 +01002770 return;
2771 }
2772
Michal Kazior139e1702015-02-15 16:50:42 +02002773 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2774 if (ret) {
2775 ath10k_warn(ar, "failed to recalc txbf for vdev %i on bss %pM: %d\n",
2776 arvif->vdev_id, bss_conf->bssid, ret);
2777 return;
2778 }
2779
Michal Kazior7aa7a722014-08-25 12:09:38 +02002780 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03002781 "mac vdev %d up (associated) bssid %pM aid %d\n",
2782 arvif->vdev_id, bss_conf->bssid, bss_conf->aid);
2783
Michal Kazior077efc82014-10-21 10:10:29 +03002784 WARN_ON(arvif->is_up);
2785
Michal Kaziorc930f742014-01-23 11:38:25 +01002786 arvif->aid = bss_conf->aid;
Kalle Valob25f32c2014-09-14 12:50:49 +03002787 ether_addr_copy(arvif->bssid, bss_conf->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01002788
2789 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid);
2790 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002791 ath10k_warn(ar, "failed to set vdev %d up: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002792 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01002793 return;
2794 }
2795
2796 arvif->is_up = true;
Michal Kazior0a987fb2015-02-13 13:30:15 +01002797
2798 /* Workaround: Some firmware revisions (tested with qca6174
2799 * WLAN.RM.2.0-00073) have buggy powersave state machine and must be
2800 * poked with peer param command.
2801 */
2802 ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, arvif->bssid,
2803 WMI_PEER_DUMMY_VAR, 1);
2804 if (ret) {
2805 ath10k_warn(ar, "failed to poke peer %pM param for ps workaround on vdev %i: %d\n",
2806 arvif->bssid, arvif->vdev_id, ret);
2807 return;
2808 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002809}
2810
Kalle Valo5e3dd152013-06-12 20:52:10 +03002811static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
2812 struct ieee80211_vif *vif)
2813{
2814 struct ath10k *ar = hw->priv;
2815 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior139e1702015-02-15 16:50:42 +02002816 struct ieee80211_sta_vht_cap vht_cap = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +03002817 int ret;
2818
Michal Kazior548db542013-07-05 16:15:15 +03002819 lockdep_assert_held(&ar->conf_mutex);
2820
Michal Kazior077efc82014-10-21 10:10:29 +03002821 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i disassoc bssid %pM\n",
2822 arvif->vdev_id, arvif->bssid);
Kalle Valo60c3daa2013-09-08 17:56:07 +03002823
Kalle Valo5e3dd152013-06-12 20:52:10 +03002824 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
Michal Kazior077efc82014-10-21 10:10:29 +03002825 if (ret)
Ben Greearaa66ba02016-09-26 21:56:25 +03002826 ath10k_warn(ar, "failed to down vdev %i: %d\n",
Michal Kazior077efc82014-10-21 10:10:29 +03002827 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002828
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002829 arvif->def_wep_key_idx = -1;
2830
Michal Kazior139e1702015-02-15 16:50:42 +02002831 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2832 if (ret) {
2833 ath10k_warn(ar, "failed to recalc txbf for vdev %i: %d\n",
2834 arvif->vdev_id, ret);
2835 return;
2836 }
2837
Michal Kaziorc930f742014-01-23 11:38:25 +01002838 arvif->is_up = false;
Michal Kaziorcc9904e2015-03-10 16:22:01 +02002839
2840 cancel_delayed_work_sync(&arvif->connection_loss_work);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002841}
2842
Michal Kazior590922a2014-10-21 10:10:29 +03002843static int ath10k_station_assoc(struct ath10k *ar,
2844 struct ieee80211_vif *vif,
2845 struct ieee80211_sta *sta,
2846 bool reassoc)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002847{
Michal Kazior590922a2014-10-21 10:10:29 +03002848 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valob9ada652013-10-16 15:44:46 +03002849 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002850 int ret = 0;
2851
Michal Kazior548db542013-07-05 16:15:15 +03002852 lockdep_assert_held(&ar->conf_mutex);
2853
Michal Kazior590922a2014-10-21 10:10:29 +03002854 ret = ath10k_peer_assoc_prepare(ar, vif, sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002855 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002856 ath10k_warn(ar, "failed to prepare WMI peer assoc for %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002857 sta->addr, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002858 return ret;
2859 }
2860
2861 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2862 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002863 ath10k_warn(ar, "failed to run peer assoc for STA %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002864 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002865 return ret;
2866 }
2867
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002868 /* Re-assoc is run only to update supported rates for given station. It
2869 * doesn't make much sense to reconfigure the peer completely.
2870 */
2871 if (!reassoc) {
2872 ret = ath10k_setup_peer_smps(ar, arvif, sta->addr,
2873 &sta->ht_cap);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002874 if (ret) {
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002875 ath10k_warn(ar, "failed to setup peer SMPS for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002876 arvif->vdev_id, ret);
2877 return ret;
2878 }
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002879
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002880 ret = ath10k_peer_assoc_qos_ap(ar, arvif, sta);
2881 if (ret) {
2882 ath10k_warn(ar, "failed to set qos params for STA %pM for vdev %i: %d\n",
2883 sta->addr, arvif->vdev_id, ret);
2884 return ret;
2885 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002886
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002887 if (!sta->wme) {
2888 arvif->num_legacy_stations++;
2889 ret = ath10k_recalc_rtscts_prot(arvif);
2890 if (ret) {
2891 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
2892 arvif->vdev_id, ret);
2893 return ret;
2894 }
2895 }
2896
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002897 /* Plumb cached keys only for static WEP */
2898 if (arvif->def_wep_key_idx != -1) {
2899 ret = ath10k_install_peer_wep_keys(arvif, sta->addr);
2900 if (ret) {
2901 ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n",
2902 arvif->vdev_id, ret);
2903 return ret;
2904 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002905 }
2906 }
2907
Kalle Valo5e3dd152013-06-12 20:52:10 +03002908 return ret;
2909}
2910
Michal Kazior590922a2014-10-21 10:10:29 +03002911static int ath10k_station_disassoc(struct ath10k *ar,
2912 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002913 struct ieee80211_sta *sta)
2914{
Michal Kazior590922a2014-10-21 10:10:29 +03002915 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002916 int ret = 0;
2917
2918 lockdep_assert_held(&ar->conf_mutex);
2919
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002920 if (!sta->wme) {
2921 arvif->num_legacy_stations--;
2922 ret = ath10k_recalc_rtscts_prot(arvif);
2923 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002924 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002925 arvif->vdev_id, ret);
2926 return ret;
2927 }
2928 }
2929
Kalle Valo5e3dd152013-06-12 20:52:10 +03002930 ret = ath10k_clear_peer_keys(arvif, sta->addr);
2931 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002932 ath10k_warn(ar, "failed to clear all peer wep keys for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002933 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002934 return ret;
2935 }
2936
2937 return ret;
2938}
2939
2940/**************/
2941/* Regulatory */
2942/**************/
2943
2944static int ath10k_update_channel_list(struct ath10k *ar)
2945{
2946 struct ieee80211_hw *hw = ar->hw;
2947 struct ieee80211_supported_band **bands;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002948 enum nl80211_band band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002949 struct ieee80211_channel *channel;
2950 struct wmi_scan_chan_list_arg arg = {0};
2951 struct wmi_channel_arg *ch;
2952 bool passive;
2953 int len;
2954 int ret;
2955 int i;
2956
Michal Kazior548db542013-07-05 16:15:15 +03002957 lockdep_assert_held(&ar->conf_mutex);
2958
Kalle Valo5e3dd152013-06-12 20:52:10 +03002959 bands = hw->wiphy->bands;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002960 for (band = 0; band < NUM_NL80211_BANDS; band++) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002961 if (!bands[band])
2962 continue;
2963
2964 for (i = 0; i < bands[band]->n_channels; i++) {
2965 if (bands[band]->channels[i].flags &
2966 IEEE80211_CHAN_DISABLED)
2967 continue;
2968
2969 arg.n_channels++;
2970 }
2971 }
2972
2973 len = sizeof(struct wmi_channel_arg) * arg.n_channels;
2974 arg.channels = kzalloc(len, GFP_KERNEL);
2975 if (!arg.channels)
2976 return -ENOMEM;
2977
2978 ch = arg.channels;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002979 for (band = 0; band < NUM_NL80211_BANDS; band++) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002980 if (!bands[band])
2981 continue;
2982
2983 for (i = 0; i < bands[band]->n_channels; i++) {
2984 channel = &bands[band]->channels[i];
2985
2986 if (channel->flags & IEEE80211_CHAN_DISABLED)
2987 continue;
2988
Eduardo Abinader98029772016-06-30 15:23:55 +03002989 ch->allow_ht = true;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002990
2991 /* FIXME: when should we really allow VHT? */
2992 ch->allow_vht = true;
2993
2994 ch->allow_ibss =
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02002995 !(channel->flags & IEEE80211_CHAN_NO_IR);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002996
2997 ch->ht40plus =
2998 !(channel->flags & IEEE80211_CHAN_NO_HT40PLUS);
2999
Marek Puzyniake8a50f82013-11-20 09:59:47 +02003000 ch->chan_radar =
3001 !!(channel->flags & IEEE80211_CHAN_RADAR);
3002
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02003003 passive = channel->flags & IEEE80211_CHAN_NO_IR;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003004 ch->passive = passive;
3005
3006 ch->freq = channel->center_freq;
Michal Kazior2d667212014-09-18 15:21:21 +02003007 ch->band_center_freq1 = channel->center_freq;
Michal Kazior89c5c842013-10-23 04:02:13 -07003008 ch->min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -07003009 ch->max_power = channel->max_power * 2;
3010 ch->max_reg_power = channel->max_reg_power * 2;
3011 ch->max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003012 ch->reg_class_id = 0; /* FIXME */
3013
3014 /* FIXME: why use only legacy modes, why not any
3015 * HT/VHT modes? Would that even make any
3016 * difference? */
Johannes Berg57fbcce2016-04-12 15:56:15 +02003017 if (channel->band == NL80211_BAND_2GHZ)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003018 ch->mode = MODE_11G;
3019 else
3020 ch->mode = MODE_11A;
3021
3022 if (WARN_ON_ONCE(ch->mode == MODE_UNKNOWN))
3023 continue;
3024
Michal Kazior7aa7a722014-08-25 12:09:38 +02003025 ath10k_dbg(ar, ATH10K_DBG_WMI,
Kalle Valo60c3daa2013-09-08 17:56:07 +03003026 "mac channel [%zd/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n",
3027 ch - arg.channels, arg.n_channels,
Kalle Valo5e3dd152013-06-12 20:52:10 +03003028 ch->freq, ch->max_power, ch->max_reg_power,
3029 ch->max_antenna_gain, ch->mode);
3030
3031 ch++;
3032 }
3033 }
3034
3035 ret = ath10k_wmi_scan_chan_list(ar, &arg);
3036 kfree(arg.channels);
3037
3038 return ret;
3039}
3040
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003041static enum wmi_dfs_region
3042ath10k_mac_get_dfs_region(enum nl80211_dfs_regions dfs_region)
3043{
3044 switch (dfs_region) {
3045 case NL80211_DFS_UNSET:
3046 return WMI_UNINIT_DFS_DOMAIN;
3047 case NL80211_DFS_FCC:
3048 return WMI_FCC_DFS_DOMAIN;
3049 case NL80211_DFS_ETSI:
3050 return WMI_ETSI_DFS_DOMAIN;
3051 case NL80211_DFS_JP:
3052 return WMI_MKK4_DFS_DOMAIN;
3053 }
3054 return WMI_UNINIT_DFS_DOMAIN;
3055}
3056
Michal Kaziorf7843d72013-07-16 09:38:52 +02003057static void ath10k_regd_update(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003058{
Kalle Valo5e3dd152013-06-12 20:52:10 +03003059 struct reg_dmn_pair_mapping *regpair;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003060 int ret;
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003061 enum wmi_dfs_region wmi_dfs_reg;
3062 enum nl80211_dfs_regions nl_dfs_reg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003063
Michal Kaziorf7843d72013-07-16 09:38:52 +02003064 lockdep_assert_held(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003065
3066 ret = ath10k_update_channel_list(ar);
3067 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003068 ath10k_warn(ar, "failed to update channel list: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003069
3070 regpair = ar->ath_common.regulatory.regpair;
Michal Kaziorf7843d72013-07-16 09:38:52 +02003071
Masahiro Yamada97f26452016-08-03 13:45:50 -07003072 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003073 nl_dfs_reg = ar->dfs_detector->region;
3074 wmi_dfs_reg = ath10k_mac_get_dfs_region(nl_dfs_reg);
3075 } else {
3076 wmi_dfs_reg = WMI_UNINIT_DFS_DOMAIN;
3077 }
3078
Kalle Valo5e3dd152013-06-12 20:52:10 +03003079 /* Target allows setting up per-band regdomain but ath_common provides
3080 * a combined one only */
3081 ret = ath10k_wmi_pdev_set_regdomain(ar,
Kalle Valoef8c0012014-02-13 18:13:12 +02003082 regpair->reg_domain,
3083 regpair->reg_domain, /* 2ghz */
3084 regpair->reg_domain, /* 5ghz */
Kalle Valo5e3dd152013-06-12 20:52:10 +03003085 regpair->reg_2ghz_ctl,
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003086 regpair->reg_5ghz_ctl,
3087 wmi_dfs_reg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003088 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003089 ath10k_warn(ar, "failed to set pdev regdomain: %d\n", ret);
Michal Kaziorf7843d72013-07-16 09:38:52 +02003090}
Michal Kazior548db542013-07-05 16:15:15 +03003091
Michal Kaziorf7843d72013-07-16 09:38:52 +02003092static void ath10k_reg_notifier(struct wiphy *wiphy,
3093 struct regulatory_request *request)
3094{
3095 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
3096 struct ath10k *ar = hw->priv;
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003097 bool result;
Michal Kaziorf7843d72013-07-16 09:38:52 +02003098
3099 ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory);
3100
Masahiro Yamada97f26452016-08-03 13:45:50 -07003101 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003102 ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs region 0x%x\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003103 request->dfs_region);
3104 result = ar->dfs_detector->set_dfs_domain(ar->dfs_detector,
3105 request->dfs_region);
3106 if (!result)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003107 ath10k_warn(ar, "DFS region 0x%X not supported, will trigger radar for every pulse\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003108 request->dfs_region);
3109 }
3110
Michal Kaziorf7843d72013-07-16 09:38:52 +02003111 mutex_lock(&ar->conf_mutex);
3112 if (ar->state == ATH10K_STATE_ON)
3113 ath10k_regd_update(ar);
Michal Kazior548db542013-07-05 16:15:15 +03003114 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003115}
3116
3117/***************/
3118/* TX handlers */
3119/***************/
3120
Michal Kaziora30c7d02016-03-06 16:14:23 +02003121enum ath10k_mac_tx_path {
3122 ATH10K_MAC_TX_HTT,
3123 ATH10K_MAC_TX_HTT_MGMT,
3124 ATH10K_MAC_TX_WMI_MGMT,
3125 ATH10K_MAC_TX_UNKNOWN,
3126};
3127
Michal Kazior96d828d2015-03-31 10:26:23 +00003128void ath10k_mac_tx_lock(struct ath10k *ar, int reason)
3129{
3130 lockdep_assert_held(&ar->htt.tx_lock);
3131
3132 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
3133 ar->tx_paused |= BIT(reason);
3134 ieee80211_stop_queues(ar->hw);
3135}
3136
3137static void ath10k_mac_tx_unlock_iter(void *data, u8 *mac,
3138 struct ieee80211_vif *vif)
3139{
3140 struct ath10k *ar = data;
3141 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3142
3143 if (arvif->tx_paused)
3144 return;
3145
3146 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
3147}
3148
3149void ath10k_mac_tx_unlock(struct ath10k *ar, int reason)
3150{
3151 lockdep_assert_held(&ar->htt.tx_lock);
3152
3153 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
3154 ar->tx_paused &= ~BIT(reason);
3155
3156 if (ar->tx_paused)
3157 return;
3158
3159 ieee80211_iterate_active_interfaces_atomic(ar->hw,
3160 IEEE80211_IFACE_ITER_RESUME_ALL,
3161 ath10k_mac_tx_unlock_iter,
3162 ar);
Michal Kazior3a73d1a2015-08-06 14:46:54 +02003163
3164 ieee80211_wake_queue(ar->hw, ar->hw->offchannel_tx_hw_queue);
Michal Kazior96d828d2015-03-31 10:26:23 +00003165}
3166
3167void ath10k_mac_vif_tx_lock(struct ath10k_vif *arvif, int reason)
3168{
3169 struct ath10k *ar = arvif->ar;
3170
3171 lockdep_assert_held(&ar->htt.tx_lock);
3172
3173 WARN_ON(reason >= BITS_PER_LONG);
3174 arvif->tx_paused |= BIT(reason);
3175 ieee80211_stop_queue(ar->hw, arvif->vdev_id);
3176}
3177
3178void ath10k_mac_vif_tx_unlock(struct ath10k_vif *arvif, int reason)
3179{
3180 struct ath10k *ar = arvif->ar;
3181
3182 lockdep_assert_held(&ar->htt.tx_lock);
3183
3184 WARN_ON(reason >= BITS_PER_LONG);
3185 arvif->tx_paused &= ~BIT(reason);
3186
3187 if (ar->tx_paused)
3188 return;
3189
3190 if (arvif->tx_paused)
3191 return;
3192
3193 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
3194}
3195
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003196static void ath10k_mac_vif_handle_tx_pause(struct ath10k_vif *arvif,
3197 enum wmi_tlv_tx_pause_id pause_id,
3198 enum wmi_tlv_tx_pause_action action)
3199{
3200 struct ath10k *ar = arvif->ar;
3201
3202 lockdep_assert_held(&ar->htt.tx_lock);
3203
Michal Kazioracd0b272015-07-09 13:08:38 +02003204 switch (action) {
3205 case WMI_TLV_TX_PAUSE_ACTION_STOP:
3206 ath10k_mac_vif_tx_lock(arvif, pause_id);
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003207 break;
Michal Kazioracd0b272015-07-09 13:08:38 +02003208 case WMI_TLV_TX_PAUSE_ACTION_WAKE:
3209 ath10k_mac_vif_tx_unlock(arvif, pause_id);
3210 break;
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003211 default:
Michal Kazioracd0b272015-07-09 13:08:38 +02003212 ath10k_warn(ar, "received unknown tx pause action %d on vdev %i, ignoring\n",
3213 action, arvif->vdev_id);
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003214 break;
3215 }
3216}
3217
3218struct ath10k_mac_tx_pause {
3219 u32 vdev_id;
3220 enum wmi_tlv_tx_pause_id pause_id;
3221 enum wmi_tlv_tx_pause_action action;
3222};
3223
3224static void ath10k_mac_handle_tx_pause_iter(void *data, u8 *mac,
3225 struct ieee80211_vif *vif)
3226{
3227 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3228 struct ath10k_mac_tx_pause *arg = data;
3229
Michal Kazioracd0b272015-07-09 13:08:38 +02003230 if (arvif->vdev_id != arg->vdev_id)
3231 return;
3232
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003233 ath10k_mac_vif_handle_tx_pause(arvif, arg->pause_id, arg->action);
3234}
3235
Michal Kazioracd0b272015-07-09 13:08:38 +02003236void ath10k_mac_handle_tx_pause_vdev(struct ath10k *ar, u32 vdev_id,
3237 enum wmi_tlv_tx_pause_id pause_id,
3238 enum wmi_tlv_tx_pause_action action)
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003239{
3240 struct ath10k_mac_tx_pause arg = {
3241 .vdev_id = vdev_id,
3242 .pause_id = pause_id,
3243 .action = action,
3244 };
3245
3246 spin_lock_bh(&ar->htt.tx_lock);
3247 ieee80211_iterate_active_interfaces_atomic(ar->hw,
3248 IEEE80211_IFACE_ITER_RESUME_ALL,
3249 ath10k_mac_handle_tx_pause_iter,
3250 &arg);
3251 spin_unlock_bh(&ar->htt.tx_lock);
3252}
3253
Michal Kaziord740d8f2015-03-30 09:51:51 +03003254static enum ath10k_hw_txrx_mode
Michal Kazior6a2636d2015-11-18 06:59:16 +01003255ath10k_mac_tx_h_get_txmode(struct ath10k *ar,
3256 struct ieee80211_vif *vif,
3257 struct ieee80211_sta *sta,
3258 struct sk_buff *skb)
Michal Kaziord740d8f2015-03-30 09:51:51 +03003259{
3260 const struct ieee80211_hdr *hdr = (void *)skb->data;
3261 __le16 fc = hdr->frame_control;
3262
3263 if (!vif || vif->type == NL80211_IFTYPE_MONITOR)
3264 return ATH10K_HW_TXRX_RAW;
3265
3266 if (ieee80211_is_mgmt(fc))
3267 return ATH10K_HW_TXRX_MGMT;
3268
3269 /* Workaround:
3270 *
3271 * NullFunc frames are mostly used to ping if a client or AP are still
3272 * reachable and responsive. This implies tx status reports must be
3273 * accurate - otherwise either mac80211 or userspace (e.g. hostapd) can
3274 * come to a conclusion that the other end disappeared and tear down
3275 * BSS connection or it can never disconnect from BSS/client (which is
3276 * the case).
3277 *
3278 * Firmware with HTT older than 3.0 delivers incorrect tx status for
3279 * NullFunc frames to driver. However there's a HTT Mgmt Tx command
3280 * which seems to deliver correct tx reports for NullFunc frames. The
3281 * downside of using it is it ignores client powersave state so it can
3282 * end up disconnecting sleeping clients in AP mode. It should fix STA
3283 * mode though because AP don't sleep.
3284 */
3285 if (ar->htt.target_version_major < 3 &&
3286 (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) &&
Kalle Valoc4cdf752016-04-20 19:45:18 +03003287 !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
3288 ar->running_fw->fw_file.fw_features))
Michal Kaziord740d8f2015-03-30 09:51:51 +03003289 return ATH10K_HW_TXRX_MGMT;
3290
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003291 /* Workaround:
3292 *
3293 * Some wmi-tlv firmwares for qca6174 have broken Tx key selection for
3294 * NativeWifi txmode - it selects AP key instead of peer key. It seems
3295 * to work with Ethernet txmode so use it.
David Liuccec9032015-07-24 20:25:32 +03003296 *
3297 * FIXME: Check if raw mode works with TDLS.
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003298 */
3299 if (ieee80211_is_data_present(fc) && sta && sta->tdls)
3300 return ATH10K_HW_TXRX_ETHERNET;
3301
David Liuccec9032015-07-24 20:25:32 +03003302 if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
3303 return ATH10K_HW_TXRX_RAW;
3304
Michal Kaziord740d8f2015-03-30 09:51:51 +03003305 return ATH10K_HW_TXRX_NATIVE_WIFI;
3306}
3307
David Liuccec9032015-07-24 20:25:32 +03003308static bool ath10k_tx_h_use_hwcrypto(struct ieee80211_vif *vif,
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003309 struct sk_buff *skb)
3310{
3311 const struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3312 const struct ieee80211_hdr *hdr = (void *)skb->data;
David Liuccec9032015-07-24 20:25:32 +03003313 const u32 mask = IEEE80211_TX_INTFL_DONT_ENCRYPT |
3314 IEEE80211_TX_CTL_INJECTED;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003315
3316 if (!ieee80211_has_protected(hdr->frame_control))
3317 return false;
3318
David Liuccec9032015-07-24 20:25:32 +03003319 if ((info->flags & mask) == mask)
3320 return false;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003321
David Liuccec9032015-07-24 20:25:32 +03003322 if (vif)
3323 return !ath10k_vif_to_arvif(vif)->nohwcrypt;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003324
David Liuccec9032015-07-24 20:25:32 +03003325 return true;
3326}
3327
Michal Kazior4b604552014-07-21 21:03:09 +03003328/* HTT Tx uses Native Wifi tx mode which expects 802.11 frames without QoS
3329 * Control in the header.
Kalle Valo5e3dd152013-06-12 20:52:10 +03003330 */
Michal Kazior4b604552014-07-21 21:03:09 +03003331static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003332{
3333 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003334 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003335 u8 *qos_ctl;
3336
3337 if (!ieee80211_is_data_qos(hdr->frame_control))
3338 return;
3339
3340 qos_ctl = ieee80211_get_qos_ctl(hdr);
Michal Kaziorba0ccd72013-07-22 14:25:28 +02003341 memmove(skb->data + IEEE80211_QOS_CTL_LEN,
3342 skb->data, (void *)qos_ctl - (void *)skb->data);
3343 skb_pull(skb, IEEE80211_QOS_CTL_LEN);
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003344
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003345 /* Some firmware revisions don't handle sending QoS NullFunc well.
3346 * These frames are mainly used for CQM purposes so it doesn't really
3347 * matter whether QoS NullFunc or NullFunc are sent.
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003348 */
Michal Kaziorbf0a26d2015-01-24 12:14:51 +02003349 hdr = (void *)skb->data;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003350 if (ieee80211_is_qos_nullfunc(hdr->frame_control))
Michal Kazior609db222015-11-18 06:59:22 +01003351 cb->flags &= ~ATH10K_SKB_F_QOS;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003352
3353 hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003354}
3355
Michal Kaziord740d8f2015-03-30 09:51:51 +03003356static void ath10k_tx_h_8023(struct sk_buff *skb)
3357{
3358 struct ieee80211_hdr *hdr;
3359 struct rfc1042_hdr *rfc1042;
3360 struct ethhdr *eth;
3361 size_t hdrlen;
3362 u8 da[ETH_ALEN];
3363 u8 sa[ETH_ALEN];
3364 __be16 type;
3365
3366 hdr = (void *)skb->data;
3367 hdrlen = ieee80211_hdrlen(hdr->frame_control);
3368 rfc1042 = (void *)skb->data + hdrlen;
3369
3370 ether_addr_copy(da, ieee80211_get_DA(hdr));
3371 ether_addr_copy(sa, ieee80211_get_SA(hdr));
3372 type = rfc1042->snap_type;
3373
3374 skb_pull(skb, hdrlen + sizeof(*rfc1042));
3375 skb_push(skb, sizeof(*eth));
3376
3377 eth = (void *)skb->data;
3378 ether_addr_copy(eth->h_dest, da);
3379 ether_addr_copy(eth->h_source, sa);
3380 eth->h_proto = type;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003381}
3382
Michal Kazior4b604552014-07-21 21:03:09 +03003383static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
3384 struct ieee80211_vif *vif,
3385 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003386{
3387 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003388 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3389
3390 /* This is case only for P2P_GO */
Peter Oh08c27be2016-01-28 13:54:09 -08003391 if (vif->type != NL80211_IFTYPE_AP || !vif->p2p)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003392 return;
3393
3394 if (unlikely(ieee80211_is_probe_resp(hdr->frame_control))) {
3395 spin_lock_bh(&ar->data_lock);
3396 if (arvif->u.ap.noa_data)
3397 if (!pskb_expand_head(skb, 0, arvif->u.ap.noa_len,
3398 GFP_ATOMIC))
3399 memcpy(skb_put(skb, arvif->u.ap.noa_len),
3400 arvif->u.ap.noa_data,
3401 arvif->u.ap.noa_len);
3402 spin_unlock_bh(&ar->data_lock);
3403 }
3404}
3405
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003406static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,
3407 struct ieee80211_vif *vif,
Michal Kaziordd4717b2016-03-06 16:14:39 +02003408 struct ieee80211_txq *txq,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003409 struct sk_buff *skb)
3410{
3411 struct ieee80211_hdr *hdr = (void *)skb->data;
3412 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
3413
3414 cb->flags = 0;
3415 if (!ath10k_tx_h_use_hwcrypto(vif, skb))
3416 cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;
3417
3418 if (ieee80211_is_mgmt(hdr->frame_control))
3419 cb->flags |= ATH10K_SKB_F_MGMT;
3420
3421 if (ieee80211_is_data_qos(hdr->frame_control))
3422 cb->flags |= ATH10K_SKB_F_QOS;
3423
3424 cb->vif = vif;
Michal Kaziordd4717b2016-03-06 16:14:39 +02003425 cb->txq = txq;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003426}
3427
Vasanthakumar Thiagarajand39de992015-11-05 11:34:00 +05303428bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar)
Michal Kazior8d6d3622014-11-24 14:58:31 +01003429{
3430 /* FIXME: Not really sure since when the behaviour changed. At some
3431 * point new firmware stopped requiring creation of peer entries for
3432 * offchannel tx (and actually creating them causes issues with wmi-htc
3433 * tx credit replenishment and reliability). Assuming it's at least 3.4
3434 * because that's when the `freq` was introduced to TX_FRM HTT command.
3435 */
Vasanthakumar Thiagarajan8921f5f2015-11-05 11:33:59 +05303436 return (ar->htt.target_version_major >= 3 &&
Vasanthakumar Thiagarajand39de992015-11-05 11:34:00 +05303437 ar->htt.target_version_minor >= 4 &&
Kalle Valo77561f92016-04-20 19:45:47 +03003438 ar->running_fw->fw_file.htt_op_version == ATH10K_FW_HTT_OP_VERSION_TLV);
Michal Kazior8d6d3622014-11-24 14:58:31 +01003439}
3440
Michal Kaziord740d8f2015-03-30 09:51:51 +03003441static int ath10k_mac_tx_wmi_mgmt(struct ath10k *ar, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003442{
Michal Kaziord740d8f2015-03-30 09:51:51 +03003443 struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003444 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003445
Michal Kaziord740d8f2015-03-30 09:51:51 +03003446 spin_lock_bh(&ar->data_lock);
3447
3448 if (skb_queue_len(q) == ATH10K_MAX_NUM_MGMT_PENDING) {
3449 ath10k_warn(ar, "wmi mgmt tx queue is full\n");
3450 ret = -ENOSPC;
3451 goto unlock;
Michal Kazior961d4c32013-08-09 10:13:34 +02003452 }
3453
Michal Kaziord740d8f2015-03-30 09:51:51 +03003454 __skb_queue_tail(q, skb);
3455 ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work);
3456
3457unlock:
3458 spin_unlock_bh(&ar->data_lock);
3459
3460 return ret;
3461}
3462
Michal Kaziora30c7d02016-03-06 16:14:23 +02003463static enum ath10k_mac_tx_path
3464ath10k_mac_tx_h_get_txpath(struct ath10k *ar,
3465 struct sk_buff *skb,
3466 enum ath10k_hw_txrx_mode txmode)
3467{
3468 switch (txmode) {
3469 case ATH10K_HW_TXRX_RAW:
3470 case ATH10K_HW_TXRX_NATIVE_WIFI:
3471 case ATH10K_HW_TXRX_ETHERNET:
3472 return ATH10K_MAC_TX_HTT;
3473 case ATH10K_HW_TXRX_MGMT:
3474 if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
Kalle Valoc4cdf752016-04-20 19:45:18 +03003475 ar->running_fw->fw_file.fw_features))
Michal Kaziora30c7d02016-03-06 16:14:23 +02003476 return ATH10K_MAC_TX_WMI_MGMT;
3477 else if (ar->htt.target_version_major >= 3)
3478 return ATH10K_MAC_TX_HTT;
3479 else
3480 return ATH10K_MAC_TX_HTT_MGMT;
3481 }
3482
3483 return ATH10K_MAC_TX_UNKNOWN;
3484}
3485
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003486static int ath10k_mac_tx_submit(struct ath10k *ar,
3487 enum ath10k_hw_txrx_mode txmode,
Michal Kazior6421969f2016-03-06 16:14:25 +02003488 enum ath10k_mac_tx_path txpath,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003489 struct sk_buff *skb)
Michal Kaziord740d8f2015-03-30 09:51:51 +03003490{
Michal Kaziord740d8f2015-03-30 09:51:51 +03003491 struct ath10k_htt *htt = &ar->htt;
Michal Kazior6421969f2016-03-06 16:14:25 +02003492 int ret = -EINVAL;
Michal Kaziora30c7d02016-03-06 16:14:23 +02003493
3494 switch (txpath) {
3495 case ATH10K_MAC_TX_HTT:
Michal Kazior8a933962015-11-18 06:59:17 +01003496 ret = ath10k_htt_tx(htt, txmode, skb);
Michal Kaziord740d8f2015-03-30 09:51:51 +03003497 break;
Michal Kaziora30c7d02016-03-06 16:14:23 +02003498 case ATH10K_MAC_TX_HTT_MGMT:
3499 ret = ath10k_htt_mgmt_tx(htt, skb);
3500 break;
3501 case ATH10K_MAC_TX_WMI_MGMT:
3502 ret = ath10k_mac_tx_wmi_mgmt(ar, skb);
3503 break;
3504 case ATH10K_MAC_TX_UNKNOWN:
3505 WARN_ON_ONCE(1);
3506 ret = -EINVAL;
Michal Kaziord740d8f2015-03-30 09:51:51 +03003507 break;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003508 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003509
3510 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003511 ath10k_warn(ar, "failed to transmit packet, dropping: %d\n",
3512 ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003513 ieee80211_free_txskb(ar->hw, skb);
3514 }
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003515
3516 return ret;
3517}
3518
3519/* This function consumes the sk_buff regardless of return value as far as
3520 * caller is concerned so no freeing is necessary afterwards.
3521 */
3522static int ath10k_mac_tx(struct ath10k *ar,
3523 struct ieee80211_vif *vif,
3524 struct ieee80211_sta *sta,
3525 enum ath10k_hw_txrx_mode txmode,
Michal Kazior6421969f2016-03-06 16:14:25 +02003526 enum ath10k_mac_tx_path txpath,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003527 struct sk_buff *skb)
3528{
3529 struct ieee80211_hw *hw = ar->hw;
3530 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3531 int ret;
3532
3533 /* We should disable CCK RATE due to P2P */
3534 if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
3535 ath10k_dbg(ar, ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n");
3536
3537 switch (txmode) {
3538 case ATH10K_HW_TXRX_MGMT:
3539 case ATH10K_HW_TXRX_NATIVE_WIFI:
3540 ath10k_tx_h_nwifi(hw, skb);
3541 ath10k_tx_h_add_p2p_noa_ie(ar, vif, skb);
3542 ath10k_tx_h_seq_no(vif, skb);
3543 break;
3544 case ATH10K_HW_TXRX_ETHERNET:
3545 ath10k_tx_h_8023(skb);
3546 break;
3547 case ATH10K_HW_TXRX_RAW:
3548 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
3549 WARN_ON_ONCE(1);
3550 ieee80211_free_txskb(hw, skb);
3551 return -ENOTSUPP;
3552 }
3553 }
3554
3555 if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
3556 if (!ath10k_mac_tx_frm_has_freq(ar)) {
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05303557 ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %pK\n",
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003558 skb);
3559
3560 skb_queue_tail(&ar->offchan_tx_queue, skb);
3561 ieee80211_queue_work(hw, &ar->offchan_tx_work);
3562 return 0;
3563 }
3564 }
3565
Michal Kazior6421969f2016-03-06 16:14:25 +02003566 ret = ath10k_mac_tx_submit(ar, txmode, txpath, skb);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003567 if (ret) {
3568 ath10k_warn(ar, "failed to submit frame: %d\n", ret);
3569 return ret;
3570 }
3571
3572 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003573}
3574
3575void ath10k_offchan_tx_purge(struct ath10k *ar)
3576{
3577 struct sk_buff *skb;
3578
3579 for (;;) {
3580 skb = skb_dequeue(&ar->offchan_tx_queue);
3581 if (!skb)
3582 break;
3583
3584 ieee80211_free_txskb(ar->hw, skb);
3585 }
3586}
3587
3588void ath10k_offchan_tx_work(struct work_struct *work)
3589{
3590 struct ath10k *ar = container_of(work, struct ath10k, offchan_tx_work);
3591 struct ath10k_peer *peer;
Michal Kazior8a933962015-11-18 06:59:17 +01003592 struct ath10k_vif *arvif;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003593 enum ath10k_hw_txrx_mode txmode;
Michal Kazior6421969f2016-03-06 16:14:25 +02003594 enum ath10k_mac_tx_path txpath;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003595 struct ieee80211_hdr *hdr;
Michal Kazior8a933962015-11-18 06:59:17 +01003596 struct ieee80211_vif *vif;
3597 struct ieee80211_sta *sta;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003598 struct sk_buff *skb;
3599 const u8 *peer_addr;
3600 int vdev_id;
3601 int ret;
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003602 unsigned long time_left;
Michal Kazioradaeed72015-08-05 12:15:23 +02003603 bool tmp_peer_created = false;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003604
3605 /* FW requirement: We must create a peer before FW will send out
3606 * an offchannel frame. Otherwise the frame will be stuck and
3607 * never transmitted. We delete the peer upon tx completion.
3608 * It is unlikely that a peer for offchannel tx will already be
3609 * present. However it may be in some rare cases so account for that.
3610 * Otherwise we might remove a legitimate peer and break stuff. */
3611
3612 for (;;) {
3613 skb = skb_dequeue(&ar->offchan_tx_queue);
3614 if (!skb)
3615 break;
3616
3617 mutex_lock(&ar->conf_mutex);
3618
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05303619 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %pK\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003620 skb);
3621
3622 hdr = (struct ieee80211_hdr *)skb->data;
3623 peer_addr = ieee80211_get_DA(hdr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003624
3625 spin_lock_bh(&ar->data_lock);
Michal Kazior609db222015-11-18 06:59:22 +01003626 vdev_id = ar->scan.vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003627 peer = ath10k_peer_find(ar, vdev_id, peer_addr);
3628 spin_unlock_bh(&ar->data_lock);
3629
3630 if (peer)
Kalle Valo60c3daa2013-09-08 17:56:07 +03003631 /* FIXME: should this use ath10k_warn()? */
Michal Kazior7aa7a722014-08-25 12:09:38 +02003632 ath10k_dbg(ar, ATH10K_DBG_MAC, "peer %pM on vdev %d already present\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003633 peer_addr, vdev_id);
3634
3635 if (!peer) {
Michal Kazior69427262016-03-06 16:14:30 +02003636 ret = ath10k_peer_create(ar, NULL, NULL, vdev_id,
3637 peer_addr,
Marek Puzyniak7390ed32015-03-30 09:51:52 +03003638 WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003639 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003640 ath10k_warn(ar, "failed to create peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003641 peer_addr, vdev_id, ret);
Michal Kazioradaeed72015-08-05 12:15:23 +02003642 tmp_peer_created = (ret == 0);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003643 }
3644
3645 spin_lock_bh(&ar->data_lock);
Wolfram Sang16735d02013-11-14 14:32:02 -08003646 reinit_completion(&ar->offchan_tx_completed);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003647 ar->offchan_tx_skb = skb;
3648 spin_unlock_bh(&ar->data_lock);
3649
Michal Kazior8a933962015-11-18 06:59:17 +01003650 /* It's safe to access vif and sta - conf_mutex guarantees that
3651 * sta_state() and remove_interface() are locked exclusively
3652 * out wrt to this offchannel worker.
3653 */
3654 arvif = ath10k_get_arvif(ar, vdev_id);
3655 if (arvif) {
3656 vif = arvif->vif;
3657 sta = ieee80211_find_sta(vif, peer_addr);
3658 } else {
3659 vif = NULL;
3660 sta = NULL;
3661 }
3662
3663 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kazior6421969f2016-03-06 16:14:25 +02003664 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
Michal Kazior8a933962015-11-18 06:59:17 +01003665
Michal Kazior6421969f2016-03-06 16:14:25 +02003666 ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003667 if (ret) {
3668 ath10k_warn(ar, "failed to transmit offchannel frame: %d\n",
3669 ret);
3670 /* not serious */
3671 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003672
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003673 time_left =
3674 wait_for_completion_timeout(&ar->offchan_tx_completed, 3 * HZ);
3675 if (time_left == 0)
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05303676 ath10k_warn(ar, "timed out waiting for offchannel skb %pK\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003677 skb);
3678
Michal Kazioradaeed72015-08-05 12:15:23 +02003679 if (!peer && tmp_peer_created) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03003680 ret = ath10k_peer_delete(ar, vdev_id, peer_addr);
3681 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003682 ath10k_warn(ar, "failed to delete peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003683 peer_addr, vdev_id, ret);
3684 }
3685
3686 mutex_unlock(&ar->conf_mutex);
3687 }
3688}
3689
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003690void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar)
3691{
3692 struct sk_buff *skb;
3693
3694 for (;;) {
3695 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3696 if (!skb)
3697 break;
3698
3699 ieee80211_free_txskb(ar->hw, skb);
3700 }
3701}
3702
3703void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work)
3704{
3705 struct ath10k *ar = container_of(work, struct ath10k, wmi_mgmt_tx_work);
3706 struct sk_buff *skb;
3707 int ret;
3708
3709 for (;;) {
3710 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3711 if (!skb)
3712 break;
3713
3714 ret = ath10k_wmi_mgmt_tx(ar, skb);
Michal Kazior5fb5e412013-10-28 07:18:13 +01003715 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003716 ath10k_warn(ar, "failed to transmit management frame via WMI: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02003717 ret);
Michal Kazior5fb5e412013-10-28 07:18:13 +01003718 ieee80211_free_txskb(ar->hw, skb);
3719 }
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003720 }
3721}
3722
Michal Kazior29946872016-03-06 16:14:34 +02003723static void ath10k_mac_txq_init(struct ieee80211_txq *txq)
3724{
Bob Copelanda66cd732016-06-29 19:29:25 +03003725 struct ath10k_txq *artxq;
Michal Kazior29946872016-03-06 16:14:34 +02003726
3727 if (!txq)
3728 return;
3729
Bob Copelanda66cd732016-06-29 19:29:25 +03003730 artxq = (void *)txq->drv_priv;
Michal Kazior29946872016-03-06 16:14:34 +02003731 INIT_LIST_HEAD(&artxq->list);
3732}
3733
3734static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq)
3735{
Bob Copelanda66cd732016-06-29 19:29:25 +03003736 struct ath10k_txq *artxq;
Michal Kaziordd4717b2016-03-06 16:14:39 +02003737 struct ath10k_skb_cb *cb;
3738 struct sk_buff *msdu;
3739 int msdu_id;
Michal Kazior29946872016-03-06 16:14:34 +02003740
3741 if (!txq)
3742 return;
3743
Bob Copelanda66cd732016-06-29 19:29:25 +03003744 artxq = (void *)txq->drv_priv;
Michal Kazior29946872016-03-06 16:14:34 +02003745 spin_lock_bh(&ar->txqs_lock);
3746 if (!list_empty(&artxq->list))
3747 list_del_init(&artxq->list);
3748 spin_unlock_bh(&ar->txqs_lock);
Michal Kaziordd4717b2016-03-06 16:14:39 +02003749
3750 spin_lock_bh(&ar->htt.tx_lock);
3751 idr_for_each_entry(&ar->htt.pending_tx, msdu, msdu_id) {
3752 cb = ATH10K_SKB_CB(msdu);
3753 if (cb->txq == txq)
3754 cb->txq = NULL;
3755 }
3756 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazior29946872016-03-06 16:14:34 +02003757}
3758
Michal Kazior426e10e2016-03-06 16:14:43 +02003759struct ieee80211_txq *ath10k_mac_txq_lookup(struct ath10k *ar,
3760 u16 peer_id,
3761 u8 tid)
3762{
3763 struct ath10k_peer *peer;
3764
3765 lockdep_assert_held(&ar->data_lock);
3766
3767 peer = ar->peer_map[peer_id];
3768 if (!peer)
3769 return NULL;
3770
Michal Kazior874b5ac2017-01-12 16:14:30 +01003771 if (peer->removed)
3772 return NULL;
3773
Michal Kazior426e10e2016-03-06 16:14:43 +02003774 if (peer->sta)
3775 return peer->sta->txq[tid];
3776 else if (peer->vif)
3777 return peer->vif->txq;
3778 else
3779 return NULL;
3780}
3781
Michal Kazior29946872016-03-06 16:14:34 +02003782static bool ath10k_mac_tx_can_push(struct ieee80211_hw *hw,
3783 struct ieee80211_txq *txq)
3784{
Michal Kazior426e10e2016-03-06 16:14:43 +02003785 struct ath10k *ar = hw->priv;
3786 struct ath10k_txq *artxq = (void *)txq->drv_priv;
3787
3788 /* No need to get locks */
3789
3790 if (ar->htt.tx_q_state.mode == HTT_TX_MODE_SWITCH_PUSH)
3791 return true;
3792
3793 if (ar->htt.num_pending_tx < ar->htt.tx_q_state.num_push_allowed)
3794 return true;
3795
3796 if (artxq->num_fw_queued < artxq->num_push_allowed)
3797 return true;
3798
3799 return false;
Michal Kazior29946872016-03-06 16:14:34 +02003800}
3801
Michal Kazior426e10e2016-03-06 16:14:43 +02003802int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
3803 struct ieee80211_txq *txq)
Michal Kazior29946872016-03-06 16:14:34 +02003804{
Michal Kazior29946872016-03-06 16:14:34 +02003805 struct ath10k *ar = hw->priv;
3806 struct ath10k_htt *htt = &ar->htt;
Michal Kazior3cc0fef2016-03-06 16:14:41 +02003807 struct ath10k_txq *artxq = (void *)txq->drv_priv;
Michal Kazior29946872016-03-06 16:14:34 +02003808 struct ieee80211_vif *vif = txq->vif;
3809 struct ieee80211_sta *sta = txq->sta;
3810 enum ath10k_hw_txrx_mode txmode;
3811 enum ath10k_mac_tx_path txpath;
3812 struct sk_buff *skb;
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05303813 struct ieee80211_hdr *hdr;
Michal Kazior426e10e2016-03-06 16:14:43 +02003814 size_t skb_len;
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05303815 bool is_mgmt, is_presp;
Michal Kazior29946872016-03-06 16:14:34 +02003816 int ret;
3817
3818 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05303819 ret = ath10k_htt_tx_inc_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02003820 spin_unlock_bh(&ar->htt.tx_lock);
3821
3822 if (ret)
3823 return ret;
3824
3825 skb = ieee80211_tx_dequeue(hw, txq);
3826 if (!skb) {
3827 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05303828 ath10k_htt_tx_dec_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02003829 spin_unlock_bh(&ar->htt.tx_lock);
3830
3831 return -ENOENT;
3832 }
3833
Michal Kaziordd4717b2016-03-06 16:14:39 +02003834 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb);
Michal Kazior29946872016-03-06 16:14:34 +02003835
Michal Kazior426e10e2016-03-06 16:14:43 +02003836 skb_len = skb->len;
Michal Kazior29946872016-03-06 16:14:34 +02003837 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
3838 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05303839 is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
3840
3841 if (is_mgmt) {
3842 hdr = (struct ieee80211_hdr *)skb->data;
3843 is_presp = ieee80211_is_probe_resp(hdr->frame_control);
3844
3845 spin_lock_bh(&ar->htt.tx_lock);
3846 ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp);
3847
3848 if (ret) {
3849 ath10k_htt_tx_dec_pending(htt);
3850 spin_unlock_bh(&ar->htt.tx_lock);
3851 return ret;
3852 }
3853 spin_unlock_bh(&ar->htt.tx_lock);
3854 }
Michal Kazior29946872016-03-06 16:14:34 +02003855
3856 ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
3857 if (unlikely(ret)) {
3858 ath10k_warn(ar, "failed to push frame: %d\n", ret);
3859
3860 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05303861 ath10k_htt_tx_dec_pending(htt);
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05303862 if (is_mgmt)
3863 ath10k_htt_tx_mgmt_dec_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02003864 spin_unlock_bh(&ar->htt.tx_lock);
3865
3866 return ret;
3867 }
3868
Michal Kazior3cc0fef2016-03-06 16:14:41 +02003869 spin_lock_bh(&ar->htt.tx_lock);
3870 artxq->num_fw_queued++;
3871 spin_unlock_bh(&ar->htt.tx_lock);
3872
Michal Kazior426e10e2016-03-06 16:14:43 +02003873 return skb_len;
Michal Kazior29946872016-03-06 16:14:34 +02003874}
3875
3876void ath10k_mac_tx_push_pending(struct ath10k *ar)
3877{
3878 struct ieee80211_hw *hw = ar->hw;
3879 struct ieee80211_txq *txq;
3880 struct ath10k_txq *artxq;
3881 struct ath10k_txq *last;
3882 int ret;
3883 int max;
3884
Michal Kazior7a0adc82016-05-23 23:12:45 +03003885 if (ar->htt.num_pending_tx >= (ar->htt.max_num_pending_tx / 2))
3886 return;
3887
Michal Kazior29946872016-03-06 16:14:34 +02003888 spin_lock_bh(&ar->txqs_lock);
3889 rcu_read_lock();
3890
3891 last = list_last_entry(&ar->txqs, struct ath10k_txq, list);
3892 while (!list_empty(&ar->txqs)) {
3893 artxq = list_first_entry(&ar->txqs, struct ath10k_txq, list);
3894 txq = container_of((void *)artxq, struct ieee80211_txq,
3895 drv_priv);
3896
3897 /* Prevent aggressive sta/tid taking over tx queue */
3898 max = 16;
Michal Kazior750eeed2016-03-17 10:51:05 +01003899 ret = 0;
3900 while (ath10k_mac_tx_can_push(hw, txq) && max--) {
Michal Kazior29946872016-03-06 16:14:34 +02003901 ret = ath10k_mac_tx_push_txq(hw, txq);
3902 if (ret < 0)
3903 break;
3904 }
3905
3906 list_del_init(&artxq->list);
Michal Kazior9d71d472016-03-17 10:51:04 +01003907 if (ret != -ENOENT)
3908 list_add_tail(&artxq->list, &ar->txqs);
3909
Michal Kaziorc1a43d92016-03-06 16:14:36 +02003910 ath10k_htt_tx_txq_update(hw, txq);
Michal Kazior29946872016-03-06 16:14:34 +02003911
Michal Kazior9d71d472016-03-17 10:51:04 +01003912 if (artxq == last || (ret < 0 && ret != -ENOENT))
Michal Kazior29946872016-03-06 16:14:34 +02003913 break;
Michal Kazior29946872016-03-06 16:14:34 +02003914 }
3915
3916 rcu_read_unlock();
3917 spin_unlock_bh(&ar->txqs_lock);
3918}
3919
Kalle Valo5e3dd152013-06-12 20:52:10 +03003920/************/
3921/* Scanning */
3922/************/
3923
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003924void __ath10k_scan_finish(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003925{
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003926 lockdep_assert_held(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003927
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003928 switch (ar->scan.state) {
3929 case ATH10K_SCAN_IDLE:
3930 break;
3931 case ATH10K_SCAN_RUNNING:
Michal Kazior7305d3e2014-11-24 14:58:33 +01003932 case ATH10K_SCAN_ABORTING:
Avraham Stern7947d3e2016-07-05 15:23:12 +03003933 if (!ar->scan.is_roc) {
3934 struct cfg80211_scan_info info = {
3935 .aborted = (ar->scan.state ==
3936 ATH10K_SCAN_ABORTING),
3937 };
3938
3939 ieee80211_scan_completed(ar->hw, &info);
3940 } else if (ar->scan.roc_notify) {
Michal Kaziord710e752015-07-09 13:08:36 +02003941 ieee80211_remain_on_channel_expired(ar->hw);
Avraham Stern7947d3e2016-07-05 15:23:12 +03003942 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003943 /* fall through */
3944 case ATH10K_SCAN_STARTING:
3945 ar->scan.state = ATH10K_SCAN_IDLE;
3946 ar->scan_channel = NULL;
Michal Kaziorbd877442015-11-18 06:59:19 +01003947 ar->scan.roc_freq = 0;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003948 ath10k_offchan_tx_purge(ar);
3949 cancel_delayed_work(&ar->scan.timeout);
Daniel Wagner881ed542016-08-18 15:12:06 +02003950 complete(&ar->scan.completed);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003951 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003952 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003953}
Kalle Valo5e3dd152013-06-12 20:52:10 +03003954
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003955void ath10k_scan_finish(struct ath10k *ar)
3956{
3957 spin_lock_bh(&ar->data_lock);
3958 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003959 spin_unlock_bh(&ar->data_lock);
3960}
3961
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003962static int ath10k_scan_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003963{
3964 struct wmi_stop_scan_arg arg = {
3965 .req_id = 1, /* FIXME */
3966 .req_type = WMI_SCAN_STOP_ONE,
3967 .u.scan_id = ATH10K_SCAN_ID,
3968 };
3969 int ret;
3970
3971 lockdep_assert_held(&ar->conf_mutex);
3972
Kalle Valo5e3dd152013-06-12 20:52:10 +03003973 ret = ath10k_wmi_stop_scan(ar, &arg);
3974 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003975 ath10k_warn(ar, "failed to stop wmi scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003976 goto out;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003977 }
3978
Kalle Valo14e105c2016-04-13 14:13:21 +03003979 ret = wait_for_completion_timeout(&ar->scan.completed, 3 * HZ);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003980 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003981 ath10k_warn(ar, "failed to receive scan abortion completion: timed out\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03003982 ret = -ETIMEDOUT;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003983 } else if (ret > 0) {
3984 ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003985 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003986
3987out:
3988 /* Scan state should be updated upon scan completion but in case
3989 * firmware fails to deliver the event (for whatever reason) it is
3990 * desired to clean up scan state anyway. Firmware may have just
3991 * dropped the scan completion event delivery due to transport pipe
3992 * being overflown with data and/or it can recover on its own before
3993 * next scan request is submitted.
3994 */
3995 spin_lock_bh(&ar->data_lock);
3996 if (ar->scan.state != ATH10K_SCAN_IDLE)
3997 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003998 spin_unlock_bh(&ar->data_lock);
3999
4000 return ret;
4001}
4002
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004003static void ath10k_scan_abort(struct ath10k *ar)
4004{
4005 int ret;
4006
4007 lockdep_assert_held(&ar->conf_mutex);
4008
4009 spin_lock_bh(&ar->data_lock);
4010
4011 switch (ar->scan.state) {
4012 case ATH10K_SCAN_IDLE:
4013 /* This can happen if timeout worker kicked in and called
4014 * abortion while scan completion was being processed.
4015 */
4016 break;
4017 case ATH10K_SCAN_STARTING:
4018 case ATH10K_SCAN_ABORTING:
Michal Kazior7aa7a722014-08-25 12:09:38 +02004019 ath10k_warn(ar, "refusing scan abortion due to invalid scan state: %s (%d)\n",
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004020 ath10k_scan_state_str(ar->scan.state),
4021 ar->scan.state);
4022 break;
4023 case ATH10K_SCAN_RUNNING:
4024 ar->scan.state = ATH10K_SCAN_ABORTING;
4025 spin_unlock_bh(&ar->data_lock);
4026
4027 ret = ath10k_scan_stop(ar);
4028 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004029 ath10k_warn(ar, "failed to abort scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004030
4031 spin_lock_bh(&ar->data_lock);
4032 break;
4033 }
4034
4035 spin_unlock_bh(&ar->data_lock);
4036}
4037
4038void ath10k_scan_timeout_work(struct work_struct *work)
4039{
4040 struct ath10k *ar = container_of(work, struct ath10k,
4041 scan.timeout.work);
4042
4043 mutex_lock(&ar->conf_mutex);
4044 ath10k_scan_abort(ar);
4045 mutex_unlock(&ar->conf_mutex);
4046}
4047
Kalle Valo5e3dd152013-06-12 20:52:10 +03004048static int ath10k_start_scan(struct ath10k *ar,
4049 const struct wmi_start_scan_arg *arg)
4050{
4051 int ret;
4052
4053 lockdep_assert_held(&ar->conf_mutex);
4054
4055 ret = ath10k_wmi_start_scan(ar, arg);
4056 if (ret)
4057 return ret;
4058
Kalle Valo14e105c2016-04-13 14:13:21 +03004059 ret = wait_for_completion_timeout(&ar->scan.started, 1 * HZ);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004060 if (ret == 0) {
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004061 ret = ath10k_scan_stop(ar);
4062 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004063 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004064
4065 return -ETIMEDOUT;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004066 }
4067
Ben Greear2f9eec02015-02-15 16:50:38 +02004068 /* If we failed to start the scan, return error code at
4069 * this point. This is probably due to some issue in the
4070 * firmware, but no need to wedge the driver due to that...
4071 */
4072 spin_lock_bh(&ar->data_lock);
4073 if (ar->scan.state == ATH10K_SCAN_IDLE) {
4074 spin_unlock_bh(&ar->data_lock);
4075 return -EINVAL;
4076 }
4077 spin_unlock_bh(&ar->data_lock);
4078
Kalle Valo5e3dd152013-06-12 20:52:10 +03004079 return 0;
4080}
4081
4082/**********************/
4083/* mac80211 callbacks */
4084/**********************/
4085
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004086static void ath10k_mac_op_tx(struct ieee80211_hw *hw,
4087 struct ieee80211_tx_control *control,
4088 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03004089{
Kalle Valo5e3dd152013-06-12 20:52:10 +03004090 struct ath10k *ar = hw->priv;
Michal Kazior6421969f2016-03-06 16:14:25 +02004091 struct ath10k_htt *htt = &ar->htt;
Michal Kazior4b604552014-07-21 21:03:09 +03004092 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
4093 struct ieee80211_vif *vif = info->control.vif;
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03004094 struct ieee80211_sta *sta = control->sta;
Michal Kaziordd4717b2016-03-06 16:14:39 +02004095 struct ieee80211_txq *txq = NULL;
Michal Kazior6421969f2016-03-06 16:14:25 +02004096 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kazior8a933962015-11-18 06:59:17 +01004097 enum ath10k_hw_txrx_mode txmode;
Michal Kazior6421969f2016-03-06 16:14:25 +02004098 enum ath10k_mac_tx_path txpath;
4099 bool is_htt;
4100 bool is_mgmt;
4101 bool is_presp;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004102 int ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004103
Michal Kaziordd4717b2016-03-06 16:14:39 +02004104 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004105
Michal Kazior8a933962015-11-18 06:59:17 +01004106 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kazior6421969f2016-03-06 16:14:25 +02004107 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
4108 is_htt = (txpath == ATH10K_MAC_TX_HTT ||
4109 txpath == ATH10K_MAC_TX_HTT_MGMT);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304110 is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004111
Michal Kazior6421969f2016-03-06 16:14:25 +02004112 if (is_htt) {
4113 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior6421969f2016-03-06 16:14:25 +02004114 is_presp = ieee80211_is_probe_resp(hdr->frame_control);
4115
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304116 ret = ath10k_htt_tx_inc_pending(htt);
Michal Kazior6421969f2016-03-06 16:14:25 +02004117 if (ret) {
4118 ath10k_warn(ar, "failed to increase tx pending count: %d, dropping\n",
4119 ret);
4120 spin_unlock_bh(&ar->htt.tx_lock);
4121 ieee80211_free_txskb(ar->hw, skb);
4122 return;
4123 }
4124
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304125 ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp);
4126 if (ret) {
Rajkumar Manoharandd7c2802016-04-07 12:07:30 +05304127 ath10k_dbg(ar, ATH10K_DBG_MAC, "failed to increase tx mgmt pending count: %d, dropping\n",
4128 ret);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304129 ath10k_htt_tx_dec_pending(htt);
4130 spin_unlock_bh(&ar->htt.tx_lock);
4131 ieee80211_free_txskb(ar->hw, skb);
4132 return;
4133 }
Michal Kazior6421969f2016-03-06 16:14:25 +02004134 spin_unlock_bh(&ar->htt.tx_lock);
4135 }
4136
4137 ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
4138 if (ret) {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004139 ath10k_warn(ar, "failed to transmit frame: %d\n", ret);
Michal Kazior6421969f2016-03-06 16:14:25 +02004140 if (is_htt) {
4141 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304142 ath10k_htt_tx_dec_pending(htt);
4143 if (is_mgmt)
4144 ath10k_htt_tx_mgmt_dec_pending(htt);
Michal Kazior6421969f2016-03-06 16:14:25 +02004145 spin_unlock_bh(&ar->htt.tx_lock);
4146 }
4147 return;
4148 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004149}
4150
Michal Kazior29946872016-03-06 16:14:34 +02004151static void ath10k_mac_op_wake_tx_queue(struct ieee80211_hw *hw,
4152 struct ieee80211_txq *txq)
4153{
4154 struct ath10k *ar = hw->priv;
4155 struct ath10k_txq *artxq = (void *)txq->drv_priv;
Rajkumar Manoharan83e164b2016-08-17 21:02:53 +05304156 struct ieee80211_txq *f_txq;
4157 struct ath10k_txq *f_artxq;
4158 int ret = 0;
4159 int max = 16;
Michal Kazior29946872016-03-06 16:14:34 +02004160
Michal Kazior750eeed2016-03-17 10:51:05 +01004161 spin_lock_bh(&ar->txqs_lock);
4162 if (list_empty(&artxq->list))
4163 list_add_tail(&artxq->list, &ar->txqs);
Rajkumar Manoharan83e164b2016-08-17 21:02:53 +05304164
4165 f_artxq = list_first_entry(&ar->txqs, struct ath10k_txq, list);
4166 f_txq = container_of((void *)f_artxq, struct ieee80211_txq, drv_priv);
4167 list_del_init(&f_artxq->list);
4168
4169 while (ath10k_mac_tx_can_push(hw, f_txq) && max--) {
4170 ret = ath10k_mac_tx_push_txq(hw, f_txq);
4171 if (ret)
4172 break;
4173 }
4174 if (ret != -ENOENT)
4175 list_add_tail(&f_artxq->list, &ar->txqs);
Michal Kazior750eeed2016-03-17 10:51:05 +01004176 spin_unlock_bh(&ar->txqs_lock);
Michal Kazior29946872016-03-06 16:14:34 +02004177
Rajkumar Manoharan83e164b2016-08-17 21:02:53 +05304178 ath10k_htt_tx_txq_update(hw, f_txq);
Michal Kaziorc1a43d92016-03-06 16:14:36 +02004179 ath10k_htt_tx_txq_update(hw, txq);
Michal Kazior29946872016-03-06 16:14:34 +02004180}
4181
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004182/* Must not be called with conf_mutex held as workers can use that also. */
Michal Kazior7962b0d2014-10-28 10:34:38 +01004183void ath10k_drain_tx(struct ath10k *ar)
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004184{
4185 /* make sure rcu-protected mac80211 tx path itself is drained */
4186 synchronize_net();
4187
4188 ath10k_offchan_tx_purge(ar);
4189 ath10k_mgmt_over_wmi_tx_purge(ar);
4190
4191 cancel_work_sync(&ar->offchan_tx_work);
4192 cancel_work_sync(&ar->wmi_mgmt_tx_work);
4193}
4194
Michal Kazioraffd3212013-07-16 09:54:35 +02004195void ath10k_halt(struct ath10k *ar)
Michal Kazior818bdd12013-07-16 09:38:57 +02004196{
Michal Kaziord9bc4b92014-04-23 19:30:06 +03004197 struct ath10k_vif *arvif;
4198
Michal Kazior818bdd12013-07-16 09:38:57 +02004199 lockdep_assert_held(&ar->conf_mutex);
4200
Michal Kazior19337472014-08-28 12:58:16 +02004201 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
4202 ar->filter_flags = 0;
4203 ar->monitor = false;
Michal Kazior500ff9f2015-03-31 10:26:21 +00004204 ar->monitor_arvif = NULL;
Michal Kazior19337472014-08-28 12:58:16 +02004205
4206 if (ar->monitor_started)
Michal Kazior1bbc0972014-04-08 09:45:47 +03004207 ath10k_monitor_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02004208
4209 ar->monitor_started = false;
Michal Kazior96d828d2015-03-31 10:26:23 +00004210 ar->tx_paused = 0;
Michal Kazior1bbc0972014-04-08 09:45:47 +03004211
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004212 ath10k_scan_finish(ar);
Michal Kazior818bdd12013-07-16 09:38:57 +02004213 ath10k_peer_cleanup_all(ar);
4214 ath10k_core_stop(ar);
4215 ath10k_hif_power_down(ar);
4216
4217 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03004218 list_for_each_entry(arvif, &ar->arvifs, list)
4219 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kazior818bdd12013-07-16 09:38:57 +02004220 spin_unlock_bh(&ar->data_lock);
4221}
4222
Ben Greear46acf7b2014-05-16 17:15:38 +03004223static int ath10k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
4224{
4225 struct ath10k *ar = hw->priv;
4226
4227 mutex_lock(&ar->conf_mutex);
4228
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05304229 *tx_ant = ar->cfg_tx_chainmask;
4230 *rx_ant = ar->cfg_rx_chainmask;
Ben Greear46acf7b2014-05-16 17:15:38 +03004231
4232 mutex_unlock(&ar->conf_mutex);
4233
4234 return 0;
4235}
4236
Ben Greear5572a952014-11-24 16:22:10 +02004237static void ath10k_check_chain_mask(struct ath10k *ar, u32 cm, const char *dbg)
4238{
4239 /* It is not clear that allowing gaps in chainmask
4240 * is helpful. Probably it will not do what user
4241 * is hoping for, so warn in that case.
4242 */
4243 if (cm == 15 || cm == 7 || cm == 3 || cm == 1 || cm == 0)
4244 return;
4245
4246 ath10k_warn(ar, "mac %s antenna chainmask may be invalid: 0x%x. Suggested values: 15, 7, 3, 1 or 0.\n",
4247 dbg, cm);
4248}
4249
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304250static int ath10k_mac_get_vht_cap_bf_sts(struct ath10k *ar)
4251{
4252 int nsts = ar->vht_cap_info;
4253
4254 nsts &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
4255 nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
4256
4257 /* If firmware does not deliver to host number of space-time
4258 * streams supported, assume it support up to 4 BF STS and return
4259 * the value for VHT CAP: nsts-1)
4260 */
4261 if (nsts == 0)
4262 return 3;
4263
4264 return nsts;
4265}
4266
4267static int ath10k_mac_get_vht_cap_bf_sound_dim(struct ath10k *ar)
4268{
4269 int sound_dim = ar->vht_cap_info;
4270
4271 sound_dim &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
4272 sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
4273
4274 /* If the sounding dimension is not advertised by the firmware,
4275 * let's use a default value of 1
4276 */
4277 if (sound_dim == 0)
4278 return 1;
4279
4280 return sound_dim;
4281}
4282
4283static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
4284{
4285 struct ieee80211_sta_vht_cap vht_cap = {0};
4286 u16 mcs_map;
4287 u32 val;
4288 int i;
4289
4290 vht_cap.vht_supported = 1;
4291 vht_cap.cap = ar->vht_cap_info;
4292
4293 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
4294 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
4295 val = ath10k_mac_get_vht_cap_bf_sts(ar);
4296 val <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
4297 val &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
4298
4299 vht_cap.cap |= val;
4300 }
4301
4302 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
4303 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
4304 val = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
4305 val <<= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
4306 val &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
4307
4308 vht_cap.cap |= val;
4309 }
4310
4311 mcs_map = 0;
4312 for (i = 0; i < 8; i++) {
4313 if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i)))
4314 mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2);
4315 else
4316 mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2);
4317 }
4318
Mohammed Shafi Shajakhan34663242016-06-29 19:29:27 +03004319 if (ar->cfg_tx_chainmask <= 1)
4320 vht_cap.cap &= ~IEEE80211_VHT_CAP_TXSTBC;
4321
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304322 vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
4323 vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
4324
4325 return vht_cap;
4326}
4327
4328static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar)
4329{
4330 int i;
4331 struct ieee80211_sta_ht_cap ht_cap = {0};
4332
4333 if (!(ar->ht_cap_info & WMI_HT_CAP_ENABLED))
4334 return ht_cap;
4335
4336 ht_cap.ht_supported = 1;
4337 ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
4338 ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
4339 ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4340 ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
Peter Ohe33a99e2015-12-31 15:26:20 +02004341 ht_cap.cap |=
4342 WLAN_HT_CAP_SM_PS_DISABLED << IEEE80211_HT_CAP_SM_PS_SHIFT;
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304343
4344 if (ar->ht_cap_info & WMI_HT_CAP_HT20_SGI)
4345 ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
4346
4347 if (ar->ht_cap_info & WMI_HT_CAP_HT40_SGI)
4348 ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
4349
4350 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) {
4351 u32 smps;
4352
4353 smps = WLAN_HT_CAP_SM_PS_DYNAMIC;
4354 smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT;
4355
4356 ht_cap.cap |= smps;
4357 }
4358
Mohammed Shafi Shajakhan34663242016-06-29 19:29:27 +03004359 if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC && (ar->cfg_tx_chainmask > 1))
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304360 ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
4361
4362 if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) {
4363 u32 stbc;
4364
4365 stbc = ar->ht_cap_info;
4366 stbc &= WMI_HT_CAP_RX_STBC;
4367 stbc >>= WMI_HT_CAP_RX_STBC_MASK_SHIFT;
4368 stbc <<= IEEE80211_HT_CAP_RX_STBC_SHIFT;
4369 stbc &= IEEE80211_HT_CAP_RX_STBC;
4370
4371 ht_cap.cap |= stbc;
4372 }
4373
4374 if (ar->ht_cap_info & WMI_HT_CAP_LDPC)
4375 ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
4376
4377 if (ar->ht_cap_info & WMI_HT_CAP_L_SIG_TXOP_PROT)
4378 ht_cap.cap |= IEEE80211_HT_CAP_LSIG_TXOP_PROT;
4379
4380 /* max AMSDU is implicitly taken from vht_cap_info */
4381 if (ar->vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_MASK)
4382 ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
4383
4384 for (i = 0; i < ar->num_rf_chains; i++) {
4385 if (ar->cfg_rx_chainmask & BIT(i))
4386 ht_cap.mcs.rx_mask[i] = 0xFF;
4387 }
4388
4389 ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
4390
4391 return ht_cap;
4392}
4393
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304394static void ath10k_mac_setup_ht_vht_cap(struct ath10k *ar)
4395{
4396 struct ieee80211_supported_band *band;
4397 struct ieee80211_sta_vht_cap vht_cap;
4398 struct ieee80211_sta_ht_cap ht_cap;
4399
4400 ht_cap = ath10k_get_ht_cap(ar);
4401 vht_cap = ath10k_create_vht_cap(ar);
4402
4403 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02004404 band = &ar->mac.sbands[NL80211_BAND_2GHZ];
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304405 band->ht_cap = ht_cap;
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304406 }
4407 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02004408 band = &ar->mac.sbands[NL80211_BAND_5GHZ];
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304409 band->ht_cap = ht_cap;
4410 band->vht_cap = vht_cap;
4411 }
4412}
4413
Ben Greear46acf7b2014-05-16 17:15:38 +03004414static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant)
4415{
4416 int ret;
4417
4418 lockdep_assert_held(&ar->conf_mutex);
4419
Ben Greear5572a952014-11-24 16:22:10 +02004420 ath10k_check_chain_mask(ar, tx_ant, "tx");
4421 ath10k_check_chain_mask(ar, rx_ant, "rx");
4422
Ben Greear46acf7b2014-05-16 17:15:38 +03004423 ar->cfg_tx_chainmask = tx_ant;
4424 ar->cfg_rx_chainmask = rx_ant;
4425
4426 if ((ar->state != ATH10K_STATE_ON) &&
4427 (ar->state != ATH10K_STATE_RESTARTED))
4428 return 0;
4429
4430 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->tx_chain_mask,
4431 tx_ant);
4432 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004433 ath10k_warn(ar, "failed to set tx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7b2014-05-16 17:15:38 +03004434 ret, tx_ant);
4435 return ret;
4436 }
4437
4438 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rx_chain_mask,
4439 rx_ant);
4440 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004441 ath10k_warn(ar, "failed to set rx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7b2014-05-16 17:15:38 +03004442 ret, rx_ant);
4443 return ret;
4444 }
4445
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304446 /* Reload HT/VHT capability */
4447 ath10k_mac_setup_ht_vht_cap(ar);
4448
Ben Greear46acf7b2014-05-16 17:15:38 +03004449 return 0;
4450}
4451
4452static int ath10k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
4453{
4454 struct ath10k *ar = hw->priv;
4455 int ret;
4456
4457 mutex_lock(&ar->conf_mutex);
4458 ret = __ath10k_set_antenna(ar, tx_ant, rx_ant);
4459 mutex_unlock(&ar->conf_mutex);
4460 return ret;
4461}
4462
Kalle Valo5e3dd152013-06-12 20:52:10 +03004463static int ath10k_start(struct ieee80211_hw *hw)
4464{
4465 struct ath10k *ar = hw->priv;
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304466 u32 param;
Michal Kazior818bdd12013-07-16 09:38:57 +02004467 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004468
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004469 /*
4470 * This makes sense only when restarting hw. It is harmless to call
Mohammed Shafi Shajakhan6dfdbfc2016-04-26 14:41:36 +03004471 * unconditionally. This is necessary to make sure no HTT/WMI tx
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004472 * commands will be submitted while restarting.
4473 */
4474 ath10k_drain_tx(ar);
4475
Michal Kazior548db542013-07-05 16:15:15 +03004476 mutex_lock(&ar->conf_mutex);
4477
Michal Kaziorc5058f52014-05-26 12:46:03 +03004478 switch (ar->state) {
4479 case ATH10K_STATE_OFF:
4480 ar->state = ATH10K_STATE_ON;
4481 break;
4482 case ATH10K_STATE_RESTARTING:
Michal Kaziorc5058f52014-05-26 12:46:03 +03004483 ar->state = ATH10K_STATE_RESTARTED;
4484 break;
4485 case ATH10K_STATE_ON:
4486 case ATH10K_STATE_RESTARTED:
4487 case ATH10K_STATE_WEDGED:
4488 WARN_ON(1);
Michal Kazior818bdd12013-07-16 09:38:57 +02004489 ret = -EINVAL;
Michal Kaziorae254432014-05-26 12:46:02 +03004490 goto err;
Kalle Valo43d2a302014-09-10 18:23:30 +03004491 case ATH10K_STATE_UTF:
4492 ret = -EBUSY;
4493 goto err;
Michal Kazior818bdd12013-07-16 09:38:57 +02004494 }
4495
4496 ret = ath10k_hif_power_up(ar);
4497 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004498 ath10k_err(ar, "Could not init hif: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004499 goto err_off;
Michal Kazior818bdd12013-07-16 09:38:57 +02004500 }
4501
Kalle Valo7ebf7212016-04-20 19:44:51 +03004502 ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL,
4503 &ar->normal_mode_fw);
Michal Kazior818bdd12013-07-16 09:38:57 +02004504 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004505 ath10k_err(ar, "Could not init core: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004506 goto err_power_down;
Michal Kazior818bdd12013-07-16 09:38:57 +02004507 }
4508
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304509 param = ar->wmi.pdev_param->pmf_qos;
4510 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004511 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004512 ath10k_warn(ar, "failed to enable PMF QOS: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004513 goto err_core_stop;
4514 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004515
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304516 param = ar->wmi.pdev_param->dynamic_bw;
4517 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004518 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004519 ath10k_warn(ar, "failed to enable dynamic BW: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004520 goto err_core_stop;
4521 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004522
Michal Kaziorcf327842015-03-31 10:26:25 +00004523 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
4524 ret = ath10k_wmi_adaptive_qcs(ar, true);
4525 if (ret) {
4526 ath10k_warn(ar, "failed to enable adaptive qcs: %d\n",
4527 ret);
4528 goto err_core_stop;
4529 }
4530 }
4531
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03004532 if (test_bit(WMI_SERVICE_BURST, ar->wmi.svc_map)) {
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304533 param = ar->wmi.pdev_param->burst_enable;
4534 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03004535 if (ret) {
4536 ath10k_warn(ar, "failed to disable burst: %d\n", ret);
4537 goto err_core_stop;
4538 }
4539 }
4540
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05304541 __ath10k_set_antenna(ar, ar->cfg_tx_chainmask, ar->cfg_rx_chainmask);
Ben Greear46acf7b2014-05-16 17:15:38 +03004542
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004543 /*
4544 * By default FW set ARP frames ac to voice (6). In that case ARP
4545 * exchange is not working properly for UAPSD enabled AP. ARP requests
4546 * which arrives with access category 0 are processed by network stack
4547 * and send back with access category 0, but FW changes access category
4548 * to 6. Set ARP frames access category to best effort (0) solves
4549 * this problem.
4550 */
4551
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304552 param = ar->wmi.pdev_param->arp_ac_override;
4553 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004554 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004555 ath10k_warn(ar, "failed to set arp ac override parameter: %d\n",
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004556 ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004557 goto err_core_stop;
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004558 }
4559
Maharaja62f77f02015-10-21 11:49:18 +03004560 if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA,
Kalle Valoc4cdf752016-04-20 19:45:18 +03004561 ar->running_fw->fw_file.fw_features)) {
Maharaja62f77f02015-10-21 11:49:18 +03004562 ret = ath10k_wmi_pdev_enable_adaptive_cca(ar, 1,
4563 WMI_CCA_DETECT_LEVEL_AUTO,
4564 WMI_CCA_DETECT_MARGIN_AUTO);
4565 if (ret) {
4566 ath10k_warn(ar, "failed to enable adaptive cca: %d\n",
4567 ret);
4568 goto err_core_stop;
4569 }
4570 }
4571
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304572 param = ar->wmi.pdev_param->ani_enable;
4573 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Ashok Raj Nagarajan575f1c32015-03-19 16:37:59 +05304574 if (ret) {
4575 ath10k_warn(ar, "failed to enable ani by default: %d\n",
4576 ret);
4577 goto err_core_stop;
4578 }
4579
Ashok Raj Nagarajanb3e71d72015-03-19 16:38:00 +05304580 ar->ani_enabled = true;
4581
Mohammed Shafi Shajakhancc61a1b2016-03-16 18:13:32 +05304582 if (ath10k_peer_stats_enabled(ar)) {
Mohammed Shafi Shajakhan8351c052016-01-13 21:16:33 +05304583 param = ar->wmi.pdev_param->peer_stats_update_period;
4584 ret = ath10k_wmi_pdev_set_param(ar, param,
4585 PEER_DEFAULT_STATS_UPDATE_PERIOD);
4586 if (ret) {
4587 ath10k_warn(ar,
4588 "failed to set peer stats period : %d\n",
4589 ret);
4590 goto err_core_stop;
4591 }
4592 }
4593
Rajkumar Manoharan39136242016-05-27 20:15:59 +05304594 param = ar->wmi.pdev_param->enable_btcoex;
4595 if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map) &&
4596 test_bit(ATH10K_FW_FEATURE_BTCOEX_PARAM,
4597 ar->running_fw->fw_file.fw_features)) {
4598 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
4599 if (ret) {
4600 ath10k_warn(ar,
4601 "failed to set btcoex param: %d\n", ret);
4602 goto err_core_stop;
4603 }
4604 clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
4605 }
4606
Michal Kaziord6500972014-04-08 09:56:09 +03004607 ar->num_started_vdevs = 0;
Michal Kaziorf7843d72013-07-16 09:38:52 +02004608 ath10k_regd_update(ar);
4609
Simon Wunderlich855aed12014-08-02 09:12:54 +03004610 ath10k_spectral_start(ar);
Rajkumar Manoharan8515b5c2015-03-15 20:36:22 +05304611 ath10k_thermal_set_throttling(ar);
Simon Wunderlich855aed12014-08-02 09:12:54 +03004612
Michal Kaziorae254432014-05-26 12:46:02 +03004613 mutex_unlock(&ar->conf_mutex);
4614 return 0;
4615
4616err_core_stop:
4617 ath10k_core_stop(ar);
4618
4619err_power_down:
4620 ath10k_hif_power_down(ar);
4621
4622err_off:
4623 ar->state = ATH10K_STATE_OFF;
4624
4625err:
Michal Kazior548db542013-07-05 16:15:15 +03004626 mutex_unlock(&ar->conf_mutex);
Michal Kaziorc60bdd82014-01-29 07:26:31 +01004627 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004628}
4629
4630static void ath10k_stop(struct ieee80211_hw *hw)
4631{
4632 struct ath10k *ar = hw->priv;
4633
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004634 ath10k_drain_tx(ar);
4635
Michal Kazior548db542013-07-05 16:15:15 +03004636 mutex_lock(&ar->conf_mutex);
Michal Kaziorc5058f52014-05-26 12:46:03 +03004637 if (ar->state != ATH10K_STATE_OFF) {
Michal Kazior818bdd12013-07-16 09:38:57 +02004638 ath10k_halt(ar);
Michal Kaziorc5058f52014-05-26 12:46:03 +03004639 ar->state = ATH10K_STATE_OFF;
4640 }
Michal Kazior548db542013-07-05 16:15:15 +03004641 mutex_unlock(&ar->conf_mutex);
4642
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004643 cancel_delayed_work_sync(&ar->scan.timeout);
Michal Kazioraffd3212013-07-16 09:54:35 +02004644 cancel_work_sync(&ar->restart_work);
4645}
4646
Michal Kaziorad088bf2013-10-16 15:44:46 +03004647static int ath10k_config_ps(struct ath10k *ar)
Michal Kazioraffd3212013-07-16 09:54:35 +02004648{
Michal Kaziorad088bf2013-10-16 15:44:46 +03004649 struct ath10k_vif *arvif;
4650 int ret = 0;
Michal Kazioraffd3212013-07-16 09:54:35 +02004651
4652 lockdep_assert_held(&ar->conf_mutex);
4653
Michal Kaziorad088bf2013-10-16 15:44:46 +03004654 list_for_each_entry(arvif, &ar->arvifs, list) {
4655 ret = ath10k_mac_vif_setup_ps(arvif);
4656 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004657 ath10k_warn(ar, "failed to setup powersave: %d\n", ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03004658 break;
4659 }
4660 }
Michal Kazioraffd3212013-07-16 09:54:35 +02004661
Michal Kaziorad088bf2013-10-16 15:44:46 +03004662 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004663}
4664
Michal Kazior7d9d5582014-10-21 10:40:15 +03004665static int ath10k_mac_txpower_setup(struct ath10k *ar, int txpower)
4666{
4667 int ret;
4668 u32 param;
4669
4670 lockdep_assert_held(&ar->conf_mutex);
4671
4672 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac txpower %d\n", txpower);
4673
4674 param = ar->wmi.pdev_param->txpower_limit2g;
4675 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
4676 if (ret) {
4677 ath10k_warn(ar, "failed to set 2g txpower %d: %d\n",
4678 txpower, ret);
4679 return ret;
4680 }
4681
4682 param = ar->wmi.pdev_param->txpower_limit5g;
4683 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
4684 if (ret) {
4685 ath10k_warn(ar, "failed to set 5g txpower %d: %d\n",
4686 txpower, ret);
4687 return ret;
4688 }
4689
4690 return 0;
4691}
4692
4693static int ath10k_mac_txpower_recalc(struct ath10k *ar)
4694{
4695 struct ath10k_vif *arvif;
4696 int ret, txpower = -1;
4697
4698 lockdep_assert_held(&ar->conf_mutex);
4699
4700 list_for_each_entry(arvif, &ar->arvifs, list) {
Ryan Hsu77bc3e92016-12-13 14:55:19 -08004701 if (arvif->txpower <= 0)
4702 continue;
Michal Kazior7d9d5582014-10-21 10:40:15 +03004703
4704 if (txpower == -1)
4705 txpower = arvif->txpower;
4706 else
4707 txpower = min(txpower, arvif->txpower);
4708 }
4709
Ryan Hsu77bc3e92016-12-13 14:55:19 -08004710 if (txpower == -1)
4711 return 0;
Michal Kazior7d9d5582014-10-21 10:40:15 +03004712
4713 ret = ath10k_mac_txpower_setup(ar, txpower);
4714 if (ret) {
4715 ath10k_warn(ar, "failed to setup tx power %d: %d\n",
4716 txpower, ret);
4717 return ret;
4718 }
4719
4720 return 0;
4721}
4722
Kalle Valo5e3dd152013-06-12 20:52:10 +03004723static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
4724{
Kalle Valo5e3dd152013-06-12 20:52:10 +03004725 struct ath10k *ar = hw->priv;
4726 struct ieee80211_conf *conf = &hw->conf;
4727 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004728
4729 mutex_lock(&ar->conf_mutex);
4730
Michal Kazioraffd3212013-07-16 09:54:35 +02004731 if (changed & IEEE80211_CONF_CHANGE_PS)
4732 ath10k_config_ps(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004733
4734 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
Michal Kazior19337472014-08-28 12:58:16 +02004735 ar->monitor = conf->flags & IEEE80211_CONF_MONITOR;
4736 ret = ath10k_monitor_recalc(ar);
4737 if (ret)
4738 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004739 }
4740
4741 mutex_unlock(&ar->conf_mutex);
4742 return ret;
4743}
4744
Ben Greear5572a952014-11-24 16:22:10 +02004745static u32 get_nss_from_chainmask(u16 chain_mask)
4746{
Rajkumar Manoharanf680f702015-11-03 11:51:33 +05304747 if ((chain_mask & 0xf) == 0xf)
Ben Greear5572a952014-11-24 16:22:10 +02004748 return 4;
4749 else if ((chain_mask & 0x7) == 0x7)
4750 return 3;
4751 else if ((chain_mask & 0x3) == 0x3)
4752 return 2;
4753 return 1;
4754}
4755
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304756static int ath10k_mac_set_txbf_conf(struct ath10k_vif *arvif)
4757{
4758 u32 value = 0;
4759 struct ath10k *ar = arvif->ar;
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004760 int nsts;
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004761 int sound_dim;
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304762
4763 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_BEFORE_ASSOC)
4764 return 0;
4765
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004766 nsts = ath10k_mac_get_vht_cap_bf_sts(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304767 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
4768 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE))
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004769 value |= SM(nsts, WMI_TXBF_STS_CAP_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304770
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004771 sound_dim = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304772 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
4773 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE))
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004774 value |= SM(sound_dim, WMI_BF_SOUND_DIM_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304775
4776 if (!value)
4777 return 0;
4778
4779 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
4780 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
4781
4782 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
4783 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFER |
4784 WMI_VDEV_PARAM_TXBF_SU_TX_BFER);
4785
4786 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
4787 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
4788
4789 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
4790 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFEE |
4791 WMI_VDEV_PARAM_TXBF_SU_TX_BFEE);
4792
4793 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
4794 ar->wmi.vdev_param->txbf, value);
4795}
4796
Kalle Valo5e3dd152013-06-12 20:52:10 +03004797/*
4798 * TODO:
4799 * Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE,
4800 * because we will send mgmt frames without CCK. This requirement
4801 * for P2P_FIND/GO_NEG should be handled by checking CCK flag
4802 * in the TX packet.
4803 */
4804static int ath10k_add_interface(struct ieee80211_hw *hw,
4805 struct ieee80211_vif *vif)
4806{
4807 struct ath10k *ar = hw->priv;
4808 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02004809 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004810 enum wmi_sta_powersave_param param;
4811 int ret = 0;
Kalle Valo5a13e762014-01-20 11:01:46 +02004812 u32 value;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004813 int bit;
Michal Kazior96d828d2015-03-31 10:26:23 +00004814 int i;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004815 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004816
Johannes Berg848955c2014-11-11 12:48:42 +01004817 vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
4818
Kalle Valo5e3dd152013-06-12 20:52:10 +03004819 mutex_lock(&ar->conf_mutex);
4820
Michal Kazior0dbd09e2013-07-31 10:55:14 +02004821 memset(arvif, 0, sizeof(*arvif));
Michal Kazior29946872016-03-06 16:14:34 +02004822 ath10k_mac_txq_init(vif->txq);
Michal Kazior0dbd09e2013-07-31 10:55:14 +02004823
Kalle Valo5e3dd152013-06-12 20:52:10 +03004824 arvif->ar = ar;
4825 arvif->vif = vif;
4826
Ben Greeare63b33f2013-10-22 14:54:14 -07004827 INIT_LIST_HEAD(&arvif->list);
Michal Kazior81a9a172015-03-05 16:02:17 +02004828 INIT_WORK(&arvif->ap_csa_work, ath10k_mac_vif_ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02004829 INIT_DELAYED_WORK(&arvif->connection_loss_work,
4830 ath10k_mac_vif_sta_connection_loss_work);
Michal Kaziorcc4827b2013-10-16 15:44:45 +03004831
Michal Kazior45c9abc2015-04-21 20:42:58 +03004832 for (i = 0; i < ARRAY_SIZE(arvif->bitrate_mask.control); i++) {
4833 arvif->bitrate_mask.control[i].legacy = 0xffffffff;
4834 memset(arvif->bitrate_mask.control[i].ht_mcs, 0xff,
4835 sizeof(arvif->bitrate_mask.control[i].ht_mcs));
4836 memset(arvif->bitrate_mask.control[i].vht_mcs, 0xff,
4837 sizeof(arvif->bitrate_mask.control[i].vht_mcs));
4838 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004839
Michal Kaziore04cafb2015-08-05 12:15:24 +02004840 if (ar->num_peers >= ar->max_num_peers) {
4841 ath10k_warn(ar, "refusing vdev creation due to insufficient peer entry resources in firmware\n");
Michal Kazior503422d2015-08-19 13:08:53 +02004842 ret = -ENOBUFS;
4843 goto err;
Michal Kaziore04cafb2015-08-05 12:15:24 +02004844 }
4845
Ben Greeara9aefb32014-08-12 11:02:19 +03004846 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004847 ath10k_warn(ar, "Free vdev map is empty, no more interfaces allowed.\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004848 ret = -EBUSY;
Michal Kazior9dad14a2013-10-16 15:44:45 +03004849 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004850 }
Ben Greear16c11172014-09-23 14:17:16 -07004851 bit = __ffs64(ar->free_vdev_map);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004852
Ben Greear16c11172014-09-23 14:17:16 -07004853 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac create vdev %i map %llx\n",
4854 bit, ar->free_vdev_map);
4855
4856 arvif->vdev_id = bit;
Peter Oh6e4de1a2016-01-28 13:54:10 -08004857 arvif->vdev_subtype =
4858 ath10k_wmi_get_vdev_subtype(ar, WMI_VDEV_SUBTYPE_NONE);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004859
Kalle Valo5e3dd152013-06-12 20:52:10 +03004860 switch (vif->type) {
Michal Kazior75d2bd42014-12-12 12:41:39 +01004861 case NL80211_IFTYPE_P2P_DEVICE:
4862 arvif->vdev_type = WMI_VDEV_TYPE_STA;
Peter Oh6e4de1a2016-01-28 13:54:10 -08004863 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4864 (ar, WMI_VDEV_SUBTYPE_P2P_DEVICE);
Michal Kazior75d2bd42014-12-12 12:41:39 +01004865 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004866 case NL80211_IFTYPE_UNSPECIFIED:
4867 case NL80211_IFTYPE_STATION:
4868 arvif->vdev_type = WMI_VDEV_TYPE_STA;
4869 if (vif->p2p)
Peter Oh6e4de1a2016-01-28 13:54:10 -08004870 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4871 (ar, WMI_VDEV_SUBTYPE_P2P_CLIENT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004872 break;
4873 case NL80211_IFTYPE_ADHOC:
4874 arvif->vdev_type = WMI_VDEV_TYPE_IBSS;
4875 break;
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004876 case NL80211_IFTYPE_MESH_POINT:
Peter Oh0b3d76e2016-01-28 13:54:07 -08004877 if (test_bit(WMI_SERVICE_MESH_11S, ar->wmi.svc_map)) {
Peter Oh6e4de1a2016-01-28 13:54:10 -08004878 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4879 (ar, WMI_VDEV_SUBTYPE_MESH_11S);
Peter Ohbb58b892015-11-24 09:37:35 -08004880 } else if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004881 ret = -EINVAL;
4882 ath10k_warn(ar, "must load driver with rawmode=1 to add mesh interfaces\n");
4883 goto err;
4884 }
4885 arvif->vdev_type = WMI_VDEV_TYPE_AP;
4886 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004887 case NL80211_IFTYPE_AP:
4888 arvif->vdev_type = WMI_VDEV_TYPE_AP;
4889
4890 if (vif->p2p)
Peter Oh6e4de1a2016-01-28 13:54:10 -08004891 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4892 (ar, WMI_VDEV_SUBTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004893 break;
4894 case NL80211_IFTYPE_MONITOR:
4895 arvif->vdev_type = WMI_VDEV_TYPE_MONITOR;
4896 break;
4897 default:
4898 WARN_ON(1);
4899 break;
4900 }
4901
Michal Kazior96d828d2015-03-31 10:26:23 +00004902 /* Using vdev_id as queue number will make it very easy to do per-vif
4903 * tx queue locking. This shouldn't wrap due to interface combinations
4904 * but do a modulo for correctness sake and prevent using offchannel tx
4905 * queues for regular vif tx.
4906 */
4907 vif->cab_queue = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
4908 for (i = 0; i < ARRAY_SIZE(vif->hw_queue); i++)
4909 vif->hw_queue[i] = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
4910
Michal Kazior64badcb2014-09-18 11:18:02 +03004911 /* Some firmware revisions don't wait for beacon tx completion before
4912 * sending another SWBA event. This could lead to hardware using old
4913 * (freed) beacon data in some cases, e.g. tx credit starvation
4914 * combined with missed TBTT. This is very very rare.
4915 *
4916 * On non-IOMMU-enabled hosts this could be a possible security issue
4917 * because hw could beacon some random data on the air. On
4918 * IOMMU-enabled hosts DMAR faults would occur in most cases and target
4919 * device would crash.
4920 *
4921 * Since there are no beacon tx completions (implicit nor explicit)
4922 * propagated to host the only workaround for this is to allocate a
4923 * DMA-coherent buffer for a lifetime of a vif and use it for all
4924 * beacon tx commands. Worst case for this approach is some beacons may
4925 * become corrupted, e.g. have garbled IEs or out-of-date TIM bitmap.
4926 */
4927 if (vif->type == NL80211_IFTYPE_ADHOC ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004928 vif->type == NL80211_IFTYPE_MESH_POINT ||
Michal Kazior64badcb2014-09-18 11:18:02 +03004929 vif->type == NL80211_IFTYPE_AP) {
4930 arvif->beacon_buf = dma_zalloc_coherent(ar->dev,
4931 IEEE80211_MAX_FRAME_LEN,
4932 &arvif->beacon_paddr,
Rajkumar Manoharan82d7aba2014-10-10 17:38:27 +05304933 GFP_ATOMIC);
Michal Kazior64badcb2014-09-18 11:18:02 +03004934 if (!arvif->beacon_buf) {
4935 ret = -ENOMEM;
4936 ath10k_warn(ar, "failed to allocate beacon buffer: %d\n",
4937 ret);
4938 goto err;
4939 }
4940 }
David Liuccec9032015-07-24 20:25:32 +03004941 if (test_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags))
4942 arvif->nohwcrypt = true;
4943
4944 if (arvif->nohwcrypt &&
4945 !test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
4946 ath10k_warn(ar, "cryptmode module param needed for sw crypto\n");
4947 goto err;
4948 }
Michal Kazior64badcb2014-09-18 11:18:02 +03004949
4950 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev create %d (add interface) type %d subtype %d bcnmode %s\n",
4951 arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype,
4952 arvif->beacon_buf ? "single-buf" : "per-skb");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004953
4954 ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id, arvif->vdev_type,
4955 arvif->vdev_subtype, vif->addr);
4956 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004957 ath10k_warn(ar, "failed to create WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004958 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004959 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004960 }
4961
Ben Greear16c11172014-09-23 14:17:16 -07004962 ar->free_vdev_map &= ~(1LL << arvif->vdev_id);
Michal Kazior05791192013-10-16 15:44:45 +03004963 list_add(&arvif->list, &ar->arvifs);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004964
Michal Kazior46725b12015-01-28 09:57:49 +02004965 /* It makes no sense to have firmware do keepalives. mac80211 already
4966 * takes care of this with idle connection polling.
4967 */
4968 ret = ath10k_mac_vif_disable_keepalive(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004969 if (ret) {
Michal Kazior46725b12015-01-28 09:57:49 +02004970 ath10k_warn(ar, "failed to disable keepalive on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004971 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004972 goto err_vdev_delete;
4973 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004974
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02004975 arvif->def_wep_key_idx = -1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004976
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004977 vdev_param = ar->wmi.vdev_param->tx_encap_type;
4978 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004979 ATH10K_HW_TXRX_NATIVE_WIFI);
Bartosz Markowskiebc9abd2013-10-15 09:26:20 +02004980 /* 10.X firmware does not support this VDEV parameter. Do not warn */
Michal Kazior9dad14a2013-10-16 15:44:45 +03004981 if (ret && ret != -EOPNOTSUPP) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004982 ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004983 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004984 goto err_vdev_delete;
4985 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004986
Rajkumar Manoharan8a75fc52016-03-02 20:13:52 +05304987 /* Configuring number of spatial stream for monitor interface is causing
4988 * target assert in qca9888 and qca6174.
4989 */
4990 if (ar->cfg_tx_chainmask && (vif->type != NL80211_IFTYPE_MONITOR)) {
Ben Greear5572a952014-11-24 16:22:10 +02004991 u16 nss = get_nss_from_chainmask(ar->cfg_tx_chainmask);
4992
4993 vdev_param = ar->wmi.vdev_param->nss;
4994 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
4995 nss);
4996 if (ret) {
4997 ath10k_warn(ar, "failed to set vdev %i chainmask 0x%x, nss %i: %d\n",
4998 arvif->vdev_id, ar->cfg_tx_chainmask, nss,
4999 ret);
5000 goto err_vdev_delete;
5001 }
5002 }
5003
Michal Kaziore57e0572015-03-24 13:14:03 +00005004 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5005 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior69427262016-03-06 16:14:30 +02005006 ret = ath10k_peer_create(ar, vif, NULL, arvif->vdev_id,
5007 vif->addr, WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005008 if (ret) {
Michal Kaziore57e0572015-03-24 13:14:03 +00005009 ath10k_warn(ar, "failed to create vdev %i peer for AP/IBSS: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005010 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005011 goto err_vdev_delete;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005012 }
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02005013
5014 spin_lock_bh(&ar->data_lock);
5015
5016 peer = ath10k_peer_find(ar, arvif->vdev_id, vif->addr);
5017 if (!peer) {
5018 ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",
5019 vif->addr, arvif->vdev_id);
5020 spin_unlock_bh(&ar->data_lock);
5021 ret = -ENOENT;
5022 goto err_peer_delete;
5023 }
5024
5025 arvif->peer_id = find_first_bit(peer->peer_ids,
5026 ATH10K_MAX_NUM_PEER_IDS);
5027
5028 spin_unlock_bh(&ar->data_lock);
5029 } else {
5030 arvif->peer_id = HTT_INVALID_PEERID;
Michal Kaziore57e0572015-03-24 13:14:03 +00005031 }
Marek Puzyniakcdf07402013-12-30 09:07:51 +01005032
Michal Kaziore57e0572015-03-24 13:14:03 +00005033 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
Kalle Valo5a13e762014-01-20 11:01:46 +02005034 ret = ath10k_mac_set_kickout(arvif);
5035 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005036 ath10k_warn(ar, "failed to set vdev %i kickout parameters: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005037 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +02005038 goto err_peer_delete;
5039 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005040 }
5041
5042 if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {
5043 param = WMI_STA_PS_PARAM_RX_WAKE_POLICY;
5044 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
5045 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
5046 param, value);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005047 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005048 ath10k_warn(ar, "failed to set vdev %i RX wake policy: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005049 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005050 goto err_peer_delete;
5051 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005052
Michal Kazior9f9b5742014-12-12 12:41:36 +01005053 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005054 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01005055 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005056 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005057 goto err_peer_delete;
5058 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005059
Michal Kazior9f9b5742014-12-12 12:41:36 +01005060 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005061 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01005062 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005063 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005064 goto err_peer_delete;
5065 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005066 }
5067
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05305068 ret = ath10k_mac_set_txbf_conf(arvif);
5069 if (ret) {
5070 ath10k_warn(ar, "failed to set txbf for vdev %d: %d\n",
5071 arvif->vdev_id, ret);
5072 goto err_peer_delete;
5073 }
5074
Michal Kazior424121c2013-07-22 14:13:31 +02005075 ret = ath10k_mac_set_rts(arvif, ar->hw->wiphy->rts_threshold);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005076 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005077 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kazior679c54a2013-07-05 16:15:04 +03005078 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005079 goto err_peer_delete;
5080 }
Michal Kazior679c54a2013-07-05 16:15:04 +03005081
Michal Kazior7d9d5582014-10-21 10:40:15 +03005082 arvif->txpower = vif->bss_conf.txpower;
5083 ret = ath10k_mac_txpower_recalc(ar);
5084 if (ret) {
5085 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
5086 goto err_peer_delete;
5087 }
5088
Michal Kazior500ff9f2015-03-31 10:26:21 +00005089 if (vif->type == NL80211_IFTYPE_MONITOR) {
5090 ar->monitor_arvif = arvif;
5091 ret = ath10k_monitor_recalc(ar);
5092 if (ret) {
5093 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
5094 goto err_peer_delete;
5095 }
5096 }
5097
Michal Kazior6d2d51e2015-08-07 09:08:21 +02005098 spin_lock_bh(&ar->htt.tx_lock);
5099 if (!ar->tx_paused)
5100 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
5101 spin_unlock_bh(&ar->htt.tx_lock);
5102
Kalle Valo5e3dd152013-06-12 20:52:10 +03005103 mutex_unlock(&ar->conf_mutex);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005104 return 0;
5105
5106err_peer_delete:
Michal Kaziore57e0572015-03-24 13:14:03 +00005107 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5108 arvif->vdev_type == WMI_VDEV_TYPE_IBSS)
Michal Kazior9dad14a2013-10-16 15:44:45 +03005109 ath10k_wmi_peer_delete(ar, arvif->vdev_id, vif->addr);
5110
5111err_vdev_delete:
5112 ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
Ben Greear16c11172014-09-23 14:17:16 -07005113 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Michal Kazior05791192013-10-16 15:44:45 +03005114 list_del(&arvif->list);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005115
5116err:
Michal Kazior64badcb2014-09-18 11:18:02 +03005117 if (arvif->beacon_buf) {
5118 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
5119 arvif->beacon_buf, arvif->beacon_paddr);
5120 arvif->beacon_buf = NULL;
5121 }
5122
Michal Kazior9dad14a2013-10-16 15:44:45 +03005123 mutex_unlock(&ar->conf_mutex);
5124
Kalle Valo5e3dd152013-06-12 20:52:10 +03005125 return ret;
5126}
5127
Michal Kaziorb4aa5392015-03-31 10:26:24 +00005128static void ath10k_mac_vif_tx_unlock_all(struct ath10k_vif *arvif)
5129{
5130 int i;
5131
5132 for (i = 0; i < BITS_PER_LONG; i++)
5133 ath10k_mac_vif_tx_unlock(arvif, i);
5134}
5135
Kalle Valo5e3dd152013-06-12 20:52:10 +03005136static void ath10k_remove_interface(struct ieee80211_hw *hw,
5137 struct ieee80211_vif *vif)
5138{
5139 struct ath10k *ar = hw->priv;
5140 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior69427262016-03-06 16:14:30 +02005141 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005142 int ret;
Michal Kazior69427262016-03-06 16:14:30 +02005143 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005144
Michal Kazior81a9a172015-03-05 16:02:17 +02005145 cancel_work_sync(&arvif->ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02005146 cancel_delayed_work_sync(&arvif->connection_loss_work);
Michal Kazior81a9a172015-03-05 16:02:17 +02005147
Sujith Manoharan5d011f52014-11-25 11:47:00 +05305148 mutex_lock(&ar->conf_mutex);
5149
Michal Kaziored543882013-09-13 14:16:56 +02005150 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03005151 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kaziored543882013-09-13 14:16:56 +02005152 spin_unlock_bh(&ar->data_lock);
5153
Simon Wunderlich855aed12014-08-02 09:12:54 +03005154 ret = ath10k_spectral_vif_stop(arvif);
5155 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005156 ath10k_warn(ar, "failed to stop spectral for vdev %i: %d\n",
Simon Wunderlich855aed12014-08-02 09:12:54 +03005157 arvif->vdev_id, ret);
5158
Ben Greear16c11172014-09-23 14:17:16 -07005159 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Michal Kazior05791192013-10-16 15:44:45 +03005160 list_del(&arvif->list);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005161
Michal Kaziore57e0572015-03-24 13:14:03 +00005162 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5163 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02005164 ret = ath10k_wmi_peer_delete(arvif->ar, arvif->vdev_id,
5165 vif->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005166 if (ret)
Michal Kaziore57e0572015-03-24 13:14:03 +00005167 ath10k_warn(ar, "failed to submit AP/IBSS self-peer removal on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005168 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005169
5170 kfree(arvif->u.ap.noa_data);
5171 }
5172
Michal Kazior7aa7a722014-08-25 12:09:38 +02005173 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i delete (remove interface)\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005174 arvif->vdev_id);
5175
Kalle Valo5e3dd152013-06-12 20:52:10 +03005176 ret = ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
5177 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005178 ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005179 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005180
Michal Kazior2c512052015-02-15 16:50:40 +02005181 /* Some firmware revisions don't notify host about self-peer removal
5182 * until after associated vdev is deleted.
5183 */
Michal Kaziore57e0572015-03-24 13:14:03 +00005184 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5185 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02005186 ret = ath10k_wait_for_peer_deleted(ar, arvif->vdev_id,
5187 vif->addr);
5188 if (ret)
5189 ath10k_warn(ar, "failed to remove AP self-peer on vdev %i: %d\n",
5190 arvif->vdev_id, ret);
5191
5192 spin_lock_bh(&ar->data_lock);
5193 ar->num_peers--;
5194 spin_unlock_bh(&ar->data_lock);
5195 }
5196
Michal Kazior69427262016-03-06 16:14:30 +02005197 spin_lock_bh(&ar->data_lock);
5198 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
5199 peer = ar->peer_map[i];
5200 if (!peer)
5201 continue;
5202
5203 if (peer->vif == vif) {
5204 ath10k_warn(ar, "found vif peer %pM entry on vdev %i after it was supposedly removed\n",
5205 vif->addr, arvif->vdev_id);
5206 peer->vif = NULL;
5207 }
5208 }
5209 spin_unlock_bh(&ar->data_lock);
5210
Kalle Valo5e3dd152013-06-12 20:52:10 +03005211 ath10k_peer_cleanup(ar, arvif->vdev_id);
Michal Kaziordd4717b2016-03-06 16:14:39 +02005212 ath10k_mac_txq_unref(ar, vif->txq);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005213
Michal Kazior500ff9f2015-03-31 10:26:21 +00005214 if (vif->type == NL80211_IFTYPE_MONITOR) {
5215 ar->monitor_arvif = NULL;
5216 ret = ath10k_monitor_recalc(ar);
5217 if (ret)
5218 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
5219 }
5220
Michal Kaziorb4aa5392015-03-31 10:26:24 +00005221 spin_lock_bh(&ar->htt.tx_lock);
5222 ath10k_mac_vif_tx_unlock_all(arvif);
5223 spin_unlock_bh(&ar->htt.tx_lock);
5224
Michal Kazior29946872016-03-06 16:14:34 +02005225 ath10k_mac_txq_unref(ar, vif->txq);
5226
Kalle Valo5e3dd152013-06-12 20:52:10 +03005227 mutex_unlock(&ar->conf_mutex);
5228}
5229
5230/*
5231 * FIXME: Has to be verified.
5232 */
5233#define SUPPORTED_FILTERS \
Johannes Bergdf140462015-04-22 14:40:58 +02005234 (FIF_ALLMULTI | \
Kalle Valo5e3dd152013-06-12 20:52:10 +03005235 FIF_CONTROL | \
5236 FIF_PSPOLL | \
5237 FIF_OTHER_BSS | \
5238 FIF_BCN_PRBRESP_PROMISC | \
5239 FIF_PROBE_REQ | \
5240 FIF_FCSFAIL)
5241
5242static void ath10k_configure_filter(struct ieee80211_hw *hw,
5243 unsigned int changed_flags,
5244 unsigned int *total_flags,
5245 u64 multicast)
5246{
5247 struct ath10k *ar = hw->priv;
5248 int ret;
5249
5250 mutex_lock(&ar->conf_mutex);
5251
5252 changed_flags &= SUPPORTED_FILTERS;
5253 *total_flags &= SUPPORTED_FILTERS;
5254 ar->filter_flags = *total_flags;
5255
Michal Kazior19337472014-08-28 12:58:16 +02005256 ret = ath10k_monitor_recalc(ar);
5257 if (ret)
Colin Ian King7f03d302016-08-26 19:08:52 +01005258 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005259
5260 mutex_unlock(&ar->conf_mutex);
5261}
5262
5263static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
5264 struct ieee80211_vif *vif,
5265 struct ieee80211_bss_conf *info,
5266 u32 changed)
5267{
5268 struct ath10k *ar = hw->priv;
5269 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5270 int ret = 0;
Kalle Valoaf762c02014-09-14 12:50:17 +03005271 u32 vdev_param, pdev_param, slottime, preamble;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005272
5273 mutex_lock(&ar->conf_mutex);
5274
5275 if (changed & BSS_CHANGED_IBSS)
5276 ath10k_control_ibss(arvif, info, vif->addr);
5277
5278 if (changed & BSS_CHANGED_BEACON_INT) {
5279 arvif->beacon_interval = info->beacon_int;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005280 vdev_param = ar->wmi.vdev_param->beacon_interval;
5281 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005282 arvif->beacon_interval);
Michal Kazior7aa7a722014-08-25 12:09:38 +02005283 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005284 "mac vdev %d beacon_interval %d\n",
5285 arvif->vdev_id, arvif->beacon_interval);
5286
Kalle Valo5e3dd152013-06-12 20:52:10 +03005287 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005288 ath10k_warn(ar, "failed to set beacon interval for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005289 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005290 }
5291
5292 if (changed & BSS_CHANGED_BEACON) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005293 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005294 "vdev %d set beacon tx mode to staggered\n",
5295 arvif->vdev_id);
5296
Bartosz Markowski226a3392013-09-26 17:47:16 +02005297 pdev_param = ar->wmi.pdev_param->beacon_tx_mode;
5298 ret = ath10k_wmi_pdev_set_param(ar, pdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005299 WMI_BEACON_STAGGERED_MODE);
5300 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005301 ath10k_warn(ar, "failed to set beacon mode for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005302 arvif->vdev_id, ret);
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02005303
5304 ret = ath10k_mac_setup_bcn_tmpl(arvif);
5305 if (ret)
5306 ath10k_warn(ar, "failed to update beacon template: %d\n",
5307 ret);
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005308
5309 if (ieee80211_vif_is_mesh(vif)) {
5310 /* mesh doesn't use SSID but firmware needs it */
5311 strncpy(arvif->u.ap.ssid, "mesh",
5312 sizeof(arvif->u.ap.ssid));
5313 arvif->u.ap.ssid_len = 4;
5314 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005315 }
5316
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02005317 if (changed & BSS_CHANGED_AP_PROBE_RESP) {
5318 ret = ath10k_mac_setup_prb_tmpl(arvif);
5319 if (ret)
5320 ath10k_warn(ar, "failed to setup probe resp template on vdev %i: %d\n",
5321 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005322 }
5323
Michal Kaziorba2479f2015-01-24 12:14:51 +02005324 if (changed & (BSS_CHANGED_BEACON_INFO | BSS_CHANGED_BEACON)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005325 arvif->dtim_period = info->dtim_period;
5326
Michal Kazior7aa7a722014-08-25 12:09:38 +02005327 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005328 "mac vdev %d dtim_period %d\n",
5329 arvif->vdev_id, arvif->dtim_period);
5330
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005331 vdev_param = ar->wmi.vdev_param->dtim_period;
5332 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005333 arvif->dtim_period);
5334 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005335 ath10k_warn(ar, "failed to set dtim period for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005336 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005337 }
5338
5339 if (changed & BSS_CHANGED_SSID &&
5340 vif->type == NL80211_IFTYPE_AP) {
5341 arvif->u.ap.ssid_len = info->ssid_len;
5342 if (info->ssid_len)
5343 memcpy(arvif->u.ap.ssid, info->ssid, info->ssid_len);
5344 arvif->u.ap.hidden_ssid = info->hidden_ssid;
5345 }
5346
Michal Kazior077efc82014-10-21 10:10:29 +03005347 if (changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid))
5348 ether_addr_copy(arvif->bssid, info->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005349
5350 if (changed & BSS_CHANGED_BEACON_ENABLED)
5351 ath10k_control_beaconing(arvif, info);
5352
5353 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005354 arvif->use_cts_prot = info->use_cts_prot;
Kalle Valo60c3daa2013-09-08 17:56:07 +03005355
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005356 ret = ath10k_recalc_rtscts_prot(arvif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005357 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005358 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005359 arvif->vdev_id, ret);
Michal Kaziora87fd4b2015-03-02 11:21:17 +01005360
Bartosz Markowski83e48fc2016-12-15 11:23:24 +02005361 if (ath10k_mac_can_set_cts_prot(arvif)) {
5362 ret = ath10k_mac_set_cts_prot(arvif);
5363 if (ret)
5364 ath10k_warn(ar, "failed to set cts protection for vdev %d: %d\n",
5365 arvif->vdev_id, ret);
5366 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005367 }
5368
5369 if (changed & BSS_CHANGED_ERP_SLOT) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005370 if (info->use_short_slot)
5371 slottime = WMI_VDEV_SLOT_TIME_SHORT; /* 9us */
5372
5373 else
5374 slottime = WMI_VDEV_SLOT_TIME_LONG; /* 20us */
5375
Michal Kazior7aa7a722014-08-25 12:09:38 +02005376 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d slot_time %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005377 arvif->vdev_id, slottime);
5378
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005379 vdev_param = ar->wmi.vdev_param->slot_time;
5380 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005381 slottime);
5382 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005383 ath10k_warn(ar, "failed to set erp slot for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005384 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005385 }
5386
5387 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005388 if (info->use_short_preamble)
5389 preamble = WMI_VDEV_PREAMBLE_SHORT;
5390 else
5391 preamble = WMI_VDEV_PREAMBLE_LONG;
5392
Michal Kazior7aa7a722014-08-25 12:09:38 +02005393 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005394 "mac vdev %d preamble %dn",
5395 arvif->vdev_id, preamble);
5396
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005397 vdev_param = ar->wmi.vdev_param->preamble;
5398 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005399 preamble);
5400 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005401 ath10k_warn(ar, "failed to set preamble for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005402 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005403 }
5404
5405 if (changed & BSS_CHANGED_ASSOC) {
Michal Kaziore556f112014-08-28 12:58:17 +02005406 if (info->assoc) {
5407 /* Workaround: Make sure monitor vdev is not running
5408 * when associating to prevent some firmware revisions
5409 * (e.g. 10.1 and 10.2) from crashing.
5410 */
5411 if (ar->monitor_started)
5412 ath10k_monitor_stop(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005413 ath10k_bss_assoc(hw, vif, info);
Michal Kaziore556f112014-08-28 12:58:17 +02005414 ath10k_monitor_recalc(ar);
Michal Kazior077efc82014-10-21 10:10:29 +03005415 } else {
5416 ath10k_bss_disassoc(hw, vif);
Michal Kaziore556f112014-08-28 12:58:17 +02005417 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005418 }
5419
Michal Kazior7d9d5582014-10-21 10:40:15 +03005420 if (changed & BSS_CHANGED_TXPOWER) {
5421 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev_id %i txpower %d\n",
5422 arvif->vdev_id, info->txpower);
5423
5424 arvif->txpower = info->txpower;
5425 ret = ath10k_mac_txpower_recalc(ar);
5426 if (ret)
5427 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
5428 }
5429
Michal Kaziorbf14e652014-12-12 12:41:38 +01005430 if (changed & BSS_CHANGED_PS) {
Michal Kaziorcffb41f2015-02-13 13:30:16 +01005431 arvif->ps = vif->bss_conf.ps;
5432
5433 ret = ath10k_config_ps(ar);
Michal Kaziorbf14e652014-12-12 12:41:38 +01005434 if (ret)
5435 ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n",
5436 arvif->vdev_id, ret);
5437 }
5438
Kalle Valo5e3dd152013-06-12 20:52:10 +03005439 mutex_unlock(&ar->conf_mutex);
5440}
5441
5442static int ath10k_hw_scan(struct ieee80211_hw *hw,
5443 struct ieee80211_vif *vif,
David Spinadelc56ef672014-02-05 15:21:13 +02005444 struct ieee80211_scan_request *hw_req)
Kalle Valo5e3dd152013-06-12 20:52:10 +03005445{
5446 struct ath10k *ar = hw->priv;
5447 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
David Spinadelc56ef672014-02-05 15:21:13 +02005448 struct cfg80211_scan_request *req = &hw_req->req;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005449 struct wmi_start_scan_arg arg;
5450 int ret = 0;
5451 int i;
5452
5453 mutex_lock(&ar->conf_mutex);
5454
5455 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005456 switch (ar->scan.state) {
5457 case ATH10K_SCAN_IDLE:
5458 reinit_completion(&ar->scan.started);
5459 reinit_completion(&ar->scan.completed);
5460 ar->scan.state = ATH10K_SCAN_STARTING;
5461 ar->scan.is_roc = false;
5462 ar->scan.vdev_id = arvif->vdev_id;
5463 ret = 0;
5464 break;
5465 case ATH10K_SCAN_STARTING:
5466 case ATH10K_SCAN_RUNNING:
5467 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03005468 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005469 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005470 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005471 spin_unlock_bh(&ar->data_lock);
5472
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005473 if (ret)
5474 goto exit;
5475
Kalle Valo5e3dd152013-06-12 20:52:10 +03005476 memset(&arg, 0, sizeof(arg));
5477 ath10k_wmi_start_scan_init(ar, &arg);
5478 arg.vdev_id = arvif->vdev_id;
5479 arg.scan_id = ATH10K_SCAN_ID;
5480
Kalle Valo5e3dd152013-06-12 20:52:10 +03005481 if (req->ie_len) {
5482 arg.ie_len = req->ie_len;
5483 memcpy(arg.ie, req->ie, arg.ie_len);
5484 }
5485
5486 if (req->n_ssids) {
5487 arg.n_ssids = req->n_ssids;
5488 for (i = 0; i < arg.n_ssids; i++) {
5489 arg.ssids[i].len = req->ssids[i].ssid_len;
5490 arg.ssids[i].ssid = req->ssids[i].ssid;
5491 }
Michal Kaziordcd4a562013-07-31 10:55:12 +02005492 } else {
5493 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005494 }
5495
5496 if (req->n_channels) {
5497 arg.n_channels = req->n_channels;
5498 for (i = 0; i < arg.n_channels; i++)
5499 arg.channels[i] = req->channels[i]->center_freq;
5500 }
5501
5502 ret = ath10k_start_scan(ar, &arg);
5503 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005504 ath10k_warn(ar, "failed to start hw scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005505 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005506 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005507 spin_unlock_bh(&ar->data_lock);
5508 }
5509
Michal Kazior634349b2015-09-03 10:43:45 +02005510 /* Add a 200ms margin to account for event/command processing */
5511 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
5512 msecs_to_jiffies(arg.max_scan_time +
5513 200));
5514
Kalle Valo5e3dd152013-06-12 20:52:10 +03005515exit:
5516 mutex_unlock(&ar->conf_mutex);
5517 return ret;
5518}
5519
5520static void ath10k_cancel_hw_scan(struct ieee80211_hw *hw,
5521 struct ieee80211_vif *vif)
5522{
5523 struct ath10k *ar = hw->priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005524
5525 mutex_lock(&ar->conf_mutex);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005526 ath10k_scan_abort(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005527 mutex_unlock(&ar->conf_mutex);
Michal Kazior4eb2e162014-10-28 10:23:09 +01005528
5529 cancel_delayed_work_sync(&ar->scan.timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005530}
5531
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005532static void ath10k_set_key_h_def_keyidx(struct ath10k *ar,
5533 struct ath10k_vif *arvif,
5534 enum set_key_cmd cmd,
5535 struct ieee80211_key_conf *key)
5536{
5537 u32 vdev_param = arvif->ar->wmi.vdev_param->def_keyid;
5538 int ret;
5539
5540 /* 10.1 firmware branch requires default key index to be set to group
5541 * key index after installing it. Otherwise FW/HW Txes corrupted
5542 * frames with multi-vif APs. This is not required for main firmware
5543 * branch (e.g. 636).
5544 *
Michal Kazior8461baf2015-04-10 13:23:22 +00005545 * This is also needed for 636 fw for IBSS-RSN to work more reliably.
5546 *
5547 * FIXME: It remains unknown if this is required for multi-vif STA
5548 * interfaces on 10.1.
5549 */
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005550
Michal Kazior8461baf2015-04-10 13:23:22 +00005551 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
5552 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005553 return;
5554
5555 if (key->cipher == WLAN_CIPHER_SUITE_WEP40)
5556 return;
5557
5558 if (key->cipher == WLAN_CIPHER_SUITE_WEP104)
5559 return;
5560
5561 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
5562 return;
5563
5564 if (cmd != SET_KEY)
5565 return;
5566
5567 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5568 key->keyidx);
5569 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005570 ath10k_warn(ar, "failed to set vdev %i group key as default key: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005571 arvif->vdev_id, ret);
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005572}
5573
Kalle Valo5e3dd152013-06-12 20:52:10 +03005574static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
5575 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
5576 struct ieee80211_key_conf *key)
5577{
5578 struct ath10k *ar = hw->priv;
5579 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5580 struct ath10k_peer *peer;
5581 const u8 *peer_addr;
5582 bool is_wep = key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
5583 key->cipher == WLAN_CIPHER_SUITE_WEP104;
5584 int ret = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00005585 int ret2;
Michal Kazior370e5672015-02-18 14:02:26 +01005586 u32 flags = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00005587 u32 flags2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005588
Bartosz Markowskid7131c02015-03-10 14:32:19 +01005589 /* this one needs to be done in software */
5590 if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC)
5591 return 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005592
David Liuccec9032015-07-24 20:25:32 +03005593 if (arvif->nohwcrypt)
5594 return 1;
5595
Kalle Valo5e3dd152013-06-12 20:52:10 +03005596 if (key->keyidx > WMI_MAX_KEY_INDEX)
5597 return -ENOSPC;
5598
5599 mutex_lock(&ar->conf_mutex);
5600
5601 if (sta)
5602 peer_addr = sta->addr;
5603 else if (arvif->vdev_type == WMI_VDEV_TYPE_STA)
5604 peer_addr = vif->bss_conf.bssid;
5605 else
5606 peer_addr = vif->addr;
5607
5608 key->hw_key_idx = key->keyidx;
5609
Michal Kazior7c8cc7e2015-04-01 22:53:19 +03005610 if (is_wep) {
5611 if (cmd == SET_KEY)
5612 arvif->wep_keys[key->keyidx] = key;
5613 else
5614 arvif->wep_keys[key->keyidx] = NULL;
5615 }
5616
Kalle Valo5e3dd152013-06-12 20:52:10 +03005617 /* the peer should not disappear in mid-way (unless FW goes awry) since
5618 * we already hold conf_mutex. we just make sure its there now. */
5619 spin_lock_bh(&ar->data_lock);
5620 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
5621 spin_unlock_bh(&ar->data_lock);
5622
5623 if (!peer) {
5624 if (cmd == SET_KEY) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005625 ath10k_warn(ar, "failed to install key for non-existent peer %pM\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03005626 peer_addr);
5627 ret = -EOPNOTSUPP;
5628 goto exit;
5629 } else {
5630 /* if the peer doesn't exist there is no key to disable
5631 * anymore */
5632 goto exit;
5633 }
5634 }
5635
Michal Kazior7cc45732015-03-09 14:24:17 +01005636 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
5637 flags |= WMI_KEY_PAIRWISE;
5638 else
5639 flags |= WMI_KEY_GROUP;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005640
Kalle Valo5e3dd152013-06-12 20:52:10 +03005641 if (is_wep) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005642 if (cmd == DISABLE_KEY)
5643 ath10k_clear_vdev_key(arvif, key);
Michal Kazior370e5672015-02-18 14:02:26 +01005644
Michal Kaziorad325cb2015-02-18 14:02:27 +01005645 /* When WEP keys are uploaded it's possible that there are
5646 * stations associated already (e.g. when merging) without any
5647 * keys. Static WEP needs an explicit per-peer key upload.
5648 */
5649 if (vif->type == NL80211_IFTYPE_ADHOC &&
5650 cmd == SET_KEY)
5651 ath10k_mac_vif_update_wep_key(arvif, key);
5652
Michal Kazior370e5672015-02-18 14:02:26 +01005653 /* 802.1x never sets the def_wep_key_idx so each set_key()
5654 * call changes default tx key.
5655 *
5656 * Static WEP sets def_wep_key_idx via .set_default_unicast_key
5657 * after first set_key().
5658 */
5659 if (cmd == SET_KEY && arvif->def_wep_key_idx == -1)
5660 flags |= WMI_KEY_TX_USAGE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005661 }
5662
Michal Kazior370e5672015-02-18 14:02:26 +01005663 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005664 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03005665 WARN_ON(ret > 0);
Michal Kazior7aa7a722014-08-25 12:09:38 +02005666 ath10k_warn(ar, "failed to install key for vdev %i peer %pM: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005667 arvif->vdev_id, peer_addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005668 goto exit;
5669 }
5670
Michal Kazior29a10002015-04-10 13:05:58 +00005671 /* mac80211 sets static WEP keys as groupwise while firmware requires
5672 * them to be installed twice as both pairwise and groupwise.
5673 */
5674 if (is_wep && !sta && vif->type == NL80211_IFTYPE_STATION) {
5675 flags2 = flags;
5676 flags2 &= ~WMI_KEY_GROUP;
5677 flags2 |= WMI_KEY_PAIRWISE;
5678
5679 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags2);
5680 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03005681 WARN_ON(ret > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00005682 ath10k_warn(ar, "failed to install (ucast) key for vdev %i peer %pM: %d\n",
5683 arvif->vdev_id, peer_addr, ret);
5684 ret2 = ath10k_install_key(arvif, key, DISABLE_KEY,
5685 peer_addr, flags);
David Liuccec9032015-07-24 20:25:32 +03005686 if (ret2) {
5687 WARN_ON(ret2 > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00005688 ath10k_warn(ar, "failed to disable (mcast) key for vdev %i peer %pM: %d\n",
5689 arvif->vdev_id, peer_addr, ret2);
David Liuccec9032015-07-24 20:25:32 +03005690 }
Michal Kazior29a10002015-04-10 13:05:58 +00005691 goto exit;
5692 }
5693 }
5694
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005695 ath10k_set_key_h_def_keyidx(ar, arvif, cmd, key);
5696
Kalle Valo5e3dd152013-06-12 20:52:10 +03005697 spin_lock_bh(&ar->data_lock);
5698 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
5699 if (peer && cmd == SET_KEY)
5700 peer->keys[key->keyidx] = key;
5701 else if (peer && cmd == DISABLE_KEY)
5702 peer->keys[key->keyidx] = NULL;
5703 else if (peer == NULL)
5704 /* impossible unless FW goes crazy */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005705 ath10k_warn(ar, "Peer %pM disappeared!\n", peer_addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005706 spin_unlock_bh(&ar->data_lock);
5707
5708exit:
5709 mutex_unlock(&ar->conf_mutex);
5710 return ret;
5711}
5712
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005713static void ath10k_set_default_unicast_key(struct ieee80211_hw *hw,
5714 struct ieee80211_vif *vif,
5715 int keyidx)
5716{
5717 struct ath10k *ar = hw->priv;
5718 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5719 int ret;
5720
5721 mutex_lock(&arvif->ar->conf_mutex);
5722
5723 if (arvif->ar->state != ATH10K_STATE_ON)
5724 goto unlock;
5725
5726 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n",
5727 arvif->vdev_id, keyidx);
5728
5729 ret = ath10k_wmi_vdev_set_param(arvif->ar,
5730 arvif->vdev_id,
5731 arvif->ar->wmi.vdev_param->def_keyid,
5732 keyidx);
5733
5734 if (ret) {
5735 ath10k_warn(ar, "failed to update wep key index for vdev %d: %d\n",
5736 arvif->vdev_id,
5737 ret);
5738 goto unlock;
5739 }
5740
5741 arvif->def_wep_key_idx = keyidx;
Michal Kazior370e5672015-02-18 14:02:26 +01005742
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005743unlock:
5744 mutex_unlock(&arvif->ar->conf_mutex);
5745}
5746
Michal Kazior9797feb2014-02-14 14:49:48 +01005747static void ath10k_sta_rc_update_wk(struct work_struct *wk)
5748{
5749 struct ath10k *ar;
5750 struct ath10k_vif *arvif;
5751 struct ath10k_sta *arsta;
5752 struct ieee80211_sta *sta;
Michal Kazior45c9abc2015-04-21 20:42:58 +03005753 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02005754 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03005755 const u8 *ht_mcs_mask;
5756 const u16 *vht_mcs_mask;
Michal Kazior9797feb2014-02-14 14:49:48 +01005757 u32 changed, bw, nss, smps;
5758 int err;
5759
5760 arsta = container_of(wk, struct ath10k_sta, update_wk);
5761 sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);
5762 arvif = arsta->arvif;
5763 ar = arvif->ar;
5764
Michal Kazior45c9abc2015-04-21 20:42:58 +03005765 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
5766 return;
5767
5768 band = def.chan->band;
5769 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
5770 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
5771
Michal Kazior9797feb2014-02-14 14:49:48 +01005772 spin_lock_bh(&ar->data_lock);
5773
5774 changed = arsta->changed;
5775 arsta->changed = 0;
5776
5777 bw = arsta->bw;
5778 nss = arsta->nss;
5779 smps = arsta->smps;
5780
5781 spin_unlock_bh(&ar->data_lock);
5782
5783 mutex_lock(&ar->conf_mutex);
5784
Michal Kazior45c9abc2015-04-21 20:42:58 +03005785 nss = max_t(u32, 1, nss);
5786 nss = min(nss, max(ath10k_mac_max_ht_nss(ht_mcs_mask),
5787 ath10k_mac_max_vht_nss(vht_mcs_mask)));
5788
Michal Kazior9797feb2014-02-14 14:49:48 +01005789 if (changed & IEEE80211_RC_BW_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005790 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM peer bw %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005791 sta->addr, bw);
5792
5793 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5794 WMI_PEER_CHAN_WIDTH, bw);
5795 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005796 ath10k_warn(ar, "failed to update STA %pM peer bw %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005797 sta->addr, bw, err);
5798 }
5799
5800 if (changed & IEEE80211_RC_NSS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005801 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM nss %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005802 sta->addr, nss);
5803
5804 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5805 WMI_PEER_NSS, nss);
5806 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005807 ath10k_warn(ar, "failed to update STA %pM nss %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005808 sta->addr, nss, err);
5809 }
5810
5811 if (changed & IEEE80211_RC_SMPS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005812 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM smps %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005813 sta->addr, smps);
5814
5815 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5816 WMI_PEER_SMPS_STATE, smps);
5817 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005818 ath10k_warn(ar, "failed to update STA %pM smps %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005819 sta->addr, smps, err);
5820 }
5821
Karthikeyan Periyasamy237b5a32018-03-27 11:25:29 +03005822 if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) {
5823 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005824 sta->addr);
5825
Michal Kazior590922a2014-10-21 10:10:29 +03005826 err = ath10k_station_assoc(ar, arvif->vif, sta, true);
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005827 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005828 ath10k_warn(ar, "failed to reassociate station: %pM\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005829 sta->addr);
5830 }
5831
Michal Kazior9797feb2014-02-14 14:49:48 +01005832 mutex_unlock(&ar->conf_mutex);
5833}
5834
Marek Puzyniak7c354242015-03-30 09:51:52 +03005835static int ath10k_mac_inc_num_stations(struct ath10k_vif *arvif,
5836 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005837{
5838 struct ath10k *ar = arvif->ar;
5839
5840 lockdep_assert_held(&ar->conf_mutex);
5841
Marek Puzyniak7c354242015-03-30 09:51:52 +03005842 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005843 return 0;
5844
5845 if (ar->num_stations >= ar->max_num_stations)
5846 return -ENOBUFS;
5847
5848 ar->num_stations++;
5849
5850 return 0;
5851}
5852
Marek Puzyniak7c354242015-03-30 09:51:52 +03005853static void ath10k_mac_dec_num_stations(struct ath10k_vif *arvif,
5854 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005855{
5856 struct ath10k *ar = arvif->ar;
5857
5858 lockdep_assert_held(&ar->conf_mutex);
5859
Marek Puzyniak7c354242015-03-30 09:51:52 +03005860 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005861 return;
5862
5863 ar->num_stations--;
5864}
5865
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005866struct ath10k_mac_tdls_iter_data {
5867 u32 num_tdls_stations;
5868 struct ieee80211_vif *curr_vif;
5869};
5870
5871static void ath10k_mac_tdls_vif_stations_count_iter(void *data,
5872 struct ieee80211_sta *sta)
5873{
5874 struct ath10k_mac_tdls_iter_data *iter_data = data;
5875 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
5876 struct ieee80211_vif *sta_vif = arsta->arvif->vif;
5877
5878 if (sta->tdls && sta_vif == iter_data->curr_vif)
5879 iter_data->num_tdls_stations++;
5880}
5881
5882static int ath10k_mac_tdls_vif_stations_count(struct ieee80211_hw *hw,
5883 struct ieee80211_vif *vif)
5884{
5885 struct ath10k_mac_tdls_iter_data data = {};
5886
5887 data.curr_vif = vif;
5888
5889 ieee80211_iterate_stations_atomic(hw,
5890 ath10k_mac_tdls_vif_stations_count_iter,
5891 &data);
5892 return data.num_tdls_stations;
5893}
5894
5895static void ath10k_mac_tdls_vifs_count_iter(void *data, u8 *mac,
5896 struct ieee80211_vif *vif)
5897{
5898 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5899 int *num_tdls_vifs = data;
5900
5901 if (vif->type != NL80211_IFTYPE_STATION)
5902 return;
5903
5904 if (ath10k_mac_tdls_vif_stations_count(arvif->ar->hw, vif) > 0)
5905 (*num_tdls_vifs)++;
5906}
5907
5908static int ath10k_mac_tdls_vifs_count(struct ieee80211_hw *hw)
5909{
5910 int num_tdls_vifs = 0;
5911
5912 ieee80211_iterate_active_interfaces_atomic(hw,
5913 IEEE80211_IFACE_ITER_NORMAL,
5914 ath10k_mac_tdls_vifs_count_iter,
5915 &num_tdls_vifs);
5916 return num_tdls_vifs;
5917}
5918
Kalle Valo5e3dd152013-06-12 20:52:10 +03005919static int ath10k_sta_state(struct ieee80211_hw *hw,
5920 struct ieee80211_vif *vif,
5921 struct ieee80211_sta *sta,
5922 enum ieee80211_sta_state old_state,
5923 enum ieee80211_sta_state new_state)
5924{
5925 struct ath10k *ar = hw->priv;
5926 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01005927 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02005928 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005929 int ret = 0;
Michal Kazior69427262016-03-06 16:14:30 +02005930 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005931
Michal Kazior76f90022014-02-25 09:29:57 +02005932 if (old_state == IEEE80211_STA_NOTEXIST &&
5933 new_state == IEEE80211_STA_NONE) {
5934 memset(arsta, 0, sizeof(*arsta));
5935 arsta->arvif = arvif;
5936 INIT_WORK(&arsta->update_wk, ath10k_sta_rc_update_wk);
Michal Kazior29946872016-03-06 16:14:34 +02005937
5938 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
5939 ath10k_mac_txq_init(sta->txq[i]);
Michal Kazior76f90022014-02-25 09:29:57 +02005940 }
5941
Michal Kazior9797feb2014-02-14 14:49:48 +01005942 /* cancel must be done outside the mutex to avoid deadlock */
5943 if ((old_state == IEEE80211_STA_NONE &&
5944 new_state == IEEE80211_STA_NOTEXIST))
5945 cancel_work_sync(&arsta->update_wk);
5946
Kalle Valo5e3dd152013-06-12 20:52:10 +03005947 mutex_lock(&ar->conf_mutex);
5948
5949 if (old_state == IEEE80211_STA_NOTEXIST &&
Michal Kazior077efc82014-10-21 10:10:29 +03005950 new_state == IEEE80211_STA_NONE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005951 /*
5952 * New station addition.
5953 */
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005954 enum wmi_peer_type peer_type = WMI_PEER_TYPE_DEFAULT;
5955 u32 num_tdls_stations;
5956 u32 num_tdls_vifs;
5957
Michal Kaziorcfd10612014-11-25 15:16:05 +01005958 ath10k_dbg(ar, ATH10K_DBG_MAC,
5959 "mac vdev %d peer create %pM (new sta) sta %d / %d peer %d / %d\n",
5960 arvif->vdev_id, sta->addr,
5961 ar->num_stations + 1, ar->max_num_stations,
5962 ar->num_peers + 1, ar->max_num_peers);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005963
Marek Puzyniak7c354242015-03-30 09:51:52 +03005964 ret = ath10k_mac_inc_num_stations(arvif, sta);
Michal Kaziorcfd10612014-11-25 15:16:05 +01005965 if (ret) {
5966 ath10k_warn(ar, "refusing to associate station: too many connected already (%d)\n",
5967 ar->max_num_stations);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005968 goto exit;
5969 }
5970
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005971 if (sta->tdls)
5972 peer_type = WMI_PEER_TYPE_TDLS;
5973
Michal Kazior69427262016-03-06 16:14:30 +02005974 ret = ath10k_peer_create(ar, vif, sta, arvif->vdev_id,
5975 sta->addr, peer_type);
Michal Kaziora52c0282014-11-25 15:16:03 +01005976 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005977 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 -08005978 sta->addr, arvif->vdev_id, ret);
Marek Puzyniak7c354242015-03-30 09:51:52 +03005979 ath10k_mac_dec_num_stations(arvif, sta);
Michal Kaziora52c0282014-11-25 15:16:03 +01005980 goto exit;
5981 }
Michal Kazior077efc82014-10-21 10:10:29 +03005982
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02005983 spin_lock_bh(&ar->data_lock);
5984
5985 peer = ath10k_peer_find(ar, arvif->vdev_id, sta->addr);
5986 if (!peer) {
5987 ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",
5988 vif->addr, arvif->vdev_id);
5989 spin_unlock_bh(&ar->data_lock);
5990 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
5991 ath10k_mac_dec_num_stations(arvif, sta);
5992 ret = -ENOENT;
5993 goto exit;
5994 }
5995
5996 arsta->peer_id = find_first_bit(peer->peer_ids,
5997 ATH10K_MAX_NUM_PEER_IDS);
5998
5999 spin_unlock_bh(&ar->data_lock);
6000
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006001 if (!sta->tdls)
6002 goto exit;
Michal Kazior077efc82014-10-21 10:10:29 +03006003
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006004 num_tdls_stations = ath10k_mac_tdls_vif_stations_count(hw, vif);
6005 num_tdls_vifs = ath10k_mac_tdls_vifs_count(hw);
6006
6007 if (num_tdls_vifs >= ar->max_num_tdls_vdevs &&
6008 num_tdls_stations == 0) {
6009 ath10k_warn(ar, "vdev %i exceeded maximum number of tdls vdevs %i\n",
6010 arvif->vdev_id, ar->max_num_tdls_vdevs);
6011 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6012 ath10k_mac_dec_num_stations(arvif, sta);
6013 ret = -ENOBUFS;
6014 goto exit;
6015 }
6016
6017 if (num_tdls_stations == 0) {
6018 /* This is the first tdls peer in current vif */
6019 enum wmi_tdls_state state = WMI_TDLS_ENABLE_ACTIVE;
6020
6021 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
6022 state);
Michal Kazior077efc82014-10-21 10:10:29 +03006023 if (ret) {
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006024 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
Michal Kazior077efc82014-10-21 10:10:29 +03006025 arvif->vdev_id, ret);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006026 ath10k_peer_delete(ar, arvif->vdev_id,
6027 sta->addr);
6028 ath10k_mac_dec_num_stations(arvif, sta);
Michal Kazior077efc82014-10-21 10:10:29 +03006029 goto exit;
6030 }
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006031 }
Michal Kazior077efc82014-10-21 10:10:29 +03006032
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006033 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
6034 WMI_TDLS_PEER_STATE_PEERING);
6035 if (ret) {
6036 ath10k_warn(ar,
6037 "failed to update tdls peer %pM for vdev %d when adding a new sta: %i\n",
6038 sta->addr, arvif->vdev_id, ret);
6039 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6040 ath10k_mac_dec_num_stations(arvif, sta);
6041
6042 if (num_tdls_stations != 0)
6043 goto exit;
6044 ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
6045 WMI_TDLS_DISABLE);
Michal Kazior077efc82014-10-21 10:10:29 +03006046 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006047 } else if ((old_state == IEEE80211_STA_NONE &&
6048 new_state == IEEE80211_STA_NOTEXIST)) {
6049 /*
6050 * Existing station deletion.
6051 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006052 ath10k_dbg(ar, ATH10K_DBG_MAC,
Ben Greear30404202016-08-18 18:26:35 -07006053 "mac vdev %d peer delete %pM sta %pK (sta gone)\n",
6054 arvif->vdev_id, sta->addr, sta);
Michal Kazior077efc82014-10-21 10:10:29 +03006055
Manikanta Pubbisetty10318872017-11-06 13:39:31 +05306056 if (sta->tdls) {
6057 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id,
6058 sta,
6059 WMI_TDLS_PEER_STATE_TEARDOWN);
6060 if (ret)
6061 ath10k_warn(ar, "failed to update tdls peer state for %pM state %d: %i\n",
6062 sta->addr,
6063 WMI_TDLS_PEER_STATE_TEARDOWN, ret);
6064 }
6065
Kalle Valo5e3dd152013-06-12 20:52:10 +03006066 ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6067 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006068 ath10k_warn(ar, "failed to delete peer %pM for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006069 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006070
Marek Puzyniak7c354242015-03-30 09:51:52 +03006071 ath10k_mac_dec_num_stations(arvif, sta);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006072
Michal Kazior69427262016-03-06 16:14:30 +02006073 spin_lock_bh(&ar->data_lock);
6074 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
6075 peer = ar->peer_map[i];
6076 if (!peer)
6077 continue;
6078
6079 if (peer->sta == sta) {
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05306080 ath10k_warn(ar, "found sta peer %pM (ptr %pK id %d) entry on vdev %i after it was supposedly removed\n",
Ben Greeard0eeafa2016-06-30 15:23:59 +03006081 sta->addr, peer, i, arvif->vdev_id);
Michal Kazior69427262016-03-06 16:14:30 +02006082 peer->sta = NULL;
Ben Greeard0eeafa2016-06-30 15:23:59 +03006083
6084 /* Clean up the peer object as well since we
6085 * must have failed to do this above.
6086 */
6087 list_del(&peer->list);
6088 ar->peer_map[i] = NULL;
6089 kfree(peer);
6090 ar->num_peers--;
Michal Kazior69427262016-03-06 16:14:30 +02006091 }
6092 }
6093 spin_unlock_bh(&ar->data_lock);
6094
Michal Kazior29946872016-03-06 16:14:34 +02006095 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
6096 ath10k_mac_txq_unref(ar, sta->txq[i]);
6097
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006098 if (!sta->tdls)
6099 goto exit;
6100
6101 if (ath10k_mac_tdls_vif_stations_count(hw, vif))
6102 goto exit;
6103
6104 /* This was the last tdls peer in current vif */
6105 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
6106 WMI_TDLS_DISABLE);
6107 if (ret) {
6108 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
6109 arvif->vdev_id, ret);
6110 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006111 } else if (old_state == IEEE80211_STA_AUTH &&
6112 new_state == IEEE80211_STA_ASSOC &&
6113 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04006114 vif->type == NL80211_IFTYPE_MESH_POINT ||
Kalle Valo5e3dd152013-06-12 20:52:10 +03006115 vif->type == NL80211_IFTYPE_ADHOC)) {
6116 /*
6117 * New association.
6118 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006119 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM associated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03006120 sta->addr);
6121
Michal Kazior590922a2014-10-21 10:10:29 +03006122 ret = ath10k_station_assoc(ar, vif, sta, false);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006123 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006124 ath10k_warn(ar, "failed to associate station %pM for vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006125 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006126 } else if (old_state == IEEE80211_STA_ASSOC &&
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006127 new_state == IEEE80211_STA_AUTHORIZED &&
6128 sta->tdls) {
6129 /*
6130 * Tdls station authorized.
6131 */
6132 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac tdls sta %pM authorized\n",
6133 sta->addr);
6134
6135 ret = ath10k_station_assoc(ar, vif, sta, false);
6136 if (ret) {
6137 ath10k_warn(ar, "failed to associate tdls station %pM for vdev %i: %i\n",
6138 sta->addr, arvif->vdev_id, ret);
6139 goto exit;
6140 }
6141
6142 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
6143 WMI_TDLS_PEER_STATE_CONNECTED);
6144 if (ret)
6145 ath10k_warn(ar, "failed to update tdls peer %pM for vdev %i: %i\n",
6146 sta->addr, arvif->vdev_id, ret);
6147 } else if (old_state == IEEE80211_STA_ASSOC &&
6148 new_state == IEEE80211_STA_AUTH &&
6149 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04006150 vif->type == NL80211_IFTYPE_MESH_POINT ||
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006151 vif->type == NL80211_IFTYPE_ADHOC)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03006152 /*
6153 * Disassociation.
6154 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006155 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM disassociated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03006156 sta->addr);
6157
Michal Kazior590922a2014-10-21 10:10:29 +03006158 ret = ath10k_station_disassoc(ar, vif, sta);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006159 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006160 ath10k_warn(ar, "failed to disassociate station: %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006161 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006162 }
Bartosz Markowski0e759f32014-01-02 14:38:33 +01006163exit:
Kalle Valo5e3dd152013-06-12 20:52:10 +03006164 mutex_unlock(&ar->conf_mutex);
6165 return ret;
6166}
6167
6168static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,
Kalle Valo5b07e072014-09-14 12:50:06 +03006169 u16 ac, bool enable)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006170{
6171 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorb0e56152015-01-24 12:14:52 +02006172 struct wmi_sta_uapsd_auto_trig_arg arg = {};
6173 u32 prio = 0, acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006174 u32 value = 0;
6175 int ret = 0;
6176
Michal Kazior548db542013-07-05 16:15:15 +03006177 lockdep_assert_held(&ar->conf_mutex);
6178
Kalle Valo5e3dd152013-06-12 20:52:10 +03006179 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
6180 return 0;
6181
6182 switch (ac) {
6183 case IEEE80211_AC_VO:
6184 value = WMI_STA_PS_UAPSD_AC3_DELIVERY_EN |
6185 WMI_STA_PS_UAPSD_AC3_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006186 prio = 7;
6187 acc = 3;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006188 break;
6189 case IEEE80211_AC_VI:
6190 value = WMI_STA_PS_UAPSD_AC2_DELIVERY_EN |
6191 WMI_STA_PS_UAPSD_AC2_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006192 prio = 5;
6193 acc = 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006194 break;
6195 case IEEE80211_AC_BE:
6196 value = WMI_STA_PS_UAPSD_AC1_DELIVERY_EN |
6197 WMI_STA_PS_UAPSD_AC1_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006198 prio = 2;
6199 acc = 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006200 break;
6201 case IEEE80211_AC_BK:
6202 value = WMI_STA_PS_UAPSD_AC0_DELIVERY_EN |
6203 WMI_STA_PS_UAPSD_AC0_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006204 prio = 0;
6205 acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006206 break;
6207 }
6208
6209 if (enable)
6210 arvif->u.sta.uapsd |= value;
6211 else
6212 arvif->u.sta.uapsd &= ~value;
6213
6214 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
6215 WMI_STA_PS_PARAM_UAPSD,
6216 arvif->u.sta.uapsd);
6217 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006218 ath10k_warn(ar, "failed to set uapsd params: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006219 goto exit;
6220 }
6221
6222 if (arvif->u.sta.uapsd)
6223 value = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD;
6224 else
6225 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
6226
6227 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
6228 WMI_STA_PS_PARAM_RX_WAKE_POLICY,
6229 value);
6230 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006231 ath10k_warn(ar, "failed to set rx wake param: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006232
Michal Kazior9f9b5742014-12-12 12:41:36 +01006233 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
6234 if (ret) {
6235 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
6236 arvif->vdev_id, ret);
6237 return ret;
6238 }
6239
6240 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
6241 if (ret) {
6242 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
6243 arvif->vdev_id, ret);
6244 return ret;
6245 }
6246
Michal Kaziorb0e56152015-01-24 12:14:52 +02006247 if (test_bit(WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, ar->wmi.svc_map) ||
6248 test_bit(WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, ar->wmi.svc_map)) {
6249 /* Only userspace can make an educated decision when to send
6250 * trigger frame. The following effectively disables u-UAPSD
6251 * autotrigger in firmware (which is enabled by default
6252 * provided the autotrigger service is available).
6253 */
6254
6255 arg.wmm_ac = acc;
6256 arg.user_priority = prio;
6257 arg.service_interval = 0;
6258 arg.suspend_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
6259 arg.delay_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
6260
6261 ret = ath10k_wmi_vdev_sta_uapsd(ar, arvif->vdev_id,
6262 arvif->bssid, &arg, 1);
6263 if (ret) {
6264 ath10k_warn(ar, "failed to set uapsd auto trigger %d\n",
6265 ret);
6266 return ret;
6267 }
6268 }
6269
Kalle Valo5e3dd152013-06-12 20:52:10 +03006270exit:
6271 return ret;
6272}
6273
6274static int ath10k_conf_tx(struct ieee80211_hw *hw,
6275 struct ieee80211_vif *vif, u16 ac,
6276 const struct ieee80211_tx_queue_params *params)
6277{
6278 struct ath10k *ar = hw->priv;
Michal Kazior5e752e42015-01-19 09:53:41 +01006279 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006280 struct wmi_wmm_params_arg *p = NULL;
6281 int ret;
6282
6283 mutex_lock(&ar->conf_mutex);
6284
6285 switch (ac) {
6286 case IEEE80211_AC_VO:
Michal Kazior5e752e42015-01-19 09:53:41 +01006287 p = &arvif->wmm_params.ac_vo;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006288 break;
6289 case IEEE80211_AC_VI:
Michal Kazior5e752e42015-01-19 09:53:41 +01006290 p = &arvif->wmm_params.ac_vi;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006291 break;
6292 case IEEE80211_AC_BE:
Michal Kazior5e752e42015-01-19 09:53:41 +01006293 p = &arvif->wmm_params.ac_be;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006294 break;
6295 case IEEE80211_AC_BK:
Michal Kazior5e752e42015-01-19 09:53:41 +01006296 p = &arvif->wmm_params.ac_bk;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006297 break;
6298 }
6299
6300 if (WARN_ON(!p)) {
6301 ret = -EINVAL;
6302 goto exit;
6303 }
6304
6305 p->cwmin = params->cw_min;
6306 p->cwmax = params->cw_max;
6307 p->aifs = params->aifs;
6308
6309 /*
6310 * The channel time duration programmed in the HW is in absolute
6311 * microseconds, while mac80211 gives the txop in units of
6312 * 32 microseconds.
6313 */
6314 p->txop = params->txop * 32;
6315
Michal Kazior7fc979a2015-01-28 09:57:28 +02006316 if (ar->wmi.ops->gen_vdev_wmm_conf) {
6317 ret = ath10k_wmi_vdev_wmm_conf(ar, arvif->vdev_id,
6318 &arvif->wmm_params);
6319 if (ret) {
6320 ath10k_warn(ar, "failed to set vdev wmm params on vdev %i: %d\n",
6321 arvif->vdev_id, ret);
6322 goto exit;
6323 }
6324 } else {
6325 /* This won't work well with multi-interface cases but it's
6326 * better than nothing.
6327 */
6328 ret = ath10k_wmi_pdev_set_wmm_params(ar, &arvif->wmm_params);
6329 if (ret) {
6330 ath10k_warn(ar, "failed to set wmm params: %d\n", ret);
6331 goto exit;
6332 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006333 }
6334
6335 ret = ath10k_conf_tx_uapsd(ar, vif, ac, params->uapsd);
6336 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006337 ath10k_warn(ar, "failed to set sta uapsd: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006338
6339exit:
6340 mutex_unlock(&ar->conf_mutex);
6341 return ret;
6342}
6343
Kalle Valo14e105c2016-04-13 14:13:21 +03006344#define ATH10K_ROC_TIMEOUT_HZ (2 * HZ)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006345
6346static int ath10k_remain_on_channel(struct ieee80211_hw *hw,
6347 struct ieee80211_vif *vif,
6348 struct ieee80211_channel *chan,
6349 int duration,
6350 enum ieee80211_roc_type type)
6351{
6352 struct ath10k *ar = hw->priv;
6353 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
6354 struct wmi_start_scan_arg arg;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006355 int ret = 0;
Michal Kaziorfcf98442015-03-31 11:03:47 +00006356 u32 scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006357
6358 mutex_lock(&ar->conf_mutex);
6359
6360 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006361 switch (ar->scan.state) {
6362 case ATH10K_SCAN_IDLE:
6363 reinit_completion(&ar->scan.started);
6364 reinit_completion(&ar->scan.completed);
6365 reinit_completion(&ar->scan.on_channel);
6366 ar->scan.state = ATH10K_SCAN_STARTING;
6367 ar->scan.is_roc = true;
6368 ar->scan.vdev_id = arvif->vdev_id;
6369 ar->scan.roc_freq = chan->center_freq;
Michal Kaziord710e752015-07-09 13:08:36 +02006370 ar->scan.roc_notify = true;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006371 ret = 0;
6372 break;
6373 case ATH10K_SCAN_STARTING:
6374 case ATH10K_SCAN_RUNNING:
6375 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03006376 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006377 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006378 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006379 spin_unlock_bh(&ar->data_lock);
6380
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006381 if (ret)
6382 goto exit;
6383
Michal Kaziorfcf98442015-03-31 11:03:47 +00006384 scan_time_msec = ar->hw->wiphy->max_remain_on_channel_duration * 2;
Michal Kaziordcca0bd2014-11-24 14:58:32 +01006385
Kalle Valo5e3dd152013-06-12 20:52:10 +03006386 memset(&arg, 0, sizeof(arg));
6387 ath10k_wmi_start_scan_init(ar, &arg);
6388 arg.vdev_id = arvif->vdev_id;
6389 arg.scan_id = ATH10K_SCAN_ID;
6390 arg.n_channels = 1;
6391 arg.channels[0] = chan->center_freq;
Michal Kaziorfcf98442015-03-31 11:03:47 +00006392 arg.dwell_time_active = scan_time_msec;
6393 arg.dwell_time_passive = scan_time_msec;
6394 arg.max_scan_time = scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006395 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
6396 arg.scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ;
Michal Kaziordbd3f9f2015-03-31 11:03:48 +00006397 arg.burst_duration_ms = duration;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006398
6399 ret = ath10k_start_scan(ar, &arg);
6400 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006401 ath10k_warn(ar, "failed to start roc scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006402 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006403 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006404 spin_unlock_bh(&ar->data_lock);
6405 goto exit;
6406 }
6407
Kalle Valo14e105c2016-04-13 14:13:21 +03006408 ret = wait_for_completion_timeout(&ar->scan.on_channel, 3 * HZ);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006409 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006410 ath10k_warn(ar, "failed to switch to channel for roc scan\n");
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006411
6412 ret = ath10k_scan_stop(ar);
6413 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006414 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006415
Kalle Valo5e3dd152013-06-12 20:52:10 +03006416 ret = -ETIMEDOUT;
6417 goto exit;
6418 }
6419
Michal Kaziorfcf98442015-03-31 11:03:47 +00006420 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
6421 msecs_to_jiffies(duration));
6422
Kalle Valo5e3dd152013-06-12 20:52:10 +03006423 ret = 0;
6424exit:
6425 mutex_unlock(&ar->conf_mutex);
6426 return ret;
6427}
6428
6429static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw)
6430{
6431 struct ath10k *ar = hw->priv;
6432
6433 mutex_lock(&ar->conf_mutex);
Michal Kaziord710e752015-07-09 13:08:36 +02006434
6435 spin_lock_bh(&ar->data_lock);
6436 ar->scan.roc_notify = false;
6437 spin_unlock_bh(&ar->data_lock);
6438
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006439 ath10k_scan_abort(ar);
Michal Kaziord710e752015-07-09 13:08:36 +02006440
Kalle Valo5e3dd152013-06-12 20:52:10 +03006441 mutex_unlock(&ar->conf_mutex);
6442
Michal Kazior4eb2e162014-10-28 10:23:09 +01006443 cancel_delayed_work_sync(&ar->scan.timeout);
6444
Kalle Valo5e3dd152013-06-12 20:52:10 +03006445 return 0;
6446}
6447
6448/*
6449 * Both RTS and Fragmentation threshold are interface-specific
6450 * in ath10k, but device-specific in mac80211.
6451 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03006452
6453static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
6454{
Kalle Valo5e3dd152013-06-12 20:52:10 +03006455 struct ath10k *ar = hw->priv;
Michal Kaziorad088bf2013-10-16 15:44:46 +03006456 struct ath10k_vif *arvif;
6457 int ret = 0;
Michal Kazior548db542013-07-05 16:15:15 +03006458
Michal Kaziorad088bf2013-10-16 15:44:46 +03006459 mutex_lock(&ar->conf_mutex);
6460 list_for_each_entry(arvif, &ar->arvifs, list) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006461 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d rts threshold %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03006462 arvif->vdev_id, value);
Kalle Valo60c3daa2013-09-08 17:56:07 +03006463
Michal Kaziorad088bf2013-10-16 15:44:46 +03006464 ret = ath10k_mac_set_rts(arvif, value);
6465 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006466 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03006467 arvif->vdev_id, ret);
6468 break;
6469 }
6470 }
6471 mutex_unlock(&ar->conf_mutex);
6472
6473 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006474}
6475
Michal Kazior92092fe2015-08-03 11:16:43 +02006476static int ath10k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
6477{
6478 /* Even though there's a WMI enum for fragmentation threshold no known
6479 * firmware actually implements it. Moreover it is not possible to rely
6480 * frame fragmentation to mac80211 because firmware clears the "more
6481 * fragments" bit in frame control making it impossible for remote
6482 * devices to reassemble frames.
6483 *
6484 * Hence implement a dummy callback just to say fragmentation isn't
6485 * supported. This effectively prevents mac80211 from doing frame
6486 * fragmentation in software.
6487 */
6488 return -EOPNOTSUPP;
6489}
6490
Emmanuel Grumbach77be2c52014-03-27 11:30:29 +02006491static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
6492 u32 queues, bool drop)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006493{
6494 struct ath10k *ar = hw->priv;
Michal Kazioraffd3212013-07-16 09:54:35 +02006495 bool skip;
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006496 long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006497
6498 /* mac80211 doesn't care if we really xmit queued frames or not
6499 * we'll collect those frames either way if we stop/delete vdevs */
6500 if (drop)
6501 return;
6502
Michal Kazior548db542013-07-05 16:15:15 +03006503 mutex_lock(&ar->conf_mutex);
6504
Michal Kazioraffd3212013-07-16 09:54:35 +02006505 if (ar->state == ATH10K_STATE_WEDGED)
6506 goto skip;
6507
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006508 time_left = wait_event_timeout(ar->htt.empty_tx_wq, ({
Kalle Valo5e3dd152013-06-12 20:52:10 +03006509 bool empty;
Michal Kazioraffd3212013-07-16 09:54:35 +02006510
Michal Kazioredb82362013-07-05 16:15:14 +03006511 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior0945baf2013-09-18 14:43:18 +02006512 empty = (ar->htt.num_pending_tx == 0);
Michal Kazioredb82362013-07-05 16:15:14 +03006513 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazioraffd3212013-07-16 09:54:35 +02006514
Michal Kazior7962b0d2014-10-28 10:34:38 +01006515 skip = (ar->state == ATH10K_STATE_WEDGED) ||
6516 test_bit(ATH10K_FLAG_CRASH_FLUSH,
6517 &ar->dev_flags);
Michal Kazioraffd3212013-07-16 09:54:35 +02006518
6519 (empty || skip);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006520 }), ATH10K_FLUSH_TIMEOUT_HZ);
Michal Kazioraffd3212013-07-16 09:54:35 +02006521
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006522 if (time_left == 0 || skip)
6523 ath10k_warn(ar, "failed to flush transmit queue (skip %i ar-state %i): %ld\n",
6524 skip, ar->state, time_left);
Michal Kazior548db542013-07-05 16:15:15 +03006525
Michal Kazioraffd3212013-07-16 09:54:35 +02006526skip:
Michal Kazior548db542013-07-05 16:15:15 +03006527 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006528}
6529
6530/* TODO: Implement this function properly
6531 * For now it is needed to reply to Probe Requests in IBSS mode.
6532 * Propably we need this information from FW.
6533 */
6534static int ath10k_tx_last_beacon(struct ieee80211_hw *hw)
6535{
6536 return 1;
6537}
6538
Eliad Pellercf2c92d2014-11-04 11:43:54 +02006539static void ath10k_reconfig_complete(struct ieee80211_hw *hw,
6540 enum ieee80211_reconfig_type reconfig_type)
Michal Kazioraffd3212013-07-16 09:54:35 +02006541{
6542 struct ath10k *ar = hw->priv;
6543
Eliad Pellercf2c92d2014-11-04 11:43:54 +02006544 if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)
6545 return;
6546
Michal Kazioraffd3212013-07-16 09:54:35 +02006547 mutex_lock(&ar->conf_mutex);
6548
6549 /* If device failed to restart it will be in a different state, e.g.
6550 * ATH10K_STATE_WEDGED */
6551 if (ar->state == ATH10K_STATE_RESTARTED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006552 ath10k_info(ar, "device successfully recovered\n");
Michal Kazioraffd3212013-07-16 09:54:35 +02006553 ar->state = ATH10K_STATE_ON;
Michal Kazior7962b0d2014-10-28 10:34:38 +01006554 ieee80211_wake_queues(ar->hw);
Michal Kazioraffd3212013-07-16 09:54:35 +02006555 }
6556
6557 mutex_unlock(&ar->conf_mutex);
6558}
6559
Rajkumar Manoharanfa7937e2016-04-27 16:23:22 +05306560static void
6561ath10k_mac_update_bss_chan_survey(struct ath10k *ar,
6562 struct ieee80211_channel *channel)
6563{
6564 int ret;
6565 enum wmi_bss_survey_req_type type = WMI_BSS_SURVEY_REQ_TYPE_READ_CLEAR;
6566
6567 lockdep_assert_held(&ar->conf_mutex);
6568
6569 if (!test_bit(WMI_SERVICE_BSS_CHANNEL_INFO_64, ar->wmi.svc_map) ||
6570 (ar->rx_channel != channel))
6571 return;
6572
6573 if (ar->scan.state != ATH10K_SCAN_IDLE) {
6574 ath10k_dbg(ar, ATH10K_DBG_MAC, "ignoring bss chan info request while scanning..\n");
6575 return;
6576 }
6577
6578 reinit_completion(&ar->bss_survey_done);
6579
6580 ret = ath10k_wmi_pdev_bss_chan_info_request(ar, type);
6581 if (ret) {
6582 ath10k_warn(ar, "failed to send pdev bss chan info request\n");
6583 return;
6584 }
6585
6586 ret = wait_for_completion_timeout(&ar->bss_survey_done, 3 * HZ);
6587 if (!ret) {
6588 ath10k_warn(ar, "bss channel survey timed out\n");
6589 return;
6590 }
6591}
6592
Michal Kazior2e1dea42013-07-31 10:32:40 +02006593static int ath10k_get_survey(struct ieee80211_hw *hw, int idx,
6594 struct survey_info *survey)
6595{
6596 struct ath10k *ar = hw->priv;
6597 struct ieee80211_supported_band *sband;
6598 struct survey_info *ar_survey = &ar->survey[idx];
6599 int ret = 0;
6600
6601 mutex_lock(&ar->conf_mutex);
6602
Johannes Berg57fbcce2016-04-12 15:56:15 +02006603 sband = hw->wiphy->bands[NL80211_BAND_2GHZ];
Michal Kazior2e1dea42013-07-31 10:32:40 +02006604 if (sband && idx >= sband->n_channels) {
6605 idx -= sband->n_channels;
6606 sband = NULL;
6607 }
6608
6609 if (!sband)
Johannes Berg57fbcce2016-04-12 15:56:15 +02006610 sband = hw->wiphy->bands[NL80211_BAND_5GHZ];
Michal Kazior2e1dea42013-07-31 10:32:40 +02006611
6612 if (!sband || idx >= sband->n_channels) {
6613 ret = -ENOENT;
6614 goto exit;
6615 }
6616
Ashok Raj Nagarajan77eb3d62016-09-02 10:59:53 +05306617 ath10k_mac_update_bss_chan_survey(ar, &sband->channels[idx]);
Rajkumar Manoharanfa7937e2016-04-27 16:23:22 +05306618
Michal Kazior2e1dea42013-07-31 10:32:40 +02006619 spin_lock_bh(&ar->data_lock);
6620 memcpy(survey, ar_survey, sizeof(*survey));
6621 spin_unlock_bh(&ar->data_lock);
6622
6623 survey->channel = &sband->channels[idx];
6624
Felix Fietkaufa1d4df2014-10-23 17:04:28 +03006625 if (ar->rx_channel == survey->channel)
6626 survey->filled |= SURVEY_INFO_IN_USE;
6627
Michal Kazior2e1dea42013-07-31 10:32:40 +02006628exit:
6629 mutex_unlock(&ar->conf_mutex);
6630 return ret;
6631}
6632
Michal Kazior3ae54222015-03-31 10:49:20 +00006633static bool
6634ath10k_mac_bitrate_mask_has_single_rate(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006635 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00006636 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006637{
Michal Kazior3ae54222015-03-31 10:49:20 +00006638 int num_rates = 0;
6639 int i;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006640
Michal Kazior3ae54222015-03-31 10:49:20 +00006641 num_rates += hweight32(mask->control[band].legacy);
6642
6643 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++)
6644 num_rates += hweight8(mask->control[band].ht_mcs[i]);
6645
6646 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++)
6647 num_rates += hweight16(mask->control[band].vht_mcs[i]);
6648
6649 return num_rates == 1;
6650}
6651
6652static bool
6653ath10k_mac_bitrate_mask_get_single_nss(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006654 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00006655 const struct cfg80211_bitrate_mask *mask,
6656 int *nss)
6657{
6658 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
6659 u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
6660 u8 ht_nss_mask = 0;
6661 u8 vht_nss_mask = 0;
6662 int i;
6663
6664 if (mask->control[band].legacy)
6665 return false;
6666
6667 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
6668 if (mask->control[band].ht_mcs[i] == 0)
6669 continue;
6670 else if (mask->control[band].ht_mcs[i] ==
6671 sband->ht_cap.mcs.rx_mask[i])
6672 ht_nss_mask |= BIT(i);
6673 else
6674 return false;
6675 }
6676
6677 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
6678 if (mask->control[band].vht_mcs[i] == 0)
6679 continue;
6680 else if (mask->control[band].vht_mcs[i] ==
6681 ath10k_mac_get_max_vht_mcs_map(vht_mcs_map, i))
6682 vht_nss_mask |= BIT(i);
6683 else
6684 return false;
6685 }
6686
6687 if (ht_nss_mask != vht_nss_mask)
6688 return false;
6689
6690 if (ht_nss_mask == 0)
6691 return false;
6692
6693 if (BIT(fls(ht_nss_mask)) - 1 != ht_nss_mask)
6694 return false;
6695
6696 *nss = fls(ht_nss_mask);
6697
6698 return true;
6699}
6700
6701static int
6702ath10k_mac_bitrate_mask_get_single_rate(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006703 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00006704 const struct cfg80211_bitrate_mask *mask,
6705 u8 *rate, u8 *nss)
6706{
6707 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
6708 int rate_idx;
6709 int i;
6710 u16 bitrate;
6711 u8 preamble;
6712 u8 hw_rate;
6713
6714 if (hweight32(mask->control[band].legacy) == 1) {
6715 rate_idx = ffs(mask->control[band].legacy) - 1;
6716
6717 hw_rate = sband->bitrates[rate_idx].hw_value;
6718 bitrate = sband->bitrates[rate_idx].bitrate;
6719
6720 if (ath10k_mac_bitrate_is_cck(bitrate))
6721 preamble = WMI_RATE_PREAMBLE_CCK;
6722 else
6723 preamble = WMI_RATE_PREAMBLE_OFDM;
6724
6725 *nss = 1;
6726 *rate = preamble << 6 |
6727 (*nss - 1) << 4 |
6728 hw_rate << 0;
6729
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006730 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006731 }
6732
Michal Kazior3ae54222015-03-31 10:49:20 +00006733 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
6734 if (hweight8(mask->control[band].ht_mcs[i]) == 1) {
6735 *nss = i + 1;
6736 *rate = WMI_RATE_PREAMBLE_HT << 6 |
6737 (*nss - 1) << 4 |
6738 (ffs(mask->control[band].ht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006739
Michal Kazior3ae54222015-03-31 10:49:20 +00006740 return 0;
6741 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006742 }
6743
Michal Kazior3ae54222015-03-31 10:49:20 +00006744 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
6745 if (hweight16(mask->control[band].vht_mcs[i]) == 1) {
6746 *nss = i + 1;
6747 *rate = WMI_RATE_PREAMBLE_VHT << 6 |
6748 (*nss - 1) << 4 |
6749 (ffs(mask->control[band].vht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006750
Michal Kazior3ae54222015-03-31 10:49:20 +00006751 return 0;
6752 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006753 }
6754
Michal Kazior3ae54222015-03-31 10:49:20 +00006755 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006756}
6757
Michal Kazior3ae54222015-03-31 10:49:20 +00006758static int ath10k_mac_set_fixed_rate_params(struct ath10k_vif *arvif,
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306759 u8 rate, u8 nss, u8 sgi, u8 ldpc)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006760{
6761 struct ath10k *ar = arvif->ar;
6762 u32 vdev_param;
Michal Kazior3ae54222015-03-31 10:49:20 +00006763 int ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006764
Michal Kazior3ae54222015-03-31 10:49:20 +00006765 lockdep_assert_held(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006766
Michal Kazior3ae54222015-03-31 10:49:20 +00006767 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac set fixed rate params vdev %i rate 0x%02hhx nss %hhu sgi %hhu\n",
6768 arvif->vdev_id, rate, nss, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006769
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006770 vdev_param = ar->wmi.vdev_param->fixed_rate;
Michal Kazior3ae54222015-03-31 10:49:20 +00006771 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, rate);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006772 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006773 ath10k_warn(ar, "failed to set fixed rate param 0x%02x: %d\n",
Michal Kazior3ae54222015-03-31 10:49:20 +00006774 rate, ret);
6775 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006776 }
6777
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006778 vdev_param = ar->wmi.vdev_param->nss;
Michal Kazior3ae54222015-03-31 10:49:20 +00006779 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, nss);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006780 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006781 ath10k_warn(ar, "failed to set nss param %d: %d\n", nss, ret);
6782 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006783 }
6784
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006785 vdev_param = ar->wmi.vdev_param->sgi;
Michal Kazior3ae54222015-03-31 10:49:20 +00006786 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006787 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006788 ath10k_warn(ar, "failed to set sgi param %d: %d\n", sgi, ret);
6789 return ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006790 }
6791
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306792 vdev_param = ar->wmi.vdev_param->ldpc;
6793 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, ldpc);
6794 if (ret) {
6795 ath10k_warn(ar, "failed to set ldpc param %d: %d\n", ldpc, ret);
6796 return ret;
6797 }
6798
Michal Kazior3ae54222015-03-31 10:49:20 +00006799 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006800}
6801
Michal Kazior45c9abc2015-04-21 20:42:58 +03006802static bool
6803ath10k_mac_can_set_bitrate_mask(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006804 enum nl80211_band band,
Michal Kazior45c9abc2015-04-21 20:42:58 +03006805 const struct cfg80211_bitrate_mask *mask)
6806{
6807 int i;
6808 u16 vht_mcs;
6809
6810 /* Due to firmware limitation in WMI_PEER_ASSOC_CMDID it is impossible
6811 * to express all VHT MCS rate masks. Effectively only the following
6812 * ranges can be used: none, 0-7, 0-8 and 0-9.
6813 */
6814 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
6815 vht_mcs = mask->control[band].vht_mcs[i];
6816
6817 switch (vht_mcs) {
6818 case 0:
6819 case BIT(8) - 1:
6820 case BIT(9) - 1:
6821 case BIT(10) - 1:
6822 break;
6823 default:
6824 ath10k_warn(ar, "refusing bitrate mask with missing 0-7 VHT MCS rates\n");
6825 return false;
6826 }
6827 }
6828
6829 return true;
6830}
6831
6832static void ath10k_mac_set_bitrate_mask_iter(void *data,
6833 struct ieee80211_sta *sta)
6834{
6835 struct ath10k_vif *arvif = data;
6836 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
6837 struct ath10k *ar = arvif->ar;
6838
6839 if (arsta->arvif != arvif)
6840 return;
6841
6842 spin_lock_bh(&ar->data_lock);
6843 arsta->changed |= IEEE80211_RC_SUPP_RATES_CHANGED;
6844 spin_unlock_bh(&ar->data_lock);
6845
6846 ieee80211_queue_work(ar->hw, &arsta->update_wk);
6847}
6848
Michal Kazior3ae54222015-03-31 10:49:20 +00006849static int ath10k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
6850 struct ieee80211_vif *vif,
6851 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006852{
6853 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006854 struct cfg80211_chan_def def;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006855 struct ath10k *ar = arvif->ar;
Johannes Berg57fbcce2016-04-12 15:56:15 +02006856 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006857 const u8 *ht_mcs_mask;
6858 const u16 *vht_mcs_mask;
Michal Kazior3ae54222015-03-31 10:49:20 +00006859 u8 rate;
6860 u8 nss;
6861 u8 sgi;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306862 u8 ldpc;
Michal Kazior3ae54222015-03-31 10:49:20 +00006863 int single_nss;
6864 int ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006865
Michal Kazior500ff9f2015-03-31 10:26:21 +00006866 if (ath10k_mac_vif_chan(vif, &def))
6867 return -EPERM;
6868
Michal Kazior500ff9f2015-03-31 10:26:21 +00006869 band = def.chan->band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006870 ht_mcs_mask = mask->control[band].ht_mcs;
6871 vht_mcs_mask = mask->control[band].vht_mcs;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306872 ldpc = !!(ar->ht_cap_info & WMI_HT_CAP_LDPC);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006873
Michal Kazior3ae54222015-03-31 10:49:20 +00006874 sgi = mask->control[band].gi;
6875 if (sgi == NL80211_TXRATE_FORCE_LGI)
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006876 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006877
Michal Kazior3ae54222015-03-31 10:49:20 +00006878 if (ath10k_mac_bitrate_mask_has_single_rate(ar, band, mask)) {
6879 ret = ath10k_mac_bitrate_mask_get_single_rate(ar, band, mask,
6880 &rate, &nss);
6881 if (ret) {
6882 ath10k_warn(ar, "failed to get single rate for vdev %i: %d\n",
6883 arvif->vdev_id, ret);
6884 return ret;
6885 }
6886 } else if (ath10k_mac_bitrate_mask_get_single_nss(ar, band, mask,
6887 &single_nss)) {
6888 rate = WMI_FIXED_RATE_NONE;
6889 nss = single_nss;
6890 } else {
6891 rate = WMI_FIXED_RATE_NONE;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006892 nss = min(ar->num_rf_chains,
6893 max(ath10k_mac_max_ht_nss(ht_mcs_mask),
6894 ath10k_mac_max_vht_nss(vht_mcs_mask)));
6895
6896 if (!ath10k_mac_can_set_bitrate_mask(ar, band, mask))
6897 return -EINVAL;
6898
6899 mutex_lock(&ar->conf_mutex);
6900
6901 arvif->bitrate_mask = *mask;
6902 ieee80211_iterate_stations_atomic(ar->hw,
6903 ath10k_mac_set_bitrate_mask_iter,
6904 arvif);
6905
6906 mutex_unlock(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006907 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006908
6909 mutex_lock(&ar->conf_mutex);
6910
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306911 ret = ath10k_mac_set_fixed_rate_params(arvif, rate, nss, sgi, ldpc);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006912 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006913 ath10k_warn(ar, "failed to set fixed rate params on vdev %i: %d\n",
6914 arvif->vdev_id, ret);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006915 goto exit;
6916 }
6917
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006918exit:
6919 mutex_unlock(&ar->conf_mutex);
Michal Kazior3ae54222015-03-31 10:49:20 +00006920
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006921 return ret;
6922}
6923
Michal Kazior9797feb2014-02-14 14:49:48 +01006924static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
6925 struct ieee80211_vif *vif,
6926 struct ieee80211_sta *sta,
6927 u32 changed)
6928{
6929 struct ath10k *ar = hw->priv;
6930 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
6931 u32 bw, smps;
6932
6933 spin_lock_bh(&ar->data_lock);
6934
Michal Kazior7aa7a722014-08-25 12:09:38 +02006935 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior9797feb2014-02-14 14:49:48 +01006936 "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n",
6937 sta->addr, changed, sta->bandwidth, sta->rx_nss,
6938 sta->smps_mode);
6939
6940 if (changed & IEEE80211_RC_BW_CHANGED) {
6941 bw = WMI_PEER_CHWIDTH_20MHZ;
6942
6943 switch (sta->bandwidth) {
6944 case IEEE80211_STA_RX_BW_20:
6945 bw = WMI_PEER_CHWIDTH_20MHZ;
6946 break;
6947 case IEEE80211_STA_RX_BW_40:
6948 bw = WMI_PEER_CHWIDTH_40MHZ;
6949 break;
6950 case IEEE80211_STA_RX_BW_80:
6951 bw = WMI_PEER_CHWIDTH_80MHZ;
6952 break;
6953 case IEEE80211_STA_RX_BW_160:
Masanari Iidad939be32015-02-27 23:52:31 +09006954 ath10k_warn(ar, "Invalid bandwidth %d in rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02006955 sta->bandwidth, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01006956 bw = WMI_PEER_CHWIDTH_20MHZ;
6957 break;
6958 }
6959
6960 arsta->bw = bw;
6961 }
6962
6963 if (changed & IEEE80211_RC_NSS_CHANGED)
6964 arsta->nss = sta->rx_nss;
6965
6966 if (changed & IEEE80211_RC_SMPS_CHANGED) {
6967 smps = WMI_PEER_SMPS_PS_NONE;
6968
6969 switch (sta->smps_mode) {
6970 case IEEE80211_SMPS_AUTOMATIC:
6971 case IEEE80211_SMPS_OFF:
6972 smps = WMI_PEER_SMPS_PS_NONE;
6973 break;
6974 case IEEE80211_SMPS_STATIC:
6975 smps = WMI_PEER_SMPS_STATIC;
6976 break;
6977 case IEEE80211_SMPS_DYNAMIC:
6978 smps = WMI_PEER_SMPS_DYNAMIC;
6979 break;
6980 case IEEE80211_SMPS_NUM_MODES:
Michal Kazior7aa7a722014-08-25 12:09:38 +02006981 ath10k_warn(ar, "Invalid smps %d in sta rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02006982 sta->smps_mode, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01006983 smps = WMI_PEER_SMPS_PS_NONE;
6984 break;
6985 }
6986
6987 arsta->smps = smps;
6988 }
6989
Michal Kazior9797feb2014-02-14 14:49:48 +01006990 arsta->changed |= changed;
6991
6992 spin_unlock_bh(&ar->data_lock);
6993
6994 ieee80211_queue_work(hw, &arsta->update_wk);
6995}
6996
Chun-Yeow Yeoh26ebbcc2014-02-25 09:29:54 +02006997static u64 ath10k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
6998{
6999 /*
7000 * FIXME: Return 0 for time being. Need to figure out whether FW
7001 * has the API to fetch 64-bit local TSF
7002 */
7003
7004 return 0;
7005}
7006
Peter Oh9f0b7e72016-04-04 16:19:14 -07007007static void ath10k_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
Kalle Valo4d165442016-04-13 14:14:16 +03007008 u64 tsf)
Peter Oh9f0b7e72016-04-04 16:19:14 -07007009{
7010 struct ath10k *ar = hw->priv;
7011 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
7012 u32 tsf_offset, vdev_param = ar->wmi.vdev_param->set_tsf;
7013 int ret;
7014
7015 /* Workaround:
7016 *
7017 * Given tsf argument is entire TSF value, but firmware accepts
7018 * only TSF offset to current TSF.
7019 *
7020 * get_tsf function is used to get offset value, however since
7021 * ath10k_get_tsf is not implemented properly, it will return 0 always.
7022 * Luckily all the caller functions to set_tsf, as of now, also rely on
7023 * get_tsf function to get entire tsf value such get_tsf() + tsf_delta,
7024 * final tsf offset value to firmware will be arithmetically correct.
7025 */
7026 tsf_offset = tsf - ath10k_get_tsf(hw, vif);
7027 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
7028 vdev_param, tsf_offset);
7029 if (ret && ret != -EOPNOTSUPP)
7030 ath10k_warn(ar, "failed to set tsf offset: %d\n", ret);
7031}
7032
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007033static int ath10k_ampdu_action(struct ieee80211_hw *hw,
7034 struct ieee80211_vif *vif,
Sara Sharon50ea05e2015-12-30 16:06:04 +02007035 struct ieee80211_ampdu_params *params)
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007036{
Michal Kazior7aa7a722014-08-25 12:09:38 +02007037 struct ath10k *ar = hw->priv;
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007038 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Sara Sharon50ea05e2015-12-30 16:06:04 +02007039 struct ieee80211_sta *sta = params->sta;
7040 enum ieee80211_ampdu_mlme_action action = params->action;
7041 u16 tid = params->tid;
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007042
Michal Kazior7aa7a722014-08-25 12:09:38 +02007043 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 +02007044 arvif->vdev_id, sta->addr, tid, action);
7045
7046 switch (action) {
7047 case IEEE80211_AMPDU_RX_START:
7048 case IEEE80211_AMPDU_RX_STOP:
7049 /* HTT AddBa/DelBa events trigger mac80211 Rx BA session
7050 * creation/removal. Do we need to verify this?
7051 */
7052 return 0;
7053 case IEEE80211_AMPDU_TX_START:
7054 case IEEE80211_AMPDU_TX_STOP_CONT:
7055 case IEEE80211_AMPDU_TX_STOP_FLUSH:
7056 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
7057 case IEEE80211_AMPDU_TX_OPERATIONAL:
7058 /* Firmware offloads Tx aggregation entirely so deny mac80211
7059 * Tx aggregation requests.
7060 */
7061 return -EOPNOTSUPP;
7062 }
7063
7064 return -EINVAL;
7065}
7066
Michal Kazior500ff9f2015-03-31 10:26:21 +00007067static void
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007068ath10k_mac_update_rx_channel(struct ath10k *ar,
7069 struct ieee80211_chanctx_conf *ctx,
7070 struct ieee80211_vif_chanctx_switch *vifs,
7071 int n_vifs)
Michal Kazior500ff9f2015-03-31 10:26:21 +00007072{
7073 struct cfg80211_chan_def *def = NULL;
7074
7075 /* Both locks are required because ar->rx_channel is modified. This
7076 * allows readers to hold either lock.
7077 */
7078 lockdep_assert_held(&ar->conf_mutex);
7079 lockdep_assert_held(&ar->data_lock);
7080
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007081 WARN_ON(ctx && vifs);
Mohammed Shafi Shajakhan5d2db0d2017-03-08 13:52:06 +02007082 WARN_ON(vifs && !n_vifs);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007083
Michal Kazior500ff9f2015-03-31 10:26:21 +00007084 /* FIXME: Sort of an optimization and a workaround. Peers and vifs are
7085 * on a linked list now. Doing a lookup peer -> vif -> chanctx for each
7086 * ppdu on Rx may reduce performance on low-end systems. It should be
7087 * possible to make tables/hashmaps to speed the lookup up (be vary of
7088 * cpu data cache lines though regarding sizes) but to keep the initial
7089 * implementation simple and less intrusive fallback to the slow lookup
7090 * only for multi-channel cases. Single-channel cases will remain to
7091 * use the old channel derival and thus performance should not be
7092 * affected much.
7093 */
7094 rcu_read_lock();
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007095 if (!ctx && ath10k_mac_num_chanctxs(ar) == 1) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00007096 ieee80211_iter_chan_contexts_atomic(ar->hw,
Kalle Valo617b0f42015-10-05 17:56:35 +03007097 ath10k_mac_get_any_chandef_iter,
7098 &def);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007099
7100 if (vifs)
7101 def = &vifs[0].new_ctx->def;
7102
Michal Kazior500ff9f2015-03-31 10:26:21 +00007103 ar->rx_channel = def->chan;
Rajkumar Manoharan1ce8c142016-04-07 12:11:54 +05307104 } else if ((ctx && ath10k_mac_num_chanctxs(ar) == 0) ||
7105 (ctx && (ar->state == ATH10K_STATE_RESTARTED))) {
7106 /* During driver restart due to firmware assert, since mac80211
7107 * already has valid channel context for given radio, channel
7108 * context iteration return num_chanctx > 0. So fix rx_channel
7109 * when restart is in progress.
7110 */
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007111 ar->rx_channel = ctx->def.chan;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007112 } else {
7113 ar->rx_channel = NULL;
7114 }
7115 rcu_read_unlock();
7116}
7117
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007118static void
7119ath10k_mac_update_vif_chan(struct ath10k *ar,
7120 struct ieee80211_vif_chanctx_switch *vifs,
7121 int n_vifs)
7122{
7123 struct ath10k_vif *arvif;
7124 int ret;
7125 int i;
7126
7127 lockdep_assert_held(&ar->conf_mutex);
7128
7129 /* First stop monitor interface. Some FW versions crash if there's a
7130 * lone monitor interface.
7131 */
7132 if (ar->monitor_started)
7133 ath10k_monitor_stop(ar);
7134
7135 for (i = 0; i < n_vifs; i++) {
7136 arvif = ath10k_vif_to_arvif(vifs[i].vif);
7137
7138 ath10k_dbg(ar, ATH10K_DBG_MAC,
7139 "mac chanctx switch vdev_id %i freq %hu->%hu width %d->%d\n",
7140 arvif->vdev_id,
7141 vifs[i].old_ctx->def.chan->center_freq,
7142 vifs[i].new_ctx->def.chan->center_freq,
7143 vifs[i].old_ctx->def.width,
7144 vifs[i].new_ctx->def.width);
7145
7146 if (WARN_ON(!arvif->is_started))
7147 continue;
7148
7149 if (WARN_ON(!arvif->is_up))
7150 continue;
7151
7152 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
7153 if (ret) {
7154 ath10k_warn(ar, "failed to down vdev %d: %d\n",
7155 arvif->vdev_id, ret);
7156 continue;
7157 }
7158 }
7159
7160 /* All relevant vdevs are downed and associated channel resources
7161 * should be available for the channel switch now.
7162 */
7163
7164 spin_lock_bh(&ar->data_lock);
7165 ath10k_mac_update_rx_channel(ar, NULL, vifs, n_vifs);
7166 spin_unlock_bh(&ar->data_lock);
7167
7168 for (i = 0; i < n_vifs; i++) {
7169 arvif = ath10k_vif_to_arvif(vifs[i].vif);
7170
7171 if (WARN_ON(!arvif->is_started))
7172 continue;
7173
7174 if (WARN_ON(!arvif->is_up))
7175 continue;
7176
7177 ret = ath10k_mac_setup_bcn_tmpl(arvif);
7178 if (ret)
7179 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
7180 ret);
7181
7182 ret = ath10k_mac_setup_prb_tmpl(arvif);
7183 if (ret)
7184 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
7185 ret);
7186
7187 ret = ath10k_vdev_restart(arvif, &vifs[i].new_ctx->def);
7188 if (ret) {
7189 ath10k_warn(ar, "failed to restart vdev %d: %d\n",
7190 arvif->vdev_id, ret);
7191 continue;
7192 }
7193
7194 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
7195 arvif->bssid);
7196 if (ret) {
7197 ath10k_warn(ar, "failed to bring vdev up %d: %d\n",
7198 arvif->vdev_id, ret);
7199 continue;
7200 }
7201 }
7202
7203 ath10k_monitor_recalc(ar);
7204}
7205
Michal Kazior500ff9f2015-03-31 10:26:21 +00007206static int
7207ath10k_mac_op_add_chanctx(struct ieee80211_hw *hw,
7208 struct ieee80211_chanctx_conf *ctx)
7209{
7210 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007211
7212 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307213 "mac chanctx add freq %hu width %d ptr %pK\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007214 ctx->def.chan->center_freq, ctx->def.width, ctx);
7215
7216 mutex_lock(&ar->conf_mutex);
7217
7218 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007219 ath10k_mac_update_rx_channel(ar, ctx, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007220 spin_unlock_bh(&ar->data_lock);
7221
7222 ath10k_recalc_radar_detection(ar);
7223 ath10k_monitor_recalc(ar);
7224
7225 mutex_unlock(&ar->conf_mutex);
7226
7227 return 0;
7228}
7229
7230static void
7231ath10k_mac_op_remove_chanctx(struct ieee80211_hw *hw,
7232 struct ieee80211_chanctx_conf *ctx)
7233{
7234 struct ath10k *ar = hw->priv;
7235
7236 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307237 "mac chanctx remove freq %hu width %d ptr %pK\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007238 ctx->def.chan->center_freq, ctx->def.width, ctx);
7239
7240 mutex_lock(&ar->conf_mutex);
7241
7242 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007243 ath10k_mac_update_rx_channel(ar, NULL, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007244 spin_unlock_bh(&ar->data_lock);
7245
7246 ath10k_recalc_radar_detection(ar);
7247 ath10k_monitor_recalc(ar);
7248
7249 mutex_unlock(&ar->conf_mutex);
7250}
7251
Michal Kazior9713e3d2015-09-03 10:44:52 +02007252struct ath10k_mac_change_chanctx_arg {
7253 struct ieee80211_chanctx_conf *ctx;
7254 struct ieee80211_vif_chanctx_switch *vifs;
7255 int n_vifs;
7256 int next_vif;
7257};
7258
7259static void
7260ath10k_mac_change_chanctx_cnt_iter(void *data, u8 *mac,
7261 struct ieee80211_vif *vif)
7262{
7263 struct ath10k_mac_change_chanctx_arg *arg = data;
7264
7265 if (rcu_access_pointer(vif->chanctx_conf) != arg->ctx)
7266 return;
7267
7268 arg->n_vifs++;
7269}
7270
7271static void
7272ath10k_mac_change_chanctx_fill_iter(void *data, u8 *mac,
7273 struct ieee80211_vif *vif)
7274{
7275 struct ath10k_mac_change_chanctx_arg *arg = data;
7276 struct ieee80211_chanctx_conf *ctx;
7277
7278 ctx = rcu_access_pointer(vif->chanctx_conf);
7279 if (ctx != arg->ctx)
7280 return;
7281
7282 if (WARN_ON(arg->next_vif == arg->n_vifs))
7283 return;
7284
7285 arg->vifs[arg->next_vif].vif = vif;
7286 arg->vifs[arg->next_vif].old_ctx = ctx;
7287 arg->vifs[arg->next_vif].new_ctx = ctx;
7288 arg->next_vif++;
7289}
7290
Michal Kazior500ff9f2015-03-31 10:26:21 +00007291static void
7292ath10k_mac_op_change_chanctx(struct ieee80211_hw *hw,
7293 struct ieee80211_chanctx_conf *ctx,
7294 u32 changed)
7295{
7296 struct ath10k *ar = hw->priv;
Michal Kazior9713e3d2015-09-03 10:44:52 +02007297 struct ath10k_mac_change_chanctx_arg arg = { .ctx = ctx };
Michal Kazior500ff9f2015-03-31 10:26:21 +00007298
7299 mutex_lock(&ar->conf_mutex);
7300
7301 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307302 "mac chanctx change freq %hu width %d ptr %pK changed %x\n",
Michal Kazior089ab7a2015-06-03 12:16:55 +02007303 ctx->def.chan->center_freq, ctx->def.width, ctx, changed);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007304
7305 /* This shouldn't really happen because channel switching should use
7306 * switch_vif_chanctx().
7307 */
7308 if (WARN_ON(changed & IEEE80211_CHANCTX_CHANGE_CHANNEL))
7309 goto unlock;
7310
Michal Kazior9713e3d2015-09-03 10:44:52 +02007311 if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH) {
7312 ieee80211_iterate_active_interfaces_atomic(
7313 hw,
7314 IEEE80211_IFACE_ITER_NORMAL,
7315 ath10k_mac_change_chanctx_cnt_iter,
7316 &arg);
7317 if (arg.n_vifs == 0)
7318 goto radar;
7319
7320 arg.vifs = kcalloc(arg.n_vifs, sizeof(arg.vifs[0]),
7321 GFP_KERNEL);
7322 if (!arg.vifs)
7323 goto radar;
7324
7325 ieee80211_iterate_active_interfaces_atomic(
7326 hw,
7327 IEEE80211_IFACE_ITER_NORMAL,
7328 ath10k_mac_change_chanctx_fill_iter,
7329 &arg);
7330 ath10k_mac_update_vif_chan(ar, arg.vifs, arg.n_vifs);
7331 kfree(arg.vifs);
7332 }
7333
7334radar:
Michal Kazior500ff9f2015-03-31 10:26:21 +00007335 ath10k_recalc_radar_detection(ar);
7336
7337 /* FIXME: How to configure Rx chains properly? */
7338
7339 /* No other actions are actually necessary. Firmware maintains channel
7340 * definitions per vdev internally and there's no host-side channel
7341 * context abstraction to configure, e.g. channel width.
7342 */
7343
7344unlock:
7345 mutex_unlock(&ar->conf_mutex);
7346}
7347
7348static int
7349ath10k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
7350 struct ieee80211_vif *vif,
7351 struct ieee80211_chanctx_conf *ctx)
7352{
7353 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007354 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7355 int ret;
7356
7357 mutex_lock(&ar->conf_mutex);
7358
7359 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307360 "mac chanctx assign ptr %pK vdev_id %i\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007361 ctx, arvif->vdev_id);
7362
7363 if (WARN_ON(arvif->is_started)) {
7364 mutex_unlock(&ar->conf_mutex);
7365 return -EBUSY;
7366 }
7367
Michal Kazior089ab7a2015-06-03 12:16:55 +02007368 ret = ath10k_vdev_start(arvif, &ctx->def);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007369 if (ret) {
7370 ath10k_warn(ar, "failed to start vdev %i addr %pM on freq %d: %d\n",
7371 arvif->vdev_id, vif->addr,
Michal Kazior089ab7a2015-06-03 12:16:55 +02007372 ctx->def.chan->center_freq, ret);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007373 goto err;
7374 }
7375
7376 arvif->is_started = true;
7377
Michal Kaziorf23e587e2015-07-09 13:08:37 +02007378 ret = ath10k_mac_vif_setup_ps(arvif);
7379 if (ret) {
7380 ath10k_warn(ar, "failed to update vdev %i ps: %d\n",
7381 arvif->vdev_id, ret);
7382 goto err_stop;
7383 }
7384
Michal Kazior500ff9f2015-03-31 10:26:21 +00007385 if (vif->type == NL80211_IFTYPE_MONITOR) {
7386 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, 0, vif->addr);
7387 if (ret) {
7388 ath10k_warn(ar, "failed to up monitor vdev %i: %d\n",
7389 arvif->vdev_id, ret);
7390 goto err_stop;
7391 }
7392
7393 arvif->is_up = true;
7394 }
7395
Bartosz Markowski83e48fc2016-12-15 11:23:24 +02007396 if (ath10k_mac_can_set_cts_prot(arvif)) {
7397 ret = ath10k_mac_set_cts_prot(arvif);
7398 if (ret)
7399 ath10k_warn(ar, "failed to set cts protection for vdev %d: %d\n",
7400 arvif->vdev_id, ret);
7401 }
7402
Michal Kazior500ff9f2015-03-31 10:26:21 +00007403 mutex_unlock(&ar->conf_mutex);
7404 return 0;
7405
7406err_stop:
7407 ath10k_vdev_stop(arvif);
7408 arvif->is_started = false;
Michal Kaziorf23e587e2015-07-09 13:08:37 +02007409 ath10k_mac_vif_setup_ps(arvif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007410
7411err:
7412 mutex_unlock(&ar->conf_mutex);
7413 return ret;
7414}
7415
7416static void
7417ath10k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
7418 struct ieee80211_vif *vif,
7419 struct ieee80211_chanctx_conf *ctx)
7420{
7421 struct ath10k *ar = hw->priv;
7422 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7423 int ret;
7424
7425 mutex_lock(&ar->conf_mutex);
7426
7427 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307428 "mac chanctx unassign ptr %pK vdev_id %i\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007429 ctx, arvif->vdev_id);
7430
7431 WARN_ON(!arvif->is_started);
7432
7433 if (vif->type == NL80211_IFTYPE_MONITOR) {
7434 WARN_ON(!arvif->is_up);
7435
7436 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
7437 if (ret)
7438 ath10k_warn(ar, "failed to down monitor vdev %i: %d\n",
7439 arvif->vdev_id, ret);
7440
7441 arvif->is_up = false;
7442 }
7443
7444 ret = ath10k_vdev_stop(arvif);
7445 if (ret)
7446 ath10k_warn(ar, "failed to stop vdev %i: %d\n",
7447 arvif->vdev_id, ret);
7448
7449 arvif->is_started = false;
7450
7451 mutex_unlock(&ar->conf_mutex);
7452}
7453
7454static int
7455ath10k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw,
7456 struct ieee80211_vif_chanctx_switch *vifs,
7457 int n_vifs,
7458 enum ieee80211_chanctx_switch_mode mode)
7459{
7460 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007461
7462 mutex_lock(&ar->conf_mutex);
7463
7464 ath10k_dbg(ar, ATH10K_DBG_MAC,
7465 "mac chanctx switch n_vifs %d mode %d\n",
7466 n_vifs, mode);
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007467 ath10k_mac_update_vif_chan(ar, vifs, n_vifs);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007468
7469 mutex_unlock(&ar->conf_mutex);
7470 return 0;
7471}
7472
Michal Kazior874b5ac2017-01-12 16:14:30 +01007473static void ath10k_mac_op_sta_pre_rcu_remove(struct ieee80211_hw *hw,
7474 struct ieee80211_vif *vif,
7475 struct ieee80211_sta *sta)
7476{
7477 struct ath10k *ar;
7478 struct ath10k_peer *peer;
7479
7480 ar = hw->priv;
7481
7482 list_for_each_entry(peer, &ar->peers, list)
7483 if (peer->sta == sta)
7484 peer->removed = true;
7485}
7486
Kalle Valo5e3dd152013-06-12 20:52:10 +03007487static const struct ieee80211_ops ath10k_ops = {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01007488 .tx = ath10k_mac_op_tx,
Michal Kazior29946872016-03-06 16:14:34 +02007489 .wake_tx_queue = ath10k_mac_op_wake_tx_queue,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007490 .start = ath10k_start,
7491 .stop = ath10k_stop,
7492 .config = ath10k_config,
7493 .add_interface = ath10k_add_interface,
7494 .remove_interface = ath10k_remove_interface,
7495 .configure_filter = ath10k_configure_filter,
7496 .bss_info_changed = ath10k_bss_info_changed,
7497 .hw_scan = ath10k_hw_scan,
7498 .cancel_hw_scan = ath10k_cancel_hw_scan,
7499 .set_key = ath10k_set_key,
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02007500 .set_default_unicast_key = ath10k_set_default_unicast_key,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007501 .sta_state = ath10k_sta_state,
7502 .conf_tx = ath10k_conf_tx,
7503 .remain_on_channel = ath10k_remain_on_channel,
7504 .cancel_remain_on_channel = ath10k_cancel_remain_on_channel,
7505 .set_rts_threshold = ath10k_set_rts_threshold,
Michal Kazior92092fe2015-08-03 11:16:43 +02007506 .set_frag_threshold = ath10k_mac_op_set_frag_threshold,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007507 .flush = ath10k_flush,
7508 .tx_last_beacon = ath10k_tx_last_beacon,
Ben Greear46acf7b2014-05-16 17:15:38 +03007509 .set_antenna = ath10k_set_antenna,
7510 .get_antenna = ath10k_get_antenna,
Eliad Pellercf2c92d2014-11-04 11:43:54 +02007511 .reconfig_complete = ath10k_reconfig_complete,
Michal Kazior2e1dea42013-07-31 10:32:40 +02007512 .get_survey = ath10k_get_survey,
Michal Kazior3ae54222015-03-31 10:49:20 +00007513 .set_bitrate_mask = ath10k_mac_op_set_bitrate_mask,
Michal Kazior9797feb2014-02-14 14:49:48 +01007514 .sta_rc_update = ath10k_sta_rc_update,
Chun-Yeow Yeoh26ebbcc2014-02-25 09:29:54 +02007515 .get_tsf = ath10k_get_tsf,
Peter Oh9f0b7e72016-04-04 16:19:14 -07007516 .set_tsf = ath10k_set_tsf,
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007517 .ampdu_action = ath10k_ampdu_action,
Ben Greear6cddcc72014-09-29 14:41:46 +03007518 .get_et_sset_count = ath10k_debug_get_et_sset_count,
7519 .get_et_stats = ath10k_debug_get_et_stats,
7520 .get_et_strings = ath10k_debug_get_et_strings,
Michal Kazior500ff9f2015-03-31 10:26:21 +00007521 .add_chanctx = ath10k_mac_op_add_chanctx,
7522 .remove_chanctx = ath10k_mac_op_remove_chanctx,
7523 .change_chanctx = ath10k_mac_op_change_chanctx,
7524 .assign_vif_chanctx = ath10k_mac_op_assign_vif_chanctx,
7525 .unassign_vif_chanctx = ath10k_mac_op_unassign_vif_chanctx,
7526 .switch_vif_chanctx = ath10k_mac_op_switch_vif_chanctx,
Michal Kazior874b5ac2017-01-12 16:14:30 +01007527 .sta_pre_rcu_remove = ath10k_mac_op_sta_pre_rcu_remove,
Kalle Valo43d2a302014-09-10 18:23:30 +03007528
7529 CFG80211_TESTMODE_CMD(ath10k_tm_cmd)
7530
Michal Kazior8cd13ca2013-07-16 09:38:54 +02007531#ifdef CONFIG_PM
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02007532 .suspend = ath10k_wow_op_suspend,
7533 .resume = ath10k_wow_op_resume,
Michal Kazior8cd13ca2013-07-16 09:38:54 +02007534#endif
Rajkumar Manoharanf5045982015-01-12 14:07:27 +02007535#ifdef CONFIG_MAC80211_DEBUGFS
7536 .sta_add_debugfs = ath10k_sta_add_debugfs,
Mohammed Shafi Shajakhan120a1f02016-06-30 15:23:50 +03007537 .sta_statistics = ath10k_sta_statistics,
Rajkumar Manoharanf5045982015-01-12 14:07:27 +02007538#endif
Kalle Valo5e3dd152013-06-12 20:52:10 +03007539};
7540
Kalle Valo5e3dd152013-06-12 20:52:10 +03007541#define CHAN2G(_channel, _freq, _flags) { \
Johannes Berg57fbcce2016-04-12 15:56:15 +02007542 .band = NL80211_BAND_2GHZ, \
Kalle Valo5e3dd152013-06-12 20:52:10 +03007543 .hw_value = (_channel), \
7544 .center_freq = (_freq), \
7545 .flags = (_flags), \
7546 .max_antenna_gain = 0, \
7547 .max_power = 30, \
7548}
7549
7550#define CHAN5G(_channel, _freq, _flags) { \
Johannes Berg57fbcce2016-04-12 15:56:15 +02007551 .band = NL80211_BAND_5GHZ, \
Kalle Valo5e3dd152013-06-12 20:52:10 +03007552 .hw_value = (_channel), \
7553 .center_freq = (_freq), \
7554 .flags = (_flags), \
7555 .max_antenna_gain = 0, \
7556 .max_power = 30, \
7557}
7558
7559static const struct ieee80211_channel ath10k_2ghz_channels[] = {
7560 CHAN2G(1, 2412, 0),
7561 CHAN2G(2, 2417, 0),
7562 CHAN2G(3, 2422, 0),
7563 CHAN2G(4, 2427, 0),
7564 CHAN2G(5, 2432, 0),
7565 CHAN2G(6, 2437, 0),
7566 CHAN2G(7, 2442, 0),
7567 CHAN2G(8, 2447, 0),
7568 CHAN2G(9, 2452, 0),
7569 CHAN2G(10, 2457, 0),
7570 CHAN2G(11, 2462, 0),
7571 CHAN2G(12, 2467, 0),
7572 CHAN2G(13, 2472, 0),
7573 CHAN2G(14, 2484, 0),
7574};
7575
7576static const struct ieee80211_channel ath10k_5ghz_channels[] = {
Michal Kazior429ff562013-06-26 08:54:54 +02007577 CHAN5G(36, 5180, 0),
7578 CHAN5G(40, 5200, 0),
7579 CHAN5G(44, 5220, 0),
7580 CHAN5G(48, 5240, 0),
7581 CHAN5G(52, 5260, 0),
7582 CHAN5G(56, 5280, 0),
7583 CHAN5G(60, 5300, 0),
7584 CHAN5G(64, 5320, 0),
7585 CHAN5G(100, 5500, 0),
7586 CHAN5G(104, 5520, 0),
7587 CHAN5G(108, 5540, 0),
7588 CHAN5G(112, 5560, 0),
7589 CHAN5G(116, 5580, 0),
7590 CHAN5G(120, 5600, 0),
7591 CHAN5G(124, 5620, 0),
7592 CHAN5G(128, 5640, 0),
7593 CHAN5G(132, 5660, 0),
7594 CHAN5G(136, 5680, 0),
7595 CHAN5G(140, 5700, 0),
Peter Oh4a7898f2015-03-18 11:39:18 -07007596 CHAN5G(144, 5720, 0),
Michal Kazior429ff562013-06-26 08:54:54 +02007597 CHAN5G(149, 5745, 0),
7598 CHAN5G(153, 5765, 0),
7599 CHAN5G(157, 5785, 0),
7600 CHAN5G(161, 5805, 0),
7601 CHAN5G(165, 5825, 0),
Kalle Valo5e3dd152013-06-12 20:52:10 +03007602};
7603
Michal Kaziore7b54192014-08-07 11:03:27 +02007604struct ath10k *ath10k_mac_create(size_t priv_size)
Kalle Valo5e3dd152013-06-12 20:52:10 +03007605{
7606 struct ieee80211_hw *hw;
Michal Kazior4ca18072016-07-18 23:22:18 +03007607 struct ieee80211_ops *ops;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007608 struct ath10k *ar;
7609
Michal Kazior4ca18072016-07-18 23:22:18 +03007610 ops = kmemdup(&ath10k_ops, sizeof(ath10k_ops), GFP_KERNEL);
7611 if (!ops)
Kalle Valo5e3dd152013-06-12 20:52:10 +03007612 return NULL;
7613
Michal Kazior4ca18072016-07-18 23:22:18 +03007614 hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, ops);
7615 if (!hw) {
7616 kfree(ops);
7617 return NULL;
7618 }
7619
Kalle Valo5e3dd152013-06-12 20:52:10 +03007620 ar = hw->priv;
7621 ar->hw = hw;
Michal Kazior4ca18072016-07-18 23:22:18 +03007622 ar->ops = ops;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007623
7624 return ar;
7625}
7626
7627void ath10k_mac_destroy(struct ath10k *ar)
7628{
Michal Kazior4ca18072016-07-18 23:22:18 +03007629 struct ieee80211_ops *ops = ar->ops;
7630
Kalle Valo5e3dd152013-06-12 20:52:10 +03007631 ieee80211_free_hw(ar->hw);
Michal Kazior4ca18072016-07-18 23:22:18 +03007632 kfree(ops);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007633}
7634
7635static const struct ieee80211_iface_limit ath10k_if_limits[] = {
7636 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307637 .max = 8,
7638 .types = BIT(NL80211_IFTYPE_STATION)
7639 | BIT(NL80211_IFTYPE_P2P_CLIENT)
Michal Kaziord531cb82013-07-31 10:55:13 +02007640 },
7641 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307642 .max = 3,
7643 .types = BIT(NL80211_IFTYPE_P2P_GO)
Michal Kaziord531cb82013-07-31 10:55:13 +02007644 },
7645 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307646 .max = 1,
7647 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
Michal Kazior75d2bd42014-12-12 12:41:39 +01007648 },
7649 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307650 .max = 7,
7651 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007652#ifdef CONFIG_MAC80211_MESH
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307653 | BIT(NL80211_IFTYPE_MESH_POINT)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007654#endif
Michal Kaziord531cb82013-07-31 10:55:13 +02007655 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03007656};
7657
Bartosz Markowskif2595092013-12-10 16:20:39 +01007658static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007659 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307660 .max = 8,
7661 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007662#ifdef CONFIG_MAC80211_MESH
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307663 | BIT(NL80211_IFTYPE_MESH_POINT)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007664#endif
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007665 },
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307666 {
7667 .max = 1,
7668 .types = BIT(NL80211_IFTYPE_STATION)
7669 },
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007670};
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007671
7672static const struct ieee80211_iface_combination ath10k_if_comb[] = {
7673 {
7674 .limits = ath10k_if_limits,
7675 .n_limits = ARRAY_SIZE(ath10k_if_limits),
7676 .max_interfaces = 8,
7677 .num_different_channels = 1,
7678 .beacon_int_infra_match = true,
7679 },
Bartosz Markowskif2595092013-12-10 16:20:39 +01007680};
7681
7682static const struct ieee80211_iface_combination ath10k_10x_if_comb[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007683 {
Bartosz Markowskif2595092013-12-10 16:20:39 +01007684 .limits = ath10k_10x_if_limits,
7685 .n_limits = ARRAY_SIZE(ath10k_10x_if_limits),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007686 .max_interfaces = 8,
7687 .num_different_channels = 1,
7688 .beacon_int_infra_match = true,
Bartosz Markowskif2595092013-12-10 16:20:39 +01007689#ifdef CONFIG_ATH10K_DFS_CERTIFIED
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007690 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
7691 BIT(NL80211_CHAN_WIDTH_20) |
7692 BIT(NL80211_CHAN_WIDTH_40) |
7693 BIT(NL80211_CHAN_WIDTH_80),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007694#endif
Bartosz Markowskif2595092013-12-10 16:20:39 +01007695 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03007696};
7697
Michal Kaziorcf327842015-03-31 10:26:25 +00007698static const struct ieee80211_iface_limit ath10k_tlv_if_limit[] = {
7699 {
7700 .max = 2,
Michal Kaziored25b112015-07-09 13:08:39 +02007701 .types = BIT(NL80211_IFTYPE_STATION),
7702 },
7703 {
7704 .max = 2,
7705 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007706#ifdef CONFIG_MAC80211_MESH
7707 BIT(NL80211_IFTYPE_MESH_POINT) |
7708#endif
Michal Kaziorcf327842015-03-31 10:26:25 +00007709 BIT(NL80211_IFTYPE_P2P_CLIENT) |
7710 BIT(NL80211_IFTYPE_P2P_GO),
7711 },
7712 {
7713 .max = 1,
7714 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
7715 },
7716};
7717
Michal Kaziored25b112015-07-09 13:08:39 +02007718static const struct ieee80211_iface_limit ath10k_tlv_qcs_if_limit[] = {
7719 {
7720 .max = 2,
7721 .types = BIT(NL80211_IFTYPE_STATION),
7722 },
7723 {
7724 .max = 2,
7725 .types = BIT(NL80211_IFTYPE_P2P_CLIENT),
7726 },
7727 {
7728 .max = 1,
7729 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007730#ifdef CONFIG_MAC80211_MESH
7731 BIT(NL80211_IFTYPE_MESH_POINT) |
7732#endif
Michal Kaziored25b112015-07-09 13:08:39 +02007733 BIT(NL80211_IFTYPE_P2P_GO),
7734 },
7735 {
7736 .max = 1,
7737 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
7738 },
7739};
7740
Michal Kaziorcf327842015-03-31 10:26:25 +00007741static const struct ieee80211_iface_limit ath10k_tlv_if_limit_ibss[] = {
7742 {
7743 .max = 1,
7744 .types = BIT(NL80211_IFTYPE_STATION),
7745 },
7746 {
7747 .max = 1,
7748 .types = BIT(NL80211_IFTYPE_ADHOC),
7749 },
7750};
7751
7752/* FIXME: This is not thouroughly tested. These combinations may over- or
7753 * underestimate hw/fw capabilities.
7754 */
7755static struct ieee80211_iface_combination ath10k_tlv_if_comb[] = {
7756 {
7757 .limits = ath10k_tlv_if_limit,
7758 .num_different_channels = 1,
Michal Kaziored25b112015-07-09 13:08:39 +02007759 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00007760 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
7761 },
7762 {
7763 .limits = ath10k_tlv_if_limit_ibss,
7764 .num_different_channels = 1,
7765 .max_interfaces = 2,
7766 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
7767 },
7768};
7769
7770static struct ieee80211_iface_combination ath10k_tlv_qcs_if_comb[] = {
7771 {
7772 .limits = ath10k_tlv_if_limit,
Michal Kaziored25b112015-07-09 13:08:39 +02007773 .num_different_channels = 1,
7774 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00007775 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
7776 },
7777 {
Michal Kaziored25b112015-07-09 13:08:39 +02007778 .limits = ath10k_tlv_qcs_if_limit,
7779 .num_different_channels = 2,
7780 .max_interfaces = 4,
7781 .n_limits = ARRAY_SIZE(ath10k_tlv_qcs_if_limit),
7782 },
7783 {
Michal Kaziorcf327842015-03-31 10:26:25 +00007784 .limits = ath10k_tlv_if_limit_ibss,
7785 .num_different_channels = 1,
7786 .max_interfaces = 2,
7787 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
7788 },
7789};
7790
Raja Manicf36fef2015-06-22 20:22:25 +05307791static const struct ieee80211_iface_limit ath10k_10_4_if_limits[] = {
7792 {
7793 .max = 1,
7794 .types = BIT(NL80211_IFTYPE_STATION),
7795 },
7796 {
7797 .max = 16,
7798 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007799#ifdef CONFIG_MAC80211_MESH
7800 | BIT(NL80211_IFTYPE_MESH_POINT)
7801#endif
Raja Manicf36fef2015-06-22 20:22:25 +05307802 },
7803};
7804
7805static const struct ieee80211_iface_combination ath10k_10_4_if_comb[] = {
7806 {
7807 .limits = ath10k_10_4_if_limits,
7808 .n_limits = ARRAY_SIZE(ath10k_10_4_if_limits),
7809 .max_interfaces = 16,
7810 .num_different_channels = 1,
7811 .beacon_int_infra_match = true,
7812#ifdef CONFIG_ATH10K_DFS_CERTIFIED
7813 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
7814 BIT(NL80211_CHAN_WIDTH_20) |
7815 BIT(NL80211_CHAN_WIDTH_40) |
7816 BIT(NL80211_CHAN_WIDTH_80),
7817#endif
7818 },
7819};
7820
Kalle Valo5e3dd152013-06-12 20:52:10 +03007821static void ath10k_get_arvif_iter(void *data, u8 *mac,
7822 struct ieee80211_vif *vif)
7823{
7824 struct ath10k_vif_iter *arvif_iter = data;
7825 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
7826
7827 if (arvif->vdev_id == arvif_iter->vdev_id)
7828 arvif_iter->arvif = arvif;
7829}
7830
7831struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id)
7832{
7833 struct ath10k_vif_iter arvif_iter;
7834 u32 flags;
7835
7836 memset(&arvif_iter, 0, sizeof(struct ath10k_vif_iter));
7837 arvif_iter.vdev_id = vdev_id;
7838
7839 flags = IEEE80211_IFACE_ITER_RESUME_ALL;
7840 ieee80211_iterate_active_interfaces_atomic(ar->hw,
7841 flags,
7842 ath10k_get_arvif_iter,
7843 &arvif_iter);
7844 if (!arvif_iter.arvif) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007845 ath10k_warn(ar, "No VIF found for vdev %d\n", vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007846 return NULL;
7847 }
7848
7849 return arvif_iter.arvif;
7850}
7851
7852int ath10k_mac_register(struct ath10k *ar)
7853{
Johannes Berg3cb10942015-01-22 21:38:45 +01007854 static const u32 cipher_suites[] = {
7855 WLAN_CIPHER_SUITE_WEP40,
7856 WLAN_CIPHER_SUITE_WEP104,
7857 WLAN_CIPHER_SUITE_TKIP,
7858 WLAN_CIPHER_SUITE_CCMP,
7859 WLAN_CIPHER_SUITE_AES_CMAC,
7860 };
Kalle Valo5e3dd152013-06-12 20:52:10 +03007861 struct ieee80211_supported_band *band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007862 void *channels;
7863 int ret;
7864
7865 SET_IEEE80211_PERM_ADDR(ar->hw, ar->mac_addr);
7866
7867 SET_IEEE80211_DEV(ar->hw, ar->dev);
7868
Michal Kaziorc94aa7e2015-03-24 12:38:11 +00007869 BUILD_BUG_ON((ARRAY_SIZE(ath10k_2ghz_channels) +
7870 ARRAY_SIZE(ath10k_5ghz_channels)) !=
7871 ATH10K_NUM_CHANS);
7872
Kalle Valo5e3dd152013-06-12 20:52:10 +03007873 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
7874 channels = kmemdup(ath10k_2ghz_channels,
7875 sizeof(ath10k_2ghz_channels),
7876 GFP_KERNEL);
Michal Kaziord6015b22013-07-22 14:13:30 +02007877 if (!channels) {
7878 ret = -ENOMEM;
7879 goto err_free;
7880 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03007881
Johannes Berg57fbcce2016-04-12 15:56:15 +02007882 band = &ar->mac.sbands[NL80211_BAND_2GHZ];
Kalle Valo5e3dd152013-06-12 20:52:10 +03007883 band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels);
7884 band->channels = channels;
Mohammed Shafi Shajakhan5269c652016-06-07 15:47:04 +03007885
7886 if (ar->hw_params.cck_rate_map_rev2) {
7887 band->n_bitrates = ath10k_g_rates_rev2_size;
7888 band->bitrates = ath10k_g_rates_rev2;
7889 } else {
7890 band->n_bitrates = ath10k_g_rates_size;
7891 band->bitrates = ath10k_g_rates;
7892 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03007893
Johannes Berg57fbcce2016-04-12 15:56:15 +02007894 ar->hw->wiphy->bands[NL80211_BAND_2GHZ] = band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007895 }
7896
7897 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
7898 channels = kmemdup(ath10k_5ghz_channels,
7899 sizeof(ath10k_5ghz_channels),
7900 GFP_KERNEL);
7901 if (!channels) {
Michal Kaziord6015b22013-07-22 14:13:30 +02007902 ret = -ENOMEM;
7903 goto err_free;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007904 }
7905
Johannes Berg57fbcce2016-04-12 15:56:15 +02007906 band = &ar->mac.sbands[NL80211_BAND_5GHZ];
Kalle Valo5e3dd152013-06-12 20:52:10 +03007907 band->n_channels = ARRAY_SIZE(ath10k_5ghz_channels);
7908 band->channels = channels;
7909 band->n_bitrates = ath10k_a_rates_size;
7910 band->bitrates = ath10k_a_rates;
Johannes Berg57fbcce2016-04-12 15:56:15 +02007911 ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007912 }
7913
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05307914 ath10k_mac_setup_ht_vht_cap(ar);
7915
Kalle Valo5e3dd152013-06-12 20:52:10 +03007916 ar->hw->wiphy->interface_modes =
7917 BIT(NL80211_IFTYPE_STATION) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007918 BIT(NL80211_IFTYPE_AP) |
7919 BIT(NL80211_IFTYPE_MESH_POINT);
Bartosz Markowskid3541812013-12-10 16:20:40 +01007920
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05307921 ar->hw->wiphy->available_antennas_rx = ar->cfg_rx_chainmask;
7922 ar->hw->wiphy->available_antennas_tx = ar->cfg_tx_chainmask;
Ben Greear46acf7b2014-05-16 17:15:38 +03007923
Kalle Valoc4cdf752016-04-20 19:45:18 +03007924 if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->normal_mode_fw.fw_file.fw_features))
Bartosz Markowskid3541812013-12-10 16:20:40 +01007925 ar->hw->wiphy->interface_modes |=
Michal Kazior75d2bd42014-12-12 12:41:39 +01007926 BIT(NL80211_IFTYPE_P2P_DEVICE) |
Bartosz Markowskid3541812013-12-10 16:20:40 +01007927 BIT(NL80211_IFTYPE_P2P_CLIENT) |
7928 BIT(NL80211_IFTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007929
Johannes Berg30686bf2015-06-02 21:39:54 +02007930 ieee80211_hw_set(ar->hw, SIGNAL_DBM);
7931 ieee80211_hw_set(ar->hw, SUPPORTS_PS);
7932 ieee80211_hw_set(ar->hw, SUPPORTS_DYNAMIC_PS);
7933 ieee80211_hw_set(ar->hw, MFP_CAPABLE);
7934 ieee80211_hw_set(ar->hw, REPORTS_TX_ACK_STATUS);
7935 ieee80211_hw_set(ar->hw, HAS_RATE_CONTROL);
7936 ieee80211_hw_set(ar->hw, AP_LINK_PS);
7937 ieee80211_hw_set(ar->hw, SPECTRUM_MGMT);
Johannes Berg30686bf2015-06-02 21:39:54 +02007938 ieee80211_hw_set(ar->hw, SUPPORT_FAST_XMIT);
7939 ieee80211_hw_set(ar->hw, CONNECTION_MONITOR);
7940 ieee80211_hw_set(ar->hw, SUPPORTS_PER_STA_GTK);
7941 ieee80211_hw_set(ar->hw, WANT_MONITOR_VIF);
7942 ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA);
7943 ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007944
David Liuccec9032015-07-24 20:25:32 +03007945 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
7946 ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL);
7947
Eliad Peller0d8614b2014-09-10 14:07:36 +03007948 ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS;
Janusz Dziedzic0cd9bc12015-04-10 13:23:23 +00007949 ar->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
Eliad Peller0d8614b2014-09-10 14:07:36 +03007950
Kalle Valo5e3dd152013-06-12 20:52:10 +03007951 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS)
Eliad Peller0d8614b2014-09-10 14:07:36 +03007952 ar->hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007953
7954 if (ar->ht_cap_info & WMI_HT_CAP_ENABLED) {
Johannes Berg30686bf2015-06-02 21:39:54 +02007955 ieee80211_hw_set(ar->hw, AMPDU_AGGREGATION);
7956 ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007957 }
7958
7959 ar->hw->wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID;
7960 ar->hw->wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN;
7961
7962 ar->hw->vif_data_size = sizeof(struct ath10k_vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01007963 ar->hw->sta_data_size = sizeof(struct ath10k_sta);
Michal Kazior29946872016-03-06 16:14:34 +02007964 ar->hw->txq_data_size = sizeof(struct ath10k_txq);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007965
Kalle Valo5e3dd152013-06-12 20:52:10 +03007966 ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL;
7967
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02007968 if (test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)) {
7969 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
7970
7971 /* Firmware delivers WPS/P2P Probe Requests frames to driver so
7972 * that userspace (e.g. wpa_supplicant/hostapd) can generate
7973 * correct Probe Responses. This is more of a hack advert..
7974 */
7975 ar->hw->wiphy->probe_resp_offload |=
7976 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
7977 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
7978 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
7979 }
7980
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03007981 if (test_bit(WMI_SERVICE_TDLS, ar->wmi.svc_map))
7982 ar->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
7983
Kalle Valo5e3dd152013-06-12 20:52:10 +03007984 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Michal Kaziorc2df44b2014-01-23 11:38:26 +01007985 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007986 ar->hw->wiphy->max_remain_on_channel_duration = 5000;
7987
7988 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
Vasanthakumar Thiagarajanbf031bc2016-03-15 15:25:53 +05307989 ar->hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |
7990 NL80211_FEATURE_AP_SCAN;
Rajkumar Manoharan78157a12014-11-17 16:44:15 +02007991
Janusz.Dziedzic@tieto.com37a0b392015-03-12 13:11:41 +01007992 ar->hw->wiphy->max_ap_assoc_sta = ar->max_num_stations;
7993
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02007994 ret = ath10k_wow_init(ar);
7995 if (ret) {
7996 ath10k_warn(ar, "failed to init wow: %d\n", ret);
7997 goto err_free;
7998 }
7999
Janusz Dziedzicc7025342015-06-15 14:46:41 +03008000 wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
8001
Kalle Valo5e3dd152013-06-12 20:52:10 +03008002 /*
8003 * on LL hardware queues are managed entirely by the FW
8004 * so we only advertise to mac we can do the queues thing
8005 */
Michal Kazior96d828d2015-03-31 10:26:23 +00008006 ar->hw->queues = IEEE80211_MAX_QUEUES;
8007
8008 /* vdev_ids are used as hw queue numbers. Make sure offchan tx queue is
8009 * something that vdev_ids can't reach so that we don't stop the queue
8010 * accidentally.
8011 */
8012 ar->hw->offchannel_tx_hw_queue = IEEE80211_MAX_QUEUES - 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008013
Kalle Valobf3c13a2016-04-20 19:45:33 +03008014 switch (ar->running_fw->fw_file.wmi_op_version) {
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008015 case ATH10K_FW_WMI_OP_VERSION_MAIN:
Bartosz Markowskif2595092013-12-10 16:20:39 +01008016 ar->hw->wiphy->iface_combinations = ath10k_if_comb;
8017 ar->hw->wiphy->n_iface_combinations =
8018 ARRAY_SIZE(ath10k_if_comb);
Michal Kaziorcf850d12014-07-24 20:07:00 +03008019 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008020 break;
Michal Kaziorcf327842015-03-31 10:26:25 +00008021 case ATH10K_FW_WMI_OP_VERSION_TLV:
8022 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
8023 ar->hw->wiphy->iface_combinations =
8024 ath10k_tlv_qcs_if_comb;
8025 ar->hw->wiphy->n_iface_combinations =
8026 ARRAY_SIZE(ath10k_tlv_qcs_if_comb);
8027 } else {
8028 ar->hw->wiphy->iface_combinations = ath10k_tlv_if_comb;
8029 ar->hw->wiphy->n_iface_combinations =
8030 ARRAY_SIZE(ath10k_tlv_if_comb);
8031 }
8032 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
8033 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008034 case ATH10K_FW_WMI_OP_VERSION_10_1:
8035 case ATH10K_FW_WMI_OP_VERSION_10_2:
Rajkumar Manoharan4a16fbe2014-12-17 12:21:12 +02008036 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008037 ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb;
8038 ar->hw->wiphy->n_iface_combinations =
8039 ARRAY_SIZE(ath10k_10x_if_comb);
8040 break;
Raja Mani9bd21322015-06-22 20:10:09 +05308041 case ATH10K_FW_WMI_OP_VERSION_10_4:
Raja Manicf36fef2015-06-22 20:22:25 +05308042 ar->hw->wiphy->iface_combinations = ath10k_10_4_if_comb;
8043 ar->hw->wiphy->n_iface_combinations =
8044 ARRAY_SIZE(ath10k_10_4_if_comb);
Raja Mani9bd21322015-06-22 20:10:09 +05308045 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008046 case ATH10K_FW_WMI_OP_VERSION_UNSET:
8047 case ATH10K_FW_WMI_OP_VERSION_MAX:
8048 WARN_ON(1);
8049 ret = -EINVAL;
8050 goto err_free;
Bartosz Markowskif2595092013-12-10 16:20:39 +01008051 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03008052
David Liuccec9032015-07-24 20:25:32 +03008053 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
8054 ar->hw->netdev_features = NETIF_F_HW_CSUM;
Michal Kazior7c199992013-07-31 10:47:57 +02008055
Masahiro Yamada97f26452016-08-03 13:45:50 -07008056 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED)) {
Janusz Dziedzic9702c682013-11-20 09:59:41 +02008057 /* Init ath dfs pattern detector */
8058 ar->ath_common.debug_mask = ATH_DBG_DFS;
8059 ar->dfs_detector = dfs_pattern_detector_init(&ar->ath_common,
8060 NL80211_DFS_UNSET);
8061
8062 if (!ar->dfs_detector)
Michal Kazior7aa7a722014-08-25 12:09:38 +02008063 ath10k_warn(ar, "failed to initialise DFS pattern detector\n");
Janusz Dziedzic9702c682013-11-20 09:59:41 +02008064 }
8065
Michal Kazior4ca18072016-07-18 23:22:18 +03008066 /* Current wake_tx_queue implementation imposes a significant
8067 * performance penalty in some setups. The tx scheduling code needs
8068 * more work anyway so disable the wake_tx_queue unless firmware
8069 * supports the pull-push mechanism.
8070 */
8071 if (!test_bit(ATH10K_FW_FEATURE_PEER_FLOW_CONTROL,
8072 ar->running_fw->fw_file.fw_features))
8073 ar->ops->wake_tx_queue = NULL;
8074
Kalle Valo5e3dd152013-06-12 20:52:10 +03008075 ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy,
8076 ath10k_reg_notifier);
8077 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02008078 ath10k_err(ar, "failed to initialise regulatory: %i\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07008079 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008080 }
8081
Johannes Berg3cb10942015-01-22 21:38:45 +01008082 ar->hw->wiphy->cipher_suites = cipher_suites;
8083 ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
8084
Kalle Valo5e3dd152013-06-12 20:52:10 +03008085 ret = ieee80211_register_hw(ar->hw);
8086 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02008087 ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07008088 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008089 }
8090
8091 if (!ath_is_world_regd(&ar->ath_common.regulatory)) {
8092 ret = regulatory_hint(ar->hw->wiphy,
8093 ar->ath_common.regulatory.alpha2);
8094 if (ret)
Michal Kaziord6015b22013-07-22 14:13:30 +02008095 goto err_unregister;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008096 }
8097
8098 return 0;
Michal Kaziord6015b22013-07-22 14:13:30 +02008099
8100err_unregister:
Kalle Valo5e3dd152013-06-12 20:52:10 +03008101 ieee80211_unregister_hw(ar->hw);
Jeff Johnson0e339442015-10-08 09:15:53 -07008102
8103err_dfs_detector_exit:
Masahiro Yamada97f26452016-08-03 13:45:50 -07008104 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
Jeff Johnson0e339442015-10-08 09:15:53 -07008105 ar->dfs_detector->exit(ar->dfs_detector);
8106
Michal Kaziord6015b22013-07-22 14:13:30 +02008107err_free:
Johannes Berg57fbcce2016-04-12 15:56:15 +02008108 kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
8109 kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
Michal Kaziord6015b22013-07-22 14:13:30 +02008110
Jeff Johnson0e339442015-10-08 09:15:53 -07008111 SET_IEEE80211_DEV(ar->hw, NULL);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008112 return ret;
8113}
8114
8115void ath10k_mac_unregister(struct ath10k *ar)
8116{
8117 ieee80211_unregister_hw(ar->hw);
8118
Masahiro Yamada97f26452016-08-03 13:45:50 -07008119 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
Janusz Dziedzic9702c682013-11-20 09:59:41 +02008120 ar->dfs_detector->exit(ar->dfs_detector);
8121
Johannes Berg57fbcce2016-04-12 15:56:15 +02008122 kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
8123 kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008124
8125 SET_IEEE80211_DEV(ar->hw, NULL);
8126}