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