ath9k: make rfkill configurable
[deliverable/linux.git] / drivers / net / wireless / ath / ath9k / htc_drv_main.c
CommitLineData
fb9987d0 1/*
5b68138e 2 * Copyright (c) 2010-2011 Atheros Communications Inc.
fb9987d0
S
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "htc.h"
18
fb9987d0
S
19/*************/
20/* Utilities */
21/*************/
22
fb9987d0
S
23/* HACK Alert: Use 11NG for 2.4, use 11NA for 5 */
24static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv,
25 struct ath9k_channel *ichan)
26{
27 enum htc_phymode mode;
28
c75197a7 29 mode = -EINVAL;
fb9987d0
S
30
31 switch (ichan->chanmode) {
32 case CHANNEL_G:
33 case CHANNEL_G_HT20:
34 case CHANNEL_G_HT40PLUS:
35 case CHANNEL_G_HT40MINUS:
36 mode = HTC_MODE_11NG;
37 break;
38 case CHANNEL_A:
39 case CHANNEL_A_HT20:
40 case CHANNEL_A_HT40PLUS:
41 case CHANNEL_A_HT40MINUS:
42 mode = HTC_MODE_11NA;
43 break;
44 default:
45 break;
46 }
47
c75197a7
SM
48 WARN_ON(mode < 0);
49
fb9987d0
S
50 return mode;
51}
52
f933ebed
SM
53bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
54 enum ath9k_power_mode mode)
bde748a4
VN
55{
56 bool ret;
57
58 mutex_lock(&priv->htc_pm_lock);
59 ret = ath9k_hw_setpower(priv->ah, mode);
60 mutex_unlock(&priv->htc_pm_lock);
61
62 return ret;
63}
64
65void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv)
66{
67 mutex_lock(&priv->htc_pm_lock);
68 if (++priv->ps_usecount != 1)
69 goto unlock;
70 ath9k_hw_setpower(priv->ah, ATH9K_PM_AWAKE);
71
72unlock:
73 mutex_unlock(&priv->htc_pm_lock);
74}
75
76void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv)
77{
6bcfe67f
SM
78 bool reset;
79
bde748a4
VN
80 mutex_lock(&priv->htc_pm_lock);
81 if (--priv->ps_usecount != 0)
82 goto unlock;
83
6bcfe67f
SM
84 if (priv->ps_idle) {
85 ath9k_hw_setrxabort(priv->ah, true);
86 ath9k_hw_stopdmarecv(priv->ah, &reset);
8a8572a8 87 ath9k_hw_setpower(priv->ah, ATH9K_PM_FULL_SLEEP);
6bcfe67f 88 } else if (priv->ps_enabled) {
bde748a4 89 ath9k_hw_setpower(priv->ah, ATH9K_PM_NETWORK_SLEEP);
6bcfe67f 90 }
8a8572a8 91
bde748a4
VN
92unlock:
93 mutex_unlock(&priv->htc_pm_lock);
94}
95
96void ath9k_ps_work(struct work_struct *work)
97{
98 struct ath9k_htc_priv *priv =
99 container_of(work, struct ath9k_htc_priv,
100 ps_work);
101 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
102
103 /* The chip wakes up after receiving the first beacon
104 while network sleep is enabled. For the driver to
105 be in sync with the hw, set the chip to awake and
106 only then set it to sleep.
107 */
108 ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP);
109}
110
7c277349
SM
111static void ath9k_htc_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
112{
113 struct ath9k_htc_priv *priv = data;
114 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
115
594e65b6
JC
116 if ((vif->type == NL80211_IFTYPE_AP ||
117 vif->type == NL80211_IFTYPE_MESH_POINT) &&
118 bss_conf->enable_beacon)
a5fae37d
SM
119 priv->reconfig_beacon = true;
120
7c277349
SM
121 if (bss_conf->assoc) {
122 priv->rearm_ani = true;
123 priv->reconfig_beacon = true;
124 }
125}
126
127static void ath9k_htc_vif_reconfig(struct ath9k_htc_priv *priv)
128{
129 priv->rearm_ani = false;
130 priv->reconfig_beacon = false;
131
8b2c9824
JB
132 ieee80211_iterate_active_interfaces_atomic(
133 priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
134 ath9k_htc_vif_iter, priv);
7c277349 135 if (priv->rearm_ani)
a236254c 136 ath9k_htc_start_ani(priv);
7c277349
SM
137
138 if (priv->reconfig_beacon) {
139 ath9k_htc_ps_wakeup(priv);
140 ath9k_htc_beacon_reconfig(priv);
141 ath9k_htc_ps_restore(priv);
142 }
143}
144
585895cd
SM
145static void ath9k_htc_bssid_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
146{
147 struct ath9k_vif_iter_data *iter_data = data;
148 int i;
149
150 for (i = 0; i < ETH_ALEN; i++)
151 iter_data->mask[i] &= ~(iter_data->hw_macaddr[i] ^ mac[i]);
152}
153
154static void ath9k_htc_set_bssid_mask(struct ath9k_htc_priv *priv,
155 struct ieee80211_vif *vif)
156{
157 struct ath_common *common = ath9k_hw_common(priv->ah);
158 struct ath9k_vif_iter_data iter_data;
159
160 /*
161 * Use the hardware MAC address as reference, the hardware uses it
162 * together with the BSSID mask when matching addresses.
163 */
164 iter_data.hw_macaddr = common->macaddr;
165 memset(&iter_data.mask, 0xff, ETH_ALEN);
166
167 if (vif)
168 ath9k_htc_bssid_iter(&iter_data, vif->addr, vif);
169
170 /* Get list of all active MAC addresses */
8b2c9824
JB
171 ieee80211_iterate_active_interfaces_atomic(
172 priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
173 ath9k_htc_bssid_iter, &iter_data);
585895cd
SM
174
175 memcpy(common->bssidmask, iter_data.mask, ETH_ALEN);
176 ath_hw_setbssidmask(common);
177}
178
ffbe7c83
SM
179static void ath9k_htc_set_opmode(struct ath9k_htc_priv *priv)
180{
181 if (priv->num_ibss_vif)
182 priv->ah->opmode = NL80211_IFTYPE_ADHOC;
183 else if (priv->num_ap_vif)
184 priv->ah->opmode = NL80211_IFTYPE_AP;
594e65b6
JC
185 else if (priv->num_mbss_vif)
186 priv->ah->opmode = NL80211_IFTYPE_MESH_POINT;
ffbe7c83
SM
187 else
188 priv->ah->opmode = NL80211_IFTYPE_STATION;
189
190 ath9k_hw_setopmode(priv->ah);
191}
192
73908674
SM
193void ath9k_htc_reset(struct ath9k_htc_priv *priv)
194{
195 struct ath_hw *ah = priv->ah;
196 struct ath_common *common = ath9k_hw_common(ah);
675a0b04 197 struct ieee80211_channel *channel = priv->hw->conf.chandef.chan;
4e3ae387 198 struct ath9k_hw_cal_data *caldata = NULL;
73908674
SM
199 enum htc_phymode mode;
200 __be16 htc_mode;
201 u8 cmd_rsp;
202 int ret;
203
204 mutex_lock(&priv->mutex);
205 ath9k_htc_ps_wakeup(priv);
206
a236254c 207 ath9k_htc_stop_ani(priv);
73908674 208 ieee80211_stop_queues(priv->hw);
b587fc81 209
859c3ca1 210 del_timer_sync(&priv->tx.cleanup_timer);
b587fc81
SM
211 ath9k_htc_tx_drain(priv);
212
73908674
SM
213 WMI_CMD(WMI_DISABLE_INTR_CMDID);
214 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
215 WMI_CMD(WMI_STOP_RECV_CMDID);
216
f4c88991
SM
217 ath9k_wmi_event_drain(priv);
218
4e3ae387 219 caldata = &priv->caldata;
73908674
SM
220 ret = ath9k_hw_reset(ah, ah->curchan, caldata, false);
221 if (ret) {
222 ath_err(common,
223 "Unable to reset device (%u Mhz) reset status %d\n",
224 channel->center_freq, ret);
225 }
226
b2a5c3df
RM
227 ath9k_cmn_update_txpow(ah, priv->curtxpow, priv->txpowlimit,
228 &priv->curtxpow);
73908674
SM
229
230 WMI_CMD(WMI_START_RECV_CMDID);
231 ath9k_host_rx_init(priv);
232
233 mode = ath9k_htc_get_curmode(priv, ah->curchan);
234 htc_mode = cpu_to_be16(mode);
235 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
236
237 WMI_CMD(WMI_ENABLE_INTR_CMDID);
238 htc_start(priv->htc);
7c277349 239 ath9k_htc_vif_reconfig(priv);
73908674
SM
240 ieee80211_wake_queues(priv->hw);
241
859c3ca1
SM
242 mod_timer(&priv->tx.cleanup_timer,
243 jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
244
73908674
SM
245 ath9k_htc_ps_restore(priv);
246 mutex_unlock(&priv->mutex);
247}
248
fb9987d0
S
249static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
250 struct ieee80211_hw *hw,
251 struct ath9k_channel *hchan)
252{
253 struct ath_hw *ah = priv->ah;
254 struct ath_common *common = ath9k_hw_common(ah);
255 struct ieee80211_conf *conf = &common->hw->conf;
039a0721 256 bool fastcc;
675a0b04 257 struct ieee80211_channel *channel = hw->conf.chandef.chan;
8354dd3e 258 struct ath9k_hw_cal_data *caldata = NULL;
fb9987d0 259 enum htc_phymode mode;
7f1f5a00 260 __be16 htc_mode;
fb9987d0
S
261 u8 cmd_rsp;
262 int ret;
263
d8a2c51c 264 if (test_bit(OP_INVALID, &priv->op_flags))
fb9987d0
S
265 return -EIO;
266
039a0721 267 fastcc = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL);
fb9987d0 268
bde748a4 269 ath9k_htc_ps_wakeup(priv);
b587fc81 270
859c3ca1 271 del_timer_sync(&priv->tx.cleanup_timer);
b587fc81
SM
272 ath9k_htc_tx_drain(priv);
273
fb9987d0
S
274 WMI_CMD(WMI_DISABLE_INTR_CMDID);
275 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
276 WMI_CMD(WMI_STOP_RECV_CMDID);
277
f4c88991
SM
278 ath9k_wmi_event_drain(priv);
279
d2182b69 280 ath_dbg(common, CONFIG,
226afe68
JP
281 "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n",
282 priv->ah->curchan->channel,
283 channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf),
284 fastcc);
fb9987d0 285
4e3ae387
RM
286 if (!fastcc)
287 caldata = &priv->caldata;
b587fc81 288
20bd2a09 289 ret = ath9k_hw_reset(ah, hchan, caldata, fastcc);
fb9987d0 290 if (ret) {
3800276a
JP
291 ath_err(common,
292 "Unable to reset channel (%u Mhz) reset status %d\n",
293 channel->center_freq, ret);
fb9987d0
S
294 goto err;
295 }
296
b2a5c3df
RM
297 ath9k_cmn_update_txpow(ah, priv->curtxpow, priv->txpowlimit,
298 &priv->curtxpow);
fb9987d0
S
299
300 WMI_CMD(WMI_START_RECV_CMDID);
301 if (ret)
302 goto err;
303
304 ath9k_host_rx_init(priv);
305
306 mode = ath9k_htc_get_curmode(priv, hchan);
307 htc_mode = cpu_to_be16(mode);
308 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
309 if (ret)
310 goto err;
311
312 WMI_CMD(WMI_ENABLE_INTR_CMDID);
313 if (ret)
314 goto err;
315
316 htc_start(priv->htc);
a5fae37d 317
d8a2c51c 318 if (!test_bit(OP_SCANNING, &priv->op_flags) &&
a5fae37d
SM
319 !(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL))
320 ath9k_htc_vif_reconfig(priv);
321
859c3ca1
SM
322 mod_timer(&priv->tx.cleanup_timer,
323 jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
324
fb9987d0 325err:
bde748a4 326 ath9k_htc_ps_restore(priv);
fb9987d0
S
327 return ret;
328}
329
a97b478c
SM
330/*
331 * Monitor mode handling is a tad complicated because the firmware requires
332 * an interface to be created exclusively, while mac80211 doesn't associate
333 * an interface with the mode.
334 *
335 * So, for now, only one monitor interface can be configured.
336 */
cc721287
SM
337static void __ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
338{
339 struct ath_common *common = ath9k_hw_common(priv->ah);
340 struct ath9k_htc_target_vif hvif;
341 int ret = 0;
342 u8 cmd_rsp;
343
344 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
345 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
a97b478c 346 hvif.index = priv->mon_vif_idx;
cc721287 347 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
0ff2b5c0
SM
348 if (ret) {
349 ath_err(common, "Unable to remove monitor interface at idx: %d\n",
350 priv->mon_vif_idx);
351 }
352
cc721287 353 priv->nvifs--;
a97b478c 354 priv->vif_slot &= ~(1 << priv->mon_vif_idx);
cc721287
SM
355}
356
81fc2a33
RM
357static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
358{
359 struct ath_common *common = ath9k_hw_common(priv->ah);
360 struct ath9k_htc_target_vif hvif;
cc721287 361 struct ath9k_htc_target_sta tsta;
a97b478c 362 int ret = 0, sta_idx;
81fc2a33
RM
363 u8 cmd_rsp;
364
a97b478c
SM
365 if ((priv->nvifs >= ATH9K_HTC_MAX_VIF) ||
366 (priv->nstations >= ATH9K_HTC_MAX_STA)) {
367 ret = -ENOBUFS;
368 goto err_vif;
369 }
81fc2a33 370
a97b478c
SM
371 sta_idx = ffz(priv->sta_slot);
372 if ((sta_idx < 0) || (sta_idx > ATH9K_HTC_MAX_STA)) {
373 ret = -ENOBUFS;
374 goto err_vif;
375 }
cc721287
SM
376
377 /*
378 * Add an interface.
379 */
81fc2a33
RM
380 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
381 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
382
e4c62506 383 hvif.opmode = HTC_M_MONITOR;
a97b478c 384 hvif.index = ffz(priv->vif_slot);
81fc2a33
RM
385
386 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
387 if (ret)
a97b478c
SM
388 goto err_vif;
389
390 /*
391 * Assign the monitor interface index as a special case here.
392 * This is needed when the interface is brought down.
393 */
394 priv->mon_vif_idx = hvif.index;
395 priv->vif_slot |= (1 << hvif.index);
396
397 /*
398 * Set the hardware mode to monitor only if there are no
399 * other interfaces.
400 */
401 if (!priv->nvifs)
402 priv->ah->opmode = NL80211_IFTYPE_MONITOR;
81fc2a33
RM
403
404 priv->nvifs++;
cc721287
SM
405
406 /*
407 * Associate a station with the interface for packet injection.
408 */
cc721287
SM
409 memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta));
410
411 memcpy(&tsta.macaddr, common->macaddr, ETH_ALEN);
412
413 tsta.is_vif_sta = 1;
a97b478c 414 tsta.sta_index = sta_idx;
cc721287 415 tsta.vif_index = hvif.index;
b97c57ff 416 tsta.maxampdu = cpu_to_be16(0xffff);
cc721287
SM
417
418 WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
419 if (ret) {
420 ath_err(common, "Unable to add station entry for monitor mode\n");
a97b478c 421 goto err_sta;
cc721287
SM
422 }
423
a97b478c 424 priv->sta_slot |= (1 << sta_idx);
cc721287 425 priv->nstations++;
a97b478c 426 priv->vif_sta_pos[priv->mon_vif_idx] = sta_idx;
55de80d6
SM
427 priv->ah->is_monitoring = true;
428
d2182b69 429 ath_dbg(common, CONFIG,
a97b478c
SM
430 "Attached a monitor interface at idx: %d, sta idx: %d\n",
431 priv->mon_vif_idx, sta_idx);
432
81fc2a33 433 return 0;
cc721287 434
a97b478c 435err_sta:
cc721287
SM
436 /*
437 * Remove the interface from the target.
438 */
439 __ath9k_htc_remove_monitor_interface(priv);
a97b478c 440err_vif:
d2182b69 441 ath_dbg(common, FATAL, "Unable to attach a monitor interface\n");
a97b478c 442
cc721287 443 return ret;
81fc2a33
RM
444}
445
446static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
447{
448 struct ath_common *common = ath9k_hw_common(priv->ah);
81fc2a33 449 int ret = 0;
cc721287 450 u8 cmd_rsp, sta_idx;
81fc2a33 451
cc721287 452 __ath9k_htc_remove_monitor_interface(priv);
81fc2a33 453
a97b478c 454 sta_idx = priv->vif_sta_pos[priv->mon_vif_idx];
cc721287
SM
455
456 WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx);
457 if (ret) {
458 ath_err(common, "Unable to remove station entry for monitor mode\n");
459 return ret;
460 }
461
a97b478c 462 priv->sta_slot &= ~(1 << sta_idx);
cc721287 463 priv->nstations--;
55de80d6 464 priv->ah->is_monitoring = false;
cc721287 465
d2182b69 466 ath_dbg(common, CONFIG,
a97b478c
SM
467 "Removed a monitor interface at idx: %d, sta idx: %d\n",
468 priv->mon_vif_idx, sta_idx);
469
cc721287 470 return 0;
81fc2a33
RM
471}
472
fb9987d0
S
473static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
474 struct ieee80211_vif *vif,
475 struct ieee80211_sta *sta)
476{
477 struct ath_common *common = ath9k_hw_common(priv->ah);
478 struct ath9k_htc_target_sta tsta;
479 struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
480 struct ath9k_htc_sta *ista;
a97b478c 481 int ret, sta_idx;
fb9987d0 482 u8 cmd_rsp;
f0dd4980 483 u16 maxampdu;
fb9987d0
S
484
485 if (priv->nstations >= ATH9K_HTC_MAX_STA)
486 return -ENOBUFS;
487
a97b478c
SM
488 sta_idx = ffz(priv->sta_slot);
489 if ((sta_idx < 0) || (sta_idx > ATH9K_HTC_MAX_STA))
490 return -ENOBUFS;
491
fb9987d0
S
492 memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta));
493
494 if (sta) {
495 ista = (struct ath9k_htc_sta *) sta->drv_priv;
496 memcpy(&tsta.macaddr, sta->addr, ETH_ALEN);
497 memcpy(&tsta.bssid, common->curbssid, ETH_ALEN);
a97b478c 498 ista->index = sta_idx;
fed27f6f
MSS
499 tsta.is_vif_sta = 0;
500 maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
501 sta->ht_cap.ampdu_factor);
502 tsta.maxampdu = cpu_to_be16(maxampdu);
fb9987d0
S
503 } else {
504 memcpy(&tsta.macaddr, vif->addr, ETH_ALEN);
505 tsta.is_vif_sta = 1;
fed27f6f 506 tsta.maxampdu = cpu_to_be16(0xffff);
fb9987d0
S
507 }
508
a97b478c 509 tsta.sta_index = sta_idx;
fb9987d0 510 tsta.vif_index = avp->index;
f0dd4980 511
fb9987d0
S
512 WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
513 if (ret) {
514 if (sta)
3800276a
JP
515 ath_err(common,
516 "Unable to add station entry for: %pM\n",
517 sta->addr);
fb9987d0
S
518 return ret;
519 }
520
a97b478c 521 if (sta) {
d2182b69 522 ath_dbg(common, CONFIG,
226afe68
JP
523 "Added a station entry for: %pM (idx: %d)\n",
524 sta->addr, tsta.sta_index);
a97b478c 525 } else {
d2182b69 526 ath_dbg(common, CONFIG,
a97b478c
SM
527 "Added a station entry for VIF %d (idx: %d)\n",
528 avp->index, tsta.sta_index);
529 }
fb9987d0 530
a97b478c 531 priv->sta_slot |= (1 << sta_idx);
fb9987d0 532 priv->nstations++;
a97b478c
SM
533 if (!sta)
534 priv->vif_sta_pos[avp->index] = sta_idx;
535
fb9987d0
S
536 return 0;
537}
538
539static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
540 struct ieee80211_vif *vif,
541 struct ieee80211_sta *sta)
542{
543 struct ath_common *common = ath9k_hw_common(priv->ah);
a97b478c 544 struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
fb9987d0
S
545 struct ath9k_htc_sta *ista;
546 int ret;
547 u8 cmd_rsp, sta_idx;
548
549 if (sta) {
550 ista = (struct ath9k_htc_sta *) sta->drv_priv;
551 sta_idx = ista->index;
552 } else {
a97b478c 553 sta_idx = priv->vif_sta_pos[avp->index];
fb9987d0
S
554 }
555
556 WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx);
557 if (ret) {
558 if (sta)
3800276a
JP
559 ath_err(common,
560 "Unable to remove station entry for: %pM\n",
561 sta->addr);
fb9987d0
S
562 return ret;
563 }
564
a97b478c 565 if (sta) {
d2182b69 566 ath_dbg(common, CONFIG,
226afe68
JP
567 "Removed a station entry for: %pM (idx: %d)\n",
568 sta->addr, sta_idx);
a97b478c 569 } else {
d2182b69 570 ath_dbg(common, CONFIG,
a97b478c
SM
571 "Removed a station entry for VIF %d (idx: %d)\n",
572 avp->index, sta_idx);
573 }
fb9987d0 574
a97b478c 575 priv->sta_slot &= ~(1 << sta_idx);
fb9987d0 576 priv->nstations--;
a97b478c 577
fb9987d0
S
578 return 0;
579}
580
3a0593ef
SM
581int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv,
582 u8 enable_coex)
fb9987d0
S
583{
584 struct ath9k_htc_cap_target tcap;
585 int ret;
586 u8 cmd_rsp;
587
588 memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target));
589
3a0593ef 590 tcap.ampdu_limit = cpu_to_be32(0xffff);
bd548799 591 tcap.ampdu_subframes = 0xff;
3a0593ef 592 tcap.enable_coex = enable_coex;
29d9075e 593 tcap.tx_chainmask = priv->ah->caps.tx_chainmask;
fb9987d0
S
594
595 WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap);
596
597 return ret;
598}
599
0d425a7d
S
600static void ath9k_htc_setup_rate(struct ath9k_htc_priv *priv,
601 struct ieee80211_sta *sta,
602 struct ath9k_htc_target_rate *trate)
fb9987d0 603{
fb9987d0
S
604 struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
605 struct ieee80211_supported_band *sband;
fb9987d0 606 u32 caps = 0;
0d425a7d 607 int i, j;
fb9987d0 608
675a0b04 609 sband = priv->hw->wiphy->bands[priv->hw->conf.chandef.chan->band];
fb9987d0
S
610
611 for (i = 0, j = 0; i < sband->n_bitrates; i++) {
612 if (sta->supp_rates[sband->band] & BIT(i)) {
0d425a7d 613 trate->rates.legacy_rates.rs_rates[j]
fb9987d0
S
614 = (sband->bitrates[i].bitrate * 2) / 10;
615 j++;
616 }
617 }
0d425a7d 618 trate->rates.legacy_rates.rs_nrates = j;
fb9987d0
S
619
620 if (sta->ht_cap.ht_supported) {
621 for (i = 0, j = 0; i < 77; i++) {
622 if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8)))
0d425a7d 623 trate->rates.ht_rates.rs_rates[j++] = i;
fb9987d0
S
624 if (j == ATH_HTC_RATE_MAX)
625 break;
626 }
0d425a7d 627 trate->rates.ht_rates.rs_nrates = j;
fb9987d0
S
628
629 caps = WLAN_RC_HT_FLAG;
a226c3d9
OR
630 if (sta->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC)
631 caps |= ATH_RC_TX_STBC_FLAG;
3553727c
FF
632 if (sta->ht_cap.mcs.rx_mask[1])
633 caps |= WLAN_RC_DS_FLAG;
71ba186c
VN
634 if ((sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
635 (conf_is_ht40(&priv->hw->conf)))
fb9987d0 636 caps |= WLAN_RC_40_FLAG;
b4dec5e8
S
637 if (conf_is_ht40(&priv->hw->conf) &&
638 (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40))
639 caps |= WLAN_RC_SGI_FLAG;
640 else if (conf_is_ht20(&priv->hw->conf) &&
641 (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20))
fb9987d0 642 caps |= WLAN_RC_SGI_FLAG;
fb9987d0
S
643 }
644
0d425a7d
S
645 trate->sta_index = ista->index;
646 trate->isnew = 1;
647 trate->capflags = cpu_to_be32(caps);
648}
649
650static int ath9k_htc_send_rate_cmd(struct ath9k_htc_priv *priv,
651 struct ath9k_htc_target_rate *trate)
652{
653 struct ath_common *common = ath9k_hw_common(priv->ah);
654 int ret;
655 u8 cmd_rsp;
fb9987d0 656
0d425a7d 657 WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, trate);
fb9987d0 658 if (ret) {
3800276a
JP
659 ath_err(common,
660 "Unable to initialize Rate information on target\n");
fb9987d0
S
661 }
662
0d425a7d 663 return ret;
fb9987d0
S
664}
665
0d425a7d
S
666static void ath9k_htc_init_rate(struct ath9k_htc_priv *priv,
667 struct ieee80211_sta *sta)
fb9987d0 668{
fb9987d0 669 struct ath_common *common = ath9k_hw_common(priv->ah);
0d425a7d 670 struct ath9k_htc_target_rate trate;
fb9987d0 671 int ret;
fb9987d0 672
0d425a7d
S
673 memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
674 ath9k_htc_setup_rate(priv, sta, &trate);
675 ret = ath9k_htc_send_rate_cmd(priv, &trate);
676 if (!ret)
d2182b69 677 ath_dbg(common, CONFIG,
226afe68
JP
678 "Updated target sta: %pM, rate caps: 0x%X\n",
679 sta->addr, be32_to_cpu(trate.capflags));
fb9987d0
S
680}
681
2c76ef89
S
682static void ath9k_htc_update_rate(struct ath9k_htc_priv *priv,
683 struct ieee80211_vif *vif,
684 struct ieee80211_bss_conf *bss_conf)
685{
686 struct ath_common *common = ath9k_hw_common(priv->ah);
687 struct ath9k_htc_target_rate trate;
688 struct ieee80211_sta *sta;
689 int ret;
690
691 memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
692
693 rcu_read_lock();
694 sta = ieee80211_find_sta(vif, bss_conf->bssid);
695 if (!sta) {
696 rcu_read_unlock();
697 return;
698 }
699 ath9k_htc_setup_rate(priv, sta, &trate);
700 rcu_read_unlock();
701
702 ret = ath9k_htc_send_rate_cmd(priv, &trate);
703 if (!ret)
d2182b69 704 ath_dbg(common, CONFIG,
226afe68
JP
705 "Updated target sta: %pM, rate caps: 0x%X\n",
706 bss_conf->bssid, be32_to_cpu(trate.capflags));
2c76ef89
S
707}
708
9edd9520
LR
709static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv,
710 struct ieee80211_vif *vif,
711 struct ieee80211_sta *sta,
712 enum ieee80211_ampdu_mlme_action action,
713 u16 tid)
fb9987d0
S
714{
715 struct ath_common *common = ath9k_hw_common(priv->ah);
716 struct ath9k_htc_target_aggr aggr;
277a64d1 717 struct ath9k_htc_sta *ista;
fb9987d0
S
718 int ret = 0;
719 u8 cmd_rsp;
720
0730d114 721 if (tid >= ATH9K_HTC_MAX_TID)
fb9987d0
S
722 return -EINVAL;
723
ef98c3cd 724 memset(&aggr, 0, sizeof(struct ath9k_htc_target_aggr));
ef98c3cd 725 ista = (struct ath9k_htc_sta *) sta->drv_priv;
fb9987d0 726
fb9987d0 727 aggr.sta_index = ista->index;
d7ca2139
S
728 aggr.tidno = tid & 0xf;
729 aggr.aggr_enable = (action == IEEE80211_AMPDU_TX_START) ? true : false;
fb9987d0 730
fb9987d0
S
731 WMI_CMD_BUF(WMI_TX_AGGR_ENABLE_CMDID, &aggr);
732 if (ret)
d2182b69 733 ath_dbg(common, CONFIG,
226afe68
JP
734 "Unable to %s TX aggregation for (%pM, %d)\n",
735 (aggr.aggr_enable) ? "start" : "stop", sta->addr, tid);
fb9987d0 736 else
d2182b69 737 ath_dbg(common, CONFIG,
226afe68
JP
738 "%s TX aggregation for (%pM, %d)\n",
739 (aggr.aggr_enable) ? "Starting" : "Stopping",
740 sta->addr, tid);
fb9987d0 741
658ef04f 742 spin_lock_bh(&priv->tx.tx_lock);
d7ca2139 743 ista->tid_state[tid] = (aggr.aggr_enable && !ret) ? AGGR_START : AGGR_STOP;
658ef04f 744 spin_unlock_bh(&priv->tx.tx_lock);
fb9987d0 745
d7ca2139 746 return ret;
fb9987d0
S
747}
748
fb9987d0
S
749/*******/
750/* ANI */
751/*******/
752
a236254c 753void ath9k_htc_start_ani(struct ath9k_htc_priv *priv)
fb9987d0
S
754{
755 struct ath_common *common = ath9k_hw_common(priv->ah);
756 unsigned long timestamp = jiffies_to_msecs(jiffies);
757
758 common->ani.longcal_timer = timestamp;
759 common->ani.shortcal_timer = timestamp;
760 common->ani.checkani_timer = timestamp;
761
d8a2c51c 762 set_bit(OP_ANI_RUNNING, &priv->op_flags);
a236254c
SM
763
764 ieee80211_queue_delayed_work(common->hw, &priv->ani_work,
fb9987d0
S
765 msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
766}
767
a236254c
SM
768void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv)
769{
770 cancel_delayed_work_sync(&priv->ani_work);
d8a2c51c 771 clear_bit(OP_ANI_RUNNING, &priv->op_flags);
a236254c
SM
772}
773
774void ath9k_htc_ani_work(struct work_struct *work)
fb9987d0
S
775{
776 struct ath9k_htc_priv *priv =
a236254c 777 container_of(work, struct ath9k_htc_priv, ani_work.work);
fb9987d0
S
778 struct ath_hw *ah = priv->ah;
779 struct ath_common *common = ath9k_hw_common(ah);
780 bool longcal = false;
781 bool shortcal = false;
782 bool aniflag = false;
783 unsigned int timestamp = jiffies_to_msecs(jiffies);
784 u32 cal_interval, short_cal_interval;
785
a236254c
SM
786 short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ?
787 ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL;
fb9987d0 788
bde748a4
VN
789 /* Only calibrate if awake */
790 if (ah->power_mode != ATH9K_PM_AWAKE)
791 goto set_timer;
792
fb9987d0
S
793 /* Long calibration runs independently of short calibration. */
794 if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
795 longcal = true;
d2182b69 796 ath_dbg(common, ANI, "longcal @%lu\n", jiffies);
fb9987d0
S
797 common->ani.longcal_timer = timestamp;
798 }
799
800 /* Short calibration applies only while caldone is false */
801 if (!common->ani.caldone) {
802 if ((timestamp - common->ani.shortcal_timer) >=
803 short_cal_interval) {
804 shortcal = true;
d2182b69 805 ath_dbg(common, ANI, "shortcal @%lu\n", jiffies);
fb9987d0
S
806 common->ani.shortcal_timer = timestamp;
807 common->ani.resetcal_timer = timestamp;
808 }
809 } else {
810 if ((timestamp - common->ani.resetcal_timer) >=
811 ATH_RESTART_CALINTERVAL) {
812 common->ani.caldone = ath9k_hw_reset_calvalid(ah);
813 if (common->ani.caldone)
814 common->ani.resetcal_timer = timestamp;
815 }
816 }
817
818 /* Verify whether we must check ANI */
e323300d 819 if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
fb9987d0
S
820 aniflag = true;
821 common->ani.checkani_timer = timestamp;
822 }
823
824 /* Skip all processing if there's nothing to do. */
825 if (longcal || shortcal || aniflag) {
bde748a4
VN
826
827 ath9k_htc_ps_wakeup(priv);
828
fb9987d0
S
829 /* Call ANI routine if necessary */
830 if (aniflag)
831 ath9k_hw_ani_monitor(ah, ah->curchan);
832
833 /* Perform calibration if necessary */
35ecfe03 834 if (longcal || shortcal)
fb9987d0
S
835 common->ani.caldone =
836 ath9k_hw_calibrate(ah, ah->curchan,
82b2d334 837 ah->rxchainmask, longcal);
fb9987d0 838
bde748a4 839 ath9k_htc_ps_restore(priv);
fb9987d0
S
840 }
841
bde748a4 842set_timer:
fb9987d0
S
843 /*
844 * Set timer interval based on previous results.
845 * The interval must be the shortest necessary to satisfy ANI,
846 * short calibration and long calibration.
847 */
848 cal_interval = ATH_LONG_CALINTERVAL;
e323300d 849 cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
fb9987d0
S
850 if (!common->ani.caldone)
851 cal_interval = min(cal_interval, (u32)short_cal_interval);
852
a236254c 853 ieee80211_queue_delayed_work(common->hw, &priv->ani_work,
fb9987d0
S
854 msecs_to_jiffies(cal_interval));
855}
856
fb9987d0
S
857/**********************/
858/* mac80211 Callbacks */
859/**********************/
860
36323f81
TH
861static void ath9k_htc_tx(struct ieee80211_hw *hw,
862 struct ieee80211_tx_control *control,
863 struct sk_buff *skb)
fb9987d0
S
864{
865 struct ieee80211_hdr *hdr;
866 struct ath9k_htc_priv *priv = hw->priv;
8e86a547 867 struct ath_common *common = ath9k_hw_common(priv->ah);
2c5d57f0 868 int padpos, padsize, ret, slot;
fb9987d0
S
869
870 hdr = (struct ieee80211_hdr *) skb->data;
871
872 /* Add the padding after the header if this is not already done */
c60c9929 873 padpos = ieee80211_hdrlen(hdr->frame_control);
fb9987d0
S
874 padsize = padpos & 3;
875 if (padsize && skb->len > padpos) {
8e86a547 876 if (skb_headroom(skb) < padsize) {
d2182b69 877 ath_dbg(common, XMIT, "No room for padding\n");
7bb45683 878 goto fail_tx;
8e86a547 879 }
fb9987d0
S
880 skb_push(skb, padsize);
881 memmove(skb->data, skb->data + padsize, padpos);
882 }
883
2c5d57f0
SM
884 slot = ath9k_htc_tx_get_slot(priv);
885 if (slot < 0) {
d2182b69 886 ath_dbg(common, XMIT, "No free TX slot\n");
2c5d57f0
SM
887 goto fail_tx;
888 }
889
36323f81 890 ret = ath9k_htc_tx_start(priv, control->sta, skb, slot, false);
7757dfed 891 if (ret != 0) {
d2182b69 892 ath_dbg(common, XMIT, "Tx failed\n");
2c5d57f0 893 goto clear_slot;
fb9987d0
S
894 }
895
8e86a547
SM
896 ath9k_htc_check_stop_queues(priv);
897
7bb45683 898 return;
fb9987d0 899
2c5d57f0
SM
900clear_slot:
901 ath9k_htc_tx_clear_slot(priv, slot);
fb9987d0
S
902fail_tx:
903 dev_kfree_skb_any(skb);
fb9987d0
S
904}
905
881ac6a5 906static int ath9k_htc_start(struct ieee80211_hw *hw)
fb9987d0
S
907{
908 struct ath9k_htc_priv *priv = hw->priv;
909 struct ath_hw *ah = priv->ah;
910 struct ath_common *common = ath9k_hw_common(ah);
675a0b04 911 struct ieee80211_channel *curchan = hw->conf.chandef.chan;
fb9987d0
S
912 struct ath9k_channel *init_channel;
913 int ret = 0;
914 enum htc_phymode mode;
7f1f5a00 915 __be16 htc_mode;
fb9987d0
S
916 u8 cmd_rsp;
917
881ac6a5
S
918 mutex_lock(&priv->mutex);
919
d2182b69 920 ath_dbg(common, CONFIG,
226afe68
JP
921 "Starting driver with initial channel: %d MHz\n",
922 curchan->center_freq);
fb9987d0 923
21d5130b
S
924 /* Ensure that HW is awake before flushing RX */
925 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
926 WMI_CMD(WMI_FLUSH_RECV_CMDID);
927
fb9987d0
S
928 /* setup initial channel */
929 init_channel = ath9k_cmn_get_curchannel(hw, ah);
930
20bd2a09 931 ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
fb9987d0 932 if (ret) {
3800276a
JP
933 ath_err(common,
934 "Unable to reset hardware; reset status %d (freq %u MHz)\n",
935 ret, curchan->center_freq);
881ac6a5 936 mutex_unlock(&priv->mutex);
8a8572a8 937 return ret;
fb9987d0
S
938 }
939
b2a5c3df
RM
940 ath9k_cmn_update_txpow(ah, priv->curtxpow, priv->txpowlimit,
941 &priv->curtxpow);
fb9987d0
S
942
943 mode = ath9k_htc_get_curmode(priv, init_channel);
944 htc_mode = cpu_to_be16(mode);
945 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
fb9987d0 946 WMI_CMD(WMI_ATH_INIT_CMDID);
fb9987d0 947 WMI_CMD(WMI_START_RECV_CMDID);
fb9987d0
S
948
949 ath9k_host_rx_init(priv);
950
3a0593ef 951 ret = ath9k_htc_update_cap_target(priv, 0);
1057b750 952 if (ret)
d2182b69 953 ath_dbg(common, CONFIG,
1057b750
SM
954 "Failed to update capability in target\n");
955
d8a2c51c 956 clear_bit(OP_INVALID, &priv->op_flags);
fb9987d0
S
957 htc_start(priv->htc);
958
658ef04f 959 spin_lock_bh(&priv->tx.tx_lock);
8e86a547 960 priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP;
658ef04f 961 spin_unlock_bh(&priv->tx.tx_lock);
7757dfed
S
962
963 ieee80211_wake_queues(hw);
964
859c3ca1
SM
965 mod_timer(&priv->tx.cleanup_timer,
966 jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
967
bf047fcd
SM
968 ath9k_htc_start_btcoex(priv);
969
fb9987d0 970 mutex_unlock(&priv->mutex);
8a8572a8 971
fb9987d0
S
972 return ret;
973}
974
881ac6a5 975static void ath9k_htc_stop(struct ieee80211_hw *hw)
fb9987d0
S
976{
977 struct ath9k_htc_priv *priv = hw->priv;
978 struct ath_hw *ah = priv->ah;
979 struct ath_common *common = ath9k_hw_common(ah);
0ff2b5c0 980 int ret __attribute__ ((unused));
fb9987d0
S
981 u8 cmd_rsp;
982
881ac6a5
S
983 mutex_lock(&priv->mutex);
984
d8a2c51c 985 if (test_bit(OP_INVALID, &priv->op_flags)) {
d2182b69 986 ath_dbg(common, ANY, "Device not present\n");
881ac6a5 987 mutex_unlock(&priv->mutex);
fb9987d0
S
988 return;
989 }
990
bde748a4 991 ath9k_htc_ps_wakeup(priv);
b587fc81 992
fb9987d0
S
993 WMI_CMD(WMI_DISABLE_INTR_CMDID);
994 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
995 WMI_CMD(WMI_STOP_RECV_CMDID);
ea888357 996
ea888357 997 tasklet_kill(&priv->rx_tasklet);
fb9987d0 998
859c3ca1 999 del_timer_sync(&priv->tx.cleanup_timer);
b587fc81 1000 ath9k_htc_tx_drain(priv);
f4c88991
SM
1001 ath9k_wmi_event_drain(priv);
1002
ea888357
SG
1003 mutex_unlock(&priv->mutex);
1004
1005 /* Cancel all the running timers/work .. */
1006 cancel_work_sync(&priv->fatal_work);
1007 cancel_work_sync(&priv->ps_work);
d244f21e
SM
1008
1009#ifdef CONFIG_MAC80211_LEDS
1010 cancel_work_sync(&priv->led_work);
1011#endif
a236254c 1012 ath9k_htc_stop_ani(priv);
ea888357
SG
1013
1014 mutex_lock(&priv->mutex);
1015
bf047fcd 1016 ath9k_htc_stop_btcoex(priv);
21cb9879 1017
a97b478c
SM
1018 /* Remove a monitor interface if it's present. */
1019 if (priv->ah->is_monitoring)
1020 ath9k_htc_remove_monitor_interface(priv);
1021
e9201f09
S
1022 ath9k_hw_phy_disable(ah);
1023 ath9k_hw_disable(ah);
e9201f09
S
1024 ath9k_htc_ps_restore(priv);
1025 ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
1026
d8a2c51c 1027 set_bit(OP_INVALID, &priv->op_flags);
fb9987d0 1028
d2182b69 1029 ath_dbg(common, CONFIG, "Driver halt\n");
8a8572a8
VN
1030 mutex_unlock(&priv->mutex);
1031}
1032
fb9987d0
S
1033static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1034 struct ieee80211_vif *vif)
1035{
1036 struct ath9k_htc_priv *priv = hw->priv;
1037 struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1038 struct ath_common *common = ath9k_hw_common(priv->ah);
1039 struct ath9k_htc_target_vif hvif;
1040 int ret = 0;
1041 u8 cmd_rsp;
1042
1043 mutex_lock(&priv->mutex);
1044
bde748a4 1045 ath9k_htc_ps_wakeup(priv);
fb9987d0
S
1046 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
1047 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
1048
1049 switch (vif->type) {
1050 case NL80211_IFTYPE_STATION:
e4c62506 1051 hvif.opmode = HTC_M_STA;
fb9987d0
S
1052 break;
1053 case NL80211_IFTYPE_ADHOC:
e4c62506 1054 hvif.opmode = HTC_M_IBSS;
fb9987d0 1055 break;
da8d9d93 1056 case NL80211_IFTYPE_AP:
e4c62506 1057 hvif.opmode = HTC_M_HOSTAP;
da8d9d93 1058 break;
594e65b6
JC
1059 case NL80211_IFTYPE_MESH_POINT:
1060 hvif.opmode = HTC_M_WDS; /* close enough */
1061 break;
fb9987d0 1062 default:
3800276a 1063 ath_err(common,
fb9987d0
S
1064 "Interface type %d not yet supported\n", vif->type);
1065 ret = -EOPNOTSUPP;
1066 goto out;
1067 }
1068
fb9987d0 1069 /* Index starts from zero on the target */
a97b478c 1070 avp->index = hvif.index = ffz(priv->vif_slot);
fb9987d0
S
1071 hvif.rtsthreshold = cpu_to_be16(2304);
1072 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
1073 if (ret)
1074 goto out;
1075
fb9987d0
S
1076 /*
1077 * We need a node in target to tx mgmt frames
1078 * before association.
1079 */
1080 ret = ath9k_htc_add_station(priv, vif, NULL);
ab77c70a
SM
1081 if (ret) {
1082 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
fb9987d0 1083 goto out;
ab77c70a 1084 }
fb9987d0 1085
585895cd
SM
1086 ath9k_htc_set_bssid_mask(priv, vif);
1087
a97b478c 1088 priv->vif_slot |= (1 << avp->index);
ab77c70a 1089 priv->nvifs++;
a97b478c 1090
0df8359a 1091 INC_VIF(priv, vif->type);
832f6a18
SM
1092
1093 if ((vif->type == NL80211_IFTYPE_AP) ||
594e65b6 1094 (vif->type == NL80211_IFTYPE_MESH_POINT) ||
832f6a18
SM
1095 (vif->type == NL80211_IFTYPE_ADHOC))
1096 ath9k_htc_assign_bslot(priv, vif);
1097
ffbe7c83 1098 ath9k_htc_set_opmode(priv);
0df8359a 1099
a236254c 1100 if ((priv->ah->opmode == NL80211_IFTYPE_AP) &&
d8a2c51c 1101 !test_bit(OP_ANI_RUNNING, &priv->op_flags)) {
60ca9f87 1102 ath9k_hw_set_tsfadjust(priv->ah, true);
a236254c 1103 ath9k_htc_start_ani(priv);
9b674a02 1104 }
a236254c 1105
d2182b69
JP
1106 ath_dbg(common, CONFIG, "Attach a VIF of type: %d at idx: %d\n",
1107 vif->type, avp->index);
a97b478c 1108
fb9987d0 1109out:
bde748a4 1110 ath9k_htc_ps_restore(priv);
fb9987d0 1111 mutex_unlock(&priv->mutex);
cb551df2 1112
fb9987d0
S
1113 return ret;
1114}
1115
1116static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
1117 struct ieee80211_vif *vif)
1118{
1119 struct ath9k_htc_priv *priv = hw->priv;
1120 struct ath_common *common = ath9k_hw_common(priv->ah);
1121 struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1122 struct ath9k_htc_target_vif hvif;
1123 int ret = 0;
1124 u8 cmd_rsp;
1125
fb9987d0 1126 mutex_lock(&priv->mutex);
cb551df2 1127 ath9k_htc_ps_wakeup(priv);
fb9987d0
S
1128
1129 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
1130 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
1131 hvif.index = avp->index;
1132 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
0ff2b5c0
SM
1133 if (ret) {
1134 ath_err(common, "Unable to remove interface at idx: %d\n",
1135 avp->index);
1136 }
fb9987d0 1137 priv->nvifs--;
a97b478c 1138 priv->vif_slot &= ~(1 << avp->index);
fb9987d0
S
1139
1140 ath9k_htc_remove_station(priv, vif, NULL);
fb9987d0 1141
0df8359a 1142 DEC_VIF(priv, vif->type);
832f6a18
SM
1143
1144 if ((vif->type == NL80211_IFTYPE_AP) ||
594e65b6 1145 vif->type == NL80211_IFTYPE_MESH_POINT ||
832f6a18
SM
1146 (vif->type == NL80211_IFTYPE_ADHOC))
1147 ath9k_htc_remove_bslot(priv, vif);
1148
ffbe7c83 1149 ath9k_htc_set_opmode(priv);
0df8359a 1150
db32124a
SM
1151 ath9k_htc_set_bssid_mask(priv, vif);
1152
a236254c
SM
1153 /*
1154 * Stop ANI only if there are no associated station interfaces.
1155 */
1156 if ((vif->type == NL80211_IFTYPE_AP) && (priv->num_ap_vif == 0)) {
1157 priv->rearm_ani = false;
8b2c9824
JB
1158 ieee80211_iterate_active_interfaces_atomic(
1159 priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
1160 ath9k_htc_vif_iter, priv);
a236254c
SM
1161 if (!priv->rearm_ani)
1162 ath9k_htc_stop_ani(priv);
1163 }
1164
d2182b69 1165 ath_dbg(common, CONFIG, "Detach Interface at idx: %d\n", avp->index);
a97b478c 1166
cb551df2 1167 ath9k_htc_ps_restore(priv);
fb9987d0
S
1168 mutex_unlock(&priv->mutex);
1169}
1170
1171static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
1172{
1173 struct ath9k_htc_priv *priv = hw->priv;
1174 struct ath_common *common = ath9k_hw_common(priv->ah);
1175 struct ieee80211_conf *conf = &hw->conf;
6bcfe67f
SM
1176 bool chip_reset = false;
1177 int ret = 0;
fb9987d0
S
1178
1179 mutex_lock(&priv->mutex);
6bcfe67f 1180 ath9k_htc_ps_wakeup(priv);
fb9987d0 1181
8a8572a8 1182 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
23367769 1183 mutex_lock(&priv->htc_pm_lock);
8a8572a8 1184
6bcfe67f 1185 priv->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE);
075163bb 1186 if (!priv->ps_idle)
6bcfe67f
SM
1187 chip_reset = true;
1188
1189 mutex_unlock(&priv->htc_pm_lock);
8a8572a8
VN
1190 }
1191
55de80d6
SM
1192 /*
1193 * Monitor interface should be added before
1194 * IEEE80211_CONF_CHANGE_CHANNEL is handled.
1195 */
1196 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
a97b478c
SM
1197 if ((conf->flags & IEEE80211_CONF_MONITOR) &&
1198 !priv->ah->is_monitoring)
1199 ath9k_htc_add_monitor_interface(priv);
1200 else if (priv->ah->is_monitoring)
1201 ath9k_htc_remove_monitor_interface(priv);
55de80d6
SM
1202 }
1203
6bcfe67f 1204 if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || chip_reset) {
675a0b04
KB
1205 struct ieee80211_channel *curchan = hw->conf.chandef.chan;
1206 enum nl80211_channel_type channel_type =
1207 cfg80211_get_chandef_type(&hw->conf.chandef);
fb9987d0 1208 int pos = curchan->hw_value;
fb9987d0 1209
d2182b69 1210 ath_dbg(common, CONFIG, "Set channel: %d MHz\n",
226afe68 1211 curchan->center_freq);
fb9987d0 1212
babcbc29 1213 ath9k_cmn_update_ichannel(&priv->ah->channels[pos],
675a0b04
KB
1214 hw->conf.chandef.chan,
1215 channel_type);
fb9987d0
S
1216
1217 if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) {
3800276a 1218 ath_err(common, "Unable to set channel\n");
6bcfe67f
SM
1219 ret = -EINVAL;
1220 goto out;
fb9987d0
S
1221 }
1222
1223 }
692d6b17 1224
bde748a4
VN
1225 if (changed & IEEE80211_CONF_CHANGE_PS) {
1226 if (conf->flags & IEEE80211_CONF_PS) {
1227 ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP);
1228 priv->ps_enabled = true;
1229 } else {
1230 priv->ps_enabled = false;
1231 cancel_work_sync(&priv->ps_work);
1232 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
1233 }
1234 }
fb9987d0 1235
692d6b17
SM
1236 if (changed & IEEE80211_CONF_CHANGE_POWER) {
1237 priv->txpowlimit = 2 * conf->power_level;
b2a5c3df
RM
1238 ath9k_cmn_update_txpow(priv->ah, priv->curtxpow,
1239 priv->txpowlimit, &priv->curtxpow);
692d6b17
SM
1240 }
1241
23367769 1242out:
6bcfe67f 1243 ath9k_htc_ps_restore(priv);
fb9987d0 1244 mutex_unlock(&priv->mutex);
6bcfe67f 1245 return ret;
fb9987d0
S
1246}
1247
1248#define SUPPORTED_FILTERS \
1249 (FIF_PROMISC_IN_BSS | \
1250 FIF_ALLMULTI | \
1251 FIF_CONTROL | \
1252 FIF_PSPOLL | \
1253 FIF_OTHER_BSS | \
1254 FIF_BCN_PRBRESP_PROMISC | \
94a40c0c 1255 FIF_PROBE_REQ | \
fb9987d0
S
1256 FIF_FCSFAIL)
1257
1258static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
1259 unsigned int changed_flags,
1260 unsigned int *total_flags,
1261 u64 multicast)
1262{
1263 struct ath9k_htc_priv *priv = hw->priv;
1264 u32 rfilt;
1265
1266 mutex_lock(&priv->mutex);
fb9987d0
S
1267 changed_flags &= SUPPORTED_FILTERS;
1268 *total_flags &= SUPPORTED_FILTERS;
1269
d8a2c51c 1270 if (test_bit(OP_INVALID, &priv->op_flags)) {
d2182b69 1271 ath_dbg(ath9k_hw_common(priv->ah), ANY,
565dfefb 1272 "Unable to configure filter on invalid state\n");
1ba45b9e 1273 mutex_unlock(&priv->mutex);
565dfefb
RM
1274 return;
1275 }
1276 ath9k_htc_ps_wakeup(priv);
1277
fb9987d0 1278 priv->rxfilter = *total_flags;
0995d110 1279 rfilt = ath9k_htc_calcrxfilter(priv);
fb9987d0
S
1280 ath9k_hw_setrxfilter(priv->ah, rfilt);
1281
d2182b69
JP
1282 ath_dbg(ath9k_hw_common(priv->ah), CONFIG, "Set HW RX filter: 0x%x\n",
1283 rfilt);
fb9987d0 1284
bde748a4 1285 ath9k_htc_ps_restore(priv);
fb9987d0
S
1286 mutex_unlock(&priv->mutex);
1287}
1288
abd984e6
S
1289static int ath9k_htc_sta_add(struct ieee80211_hw *hw,
1290 struct ieee80211_vif *vif,
1291 struct ieee80211_sta *sta)
fb9987d0
S
1292{
1293 struct ath9k_htc_priv *priv = hw->priv;
1294 int ret;
1295
05a30f9c 1296 mutex_lock(&priv->mutex);
cb551df2 1297 ath9k_htc_ps_wakeup(priv);
abd984e6
S
1298 ret = ath9k_htc_add_station(priv, vif, sta);
1299 if (!ret)
1300 ath9k_htc_init_rate(priv, sta);
1301 ath9k_htc_ps_restore(priv);
1302 mutex_unlock(&priv->mutex);
05a30f9c 1303
abd984e6
S
1304 return ret;
1305}
1306
1307static int ath9k_htc_sta_remove(struct ieee80211_hw *hw,
1308 struct ieee80211_vif *vif,
1309 struct ieee80211_sta *sta)
1310{
1311 struct ath9k_htc_priv *priv = hw->priv;
84c9e164 1312 struct ath9k_htc_sta *ista;
abd984e6 1313 int ret;
05a30f9c 1314
abd984e6
S
1315 mutex_lock(&priv->mutex);
1316 ath9k_htc_ps_wakeup(priv);
84c9e164
SM
1317 ista = (struct ath9k_htc_sta *) sta->drv_priv;
1318 htc_sta_drain(priv->htc, ista->index);
abd984e6 1319 ret = ath9k_htc_remove_station(priv, vif, sta);
cb551df2 1320 ath9k_htc_ps_restore(priv);
05a30f9c 1321 mutex_unlock(&priv->mutex);
abd984e6
S
1322
1323 return ret;
fb9987d0
S
1324}
1325
69578029
AQ
1326static void ath9k_htc_sta_rc_update(struct ieee80211_hw *hw,
1327 struct ieee80211_vif *vif,
1328 struct ieee80211_sta *sta, u32 changed)
1329{
1330 struct ath9k_htc_priv *priv = hw->priv;
1331 struct ath_common *common = ath9k_hw_common(priv->ah);
1332 struct ath9k_htc_target_rate trate;
1333
1334 mutex_lock(&priv->mutex);
1335 ath9k_htc_ps_wakeup(priv);
1336
1337 if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) {
1338 memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
1339 ath9k_htc_setup_rate(priv, sta, &trate);
1340 if (!ath9k_htc_send_rate_cmd(priv, &trate))
1341 ath_dbg(common, CONFIG,
1342 "Supported rates for sta: %pM updated, rate caps: 0x%X\n",
1343 sta->addr, be32_to_cpu(trate.capflags));
1344 else
1345 ath_dbg(common, CONFIG,
1346 "Unable to update supported rates for sta: %pM\n",
1347 sta->addr);
1348 }
1349
1350 ath9k_htc_ps_restore(priv);
1351 mutex_unlock(&priv->mutex);
1352}
1353
8a3a3c85
EP
1354static int ath9k_htc_conf_tx(struct ieee80211_hw *hw,
1355 struct ieee80211_vif *vif, u16 queue,
fb9987d0
S
1356 const struct ieee80211_tx_queue_params *params)
1357{
1358 struct ath9k_htc_priv *priv = hw->priv;
1359 struct ath_common *common = ath9k_hw_common(priv->ah);
1360 struct ath9k_tx_queue_info qi;
1361 int ret = 0, qnum;
1362
bea843c7 1363 if (queue >= IEEE80211_NUM_ACS)
fb9987d0
S
1364 return 0;
1365
1366 mutex_lock(&priv->mutex);
cb551df2 1367 ath9k_htc_ps_wakeup(priv);
fb9987d0
S
1368
1369 memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
1370
1371 qi.tqi_aifs = params->aifs;
1372 qi.tqi_cwmin = params->cw_min;
1373 qi.tqi_cwmax = params->cw_max;
531bd079 1374 qi.tqi_burstTime = params->txop * 32;
fb9987d0
S
1375
1376 qnum = get_hw_qnum(queue, priv->hwq_map);
1377
d2182b69 1378 ath_dbg(common, CONFIG,
226afe68
JP
1379 "Configure tx [queue/hwq] [%d/%d], aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
1380 queue, qnum, params->aifs, params->cw_min,
1381 params->cw_max, params->txop);
fb9987d0 1382
e1572c5e 1383 ret = ath_htc_txq_update(priv, qnum, &qi);
764580f5 1384 if (ret) {
3800276a 1385 ath_err(common, "TXQ Update failed\n");
764580f5
S
1386 goto out;
1387 }
fb9987d0 1388
764580f5 1389 if ((priv->ah->opmode == NL80211_IFTYPE_ADHOC) &&
bea843c7 1390 (qnum == priv->hwq_map[IEEE80211_AC_BE]))
764580f5
S
1391 ath9k_htc_beaconq_config(priv);
1392out:
cb551df2 1393 ath9k_htc_ps_restore(priv);
fb9987d0
S
1394 mutex_unlock(&priv->mutex);
1395
1396 return ret;
1397}
1398
1399static int ath9k_htc_set_key(struct ieee80211_hw *hw,
1400 enum set_key_cmd cmd,
1401 struct ieee80211_vif *vif,
1402 struct ieee80211_sta *sta,
1403 struct ieee80211_key_conf *key)
1404{
1405 struct ath9k_htc_priv *priv = hw->priv;
1406 struct ath_common *common = ath9k_hw_common(priv->ah);
1407 int ret = 0;
1408
e1572c5e 1409 if (htc_modparam_nohwcrypt)
fb9987d0
S
1410 return -ENOSPC;
1411
d7d312ca
AQ
1412 if ((vif->type == NL80211_IFTYPE_ADHOC ||
1413 vif->type == NL80211_IFTYPE_MESH_POINT) &&
1414 (key->cipher == WLAN_CIPHER_SUITE_TKIP ||
1415 key->cipher == WLAN_CIPHER_SUITE_CCMP) &&
1416 !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
1417 /*
1418 * For now, disable hw crypto for the RSN IBSS group keys. This
1419 * could be optimized in the future to use a modified key cache
1420 * design to support per-STA RX GTK, but until that gets
1421 * implemented, use of software crypto for group addressed
1422 * frames is a acceptable to allow RSN IBSS to be used.
1423 */
1424 return -EOPNOTSUPP;
1425 }
1426
fb9987d0 1427 mutex_lock(&priv->mutex);
d2182b69 1428 ath_dbg(common, CONFIG, "Set HW Key\n");
bde748a4 1429 ath9k_htc_ps_wakeup(priv);
fb9987d0
S
1430
1431 switch (cmd) {
1432 case SET_KEY:
040e539e 1433 ret = ath_key_config(common, vif, sta, key);
fb9987d0
S
1434 if (ret >= 0) {
1435 key->hw_key_idx = ret;
1436 /* push IV and Michael MIC generation to stack */
1437 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
97359d12 1438 if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
fb9987d0 1439 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
97359d12
JB
1440 if (priv->ah->sw_mgmt_crypto &&
1441 key->cipher == WLAN_CIPHER_SUITE_CCMP)
e548c49e 1442 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
fb9987d0
S
1443 ret = 0;
1444 }
1445 break;
1446 case DISABLE_KEY:
040e539e 1447 ath_key_delete(common, key);
fb9987d0
S
1448 break;
1449 default:
1450 ret = -EINVAL;
1451 }
1452
bde748a4 1453 ath9k_htc_ps_restore(priv);
fb9987d0
S
1454 mutex_unlock(&priv->mutex);
1455
1456 return ret;
1457}
1458
0cd075d7
SM
1459static void ath9k_htc_set_bssid(struct ath9k_htc_priv *priv)
1460{
1461 struct ath_common *common = ath9k_hw_common(priv->ah);
1462
1463 ath9k_hw_write_associd(priv->ah);
d2182b69 1464 ath_dbg(common, CONFIG, "BSSID: %pM aid: 0x%x\n",
0cd075d7
SM
1465 common->curbssid, common->curaid);
1466}
1467
1468static void ath9k_htc_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
1469{
1470 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
1471 struct ath_common *common = ath9k_hw_common(priv->ah);
1472 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
1473
1474 if ((vif->type == NL80211_IFTYPE_STATION) && bss_conf->assoc) {
1475 common->curaid = bss_conf->aid;
1476 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1477 }
1478}
1479
1480static void ath9k_htc_choose_set_bssid(struct ath9k_htc_priv *priv)
1481{
1482 if (priv->num_sta_assoc_vif == 1) {
8b2c9824
JB
1483 ieee80211_iterate_active_interfaces_atomic(
1484 priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
1485 ath9k_htc_bss_iter, priv);
0cd075d7
SM
1486 ath9k_htc_set_bssid(priv);
1487 }
1488}
1489
fb9987d0
S
1490static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
1491 struct ieee80211_vif *vif,
1492 struct ieee80211_bss_conf *bss_conf,
1493 u32 changed)
1494{
1495 struct ath9k_htc_priv *priv = hw->priv;
1496 struct ath_hw *ah = priv->ah;
1497 struct ath_common *common = ath9k_hw_common(ah);
1498
1499 mutex_lock(&priv->mutex);
bde748a4 1500 ath9k_htc_ps_wakeup(priv);
fb9987d0
S
1501
1502 if (changed & BSS_CHANGED_ASSOC) {
d2182b69 1503 ath_dbg(common, CONFIG, "BSS Changed ASSOC %d\n",
0cd075d7 1504 bss_conf->assoc);
e7a2a4f5 1505
0cd075d7
SM
1506 bss_conf->assoc ?
1507 priv->num_sta_assoc_vif++ : priv->num_sta_assoc_vif--;
e7a2a4f5 1508
0cd075d7 1509 if (priv->ah->opmode == NL80211_IFTYPE_STATION) {
931cb03a 1510 ath9k_htc_choose_set_bssid(priv);
0cd075d7 1511 if (bss_conf->assoc && (priv->num_sta_assoc_vif == 1))
e7a2a4f5 1512 ath9k_htc_start_ani(priv);
0cd075d7 1513 else if (priv->num_sta_assoc_vif == 0)
e7a2a4f5
SM
1514 ath9k_htc_stop_ani(priv);
1515 }
fb9987d0
S
1516 }
1517
931cb03a 1518 if (changed & BSS_CHANGED_IBSS) {
0cd075d7
SM
1519 if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) {
1520 common->curaid = bss_conf->aid;
e7a2a4f5 1521 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
0cd075d7 1522 ath9k_htc_set_bssid(priv);
e7a2a4f5 1523 }
fb9987d0
S
1524 }
1525
a5fae37d 1526 if ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon) {
d2182b69
JP
1527 ath_dbg(common, CONFIG, "Beacon enabled for BSS: %pM\n",
1528 bss_conf->bssid);
9b674a02 1529 ath9k_htc_set_tsfadjust(priv, vif);
d8a2c51c 1530 set_bit(OP_ENABLE_BEACON, &priv->op_flags);
1c3652a5 1531 ath9k_htc_beacon_config(priv, vif);
fb9987d0
S
1532 }
1533
a5fae37d
SM
1534 if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) {
1535 /*
1536 * Disable SWBA interrupt only if there are no
594e65b6 1537 * concurrent AP/mesh or IBSS interfaces.
a5fae37d 1538 */
594e65b6
JC
1539 if ((priv->num_ap_vif + priv->num_mbss_vif <= 1) ||
1540 priv->num_ibss_vif) {
d2182b69 1541 ath_dbg(common, CONFIG,
a5fae37d
SM
1542 "Beacon disabled for BSS: %pM\n",
1543 bss_conf->bssid);
d8a2c51c 1544 clear_bit(OP_ENABLE_BEACON, &priv->op_flags);
a5fae37d
SM
1545 ath9k_htc_beacon_config(priv, vif);
1546 }
1547 }
1548
1549 if (changed & BSS_CHANGED_BEACON_INT) {
1550 /*
594e65b6 1551 * Reset the HW TSF for the first AP or mesh interface.
a5fae37d 1552 */
594e65b6
JC
1553 if (priv->nvifs == 1 &&
1554 ((priv->ah->opmode == NL80211_IFTYPE_AP &&
1555 vif->type == NL80211_IFTYPE_AP &&
1556 priv->num_ap_vif == 1) ||
1557 (priv->ah->opmode == NL80211_IFTYPE_MESH_POINT &&
1558 vif->type == NL80211_IFTYPE_MESH_POINT &&
1559 priv->num_mbss_vif == 1))) {
d8a2c51c 1560 set_bit(OP_TSF_RESET, &priv->op_flags);
a5fae37d 1561 }
d2182b69 1562 ath_dbg(common, CONFIG,
a5fae37d
SM
1563 "Beacon interval changed for BSS: %pM\n",
1564 bss_conf->bssid);
1c3652a5 1565 ath9k_htc_beacon_config(priv, vif);
fb9987d0
S
1566 }
1567
fb9987d0
S
1568 if (changed & BSS_CHANGED_ERP_SLOT) {
1569 if (bss_conf->use_short_slot)
1570 ah->slottime = 9;
1571 else
1572 ah->slottime = 20;
1573
1574 ath9k_hw_init_global_settings(ah);
1575 }
1576
2c76ef89
S
1577 if (changed & BSS_CHANGED_HT)
1578 ath9k_htc_update_rate(priv, vif, bss_conf);
1579
bde748a4 1580 ath9k_htc_ps_restore(priv);
fb9987d0
S
1581 mutex_unlock(&priv->mutex);
1582}
1583
37a41b4a
EP
1584static u64 ath9k_htc_get_tsf(struct ieee80211_hw *hw,
1585 struct ieee80211_vif *vif)
fb9987d0
S
1586{
1587 struct ath9k_htc_priv *priv = hw->priv;
1588 u64 tsf;
1589
1590 mutex_lock(&priv->mutex);
cb551df2 1591 ath9k_htc_ps_wakeup(priv);
fb9987d0 1592 tsf = ath9k_hw_gettsf64(priv->ah);
cb551df2 1593 ath9k_htc_ps_restore(priv);
fb9987d0
S
1594 mutex_unlock(&priv->mutex);
1595
1596 return tsf;
1597}
1598
37a41b4a
EP
1599static void ath9k_htc_set_tsf(struct ieee80211_hw *hw,
1600 struct ieee80211_vif *vif, u64 tsf)
fb9987d0
S
1601{
1602 struct ath9k_htc_priv *priv = hw->priv;
1603
1604 mutex_lock(&priv->mutex);
cb551df2 1605 ath9k_htc_ps_wakeup(priv);
fb9987d0 1606 ath9k_hw_settsf64(priv->ah, tsf);
cb551df2 1607 ath9k_htc_ps_restore(priv);
fb9987d0
S
1608 mutex_unlock(&priv->mutex);
1609}
1610
37a41b4a
EP
1611static void ath9k_htc_reset_tsf(struct ieee80211_hw *hw,
1612 struct ieee80211_vif *vif)
fb9987d0
S
1613{
1614 struct ath9k_htc_priv *priv = hw->priv;
1615
1616 mutex_lock(&priv->mutex);
cb551df2 1617 ath9k_htc_ps_wakeup(priv);
fb9987d0 1618 ath9k_hw_reset_tsf(priv->ah);
bde748a4 1619 ath9k_htc_ps_restore(priv);
cb551df2 1620 mutex_unlock(&priv->mutex);
fb9987d0
S
1621}
1622
1623static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
1624 struct ieee80211_vif *vif,
1625 enum ieee80211_ampdu_mlme_action action,
1626 struct ieee80211_sta *sta,
0b01f030 1627 u16 tid, u16 *ssn, u8 buf_size)
fb9987d0
S
1628{
1629 struct ath9k_htc_priv *priv = hw->priv;
fb9987d0 1630 struct ath9k_htc_sta *ista;
d7ca2139 1631 int ret = 0;
fb9987d0 1632
87df8957 1633 mutex_lock(&priv->mutex);
c58ca5b5 1634 ath9k_htc_ps_wakeup(priv);
87df8957 1635
fb9987d0
S
1636 switch (action) {
1637 case IEEE80211_AMPDU_RX_START:
1638 break;
1639 case IEEE80211_AMPDU_RX_STOP:
1640 break;
1641 case IEEE80211_AMPDU_TX_START:
d7ca2139
S
1642 ret = ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid);
1643 if (!ret)
1644 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1645 break;
18b559d5
JB
1646 case IEEE80211_AMPDU_TX_STOP_CONT:
1647 case IEEE80211_AMPDU_TX_STOP_FLUSH:
1648 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
d7ca2139
S
1649 ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid);
1650 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
fb9987d0
S
1651 break;
1652 case IEEE80211_AMPDU_TX_OPERATIONAL:
1653 ista = (struct ath9k_htc_sta *) sta->drv_priv;
658ef04f 1654 spin_lock_bh(&priv->tx.tx_lock);
fb9987d0 1655 ista->tid_state[tid] = AGGR_OPERATIONAL;
658ef04f 1656 spin_unlock_bh(&priv->tx.tx_lock);
fb9987d0
S
1657 break;
1658 default:
3800276a 1659 ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n");
fb9987d0
S
1660 }
1661
c58ca5b5 1662 ath9k_htc_ps_restore(priv);
87df8957
SM
1663 mutex_unlock(&priv->mutex);
1664
d7ca2139 1665 return ret;
fb9987d0
S
1666}
1667
1668static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw)
1669{
1670 struct ath9k_htc_priv *priv = hw->priv;
1671
1672 mutex_lock(&priv->mutex);
1673 spin_lock_bh(&priv->beacon_lock);
d8a2c51c 1674 set_bit(OP_SCANNING, &priv->op_flags);
fb9987d0 1675 spin_unlock_bh(&priv->beacon_lock);
bde748a4 1676 cancel_work_sync(&priv->ps_work);
a236254c 1677 ath9k_htc_stop_ani(priv);
fb9987d0
S
1678 mutex_unlock(&priv->mutex);
1679}
1680
1681static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
1682{
1683 struct ath9k_htc_priv *priv = hw->priv;
1684
1685 mutex_lock(&priv->mutex);
1686 spin_lock_bh(&priv->beacon_lock);
d8a2c51c 1687 clear_bit(OP_SCANNING, &priv->op_flags);
fb9987d0 1688 spin_unlock_bh(&priv->beacon_lock);
7c277349
SM
1689 ath9k_htc_ps_wakeup(priv);
1690 ath9k_htc_vif_reconfig(priv);
bde748a4 1691 ath9k_htc_ps_restore(priv);
cb551df2 1692 mutex_unlock(&priv->mutex);
fb9987d0
S
1693}
1694
1695static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1696{
1697 return 0;
1698}
1699
1700static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw,
1701 u8 coverage_class)
1702{
1703 struct ath9k_htc_priv *priv = hw->priv;
1704
1705 mutex_lock(&priv->mutex);
cb551df2 1706 ath9k_htc_ps_wakeup(priv);
fb9987d0
S
1707 priv->ah->coverage_class = coverage_class;
1708 ath9k_hw_init_global_settings(priv->ah);
cb551df2 1709 ath9k_htc_ps_restore(priv);
fb9987d0
S
1710 mutex_unlock(&priv->mutex);
1711}
1712
e2186b7c
SM
1713/*
1714 * Currently, this is used only for selecting the minimum rate
1715 * for management frames, rate selection for data frames remain
1716 * unaffected.
1717 */
1718static int ath9k_htc_set_bitrate_mask(struct ieee80211_hw *hw,
1719 struct ieee80211_vif *vif,
1720 const struct cfg80211_bitrate_mask *mask)
1721{
1722 struct ath9k_htc_priv *priv = hw->priv;
1723 struct ath_common *common = ath9k_hw_common(priv->ah);
1724 struct ath9k_htc_target_rate_mask tmask;
1725 struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1726 int ret = 0;
1727 u8 cmd_rsp;
1728
1729 memset(&tmask, 0, sizeof(struct ath9k_htc_target_rate_mask));
1730
1731 tmask.vif_index = avp->index;
1732 tmask.band = IEEE80211_BAND_2GHZ;
1733 tmask.mask = cpu_to_be32(mask->control[IEEE80211_BAND_2GHZ].legacy);
1734
1735 WMI_CMD_BUF(WMI_BITRATE_MASK_CMDID, &tmask);
1736 if (ret) {
1737 ath_err(common,
1738 "Unable to set 2G rate mask for "
1739 "interface at idx: %d\n", avp->index);
1740 goto out;
1741 }
1742
1743 tmask.band = IEEE80211_BAND_5GHZ;
1744 tmask.mask = cpu_to_be32(mask->control[IEEE80211_BAND_5GHZ].legacy);
1745
1746 WMI_CMD_BUF(WMI_BITRATE_MASK_CMDID, &tmask);
1747 if (ret) {
1748 ath_err(common,
1749 "Unable to set 5G rate mask for "
1750 "interface at idx: %d\n", avp->index);
1751 goto out;
1752 }
1753
d2182b69 1754 ath_dbg(common, CONFIG, "Set bitrate masks: 0x%x, 0x%x\n",
e2186b7c
SM
1755 mask->control[IEEE80211_BAND_2GHZ].legacy,
1756 mask->control[IEEE80211_BAND_5GHZ].legacy);
1757out:
1758 return ret;
1759}
1760
5fa71984
MSS
1761
1762static int ath9k_htc_get_stats(struct ieee80211_hw *hw,
1763 struct ieee80211_low_level_stats *stats)
1764{
1765 struct ath9k_htc_priv *priv = hw->priv;
1766 struct ath_hw *ah = priv->ah;
1767 struct ath9k_mib_stats *mib_stats = &ah->ah_mibStats;
1768
1769 stats->dot11ACKFailureCount = mib_stats->ackrcv_bad;
1770 stats->dot11RTSFailureCount = mib_stats->rts_bad;
1771 stats->dot11FCSErrorCount = mib_stats->fcs_bad;
1772 stats->dot11RTSSuccessCount = mib_stats->rts_good;
1773
1774 return 0;
1775}
1776
156652bb
BG
1777struct base_eep_header *ath9k_htc_get_eeprom_base(struct ath9k_htc_priv *priv)
1778{
1779 struct base_eep_header *pBase = NULL;
1780 /*
1781 * This can be done since all the 3 EEPROM families have the
1782 * same base header upto a certain point, and we are interested in
1783 * the data only upto that point.
1784 */
1785
1786 if (AR_SREV_9271(priv->ah))
1787 pBase = (struct base_eep_header *)
1788 &priv->ah->eeprom.map4k.baseEepHeader;
1789 else if (priv->ah->hw_version.usbdev == AR9280_USB)
1790 pBase = (struct base_eep_header *)
1791 &priv->ah->eeprom.def.baseEepHeader;
1792 else if (priv->ah->hw_version.usbdev == AR9287_USB)
1793 pBase = (struct base_eep_header *)
1794 &priv->ah->eeprom.map9287.baseEepHeader;
1795 return pBase;
1796}
1797
1798
1799static int ath9k_htc_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant,
1800 u32 *rx_ant)
1801{
1802 struct ath9k_htc_priv *priv = hw->priv;
1803 struct base_eep_header *pBase = ath9k_htc_get_eeprom_base(priv);
1804 if (pBase) {
1805 *tx_ant = pBase->txMask;
1806 *rx_ant = pBase->rxMask;
1807 } else {
1808 *tx_ant = 0;
1809 *rx_ant = 0;
1810 }
1811 return 0;
1812}
1813
fb9987d0
S
1814struct ieee80211_ops ath9k_htc_ops = {
1815 .tx = ath9k_htc_tx,
1816 .start = ath9k_htc_start,
1817 .stop = ath9k_htc_stop,
1818 .add_interface = ath9k_htc_add_interface,
1819 .remove_interface = ath9k_htc_remove_interface,
1820 .config = ath9k_htc_config,
1821 .configure_filter = ath9k_htc_configure_filter,
abd984e6
S
1822 .sta_add = ath9k_htc_sta_add,
1823 .sta_remove = ath9k_htc_sta_remove,
fb9987d0 1824 .conf_tx = ath9k_htc_conf_tx,
69578029 1825 .sta_rc_update = ath9k_htc_sta_rc_update,
fb9987d0
S
1826 .bss_info_changed = ath9k_htc_bss_info_changed,
1827 .set_key = ath9k_htc_set_key,
1828 .get_tsf = ath9k_htc_get_tsf,
1829 .set_tsf = ath9k_htc_set_tsf,
1830 .reset_tsf = ath9k_htc_reset_tsf,
1831 .ampdu_action = ath9k_htc_ampdu_action,
1832 .sw_scan_start = ath9k_htc_sw_scan_start,
1833 .sw_scan_complete = ath9k_htc_sw_scan_complete,
1834 .set_rts_threshold = ath9k_htc_set_rts_threshold,
1835 .rfkill_poll = ath9k_htc_rfkill_poll_state,
1836 .set_coverage_class = ath9k_htc_set_coverage_class,
e2186b7c 1837 .set_bitrate_mask = ath9k_htc_set_bitrate_mask,
5fa71984 1838 .get_stats = ath9k_htc_get_stats,
156652bb 1839 .get_antenna = ath9k_htc_get_antenna,
68185a4b
BG
1840
1841#ifdef CONFIG_ATH9K_HTC_DEBUGFS
1842 .get_et_sset_count = ath9k_htc_get_et_sset_count,
1843 .get_et_stats = ath9k_htc_get_et_stats,
1844 .get_et_strings = ath9k_htc_get_et_strings,
1845#endif
fb9987d0 1846};
This page took 0.525875 seconds and 5 git commands to generate.