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