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