mac80211: track receiver's aggregation reorder buffer size
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / net / wireless / ath / ath9k / htc_drv_main.c
blobf14f37d29f45fd06ed1490a9a14f8f314b2fe09b
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 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 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 void ath9k_htc_reset(struct ath9k_htc_priv *priv)
121 struct ath_hw *ah = priv->ah;
122 struct ath_common *common = ath9k_hw_common(ah);
123 struct ieee80211_channel *channel = priv->hw->conf.channel;
124 struct ath9k_hw_cal_data *caldata = NULL;
125 enum htc_phymode mode;
126 __be16 htc_mode;
127 u8 cmd_rsp;
128 int ret;
130 mutex_lock(&priv->mutex);
131 ath9k_htc_ps_wakeup(priv);
133 if (priv->op_flags & OP_ASSOCIATED)
134 cancel_delayed_work_sync(&priv->ath9k_ani_work);
136 ieee80211_stop_queues(priv->hw);
137 htc_stop(priv->htc);
138 WMI_CMD(WMI_DISABLE_INTR_CMDID);
139 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
140 WMI_CMD(WMI_STOP_RECV_CMDID);
142 caldata = &priv->caldata;
143 ret = ath9k_hw_reset(ah, ah->curchan, caldata, false);
144 if (ret) {
145 ath_err(common,
146 "Unable to reset device (%u Mhz) reset status %d\n",
147 channel->center_freq, ret);
150 ath_update_txpow(priv);
152 WMI_CMD(WMI_START_RECV_CMDID);
153 ath9k_host_rx_init(priv);
155 mode = ath9k_htc_get_curmode(priv, ah->curchan);
156 htc_mode = cpu_to_be16(mode);
157 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
159 WMI_CMD(WMI_ENABLE_INTR_CMDID);
160 htc_start(priv->htc);
162 if (priv->op_flags & OP_ASSOCIATED) {
163 ath9k_htc_beacon_config(priv, priv->vif);
164 ath_start_ani(priv);
167 ieee80211_wake_queues(priv->hw);
169 ath9k_htc_ps_restore(priv);
170 mutex_unlock(&priv->mutex);
173 static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
174 struct ieee80211_hw *hw,
175 struct ath9k_channel *hchan)
177 struct ath_hw *ah = priv->ah;
178 struct ath_common *common = ath9k_hw_common(ah);
179 struct ieee80211_conf *conf = &common->hw->conf;
180 bool fastcc;
181 struct ieee80211_channel *channel = hw->conf.channel;
182 struct ath9k_hw_cal_data *caldata;
183 enum htc_phymode mode;
184 __be16 htc_mode;
185 u8 cmd_rsp;
186 int ret;
188 if (priv->op_flags & OP_INVALID)
189 return -EIO;
191 fastcc = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL);
193 ath9k_htc_ps_wakeup(priv);
194 htc_stop(priv->htc);
195 WMI_CMD(WMI_DISABLE_INTR_CMDID);
196 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
197 WMI_CMD(WMI_STOP_RECV_CMDID);
199 ath_dbg(common, ATH_DBG_CONFIG,
200 "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n",
201 priv->ah->curchan->channel,
202 channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf),
203 fastcc);
205 if (!fastcc)
206 caldata = &priv->caldata;
207 ret = ath9k_hw_reset(ah, hchan, caldata, fastcc);
208 if (ret) {
209 ath_err(common,
210 "Unable to reset channel (%u Mhz) reset status %d\n",
211 channel->center_freq, ret);
212 goto err;
215 ath_update_txpow(priv);
217 WMI_CMD(WMI_START_RECV_CMDID);
218 if (ret)
219 goto err;
221 ath9k_host_rx_init(priv);
223 mode = ath9k_htc_get_curmode(priv, hchan);
224 htc_mode = cpu_to_be16(mode);
225 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
226 if (ret)
227 goto err;
229 WMI_CMD(WMI_ENABLE_INTR_CMDID);
230 if (ret)
231 goto err;
233 htc_start(priv->htc);
234 err:
235 ath9k_htc_ps_restore(priv);
236 return ret;
239 static void __ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
241 struct ath_common *common = ath9k_hw_common(priv->ah);
242 struct ath9k_htc_target_vif hvif;
243 int ret = 0;
244 u8 cmd_rsp;
246 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
247 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
248 hvif.index = 0; /* Should do for now */
249 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
250 priv->nvifs--;
253 static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
255 struct ath_common *common = ath9k_hw_common(priv->ah);
256 struct ath9k_htc_target_vif hvif;
257 struct ath9k_htc_target_sta tsta;
258 int ret = 0;
259 u8 cmd_rsp;
261 if (priv->nvifs > 0)
262 return -ENOBUFS;
264 if (priv->nstations >= ATH9K_HTC_MAX_STA)
265 return -ENOBUFS;
268 * Add an interface.
271 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
272 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
274 hvif.opmode = cpu_to_be32(HTC_M_MONITOR);
275 priv->ah->opmode = NL80211_IFTYPE_MONITOR;
276 hvif.index = priv->nvifs;
278 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
279 if (ret)
280 return ret;
282 priv->nvifs++;
285 * Associate a station with the interface for packet injection.
288 memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta));
290 memcpy(&tsta.macaddr, common->macaddr, ETH_ALEN);
292 tsta.is_vif_sta = 1;
293 tsta.sta_index = priv->nstations;
294 tsta.vif_index = hvif.index;
295 tsta.maxampdu = 0xffff;
297 WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
298 if (ret) {
299 ath_err(common, "Unable to add station entry for monitor mode\n");
300 goto err_vif;
303 priv->nstations++;
306 * Set chainmask etc. on the target.
308 ret = ath9k_htc_update_cap_target(priv);
309 if (ret)
310 ath_dbg(common, ATH_DBG_CONFIG,
311 "Failed to update capability in target\n");
313 priv->ah->is_monitoring = true;
315 return 0;
317 err_vif:
319 * Remove the interface from the target.
321 __ath9k_htc_remove_monitor_interface(priv);
322 return ret;
325 static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
327 struct ath_common *common = ath9k_hw_common(priv->ah);
328 int ret = 0;
329 u8 cmd_rsp, sta_idx;
331 __ath9k_htc_remove_monitor_interface(priv);
333 sta_idx = 0; /* Only single interface, for now */
335 WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx);
336 if (ret) {
337 ath_err(common, "Unable to remove station entry for monitor mode\n");
338 return ret;
341 priv->nstations--;
342 priv->ah->is_monitoring = false;
344 return 0;
347 static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
348 struct ieee80211_vif *vif,
349 struct ieee80211_sta *sta)
351 struct ath_common *common = ath9k_hw_common(priv->ah);
352 struct ath9k_htc_target_sta tsta;
353 struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
354 struct ath9k_htc_sta *ista;
355 int ret;
356 u8 cmd_rsp;
358 if (priv->nstations >= ATH9K_HTC_MAX_STA)
359 return -ENOBUFS;
361 memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta));
363 if (sta) {
364 ista = (struct ath9k_htc_sta *) sta->drv_priv;
365 memcpy(&tsta.macaddr, sta->addr, ETH_ALEN);
366 memcpy(&tsta.bssid, common->curbssid, ETH_ALEN);
367 tsta.associd = common->curaid;
368 tsta.is_vif_sta = 0;
369 tsta.valid = true;
370 ista->index = priv->nstations;
371 } else {
372 memcpy(&tsta.macaddr, vif->addr, ETH_ALEN);
373 tsta.is_vif_sta = 1;
376 tsta.sta_index = priv->nstations;
377 tsta.vif_index = avp->index;
378 tsta.maxampdu = 0xffff;
379 if (sta && sta->ht_cap.ht_supported)
380 tsta.flags = cpu_to_be16(ATH_HTC_STA_HT);
382 WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
383 if (ret) {
384 if (sta)
385 ath_err(common,
386 "Unable to add station entry for: %pM\n",
387 sta->addr);
388 return ret;
391 if (sta)
392 ath_dbg(common, ATH_DBG_CONFIG,
393 "Added a station entry for: %pM (idx: %d)\n",
394 sta->addr, tsta.sta_index);
396 priv->nstations++;
397 return 0;
400 static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
401 struct ieee80211_vif *vif,
402 struct ieee80211_sta *sta)
404 struct ath_common *common = ath9k_hw_common(priv->ah);
405 struct ath9k_htc_sta *ista;
406 int ret;
407 u8 cmd_rsp, sta_idx;
409 if (sta) {
410 ista = (struct ath9k_htc_sta *) sta->drv_priv;
411 sta_idx = ista->index;
412 } else {
413 sta_idx = 0;
416 WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx);
417 if (ret) {
418 if (sta)
419 ath_err(common,
420 "Unable to remove station entry for: %pM\n",
421 sta->addr);
422 return ret;
425 if (sta)
426 ath_dbg(common, ATH_DBG_CONFIG,
427 "Removed a station entry for: %pM (idx: %d)\n",
428 sta->addr, sta_idx);
430 priv->nstations--;
431 return 0;
434 int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv)
436 struct ath9k_htc_cap_target tcap;
437 int ret;
438 u8 cmd_rsp;
440 memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target));
442 /* FIXME: Values are hardcoded */
443 tcap.flags = 0x240c40;
444 tcap.flags_ext = 0x80601000;
445 tcap.ampdu_limit = 0xffff0000;
446 tcap.ampdu_subframes = 20;
447 tcap.tx_chainmask_legacy = priv->ah->caps.tx_chainmask;
448 tcap.protmode = 1;
449 tcap.tx_chainmask = priv->ah->caps.tx_chainmask;
451 WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap);
453 return ret;
456 static void ath9k_htc_setup_rate(struct ath9k_htc_priv *priv,
457 struct ieee80211_sta *sta,
458 struct ath9k_htc_target_rate *trate)
460 struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
461 struct ieee80211_supported_band *sband;
462 u32 caps = 0;
463 int i, j;
465 sband = priv->hw->wiphy->bands[priv->hw->conf.channel->band];
467 for (i = 0, j = 0; i < sband->n_bitrates; i++) {
468 if (sta->supp_rates[sband->band] & BIT(i)) {
469 trate->rates.legacy_rates.rs_rates[j]
470 = (sband->bitrates[i].bitrate * 2) / 10;
471 j++;
474 trate->rates.legacy_rates.rs_nrates = j;
476 if (sta->ht_cap.ht_supported) {
477 for (i = 0, j = 0; i < 77; i++) {
478 if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8)))
479 trate->rates.ht_rates.rs_rates[j++] = i;
480 if (j == ATH_HTC_RATE_MAX)
481 break;
483 trate->rates.ht_rates.rs_nrates = j;
485 caps = WLAN_RC_HT_FLAG;
486 if (sta->ht_cap.mcs.rx_mask[1])
487 caps |= WLAN_RC_DS_FLAG;
488 if ((sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
489 (conf_is_ht40(&priv->hw->conf)))
490 caps |= WLAN_RC_40_FLAG;
491 if (conf_is_ht40(&priv->hw->conf) &&
492 (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40))
493 caps |= WLAN_RC_SGI_FLAG;
494 else if (conf_is_ht20(&priv->hw->conf) &&
495 (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20))
496 caps |= WLAN_RC_SGI_FLAG;
499 trate->sta_index = ista->index;
500 trate->isnew = 1;
501 trate->capflags = cpu_to_be32(caps);
504 static int ath9k_htc_send_rate_cmd(struct ath9k_htc_priv *priv,
505 struct ath9k_htc_target_rate *trate)
507 struct ath_common *common = ath9k_hw_common(priv->ah);
508 int ret;
509 u8 cmd_rsp;
511 WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, trate);
512 if (ret) {
513 ath_err(common,
514 "Unable to initialize Rate information on target\n");
517 return ret;
520 static void ath9k_htc_init_rate(struct ath9k_htc_priv *priv,
521 struct ieee80211_sta *sta)
523 struct ath_common *common = ath9k_hw_common(priv->ah);
524 struct ath9k_htc_target_rate trate;
525 int ret;
527 memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
528 ath9k_htc_setup_rate(priv, sta, &trate);
529 ret = ath9k_htc_send_rate_cmd(priv, &trate);
530 if (!ret)
531 ath_dbg(common, ATH_DBG_CONFIG,
532 "Updated target sta: %pM, rate caps: 0x%X\n",
533 sta->addr, be32_to_cpu(trate.capflags));
536 static void ath9k_htc_update_rate(struct ath9k_htc_priv *priv,
537 struct ieee80211_vif *vif,
538 struct ieee80211_bss_conf *bss_conf)
540 struct ath_common *common = ath9k_hw_common(priv->ah);
541 struct ath9k_htc_target_rate trate;
542 struct ieee80211_sta *sta;
543 int ret;
545 memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
547 rcu_read_lock();
548 sta = ieee80211_find_sta(vif, bss_conf->bssid);
549 if (!sta) {
550 rcu_read_unlock();
551 return;
553 ath9k_htc_setup_rate(priv, sta, &trate);
554 rcu_read_unlock();
556 ret = ath9k_htc_send_rate_cmd(priv, &trate);
557 if (!ret)
558 ath_dbg(common, ATH_DBG_CONFIG,
559 "Updated target sta: %pM, rate caps: 0x%X\n",
560 bss_conf->bssid, be32_to_cpu(trate.capflags));
563 static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv,
564 struct ieee80211_vif *vif,
565 struct ieee80211_sta *sta,
566 enum ieee80211_ampdu_mlme_action action,
567 u16 tid)
569 struct ath_common *common = ath9k_hw_common(priv->ah);
570 struct ath9k_htc_target_aggr aggr;
571 struct ath9k_htc_sta *ista;
572 int ret = 0;
573 u8 cmd_rsp;
575 if (tid >= ATH9K_HTC_MAX_TID)
576 return -EINVAL;
578 memset(&aggr, 0, sizeof(struct ath9k_htc_target_aggr));
579 ista = (struct ath9k_htc_sta *) sta->drv_priv;
581 aggr.sta_index = ista->index;
582 aggr.tidno = tid & 0xf;
583 aggr.aggr_enable = (action == IEEE80211_AMPDU_TX_START) ? true : false;
585 WMI_CMD_BUF(WMI_TX_AGGR_ENABLE_CMDID, &aggr);
586 if (ret)
587 ath_dbg(common, ATH_DBG_CONFIG,
588 "Unable to %s TX aggregation for (%pM, %d)\n",
589 (aggr.aggr_enable) ? "start" : "stop", sta->addr, tid);
590 else
591 ath_dbg(common, ATH_DBG_CONFIG,
592 "%s TX aggregation for (%pM, %d)\n",
593 (aggr.aggr_enable) ? "Starting" : "Stopping",
594 sta->addr, tid);
596 spin_lock_bh(&priv->tx_lock);
597 ista->tid_state[tid] = (aggr.aggr_enable && !ret) ? AGGR_START : AGGR_STOP;
598 spin_unlock_bh(&priv->tx_lock);
600 return ret;
603 /*********/
604 /* DEBUG */
605 /*********/
607 #ifdef CONFIG_ATH9K_HTC_DEBUGFS
609 static int ath9k_debugfs_open(struct inode *inode, struct file *file)
611 file->private_data = inode->i_private;
612 return 0;
615 static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf,
616 size_t count, loff_t *ppos)
618 struct ath9k_htc_priv *priv = file->private_data;
619 struct ath9k_htc_target_stats cmd_rsp;
620 char buf[512];
621 unsigned int len = 0;
622 int ret = 0;
624 memset(&cmd_rsp, 0, sizeof(cmd_rsp));
626 WMI_CMD(WMI_TGT_STATS_CMDID);
627 if (ret)
628 return -EINVAL;
631 len += snprintf(buf + len, sizeof(buf) - len,
632 "%19s : %10u\n", "TX Short Retries",
633 be32_to_cpu(cmd_rsp.tx_shortretry));
634 len += snprintf(buf + len, sizeof(buf) - len,
635 "%19s : %10u\n", "TX Long Retries",
636 be32_to_cpu(cmd_rsp.tx_longretry));
637 len += snprintf(buf + len, sizeof(buf) - len,
638 "%19s : %10u\n", "TX Xretries",
639 be32_to_cpu(cmd_rsp.tx_xretries));
640 len += snprintf(buf + len, sizeof(buf) - len,
641 "%19s : %10u\n", "TX Unaggr. Xretries",
642 be32_to_cpu(cmd_rsp.ht_txunaggr_xretry));
643 len += snprintf(buf + len, sizeof(buf) - len,
644 "%19s : %10u\n", "TX Xretries (HT)",
645 be32_to_cpu(cmd_rsp.ht_tx_xretries));
646 len += snprintf(buf + len, sizeof(buf) - len,
647 "%19s : %10u\n", "TX Rate", priv->debug.txrate);
649 if (len > sizeof(buf))
650 len = sizeof(buf);
652 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
655 static const struct file_operations fops_tgt_stats = {
656 .read = read_file_tgt_stats,
657 .open = ath9k_debugfs_open,
658 .owner = THIS_MODULE,
659 .llseek = default_llseek,
662 static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
663 size_t count, loff_t *ppos)
665 struct ath9k_htc_priv *priv = file->private_data;
666 char buf[512];
667 unsigned int len = 0;
669 len += snprintf(buf + len, sizeof(buf) - len,
670 "%20s : %10u\n", "Buffers queued",
671 priv->debug.tx_stats.buf_queued);
672 len += snprintf(buf + len, sizeof(buf) - len,
673 "%20s : %10u\n", "Buffers completed",
674 priv->debug.tx_stats.buf_completed);
675 len += snprintf(buf + len, sizeof(buf) - len,
676 "%20s : %10u\n", "SKBs queued",
677 priv->debug.tx_stats.skb_queued);
678 len += snprintf(buf + len, sizeof(buf) - len,
679 "%20s : %10u\n", "SKBs completed",
680 priv->debug.tx_stats.skb_completed);
681 len += snprintf(buf + len, sizeof(buf) - len,
682 "%20s : %10u\n", "SKBs dropped",
683 priv->debug.tx_stats.skb_dropped);
685 len += snprintf(buf + len, sizeof(buf) - len,
686 "%20s : %10u\n", "BE queued",
687 priv->debug.tx_stats.queue_stats[WME_AC_BE]);
688 len += snprintf(buf + len, sizeof(buf) - len,
689 "%20s : %10u\n", "BK queued",
690 priv->debug.tx_stats.queue_stats[WME_AC_BK]);
691 len += snprintf(buf + len, sizeof(buf) - len,
692 "%20s : %10u\n", "VI queued",
693 priv->debug.tx_stats.queue_stats[WME_AC_VI]);
694 len += snprintf(buf + len, sizeof(buf) - len,
695 "%20s : %10u\n", "VO queued",
696 priv->debug.tx_stats.queue_stats[WME_AC_VO]);
698 if (len > sizeof(buf))
699 len = sizeof(buf);
701 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
704 static const struct file_operations fops_xmit = {
705 .read = read_file_xmit,
706 .open = ath9k_debugfs_open,
707 .owner = THIS_MODULE,
708 .llseek = default_llseek,
711 static ssize_t read_file_recv(struct file *file, char __user *user_buf,
712 size_t count, loff_t *ppos)
714 struct ath9k_htc_priv *priv = file->private_data;
715 char buf[512];
716 unsigned int len = 0;
718 len += snprintf(buf + len, sizeof(buf) - len,
719 "%20s : %10u\n", "SKBs allocated",
720 priv->debug.rx_stats.skb_allocated);
721 len += snprintf(buf + len, sizeof(buf) - len,
722 "%20s : %10u\n", "SKBs completed",
723 priv->debug.rx_stats.skb_completed);
724 len += snprintf(buf + len, sizeof(buf) - len,
725 "%20s : %10u\n", "SKBs Dropped",
726 priv->debug.rx_stats.skb_dropped);
728 if (len > sizeof(buf))
729 len = sizeof(buf);
731 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
734 static const struct file_operations fops_recv = {
735 .read = read_file_recv,
736 .open = ath9k_debugfs_open,
737 .owner = THIS_MODULE,
738 .llseek = default_llseek,
741 int ath9k_htc_init_debug(struct ath_hw *ah)
743 struct ath_common *common = ath9k_hw_common(ah);
744 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
746 if (!ath9k_debugfs_root)
747 return -ENOENT;
749 priv->debug.debugfs_phy = debugfs_create_dir(wiphy_name(priv->hw->wiphy),
750 ath9k_debugfs_root);
751 if (!priv->debug.debugfs_phy)
752 goto err;
754 priv->debug.debugfs_tgt_stats = debugfs_create_file("tgt_stats", S_IRUSR,
755 priv->debug.debugfs_phy,
756 priv, &fops_tgt_stats);
757 if (!priv->debug.debugfs_tgt_stats)
758 goto err;
761 priv->debug.debugfs_xmit = debugfs_create_file("xmit", S_IRUSR,
762 priv->debug.debugfs_phy,
763 priv, &fops_xmit);
764 if (!priv->debug.debugfs_xmit)
765 goto err;
767 priv->debug.debugfs_recv = debugfs_create_file("recv", S_IRUSR,
768 priv->debug.debugfs_phy,
769 priv, &fops_recv);
770 if (!priv->debug.debugfs_recv)
771 goto err;
773 return 0;
775 err:
776 ath9k_htc_exit_debug(ah);
777 return -ENOMEM;
780 void ath9k_htc_exit_debug(struct ath_hw *ah)
782 struct ath_common *common = ath9k_hw_common(ah);
783 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
785 debugfs_remove(priv->debug.debugfs_recv);
786 debugfs_remove(priv->debug.debugfs_xmit);
787 debugfs_remove(priv->debug.debugfs_tgt_stats);
788 debugfs_remove(priv->debug.debugfs_phy);
791 int ath9k_htc_debug_create_root(void)
793 ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
794 if (!ath9k_debugfs_root)
795 return -ENOENT;
797 return 0;
800 void ath9k_htc_debug_remove_root(void)
802 debugfs_remove(ath9k_debugfs_root);
803 ath9k_debugfs_root = NULL;
806 #endif /* CONFIG_ATH9K_HTC_DEBUGFS */
808 /*******/
809 /* ANI */
810 /*******/
812 void ath_start_ani(struct ath9k_htc_priv *priv)
814 struct ath_common *common = ath9k_hw_common(priv->ah);
815 unsigned long timestamp = jiffies_to_msecs(jiffies);
817 common->ani.longcal_timer = timestamp;
818 common->ani.shortcal_timer = timestamp;
819 common->ani.checkani_timer = timestamp;
821 ieee80211_queue_delayed_work(common->hw, &priv->ath9k_ani_work,
822 msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
825 void ath9k_ani_work(struct work_struct *work)
827 struct ath9k_htc_priv *priv =
828 container_of(work, struct ath9k_htc_priv,
829 ath9k_ani_work.work);
830 struct ath_hw *ah = priv->ah;
831 struct ath_common *common = ath9k_hw_common(ah);
832 bool longcal = false;
833 bool shortcal = false;
834 bool aniflag = false;
835 unsigned int timestamp = jiffies_to_msecs(jiffies);
836 u32 cal_interval, short_cal_interval;
838 short_cal_interval = ATH_STA_SHORT_CALINTERVAL;
840 /* Only calibrate if awake */
841 if (ah->power_mode != ATH9K_PM_AWAKE)
842 goto set_timer;
844 /* Long calibration runs independently of short calibration. */
845 if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
846 longcal = true;
847 ath_dbg(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
848 common->ani.longcal_timer = timestamp;
851 /* Short calibration applies only while caldone is false */
852 if (!common->ani.caldone) {
853 if ((timestamp - common->ani.shortcal_timer) >=
854 short_cal_interval) {
855 shortcal = true;
856 ath_dbg(common, ATH_DBG_ANI,
857 "shortcal @%lu\n", jiffies);
858 common->ani.shortcal_timer = timestamp;
859 common->ani.resetcal_timer = timestamp;
861 } else {
862 if ((timestamp - common->ani.resetcal_timer) >=
863 ATH_RESTART_CALINTERVAL) {
864 common->ani.caldone = ath9k_hw_reset_calvalid(ah);
865 if (common->ani.caldone)
866 common->ani.resetcal_timer = timestamp;
870 /* Verify whether we must check ANI */
871 if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
872 aniflag = true;
873 common->ani.checkani_timer = timestamp;
876 /* Skip all processing if there's nothing to do. */
877 if (longcal || shortcal || aniflag) {
879 ath9k_htc_ps_wakeup(priv);
881 /* Call ANI routine if necessary */
882 if (aniflag)
883 ath9k_hw_ani_monitor(ah, ah->curchan);
885 /* Perform calibration if necessary */
886 if (longcal || shortcal)
887 common->ani.caldone =
888 ath9k_hw_calibrate(ah, ah->curchan,
889 common->rx_chainmask,
890 longcal);
892 ath9k_htc_ps_restore(priv);
895 set_timer:
897 * Set timer interval based on previous results.
898 * The interval must be the shortest necessary to satisfy ANI,
899 * short calibration and long calibration.
901 cal_interval = ATH_LONG_CALINTERVAL;
902 if (priv->ah->config.enable_ani)
903 cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
904 if (!common->ani.caldone)
905 cal_interval = min(cal_interval, (u32)short_cal_interval);
907 ieee80211_queue_delayed_work(common->hw, &priv->ath9k_ani_work,
908 msecs_to_jiffies(cal_interval));
911 /**********************/
912 /* mac80211 Callbacks */
913 /**********************/
915 static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
917 struct ieee80211_hdr *hdr;
918 struct ath9k_htc_priv *priv = hw->priv;
919 int padpos, padsize, ret;
921 hdr = (struct ieee80211_hdr *) skb->data;
923 /* Add the padding after the header if this is not already done */
924 padpos = ath9k_cmn_padpos(hdr->frame_control);
925 padsize = padpos & 3;
926 if (padsize && skb->len > padpos) {
927 if (skb_headroom(skb) < padsize)
928 return -1;
929 skb_push(skb, padsize);
930 memmove(skb->data, skb->data + padsize, padpos);
933 ret = ath9k_htc_tx_start(priv, skb);
934 if (ret != 0) {
935 if (ret == -ENOMEM) {
936 ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
937 "Stopping TX queues\n");
938 ieee80211_stop_queues(hw);
939 spin_lock_bh(&priv->tx_lock);
940 priv->tx_queues_stop = true;
941 spin_unlock_bh(&priv->tx_lock);
942 } else {
943 ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
944 "Tx failed\n");
946 goto fail_tx;
949 return 0;
951 fail_tx:
952 dev_kfree_skb_any(skb);
953 return 0;
956 static int ath9k_htc_start(struct ieee80211_hw *hw)
958 struct ath9k_htc_priv *priv = hw->priv;
959 struct ath_hw *ah = priv->ah;
960 struct ath_common *common = ath9k_hw_common(ah);
961 struct ieee80211_channel *curchan = hw->conf.channel;
962 struct ath9k_channel *init_channel;
963 int ret = 0;
964 enum htc_phymode mode;
965 __be16 htc_mode;
966 u8 cmd_rsp;
968 mutex_lock(&priv->mutex);
970 ath_dbg(common, ATH_DBG_CONFIG,
971 "Starting driver with initial channel: %d MHz\n",
972 curchan->center_freq);
974 /* Ensure that HW is awake before flushing RX */
975 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
976 WMI_CMD(WMI_FLUSH_RECV_CMDID);
978 /* setup initial channel */
979 init_channel = ath9k_cmn_get_curchannel(hw, ah);
981 ath9k_hw_htc_resetinit(ah);
982 ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
983 if (ret) {
984 ath_err(common,
985 "Unable to reset hardware; reset status %d (freq %u MHz)\n",
986 ret, curchan->center_freq);
987 mutex_unlock(&priv->mutex);
988 return ret;
991 ath_update_txpow(priv);
993 mode = ath9k_htc_get_curmode(priv, init_channel);
994 htc_mode = cpu_to_be16(mode);
995 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
996 WMI_CMD(WMI_ATH_INIT_CMDID);
997 WMI_CMD(WMI_START_RECV_CMDID);
999 ath9k_host_rx_init(priv);
1001 priv->op_flags &= ~OP_INVALID;
1002 htc_start(priv->htc);
1004 spin_lock_bh(&priv->tx_lock);
1005 priv->tx_queues_stop = false;
1006 spin_unlock_bh(&priv->tx_lock);
1008 ieee80211_wake_queues(hw);
1010 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) {
1011 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
1012 AR_STOMP_LOW_WLAN_WGHT);
1013 ath9k_hw_btcoex_enable(ah);
1014 ath_htc_resume_btcoex_work(priv);
1016 mutex_unlock(&priv->mutex);
1018 return ret;
1021 static void ath9k_htc_stop(struct ieee80211_hw *hw)
1023 struct ath9k_htc_priv *priv = hw->priv;
1024 struct ath_hw *ah = priv->ah;
1025 struct ath_common *common = ath9k_hw_common(ah);
1026 int ret = 0;
1027 u8 cmd_rsp;
1029 /* Cancel all the running timers/work .. */
1030 cancel_work_sync(&priv->fatal_work);
1031 cancel_work_sync(&priv->ps_work);
1032 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
1033 ath9k_led_stop_brightness(priv);
1035 mutex_lock(&priv->mutex);
1037 if (priv->op_flags & OP_INVALID) {
1038 ath_dbg(common, ATH_DBG_ANY, "Device not present\n");
1039 mutex_unlock(&priv->mutex);
1040 return;
1043 ath9k_htc_ps_wakeup(priv);
1044 htc_stop(priv->htc);
1045 WMI_CMD(WMI_DISABLE_INTR_CMDID);
1046 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
1047 WMI_CMD(WMI_STOP_RECV_CMDID);
1048 skb_queue_purge(&priv->tx_queue);
1050 /* Remove monitor interface here */
1051 if (ah->opmode == NL80211_IFTYPE_MONITOR) {
1052 if (ath9k_htc_remove_monitor_interface(priv))
1053 ath_err(common, "Unable to remove monitor interface\n");
1054 else
1055 ath_dbg(common, ATH_DBG_CONFIG,
1056 "Monitor interface removed\n");
1059 if (ah->btcoex_hw.enabled) {
1060 ath9k_hw_btcoex_disable(ah);
1061 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
1062 ath_htc_cancel_btcoex_work(priv);
1065 ath9k_hw_phy_disable(ah);
1066 ath9k_hw_disable(ah);
1067 ath9k_htc_ps_restore(priv);
1068 ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
1070 priv->op_flags |= OP_INVALID;
1072 ath_dbg(common, ATH_DBG_CONFIG, "Driver halt\n");
1073 mutex_unlock(&priv->mutex);
1076 static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1077 struct ieee80211_vif *vif)
1079 struct ath9k_htc_priv *priv = hw->priv;
1080 struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1081 struct ath_common *common = ath9k_hw_common(priv->ah);
1082 struct ath9k_htc_target_vif hvif;
1083 int ret = 0;
1084 u8 cmd_rsp;
1086 mutex_lock(&priv->mutex);
1088 /* Only one interface for now */
1089 if (priv->nvifs > 0) {
1090 ret = -ENOBUFS;
1091 goto out;
1094 ath9k_htc_ps_wakeup(priv);
1095 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
1096 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
1098 switch (vif->type) {
1099 case NL80211_IFTYPE_STATION:
1100 hvif.opmode = cpu_to_be32(HTC_M_STA);
1101 break;
1102 case NL80211_IFTYPE_ADHOC:
1103 hvif.opmode = cpu_to_be32(HTC_M_IBSS);
1104 break;
1105 default:
1106 ath_err(common,
1107 "Interface type %d not yet supported\n", vif->type);
1108 ret = -EOPNOTSUPP;
1109 goto out;
1112 ath_dbg(common, ATH_DBG_CONFIG,
1113 "Attach a VIF of type: %d\n", vif->type);
1115 priv->ah->opmode = vif->type;
1117 /* Index starts from zero on the target */
1118 avp->index = hvif.index = priv->nvifs;
1119 hvif.rtsthreshold = cpu_to_be16(2304);
1120 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
1121 if (ret)
1122 goto out;
1124 priv->nvifs++;
1127 * We need a node in target to tx mgmt frames
1128 * before association.
1130 ret = ath9k_htc_add_station(priv, vif, NULL);
1131 if (ret)
1132 goto out;
1134 ret = ath9k_htc_update_cap_target(priv);
1135 if (ret)
1136 ath_dbg(common, ATH_DBG_CONFIG,
1137 "Failed to update capability in target\n");
1139 priv->vif = vif;
1140 out:
1141 ath9k_htc_ps_restore(priv);
1142 mutex_unlock(&priv->mutex);
1144 return ret;
1147 static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
1148 struct ieee80211_vif *vif)
1150 struct ath9k_htc_priv *priv = hw->priv;
1151 struct ath_common *common = ath9k_hw_common(priv->ah);
1152 struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1153 struct ath9k_htc_target_vif hvif;
1154 int ret = 0;
1155 u8 cmd_rsp;
1157 ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface\n");
1159 mutex_lock(&priv->mutex);
1160 ath9k_htc_ps_wakeup(priv);
1162 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
1163 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
1164 hvif.index = avp->index;
1165 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
1166 priv->nvifs--;
1168 ath9k_htc_remove_station(priv, vif, NULL);
1169 priv->vif = NULL;
1171 ath9k_htc_ps_restore(priv);
1172 mutex_unlock(&priv->mutex);
1175 static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
1177 struct ath9k_htc_priv *priv = hw->priv;
1178 struct ath_common *common = ath9k_hw_common(priv->ah);
1179 struct ieee80211_conf *conf = &hw->conf;
1181 mutex_lock(&priv->mutex);
1183 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1184 bool enable_radio = false;
1185 bool idle = !!(conf->flags & IEEE80211_CONF_IDLE);
1187 mutex_lock(&priv->htc_pm_lock);
1188 if (!idle && priv->ps_idle)
1189 enable_radio = true;
1190 priv->ps_idle = idle;
1191 mutex_unlock(&priv->htc_pm_lock);
1193 if (enable_radio) {
1194 ath_dbg(common, ATH_DBG_CONFIG,
1195 "not-idle: enabling radio\n");
1196 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
1197 ath9k_htc_radio_enable(hw);
1202 * Monitor interface should be added before
1203 * IEEE80211_CONF_CHANGE_CHANNEL is handled.
1205 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
1206 if (conf->flags & IEEE80211_CONF_MONITOR) {
1207 if (ath9k_htc_add_monitor_interface(priv))
1208 ath_err(common, "Failed to set monitor mode\n");
1209 else
1210 ath_dbg(common, ATH_DBG_CONFIG,
1211 "HW opmode set to Monitor mode\n");
1215 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1216 struct ieee80211_channel *curchan = hw->conf.channel;
1217 int pos = curchan->hw_value;
1219 ath_dbg(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
1220 curchan->center_freq);
1222 ath9k_cmn_update_ichannel(&priv->ah->channels[pos],
1223 hw->conf.channel,
1224 hw->conf.channel_type);
1226 if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) {
1227 ath_err(common, "Unable to set channel\n");
1228 mutex_unlock(&priv->mutex);
1229 return -EINVAL;
1234 if (changed & IEEE80211_CONF_CHANGE_PS) {
1235 if (conf->flags & IEEE80211_CONF_PS) {
1236 ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP);
1237 priv->ps_enabled = true;
1238 } else {
1239 priv->ps_enabled = false;
1240 cancel_work_sync(&priv->ps_work);
1241 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
1245 if (changed & IEEE80211_CONF_CHANGE_POWER) {
1246 priv->txpowlimit = 2 * conf->power_level;
1247 ath_update_txpow(priv);
1250 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1251 mutex_lock(&priv->htc_pm_lock);
1252 if (!priv->ps_idle) {
1253 mutex_unlock(&priv->htc_pm_lock);
1254 goto out;
1256 mutex_unlock(&priv->htc_pm_lock);
1258 ath_dbg(common, ATH_DBG_CONFIG,
1259 "idle: disabling radio\n");
1260 ath9k_htc_radio_disable(hw);
1263 out:
1264 mutex_unlock(&priv->mutex);
1265 return 0;
1268 #define SUPPORTED_FILTERS \
1269 (FIF_PROMISC_IN_BSS | \
1270 FIF_ALLMULTI | \
1271 FIF_CONTROL | \
1272 FIF_PSPOLL | \
1273 FIF_OTHER_BSS | \
1274 FIF_BCN_PRBRESP_PROMISC | \
1275 FIF_PROBE_REQ | \
1276 FIF_FCSFAIL)
1278 static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
1279 unsigned int changed_flags,
1280 unsigned int *total_flags,
1281 u64 multicast)
1283 struct ath9k_htc_priv *priv = hw->priv;
1284 u32 rfilt;
1286 mutex_lock(&priv->mutex);
1287 ath9k_htc_ps_wakeup(priv);
1289 changed_flags &= SUPPORTED_FILTERS;
1290 *total_flags &= SUPPORTED_FILTERS;
1292 priv->rxfilter = *total_flags;
1293 rfilt = ath9k_htc_calcrxfilter(priv);
1294 ath9k_hw_setrxfilter(priv->ah, rfilt);
1296 ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_CONFIG,
1297 "Set HW RX filter: 0x%x\n", rfilt);
1299 ath9k_htc_ps_restore(priv);
1300 mutex_unlock(&priv->mutex);
1303 static int ath9k_htc_sta_add(struct ieee80211_hw *hw,
1304 struct ieee80211_vif *vif,
1305 struct ieee80211_sta *sta)
1307 struct ath9k_htc_priv *priv = hw->priv;
1308 int ret;
1310 mutex_lock(&priv->mutex);
1311 ath9k_htc_ps_wakeup(priv);
1312 ret = ath9k_htc_add_station(priv, vif, sta);
1313 if (!ret)
1314 ath9k_htc_init_rate(priv, sta);
1315 ath9k_htc_ps_restore(priv);
1316 mutex_unlock(&priv->mutex);
1318 return ret;
1321 static int ath9k_htc_sta_remove(struct ieee80211_hw *hw,
1322 struct ieee80211_vif *vif,
1323 struct ieee80211_sta *sta)
1325 struct ath9k_htc_priv *priv = hw->priv;
1326 int ret;
1328 mutex_lock(&priv->mutex);
1329 ath9k_htc_ps_wakeup(priv);
1330 ret = ath9k_htc_remove_station(priv, vif, sta);
1331 ath9k_htc_ps_restore(priv);
1332 mutex_unlock(&priv->mutex);
1334 return ret;
1337 static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, u16 queue,
1338 const struct ieee80211_tx_queue_params *params)
1340 struct ath9k_htc_priv *priv = hw->priv;
1341 struct ath_common *common = ath9k_hw_common(priv->ah);
1342 struct ath9k_tx_queue_info qi;
1343 int ret = 0, qnum;
1345 if (queue >= WME_NUM_AC)
1346 return 0;
1348 mutex_lock(&priv->mutex);
1349 ath9k_htc_ps_wakeup(priv);
1351 memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
1353 qi.tqi_aifs = params->aifs;
1354 qi.tqi_cwmin = params->cw_min;
1355 qi.tqi_cwmax = params->cw_max;
1356 qi.tqi_burstTime = params->txop;
1358 qnum = get_hw_qnum(queue, priv->hwq_map);
1360 ath_dbg(common, ATH_DBG_CONFIG,
1361 "Configure tx [queue/hwq] [%d/%d], aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
1362 queue, qnum, params->aifs, params->cw_min,
1363 params->cw_max, params->txop);
1365 ret = ath_htc_txq_update(priv, qnum, &qi);
1366 if (ret) {
1367 ath_err(common, "TXQ Update failed\n");
1368 goto out;
1371 if ((priv->ah->opmode == NL80211_IFTYPE_ADHOC) &&
1372 (qnum == priv->hwq_map[WME_AC_BE]))
1373 ath9k_htc_beaconq_config(priv);
1374 out:
1375 ath9k_htc_ps_restore(priv);
1376 mutex_unlock(&priv->mutex);
1378 return ret;
1381 static int ath9k_htc_set_key(struct ieee80211_hw *hw,
1382 enum set_key_cmd cmd,
1383 struct ieee80211_vif *vif,
1384 struct ieee80211_sta *sta,
1385 struct ieee80211_key_conf *key)
1387 struct ath9k_htc_priv *priv = hw->priv;
1388 struct ath_common *common = ath9k_hw_common(priv->ah);
1389 int ret = 0;
1391 if (htc_modparam_nohwcrypt)
1392 return -ENOSPC;
1394 mutex_lock(&priv->mutex);
1395 ath_dbg(common, ATH_DBG_CONFIG, "Set HW Key\n");
1396 ath9k_htc_ps_wakeup(priv);
1398 switch (cmd) {
1399 case SET_KEY:
1400 ret = ath_key_config(common, vif, sta, key);
1401 if (ret >= 0) {
1402 key->hw_key_idx = ret;
1403 /* push IV and Michael MIC generation to stack */
1404 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1405 if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
1406 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1407 if (priv->ah->sw_mgmt_crypto &&
1408 key->cipher == WLAN_CIPHER_SUITE_CCMP)
1409 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
1410 ret = 0;
1412 break;
1413 case DISABLE_KEY:
1414 ath_key_delete(common, key);
1415 break;
1416 default:
1417 ret = -EINVAL;
1420 ath9k_htc_ps_restore(priv);
1421 mutex_unlock(&priv->mutex);
1423 return ret;
1426 static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
1427 struct ieee80211_vif *vif,
1428 struct ieee80211_bss_conf *bss_conf,
1429 u32 changed)
1431 struct ath9k_htc_priv *priv = hw->priv;
1432 struct ath_hw *ah = priv->ah;
1433 struct ath_common *common = ath9k_hw_common(ah);
1435 mutex_lock(&priv->mutex);
1436 ath9k_htc_ps_wakeup(priv);
1438 if (changed & BSS_CHANGED_ASSOC) {
1439 common->curaid = bss_conf->assoc ?
1440 bss_conf->aid : 0;
1441 ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
1442 bss_conf->assoc);
1444 if (bss_conf->assoc) {
1445 priv->op_flags |= OP_ASSOCIATED;
1446 ath_start_ani(priv);
1447 } else {
1448 priv->op_flags &= ~OP_ASSOCIATED;
1449 cancel_delayed_work_sync(&priv->ath9k_ani_work);
1453 if (changed & BSS_CHANGED_BSSID) {
1454 /* Set BSSID */
1455 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1456 ath9k_hw_write_associd(ah);
1458 ath_dbg(common, ATH_DBG_CONFIG,
1459 "BSSID: %pM aid: 0x%x\n",
1460 common->curbssid, common->curaid);
1463 if ((changed & BSS_CHANGED_BEACON_INT) ||
1464 (changed & BSS_CHANGED_BEACON) ||
1465 ((changed & BSS_CHANGED_BEACON_ENABLED) &&
1466 bss_conf->enable_beacon)) {
1467 priv->op_flags |= OP_ENABLE_BEACON;
1468 ath9k_htc_beacon_config(priv, vif);
1471 if ((changed & BSS_CHANGED_BEACON_ENABLED) &&
1472 !bss_conf->enable_beacon) {
1473 priv->op_flags &= ~OP_ENABLE_BEACON;
1474 ath9k_htc_beacon_config(priv, vif);
1477 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
1478 ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
1479 bss_conf->use_short_preamble);
1480 if (bss_conf->use_short_preamble)
1481 priv->op_flags |= OP_PREAMBLE_SHORT;
1482 else
1483 priv->op_flags &= ~OP_PREAMBLE_SHORT;
1486 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
1487 ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n",
1488 bss_conf->use_cts_prot);
1489 if (bss_conf->use_cts_prot &&
1490 hw->conf.channel->band != IEEE80211_BAND_5GHZ)
1491 priv->op_flags |= OP_PROTECT_ENABLE;
1492 else
1493 priv->op_flags &= ~OP_PROTECT_ENABLE;
1496 if (changed & BSS_CHANGED_ERP_SLOT) {
1497 if (bss_conf->use_short_slot)
1498 ah->slottime = 9;
1499 else
1500 ah->slottime = 20;
1502 ath9k_hw_init_global_settings(ah);
1505 if (changed & BSS_CHANGED_HT)
1506 ath9k_htc_update_rate(priv, vif, bss_conf);
1508 ath9k_htc_ps_restore(priv);
1509 mutex_unlock(&priv->mutex);
1512 static u64 ath9k_htc_get_tsf(struct ieee80211_hw *hw)
1514 struct ath9k_htc_priv *priv = hw->priv;
1515 u64 tsf;
1517 mutex_lock(&priv->mutex);
1518 ath9k_htc_ps_wakeup(priv);
1519 tsf = ath9k_hw_gettsf64(priv->ah);
1520 ath9k_htc_ps_restore(priv);
1521 mutex_unlock(&priv->mutex);
1523 return tsf;
1526 static void ath9k_htc_set_tsf(struct ieee80211_hw *hw, u64 tsf)
1528 struct ath9k_htc_priv *priv = hw->priv;
1530 mutex_lock(&priv->mutex);
1531 ath9k_htc_ps_wakeup(priv);
1532 ath9k_hw_settsf64(priv->ah, tsf);
1533 ath9k_htc_ps_restore(priv);
1534 mutex_unlock(&priv->mutex);
1537 static void ath9k_htc_reset_tsf(struct ieee80211_hw *hw)
1539 struct ath9k_htc_priv *priv = hw->priv;
1541 mutex_lock(&priv->mutex);
1542 ath9k_htc_ps_wakeup(priv);
1543 ath9k_hw_reset_tsf(priv->ah);
1544 ath9k_htc_ps_restore(priv);
1545 mutex_unlock(&priv->mutex);
1548 static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
1549 struct ieee80211_vif *vif,
1550 enum ieee80211_ampdu_mlme_action action,
1551 struct ieee80211_sta *sta,
1552 u16 tid, u16 *ssn, u8 buf_size)
1554 struct ath9k_htc_priv *priv = hw->priv;
1555 struct ath9k_htc_sta *ista;
1556 int ret = 0;
1558 switch (action) {
1559 case IEEE80211_AMPDU_RX_START:
1560 break;
1561 case IEEE80211_AMPDU_RX_STOP:
1562 break;
1563 case IEEE80211_AMPDU_TX_START:
1564 ret = ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid);
1565 if (!ret)
1566 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1567 break;
1568 case IEEE80211_AMPDU_TX_STOP:
1569 ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid);
1570 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1571 break;
1572 case IEEE80211_AMPDU_TX_OPERATIONAL:
1573 ista = (struct ath9k_htc_sta *) sta->drv_priv;
1574 spin_lock_bh(&priv->tx_lock);
1575 ista->tid_state[tid] = AGGR_OPERATIONAL;
1576 spin_unlock_bh(&priv->tx_lock);
1577 break;
1578 default:
1579 ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n");
1582 return ret;
1585 static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw)
1587 struct ath9k_htc_priv *priv = hw->priv;
1589 mutex_lock(&priv->mutex);
1590 spin_lock_bh(&priv->beacon_lock);
1591 priv->op_flags |= OP_SCANNING;
1592 spin_unlock_bh(&priv->beacon_lock);
1593 cancel_work_sync(&priv->ps_work);
1594 if (priv->op_flags & OP_ASSOCIATED)
1595 cancel_delayed_work_sync(&priv->ath9k_ani_work);
1596 mutex_unlock(&priv->mutex);
1599 static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
1601 struct ath9k_htc_priv *priv = hw->priv;
1603 mutex_lock(&priv->mutex);
1604 ath9k_htc_ps_wakeup(priv);
1605 spin_lock_bh(&priv->beacon_lock);
1606 priv->op_flags &= ~OP_SCANNING;
1607 spin_unlock_bh(&priv->beacon_lock);
1608 if (priv->op_flags & OP_ASSOCIATED) {
1609 ath9k_htc_beacon_config(priv, priv->vif);
1610 ath_start_ani(priv);
1612 ath9k_htc_ps_restore(priv);
1613 mutex_unlock(&priv->mutex);
1616 static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1618 return 0;
1621 static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw,
1622 u8 coverage_class)
1624 struct ath9k_htc_priv *priv = hw->priv;
1626 mutex_lock(&priv->mutex);
1627 ath9k_htc_ps_wakeup(priv);
1628 priv->ah->coverage_class = coverage_class;
1629 ath9k_hw_init_global_settings(priv->ah);
1630 ath9k_htc_ps_restore(priv);
1631 mutex_unlock(&priv->mutex);
1634 struct ieee80211_ops ath9k_htc_ops = {
1635 .tx = ath9k_htc_tx,
1636 .start = ath9k_htc_start,
1637 .stop = ath9k_htc_stop,
1638 .add_interface = ath9k_htc_add_interface,
1639 .remove_interface = ath9k_htc_remove_interface,
1640 .config = ath9k_htc_config,
1641 .configure_filter = ath9k_htc_configure_filter,
1642 .sta_add = ath9k_htc_sta_add,
1643 .sta_remove = ath9k_htc_sta_remove,
1644 .conf_tx = ath9k_htc_conf_tx,
1645 .bss_info_changed = ath9k_htc_bss_info_changed,
1646 .set_key = ath9k_htc_set_key,
1647 .get_tsf = ath9k_htc_get_tsf,
1648 .set_tsf = ath9k_htc_set_tsf,
1649 .reset_tsf = ath9k_htc_reset_tsf,
1650 .ampdu_action = ath9k_htc_ampdu_action,
1651 .sw_scan_start = ath9k_htc_sw_scan_start,
1652 .sw_scan_complete = ath9k_htc_sw_scan_complete,
1653 .set_rts_threshold = ath9k_htc_set_rts_threshold,
1654 .rfkill_poll = ath9k_htc_rfkill_poll_state,
1655 .set_coverage_class = ath9k_htc_set_coverage_class,