ath9k_htc: Handle monitor mode properly for HTC devices
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / net / wireless / ath / ath9k / htc_drv_main.c
blobe9761c2c870073a4fa08e6a7b276bc8f95136c40
1 /*
2 * Copyright (c) 2010 Atheros Communications Inc.
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.
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.
17 #include "htc.h"
19 #ifdef CONFIG_ATH9K_HTC_DEBUGFS
20 static struct dentry *ath9k_debugfs_root;
21 #endif
23 /*************/
24 /* Utilities */
25 /*************/
27 static void ath_update_txpow(struct ath9k_htc_priv *priv)
29 struct ath_hw *ah = priv->ah;
31 if (priv->curtxpow != priv->txpowlimit) {
32 ath9k_hw_set_txpowerlimit(ah, priv->txpowlimit, false);
33 /* read back in case value is clamped */
34 priv->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
38 /* HACK Alert: Use 11NG for 2.4, use 11NA for 5 */
39 static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv,
40 struct ath9k_channel *ichan)
42 enum htc_phymode mode;
44 mode = HTC_MODE_AUTO;
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;
63 return mode;
66 static bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
67 enum ath9k_power_mode mode)
69 bool ret;
71 mutex_lock(&priv->htc_pm_lock);
72 ret = ath9k_hw_setpower(priv->ah, mode);
73 mutex_unlock(&priv->htc_pm_lock);
75 return ret;
78 void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv)
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);
85 unlock:
86 mutex_unlock(&priv->htc_pm_lock);
89 void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv)
91 mutex_lock(&priv->htc_pm_lock);
92 if (--priv->ps_usecount != 0)
93 goto unlock;
95 if (priv->ps_idle)
96 ath9k_hw_setpower(priv->ah, ATH9K_PM_FULL_SLEEP);
97 else if (priv->ps_enabled)
98 ath9k_hw_setpower(priv->ah, ATH9K_PM_NETWORK_SLEEP);
100 unlock:
101 mutex_unlock(&priv->htc_pm_lock);
104 void ath9k_ps_work(struct work_struct *work)
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);
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.
116 ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP);
119 static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
120 struct ieee80211_hw *hw,
121 struct ath9k_channel *hchan)
123 struct ath_hw *ah = priv->ah;
124 struct ath_common *common = ath9k_hw_common(ah);
125 struct ieee80211_conf *conf = &common->hw->conf;
126 bool fastcc = true;
127 struct ieee80211_channel *channel = hw->conf.channel;
128 struct ath9k_hw_cal_data *caldata;
129 enum htc_phymode mode;
130 __be16 htc_mode;
131 u8 cmd_rsp;
132 int ret;
134 if (priv->op_flags & OP_INVALID)
135 return -EIO;
137 if (priv->op_flags & OP_FULL_RESET)
138 fastcc = false;
140 ath9k_htc_ps_wakeup(priv);
141 htc_stop(priv->htc);
142 WMI_CMD(WMI_DISABLE_INTR_CMDID);
143 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
144 WMI_CMD(WMI_STOP_RECV_CMDID);
146 ath_print(common, ATH_DBG_CONFIG,
147 "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n",
148 priv->ah->curchan->channel,
149 channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf),
150 fastcc);
152 caldata = &priv->caldata[channel->hw_value];
153 ret = ath9k_hw_reset(ah, hchan, caldata, fastcc);
154 if (ret) {
155 ath_print(common, ATH_DBG_FATAL,
156 "Unable to reset channel (%u Mhz) "
157 "reset status %d\n", channel->center_freq, ret);
158 goto err;
161 ath_update_txpow(priv);
163 WMI_CMD(WMI_START_RECV_CMDID);
164 if (ret)
165 goto err;
167 ath9k_host_rx_init(priv);
169 mode = ath9k_htc_get_curmode(priv, hchan);
170 htc_mode = cpu_to_be16(mode);
171 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
172 if (ret)
173 goto err;
175 WMI_CMD(WMI_ENABLE_INTR_CMDID);
176 if (ret)
177 goto err;
179 htc_start(priv->htc);
181 priv->op_flags &= ~OP_FULL_RESET;
182 err:
183 ath9k_htc_ps_restore(priv);
184 return ret;
187 static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
188 struct ieee80211_vif *vif,
189 struct ieee80211_sta *sta)
191 struct ath_common *common = ath9k_hw_common(priv->ah);
192 struct ath9k_htc_target_sta tsta;
193 struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
194 struct ath9k_htc_sta *ista;
195 int ret;
196 u8 cmd_rsp;
198 if (priv->nstations >= ATH9K_HTC_MAX_STA)
199 return -ENOBUFS;
201 memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta));
203 if (sta) {
204 ista = (struct ath9k_htc_sta *) sta->drv_priv;
205 memcpy(&tsta.macaddr, sta->addr, ETH_ALEN);
206 memcpy(&tsta.bssid, common->curbssid, ETH_ALEN);
207 tsta.associd = common->curaid;
208 tsta.is_vif_sta = 0;
209 tsta.valid = true;
210 ista->index = priv->nstations;
211 } else {
212 memcpy(&tsta.macaddr, vif->addr, ETH_ALEN);
213 tsta.is_vif_sta = 1;
216 tsta.sta_index = priv->nstations;
217 tsta.vif_index = avp->index;
218 tsta.maxampdu = 0xffff;
219 if (sta && sta->ht_cap.ht_supported)
220 tsta.flags = cpu_to_be16(ATH_HTC_STA_HT);
222 WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
223 if (ret) {
224 if (sta)
225 ath_print(common, ATH_DBG_FATAL,
226 "Unable to add station entry for: %pM\n", sta->addr);
227 return ret;
230 if (sta)
231 ath_print(common, ATH_DBG_CONFIG,
232 "Added a station entry for: %pM (idx: %d)\n",
233 sta->addr, tsta.sta_index);
235 priv->nstations++;
236 return 0;
239 static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
240 struct ieee80211_vif *vif,
241 struct ieee80211_sta *sta)
243 struct ath_common *common = ath9k_hw_common(priv->ah);
244 struct ath9k_htc_sta *ista;
245 int ret;
246 u8 cmd_rsp, sta_idx;
248 if (sta) {
249 ista = (struct ath9k_htc_sta *) sta->drv_priv;
250 sta_idx = ista->index;
251 } else {
252 sta_idx = 0;
255 WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx);
256 if (ret) {
257 if (sta)
258 ath_print(common, ATH_DBG_FATAL,
259 "Unable to remove station entry for: %pM\n",
260 sta->addr);
261 return ret;
264 if (sta)
265 ath_print(common, ATH_DBG_CONFIG,
266 "Removed a station entry for: %pM (idx: %d)\n",
267 sta->addr, sta_idx);
269 priv->nstations--;
270 return 0;
273 static int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv)
275 struct ath9k_htc_cap_target tcap;
276 int ret;
277 u8 cmd_rsp;
279 memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target));
281 /* FIXME: Values are hardcoded */
282 tcap.flags = 0x240c40;
283 tcap.flags_ext = 0x80601000;
284 tcap.ampdu_limit = 0xffff0000;
285 tcap.ampdu_subframes = 20;
286 tcap.tx_chainmask_legacy = priv->ah->caps.tx_chainmask;
287 tcap.protmode = 1;
288 tcap.tx_chainmask = priv->ah->caps.tx_chainmask;
290 WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap);
292 return ret;
295 static void ath9k_htc_setup_rate(struct ath9k_htc_priv *priv,
296 struct ieee80211_sta *sta,
297 struct ath9k_htc_target_rate *trate)
299 struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
300 struct ieee80211_supported_band *sband;
301 u32 caps = 0;
302 int i, j;
304 sband = priv->hw->wiphy->bands[priv->hw->conf.channel->band];
306 for (i = 0, j = 0; i < sband->n_bitrates; i++) {
307 if (sta->supp_rates[sband->band] & BIT(i)) {
308 trate->rates.legacy_rates.rs_rates[j]
309 = (sband->bitrates[i].bitrate * 2) / 10;
310 j++;
313 trate->rates.legacy_rates.rs_nrates = j;
315 if (sta->ht_cap.ht_supported) {
316 for (i = 0, j = 0; i < 77; i++) {
317 if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8)))
318 trate->rates.ht_rates.rs_rates[j++] = i;
319 if (j == ATH_HTC_RATE_MAX)
320 break;
322 trate->rates.ht_rates.rs_nrates = j;
324 caps = WLAN_RC_HT_FLAG;
325 if (sta->ht_cap.mcs.rx_mask[1])
326 caps |= WLAN_RC_DS_FLAG;
327 if ((sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
328 (conf_is_ht40(&priv->hw->conf)))
329 caps |= WLAN_RC_40_FLAG;
330 if (conf_is_ht40(&priv->hw->conf) &&
331 (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40))
332 caps |= WLAN_RC_SGI_FLAG;
333 else if (conf_is_ht20(&priv->hw->conf) &&
334 (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20))
335 caps |= WLAN_RC_SGI_FLAG;
338 trate->sta_index = ista->index;
339 trate->isnew = 1;
340 trate->capflags = cpu_to_be32(caps);
343 static int ath9k_htc_send_rate_cmd(struct ath9k_htc_priv *priv,
344 struct ath9k_htc_target_rate *trate)
346 struct ath_common *common = ath9k_hw_common(priv->ah);
347 int ret;
348 u8 cmd_rsp;
350 WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, trate);
351 if (ret) {
352 ath_print(common, ATH_DBG_FATAL,
353 "Unable to initialize Rate information on target\n");
356 return ret;
359 static void ath9k_htc_init_rate(struct ath9k_htc_priv *priv,
360 struct ieee80211_sta *sta)
362 struct ath_common *common = ath9k_hw_common(priv->ah);
363 struct ath9k_htc_target_rate trate;
364 int ret;
366 memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
367 ath9k_htc_setup_rate(priv, sta, &trate);
368 ret = ath9k_htc_send_rate_cmd(priv, &trate);
369 if (!ret)
370 ath_print(common, ATH_DBG_CONFIG,
371 "Updated target sta: %pM, rate caps: 0x%X\n",
372 sta->addr, be32_to_cpu(trate.capflags));
375 static void ath9k_htc_update_rate(struct ath9k_htc_priv *priv,
376 struct ieee80211_vif *vif,
377 struct ieee80211_bss_conf *bss_conf)
379 struct ath_common *common = ath9k_hw_common(priv->ah);
380 struct ath9k_htc_target_rate trate;
381 struct ieee80211_sta *sta;
382 int ret;
384 memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
386 rcu_read_lock();
387 sta = ieee80211_find_sta(vif, bss_conf->bssid);
388 if (!sta) {
389 rcu_read_unlock();
390 return;
392 ath9k_htc_setup_rate(priv, sta, &trate);
393 rcu_read_unlock();
395 ret = ath9k_htc_send_rate_cmd(priv, &trate);
396 if (!ret)
397 ath_print(common, ATH_DBG_CONFIG,
398 "Updated target sta: %pM, rate caps: 0x%X\n",
399 bss_conf->bssid, be32_to_cpu(trate.capflags));
402 static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv,
403 struct ieee80211_vif *vif,
404 struct ieee80211_sta *sta,
405 enum ieee80211_ampdu_mlme_action action,
406 u16 tid)
408 struct ath_common *common = ath9k_hw_common(priv->ah);
409 struct ath9k_htc_target_aggr aggr;
410 struct ath9k_htc_sta *ista;
411 int ret = 0;
412 u8 cmd_rsp;
414 if (tid >= ATH9K_HTC_MAX_TID)
415 return -EINVAL;
417 memset(&aggr, 0, sizeof(struct ath9k_htc_target_aggr));
418 ista = (struct ath9k_htc_sta *) sta->drv_priv;
420 aggr.sta_index = ista->index;
421 aggr.tidno = tid & 0xf;
422 aggr.aggr_enable = (action == IEEE80211_AMPDU_TX_START) ? true : false;
424 WMI_CMD_BUF(WMI_TX_AGGR_ENABLE_CMDID, &aggr);
425 if (ret)
426 ath_print(common, ATH_DBG_CONFIG,
427 "Unable to %s TX aggregation for (%pM, %d)\n",
428 (aggr.aggr_enable) ? "start" : "stop", sta->addr, tid);
429 else
430 ath_print(common, ATH_DBG_CONFIG,
431 "%s TX aggregation for (%pM, %d)\n",
432 (aggr.aggr_enable) ? "Starting" : "Stopping",
433 sta->addr, tid);
435 spin_lock_bh(&priv->tx_lock);
436 ista->tid_state[tid] = (aggr.aggr_enable && !ret) ? AGGR_START : AGGR_STOP;
437 spin_unlock_bh(&priv->tx_lock);
439 return ret;
442 /*********/
443 /* DEBUG */
444 /*********/
446 #ifdef CONFIG_ATH9K_HTC_DEBUGFS
448 static int ath9k_debugfs_open(struct inode *inode, struct file *file)
450 file->private_data = inode->i_private;
451 return 0;
454 static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf,
455 size_t count, loff_t *ppos)
457 struct ath9k_htc_priv *priv = file->private_data;
458 struct ath9k_htc_target_stats cmd_rsp;
459 char buf[512];
460 unsigned int len = 0;
461 int ret = 0;
463 memset(&cmd_rsp, 0, sizeof(cmd_rsp));
465 WMI_CMD(WMI_TGT_STATS_CMDID);
466 if (ret)
467 return -EINVAL;
470 len += snprintf(buf + len, sizeof(buf) - len,
471 "%19s : %10u\n", "TX Short Retries",
472 be32_to_cpu(cmd_rsp.tx_shortretry));
473 len += snprintf(buf + len, sizeof(buf) - len,
474 "%19s : %10u\n", "TX Long Retries",
475 be32_to_cpu(cmd_rsp.tx_longretry));
476 len += snprintf(buf + len, sizeof(buf) - len,
477 "%19s : %10u\n", "TX Xretries",
478 be32_to_cpu(cmd_rsp.tx_xretries));
479 len += snprintf(buf + len, sizeof(buf) - len,
480 "%19s : %10u\n", "TX Unaggr. Xretries",
481 be32_to_cpu(cmd_rsp.ht_txunaggr_xretry));
482 len += snprintf(buf + len, sizeof(buf) - len,
483 "%19s : %10u\n", "TX Xretries (HT)",
484 be32_to_cpu(cmd_rsp.ht_tx_xretries));
485 len += snprintf(buf + len, sizeof(buf) - len,
486 "%19s : %10u\n", "TX Rate", priv->debug.txrate);
488 if (len > sizeof(buf))
489 len = sizeof(buf);
491 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
494 static const struct file_operations fops_tgt_stats = {
495 .read = read_file_tgt_stats,
496 .open = ath9k_debugfs_open,
497 .owner = THIS_MODULE,
498 .llseek = default_llseek,
501 static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
502 size_t count, loff_t *ppos)
504 struct ath9k_htc_priv *priv = file->private_data;
505 char buf[512];
506 unsigned int len = 0;
508 len += snprintf(buf + len, sizeof(buf) - len,
509 "%20s : %10u\n", "Buffers queued",
510 priv->debug.tx_stats.buf_queued);
511 len += snprintf(buf + len, sizeof(buf) - len,
512 "%20s : %10u\n", "Buffers completed",
513 priv->debug.tx_stats.buf_completed);
514 len += snprintf(buf + len, sizeof(buf) - len,
515 "%20s : %10u\n", "SKBs queued",
516 priv->debug.tx_stats.skb_queued);
517 len += snprintf(buf + len, sizeof(buf) - len,
518 "%20s : %10u\n", "SKBs completed",
519 priv->debug.tx_stats.skb_completed);
520 len += snprintf(buf + len, sizeof(buf) - len,
521 "%20s : %10u\n", "SKBs dropped",
522 priv->debug.tx_stats.skb_dropped);
524 len += snprintf(buf + len, sizeof(buf) - len,
525 "%20s : %10u\n", "BE queued",
526 priv->debug.tx_stats.queue_stats[WME_AC_BE]);
527 len += snprintf(buf + len, sizeof(buf) - len,
528 "%20s : %10u\n", "BK queued",
529 priv->debug.tx_stats.queue_stats[WME_AC_BK]);
530 len += snprintf(buf + len, sizeof(buf) - len,
531 "%20s : %10u\n", "VI queued",
532 priv->debug.tx_stats.queue_stats[WME_AC_VI]);
533 len += snprintf(buf + len, sizeof(buf) - len,
534 "%20s : %10u\n", "VO queued",
535 priv->debug.tx_stats.queue_stats[WME_AC_VO]);
537 if (len > sizeof(buf))
538 len = sizeof(buf);
540 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
543 static const struct file_operations fops_xmit = {
544 .read = read_file_xmit,
545 .open = ath9k_debugfs_open,
546 .owner = THIS_MODULE,
547 .llseek = default_llseek,
550 static ssize_t read_file_recv(struct file *file, char __user *user_buf,
551 size_t count, loff_t *ppos)
553 struct ath9k_htc_priv *priv = file->private_data;
554 char buf[512];
555 unsigned int len = 0;
557 len += snprintf(buf + len, sizeof(buf) - len,
558 "%20s : %10u\n", "SKBs allocated",
559 priv->debug.rx_stats.skb_allocated);
560 len += snprintf(buf + len, sizeof(buf) - len,
561 "%20s : %10u\n", "SKBs completed",
562 priv->debug.rx_stats.skb_completed);
563 len += snprintf(buf + len, sizeof(buf) - len,
564 "%20s : %10u\n", "SKBs Dropped",
565 priv->debug.rx_stats.skb_dropped);
567 if (len > sizeof(buf))
568 len = sizeof(buf);
570 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
573 static const struct file_operations fops_recv = {
574 .read = read_file_recv,
575 .open = ath9k_debugfs_open,
576 .owner = THIS_MODULE,
577 .llseek = default_llseek,
580 int ath9k_htc_init_debug(struct ath_hw *ah)
582 struct ath_common *common = ath9k_hw_common(ah);
583 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
585 if (!ath9k_debugfs_root)
586 return -ENOENT;
588 priv->debug.debugfs_phy = debugfs_create_dir(wiphy_name(priv->hw->wiphy),
589 ath9k_debugfs_root);
590 if (!priv->debug.debugfs_phy)
591 goto err;
593 priv->debug.debugfs_tgt_stats = debugfs_create_file("tgt_stats", S_IRUSR,
594 priv->debug.debugfs_phy,
595 priv, &fops_tgt_stats);
596 if (!priv->debug.debugfs_tgt_stats)
597 goto err;
600 priv->debug.debugfs_xmit = debugfs_create_file("xmit", S_IRUSR,
601 priv->debug.debugfs_phy,
602 priv, &fops_xmit);
603 if (!priv->debug.debugfs_xmit)
604 goto err;
606 priv->debug.debugfs_recv = debugfs_create_file("recv", S_IRUSR,
607 priv->debug.debugfs_phy,
608 priv, &fops_recv);
609 if (!priv->debug.debugfs_recv)
610 goto err;
612 return 0;
614 err:
615 ath9k_htc_exit_debug(ah);
616 return -ENOMEM;
619 void ath9k_htc_exit_debug(struct ath_hw *ah)
621 struct ath_common *common = ath9k_hw_common(ah);
622 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
624 debugfs_remove(priv->debug.debugfs_recv);
625 debugfs_remove(priv->debug.debugfs_xmit);
626 debugfs_remove(priv->debug.debugfs_tgt_stats);
627 debugfs_remove(priv->debug.debugfs_phy);
630 int ath9k_htc_debug_create_root(void)
632 ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
633 if (!ath9k_debugfs_root)
634 return -ENOENT;
636 return 0;
639 void ath9k_htc_debug_remove_root(void)
641 debugfs_remove(ath9k_debugfs_root);
642 ath9k_debugfs_root = NULL;
645 #endif /* CONFIG_ATH9K_HTC_DEBUGFS */
647 /*******/
648 /* ANI */
649 /*******/
651 static void ath_start_ani(struct ath9k_htc_priv *priv)
653 struct ath_common *common = ath9k_hw_common(priv->ah);
654 unsigned long timestamp = jiffies_to_msecs(jiffies);
656 common->ani.longcal_timer = timestamp;
657 common->ani.shortcal_timer = timestamp;
658 common->ani.checkani_timer = timestamp;
660 ieee80211_queue_delayed_work(common->hw, &priv->ath9k_ani_work,
661 msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
664 void ath9k_ani_work(struct work_struct *work)
666 struct ath9k_htc_priv *priv =
667 container_of(work, struct ath9k_htc_priv,
668 ath9k_ani_work.work);
669 struct ath_hw *ah = priv->ah;
670 struct ath_common *common = ath9k_hw_common(ah);
671 bool longcal = false;
672 bool shortcal = false;
673 bool aniflag = false;
674 unsigned int timestamp = jiffies_to_msecs(jiffies);
675 u32 cal_interval, short_cal_interval;
677 short_cal_interval = ATH_STA_SHORT_CALINTERVAL;
679 /* Only calibrate if awake */
680 if (ah->power_mode != ATH9K_PM_AWAKE)
681 goto set_timer;
683 /* Long calibration runs independently of short calibration. */
684 if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
685 longcal = true;
686 ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
687 common->ani.longcal_timer = timestamp;
690 /* Short calibration applies only while caldone is false */
691 if (!common->ani.caldone) {
692 if ((timestamp - common->ani.shortcal_timer) >=
693 short_cal_interval) {
694 shortcal = true;
695 ath_print(common, ATH_DBG_ANI,
696 "shortcal @%lu\n", jiffies);
697 common->ani.shortcal_timer = timestamp;
698 common->ani.resetcal_timer = timestamp;
700 } else {
701 if ((timestamp - common->ani.resetcal_timer) >=
702 ATH_RESTART_CALINTERVAL) {
703 common->ani.caldone = ath9k_hw_reset_calvalid(ah);
704 if (common->ani.caldone)
705 common->ani.resetcal_timer = timestamp;
709 /* Verify whether we must check ANI */
710 if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
711 aniflag = true;
712 common->ani.checkani_timer = timestamp;
715 /* Skip all processing if there's nothing to do. */
716 if (longcal || shortcal || aniflag) {
718 ath9k_htc_ps_wakeup(priv);
720 /* Call ANI routine if necessary */
721 if (aniflag)
722 ath9k_hw_ani_monitor(ah, ah->curchan);
724 /* Perform calibration if necessary */
725 if (longcal || shortcal)
726 common->ani.caldone =
727 ath9k_hw_calibrate(ah, ah->curchan,
728 common->rx_chainmask,
729 longcal);
731 ath9k_htc_ps_restore(priv);
734 set_timer:
736 * Set timer interval based on previous results.
737 * The interval must be the shortest necessary to satisfy ANI,
738 * short calibration and long calibration.
740 cal_interval = ATH_LONG_CALINTERVAL;
741 if (priv->ah->config.enable_ani)
742 cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
743 if (!common->ani.caldone)
744 cal_interval = min(cal_interval, (u32)short_cal_interval);
746 ieee80211_queue_delayed_work(common->hw, &priv->ath9k_ani_work,
747 msecs_to_jiffies(cal_interval));
750 /*******/
751 /* LED */
752 /*******/
754 static void ath9k_led_blink_work(struct work_struct *work)
756 struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv,
757 ath9k_led_blink_work.work);
759 if (!(priv->op_flags & OP_LED_ASSOCIATED))
760 return;
762 if ((priv->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
763 (priv->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
764 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
765 else
766 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
767 (priv->op_flags & OP_LED_ON) ? 1 : 0);
769 ieee80211_queue_delayed_work(priv->hw,
770 &priv->ath9k_led_blink_work,
771 (priv->op_flags & OP_LED_ON) ?
772 msecs_to_jiffies(priv->led_off_duration) :
773 msecs_to_jiffies(priv->led_on_duration));
775 priv->led_on_duration = priv->led_on_cnt ?
776 max((ATH_LED_ON_DURATION_IDLE - priv->led_on_cnt), 25) :
777 ATH_LED_ON_DURATION_IDLE;
778 priv->led_off_duration = priv->led_off_cnt ?
779 max((ATH_LED_OFF_DURATION_IDLE - priv->led_off_cnt), 10) :
780 ATH_LED_OFF_DURATION_IDLE;
781 priv->led_on_cnt = priv->led_off_cnt = 0;
783 if (priv->op_flags & OP_LED_ON)
784 priv->op_flags &= ~OP_LED_ON;
785 else
786 priv->op_flags |= OP_LED_ON;
789 static void ath9k_led_brightness_work(struct work_struct *work)
791 struct ath_led *led = container_of(work, struct ath_led,
792 brightness_work.work);
793 struct ath9k_htc_priv *priv = led->priv;
795 switch (led->brightness) {
796 case LED_OFF:
797 if (led->led_type == ATH_LED_ASSOC ||
798 led->led_type == ATH_LED_RADIO) {
799 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
800 (led->led_type == ATH_LED_RADIO));
801 priv->op_flags &= ~OP_LED_ASSOCIATED;
802 if (led->led_type == ATH_LED_RADIO)
803 priv->op_flags &= ~OP_LED_ON;
804 } else {
805 priv->led_off_cnt++;
807 break;
808 case LED_FULL:
809 if (led->led_type == ATH_LED_ASSOC) {
810 priv->op_flags |= OP_LED_ASSOCIATED;
811 ieee80211_queue_delayed_work(priv->hw,
812 &priv->ath9k_led_blink_work, 0);
813 } else if (led->led_type == ATH_LED_RADIO) {
814 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
815 priv->op_flags |= OP_LED_ON;
816 } else {
817 priv->led_on_cnt++;
819 break;
820 default:
821 break;
825 static void ath9k_led_brightness(struct led_classdev *led_cdev,
826 enum led_brightness brightness)
828 struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
829 struct ath9k_htc_priv *priv = led->priv;
831 led->brightness = brightness;
832 if (!(priv->op_flags & OP_LED_DEINIT))
833 ieee80211_queue_delayed_work(priv->hw,
834 &led->brightness_work, 0);
837 static void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv)
839 cancel_delayed_work_sync(&priv->radio_led.brightness_work);
840 cancel_delayed_work_sync(&priv->assoc_led.brightness_work);
841 cancel_delayed_work_sync(&priv->tx_led.brightness_work);
842 cancel_delayed_work_sync(&priv->rx_led.brightness_work);
845 static int ath9k_register_led(struct ath9k_htc_priv *priv, struct ath_led *led,
846 char *trigger)
848 int ret;
850 led->priv = priv;
851 led->led_cdev.name = led->name;
852 led->led_cdev.default_trigger = trigger;
853 led->led_cdev.brightness_set = ath9k_led_brightness;
855 ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_cdev);
856 if (ret)
857 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
858 "Failed to register led:%s", led->name);
859 else
860 led->registered = 1;
862 INIT_DELAYED_WORK(&led->brightness_work, ath9k_led_brightness_work);
864 return ret;
867 static void ath9k_unregister_led(struct ath_led *led)
869 if (led->registered) {
870 led_classdev_unregister(&led->led_cdev);
871 led->registered = 0;
875 void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
877 priv->op_flags |= OP_LED_DEINIT;
878 ath9k_unregister_led(&priv->assoc_led);
879 priv->op_flags &= ~OP_LED_ASSOCIATED;
880 ath9k_unregister_led(&priv->tx_led);
881 ath9k_unregister_led(&priv->rx_led);
882 ath9k_unregister_led(&priv->radio_led);
885 void ath9k_init_leds(struct ath9k_htc_priv *priv)
887 char *trigger;
888 int ret;
890 if (AR_SREV_9287(priv->ah))
891 priv->ah->led_pin = ATH_LED_PIN_9287;
892 else if (AR_SREV_9271(priv->ah))
893 priv->ah->led_pin = ATH_LED_PIN_9271;
894 else if (AR_DEVID_7010(priv->ah))
895 priv->ah->led_pin = ATH_LED_PIN_7010;
896 else
897 priv->ah->led_pin = ATH_LED_PIN_DEF;
899 /* Configure gpio 1 for output */
900 ath9k_hw_cfg_output(priv->ah, priv->ah->led_pin,
901 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
902 /* LED off, active low */
903 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1);
905 INIT_DELAYED_WORK(&priv->ath9k_led_blink_work, ath9k_led_blink_work);
907 trigger = ieee80211_get_radio_led_name(priv->hw);
908 snprintf(priv->radio_led.name, sizeof(priv->radio_led.name),
909 "ath9k-%s::radio", wiphy_name(priv->hw->wiphy));
910 ret = ath9k_register_led(priv, &priv->radio_led, trigger);
911 priv->radio_led.led_type = ATH_LED_RADIO;
912 if (ret)
913 goto fail;
915 trigger = ieee80211_get_assoc_led_name(priv->hw);
916 snprintf(priv->assoc_led.name, sizeof(priv->assoc_led.name),
917 "ath9k-%s::assoc", wiphy_name(priv->hw->wiphy));
918 ret = ath9k_register_led(priv, &priv->assoc_led, trigger);
919 priv->assoc_led.led_type = ATH_LED_ASSOC;
920 if (ret)
921 goto fail;
923 trigger = ieee80211_get_tx_led_name(priv->hw);
924 snprintf(priv->tx_led.name, sizeof(priv->tx_led.name),
925 "ath9k-%s::tx", wiphy_name(priv->hw->wiphy));
926 ret = ath9k_register_led(priv, &priv->tx_led, trigger);
927 priv->tx_led.led_type = ATH_LED_TX;
928 if (ret)
929 goto fail;
931 trigger = ieee80211_get_rx_led_name(priv->hw);
932 snprintf(priv->rx_led.name, sizeof(priv->rx_led.name),
933 "ath9k-%s::rx", wiphy_name(priv->hw->wiphy));
934 ret = ath9k_register_led(priv, &priv->rx_led, trigger);
935 priv->rx_led.led_type = ATH_LED_RX;
936 if (ret)
937 goto fail;
939 priv->op_flags &= ~OP_LED_DEINIT;
941 return;
943 fail:
944 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
945 ath9k_deinit_leds(priv);
948 /*******************/
949 /* Rfkill */
950 /*******************/
952 static bool ath_is_rfkill_set(struct ath9k_htc_priv *priv)
954 return ath9k_hw_gpio_get(priv->ah, priv->ah->rfkill_gpio) ==
955 priv->ah->rfkill_polarity;
958 static void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw)
960 struct ath9k_htc_priv *priv = hw->priv;
961 bool blocked = !!ath_is_rfkill_set(priv);
963 wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
966 void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv)
968 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
969 wiphy_rfkill_start_polling(priv->hw->wiphy);
972 static void ath9k_htc_radio_enable(struct ieee80211_hw *hw)
974 struct ath9k_htc_priv *priv = hw->priv;
975 struct ath_hw *ah = priv->ah;
976 struct ath_common *common = ath9k_hw_common(ah);
977 int ret;
978 u8 cmd_rsp;
980 if (!ah->curchan)
981 ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
983 /* Reset the HW */
984 ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
985 if (ret) {
986 ath_print(common, ATH_DBG_FATAL,
987 "Unable to reset hardware; reset status %d "
988 "(freq %u MHz)\n", ret, ah->curchan->channel);
991 ath_update_txpow(priv);
993 /* Start RX */
994 WMI_CMD(WMI_START_RECV_CMDID);
995 ath9k_host_rx_init(priv);
997 /* Start TX */
998 htc_start(priv->htc);
999 spin_lock_bh(&priv->tx_lock);
1000 priv->tx_queues_stop = false;
1001 spin_unlock_bh(&priv->tx_lock);
1002 ieee80211_wake_queues(hw);
1004 WMI_CMD(WMI_ENABLE_INTR_CMDID);
1006 /* Enable LED */
1007 ath9k_hw_cfg_output(ah, ah->led_pin,
1008 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
1009 ath9k_hw_set_gpio(ah, ah->led_pin, 0);
1012 static void ath9k_htc_radio_disable(struct ieee80211_hw *hw)
1014 struct ath9k_htc_priv *priv = hw->priv;
1015 struct ath_hw *ah = priv->ah;
1016 struct ath_common *common = ath9k_hw_common(ah);
1017 int ret;
1018 u8 cmd_rsp;
1020 ath9k_htc_ps_wakeup(priv);
1022 /* Disable LED */
1023 ath9k_hw_set_gpio(ah, ah->led_pin, 1);
1024 ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
1026 WMI_CMD(WMI_DISABLE_INTR_CMDID);
1028 /* Stop TX */
1029 ieee80211_stop_queues(hw);
1030 htc_stop(priv->htc);
1031 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
1032 skb_queue_purge(&priv->tx_queue);
1034 /* Stop RX */
1035 WMI_CMD(WMI_STOP_RECV_CMDID);
1038 * The MIB counters have to be disabled here,
1039 * since the target doesn't do it.
1041 ath9k_hw_disable_mib_counters(ah);
1043 if (!ah->curchan)
1044 ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
1046 /* Reset the HW */
1047 ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
1048 if (ret) {
1049 ath_print(common, ATH_DBG_FATAL,
1050 "Unable to reset hardware; reset status %d "
1051 "(freq %u MHz)\n", ret, ah->curchan->channel);
1054 /* Disable the PHY */
1055 ath9k_hw_phy_disable(ah);
1057 ath9k_htc_ps_restore(priv);
1058 ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
1061 /**********************/
1062 /* mac80211 Callbacks */
1063 /**********************/
1065 static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
1067 struct ieee80211_hdr *hdr;
1068 struct ath9k_htc_priv *priv = hw->priv;
1069 int padpos, padsize, ret;
1071 hdr = (struct ieee80211_hdr *) skb->data;
1073 /* Add the padding after the header if this is not already done */
1074 padpos = ath9k_cmn_padpos(hdr->frame_control);
1075 padsize = padpos & 3;
1076 if (padsize && skb->len > padpos) {
1077 if (skb_headroom(skb) < padsize)
1078 return -1;
1079 skb_push(skb, padsize);
1080 memmove(skb->data, skb->data + padsize, padpos);
1083 ret = ath9k_htc_tx_start(priv, skb);
1084 if (ret != 0) {
1085 if (ret == -ENOMEM) {
1086 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
1087 "Stopping TX queues\n");
1088 ieee80211_stop_queues(hw);
1089 spin_lock_bh(&priv->tx_lock);
1090 priv->tx_queues_stop = true;
1091 spin_unlock_bh(&priv->tx_lock);
1092 } else {
1093 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
1094 "Tx failed");
1096 goto fail_tx;
1099 return 0;
1101 fail_tx:
1102 dev_kfree_skb_any(skb);
1103 return 0;
1106 static int ath9k_htc_start(struct ieee80211_hw *hw)
1108 struct ath9k_htc_priv *priv = hw->priv;
1109 struct ath_hw *ah = priv->ah;
1110 struct ath_common *common = ath9k_hw_common(ah);
1111 struct ieee80211_channel *curchan = hw->conf.channel;
1112 struct ath9k_channel *init_channel;
1113 int ret = 0;
1114 enum htc_phymode mode;
1115 __be16 htc_mode;
1116 u8 cmd_rsp;
1118 mutex_lock(&priv->mutex);
1120 ath_print(common, ATH_DBG_CONFIG,
1121 "Starting driver with initial channel: %d MHz\n",
1122 curchan->center_freq);
1124 /* Ensure that HW is awake before flushing RX */
1125 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
1126 WMI_CMD(WMI_FLUSH_RECV_CMDID);
1128 /* setup initial channel */
1129 init_channel = ath9k_cmn_get_curchannel(hw, ah);
1131 /* Reset SERDES registers */
1132 ath9k_hw_configpcipowersave(ah, 0, 0);
1134 ath9k_hw_htc_resetinit(ah);
1135 ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
1136 if (ret) {
1137 ath_print(common, ATH_DBG_FATAL,
1138 "Unable to reset hardware; reset status %d "
1139 "(freq %u MHz)\n", ret, curchan->center_freq);
1140 mutex_unlock(&priv->mutex);
1141 return ret;
1144 ath_update_txpow(priv);
1146 mode = ath9k_htc_get_curmode(priv, init_channel);
1147 htc_mode = cpu_to_be16(mode);
1148 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
1149 WMI_CMD(WMI_ATH_INIT_CMDID);
1150 WMI_CMD(WMI_START_RECV_CMDID);
1152 ath9k_host_rx_init(priv);
1154 priv->op_flags &= ~OP_INVALID;
1155 htc_start(priv->htc);
1157 spin_lock_bh(&priv->tx_lock);
1158 priv->tx_queues_stop = false;
1159 spin_unlock_bh(&priv->tx_lock);
1161 ieee80211_wake_queues(hw);
1163 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) {
1164 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
1165 AR_STOMP_LOW_WLAN_WGHT);
1166 ath9k_hw_btcoex_enable(ah);
1167 ath_htc_resume_btcoex_work(priv);
1169 mutex_unlock(&priv->mutex);
1171 return ret;
1174 static void ath9k_htc_stop(struct ieee80211_hw *hw)
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;
1182 mutex_lock(&priv->mutex);
1184 if (priv->op_flags & OP_INVALID) {
1185 ath_print(common, ATH_DBG_ANY, "Device not present\n");
1186 mutex_unlock(&priv->mutex);
1187 return;
1190 /* Cancel all the running timers/work .. */
1191 cancel_work_sync(&priv->ps_work);
1192 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
1193 ath9k_led_stop_brightness(priv);
1195 ath9k_htc_ps_wakeup(priv);
1196 htc_stop(priv->htc);
1197 WMI_CMD(WMI_DISABLE_INTR_CMDID);
1198 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
1199 WMI_CMD(WMI_STOP_RECV_CMDID);
1200 skb_queue_purge(&priv->tx_queue);
1202 if (ah->btcoex_hw.enabled) {
1203 ath9k_hw_btcoex_disable(ah);
1204 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
1205 ath_htc_cancel_btcoex_work(priv);
1208 ath9k_hw_phy_disable(ah);
1209 ath9k_hw_disable(ah);
1210 ath9k_hw_configpcipowersave(ah, 1, 1);
1211 ath9k_htc_ps_restore(priv);
1212 ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
1214 priv->op_flags |= OP_INVALID;
1216 ath_print(common, ATH_DBG_CONFIG, "Driver halt\n");
1217 mutex_unlock(&priv->mutex);
1220 static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1221 struct ieee80211_vif *vif)
1223 struct ath9k_htc_priv *priv = hw->priv;
1224 struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1225 struct ath_common *common = ath9k_hw_common(priv->ah);
1226 struct ath9k_htc_target_vif hvif;
1227 int ret = 0;
1228 u8 cmd_rsp;
1230 mutex_lock(&priv->mutex);
1232 /* Only one interface for now */
1233 if (priv->nvifs > 0) {
1234 ret = -ENOBUFS;
1235 goto out;
1238 ath9k_htc_ps_wakeup(priv);
1239 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
1240 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
1242 switch (vif->type) {
1243 case NL80211_IFTYPE_STATION:
1244 hvif.opmode = cpu_to_be32(HTC_M_STA);
1245 break;
1246 case NL80211_IFTYPE_ADHOC:
1247 hvif.opmode = cpu_to_be32(HTC_M_IBSS);
1248 break;
1249 default:
1250 ath_print(common, ATH_DBG_FATAL,
1251 "Interface type %d not yet supported\n", vif->type);
1252 ret = -EOPNOTSUPP;
1253 goto out;
1256 ath_print(common, ATH_DBG_CONFIG,
1257 "Attach a VIF of type: %d\n", vif->type);
1259 priv->ah->opmode = vif->type;
1261 /* Index starts from zero on the target */
1262 avp->index = hvif.index = priv->nvifs;
1263 hvif.rtsthreshold = cpu_to_be16(2304);
1264 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
1265 if (ret)
1266 goto out;
1268 priv->nvifs++;
1271 * We need a node in target to tx mgmt frames
1272 * before association.
1274 ret = ath9k_htc_add_station(priv, vif, NULL);
1275 if (ret)
1276 goto out;
1278 ret = ath9k_htc_update_cap_target(priv);
1279 if (ret)
1280 ath_print(common, ATH_DBG_CONFIG, "Failed to update"
1281 " capability in target \n");
1283 priv->vif = vif;
1284 out:
1285 ath9k_htc_ps_restore(priv);
1286 mutex_unlock(&priv->mutex);
1288 return ret;
1291 static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
1292 struct ieee80211_vif *vif)
1294 struct ath9k_htc_priv *priv = hw->priv;
1295 struct ath_common *common = ath9k_hw_common(priv->ah);
1296 struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1297 struct ath9k_htc_target_vif hvif;
1298 int ret = 0;
1299 u8 cmd_rsp;
1301 ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n");
1303 mutex_lock(&priv->mutex);
1304 ath9k_htc_ps_wakeup(priv);
1306 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
1307 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
1308 hvif.index = avp->index;
1309 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
1310 priv->nvifs--;
1312 ath9k_htc_remove_station(priv, vif, NULL);
1313 priv->vif = NULL;
1315 ath9k_htc_ps_restore(priv);
1316 mutex_unlock(&priv->mutex);
1319 static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
1321 struct ath9k_htc_priv *priv = hw->priv;
1322 struct ath_common *common = ath9k_hw_common(priv->ah);
1323 struct ieee80211_conf *conf = &hw->conf;
1325 mutex_lock(&priv->mutex);
1327 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1328 bool enable_radio = false;
1329 bool idle = !!(conf->flags & IEEE80211_CONF_IDLE);
1331 mutex_lock(&priv->htc_pm_lock);
1332 if (!idle && priv->ps_idle)
1333 enable_radio = true;
1334 priv->ps_idle = idle;
1335 mutex_unlock(&priv->htc_pm_lock);
1337 if (enable_radio) {
1338 ath_print(common, ATH_DBG_CONFIG,
1339 "not-idle: enabling radio\n");
1340 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
1341 ath9k_htc_radio_enable(hw);
1345 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1346 struct ieee80211_channel *curchan = hw->conf.channel;
1347 int pos = curchan->hw_value;
1349 ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
1350 curchan->center_freq);
1352 ath9k_cmn_update_ichannel(&priv->ah->channels[pos],
1353 hw->conf.channel,
1354 hw->conf.channel_type);
1356 if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) {
1357 ath_print(common, ATH_DBG_FATAL,
1358 "Unable to set channel\n");
1359 mutex_unlock(&priv->mutex);
1360 return -EINVAL;
1364 if (changed & IEEE80211_CONF_CHANGE_PS) {
1365 if (conf->flags & IEEE80211_CONF_PS) {
1366 ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP);
1367 priv->ps_enabled = true;
1368 } else {
1369 priv->ps_enabled = false;
1370 cancel_work_sync(&priv->ps_work);
1371 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
1375 if (changed & IEEE80211_CONF_CHANGE_MONITOR)
1376 if (conf->flags & IEEE80211_CONF_MONITOR) {
1377 ath_print(common, ATH_DBG_CONFIG,
1378 "HW opmode set to Monitor mode\n");
1379 priv->ah->opmode = NL80211_IFTYPE_MONITOR;
1383 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1384 mutex_lock(&priv->htc_pm_lock);
1385 if (!priv->ps_idle) {
1386 mutex_unlock(&priv->htc_pm_lock);
1387 goto out;
1389 mutex_unlock(&priv->htc_pm_lock);
1391 ath_print(common, ATH_DBG_CONFIG,
1392 "idle: disabling radio\n");
1393 ath9k_htc_radio_disable(hw);
1396 out:
1397 mutex_unlock(&priv->mutex);
1398 return 0;
1401 #define SUPPORTED_FILTERS \
1402 (FIF_PROMISC_IN_BSS | \
1403 FIF_ALLMULTI | \
1404 FIF_CONTROL | \
1405 FIF_PSPOLL | \
1406 FIF_OTHER_BSS | \
1407 FIF_BCN_PRBRESP_PROMISC | \
1408 FIF_PROBE_REQ | \
1409 FIF_FCSFAIL)
1411 static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
1412 unsigned int changed_flags,
1413 unsigned int *total_flags,
1414 u64 multicast)
1416 struct ath9k_htc_priv *priv = hw->priv;
1417 u32 rfilt;
1419 mutex_lock(&priv->mutex);
1420 ath9k_htc_ps_wakeup(priv);
1422 changed_flags &= SUPPORTED_FILTERS;
1423 *total_flags &= SUPPORTED_FILTERS;
1425 priv->rxfilter = *total_flags;
1426 rfilt = ath9k_htc_calcrxfilter(priv);
1427 ath9k_hw_setrxfilter(priv->ah, rfilt);
1429 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_CONFIG,
1430 "Set HW RX filter: 0x%x\n", rfilt);
1432 ath9k_htc_ps_restore(priv);
1433 mutex_unlock(&priv->mutex);
1436 static int ath9k_htc_sta_add(struct ieee80211_hw *hw,
1437 struct ieee80211_vif *vif,
1438 struct ieee80211_sta *sta)
1440 struct ath9k_htc_priv *priv = hw->priv;
1441 int ret;
1443 mutex_lock(&priv->mutex);
1444 ath9k_htc_ps_wakeup(priv);
1445 ret = ath9k_htc_add_station(priv, vif, sta);
1446 if (!ret)
1447 ath9k_htc_init_rate(priv, sta);
1448 ath9k_htc_ps_restore(priv);
1449 mutex_unlock(&priv->mutex);
1451 return ret;
1454 static int ath9k_htc_sta_remove(struct ieee80211_hw *hw,
1455 struct ieee80211_vif *vif,
1456 struct ieee80211_sta *sta)
1458 struct ath9k_htc_priv *priv = hw->priv;
1459 int ret;
1461 mutex_lock(&priv->mutex);
1462 ath9k_htc_ps_wakeup(priv);
1463 ret = ath9k_htc_remove_station(priv, vif, sta);
1464 ath9k_htc_ps_restore(priv);
1465 mutex_unlock(&priv->mutex);
1467 return ret;
1470 static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, u16 queue,
1471 const struct ieee80211_tx_queue_params *params)
1473 struct ath9k_htc_priv *priv = hw->priv;
1474 struct ath_common *common = ath9k_hw_common(priv->ah);
1475 struct ath9k_tx_queue_info qi;
1476 int ret = 0, qnum;
1478 if (queue >= WME_NUM_AC)
1479 return 0;
1481 mutex_lock(&priv->mutex);
1482 ath9k_htc_ps_wakeup(priv);
1484 memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
1486 qi.tqi_aifs = params->aifs;
1487 qi.tqi_cwmin = params->cw_min;
1488 qi.tqi_cwmax = params->cw_max;
1489 qi.tqi_burstTime = params->txop;
1491 qnum = get_hw_qnum(queue, priv->hwq_map);
1493 ath_print(common, ATH_DBG_CONFIG,
1494 "Configure tx [queue/hwq] [%d/%d], "
1495 "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
1496 queue, qnum, params->aifs, params->cw_min,
1497 params->cw_max, params->txop);
1499 ret = ath_htc_txq_update(priv, qnum, &qi);
1500 if (ret) {
1501 ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n");
1502 goto out;
1505 if ((priv->ah->opmode == NL80211_IFTYPE_ADHOC) &&
1506 (qnum == priv->hwq_map[WME_AC_BE]))
1507 ath9k_htc_beaconq_config(priv);
1508 out:
1509 ath9k_htc_ps_restore(priv);
1510 mutex_unlock(&priv->mutex);
1512 return ret;
1515 static int ath9k_htc_set_key(struct ieee80211_hw *hw,
1516 enum set_key_cmd cmd,
1517 struct ieee80211_vif *vif,
1518 struct ieee80211_sta *sta,
1519 struct ieee80211_key_conf *key)
1521 struct ath9k_htc_priv *priv = hw->priv;
1522 struct ath_common *common = ath9k_hw_common(priv->ah);
1523 int ret = 0;
1525 if (htc_modparam_nohwcrypt)
1526 return -ENOSPC;
1528 mutex_lock(&priv->mutex);
1529 ath_print(common, ATH_DBG_CONFIG, "Set HW Key\n");
1530 ath9k_htc_ps_wakeup(priv);
1532 switch (cmd) {
1533 case SET_KEY:
1534 ret = ath_key_config(common, vif, sta, key);
1535 if (ret >= 0) {
1536 key->hw_key_idx = ret;
1537 /* push IV and Michael MIC generation to stack */
1538 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1539 if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
1540 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1541 if (priv->ah->sw_mgmt_crypto &&
1542 key->cipher == WLAN_CIPHER_SUITE_CCMP)
1543 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
1544 ret = 0;
1546 break;
1547 case DISABLE_KEY:
1548 ath_key_delete(common, key);
1549 break;
1550 default:
1551 ret = -EINVAL;
1554 ath9k_htc_ps_restore(priv);
1555 mutex_unlock(&priv->mutex);
1557 return ret;
1560 static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
1561 struct ieee80211_vif *vif,
1562 struct ieee80211_bss_conf *bss_conf,
1563 u32 changed)
1565 struct ath9k_htc_priv *priv = hw->priv;
1566 struct ath_hw *ah = priv->ah;
1567 struct ath_common *common = ath9k_hw_common(ah);
1569 mutex_lock(&priv->mutex);
1570 ath9k_htc_ps_wakeup(priv);
1572 if (changed & BSS_CHANGED_ASSOC) {
1573 common->curaid = bss_conf->assoc ?
1574 bss_conf->aid : 0;
1575 ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
1576 bss_conf->assoc);
1578 if (bss_conf->assoc) {
1579 priv->op_flags |= OP_ASSOCIATED;
1580 ath_start_ani(priv);
1581 } else {
1582 priv->op_flags &= ~OP_ASSOCIATED;
1583 cancel_delayed_work_sync(&priv->ath9k_ani_work);
1587 if (changed & BSS_CHANGED_BSSID) {
1588 /* Set BSSID */
1589 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1590 ath9k_hw_write_associd(ah);
1592 ath_print(common, ATH_DBG_CONFIG,
1593 "BSSID: %pM aid: 0x%x\n",
1594 common->curbssid, common->curaid);
1597 if ((changed & BSS_CHANGED_BEACON_INT) ||
1598 (changed & BSS_CHANGED_BEACON) ||
1599 ((changed & BSS_CHANGED_BEACON_ENABLED) &&
1600 bss_conf->enable_beacon)) {
1601 priv->op_flags |= OP_ENABLE_BEACON;
1602 ath9k_htc_beacon_config(priv, vif);
1605 if ((changed & BSS_CHANGED_BEACON_ENABLED) &&
1606 !bss_conf->enable_beacon) {
1607 priv->op_flags &= ~OP_ENABLE_BEACON;
1608 ath9k_htc_beacon_config(priv, vif);
1611 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
1612 ath_print(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
1613 bss_conf->use_short_preamble);
1614 if (bss_conf->use_short_preamble)
1615 priv->op_flags |= OP_PREAMBLE_SHORT;
1616 else
1617 priv->op_flags &= ~OP_PREAMBLE_SHORT;
1620 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
1621 ath_print(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n",
1622 bss_conf->use_cts_prot);
1623 if (bss_conf->use_cts_prot &&
1624 hw->conf.channel->band != IEEE80211_BAND_5GHZ)
1625 priv->op_flags |= OP_PROTECT_ENABLE;
1626 else
1627 priv->op_flags &= ~OP_PROTECT_ENABLE;
1630 if (changed & BSS_CHANGED_ERP_SLOT) {
1631 if (bss_conf->use_short_slot)
1632 ah->slottime = 9;
1633 else
1634 ah->slottime = 20;
1636 ath9k_hw_init_global_settings(ah);
1639 if (changed & BSS_CHANGED_HT)
1640 ath9k_htc_update_rate(priv, vif, bss_conf);
1642 ath9k_htc_ps_restore(priv);
1643 mutex_unlock(&priv->mutex);
1646 static u64 ath9k_htc_get_tsf(struct ieee80211_hw *hw)
1648 struct ath9k_htc_priv *priv = hw->priv;
1649 u64 tsf;
1651 mutex_lock(&priv->mutex);
1652 ath9k_htc_ps_wakeup(priv);
1653 tsf = ath9k_hw_gettsf64(priv->ah);
1654 ath9k_htc_ps_restore(priv);
1655 mutex_unlock(&priv->mutex);
1657 return tsf;
1660 static void ath9k_htc_set_tsf(struct ieee80211_hw *hw, u64 tsf)
1662 struct ath9k_htc_priv *priv = hw->priv;
1664 mutex_lock(&priv->mutex);
1665 ath9k_htc_ps_wakeup(priv);
1666 ath9k_hw_settsf64(priv->ah, tsf);
1667 ath9k_htc_ps_restore(priv);
1668 mutex_unlock(&priv->mutex);
1671 static void ath9k_htc_reset_tsf(struct ieee80211_hw *hw)
1673 struct ath9k_htc_priv *priv = hw->priv;
1675 mutex_lock(&priv->mutex);
1676 ath9k_htc_ps_wakeup(priv);
1677 ath9k_hw_reset_tsf(priv->ah);
1678 ath9k_htc_ps_restore(priv);
1679 mutex_unlock(&priv->mutex);
1682 static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
1683 struct ieee80211_vif *vif,
1684 enum ieee80211_ampdu_mlme_action action,
1685 struct ieee80211_sta *sta,
1686 u16 tid, u16 *ssn)
1688 struct ath9k_htc_priv *priv = hw->priv;
1689 struct ath9k_htc_sta *ista;
1690 int ret = 0;
1692 switch (action) {
1693 case IEEE80211_AMPDU_RX_START:
1694 break;
1695 case IEEE80211_AMPDU_RX_STOP:
1696 break;
1697 case IEEE80211_AMPDU_TX_START:
1698 ret = ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid);
1699 if (!ret)
1700 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1701 break;
1702 case IEEE80211_AMPDU_TX_STOP:
1703 ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid);
1704 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1705 break;
1706 case IEEE80211_AMPDU_TX_OPERATIONAL:
1707 ista = (struct ath9k_htc_sta *) sta->drv_priv;
1708 spin_lock_bh(&priv->tx_lock);
1709 ista->tid_state[tid] = AGGR_OPERATIONAL;
1710 spin_unlock_bh(&priv->tx_lock);
1711 break;
1712 default:
1713 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
1714 "Unknown AMPDU action\n");
1717 return ret;
1720 static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw)
1722 struct ath9k_htc_priv *priv = hw->priv;
1724 mutex_lock(&priv->mutex);
1725 spin_lock_bh(&priv->beacon_lock);
1726 priv->op_flags |= OP_SCANNING;
1727 spin_unlock_bh(&priv->beacon_lock);
1728 cancel_work_sync(&priv->ps_work);
1729 if (priv->op_flags & OP_ASSOCIATED)
1730 cancel_delayed_work_sync(&priv->ath9k_ani_work);
1731 mutex_unlock(&priv->mutex);
1734 static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
1736 struct ath9k_htc_priv *priv = hw->priv;
1738 mutex_lock(&priv->mutex);
1739 ath9k_htc_ps_wakeup(priv);
1740 spin_lock_bh(&priv->beacon_lock);
1741 priv->op_flags &= ~OP_SCANNING;
1742 spin_unlock_bh(&priv->beacon_lock);
1743 priv->op_flags |= OP_FULL_RESET;
1744 if (priv->op_flags & OP_ASSOCIATED) {
1745 ath9k_htc_beacon_config(priv, priv->vif);
1746 ath_start_ani(priv);
1748 ath9k_htc_ps_restore(priv);
1749 mutex_unlock(&priv->mutex);
1752 static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1754 return 0;
1757 static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw,
1758 u8 coverage_class)
1760 struct ath9k_htc_priv *priv = hw->priv;
1762 mutex_lock(&priv->mutex);
1763 ath9k_htc_ps_wakeup(priv);
1764 priv->ah->coverage_class = coverage_class;
1765 ath9k_hw_init_global_settings(priv->ah);
1766 ath9k_htc_ps_restore(priv);
1767 mutex_unlock(&priv->mutex);
1770 struct ieee80211_ops ath9k_htc_ops = {
1771 .tx = ath9k_htc_tx,
1772 .start = ath9k_htc_start,
1773 .stop = ath9k_htc_stop,
1774 .add_interface = ath9k_htc_add_interface,
1775 .remove_interface = ath9k_htc_remove_interface,
1776 .config = ath9k_htc_config,
1777 .configure_filter = ath9k_htc_configure_filter,
1778 .sta_add = ath9k_htc_sta_add,
1779 .sta_remove = ath9k_htc_sta_remove,
1780 .conf_tx = ath9k_htc_conf_tx,
1781 .bss_info_changed = ath9k_htc_bss_info_changed,
1782 .set_key = ath9k_htc_set_key,
1783 .get_tsf = ath9k_htc_get_tsf,
1784 .set_tsf = ath9k_htc_set_tsf,
1785 .reset_tsf = ath9k_htc_reset_tsf,
1786 .ampdu_action = ath9k_htc_ampdu_action,
1787 .sw_scan_start = ath9k_htc_sw_scan_start,
1788 .sw_scan_complete = ath9k_htc_sw_scan_complete,
1789 .set_rts_threshold = ath9k_htc_set_rts_threshold,
1790 .rfkill_poll = ath9k_htc_rfkill_poll_state,
1791 .set_coverage_class = ath9k_htc_set_coverage_class,