blob: 1588fe8110d00c0f2294bd44acfc5a0e9ba3e191 [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
Surabhi Vishnoieedd6cd2019-04-17 14:01:46 +05301599 /* For mesh, probe response and beacon share the same template */
1600 if (ieee80211_vif_is_mesh(vif))
1601 return 0;
1602
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02001603 prb = ieee80211_proberesp_get(hw, vif);
1604 if (!prb) {
1605 ath10k_warn(ar, "failed to get probe resp template from mac80211\n");
1606 return -EPERM;
1607 }
1608
1609 ret = ath10k_wmi_prb_tmpl(ar, arvif->vdev_id, prb);
1610 kfree_skb(prb);
1611
1612 if (ret) {
1613 ath10k_warn(ar, "failed to submit probe resp template command: %d\n",
1614 ret);
1615 return ret;
1616 }
1617
1618 return 0;
1619}
1620
Michal Kazior500ff9f2015-03-31 10:26:21 +00001621static int ath10k_mac_vif_fix_hidden_ssid(struct ath10k_vif *arvif)
1622{
1623 struct ath10k *ar = arvif->ar;
1624 struct cfg80211_chan_def def;
1625 int ret;
1626
1627 /* When originally vdev is started during assign_vif_chanctx() some
1628 * information is missing, notably SSID. Firmware revisions with beacon
1629 * offloading require the SSID to be provided during vdev (re)start to
1630 * handle hidden SSID properly.
1631 *
1632 * Vdev restart must be done after vdev has been both started and
1633 * upped. Otherwise some firmware revisions (at least 10.2) fail to
1634 * deliver vdev restart response event causing timeouts during vdev
1635 * syncing in ath10k.
1636 *
1637 * Note: The vdev down/up and template reinstallation could be skipped
1638 * since only wmi-tlv firmware are known to have beacon offload and
1639 * wmi-tlv doesn't seem to misbehave like 10.2 wrt vdev restart
1640 * response delivery. It's probably more robust to keep it as is.
1641 */
1642 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1643 return 0;
1644
1645 if (WARN_ON(!arvif->is_started))
1646 return -EINVAL;
1647
1648 if (WARN_ON(!arvif->is_up))
1649 return -EINVAL;
1650
1651 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
1652 return -EINVAL;
1653
1654 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1655 if (ret) {
1656 ath10k_warn(ar, "failed to bring down ap vdev %i: %d\n",
1657 arvif->vdev_id, ret);
1658 return ret;
1659 }
1660
1661 /* Vdev down reset beacon & presp templates. Reinstall them. Otherwise
1662 * firmware will crash upon vdev up.
1663 */
1664
1665 ret = ath10k_mac_setup_bcn_tmpl(arvif);
1666 if (ret) {
1667 ath10k_warn(ar, "failed to update beacon template: %d\n", ret);
1668 return ret;
1669 }
1670
1671 ret = ath10k_mac_setup_prb_tmpl(arvif);
1672 if (ret) {
1673 ath10k_warn(ar, "failed to update presp template: %d\n", ret);
1674 return ret;
1675 }
1676
1677 ret = ath10k_vdev_restart(arvif, &def);
1678 if (ret) {
1679 ath10k_warn(ar, "failed to restart ap vdev %i: %d\n",
1680 arvif->vdev_id, ret);
1681 return ret;
1682 }
1683
1684 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1685 arvif->bssid);
1686 if (ret) {
1687 ath10k_warn(ar, "failed to bring up ap vdev %i: %d\n",
1688 arvif->vdev_id, ret);
1689 return ret;
1690 }
1691
1692 return 0;
1693}
1694
Kalle Valo5e3dd152013-06-12 20:52:10 +03001695static void ath10k_control_beaconing(struct ath10k_vif *arvif,
Kalle Valo5b07e072014-09-14 12:50:06 +03001696 struct ieee80211_bss_conf *info)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001697{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001698 struct ath10k *ar = arvif->ar;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001699 int ret = 0;
1700
Michal Kazior548db542013-07-05 16:15:15 +03001701 lockdep_assert_held(&arvif->ar->conf_mutex);
1702
Kalle Valo5e3dd152013-06-12 20:52:10 +03001703 if (!info->enable_beacon) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00001704 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
1705 if (ret)
1706 ath10k_warn(ar, "failed to down vdev_id %i: %d\n",
1707 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01001708
Michal Kaziorc930f742014-01-23 11:38:25 +01001709 arvif->is_up = false;
1710
Michal Kazior748afc42014-01-23 12:48:21 +01001711 spin_lock_bh(&arvif->ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03001712 ath10k_mac_vif_beacon_free(arvif);
Michal Kazior748afc42014-01-23 12:48:21 +01001713 spin_unlock_bh(&arvif->ar->data_lock);
1714
Kalle Valo5e3dd152013-06-12 20:52:10 +03001715 return;
1716 }
1717
1718 arvif->tx_seq_no = 0x1000;
1719
Michal Kaziorc930f742014-01-23 11:38:25 +01001720 arvif->aid = 0;
Kalle Valob25f32c2014-09-14 12:50:49 +03001721 ether_addr_copy(arvif->bssid, info->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01001722
1723 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
1724 arvif->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001725 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001726 ath10k_warn(ar, "failed to bring up vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001727 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001728 return;
1729 }
Michal Kaziorc930f742014-01-23 11:38:25 +01001730
Michal Kaziorc930f742014-01-23 11:38:25 +01001731 arvif->is_up = true;
1732
Michal Kazior500ff9f2015-03-31 10:26:21 +00001733 ret = ath10k_mac_vif_fix_hidden_ssid(arvif);
1734 if (ret) {
1735 ath10k_warn(ar, "failed to fix hidden ssid for vdev %i, expect trouble: %d\n",
1736 arvif->vdev_id, ret);
1737 return;
1738 }
1739
Michal Kazior7aa7a722014-08-25 12:09:38 +02001740 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d up\n", arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001741}
1742
1743static void ath10k_control_ibss(struct ath10k_vif *arvif,
1744 struct ieee80211_bss_conf *info,
1745 const u8 self_peer[ETH_ALEN])
1746{
Michal Kazior7aa7a722014-08-25 12:09:38 +02001747 struct ath10k *ar = arvif->ar;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001748 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001749 int ret = 0;
1750
Michal Kazior548db542013-07-05 16:15:15 +03001751 lockdep_assert_held(&arvif->ar->conf_mutex);
1752
Kalle Valo5e3dd152013-06-12 20:52:10 +03001753 if (!info->ibss_joined) {
Michal Kaziorc930f742014-01-23 11:38:25 +01001754 if (is_zero_ether_addr(arvif->bssid))
Kalle Valo5e3dd152013-06-12 20:52:10 +03001755 return;
1756
Joe Perches93803b32015-03-02 19:54:49 -08001757 eth_zero_addr(arvif->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001758
1759 return;
1760 }
1761
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02001762 vdev_param = arvif->ar->wmi.vdev_param->atim_window;
1763 ret = ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03001764 ATH10K_DEFAULT_ATIM);
1765 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02001766 ath10k_warn(ar, "failed to set IBSS ATIM for vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03001767 arvif->vdev_id, ret);
1768}
1769
Michal Kazior9f9b5742014-12-12 12:41:36 +01001770static int ath10k_mac_vif_recalc_ps_wake_threshold(struct ath10k_vif *arvif)
1771{
1772 struct ath10k *ar = arvif->ar;
1773 u32 param;
1774 u32 value;
1775 int ret;
1776
1777 lockdep_assert_held(&arvif->ar->conf_mutex);
1778
1779 if (arvif->u.sta.uapsd)
1780 value = WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER;
1781 else
1782 value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS;
1783
1784 param = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD;
1785 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, value);
1786 if (ret) {
1787 ath10k_warn(ar, "failed to submit ps wake threshold %u on vdev %i: %d\n",
1788 value, arvif->vdev_id, ret);
1789 return ret;
1790 }
1791
1792 return 0;
1793}
1794
1795static int ath10k_mac_vif_recalc_ps_poll_count(struct ath10k_vif *arvif)
1796{
1797 struct ath10k *ar = arvif->ar;
1798 u32 param;
1799 u32 value;
1800 int ret;
1801
1802 lockdep_assert_held(&arvif->ar->conf_mutex);
1803
1804 if (arvif->u.sta.uapsd)
1805 value = WMI_STA_PS_PSPOLL_COUNT_UAPSD;
1806 else
1807 value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX;
1808
1809 param = WMI_STA_PS_PARAM_PSPOLL_COUNT;
1810 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
1811 param, value);
1812 if (ret) {
1813 ath10k_warn(ar, "failed to submit ps poll count %u on vdev %i: %d\n",
1814 value, arvif->vdev_id, ret);
1815 return ret;
1816 }
1817
1818 return 0;
1819}
1820
Michal Kazior424f2632015-07-09 13:08:35 +02001821static int ath10k_mac_num_vifs_started(struct ath10k *ar)
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001822{
1823 struct ath10k_vif *arvif;
1824 int num = 0;
1825
1826 lockdep_assert_held(&ar->conf_mutex);
1827
1828 list_for_each_entry(arvif, &ar->arvifs, list)
Michal Kazior424f2632015-07-09 13:08:35 +02001829 if (arvif->is_started)
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001830 num++;
1831
1832 return num;
1833}
1834
Michal Kaziorad088bf2013-10-16 15:44:46 +03001835static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
Kalle Valo5e3dd152013-06-12 20:52:10 +03001836{
Michal Kaziorad088bf2013-10-16 15:44:46 +03001837 struct ath10k *ar = arvif->ar;
Michal Kazior526549a2014-12-12 12:41:37 +01001838 struct ieee80211_vif *vif = arvif->vif;
Michal Kaziorad088bf2013-10-16 15:44:46 +03001839 struct ieee80211_conf *conf = &ar->hw->conf;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001840 enum wmi_sta_powersave_param param;
1841 enum wmi_sta_ps_mode psmode;
1842 int ret;
Michal Kazior526549a2014-12-12 12:41:37 +01001843 int ps_timeout;
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001844 bool enable_ps;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001845
Michal Kazior548db542013-07-05 16:15:15 +03001846 lockdep_assert_held(&arvif->ar->conf_mutex);
1847
Michal Kaziorad088bf2013-10-16 15:44:46 +03001848 if (arvif->vif->type != NL80211_IFTYPE_STATION)
1849 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001850
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001851 enable_ps = arvif->ps;
1852
Michal Kazior424f2632015-07-09 13:08:35 +02001853 if (enable_ps && ath10k_mac_num_vifs_started(ar) > 1 &&
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001854 !test_bit(ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT,
Kalle Valoc4cdf752016-04-20 19:45:18 +03001855 ar->running_fw->fw_file.fw_features)) {
Michal Kaziorcffb41f2015-02-13 13:30:16 +01001856 ath10k_warn(ar, "refusing to enable ps on vdev %i: not supported by fw\n",
1857 arvif->vdev_id);
1858 enable_ps = false;
1859 }
1860
Janusz Dziedzic917826b2015-05-18 09:38:17 +00001861 if (!arvif->is_started) {
1862 /* mac80211 can update vif powersave state while disconnected.
1863 * Firmware doesn't behave nicely and consumes more power than
1864 * necessary if PS is disabled on a non-started vdev. Hence
1865 * force-enable PS for non-running vdevs.
1866 */
1867 psmode = WMI_STA_PS_MODE_ENABLED;
1868 } else if (enable_ps) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03001869 psmode = WMI_STA_PS_MODE_ENABLED;
1870 param = WMI_STA_PS_PARAM_INACTIVITY_TIME;
1871
Michal Kazior526549a2014-12-12 12:41:37 +01001872 ps_timeout = conf->dynamic_ps_timeout;
1873 if (ps_timeout == 0) {
1874 /* Firmware doesn't like 0 */
1875 ps_timeout = ieee80211_tu_to_usec(
1876 vif->bss_conf.beacon_int) / 1000;
1877 }
1878
Michal Kaziorad088bf2013-10-16 15:44:46 +03001879 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param,
Michal Kazior526549a2014-12-12 12:41:37 +01001880 ps_timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03001881 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001882 ath10k_warn(ar, "failed to set inactivity time for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02001883 arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001884 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001885 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03001886 } else {
1887 psmode = WMI_STA_PS_MODE_DISABLED;
1888 }
1889
Michal Kazior7aa7a722014-08-25 12:09:38 +02001890 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d psmode %s\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03001891 arvif->vdev_id, psmode ? "enable" : "disable");
1892
Michal Kaziorad088bf2013-10-16 15:44:46 +03001893 ret = ath10k_wmi_set_psmode(ar, arvif->vdev_id, psmode);
1894 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02001895 ath10k_warn(ar, "failed to set PS Mode %d for vdev %d: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02001896 psmode, arvif->vdev_id, ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03001897 return ret;
1898 }
1899
1900 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03001901}
1902
Michal Kazior46725b12015-01-28 09:57:49 +02001903static int ath10k_mac_vif_disable_keepalive(struct ath10k_vif *arvif)
1904{
1905 struct ath10k *ar = arvif->ar;
1906 struct wmi_sta_keepalive_arg arg = {};
1907 int ret;
1908
1909 lockdep_assert_held(&arvif->ar->conf_mutex);
1910
1911 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
1912 return 0;
1913
1914 if (!test_bit(WMI_SERVICE_STA_KEEP_ALIVE, ar->wmi.svc_map))
1915 return 0;
1916
1917 /* Some firmware revisions have a bug and ignore the `enabled` field.
1918 * Instead use the interval to disable the keepalive.
1919 */
1920 arg.vdev_id = arvif->vdev_id;
1921 arg.enabled = 1;
1922 arg.method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME;
1923 arg.interval = WMI_STA_KEEPALIVE_INTERVAL_DISABLE;
1924
1925 ret = ath10k_wmi_sta_keepalive(ar, &arg);
1926 if (ret) {
1927 ath10k_warn(ar, "failed to submit keepalive on vdev %i: %d\n",
1928 arvif->vdev_id, ret);
1929 return ret;
1930 }
1931
1932 return 0;
1933}
1934
Michal Kazior81a9a172015-03-05 16:02:17 +02001935static void ath10k_mac_vif_ap_csa_count_down(struct ath10k_vif *arvif)
1936{
1937 struct ath10k *ar = arvif->ar;
1938 struct ieee80211_vif *vif = arvif->vif;
1939 int ret;
1940
Michal Kazior8513d952015-03-09 14:19:24 +01001941 lockdep_assert_held(&arvif->ar->conf_mutex);
1942
1943 if (WARN_ON(!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)))
1944 return;
1945
Michal Kazior81a9a172015-03-05 16:02:17 +02001946 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
1947 return;
1948
1949 if (!vif->csa_active)
1950 return;
1951
1952 if (!arvif->is_up)
1953 return;
1954
1955 if (!ieee80211_csa_is_complete(vif)) {
1956 ieee80211_csa_update_counter(vif);
1957
1958 ret = ath10k_mac_setup_bcn_tmpl(arvif);
1959 if (ret)
1960 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
1961 ret);
1962
1963 ret = ath10k_mac_setup_prb_tmpl(arvif);
1964 if (ret)
1965 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
1966 ret);
1967 } else {
1968 ieee80211_csa_finish(vif);
1969 }
1970}
1971
1972static void ath10k_mac_vif_ap_csa_work(struct work_struct *work)
1973{
1974 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
1975 ap_csa_work);
1976 struct ath10k *ar = arvif->ar;
1977
1978 mutex_lock(&ar->conf_mutex);
1979 ath10k_mac_vif_ap_csa_count_down(arvif);
1980 mutex_unlock(&ar->conf_mutex);
1981}
1982
Michal Kaziorcc9904e2015-03-10 16:22:01 +02001983static void ath10k_mac_handle_beacon_iter(void *data, u8 *mac,
1984 struct ieee80211_vif *vif)
1985{
1986 struct sk_buff *skb = data;
1987 struct ieee80211_mgmt *mgmt = (void *)skb->data;
1988 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1989
1990 if (vif->type != NL80211_IFTYPE_STATION)
1991 return;
1992
1993 if (!ether_addr_equal(mgmt->bssid, vif->bss_conf.bssid))
1994 return;
1995
1996 cancel_delayed_work(&arvif->connection_loss_work);
1997}
1998
1999void ath10k_mac_handle_beacon(struct ath10k *ar, struct sk_buff *skb)
2000{
2001 ieee80211_iterate_active_interfaces_atomic(ar->hw,
2002 IEEE80211_IFACE_ITER_NORMAL,
2003 ath10k_mac_handle_beacon_iter,
2004 skb);
2005}
2006
2007static void ath10k_mac_handle_beacon_miss_iter(void *data, u8 *mac,
2008 struct ieee80211_vif *vif)
2009{
2010 u32 *vdev_id = data;
2011 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2012 struct ath10k *ar = arvif->ar;
2013 struct ieee80211_hw *hw = ar->hw;
2014
2015 if (arvif->vdev_id != *vdev_id)
2016 return;
2017
2018 if (!arvif->is_up)
2019 return;
2020
2021 ieee80211_beacon_loss(vif);
2022
2023 /* Firmware doesn't report beacon loss events repeatedly. If AP probe
2024 * (done by mac80211) succeeds but beacons do not resume then it
2025 * doesn't make sense to continue operation. Queue connection loss work
2026 * which can be cancelled when beacon is received.
2027 */
2028 ieee80211_queue_delayed_work(hw, &arvif->connection_loss_work,
2029 ATH10K_CONNECTION_LOSS_HZ);
2030}
2031
2032void ath10k_mac_handle_beacon_miss(struct ath10k *ar, u32 vdev_id)
2033{
2034 ieee80211_iterate_active_interfaces_atomic(ar->hw,
2035 IEEE80211_IFACE_ITER_NORMAL,
2036 ath10k_mac_handle_beacon_miss_iter,
2037 &vdev_id);
2038}
2039
2040static void ath10k_mac_vif_sta_connection_loss_work(struct work_struct *work)
2041{
2042 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
2043 connection_loss_work.work);
2044 struct ieee80211_vif *vif = arvif->vif;
2045
2046 if (!arvif->is_up)
2047 return;
2048
2049 ieee80211_connection_loss(vif);
2050}
2051
Kalle Valo5e3dd152013-06-12 20:52:10 +03002052/**********************/
2053/* Station management */
2054/**********************/
2055
Michal Kazior590922a2014-10-21 10:10:29 +03002056static u32 ath10k_peer_assoc_h_listen_intval(struct ath10k *ar,
2057 struct ieee80211_vif *vif)
2058{
2059 /* Some firmware revisions have unstable STA powersave when listen
2060 * interval is set too high (e.g. 5). The symptoms are firmware doesn't
2061 * generate NullFunc frames properly even if buffered frames have been
2062 * indicated in Beacon TIM. Firmware would seldom wake up to pull
2063 * buffered frames. Often pinging the device from AP would simply fail.
2064 *
2065 * As a workaround set it to 1.
2066 */
2067 if (vif->type == NL80211_IFTYPE_STATION)
2068 return 1;
2069
2070 return ar->hw->conf.listen_interval;
2071}
2072
Kalle Valo5e3dd152013-06-12 20:52:10 +03002073static void ath10k_peer_assoc_h_basic(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002074 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002075 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002076 struct wmi_peer_assoc_complete_arg *arg)
2077{
Michal Kazior590922a2014-10-21 10:10:29 +03002078 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorc51880e2015-03-30 09:51:57 +03002079 u32 aid;
Michal Kazior590922a2014-10-21 10:10:29 +03002080
Michal Kazior548db542013-07-05 16:15:15 +03002081 lockdep_assert_held(&ar->conf_mutex);
2082
Michal Kaziorc51880e2015-03-30 09:51:57 +03002083 if (vif->type == NL80211_IFTYPE_STATION)
2084 aid = vif->bss_conf.aid;
2085 else
2086 aid = sta->aid;
2087
Kalle Valob25f32c2014-09-14 12:50:49 +03002088 ether_addr_copy(arg->addr, sta->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002089 arg->vdev_id = arvif->vdev_id;
Michal Kaziorc51880e2015-03-30 09:51:57 +03002090 arg->peer_aid = aid;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002091 arg->peer_flags |= arvif->ar->wmi.peer_flags->auth;
Michal Kazior590922a2014-10-21 10:10:29 +03002092 arg->peer_listen_intval = ath10k_peer_assoc_h_listen_intval(ar, vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002093 arg->peer_num_spatial_streams = 1;
Michal Kazior590922a2014-10-21 10:10:29 +03002094 arg->peer_caps = vif->bss_conf.assoc_capability;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002095}
2096
2097static void ath10k_peer_assoc_h_crypto(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002098 struct ieee80211_vif *vif,
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002099 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002100 struct wmi_peer_assoc_complete_arg *arg)
2101{
Kalle Valo5e3dd152013-06-12 20:52:10 +03002102 struct ieee80211_bss_conf *info = &vif->bss_conf;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002103 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002104 struct cfg80211_bss *bss;
2105 const u8 *rsnie = NULL;
2106 const u8 *wpaie = NULL;
2107
Michal Kazior548db542013-07-05 16:15:15 +03002108 lockdep_assert_held(&ar->conf_mutex);
2109
Michal Kazior500ff9f2015-03-31 10:26:21 +00002110 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2111 return;
2112
2113 bss = cfg80211_get_bss(ar->hw->wiphy, def.chan, info->bssid, NULL, 0,
2114 IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002115 if (bss) {
2116 const struct cfg80211_bss_ies *ies;
2117
2118 rcu_read_lock();
2119 rsnie = ieee80211_bss_get_ie(bss, WLAN_EID_RSN);
2120
2121 ies = rcu_dereference(bss->ies);
2122
2123 wpaie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
Kalle Valo5b07e072014-09-14 12:50:06 +03002124 WLAN_OUI_TYPE_MICROSOFT_WPA,
2125 ies->data,
2126 ies->len);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002127 rcu_read_unlock();
2128 cfg80211_put_bss(ar->hw->wiphy, bss);
2129 }
2130
2131 /* FIXME: base on RSN IE/WPA IE is a correct idea? */
2132 if (rsnie || wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002133 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: rsn ie found\n", __func__);
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002134 arg->peer_flags |= ar->wmi.peer_flags->need_ptk_4_way;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002135 }
2136
2137 if (wpaie) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002138 ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: wpa ie found\n", __func__);
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002139 arg->peer_flags |= ar->wmi.peer_flags->need_gtk_2_way;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002140 }
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002141
2142 if (sta->mfp &&
Kalle Valoc4cdf752016-04-20 19:45:18 +03002143 test_bit(ATH10K_FW_FEATURE_MFP_SUPPORT,
2144 ar->running_fw->fw_file.fw_features)) {
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002145 arg->peer_flags |= ar->wmi.peer_flags->pmf;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002146 }
2147}
2148
2149static void ath10k_peer_assoc_h_rates(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002150 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002151 struct ieee80211_sta *sta,
2152 struct wmi_peer_assoc_complete_arg *arg)
2153{
Michal Kazior45c9abc2015-04-21 20:42:58 +03002154 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002155 struct wmi_rate_set_arg *rateset = &arg->peer_legacy_rates;
Michal Kazior500ff9f2015-03-31 10:26:21 +00002156 struct cfg80211_chan_def def;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002157 const struct ieee80211_supported_band *sband;
2158 const struct ieee80211_rate *rates;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002159 enum nl80211_band band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002160 u32 ratemask;
Michal Kazior486017c2015-03-30 09:51:54 +03002161 u8 rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002162 int i;
2163
Michal Kazior548db542013-07-05 16:15:15 +03002164 lockdep_assert_held(&ar->conf_mutex);
2165
Michal Kazior500ff9f2015-03-31 10:26:21 +00002166 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2167 return;
2168
Michal Kazior45c9abc2015-04-21 20:42:58 +03002169 band = def.chan->band;
2170 sband = ar->hw->wiphy->bands[band];
2171 ratemask = sta->supp_rates[band];
2172 ratemask &= arvif->bitrate_mask.control[band].legacy;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002173 rates = sband->bitrates;
2174
2175 rateset->num_rates = 0;
2176
2177 for (i = 0; i < 32; i++, ratemask >>= 1, rates++) {
2178 if (!(ratemask & 1))
2179 continue;
2180
Michal Kazior486017c2015-03-30 09:51:54 +03002181 rate = ath10k_mac_bitrate_to_rate(rates->bitrate);
2182 rateset->rates[rateset->num_rates] = rate;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002183 rateset->num_rates++;
2184 }
2185}
2186
Michal Kazior45c9abc2015-04-21 20:42:58 +03002187static bool
2188ath10k_peer_assoc_h_ht_masked(const u8 ht_mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
2189{
2190 int nss;
2191
2192 for (nss = 0; nss < IEEE80211_HT_MCS_MASK_LEN; nss++)
2193 if (ht_mcs_mask[nss])
2194 return false;
2195
2196 return true;
2197}
2198
2199static bool
2200ath10k_peer_assoc_h_vht_masked(const u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
2201{
2202 int nss;
2203
2204 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++)
2205 if (vht_mcs_mask[nss])
2206 return false;
2207
2208 return true;
2209}
2210
Kalle Valo5e3dd152013-06-12 20:52:10 +03002211static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
Michal Kazior45c9abc2015-04-21 20:42:58 +03002212 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002213 struct ieee80211_sta *sta,
2214 struct wmi_peer_assoc_complete_arg *arg)
2215{
2216 const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002217 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2218 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002219 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002220 const u8 *ht_mcs_mask;
2221 const u16 *vht_mcs_mask;
Vivek Natarajan72f8cef2015-10-06 15:19:34 +03002222 int i, n;
2223 u8 max_nss;
Kalle Valoaf762c02014-09-14 12:50:17 +03002224 u32 stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002225
Michal Kazior548db542013-07-05 16:15:15 +03002226 lockdep_assert_held(&ar->conf_mutex);
2227
Michal Kazior45c9abc2015-04-21 20:42:58 +03002228 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2229 return;
2230
Kalle Valo5e3dd152013-06-12 20:52:10 +03002231 if (!ht_cap->ht_supported)
2232 return;
2233
Michal Kazior45c9abc2015-04-21 20:42:58 +03002234 band = def.chan->band;
2235 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
2236 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2237
2238 if (ath10k_peer_assoc_h_ht_masked(ht_mcs_mask) &&
2239 ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
2240 return;
2241
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002242 arg->peer_flags |= ar->wmi.peer_flags->ht;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002243 arg->peer_max_mpdu = (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2244 ht_cap->ampdu_factor)) - 1;
2245
2246 arg->peer_mpdu_density =
2247 ath10k_parse_mpdudensity(ht_cap->ampdu_density);
2248
2249 arg->peer_ht_caps = ht_cap->cap;
2250 arg->peer_rate_caps |= WMI_RC_HT_FLAG;
2251
2252 if (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002253 arg->peer_flags |= ar->wmi.peer_flags->ldbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002254
2255 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) {
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002256 arg->peer_flags |= ar->wmi.peer_flags->bw40;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002257 arg->peer_rate_caps |= WMI_RC_CW40_FLAG;
2258 }
2259
Michal Kazior45c9abc2015-04-21 20:42:58 +03002260 if (arvif->bitrate_mask.control[band].gi != NL80211_TXRATE_FORCE_LGI) {
2261 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
2262 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002263
Michal Kazior45c9abc2015-04-21 20:42:58 +03002264 if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40)
2265 arg->peer_rate_caps |= WMI_RC_SGI_FLAG;
2266 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002267
2268 if (ht_cap->cap & IEEE80211_HT_CAP_TX_STBC) {
2269 arg->peer_rate_caps |= WMI_RC_TX_STBC_FLAG;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002270 arg->peer_flags |= ar->wmi.peer_flags->stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002271 }
2272
2273 if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002274 stbc = ht_cap->cap & IEEE80211_HT_CAP_RX_STBC;
2275 stbc = stbc >> IEEE80211_HT_CAP_RX_STBC_SHIFT;
2276 stbc = stbc << WMI_RC_RX_STBC_FLAG_S;
2277 arg->peer_rate_caps |= stbc;
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002278 arg->peer_flags |= ar->wmi.peer_flags->stbc;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002279 }
2280
Kalle Valo5e3dd152013-06-12 20:52:10 +03002281 if (ht_cap->mcs.rx_mask[1] && ht_cap->mcs.rx_mask[2])
2282 arg->peer_rate_caps |= WMI_RC_TS_FLAG;
2283 else if (ht_cap->mcs.rx_mask[1])
2284 arg->peer_rate_caps |= WMI_RC_DS_FLAG;
2285
Michal Kazior45c9abc2015-04-21 20:42:58 +03002286 for (i = 0, n = 0, max_nss = 0; i < IEEE80211_HT_MCS_MASK_LEN * 8; i++)
2287 if ((ht_cap->mcs.rx_mask[i / 8] & BIT(i % 8)) &&
2288 (ht_mcs_mask[i / 8] & BIT(i % 8))) {
2289 max_nss = (i / 8) + 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002290 arg->peer_ht_rates.rates[n++] = i;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002291 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002292
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002293 /*
2294 * This is a workaround for HT-enabled STAs which break the spec
2295 * and have no HT capabilities RX mask (no HT RX MCS map).
2296 *
2297 * As per spec, in section 20.3.5 Modulation and coding scheme (MCS),
2298 * MCS 0 through 7 are mandatory in 20MHz with 800 ns GI at all STAs.
2299 *
2300 * Firmware asserts if such situation occurs.
2301 */
2302 if (n == 0) {
2303 arg->peer_ht_rates.num_rates = 8;
2304 for (i = 0; i < arg->peer_ht_rates.num_rates; i++)
2305 arg->peer_ht_rates.rates[i] = i;
2306 } else {
2307 arg->peer_ht_rates.num_rates = n;
Vivek Natarajan72f8cef2015-10-06 15:19:34 +03002308 arg->peer_num_spatial_streams = min(sta->rx_nss, max_nss);
Bartosz Markowskifd71f802014-02-10 13:12:55 +01002309 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002310
Michal Kazior7aa7a722014-08-25 12:09:38 +02002311 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002312 arg->addr,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002313 arg->peer_ht_rates.num_rates,
2314 arg->peer_num_spatial_streams);
2315}
2316
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002317static int ath10k_peer_assoc_qos_ap(struct ath10k *ar,
2318 struct ath10k_vif *arvif,
2319 struct ieee80211_sta *sta)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002320{
2321 u32 uapsd = 0;
2322 u32 max_sp = 0;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002323 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002324
Michal Kazior548db542013-07-05 16:15:15 +03002325 lockdep_assert_held(&ar->conf_mutex);
2326
Kalle Valo5e3dd152013-06-12 20:52:10 +03002327 if (sta->wme && sta->uapsd_queues) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002328 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac uapsd_queues 0x%x max_sp %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002329 sta->uapsd_queues, sta->max_sp);
2330
Kalle Valo5e3dd152013-06-12 20:52:10 +03002331 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
2332 uapsd |= WMI_AP_PS_UAPSD_AC3_DELIVERY_EN |
2333 WMI_AP_PS_UAPSD_AC3_TRIGGER_EN;
2334 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
2335 uapsd |= WMI_AP_PS_UAPSD_AC2_DELIVERY_EN |
2336 WMI_AP_PS_UAPSD_AC2_TRIGGER_EN;
2337 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
2338 uapsd |= WMI_AP_PS_UAPSD_AC1_DELIVERY_EN |
2339 WMI_AP_PS_UAPSD_AC1_TRIGGER_EN;
2340 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
2341 uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN |
2342 WMI_AP_PS_UAPSD_AC0_TRIGGER_EN;
2343
Kalle Valo5e3dd152013-06-12 20:52:10 +03002344 if (sta->max_sp < MAX_WMI_AP_PS_PEER_PARAM_MAX_SP)
2345 max_sp = sta->max_sp;
2346
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002347 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2348 sta->addr,
2349 WMI_AP_PS_PEER_PARAM_UAPSD,
2350 uapsd);
2351 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002352 ath10k_warn(ar, "failed to set ap ps peer param uapsd for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002353 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002354 return ret;
2355 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002356
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002357 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id,
2358 sta->addr,
2359 WMI_AP_PS_PEER_PARAM_MAX_SP,
2360 max_sp);
2361 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002362 ath10k_warn(ar, "failed to set ap ps peer param max sp for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002363 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002364 return ret;
2365 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002366
2367 /* TODO setup this based on STA listen interval and
2368 beacon interval. Currently we don't know
2369 sta->listen_interval - mac80211 patch required.
2370 Currently use 10 seconds */
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002371 ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, sta->addr,
Kalle Valo5b07e072014-09-14 12:50:06 +03002372 WMI_AP_PS_PEER_PARAM_AGEOUT_TIME,
2373 10);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002374 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002375 ath10k_warn(ar, "failed to set ap ps peer param ageout time for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002376 arvif->vdev_id, ret);
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002377 return ret;
2378 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002379 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002380
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002381 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002382}
2383
Michal Kazior45c9abc2015-04-21 20:42:58 +03002384static u16
2385ath10k_peer_assoc_h_vht_limit(u16 tx_mcs_set,
2386 const u16 vht_mcs_limit[NL80211_VHT_NSS_MAX])
2387{
2388 int idx_limit;
2389 int nss;
2390 u16 mcs_map;
2391 u16 mcs;
2392
2393 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {
2394 mcs_map = ath10k_mac_get_max_vht_mcs_map(tx_mcs_set, nss) &
2395 vht_mcs_limit[nss];
2396
2397 if (mcs_map)
2398 idx_limit = fls(mcs_map) - 1;
2399 else
2400 idx_limit = -1;
2401
2402 switch (idx_limit) {
2403 case 0: /* fall through */
2404 case 1: /* fall through */
2405 case 2: /* fall through */
2406 case 3: /* fall through */
2407 case 4: /* fall through */
2408 case 5: /* fall through */
2409 case 6: /* fall through */
2410 default:
2411 /* see ath10k_mac_can_set_bitrate_mask() */
2412 WARN_ON(1);
2413 /* fall through */
2414 case -1:
2415 mcs = IEEE80211_VHT_MCS_NOT_SUPPORTED;
2416 break;
2417 case 7:
2418 mcs = IEEE80211_VHT_MCS_SUPPORT_0_7;
2419 break;
2420 case 8:
2421 mcs = IEEE80211_VHT_MCS_SUPPORT_0_8;
2422 break;
2423 case 9:
2424 mcs = IEEE80211_VHT_MCS_SUPPORT_0_9;
2425 break;
2426 }
2427
2428 tx_mcs_set &= ~(0x3 << (nss * 2));
2429 tx_mcs_set |= mcs << (nss * 2);
2430 }
2431
2432 return tx_mcs_set;
2433}
2434
Kalle Valo5e3dd152013-06-12 20:52:10 +03002435static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
Michal Kazior500ff9f2015-03-31 10:26:21 +00002436 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002437 struct ieee80211_sta *sta,
2438 struct wmi_peer_assoc_complete_arg *arg)
2439{
2440 const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002441 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002442 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002443 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002444 const u16 *vht_mcs_mask;
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002445 u8 ampdu_factor;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002446
Michal Kazior500ff9f2015-03-31 10:26:21 +00002447 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2448 return;
2449
Kalle Valo5e3dd152013-06-12 20:52:10 +03002450 if (!vht_cap->vht_supported)
2451 return;
2452
Michal Kazior45c9abc2015-04-21 20:42:58 +03002453 band = def.chan->band;
2454 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2455
2456 if (ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
2457 return;
2458
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002459 arg->peer_flags |= ar->wmi.peer_flags->vht;
Yanbo Lid68bb122015-01-23 08:18:20 +08002460
Johannes Berg57fbcce2016-04-12 15:56:15 +02002461 if (def.chan->band == NL80211_BAND_2GHZ)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002462 arg->peer_flags |= ar->wmi.peer_flags->vht_2g;
Yanbo Lid68bb122015-01-23 08:18:20 +08002463
Kalle Valo5e3dd152013-06-12 20:52:10 +03002464 arg->peer_vht_caps = vht_cap->cap;
2465
Sujith Manoharana24b88b2013-10-07 19:51:57 -07002466 ampdu_factor = (vht_cap->cap &
2467 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) >>
2468 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
2469
2470 /* Workaround: Some Netgear/Linksys 11ac APs set Rx A-MPDU factor to
2471 * zero in VHT IE. Using it would result in degraded throughput.
2472 * arg->peer_max_mpdu at this point contains HT max_mpdu so keep
2473 * it if VHT max_mpdu is smaller. */
2474 arg->peer_max_mpdu = max(arg->peer_max_mpdu,
2475 (1U << (IEEE80211_HT_MAX_AMPDU_FACTOR +
2476 ampdu_factor)) - 1);
2477
Kalle Valo5e3dd152013-06-12 20:52:10 +03002478 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002479 arg->peer_flags |= ar->wmi.peer_flags->bw80;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002480
2481 arg->peer_vht_rates.rx_max_rate =
2482 __le16_to_cpu(vht_cap->vht_mcs.rx_highest);
2483 arg->peer_vht_rates.rx_mcs_set =
2484 __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map);
2485 arg->peer_vht_rates.tx_max_rate =
2486 __le16_to_cpu(vht_cap->vht_mcs.tx_highest);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002487 arg->peer_vht_rates.tx_mcs_set = ath10k_peer_assoc_h_vht_limit(
2488 __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002489
Michal Kazior7aa7a722014-08-25 12:09:38 +02002490 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03002491 sta->addr, arg->peer_max_mpdu, arg->peer_flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002492}
2493
2494static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002495 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002496 struct ieee80211_sta *sta,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002497 struct wmi_peer_assoc_complete_arg *arg)
2498{
Michal Kazior590922a2014-10-21 10:10:29 +03002499 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2500
Kalle Valo5e3dd152013-06-12 20:52:10 +03002501 switch (arvif->vdev_type) {
2502 case WMI_VDEV_TYPE_AP:
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002503 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002504 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002505
2506 if (sta->wme && sta->uapsd_queues) {
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002507 arg->peer_flags |= arvif->ar->wmi.peer_flags->apsd;
Janusz Dziedzicd3d3ff42014-01-21 07:06:53 +01002508 arg->peer_rate_caps |= WMI_RC_UAPSD_FLAG;
2509 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002510 break;
2511 case WMI_VDEV_TYPE_STA:
Balaji Pothunooribb327722017-12-07 16:58:04 +02002512 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002513 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002514 break;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002515 case WMI_VDEV_TYPE_IBSS:
2516 if (sta->wme)
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002517 arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002518 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002519 default:
2520 break;
2521 }
Janusz Dziedzic627d9842014-12-17 12:29:54 +02002522
2523 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM qos %d\n",
Tamizh chelvam3fab30f2015-10-29 14:27:37 +02002524 sta->addr, !!(arg->peer_flags &
2525 arvif->ar->wmi.peer_flags->qos));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002526}
2527
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002528static bool ath10k_mac_sta_has_ofdm_only(struct ieee80211_sta *sta)
Michal Kazior91b12082014-12-12 12:41:35 +01002529{
Johannes Berg57fbcce2016-04-12 15:56:15 +02002530 return sta->supp_rates[NL80211_BAND_2GHZ] >>
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002531 ATH10K_MAC_FIRST_OFDM_RATE_IDX;
Michal Kazior91b12082014-12-12 12:41:35 +01002532}
2533
Kalle Valo5e3dd152013-06-12 20:52:10 +03002534static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002535 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002536 struct ieee80211_sta *sta,
2537 struct wmi_peer_assoc_complete_arg *arg)
2538{
Michal Kazior45c9abc2015-04-21 20:42:58 +03002539 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002540 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002541 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002542 const u8 *ht_mcs_mask;
2543 const u16 *vht_mcs_mask;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002544 enum wmi_phy_mode phymode = MODE_UNKNOWN;
2545
Michal Kazior500ff9f2015-03-31 10:26:21 +00002546 if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
2547 return;
2548
Michal Kazior45c9abc2015-04-21 20:42:58 +03002549 band = def.chan->band;
2550 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
2551 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
2552
2553 switch (band) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02002554 case NL80211_BAND_2GHZ:
Michal Kazior45c9abc2015-04-21 20:42:58 +03002555 if (sta->vht_cap.vht_supported &&
2556 !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
Yanbo Lid68bb122015-01-23 08:18:20 +08002557 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2558 phymode = MODE_11AC_VHT40;
2559 else
2560 phymode = MODE_11AC_VHT20;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002561 } else if (sta->ht_cap.ht_supported &&
2562 !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002563 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2564 phymode = MODE_11NG_HT40;
2565 else
2566 phymode = MODE_11NG_HT20;
Michal Kazior8d7aa6b2015-03-30 09:51:57 +03002567 } else if (ath10k_mac_sta_has_ofdm_only(sta)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002568 phymode = MODE_11G;
Michal Kazior91b12082014-12-12 12:41:35 +01002569 } else {
2570 phymode = MODE_11B;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002571 }
2572
2573 break;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002574 case NL80211_BAND_5GHZ:
Sujith Manoharan7cc45e92013-09-08 18:19:55 +03002575 /*
2576 * Check VHT first.
2577 */
Michal Kazior45c9abc2015-04-21 20:42:58 +03002578 if (sta->vht_cap.vht_supported &&
2579 !ath10k_peer_assoc_h_vht_masked(vht_mcs_mask)) {
Sujith Manoharan7cc45e92013-09-08 18:19:55 +03002580 if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
2581 phymode = MODE_11AC_VHT80;
2582 else if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
2583 phymode = MODE_11AC_VHT40;
2584 else if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
2585 phymode = MODE_11AC_VHT20;
Michal Kazior45c9abc2015-04-21 20:42:58 +03002586 } else if (sta->ht_cap.ht_supported &&
2587 !ath10k_peer_assoc_h_ht_masked(ht_mcs_mask)) {
2588 if (sta->bandwidth >= IEEE80211_STA_RX_BW_40)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002589 phymode = MODE_11NA_HT40;
2590 else
2591 phymode = MODE_11NA_HT20;
2592 } else {
2593 phymode = MODE_11A;
2594 }
2595
2596 break;
2597 default:
2598 break;
2599 }
2600
Michal Kazior7aa7a722014-08-25 12:09:38 +02002601 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM phymode %s\n",
Kalle Valo38a1d472013-09-08 17:56:14 +03002602 sta->addr, ath10k_wmi_phymode_str(phymode));
Kalle Valo60c3daa2013-09-08 17:56:07 +03002603
Kalle Valo5e3dd152013-06-12 20:52:10 +03002604 arg->peer_phymode = phymode;
2605 WARN_ON(phymode == MODE_UNKNOWN);
2606}
2607
Kalle Valob9ada652013-10-16 15:44:46 +03002608static int ath10k_peer_assoc_prepare(struct ath10k *ar,
Michal Kazior590922a2014-10-21 10:10:29 +03002609 struct ieee80211_vif *vif,
Kalle Valob9ada652013-10-16 15:44:46 +03002610 struct ieee80211_sta *sta,
Kalle Valob9ada652013-10-16 15:44:46 +03002611 struct wmi_peer_assoc_complete_arg *arg)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002612{
Michal Kazior548db542013-07-05 16:15:15 +03002613 lockdep_assert_held(&ar->conf_mutex);
2614
Kalle Valob9ada652013-10-16 15:44:46 +03002615 memset(arg, 0, sizeof(*arg));
Kalle Valo5e3dd152013-06-12 20:52:10 +03002616
Michal Kazior590922a2014-10-21 10:10:29 +03002617 ath10k_peer_assoc_h_basic(ar, vif, sta, arg);
Tamizh chelvam90eceb32015-10-29 14:27:42 +02002618 ath10k_peer_assoc_h_crypto(ar, vif, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002619 ath10k_peer_assoc_h_rates(ar, vif, sta, arg);
Michal Kazior45c9abc2015-04-21 20:42:58 +03002620 ath10k_peer_assoc_h_ht(ar, vif, sta, arg);
Michal Kazior500ff9f2015-03-31 10:26:21 +00002621 ath10k_peer_assoc_h_vht(ar, vif, sta, arg);
Michal Kazior590922a2014-10-21 10:10:29 +03002622 ath10k_peer_assoc_h_qos(ar, vif, sta, arg);
2623 ath10k_peer_assoc_h_phymode(ar, vif, sta, arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002624
Kalle Valob9ada652013-10-16 15:44:46 +03002625 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002626}
2627
Michal Kazior90046f52014-02-14 14:45:51 +01002628static const u32 ath10k_smps_map[] = {
2629 [WLAN_HT_CAP_SM_PS_STATIC] = WMI_PEER_SMPS_STATIC,
2630 [WLAN_HT_CAP_SM_PS_DYNAMIC] = WMI_PEER_SMPS_DYNAMIC,
2631 [WLAN_HT_CAP_SM_PS_INVALID] = WMI_PEER_SMPS_PS_NONE,
2632 [WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE,
2633};
2634
2635static int ath10k_setup_peer_smps(struct ath10k *ar, struct ath10k_vif *arvif,
2636 const u8 *addr,
2637 const struct ieee80211_sta_ht_cap *ht_cap)
2638{
2639 int smps;
2640
2641 if (!ht_cap->ht_supported)
2642 return 0;
2643
2644 smps = ht_cap->cap & IEEE80211_HT_CAP_SM_PS;
2645 smps >>= IEEE80211_HT_CAP_SM_PS_SHIFT;
2646
2647 if (smps >= ARRAY_SIZE(ath10k_smps_map))
2648 return -EINVAL;
2649
2650 return ath10k_wmi_peer_set_param(ar, arvif->vdev_id, addr,
2651 WMI_PEER_SMPS_STATE,
2652 ath10k_smps_map[smps]);
2653}
2654
Michal Kazior139e1702015-02-15 16:50:42 +02002655static int ath10k_mac_vif_recalc_txbf(struct ath10k *ar,
2656 struct ieee80211_vif *vif,
2657 struct ieee80211_sta_vht_cap vht_cap)
2658{
2659 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
2660 int ret;
2661 u32 param;
2662 u32 value;
2663
Vivek Natarajan08e75ea2015-08-04 10:45:11 +05302664 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_AFTER_ASSOC)
2665 return 0;
2666
Michal Kazior139e1702015-02-15 16:50:42 +02002667 if (!(ar->vht_cap_info &
2668 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2669 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
2670 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2671 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)))
2672 return 0;
2673
2674 param = ar->wmi.vdev_param->txbf;
2675 value = 0;
2676
2677 if (WARN_ON(param == WMI_VDEV_PARAM_UNSUPPORTED))
2678 return 0;
2679
2680 /* The following logic is correct. If a remote STA advertises support
2681 * for being a beamformer then we should enable us being a beamformee.
2682 */
2683
2684 if (ar->vht_cap_info &
2685 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
2686 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
2687 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
2688 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2689
2690 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
2691 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFEE;
2692 }
2693
2694 if (ar->vht_cap_info &
2695 (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
2696 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
2697 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
2698 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2699
2700 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
2701 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFER;
2702 }
2703
2704 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFEE)
2705 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
2706
2707 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFER)
2708 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
2709
2710 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, value);
2711 if (ret) {
2712 ath10k_warn(ar, "failed to submit vdev param txbf 0x%x: %d\n",
2713 value, ret);
2714 return ret;
2715 }
2716
2717 return 0;
2718}
2719
Kalle Valo5e3dd152013-06-12 20:52:10 +03002720/* can be called only in mac80211 callbacks due to `key_count` usage */
2721static void ath10k_bss_assoc(struct ieee80211_hw *hw,
2722 struct ieee80211_vif *vif,
2723 struct ieee80211_bss_conf *bss_conf)
2724{
2725 struct ath10k *ar = hw->priv;
2726 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior90046f52014-02-14 14:45:51 +01002727 struct ieee80211_sta_ht_cap ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002728 struct ieee80211_sta_vht_cap vht_cap;
Kalle Valob9ada652013-10-16 15:44:46 +03002729 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002730 struct ieee80211_sta *ap_sta;
2731 int ret;
2732
Michal Kazior548db542013-07-05 16:15:15 +03002733 lockdep_assert_held(&ar->conf_mutex);
2734
Michal Kazior077efc82014-10-21 10:10:29 +03002735 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i assoc bssid %pM aid %d\n",
2736 arvif->vdev_id, arvif->bssid, arvif->aid);
2737
Kalle Valo5e3dd152013-06-12 20:52:10 +03002738 rcu_read_lock();
2739
2740 ap_sta = ieee80211_find_sta(vif, bss_conf->bssid);
2741 if (!ap_sta) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002742 ath10k_warn(ar, "failed to find station entry for bss %pM vdev %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002743 bss_conf->bssid, arvif->vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002744 rcu_read_unlock();
2745 return;
2746 }
2747
Michal Kazior90046f52014-02-14 14:45:51 +01002748 /* ap_sta must be accessed only within rcu section which must be left
2749 * before calling ath10k_setup_peer_smps() which might sleep. */
2750 ht_cap = ap_sta->ht_cap;
Michal Kazior139e1702015-02-15 16:50:42 +02002751 vht_cap = ap_sta->vht_cap;
Michal Kazior90046f52014-02-14 14:45:51 +01002752
Michal Kazior590922a2014-10-21 10:10:29 +03002753 ret = ath10k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002754 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002755 ath10k_warn(ar, "failed to prepare peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002756 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002757 rcu_read_unlock();
2758 return;
2759 }
2760
2761 rcu_read_unlock();
2762
Kalle Valob9ada652013-10-16 15:44:46 +03002763 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2764 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002765 ath10k_warn(ar, "failed to run peer assoc for %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002766 bss_conf->bssid, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002767 return;
2768 }
2769
Michal Kazior90046f52014-02-14 14:45:51 +01002770 ret = ath10k_setup_peer_smps(ar, arvif, bss_conf->bssid, &ht_cap);
2771 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002772 ath10k_warn(ar, "failed to setup peer SMPS for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002773 arvif->vdev_id, ret);
Michal Kazior90046f52014-02-14 14:45:51 +01002774 return;
2775 }
2776
Michal Kazior139e1702015-02-15 16:50:42 +02002777 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2778 if (ret) {
2779 ath10k_warn(ar, "failed to recalc txbf for vdev %i on bss %pM: %d\n",
2780 arvif->vdev_id, bss_conf->bssid, ret);
2781 return;
2782 }
2783
Michal Kazior7aa7a722014-08-25 12:09:38 +02002784 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03002785 "mac vdev %d up (associated) bssid %pM aid %d\n",
2786 arvif->vdev_id, bss_conf->bssid, bss_conf->aid);
2787
Michal Kazior077efc82014-10-21 10:10:29 +03002788 WARN_ON(arvif->is_up);
2789
Michal Kaziorc930f742014-01-23 11:38:25 +01002790 arvif->aid = bss_conf->aid;
Kalle Valob25f32c2014-09-14 12:50:49 +03002791 ether_addr_copy(arvif->bssid, bss_conf->bssid);
Michal Kaziorc930f742014-01-23 11:38:25 +01002792
2793 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid);
2794 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002795 ath10k_warn(ar, "failed to set vdev %d up: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03002796 arvif->vdev_id, ret);
Michal Kaziorc930f742014-01-23 11:38:25 +01002797 return;
2798 }
2799
2800 arvif->is_up = true;
Michal Kazior0a987fb2015-02-13 13:30:15 +01002801
2802 /* Workaround: Some firmware revisions (tested with qca6174
2803 * WLAN.RM.2.0-00073) have buggy powersave state machine and must be
2804 * poked with peer param command.
2805 */
2806 ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, arvif->bssid,
2807 WMI_PEER_DUMMY_VAR, 1);
2808 if (ret) {
2809 ath10k_warn(ar, "failed to poke peer %pM param for ps workaround on vdev %i: %d\n",
2810 arvif->bssid, arvif->vdev_id, ret);
2811 return;
2812 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002813}
2814
Kalle Valo5e3dd152013-06-12 20:52:10 +03002815static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
2816 struct ieee80211_vif *vif)
2817{
2818 struct ath10k *ar = hw->priv;
2819 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior139e1702015-02-15 16:50:42 +02002820 struct ieee80211_sta_vht_cap vht_cap = {};
Kalle Valo5e3dd152013-06-12 20:52:10 +03002821 int ret;
2822
Michal Kazior548db542013-07-05 16:15:15 +03002823 lockdep_assert_held(&ar->conf_mutex);
2824
Michal Kazior077efc82014-10-21 10:10:29 +03002825 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i disassoc bssid %pM\n",
2826 arvif->vdev_id, arvif->bssid);
Kalle Valo60c3daa2013-09-08 17:56:07 +03002827
Kalle Valo5e3dd152013-06-12 20:52:10 +03002828 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
Michal Kazior077efc82014-10-21 10:10:29 +03002829 if (ret)
Ben Greearaa66ba02016-09-26 21:56:25 +03002830 ath10k_warn(ar, "failed to down vdev %i: %d\n",
Michal Kazior077efc82014-10-21 10:10:29 +03002831 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002832
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002833 arvif->def_wep_key_idx = -1;
2834
Michal Kazior139e1702015-02-15 16:50:42 +02002835 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
2836 if (ret) {
2837 ath10k_warn(ar, "failed to recalc txbf for vdev %i: %d\n",
2838 arvif->vdev_id, ret);
2839 return;
2840 }
2841
Michal Kaziorc930f742014-01-23 11:38:25 +01002842 arvif->is_up = false;
Michal Kaziorcc9904e2015-03-10 16:22:01 +02002843
2844 cancel_delayed_work_sync(&arvif->connection_loss_work);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002845}
2846
Michal Kazior590922a2014-10-21 10:10:29 +03002847static int ath10k_station_assoc(struct ath10k *ar,
2848 struct ieee80211_vif *vif,
2849 struct ieee80211_sta *sta,
2850 bool reassoc)
Kalle Valo5e3dd152013-06-12 20:52:10 +03002851{
Michal Kazior590922a2014-10-21 10:10:29 +03002852 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valob9ada652013-10-16 15:44:46 +03002853 struct wmi_peer_assoc_complete_arg peer_arg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002854 int ret = 0;
2855
Michal Kazior548db542013-07-05 16:15:15 +03002856 lockdep_assert_held(&ar->conf_mutex);
2857
Michal Kazior590922a2014-10-21 10:10:29 +03002858 ret = ath10k_peer_assoc_prepare(ar, vif, sta, &peer_arg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002859 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002860 ath10k_warn(ar, "failed to prepare WMI peer assoc for %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02002861 sta->addr, arvif->vdev_id, ret);
Kalle Valob9ada652013-10-16 15:44:46 +03002862 return ret;
2863 }
2864
2865 ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
2866 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002867 ath10k_warn(ar, "failed to run peer assoc for STA %pM vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002868 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002869 return ret;
2870 }
2871
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002872 /* Re-assoc is run only to update supported rates for given station. It
2873 * doesn't make much sense to reconfigure the peer completely.
2874 */
2875 if (!reassoc) {
2876 ret = ath10k_setup_peer_smps(ar, arvif, sta->addr,
2877 &sta->ht_cap);
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002878 if (ret) {
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002879 ath10k_warn(ar, "failed to setup peer SMPS for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002880 arvif->vdev_id, ret);
2881 return ret;
2882 }
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002883
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002884 ret = ath10k_peer_assoc_qos_ap(ar, arvif, sta);
2885 if (ret) {
2886 ath10k_warn(ar, "failed to set qos params for STA %pM for vdev %i: %d\n",
2887 sta->addr, arvif->vdev_id, ret);
2888 return ret;
2889 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002890
Michal Kaziorb1ecde32014-10-21 10:10:29 +03002891 if (!sta->wme) {
2892 arvif->num_legacy_stations++;
2893 ret = ath10k_recalc_rtscts_prot(arvif);
2894 if (ret) {
2895 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
2896 arvif->vdev_id, ret);
2897 return ret;
2898 }
2899 }
2900
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02002901 /* Plumb cached keys only for static WEP */
2902 if (arvif->def_wep_key_idx != -1) {
2903 ret = ath10k_install_peer_wep_keys(arvif, sta->addr);
2904 if (ret) {
2905 ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n",
2906 arvif->vdev_id, ret);
2907 return ret;
2908 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03002909 }
2910 }
2911
Kalle Valo5e3dd152013-06-12 20:52:10 +03002912 return ret;
2913}
2914
Michal Kazior590922a2014-10-21 10:10:29 +03002915static int ath10k_station_disassoc(struct ath10k *ar,
2916 struct ieee80211_vif *vif,
Kalle Valo5e3dd152013-06-12 20:52:10 +03002917 struct ieee80211_sta *sta)
2918{
Michal Kazior590922a2014-10-21 10:10:29 +03002919 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002920 int ret = 0;
2921
2922 lockdep_assert_held(&ar->conf_mutex);
2923
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002924 if (!sta->wme) {
2925 arvif->num_legacy_stations--;
2926 ret = ath10k_recalc_rtscts_prot(arvif);
2927 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002928 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02002929 arvif->vdev_id, ret);
2930 return ret;
2931 }
2932 }
2933
Kalle Valo5e3dd152013-06-12 20:52:10 +03002934 ret = ath10k_clear_peer_keys(arvif, sta->addr);
2935 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02002936 ath10k_warn(ar, "failed to clear all peer wep keys for vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02002937 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03002938 return ret;
2939 }
2940
2941 return ret;
2942}
2943
2944/**************/
2945/* Regulatory */
2946/**************/
2947
2948static int ath10k_update_channel_list(struct ath10k *ar)
2949{
2950 struct ieee80211_hw *hw = ar->hw;
2951 struct ieee80211_supported_band **bands;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002952 enum nl80211_band band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002953 struct ieee80211_channel *channel;
2954 struct wmi_scan_chan_list_arg arg = {0};
2955 struct wmi_channel_arg *ch;
2956 bool passive;
2957 int len;
2958 int ret;
2959 int i;
2960
Michal Kazior548db542013-07-05 16:15:15 +03002961 lockdep_assert_held(&ar->conf_mutex);
2962
Kalle Valo5e3dd152013-06-12 20:52:10 +03002963 bands = hw->wiphy->bands;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002964 for (band = 0; band < NUM_NL80211_BANDS; band++) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002965 if (!bands[band])
2966 continue;
2967
2968 for (i = 0; i < bands[band]->n_channels; i++) {
2969 if (bands[band]->channels[i].flags &
2970 IEEE80211_CHAN_DISABLED)
2971 continue;
2972
2973 arg.n_channels++;
2974 }
2975 }
2976
2977 len = sizeof(struct wmi_channel_arg) * arg.n_channels;
2978 arg.channels = kzalloc(len, GFP_KERNEL);
2979 if (!arg.channels)
2980 return -ENOMEM;
2981
2982 ch = arg.channels;
Johannes Berg57fbcce2016-04-12 15:56:15 +02002983 for (band = 0; band < NUM_NL80211_BANDS; band++) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03002984 if (!bands[band])
2985 continue;
2986
2987 for (i = 0; i < bands[band]->n_channels; i++) {
2988 channel = &bands[band]->channels[i];
2989
2990 if (channel->flags & IEEE80211_CHAN_DISABLED)
2991 continue;
2992
Eduardo Abinader98029772016-06-30 15:23:55 +03002993 ch->allow_ht = true;
Kalle Valo5e3dd152013-06-12 20:52:10 +03002994
2995 /* FIXME: when should we really allow VHT? */
2996 ch->allow_vht = true;
2997
2998 ch->allow_ibss =
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02002999 !(channel->flags & IEEE80211_CHAN_NO_IR);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003000
3001 ch->ht40plus =
3002 !(channel->flags & IEEE80211_CHAN_NO_HT40PLUS);
3003
Marek Puzyniake8a50f82013-11-20 09:59:47 +02003004 ch->chan_radar =
3005 !!(channel->flags & IEEE80211_CHAN_RADAR);
3006
Luis R. Rodriguez8fe02e12013-10-21 19:22:25 +02003007 passive = channel->flags & IEEE80211_CHAN_NO_IR;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003008 ch->passive = passive;
3009
Sven Eckelmann7ffd72b2018-07-26 15:59:48 +02003010 /* the firmware is ignoring the "radar" flag of the
3011 * channel and is scanning actively using Probe Requests
3012 * on "Radar detection"/DFS channels which are not
3013 * marked as "available"
3014 */
3015 ch->passive |= ch->chan_radar;
3016
Kalle Valo5e3dd152013-06-12 20:52:10 +03003017 ch->freq = channel->center_freq;
Michal Kazior2d667212014-09-18 15:21:21 +02003018 ch->band_center_freq1 = channel->center_freq;
Michal Kazior89c5c842013-10-23 04:02:13 -07003019 ch->min_power = 0;
Michal Kazior02256932013-10-23 04:02:14 -07003020 ch->max_power = channel->max_power * 2;
3021 ch->max_reg_power = channel->max_reg_power * 2;
3022 ch->max_antenna_gain = channel->max_antenna_gain * 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003023 ch->reg_class_id = 0; /* FIXME */
3024
3025 /* FIXME: why use only legacy modes, why not any
3026 * HT/VHT modes? Would that even make any
3027 * difference? */
Johannes Berg57fbcce2016-04-12 15:56:15 +02003028 if (channel->band == NL80211_BAND_2GHZ)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003029 ch->mode = MODE_11G;
3030 else
3031 ch->mode = MODE_11A;
3032
3033 if (WARN_ON_ONCE(ch->mode == MODE_UNKNOWN))
3034 continue;
3035
Michal Kazior7aa7a722014-08-25 12:09:38 +02003036 ath10k_dbg(ar, ATH10K_DBG_WMI,
Kalle Valo60c3daa2013-09-08 17:56:07 +03003037 "mac channel [%zd/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n",
3038 ch - arg.channels, arg.n_channels,
Kalle Valo5e3dd152013-06-12 20:52:10 +03003039 ch->freq, ch->max_power, ch->max_reg_power,
3040 ch->max_antenna_gain, ch->mode);
3041
3042 ch++;
3043 }
3044 }
3045
3046 ret = ath10k_wmi_scan_chan_list(ar, &arg);
3047 kfree(arg.channels);
3048
3049 return ret;
3050}
3051
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003052static enum wmi_dfs_region
3053ath10k_mac_get_dfs_region(enum nl80211_dfs_regions dfs_region)
3054{
3055 switch (dfs_region) {
3056 case NL80211_DFS_UNSET:
3057 return WMI_UNINIT_DFS_DOMAIN;
3058 case NL80211_DFS_FCC:
3059 return WMI_FCC_DFS_DOMAIN;
3060 case NL80211_DFS_ETSI:
3061 return WMI_ETSI_DFS_DOMAIN;
3062 case NL80211_DFS_JP:
3063 return WMI_MKK4_DFS_DOMAIN;
3064 }
3065 return WMI_UNINIT_DFS_DOMAIN;
3066}
3067
Michal Kaziorf7843d72013-07-16 09:38:52 +02003068static void ath10k_regd_update(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003069{
Kalle Valo5e3dd152013-06-12 20:52:10 +03003070 struct reg_dmn_pair_mapping *regpair;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003071 int ret;
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003072 enum wmi_dfs_region wmi_dfs_reg;
3073 enum nl80211_dfs_regions nl_dfs_reg;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003074
Michal Kaziorf7843d72013-07-16 09:38:52 +02003075 lockdep_assert_held(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003076
3077 ret = ath10k_update_channel_list(ar);
3078 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003079 ath10k_warn(ar, "failed to update channel list: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003080
3081 regpair = ar->ath_common.regulatory.regpair;
Michal Kaziorf7843d72013-07-16 09:38:52 +02003082
Masahiro Yamada97f26452016-08-03 13:45:50 -07003083 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003084 nl_dfs_reg = ar->dfs_detector->region;
3085 wmi_dfs_reg = ath10k_mac_get_dfs_region(nl_dfs_reg);
3086 } else {
3087 wmi_dfs_reg = WMI_UNINIT_DFS_DOMAIN;
3088 }
3089
Kalle Valo5e3dd152013-06-12 20:52:10 +03003090 /* Target allows setting up per-band regdomain but ath_common provides
3091 * a combined one only */
3092 ret = ath10k_wmi_pdev_set_regdomain(ar,
Kalle Valoef8c0012014-02-13 18:13:12 +02003093 regpair->reg_domain,
3094 regpair->reg_domain, /* 2ghz */
3095 regpair->reg_domain, /* 5ghz */
Kalle Valo5e3dd152013-06-12 20:52:10 +03003096 regpair->reg_2ghz_ctl,
Marek Puzyniak821af6a2014-03-21 17:46:57 +02003097 regpair->reg_5ghz_ctl,
3098 wmi_dfs_reg);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003099 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003100 ath10k_warn(ar, "failed to set pdev regdomain: %d\n", ret);
Michal Kaziorf7843d72013-07-16 09:38:52 +02003101}
Michal Kazior548db542013-07-05 16:15:15 +03003102
Michal Kaziorf7843d72013-07-16 09:38:52 +02003103static void ath10k_reg_notifier(struct wiphy *wiphy,
3104 struct regulatory_request *request)
3105{
3106 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
3107 struct ath10k *ar = hw->priv;
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003108 bool result;
Michal Kaziorf7843d72013-07-16 09:38:52 +02003109
3110 ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory);
3111
Masahiro Yamada97f26452016-08-03 13:45:50 -07003112 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003113 ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs region 0x%x\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003114 request->dfs_region);
3115 result = ar->dfs_detector->set_dfs_domain(ar->dfs_detector,
3116 request->dfs_region);
3117 if (!result)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003118 ath10k_warn(ar, "DFS region 0x%X not supported, will trigger radar for every pulse\n",
Janusz Dziedzic9702c682013-11-20 09:59:41 +02003119 request->dfs_region);
3120 }
3121
Michal Kaziorf7843d72013-07-16 09:38:52 +02003122 mutex_lock(&ar->conf_mutex);
3123 if (ar->state == ATH10K_STATE_ON)
3124 ath10k_regd_update(ar);
Michal Kazior548db542013-07-05 16:15:15 +03003125 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003126}
3127
3128/***************/
3129/* TX handlers */
3130/***************/
3131
Michal Kaziora30c7d02016-03-06 16:14:23 +02003132enum ath10k_mac_tx_path {
3133 ATH10K_MAC_TX_HTT,
3134 ATH10K_MAC_TX_HTT_MGMT,
3135 ATH10K_MAC_TX_WMI_MGMT,
3136 ATH10K_MAC_TX_UNKNOWN,
3137};
3138
Michal Kazior96d828d2015-03-31 10:26:23 +00003139void ath10k_mac_tx_lock(struct ath10k *ar, int reason)
3140{
3141 lockdep_assert_held(&ar->htt.tx_lock);
3142
3143 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
3144 ar->tx_paused |= BIT(reason);
3145 ieee80211_stop_queues(ar->hw);
3146}
3147
3148static void ath10k_mac_tx_unlock_iter(void *data, u8 *mac,
3149 struct ieee80211_vif *vif)
3150{
3151 struct ath10k *ar = data;
3152 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3153
3154 if (arvif->tx_paused)
3155 return;
3156
3157 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
3158}
3159
3160void ath10k_mac_tx_unlock(struct ath10k *ar, int reason)
3161{
3162 lockdep_assert_held(&ar->htt.tx_lock);
3163
3164 WARN_ON(reason >= ATH10K_TX_PAUSE_MAX);
3165 ar->tx_paused &= ~BIT(reason);
3166
3167 if (ar->tx_paused)
3168 return;
3169
3170 ieee80211_iterate_active_interfaces_atomic(ar->hw,
3171 IEEE80211_IFACE_ITER_RESUME_ALL,
3172 ath10k_mac_tx_unlock_iter,
3173 ar);
Michal Kazior3a73d1a2015-08-06 14:46:54 +02003174
3175 ieee80211_wake_queue(ar->hw, ar->hw->offchannel_tx_hw_queue);
Michal Kazior96d828d2015-03-31 10:26:23 +00003176}
3177
3178void ath10k_mac_vif_tx_lock(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 ieee80211_stop_queue(ar->hw, arvif->vdev_id);
3187}
3188
3189void ath10k_mac_vif_tx_unlock(struct ath10k_vif *arvif, int reason)
3190{
3191 struct ath10k *ar = arvif->ar;
3192
3193 lockdep_assert_held(&ar->htt.tx_lock);
3194
3195 WARN_ON(reason >= BITS_PER_LONG);
3196 arvif->tx_paused &= ~BIT(reason);
3197
3198 if (ar->tx_paused)
3199 return;
3200
3201 if (arvif->tx_paused)
3202 return;
3203
3204 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
3205}
3206
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003207static void ath10k_mac_vif_handle_tx_pause(struct ath10k_vif *arvif,
3208 enum wmi_tlv_tx_pause_id pause_id,
3209 enum wmi_tlv_tx_pause_action action)
3210{
3211 struct ath10k *ar = arvif->ar;
3212
3213 lockdep_assert_held(&ar->htt.tx_lock);
3214
Michal Kazioracd0b272015-07-09 13:08:38 +02003215 switch (action) {
3216 case WMI_TLV_TX_PAUSE_ACTION_STOP:
3217 ath10k_mac_vif_tx_lock(arvif, pause_id);
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003218 break;
Michal Kazioracd0b272015-07-09 13:08:38 +02003219 case WMI_TLV_TX_PAUSE_ACTION_WAKE:
3220 ath10k_mac_vif_tx_unlock(arvif, pause_id);
3221 break;
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003222 default:
Michal Kazioracd0b272015-07-09 13:08:38 +02003223 ath10k_warn(ar, "received unknown tx pause action %d on vdev %i, ignoring\n",
3224 action, arvif->vdev_id);
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003225 break;
3226 }
3227}
3228
3229struct ath10k_mac_tx_pause {
3230 u32 vdev_id;
3231 enum wmi_tlv_tx_pause_id pause_id;
3232 enum wmi_tlv_tx_pause_action action;
3233};
3234
3235static void ath10k_mac_handle_tx_pause_iter(void *data, u8 *mac,
3236 struct ieee80211_vif *vif)
3237{
3238 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3239 struct ath10k_mac_tx_pause *arg = data;
3240
Michal Kazioracd0b272015-07-09 13:08:38 +02003241 if (arvif->vdev_id != arg->vdev_id)
3242 return;
3243
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003244 ath10k_mac_vif_handle_tx_pause(arvif, arg->pause_id, arg->action);
3245}
3246
Michal Kazioracd0b272015-07-09 13:08:38 +02003247void ath10k_mac_handle_tx_pause_vdev(struct ath10k *ar, u32 vdev_id,
3248 enum wmi_tlv_tx_pause_id pause_id,
3249 enum wmi_tlv_tx_pause_action action)
Michal Kaziorb4aa5392015-03-31 10:26:24 +00003250{
3251 struct ath10k_mac_tx_pause arg = {
3252 .vdev_id = vdev_id,
3253 .pause_id = pause_id,
3254 .action = action,
3255 };
3256
3257 spin_lock_bh(&ar->htt.tx_lock);
3258 ieee80211_iterate_active_interfaces_atomic(ar->hw,
3259 IEEE80211_IFACE_ITER_RESUME_ALL,
3260 ath10k_mac_handle_tx_pause_iter,
3261 &arg);
3262 spin_unlock_bh(&ar->htt.tx_lock);
3263}
3264
Michal Kaziord740d8f2015-03-30 09:51:51 +03003265static enum ath10k_hw_txrx_mode
Michal Kazior6a2636d2015-11-18 06:59:16 +01003266ath10k_mac_tx_h_get_txmode(struct ath10k *ar,
3267 struct ieee80211_vif *vif,
3268 struct ieee80211_sta *sta,
3269 struct sk_buff *skb)
Michal Kaziord740d8f2015-03-30 09:51:51 +03003270{
3271 const struct ieee80211_hdr *hdr = (void *)skb->data;
3272 __le16 fc = hdr->frame_control;
3273
3274 if (!vif || vif->type == NL80211_IFTYPE_MONITOR)
3275 return ATH10K_HW_TXRX_RAW;
3276
3277 if (ieee80211_is_mgmt(fc))
3278 return ATH10K_HW_TXRX_MGMT;
3279
3280 /* Workaround:
3281 *
3282 * NullFunc frames are mostly used to ping if a client or AP are still
3283 * reachable and responsive. This implies tx status reports must be
3284 * accurate - otherwise either mac80211 or userspace (e.g. hostapd) can
3285 * come to a conclusion that the other end disappeared and tear down
3286 * BSS connection or it can never disconnect from BSS/client (which is
3287 * the case).
3288 *
3289 * Firmware with HTT older than 3.0 delivers incorrect tx status for
3290 * NullFunc frames to driver. However there's a HTT Mgmt Tx command
3291 * which seems to deliver correct tx reports for NullFunc frames. The
3292 * downside of using it is it ignores client powersave state so it can
3293 * end up disconnecting sleeping clients in AP mode. It should fix STA
3294 * mode though because AP don't sleep.
3295 */
3296 if (ar->htt.target_version_major < 3 &&
3297 (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) &&
Kalle Valoc4cdf752016-04-20 19:45:18 +03003298 !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
3299 ar->running_fw->fw_file.fw_features))
Michal Kaziord740d8f2015-03-30 09:51:51 +03003300 return ATH10K_HW_TXRX_MGMT;
3301
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003302 /* Workaround:
3303 *
3304 * Some wmi-tlv firmwares for qca6174 have broken Tx key selection for
3305 * NativeWifi txmode - it selects AP key instead of peer key. It seems
3306 * to work with Ethernet txmode so use it.
David Liuccec9032015-07-24 20:25:32 +03003307 *
3308 * FIXME: Check if raw mode works with TDLS.
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03003309 */
3310 if (ieee80211_is_data_present(fc) && sta && sta->tdls)
3311 return ATH10K_HW_TXRX_ETHERNET;
3312
David Liuccec9032015-07-24 20:25:32 +03003313 if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
3314 return ATH10K_HW_TXRX_RAW;
3315
Michal Kaziord740d8f2015-03-30 09:51:51 +03003316 return ATH10K_HW_TXRX_NATIVE_WIFI;
3317}
3318
David Liuccec9032015-07-24 20:25:32 +03003319static bool ath10k_tx_h_use_hwcrypto(struct ieee80211_vif *vif,
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003320 struct sk_buff *skb)
3321{
3322 const struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3323 const struct ieee80211_hdr *hdr = (void *)skb->data;
David Liuccec9032015-07-24 20:25:32 +03003324 const u32 mask = IEEE80211_TX_INTFL_DONT_ENCRYPT |
3325 IEEE80211_TX_CTL_INJECTED;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003326
3327 if (!ieee80211_has_protected(hdr->frame_control))
3328 return false;
3329
David Liuccec9032015-07-24 20:25:32 +03003330 if ((info->flags & mask) == mask)
3331 return false;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003332
David Liuccec9032015-07-24 20:25:32 +03003333 if (vif)
3334 return !ath10k_vif_to_arvif(vif)->nohwcrypt;
Michal Kaziorfd12cb32015-11-18 06:59:15 +01003335
David Liuccec9032015-07-24 20:25:32 +03003336 return true;
3337}
3338
Michal Kazior4b604552014-07-21 21:03:09 +03003339/* HTT Tx uses Native Wifi tx mode which expects 802.11 frames without QoS
3340 * Control in the header.
Kalle Valo5e3dd152013-06-12 20:52:10 +03003341 */
Michal Kazior4b604552014-07-21 21:03:09 +03003342static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003343{
3344 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003345 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003346 u8 *qos_ctl;
3347
3348 if (!ieee80211_is_data_qos(hdr->frame_control))
3349 return;
3350
3351 qos_ctl = ieee80211_get_qos_ctl(hdr);
Michal Kaziorba0ccd72013-07-22 14:25:28 +02003352 memmove(skb->data + IEEE80211_QOS_CTL_LEN,
3353 skb->data, (void *)qos_ctl - (void *)skb->data);
3354 skb_pull(skb, IEEE80211_QOS_CTL_LEN);
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003355
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003356 /* Some firmware revisions don't handle sending QoS NullFunc well.
3357 * These frames are mainly used for CQM purposes so it doesn't really
3358 * matter whether QoS NullFunc or NullFunc are sent.
Michal Kaziorc21c64d2014-07-21 21:03:10 +03003359 */
Michal Kaziorbf0a26d2015-01-24 12:14:51 +02003360 hdr = (void *)skb->data;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003361 if (ieee80211_is_qos_nullfunc(hdr->frame_control))
Michal Kazior609db222015-11-18 06:59:22 +01003362 cb->flags &= ~ATH10K_SKB_F_QOS;
Michal Kazior8bad8dc2015-03-11 14:25:26 +01003363
3364 hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003365}
3366
Michal Kaziord740d8f2015-03-30 09:51:51 +03003367static void ath10k_tx_h_8023(struct sk_buff *skb)
3368{
3369 struct ieee80211_hdr *hdr;
3370 struct rfc1042_hdr *rfc1042;
3371 struct ethhdr *eth;
3372 size_t hdrlen;
3373 u8 da[ETH_ALEN];
3374 u8 sa[ETH_ALEN];
3375 __be16 type;
3376
3377 hdr = (void *)skb->data;
3378 hdrlen = ieee80211_hdrlen(hdr->frame_control);
3379 rfc1042 = (void *)skb->data + hdrlen;
3380
3381 ether_addr_copy(da, ieee80211_get_DA(hdr));
3382 ether_addr_copy(sa, ieee80211_get_SA(hdr));
3383 type = rfc1042->snap_type;
3384
3385 skb_pull(skb, hdrlen + sizeof(*rfc1042));
3386 skb_push(skb, sizeof(*eth));
3387
3388 eth = (void *)skb->data;
3389 ether_addr_copy(eth->h_dest, da);
3390 ether_addr_copy(eth->h_source, sa);
3391 eth->h_proto = type;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003392}
3393
Michal Kazior4b604552014-07-21 21:03:09 +03003394static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
3395 struct ieee80211_vif *vif,
3396 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003397{
3398 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003399 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3400
3401 /* This is case only for P2P_GO */
Peter Oh08c27be2016-01-28 13:54:09 -08003402 if (vif->type != NL80211_IFTYPE_AP || !vif->p2p)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003403 return;
3404
3405 if (unlikely(ieee80211_is_probe_resp(hdr->frame_control))) {
3406 spin_lock_bh(&ar->data_lock);
3407 if (arvif->u.ap.noa_data)
3408 if (!pskb_expand_head(skb, 0, arvif->u.ap.noa_len,
3409 GFP_ATOMIC))
3410 memcpy(skb_put(skb, arvif->u.ap.noa_len),
3411 arvif->u.ap.noa_data,
3412 arvif->u.ap.noa_len);
3413 spin_unlock_bh(&ar->data_lock);
3414 }
3415}
3416
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003417static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,
3418 struct ieee80211_vif *vif,
Michal Kaziordd4717b2016-03-06 16:14:39 +02003419 struct ieee80211_txq *txq,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003420 struct sk_buff *skb)
3421{
3422 struct ieee80211_hdr *hdr = (void *)skb->data;
3423 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
3424
3425 cb->flags = 0;
3426 if (!ath10k_tx_h_use_hwcrypto(vif, skb))
3427 cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;
3428
3429 if (ieee80211_is_mgmt(hdr->frame_control))
3430 cb->flags |= ATH10K_SKB_F_MGMT;
3431
3432 if (ieee80211_is_data_qos(hdr->frame_control))
3433 cb->flags |= ATH10K_SKB_F_QOS;
3434
3435 cb->vif = vif;
Michal Kaziordd4717b2016-03-06 16:14:39 +02003436 cb->txq = txq;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003437}
3438
Vasanthakumar Thiagarajand39de992015-11-05 11:34:00 +05303439bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar)
Michal Kazior8d6d3622014-11-24 14:58:31 +01003440{
3441 /* FIXME: Not really sure since when the behaviour changed. At some
3442 * point new firmware stopped requiring creation of peer entries for
3443 * offchannel tx (and actually creating them causes issues with wmi-htc
3444 * tx credit replenishment and reliability). Assuming it's at least 3.4
3445 * because that's when the `freq` was introduced to TX_FRM HTT command.
3446 */
Vasanthakumar Thiagarajan8921f5f2015-11-05 11:33:59 +05303447 return (ar->htt.target_version_major >= 3 &&
Vasanthakumar Thiagarajand39de992015-11-05 11:34:00 +05303448 ar->htt.target_version_minor >= 4 &&
Kalle Valo77561f92016-04-20 19:45:47 +03003449 ar->running_fw->fw_file.htt_op_version == ATH10K_FW_HTT_OP_VERSION_TLV);
Michal Kazior8d6d3622014-11-24 14:58:31 +01003450}
3451
Michal Kaziord740d8f2015-03-30 09:51:51 +03003452static int ath10k_mac_tx_wmi_mgmt(struct ath10k *ar, struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003453{
Michal Kaziord740d8f2015-03-30 09:51:51 +03003454 struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003455 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003456
Michal Kaziord740d8f2015-03-30 09:51:51 +03003457 spin_lock_bh(&ar->data_lock);
3458
3459 if (skb_queue_len(q) == ATH10K_MAX_NUM_MGMT_PENDING) {
3460 ath10k_warn(ar, "wmi mgmt tx queue is full\n");
3461 ret = -ENOSPC;
3462 goto unlock;
Michal Kazior961d4c32013-08-09 10:13:34 +02003463 }
3464
Michal Kaziord740d8f2015-03-30 09:51:51 +03003465 __skb_queue_tail(q, skb);
3466 ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work);
3467
3468unlock:
3469 spin_unlock_bh(&ar->data_lock);
3470
3471 return ret;
3472}
3473
Michal Kaziora30c7d02016-03-06 16:14:23 +02003474static enum ath10k_mac_tx_path
3475ath10k_mac_tx_h_get_txpath(struct ath10k *ar,
3476 struct sk_buff *skb,
3477 enum ath10k_hw_txrx_mode txmode)
3478{
3479 switch (txmode) {
3480 case ATH10K_HW_TXRX_RAW:
3481 case ATH10K_HW_TXRX_NATIVE_WIFI:
3482 case ATH10K_HW_TXRX_ETHERNET:
3483 return ATH10K_MAC_TX_HTT;
3484 case ATH10K_HW_TXRX_MGMT:
3485 if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
Kalle Valoc4cdf752016-04-20 19:45:18 +03003486 ar->running_fw->fw_file.fw_features))
Michal Kaziora30c7d02016-03-06 16:14:23 +02003487 return ATH10K_MAC_TX_WMI_MGMT;
3488 else if (ar->htt.target_version_major >= 3)
3489 return ATH10K_MAC_TX_HTT;
3490 else
3491 return ATH10K_MAC_TX_HTT_MGMT;
3492 }
3493
3494 return ATH10K_MAC_TX_UNKNOWN;
3495}
3496
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003497static int ath10k_mac_tx_submit(struct ath10k *ar,
3498 enum ath10k_hw_txrx_mode txmode,
Michal Kazior6421969f2016-03-06 16:14:25 +02003499 enum ath10k_mac_tx_path txpath,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003500 struct sk_buff *skb)
Michal Kaziord740d8f2015-03-30 09:51:51 +03003501{
Michal Kaziord740d8f2015-03-30 09:51:51 +03003502 struct ath10k_htt *htt = &ar->htt;
Michal Kazior6421969f2016-03-06 16:14:25 +02003503 int ret = -EINVAL;
Michal Kaziora30c7d02016-03-06 16:14:23 +02003504
3505 switch (txpath) {
3506 case ATH10K_MAC_TX_HTT:
Michal Kazior8a933962015-11-18 06:59:17 +01003507 ret = ath10k_htt_tx(htt, txmode, skb);
Michal Kaziord740d8f2015-03-30 09:51:51 +03003508 break;
Michal Kaziora30c7d02016-03-06 16:14:23 +02003509 case ATH10K_MAC_TX_HTT_MGMT:
3510 ret = ath10k_htt_mgmt_tx(htt, skb);
3511 break;
3512 case ATH10K_MAC_TX_WMI_MGMT:
3513 ret = ath10k_mac_tx_wmi_mgmt(ar, skb);
3514 break;
3515 case ATH10K_MAC_TX_UNKNOWN:
3516 WARN_ON_ONCE(1);
3517 ret = -EINVAL;
Michal Kaziord740d8f2015-03-30 09:51:51 +03003518 break;
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003519 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003520
3521 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003522 ath10k_warn(ar, "failed to transmit packet, dropping: %d\n",
3523 ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003524 ieee80211_free_txskb(ar->hw, skb);
3525 }
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003526
3527 return ret;
3528}
3529
3530/* This function consumes the sk_buff regardless of return value as far as
3531 * caller is concerned so no freeing is necessary afterwards.
3532 */
3533static int ath10k_mac_tx(struct ath10k *ar,
3534 struct ieee80211_vif *vif,
3535 struct ieee80211_sta *sta,
3536 enum ath10k_hw_txrx_mode txmode,
Michal Kazior6421969f2016-03-06 16:14:25 +02003537 enum ath10k_mac_tx_path txpath,
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003538 struct sk_buff *skb)
3539{
3540 struct ieee80211_hw *hw = ar->hw;
3541 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3542 int ret;
3543
3544 /* We should disable CCK RATE due to P2P */
3545 if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
3546 ath10k_dbg(ar, ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n");
3547
3548 switch (txmode) {
3549 case ATH10K_HW_TXRX_MGMT:
3550 case ATH10K_HW_TXRX_NATIVE_WIFI:
3551 ath10k_tx_h_nwifi(hw, skb);
3552 ath10k_tx_h_add_p2p_noa_ie(ar, vif, skb);
3553 ath10k_tx_h_seq_no(vif, skb);
3554 break;
3555 case ATH10K_HW_TXRX_ETHERNET:
3556 ath10k_tx_h_8023(skb);
3557 break;
3558 case ATH10K_HW_TXRX_RAW:
3559 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
3560 WARN_ON_ONCE(1);
3561 ieee80211_free_txskb(hw, skb);
3562 return -ENOTSUPP;
3563 }
3564 }
3565
3566 if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
3567 if (!ath10k_mac_tx_frm_has_freq(ar)) {
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05303568 ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %pK\n",
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003569 skb);
3570
3571 skb_queue_tail(&ar->offchan_tx_queue, skb);
3572 ieee80211_queue_work(hw, &ar->offchan_tx_work);
3573 return 0;
3574 }
3575 }
3576
Michal Kazior6421969f2016-03-06 16:14:25 +02003577 ret = ath10k_mac_tx_submit(ar, txmode, txpath, skb);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003578 if (ret) {
3579 ath10k_warn(ar, "failed to submit frame: %d\n", ret);
3580 return ret;
3581 }
3582
3583 return 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003584}
3585
3586void ath10k_offchan_tx_purge(struct ath10k *ar)
3587{
3588 struct sk_buff *skb;
3589
3590 for (;;) {
3591 skb = skb_dequeue(&ar->offchan_tx_queue);
3592 if (!skb)
3593 break;
3594
3595 ieee80211_free_txskb(ar->hw, skb);
3596 }
3597}
3598
3599void ath10k_offchan_tx_work(struct work_struct *work)
3600{
3601 struct ath10k *ar = container_of(work, struct ath10k, offchan_tx_work);
3602 struct ath10k_peer *peer;
Michal Kazior8a933962015-11-18 06:59:17 +01003603 struct ath10k_vif *arvif;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003604 enum ath10k_hw_txrx_mode txmode;
Michal Kazior6421969f2016-03-06 16:14:25 +02003605 enum ath10k_mac_tx_path txpath;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003606 struct ieee80211_hdr *hdr;
Michal Kazior8a933962015-11-18 06:59:17 +01003607 struct ieee80211_vif *vif;
3608 struct ieee80211_sta *sta;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003609 struct sk_buff *skb;
3610 const u8 *peer_addr;
3611 int vdev_id;
3612 int ret;
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003613 unsigned long time_left;
Michal Kazioradaeed72015-08-05 12:15:23 +02003614 bool tmp_peer_created = false;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003615
3616 /* FW requirement: We must create a peer before FW will send out
3617 * an offchannel frame. Otherwise the frame will be stuck and
3618 * never transmitted. We delete the peer upon tx completion.
3619 * It is unlikely that a peer for offchannel tx will already be
3620 * present. However it may be in some rare cases so account for that.
3621 * Otherwise we might remove a legitimate peer and break stuff. */
3622
3623 for (;;) {
3624 skb = skb_dequeue(&ar->offchan_tx_queue);
3625 if (!skb)
3626 break;
3627
3628 mutex_lock(&ar->conf_mutex);
3629
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05303630 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %pK\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003631 skb);
3632
3633 hdr = (struct ieee80211_hdr *)skb->data;
3634 peer_addr = ieee80211_get_DA(hdr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003635
3636 spin_lock_bh(&ar->data_lock);
Michal Kazior609db222015-11-18 06:59:22 +01003637 vdev_id = ar->scan.vdev_id;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003638 peer = ath10k_peer_find(ar, vdev_id, peer_addr);
3639 spin_unlock_bh(&ar->data_lock);
3640
3641 if (peer)
Kalle Valo60c3daa2013-09-08 17:56:07 +03003642 /* FIXME: should this use ath10k_warn()? */
Michal Kazior7aa7a722014-08-25 12:09:38 +02003643 ath10k_dbg(ar, ATH10K_DBG_MAC, "peer %pM on vdev %d already present\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003644 peer_addr, vdev_id);
3645
3646 if (!peer) {
Michal Kazior69427262016-03-06 16:14:30 +02003647 ret = ath10k_peer_create(ar, NULL, NULL, vdev_id,
3648 peer_addr,
Marek Puzyniak7390ed32015-03-30 09:51:52 +03003649 WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003650 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003651 ath10k_warn(ar, "failed to create peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003652 peer_addr, vdev_id, ret);
Michal Kazioradaeed72015-08-05 12:15:23 +02003653 tmp_peer_created = (ret == 0);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003654 }
3655
3656 spin_lock_bh(&ar->data_lock);
Wolfram Sang16735d02013-11-14 14:32:02 -08003657 reinit_completion(&ar->offchan_tx_completed);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003658 ar->offchan_tx_skb = skb;
3659 spin_unlock_bh(&ar->data_lock);
3660
Michal Kazior8a933962015-11-18 06:59:17 +01003661 /* It's safe to access vif and sta - conf_mutex guarantees that
3662 * sta_state() and remove_interface() are locked exclusively
3663 * out wrt to this offchannel worker.
3664 */
3665 arvif = ath10k_get_arvif(ar, vdev_id);
3666 if (arvif) {
3667 vif = arvif->vif;
3668 sta = ieee80211_find_sta(vif, peer_addr);
3669 } else {
3670 vif = NULL;
3671 sta = NULL;
3672 }
3673
3674 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kazior6421969f2016-03-06 16:14:25 +02003675 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
Michal Kazior8a933962015-11-18 06:59:17 +01003676
Michal Kazior6421969f2016-03-06 16:14:25 +02003677 ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01003678 if (ret) {
3679 ath10k_warn(ar, "failed to transmit offchannel frame: %d\n",
3680 ret);
3681 /* not serious */
3682 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03003683
Nicholas Mc Guire8e9904f52015-03-30 15:39:19 +03003684 time_left =
3685 wait_for_completion_timeout(&ar->offchan_tx_completed, 3 * HZ);
3686 if (time_left == 0)
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05303687 ath10k_warn(ar, "timed out waiting for offchannel skb %pK\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003688 skb);
3689
Michal Kazioradaeed72015-08-05 12:15:23 +02003690 if (!peer && tmp_peer_created) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03003691 ret = ath10k_peer_delete(ar, vdev_id, peer_addr);
3692 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02003693 ath10k_warn(ar, "failed to delete peer %pM on vdev %d: %d\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03003694 peer_addr, vdev_id, ret);
3695 }
3696
3697 mutex_unlock(&ar->conf_mutex);
3698 }
3699}
3700
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003701void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar)
3702{
3703 struct sk_buff *skb;
3704
3705 for (;;) {
3706 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3707 if (!skb)
3708 break;
3709
3710 ieee80211_free_txskb(ar->hw, skb);
3711 }
3712}
3713
3714void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work)
3715{
3716 struct ath10k *ar = container_of(work, struct ath10k, wmi_mgmt_tx_work);
3717 struct sk_buff *skb;
3718 int ret;
3719
3720 for (;;) {
3721 skb = skb_dequeue(&ar->wmi_mgmt_tx_queue);
3722 if (!skb)
3723 break;
3724
3725 ret = ath10k_wmi_mgmt_tx(ar, skb);
Michal Kazior5fb5e412013-10-28 07:18:13 +01003726 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003727 ath10k_warn(ar, "failed to transmit management frame via WMI: %d\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02003728 ret);
Michal Kazior5fb5e412013-10-28 07:18:13 +01003729 ieee80211_free_txskb(ar->hw, skb);
3730 }
Bartosz Markowski5e00d312013-09-26 17:47:12 +02003731 }
3732}
3733
Michal Kazior29946872016-03-06 16:14:34 +02003734static void ath10k_mac_txq_init(struct ieee80211_txq *txq)
3735{
Bob Copelanda66cd732016-06-29 19:29:25 +03003736 struct ath10k_txq *artxq;
Michal Kazior29946872016-03-06 16:14:34 +02003737
3738 if (!txq)
3739 return;
3740
Bob Copelanda66cd732016-06-29 19:29:25 +03003741 artxq = (void *)txq->drv_priv;
Michal Kazior29946872016-03-06 16:14:34 +02003742 INIT_LIST_HEAD(&artxq->list);
3743}
3744
3745static void ath10k_mac_txq_unref(struct ath10k *ar, struct ieee80211_txq *txq)
3746{
Bob Copelanda66cd732016-06-29 19:29:25 +03003747 struct ath10k_txq *artxq;
Michal Kaziordd4717b2016-03-06 16:14:39 +02003748 struct ath10k_skb_cb *cb;
3749 struct sk_buff *msdu;
3750 int msdu_id;
Michal Kazior29946872016-03-06 16:14:34 +02003751
3752 if (!txq)
3753 return;
3754
Bob Copelanda66cd732016-06-29 19:29:25 +03003755 artxq = (void *)txq->drv_priv;
Michal Kazior29946872016-03-06 16:14:34 +02003756 spin_lock_bh(&ar->txqs_lock);
3757 if (!list_empty(&artxq->list))
3758 list_del_init(&artxq->list);
3759 spin_unlock_bh(&ar->txqs_lock);
Michal Kaziordd4717b2016-03-06 16:14:39 +02003760
3761 spin_lock_bh(&ar->htt.tx_lock);
3762 idr_for_each_entry(&ar->htt.pending_tx, msdu, msdu_id) {
3763 cb = ATH10K_SKB_CB(msdu);
3764 if (cb->txq == txq)
3765 cb->txq = NULL;
3766 }
3767 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazior29946872016-03-06 16:14:34 +02003768}
3769
Michal Kazior426e10e2016-03-06 16:14:43 +02003770struct ieee80211_txq *ath10k_mac_txq_lookup(struct ath10k *ar,
3771 u16 peer_id,
3772 u8 tid)
3773{
3774 struct ath10k_peer *peer;
3775
3776 lockdep_assert_held(&ar->data_lock);
3777
3778 peer = ar->peer_map[peer_id];
3779 if (!peer)
3780 return NULL;
3781
Michal Kazior874b5ac2017-01-12 16:14:30 +01003782 if (peer->removed)
3783 return NULL;
3784
Michal Kazior426e10e2016-03-06 16:14:43 +02003785 if (peer->sta)
3786 return peer->sta->txq[tid];
3787 else if (peer->vif)
3788 return peer->vif->txq;
3789 else
3790 return NULL;
3791}
3792
Michal Kazior29946872016-03-06 16:14:34 +02003793static bool ath10k_mac_tx_can_push(struct ieee80211_hw *hw,
3794 struct ieee80211_txq *txq)
3795{
Michal Kazior426e10e2016-03-06 16:14:43 +02003796 struct ath10k *ar = hw->priv;
3797 struct ath10k_txq *artxq = (void *)txq->drv_priv;
3798
3799 /* No need to get locks */
3800
3801 if (ar->htt.tx_q_state.mode == HTT_TX_MODE_SWITCH_PUSH)
3802 return true;
3803
3804 if (ar->htt.num_pending_tx < ar->htt.tx_q_state.num_push_allowed)
3805 return true;
3806
3807 if (artxq->num_fw_queued < artxq->num_push_allowed)
3808 return true;
3809
3810 return false;
Michal Kazior29946872016-03-06 16:14:34 +02003811}
3812
Michal Kazior426e10e2016-03-06 16:14:43 +02003813int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
3814 struct ieee80211_txq *txq)
Michal Kazior29946872016-03-06 16:14:34 +02003815{
Michal Kazior29946872016-03-06 16:14:34 +02003816 struct ath10k *ar = hw->priv;
3817 struct ath10k_htt *htt = &ar->htt;
Michal Kazior3cc0fef2016-03-06 16:14:41 +02003818 struct ath10k_txq *artxq = (void *)txq->drv_priv;
Michal Kazior29946872016-03-06 16:14:34 +02003819 struct ieee80211_vif *vif = txq->vif;
3820 struct ieee80211_sta *sta = txq->sta;
3821 enum ath10k_hw_txrx_mode txmode;
3822 enum ath10k_mac_tx_path txpath;
3823 struct sk_buff *skb;
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05303824 struct ieee80211_hdr *hdr;
Michal Kazior426e10e2016-03-06 16:14:43 +02003825 size_t skb_len;
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05303826 bool is_mgmt, is_presp;
Michal Kazior29946872016-03-06 16:14:34 +02003827 int ret;
3828
3829 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05303830 ret = ath10k_htt_tx_inc_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02003831 spin_unlock_bh(&ar->htt.tx_lock);
3832
3833 if (ret)
3834 return ret;
3835
3836 skb = ieee80211_tx_dequeue(hw, txq);
3837 if (!skb) {
3838 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05303839 ath10k_htt_tx_dec_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02003840 spin_unlock_bh(&ar->htt.tx_lock);
3841
3842 return -ENOENT;
3843 }
3844
Michal Kaziordd4717b2016-03-06 16:14:39 +02003845 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb);
Michal Kazior29946872016-03-06 16:14:34 +02003846
Michal Kazior426e10e2016-03-06 16:14:43 +02003847 skb_len = skb->len;
Michal Kazior29946872016-03-06 16:14:34 +02003848 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
3849 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05303850 is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
3851
3852 if (is_mgmt) {
3853 hdr = (struct ieee80211_hdr *)skb->data;
3854 is_presp = ieee80211_is_probe_resp(hdr->frame_control);
3855
3856 spin_lock_bh(&ar->htt.tx_lock);
3857 ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp);
3858
3859 if (ret) {
3860 ath10k_htt_tx_dec_pending(htt);
3861 spin_unlock_bh(&ar->htt.tx_lock);
3862 return ret;
3863 }
3864 spin_unlock_bh(&ar->htt.tx_lock);
3865 }
Michal Kazior29946872016-03-06 16:14:34 +02003866
3867 ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
3868 if (unlikely(ret)) {
3869 ath10k_warn(ar, "failed to push frame: %d\n", ret);
3870
3871 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05303872 ath10k_htt_tx_dec_pending(htt);
Ashok Raj Nagarajane4fd7262016-08-18 15:30:04 +05303873 if (is_mgmt)
3874 ath10k_htt_tx_mgmt_dec_pending(htt);
Michal Kazior29946872016-03-06 16:14:34 +02003875 spin_unlock_bh(&ar->htt.tx_lock);
3876
3877 return ret;
3878 }
3879
Michal Kazior3cc0fef2016-03-06 16:14:41 +02003880 spin_lock_bh(&ar->htt.tx_lock);
3881 artxq->num_fw_queued++;
3882 spin_unlock_bh(&ar->htt.tx_lock);
3883
Michal Kazior426e10e2016-03-06 16:14:43 +02003884 return skb_len;
Michal Kazior29946872016-03-06 16:14:34 +02003885}
3886
3887void ath10k_mac_tx_push_pending(struct ath10k *ar)
3888{
3889 struct ieee80211_hw *hw = ar->hw;
3890 struct ieee80211_txq *txq;
3891 struct ath10k_txq *artxq;
3892 struct ath10k_txq *last;
3893 int ret;
3894 int max;
3895
Michal Kazior7a0adc82016-05-23 23:12:45 +03003896 if (ar->htt.num_pending_tx >= (ar->htt.max_num_pending_tx / 2))
3897 return;
3898
Michal Kazior29946872016-03-06 16:14:34 +02003899 spin_lock_bh(&ar->txqs_lock);
3900 rcu_read_lock();
3901
3902 last = list_last_entry(&ar->txqs, struct ath10k_txq, list);
3903 while (!list_empty(&ar->txqs)) {
3904 artxq = list_first_entry(&ar->txqs, struct ath10k_txq, list);
3905 txq = container_of((void *)artxq, struct ieee80211_txq,
3906 drv_priv);
3907
3908 /* Prevent aggressive sta/tid taking over tx queue */
3909 max = 16;
Michal Kazior750eeed2016-03-17 10:51:05 +01003910 ret = 0;
3911 while (ath10k_mac_tx_can_push(hw, txq) && max--) {
Michal Kazior29946872016-03-06 16:14:34 +02003912 ret = ath10k_mac_tx_push_txq(hw, txq);
3913 if (ret < 0)
3914 break;
3915 }
3916
3917 list_del_init(&artxq->list);
Michal Kazior9d71d472016-03-17 10:51:04 +01003918 if (ret != -ENOENT)
3919 list_add_tail(&artxq->list, &ar->txqs);
3920
Michal Kaziorc1a43d92016-03-06 16:14:36 +02003921 ath10k_htt_tx_txq_update(hw, txq);
Michal Kazior29946872016-03-06 16:14:34 +02003922
Michal Kazior9d71d472016-03-17 10:51:04 +01003923 if (artxq == last || (ret < 0 && ret != -ENOENT))
Michal Kazior29946872016-03-06 16:14:34 +02003924 break;
Michal Kazior29946872016-03-06 16:14:34 +02003925 }
3926
3927 rcu_read_unlock();
3928 spin_unlock_bh(&ar->txqs_lock);
3929}
3930
Kalle Valo5e3dd152013-06-12 20:52:10 +03003931/************/
3932/* Scanning */
3933/************/
3934
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003935void __ath10k_scan_finish(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003936{
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003937 lockdep_assert_held(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003938
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003939 switch (ar->scan.state) {
3940 case ATH10K_SCAN_IDLE:
3941 break;
3942 case ATH10K_SCAN_RUNNING:
Michal Kazior7305d3e2014-11-24 14:58:33 +01003943 case ATH10K_SCAN_ABORTING:
Avraham Stern7947d3e2016-07-05 15:23:12 +03003944 if (!ar->scan.is_roc) {
3945 struct cfg80211_scan_info info = {
3946 .aborted = (ar->scan.state ==
3947 ATH10K_SCAN_ABORTING),
3948 };
3949
3950 ieee80211_scan_completed(ar->hw, &info);
3951 } else if (ar->scan.roc_notify) {
Michal Kaziord710e752015-07-09 13:08:36 +02003952 ieee80211_remain_on_channel_expired(ar->hw);
Avraham Stern7947d3e2016-07-05 15:23:12 +03003953 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003954 /* fall through */
3955 case ATH10K_SCAN_STARTING:
3956 ar->scan.state = ATH10K_SCAN_IDLE;
3957 ar->scan_channel = NULL;
Michal Kaziorbd877442015-11-18 06:59:19 +01003958 ar->scan.roc_freq = 0;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003959 ath10k_offchan_tx_purge(ar);
3960 cancel_delayed_work(&ar->scan.timeout);
Daniel Wagner881ed542016-08-18 15:12:06 +02003961 complete(&ar->scan.completed);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003962 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003963 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003964}
Kalle Valo5e3dd152013-06-12 20:52:10 +03003965
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003966void ath10k_scan_finish(struct ath10k *ar)
3967{
3968 spin_lock_bh(&ar->data_lock);
3969 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03003970 spin_unlock_bh(&ar->data_lock);
3971}
3972
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003973static int ath10k_scan_stop(struct ath10k *ar)
Kalle Valo5e3dd152013-06-12 20:52:10 +03003974{
3975 struct wmi_stop_scan_arg arg = {
3976 .req_id = 1, /* FIXME */
3977 .req_type = WMI_SCAN_STOP_ONE,
3978 .u.scan_id = ATH10K_SCAN_ID,
3979 };
3980 int ret;
3981
3982 lockdep_assert_held(&ar->conf_mutex);
3983
Kalle Valo5e3dd152013-06-12 20:52:10 +03003984 ret = ath10k_wmi_stop_scan(ar, &arg);
3985 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003986 ath10k_warn(ar, "failed to stop wmi scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003987 goto out;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003988 }
3989
Kalle Valo14e105c2016-04-13 14:13:21 +03003990 ret = wait_for_completion_timeout(&ar->scan.completed, 3 * HZ);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003991 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02003992 ath10k_warn(ar, "failed to receive scan abortion completion: timed out\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03003993 ret = -ETIMEDOUT;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003994 } else if (ret > 0) {
3995 ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03003996 }
Michal Kazior5c81c7f2014-08-05 14:54:44 +02003997
3998out:
3999 /* Scan state should be updated upon scan completion but in case
4000 * firmware fails to deliver the event (for whatever reason) it is
4001 * desired to clean up scan state anyway. Firmware may have just
4002 * dropped the scan completion event delivery due to transport pipe
4003 * being overflown with data and/or it can recover on its own before
4004 * next scan request is submitted.
4005 */
4006 spin_lock_bh(&ar->data_lock);
4007 if (ar->scan.state != ATH10K_SCAN_IDLE)
4008 __ath10k_scan_finish(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004009 spin_unlock_bh(&ar->data_lock);
4010
4011 return ret;
4012}
4013
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004014static void ath10k_scan_abort(struct ath10k *ar)
4015{
4016 int ret;
4017
4018 lockdep_assert_held(&ar->conf_mutex);
4019
4020 spin_lock_bh(&ar->data_lock);
4021
4022 switch (ar->scan.state) {
4023 case ATH10K_SCAN_IDLE:
4024 /* This can happen if timeout worker kicked in and called
4025 * abortion while scan completion was being processed.
4026 */
4027 break;
4028 case ATH10K_SCAN_STARTING:
4029 case ATH10K_SCAN_ABORTING:
Michal Kazior7aa7a722014-08-25 12:09:38 +02004030 ath10k_warn(ar, "refusing scan abortion due to invalid scan state: %s (%d)\n",
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004031 ath10k_scan_state_str(ar->scan.state),
4032 ar->scan.state);
4033 break;
4034 case ATH10K_SCAN_RUNNING:
4035 ar->scan.state = ATH10K_SCAN_ABORTING;
4036 spin_unlock_bh(&ar->data_lock);
4037
4038 ret = ath10k_scan_stop(ar);
4039 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004040 ath10k_warn(ar, "failed to abort scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004041
4042 spin_lock_bh(&ar->data_lock);
4043 break;
4044 }
4045
4046 spin_unlock_bh(&ar->data_lock);
4047}
4048
4049void ath10k_scan_timeout_work(struct work_struct *work)
4050{
4051 struct ath10k *ar = container_of(work, struct ath10k,
4052 scan.timeout.work);
4053
4054 mutex_lock(&ar->conf_mutex);
4055 ath10k_scan_abort(ar);
4056 mutex_unlock(&ar->conf_mutex);
4057}
4058
Kalle Valo5e3dd152013-06-12 20:52:10 +03004059static int ath10k_start_scan(struct ath10k *ar,
4060 const struct wmi_start_scan_arg *arg)
4061{
4062 int ret;
4063
4064 lockdep_assert_held(&ar->conf_mutex);
4065
4066 ret = ath10k_wmi_start_scan(ar, arg);
4067 if (ret)
4068 return ret;
4069
Kalle Valo14e105c2016-04-13 14:13:21 +03004070 ret = wait_for_completion_timeout(&ar->scan.started, 1 * HZ);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004071 if (ret == 0) {
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004072 ret = ath10k_scan_stop(ar);
4073 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02004074 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004075
4076 return -ETIMEDOUT;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004077 }
4078
Ben Greear2f9eec02015-02-15 16:50:38 +02004079 /* If we failed to start the scan, return error code at
4080 * this point. This is probably due to some issue in the
4081 * firmware, but no need to wedge the driver due to that...
4082 */
4083 spin_lock_bh(&ar->data_lock);
4084 if (ar->scan.state == ATH10K_SCAN_IDLE) {
4085 spin_unlock_bh(&ar->data_lock);
4086 return -EINVAL;
4087 }
4088 spin_unlock_bh(&ar->data_lock);
4089
Kalle Valo5e3dd152013-06-12 20:52:10 +03004090 return 0;
4091}
4092
4093/**********************/
4094/* mac80211 callbacks */
4095/**********************/
4096
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004097static void ath10k_mac_op_tx(struct ieee80211_hw *hw,
4098 struct ieee80211_tx_control *control,
4099 struct sk_buff *skb)
Kalle Valo5e3dd152013-06-12 20:52:10 +03004100{
Kalle Valo5e3dd152013-06-12 20:52:10 +03004101 struct ath10k *ar = hw->priv;
Michal Kazior6421969f2016-03-06 16:14:25 +02004102 struct ath10k_htt *htt = &ar->htt;
Michal Kazior4b604552014-07-21 21:03:09 +03004103 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
4104 struct ieee80211_vif *vif = info->control.vif;
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03004105 struct ieee80211_sta *sta = control->sta;
Michal Kaziordd4717b2016-03-06 16:14:39 +02004106 struct ieee80211_txq *txq = NULL;
Michal Kazior6421969f2016-03-06 16:14:25 +02004107 struct ieee80211_hdr *hdr = (void *)skb->data;
Michal Kazior8a933962015-11-18 06:59:17 +01004108 enum ath10k_hw_txrx_mode txmode;
Michal Kazior6421969f2016-03-06 16:14:25 +02004109 enum ath10k_mac_tx_path txpath;
4110 bool is_htt;
4111 bool is_mgmt;
4112 bool is_presp;
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004113 int ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004114
Michal Kaziordd4717b2016-03-06 16:14:39 +02004115 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004116
Michal Kazior8a933962015-11-18 06:59:17 +01004117 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
Michal Kazior6421969f2016-03-06 16:14:25 +02004118 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
4119 is_htt = (txpath == ATH10K_MAC_TX_HTT ||
4120 txpath == ATH10K_MAC_TX_HTT_MGMT);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304121 is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004122
Michal Kazior6421969f2016-03-06 16:14:25 +02004123 if (is_htt) {
4124 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior6421969f2016-03-06 16:14:25 +02004125 is_presp = ieee80211_is_probe_resp(hdr->frame_control);
4126
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304127 ret = ath10k_htt_tx_inc_pending(htt);
Michal Kazior6421969f2016-03-06 16:14:25 +02004128 if (ret) {
4129 ath10k_warn(ar, "failed to increase tx pending count: %d, dropping\n",
4130 ret);
4131 spin_unlock_bh(&ar->htt.tx_lock);
4132 ieee80211_free_txskb(ar->hw, skb);
4133 return;
4134 }
4135
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304136 ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp);
4137 if (ret) {
Rajkumar Manoharandd7c2802016-04-07 12:07:30 +05304138 ath10k_dbg(ar, ATH10K_DBG_MAC, "failed to increase tx mgmt pending count: %d, dropping\n",
4139 ret);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304140 ath10k_htt_tx_dec_pending(htt);
4141 spin_unlock_bh(&ar->htt.tx_lock);
4142 ieee80211_free_txskb(ar->hw, skb);
4143 return;
4144 }
Michal Kazior6421969f2016-03-06 16:14:25 +02004145 spin_unlock_bh(&ar->htt.tx_lock);
4146 }
4147
4148 ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
4149 if (ret) {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01004150 ath10k_warn(ar, "failed to transmit frame: %d\n", ret);
Michal Kazior6421969f2016-03-06 16:14:25 +02004151 if (is_htt) {
4152 spin_lock_bh(&ar->htt.tx_lock);
Rajkumar Manoharancac08552016-03-09 20:25:46 +05304153 ath10k_htt_tx_dec_pending(htt);
4154 if (is_mgmt)
4155 ath10k_htt_tx_mgmt_dec_pending(htt);
Michal Kazior6421969f2016-03-06 16:14:25 +02004156 spin_unlock_bh(&ar->htt.tx_lock);
4157 }
4158 return;
4159 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004160}
4161
Michal Kazior29946872016-03-06 16:14:34 +02004162static void ath10k_mac_op_wake_tx_queue(struct ieee80211_hw *hw,
4163 struct ieee80211_txq *txq)
4164{
4165 struct ath10k *ar = hw->priv;
4166 struct ath10k_txq *artxq = (void *)txq->drv_priv;
Rajkumar Manoharan83e164b2016-08-17 21:02:53 +05304167 struct ieee80211_txq *f_txq;
4168 struct ath10k_txq *f_artxq;
4169 int ret = 0;
4170 int max = 16;
Michal Kazior29946872016-03-06 16:14:34 +02004171
Michal Kazior750eeed2016-03-17 10:51:05 +01004172 spin_lock_bh(&ar->txqs_lock);
4173 if (list_empty(&artxq->list))
4174 list_add_tail(&artxq->list, &ar->txqs);
Rajkumar Manoharan83e164b2016-08-17 21:02:53 +05304175
4176 f_artxq = list_first_entry(&ar->txqs, struct ath10k_txq, list);
4177 f_txq = container_of((void *)f_artxq, struct ieee80211_txq, drv_priv);
4178 list_del_init(&f_artxq->list);
4179
4180 while (ath10k_mac_tx_can_push(hw, f_txq) && max--) {
4181 ret = ath10k_mac_tx_push_txq(hw, f_txq);
4182 if (ret)
4183 break;
4184 }
4185 if (ret != -ENOENT)
4186 list_add_tail(&f_artxq->list, &ar->txqs);
Michal Kazior750eeed2016-03-17 10:51:05 +01004187 spin_unlock_bh(&ar->txqs_lock);
Michal Kazior29946872016-03-06 16:14:34 +02004188
Rajkumar Manoharan83e164b2016-08-17 21:02:53 +05304189 ath10k_htt_tx_txq_update(hw, f_txq);
Michal Kaziorc1a43d92016-03-06 16:14:36 +02004190 ath10k_htt_tx_txq_update(hw, txq);
Michal Kazior29946872016-03-06 16:14:34 +02004191}
4192
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004193/* Must not be called with conf_mutex held as workers can use that also. */
Michal Kazior7962b0d2014-10-28 10:34:38 +01004194void ath10k_drain_tx(struct ath10k *ar)
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004195{
4196 /* make sure rcu-protected mac80211 tx path itself is drained */
4197 synchronize_net();
4198
4199 ath10k_offchan_tx_purge(ar);
4200 ath10k_mgmt_over_wmi_tx_purge(ar);
4201
4202 cancel_work_sync(&ar->offchan_tx_work);
4203 cancel_work_sync(&ar->wmi_mgmt_tx_work);
4204}
4205
Michal Kazioraffd3212013-07-16 09:54:35 +02004206void ath10k_halt(struct ath10k *ar)
Michal Kazior818bdd12013-07-16 09:38:57 +02004207{
Michal Kaziord9bc4b92014-04-23 19:30:06 +03004208 struct ath10k_vif *arvif;
4209
Michal Kazior818bdd12013-07-16 09:38:57 +02004210 lockdep_assert_held(&ar->conf_mutex);
4211
Michal Kazior19337472014-08-28 12:58:16 +02004212 clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
4213 ar->filter_flags = 0;
4214 ar->monitor = false;
Michal Kazior500ff9f2015-03-31 10:26:21 +00004215 ar->monitor_arvif = NULL;
Michal Kazior19337472014-08-28 12:58:16 +02004216
4217 if (ar->monitor_started)
Michal Kazior1bbc0972014-04-08 09:45:47 +03004218 ath10k_monitor_stop(ar);
Michal Kazior19337472014-08-28 12:58:16 +02004219
4220 ar->monitor_started = false;
Michal Kazior96d828d2015-03-31 10:26:23 +00004221 ar->tx_paused = 0;
Michal Kazior1bbc0972014-04-08 09:45:47 +03004222
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004223 ath10k_scan_finish(ar);
Michal Kazior818bdd12013-07-16 09:38:57 +02004224 ath10k_peer_cleanup_all(ar);
4225 ath10k_core_stop(ar);
4226 ath10k_hif_power_down(ar);
4227
4228 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03004229 list_for_each_entry(arvif, &ar->arvifs, list)
4230 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kazior818bdd12013-07-16 09:38:57 +02004231 spin_unlock_bh(&ar->data_lock);
4232}
4233
Ben Greear46acf7b2014-05-16 17:15:38 +03004234static int ath10k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
4235{
4236 struct ath10k *ar = hw->priv;
4237
4238 mutex_lock(&ar->conf_mutex);
4239
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05304240 *tx_ant = ar->cfg_tx_chainmask;
4241 *rx_ant = ar->cfg_rx_chainmask;
Ben Greear46acf7b2014-05-16 17:15:38 +03004242
4243 mutex_unlock(&ar->conf_mutex);
4244
4245 return 0;
4246}
4247
Ben Greear5572a952014-11-24 16:22:10 +02004248static void ath10k_check_chain_mask(struct ath10k *ar, u32 cm, const char *dbg)
4249{
4250 /* It is not clear that allowing gaps in chainmask
4251 * is helpful. Probably it will not do what user
4252 * is hoping for, so warn in that case.
4253 */
4254 if (cm == 15 || cm == 7 || cm == 3 || cm == 1 || cm == 0)
4255 return;
4256
4257 ath10k_warn(ar, "mac %s antenna chainmask may be invalid: 0x%x. Suggested values: 15, 7, 3, 1 or 0.\n",
4258 dbg, cm);
4259}
4260
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304261static int ath10k_mac_get_vht_cap_bf_sts(struct ath10k *ar)
4262{
4263 int nsts = ar->vht_cap_info;
4264
4265 nsts &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
4266 nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
4267
4268 /* If firmware does not deliver to host number of space-time
4269 * streams supported, assume it support up to 4 BF STS and return
4270 * the value for VHT CAP: nsts-1)
4271 */
4272 if (nsts == 0)
4273 return 3;
4274
4275 return nsts;
4276}
4277
4278static int ath10k_mac_get_vht_cap_bf_sound_dim(struct ath10k *ar)
4279{
4280 int sound_dim = ar->vht_cap_info;
4281
4282 sound_dim &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
4283 sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
4284
4285 /* If the sounding dimension is not advertised by the firmware,
4286 * let's use a default value of 1
4287 */
4288 if (sound_dim == 0)
4289 return 1;
4290
4291 return sound_dim;
4292}
4293
4294static struct ieee80211_sta_vht_cap ath10k_create_vht_cap(struct ath10k *ar)
4295{
4296 struct ieee80211_sta_vht_cap vht_cap = {0};
4297 u16 mcs_map;
4298 u32 val;
4299 int i;
4300
4301 vht_cap.vht_supported = 1;
4302 vht_cap.cap = ar->vht_cap_info;
4303
4304 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
4305 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
4306 val = ath10k_mac_get_vht_cap_bf_sts(ar);
4307 val <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
4308 val &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
4309
4310 vht_cap.cap |= val;
4311 }
4312
4313 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
4314 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
4315 val = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
4316 val <<= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
4317 val &= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
4318
4319 vht_cap.cap |= val;
4320 }
4321
4322 mcs_map = 0;
4323 for (i = 0; i < 8; i++) {
4324 if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i)))
4325 mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2);
4326 else
4327 mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2);
4328 }
4329
Mohammed Shafi Shajakhan34663242016-06-29 19:29:27 +03004330 if (ar->cfg_tx_chainmask <= 1)
4331 vht_cap.cap &= ~IEEE80211_VHT_CAP_TXSTBC;
4332
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304333 vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
4334 vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
4335
4336 return vht_cap;
4337}
4338
4339static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar)
4340{
4341 int i;
4342 struct ieee80211_sta_ht_cap ht_cap = {0};
4343
4344 if (!(ar->ht_cap_info & WMI_HT_CAP_ENABLED))
4345 return ht_cap;
4346
4347 ht_cap.ht_supported = 1;
4348 ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
4349 ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
4350 ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4351 ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
Peter Ohe33a99e2015-12-31 15:26:20 +02004352 ht_cap.cap |=
4353 WLAN_HT_CAP_SM_PS_DISABLED << IEEE80211_HT_CAP_SM_PS_SHIFT;
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304354
4355 if (ar->ht_cap_info & WMI_HT_CAP_HT20_SGI)
4356 ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
4357
4358 if (ar->ht_cap_info & WMI_HT_CAP_HT40_SGI)
4359 ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
4360
4361 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) {
4362 u32 smps;
4363
4364 smps = WLAN_HT_CAP_SM_PS_DYNAMIC;
4365 smps <<= IEEE80211_HT_CAP_SM_PS_SHIFT;
4366
4367 ht_cap.cap |= smps;
4368 }
4369
Mohammed Shafi Shajakhan34663242016-06-29 19:29:27 +03004370 if (ar->ht_cap_info & WMI_HT_CAP_TX_STBC && (ar->cfg_tx_chainmask > 1))
Rajkumar Manoharanf58512f2015-10-27 17:51:13 +05304371 ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
4372
4373 if (ar->ht_cap_info & WMI_HT_CAP_RX_STBC) {
4374 u32 stbc;
4375
4376 stbc = ar->ht_cap_info;
4377 stbc &= WMI_HT_CAP_RX_STBC;
4378 stbc >>= WMI_HT_CAP_RX_STBC_MASK_SHIFT;
4379 stbc <<= IEEE80211_HT_CAP_RX_STBC_SHIFT;
4380 stbc &= IEEE80211_HT_CAP_RX_STBC;
4381
4382 ht_cap.cap |= stbc;
4383 }
4384
4385 if (ar->ht_cap_info & WMI_HT_CAP_LDPC)
4386 ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
4387
4388 if (ar->ht_cap_info & WMI_HT_CAP_L_SIG_TXOP_PROT)
4389 ht_cap.cap |= IEEE80211_HT_CAP_LSIG_TXOP_PROT;
4390
4391 /* max AMSDU is implicitly taken from vht_cap_info */
4392 if (ar->vht_cap_info & WMI_VHT_CAP_MAX_MPDU_LEN_MASK)
4393 ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
4394
4395 for (i = 0; i < ar->num_rf_chains; i++) {
4396 if (ar->cfg_rx_chainmask & BIT(i))
4397 ht_cap.mcs.rx_mask[i] = 0xFF;
4398 }
4399
4400 ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
4401
4402 return ht_cap;
4403}
4404
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304405static void ath10k_mac_setup_ht_vht_cap(struct ath10k *ar)
4406{
4407 struct ieee80211_supported_band *band;
4408 struct ieee80211_sta_vht_cap vht_cap;
4409 struct ieee80211_sta_ht_cap ht_cap;
4410
4411 ht_cap = ath10k_get_ht_cap(ar);
4412 vht_cap = ath10k_create_vht_cap(ar);
4413
4414 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02004415 band = &ar->mac.sbands[NL80211_BAND_2GHZ];
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304416 band->ht_cap = ht_cap;
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304417 }
4418 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
Johannes Berg57fbcce2016-04-12 15:56:15 +02004419 band = &ar->mac.sbands[NL80211_BAND_5GHZ];
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304420 band->ht_cap = ht_cap;
4421 band->vht_cap = vht_cap;
4422 }
4423}
4424
Ben Greear46acf7b2014-05-16 17:15:38 +03004425static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant)
4426{
4427 int ret;
4428
4429 lockdep_assert_held(&ar->conf_mutex);
4430
Ben Greear5572a952014-11-24 16:22:10 +02004431 ath10k_check_chain_mask(ar, tx_ant, "tx");
4432 ath10k_check_chain_mask(ar, rx_ant, "rx");
4433
Ben Greear46acf7b2014-05-16 17:15:38 +03004434 ar->cfg_tx_chainmask = tx_ant;
4435 ar->cfg_rx_chainmask = rx_ant;
4436
4437 if ((ar->state != ATH10K_STATE_ON) &&
4438 (ar->state != ATH10K_STATE_RESTARTED))
4439 return 0;
4440
4441 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->tx_chain_mask,
4442 tx_ant);
4443 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004444 ath10k_warn(ar, "failed to set tx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7b2014-05-16 17:15:38 +03004445 ret, tx_ant);
4446 return ret;
4447 }
4448
4449 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rx_chain_mask,
4450 rx_ant);
4451 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004452 ath10k_warn(ar, "failed to set rx-chainmask: %d, req 0x%x\n",
Ben Greear46acf7b2014-05-16 17:15:38 +03004453 ret, rx_ant);
4454 return ret;
4455 }
4456
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05304457 /* Reload HT/VHT capability */
4458 ath10k_mac_setup_ht_vht_cap(ar);
4459
Ben Greear46acf7b2014-05-16 17:15:38 +03004460 return 0;
4461}
4462
4463static int ath10k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
4464{
4465 struct ath10k *ar = hw->priv;
4466 int ret;
4467
4468 mutex_lock(&ar->conf_mutex);
4469 ret = __ath10k_set_antenna(ar, tx_ant, rx_ant);
4470 mutex_unlock(&ar->conf_mutex);
4471 return ret;
4472}
4473
Kalle Valo5e3dd152013-06-12 20:52:10 +03004474static int ath10k_start(struct ieee80211_hw *hw)
4475{
4476 struct ath10k *ar = hw->priv;
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304477 u32 param;
Michal Kazior818bdd12013-07-16 09:38:57 +02004478 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004479
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004480 /*
4481 * This makes sense only when restarting hw. It is harmless to call
Mohammed Shafi Shajakhan6dfdbfc2016-04-26 14:41:36 +03004482 * unconditionally. This is necessary to make sure no HTT/WMI tx
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004483 * commands will be submitted while restarting.
4484 */
4485 ath10k_drain_tx(ar);
4486
Michal Kazior548db542013-07-05 16:15:15 +03004487 mutex_lock(&ar->conf_mutex);
4488
Michal Kaziorc5058f52014-05-26 12:46:03 +03004489 switch (ar->state) {
4490 case ATH10K_STATE_OFF:
4491 ar->state = ATH10K_STATE_ON;
4492 break;
4493 case ATH10K_STATE_RESTARTING:
Michal Kaziorc5058f52014-05-26 12:46:03 +03004494 ar->state = ATH10K_STATE_RESTARTED;
4495 break;
4496 case ATH10K_STATE_ON:
4497 case ATH10K_STATE_RESTARTED:
4498 case ATH10K_STATE_WEDGED:
4499 WARN_ON(1);
Michal Kazior818bdd12013-07-16 09:38:57 +02004500 ret = -EINVAL;
Michal Kaziorae254432014-05-26 12:46:02 +03004501 goto err;
Kalle Valo43d2a302014-09-10 18:23:30 +03004502 case ATH10K_STATE_UTF:
4503 ret = -EBUSY;
4504 goto err;
Michal Kazior818bdd12013-07-16 09:38:57 +02004505 }
4506
4507 ret = ath10k_hif_power_up(ar);
4508 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004509 ath10k_err(ar, "Could not init hif: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004510 goto err_off;
Michal Kazior818bdd12013-07-16 09:38:57 +02004511 }
4512
Kalle Valo7ebf7212016-04-20 19:44:51 +03004513 ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL,
4514 &ar->normal_mode_fw);
Michal Kazior818bdd12013-07-16 09:38:57 +02004515 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004516 ath10k_err(ar, "Could not init core: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004517 goto err_power_down;
Michal Kazior818bdd12013-07-16 09:38:57 +02004518 }
4519
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304520 param = ar->wmi.pdev_param->pmf_qos;
4521 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004522 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004523 ath10k_warn(ar, "failed to enable PMF QOS: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004524 goto err_core_stop;
4525 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004526
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304527 param = ar->wmi.pdev_param->dynamic_bw;
4528 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Michal Kaziorae254432014-05-26 12:46:02 +03004529 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004530 ath10k_warn(ar, "failed to enable dynamic BW: %d\n", ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004531 goto err_core_stop;
4532 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004533
Michal Kaziorcf327842015-03-31 10:26:25 +00004534 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
4535 ret = ath10k_wmi_adaptive_qcs(ar, true);
4536 if (ret) {
4537 ath10k_warn(ar, "failed to enable adaptive qcs: %d\n",
4538 ret);
4539 goto err_core_stop;
4540 }
4541 }
4542
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03004543 if (test_bit(WMI_SERVICE_BURST, ar->wmi.svc_map)) {
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304544 param = ar->wmi.pdev_param->burst_enable;
4545 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
Janusz Dziedzic24ab13e2015-04-01 22:53:18 +03004546 if (ret) {
4547 ath10k_warn(ar, "failed to disable burst: %d\n", ret);
4548 goto err_core_stop;
4549 }
4550 }
4551
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05304552 __ath10k_set_antenna(ar, ar->cfg_tx_chainmask, ar->cfg_rx_chainmask);
Ben Greear46acf7b2014-05-16 17:15:38 +03004553
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004554 /*
4555 * By default FW set ARP frames ac to voice (6). In that case ARP
4556 * exchange is not working properly for UAPSD enabled AP. ARP requests
4557 * which arrives with access category 0 are processed by network stack
4558 * and send back with access category 0, but FW changes access category
4559 * to 6. Set ARP frames access category to best effort (0) solves
4560 * this problem.
4561 */
4562
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304563 param = ar->wmi.pdev_param->arp_ac_override;
4564 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004565 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004566 ath10k_warn(ar, "failed to set arp ac override parameter: %d\n",
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004567 ret);
Michal Kaziorae254432014-05-26 12:46:02 +03004568 goto err_core_stop;
Marek Puzyniakab6258e2014-01-29 15:03:31 +02004569 }
4570
Maharaja62f77f02015-10-21 11:49:18 +03004571 if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA,
Kalle Valoc4cdf752016-04-20 19:45:18 +03004572 ar->running_fw->fw_file.fw_features)) {
Maharaja62f77f02015-10-21 11:49:18 +03004573 ret = ath10k_wmi_pdev_enable_adaptive_cca(ar, 1,
4574 WMI_CCA_DETECT_LEVEL_AUTO,
4575 WMI_CCA_DETECT_MARGIN_AUTO);
4576 if (ret) {
4577 ath10k_warn(ar, "failed to enable adaptive cca: %d\n",
4578 ret);
4579 goto err_core_stop;
4580 }
4581 }
4582
Mohammed Shafi Shajakhan1fe374f2016-01-13 21:16:30 +05304583 param = ar->wmi.pdev_param->ani_enable;
4584 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
Ashok Raj Nagarajan575f1c32015-03-19 16:37:59 +05304585 if (ret) {
4586 ath10k_warn(ar, "failed to enable ani by default: %d\n",
4587 ret);
4588 goto err_core_stop;
4589 }
4590
Ashok Raj Nagarajanb3e71d72015-03-19 16:38:00 +05304591 ar->ani_enabled = true;
4592
Mohammed Shafi Shajakhancc61a1b2016-03-16 18:13:32 +05304593 if (ath10k_peer_stats_enabled(ar)) {
Mohammed Shafi Shajakhan8351c052016-01-13 21:16:33 +05304594 param = ar->wmi.pdev_param->peer_stats_update_period;
4595 ret = ath10k_wmi_pdev_set_param(ar, param,
4596 PEER_DEFAULT_STATS_UPDATE_PERIOD);
4597 if (ret) {
4598 ath10k_warn(ar,
4599 "failed to set peer stats period : %d\n",
4600 ret);
4601 goto err_core_stop;
4602 }
4603 }
4604
Rajkumar Manoharan39136242016-05-27 20:15:59 +05304605 param = ar->wmi.pdev_param->enable_btcoex;
4606 if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map) &&
4607 test_bit(ATH10K_FW_FEATURE_BTCOEX_PARAM,
4608 ar->running_fw->fw_file.fw_features)) {
4609 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
4610 if (ret) {
4611 ath10k_warn(ar,
4612 "failed to set btcoex param: %d\n", ret);
4613 goto err_core_stop;
4614 }
4615 clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
4616 }
4617
Michal Kaziord6500972014-04-08 09:56:09 +03004618 ar->num_started_vdevs = 0;
Michal Kaziorf7843d72013-07-16 09:38:52 +02004619 ath10k_regd_update(ar);
4620
Simon Wunderlich855aed12014-08-02 09:12:54 +03004621 ath10k_spectral_start(ar);
Rajkumar Manoharan8515b5c2015-03-15 20:36:22 +05304622 ath10k_thermal_set_throttling(ar);
Simon Wunderlich855aed12014-08-02 09:12:54 +03004623
Michal Kaziorae254432014-05-26 12:46:02 +03004624 mutex_unlock(&ar->conf_mutex);
4625 return 0;
4626
4627err_core_stop:
4628 ath10k_core_stop(ar);
4629
4630err_power_down:
4631 ath10k_hif_power_down(ar);
4632
4633err_off:
4634 ar->state = ATH10K_STATE_OFF;
4635
4636err:
Michal Kazior548db542013-07-05 16:15:15 +03004637 mutex_unlock(&ar->conf_mutex);
Michal Kaziorc60bdd82014-01-29 07:26:31 +01004638 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004639}
4640
4641static void ath10k_stop(struct ieee80211_hw *hw)
4642{
4643 struct ath10k *ar = hw->priv;
4644
Michal Kaziorbca7baf2014-05-26 12:46:03 +03004645 ath10k_drain_tx(ar);
4646
Michal Kazior548db542013-07-05 16:15:15 +03004647 mutex_lock(&ar->conf_mutex);
Michal Kaziorc5058f52014-05-26 12:46:03 +03004648 if (ar->state != ATH10K_STATE_OFF) {
Michal Kazior818bdd12013-07-16 09:38:57 +02004649 ath10k_halt(ar);
Michal Kaziorc5058f52014-05-26 12:46:03 +03004650 ar->state = ATH10K_STATE_OFF;
4651 }
Michal Kazior548db542013-07-05 16:15:15 +03004652 mutex_unlock(&ar->conf_mutex);
4653
Michal Kazior5c81c7f2014-08-05 14:54:44 +02004654 cancel_delayed_work_sync(&ar->scan.timeout);
Michal Kazioraffd3212013-07-16 09:54:35 +02004655 cancel_work_sync(&ar->restart_work);
4656}
4657
Michal Kaziorad088bf2013-10-16 15:44:46 +03004658static int ath10k_config_ps(struct ath10k *ar)
Michal Kazioraffd3212013-07-16 09:54:35 +02004659{
Michal Kaziorad088bf2013-10-16 15:44:46 +03004660 struct ath10k_vif *arvif;
4661 int ret = 0;
Michal Kazioraffd3212013-07-16 09:54:35 +02004662
4663 lockdep_assert_held(&ar->conf_mutex);
4664
Michal Kaziorad088bf2013-10-16 15:44:46 +03004665 list_for_each_entry(arvif, &ar->arvifs, list) {
4666 ret = ath10k_mac_vif_setup_ps(arvif);
4667 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004668 ath10k_warn(ar, "failed to setup powersave: %d\n", ret);
Michal Kaziorad088bf2013-10-16 15:44:46 +03004669 break;
4670 }
4671 }
Michal Kazioraffd3212013-07-16 09:54:35 +02004672
Michal Kaziorad088bf2013-10-16 15:44:46 +03004673 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004674}
4675
Michal Kazior7d9d5582014-10-21 10:40:15 +03004676static int ath10k_mac_txpower_setup(struct ath10k *ar, int txpower)
4677{
4678 int ret;
4679 u32 param;
4680
4681 lockdep_assert_held(&ar->conf_mutex);
4682
4683 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac txpower %d\n", txpower);
4684
4685 param = ar->wmi.pdev_param->txpower_limit2g;
4686 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
4687 if (ret) {
4688 ath10k_warn(ar, "failed to set 2g txpower %d: %d\n",
4689 txpower, ret);
4690 return ret;
4691 }
4692
4693 param = ar->wmi.pdev_param->txpower_limit5g;
4694 ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2);
4695 if (ret) {
4696 ath10k_warn(ar, "failed to set 5g txpower %d: %d\n",
4697 txpower, ret);
4698 return ret;
4699 }
4700
4701 return 0;
4702}
4703
4704static int ath10k_mac_txpower_recalc(struct ath10k *ar)
4705{
4706 struct ath10k_vif *arvif;
4707 int ret, txpower = -1;
4708
4709 lockdep_assert_held(&ar->conf_mutex);
4710
4711 list_for_each_entry(arvif, &ar->arvifs, list) {
Ryan Hsu77bc3e92016-12-13 14:55:19 -08004712 if (arvif->txpower <= 0)
4713 continue;
Michal Kazior7d9d5582014-10-21 10:40:15 +03004714
4715 if (txpower == -1)
4716 txpower = arvif->txpower;
4717 else
4718 txpower = min(txpower, arvif->txpower);
4719 }
4720
Ryan Hsu77bc3e92016-12-13 14:55:19 -08004721 if (txpower == -1)
4722 return 0;
Michal Kazior7d9d5582014-10-21 10:40:15 +03004723
4724 ret = ath10k_mac_txpower_setup(ar, txpower);
4725 if (ret) {
4726 ath10k_warn(ar, "failed to setup tx power %d: %d\n",
4727 txpower, ret);
4728 return ret;
4729 }
4730
4731 return 0;
4732}
4733
Kalle Valo5e3dd152013-06-12 20:52:10 +03004734static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
4735{
Kalle Valo5e3dd152013-06-12 20:52:10 +03004736 struct ath10k *ar = hw->priv;
4737 struct ieee80211_conf *conf = &hw->conf;
4738 int ret = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004739
4740 mutex_lock(&ar->conf_mutex);
4741
Michal Kazioraffd3212013-07-16 09:54:35 +02004742 if (changed & IEEE80211_CONF_CHANGE_PS)
4743 ath10k_config_ps(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004744
4745 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
Michal Kazior19337472014-08-28 12:58:16 +02004746 ar->monitor = conf->flags & IEEE80211_CONF_MONITOR;
4747 ret = ath10k_monitor_recalc(ar);
4748 if (ret)
4749 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004750 }
4751
4752 mutex_unlock(&ar->conf_mutex);
4753 return ret;
4754}
4755
Ben Greear5572a952014-11-24 16:22:10 +02004756static u32 get_nss_from_chainmask(u16 chain_mask)
4757{
Rajkumar Manoharanf680f702015-11-03 11:51:33 +05304758 if ((chain_mask & 0xf) == 0xf)
Ben Greear5572a952014-11-24 16:22:10 +02004759 return 4;
4760 else if ((chain_mask & 0x7) == 0x7)
4761 return 3;
4762 else if ((chain_mask & 0x3) == 0x3)
4763 return 2;
4764 return 1;
4765}
4766
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304767static int ath10k_mac_set_txbf_conf(struct ath10k_vif *arvif)
4768{
4769 u32 value = 0;
4770 struct ath10k *ar = arvif->ar;
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004771 int nsts;
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004772 int sound_dim;
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304773
4774 if (ath10k_wmi_get_txbf_conf_scheme(ar) != WMI_TXBF_CONF_BEFORE_ASSOC)
4775 return 0;
4776
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004777 nsts = ath10k_mac_get_vht_cap_bf_sts(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304778 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
4779 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE))
Bartosz Markowski707a0c82015-09-02 13:20:19 +02004780 value |= SM(nsts, WMI_TXBF_STS_CAP_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304781
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004782 sound_dim = ath10k_mac_get_vht_cap_bf_sound_dim(ar);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304783 if (ar->vht_cap_info & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
4784 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE))
Bartosz Markowski0c6d6f22015-09-02 13:20:20 +02004785 value |= SM(sound_dim, WMI_BF_SOUND_DIM_OFFSET);
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05304786
4787 if (!value)
4788 return 0;
4789
4790 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
4791 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
4792
4793 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
4794 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFER |
4795 WMI_VDEV_PARAM_TXBF_SU_TX_BFER);
4796
4797 if (ar->vht_cap_info & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
4798 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
4799
4800 if (ar->vht_cap_info & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
4801 value |= (WMI_VDEV_PARAM_TXBF_MU_TX_BFEE |
4802 WMI_VDEV_PARAM_TXBF_SU_TX_BFEE);
4803
4804 return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
4805 ar->wmi.vdev_param->txbf, value);
4806}
4807
Kalle Valo5e3dd152013-06-12 20:52:10 +03004808/*
4809 * TODO:
4810 * Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE,
4811 * because we will send mgmt frames without CCK. This requirement
4812 * for P2P_FIND/GO_NEG should be handled by checking CCK flag
4813 * in the TX packet.
4814 */
4815static int ath10k_add_interface(struct ieee80211_hw *hw,
4816 struct ieee80211_vif *vif)
4817{
4818 struct ath10k *ar = hw->priv;
4819 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02004820 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004821 enum wmi_sta_powersave_param param;
4822 int ret = 0;
Kalle Valo5a13e762014-01-20 11:01:46 +02004823 u32 value;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004824 int bit;
Michal Kazior96d828d2015-03-31 10:26:23 +00004825 int i;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004826 u32 vdev_param;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004827
Johannes Berg848955c2014-11-11 12:48:42 +01004828 vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
4829
Kalle Valo5e3dd152013-06-12 20:52:10 +03004830 mutex_lock(&ar->conf_mutex);
4831
Michal Kazior0dbd09e2013-07-31 10:55:14 +02004832 memset(arvif, 0, sizeof(*arvif));
Michal Kazior29946872016-03-06 16:14:34 +02004833 ath10k_mac_txq_init(vif->txq);
Michal Kazior0dbd09e2013-07-31 10:55:14 +02004834
Kalle Valo5e3dd152013-06-12 20:52:10 +03004835 arvif->ar = ar;
4836 arvif->vif = vif;
4837
Ben Greeare63b33f2013-10-22 14:54:14 -07004838 INIT_LIST_HEAD(&arvif->list);
Michal Kazior81a9a172015-03-05 16:02:17 +02004839 INIT_WORK(&arvif->ap_csa_work, ath10k_mac_vif_ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02004840 INIT_DELAYED_WORK(&arvif->connection_loss_work,
4841 ath10k_mac_vif_sta_connection_loss_work);
Michal Kaziorcc4827b2013-10-16 15:44:45 +03004842
Michal Kazior45c9abc2015-04-21 20:42:58 +03004843 for (i = 0; i < ARRAY_SIZE(arvif->bitrate_mask.control); i++) {
4844 arvif->bitrate_mask.control[i].legacy = 0xffffffff;
4845 memset(arvif->bitrate_mask.control[i].ht_mcs, 0xff,
4846 sizeof(arvif->bitrate_mask.control[i].ht_mcs));
4847 memset(arvif->bitrate_mask.control[i].vht_mcs, 0xff,
4848 sizeof(arvif->bitrate_mask.control[i].vht_mcs));
4849 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004850
Michal Kaziore04cafb2015-08-05 12:15:24 +02004851 if (ar->num_peers >= ar->max_num_peers) {
4852 ath10k_warn(ar, "refusing vdev creation due to insufficient peer entry resources in firmware\n");
Michal Kazior503422d2015-08-19 13:08:53 +02004853 ret = -ENOBUFS;
4854 goto err;
Michal Kaziore04cafb2015-08-05 12:15:24 +02004855 }
4856
Ben Greeara9aefb32014-08-12 11:02:19 +03004857 if (ar->free_vdev_map == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004858 ath10k_warn(ar, "Free vdev map is empty, no more interfaces allowed.\n");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004859 ret = -EBUSY;
Michal Kazior9dad14a2013-10-16 15:44:45 +03004860 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004861 }
Ben Greear16c11172014-09-23 14:17:16 -07004862 bit = __ffs64(ar->free_vdev_map);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004863
Ben Greear16c11172014-09-23 14:17:16 -07004864 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac create vdev %i map %llx\n",
4865 bit, ar->free_vdev_map);
4866
4867 arvif->vdev_id = bit;
Peter Oh6e4de1a2016-01-28 13:54:10 -08004868 arvif->vdev_subtype =
4869 ath10k_wmi_get_vdev_subtype(ar, WMI_VDEV_SUBTYPE_NONE);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004870
Kalle Valo5e3dd152013-06-12 20:52:10 +03004871 switch (vif->type) {
Michal Kazior75d2bd42014-12-12 12:41:39 +01004872 case NL80211_IFTYPE_P2P_DEVICE:
4873 arvif->vdev_type = WMI_VDEV_TYPE_STA;
Peter Oh6e4de1a2016-01-28 13:54:10 -08004874 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4875 (ar, WMI_VDEV_SUBTYPE_P2P_DEVICE);
Michal Kazior75d2bd42014-12-12 12:41:39 +01004876 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004877 case NL80211_IFTYPE_UNSPECIFIED:
4878 case NL80211_IFTYPE_STATION:
4879 arvif->vdev_type = WMI_VDEV_TYPE_STA;
4880 if (vif->p2p)
Peter Oh6e4de1a2016-01-28 13:54:10 -08004881 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4882 (ar, WMI_VDEV_SUBTYPE_P2P_CLIENT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004883 break;
4884 case NL80211_IFTYPE_ADHOC:
4885 arvif->vdev_type = WMI_VDEV_TYPE_IBSS;
4886 break;
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004887 case NL80211_IFTYPE_MESH_POINT:
Peter Oh0b3d76e2016-01-28 13:54:07 -08004888 if (test_bit(WMI_SERVICE_MESH_11S, ar->wmi.svc_map)) {
Peter Oh6e4de1a2016-01-28 13:54:10 -08004889 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4890 (ar, WMI_VDEV_SUBTYPE_MESH_11S);
Peter Ohbb58b892015-11-24 09:37:35 -08004891 } else if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004892 ret = -EINVAL;
4893 ath10k_warn(ar, "must load driver with rawmode=1 to add mesh interfaces\n");
4894 goto err;
4895 }
4896 arvif->vdev_type = WMI_VDEV_TYPE_AP;
4897 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004898 case NL80211_IFTYPE_AP:
4899 arvif->vdev_type = WMI_VDEV_TYPE_AP;
4900
4901 if (vif->p2p)
Peter Oh6e4de1a2016-01-28 13:54:10 -08004902 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4903 (ar, WMI_VDEV_SUBTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03004904 break;
4905 case NL80211_IFTYPE_MONITOR:
4906 arvif->vdev_type = WMI_VDEV_TYPE_MONITOR;
4907 break;
4908 default:
4909 WARN_ON(1);
4910 break;
4911 }
4912
Michal Kazior96d828d2015-03-31 10:26:23 +00004913 /* Using vdev_id as queue number will make it very easy to do per-vif
4914 * tx queue locking. This shouldn't wrap due to interface combinations
4915 * but do a modulo for correctness sake and prevent using offchannel tx
4916 * queues for regular vif tx.
4917 */
4918 vif->cab_queue = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
4919 for (i = 0; i < ARRAY_SIZE(vif->hw_queue); i++)
4920 vif->hw_queue[i] = arvif->vdev_id % (IEEE80211_MAX_QUEUES - 1);
4921
Michal Kazior64badcb2014-09-18 11:18:02 +03004922 /* Some firmware revisions don't wait for beacon tx completion before
4923 * sending another SWBA event. This could lead to hardware using old
4924 * (freed) beacon data in some cases, e.g. tx credit starvation
4925 * combined with missed TBTT. This is very very rare.
4926 *
4927 * On non-IOMMU-enabled hosts this could be a possible security issue
4928 * because hw could beacon some random data on the air. On
4929 * IOMMU-enabled hosts DMAR faults would occur in most cases and target
4930 * device would crash.
4931 *
4932 * Since there are no beacon tx completions (implicit nor explicit)
4933 * propagated to host the only workaround for this is to allocate a
4934 * DMA-coherent buffer for a lifetime of a vif and use it for all
4935 * beacon tx commands. Worst case for this approach is some beacons may
4936 * become corrupted, e.g. have garbled IEs or out-of-date TIM bitmap.
4937 */
4938 if (vif->type == NL80211_IFTYPE_ADHOC ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04004939 vif->type == NL80211_IFTYPE_MESH_POINT ||
Michal Kazior64badcb2014-09-18 11:18:02 +03004940 vif->type == NL80211_IFTYPE_AP) {
4941 arvif->beacon_buf = dma_zalloc_coherent(ar->dev,
4942 IEEE80211_MAX_FRAME_LEN,
4943 &arvif->beacon_paddr,
Rajkumar Manoharan82d7aba2014-10-10 17:38:27 +05304944 GFP_ATOMIC);
Michal Kazior64badcb2014-09-18 11:18:02 +03004945 if (!arvif->beacon_buf) {
4946 ret = -ENOMEM;
4947 ath10k_warn(ar, "failed to allocate beacon buffer: %d\n",
4948 ret);
4949 goto err;
4950 }
4951 }
David Liuccec9032015-07-24 20:25:32 +03004952 if (test_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags))
4953 arvif->nohwcrypt = true;
4954
4955 if (arvif->nohwcrypt &&
4956 !test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
4957 ath10k_warn(ar, "cryptmode module param needed for sw crypto\n");
4958 goto err;
4959 }
Michal Kazior64badcb2014-09-18 11:18:02 +03004960
4961 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev create %d (add interface) type %d subtype %d bcnmode %s\n",
4962 arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype,
4963 arvif->beacon_buf ? "single-buf" : "per-skb");
Kalle Valo5e3dd152013-06-12 20:52:10 +03004964
4965 ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id, arvif->vdev_type,
4966 arvif->vdev_subtype, vif->addr);
4967 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004968 ath10k_warn(ar, "failed to create WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004969 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004970 goto err;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004971 }
4972
Ben Greear16c11172014-09-23 14:17:16 -07004973 ar->free_vdev_map &= ~(1LL << arvif->vdev_id);
Vasanthakumar Thiagarajan5f0de8822016-10-10 19:51:18 +05304974 spin_lock_bh(&ar->data_lock);
Michal Kazior05791192013-10-16 15:44:45 +03004975 list_add(&arvif->list, &ar->arvifs);
Vasanthakumar Thiagarajan5f0de8822016-10-10 19:51:18 +05304976 spin_unlock_bh(&ar->data_lock);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004977
Michal Kazior46725b12015-01-28 09:57:49 +02004978 /* It makes no sense to have firmware do keepalives. mac80211 already
4979 * takes care of this with idle connection polling.
4980 */
4981 ret = ath10k_mac_vif_disable_keepalive(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004982 if (ret) {
Michal Kazior46725b12015-01-28 09:57:49 +02004983 ath10k_warn(ar, "failed to disable keepalive on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004984 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004985 goto err_vdev_delete;
4986 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004987
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02004988 arvif->def_wep_key_idx = -1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03004989
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02004990 vdev_param = ar->wmi.vdev_param->tx_encap_type;
4991 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03004992 ATH10K_HW_TXRX_NATIVE_WIFI);
Bartosz Markowskiebc9abd2013-10-15 09:26:20 +02004993 /* 10.X firmware does not support this VDEV parameter. Do not warn */
Michal Kazior9dad14a2013-10-16 15:44:45 +03004994 if (ret && ret != -EOPNOTSUPP) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02004995 ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02004996 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03004997 goto err_vdev_delete;
4998 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03004999
Rajkumar Manoharan8a75fc52016-03-02 20:13:52 +05305000 /* Configuring number of spatial stream for monitor interface is causing
5001 * target assert in qca9888 and qca6174.
5002 */
5003 if (ar->cfg_tx_chainmask && (vif->type != NL80211_IFTYPE_MONITOR)) {
Ben Greear5572a952014-11-24 16:22:10 +02005004 u16 nss = get_nss_from_chainmask(ar->cfg_tx_chainmask);
5005
5006 vdev_param = ar->wmi.vdev_param->nss;
5007 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5008 nss);
5009 if (ret) {
5010 ath10k_warn(ar, "failed to set vdev %i chainmask 0x%x, nss %i: %d\n",
5011 arvif->vdev_id, ar->cfg_tx_chainmask, nss,
5012 ret);
5013 goto err_vdev_delete;
5014 }
5015 }
5016
Michal Kaziore57e0572015-03-24 13:14:03 +00005017 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5018 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior69427262016-03-06 16:14:30 +02005019 ret = ath10k_peer_create(ar, vif, NULL, arvif->vdev_id,
5020 vif->addr, WMI_PEER_TYPE_DEFAULT);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005021 if (ret) {
Michal Kaziore57e0572015-03-24 13:14:03 +00005022 ath10k_warn(ar, "failed to create vdev %i peer for AP/IBSS: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005023 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005024 goto err_vdev_delete;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005025 }
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02005026
5027 spin_lock_bh(&ar->data_lock);
5028
5029 peer = ath10k_peer_find(ar, arvif->vdev_id, vif->addr);
5030 if (!peer) {
5031 ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",
5032 vif->addr, arvif->vdev_id);
5033 spin_unlock_bh(&ar->data_lock);
5034 ret = -ENOENT;
5035 goto err_peer_delete;
5036 }
5037
5038 arvif->peer_id = find_first_bit(peer->peer_ids,
5039 ATH10K_MAX_NUM_PEER_IDS);
5040
5041 spin_unlock_bh(&ar->data_lock);
5042 } else {
5043 arvif->peer_id = HTT_INVALID_PEERID;
Michal Kaziore57e0572015-03-24 13:14:03 +00005044 }
Marek Puzyniakcdf07402013-12-30 09:07:51 +01005045
Michal Kaziore57e0572015-03-24 13:14:03 +00005046 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
Kalle Valo5a13e762014-01-20 11:01:46 +02005047 ret = ath10k_mac_set_kickout(arvif);
5048 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005049 ath10k_warn(ar, "failed to set vdev %i kickout parameters: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005050 arvif->vdev_id, ret);
Kalle Valo5a13e762014-01-20 11:01:46 +02005051 goto err_peer_delete;
5052 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005053 }
5054
5055 if (arvif->vdev_type == WMI_VDEV_TYPE_STA) {
5056 param = WMI_STA_PS_PARAM_RX_WAKE_POLICY;
5057 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
5058 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
5059 param, value);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005060 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005061 ath10k_warn(ar, "failed to set vdev %i RX wake policy: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005062 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005063 goto err_peer_delete;
5064 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005065
Michal Kazior9f9b5742014-12-12 12:41:36 +01005066 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005067 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01005068 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005069 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005070 goto err_peer_delete;
5071 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005072
Michal Kazior9f9b5742014-12-12 12:41:36 +01005073 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005074 if (ret) {
Michal Kazior9f9b5742014-12-12 12:41:36 +01005075 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005076 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005077 goto err_peer_delete;
5078 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005079 }
5080
Vivek Natarajana48e2cc2015-08-04 10:45:12 +05305081 ret = ath10k_mac_set_txbf_conf(arvif);
5082 if (ret) {
5083 ath10k_warn(ar, "failed to set txbf for vdev %d: %d\n",
5084 arvif->vdev_id, ret);
5085 goto err_peer_delete;
5086 }
5087
Michal Kazior424121c2013-07-22 14:13:31 +02005088 ret = ath10k_mac_set_rts(arvif, ar->hw->wiphy->rts_threshold);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005089 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005090 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kazior679c54a2013-07-05 16:15:04 +03005091 arvif->vdev_id, ret);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005092 goto err_peer_delete;
5093 }
Michal Kazior679c54a2013-07-05 16:15:04 +03005094
Michal Kazior7d9d5582014-10-21 10:40:15 +03005095 arvif->txpower = vif->bss_conf.txpower;
5096 ret = ath10k_mac_txpower_recalc(ar);
5097 if (ret) {
5098 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
5099 goto err_peer_delete;
5100 }
5101
Michal Kazior500ff9f2015-03-31 10:26:21 +00005102 if (vif->type == NL80211_IFTYPE_MONITOR) {
5103 ar->monitor_arvif = arvif;
5104 ret = ath10k_monitor_recalc(ar);
5105 if (ret) {
5106 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
5107 goto err_peer_delete;
5108 }
5109 }
5110
Michal Kazior6d2d51e2015-08-07 09:08:21 +02005111 spin_lock_bh(&ar->htt.tx_lock);
5112 if (!ar->tx_paused)
5113 ieee80211_wake_queue(ar->hw, arvif->vdev_id);
5114 spin_unlock_bh(&ar->htt.tx_lock);
5115
Kalle Valo5e3dd152013-06-12 20:52:10 +03005116 mutex_unlock(&ar->conf_mutex);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005117 return 0;
5118
5119err_peer_delete:
Michal Kaziore57e0572015-03-24 13:14:03 +00005120 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5121 arvif->vdev_type == WMI_VDEV_TYPE_IBSS)
Michal Kazior9dad14a2013-10-16 15:44:45 +03005122 ath10k_wmi_peer_delete(ar, arvif->vdev_id, vif->addr);
5123
5124err_vdev_delete:
5125 ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
Ben Greear16c11172014-09-23 14:17:16 -07005126 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Vasanthakumar Thiagarajan5f0de8822016-10-10 19:51:18 +05305127 spin_lock_bh(&ar->data_lock);
Michal Kazior05791192013-10-16 15:44:45 +03005128 list_del(&arvif->list);
Vasanthakumar Thiagarajan5f0de8822016-10-10 19:51:18 +05305129 spin_unlock_bh(&ar->data_lock);
Michal Kazior9dad14a2013-10-16 15:44:45 +03005130
5131err:
Michal Kazior64badcb2014-09-18 11:18:02 +03005132 if (arvif->beacon_buf) {
5133 dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN,
5134 arvif->beacon_buf, arvif->beacon_paddr);
5135 arvif->beacon_buf = NULL;
5136 }
5137
Michal Kazior9dad14a2013-10-16 15:44:45 +03005138 mutex_unlock(&ar->conf_mutex);
5139
Kalle Valo5e3dd152013-06-12 20:52:10 +03005140 return ret;
5141}
5142
Michal Kaziorb4aa5392015-03-31 10:26:24 +00005143static void ath10k_mac_vif_tx_unlock_all(struct ath10k_vif *arvif)
5144{
5145 int i;
5146
5147 for (i = 0; i < BITS_PER_LONG; i++)
5148 ath10k_mac_vif_tx_unlock(arvif, i);
5149}
5150
Kalle Valo5e3dd152013-06-12 20:52:10 +03005151static void ath10k_remove_interface(struct ieee80211_hw *hw,
5152 struct ieee80211_vif *vif)
5153{
5154 struct ath10k *ar = hw->priv;
5155 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior69427262016-03-06 16:14:30 +02005156 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005157 int ret;
Michal Kazior69427262016-03-06 16:14:30 +02005158 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005159
Michal Kazior81a9a172015-03-05 16:02:17 +02005160 cancel_work_sync(&arvif->ap_csa_work);
Michal Kaziorcc9904e2015-03-10 16:22:01 +02005161 cancel_delayed_work_sync(&arvif->connection_loss_work);
Michal Kazior81a9a172015-03-05 16:02:17 +02005162
Sujith Manoharan5d011f52014-11-25 11:47:00 +05305163 mutex_lock(&ar->conf_mutex);
5164
Michal Kaziored543882013-09-13 14:16:56 +02005165 spin_lock_bh(&ar->data_lock);
Michal Kazior64badcb2014-09-18 11:18:02 +03005166 ath10k_mac_vif_beacon_cleanup(arvif);
Michal Kaziored543882013-09-13 14:16:56 +02005167 spin_unlock_bh(&ar->data_lock);
5168
Simon Wunderlich855aed12014-08-02 09:12:54 +03005169 ret = ath10k_spectral_vif_stop(arvif);
5170 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005171 ath10k_warn(ar, "failed to stop spectral for vdev %i: %d\n",
Simon Wunderlich855aed12014-08-02 09:12:54 +03005172 arvif->vdev_id, ret);
5173
Ben Greear16c11172014-09-23 14:17:16 -07005174 ar->free_vdev_map |= 1LL << arvif->vdev_id;
Vasanthakumar Thiagarajan5f0de8822016-10-10 19:51:18 +05305175 spin_lock_bh(&ar->data_lock);
Michal Kazior05791192013-10-16 15:44:45 +03005176 list_del(&arvif->list);
Vasanthakumar Thiagarajan5f0de8822016-10-10 19:51:18 +05305177 spin_unlock_bh(&ar->data_lock);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005178
Michal Kaziore57e0572015-03-24 13:14:03 +00005179 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5180 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02005181 ret = ath10k_wmi_peer_delete(arvif->ar, arvif->vdev_id,
5182 vif->addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005183 if (ret)
Michal Kaziore57e0572015-03-24 13:14:03 +00005184 ath10k_warn(ar, "failed to submit AP/IBSS self-peer removal on vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005185 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005186
5187 kfree(arvif->u.ap.noa_data);
5188 }
5189
Michal Kazior7aa7a722014-08-25 12:09:38 +02005190 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i delete (remove interface)\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005191 arvif->vdev_id);
5192
Kalle Valo5e3dd152013-06-12 20:52:10 +03005193 ret = ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
5194 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005195 ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005196 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005197
Michal Kazior2c512052015-02-15 16:50:40 +02005198 /* Some firmware revisions don't notify host about self-peer removal
5199 * until after associated vdev is deleted.
5200 */
Michal Kaziore57e0572015-03-24 13:14:03 +00005201 if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
5202 arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
Michal Kazior2c512052015-02-15 16:50:40 +02005203 ret = ath10k_wait_for_peer_deleted(ar, arvif->vdev_id,
5204 vif->addr);
5205 if (ret)
5206 ath10k_warn(ar, "failed to remove AP self-peer on vdev %i: %d\n",
5207 arvif->vdev_id, ret);
5208
5209 spin_lock_bh(&ar->data_lock);
5210 ar->num_peers--;
5211 spin_unlock_bh(&ar->data_lock);
5212 }
5213
Michal Kazior69427262016-03-06 16:14:30 +02005214 spin_lock_bh(&ar->data_lock);
5215 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
5216 peer = ar->peer_map[i];
5217 if (!peer)
5218 continue;
5219
5220 if (peer->vif == vif) {
5221 ath10k_warn(ar, "found vif peer %pM entry on vdev %i after it was supposedly removed\n",
5222 vif->addr, arvif->vdev_id);
5223 peer->vif = NULL;
5224 }
5225 }
5226 spin_unlock_bh(&ar->data_lock);
5227
Kalle Valo5e3dd152013-06-12 20:52:10 +03005228 ath10k_peer_cleanup(ar, arvif->vdev_id);
Michal Kaziordd4717b2016-03-06 16:14:39 +02005229 ath10k_mac_txq_unref(ar, vif->txq);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005230
Michal Kazior500ff9f2015-03-31 10:26:21 +00005231 if (vif->type == NL80211_IFTYPE_MONITOR) {
5232 ar->monitor_arvif = NULL;
5233 ret = ath10k_monitor_recalc(ar);
5234 if (ret)
5235 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
5236 }
5237
Michal Kaziorb4aa5392015-03-31 10:26:24 +00005238 spin_lock_bh(&ar->htt.tx_lock);
5239 ath10k_mac_vif_tx_unlock_all(arvif);
5240 spin_unlock_bh(&ar->htt.tx_lock);
5241
Michal Kazior29946872016-03-06 16:14:34 +02005242 ath10k_mac_txq_unref(ar, vif->txq);
5243
Kalle Valo5e3dd152013-06-12 20:52:10 +03005244 mutex_unlock(&ar->conf_mutex);
5245}
5246
5247/*
5248 * FIXME: Has to be verified.
5249 */
5250#define SUPPORTED_FILTERS \
Johannes Bergdf140462015-04-22 14:40:58 +02005251 (FIF_ALLMULTI | \
Kalle Valo5e3dd152013-06-12 20:52:10 +03005252 FIF_CONTROL | \
5253 FIF_PSPOLL | \
5254 FIF_OTHER_BSS | \
5255 FIF_BCN_PRBRESP_PROMISC | \
5256 FIF_PROBE_REQ | \
5257 FIF_FCSFAIL)
5258
5259static void ath10k_configure_filter(struct ieee80211_hw *hw,
5260 unsigned int changed_flags,
5261 unsigned int *total_flags,
5262 u64 multicast)
5263{
5264 struct ath10k *ar = hw->priv;
5265 int ret;
5266
5267 mutex_lock(&ar->conf_mutex);
5268
5269 changed_flags &= SUPPORTED_FILTERS;
5270 *total_flags &= SUPPORTED_FILTERS;
5271 ar->filter_flags = *total_flags;
5272
Michal Kazior19337472014-08-28 12:58:16 +02005273 ret = ath10k_monitor_recalc(ar);
5274 if (ret)
Colin Ian King7f03d302016-08-26 19:08:52 +01005275 ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005276
5277 mutex_unlock(&ar->conf_mutex);
5278}
5279
5280static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
5281 struct ieee80211_vif *vif,
5282 struct ieee80211_bss_conf *info,
5283 u32 changed)
5284{
5285 struct ath10k *ar = hw->priv;
5286 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5287 int ret = 0;
Kalle Valoaf762c02014-09-14 12:50:17 +03005288 u32 vdev_param, pdev_param, slottime, preamble;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005289
5290 mutex_lock(&ar->conf_mutex);
5291
5292 if (changed & BSS_CHANGED_IBSS)
5293 ath10k_control_ibss(arvif, info, vif->addr);
5294
5295 if (changed & BSS_CHANGED_BEACON_INT) {
5296 arvif->beacon_interval = info->beacon_int;
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005297 vdev_param = ar->wmi.vdev_param->beacon_interval;
5298 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005299 arvif->beacon_interval);
Michal Kazior7aa7a722014-08-25 12:09:38 +02005300 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005301 "mac vdev %d beacon_interval %d\n",
5302 arvif->vdev_id, arvif->beacon_interval);
5303
Kalle Valo5e3dd152013-06-12 20:52:10 +03005304 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005305 ath10k_warn(ar, "failed to set beacon interval for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005306 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005307 }
5308
5309 if (changed & BSS_CHANGED_BEACON) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005310 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005311 "vdev %d set beacon tx mode to staggered\n",
5312 arvif->vdev_id);
5313
Bartosz Markowski226a3392013-09-26 17:47:16 +02005314 pdev_param = ar->wmi.pdev_param->beacon_tx_mode;
5315 ret = ath10k_wmi_pdev_set_param(ar, pdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005316 WMI_BEACON_STAGGERED_MODE);
5317 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005318 ath10k_warn(ar, "failed to set beacon mode for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005319 arvif->vdev_id, ret);
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02005320
5321 ret = ath10k_mac_setup_bcn_tmpl(arvif);
5322 if (ret)
5323 ath10k_warn(ar, "failed to update beacon template: %d\n",
5324 ret);
Bob Copelandb6c7baf2015-09-09 12:47:36 -04005325
5326 if (ieee80211_vif_is_mesh(vif)) {
5327 /* mesh doesn't use SSID but firmware needs it */
5328 strncpy(arvif->u.ap.ssid, "mesh",
5329 sizeof(arvif->u.ap.ssid));
5330 arvif->u.ap.ssid_len = 4;
5331 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005332 }
5333
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02005334 if (changed & BSS_CHANGED_AP_PROBE_RESP) {
5335 ret = ath10k_mac_setup_prb_tmpl(arvif);
5336 if (ret)
5337 ath10k_warn(ar, "failed to setup probe resp template on vdev %i: %d\n",
5338 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005339 }
5340
Michal Kaziorba2479f2015-01-24 12:14:51 +02005341 if (changed & (BSS_CHANGED_BEACON_INFO | BSS_CHANGED_BEACON)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005342 arvif->dtim_period = info->dtim_period;
5343
Michal Kazior7aa7a722014-08-25 12:09:38 +02005344 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005345 "mac vdev %d dtim_period %d\n",
5346 arvif->vdev_id, arvif->dtim_period);
5347
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005348 vdev_param = ar->wmi.vdev_param->dtim_period;
5349 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005350 arvif->dtim_period);
5351 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005352 ath10k_warn(ar, "failed to set dtim period for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005353 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005354 }
5355
5356 if (changed & BSS_CHANGED_SSID &&
5357 vif->type == NL80211_IFTYPE_AP) {
5358 arvif->u.ap.ssid_len = info->ssid_len;
5359 if (info->ssid_len)
5360 memcpy(arvif->u.ap.ssid, info->ssid, info->ssid_len);
5361 arvif->u.ap.hidden_ssid = info->hidden_ssid;
5362 }
5363
Michal Kazior077efc82014-10-21 10:10:29 +03005364 if (changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid))
5365 ether_addr_copy(arvif->bssid, info->bssid);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005366
5367 if (changed & BSS_CHANGED_BEACON_ENABLED)
5368 ath10k_control_beaconing(arvif, info);
5369
5370 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005371 arvif->use_cts_prot = info->use_cts_prot;
Kalle Valo60c3daa2013-09-08 17:56:07 +03005372
Marek Kwaczynskie81bd102014-03-11 12:58:00 +02005373 ret = ath10k_recalc_rtscts_prot(arvif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005374 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005375 ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005376 arvif->vdev_id, ret);
Michal Kaziora87fd4b2015-03-02 11:21:17 +01005377
Bartosz Markowski83e48fc2016-12-15 11:23:24 +02005378 if (ath10k_mac_can_set_cts_prot(arvif)) {
5379 ret = ath10k_mac_set_cts_prot(arvif);
5380 if (ret)
5381 ath10k_warn(ar, "failed to set cts protection for vdev %d: %d\n",
5382 arvif->vdev_id, ret);
5383 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005384 }
5385
5386 if (changed & BSS_CHANGED_ERP_SLOT) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005387 if (info->use_short_slot)
5388 slottime = WMI_VDEV_SLOT_TIME_SHORT; /* 9us */
5389
5390 else
5391 slottime = WMI_VDEV_SLOT_TIME_LONG; /* 20us */
5392
Michal Kazior7aa7a722014-08-25 12:09:38 +02005393 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d slot_time %d\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03005394 arvif->vdev_id, slottime);
5395
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005396 vdev_param = ar->wmi.vdev_param->slot_time;
5397 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005398 slottime);
5399 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005400 ath10k_warn(ar, "failed to set erp slot for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005401 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005402 }
5403
5404 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005405 if (info->use_short_preamble)
5406 preamble = WMI_VDEV_PREAMBLE_SHORT;
5407 else
5408 preamble = WMI_VDEV_PREAMBLE_LONG;
5409
Michal Kazior7aa7a722014-08-25 12:09:38 +02005410 ath10k_dbg(ar, ATH10K_DBG_MAC,
Kalle Valo60c3daa2013-09-08 17:56:07 +03005411 "mac vdev %d preamble %dn",
5412 arvif->vdev_id, preamble);
5413
Bartosz Markowski6d1506e2013-09-26 17:47:15 +02005414 vdev_param = ar->wmi.vdev_param->preamble;
5415 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
Kalle Valo5e3dd152013-06-12 20:52:10 +03005416 preamble);
5417 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005418 ath10k_warn(ar, "failed to set preamble for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02005419 arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005420 }
5421
5422 if (changed & BSS_CHANGED_ASSOC) {
Michal Kaziore556f112014-08-28 12:58:17 +02005423 if (info->assoc) {
5424 /* Workaround: Make sure monitor vdev is not running
5425 * when associating to prevent some firmware revisions
5426 * (e.g. 10.1 and 10.2) from crashing.
5427 */
5428 if (ar->monitor_started)
5429 ath10k_monitor_stop(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005430 ath10k_bss_assoc(hw, vif, info);
Michal Kaziore556f112014-08-28 12:58:17 +02005431 ath10k_monitor_recalc(ar);
Michal Kazior077efc82014-10-21 10:10:29 +03005432 } else {
5433 ath10k_bss_disassoc(hw, vif);
Michal Kaziore556f112014-08-28 12:58:17 +02005434 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005435 }
5436
Michal Kazior7d9d5582014-10-21 10:40:15 +03005437 if (changed & BSS_CHANGED_TXPOWER) {
5438 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev_id %i txpower %d\n",
5439 arvif->vdev_id, info->txpower);
5440
5441 arvif->txpower = info->txpower;
5442 ret = ath10k_mac_txpower_recalc(ar);
5443 if (ret)
5444 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
5445 }
5446
Michal Kaziorbf14e652014-12-12 12:41:38 +01005447 if (changed & BSS_CHANGED_PS) {
Michal Kaziorcffb41f2015-02-13 13:30:16 +01005448 arvif->ps = vif->bss_conf.ps;
5449
5450 ret = ath10k_config_ps(ar);
Michal Kaziorbf14e652014-12-12 12:41:38 +01005451 if (ret)
5452 ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n",
5453 arvif->vdev_id, ret);
5454 }
5455
Kalle Valo5e3dd152013-06-12 20:52:10 +03005456 mutex_unlock(&ar->conf_mutex);
5457}
5458
5459static int ath10k_hw_scan(struct ieee80211_hw *hw,
5460 struct ieee80211_vif *vif,
David Spinadelc56ef672014-02-05 15:21:13 +02005461 struct ieee80211_scan_request *hw_req)
Kalle Valo5e3dd152013-06-12 20:52:10 +03005462{
5463 struct ath10k *ar = hw->priv;
5464 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
David Spinadelc56ef672014-02-05 15:21:13 +02005465 struct cfg80211_scan_request *req = &hw_req->req;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005466 struct wmi_start_scan_arg arg;
5467 int ret = 0;
5468 int i;
5469
5470 mutex_lock(&ar->conf_mutex);
5471
5472 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005473 switch (ar->scan.state) {
5474 case ATH10K_SCAN_IDLE:
5475 reinit_completion(&ar->scan.started);
5476 reinit_completion(&ar->scan.completed);
5477 ar->scan.state = ATH10K_SCAN_STARTING;
5478 ar->scan.is_roc = false;
5479 ar->scan.vdev_id = arvif->vdev_id;
5480 ret = 0;
5481 break;
5482 case ATH10K_SCAN_STARTING:
5483 case ATH10K_SCAN_RUNNING:
5484 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03005485 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005486 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005487 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03005488 spin_unlock_bh(&ar->data_lock);
5489
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005490 if (ret)
5491 goto exit;
5492
Kalle Valo5e3dd152013-06-12 20:52:10 +03005493 memset(&arg, 0, sizeof(arg));
5494 ath10k_wmi_start_scan_init(ar, &arg);
5495 arg.vdev_id = arvif->vdev_id;
5496 arg.scan_id = ATH10K_SCAN_ID;
5497
Kalle Valo5e3dd152013-06-12 20:52:10 +03005498 if (req->ie_len) {
5499 arg.ie_len = req->ie_len;
5500 memcpy(arg.ie, req->ie, arg.ie_len);
5501 }
5502
5503 if (req->n_ssids) {
5504 arg.n_ssids = req->n_ssids;
5505 for (i = 0; i < arg.n_ssids; i++) {
5506 arg.ssids[i].len = req->ssids[i].ssid_len;
5507 arg.ssids[i].ssid = req->ssids[i].ssid;
5508 }
Michal Kaziordcd4a562013-07-31 10:55:12 +02005509 } else {
5510 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005511 }
5512
5513 if (req->n_channels) {
5514 arg.n_channels = req->n_channels;
5515 for (i = 0; i < arg.n_channels; i++)
5516 arg.channels[i] = req->channels[i]->center_freq;
5517 }
5518
5519 ret = ath10k_start_scan(ar, &arg);
5520 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005521 ath10k_warn(ar, "failed to start hw scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005522 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005523 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005524 spin_unlock_bh(&ar->data_lock);
5525 }
5526
Michal Kazior634349b2015-09-03 10:43:45 +02005527 /* Add a 200ms margin to account for event/command processing */
5528 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
5529 msecs_to_jiffies(arg.max_scan_time +
5530 200));
5531
Kalle Valo5e3dd152013-06-12 20:52:10 +03005532exit:
5533 mutex_unlock(&ar->conf_mutex);
5534 return ret;
5535}
5536
5537static void ath10k_cancel_hw_scan(struct ieee80211_hw *hw,
5538 struct ieee80211_vif *vif)
5539{
5540 struct ath10k *ar = hw->priv;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005541
5542 mutex_lock(&ar->conf_mutex);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02005543 ath10k_scan_abort(ar);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005544 mutex_unlock(&ar->conf_mutex);
Michal Kazior4eb2e162014-10-28 10:23:09 +01005545
5546 cancel_delayed_work_sync(&ar->scan.timeout);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005547}
5548
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005549static void ath10k_set_key_h_def_keyidx(struct ath10k *ar,
5550 struct ath10k_vif *arvif,
5551 enum set_key_cmd cmd,
5552 struct ieee80211_key_conf *key)
5553{
5554 u32 vdev_param = arvif->ar->wmi.vdev_param->def_keyid;
5555 int ret;
5556
5557 /* 10.1 firmware branch requires default key index to be set to group
5558 * key index after installing it. Otherwise FW/HW Txes corrupted
5559 * frames with multi-vif APs. This is not required for main firmware
5560 * branch (e.g. 636).
5561 *
Michal Kazior8461baf2015-04-10 13:23:22 +00005562 * This is also needed for 636 fw for IBSS-RSN to work more reliably.
5563 *
5564 * FIXME: It remains unknown if this is required for multi-vif STA
5565 * interfaces on 10.1.
5566 */
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005567
Michal Kazior8461baf2015-04-10 13:23:22 +00005568 if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
5569 arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005570 return;
5571
5572 if (key->cipher == WLAN_CIPHER_SUITE_WEP40)
5573 return;
5574
5575 if (key->cipher == WLAN_CIPHER_SUITE_WEP104)
5576 return;
5577
5578 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
5579 return;
5580
5581 if (cmd != SET_KEY)
5582 return;
5583
5584 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
5585 key->keyidx);
5586 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005587 ath10k_warn(ar, "failed to set vdev %i group key as default key: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005588 arvif->vdev_id, ret);
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005589}
5590
Kalle Valo5e3dd152013-06-12 20:52:10 +03005591static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
5592 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
5593 struct ieee80211_key_conf *key)
5594{
5595 struct ath10k *ar = hw->priv;
5596 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5597 struct ath10k_peer *peer;
5598 const u8 *peer_addr;
5599 bool is_wep = key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
5600 key->cipher == WLAN_CIPHER_SUITE_WEP104;
5601 int ret = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00005602 int ret2;
Michal Kazior370e5672015-02-18 14:02:26 +01005603 u32 flags = 0;
Michal Kazior29a10002015-04-10 13:05:58 +00005604 u32 flags2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005605
Bartosz Markowskid7131c02015-03-10 14:32:19 +01005606 /* this one needs to be done in software */
5607 if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC)
5608 return 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005609
David Liuccec9032015-07-24 20:25:32 +03005610 if (arvif->nohwcrypt)
5611 return 1;
5612
Kalle Valo5e3dd152013-06-12 20:52:10 +03005613 if (key->keyidx > WMI_MAX_KEY_INDEX)
5614 return -ENOSPC;
5615
5616 mutex_lock(&ar->conf_mutex);
5617
5618 if (sta)
5619 peer_addr = sta->addr;
5620 else if (arvif->vdev_type == WMI_VDEV_TYPE_STA)
5621 peer_addr = vif->bss_conf.bssid;
5622 else
5623 peer_addr = vif->addr;
5624
5625 key->hw_key_idx = key->keyidx;
5626
Michal Kazior7c8cc7e2015-04-01 22:53:19 +03005627 if (is_wep) {
5628 if (cmd == SET_KEY)
5629 arvif->wep_keys[key->keyidx] = key;
5630 else
5631 arvif->wep_keys[key->keyidx] = NULL;
5632 }
5633
Kalle Valo5e3dd152013-06-12 20:52:10 +03005634 /* the peer should not disappear in mid-way (unless FW goes awry) since
5635 * we already hold conf_mutex. we just make sure its there now. */
5636 spin_lock_bh(&ar->data_lock);
5637 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
5638 spin_unlock_bh(&ar->data_lock);
5639
5640 if (!peer) {
5641 if (cmd == SET_KEY) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005642 ath10k_warn(ar, "failed to install key for non-existent peer %pM\n",
Kalle Valo5e3dd152013-06-12 20:52:10 +03005643 peer_addr);
5644 ret = -EOPNOTSUPP;
5645 goto exit;
5646 } else {
5647 /* if the peer doesn't exist there is no key to disable
5648 * anymore */
5649 goto exit;
5650 }
5651 }
5652
Michal Kazior7cc45732015-03-09 14:24:17 +01005653 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
5654 flags |= WMI_KEY_PAIRWISE;
5655 else
5656 flags |= WMI_KEY_GROUP;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005657
Kalle Valo5e3dd152013-06-12 20:52:10 +03005658 if (is_wep) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005659 if (cmd == DISABLE_KEY)
5660 ath10k_clear_vdev_key(arvif, key);
Michal Kazior370e5672015-02-18 14:02:26 +01005661
Michal Kaziorad325cb2015-02-18 14:02:27 +01005662 /* When WEP keys are uploaded it's possible that there are
5663 * stations associated already (e.g. when merging) without any
5664 * keys. Static WEP needs an explicit per-peer key upload.
5665 */
5666 if (vif->type == NL80211_IFTYPE_ADHOC &&
5667 cmd == SET_KEY)
5668 ath10k_mac_vif_update_wep_key(arvif, key);
5669
Michal Kazior370e5672015-02-18 14:02:26 +01005670 /* 802.1x never sets the def_wep_key_idx so each set_key()
5671 * call changes default tx key.
5672 *
5673 * Static WEP sets def_wep_key_idx via .set_default_unicast_key
5674 * after first set_key().
5675 */
5676 if (cmd == SET_KEY && arvif->def_wep_key_idx == -1)
5677 flags |= WMI_KEY_TX_USAGE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005678 }
5679
Michal Kazior370e5672015-02-18 14:02:26 +01005680 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005681 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03005682 WARN_ON(ret > 0);
Michal Kazior7aa7a722014-08-25 12:09:38 +02005683 ath10k_warn(ar, "failed to install key for vdev %i peer %pM: %d\n",
Ben Greear69244e52014-02-27 18:50:00 +02005684 arvif->vdev_id, peer_addr, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005685 goto exit;
5686 }
5687
Michal Kazior29a10002015-04-10 13:05:58 +00005688 /* mac80211 sets static WEP keys as groupwise while firmware requires
5689 * them to be installed twice as both pairwise and groupwise.
5690 */
5691 if (is_wep && !sta && vif->type == NL80211_IFTYPE_STATION) {
5692 flags2 = flags;
5693 flags2 &= ~WMI_KEY_GROUP;
5694 flags2 |= WMI_KEY_PAIRWISE;
5695
5696 ret = ath10k_install_key(arvif, key, cmd, peer_addr, flags2);
5697 if (ret) {
David Liuccec9032015-07-24 20:25:32 +03005698 WARN_ON(ret > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00005699 ath10k_warn(ar, "failed to install (ucast) key for vdev %i peer %pM: %d\n",
5700 arvif->vdev_id, peer_addr, ret);
5701 ret2 = ath10k_install_key(arvif, key, DISABLE_KEY,
5702 peer_addr, flags);
David Liuccec9032015-07-24 20:25:32 +03005703 if (ret2) {
5704 WARN_ON(ret2 > 0);
Michal Kazior29a10002015-04-10 13:05:58 +00005705 ath10k_warn(ar, "failed to disable (mcast) key for vdev %i peer %pM: %d\n",
5706 arvif->vdev_id, peer_addr, ret2);
David Liuccec9032015-07-24 20:25:32 +03005707 }
Michal Kazior29a10002015-04-10 13:05:58 +00005708 goto exit;
5709 }
5710 }
5711
Michal Kaziorcfb27d22013-12-02 09:06:36 +01005712 ath10k_set_key_h_def_keyidx(ar, arvif, cmd, key);
5713
Kalle Valo5e3dd152013-06-12 20:52:10 +03005714 spin_lock_bh(&ar->data_lock);
5715 peer = ath10k_peer_find(ar, arvif->vdev_id, peer_addr);
5716 if (peer && cmd == SET_KEY)
5717 peer->keys[key->keyidx] = key;
5718 else if (peer && cmd == DISABLE_KEY)
5719 peer->keys[key->keyidx] = NULL;
5720 else if (peer == NULL)
5721 /* impossible unless FW goes crazy */
Michal Kazior7aa7a722014-08-25 12:09:38 +02005722 ath10k_warn(ar, "Peer %pM disappeared!\n", peer_addr);
Kalle Valo5e3dd152013-06-12 20:52:10 +03005723 spin_unlock_bh(&ar->data_lock);
5724
5725exit:
5726 mutex_unlock(&ar->conf_mutex);
5727 return ret;
5728}
5729
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005730static void ath10k_set_default_unicast_key(struct ieee80211_hw *hw,
5731 struct ieee80211_vif *vif,
5732 int keyidx)
5733{
5734 struct ath10k *ar = hw->priv;
5735 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5736 int ret;
5737
5738 mutex_lock(&arvif->ar->conf_mutex);
5739
5740 if (arvif->ar->state != ATH10K_STATE_ON)
5741 goto unlock;
5742
5743 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n",
5744 arvif->vdev_id, keyidx);
5745
5746 ret = ath10k_wmi_vdev_set_param(arvif->ar,
5747 arvif->vdev_id,
5748 arvif->ar->wmi.vdev_param->def_keyid,
5749 keyidx);
5750
5751 if (ret) {
5752 ath10k_warn(ar, "failed to update wep key index for vdev %d: %d\n",
5753 arvif->vdev_id,
5754 ret);
5755 goto unlock;
5756 }
5757
5758 arvif->def_wep_key_idx = keyidx;
Michal Kazior370e5672015-02-18 14:02:26 +01005759
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02005760unlock:
5761 mutex_unlock(&arvif->ar->conf_mutex);
5762}
5763
Michal Kazior9797feb2014-02-14 14:49:48 +01005764static void ath10k_sta_rc_update_wk(struct work_struct *wk)
5765{
5766 struct ath10k *ar;
5767 struct ath10k_vif *arvif;
5768 struct ath10k_sta *arsta;
5769 struct ieee80211_sta *sta;
Michal Kazior45c9abc2015-04-21 20:42:58 +03005770 struct cfg80211_chan_def def;
Johannes Berg57fbcce2016-04-12 15:56:15 +02005771 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03005772 const u8 *ht_mcs_mask;
5773 const u16 *vht_mcs_mask;
Michal Kazior9797feb2014-02-14 14:49:48 +01005774 u32 changed, bw, nss, smps;
5775 int err;
5776
5777 arsta = container_of(wk, struct ath10k_sta, update_wk);
5778 sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);
5779 arvif = arsta->arvif;
5780 ar = arvif->ar;
5781
Michal Kazior45c9abc2015-04-21 20:42:58 +03005782 if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
5783 return;
5784
5785 band = def.chan->band;
5786 ht_mcs_mask = arvif->bitrate_mask.control[band].ht_mcs;
5787 vht_mcs_mask = arvif->bitrate_mask.control[band].vht_mcs;
5788
Michal Kazior9797feb2014-02-14 14:49:48 +01005789 spin_lock_bh(&ar->data_lock);
5790
5791 changed = arsta->changed;
5792 arsta->changed = 0;
5793
5794 bw = arsta->bw;
5795 nss = arsta->nss;
5796 smps = arsta->smps;
5797
5798 spin_unlock_bh(&ar->data_lock);
5799
5800 mutex_lock(&ar->conf_mutex);
5801
Michal Kazior45c9abc2015-04-21 20:42:58 +03005802 nss = max_t(u32, 1, nss);
5803 nss = min(nss, max(ath10k_mac_max_ht_nss(ht_mcs_mask),
5804 ath10k_mac_max_vht_nss(vht_mcs_mask)));
5805
Michal Kazior9797feb2014-02-14 14:49:48 +01005806 if (changed & IEEE80211_RC_BW_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005807 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM peer bw %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005808 sta->addr, bw);
5809
5810 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5811 WMI_PEER_CHAN_WIDTH, bw);
5812 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005813 ath10k_warn(ar, "failed to update STA %pM peer bw %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005814 sta->addr, bw, err);
5815 }
5816
5817 if (changed & IEEE80211_RC_NSS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005818 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM nss %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005819 sta->addr, nss);
5820
5821 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5822 WMI_PEER_NSS, nss);
5823 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005824 ath10k_warn(ar, "failed to update STA %pM nss %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005825 sta->addr, nss, err);
5826 }
5827
5828 if (changed & IEEE80211_RC_SMPS_CHANGED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005829 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM smps %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005830 sta->addr, smps);
5831
5832 err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
5833 WMI_PEER_SMPS_STATE, smps);
5834 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005835 ath10k_warn(ar, "failed to update STA %pM smps %d: %d\n",
Michal Kazior9797feb2014-02-14 14:49:48 +01005836 sta->addr, smps, err);
5837 }
5838
Karthikeyan Periyasamy237b5a32018-03-27 11:25:29 +03005839 if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) {
5840 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005841 sta->addr);
5842
Michal Kazior590922a2014-10-21 10:10:29 +03005843 err = ath10k_station_assoc(ar, arvif->vif, sta, true);
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005844 if (err)
Michal Kazior7aa7a722014-08-25 12:09:38 +02005845 ath10k_warn(ar, "failed to reassociate station: %pM\n",
Chun-Yeow Yeoh44d6fa92014-03-07 10:19:30 +02005846 sta->addr);
5847 }
5848
Michal Kazior9797feb2014-02-14 14:49:48 +01005849 mutex_unlock(&ar->conf_mutex);
5850}
5851
Marek Puzyniak7c354242015-03-30 09:51:52 +03005852static int ath10k_mac_inc_num_stations(struct ath10k_vif *arvif,
5853 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005854{
5855 struct ath10k *ar = arvif->ar;
5856
5857 lockdep_assert_held(&ar->conf_mutex);
5858
Marek Puzyniak7c354242015-03-30 09:51:52 +03005859 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005860 return 0;
5861
5862 if (ar->num_stations >= ar->max_num_stations)
5863 return -ENOBUFS;
5864
5865 ar->num_stations++;
5866
5867 return 0;
5868}
5869
Marek Puzyniak7c354242015-03-30 09:51:52 +03005870static void ath10k_mac_dec_num_stations(struct ath10k_vif *arvif,
5871 struct ieee80211_sta *sta)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005872{
5873 struct ath10k *ar = arvif->ar;
5874
5875 lockdep_assert_held(&ar->conf_mutex);
5876
Marek Puzyniak7c354242015-03-30 09:51:52 +03005877 if (arvif->vdev_type == WMI_VDEV_TYPE_STA && !sta->tdls)
Michal Kaziorcfd10612014-11-25 15:16:05 +01005878 return;
5879
5880 ar->num_stations--;
5881}
5882
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005883struct ath10k_mac_tdls_iter_data {
5884 u32 num_tdls_stations;
5885 struct ieee80211_vif *curr_vif;
5886};
5887
5888static void ath10k_mac_tdls_vif_stations_count_iter(void *data,
5889 struct ieee80211_sta *sta)
5890{
5891 struct ath10k_mac_tdls_iter_data *iter_data = data;
5892 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
5893 struct ieee80211_vif *sta_vif = arsta->arvif->vif;
5894
5895 if (sta->tdls && sta_vif == iter_data->curr_vif)
5896 iter_data->num_tdls_stations++;
5897}
5898
5899static int ath10k_mac_tdls_vif_stations_count(struct ieee80211_hw *hw,
5900 struct ieee80211_vif *vif)
5901{
5902 struct ath10k_mac_tdls_iter_data data = {};
5903
5904 data.curr_vif = vif;
5905
5906 ieee80211_iterate_stations_atomic(hw,
5907 ath10k_mac_tdls_vif_stations_count_iter,
5908 &data);
5909 return data.num_tdls_stations;
5910}
5911
5912static void ath10k_mac_tdls_vifs_count_iter(void *data, u8 *mac,
5913 struct ieee80211_vif *vif)
5914{
5915 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
5916 int *num_tdls_vifs = data;
5917
5918 if (vif->type != NL80211_IFTYPE_STATION)
5919 return;
5920
5921 if (ath10k_mac_tdls_vif_stations_count(arvif->ar->hw, vif) > 0)
5922 (*num_tdls_vifs)++;
5923}
5924
5925static int ath10k_mac_tdls_vifs_count(struct ieee80211_hw *hw)
5926{
5927 int num_tdls_vifs = 0;
5928
5929 ieee80211_iterate_active_interfaces_atomic(hw,
5930 IEEE80211_IFACE_ITER_NORMAL,
5931 ath10k_mac_tdls_vifs_count_iter,
5932 &num_tdls_vifs);
5933 return num_tdls_vifs;
5934}
5935
Kalle Valo5e3dd152013-06-12 20:52:10 +03005936static int ath10k_sta_state(struct ieee80211_hw *hw,
5937 struct ieee80211_vif *vif,
5938 struct ieee80211_sta *sta,
5939 enum ieee80211_sta_state old_state,
5940 enum ieee80211_sta_state new_state)
5941{
5942 struct ath10k *ar = hw->priv;
5943 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01005944 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02005945 struct ath10k_peer *peer;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005946 int ret = 0;
Michal Kazior69427262016-03-06 16:14:30 +02005947 int i;
Kalle Valo5e3dd152013-06-12 20:52:10 +03005948
Michal Kazior76f90022014-02-25 09:29:57 +02005949 if (old_state == IEEE80211_STA_NOTEXIST &&
5950 new_state == IEEE80211_STA_NONE) {
5951 memset(arsta, 0, sizeof(*arsta));
5952 arsta->arvif = arvif;
5953 INIT_WORK(&arsta->update_wk, ath10k_sta_rc_update_wk);
Michal Kazior29946872016-03-06 16:14:34 +02005954
5955 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
5956 ath10k_mac_txq_init(sta->txq[i]);
Michal Kazior76f90022014-02-25 09:29:57 +02005957 }
5958
Michal Kazior9797feb2014-02-14 14:49:48 +01005959 /* cancel must be done outside the mutex to avoid deadlock */
5960 if ((old_state == IEEE80211_STA_NONE &&
5961 new_state == IEEE80211_STA_NOTEXIST))
5962 cancel_work_sync(&arsta->update_wk);
5963
Kalle Valo5e3dd152013-06-12 20:52:10 +03005964 mutex_lock(&ar->conf_mutex);
5965
5966 if (old_state == IEEE80211_STA_NOTEXIST &&
Michal Kazior077efc82014-10-21 10:10:29 +03005967 new_state == IEEE80211_STA_NONE) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03005968 /*
5969 * New station addition.
5970 */
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005971 enum wmi_peer_type peer_type = WMI_PEER_TYPE_DEFAULT;
5972 u32 num_tdls_stations;
5973 u32 num_tdls_vifs;
5974
Michal Kaziorcfd10612014-11-25 15:16:05 +01005975 ath10k_dbg(ar, ATH10K_DBG_MAC,
5976 "mac vdev %d peer create %pM (new sta) sta %d / %d peer %d / %d\n",
5977 arvif->vdev_id, sta->addr,
5978 ar->num_stations + 1, ar->max_num_stations,
5979 ar->num_peers + 1, ar->max_num_peers);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005980
Marek Puzyniak7c354242015-03-30 09:51:52 +03005981 ret = ath10k_mac_inc_num_stations(arvif, sta);
Michal Kaziorcfd10612014-11-25 15:16:05 +01005982 if (ret) {
5983 ath10k_warn(ar, "refusing to associate station: too many connected already (%d)\n",
5984 ar->max_num_stations);
Bartosz Markowski0e759f32014-01-02 14:38:33 +01005985 goto exit;
5986 }
5987
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03005988 if (sta->tdls)
5989 peer_type = WMI_PEER_TYPE_TDLS;
5990
Michal Kazior69427262016-03-06 16:14:30 +02005991 ret = ath10k_peer_create(ar, vif, sta, arvif->vdev_id,
5992 sta->addr, peer_type);
Michal Kaziora52c0282014-11-25 15:16:03 +01005993 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02005994 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 -08005995 sta->addr, arvif->vdev_id, ret);
Marek Puzyniak7c354242015-03-30 09:51:52 +03005996 ath10k_mac_dec_num_stations(arvif, sta);
Michal Kaziora52c0282014-11-25 15:16:03 +01005997 goto exit;
5998 }
Michal Kazior077efc82014-10-21 10:10:29 +03005999
Michal Kaziorbb8f0c62016-03-06 16:14:27 +02006000 spin_lock_bh(&ar->data_lock);
6001
6002 peer = ath10k_peer_find(ar, arvif->vdev_id, sta->addr);
6003 if (!peer) {
6004 ath10k_warn(ar, "failed to lookup peer %pM on vdev %i\n",
6005 vif->addr, arvif->vdev_id);
6006 spin_unlock_bh(&ar->data_lock);
6007 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6008 ath10k_mac_dec_num_stations(arvif, sta);
6009 ret = -ENOENT;
6010 goto exit;
6011 }
6012
6013 arsta->peer_id = find_first_bit(peer->peer_ids,
6014 ATH10K_MAX_NUM_PEER_IDS);
6015
6016 spin_unlock_bh(&ar->data_lock);
6017
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006018 if (!sta->tdls)
6019 goto exit;
Michal Kazior077efc82014-10-21 10:10:29 +03006020
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006021 num_tdls_stations = ath10k_mac_tdls_vif_stations_count(hw, vif);
6022 num_tdls_vifs = ath10k_mac_tdls_vifs_count(hw);
6023
6024 if (num_tdls_vifs >= ar->max_num_tdls_vdevs &&
6025 num_tdls_stations == 0) {
6026 ath10k_warn(ar, "vdev %i exceeded maximum number of tdls vdevs %i\n",
6027 arvif->vdev_id, ar->max_num_tdls_vdevs);
6028 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6029 ath10k_mac_dec_num_stations(arvif, sta);
6030 ret = -ENOBUFS;
6031 goto exit;
6032 }
6033
6034 if (num_tdls_stations == 0) {
6035 /* This is the first tdls peer in current vif */
6036 enum wmi_tdls_state state = WMI_TDLS_ENABLE_ACTIVE;
6037
6038 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
6039 state);
Michal Kazior077efc82014-10-21 10:10:29 +03006040 if (ret) {
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006041 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
Michal Kazior077efc82014-10-21 10:10:29 +03006042 arvif->vdev_id, ret);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006043 ath10k_peer_delete(ar, arvif->vdev_id,
6044 sta->addr);
6045 ath10k_mac_dec_num_stations(arvif, sta);
Michal Kazior077efc82014-10-21 10:10:29 +03006046 goto exit;
6047 }
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006048 }
Michal Kazior077efc82014-10-21 10:10:29 +03006049
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006050 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
6051 WMI_TDLS_PEER_STATE_PEERING);
6052 if (ret) {
6053 ath10k_warn(ar,
6054 "failed to update tdls peer %pM for vdev %d when adding a new sta: %i\n",
6055 sta->addr, arvif->vdev_id, ret);
6056 ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6057 ath10k_mac_dec_num_stations(arvif, sta);
6058
6059 if (num_tdls_stations != 0)
6060 goto exit;
6061 ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
6062 WMI_TDLS_DISABLE);
Michal Kazior077efc82014-10-21 10:10:29 +03006063 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006064 } else if ((old_state == IEEE80211_STA_NONE &&
6065 new_state == IEEE80211_STA_NOTEXIST)) {
6066 /*
6067 * Existing station deletion.
6068 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006069 ath10k_dbg(ar, ATH10K_DBG_MAC,
Ben Greear30404202016-08-18 18:26:35 -07006070 "mac vdev %d peer delete %pM sta %pK (sta gone)\n",
6071 arvif->vdev_id, sta->addr, sta);
Michal Kazior077efc82014-10-21 10:10:29 +03006072
Manikanta Pubbisetty10318872017-11-06 13:39:31 +05306073 if (sta->tdls) {
6074 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id,
6075 sta,
6076 WMI_TDLS_PEER_STATE_TEARDOWN);
6077 if (ret)
6078 ath10k_warn(ar, "failed to update tdls peer state for %pM state %d: %i\n",
6079 sta->addr,
6080 WMI_TDLS_PEER_STATE_TEARDOWN, ret);
6081 }
6082
Kalle Valo5e3dd152013-06-12 20:52:10 +03006083 ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
6084 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006085 ath10k_warn(ar, "failed to delete peer %pM for vdev %d: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006086 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006087
Marek Puzyniak7c354242015-03-30 09:51:52 +03006088 ath10k_mac_dec_num_stations(arvif, sta);
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006089
Michal Kazior69427262016-03-06 16:14:30 +02006090 spin_lock_bh(&ar->data_lock);
6091 for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
6092 peer = ar->peer_map[i];
6093 if (!peer)
6094 continue;
6095
6096 if (peer->sta == sta) {
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05306097 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 +03006098 sta->addr, peer, i, arvif->vdev_id);
Michal Kazior69427262016-03-06 16:14:30 +02006099 peer->sta = NULL;
Ben Greeard0eeafa2016-06-30 15:23:59 +03006100
6101 /* Clean up the peer object as well since we
6102 * must have failed to do this above.
6103 */
6104 list_del(&peer->list);
6105 ar->peer_map[i] = NULL;
6106 kfree(peer);
6107 ar->num_peers--;
Michal Kazior69427262016-03-06 16:14:30 +02006108 }
6109 }
6110 spin_unlock_bh(&ar->data_lock);
6111
Michal Kazior29946872016-03-06 16:14:34 +02006112 for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
6113 ath10k_mac_txq_unref(ar, sta->txq[i]);
6114
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006115 if (!sta->tdls)
6116 goto exit;
6117
6118 if (ath10k_mac_tdls_vif_stations_count(hw, vif))
6119 goto exit;
6120
6121 /* This was the last tdls peer in current vif */
6122 ret = ath10k_wmi_update_fw_tdls_state(ar, arvif->vdev_id,
6123 WMI_TDLS_DISABLE);
6124 if (ret) {
6125 ath10k_warn(ar, "failed to update fw tdls state on vdev %i: %i\n",
6126 arvif->vdev_id, ret);
6127 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006128 } else if (old_state == IEEE80211_STA_AUTH &&
6129 new_state == IEEE80211_STA_ASSOC &&
6130 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04006131 vif->type == NL80211_IFTYPE_MESH_POINT ||
Kalle Valo5e3dd152013-06-12 20:52:10 +03006132 vif->type == NL80211_IFTYPE_ADHOC)) {
6133 /*
6134 * New association.
6135 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006136 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM associated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03006137 sta->addr);
6138
Michal Kazior590922a2014-10-21 10:10:29 +03006139 ret = ath10k_station_assoc(ar, vif, sta, false);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006140 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006141 ath10k_warn(ar, "failed to associate station %pM for vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006142 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006143 } else if (old_state == IEEE80211_STA_ASSOC &&
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006144 new_state == IEEE80211_STA_AUTHORIZED &&
6145 sta->tdls) {
6146 /*
6147 * Tdls station authorized.
6148 */
6149 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac tdls sta %pM authorized\n",
6150 sta->addr);
6151
6152 ret = ath10k_station_assoc(ar, vif, sta, false);
6153 if (ret) {
6154 ath10k_warn(ar, "failed to associate tdls station %pM for vdev %i: %i\n",
6155 sta->addr, arvif->vdev_id, ret);
6156 goto exit;
6157 }
6158
6159 ret = ath10k_mac_tdls_peer_update(ar, arvif->vdev_id, sta,
6160 WMI_TDLS_PEER_STATE_CONNECTED);
6161 if (ret)
6162 ath10k_warn(ar, "failed to update tdls peer %pM for vdev %i: %i\n",
6163 sta->addr, arvif->vdev_id, ret);
6164 } else if (old_state == IEEE80211_STA_ASSOC &&
6165 new_state == IEEE80211_STA_AUTH &&
6166 (vif->type == NL80211_IFTYPE_AP ||
Bob Copelandb6c7baf2015-09-09 12:47:36 -04006167 vif->type == NL80211_IFTYPE_MESH_POINT ||
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03006168 vif->type == NL80211_IFTYPE_ADHOC)) {
Kalle Valo5e3dd152013-06-12 20:52:10 +03006169 /*
6170 * Disassociation.
6171 */
Michal Kazior7aa7a722014-08-25 12:09:38 +02006172 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM disassociated\n",
Kalle Valo60c3daa2013-09-08 17:56:07 +03006173 sta->addr);
6174
Michal Kazior590922a2014-10-21 10:10:29 +03006175 ret = ath10k_station_disassoc(ar, vif, sta);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006176 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006177 ath10k_warn(ar, "failed to disassociate station: %pM vdev %i: %i\n",
Ben Greear69244e52014-02-27 18:50:00 +02006178 sta->addr, arvif->vdev_id, ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006179 }
Bartosz Markowski0e759f32014-01-02 14:38:33 +01006180exit:
Kalle Valo5e3dd152013-06-12 20:52:10 +03006181 mutex_unlock(&ar->conf_mutex);
6182 return ret;
6183}
6184
6185static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,
Kalle Valo5b07e072014-09-14 12:50:06 +03006186 u16 ac, bool enable)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006187{
6188 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kaziorb0e56152015-01-24 12:14:52 +02006189 struct wmi_sta_uapsd_auto_trig_arg arg = {};
6190 u32 prio = 0, acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006191 u32 value = 0;
6192 int ret = 0;
6193
Michal Kazior548db542013-07-05 16:15:15 +03006194 lockdep_assert_held(&ar->conf_mutex);
6195
Kalle Valo5e3dd152013-06-12 20:52:10 +03006196 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
6197 return 0;
6198
6199 switch (ac) {
6200 case IEEE80211_AC_VO:
6201 value = WMI_STA_PS_UAPSD_AC3_DELIVERY_EN |
6202 WMI_STA_PS_UAPSD_AC3_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006203 prio = 7;
6204 acc = 3;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006205 break;
6206 case IEEE80211_AC_VI:
6207 value = WMI_STA_PS_UAPSD_AC2_DELIVERY_EN |
6208 WMI_STA_PS_UAPSD_AC2_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006209 prio = 5;
6210 acc = 2;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006211 break;
6212 case IEEE80211_AC_BE:
6213 value = WMI_STA_PS_UAPSD_AC1_DELIVERY_EN |
6214 WMI_STA_PS_UAPSD_AC1_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006215 prio = 2;
6216 acc = 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006217 break;
6218 case IEEE80211_AC_BK:
6219 value = WMI_STA_PS_UAPSD_AC0_DELIVERY_EN |
6220 WMI_STA_PS_UAPSD_AC0_TRIGGER_EN;
Michal Kaziorb0e56152015-01-24 12:14:52 +02006221 prio = 0;
6222 acc = 0;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006223 break;
6224 }
6225
6226 if (enable)
6227 arvif->u.sta.uapsd |= value;
6228 else
6229 arvif->u.sta.uapsd &= ~value;
6230
6231 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
6232 WMI_STA_PS_PARAM_UAPSD,
6233 arvif->u.sta.uapsd);
6234 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006235 ath10k_warn(ar, "failed to set uapsd params: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006236 goto exit;
6237 }
6238
6239 if (arvif->u.sta.uapsd)
6240 value = WMI_STA_PS_RX_WAKE_POLICY_POLL_UAPSD;
6241 else
6242 value = WMI_STA_PS_RX_WAKE_POLICY_WAKE;
6243
6244 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
6245 WMI_STA_PS_PARAM_RX_WAKE_POLICY,
6246 value);
6247 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006248 ath10k_warn(ar, "failed to set rx wake param: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006249
Michal Kazior9f9b5742014-12-12 12:41:36 +01006250 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
6251 if (ret) {
6252 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
6253 arvif->vdev_id, ret);
6254 return ret;
6255 }
6256
6257 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
6258 if (ret) {
6259 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
6260 arvif->vdev_id, ret);
6261 return ret;
6262 }
6263
Michal Kaziorb0e56152015-01-24 12:14:52 +02006264 if (test_bit(WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, ar->wmi.svc_map) ||
6265 test_bit(WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, ar->wmi.svc_map)) {
6266 /* Only userspace can make an educated decision when to send
6267 * trigger frame. The following effectively disables u-UAPSD
6268 * autotrigger in firmware (which is enabled by default
6269 * provided the autotrigger service is available).
6270 */
6271
6272 arg.wmm_ac = acc;
6273 arg.user_priority = prio;
6274 arg.service_interval = 0;
6275 arg.suspend_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
6276 arg.delay_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
6277
6278 ret = ath10k_wmi_vdev_sta_uapsd(ar, arvif->vdev_id,
6279 arvif->bssid, &arg, 1);
6280 if (ret) {
6281 ath10k_warn(ar, "failed to set uapsd auto trigger %d\n",
6282 ret);
6283 return ret;
6284 }
6285 }
6286
Kalle Valo5e3dd152013-06-12 20:52:10 +03006287exit:
6288 return ret;
6289}
6290
6291static int ath10k_conf_tx(struct ieee80211_hw *hw,
6292 struct ieee80211_vif *vif, u16 ac,
6293 const struct ieee80211_tx_queue_params *params)
6294{
6295 struct ath10k *ar = hw->priv;
Michal Kazior5e752e42015-01-19 09:53:41 +01006296 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006297 struct wmi_wmm_params_arg *p = NULL;
6298 int ret;
6299
6300 mutex_lock(&ar->conf_mutex);
6301
6302 switch (ac) {
6303 case IEEE80211_AC_VO:
Michal Kazior5e752e42015-01-19 09:53:41 +01006304 p = &arvif->wmm_params.ac_vo;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006305 break;
6306 case IEEE80211_AC_VI:
Michal Kazior5e752e42015-01-19 09:53:41 +01006307 p = &arvif->wmm_params.ac_vi;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006308 break;
6309 case IEEE80211_AC_BE:
Michal Kazior5e752e42015-01-19 09:53:41 +01006310 p = &arvif->wmm_params.ac_be;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006311 break;
6312 case IEEE80211_AC_BK:
Michal Kazior5e752e42015-01-19 09:53:41 +01006313 p = &arvif->wmm_params.ac_bk;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006314 break;
6315 }
6316
6317 if (WARN_ON(!p)) {
6318 ret = -EINVAL;
6319 goto exit;
6320 }
6321
6322 p->cwmin = params->cw_min;
6323 p->cwmax = params->cw_max;
6324 p->aifs = params->aifs;
6325
6326 /*
6327 * The channel time duration programmed in the HW is in absolute
6328 * microseconds, while mac80211 gives the txop in units of
6329 * 32 microseconds.
6330 */
6331 p->txop = params->txop * 32;
6332
Michal Kazior7fc979a2015-01-28 09:57:28 +02006333 if (ar->wmi.ops->gen_vdev_wmm_conf) {
6334 ret = ath10k_wmi_vdev_wmm_conf(ar, arvif->vdev_id,
6335 &arvif->wmm_params);
6336 if (ret) {
6337 ath10k_warn(ar, "failed to set vdev wmm params on vdev %i: %d\n",
6338 arvif->vdev_id, ret);
6339 goto exit;
6340 }
6341 } else {
6342 /* This won't work well with multi-interface cases but it's
6343 * better than nothing.
6344 */
6345 ret = ath10k_wmi_pdev_set_wmm_params(ar, &arvif->wmm_params);
6346 if (ret) {
6347 ath10k_warn(ar, "failed to set wmm params: %d\n", ret);
6348 goto exit;
6349 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006350 }
6351
6352 ret = ath10k_conf_tx_uapsd(ar, vif, ac, params->uapsd);
6353 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006354 ath10k_warn(ar, "failed to set sta uapsd: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006355
6356exit:
6357 mutex_unlock(&ar->conf_mutex);
6358 return ret;
6359}
6360
Kalle Valo14e105c2016-04-13 14:13:21 +03006361#define ATH10K_ROC_TIMEOUT_HZ (2 * HZ)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006362
6363static int ath10k_remain_on_channel(struct ieee80211_hw *hw,
6364 struct ieee80211_vif *vif,
6365 struct ieee80211_channel *chan,
6366 int duration,
6367 enum ieee80211_roc_type type)
6368{
6369 struct ath10k *ar = hw->priv;
6370 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
6371 struct wmi_start_scan_arg arg;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006372 int ret = 0;
Michal Kaziorfcf98442015-03-31 11:03:47 +00006373 u32 scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006374
6375 mutex_lock(&ar->conf_mutex);
6376
6377 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006378 switch (ar->scan.state) {
6379 case ATH10K_SCAN_IDLE:
6380 reinit_completion(&ar->scan.started);
6381 reinit_completion(&ar->scan.completed);
6382 reinit_completion(&ar->scan.on_channel);
6383 ar->scan.state = ATH10K_SCAN_STARTING;
6384 ar->scan.is_roc = true;
6385 ar->scan.vdev_id = arvif->vdev_id;
6386 ar->scan.roc_freq = chan->center_freq;
Michal Kaziord710e752015-07-09 13:08:36 +02006387 ar->scan.roc_notify = true;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006388 ret = 0;
6389 break;
6390 case ATH10K_SCAN_STARTING:
6391 case ATH10K_SCAN_RUNNING:
6392 case ATH10K_SCAN_ABORTING:
Kalle Valo5e3dd152013-06-12 20:52:10 +03006393 ret = -EBUSY;
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006394 break;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006395 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03006396 spin_unlock_bh(&ar->data_lock);
6397
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006398 if (ret)
6399 goto exit;
6400
Michal Kaziorfcf98442015-03-31 11:03:47 +00006401 scan_time_msec = ar->hw->wiphy->max_remain_on_channel_duration * 2;
Michal Kaziordcca0bd2014-11-24 14:58:32 +01006402
Kalle Valo5e3dd152013-06-12 20:52:10 +03006403 memset(&arg, 0, sizeof(arg));
6404 ath10k_wmi_start_scan_init(ar, &arg);
6405 arg.vdev_id = arvif->vdev_id;
6406 arg.scan_id = ATH10K_SCAN_ID;
6407 arg.n_channels = 1;
6408 arg.channels[0] = chan->center_freq;
Michal Kaziorfcf98442015-03-31 11:03:47 +00006409 arg.dwell_time_active = scan_time_msec;
6410 arg.dwell_time_passive = scan_time_msec;
6411 arg.max_scan_time = scan_time_msec;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006412 arg.scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE;
6413 arg.scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ;
Michal Kaziordbd3f9f2015-03-31 11:03:48 +00006414 arg.burst_duration_ms = duration;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006415
6416 ret = ath10k_start_scan(ar, &arg);
6417 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006418 ath10k_warn(ar, "failed to start roc scan: %d\n", ret);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006419 spin_lock_bh(&ar->data_lock);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006420 ar->scan.state = ATH10K_SCAN_IDLE;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006421 spin_unlock_bh(&ar->data_lock);
6422 goto exit;
6423 }
6424
Kalle Valo14e105c2016-04-13 14:13:21 +03006425 ret = wait_for_completion_timeout(&ar->scan.on_channel, 3 * HZ);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006426 if (ret == 0) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006427 ath10k_warn(ar, "failed to switch to channel for roc scan\n");
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006428
6429 ret = ath10k_scan_stop(ar);
6430 if (ret)
Michal Kazior7aa7a722014-08-25 12:09:38 +02006431 ath10k_warn(ar, "failed to stop scan: %d\n", ret);
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006432
Kalle Valo5e3dd152013-06-12 20:52:10 +03006433 ret = -ETIMEDOUT;
6434 goto exit;
6435 }
6436
Michal Kaziorfcf98442015-03-31 11:03:47 +00006437 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
6438 msecs_to_jiffies(duration));
6439
Kalle Valo5e3dd152013-06-12 20:52:10 +03006440 ret = 0;
6441exit:
6442 mutex_unlock(&ar->conf_mutex);
6443 return ret;
6444}
6445
6446static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw)
6447{
6448 struct ath10k *ar = hw->priv;
6449
6450 mutex_lock(&ar->conf_mutex);
Michal Kaziord710e752015-07-09 13:08:36 +02006451
6452 spin_lock_bh(&ar->data_lock);
6453 ar->scan.roc_notify = false;
6454 spin_unlock_bh(&ar->data_lock);
6455
Michal Kazior5c81c7f2014-08-05 14:54:44 +02006456 ath10k_scan_abort(ar);
Michal Kaziord710e752015-07-09 13:08:36 +02006457
Kalle Valo5e3dd152013-06-12 20:52:10 +03006458 mutex_unlock(&ar->conf_mutex);
6459
Michal Kazior4eb2e162014-10-28 10:23:09 +01006460 cancel_delayed_work_sync(&ar->scan.timeout);
6461
Kalle Valo5e3dd152013-06-12 20:52:10 +03006462 return 0;
6463}
6464
6465/*
6466 * Both RTS and Fragmentation threshold are interface-specific
6467 * in ath10k, but device-specific in mac80211.
6468 */
Kalle Valo5e3dd152013-06-12 20:52:10 +03006469
6470static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
6471{
Kalle Valo5e3dd152013-06-12 20:52:10 +03006472 struct ath10k *ar = hw->priv;
Michal Kaziorad088bf2013-10-16 15:44:46 +03006473 struct ath10k_vif *arvif;
6474 int ret = 0;
Michal Kazior548db542013-07-05 16:15:15 +03006475
Michal Kaziorad088bf2013-10-16 15:44:46 +03006476 mutex_lock(&ar->conf_mutex);
6477 list_for_each_entry(arvif, &ar->arvifs, list) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006478 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d rts threshold %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03006479 arvif->vdev_id, value);
Kalle Valo60c3daa2013-09-08 17:56:07 +03006480
Michal Kaziorad088bf2013-10-16 15:44:46 +03006481 ret = ath10k_mac_set_rts(arvif, value);
6482 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006483 ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
Michal Kaziorad088bf2013-10-16 15:44:46 +03006484 arvif->vdev_id, ret);
6485 break;
6486 }
6487 }
6488 mutex_unlock(&ar->conf_mutex);
6489
6490 return ret;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006491}
6492
Michal Kazior92092fe2015-08-03 11:16:43 +02006493static int ath10k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
6494{
6495 /* Even though there's a WMI enum for fragmentation threshold no known
6496 * firmware actually implements it. Moreover it is not possible to rely
6497 * frame fragmentation to mac80211 because firmware clears the "more
6498 * fragments" bit in frame control making it impossible for remote
6499 * devices to reassemble frames.
6500 *
6501 * Hence implement a dummy callback just to say fragmentation isn't
6502 * supported. This effectively prevents mac80211 from doing frame
6503 * fragmentation in software.
6504 */
6505 return -EOPNOTSUPP;
6506}
6507
Emmanuel Grumbach77be2c52014-03-27 11:30:29 +02006508static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
6509 u32 queues, bool drop)
Kalle Valo5e3dd152013-06-12 20:52:10 +03006510{
6511 struct ath10k *ar = hw->priv;
Michal Kazioraffd3212013-07-16 09:54:35 +02006512 bool skip;
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006513 long time_left;
Kalle Valo5e3dd152013-06-12 20:52:10 +03006514
6515 /* mac80211 doesn't care if we really xmit queued frames or not
6516 * we'll collect those frames either way if we stop/delete vdevs */
6517 if (drop)
6518 return;
6519
Michal Kazior548db542013-07-05 16:15:15 +03006520 mutex_lock(&ar->conf_mutex);
6521
Michal Kazioraffd3212013-07-16 09:54:35 +02006522 if (ar->state == ATH10K_STATE_WEDGED)
6523 goto skip;
6524
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006525 time_left = wait_event_timeout(ar->htt.empty_tx_wq, ({
Kalle Valo5e3dd152013-06-12 20:52:10 +03006526 bool empty;
Michal Kazioraffd3212013-07-16 09:54:35 +02006527
Michal Kazioredb82362013-07-05 16:15:14 +03006528 spin_lock_bh(&ar->htt.tx_lock);
Michal Kazior0945baf2013-09-18 14:43:18 +02006529 empty = (ar->htt.num_pending_tx == 0);
Michal Kazioredb82362013-07-05 16:15:14 +03006530 spin_unlock_bh(&ar->htt.tx_lock);
Michal Kazioraffd3212013-07-16 09:54:35 +02006531
Michal Kazior7962b0d2014-10-28 10:34:38 +01006532 skip = (ar->state == ATH10K_STATE_WEDGED) ||
6533 test_bit(ATH10K_FLAG_CRASH_FLUSH,
6534 &ar->dev_flags);
Michal Kazioraffd3212013-07-16 09:54:35 +02006535
6536 (empty || skip);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006537 }), ATH10K_FLUSH_TIMEOUT_HZ);
Michal Kazioraffd3212013-07-16 09:54:35 +02006538
Nicholas Mc Guired4298a32015-06-15 14:46:43 +03006539 if (time_left == 0 || skip)
6540 ath10k_warn(ar, "failed to flush transmit queue (skip %i ar-state %i): %ld\n",
6541 skip, ar->state, time_left);
Michal Kazior548db542013-07-05 16:15:15 +03006542
Michal Kazioraffd3212013-07-16 09:54:35 +02006543skip:
Michal Kazior548db542013-07-05 16:15:15 +03006544 mutex_unlock(&ar->conf_mutex);
Kalle Valo5e3dd152013-06-12 20:52:10 +03006545}
6546
6547/* TODO: Implement this function properly
6548 * For now it is needed to reply to Probe Requests in IBSS mode.
6549 * Propably we need this information from FW.
6550 */
6551static int ath10k_tx_last_beacon(struct ieee80211_hw *hw)
6552{
6553 return 1;
6554}
6555
Eliad Pellercf2c92d2014-11-04 11:43:54 +02006556static void ath10k_reconfig_complete(struct ieee80211_hw *hw,
6557 enum ieee80211_reconfig_type reconfig_type)
Michal Kazioraffd3212013-07-16 09:54:35 +02006558{
6559 struct ath10k *ar = hw->priv;
6560
Eliad Pellercf2c92d2014-11-04 11:43:54 +02006561 if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)
6562 return;
6563
Michal Kazioraffd3212013-07-16 09:54:35 +02006564 mutex_lock(&ar->conf_mutex);
6565
6566 /* If device failed to restart it will be in a different state, e.g.
6567 * ATH10K_STATE_WEDGED */
6568 if (ar->state == ATH10K_STATE_RESTARTED) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006569 ath10k_info(ar, "device successfully recovered\n");
Michal Kazioraffd3212013-07-16 09:54:35 +02006570 ar->state = ATH10K_STATE_ON;
Michal Kazior7962b0d2014-10-28 10:34:38 +01006571 ieee80211_wake_queues(ar->hw);
Michal Kazioraffd3212013-07-16 09:54:35 +02006572 }
6573
6574 mutex_unlock(&ar->conf_mutex);
6575}
6576
Rajkumar Manoharanfa7937e2016-04-27 16:23:22 +05306577static void
6578ath10k_mac_update_bss_chan_survey(struct ath10k *ar,
6579 struct ieee80211_channel *channel)
6580{
6581 int ret;
6582 enum wmi_bss_survey_req_type type = WMI_BSS_SURVEY_REQ_TYPE_READ_CLEAR;
6583
6584 lockdep_assert_held(&ar->conf_mutex);
6585
6586 if (!test_bit(WMI_SERVICE_BSS_CHANNEL_INFO_64, ar->wmi.svc_map) ||
6587 (ar->rx_channel != channel))
6588 return;
6589
6590 if (ar->scan.state != ATH10K_SCAN_IDLE) {
6591 ath10k_dbg(ar, ATH10K_DBG_MAC, "ignoring bss chan info request while scanning..\n");
6592 return;
6593 }
6594
6595 reinit_completion(&ar->bss_survey_done);
6596
6597 ret = ath10k_wmi_pdev_bss_chan_info_request(ar, type);
6598 if (ret) {
6599 ath10k_warn(ar, "failed to send pdev bss chan info request\n");
6600 return;
6601 }
6602
6603 ret = wait_for_completion_timeout(&ar->bss_survey_done, 3 * HZ);
6604 if (!ret) {
6605 ath10k_warn(ar, "bss channel survey timed out\n");
6606 return;
6607 }
6608}
6609
Michal Kazior2e1dea42013-07-31 10:32:40 +02006610static int ath10k_get_survey(struct ieee80211_hw *hw, int idx,
6611 struct survey_info *survey)
6612{
6613 struct ath10k *ar = hw->priv;
6614 struct ieee80211_supported_band *sband;
6615 struct survey_info *ar_survey = &ar->survey[idx];
6616 int ret = 0;
6617
6618 mutex_lock(&ar->conf_mutex);
6619
Johannes Berg57fbcce2016-04-12 15:56:15 +02006620 sband = hw->wiphy->bands[NL80211_BAND_2GHZ];
Michal Kazior2e1dea42013-07-31 10:32:40 +02006621 if (sband && idx >= sband->n_channels) {
6622 idx -= sband->n_channels;
6623 sband = NULL;
6624 }
6625
6626 if (!sband)
Johannes Berg57fbcce2016-04-12 15:56:15 +02006627 sband = hw->wiphy->bands[NL80211_BAND_5GHZ];
Michal Kazior2e1dea42013-07-31 10:32:40 +02006628
6629 if (!sband || idx >= sband->n_channels) {
6630 ret = -ENOENT;
6631 goto exit;
6632 }
6633
Ashok Raj Nagarajan77eb3d62016-09-02 10:59:53 +05306634 ath10k_mac_update_bss_chan_survey(ar, &sband->channels[idx]);
Rajkumar Manoharanfa7937e2016-04-27 16:23:22 +05306635
Michal Kazior2e1dea42013-07-31 10:32:40 +02006636 spin_lock_bh(&ar->data_lock);
6637 memcpy(survey, ar_survey, sizeof(*survey));
6638 spin_unlock_bh(&ar->data_lock);
6639
6640 survey->channel = &sband->channels[idx];
6641
Felix Fietkaufa1d4df2014-10-23 17:04:28 +03006642 if (ar->rx_channel == survey->channel)
6643 survey->filled |= SURVEY_INFO_IN_USE;
6644
Michal Kazior2e1dea42013-07-31 10:32:40 +02006645exit:
6646 mutex_unlock(&ar->conf_mutex);
6647 return ret;
6648}
6649
Michal Kazior3ae54222015-03-31 10:49:20 +00006650static bool
6651ath10k_mac_bitrate_mask_has_single_rate(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006652 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00006653 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006654{
Michal Kazior3ae54222015-03-31 10:49:20 +00006655 int num_rates = 0;
6656 int i;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006657
Michal Kazior3ae54222015-03-31 10:49:20 +00006658 num_rates += hweight32(mask->control[band].legacy);
6659
6660 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++)
6661 num_rates += hweight8(mask->control[band].ht_mcs[i]);
6662
6663 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++)
6664 num_rates += hweight16(mask->control[band].vht_mcs[i]);
6665
6666 return num_rates == 1;
6667}
6668
6669static bool
6670ath10k_mac_bitrate_mask_get_single_nss(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006671 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00006672 const struct cfg80211_bitrate_mask *mask,
6673 int *nss)
6674{
6675 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
6676 u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
6677 u8 ht_nss_mask = 0;
6678 u8 vht_nss_mask = 0;
6679 int i;
6680
6681 if (mask->control[band].legacy)
6682 return false;
6683
6684 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
6685 if (mask->control[band].ht_mcs[i] == 0)
6686 continue;
6687 else if (mask->control[band].ht_mcs[i] ==
6688 sband->ht_cap.mcs.rx_mask[i])
6689 ht_nss_mask |= BIT(i);
6690 else
6691 return false;
6692 }
6693
6694 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
6695 if (mask->control[band].vht_mcs[i] == 0)
6696 continue;
6697 else if (mask->control[band].vht_mcs[i] ==
6698 ath10k_mac_get_max_vht_mcs_map(vht_mcs_map, i))
6699 vht_nss_mask |= BIT(i);
6700 else
6701 return false;
6702 }
6703
6704 if (ht_nss_mask != vht_nss_mask)
6705 return false;
6706
6707 if (ht_nss_mask == 0)
6708 return false;
6709
6710 if (BIT(fls(ht_nss_mask)) - 1 != ht_nss_mask)
6711 return false;
6712
6713 *nss = fls(ht_nss_mask);
6714
6715 return true;
6716}
6717
6718static int
6719ath10k_mac_bitrate_mask_get_single_rate(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006720 enum nl80211_band band,
Michal Kazior3ae54222015-03-31 10:49:20 +00006721 const struct cfg80211_bitrate_mask *mask,
6722 u8 *rate, u8 *nss)
6723{
6724 struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
6725 int rate_idx;
6726 int i;
6727 u16 bitrate;
6728 u8 preamble;
6729 u8 hw_rate;
6730
6731 if (hweight32(mask->control[band].legacy) == 1) {
6732 rate_idx = ffs(mask->control[band].legacy) - 1;
6733
6734 hw_rate = sband->bitrates[rate_idx].hw_value;
6735 bitrate = sband->bitrates[rate_idx].bitrate;
6736
6737 if (ath10k_mac_bitrate_is_cck(bitrate))
6738 preamble = WMI_RATE_PREAMBLE_CCK;
6739 else
6740 preamble = WMI_RATE_PREAMBLE_OFDM;
6741
6742 *nss = 1;
6743 *rate = preamble << 6 |
6744 (*nss - 1) << 4 |
6745 hw_rate << 0;
6746
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006747 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006748 }
6749
Michal Kazior3ae54222015-03-31 10:49:20 +00006750 for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
6751 if (hweight8(mask->control[band].ht_mcs[i]) == 1) {
6752 *nss = i + 1;
6753 *rate = WMI_RATE_PREAMBLE_HT << 6 |
6754 (*nss - 1) << 4 |
6755 (ffs(mask->control[band].ht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006756
Michal Kazior3ae54222015-03-31 10:49:20 +00006757 return 0;
6758 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006759 }
6760
Michal Kazior3ae54222015-03-31 10:49:20 +00006761 for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
6762 if (hweight16(mask->control[band].vht_mcs[i]) == 1) {
6763 *nss = i + 1;
6764 *rate = WMI_RATE_PREAMBLE_VHT << 6 |
6765 (*nss - 1) << 4 |
6766 (ffs(mask->control[band].vht_mcs[i]) - 1);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006767
Michal Kazior3ae54222015-03-31 10:49:20 +00006768 return 0;
6769 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006770 }
6771
Michal Kazior3ae54222015-03-31 10:49:20 +00006772 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006773}
6774
Michal Kazior3ae54222015-03-31 10:49:20 +00006775static int ath10k_mac_set_fixed_rate_params(struct ath10k_vif *arvif,
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306776 u8 rate, u8 nss, u8 sgi, u8 ldpc)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006777{
6778 struct ath10k *ar = arvif->ar;
6779 u32 vdev_param;
Michal Kazior3ae54222015-03-31 10:49:20 +00006780 int ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006781
Michal Kazior3ae54222015-03-31 10:49:20 +00006782 lockdep_assert_held(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006783
Michal Kazior3ae54222015-03-31 10:49:20 +00006784 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac set fixed rate params vdev %i rate 0x%02hhx nss %hhu sgi %hhu\n",
6785 arvif->vdev_id, rate, nss, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006786
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006787 vdev_param = ar->wmi.vdev_param->fixed_rate;
Michal Kazior3ae54222015-03-31 10:49:20 +00006788 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, rate);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006789 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02006790 ath10k_warn(ar, "failed to set fixed rate param 0x%02x: %d\n",
Michal Kazior3ae54222015-03-31 10:49:20 +00006791 rate, ret);
6792 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006793 }
6794
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006795 vdev_param = ar->wmi.vdev_param->nss;
Michal Kazior3ae54222015-03-31 10:49:20 +00006796 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, nss);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006797 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006798 ath10k_warn(ar, "failed to set nss param %d: %d\n", nss, ret);
6799 return ret;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006800 }
6801
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006802 vdev_param = ar->wmi.vdev_param->sgi;
Michal Kazior3ae54222015-03-31 10:49:20 +00006803 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, sgi);
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006804 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006805 ath10k_warn(ar, "failed to set sgi param %d: %d\n", sgi, ret);
6806 return ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006807 }
6808
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306809 vdev_param = ar->wmi.vdev_param->ldpc;
6810 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, ldpc);
6811 if (ret) {
6812 ath10k_warn(ar, "failed to set ldpc param %d: %d\n", ldpc, ret);
6813 return ret;
6814 }
6815
Michal Kazior3ae54222015-03-31 10:49:20 +00006816 return 0;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006817}
6818
Michal Kazior45c9abc2015-04-21 20:42:58 +03006819static bool
6820ath10k_mac_can_set_bitrate_mask(struct ath10k *ar,
Johannes Berg57fbcce2016-04-12 15:56:15 +02006821 enum nl80211_band band,
Michal Kazior45c9abc2015-04-21 20:42:58 +03006822 const struct cfg80211_bitrate_mask *mask)
6823{
6824 int i;
6825 u16 vht_mcs;
6826
6827 /* Due to firmware limitation in WMI_PEER_ASSOC_CMDID it is impossible
6828 * to express all VHT MCS rate masks. Effectively only the following
6829 * ranges can be used: none, 0-7, 0-8 and 0-9.
6830 */
6831 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
6832 vht_mcs = mask->control[band].vht_mcs[i];
6833
6834 switch (vht_mcs) {
6835 case 0:
6836 case BIT(8) - 1:
6837 case BIT(9) - 1:
6838 case BIT(10) - 1:
6839 break;
6840 default:
6841 ath10k_warn(ar, "refusing bitrate mask with missing 0-7 VHT MCS rates\n");
6842 return false;
6843 }
6844 }
6845
6846 return true;
6847}
6848
6849static void ath10k_mac_set_bitrate_mask_iter(void *data,
6850 struct ieee80211_sta *sta)
6851{
6852 struct ath10k_vif *arvif = data;
6853 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
6854 struct ath10k *ar = arvif->ar;
6855
6856 if (arsta->arvif != arvif)
6857 return;
6858
6859 spin_lock_bh(&ar->data_lock);
6860 arsta->changed |= IEEE80211_RC_SUPP_RATES_CHANGED;
6861 spin_unlock_bh(&ar->data_lock);
6862
6863 ieee80211_queue_work(ar->hw, &arsta->update_wk);
6864}
6865
Michal Kazior3ae54222015-03-31 10:49:20 +00006866static int ath10k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
6867 struct ieee80211_vif *vif,
6868 const struct cfg80211_bitrate_mask *mask)
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006869{
6870 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006871 struct cfg80211_chan_def def;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006872 struct ath10k *ar = arvif->ar;
Johannes Berg57fbcce2016-04-12 15:56:15 +02006873 enum nl80211_band band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006874 const u8 *ht_mcs_mask;
6875 const u16 *vht_mcs_mask;
Michal Kazior3ae54222015-03-31 10:49:20 +00006876 u8 rate;
6877 u8 nss;
6878 u8 sgi;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306879 u8 ldpc;
Michal Kazior3ae54222015-03-31 10:49:20 +00006880 int single_nss;
6881 int ret;
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006882
Michal Kazior500ff9f2015-03-31 10:26:21 +00006883 if (ath10k_mac_vif_chan(vif, &def))
6884 return -EPERM;
6885
Michal Kazior500ff9f2015-03-31 10:26:21 +00006886 band = def.chan->band;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006887 ht_mcs_mask = mask->control[band].ht_mcs;
6888 vht_mcs_mask = mask->control[band].vht_mcs;
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306889 ldpc = !!(ar->ht_cap_info & WMI_HT_CAP_LDPC);
Michal Kazior500ff9f2015-03-31 10:26:21 +00006890
Michal Kazior3ae54222015-03-31 10:49:20 +00006891 sgi = mask->control[band].gi;
6892 if (sgi == NL80211_TXRATE_FORCE_LGI)
Janusz Dziedzic9f81f722014-01-17 20:04:14 +01006893 return -EINVAL;
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006894
Michal Kazior3ae54222015-03-31 10:49:20 +00006895 if (ath10k_mac_bitrate_mask_has_single_rate(ar, band, mask)) {
6896 ret = ath10k_mac_bitrate_mask_get_single_rate(ar, band, mask,
6897 &rate, &nss);
6898 if (ret) {
6899 ath10k_warn(ar, "failed to get single rate for vdev %i: %d\n",
6900 arvif->vdev_id, ret);
6901 return ret;
6902 }
6903 } else if (ath10k_mac_bitrate_mask_get_single_nss(ar, band, mask,
6904 &single_nss)) {
6905 rate = WMI_FIXED_RATE_NONE;
6906 nss = single_nss;
6907 } else {
6908 rate = WMI_FIXED_RATE_NONE;
Michal Kazior45c9abc2015-04-21 20:42:58 +03006909 nss = min(ar->num_rf_chains,
6910 max(ath10k_mac_max_ht_nss(ht_mcs_mask),
6911 ath10k_mac_max_vht_nss(vht_mcs_mask)));
6912
6913 if (!ath10k_mac_can_set_bitrate_mask(ar, band, mask))
6914 return -EINVAL;
6915
6916 mutex_lock(&ar->conf_mutex);
6917
6918 arvif->bitrate_mask = *mask;
6919 ieee80211_iterate_stations_atomic(ar->hw,
6920 ath10k_mac_set_bitrate_mask_iter,
6921 arvif);
6922
6923 mutex_unlock(&ar->conf_mutex);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006924 }
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006925
6926 mutex_lock(&ar->conf_mutex);
6927
Rajkumar Manoharanbd4a41e2015-09-16 13:19:00 +05306928 ret = ath10k_mac_set_fixed_rate_params(arvif, rate, nss, sgi, ldpc);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006929 if (ret) {
Michal Kazior3ae54222015-03-31 10:49:20 +00006930 ath10k_warn(ar, "failed to set fixed rate params on vdev %i: %d\n",
6931 arvif->vdev_id, ret);
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006932 goto exit;
6933 }
6934
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006935exit:
6936 mutex_unlock(&ar->conf_mutex);
Michal Kazior3ae54222015-03-31 10:49:20 +00006937
Janusz Dziedzic51ab1a02014-01-08 09:08:33 +01006938 return ret;
6939}
6940
Michal Kazior9797feb2014-02-14 14:49:48 +01006941static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
6942 struct ieee80211_vif *vif,
6943 struct ieee80211_sta *sta,
6944 u32 changed)
6945{
6946 struct ath10k *ar = hw->priv;
6947 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
Karthikeyan Periyasamye63ff842018-03-12 17:09:40 +05306948 struct ath10k_vif *arvif = (void *)vif->drv_priv;
6949 struct ath10k_peer *peer;
Michal Kazior9797feb2014-02-14 14:49:48 +01006950 u32 bw, smps;
6951
6952 spin_lock_bh(&ar->data_lock);
6953
Karthikeyan Periyasamye63ff842018-03-12 17:09:40 +05306954 peer = ath10k_peer_find(ar, arvif->vdev_id, sta->addr);
6955 if (!peer) {
6956 spin_unlock_bh(&ar->data_lock);
6957 ath10k_warn(ar, "mac sta rc update failed to find peer %pM on vdev %i\n",
6958 sta->addr, arvif->vdev_id);
6959 return;
6960 }
6961
Michal Kazior7aa7a722014-08-25 12:09:38 +02006962 ath10k_dbg(ar, ATH10K_DBG_MAC,
Michal Kazior9797feb2014-02-14 14:49:48 +01006963 "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n",
6964 sta->addr, changed, sta->bandwidth, sta->rx_nss,
6965 sta->smps_mode);
6966
6967 if (changed & IEEE80211_RC_BW_CHANGED) {
6968 bw = WMI_PEER_CHWIDTH_20MHZ;
6969
6970 switch (sta->bandwidth) {
6971 case IEEE80211_STA_RX_BW_20:
6972 bw = WMI_PEER_CHWIDTH_20MHZ;
6973 break;
6974 case IEEE80211_STA_RX_BW_40:
6975 bw = WMI_PEER_CHWIDTH_40MHZ;
6976 break;
6977 case IEEE80211_STA_RX_BW_80:
6978 bw = WMI_PEER_CHWIDTH_80MHZ;
6979 break;
6980 case IEEE80211_STA_RX_BW_160:
Masanari Iidad939be32015-02-27 23:52:31 +09006981 ath10k_warn(ar, "Invalid bandwidth %d in rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02006982 sta->bandwidth, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01006983 bw = WMI_PEER_CHWIDTH_20MHZ;
6984 break;
6985 }
6986
6987 arsta->bw = bw;
6988 }
6989
6990 if (changed & IEEE80211_RC_NSS_CHANGED)
6991 arsta->nss = sta->rx_nss;
6992
6993 if (changed & IEEE80211_RC_SMPS_CHANGED) {
6994 smps = WMI_PEER_SMPS_PS_NONE;
6995
6996 switch (sta->smps_mode) {
6997 case IEEE80211_SMPS_AUTOMATIC:
6998 case IEEE80211_SMPS_OFF:
6999 smps = WMI_PEER_SMPS_PS_NONE;
7000 break;
7001 case IEEE80211_SMPS_STATIC:
7002 smps = WMI_PEER_SMPS_STATIC;
7003 break;
7004 case IEEE80211_SMPS_DYNAMIC:
7005 smps = WMI_PEER_SMPS_DYNAMIC;
7006 break;
7007 case IEEE80211_SMPS_NUM_MODES:
Michal Kazior7aa7a722014-08-25 12:09:38 +02007008 ath10k_warn(ar, "Invalid smps %d in sta rc update for %pM\n",
Kalle Valobe6546f2014-03-25 14:18:51 +02007009 sta->smps_mode, sta->addr);
Michal Kazior9797feb2014-02-14 14:49:48 +01007010 smps = WMI_PEER_SMPS_PS_NONE;
7011 break;
7012 }
7013
7014 arsta->smps = smps;
7015 }
7016
Michal Kazior9797feb2014-02-14 14:49:48 +01007017 arsta->changed |= changed;
7018
7019 spin_unlock_bh(&ar->data_lock);
7020
7021 ieee80211_queue_work(hw, &arsta->update_wk);
7022}
7023
Chun-Yeow Yeoh26ebbcc2014-02-25 09:29:54 +02007024static u64 ath10k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
7025{
7026 /*
7027 * FIXME: Return 0 for time being. Need to figure out whether FW
7028 * has the API to fetch 64-bit local TSF
7029 */
7030
7031 return 0;
7032}
7033
Peter Oh9f0b7e72016-04-04 16:19:14 -07007034static void ath10k_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
Kalle Valo4d165442016-04-13 14:14:16 +03007035 u64 tsf)
Peter Oh9f0b7e72016-04-04 16:19:14 -07007036{
7037 struct ath10k *ar = hw->priv;
7038 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
7039 u32 tsf_offset, vdev_param = ar->wmi.vdev_param->set_tsf;
7040 int ret;
7041
7042 /* Workaround:
7043 *
7044 * Given tsf argument is entire TSF value, but firmware accepts
7045 * only TSF offset to current TSF.
7046 *
7047 * get_tsf function is used to get offset value, however since
7048 * ath10k_get_tsf is not implemented properly, it will return 0 always.
7049 * Luckily all the caller functions to set_tsf, as of now, also rely on
7050 * get_tsf function to get entire tsf value such get_tsf() + tsf_delta,
7051 * final tsf offset value to firmware will be arithmetically correct.
7052 */
7053 tsf_offset = tsf - ath10k_get_tsf(hw, vif);
7054 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
7055 vdev_param, tsf_offset);
7056 if (ret && ret != -EOPNOTSUPP)
7057 ath10k_warn(ar, "failed to set tsf offset: %d\n", ret);
7058}
7059
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007060static int ath10k_ampdu_action(struct ieee80211_hw *hw,
7061 struct ieee80211_vif *vif,
Sara Sharon50ea05e2015-12-30 16:06:04 +02007062 struct ieee80211_ampdu_params *params)
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007063{
Michal Kazior7aa7a722014-08-25 12:09:38 +02007064 struct ath10k *ar = hw->priv;
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007065 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
Sara Sharon50ea05e2015-12-30 16:06:04 +02007066 struct ieee80211_sta *sta = params->sta;
7067 enum ieee80211_ampdu_mlme_action action = params->action;
7068 u16 tid = params->tid;
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007069
Michal Kazior7aa7a722014-08-25 12:09:38 +02007070 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 +02007071 arvif->vdev_id, sta->addr, tid, action);
7072
7073 switch (action) {
7074 case IEEE80211_AMPDU_RX_START:
7075 case IEEE80211_AMPDU_RX_STOP:
7076 /* HTT AddBa/DelBa events trigger mac80211 Rx BA session
7077 * creation/removal. Do we need to verify this?
7078 */
7079 return 0;
7080 case IEEE80211_AMPDU_TX_START:
7081 case IEEE80211_AMPDU_TX_STOP_CONT:
7082 case IEEE80211_AMPDU_TX_STOP_FLUSH:
7083 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
7084 case IEEE80211_AMPDU_TX_OPERATIONAL:
7085 /* Firmware offloads Tx aggregation entirely so deny mac80211
7086 * Tx aggregation requests.
7087 */
7088 return -EOPNOTSUPP;
7089 }
7090
7091 return -EINVAL;
7092}
7093
Michal Kazior500ff9f2015-03-31 10:26:21 +00007094static void
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007095ath10k_mac_update_rx_channel(struct ath10k *ar,
7096 struct ieee80211_chanctx_conf *ctx,
7097 struct ieee80211_vif_chanctx_switch *vifs,
7098 int n_vifs)
Michal Kazior500ff9f2015-03-31 10:26:21 +00007099{
7100 struct cfg80211_chan_def *def = NULL;
7101
7102 /* Both locks are required because ar->rx_channel is modified. This
7103 * allows readers to hold either lock.
7104 */
7105 lockdep_assert_held(&ar->conf_mutex);
7106 lockdep_assert_held(&ar->data_lock);
7107
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007108 WARN_ON(ctx && vifs);
Mohammed Shafi Shajakhan5d2db0d2017-03-08 13:52:06 +02007109 WARN_ON(vifs && !n_vifs);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007110
Michal Kazior500ff9f2015-03-31 10:26:21 +00007111 /* FIXME: Sort of an optimization and a workaround. Peers and vifs are
7112 * on a linked list now. Doing a lookup peer -> vif -> chanctx for each
7113 * ppdu on Rx may reduce performance on low-end systems. It should be
7114 * possible to make tables/hashmaps to speed the lookup up (be vary of
7115 * cpu data cache lines though regarding sizes) but to keep the initial
7116 * implementation simple and less intrusive fallback to the slow lookup
7117 * only for multi-channel cases. Single-channel cases will remain to
7118 * use the old channel derival and thus performance should not be
7119 * affected much.
7120 */
7121 rcu_read_lock();
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007122 if (!ctx && ath10k_mac_num_chanctxs(ar) == 1) {
Michal Kazior500ff9f2015-03-31 10:26:21 +00007123 ieee80211_iter_chan_contexts_atomic(ar->hw,
Kalle Valo617b0f42015-10-05 17:56:35 +03007124 ath10k_mac_get_any_chandef_iter,
7125 &def);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007126
7127 if (vifs)
7128 def = &vifs[0].new_ctx->def;
7129
Michal Kazior500ff9f2015-03-31 10:26:21 +00007130 ar->rx_channel = def->chan;
Rajkumar Manoharan1ce8c142016-04-07 12:11:54 +05307131 } else if ((ctx && ath10k_mac_num_chanctxs(ar) == 0) ||
7132 (ctx && (ar->state == ATH10K_STATE_RESTARTED))) {
7133 /* During driver restart due to firmware assert, since mac80211
7134 * already has valid channel context for given radio, channel
7135 * context iteration return num_chanctx > 0. So fix rx_channel
7136 * when restart is in progress.
7137 */
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007138 ar->rx_channel = ctx->def.chan;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007139 } else {
7140 ar->rx_channel = NULL;
7141 }
7142 rcu_read_unlock();
7143}
7144
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007145static void
7146ath10k_mac_update_vif_chan(struct ath10k *ar,
7147 struct ieee80211_vif_chanctx_switch *vifs,
7148 int n_vifs)
7149{
7150 struct ath10k_vif *arvif;
7151 int ret;
7152 int i;
7153
7154 lockdep_assert_held(&ar->conf_mutex);
7155
7156 /* First stop monitor interface. Some FW versions crash if there's a
7157 * lone monitor interface.
7158 */
7159 if (ar->monitor_started)
7160 ath10k_monitor_stop(ar);
7161
7162 for (i = 0; i < n_vifs; i++) {
7163 arvif = ath10k_vif_to_arvif(vifs[i].vif);
7164
7165 ath10k_dbg(ar, ATH10K_DBG_MAC,
7166 "mac chanctx switch vdev_id %i freq %hu->%hu width %d->%d\n",
7167 arvif->vdev_id,
7168 vifs[i].old_ctx->def.chan->center_freq,
7169 vifs[i].new_ctx->def.chan->center_freq,
7170 vifs[i].old_ctx->def.width,
7171 vifs[i].new_ctx->def.width);
7172
7173 if (WARN_ON(!arvif->is_started))
7174 continue;
7175
7176 if (WARN_ON(!arvif->is_up))
7177 continue;
7178
7179 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
7180 if (ret) {
7181 ath10k_warn(ar, "failed to down vdev %d: %d\n",
7182 arvif->vdev_id, ret);
7183 continue;
7184 }
7185 }
7186
7187 /* All relevant vdevs are downed and associated channel resources
7188 * should be available for the channel switch now.
7189 */
7190
7191 spin_lock_bh(&ar->data_lock);
7192 ath10k_mac_update_rx_channel(ar, NULL, vifs, n_vifs);
7193 spin_unlock_bh(&ar->data_lock);
7194
7195 for (i = 0; i < n_vifs; i++) {
7196 arvif = ath10k_vif_to_arvif(vifs[i].vif);
7197
7198 if (WARN_ON(!arvif->is_started))
7199 continue;
7200
7201 if (WARN_ON(!arvif->is_up))
7202 continue;
7203
7204 ret = ath10k_mac_setup_bcn_tmpl(arvif);
7205 if (ret)
7206 ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
7207 ret);
7208
7209 ret = ath10k_mac_setup_prb_tmpl(arvif);
7210 if (ret)
7211 ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
7212 ret);
7213
7214 ret = ath10k_vdev_restart(arvif, &vifs[i].new_ctx->def);
7215 if (ret) {
7216 ath10k_warn(ar, "failed to restart vdev %d: %d\n",
7217 arvif->vdev_id, ret);
7218 continue;
7219 }
7220
7221 ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
7222 arvif->bssid);
7223 if (ret) {
7224 ath10k_warn(ar, "failed to bring vdev up %d: %d\n",
7225 arvif->vdev_id, ret);
7226 continue;
7227 }
7228 }
7229
7230 ath10k_monitor_recalc(ar);
7231}
7232
Michal Kazior500ff9f2015-03-31 10:26:21 +00007233static int
7234ath10k_mac_op_add_chanctx(struct ieee80211_hw *hw,
7235 struct ieee80211_chanctx_conf *ctx)
7236{
7237 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007238
7239 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307240 "mac chanctx add freq %hu width %d ptr %pK\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007241 ctx->def.chan->center_freq, ctx->def.width, ctx);
7242
7243 mutex_lock(&ar->conf_mutex);
7244
7245 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007246 ath10k_mac_update_rx_channel(ar, ctx, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007247 spin_unlock_bh(&ar->data_lock);
7248
7249 ath10k_recalc_radar_detection(ar);
7250 ath10k_monitor_recalc(ar);
7251
7252 mutex_unlock(&ar->conf_mutex);
7253
7254 return 0;
7255}
7256
7257static void
7258ath10k_mac_op_remove_chanctx(struct ieee80211_hw *hw,
7259 struct ieee80211_chanctx_conf *ctx)
7260{
7261 struct ath10k *ar = hw->priv;
7262
7263 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307264 "mac chanctx remove freq %hu width %d ptr %pK\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007265 ctx->def.chan->center_freq, ctx->def.width, ctx);
7266
7267 mutex_lock(&ar->conf_mutex);
7268
7269 spin_lock_bh(&ar->data_lock);
Michal Kaziord7bf4b42015-06-03 12:16:54 +02007270 ath10k_mac_update_rx_channel(ar, NULL, NULL, 0);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007271 spin_unlock_bh(&ar->data_lock);
7272
7273 ath10k_recalc_radar_detection(ar);
7274 ath10k_monitor_recalc(ar);
7275
7276 mutex_unlock(&ar->conf_mutex);
7277}
7278
Michal Kazior9713e3d2015-09-03 10:44:52 +02007279struct ath10k_mac_change_chanctx_arg {
7280 struct ieee80211_chanctx_conf *ctx;
7281 struct ieee80211_vif_chanctx_switch *vifs;
7282 int n_vifs;
7283 int next_vif;
7284};
7285
7286static void
7287ath10k_mac_change_chanctx_cnt_iter(void *data, u8 *mac,
7288 struct ieee80211_vif *vif)
7289{
7290 struct ath10k_mac_change_chanctx_arg *arg = data;
7291
7292 if (rcu_access_pointer(vif->chanctx_conf) != arg->ctx)
7293 return;
7294
7295 arg->n_vifs++;
7296}
7297
7298static void
7299ath10k_mac_change_chanctx_fill_iter(void *data, u8 *mac,
7300 struct ieee80211_vif *vif)
7301{
7302 struct ath10k_mac_change_chanctx_arg *arg = data;
7303 struct ieee80211_chanctx_conf *ctx;
7304
7305 ctx = rcu_access_pointer(vif->chanctx_conf);
7306 if (ctx != arg->ctx)
7307 return;
7308
7309 if (WARN_ON(arg->next_vif == arg->n_vifs))
7310 return;
7311
7312 arg->vifs[arg->next_vif].vif = vif;
7313 arg->vifs[arg->next_vif].old_ctx = ctx;
7314 arg->vifs[arg->next_vif].new_ctx = ctx;
7315 arg->next_vif++;
7316}
7317
Michal Kazior500ff9f2015-03-31 10:26:21 +00007318static void
7319ath10k_mac_op_change_chanctx(struct ieee80211_hw *hw,
7320 struct ieee80211_chanctx_conf *ctx,
7321 u32 changed)
7322{
7323 struct ath10k *ar = hw->priv;
Michal Kazior9713e3d2015-09-03 10:44:52 +02007324 struct ath10k_mac_change_chanctx_arg arg = { .ctx = ctx };
Michal Kazior500ff9f2015-03-31 10:26:21 +00007325
7326 mutex_lock(&ar->conf_mutex);
7327
7328 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307329 "mac chanctx change freq %hu width %d ptr %pK changed %x\n",
Michal Kazior089ab7a2015-06-03 12:16:55 +02007330 ctx->def.chan->center_freq, ctx->def.width, ctx, changed);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007331
7332 /* This shouldn't really happen because channel switching should use
7333 * switch_vif_chanctx().
7334 */
7335 if (WARN_ON(changed & IEEE80211_CHANCTX_CHANGE_CHANNEL))
7336 goto unlock;
7337
Michal Kazior9713e3d2015-09-03 10:44:52 +02007338 if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH) {
7339 ieee80211_iterate_active_interfaces_atomic(
7340 hw,
7341 IEEE80211_IFACE_ITER_NORMAL,
7342 ath10k_mac_change_chanctx_cnt_iter,
7343 &arg);
7344 if (arg.n_vifs == 0)
7345 goto radar;
7346
7347 arg.vifs = kcalloc(arg.n_vifs, sizeof(arg.vifs[0]),
7348 GFP_KERNEL);
7349 if (!arg.vifs)
7350 goto radar;
7351
7352 ieee80211_iterate_active_interfaces_atomic(
7353 hw,
7354 IEEE80211_IFACE_ITER_NORMAL,
7355 ath10k_mac_change_chanctx_fill_iter,
7356 &arg);
7357 ath10k_mac_update_vif_chan(ar, arg.vifs, arg.n_vifs);
7358 kfree(arg.vifs);
7359 }
7360
7361radar:
Michal Kazior500ff9f2015-03-31 10:26:21 +00007362 ath10k_recalc_radar_detection(ar);
7363
7364 /* FIXME: How to configure Rx chains properly? */
7365
7366 /* No other actions are actually necessary. Firmware maintains channel
7367 * definitions per vdev internally and there's no host-side channel
7368 * context abstraction to configure, e.g. channel width.
7369 */
7370
7371unlock:
7372 mutex_unlock(&ar->conf_mutex);
7373}
7374
7375static int
7376ath10k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
7377 struct ieee80211_vif *vif,
7378 struct ieee80211_chanctx_conf *ctx)
7379{
7380 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007381 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7382 int ret;
7383
7384 mutex_lock(&ar->conf_mutex);
7385
7386 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307387 "mac chanctx assign ptr %pK vdev_id %i\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007388 ctx, arvif->vdev_id);
7389
7390 if (WARN_ON(arvif->is_started)) {
7391 mutex_unlock(&ar->conf_mutex);
7392 return -EBUSY;
7393 }
7394
Michal Kazior089ab7a2015-06-03 12:16:55 +02007395 ret = ath10k_vdev_start(arvif, &ctx->def);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007396 if (ret) {
7397 ath10k_warn(ar, "failed to start vdev %i addr %pM on freq %d: %d\n",
7398 arvif->vdev_id, vif->addr,
Michal Kazior089ab7a2015-06-03 12:16:55 +02007399 ctx->def.chan->center_freq, ret);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007400 goto err;
7401 }
7402
7403 arvif->is_started = true;
7404
Michal Kaziorf23e587e2015-07-09 13:08:37 +02007405 ret = ath10k_mac_vif_setup_ps(arvif);
7406 if (ret) {
7407 ath10k_warn(ar, "failed to update vdev %i ps: %d\n",
7408 arvif->vdev_id, ret);
7409 goto err_stop;
7410 }
7411
Michal Kazior500ff9f2015-03-31 10:26:21 +00007412 if (vif->type == NL80211_IFTYPE_MONITOR) {
7413 ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, 0, vif->addr);
7414 if (ret) {
7415 ath10k_warn(ar, "failed to up monitor vdev %i: %d\n",
7416 arvif->vdev_id, ret);
7417 goto err_stop;
7418 }
7419
7420 arvif->is_up = true;
7421 }
7422
Bartosz Markowski83e48fc2016-12-15 11:23:24 +02007423 if (ath10k_mac_can_set_cts_prot(arvif)) {
7424 ret = ath10k_mac_set_cts_prot(arvif);
7425 if (ret)
7426 ath10k_warn(ar, "failed to set cts protection for vdev %d: %d\n",
7427 arvif->vdev_id, ret);
7428 }
7429
Michal Kazior500ff9f2015-03-31 10:26:21 +00007430 mutex_unlock(&ar->conf_mutex);
7431 return 0;
7432
7433err_stop:
7434 ath10k_vdev_stop(arvif);
7435 arvif->is_started = false;
Michal Kaziorf23e587e2015-07-09 13:08:37 +02007436 ath10k_mac_vif_setup_ps(arvif);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007437
7438err:
7439 mutex_unlock(&ar->conf_mutex);
7440 return ret;
7441}
7442
7443static void
7444ath10k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
7445 struct ieee80211_vif *vif,
7446 struct ieee80211_chanctx_conf *ctx)
7447{
7448 struct ath10k *ar = hw->priv;
7449 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7450 int ret;
7451
7452 mutex_lock(&ar->conf_mutex);
7453
7454 ath10k_dbg(ar, ATH10K_DBG_MAC,
Maharaja Kennadyrajan75b34802016-08-04 19:21:51 +05307455 "mac chanctx unassign ptr %pK vdev_id %i\n",
Michal Kazior500ff9f2015-03-31 10:26:21 +00007456 ctx, arvif->vdev_id);
7457
7458 WARN_ON(!arvif->is_started);
7459
7460 if (vif->type == NL80211_IFTYPE_MONITOR) {
7461 WARN_ON(!arvif->is_up);
7462
7463 ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
7464 if (ret)
7465 ath10k_warn(ar, "failed to down monitor vdev %i: %d\n",
7466 arvif->vdev_id, ret);
7467
7468 arvif->is_up = false;
7469 }
7470
7471 ret = ath10k_vdev_stop(arvif);
7472 if (ret)
7473 ath10k_warn(ar, "failed to stop vdev %i: %d\n",
7474 arvif->vdev_id, ret);
7475
7476 arvif->is_started = false;
7477
7478 mutex_unlock(&ar->conf_mutex);
7479}
7480
7481static int
7482ath10k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw,
7483 struct ieee80211_vif_chanctx_switch *vifs,
7484 int n_vifs,
7485 enum ieee80211_chanctx_switch_mode mode)
7486{
7487 struct ath10k *ar = hw->priv;
Michal Kazior500ff9f2015-03-31 10:26:21 +00007488
7489 mutex_lock(&ar->conf_mutex);
7490
7491 ath10k_dbg(ar, ATH10K_DBG_MAC,
7492 "mac chanctx switch n_vifs %d mode %d\n",
7493 n_vifs, mode);
Michal Kazior7be6d1b2015-09-03 10:44:51 +02007494 ath10k_mac_update_vif_chan(ar, vifs, n_vifs);
Michal Kazior500ff9f2015-03-31 10:26:21 +00007495
7496 mutex_unlock(&ar->conf_mutex);
7497 return 0;
7498}
7499
Michal Kazior874b5ac2017-01-12 16:14:30 +01007500static void ath10k_mac_op_sta_pre_rcu_remove(struct ieee80211_hw *hw,
7501 struct ieee80211_vif *vif,
7502 struct ieee80211_sta *sta)
7503{
7504 struct ath10k *ar;
7505 struct ath10k_peer *peer;
7506
7507 ar = hw->priv;
7508
7509 list_for_each_entry(peer, &ar->peers, list)
7510 if (peer->sta == sta)
7511 peer->removed = true;
7512}
7513
Kalle Valo5e3dd152013-06-12 20:52:10 +03007514static const struct ieee80211_ops ath10k_ops = {
Michal Kaziorf2f6eca2016-03-01 11:32:46 +01007515 .tx = ath10k_mac_op_tx,
Michal Kazior29946872016-03-06 16:14:34 +02007516 .wake_tx_queue = ath10k_mac_op_wake_tx_queue,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007517 .start = ath10k_start,
7518 .stop = ath10k_stop,
7519 .config = ath10k_config,
7520 .add_interface = ath10k_add_interface,
7521 .remove_interface = ath10k_remove_interface,
7522 .configure_filter = ath10k_configure_filter,
7523 .bss_info_changed = ath10k_bss_info_changed,
7524 .hw_scan = ath10k_hw_scan,
7525 .cancel_hw_scan = ath10k_cancel_hw_scan,
7526 .set_key = ath10k_set_key,
SenthilKumar Jegadeesan627613f2015-01-29 13:50:38 +02007527 .set_default_unicast_key = ath10k_set_default_unicast_key,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007528 .sta_state = ath10k_sta_state,
7529 .conf_tx = ath10k_conf_tx,
7530 .remain_on_channel = ath10k_remain_on_channel,
7531 .cancel_remain_on_channel = ath10k_cancel_remain_on_channel,
7532 .set_rts_threshold = ath10k_set_rts_threshold,
Michal Kazior92092fe2015-08-03 11:16:43 +02007533 .set_frag_threshold = ath10k_mac_op_set_frag_threshold,
Kalle Valo5e3dd152013-06-12 20:52:10 +03007534 .flush = ath10k_flush,
7535 .tx_last_beacon = ath10k_tx_last_beacon,
Ben Greear46acf7b2014-05-16 17:15:38 +03007536 .set_antenna = ath10k_set_antenna,
7537 .get_antenna = ath10k_get_antenna,
Eliad Pellercf2c92d2014-11-04 11:43:54 +02007538 .reconfig_complete = ath10k_reconfig_complete,
Michal Kazior2e1dea42013-07-31 10:32:40 +02007539 .get_survey = ath10k_get_survey,
Michal Kazior3ae54222015-03-31 10:49:20 +00007540 .set_bitrate_mask = ath10k_mac_op_set_bitrate_mask,
Michal Kazior9797feb2014-02-14 14:49:48 +01007541 .sta_rc_update = ath10k_sta_rc_update,
Chun-Yeow Yeoh26ebbcc2014-02-25 09:29:54 +02007542 .get_tsf = ath10k_get_tsf,
Peter Oh9f0b7e72016-04-04 16:19:14 -07007543 .set_tsf = ath10k_set_tsf,
Michal Kazioraa5b4fb2014-07-23 12:20:33 +02007544 .ampdu_action = ath10k_ampdu_action,
Ben Greear6cddcc72014-09-29 14:41:46 +03007545 .get_et_sset_count = ath10k_debug_get_et_sset_count,
7546 .get_et_stats = ath10k_debug_get_et_stats,
7547 .get_et_strings = ath10k_debug_get_et_strings,
Michal Kazior500ff9f2015-03-31 10:26:21 +00007548 .add_chanctx = ath10k_mac_op_add_chanctx,
7549 .remove_chanctx = ath10k_mac_op_remove_chanctx,
7550 .change_chanctx = ath10k_mac_op_change_chanctx,
7551 .assign_vif_chanctx = ath10k_mac_op_assign_vif_chanctx,
7552 .unassign_vif_chanctx = ath10k_mac_op_unassign_vif_chanctx,
7553 .switch_vif_chanctx = ath10k_mac_op_switch_vif_chanctx,
Michal Kazior874b5ac2017-01-12 16:14:30 +01007554 .sta_pre_rcu_remove = ath10k_mac_op_sta_pre_rcu_remove,
Kalle Valo43d2a302014-09-10 18:23:30 +03007555
7556 CFG80211_TESTMODE_CMD(ath10k_tm_cmd)
7557
Michal Kazior8cd13ca2013-07-16 09:38:54 +02007558#ifdef CONFIG_PM
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02007559 .suspend = ath10k_wow_op_suspend,
7560 .resume = ath10k_wow_op_resume,
Michal Kazior8cd13ca2013-07-16 09:38:54 +02007561#endif
Rajkumar Manoharanf5045982015-01-12 14:07:27 +02007562#ifdef CONFIG_MAC80211_DEBUGFS
7563 .sta_add_debugfs = ath10k_sta_add_debugfs,
Mohammed Shafi Shajakhan120a1f02016-06-30 15:23:50 +03007564 .sta_statistics = ath10k_sta_statistics,
Rajkumar Manoharanf5045982015-01-12 14:07:27 +02007565#endif
Kalle Valo5e3dd152013-06-12 20:52:10 +03007566};
7567
Kalle Valo5e3dd152013-06-12 20:52:10 +03007568#define CHAN2G(_channel, _freq, _flags) { \
Johannes Berg57fbcce2016-04-12 15:56:15 +02007569 .band = NL80211_BAND_2GHZ, \
Kalle Valo5e3dd152013-06-12 20:52:10 +03007570 .hw_value = (_channel), \
7571 .center_freq = (_freq), \
7572 .flags = (_flags), \
7573 .max_antenna_gain = 0, \
7574 .max_power = 30, \
7575}
7576
7577#define CHAN5G(_channel, _freq, _flags) { \
Johannes Berg57fbcce2016-04-12 15:56:15 +02007578 .band = NL80211_BAND_5GHZ, \
Kalle Valo5e3dd152013-06-12 20:52:10 +03007579 .hw_value = (_channel), \
7580 .center_freq = (_freq), \
7581 .flags = (_flags), \
7582 .max_antenna_gain = 0, \
7583 .max_power = 30, \
7584}
7585
7586static const struct ieee80211_channel ath10k_2ghz_channels[] = {
7587 CHAN2G(1, 2412, 0),
7588 CHAN2G(2, 2417, 0),
7589 CHAN2G(3, 2422, 0),
7590 CHAN2G(4, 2427, 0),
7591 CHAN2G(5, 2432, 0),
7592 CHAN2G(6, 2437, 0),
7593 CHAN2G(7, 2442, 0),
7594 CHAN2G(8, 2447, 0),
7595 CHAN2G(9, 2452, 0),
7596 CHAN2G(10, 2457, 0),
7597 CHAN2G(11, 2462, 0),
7598 CHAN2G(12, 2467, 0),
7599 CHAN2G(13, 2472, 0),
7600 CHAN2G(14, 2484, 0),
7601};
7602
7603static const struct ieee80211_channel ath10k_5ghz_channels[] = {
Michal Kazior429ff562013-06-26 08:54:54 +02007604 CHAN5G(36, 5180, 0),
7605 CHAN5G(40, 5200, 0),
7606 CHAN5G(44, 5220, 0),
7607 CHAN5G(48, 5240, 0),
7608 CHAN5G(52, 5260, 0),
7609 CHAN5G(56, 5280, 0),
7610 CHAN5G(60, 5300, 0),
7611 CHAN5G(64, 5320, 0),
7612 CHAN5G(100, 5500, 0),
7613 CHAN5G(104, 5520, 0),
7614 CHAN5G(108, 5540, 0),
7615 CHAN5G(112, 5560, 0),
7616 CHAN5G(116, 5580, 0),
7617 CHAN5G(120, 5600, 0),
7618 CHAN5G(124, 5620, 0),
7619 CHAN5G(128, 5640, 0),
7620 CHAN5G(132, 5660, 0),
7621 CHAN5G(136, 5680, 0),
7622 CHAN5G(140, 5700, 0),
Peter Oh4a7898f2015-03-18 11:39:18 -07007623 CHAN5G(144, 5720, 0),
Michal Kazior429ff562013-06-26 08:54:54 +02007624 CHAN5G(149, 5745, 0),
7625 CHAN5G(153, 5765, 0),
7626 CHAN5G(157, 5785, 0),
7627 CHAN5G(161, 5805, 0),
7628 CHAN5G(165, 5825, 0),
Kalle Valo5e3dd152013-06-12 20:52:10 +03007629};
7630
Michal Kaziore7b54192014-08-07 11:03:27 +02007631struct ath10k *ath10k_mac_create(size_t priv_size)
Kalle Valo5e3dd152013-06-12 20:52:10 +03007632{
7633 struct ieee80211_hw *hw;
Michal Kazior4ca18072016-07-18 23:22:18 +03007634 struct ieee80211_ops *ops;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007635 struct ath10k *ar;
7636
Michal Kazior4ca18072016-07-18 23:22:18 +03007637 ops = kmemdup(&ath10k_ops, sizeof(ath10k_ops), GFP_KERNEL);
7638 if (!ops)
Kalle Valo5e3dd152013-06-12 20:52:10 +03007639 return NULL;
7640
Michal Kazior4ca18072016-07-18 23:22:18 +03007641 hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, ops);
7642 if (!hw) {
7643 kfree(ops);
7644 return NULL;
7645 }
7646
Kalle Valo5e3dd152013-06-12 20:52:10 +03007647 ar = hw->priv;
7648 ar->hw = hw;
Michal Kazior4ca18072016-07-18 23:22:18 +03007649 ar->ops = ops;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007650
7651 return ar;
7652}
7653
7654void ath10k_mac_destroy(struct ath10k *ar)
7655{
Michal Kazior4ca18072016-07-18 23:22:18 +03007656 struct ieee80211_ops *ops = ar->ops;
7657
Kalle Valo5e3dd152013-06-12 20:52:10 +03007658 ieee80211_free_hw(ar->hw);
Michal Kazior4ca18072016-07-18 23:22:18 +03007659 kfree(ops);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007660}
7661
7662static const struct ieee80211_iface_limit ath10k_if_limits[] = {
7663 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307664 .max = 8,
7665 .types = BIT(NL80211_IFTYPE_STATION)
7666 | BIT(NL80211_IFTYPE_P2P_CLIENT)
Michal Kaziord531cb82013-07-31 10:55:13 +02007667 },
7668 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307669 .max = 3,
7670 .types = BIT(NL80211_IFTYPE_P2P_GO)
Michal Kaziord531cb82013-07-31 10:55:13 +02007671 },
7672 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307673 .max = 1,
7674 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
Michal Kazior75d2bd42014-12-12 12:41:39 +01007675 },
7676 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307677 .max = 7,
7678 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007679#ifdef CONFIG_MAC80211_MESH
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307680 | BIT(NL80211_IFTYPE_MESH_POINT)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007681#endif
Michal Kaziord531cb82013-07-31 10:55:13 +02007682 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03007683};
7684
Bartosz Markowskif2595092013-12-10 16:20:39 +01007685static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007686 {
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307687 .max = 8,
7688 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007689#ifdef CONFIG_MAC80211_MESH
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307690 | BIT(NL80211_IFTYPE_MESH_POINT)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007691#endif
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007692 },
Mohammed Shafi Shajakhan78f7aeb2015-11-21 15:24:41 +05307693 {
7694 .max = 1,
7695 .types = BIT(NL80211_IFTYPE_STATION)
7696 },
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007697};
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007698
7699static const struct ieee80211_iface_combination ath10k_if_comb[] = {
7700 {
7701 .limits = ath10k_if_limits,
7702 .n_limits = ARRAY_SIZE(ath10k_if_limits),
7703 .max_interfaces = 8,
7704 .num_different_channels = 1,
7705 .beacon_int_infra_match = true,
7706 },
Bartosz Markowskif2595092013-12-10 16:20:39 +01007707};
7708
7709static const struct ieee80211_iface_combination ath10k_10x_if_comb[] = {
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007710 {
Bartosz Markowskif2595092013-12-10 16:20:39 +01007711 .limits = ath10k_10x_if_limits,
7712 .n_limits = ARRAY_SIZE(ath10k_10x_if_limits),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007713 .max_interfaces = 8,
7714 .num_different_channels = 1,
7715 .beacon_int_infra_match = true,
Bartosz Markowskif2595092013-12-10 16:20:39 +01007716#ifdef CONFIG_ATH10K_DFS_CERTIFIED
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007717 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
7718 BIT(NL80211_CHAN_WIDTH_20) |
7719 BIT(NL80211_CHAN_WIDTH_40) |
7720 BIT(NL80211_CHAN_WIDTH_80),
Marek Puzyniake8a50f82013-11-20 09:59:47 +02007721#endif
Bartosz Markowskif2595092013-12-10 16:20:39 +01007722 },
Kalle Valo5e3dd152013-06-12 20:52:10 +03007723};
7724
Michal Kaziorcf327842015-03-31 10:26:25 +00007725static const struct ieee80211_iface_limit ath10k_tlv_if_limit[] = {
7726 {
7727 .max = 2,
Michal Kaziored25b112015-07-09 13:08:39 +02007728 .types = BIT(NL80211_IFTYPE_STATION),
7729 },
7730 {
7731 .max = 2,
7732 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007733#ifdef CONFIG_MAC80211_MESH
7734 BIT(NL80211_IFTYPE_MESH_POINT) |
7735#endif
Michal Kaziorcf327842015-03-31 10:26:25 +00007736 BIT(NL80211_IFTYPE_P2P_CLIENT) |
7737 BIT(NL80211_IFTYPE_P2P_GO),
7738 },
7739 {
7740 .max = 1,
7741 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
7742 },
7743};
7744
Michal Kaziored25b112015-07-09 13:08:39 +02007745static const struct ieee80211_iface_limit ath10k_tlv_qcs_if_limit[] = {
7746 {
7747 .max = 2,
7748 .types = BIT(NL80211_IFTYPE_STATION),
7749 },
7750 {
7751 .max = 2,
7752 .types = BIT(NL80211_IFTYPE_P2P_CLIENT),
7753 },
7754 {
7755 .max = 1,
7756 .types = BIT(NL80211_IFTYPE_AP) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007757#ifdef CONFIG_MAC80211_MESH
7758 BIT(NL80211_IFTYPE_MESH_POINT) |
7759#endif
Michal Kaziored25b112015-07-09 13:08:39 +02007760 BIT(NL80211_IFTYPE_P2P_GO),
7761 },
7762 {
7763 .max = 1,
7764 .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
7765 },
7766};
7767
Michal Kaziorcf327842015-03-31 10:26:25 +00007768static const struct ieee80211_iface_limit ath10k_tlv_if_limit_ibss[] = {
7769 {
7770 .max = 1,
7771 .types = BIT(NL80211_IFTYPE_STATION),
7772 },
7773 {
7774 .max = 1,
7775 .types = BIT(NL80211_IFTYPE_ADHOC),
7776 },
7777};
7778
7779/* FIXME: This is not thouroughly tested. These combinations may over- or
7780 * underestimate hw/fw capabilities.
7781 */
7782static struct ieee80211_iface_combination ath10k_tlv_if_comb[] = {
7783 {
7784 .limits = ath10k_tlv_if_limit,
7785 .num_different_channels = 1,
Michal Kaziored25b112015-07-09 13:08:39 +02007786 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00007787 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
7788 },
7789 {
7790 .limits = ath10k_tlv_if_limit_ibss,
7791 .num_different_channels = 1,
7792 .max_interfaces = 2,
7793 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
7794 },
7795};
7796
7797static struct ieee80211_iface_combination ath10k_tlv_qcs_if_comb[] = {
7798 {
7799 .limits = ath10k_tlv_if_limit,
Michal Kaziored25b112015-07-09 13:08:39 +02007800 .num_different_channels = 1,
7801 .max_interfaces = 4,
Michal Kaziorcf327842015-03-31 10:26:25 +00007802 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit),
7803 },
7804 {
Michal Kaziored25b112015-07-09 13:08:39 +02007805 .limits = ath10k_tlv_qcs_if_limit,
7806 .num_different_channels = 2,
7807 .max_interfaces = 4,
7808 .n_limits = ARRAY_SIZE(ath10k_tlv_qcs_if_limit),
7809 },
7810 {
Michal Kaziorcf327842015-03-31 10:26:25 +00007811 .limits = ath10k_tlv_if_limit_ibss,
7812 .num_different_channels = 1,
7813 .max_interfaces = 2,
7814 .n_limits = ARRAY_SIZE(ath10k_tlv_if_limit_ibss),
7815 },
7816};
7817
Raja Manicf36fef2015-06-22 20:22:25 +05307818static const struct ieee80211_iface_limit ath10k_10_4_if_limits[] = {
7819 {
7820 .max = 1,
7821 .types = BIT(NL80211_IFTYPE_STATION),
7822 },
7823 {
7824 .max = 16,
7825 .types = BIT(NL80211_IFTYPE_AP)
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007826#ifdef CONFIG_MAC80211_MESH
7827 | BIT(NL80211_IFTYPE_MESH_POINT)
7828#endif
Raja Manicf36fef2015-06-22 20:22:25 +05307829 },
7830};
7831
7832static const struct ieee80211_iface_combination ath10k_10_4_if_comb[] = {
7833 {
7834 .limits = ath10k_10_4_if_limits,
7835 .n_limits = ARRAY_SIZE(ath10k_10_4_if_limits),
7836 .max_interfaces = 16,
7837 .num_different_channels = 1,
7838 .beacon_int_infra_match = true,
7839#ifdef CONFIG_ATH10K_DFS_CERTIFIED
7840 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
7841 BIT(NL80211_CHAN_WIDTH_20) |
7842 BIT(NL80211_CHAN_WIDTH_40) |
7843 BIT(NL80211_CHAN_WIDTH_80),
7844#endif
7845 },
7846};
7847
Kalle Valo5e3dd152013-06-12 20:52:10 +03007848static void ath10k_get_arvif_iter(void *data, u8 *mac,
7849 struct ieee80211_vif *vif)
7850{
7851 struct ath10k_vif_iter *arvif_iter = data;
7852 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
7853
7854 if (arvif->vdev_id == arvif_iter->vdev_id)
7855 arvif_iter->arvif = arvif;
7856}
7857
7858struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id)
7859{
7860 struct ath10k_vif_iter arvif_iter;
7861 u32 flags;
7862
7863 memset(&arvif_iter, 0, sizeof(struct ath10k_vif_iter));
7864 arvif_iter.vdev_id = vdev_id;
7865
7866 flags = IEEE80211_IFACE_ITER_RESUME_ALL;
7867 ieee80211_iterate_active_interfaces_atomic(ar->hw,
7868 flags,
7869 ath10k_get_arvif_iter,
7870 &arvif_iter);
7871 if (!arvif_iter.arvif) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02007872 ath10k_warn(ar, "No VIF found for vdev %d\n", vdev_id);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007873 return NULL;
7874 }
7875
7876 return arvif_iter.arvif;
7877}
7878
7879int ath10k_mac_register(struct ath10k *ar)
7880{
Johannes Berg3cb10942015-01-22 21:38:45 +01007881 static const u32 cipher_suites[] = {
7882 WLAN_CIPHER_SUITE_WEP40,
7883 WLAN_CIPHER_SUITE_WEP104,
7884 WLAN_CIPHER_SUITE_TKIP,
7885 WLAN_CIPHER_SUITE_CCMP,
7886 WLAN_CIPHER_SUITE_AES_CMAC,
7887 };
Kalle Valo5e3dd152013-06-12 20:52:10 +03007888 struct ieee80211_supported_band *band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007889 void *channels;
7890 int ret;
7891
7892 SET_IEEE80211_PERM_ADDR(ar->hw, ar->mac_addr);
7893
7894 SET_IEEE80211_DEV(ar->hw, ar->dev);
7895
Michal Kaziorc94aa7e2015-03-24 12:38:11 +00007896 BUILD_BUG_ON((ARRAY_SIZE(ath10k_2ghz_channels) +
7897 ARRAY_SIZE(ath10k_5ghz_channels)) !=
7898 ATH10K_NUM_CHANS);
7899
Kalle Valo5e3dd152013-06-12 20:52:10 +03007900 if (ar->phy_capability & WHAL_WLAN_11G_CAPABILITY) {
7901 channels = kmemdup(ath10k_2ghz_channels,
7902 sizeof(ath10k_2ghz_channels),
7903 GFP_KERNEL);
Michal Kaziord6015b22013-07-22 14:13:30 +02007904 if (!channels) {
7905 ret = -ENOMEM;
7906 goto err_free;
7907 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03007908
Johannes Berg57fbcce2016-04-12 15:56:15 +02007909 band = &ar->mac.sbands[NL80211_BAND_2GHZ];
Kalle Valo5e3dd152013-06-12 20:52:10 +03007910 band->n_channels = ARRAY_SIZE(ath10k_2ghz_channels);
7911 band->channels = channels;
Mohammed Shafi Shajakhan5269c652016-06-07 15:47:04 +03007912
7913 if (ar->hw_params.cck_rate_map_rev2) {
7914 band->n_bitrates = ath10k_g_rates_rev2_size;
7915 band->bitrates = ath10k_g_rates_rev2;
7916 } else {
7917 band->n_bitrates = ath10k_g_rates_size;
7918 band->bitrates = ath10k_g_rates;
7919 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03007920
Johannes Berg57fbcce2016-04-12 15:56:15 +02007921 ar->hw->wiphy->bands[NL80211_BAND_2GHZ] = band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007922 }
7923
7924 if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY) {
7925 channels = kmemdup(ath10k_5ghz_channels,
7926 sizeof(ath10k_5ghz_channels),
7927 GFP_KERNEL);
7928 if (!channels) {
Michal Kaziord6015b22013-07-22 14:13:30 +02007929 ret = -ENOMEM;
7930 goto err_free;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007931 }
7932
Johannes Berg57fbcce2016-04-12 15:56:15 +02007933 band = &ar->mac.sbands[NL80211_BAND_5GHZ];
Kalle Valo5e3dd152013-06-12 20:52:10 +03007934 band->n_channels = ARRAY_SIZE(ath10k_5ghz_channels);
7935 band->channels = channels;
7936 band->n_bitrates = ath10k_a_rates_size;
7937 band->bitrates = ath10k_a_rates;
Johannes Berg57fbcce2016-04-12 15:56:15 +02007938 ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007939 }
7940
Rajkumar Manoharan5036fe02015-10-27 17:51:14 +05307941 ath10k_mac_setup_ht_vht_cap(ar);
7942
Kalle Valo5e3dd152013-06-12 20:52:10 +03007943 ar->hw->wiphy->interface_modes =
7944 BIT(NL80211_IFTYPE_STATION) |
Bob Copelandb6c7baf2015-09-09 12:47:36 -04007945 BIT(NL80211_IFTYPE_AP) |
7946 BIT(NL80211_IFTYPE_MESH_POINT);
Bartosz Markowskid3541812013-12-10 16:20:40 +01007947
Rajkumar Manoharan166de3f2015-10-27 17:51:11 +05307948 ar->hw->wiphy->available_antennas_rx = ar->cfg_rx_chainmask;
7949 ar->hw->wiphy->available_antennas_tx = ar->cfg_tx_chainmask;
Ben Greear46acf7b2014-05-16 17:15:38 +03007950
Kalle Valoc4cdf752016-04-20 19:45:18 +03007951 if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->normal_mode_fw.fw_file.fw_features))
Bartosz Markowskid3541812013-12-10 16:20:40 +01007952 ar->hw->wiphy->interface_modes |=
Michal Kazior75d2bd42014-12-12 12:41:39 +01007953 BIT(NL80211_IFTYPE_P2P_DEVICE) |
Bartosz Markowskid3541812013-12-10 16:20:40 +01007954 BIT(NL80211_IFTYPE_P2P_CLIENT) |
7955 BIT(NL80211_IFTYPE_P2P_GO);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007956
Johannes Berg30686bf2015-06-02 21:39:54 +02007957 ieee80211_hw_set(ar->hw, SIGNAL_DBM);
7958 ieee80211_hw_set(ar->hw, SUPPORTS_PS);
7959 ieee80211_hw_set(ar->hw, SUPPORTS_DYNAMIC_PS);
7960 ieee80211_hw_set(ar->hw, MFP_CAPABLE);
7961 ieee80211_hw_set(ar->hw, REPORTS_TX_ACK_STATUS);
7962 ieee80211_hw_set(ar->hw, HAS_RATE_CONTROL);
7963 ieee80211_hw_set(ar->hw, AP_LINK_PS);
7964 ieee80211_hw_set(ar->hw, SPECTRUM_MGMT);
Johannes Berg30686bf2015-06-02 21:39:54 +02007965 ieee80211_hw_set(ar->hw, SUPPORT_FAST_XMIT);
7966 ieee80211_hw_set(ar->hw, CONNECTION_MONITOR);
7967 ieee80211_hw_set(ar->hw, SUPPORTS_PER_STA_GTK);
7968 ieee80211_hw_set(ar->hw, WANT_MONITOR_VIF);
7969 ieee80211_hw_set(ar->hw, CHANCTX_STA_CSA);
7970 ieee80211_hw_set(ar->hw, QUEUE_CONTROL);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007971
David Liuccec9032015-07-24 20:25:32 +03007972 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
7973 ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL);
7974
Eliad Peller0d8614b2014-09-10 14:07:36 +03007975 ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS;
Janusz Dziedzic0cd9bc12015-04-10 13:23:23 +00007976 ar->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
Eliad Peller0d8614b2014-09-10 14:07:36 +03007977
Kalle Valo5e3dd152013-06-12 20:52:10 +03007978 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS)
Eliad Peller0d8614b2014-09-10 14:07:36 +03007979 ar->hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS;
Kalle Valo5e3dd152013-06-12 20:52:10 +03007980
7981 if (ar->ht_cap_info & WMI_HT_CAP_ENABLED) {
Johannes Berg30686bf2015-06-02 21:39:54 +02007982 ieee80211_hw_set(ar->hw, AMPDU_AGGREGATION);
7983 ieee80211_hw_set(ar->hw, TX_AMPDU_SETUP_IN_HW);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007984 }
7985
7986 ar->hw->wiphy->max_scan_ssids = WLAN_SCAN_PARAMS_MAX_SSID;
7987 ar->hw->wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN;
7988
7989 ar->hw->vif_data_size = sizeof(struct ath10k_vif);
Michal Kazior9797feb2014-02-14 14:49:48 +01007990 ar->hw->sta_data_size = sizeof(struct ath10k_sta);
Michal Kazior29946872016-03-06 16:14:34 +02007991 ar->hw->txq_data_size = sizeof(struct ath10k_txq);
Kalle Valo5e3dd152013-06-12 20:52:10 +03007992
Kalle Valo5e3dd152013-06-12 20:52:10 +03007993 ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL;
7994
Michal Kaziorfbb8f1b2015-01-13 16:30:12 +02007995 if (test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)) {
7996 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
7997
7998 /* Firmware delivers WPS/P2P Probe Requests frames to driver so
7999 * that userspace (e.g. wpa_supplicant/hostapd) can generate
8000 * correct Probe Responses. This is more of a hack advert..
8001 */
8002 ar->hw->wiphy->probe_resp_offload |=
8003 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
8004 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
8005 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
8006 }
8007
Marek Puzyniak75d85fd2015-03-30 09:51:53 +03008008 if (test_bit(WMI_SERVICE_TDLS, ar->wmi.svc_map))
8009 ar->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
8010
Kalle Valo5e3dd152013-06-12 20:52:10 +03008011 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Michal Kaziorc2df44b2014-01-23 11:38:26 +01008012 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008013 ar->hw->wiphy->max_remain_on_channel_duration = 5000;
8014
8015 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
Vasanthakumar Thiagarajanbf031bc2016-03-15 15:25:53 +05308016 ar->hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |
8017 NL80211_FEATURE_AP_SCAN;
Rajkumar Manoharan78157a12014-11-17 16:44:15 +02008018
Janusz.Dziedzic@tieto.com37a0b392015-03-12 13:11:41 +01008019 ar->hw->wiphy->max_ap_assoc_sta = ar->max_num_stations;
8020
Janusz Dziedzic5fd3ac32015-03-23 17:32:53 +02008021 ret = ath10k_wow_init(ar);
8022 if (ret) {
8023 ath10k_warn(ar, "failed to init wow: %d\n", ret);
8024 goto err_free;
8025 }
8026
Janusz Dziedzicc7025342015-06-15 14:46:41 +03008027 wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
8028
Kalle Valo5e3dd152013-06-12 20:52:10 +03008029 /*
8030 * on LL hardware queues are managed entirely by the FW
8031 * so we only advertise to mac we can do the queues thing
8032 */
Michal Kazior96d828d2015-03-31 10:26:23 +00008033 ar->hw->queues = IEEE80211_MAX_QUEUES;
8034
8035 /* vdev_ids are used as hw queue numbers. Make sure offchan tx queue is
8036 * something that vdev_ids can't reach so that we don't stop the queue
8037 * accidentally.
8038 */
8039 ar->hw->offchannel_tx_hw_queue = IEEE80211_MAX_QUEUES - 1;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008040
Kalle Valobf3c13a2016-04-20 19:45:33 +03008041 switch (ar->running_fw->fw_file.wmi_op_version) {
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008042 case ATH10K_FW_WMI_OP_VERSION_MAIN:
Bartosz Markowskif2595092013-12-10 16:20:39 +01008043 ar->hw->wiphy->iface_combinations = ath10k_if_comb;
8044 ar->hw->wiphy->n_iface_combinations =
8045 ARRAY_SIZE(ath10k_if_comb);
Michal Kaziorcf850d12014-07-24 20:07:00 +03008046 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008047 break;
Michal Kaziorcf327842015-03-31 10:26:25 +00008048 case ATH10K_FW_WMI_OP_VERSION_TLV:
8049 if (test_bit(WMI_SERVICE_ADAPTIVE_OCS, ar->wmi.svc_map)) {
8050 ar->hw->wiphy->iface_combinations =
8051 ath10k_tlv_qcs_if_comb;
8052 ar->hw->wiphy->n_iface_combinations =
8053 ARRAY_SIZE(ath10k_tlv_qcs_if_comb);
8054 } else {
8055 ar->hw->wiphy->iface_combinations = ath10k_tlv_if_comb;
8056 ar->hw->wiphy->n_iface_combinations =
8057 ARRAY_SIZE(ath10k_tlv_if_comb);
8058 }
8059 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
8060 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008061 case ATH10K_FW_WMI_OP_VERSION_10_1:
8062 case ATH10K_FW_WMI_OP_VERSION_10_2:
Rajkumar Manoharan4a16fbe2014-12-17 12:21:12 +02008063 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008064 ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb;
8065 ar->hw->wiphy->n_iface_combinations =
8066 ARRAY_SIZE(ath10k_10x_if_comb);
8067 break;
Raja Mani9bd21322015-06-22 20:10:09 +05308068 case ATH10K_FW_WMI_OP_VERSION_10_4:
Raja Manicf36fef2015-06-22 20:22:25 +05308069 ar->hw->wiphy->iface_combinations = ath10k_10_4_if_comb;
8070 ar->hw->wiphy->n_iface_combinations =
8071 ARRAY_SIZE(ath10k_10_4_if_comb);
Raja Mani9bd21322015-06-22 20:10:09 +05308072 break;
Kalle Valo5cc7caf2014-12-17 12:20:54 +02008073 case ATH10K_FW_WMI_OP_VERSION_UNSET:
8074 case ATH10K_FW_WMI_OP_VERSION_MAX:
8075 WARN_ON(1);
8076 ret = -EINVAL;
8077 goto err_free;
Bartosz Markowskif2595092013-12-10 16:20:39 +01008078 }
Kalle Valo5e3dd152013-06-12 20:52:10 +03008079
David Liuccec9032015-07-24 20:25:32 +03008080 if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))
8081 ar->hw->netdev_features = NETIF_F_HW_CSUM;
Michal Kazior7c199992013-07-31 10:47:57 +02008082
Masahiro Yamada97f26452016-08-03 13:45:50 -07008083 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED)) {
Janusz Dziedzic9702c682013-11-20 09:59:41 +02008084 /* Init ath dfs pattern detector */
8085 ar->ath_common.debug_mask = ATH_DBG_DFS;
8086 ar->dfs_detector = dfs_pattern_detector_init(&ar->ath_common,
8087 NL80211_DFS_UNSET);
8088
8089 if (!ar->dfs_detector)
Michal Kazior7aa7a722014-08-25 12:09:38 +02008090 ath10k_warn(ar, "failed to initialise DFS pattern detector\n");
Janusz Dziedzic9702c682013-11-20 09:59:41 +02008091 }
8092
Michal Kazior4ca18072016-07-18 23:22:18 +03008093 /* Current wake_tx_queue implementation imposes a significant
8094 * performance penalty in some setups. The tx scheduling code needs
8095 * more work anyway so disable the wake_tx_queue unless firmware
8096 * supports the pull-push mechanism.
8097 */
8098 if (!test_bit(ATH10K_FW_FEATURE_PEER_FLOW_CONTROL,
8099 ar->running_fw->fw_file.fw_features))
8100 ar->ops->wake_tx_queue = NULL;
8101
Kalle Valo5e3dd152013-06-12 20:52:10 +03008102 ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy,
8103 ath10k_reg_notifier);
8104 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02008105 ath10k_err(ar, "failed to initialise regulatory: %i\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07008106 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008107 }
8108
Johannes Berg3cb10942015-01-22 21:38:45 +01008109 ar->hw->wiphy->cipher_suites = cipher_suites;
8110 ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
8111
Kalle Valo5e3dd152013-06-12 20:52:10 +03008112 ret = ieee80211_register_hw(ar->hw);
8113 if (ret) {
Michal Kazior7aa7a722014-08-25 12:09:38 +02008114 ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
Jeff Johnson0e339442015-10-08 09:15:53 -07008115 goto err_dfs_detector_exit;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008116 }
8117
8118 if (!ath_is_world_regd(&ar->ath_common.regulatory)) {
8119 ret = regulatory_hint(ar->hw->wiphy,
8120 ar->ath_common.regulatory.alpha2);
8121 if (ret)
Michal Kaziord6015b22013-07-22 14:13:30 +02008122 goto err_unregister;
Kalle Valo5e3dd152013-06-12 20:52:10 +03008123 }
8124
8125 return 0;
Michal Kaziord6015b22013-07-22 14:13:30 +02008126
8127err_unregister:
Kalle Valo5e3dd152013-06-12 20:52:10 +03008128 ieee80211_unregister_hw(ar->hw);
Jeff Johnson0e339442015-10-08 09:15:53 -07008129
8130err_dfs_detector_exit:
Masahiro Yamada97f26452016-08-03 13:45:50 -07008131 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
Jeff Johnson0e339442015-10-08 09:15:53 -07008132 ar->dfs_detector->exit(ar->dfs_detector);
8133
Michal Kaziord6015b22013-07-22 14:13:30 +02008134err_free:
Johannes Berg57fbcce2016-04-12 15:56:15 +02008135 kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
8136 kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
Michal Kaziord6015b22013-07-22 14:13:30 +02008137
Jeff Johnson0e339442015-10-08 09:15:53 -07008138 SET_IEEE80211_DEV(ar->hw, NULL);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008139 return ret;
8140}
8141
8142void ath10k_mac_unregister(struct ath10k *ar)
8143{
8144 ieee80211_unregister_hw(ar->hw);
8145
Masahiro Yamada97f26452016-08-03 13:45:50 -07008146 if (IS_ENABLED(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector)
Janusz Dziedzic9702c682013-11-20 09:59:41 +02008147 ar->dfs_detector->exit(ar->dfs_detector);
8148
Johannes Berg57fbcce2016-04-12 15:56:15 +02008149 kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
8150 kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
Kalle Valo5e3dd152013-06-12 20:52:10 +03008151
8152 SET_IEEE80211_DEV(ar->hw, NULL);
8153}