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