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