ath9k_htc: Fix suspend/resume
[deliverable/linux.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
f933ebed
SM
66bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
67 enum ath9k_power_mode mode)
bde748a4
VN
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,
6038f373
AB
538 .owner = THIS_MODULE,
539 .llseek = default_llseek,
fb9987d0
S
540};
541
542static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
543 size_t count, loff_t *ppos)
544{
57674308 545 struct ath9k_htc_priv *priv = file->private_data;
fb9987d0
S
546 char buf[512];
547 unsigned int len = 0;
548
549 len += snprintf(buf + len, sizeof(buf) - len,
550 "%20s : %10u\n", "Buffers queued",
551 priv->debug.tx_stats.buf_queued);
552 len += snprintf(buf + len, sizeof(buf) - len,
553 "%20s : %10u\n", "Buffers completed",
554 priv->debug.tx_stats.buf_completed);
555 len += snprintf(buf + len, sizeof(buf) - len,
556 "%20s : %10u\n", "SKBs queued",
557 priv->debug.tx_stats.skb_queued);
558 len += snprintf(buf + len, sizeof(buf) - len,
559 "%20s : %10u\n", "SKBs completed",
560 priv->debug.tx_stats.skb_completed);
eac8e385
S
561 len += snprintf(buf + len, sizeof(buf) - len,
562 "%20s : %10u\n", "SKBs dropped",
563 priv->debug.tx_stats.skb_dropped);
fb9987d0 564
2edb4583
S
565 len += snprintf(buf + len, sizeof(buf) - len,
566 "%20s : %10u\n", "BE queued",
567 priv->debug.tx_stats.queue_stats[WME_AC_BE]);
568 len += snprintf(buf + len, sizeof(buf) - len,
569 "%20s : %10u\n", "BK queued",
570 priv->debug.tx_stats.queue_stats[WME_AC_BK]);
571 len += snprintf(buf + len, sizeof(buf) - len,
572 "%20s : %10u\n", "VI queued",
573 priv->debug.tx_stats.queue_stats[WME_AC_VI]);
574 len += snprintf(buf + len, sizeof(buf) - len,
575 "%20s : %10u\n", "VO queued",
576 priv->debug.tx_stats.queue_stats[WME_AC_VO]);
577
9746010b
DC
578 if (len > sizeof(buf))
579 len = sizeof(buf);
580
fb9987d0
S
581 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
582}
583
584static const struct file_operations fops_xmit = {
585 .read = read_file_xmit,
586 .open = ath9k_debugfs_open,
6038f373
AB
587 .owner = THIS_MODULE,
588 .llseek = default_llseek,
fb9987d0
S
589};
590
591static ssize_t read_file_recv(struct file *file, char __user *user_buf,
592 size_t count, loff_t *ppos)
593{
57674308 594 struct ath9k_htc_priv *priv = file->private_data;
fb9987d0
S
595 char buf[512];
596 unsigned int len = 0;
597
598 len += snprintf(buf + len, sizeof(buf) - len,
599 "%20s : %10u\n", "SKBs allocated",
600 priv->debug.rx_stats.skb_allocated);
601 len += snprintf(buf + len, sizeof(buf) - len,
602 "%20s : %10u\n", "SKBs completed",
603 priv->debug.rx_stats.skb_completed);
604 len += snprintf(buf + len, sizeof(buf) - len,
605 "%20s : %10u\n", "SKBs Dropped",
606 priv->debug.rx_stats.skb_dropped);
607
9746010b
DC
608 if (len > sizeof(buf))
609 len = sizeof(buf);
610
fb9987d0
S
611 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
612}
613
614static const struct file_operations fops_recv = {
615 .read = read_file_recv,
616 .open = ath9k_debugfs_open,
6038f373
AB
617 .owner = THIS_MODULE,
618 .llseek = default_llseek,
fb9987d0
S
619};
620
e1572c5e 621int ath9k_htc_init_debug(struct ath_hw *ah)
fb9987d0
S
622{
623 struct ath_common *common = ath9k_hw_common(ah);
624 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
625
626 if (!ath9k_debugfs_root)
627 return -ENOENT;
628
629 priv->debug.debugfs_phy = debugfs_create_dir(wiphy_name(priv->hw->wiphy),
630 ath9k_debugfs_root);
631 if (!priv->debug.debugfs_phy)
632 goto err;
633
634 priv->debug.debugfs_tgt_stats = debugfs_create_file("tgt_stats", S_IRUSR,
635 priv->debug.debugfs_phy,
636 priv, &fops_tgt_stats);
637 if (!priv->debug.debugfs_tgt_stats)
638 goto err;
639
640
641 priv->debug.debugfs_xmit = debugfs_create_file("xmit", S_IRUSR,
642 priv->debug.debugfs_phy,
643 priv, &fops_xmit);
644 if (!priv->debug.debugfs_xmit)
645 goto err;
646
647 priv->debug.debugfs_recv = debugfs_create_file("recv", S_IRUSR,
648 priv->debug.debugfs_phy,
649 priv, &fops_recv);
650 if (!priv->debug.debugfs_recv)
651 goto err;
652
653 return 0;
654
655err:
e1572c5e 656 ath9k_htc_exit_debug(ah);
fb9987d0
S
657 return -ENOMEM;
658}
659
e1572c5e 660void ath9k_htc_exit_debug(struct ath_hw *ah)
fb9987d0
S
661{
662 struct ath_common *common = ath9k_hw_common(ah);
663 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
664
665 debugfs_remove(priv->debug.debugfs_recv);
666 debugfs_remove(priv->debug.debugfs_xmit);
667 debugfs_remove(priv->debug.debugfs_tgt_stats);
668 debugfs_remove(priv->debug.debugfs_phy);
669}
670
e1572c5e 671int ath9k_htc_debug_create_root(void)
fb9987d0
S
672{
673 ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
674 if (!ath9k_debugfs_root)
675 return -ENOENT;
676
677 return 0;
678}
679
e1572c5e 680void ath9k_htc_debug_remove_root(void)
fb9987d0
S
681{
682 debugfs_remove(ath9k_debugfs_root);
683 ath9k_debugfs_root = NULL;
684}
685
686#endif /* CONFIG_ATH9K_HTC_DEBUGFS */
687
688/*******/
689/* ANI */
690/*******/
691
692static void ath_start_ani(struct ath9k_htc_priv *priv)
693{
694 struct ath_common *common = ath9k_hw_common(priv->ah);
695 unsigned long timestamp = jiffies_to_msecs(jiffies);
696
697 common->ani.longcal_timer = timestamp;
698 common->ani.shortcal_timer = timestamp;
699 common->ani.checkani_timer = timestamp;
700
701 ieee80211_queue_delayed_work(common->hw, &priv->ath9k_ani_work,
702 msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
703}
704
705void ath9k_ani_work(struct work_struct *work)
706{
707 struct ath9k_htc_priv *priv =
708 container_of(work, struct ath9k_htc_priv,
709 ath9k_ani_work.work);
710 struct ath_hw *ah = priv->ah;
711 struct ath_common *common = ath9k_hw_common(ah);
712 bool longcal = false;
713 bool shortcal = false;
714 bool aniflag = false;
715 unsigned int timestamp = jiffies_to_msecs(jiffies);
716 u32 cal_interval, short_cal_interval;
717
718 short_cal_interval = ATH_STA_SHORT_CALINTERVAL;
719
bde748a4
VN
720 /* Only calibrate if awake */
721 if (ah->power_mode != ATH9K_PM_AWAKE)
722 goto set_timer;
723
fb9987d0
S
724 /* Long calibration runs independently of short calibration. */
725 if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
726 longcal = true;
727 ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
728 common->ani.longcal_timer = timestamp;
729 }
730
731 /* Short calibration applies only while caldone is false */
732 if (!common->ani.caldone) {
733 if ((timestamp - common->ani.shortcal_timer) >=
734 short_cal_interval) {
735 shortcal = true;
736 ath_print(common, ATH_DBG_ANI,
737 "shortcal @%lu\n", jiffies);
738 common->ani.shortcal_timer = timestamp;
739 common->ani.resetcal_timer = timestamp;
740 }
741 } else {
742 if ((timestamp - common->ani.resetcal_timer) >=
743 ATH_RESTART_CALINTERVAL) {
744 common->ani.caldone = ath9k_hw_reset_calvalid(ah);
745 if (common->ani.caldone)
746 common->ani.resetcal_timer = timestamp;
747 }
748 }
749
750 /* Verify whether we must check ANI */
751 if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
752 aniflag = true;
753 common->ani.checkani_timer = timestamp;
754 }
755
756 /* Skip all processing if there's nothing to do. */
757 if (longcal || shortcal || aniflag) {
bde748a4
VN
758
759 ath9k_htc_ps_wakeup(priv);
760
fb9987d0
S
761 /* Call ANI routine if necessary */
762 if (aniflag)
763 ath9k_hw_ani_monitor(ah, ah->curchan);
764
765 /* Perform calibration if necessary */
35ecfe03 766 if (longcal || shortcal)
fb9987d0
S
767 common->ani.caldone =
768 ath9k_hw_calibrate(ah, ah->curchan,
769 common->rx_chainmask,
770 longcal);
771
bde748a4 772 ath9k_htc_ps_restore(priv);
fb9987d0
S
773 }
774
bde748a4 775set_timer:
fb9987d0
S
776 /*
777 * Set timer interval based on previous results.
778 * The interval must be the shortest necessary to satisfy ANI,
779 * short calibration and long calibration.
780 */
781 cal_interval = ATH_LONG_CALINTERVAL;
782 if (priv->ah->config.enable_ani)
783 cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
784 if (!common->ani.caldone)
785 cal_interval = min(cal_interval, (u32)short_cal_interval);
786
787 ieee80211_queue_delayed_work(common->hw, &priv->ath9k_ani_work,
788 msecs_to_jiffies(cal_interval));
789}
790
791/*******/
792/* LED */
793/*******/
794
795static void ath9k_led_blink_work(struct work_struct *work)
796{
797 struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv,
798 ath9k_led_blink_work.work);
799
800 if (!(priv->op_flags & OP_LED_ASSOCIATED))
801 return;
802
803 if ((priv->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
804 (priv->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
805 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
806 else
807 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
808 (priv->op_flags & OP_LED_ON) ? 1 : 0);
809
810 ieee80211_queue_delayed_work(priv->hw,
811 &priv->ath9k_led_blink_work,
812 (priv->op_flags & OP_LED_ON) ?
813 msecs_to_jiffies(priv->led_off_duration) :
814 msecs_to_jiffies(priv->led_on_duration));
815
816 priv->led_on_duration = priv->led_on_cnt ?
817 max((ATH_LED_ON_DURATION_IDLE - priv->led_on_cnt), 25) :
818 ATH_LED_ON_DURATION_IDLE;
819 priv->led_off_duration = priv->led_off_cnt ?
820 max((ATH_LED_OFF_DURATION_IDLE - priv->led_off_cnt), 10) :
821 ATH_LED_OFF_DURATION_IDLE;
822 priv->led_on_cnt = priv->led_off_cnt = 0;
823
824 if (priv->op_flags & OP_LED_ON)
825 priv->op_flags &= ~OP_LED_ON;
826 else
827 priv->op_flags |= OP_LED_ON;
828}
829
830static void ath9k_led_brightness_work(struct work_struct *work)
831{
832 struct ath_led *led = container_of(work, struct ath_led,
833 brightness_work.work);
834 struct ath9k_htc_priv *priv = led->priv;
835
836 switch (led->brightness) {
837 case LED_OFF:
838 if (led->led_type == ATH_LED_ASSOC ||
839 led->led_type == ATH_LED_RADIO) {
840 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
841 (led->led_type == ATH_LED_RADIO));
842 priv->op_flags &= ~OP_LED_ASSOCIATED;
843 if (led->led_type == ATH_LED_RADIO)
844 priv->op_flags &= ~OP_LED_ON;
845 } else {
846 priv->led_off_cnt++;
847 }
848 break;
849 case LED_FULL:
850 if (led->led_type == ATH_LED_ASSOC) {
851 priv->op_flags |= OP_LED_ASSOCIATED;
852 ieee80211_queue_delayed_work(priv->hw,
853 &priv->ath9k_led_blink_work, 0);
854 } else if (led->led_type == ATH_LED_RADIO) {
855 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
856 priv->op_flags |= OP_LED_ON;
857 } else {
858 priv->led_on_cnt++;
859 }
860 break;
861 default:
862 break;
863 }
864}
865
866static void ath9k_led_brightness(struct led_classdev *led_cdev,
867 enum led_brightness brightness)
868{
869 struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
870 struct ath9k_htc_priv *priv = led->priv;
871
872 led->brightness = brightness;
873 if (!(priv->op_flags & OP_LED_DEINIT))
874 ieee80211_queue_delayed_work(priv->hw,
875 &led->brightness_work, 0);
876}
877
878static void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv)
879{
880 cancel_delayed_work_sync(&priv->radio_led.brightness_work);
881 cancel_delayed_work_sync(&priv->assoc_led.brightness_work);
882 cancel_delayed_work_sync(&priv->tx_led.brightness_work);
883 cancel_delayed_work_sync(&priv->rx_led.brightness_work);
884}
885
886static int ath9k_register_led(struct ath9k_htc_priv *priv, struct ath_led *led,
887 char *trigger)
888{
889 int ret;
890
891 led->priv = priv;
892 led->led_cdev.name = led->name;
893 led->led_cdev.default_trigger = trigger;
894 led->led_cdev.brightness_set = ath9k_led_brightness;
895
896 ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_cdev);
897 if (ret)
898 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
899 "Failed to register led:%s", led->name);
900 else
901 led->registered = 1;
902
903 INIT_DELAYED_WORK(&led->brightness_work, ath9k_led_brightness_work);
904
905 return ret;
906}
907
908static void ath9k_unregister_led(struct ath_led *led)
909{
910 if (led->registered) {
911 led_classdev_unregister(&led->led_cdev);
912 led->registered = 0;
913 }
914}
915
916void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
917{
918 priv->op_flags |= OP_LED_DEINIT;
919 ath9k_unregister_led(&priv->assoc_led);
920 priv->op_flags &= ~OP_LED_ASSOCIATED;
921 ath9k_unregister_led(&priv->tx_led);
922 ath9k_unregister_led(&priv->rx_led);
923 ath9k_unregister_led(&priv->radio_led);
fb9987d0
S
924}
925
926void ath9k_init_leds(struct ath9k_htc_priv *priv)
927{
928 char *trigger;
929 int ret;
930
931 if (AR_SREV_9287(priv->ah))
932 priv->ah->led_pin = ATH_LED_PIN_9287;
933 else if (AR_SREV_9271(priv->ah))
934 priv->ah->led_pin = ATH_LED_PIN_9271;
88c1f4f6
S
935 else if (AR_DEVID_7010(priv->ah))
936 priv->ah->led_pin = ATH_LED_PIN_7010;
fb9987d0
S
937 else
938 priv->ah->led_pin = ATH_LED_PIN_DEF;
939
940 /* Configure gpio 1 for output */
941 ath9k_hw_cfg_output(priv->ah, priv->ah->led_pin,
942 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
943 /* LED off, active low */
944 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1);
945
946 INIT_DELAYED_WORK(&priv->ath9k_led_blink_work, ath9k_led_blink_work);
947
948 trigger = ieee80211_get_radio_led_name(priv->hw);
949 snprintf(priv->radio_led.name, sizeof(priv->radio_led.name),
950 "ath9k-%s::radio", wiphy_name(priv->hw->wiphy));
951 ret = ath9k_register_led(priv, &priv->radio_led, trigger);
952 priv->radio_led.led_type = ATH_LED_RADIO;
953 if (ret)
954 goto fail;
955
956 trigger = ieee80211_get_assoc_led_name(priv->hw);
957 snprintf(priv->assoc_led.name, sizeof(priv->assoc_led.name),
958 "ath9k-%s::assoc", wiphy_name(priv->hw->wiphy));
959 ret = ath9k_register_led(priv, &priv->assoc_led, trigger);
960 priv->assoc_led.led_type = ATH_LED_ASSOC;
961 if (ret)
962 goto fail;
963
964 trigger = ieee80211_get_tx_led_name(priv->hw);
965 snprintf(priv->tx_led.name, sizeof(priv->tx_led.name),
966 "ath9k-%s::tx", wiphy_name(priv->hw->wiphy));
967 ret = ath9k_register_led(priv, &priv->tx_led, trigger);
968 priv->tx_led.led_type = ATH_LED_TX;
969 if (ret)
970 goto fail;
971
972 trigger = ieee80211_get_rx_led_name(priv->hw);
973 snprintf(priv->rx_led.name, sizeof(priv->rx_led.name),
974 "ath9k-%s::rx", wiphy_name(priv->hw->wiphy));
975 ret = ath9k_register_led(priv, &priv->rx_led, trigger);
976 priv->rx_led.led_type = ATH_LED_RX;
977 if (ret)
978 goto fail;
979
980 priv->op_flags &= ~OP_LED_DEINIT;
981
982 return;
983
984fail:
985 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
986 ath9k_deinit_leds(priv);
987}
988
989/*******************/
990/* Rfkill */
991/*******************/
992
993static bool ath_is_rfkill_set(struct ath9k_htc_priv *priv)
994{
995 return ath9k_hw_gpio_get(priv->ah, priv->ah->rfkill_gpio) ==
996 priv->ah->rfkill_polarity;
997}
998
999static void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw)
1000{
1001 struct ath9k_htc_priv *priv = hw->priv;
1002 bool blocked = !!ath_is_rfkill_set(priv);
1003
1004 wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
1005}
1006
1007void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv)
1008{
1009 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
1010 wiphy_rfkill_start_polling(priv->hw->wiphy);
1011}
1012
881ac6a5
S
1013static void ath9k_htc_radio_enable(struct ieee80211_hw *hw)
1014{
1015 struct ath9k_htc_priv *priv = hw->priv;
1016 struct ath_hw *ah = priv->ah;
1017 struct ath_common *common = ath9k_hw_common(ah);
1018 int ret;
1019 u8 cmd_rsp;
1020
1021 if (!ah->curchan)
1022 ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
1023
1024 /* Reset the HW */
20bd2a09 1025 ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
881ac6a5
S
1026 if (ret) {
1027 ath_print(common, ATH_DBG_FATAL,
1028 "Unable to reset hardware; reset status %d "
1029 "(freq %u MHz)\n", ret, ah->curchan->channel);
1030 }
1031
1032 ath_update_txpow(priv);
1033
1034 /* Start RX */
1035 WMI_CMD(WMI_START_RECV_CMDID);
1036 ath9k_host_rx_init(priv);
1037
1038 /* Start TX */
1039 htc_start(priv->htc);
1040 spin_lock_bh(&priv->tx_lock);
1041 priv->tx_queues_stop = false;
1042 spin_unlock_bh(&priv->tx_lock);
1043 ieee80211_wake_queues(hw);
1044
1045 WMI_CMD(WMI_ENABLE_INTR_CMDID);
1046
1047 /* Enable LED */
1048 ath9k_hw_cfg_output(ah, ah->led_pin,
1049 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
1050 ath9k_hw_set_gpio(ah, ah->led_pin, 0);
1051}
1052
1053static void ath9k_htc_radio_disable(struct ieee80211_hw *hw)
1054{
1055 struct ath9k_htc_priv *priv = hw->priv;
1056 struct ath_hw *ah = priv->ah;
1057 struct ath_common *common = ath9k_hw_common(ah);
1058 int ret;
1059 u8 cmd_rsp;
1060
1061 ath9k_htc_ps_wakeup(priv);
1062
1063 /* Disable LED */
1064 ath9k_hw_set_gpio(ah, ah->led_pin, 1);
1065 ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
1066
1067 WMI_CMD(WMI_DISABLE_INTR_CMDID);
1068
1069 /* Stop TX */
1070 ieee80211_stop_queues(hw);
1071 htc_stop(priv->htc);
1072 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
1073 skb_queue_purge(&priv->tx_queue);
1074
1075 /* Stop RX */
1076 WMI_CMD(WMI_STOP_RECV_CMDID);
1077
21d5130b
S
1078 /*
1079 * The MIB counters have to be disabled here,
1080 * since the target doesn't do it.
1081 */
1082 ath9k_hw_disable_mib_counters(ah);
1083
881ac6a5
S
1084 if (!ah->curchan)
1085 ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
1086
1087 /* Reset the HW */
20bd2a09 1088 ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
881ac6a5
S
1089 if (ret) {
1090 ath_print(common, ATH_DBG_FATAL,
1091 "Unable to reset hardware; reset status %d "
1092 "(freq %u MHz)\n", ret, ah->curchan->channel);
1093 }
1094
1095 /* Disable the PHY */
1096 ath9k_hw_phy_disable(ah);
1097
1098 ath9k_htc_ps_restore(priv);
1099 ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
1100}
1101
fb9987d0
S
1102/**********************/
1103/* mac80211 Callbacks */
1104/**********************/
1105
1106static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
1107{
1108 struct ieee80211_hdr *hdr;
1109 struct ath9k_htc_priv *priv = hw->priv;
7757dfed 1110 int padpos, padsize, ret;
fb9987d0
S
1111
1112 hdr = (struct ieee80211_hdr *) skb->data;
1113
1114 /* Add the padding after the header if this is not already done */
1115 padpos = ath9k_cmn_padpos(hdr->frame_control);
1116 padsize = padpos & 3;
1117 if (padsize && skb->len > padpos) {
1118 if (skb_headroom(skb) < padsize)
1119 return -1;
1120 skb_push(skb, padsize);
1121 memmove(skb->data, skb->data + padsize, padpos);
1122 }
1123
7757dfed
S
1124 ret = ath9k_htc_tx_start(priv, skb);
1125 if (ret != 0) {
1126 if (ret == -ENOMEM) {
1127 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
1128 "Stopping TX queues\n");
1129 ieee80211_stop_queues(hw);
1130 spin_lock_bh(&priv->tx_lock);
1131 priv->tx_queues_stop = true;
1132 spin_unlock_bh(&priv->tx_lock);
1133 } else {
1134 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
1135 "Tx failed");
1136 }
fb9987d0
S
1137 goto fail_tx;
1138 }
1139
1140 return 0;
1141
1142fail_tx:
1143 dev_kfree_skb_any(skb);
1144 return 0;
1145}
1146
881ac6a5 1147static int ath9k_htc_start(struct ieee80211_hw *hw)
fb9987d0
S
1148{
1149 struct ath9k_htc_priv *priv = hw->priv;
1150 struct ath_hw *ah = priv->ah;
1151 struct ath_common *common = ath9k_hw_common(ah);
1152 struct ieee80211_channel *curchan = hw->conf.channel;
1153 struct ath9k_channel *init_channel;
1154 int ret = 0;
1155 enum htc_phymode mode;
7f1f5a00 1156 __be16 htc_mode;
fb9987d0
S
1157 u8 cmd_rsp;
1158
881ac6a5
S
1159 mutex_lock(&priv->mutex);
1160
fb9987d0
S
1161 ath_print(common, ATH_DBG_CONFIG,
1162 "Starting driver with initial channel: %d MHz\n",
1163 curchan->center_freq);
1164
21d5130b
S
1165 /* Ensure that HW is awake before flushing RX */
1166 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
1167 WMI_CMD(WMI_FLUSH_RECV_CMDID);
1168
fb9987d0
S
1169 /* setup initial channel */
1170 init_channel = ath9k_cmn_get_curchannel(hw, ah);
1171
1172 /* Reset SERDES registers */
1173 ath9k_hw_configpcipowersave(ah, 0, 0);
1174
1175 ath9k_hw_htc_resetinit(ah);
20bd2a09 1176 ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
fb9987d0
S
1177 if (ret) {
1178 ath_print(common, ATH_DBG_FATAL,
1179 "Unable to reset hardware; reset status %d "
1180 "(freq %u MHz)\n", ret, curchan->center_freq);
881ac6a5 1181 mutex_unlock(&priv->mutex);
8a8572a8 1182 return ret;
fb9987d0
S
1183 }
1184
1185 ath_update_txpow(priv);
1186
1187 mode = ath9k_htc_get_curmode(priv, init_channel);
1188 htc_mode = cpu_to_be16(mode);
1189 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
fb9987d0 1190 WMI_CMD(WMI_ATH_INIT_CMDID);
fb9987d0 1191 WMI_CMD(WMI_START_RECV_CMDID);
fb9987d0
S
1192
1193 ath9k_host_rx_init(priv);
1194
1195 priv->op_flags &= ~OP_INVALID;
1196 htc_start(priv->htc);
1197
7757dfed
S
1198 spin_lock_bh(&priv->tx_lock);
1199 priv->tx_queues_stop = false;
1200 spin_unlock_bh(&priv->tx_lock);
1201
1202 ieee80211_wake_queues(hw);
1203
21cb9879
VN
1204 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) {
1205 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
1206 AR_STOMP_LOW_WLAN_WGHT);
1207 ath9k_hw_btcoex_enable(ah);
1208 ath_htc_resume_btcoex_work(priv);
1209 }
fb9987d0 1210 mutex_unlock(&priv->mutex);
8a8572a8 1211
fb9987d0
S
1212 return ret;
1213}
1214
881ac6a5 1215static void ath9k_htc_stop(struct ieee80211_hw *hw)
fb9987d0
S
1216{
1217 struct ath9k_htc_priv *priv = hw->priv;
1218 struct ath_hw *ah = priv->ah;
1219 struct ath_common *common = ath9k_hw_common(ah);
1220 int ret = 0;
1221 u8 cmd_rsp;
1222
881ac6a5
S
1223 mutex_lock(&priv->mutex);
1224
fb9987d0
S
1225 if (priv->op_flags & OP_INVALID) {
1226 ath_print(common, ATH_DBG_ANY, "Device not present\n");
881ac6a5 1227 mutex_unlock(&priv->mutex);
fb9987d0
S
1228 return;
1229 }
1230
7073daa6
S
1231 /* Cancel all the running timers/work .. */
1232 cancel_work_sync(&priv->ps_work);
7073daa6
S
1233 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
1234 ath9k_led_stop_brightness(priv);
1235
bde748a4 1236 ath9k_htc_ps_wakeup(priv);
fb9987d0
S
1237 htc_stop(priv->htc);
1238 WMI_CMD(WMI_DISABLE_INTR_CMDID);
1239 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
1240 WMI_CMD(WMI_STOP_RECV_CMDID);
fb9987d0
S
1241 skb_queue_purge(&priv->tx_queue);
1242
1243 /* Remove monitor interface here */
1244 if (ah->opmode == NL80211_IFTYPE_MONITOR) {
1245 if (ath9k_htc_remove_monitor_interface(priv))
1246 ath_print(common, ATH_DBG_FATAL,
1247 "Unable to remove monitor interface\n");
1248 else
1249 ath_print(common, ATH_DBG_CONFIG,
1250 "Monitor interface removed\n");
1251 }
1252
21cb9879
VN
1253 if (ah->btcoex_hw.enabled) {
1254 ath9k_hw_btcoex_disable(ah);
1255 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
1256 ath_htc_cancel_btcoex_work(priv);
1257 }
1258
e9201f09
S
1259 ath9k_hw_phy_disable(ah);
1260 ath9k_hw_disable(ah);
1261 ath9k_hw_configpcipowersave(ah, 1, 1);
1262 ath9k_htc_ps_restore(priv);
1263 ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
1264
fb9987d0 1265 priv->op_flags |= OP_INVALID;
fb9987d0
S
1266
1267 ath_print(common, ATH_DBG_CONFIG, "Driver halt\n");
8a8572a8
VN
1268 mutex_unlock(&priv->mutex);
1269}
1270
fb9987d0
S
1271static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1272 struct ieee80211_vif *vif)
1273{
1274 struct ath9k_htc_priv *priv = hw->priv;
1275 struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1276 struct ath_common *common = ath9k_hw_common(priv->ah);
1277 struct ath9k_htc_target_vif hvif;
1278 int ret = 0;
1279 u8 cmd_rsp;
1280
1281 mutex_lock(&priv->mutex);
1282
1283 /* Only one interface for now */
1284 if (priv->nvifs > 0) {
1285 ret = -ENOBUFS;
1286 goto out;
1287 }
1288
bde748a4 1289 ath9k_htc_ps_wakeup(priv);
fb9987d0
S
1290 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
1291 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
1292
1293 switch (vif->type) {
1294 case NL80211_IFTYPE_STATION:
1295 hvif.opmode = cpu_to_be32(HTC_M_STA);
1296 break;
1297 case NL80211_IFTYPE_ADHOC:
1298 hvif.opmode = cpu_to_be32(HTC_M_IBSS);
1299 break;
1300 default:
1301 ath_print(common, ATH_DBG_FATAL,
1302 "Interface type %d not yet supported\n", vif->type);
1303 ret = -EOPNOTSUPP;
1304 goto out;
1305 }
1306
1307 ath_print(common, ATH_DBG_CONFIG,
1308 "Attach a VIF of type: %d\n", vif->type);
1309
1310 priv->ah->opmode = vif->type;
1311
1312 /* Index starts from zero on the target */
1313 avp->index = hvif.index = priv->nvifs;
1314 hvif.rtsthreshold = cpu_to_be16(2304);
1315 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
1316 if (ret)
1317 goto out;
1318
1319 priv->nvifs++;
1320
1321 /*
1322 * We need a node in target to tx mgmt frames
1323 * before association.
1324 */
1325 ret = ath9k_htc_add_station(priv, vif, NULL);
1326 if (ret)
1327 goto out;
1328
1329 ret = ath9k_htc_update_cap_target(priv);
1330 if (ret)
1331 ath_print(common, ATH_DBG_CONFIG, "Failed to update"
1332 " capability in target \n");
1333
1334 priv->vif = vif;
1335out:
bde748a4 1336 ath9k_htc_ps_restore(priv);
fb9987d0 1337 mutex_unlock(&priv->mutex);
cb551df2 1338
fb9987d0
S
1339 return ret;
1340}
1341
1342static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
1343 struct ieee80211_vif *vif)
1344{
1345 struct ath9k_htc_priv *priv = hw->priv;
1346 struct ath_common *common = ath9k_hw_common(priv->ah);
1347 struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1348 struct ath9k_htc_target_vif hvif;
1349 int ret = 0;
1350 u8 cmd_rsp;
1351
1352 ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n");
1353
1354 mutex_lock(&priv->mutex);
cb551df2 1355 ath9k_htc_ps_wakeup(priv);
fb9987d0
S
1356
1357 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
1358 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
1359 hvif.index = avp->index;
1360 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
1361 priv->nvifs--;
1362
1363 ath9k_htc_remove_station(priv, vif, NULL);
fb9987d0
S
1364 priv->vif = NULL;
1365
cb551df2 1366 ath9k_htc_ps_restore(priv);
fb9987d0
S
1367 mutex_unlock(&priv->mutex);
1368}
1369
1370static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
1371{
1372 struct ath9k_htc_priv *priv = hw->priv;
1373 struct ath_common *common = ath9k_hw_common(priv->ah);
1374 struct ieee80211_conf *conf = &hw->conf;
1375
1376 mutex_lock(&priv->mutex);
1377
8a8572a8
VN
1378 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1379 bool enable_radio = false;
1380 bool idle = !!(conf->flags & IEEE80211_CONF_IDLE);
1381
23367769 1382 mutex_lock(&priv->htc_pm_lock);
8a8572a8
VN
1383 if (!idle && priv->ps_idle)
1384 enable_radio = true;
8a8572a8 1385 priv->ps_idle = idle;
23367769 1386 mutex_unlock(&priv->htc_pm_lock);
8a8572a8
VN
1387
1388 if (enable_radio) {
8a8572a8
VN
1389 ath_print(common, ATH_DBG_CONFIG,
1390 "not-idle: enabling radio\n");
23367769
S
1391 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
1392 ath9k_htc_radio_enable(hw);
8a8572a8
VN
1393 }
1394 }
1395
fb9987d0
S
1396 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1397 struct ieee80211_channel *curchan = hw->conf.channel;
1398 int pos = curchan->hw_value;
fb9987d0
S
1399
1400 ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
1401 curchan->center_freq);
1402
fb9987d0
S
1403 ath9k_cmn_update_ichannel(hw, &priv->ah->channels[pos]);
1404
1405 if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) {
1406 ath_print(common, ATH_DBG_FATAL,
1407 "Unable to set channel\n");
1408 mutex_unlock(&priv->mutex);
1409 return -EINVAL;
1410 }
1411
1412 }
bde748a4
VN
1413 if (changed & IEEE80211_CONF_CHANGE_PS) {
1414 if (conf->flags & IEEE80211_CONF_PS) {
1415 ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP);
1416 priv->ps_enabled = true;
1417 } else {
1418 priv->ps_enabled = false;
1419 cancel_work_sync(&priv->ps_work);
1420 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
1421 }
1422 }
fb9987d0
S
1423
1424 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
1425 if (conf->flags & IEEE80211_CONF_MONITOR) {
1426 if (ath9k_htc_add_monitor_interface(priv))
1427 ath_print(common, ATH_DBG_FATAL,
1428 "Failed to set monitor mode\n");
1429 else
1430 ath_print(common, ATH_DBG_CONFIG,
1431 "HW opmode set to Monitor mode\n");
1432 }
1433 }
1434
23367769
S
1435 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1436 mutex_lock(&priv->htc_pm_lock);
1437 if (!priv->ps_idle) {
1438 mutex_unlock(&priv->htc_pm_lock);
1439 goto out;
1440 }
1441 mutex_unlock(&priv->htc_pm_lock);
1442
8a8572a8
VN
1443 ath_print(common, ATH_DBG_CONFIG,
1444 "idle: disabling radio\n");
881ac6a5 1445 ath9k_htc_radio_disable(hw);
8a8572a8
VN
1446 }
1447
23367769 1448out:
fb9987d0 1449 mutex_unlock(&priv->mutex);
fb9987d0
S
1450 return 0;
1451}
1452
1453#define SUPPORTED_FILTERS \
1454 (FIF_PROMISC_IN_BSS | \
1455 FIF_ALLMULTI | \
1456 FIF_CONTROL | \
1457 FIF_PSPOLL | \
1458 FIF_OTHER_BSS | \
1459 FIF_BCN_PRBRESP_PROMISC | \
94a40c0c 1460 FIF_PROBE_REQ | \
fb9987d0
S
1461 FIF_FCSFAIL)
1462
1463static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
1464 unsigned int changed_flags,
1465 unsigned int *total_flags,
1466 u64 multicast)
1467{
1468 struct ath9k_htc_priv *priv = hw->priv;
1469 u32 rfilt;
1470
1471 mutex_lock(&priv->mutex);
bde748a4 1472 ath9k_htc_ps_wakeup(priv);
cb551df2 1473
fb9987d0
S
1474 changed_flags &= SUPPORTED_FILTERS;
1475 *total_flags &= SUPPORTED_FILTERS;
1476
1477 priv->rxfilter = *total_flags;
0995d110 1478 rfilt = ath9k_htc_calcrxfilter(priv);
fb9987d0
S
1479 ath9k_hw_setrxfilter(priv->ah, rfilt);
1480
1481 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_CONFIG,
1482 "Set HW RX filter: 0x%x\n", rfilt);
1483
bde748a4 1484 ath9k_htc_ps_restore(priv);
fb9987d0
S
1485 mutex_unlock(&priv->mutex);
1486}
1487
abd984e6
S
1488static int ath9k_htc_sta_add(struct ieee80211_hw *hw,
1489 struct ieee80211_vif *vif,
1490 struct ieee80211_sta *sta)
fb9987d0
S
1491{
1492 struct ath9k_htc_priv *priv = hw->priv;
1493 int ret;
1494
05a30f9c 1495 mutex_lock(&priv->mutex);
cb551df2 1496 ath9k_htc_ps_wakeup(priv);
abd984e6
S
1497 ret = ath9k_htc_add_station(priv, vif, sta);
1498 if (!ret)
1499 ath9k_htc_init_rate(priv, sta);
1500 ath9k_htc_ps_restore(priv);
1501 mutex_unlock(&priv->mutex);
05a30f9c 1502
abd984e6
S
1503 return ret;
1504}
1505
1506static int ath9k_htc_sta_remove(struct ieee80211_hw *hw,
1507 struct ieee80211_vif *vif,
1508 struct ieee80211_sta *sta)
1509{
1510 struct ath9k_htc_priv *priv = hw->priv;
1511 int ret;
05a30f9c 1512
abd984e6
S
1513 mutex_lock(&priv->mutex);
1514 ath9k_htc_ps_wakeup(priv);
1515 ret = ath9k_htc_remove_station(priv, vif, sta);
cb551df2 1516 ath9k_htc_ps_restore(priv);
05a30f9c 1517 mutex_unlock(&priv->mutex);
abd984e6
S
1518
1519 return ret;
fb9987d0
S
1520}
1521
1522static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, u16 queue,
1523 const struct ieee80211_tx_queue_params *params)
1524{
1525 struct ath9k_htc_priv *priv = hw->priv;
1526 struct ath_common *common = ath9k_hw_common(priv->ah);
1527 struct ath9k_tx_queue_info qi;
1528 int ret = 0, qnum;
1529
1530 if (queue >= WME_NUM_AC)
1531 return 0;
1532
1533 mutex_lock(&priv->mutex);
cb551df2 1534 ath9k_htc_ps_wakeup(priv);
fb9987d0
S
1535
1536 memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
1537
1538 qi.tqi_aifs = params->aifs;
1539 qi.tqi_cwmin = params->cw_min;
1540 qi.tqi_cwmax = params->cw_max;
1541 qi.tqi_burstTime = params->txop;
1542
1543 qnum = get_hw_qnum(queue, priv->hwq_map);
1544
1545 ath_print(common, ATH_DBG_CONFIG,
1546 "Configure tx [queue/hwq] [%d/%d], "
1547 "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
1548 queue, qnum, params->aifs, params->cw_min,
1549 params->cw_max, params->txop);
1550
e1572c5e 1551 ret = ath_htc_txq_update(priv, qnum, &qi);
764580f5 1552 if (ret) {
fb9987d0 1553 ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n");
764580f5
S
1554 goto out;
1555 }
fb9987d0 1556
764580f5 1557 if ((priv->ah->opmode == NL80211_IFTYPE_ADHOC) &&
e8c35a77 1558 (qnum == priv->hwq_map[WME_AC_BE]))
764580f5
S
1559 ath9k_htc_beaconq_config(priv);
1560out:
cb551df2 1561 ath9k_htc_ps_restore(priv);
fb9987d0
S
1562 mutex_unlock(&priv->mutex);
1563
1564 return ret;
1565}
1566
1567static int ath9k_htc_set_key(struct ieee80211_hw *hw,
1568 enum set_key_cmd cmd,
1569 struct ieee80211_vif *vif,
1570 struct ieee80211_sta *sta,
1571 struct ieee80211_key_conf *key)
1572{
1573 struct ath9k_htc_priv *priv = hw->priv;
1574 struct ath_common *common = ath9k_hw_common(priv->ah);
1575 int ret = 0;
1576
e1572c5e 1577 if (htc_modparam_nohwcrypt)
fb9987d0
S
1578 return -ENOSPC;
1579
1580 mutex_lock(&priv->mutex);
1581 ath_print(common, ATH_DBG_CONFIG, "Set HW Key\n");
bde748a4 1582 ath9k_htc_ps_wakeup(priv);
fb9987d0
S
1583
1584 switch (cmd) {
1585 case SET_KEY:
040e539e 1586 ret = ath_key_config(common, vif, sta, key);
fb9987d0
S
1587 if (ret >= 0) {
1588 key->hw_key_idx = ret;
1589 /* push IV and Michael MIC generation to stack */
1590 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
97359d12 1591 if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
fb9987d0 1592 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
97359d12
JB
1593 if (priv->ah->sw_mgmt_crypto &&
1594 key->cipher == WLAN_CIPHER_SUITE_CCMP)
fb9987d0
S
1595 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
1596 ret = 0;
1597 }
1598 break;
1599 case DISABLE_KEY:
040e539e 1600 ath_key_delete(common, key);
fb9987d0
S
1601 break;
1602 default:
1603 ret = -EINVAL;
1604 }
1605
bde748a4 1606 ath9k_htc_ps_restore(priv);
fb9987d0
S
1607 mutex_unlock(&priv->mutex);
1608
1609 return ret;
1610}
1611
1612static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
1613 struct ieee80211_vif *vif,
1614 struct ieee80211_bss_conf *bss_conf,
1615 u32 changed)
1616{
1617 struct ath9k_htc_priv *priv = hw->priv;
1618 struct ath_hw *ah = priv->ah;
1619 struct ath_common *common = ath9k_hw_common(ah);
1620
1621 mutex_lock(&priv->mutex);
bde748a4 1622 ath9k_htc_ps_wakeup(priv);
fb9987d0
S
1623
1624 if (changed & BSS_CHANGED_ASSOC) {
1625 common->curaid = bss_conf->assoc ?
1626 bss_conf->aid : 0;
1627 ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
1628 bss_conf->assoc);
1629
1630 if (bss_conf->assoc) {
1631 priv->op_flags |= OP_ASSOCIATED;
1632 ath_start_ani(priv);
1633 } else {
1634 priv->op_flags &= ~OP_ASSOCIATED;
1635 cancel_delayed_work_sync(&priv->ath9k_ani_work);
1636 }
1637 }
1638
1639 if (changed & BSS_CHANGED_BSSID) {
1640 /* Set BSSID */
1641 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1642 ath9k_hw_write_associd(ah);
1643
1644 ath_print(common, ATH_DBG_CONFIG,
1645 "BSSID: %pM aid: 0x%x\n",
1646 common->curbssid, common->curaid);
1647 }
1648
1649 if ((changed & BSS_CHANGED_BEACON_INT) ||
1650 (changed & BSS_CHANGED_BEACON) ||
1651 ((changed & BSS_CHANGED_BEACON_ENABLED) &&
1652 bss_conf->enable_beacon)) {
1653 priv->op_flags |= OP_ENABLE_BEACON;
1c3652a5 1654 ath9k_htc_beacon_config(priv, vif);
fb9987d0
S
1655 }
1656
fb9987d0
S
1657 if ((changed & BSS_CHANGED_BEACON_ENABLED) &&
1658 !bss_conf->enable_beacon) {
1659 priv->op_flags &= ~OP_ENABLE_BEACON;
1c3652a5 1660 ath9k_htc_beacon_config(priv, vif);
fb9987d0
S
1661 }
1662
1663 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
1664 ath_print(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
1665 bss_conf->use_short_preamble);
1666 if (bss_conf->use_short_preamble)
1667 priv->op_flags |= OP_PREAMBLE_SHORT;
1668 else
1669 priv->op_flags &= ~OP_PREAMBLE_SHORT;
1670 }
1671
1672 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
1673 ath_print(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n",
1674 bss_conf->use_cts_prot);
1675 if (bss_conf->use_cts_prot &&
1676 hw->conf.channel->band != IEEE80211_BAND_5GHZ)
1677 priv->op_flags |= OP_PROTECT_ENABLE;
1678 else
1679 priv->op_flags &= ~OP_PROTECT_ENABLE;
1680 }
1681
1682 if (changed & BSS_CHANGED_ERP_SLOT) {
1683 if (bss_conf->use_short_slot)
1684 ah->slottime = 9;
1685 else
1686 ah->slottime = 20;
1687
1688 ath9k_hw_init_global_settings(ah);
1689 }
1690
2c76ef89
S
1691 if (changed & BSS_CHANGED_HT)
1692 ath9k_htc_update_rate(priv, vif, bss_conf);
1693
bde748a4 1694 ath9k_htc_ps_restore(priv);
fb9987d0
S
1695 mutex_unlock(&priv->mutex);
1696}
1697
1698static u64 ath9k_htc_get_tsf(struct ieee80211_hw *hw)
1699{
1700 struct ath9k_htc_priv *priv = hw->priv;
1701 u64 tsf;
1702
1703 mutex_lock(&priv->mutex);
cb551df2 1704 ath9k_htc_ps_wakeup(priv);
fb9987d0 1705 tsf = ath9k_hw_gettsf64(priv->ah);
cb551df2 1706 ath9k_htc_ps_restore(priv);
fb9987d0
S
1707 mutex_unlock(&priv->mutex);
1708
1709 return tsf;
1710}
1711
1712static void ath9k_htc_set_tsf(struct ieee80211_hw *hw, u64 tsf)
1713{
1714 struct ath9k_htc_priv *priv = hw->priv;
1715
1716 mutex_lock(&priv->mutex);
cb551df2 1717 ath9k_htc_ps_wakeup(priv);
fb9987d0 1718 ath9k_hw_settsf64(priv->ah, tsf);
cb551df2 1719 ath9k_htc_ps_restore(priv);
fb9987d0
S
1720 mutex_unlock(&priv->mutex);
1721}
1722
1723static void ath9k_htc_reset_tsf(struct ieee80211_hw *hw)
1724{
1725 struct ath9k_htc_priv *priv = hw->priv;
1726
1727 mutex_lock(&priv->mutex);
cb551df2 1728 ath9k_htc_ps_wakeup(priv);
fb9987d0 1729 ath9k_hw_reset_tsf(priv->ah);
bde748a4 1730 ath9k_htc_ps_restore(priv);
cb551df2 1731 mutex_unlock(&priv->mutex);
fb9987d0
S
1732}
1733
1734static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
1735 struct ieee80211_vif *vif,
1736 enum ieee80211_ampdu_mlme_action action,
1737 struct ieee80211_sta *sta,
1738 u16 tid, u16 *ssn)
1739{
1740 struct ath9k_htc_priv *priv = hw->priv;
fb9987d0 1741 struct ath9k_htc_sta *ista;
d7ca2139 1742 int ret = 0;
fb9987d0
S
1743
1744 switch (action) {
1745 case IEEE80211_AMPDU_RX_START:
1746 break;
1747 case IEEE80211_AMPDU_RX_STOP:
1748 break;
1749 case IEEE80211_AMPDU_TX_START:
d7ca2139
S
1750 ret = ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid);
1751 if (!ret)
1752 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1753 break;
fb9987d0 1754 case IEEE80211_AMPDU_TX_STOP:
d7ca2139
S
1755 ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid);
1756 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
fb9987d0
S
1757 break;
1758 case IEEE80211_AMPDU_TX_OPERATIONAL:
1759 ista = (struct ath9k_htc_sta *) sta->drv_priv;
d7ca2139 1760 spin_lock_bh(&priv->tx_lock);
fb9987d0 1761 ista->tid_state[tid] = AGGR_OPERATIONAL;
d7ca2139 1762 spin_unlock_bh(&priv->tx_lock);
fb9987d0
S
1763 break;
1764 default:
1765 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
1766 "Unknown AMPDU action\n");
1767 }
1768
d7ca2139 1769 return ret;
fb9987d0
S
1770}
1771
1772static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw)
1773{
1774 struct ath9k_htc_priv *priv = hw->priv;
1775
1776 mutex_lock(&priv->mutex);
1777 spin_lock_bh(&priv->beacon_lock);
1778 priv->op_flags |= OP_SCANNING;
1779 spin_unlock_bh(&priv->beacon_lock);
bde748a4 1780 cancel_work_sync(&priv->ps_work);
fe67470d
RM
1781 if (priv->op_flags & OP_ASSOCIATED)
1782 cancel_delayed_work_sync(&priv->ath9k_ani_work);
fb9987d0
S
1783 mutex_unlock(&priv->mutex);
1784}
1785
1786static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
1787{
1788 struct ath9k_htc_priv *priv = hw->priv;
1789
1790 mutex_lock(&priv->mutex);
cb551df2 1791 ath9k_htc_ps_wakeup(priv);
fb9987d0
S
1792 spin_lock_bh(&priv->beacon_lock);
1793 priv->op_flags &= ~OP_SCANNING;
1794 spin_unlock_bh(&priv->beacon_lock);
1795 priv->op_flags |= OP_FULL_RESET;
fe67470d 1796 if (priv->op_flags & OP_ASSOCIATED) {
fcb9392f 1797 ath9k_htc_beacon_config(priv, priv->vif);
fe67470d
RM
1798 ath_start_ani(priv);
1799 }
bde748a4 1800 ath9k_htc_ps_restore(priv);
cb551df2 1801 mutex_unlock(&priv->mutex);
fb9987d0
S
1802}
1803
1804static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1805{
1806 return 0;
1807}
1808
1809static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw,
1810 u8 coverage_class)
1811{
1812 struct ath9k_htc_priv *priv = hw->priv;
1813
1814 mutex_lock(&priv->mutex);
cb551df2 1815 ath9k_htc_ps_wakeup(priv);
fb9987d0
S
1816 priv->ah->coverage_class = coverage_class;
1817 ath9k_hw_init_global_settings(priv->ah);
cb551df2 1818 ath9k_htc_ps_restore(priv);
fb9987d0
S
1819 mutex_unlock(&priv->mutex);
1820}
1821
1822struct ieee80211_ops ath9k_htc_ops = {
1823 .tx = ath9k_htc_tx,
1824 .start = ath9k_htc_start,
1825 .stop = ath9k_htc_stop,
1826 .add_interface = ath9k_htc_add_interface,
1827 .remove_interface = ath9k_htc_remove_interface,
1828 .config = ath9k_htc_config,
1829 .configure_filter = ath9k_htc_configure_filter,
abd984e6
S
1830 .sta_add = ath9k_htc_sta_add,
1831 .sta_remove = ath9k_htc_sta_remove,
fb9987d0
S
1832 .conf_tx = ath9k_htc_conf_tx,
1833 .bss_info_changed = ath9k_htc_bss_info_changed,
1834 .set_key = ath9k_htc_set_key,
1835 .get_tsf = ath9k_htc_get_tsf,
1836 .set_tsf = ath9k_htc_set_tsf,
1837 .reset_tsf = ath9k_htc_reset_tsf,
1838 .ampdu_action = ath9k_htc_ampdu_action,
1839 .sw_scan_start = ath9k_htc_sw_scan_start,
1840 .sw_scan_complete = ath9k_htc_sw_scan_complete,
1841 .set_rts_threshold = ath9k_htc_set_rts_threshold,
1842 .rfkill_poll = ath9k_htc_rfkill_poll_state,
1843 .set_coverage_class = ath9k_htc_set_coverage_class,
1844};
This page took 0.662989 seconds and 5 git commands to generate.