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