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