]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/net/wireless/ath/ath9k/htc_drv_main.c
ath9k_htc: set probe request rx filter
[net-next-2.6.git] / drivers / net / wireless / ath / ath9k / htc_drv_main.c
CommitLineData
fb9987d0
S
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
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
19#ifdef CONFIG_ATH9K_HTC_DEBUGFS
20static struct dentry *ath9k_debugfs_root;
21#endif
22
23/*************/
24/* Utilities */
25/*************/
26
27static void ath_update_txpow(struct ath9k_htc_priv *priv)
28{
29 struct ath_hw *ah = priv->ah;
fb9987d0
S
30
31 if (priv->curtxpow != priv->txpowlimit) {
32 ath9k_hw_set_txpowerlimit(ah, priv->txpowlimit);
33 /* read back in case value is clamped */
9cc3271f 34 priv->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
fb9987d0
S
35 }
36}
37
38/* HACK Alert: Use 11NG for 2.4, use 11NA for 5 */
39static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv,
40 struct ath9k_channel *ichan)
41{
42 enum htc_phymode mode;
43
44 mode = HTC_MODE_AUTO;
45
46 switch (ichan->chanmode) {
47 case CHANNEL_G:
48 case CHANNEL_G_HT20:
49 case CHANNEL_G_HT40PLUS:
50 case CHANNEL_G_HT40MINUS:
51 mode = HTC_MODE_11NG;
52 break;
53 case CHANNEL_A:
54 case CHANNEL_A_HT20:
55 case CHANNEL_A_HT40PLUS:
56 case CHANNEL_A_HT40MINUS:
57 mode = HTC_MODE_11NA;
58 break;
59 default:
60 break;
61 }
62
63 return mode;
64}
65
bde748a4
VN
66static bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
67 enum ath9k_power_mode mode)
68{
69 bool ret;
70
71 mutex_lock(&priv->htc_pm_lock);
72 ret = ath9k_hw_setpower(priv->ah, mode);
73 mutex_unlock(&priv->htc_pm_lock);
74
75 return ret;
76}
77
78void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv)
79{
80 mutex_lock(&priv->htc_pm_lock);
81 if (++priv->ps_usecount != 1)
82 goto unlock;
83 ath9k_hw_setpower(priv->ah, ATH9K_PM_AWAKE);
84
85unlock:
86 mutex_unlock(&priv->htc_pm_lock);
87}
88
89void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv)
90{
91 mutex_lock(&priv->htc_pm_lock);
92 if (--priv->ps_usecount != 0)
93 goto unlock;
94
8a8572a8
VN
95 if (priv->ps_idle)
96 ath9k_hw_setpower(priv->ah, ATH9K_PM_FULL_SLEEP);
97 else if (priv->ps_enabled)
bde748a4 98 ath9k_hw_setpower(priv->ah, ATH9K_PM_NETWORK_SLEEP);
8a8572a8 99
bde748a4
VN
100unlock:
101 mutex_unlock(&priv->htc_pm_lock);
102}
103
104void ath9k_ps_work(struct work_struct *work)
105{
106 struct ath9k_htc_priv *priv =
107 container_of(work, struct ath9k_htc_priv,
108 ps_work);
109 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
110
111 /* The chip wakes up after receiving the first beacon
112 while network sleep is enabled. For the driver to
113 be in sync with the hw, set the chip to awake and
114 only then set it to sleep.
115 */
116 ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP);
117}
118
fb9987d0
S
119static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
120 struct ieee80211_hw *hw,
121 struct ath9k_channel *hchan)
122{
123 struct ath_hw *ah = priv->ah;
124 struct ath_common *common = ath9k_hw_common(ah);
125 struct ieee80211_conf *conf = &common->hw->conf;
126 bool fastcc = true;
127 struct ieee80211_channel *channel = hw->conf.channel;
20bd2a09 128 struct ath9k_hw_cal_data *caldata;
fb9987d0 129 enum htc_phymode mode;
7f1f5a00 130 __be16 htc_mode;
fb9987d0
S
131 u8 cmd_rsp;
132 int ret;
133
134 if (priv->op_flags & OP_INVALID)
135 return -EIO;
136
137 if (priv->op_flags & OP_FULL_RESET)
138 fastcc = false;
139
bde748a4 140 ath9k_htc_ps_wakeup(priv);
fb9987d0
S
141 htc_stop(priv->htc);
142 WMI_CMD(WMI_DISABLE_INTR_CMDID);
143 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
144 WMI_CMD(WMI_STOP_RECV_CMDID);
145
146 ath_print(common, ATH_DBG_CONFIG,
7cf1f2dd 147 "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n",
fb9987d0 148 priv->ah->curchan->channel,
7cf1f2dd
RM
149 channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf),
150 fastcc);
fb9987d0 151
20bd2a09
FF
152 caldata = &priv->caldata[channel->hw_value];
153 ret = ath9k_hw_reset(ah, hchan, caldata, fastcc);
fb9987d0
S
154 if (ret) {
155 ath_print(common, ATH_DBG_FATAL,
156 "Unable to reset channel (%u Mhz) "
157 "reset status %d\n", channel->center_freq, ret);
158 goto err;
159 }
160
161 ath_update_txpow(priv);
162
163 WMI_CMD(WMI_START_RECV_CMDID);
164 if (ret)
165 goto err;
166
167 ath9k_host_rx_init(priv);
168
169 mode = ath9k_htc_get_curmode(priv, hchan);
170 htc_mode = cpu_to_be16(mode);
171 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
172 if (ret)
173 goto err;
174
175 WMI_CMD(WMI_ENABLE_INTR_CMDID);
176 if (ret)
177 goto err;
178
179 htc_start(priv->htc);
180
181 priv->op_flags &= ~OP_FULL_RESET;
182err:
bde748a4 183 ath9k_htc_ps_restore(priv);
fb9987d0
S
184 return ret;
185}
186
187static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
188{
189 struct ath_common *common = ath9k_hw_common(priv->ah);
190 struct ath9k_htc_target_vif hvif;
191 int ret = 0;
192 u8 cmd_rsp;
193
194 if (priv->nvifs > 0)
195 return -ENOBUFS;
196
197 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
198 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
199
200 hvif.opmode = cpu_to_be32(HTC_M_MONITOR);
201 priv->ah->opmode = NL80211_IFTYPE_MONITOR;
202 hvif.index = priv->nvifs;
203
204 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
205 if (ret)
206 return ret;
207
208 priv->nvifs++;
209 return 0;
210}
211
212static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
213{
214 struct ath_common *common = ath9k_hw_common(priv->ah);
215 struct ath9k_htc_target_vif hvif;
216 int ret = 0;
217 u8 cmd_rsp;
218
219 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
220 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
221 hvif.index = 0; /* Should do for now */
222 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
223 priv->nvifs--;
224
225 return ret;
226}
227
228static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
229 struct ieee80211_vif *vif,
230 struct ieee80211_sta *sta)
231{
232 struct ath_common *common = ath9k_hw_common(priv->ah);
233 struct ath9k_htc_target_sta tsta;
234 struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
235 struct ath9k_htc_sta *ista;
236 int ret;
237 u8 cmd_rsp;
238
239 if (priv->nstations >= ATH9K_HTC_MAX_STA)
240 return -ENOBUFS;
241
242 memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta));
243
244 if (sta) {
245 ista = (struct ath9k_htc_sta *) sta->drv_priv;
246 memcpy(&tsta.macaddr, sta->addr, ETH_ALEN);
247 memcpy(&tsta.bssid, common->curbssid, ETH_ALEN);
248 tsta.associd = common->curaid;
249 tsta.is_vif_sta = 0;
250 tsta.valid = true;
251 ista->index = priv->nstations;
252 } else {
253 memcpy(&tsta.macaddr, vif->addr, ETH_ALEN);
254 tsta.is_vif_sta = 1;
255 }
256
257 tsta.sta_index = priv->nstations;
258 tsta.vif_index = avp->index;
259 tsta.maxampdu = 0xffff;
260 if (sta && sta->ht_cap.ht_supported)
261 tsta.flags = cpu_to_be16(ATH_HTC_STA_HT);
262
263 WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
264 if (ret) {
265 if (sta)
266 ath_print(common, ATH_DBG_FATAL,
267 "Unable to add station entry for: %pM\n", sta->addr);
268 return ret;
269 }
270
271 if (sta)
272 ath_print(common, ATH_DBG_CONFIG,
273 "Added a station entry for: %pM (idx: %d)\n",
274 sta->addr, tsta.sta_index);
275
276 priv->nstations++;
277 return 0;
278}
279
280static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
281 struct ieee80211_vif *vif,
282 struct ieee80211_sta *sta)
283{
284 struct ath_common *common = ath9k_hw_common(priv->ah);
285 struct ath9k_htc_sta *ista;
286 int ret;
287 u8 cmd_rsp, sta_idx;
288
289 if (sta) {
290 ista = (struct ath9k_htc_sta *) sta->drv_priv;
291 sta_idx = ista->index;
292 } else {
293 sta_idx = 0;
294 }
295
296 WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx);
297 if (ret) {
298 if (sta)
299 ath_print(common, ATH_DBG_FATAL,
300 "Unable to remove station entry for: %pM\n",
301 sta->addr);
302 return ret;
303 }
304
305 if (sta)
306 ath_print(common, ATH_DBG_CONFIG,
307 "Removed a station entry for: %pM (idx: %d)\n",
308 sta->addr, sta_idx);
309
310 priv->nstations--;
311 return 0;
312}
313
314static int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv)
315{
316 struct ath9k_htc_cap_target tcap;
317 int ret;
318 u8 cmd_rsp;
319
320 memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target));
321
322 /* FIXME: Values are hardcoded */
323 tcap.flags = 0x240c40;
324 tcap.flags_ext = 0x80601000;
325 tcap.ampdu_limit = 0xffff0000;
326 tcap.ampdu_subframes = 20;
29d9075e 327 tcap.tx_chainmask_legacy = priv->ah->caps.tx_chainmask;
fb9987d0 328 tcap.protmode = 1;
29d9075e 329 tcap.tx_chainmask = priv->ah->caps.tx_chainmask;
fb9987d0
S
330
331 WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap);
332
333 return ret;
334}
335
0d425a7d
S
336static void ath9k_htc_setup_rate(struct ath9k_htc_priv *priv,
337 struct ieee80211_sta *sta,
338 struct ath9k_htc_target_rate *trate)
fb9987d0 339{
fb9987d0
S
340 struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
341 struct ieee80211_supported_band *sband;
fb9987d0 342 u32 caps = 0;
0d425a7d 343 int i, j;
fb9987d0 344
ea46e644 345 sband = priv->hw->wiphy->bands[priv->hw->conf.channel->band];
fb9987d0
S
346
347 for (i = 0, j = 0; i < sband->n_bitrates; i++) {
348 if (sta->supp_rates[sband->band] & BIT(i)) {
0d425a7d 349 trate->rates.legacy_rates.rs_rates[j]
fb9987d0
S
350 = (sband->bitrates[i].bitrate * 2) / 10;
351 j++;
352 }
353 }
0d425a7d 354 trate->rates.legacy_rates.rs_nrates = j;
fb9987d0
S
355
356 if (sta->ht_cap.ht_supported) {
357 for (i = 0, j = 0; i < 77; i++) {
358 if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8)))
0d425a7d 359 trate->rates.ht_rates.rs_rates[j++] = i;
fb9987d0
S
360 if (j == ATH_HTC_RATE_MAX)
361 break;
362 }
0d425a7d 363 trate->rates.ht_rates.rs_nrates = j;
fb9987d0
S
364
365 caps = WLAN_RC_HT_FLAG;
3553727c
FF
366 if (sta->ht_cap.mcs.rx_mask[1])
367 caps |= WLAN_RC_DS_FLAG;
71ba186c
VN
368 if ((sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
369 (conf_is_ht40(&priv->hw->conf)))
fb9987d0 370 caps |= WLAN_RC_40_FLAG;
b4dec5e8
S
371 if (conf_is_ht40(&priv->hw->conf) &&
372 (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40))
373 caps |= WLAN_RC_SGI_FLAG;
374 else if (conf_is_ht20(&priv->hw->conf) &&
375 (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20))
fb9987d0 376 caps |= WLAN_RC_SGI_FLAG;
fb9987d0
S
377 }
378
0d425a7d
S
379 trate->sta_index = ista->index;
380 trate->isnew = 1;
381 trate->capflags = cpu_to_be32(caps);
382}
383
384static int ath9k_htc_send_rate_cmd(struct ath9k_htc_priv *priv,
385 struct ath9k_htc_target_rate *trate)
386{
387 struct ath_common *common = ath9k_hw_common(priv->ah);
388 int ret;
389 u8 cmd_rsp;
fb9987d0 390
0d425a7d 391 WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, trate);
fb9987d0
S
392 if (ret) {
393 ath_print(common, ATH_DBG_FATAL,
394 "Unable to initialize Rate information on target\n");
fb9987d0
S
395 }
396
0d425a7d 397 return ret;
fb9987d0
S
398}
399
0d425a7d
S
400static void ath9k_htc_init_rate(struct ath9k_htc_priv *priv,
401 struct ieee80211_sta *sta)
fb9987d0 402{
fb9987d0 403 struct ath_common *common = ath9k_hw_common(priv->ah);
0d425a7d 404 struct ath9k_htc_target_rate trate;
fb9987d0 405 int ret;
fb9987d0 406
0d425a7d
S
407 memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
408 ath9k_htc_setup_rate(priv, sta, &trate);
409 ret = ath9k_htc_send_rate_cmd(priv, &trate);
410 if (!ret)
411 ath_print(common, ATH_DBG_CONFIG,
412 "Updated target sta: %pM, rate caps: 0x%X\n",
413 sta->addr, be32_to_cpu(trate.capflags));
fb9987d0
S
414}
415
2c76ef89
S
416static void ath9k_htc_update_rate(struct ath9k_htc_priv *priv,
417 struct ieee80211_vif *vif,
418 struct ieee80211_bss_conf *bss_conf)
419{
420 struct ath_common *common = ath9k_hw_common(priv->ah);
421 struct ath9k_htc_target_rate trate;
422 struct ieee80211_sta *sta;
423 int ret;
424
425 memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
426
427 rcu_read_lock();
428 sta = ieee80211_find_sta(vif, bss_conf->bssid);
429 if (!sta) {
430 rcu_read_unlock();
431 return;
432 }
433 ath9k_htc_setup_rate(priv, sta, &trate);
434 rcu_read_unlock();
435
436 ret = ath9k_htc_send_rate_cmd(priv, &trate);
437 if (!ret)
438 ath_print(common, ATH_DBG_CONFIG,
439 "Updated target sta: %pM, rate caps: 0x%X\n",
440 bss_conf->bssid, be32_to_cpu(trate.capflags));
441}
442
9edd9520
LR
443static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv,
444 struct ieee80211_vif *vif,
445 struct ieee80211_sta *sta,
446 enum ieee80211_ampdu_mlme_action action,
447 u16 tid)
fb9987d0
S
448{
449 struct ath_common *common = ath9k_hw_common(priv->ah);
450 struct ath9k_htc_target_aggr aggr;
277a64d1 451 struct ath9k_htc_sta *ista;
fb9987d0
S
452 int ret = 0;
453 u8 cmd_rsp;
454
0730d114 455 if (tid >= ATH9K_HTC_MAX_TID)
fb9987d0
S
456 return -EINVAL;
457
ef98c3cd 458 memset(&aggr, 0, sizeof(struct ath9k_htc_target_aggr));
ef98c3cd 459 ista = (struct ath9k_htc_sta *) sta->drv_priv;
fb9987d0 460
fb9987d0 461 aggr.sta_index = ista->index;
d7ca2139
S
462 aggr.tidno = tid & 0xf;
463 aggr.aggr_enable = (action == IEEE80211_AMPDU_TX_START) ? true : false;
fb9987d0 464
fb9987d0
S
465 WMI_CMD_BUF(WMI_TX_AGGR_ENABLE_CMDID, &aggr);
466 if (ret)
467 ath_print(common, ATH_DBG_CONFIG,
468 "Unable to %s TX aggregation for (%pM, %d)\n",
d7ca2139 469 (aggr.aggr_enable) ? "start" : "stop", sta->addr, tid);
fb9987d0
S
470 else
471 ath_print(common, ATH_DBG_CONFIG,
d7ca2139
S
472 "%s TX aggregation for (%pM, %d)\n",
473 (aggr.aggr_enable) ? "Starting" : "Stopping",
474 sta->addr, tid);
fb9987d0 475
d7ca2139
S
476 spin_lock_bh(&priv->tx_lock);
477 ista->tid_state[tid] = (aggr.aggr_enable && !ret) ? AGGR_START : AGGR_STOP;
478 spin_unlock_bh(&priv->tx_lock);
fb9987d0 479
d7ca2139 480 return ret;
fb9987d0
S
481}
482
483/*********/
484/* DEBUG */
485/*********/
486
487#ifdef CONFIG_ATH9K_HTC_DEBUGFS
488
489static int ath9k_debugfs_open(struct inode *inode, struct file *file)
490{
491 file->private_data = inode->i_private;
492 return 0;
493}
494
495static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf,
496 size_t count, loff_t *ppos)
497{
57674308 498 struct ath9k_htc_priv *priv = file->private_data;
fb9987d0
S
499 struct ath9k_htc_target_stats cmd_rsp;
500 char buf[512];
501 unsigned int len = 0;
502 int ret = 0;
503
504 memset(&cmd_rsp, 0, sizeof(cmd_rsp));
505
506 WMI_CMD(WMI_TGT_STATS_CMDID);
507 if (ret)
508 return -EINVAL;
509
510
511 len += snprintf(buf + len, sizeof(buf) - len,
512 "%19s : %10u\n", "TX Short Retries",
513 be32_to_cpu(cmd_rsp.tx_shortretry));
514 len += snprintf(buf + len, sizeof(buf) - len,
515 "%19s : %10u\n", "TX Long Retries",
516 be32_to_cpu(cmd_rsp.tx_longretry));
517 len += snprintf(buf + len, sizeof(buf) - len,
518 "%19s : %10u\n", "TX Xretries",
519 be32_to_cpu(cmd_rsp.tx_xretries));
520 len += snprintf(buf + len, sizeof(buf) - len,
521 "%19s : %10u\n", "TX Unaggr. Xretries",
522 be32_to_cpu(cmd_rsp.ht_txunaggr_xretry));
523 len += snprintf(buf + len, sizeof(buf) - len,
524 "%19s : %10u\n", "TX Xretries (HT)",
525 be32_to_cpu(cmd_rsp.ht_tx_xretries));
526 len += snprintf(buf + len, sizeof(buf) - len,
527 "%19s : %10u\n", "TX Rate", priv->debug.txrate);
528
9746010b
DC
529 if (len > sizeof(buf))
530 len = sizeof(buf);
531
fb9987d0
S
532 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
533}
534
535static const struct file_operations fops_tgt_stats = {
536 .read = read_file_tgt_stats,
537 .open = ath9k_debugfs_open,
538 .owner = THIS_MODULE
539};
540
541static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
542 size_t count, loff_t *ppos)
543{
57674308 544 struct ath9k_htc_priv *priv = file->private_data;
fb9987d0
S
545 char buf[512];
546 unsigned int len = 0;
547
548 len += snprintf(buf + len, sizeof(buf) - len,
549 "%20s : %10u\n", "Buffers queued",
550 priv->debug.tx_stats.buf_queued);
551 len += snprintf(buf + len, sizeof(buf) - len,
552 "%20s : %10u\n", "Buffers completed",
553 priv->debug.tx_stats.buf_completed);
554 len += snprintf(buf + len, sizeof(buf) - len,
555 "%20s : %10u\n", "SKBs queued",
556 priv->debug.tx_stats.skb_queued);
557 len += snprintf(buf + len, sizeof(buf) - len,
558 "%20s : %10u\n", "SKBs completed",
559 priv->debug.tx_stats.skb_completed);
eac8e385
S
560 len += snprintf(buf + len, sizeof(buf) - len,
561 "%20s : %10u\n", "SKBs dropped",
562 priv->debug.tx_stats.skb_dropped);
fb9987d0 563
2edb4583
S
564 len += snprintf(buf + len, sizeof(buf) - len,
565 "%20s : %10u\n", "BE queued",
566 priv->debug.tx_stats.queue_stats[WME_AC_BE]);
567 len += snprintf(buf + len, sizeof(buf) - len,
568 "%20s : %10u\n", "BK queued",
569 priv->debug.tx_stats.queue_stats[WME_AC_BK]);
570 len += snprintf(buf + len, sizeof(buf) - len,
571 "%20s : %10u\n", "VI queued",
572 priv->debug.tx_stats.queue_stats[WME_AC_VI]);
573 len += snprintf(buf + len, sizeof(buf) - len,
574 "%20s : %10u\n", "VO queued",
575 priv->debug.tx_stats.queue_stats[WME_AC_VO]);
576
9746010b
DC
577 if (len > sizeof(buf))
578 len = sizeof(buf);
579
fb9987d0
S
580 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
581}
582
583static const struct file_operations fops_xmit = {
584 .read = read_file_xmit,
585 .open = ath9k_debugfs_open,
586 .owner = THIS_MODULE
587};
588
589static ssize_t read_file_recv(struct file *file, char __user *user_buf,
590 size_t count, loff_t *ppos)
591{
57674308 592 struct ath9k_htc_priv *priv = file->private_data;
fb9987d0
S
593 char buf[512];
594 unsigned int len = 0;
595
596 len += snprintf(buf + len, sizeof(buf) - len,
597 "%20s : %10u\n", "SKBs allocated",
598 priv->debug.rx_stats.skb_allocated);
599 len += snprintf(buf + len, sizeof(buf) - len,
600 "%20s : %10u\n", "SKBs completed",
601 priv->debug.rx_stats.skb_completed);
602 len += snprintf(buf + len, sizeof(buf) - len,
603 "%20s : %10u\n", "SKBs Dropped",
604 priv->debug.rx_stats.skb_dropped);
605
9746010b
DC
606 if (len > sizeof(buf))
607 len = sizeof(buf);
608
fb9987d0
S
609 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
610}
611
612static const struct file_operations fops_recv = {
613 .read = read_file_recv,
614 .open = ath9k_debugfs_open,
615 .owner = THIS_MODULE
616};
617
e1572c5e 618int ath9k_htc_init_debug(struct ath_hw *ah)
fb9987d0
S
619{
620 struct ath_common *common = ath9k_hw_common(ah);
621 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
622
623 if (!ath9k_debugfs_root)
624 return -ENOENT;
625
626 priv->debug.debugfs_phy = debugfs_create_dir(wiphy_name(priv->hw->wiphy),
627 ath9k_debugfs_root);
628 if (!priv->debug.debugfs_phy)
629 goto err;
630
631 priv->debug.debugfs_tgt_stats = debugfs_create_file("tgt_stats", S_IRUSR,
632 priv->debug.debugfs_phy,
633 priv, &fops_tgt_stats);
634 if (!priv->debug.debugfs_tgt_stats)
635 goto err;
636
637
638 priv->debug.debugfs_xmit = debugfs_create_file("xmit", S_IRUSR,
639 priv->debug.debugfs_phy,
640 priv, &fops_xmit);
641 if (!priv->debug.debugfs_xmit)
642 goto err;
643
644 priv->debug.debugfs_recv = debugfs_create_file("recv", S_IRUSR,
645 priv->debug.debugfs_phy,
646 priv, &fops_recv);
647 if (!priv->debug.debugfs_recv)
648 goto err;
649
650 return 0;
651
652err:
e1572c5e 653 ath9k_htc_exit_debug(ah);
fb9987d0
S
654 return -ENOMEM;
655}
656
e1572c5e 657void ath9k_htc_exit_debug(struct ath_hw *ah)
fb9987d0
S
658{
659 struct ath_common *common = ath9k_hw_common(ah);
660 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
661
662 debugfs_remove(priv->debug.debugfs_recv);
663 debugfs_remove(priv->debug.debugfs_xmit);
664 debugfs_remove(priv->debug.debugfs_tgt_stats);
665 debugfs_remove(priv->debug.debugfs_phy);
666}
667
e1572c5e 668int ath9k_htc_debug_create_root(void)
fb9987d0
S
669{
670 ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
671 if (!ath9k_debugfs_root)
672 return -ENOENT;
673
674 return 0;
675}
676
e1572c5e 677void ath9k_htc_debug_remove_root(void)
fb9987d0
S
678{
679 debugfs_remove(ath9k_debugfs_root);
680 ath9k_debugfs_root = NULL;
681}
682
683#endif /* CONFIG_ATH9K_HTC_DEBUGFS */
684
685/*******/
686/* ANI */
687/*******/
688
689static void ath_start_ani(struct ath9k_htc_priv *priv)
690{
691 struct ath_common *common = ath9k_hw_common(priv->ah);
692 unsigned long timestamp = jiffies_to_msecs(jiffies);
693
694 common->ani.longcal_timer = timestamp;
695 common->ani.shortcal_timer = timestamp;
696 common->ani.checkani_timer = timestamp;
697
698 ieee80211_queue_delayed_work(common->hw, &priv->ath9k_ani_work,
699 msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
700}
701
702void ath9k_ani_work(struct work_struct *work)
703{
704 struct ath9k_htc_priv *priv =
705 container_of(work, struct ath9k_htc_priv,
706 ath9k_ani_work.work);
707 struct ath_hw *ah = priv->ah;
708 struct ath_common *common = ath9k_hw_common(ah);
709 bool longcal = false;
710 bool shortcal = false;
711 bool aniflag = false;
712 unsigned int timestamp = jiffies_to_msecs(jiffies);
713 u32 cal_interval, short_cal_interval;
714
715 short_cal_interval = ATH_STA_SHORT_CALINTERVAL;
716
bde748a4
VN
717 /* Only calibrate if awake */
718 if (ah->power_mode != ATH9K_PM_AWAKE)
719 goto set_timer;
720
fb9987d0
S
721 /* Long calibration runs independently of short calibration. */
722 if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
723 longcal = true;
724 ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
725 common->ani.longcal_timer = timestamp;
726 }
727
728 /* Short calibration applies only while caldone is false */
729 if (!common->ani.caldone) {
730 if ((timestamp - common->ani.shortcal_timer) >=
731 short_cal_interval) {
732 shortcal = true;
733 ath_print(common, ATH_DBG_ANI,
734 "shortcal @%lu\n", jiffies);
735 common->ani.shortcal_timer = timestamp;
736 common->ani.resetcal_timer = timestamp;
737 }
738 } else {
739 if ((timestamp - common->ani.resetcal_timer) >=
740 ATH_RESTART_CALINTERVAL) {
741 common->ani.caldone = ath9k_hw_reset_calvalid(ah);
742 if (common->ani.caldone)
743 common->ani.resetcal_timer = timestamp;
744 }
745 }
746
747 /* Verify whether we must check ANI */
748 if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
749 aniflag = true;
750 common->ani.checkani_timer = timestamp;
751 }
752
753 /* Skip all processing if there's nothing to do. */
754 if (longcal || shortcal || aniflag) {
bde748a4
VN
755
756 ath9k_htc_ps_wakeup(priv);
757
fb9987d0
S
758 /* Call ANI routine if necessary */
759 if (aniflag)
760 ath9k_hw_ani_monitor(ah, ah->curchan);
761
762 /* Perform calibration if necessary */
35ecfe03 763 if (longcal || shortcal)
fb9987d0
S
764 common->ani.caldone =
765 ath9k_hw_calibrate(ah, ah->curchan,
766 common->rx_chainmask,
767 longcal);
768
bde748a4 769 ath9k_htc_ps_restore(priv);
fb9987d0
S
770 }
771
bde748a4 772set_timer:
fb9987d0
S
773 /*
774 * Set timer interval based on previous results.
775 * The interval must be the shortest necessary to satisfy ANI,
776 * short calibration and long calibration.
777 */
778 cal_interval = ATH_LONG_CALINTERVAL;
779 if (priv->ah->config.enable_ani)
780 cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
781 if (!common->ani.caldone)
782 cal_interval = min(cal_interval, (u32)short_cal_interval);
783
784 ieee80211_queue_delayed_work(common->hw, &priv->ath9k_ani_work,
785 msecs_to_jiffies(cal_interval));
786}
787
788/*******/
789/* LED */
790/*******/
791
792static void ath9k_led_blink_work(struct work_struct *work)
793{
794 struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv,
795 ath9k_led_blink_work.work);
796
797 if (!(priv->op_flags & OP_LED_ASSOCIATED))
798 return;
799
800 if ((priv->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
801 (priv->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
802 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
803 else
804 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
805 (priv->op_flags & OP_LED_ON) ? 1 : 0);
806
807 ieee80211_queue_delayed_work(priv->hw,
808 &priv->ath9k_led_blink_work,
809 (priv->op_flags & OP_LED_ON) ?
810 msecs_to_jiffies(priv->led_off_duration) :
811 msecs_to_jiffies(priv->led_on_duration));
812
813 priv->led_on_duration = priv->led_on_cnt ?
814 max((ATH_LED_ON_DURATION_IDLE - priv->led_on_cnt), 25) :
815 ATH_LED_ON_DURATION_IDLE;
816 priv->led_off_duration = priv->led_off_cnt ?
817 max((ATH_LED_OFF_DURATION_IDLE - priv->led_off_cnt), 10) :
818 ATH_LED_OFF_DURATION_IDLE;
819 priv->led_on_cnt = priv->led_off_cnt = 0;
820
821 if (priv->op_flags & OP_LED_ON)
822 priv->op_flags &= ~OP_LED_ON;
823 else
824 priv->op_flags |= OP_LED_ON;
825}
826
827static void ath9k_led_brightness_work(struct work_struct *work)
828{
829 struct ath_led *led = container_of(work, struct ath_led,
830 brightness_work.work);
831 struct ath9k_htc_priv *priv = led->priv;
832
833 switch (led->brightness) {
834 case LED_OFF:
835 if (led->led_type == ATH_LED_ASSOC ||
836 led->led_type == ATH_LED_RADIO) {
837 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
838 (led->led_type == ATH_LED_RADIO));
839 priv->op_flags &= ~OP_LED_ASSOCIATED;
840 if (led->led_type == ATH_LED_RADIO)
841 priv->op_flags &= ~OP_LED_ON;
842 } else {
843 priv->led_off_cnt++;
844 }
845 break;
846 case LED_FULL:
847 if (led->led_type == ATH_LED_ASSOC) {
848 priv->op_flags |= OP_LED_ASSOCIATED;
849 ieee80211_queue_delayed_work(priv->hw,
850 &priv->ath9k_led_blink_work, 0);
851 } else if (led->led_type == ATH_LED_RADIO) {
852 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
853 priv->op_flags |= OP_LED_ON;
854 } else {
855 priv->led_on_cnt++;
856 }
857 break;
858 default:
859 break;
860 }
861}
862
863static void ath9k_led_brightness(struct led_classdev *led_cdev,
864 enum led_brightness brightness)
865{
866 struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
867 struct ath9k_htc_priv *priv = led->priv;
868
869 led->brightness = brightness;
870 if (!(priv->op_flags & OP_LED_DEINIT))
871 ieee80211_queue_delayed_work(priv->hw,
872 &led->brightness_work, 0);
873}
874
875static void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv)
876{
877 cancel_delayed_work_sync(&priv->radio_led.brightness_work);
878 cancel_delayed_work_sync(&priv->assoc_led.brightness_work);
879 cancel_delayed_work_sync(&priv->tx_led.brightness_work);
880 cancel_delayed_work_sync(&priv->rx_led.brightness_work);
881}
882
883static int ath9k_register_led(struct ath9k_htc_priv *priv, struct ath_led *led,
884 char *trigger)
885{
886 int ret;
887
888 led->priv = priv;
889 led->led_cdev.name = led->name;
890 led->led_cdev.default_trigger = trigger;
891 led->led_cdev.brightness_set = ath9k_led_brightness;
892
893 ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_cdev);
894 if (ret)
895 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
896 "Failed to register led:%s", led->name);
897 else
898 led->registered = 1;
899
900 INIT_DELAYED_WORK(&led->brightness_work, ath9k_led_brightness_work);
901
902 return ret;
903}
904
905static void ath9k_unregister_led(struct ath_led *led)
906{
907 if (led->registered) {
908 led_classdev_unregister(&led->led_cdev);
909 led->registered = 0;
910 }
911}
912
913void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
914{
915 priv->op_flags |= OP_LED_DEINIT;
916 ath9k_unregister_led(&priv->assoc_led);
917 priv->op_flags &= ~OP_LED_ASSOCIATED;
918 ath9k_unregister_led(&priv->tx_led);
919 ath9k_unregister_led(&priv->rx_led);
920 ath9k_unregister_led(&priv->radio_led);
fb9987d0
S
921}
922
923void ath9k_init_leds(struct ath9k_htc_priv *priv)
924{
925 char *trigger;
926 int ret;
927
928 if (AR_SREV_9287(priv->ah))
929 priv->ah->led_pin = ATH_LED_PIN_9287;
930 else if (AR_SREV_9271(priv->ah))
931 priv->ah->led_pin = ATH_LED_PIN_9271;
88c1f4f6
S
932 else if (AR_DEVID_7010(priv->ah))
933 priv->ah->led_pin = ATH_LED_PIN_7010;
fb9987d0
S
934 else
935 priv->ah->led_pin = ATH_LED_PIN_DEF;
936
937 /* Configure gpio 1 for output */
938 ath9k_hw_cfg_output(priv->ah, priv->ah->led_pin,
939 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
940 /* LED off, active low */
941 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1);
942
943 INIT_DELAYED_WORK(&priv->ath9k_led_blink_work, ath9k_led_blink_work);
944
945 trigger = ieee80211_get_radio_led_name(priv->hw);
946 snprintf(priv->radio_led.name, sizeof(priv->radio_led.name),
947 "ath9k-%s::radio", wiphy_name(priv->hw->wiphy));
948 ret = ath9k_register_led(priv, &priv->radio_led, trigger);
949 priv->radio_led.led_type = ATH_LED_RADIO;
950 if (ret)
951 goto fail;
952
953 trigger = ieee80211_get_assoc_led_name(priv->hw);
954 snprintf(priv->assoc_led.name, sizeof(priv->assoc_led.name),
955 "ath9k-%s::assoc", wiphy_name(priv->hw->wiphy));
956 ret = ath9k_register_led(priv, &priv->assoc_led, trigger);
957 priv->assoc_led.led_type = ATH_LED_ASSOC;
958 if (ret)
959 goto fail;
960
961 trigger = ieee80211_get_tx_led_name(priv->hw);
962 snprintf(priv->tx_led.name, sizeof(priv->tx_led.name),
963 "ath9k-%s::tx", wiphy_name(priv->hw->wiphy));
964 ret = ath9k_register_led(priv, &priv->tx_led, trigger);
965 priv->tx_led.led_type = ATH_LED_TX;
966 if (ret)
967 goto fail;
968
969 trigger = ieee80211_get_rx_led_name(priv->hw);
970 snprintf(priv->rx_led.name, sizeof(priv->rx_led.name),
971 "ath9k-%s::rx", wiphy_name(priv->hw->wiphy));
972 ret = ath9k_register_led(priv, &priv->rx_led, trigger);
973 priv->rx_led.led_type = ATH_LED_RX;
974 if (ret)
975 goto fail;
976
977 priv->op_flags &= ~OP_LED_DEINIT;
978
979 return;
980
981fail:
982 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
983 ath9k_deinit_leds(priv);
984}
985
986/*******************/
987/* Rfkill */
988/*******************/
989
990static bool ath_is_rfkill_set(struct ath9k_htc_priv *priv)
991{
992 return ath9k_hw_gpio_get(priv->ah, priv->ah->rfkill_gpio) ==
993 priv->ah->rfkill_polarity;
994}
995
996static void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw)
997{
998 struct ath9k_htc_priv *priv = hw->priv;
999 bool blocked = !!ath_is_rfkill_set(priv);
1000
1001 wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
1002}
1003
1004void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv)
1005{
1006 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
1007 wiphy_rfkill_start_polling(priv->hw->wiphy);
1008}
1009
881ac6a5
S
1010static void ath9k_htc_radio_enable(struct ieee80211_hw *hw)
1011{
1012 struct ath9k_htc_priv *priv = hw->priv;
1013 struct ath_hw *ah = priv->ah;
1014 struct ath_common *common = ath9k_hw_common(ah);
1015 int ret;
1016 u8 cmd_rsp;
1017
1018 if (!ah->curchan)
1019 ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
1020
1021 /* Reset the HW */
20bd2a09 1022 ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
881ac6a5
S
1023 if (ret) {
1024 ath_print(common, ATH_DBG_FATAL,
1025 "Unable to reset hardware; reset status %d "
1026 "(freq %u MHz)\n", ret, ah->curchan->channel);
1027 }
1028
1029 ath_update_txpow(priv);
1030
1031 /* Start RX */
1032 WMI_CMD(WMI_START_RECV_CMDID);
1033 ath9k_host_rx_init(priv);
1034
1035 /* Start TX */
1036 htc_start(priv->htc);
1037 spin_lock_bh(&priv->tx_lock);
1038 priv->tx_queues_stop = false;
1039 spin_unlock_bh(&priv->tx_lock);
1040 ieee80211_wake_queues(hw);
1041
1042 WMI_CMD(WMI_ENABLE_INTR_CMDID);
1043
1044 /* Enable LED */
1045 ath9k_hw_cfg_output(ah, ah->led_pin,
1046 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
1047 ath9k_hw_set_gpio(ah, ah->led_pin, 0);
1048}
1049
1050static void ath9k_htc_radio_disable(struct ieee80211_hw *hw)
1051{
1052 struct ath9k_htc_priv *priv = hw->priv;
1053 struct ath_hw *ah = priv->ah;
1054 struct ath_common *common = ath9k_hw_common(ah);
1055 int ret;
1056 u8 cmd_rsp;
1057
1058 ath9k_htc_ps_wakeup(priv);
1059
1060 /* Disable LED */
1061 ath9k_hw_set_gpio(ah, ah->led_pin, 1);
1062 ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
1063
1064 WMI_CMD(WMI_DISABLE_INTR_CMDID);
1065
1066 /* Stop TX */
1067 ieee80211_stop_queues(hw);
1068 htc_stop(priv->htc);
1069 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
1070 skb_queue_purge(&priv->tx_queue);
1071
1072 /* Stop RX */
1073 WMI_CMD(WMI_STOP_RECV_CMDID);
1074
21d5130b
S
1075 /*
1076 * The MIB counters have to be disabled here,
1077 * since the target doesn't do it.
1078 */
1079 ath9k_hw_disable_mib_counters(ah);
1080
881ac6a5
S
1081 if (!ah->curchan)
1082 ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
1083
1084 /* Reset the HW */
20bd2a09 1085 ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
881ac6a5
S
1086 if (ret) {
1087 ath_print(common, ATH_DBG_FATAL,
1088 "Unable to reset hardware; reset status %d "
1089 "(freq %u MHz)\n", ret, ah->curchan->channel);
1090 }
1091
1092 /* Disable the PHY */
1093 ath9k_hw_phy_disable(ah);
1094
1095 ath9k_htc_ps_restore(priv);
1096 ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
1097}
1098
fb9987d0
S
1099/**********************/
1100/* mac80211 Callbacks */
1101/**********************/
1102
1103static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
1104{
1105 struct ieee80211_hdr *hdr;
1106 struct ath9k_htc_priv *priv = hw->priv;
7757dfed 1107 int padpos, padsize, ret;
fb9987d0
S
1108
1109 hdr = (struct ieee80211_hdr *) skb->data;
1110
1111 /* Add the padding after the header if this is not already done */
1112 padpos = ath9k_cmn_padpos(hdr->frame_control);
1113 padsize = padpos & 3;
1114 if (padsize && skb->len > padpos) {
1115 if (skb_headroom(skb) < padsize)
1116 return -1;
1117 skb_push(skb, padsize);
1118 memmove(skb->data, skb->data + padsize, padpos);
1119 }
1120
7757dfed
S
1121 ret = ath9k_htc_tx_start(priv, skb);
1122 if (ret != 0) {
1123 if (ret == -ENOMEM) {
1124 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
1125 "Stopping TX queues\n");
1126 ieee80211_stop_queues(hw);
1127 spin_lock_bh(&priv->tx_lock);
1128 priv->tx_queues_stop = true;
1129 spin_unlock_bh(&priv->tx_lock);
1130 } else {
1131 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
1132 "Tx failed");
1133 }
fb9987d0
S
1134 goto fail_tx;
1135 }
1136
1137 return 0;
1138
1139fail_tx:
1140 dev_kfree_skb_any(skb);
1141 return 0;
1142}
1143
881ac6a5 1144static int ath9k_htc_start(struct ieee80211_hw *hw)
fb9987d0
S
1145{
1146 struct ath9k_htc_priv *priv = hw->priv;
1147 struct ath_hw *ah = priv->ah;
1148 struct ath_common *common = ath9k_hw_common(ah);
1149 struct ieee80211_channel *curchan = hw->conf.channel;
1150 struct ath9k_channel *init_channel;
1151 int ret = 0;
1152 enum htc_phymode mode;
7f1f5a00 1153 __be16 htc_mode;
fb9987d0
S
1154 u8 cmd_rsp;
1155
881ac6a5
S
1156 mutex_lock(&priv->mutex);
1157
fb9987d0
S
1158 ath_print(common, ATH_DBG_CONFIG,
1159 "Starting driver with initial channel: %d MHz\n",
1160 curchan->center_freq);
1161
21d5130b
S
1162 /* Ensure that HW is awake before flushing RX */
1163 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
1164 WMI_CMD(WMI_FLUSH_RECV_CMDID);
1165
fb9987d0
S
1166 /* setup initial channel */
1167 init_channel = ath9k_cmn_get_curchannel(hw, ah);
1168
1169 /* Reset SERDES registers */
1170 ath9k_hw_configpcipowersave(ah, 0, 0);
1171
1172 ath9k_hw_htc_resetinit(ah);
20bd2a09 1173 ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
fb9987d0
S
1174 if (ret) {
1175 ath_print(common, ATH_DBG_FATAL,
1176 "Unable to reset hardware; reset status %d "
1177 "(freq %u MHz)\n", ret, curchan->center_freq);
881ac6a5 1178 mutex_unlock(&priv->mutex);
8a8572a8 1179 return ret;
fb9987d0
S
1180 }
1181
1182 ath_update_txpow(priv);
1183
1184 mode = ath9k_htc_get_curmode(priv, init_channel);
1185 htc_mode = cpu_to_be16(mode);
1186 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
fb9987d0 1187 WMI_CMD(WMI_ATH_INIT_CMDID);
fb9987d0 1188 WMI_CMD(WMI_START_RECV_CMDID);
fb9987d0
S
1189
1190 ath9k_host_rx_init(priv);
1191
1192 priv->op_flags &= ~OP_INVALID;
1193 htc_start(priv->htc);
1194
7757dfed
S
1195 spin_lock_bh(&priv->tx_lock);
1196 priv->tx_queues_stop = false;
1197 spin_unlock_bh(&priv->tx_lock);
1198
1199 ieee80211_wake_queues(hw);
1200
21cb9879
VN
1201 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) {
1202 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
1203 AR_STOMP_LOW_WLAN_WGHT);
1204 ath9k_hw_btcoex_enable(ah);
1205 ath_htc_resume_btcoex_work(priv);
1206 }
fb9987d0 1207 mutex_unlock(&priv->mutex);
8a8572a8 1208
fb9987d0
S
1209 return ret;
1210}
1211
881ac6a5 1212static void ath9k_htc_stop(struct ieee80211_hw *hw)
fb9987d0
S
1213{
1214 struct ath9k_htc_priv *priv = hw->priv;
1215 struct ath_hw *ah = priv->ah;
1216 struct ath_common *common = ath9k_hw_common(ah);
1217 int ret = 0;
1218 u8 cmd_rsp;
1219
881ac6a5
S
1220 mutex_lock(&priv->mutex);
1221
fb9987d0
S
1222 if (priv->op_flags & OP_INVALID) {
1223 ath_print(common, ATH_DBG_ANY, "Device not present\n");
881ac6a5 1224 mutex_unlock(&priv->mutex);
fb9987d0
S
1225 return;
1226 }
1227
7073daa6
S
1228 /* Cancel all the running timers/work .. */
1229 cancel_work_sync(&priv->ps_work);
7073daa6
S
1230 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
1231 ath9k_led_stop_brightness(priv);
1232
bde748a4 1233 ath9k_htc_ps_wakeup(priv);
fb9987d0
S
1234 htc_stop(priv->htc);
1235 WMI_CMD(WMI_DISABLE_INTR_CMDID);
1236 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
1237 WMI_CMD(WMI_STOP_RECV_CMDID);
fb9987d0
S
1238 skb_queue_purge(&priv->tx_queue);
1239
1240 /* Remove monitor interface here */
1241 if (ah->opmode == NL80211_IFTYPE_MONITOR) {
1242 if (ath9k_htc_remove_monitor_interface(priv))
1243 ath_print(common, ATH_DBG_FATAL,
1244 "Unable to remove monitor interface\n");
1245 else
1246 ath_print(common, ATH_DBG_CONFIG,
1247 "Monitor interface removed\n");
1248 }
1249
21cb9879
VN
1250 if (ah->btcoex_hw.enabled) {
1251 ath9k_hw_btcoex_disable(ah);
1252 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
1253 ath_htc_cancel_btcoex_work(priv);
1254 }
1255
e9201f09
S
1256 ath9k_hw_phy_disable(ah);
1257 ath9k_hw_disable(ah);
1258 ath9k_hw_configpcipowersave(ah, 1, 1);
1259 ath9k_htc_ps_restore(priv);
1260 ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
1261
fb9987d0 1262 priv->op_flags |= OP_INVALID;
fb9987d0
S
1263
1264 ath_print(common, ATH_DBG_CONFIG, "Driver halt\n");
8a8572a8
VN
1265 mutex_unlock(&priv->mutex);
1266}
1267
fb9987d0
S
1268static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1269 struct ieee80211_vif *vif)
1270{
1271 struct ath9k_htc_priv *priv = hw->priv;
1272 struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1273 struct ath_common *common = ath9k_hw_common(priv->ah);
1274 struct ath9k_htc_target_vif hvif;
1275 int ret = 0;
1276 u8 cmd_rsp;
1277
1278 mutex_lock(&priv->mutex);
1279
1280 /* Only one interface for now */
1281 if (priv->nvifs > 0) {
1282 ret = -ENOBUFS;
1283 goto out;
1284 }
1285
bde748a4 1286 ath9k_htc_ps_wakeup(priv);
fb9987d0
S
1287 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
1288 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
1289
1290 switch (vif->type) {
1291 case NL80211_IFTYPE_STATION:
1292 hvif.opmode = cpu_to_be32(HTC_M_STA);
1293 break;
1294 case NL80211_IFTYPE_ADHOC:
1295 hvif.opmode = cpu_to_be32(HTC_M_IBSS);
1296 break;
1297 default:
1298 ath_print(common, ATH_DBG_FATAL,
1299 "Interface type %d not yet supported\n", vif->type);
1300 ret = -EOPNOTSUPP;
1301 goto out;
1302 }
1303
1304 ath_print(common, ATH_DBG_CONFIG,
1305 "Attach a VIF of type: %d\n", vif->type);
1306
1307 priv->ah->opmode = vif->type;
1308
1309 /* Index starts from zero on the target */
1310 avp->index = hvif.index = priv->nvifs;
1311 hvif.rtsthreshold = cpu_to_be16(2304);
1312 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
1313 if (ret)
1314 goto out;
1315
1316 priv->nvifs++;
1317
1318 /*
1319 * We need a node in target to tx mgmt frames
1320 * before association.
1321 */
1322 ret = ath9k_htc_add_station(priv, vif, NULL);
1323 if (ret)
1324 goto out;
1325
1326 ret = ath9k_htc_update_cap_target(priv);
1327 if (ret)
1328 ath_print(common, ATH_DBG_CONFIG, "Failed to update"
1329 " capability in target \n");
1330
1331 priv->vif = vif;
1332out:
bde748a4 1333 ath9k_htc_ps_restore(priv);
fb9987d0 1334 mutex_unlock(&priv->mutex);
cb551df2 1335
fb9987d0
S
1336 return ret;
1337}
1338
1339static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
1340 struct ieee80211_vif *vif)
1341{
1342 struct ath9k_htc_priv *priv = hw->priv;
1343 struct ath_common *common = ath9k_hw_common(priv->ah);
1344 struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1345 struct ath9k_htc_target_vif hvif;
1346 int ret = 0;
1347 u8 cmd_rsp;
1348
1349 ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n");
1350
1351 mutex_lock(&priv->mutex);
cb551df2 1352 ath9k_htc_ps_wakeup(priv);
fb9987d0
S
1353
1354 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
1355 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
1356 hvif.index = avp->index;
1357 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
1358 priv->nvifs--;
1359
1360 ath9k_htc_remove_station(priv, vif, NULL);
fb9987d0
S
1361 priv->vif = NULL;
1362
cb551df2 1363 ath9k_htc_ps_restore(priv);
fb9987d0
S
1364 mutex_unlock(&priv->mutex);
1365}
1366
1367static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
1368{
1369 struct ath9k_htc_priv *priv = hw->priv;
1370 struct ath_common *common = ath9k_hw_common(priv->ah);
1371 struct ieee80211_conf *conf = &hw->conf;
1372
1373 mutex_lock(&priv->mutex);
1374
8a8572a8
VN
1375 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1376 bool enable_radio = false;
1377 bool idle = !!(conf->flags & IEEE80211_CONF_IDLE);
1378
23367769 1379 mutex_lock(&priv->htc_pm_lock);
8a8572a8
VN
1380 if (!idle && priv->ps_idle)
1381 enable_radio = true;
8a8572a8 1382 priv->ps_idle = idle;
23367769 1383 mutex_unlock(&priv->htc_pm_lock);
8a8572a8
VN
1384
1385 if (enable_radio) {
8a8572a8
VN
1386 ath_print(common, ATH_DBG_CONFIG,
1387 "not-idle: enabling radio\n");
23367769
S
1388 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
1389 ath9k_htc_radio_enable(hw);
8a8572a8
VN
1390 }
1391 }
1392
fb9987d0
S
1393 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1394 struct ieee80211_channel *curchan = hw->conf.channel;
1395 int pos = curchan->hw_value;
fb9987d0
S
1396
1397 ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
1398 curchan->center_freq);
1399
fb9987d0
S
1400 ath9k_cmn_update_ichannel(hw, &priv->ah->channels[pos]);
1401
1402 if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) {
1403 ath_print(common, ATH_DBG_FATAL,
1404 "Unable to set channel\n");
1405 mutex_unlock(&priv->mutex);
1406 return -EINVAL;
1407 }
1408
1409 }
bde748a4
VN
1410 if (changed & IEEE80211_CONF_CHANGE_PS) {
1411 if (conf->flags & IEEE80211_CONF_PS) {
1412 ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP);
1413 priv->ps_enabled = true;
1414 } else {
1415 priv->ps_enabled = false;
1416 cancel_work_sync(&priv->ps_work);
1417 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
1418 }
1419 }
fb9987d0
S
1420
1421 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
1422 if (conf->flags & IEEE80211_CONF_MONITOR) {
1423 if (ath9k_htc_add_monitor_interface(priv))
1424 ath_print(common, ATH_DBG_FATAL,
1425 "Failed to set monitor mode\n");
1426 else
1427 ath_print(common, ATH_DBG_CONFIG,
1428 "HW opmode set to Monitor mode\n");
1429 }
1430 }
1431
23367769
S
1432 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1433 mutex_lock(&priv->htc_pm_lock);
1434 if (!priv->ps_idle) {
1435 mutex_unlock(&priv->htc_pm_lock);
1436 goto out;
1437 }
1438 mutex_unlock(&priv->htc_pm_lock);
1439
8a8572a8
VN
1440 ath_print(common, ATH_DBG_CONFIG,
1441 "idle: disabling radio\n");
881ac6a5 1442 ath9k_htc_radio_disable(hw);
8a8572a8
VN
1443 }
1444
23367769 1445out:
fb9987d0 1446 mutex_unlock(&priv->mutex);
fb9987d0
S
1447 return 0;
1448}
1449
1450#define SUPPORTED_FILTERS \
1451 (FIF_PROMISC_IN_BSS | \
1452 FIF_ALLMULTI | \
1453 FIF_CONTROL | \
1454 FIF_PSPOLL | \
1455 FIF_OTHER_BSS | \
1456 FIF_BCN_PRBRESP_PROMISC | \
94a40c0c 1457 FIF_PROBE_REQ | \
fb9987d0
S
1458 FIF_FCSFAIL)
1459
1460static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
1461 unsigned int changed_flags,
1462 unsigned int *total_flags,
1463 u64 multicast)
1464{
1465 struct ath9k_htc_priv *priv = hw->priv;
1466 u32 rfilt;
1467
1468 mutex_lock(&priv->mutex);
bde748a4 1469 ath9k_htc_ps_wakeup(priv);
cb551df2 1470
fb9987d0
S
1471 changed_flags &= SUPPORTED_FILTERS;
1472 *total_flags &= SUPPORTED_FILTERS;
1473
1474 priv->rxfilter = *total_flags;
0995d110 1475 rfilt = ath9k_htc_calcrxfilter(priv);
fb9987d0
S
1476 ath9k_hw_setrxfilter(priv->ah, rfilt);
1477
1478 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_CONFIG,
1479 "Set HW RX filter: 0x%x\n", rfilt);
1480
bde748a4 1481 ath9k_htc_ps_restore(priv);
fb9987d0
S
1482 mutex_unlock(&priv->mutex);
1483}
1484
abd984e6
S
1485static int ath9k_htc_sta_add(struct ieee80211_hw *hw,
1486 struct ieee80211_vif *vif,
1487 struct ieee80211_sta *sta)
fb9987d0
S
1488{
1489 struct ath9k_htc_priv *priv = hw->priv;
1490 int ret;
1491
05a30f9c 1492 mutex_lock(&priv->mutex);
cb551df2 1493 ath9k_htc_ps_wakeup(priv);
abd984e6
S
1494 ret = ath9k_htc_add_station(priv, vif, sta);
1495 if (!ret)
1496 ath9k_htc_init_rate(priv, sta);
1497 ath9k_htc_ps_restore(priv);
1498 mutex_unlock(&priv->mutex);
05a30f9c 1499
abd984e6
S
1500 return ret;
1501}
1502
1503static int ath9k_htc_sta_remove(struct ieee80211_hw *hw,
1504 struct ieee80211_vif *vif,
1505 struct ieee80211_sta *sta)
1506{
1507 struct ath9k_htc_priv *priv = hw->priv;
1508 int ret;
05a30f9c 1509
abd984e6
S
1510 mutex_lock(&priv->mutex);
1511 ath9k_htc_ps_wakeup(priv);
1512 ret = ath9k_htc_remove_station(priv, vif, sta);
cb551df2 1513 ath9k_htc_ps_restore(priv);
05a30f9c 1514 mutex_unlock(&priv->mutex);
abd984e6
S
1515
1516 return ret;
fb9987d0
S
1517}
1518
1519static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, u16 queue,
1520 const struct ieee80211_tx_queue_params *params)
1521{
1522 struct ath9k_htc_priv *priv = hw->priv;
1523 struct ath_common *common = ath9k_hw_common(priv->ah);
1524 struct ath9k_tx_queue_info qi;
1525 int ret = 0, qnum;
1526
1527 if (queue >= WME_NUM_AC)
1528 return 0;
1529
1530 mutex_lock(&priv->mutex);
cb551df2 1531 ath9k_htc_ps_wakeup(priv);
fb9987d0
S
1532
1533 memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
1534
1535 qi.tqi_aifs = params->aifs;
1536 qi.tqi_cwmin = params->cw_min;
1537 qi.tqi_cwmax = params->cw_max;
1538 qi.tqi_burstTime = params->txop;
1539
1540 qnum = get_hw_qnum(queue, priv->hwq_map);
1541
1542 ath_print(common, ATH_DBG_CONFIG,
1543 "Configure tx [queue/hwq] [%d/%d], "
1544 "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
1545 queue, qnum, params->aifs, params->cw_min,
1546 params->cw_max, params->txop);
1547
e1572c5e 1548 ret = ath_htc_txq_update(priv, qnum, &qi);
764580f5 1549 if (ret) {
fb9987d0 1550 ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n");
764580f5
S
1551 goto out;
1552 }
fb9987d0 1553
764580f5 1554 if ((priv->ah->opmode == NL80211_IFTYPE_ADHOC) &&
e8c35a77 1555 (qnum == priv->hwq_map[WME_AC_BE]))
764580f5
S
1556 ath9k_htc_beaconq_config(priv);
1557out:
cb551df2 1558 ath9k_htc_ps_restore(priv);
fb9987d0
S
1559 mutex_unlock(&priv->mutex);
1560
1561 return ret;
1562}
1563
1564static int ath9k_htc_set_key(struct ieee80211_hw *hw,
1565 enum set_key_cmd cmd,
1566 struct ieee80211_vif *vif,
1567 struct ieee80211_sta *sta,
1568 struct ieee80211_key_conf *key)
1569{
1570 struct ath9k_htc_priv *priv = hw->priv;
1571 struct ath_common *common = ath9k_hw_common(priv->ah);
1572 int ret = 0;
1573
e1572c5e 1574 if (htc_modparam_nohwcrypt)
fb9987d0
S
1575 return -ENOSPC;
1576
1577 mutex_lock(&priv->mutex);
1578 ath_print(common, ATH_DBG_CONFIG, "Set HW Key\n");
bde748a4 1579 ath9k_htc_ps_wakeup(priv);
fb9987d0
S
1580
1581 switch (cmd) {
1582 case SET_KEY:
040e539e 1583 ret = ath_key_config(common, vif, sta, key);
fb9987d0
S
1584 if (ret >= 0) {
1585 key->hw_key_idx = ret;
1586 /* push IV and Michael MIC generation to stack */
1587 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
97359d12 1588 if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
fb9987d0 1589 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
97359d12
JB
1590 if (priv->ah->sw_mgmt_crypto &&
1591 key->cipher == WLAN_CIPHER_SUITE_CCMP)
fb9987d0
S
1592 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
1593 ret = 0;
1594 }
1595 break;
1596 case DISABLE_KEY:
040e539e 1597 ath_key_delete(common, key);
fb9987d0
S
1598 break;
1599 default:
1600 ret = -EINVAL;
1601 }
1602
bde748a4 1603 ath9k_htc_ps_restore(priv);
fb9987d0
S
1604 mutex_unlock(&priv->mutex);
1605
1606 return ret;
1607}
1608
1609static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
1610 struct ieee80211_vif *vif,
1611 struct ieee80211_bss_conf *bss_conf,
1612 u32 changed)
1613{
1614 struct ath9k_htc_priv *priv = hw->priv;
1615 struct ath_hw *ah = priv->ah;
1616 struct ath_common *common = ath9k_hw_common(ah);
1617
1618 mutex_lock(&priv->mutex);
bde748a4 1619 ath9k_htc_ps_wakeup(priv);
fb9987d0
S
1620
1621 if (changed & BSS_CHANGED_ASSOC) {
1622 common->curaid = bss_conf->assoc ?
1623 bss_conf->aid : 0;
1624 ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
1625 bss_conf->assoc);
1626
1627 if (bss_conf->assoc) {
1628 priv->op_flags |= OP_ASSOCIATED;
1629 ath_start_ani(priv);
1630 } else {
1631 priv->op_flags &= ~OP_ASSOCIATED;
1632 cancel_delayed_work_sync(&priv->ath9k_ani_work);
1633 }
1634 }
1635
1636 if (changed & BSS_CHANGED_BSSID) {
1637 /* Set BSSID */
1638 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1639 ath9k_hw_write_associd(ah);
1640
1641 ath_print(common, ATH_DBG_CONFIG,
1642 "BSSID: %pM aid: 0x%x\n",
1643 common->curbssid, common->curaid);
1644 }
1645
1646 if ((changed & BSS_CHANGED_BEACON_INT) ||
1647 (changed & BSS_CHANGED_BEACON) ||
1648 ((changed & BSS_CHANGED_BEACON_ENABLED) &&
1649 bss_conf->enable_beacon)) {
1650 priv->op_flags |= OP_ENABLE_BEACON;
1c3652a5 1651 ath9k_htc_beacon_config(priv, vif);
fb9987d0
S
1652 }
1653
fb9987d0
S
1654 if ((changed & BSS_CHANGED_BEACON_ENABLED) &&
1655 !bss_conf->enable_beacon) {
1656 priv->op_flags &= ~OP_ENABLE_BEACON;
1c3652a5 1657 ath9k_htc_beacon_config(priv, vif);
fb9987d0
S
1658 }
1659
1660 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
1661 ath_print(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
1662 bss_conf->use_short_preamble);
1663 if (bss_conf->use_short_preamble)
1664 priv->op_flags |= OP_PREAMBLE_SHORT;
1665 else
1666 priv->op_flags &= ~OP_PREAMBLE_SHORT;
1667 }
1668
1669 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
1670 ath_print(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n",
1671 bss_conf->use_cts_prot);
1672 if (bss_conf->use_cts_prot &&
1673 hw->conf.channel->band != IEEE80211_BAND_5GHZ)
1674 priv->op_flags |= OP_PROTECT_ENABLE;
1675 else
1676 priv->op_flags &= ~OP_PROTECT_ENABLE;
1677 }
1678
1679 if (changed & BSS_CHANGED_ERP_SLOT) {
1680 if (bss_conf->use_short_slot)
1681 ah->slottime = 9;
1682 else
1683 ah->slottime = 20;
1684
1685 ath9k_hw_init_global_settings(ah);
1686 }
1687
2c76ef89
S
1688 if (changed & BSS_CHANGED_HT)
1689 ath9k_htc_update_rate(priv, vif, bss_conf);
1690
bde748a4 1691 ath9k_htc_ps_restore(priv);
fb9987d0
S
1692 mutex_unlock(&priv->mutex);
1693}
1694
1695static u64 ath9k_htc_get_tsf(struct ieee80211_hw *hw)
1696{
1697 struct ath9k_htc_priv *priv = hw->priv;
1698 u64 tsf;
1699
1700 mutex_lock(&priv->mutex);
cb551df2 1701 ath9k_htc_ps_wakeup(priv);
fb9987d0 1702 tsf = ath9k_hw_gettsf64(priv->ah);
cb551df2 1703 ath9k_htc_ps_restore(priv);
fb9987d0
S
1704 mutex_unlock(&priv->mutex);
1705
1706 return tsf;
1707}
1708
1709static void ath9k_htc_set_tsf(struct ieee80211_hw *hw, u64 tsf)
1710{
1711 struct ath9k_htc_priv *priv = hw->priv;
1712
1713 mutex_lock(&priv->mutex);
cb551df2 1714 ath9k_htc_ps_wakeup(priv);
fb9987d0 1715 ath9k_hw_settsf64(priv->ah, tsf);
cb551df2 1716 ath9k_htc_ps_restore(priv);
fb9987d0
S
1717 mutex_unlock(&priv->mutex);
1718}
1719
1720static void ath9k_htc_reset_tsf(struct ieee80211_hw *hw)
1721{
1722 struct ath9k_htc_priv *priv = hw->priv;
1723
1724 mutex_lock(&priv->mutex);
cb551df2 1725 ath9k_htc_ps_wakeup(priv);
fb9987d0 1726 ath9k_hw_reset_tsf(priv->ah);
bde748a4 1727 ath9k_htc_ps_restore(priv);
cb551df2 1728 mutex_unlock(&priv->mutex);
fb9987d0
S
1729}
1730
1731static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
1732 struct ieee80211_vif *vif,
1733 enum ieee80211_ampdu_mlme_action action,
1734 struct ieee80211_sta *sta,
1735 u16 tid, u16 *ssn)
1736{
1737 struct ath9k_htc_priv *priv = hw->priv;
fb9987d0 1738 struct ath9k_htc_sta *ista;
d7ca2139 1739 int ret = 0;
fb9987d0
S
1740
1741 switch (action) {
1742 case IEEE80211_AMPDU_RX_START:
1743 break;
1744 case IEEE80211_AMPDU_RX_STOP:
1745 break;
1746 case IEEE80211_AMPDU_TX_START:
d7ca2139
S
1747 ret = ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid);
1748 if (!ret)
1749 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1750 break;
fb9987d0 1751 case IEEE80211_AMPDU_TX_STOP:
d7ca2139
S
1752 ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid);
1753 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
fb9987d0
S
1754 break;
1755 case IEEE80211_AMPDU_TX_OPERATIONAL:
1756 ista = (struct ath9k_htc_sta *) sta->drv_priv;
d7ca2139 1757 spin_lock_bh(&priv->tx_lock);
fb9987d0 1758 ista->tid_state[tid] = AGGR_OPERATIONAL;
d7ca2139 1759 spin_unlock_bh(&priv->tx_lock);
fb9987d0
S
1760 break;
1761 default:
1762 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
1763 "Unknown AMPDU action\n");
1764 }
1765
d7ca2139 1766 return ret;
fb9987d0
S
1767}
1768
1769static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw)
1770{
1771 struct ath9k_htc_priv *priv = hw->priv;
1772
1773 mutex_lock(&priv->mutex);
1774 spin_lock_bh(&priv->beacon_lock);
1775 priv->op_flags |= OP_SCANNING;
1776 spin_unlock_bh(&priv->beacon_lock);
bde748a4 1777 cancel_work_sync(&priv->ps_work);
fe67470d
RM
1778 if (priv->op_flags & OP_ASSOCIATED)
1779 cancel_delayed_work_sync(&priv->ath9k_ani_work);
fb9987d0
S
1780 mutex_unlock(&priv->mutex);
1781}
1782
1783static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
1784{
1785 struct ath9k_htc_priv *priv = hw->priv;
1786
1787 mutex_lock(&priv->mutex);
cb551df2 1788 ath9k_htc_ps_wakeup(priv);
fb9987d0
S
1789 spin_lock_bh(&priv->beacon_lock);
1790 priv->op_flags &= ~OP_SCANNING;
1791 spin_unlock_bh(&priv->beacon_lock);
1792 priv->op_flags |= OP_FULL_RESET;
fe67470d 1793 if (priv->op_flags & OP_ASSOCIATED) {
fcb9392f 1794 ath9k_htc_beacon_config(priv, priv->vif);
fe67470d
RM
1795 ath_start_ani(priv);
1796 }
bde748a4 1797 ath9k_htc_ps_restore(priv);
cb551df2 1798 mutex_unlock(&priv->mutex);
fb9987d0
S
1799}
1800
1801static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1802{
1803 return 0;
1804}
1805
1806static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw,
1807 u8 coverage_class)
1808{
1809 struct ath9k_htc_priv *priv = hw->priv;
1810
1811 mutex_lock(&priv->mutex);
cb551df2 1812 ath9k_htc_ps_wakeup(priv);
fb9987d0
S
1813 priv->ah->coverage_class = coverage_class;
1814 ath9k_hw_init_global_settings(priv->ah);
cb551df2 1815 ath9k_htc_ps_restore(priv);
fb9987d0
S
1816 mutex_unlock(&priv->mutex);
1817}
1818
1819struct ieee80211_ops ath9k_htc_ops = {
1820 .tx = ath9k_htc_tx,
1821 .start = ath9k_htc_start,
1822 .stop = ath9k_htc_stop,
1823 .add_interface = ath9k_htc_add_interface,
1824 .remove_interface = ath9k_htc_remove_interface,
1825 .config = ath9k_htc_config,
1826 .configure_filter = ath9k_htc_configure_filter,
abd984e6
S
1827 .sta_add = ath9k_htc_sta_add,
1828 .sta_remove = ath9k_htc_sta_remove,
fb9987d0
S
1829 .conf_tx = ath9k_htc_conf_tx,
1830 .bss_info_changed = ath9k_htc_bss_info_changed,
1831 .set_key = ath9k_htc_set_key,
1832 .get_tsf = ath9k_htc_get_tsf,
1833 .set_tsf = ath9k_htc_set_tsf,
1834 .reset_tsf = ath9k_htc_reset_tsf,
1835 .ampdu_action = ath9k_htc_ampdu_action,
1836 .sw_scan_start = ath9k_htc_sw_scan_start,
1837 .sw_scan_complete = ath9k_htc_sw_scan_complete,
1838 .set_rts_threshold = ath9k_htc_set_rts_threshold,
1839 .rfkill_poll = ath9k_htc_rfkill_poll_state,
1840 .set_coverage_class = ath9k_htc_set_coverage_class,
1841};