spi-topcliff-pch: add recovery processing in case wait-event timeout
[zen-stable.git] / drivers / net / wireless / ath / ath9k / htc_drv_main.c
blobef4c6066129022d90bda90416a65bdab93d59c27
1 /*
2 * Copyright (c) 2010-2011 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 /*************/
20 /* Utilities */
21 /*************/
23 /* HACK Alert: Use 11NG for 2.4, use 11NA for 5 */
24 static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv,
25 struct ath9k_channel *ichan)
27 enum htc_phymode mode;
29 mode = -EINVAL;
31 switch (ichan->chanmode) {
32 case CHANNEL_G:
33 case CHANNEL_G_HT20:
34 case CHANNEL_G_HT40PLUS:
35 case CHANNEL_G_HT40MINUS:
36 mode = HTC_MODE_11NG;
37 break;
38 case CHANNEL_A:
39 case CHANNEL_A_HT20:
40 case CHANNEL_A_HT40PLUS:
41 case CHANNEL_A_HT40MINUS:
42 mode = HTC_MODE_11NA;
43 break;
44 default:
45 break;
48 WARN_ON(mode < 0);
50 return mode;
53 bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
54 enum ath9k_power_mode mode)
56 bool ret;
58 mutex_lock(&priv->htc_pm_lock);
59 ret = ath9k_hw_setpower(priv->ah, mode);
60 mutex_unlock(&priv->htc_pm_lock);
62 return ret;
65 void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv)
67 mutex_lock(&priv->htc_pm_lock);
68 if (++priv->ps_usecount != 1)
69 goto unlock;
70 ath9k_hw_setpower(priv->ah, ATH9K_PM_AWAKE);
72 unlock:
73 mutex_unlock(&priv->htc_pm_lock);
76 void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv)
78 mutex_lock(&priv->htc_pm_lock);
79 if (--priv->ps_usecount != 0)
80 goto unlock;
82 if (priv->ps_idle)
83 ath9k_hw_setpower(priv->ah, ATH9K_PM_FULL_SLEEP);
84 else if (priv->ps_enabled)
85 ath9k_hw_setpower(priv->ah, ATH9K_PM_NETWORK_SLEEP);
87 unlock:
88 mutex_unlock(&priv->htc_pm_lock);
91 void ath9k_ps_work(struct work_struct *work)
93 struct ath9k_htc_priv *priv =
94 container_of(work, struct ath9k_htc_priv,
95 ps_work);
96 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
98 /* The chip wakes up after receiving the first beacon
99 while network sleep is enabled. For the driver to
100 be in sync with the hw, set the chip to awake and
101 only then set it to sleep.
103 ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP);
106 static void ath9k_htc_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
108 struct ath9k_htc_priv *priv = data;
109 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
111 if ((vif->type == NL80211_IFTYPE_AP) && bss_conf->enable_beacon)
112 priv->reconfig_beacon = true;
114 if (bss_conf->assoc) {
115 priv->rearm_ani = true;
116 priv->reconfig_beacon = true;
120 static void ath9k_htc_vif_reconfig(struct ath9k_htc_priv *priv)
122 priv->rearm_ani = false;
123 priv->reconfig_beacon = false;
125 ieee80211_iterate_active_interfaces_atomic(priv->hw,
126 ath9k_htc_vif_iter, priv);
127 if (priv->rearm_ani)
128 ath9k_htc_start_ani(priv);
130 if (priv->reconfig_beacon) {
131 ath9k_htc_ps_wakeup(priv);
132 ath9k_htc_beacon_reconfig(priv);
133 ath9k_htc_ps_restore(priv);
137 static void ath9k_htc_bssid_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
139 struct ath9k_vif_iter_data *iter_data = data;
140 int i;
142 for (i = 0; i < ETH_ALEN; i++)
143 iter_data->mask[i] &= ~(iter_data->hw_macaddr[i] ^ mac[i]);
146 static void ath9k_htc_set_bssid_mask(struct ath9k_htc_priv *priv,
147 struct ieee80211_vif *vif)
149 struct ath_common *common = ath9k_hw_common(priv->ah);
150 struct ath9k_vif_iter_data iter_data;
153 * Use the hardware MAC address as reference, the hardware uses it
154 * together with the BSSID mask when matching addresses.
156 iter_data.hw_macaddr = common->macaddr;
157 memset(&iter_data.mask, 0xff, ETH_ALEN);
159 if (vif)
160 ath9k_htc_bssid_iter(&iter_data, vif->addr, vif);
162 /* Get list of all active MAC addresses */
163 ieee80211_iterate_active_interfaces_atomic(priv->hw, ath9k_htc_bssid_iter,
164 &iter_data);
166 memcpy(common->bssidmask, iter_data.mask, ETH_ALEN);
167 ath_hw_setbssidmask(common);
170 static void ath9k_htc_set_opmode(struct ath9k_htc_priv *priv)
172 if (priv->num_ibss_vif)
173 priv->ah->opmode = NL80211_IFTYPE_ADHOC;
174 else if (priv->num_ap_vif)
175 priv->ah->opmode = NL80211_IFTYPE_AP;
176 else
177 priv->ah->opmode = NL80211_IFTYPE_STATION;
179 ath9k_hw_setopmode(priv->ah);
182 void ath9k_htc_reset(struct ath9k_htc_priv *priv)
184 struct ath_hw *ah = priv->ah;
185 struct ath_common *common = ath9k_hw_common(ah);
186 struct ieee80211_channel *channel = priv->hw->conf.channel;
187 struct ath9k_hw_cal_data *caldata = NULL;
188 enum htc_phymode mode;
189 __be16 htc_mode;
190 u8 cmd_rsp;
191 int ret;
193 mutex_lock(&priv->mutex);
194 ath9k_htc_ps_wakeup(priv);
196 ath9k_htc_stop_ani(priv);
197 ieee80211_stop_queues(priv->hw);
199 del_timer_sync(&priv->tx.cleanup_timer);
200 ath9k_htc_tx_drain(priv);
202 WMI_CMD(WMI_DISABLE_INTR_CMDID);
203 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
204 WMI_CMD(WMI_STOP_RECV_CMDID);
206 ath9k_wmi_event_drain(priv);
208 caldata = &priv->caldata;
209 ret = ath9k_hw_reset(ah, ah->curchan, caldata, false);
210 if (ret) {
211 ath_err(common,
212 "Unable to reset device (%u Mhz) reset status %d\n",
213 channel->center_freq, ret);
216 ath9k_cmn_update_txpow(ah, priv->curtxpow, priv->txpowlimit,
217 &priv->curtxpow);
219 WMI_CMD(WMI_START_RECV_CMDID);
220 ath9k_host_rx_init(priv);
222 mode = ath9k_htc_get_curmode(priv, ah->curchan);
223 htc_mode = cpu_to_be16(mode);
224 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
226 WMI_CMD(WMI_ENABLE_INTR_CMDID);
227 htc_start(priv->htc);
228 ath9k_htc_vif_reconfig(priv);
229 ieee80211_wake_queues(priv->hw);
231 mod_timer(&priv->tx.cleanup_timer,
232 jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
234 ath9k_htc_ps_restore(priv);
235 mutex_unlock(&priv->mutex);
238 static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
239 struct ieee80211_hw *hw,
240 struct ath9k_channel *hchan)
242 struct ath_hw *ah = priv->ah;
243 struct ath_common *common = ath9k_hw_common(ah);
244 struct ieee80211_conf *conf = &common->hw->conf;
245 bool fastcc;
246 struct ieee80211_channel *channel = hw->conf.channel;
247 struct ath9k_hw_cal_data *caldata = NULL;
248 enum htc_phymode mode;
249 __be16 htc_mode;
250 u8 cmd_rsp;
251 int ret;
253 if (priv->op_flags & OP_INVALID)
254 return -EIO;
256 fastcc = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL);
258 ath9k_htc_ps_wakeup(priv);
260 del_timer_sync(&priv->tx.cleanup_timer);
261 ath9k_htc_tx_drain(priv);
263 WMI_CMD(WMI_DISABLE_INTR_CMDID);
264 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
265 WMI_CMD(WMI_STOP_RECV_CMDID);
267 ath9k_wmi_event_drain(priv);
269 ath_dbg(common, CONFIG,
270 "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n",
271 priv->ah->curchan->channel,
272 channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf),
273 fastcc);
275 if (!fastcc)
276 caldata = &priv->caldata;
278 ret = ath9k_hw_reset(ah, hchan, caldata, fastcc);
279 if (ret) {
280 ath_err(common,
281 "Unable to reset channel (%u Mhz) reset status %d\n",
282 channel->center_freq, ret);
283 goto err;
286 ath9k_cmn_update_txpow(ah, priv->curtxpow, priv->txpowlimit,
287 &priv->curtxpow);
289 WMI_CMD(WMI_START_RECV_CMDID);
290 if (ret)
291 goto err;
293 ath9k_host_rx_init(priv);
295 mode = ath9k_htc_get_curmode(priv, hchan);
296 htc_mode = cpu_to_be16(mode);
297 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
298 if (ret)
299 goto err;
301 WMI_CMD(WMI_ENABLE_INTR_CMDID);
302 if (ret)
303 goto err;
305 htc_start(priv->htc);
307 if (!(priv->op_flags & OP_SCANNING) &&
308 !(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL))
309 ath9k_htc_vif_reconfig(priv);
311 mod_timer(&priv->tx.cleanup_timer,
312 jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
314 err:
315 ath9k_htc_ps_restore(priv);
316 return ret;
320 * Monitor mode handling is a tad complicated because the firmware requires
321 * an interface to be created exclusively, while mac80211 doesn't associate
322 * an interface with the mode.
324 * So, for now, only one monitor interface can be configured.
326 static void __ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
328 struct ath_common *common = ath9k_hw_common(priv->ah);
329 struct ath9k_htc_target_vif hvif;
330 int ret = 0;
331 u8 cmd_rsp;
333 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
334 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
335 hvif.index = priv->mon_vif_idx;
336 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
337 if (ret) {
338 ath_err(common, "Unable to remove monitor interface at idx: %d\n",
339 priv->mon_vif_idx);
342 priv->nvifs--;
343 priv->vif_slot &= ~(1 << priv->mon_vif_idx);
346 static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
348 struct ath_common *common = ath9k_hw_common(priv->ah);
349 struct ath9k_htc_target_vif hvif;
350 struct ath9k_htc_target_sta tsta;
351 int ret = 0, sta_idx;
352 u8 cmd_rsp;
354 if ((priv->nvifs >= ATH9K_HTC_MAX_VIF) ||
355 (priv->nstations >= ATH9K_HTC_MAX_STA)) {
356 ret = -ENOBUFS;
357 goto err_vif;
360 sta_idx = ffz(priv->sta_slot);
361 if ((sta_idx < 0) || (sta_idx > ATH9K_HTC_MAX_STA)) {
362 ret = -ENOBUFS;
363 goto err_vif;
367 * Add an interface.
369 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
370 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
372 hvif.opmode = HTC_M_MONITOR;
373 hvif.index = ffz(priv->vif_slot);
375 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
376 if (ret)
377 goto err_vif;
380 * Assign the monitor interface index as a special case here.
381 * This is needed when the interface is brought down.
383 priv->mon_vif_idx = hvif.index;
384 priv->vif_slot |= (1 << hvif.index);
387 * Set the hardware mode to monitor only if there are no
388 * other interfaces.
390 if (!priv->nvifs)
391 priv->ah->opmode = NL80211_IFTYPE_MONITOR;
393 priv->nvifs++;
396 * Associate a station with the interface for packet injection.
398 memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta));
400 memcpy(&tsta.macaddr, common->macaddr, ETH_ALEN);
402 tsta.is_vif_sta = 1;
403 tsta.sta_index = sta_idx;
404 tsta.vif_index = hvif.index;
405 tsta.maxampdu = cpu_to_be16(0xffff);
407 WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
408 if (ret) {
409 ath_err(common, "Unable to add station entry for monitor mode\n");
410 goto err_sta;
413 priv->sta_slot |= (1 << sta_idx);
414 priv->nstations++;
415 priv->vif_sta_pos[priv->mon_vif_idx] = sta_idx;
416 priv->ah->is_monitoring = true;
418 ath_dbg(common, CONFIG,
419 "Attached a monitor interface at idx: %d, sta idx: %d\n",
420 priv->mon_vif_idx, sta_idx);
422 return 0;
424 err_sta:
426 * Remove the interface from the target.
428 __ath9k_htc_remove_monitor_interface(priv);
429 err_vif:
430 ath_dbg(common, FATAL, "Unable to attach a monitor interface\n");
432 return ret;
435 static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
437 struct ath_common *common = ath9k_hw_common(priv->ah);
438 int ret = 0;
439 u8 cmd_rsp, sta_idx;
441 __ath9k_htc_remove_monitor_interface(priv);
443 sta_idx = priv->vif_sta_pos[priv->mon_vif_idx];
445 WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx);
446 if (ret) {
447 ath_err(common, "Unable to remove station entry for monitor mode\n");
448 return ret;
451 priv->sta_slot &= ~(1 << sta_idx);
452 priv->nstations--;
453 priv->ah->is_monitoring = false;
455 ath_dbg(common, CONFIG,
456 "Removed a monitor interface at idx: %d, sta idx: %d\n",
457 priv->mon_vif_idx, sta_idx);
459 return 0;
462 static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
463 struct ieee80211_vif *vif,
464 struct ieee80211_sta *sta)
466 struct ath_common *common = ath9k_hw_common(priv->ah);
467 struct ath9k_htc_target_sta tsta;
468 struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
469 struct ath9k_htc_sta *ista;
470 int ret, sta_idx;
471 u8 cmd_rsp;
472 u16 maxampdu;
474 if (priv->nstations >= ATH9K_HTC_MAX_STA)
475 return -ENOBUFS;
477 sta_idx = ffz(priv->sta_slot);
478 if ((sta_idx < 0) || (sta_idx > ATH9K_HTC_MAX_STA))
479 return -ENOBUFS;
481 memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta));
483 if (sta) {
484 ista = (struct ath9k_htc_sta *) sta->drv_priv;
485 memcpy(&tsta.macaddr, sta->addr, ETH_ALEN);
486 memcpy(&tsta.bssid, common->curbssid, ETH_ALEN);
487 tsta.is_vif_sta = 0;
488 ista->index = sta_idx;
489 } else {
490 memcpy(&tsta.macaddr, vif->addr, ETH_ALEN);
491 tsta.is_vif_sta = 1;
494 tsta.sta_index = sta_idx;
495 tsta.vif_index = avp->index;
497 if (!sta) {
498 tsta.maxampdu = cpu_to_be16(0xffff);
499 } else {
500 maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
501 sta->ht_cap.ampdu_factor);
502 tsta.maxampdu = cpu_to_be16(maxampdu);
505 WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
506 if (ret) {
507 if (sta)
508 ath_err(common,
509 "Unable to add station entry for: %pM\n",
510 sta->addr);
511 return ret;
514 if (sta) {
515 ath_dbg(common, CONFIG,
516 "Added a station entry for: %pM (idx: %d)\n",
517 sta->addr, tsta.sta_index);
518 } else {
519 ath_dbg(common, CONFIG,
520 "Added a station entry for VIF %d (idx: %d)\n",
521 avp->index, tsta.sta_index);
524 priv->sta_slot |= (1 << sta_idx);
525 priv->nstations++;
526 if (!sta)
527 priv->vif_sta_pos[avp->index] = sta_idx;
529 return 0;
532 static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
533 struct ieee80211_vif *vif,
534 struct ieee80211_sta *sta)
536 struct ath_common *common = ath9k_hw_common(priv->ah);
537 struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
538 struct ath9k_htc_sta *ista;
539 int ret;
540 u8 cmd_rsp, sta_idx;
542 if (sta) {
543 ista = (struct ath9k_htc_sta *) sta->drv_priv;
544 sta_idx = ista->index;
545 } else {
546 sta_idx = priv->vif_sta_pos[avp->index];
549 WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx);
550 if (ret) {
551 if (sta)
552 ath_err(common,
553 "Unable to remove station entry for: %pM\n",
554 sta->addr);
555 return ret;
558 if (sta) {
559 ath_dbg(common, CONFIG,
560 "Removed a station entry for: %pM (idx: %d)\n",
561 sta->addr, sta_idx);
562 } else {
563 ath_dbg(common, CONFIG,
564 "Removed a station entry for VIF %d (idx: %d)\n",
565 avp->index, sta_idx);
568 priv->sta_slot &= ~(1 << sta_idx);
569 priv->nstations--;
571 return 0;
574 int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv,
575 u8 enable_coex)
577 struct ath9k_htc_cap_target tcap;
578 int ret;
579 u8 cmd_rsp;
581 memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target));
583 tcap.ampdu_limit = cpu_to_be32(0xffff);
584 tcap.ampdu_subframes = 0xff;
585 tcap.enable_coex = enable_coex;
586 tcap.tx_chainmask = priv->ah->caps.tx_chainmask;
588 WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap);
590 return ret;
593 static void ath9k_htc_setup_rate(struct ath9k_htc_priv *priv,
594 struct ieee80211_sta *sta,
595 struct ath9k_htc_target_rate *trate)
597 struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
598 struct ieee80211_supported_band *sband;
599 u32 caps = 0;
600 int i, j;
602 sband = priv->hw->wiphy->bands[priv->hw->conf.channel->band];
604 for (i = 0, j = 0; i < sband->n_bitrates; i++) {
605 if (sta->supp_rates[sband->band] & BIT(i)) {
606 trate->rates.legacy_rates.rs_rates[j]
607 = (sband->bitrates[i].bitrate * 2) / 10;
608 j++;
611 trate->rates.legacy_rates.rs_nrates = j;
613 if (sta->ht_cap.ht_supported) {
614 for (i = 0, j = 0; i < 77; i++) {
615 if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8)))
616 trate->rates.ht_rates.rs_rates[j++] = i;
617 if (j == ATH_HTC_RATE_MAX)
618 break;
620 trate->rates.ht_rates.rs_nrates = j;
622 caps = WLAN_RC_HT_FLAG;
623 if (sta->ht_cap.mcs.rx_mask[1])
624 caps |= WLAN_RC_DS_FLAG;
625 if ((sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
626 (conf_is_ht40(&priv->hw->conf)))
627 caps |= WLAN_RC_40_FLAG;
628 if (conf_is_ht40(&priv->hw->conf) &&
629 (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40))
630 caps |= WLAN_RC_SGI_FLAG;
631 else if (conf_is_ht20(&priv->hw->conf) &&
632 (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20))
633 caps |= WLAN_RC_SGI_FLAG;
636 trate->sta_index = ista->index;
637 trate->isnew = 1;
638 trate->capflags = cpu_to_be32(caps);
641 static int ath9k_htc_send_rate_cmd(struct ath9k_htc_priv *priv,
642 struct ath9k_htc_target_rate *trate)
644 struct ath_common *common = ath9k_hw_common(priv->ah);
645 int ret;
646 u8 cmd_rsp;
648 WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, trate);
649 if (ret) {
650 ath_err(common,
651 "Unable to initialize Rate information on target\n");
654 return ret;
657 static void ath9k_htc_init_rate(struct ath9k_htc_priv *priv,
658 struct ieee80211_sta *sta)
660 struct ath_common *common = ath9k_hw_common(priv->ah);
661 struct ath9k_htc_target_rate trate;
662 int ret;
664 memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
665 ath9k_htc_setup_rate(priv, sta, &trate);
666 ret = ath9k_htc_send_rate_cmd(priv, &trate);
667 if (!ret)
668 ath_dbg(common, CONFIG,
669 "Updated target sta: %pM, rate caps: 0x%X\n",
670 sta->addr, be32_to_cpu(trate.capflags));
673 static void ath9k_htc_update_rate(struct ath9k_htc_priv *priv,
674 struct ieee80211_vif *vif,
675 struct ieee80211_bss_conf *bss_conf)
677 struct ath_common *common = ath9k_hw_common(priv->ah);
678 struct ath9k_htc_target_rate trate;
679 struct ieee80211_sta *sta;
680 int ret;
682 memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
684 rcu_read_lock();
685 sta = ieee80211_find_sta(vif, bss_conf->bssid);
686 if (!sta) {
687 rcu_read_unlock();
688 return;
690 ath9k_htc_setup_rate(priv, sta, &trate);
691 rcu_read_unlock();
693 ret = ath9k_htc_send_rate_cmd(priv, &trate);
694 if (!ret)
695 ath_dbg(common, CONFIG,
696 "Updated target sta: %pM, rate caps: 0x%X\n",
697 bss_conf->bssid, be32_to_cpu(trate.capflags));
700 static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv,
701 struct ieee80211_vif *vif,
702 struct ieee80211_sta *sta,
703 enum ieee80211_ampdu_mlme_action action,
704 u16 tid)
706 struct ath_common *common = ath9k_hw_common(priv->ah);
707 struct ath9k_htc_target_aggr aggr;
708 struct ath9k_htc_sta *ista;
709 int ret = 0;
710 u8 cmd_rsp;
712 if (tid >= ATH9K_HTC_MAX_TID)
713 return -EINVAL;
715 memset(&aggr, 0, sizeof(struct ath9k_htc_target_aggr));
716 ista = (struct ath9k_htc_sta *) sta->drv_priv;
718 aggr.sta_index = ista->index;
719 aggr.tidno = tid & 0xf;
720 aggr.aggr_enable = (action == IEEE80211_AMPDU_TX_START) ? true : false;
722 WMI_CMD_BUF(WMI_TX_AGGR_ENABLE_CMDID, &aggr);
723 if (ret)
724 ath_dbg(common, CONFIG,
725 "Unable to %s TX aggregation for (%pM, %d)\n",
726 (aggr.aggr_enable) ? "start" : "stop", sta->addr, tid);
727 else
728 ath_dbg(common, CONFIG,
729 "%s TX aggregation for (%pM, %d)\n",
730 (aggr.aggr_enable) ? "Starting" : "Stopping",
731 sta->addr, tid);
733 spin_lock_bh(&priv->tx.tx_lock);
734 ista->tid_state[tid] = (aggr.aggr_enable && !ret) ? AGGR_START : AGGR_STOP;
735 spin_unlock_bh(&priv->tx.tx_lock);
737 return ret;
740 /*******/
741 /* ANI */
742 /*******/
744 void ath9k_htc_start_ani(struct ath9k_htc_priv *priv)
746 struct ath_common *common = ath9k_hw_common(priv->ah);
747 unsigned long timestamp = jiffies_to_msecs(jiffies);
749 common->ani.longcal_timer = timestamp;
750 common->ani.shortcal_timer = timestamp;
751 common->ani.checkani_timer = timestamp;
753 priv->op_flags |= OP_ANI_RUNNING;
755 ieee80211_queue_delayed_work(common->hw, &priv->ani_work,
756 msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
759 void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv)
761 cancel_delayed_work_sync(&priv->ani_work);
762 priv->op_flags &= ~OP_ANI_RUNNING;
765 void ath9k_htc_ani_work(struct work_struct *work)
767 struct ath9k_htc_priv *priv =
768 container_of(work, struct ath9k_htc_priv, ani_work.work);
769 struct ath_hw *ah = priv->ah;
770 struct ath_common *common = ath9k_hw_common(ah);
771 bool longcal = false;
772 bool shortcal = false;
773 bool aniflag = false;
774 unsigned int timestamp = jiffies_to_msecs(jiffies);
775 u32 cal_interval, short_cal_interval;
777 short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ?
778 ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL;
780 /* Only calibrate if awake */
781 if (ah->power_mode != ATH9K_PM_AWAKE)
782 goto set_timer;
784 /* Long calibration runs independently of short calibration. */
785 if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
786 longcal = true;
787 ath_dbg(common, ANI, "longcal @%lu\n", jiffies);
788 common->ani.longcal_timer = timestamp;
791 /* Short calibration applies only while caldone is false */
792 if (!common->ani.caldone) {
793 if ((timestamp - common->ani.shortcal_timer) >=
794 short_cal_interval) {
795 shortcal = true;
796 ath_dbg(common, ANI, "shortcal @%lu\n", jiffies);
797 common->ani.shortcal_timer = timestamp;
798 common->ani.resetcal_timer = timestamp;
800 } else {
801 if ((timestamp - common->ani.resetcal_timer) >=
802 ATH_RESTART_CALINTERVAL) {
803 common->ani.caldone = ath9k_hw_reset_calvalid(ah);
804 if (common->ani.caldone)
805 common->ani.resetcal_timer = timestamp;
809 /* Verify whether we must check ANI */
810 if (ah->config.enable_ani &&
811 (timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
812 aniflag = true;
813 common->ani.checkani_timer = timestamp;
816 /* Skip all processing if there's nothing to do. */
817 if (longcal || shortcal || aniflag) {
819 ath9k_htc_ps_wakeup(priv);
821 /* Call ANI routine if necessary */
822 if (aniflag)
823 ath9k_hw_ani_monitor(ah, ah->curchan);
825 /* Perform calibration if necessary */
826 if (longcal || shortcal)
827 common->ani.caldone =
828 ath9k_hw_calibrate(ah, ah->curchan,
829 ah->rxchainmask, longcal);
831 ath9k_htc_ps_restore(priv);
834 set_timer:
836 * Set timer interval based on previous results.
837 * The interval must be the shortest necessary to satisfy ANI,
838 * short calibration and long calibration.
840 cal_interval = ATH_LONG_CALINTERVAL;
841 if (ah->config.enable_ani)
842 cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
843 if (!common->ani.caldone)
844 cal_interval = min(cal_interval, (u32)short_cal_interval);
846 ieee80211_queue_delayed_work(common->hw, &priv->ani_work,
847 msecs_to_jiffies(cal_interval));
850 /**********************/
851 /* mac80211 Callbacks */
852 /**********************/
854 static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
856 struct ieee80211_hdr *hdr;
857 struct ath9k_htc_priv *priv = hw->priv;
858 struct ath_common *common = ath9k_hw_common(priv->ah);
859 int padpos, padsize, ret, slot;
861 hdr = (struct ieee80211_hdr *) skb->data;
863 /* Add the padding after the header if this is not already done */
864 padpos = ath9k_cmn_padpos(hdr->frame_control);
865 padsize = padpos & 3;
866 if (padsize && skb->len > padpos) {
867 if (skb_headroom(skb) < padsize) {
868 ath_dbg(common, XMIT, "No room for padding\n");
869 goto fail_tx;
871 skb_push(skb, padsize);
872 memmove(skb->data, skb->data + padsize, padpos);
875 slot = ath9k_htc_tx_get_slot(priv);
876 if (slot < 0) {
877 ath_dbg(common, XMIT, "No free TX slot\n");
878 goto fail_tx;
881 ret = ath9k_htc_tx_start(priv, skb, slot, false);
882 if (ret != 0) {
883 ath_dbg(common, XMIT, "Tx failed\n");
884 goto clear_slot;
887 ath9k_htc_check_stop_queues(priv);
889 return;
891 clear_slot:
892 ath9k_htc_tx_clear_slot(priv, slot);
893 fail_tx:
894 dev_kfree_skb_any(skb);
897 static int ath9k_htc_start(struct ieee80211_hw *hw)
899 struct ath9k_htc_priv *priv = hw->priv;
900 struct ath_hw *ah = priv->ah;
901 struct ath_common *common = ath9k_hw_common(ah);
902 struct ieee80211_channel *curchan = hw->conf.channel;
903 struct ath9k_channel *init_channel;
904 int ret = 0;
905 enum htc_phymode mode;
906 __be16 htc_mode;
907 u8 cmd_rsp;
909 mutex_lock(&priv->mutex);
911 ath_dbg(common, CONFIG,
912 "Starting driver with initial channel: %d MHz\n",
913 curchan->center_freq);
915 /* Ensure that HW is awake before flushing RX */
916 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
917 WMI_CMD(WMI_FLUSH_RECV_CMDID);
919 /* setup initial channel */
920 init_channel = ath9k_cmn_get_curchannel(hw, ah);
922 ath9k_hw_htc_resetinit(ah);
923 ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
924 if (ret) {
925 ath_err(common,
926 "Unable to reset hardware; reset status %d (freq %u MHz)\n",
927 ret, curchan->center_freq);
928 mutex_unlock(&priv->mutex);
929 return ret;
932 ath9k_cmn_update_txpow(ah, priv->curtxpow, priv->txpowlimit,
933 &priv->curtxpow);
935 mode = ath9k_htc_get_curmode(priv, init_channel);
936 htc_mode = cpu_to_be16(mode);
937 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
938 WMI_CMD(WMI_ATH_INIT_CMDID);
939 WMI_CMD(WMI_START_RECV_CMDID);
941 ath9k_host_rx_init(priv);
943 ret = ath9k_htc_update_cap_target(priv, 0);
944 if (ret)
945 ath_dbg(common, CONFIG,
946 "Failed to update capability in target\n");
948 priv->op_flags &= ~OP_INVALID;
949 htc_start(priv->htc);
951 spin_lock_bh(&priv->tx.tx_lock);
952 priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP;
953 spin_unlock_bh(&priv->tx.tx_lock);
955 ieee80211_wake_queues(hw);
957 mod_timer(&priv->tx.cleanup_timer,
958 jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
960 if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) {
961 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
962 AR_STOMP_LOW_WLAN_WGHT);
963 ath9k_hw_btcoex_enable(ah);
964 ath_htc_resume_btcoex_work(priv);
966 mutex_unlock(&priv->mutex);
968 return ret;
971 static void ath9k_htc_stop(struct ieee80211_hw *hw)
973 struct ath9k_htc_priv *priv = hw->priv;
974 struct ath_hw *ah = priv->ah;
975 struct ath_common *common = ath9k_hw_common(ah);
976 int ret __attribute__ ((unused));
977 u8 cmd_rsp;
979 mutex_lock(&priv->mutex);
981 if (priv->op_flags & OP_INVALID) {
982 ath_dbg(common, ANY, "Device not present\n");
983 mutex_unlock(&priv->mutex);
984 return;
987 ath9k_htc_ps_wakeup(priv);
989 WMI_CMD(WMI_DISABLE_INTR_CMDID);
990 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
991 WMI_CMD(WMI_STOP_RECV_CMDID);
993 tasklet_kill(&priv->rx_tasklet);
995 del_timer_sync(&priv->tx.cleanup_timer);
996 ath9k_htc_tx_drain(priv);
997 ath9k_wmi_event_drain(priv);
999 mutex_unlock(&priv->mutex);
1001 /* Cancel all the running timers/work .. */
1002 cancel_work_sync(&priv->fatal_work);
1003 cancel_work_sync(&priv->ps_work);
1005 #ifdef CONFIG_MAC80211_LEDS
1006 cancel_work_sync(&priv->led_work);
1007 #endif
1008 ath9k_htc_stop_ani(priv);
1010 mutex_lock(&priv->mutex);
1012 if (ah->btcoex_hw.enabled &&
1013 ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) {
1014 ath9k_hw_btcoex_disable(ah);
1015 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
1016 ath_htc_cancel_btcoex_work(priv);
1019 /* Remove a monitor interface if it's present. */
1020 if (priv->ah->is_monitoring)
1021 ath9k_htc_remove_monitor_interface(priv);
1023 ath9k_hw_phy_disable(ah);
1024 ath9k_hw_disable(ah);
1025 ath9k_htc_ps_restore(priv);
1026 ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
1028 priv->op_flags |= OP_INVALID;
1030 ath_dbg(common, CONFIG, "Driver halt\n");
1031 mutex_unlock(&priv->mutex);
1034 static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1035 struct ieee80211_vif *vif)
1037 struct ath9k_htc_priv *priv = hw->priv;
1038 struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1039 struct ath_common *common = ath9k_hw_common(priv->ah);
1040 struct ath9k_htc_target_vif hvif;
1041 int ret = 0;
1042 u8 cmd_rsp;
1044 mutex_lock(&priv->mutex);
1046 if (priv->nvifs >= ATH9K_HTC_MAX_VIF) {
1047 mutex_unlock(&priv->mutex);
1048 return -ENOBUFS;
1051 if (priv->num_ibss_vif ||
1052 (priv->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) {
1053 ath_err(common, "IBSS coexistence with other modes is not allowed\n");
1054 mutex_unlock(&priv->mutex);
1055 return -ENOBUFS;
1058 if (((vif->type == NL80211_IFTYPE_AP) ||
1059 (vif->type == NL80211_IFTYPE_ADHOC)) &&
1060 ((priv->num_ap_vif + priv->num_ibss_vif) >= ATH9K_HTC_MAX_BCN_VIF)) {
1061 ath_err(common, "Max. number of beaconing interfaces reached\n");
1062 mutex_unlock(&priv->mutex);
1063 return -ENOBUFS;
1066 ath9k_htc_ps_wakeup(priv);
1067 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
1068 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
1070 switch (vif->type) {
1071 case NL80211_IFTYPE_STATION:
1072 hvif.opmode = HTC_M_STA;
1073 break;
1074 case NL80211_IFTYPE_ADHOC:
1075 hvif.opmode = HTC_M_IBSS;
1076 break;
1077 case NL80211_IFTYPE_AP:
1078 hvif.opmode = HTC_M_HOSTAP;
1079 break;
1080 default:
1081 ath_err(common,
1082 "Interface type %d not yet supported\n", vif->type);
1083 ret = -EOPNOTSUPP;
1084 goto out;
1087 /* Index starts from zero on the target */
1088 avp->index = hvif.index = ffz(priv->vif_slot);
1089 hvif.rtsthreshold = cpu_to_be16(2304);
1090 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
1091 if (ret)
1092 goto out;
1095 * We need a node in target to tx mgmt frames
1096 * before association.
1098 ret = ath9k_htc_add_station(priv, vif, NULL);
1099 if (ret) {
1100 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
1101 goto out;
1104 ath9k_htc_set_bssid_mask(priv, vif);
1106 priv->vif_slot |= (1 << avp->index);
1107 priv->nvifs++;
1109 INC_VIF(priv, vif->type);
1111 if ((vif->type == NL80211_IFTYPE_AP) ||
1112 (vif->type == NL80211_IFTYPE_ADHOC))
1113 ath9k_htc_assign_bslot(priv, vif);
1115 ath9k_htc_set_opmode(priv);
1117 if ((priv->ah->opmode == NL80211_IFTYPE_AP) &&
1118 !(priv->op_flags & OP_ANI_RUNNING)) {
1119 ath9k_hw_set_tsfadjust(priv->ah, 1);
1120 ath9k_htc_start_ani(priv);
1123 ath_dbg(common, CONFIG, "Attach a VIF of type: %d at idx: %d\n",
1124 vif->type, avp->index);
1126 out:
1127 ath9k_htc_ps_restore(priv);
1128 mutex_unlock(&priv->mutex);
1130 return ret;
1133 static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
1134 struct ieee80211_vif *vif)
1136 struct ath9k_htc_priv *priv = hw->priv;
1137 struct ath_common *common = ath9k_hw_common(priv->ah);
1138 struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1139 struct ath9k_htc_target_vif hvif;
1140 int ret = 0;
1141 u8 cmd_rsp;
1143 mutex_lock(&priv->mutex);
1144 ath9k_htc_ps_wakeup(priv);
1146 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
1147 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
1148 hvif.index = avp->index;
1149 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
1150 if (ret) {
1151 ath_err(common, "Unable to remove interface at idx: %d\n",
1152 avp->index);
1154 priv->nvifs--;
1155 priv->vif_slot &= ~(1 << avp->index);
1157 ath9k_htc_remove_station(priv, vif, NULL);
1159 DEC_VIF(priv, vif->type);
1161 if ((vif->type == NL80211_IFTYPE_AP) ||
1162 (vif->type == NL80211_IFTYPE_ADHOC))
1163 ath9k_htc_remove_bslot(priv, vif);
1165 ath9k_htc_set_opmode(priv);
1167 ath9k_htc_set_bssid_mask(priv, vif);
1170 * Stop ANI only if there are no associated station interfaces.
1172 if ((vif->type == NL80211_IFTYPE_AP) && (priv->num_ap_vif == 0)) {
1173 priv->rearm_ani = false;
1174 ieee80211_iterate_active_interfaces_atomic(priv->hw,
1175 ath9k_htc_vif_iter, priv);
1176 if (!priv->rearm_ani)
1177 ath9k_htc_stop_ani(priv);
1180 ath_dbg(common, CONFIG, "Detach Interface at idx: %d\n", avp->index);
1182 ath9k_htc_ps_restore(priv);
1183 mutex_unlock(&priv->mutex);
1186 static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
1188 struct ath9k_htc_priv *priv = hw->priv;
1189 struct ath_common *common = ath9k_hw_common(priv->ah);
1190 struct ieee80211_conf *conf = &hw->conf;
1192 mutex_lock(&priv->mutex);
1194 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1195 bool enable_radio = false;
1196 bool idle = !!(conf->flags & IEEE80211_CONF_IDLE);
1198 mutex_lock(&priv->htc_pm_lock);
1199 if (!idle && priv->ps_idle)
1200 enable_radio = true;
1201 priv->ps_idle = idle;
1202 mutex_unlock(&priv->htc_pm_lock);
1204 if (enable_radio) {
1205 ath_dbg(common, CONFIG, "not-idle: enabling radio\n");
1206 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
1207 ath9k_htc_radio_enable(hw);
1212 * Monitor interface should be added before
1213 * IEEE80211_CONF_CHANGE_CHANNEL is handled.
1215 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
1216 if ((conf->flags & IEEE80211_CONF_MONITOR) &&
1217 !priv->ah->is_monitoring)
1218 ath9k_htc_add_monitor_interface(priv);
1219 else if (priv->ah->is_monitoring)
1220 ath9k_htc_remove_monitor_interface(priv);
1223 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1224 struct ieee80211_channel *curchan = hw->conf.channel;
1225 int pos = curchan->hw_value;
1227 ath_dbg(common, CONFIG, "Set channel: %d MHz\n",
1228 curchan->center_freq);
1230 ath9k_cmn_update_ichannel(&priv->ah->channels[pos],
1231 hw->conf.channel,
1232 hw->conf.channel_type);
1234 if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) {
1235 ath_err(common, "Unable to set channel\n");
1236 mutex_unlock(&priv->mutex);
1237 return -EINVAL;
1242 if (changed & IEEE80211_CONF_CHANGE_PS) {
1243 if (conf->flags & IEEE80211_CONF_PS) {
1244 ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP);
1245 priv->ps_enabled = true;
1246 } else {
1247 priv->ps_enabled = false;
1248 cancel_work_sync(&priv->ps_work);
1249 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
1253 if (changed & IEEE80211_CONF_CHANGE_POWER) {
1254 priv->txpowlimit = 2 * conf->power_level;
1255 ath9k_cmn_update_txpow(priv->ah, priv->curtxpow,
1256 priv->txpowlimit, &priv->curtxpow);
1259 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1260 mutex_lock(&priv->htc_pm_lock);
1261 if (!priv->ps_idle) {
1262 mutex_unlock(&priv->htc_pm_lock);
1263 goto out;
1265 mutex_unlock(&priv->htc_pm_lock);
1267 ath_dbg(common, CONFIG, "idle: disabling radio\n");
1268 ath9k_htc_radio_disable(hw);
1271 out:
1272 mutex_unlock(&priv->mutex);
1273 return 0;
1276 #define SUPPORTED_FILTERS \
1277 (FIF_PROMISC_IN_BSS | \
1278 FIF_ALLMULTI | \
1279 FIF_CONTROL | \
1280 FIF_PSPOLL | \
1281 FIF_OTHER_BSS | \
1282 FIF_BCN_PRBRESP_PROMISC | \
1283 FIF_PROBE_REQ | \
1284 FIF_FCSFAIL)
1286 static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
1287 unsigned int changed_flags,
1288 unsigned int *total_flags,
1289 u64 multicast)
1291 struct ath9k_htc_priv *priv = hw->priv;
1292 u32 rfilt;
1294 mutex_lock(&priv->mutex);
1295 changed_flags &= SUPPORTED_FILTERS;
1296 *total_flags &= SUPPORTED_FILTERS;
1298 if (priv->op_flags & OP_INVALID) {
1299 ath_dbg(ath9k_hw_common(priv->ah), ANY,
1300 "Unable to configure filter on invalid state\n");
1301 mutex_unlock(&priv->mutex);
1302 return;
1304 ath9k_htc_ps_wakeup(priv);
1306 priv->rxfilter = *total_flags;
1307 rfilt = ath9k_htc_calcrxfilter(priv);
1308 ath9k_hw_setrxfilter(priv->ah, rfilt);
1310 ath_dbg(ath9k_hw_common(priv->ah), CONFIG, "Set HW RX filter: 0x%x\n",
1311 rfilt);
1313 ath9k_htc_ps_restore(priv);
1314 mutex_unlock(&priv->mutex);
1317 static int ath9k_htc_sta_add(struct ieee80211_hw *hw,
1318 struct ieee80211_vif *vif,
1319 struct ieee80211_sta *sta)
1321 struct ath9k_htc_priv *priv = hw->priv;
1322 int ret;
1324 mutex_lock(&priv->mutex);
1325 ath9k_htc_ps_wakeup(priv);
1326 ret = ath9k_htc_add_station(priv, vif, sta);
1327 if (!ret)
1328 ath9k_htc_init_rate(priv, sta);
1329 ath9k_htc_ps_restore(priv);
1330 mutex_unlock(&priv->mutex);
1332 return ret;
1335 static int ath9k_htc_sta_remove(struct ieee80211_hw *hw,
1336 struct ieee80211_vif *vif,
1337 struct ieee80211_sta *sta)
1339 struct ath9k_htc_priv *priv = hw->priv;
1340 struct ath9k_htc_sta *ista;
1341 int ret;
1343 mutex_lock(&priv->mutex);
1344 ath9k_htc_ps_wakeup(priv);
1345 ista = (struct ath9k_htc_sta *) sta->drv_priv;
1346 htc_sta_drain(priv->htc, ista->index);
1347 ret = ath9k_htc_remove_station(priv, vif, sta);
1348 ath9k_htc_ps_restore(priv);
1349 mutex_unlock(&priv->mutex);
1351 return ret;
1354 static int ath9k_htc_conf_tx(struct ieee80211_hw *hw,
1355 struct ieee80211_vif *vif, u16 queue,
1356 const struct ieee80211_tx_queue_params *params)
1358 struct ath9k_htc_priv *priv = hw->priv;
1359 struct ath_common *common = ath9k_hw_common(priv->ah);
1360 struct ath9k_tx_queue_info qi;
1361 int ret = 0, qnum;
1363 if (queue >= WME_NUM_AC)
1364 return 0;
1366 mutex_lock(&priv->mutex);
1367 ath9k_htc_ps_wakeup(priv);
1369 memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
1371 qi.tqi_aifs = params->aifs;
1372 qi.tqi_cwmin = params->cw_min;
1373 qi.tqi_cwmax = params->cw_max;
1374 qi.tqi_burstTime = params->txop;
1376 qnum = get_hw_qnum(queue, priv->hwq_map);
1378 ath_dbg(common, CONFIG,
1379 "Configure tx [queue/hwq] [%d/%d], aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
1380 queue, qnum, params->aifs, params->cw_min,
1381 params->cw_max, params->txop);
1383 ret = ath_htc_txq_update(priv, qnum, &qi);
1384 if (ret) {
1385 ath_err(common, "TXQ Update failed\n");
1386 goto out;
1389 if ((priv->ah->opmode == NL80211_IFTYPE_ADHOC) &&
1390 (qnum == priv->hwq_map[WME_AC_BE]))
1391 ath9k_htc_beaconq_config(priv);
1392 out:
1393 ath9k_htc_ps_restore(priv);
1394 mutex_unlock(&priv->mutex);
1396 return ret;
1399 static int ath9k_htc_set_key(struct ieee80211_hw *hw,
1400 enum set_key_cmd cmd,
1401 struct ieee80211_vif *vif,
1402 struct ieee80211_sta *sta,
1403 struct ieee80211_key_conf *key)
1405 struct ath9k_htc_priv *priv = hw->priv;
1406 struct ath_common *common = ath9k_hw_common(priv->ah);
1407 int ret = 0;
1409 if (htc_modparam_nohwcrypt)
1410 return -ENOSPC;
1412 mutex_lock(&priv->mutex);
1413 ath_dbg(common, CONFIG, "Set HW Key\n");
1414 ath9k_htc_ps_wakeup(priv);
1416 switch (cmd) {
1417 case SET_KEY:
1418 ret = ath_key_config(common, vif, sta, key);
1419 if (ret >= 0) {
1420 key->hw_key_idx = ret;
1421 /* push IV and Michael MIC generation to stack */
1422 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1423 if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
1424 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1425 if (priv->ah->sw_mgmt_crypto &&
1426 key->cipher == WLAN_CIPHER_SUITE_CCMP)
1427 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
1428 ret = 0;
1430 break;
1431 case DISABLE_KEY:
1432 ath_key_delete(common, key);
1433 break;
1434 default:
1435 ret = -EINVAL;
1438 ath9k_htc_ps_restore(priv);
1439 mutex_unlock(&priv->mutex);
1441 return ret;
1444 static void ath9k_htc_set_bssid(struct ath9k_htc_priv *priv)
1446 struct ath_common *common = ath9k_hw_common(priv->ah);
1448 ath9k_hw_write_associd(priv->ah);
1449 ath_dbg(common, CONFIG, "BSSID: %pM aid: 0x%x\n",
1450 common->curbssid, common->curaid);
1453 static void ath9k_htc_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
1455 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
1456 struct ath_common *common = ath9k_hw_common(priv->ah);
1457 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
1459 if ((vif->type == NL80211_IFTYPE_STATION) && bss_conf->assoc) {
1460 common->curaid = bss_conf->aid;
1461 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1465 static void ath9k_htc_choose_set_bssid(struct ath9k_htc_priv *priv)
1467 if (priv->num_sta_assoc_vif == 1) {
1468 ieee80211_iterate_active_interfaces_atomic(priv->hw,
1469 ath9k_htc_bss_iter, priv);
1470 ath9k_htc_set_bssid(priv);
1474 static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
1475 struct ieee80211_vif *vif,
1476 struct ieee80211_bss_conf *bss_conf,
1477 u32 changed)
1479 struct ath9k_htc_priv *priv = hw->priv;
1480 struct ath_hw *ah = priv->ah;
1481 struct ath_common *common = ath9k_hw_common(ah);
1483 mutex_lock(&priv->mutex);
1484 ath9k_htc_ps_wakeup(priv);
1486 if (changed & BSS_CHANGED_ASSOC) {
1487 ath_dbg(common, CONFIG, "BSS Changed ASSOC %d\n",
1488 bss_conf->assoc);
1490 bss_conf->assoc ?
1491 priv->num_sta_assoc_vif++ : priv->num_sta_assoc_vif--;
1493 if (priv->ah->opmode == NL80211_IFTYPE_STATION) {
1494 if (bss_conf->assoc && (priv->num_sta_assoc_vif == 1))
1495 ath9k_htc_start_ani(priv);
1496 else if (priv->num_sta_assoc_vif == 0)
1497 ath9k_htc_stop_ani(priv);
1501 if (changed & BSS_CHANGED_BSSID) {
1502 if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) {
1503 common->curaid = bss_conf->aid;
1504 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1505 ath9k_htc_set_bssid(priv);
1506 } else if (priv->ah->opmode == NL80211_IFTYPE_STATION) {
1507 ath9k_htc_choose_set_bssid(priv);
1511 if ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon) {
1512 ath_dbg(common, CONFIG, "Beacon enabled for BSS: %pM\n",
1513 bss_conf->bssid);
1514 ath9k_htc_set_tsfadjust(priv, vif);
1515 priv->op_flags |= OP_ENABLE_BEACON;
1516 ath9k_htc_beacon_config(priv, vif);
1519 if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) {
1521 * Disable SWBA interrupt only if there are no
1522 * AP/IBSS interfaces.
1524 if ((priv->num_ap_vif <= 1) || priv->num_ibss_vif) {
1525 ath_dbg(common, CONFIG,
1526 "Beacon disabled for BSS: %pM\n",
1527 bss_conf->bssid);
1528 priv->op_flags &= ~OP_ENABLE_BEACON;
1529 ath9k_htc_beacon_config(priv, vif);
1533 if (changed & BSS_CHANGED_BEACON_INT) {
1535 * Reset the HW TSF for the first AP interface.
1537 if ((priv->ah->opmode == NL80211_IFTYPE_AP) &&
1538 (priv->nvifs == 1) &&
1539 (priv->num_ap_vif == 1) &&
1540 (vif->type == NL80211_IFTYPE_AP)) {
1541 priv->op_flags |= OP_TSF_RESET;
1543 ath_dbg(common, CONFIG,
1544 "Beacon interval changed for BSS: %pM\n",
1545 bss_conf->bssid);
1546 ath9k_htc_beacon_config(priv, vif);
1549 if (changed & BSS_CHANGED_ERP_SLOT) {
1550 if (bss_conf->use_short_slot)
1551 ah->slottime = 9;
1552 else
1553 ah->slottime = 20;
1555 ath9k_hw_init_global_settings(ah);
1558 if (changed & BSS_CHANGED_HT)
1559 ath9k_htc_update_rate(priv, vif, bss_conf);
1561 ath9k_htc_ps_restore(priv);
1562 mutex_unlock(&priv->mutex);
1565 static u64 ath9k_htc_get_tsf(struct ieee80211_hw *hw,
1566 struct ieee80211_vif *vif)
1568 struct ath9k_htc_priv *priv = hw->priv;
1569 u64 tsf;
1571 mutex_lock(&priv->mutex);
1572 ath9k_htc_ps_wakeup(priv);
1573 tsf = ath9k_hw_gettsf64(priv->ah);
1574 ath9k_htc_ps_restore(priv);
1575 mutex_unlock(&priv->mutex);
1577 return tsf;
1580 static void ath9k_htc_set_tsf(struct ieee80211_hw *hw,
1581 struct ieee80211_vif *vif, u64 tsf)
1583 struct ath9k_htc_priv *priv = hw->priv;
1585 mutex_lock(&priv->mutex);
1586 ath9k_htc_ps_wakeup(priv);
1587 ath9k_hw_settsf64(priv->ah, tsf);
1588 ath9k_htc_ps_restore(priv);
1589 mutex_unlock(&priv->mutex);
1592 static void ath9k_htc_reset_tsf(struct ieee80211_hw *hw,
1593 struct ieee80211_vif *vif)
1595 struct ath9k_htc_priv *priv = hw->priv;
1597 mutex_lock(&priv->mutex);
1598 ath9k_htc_ps_wakeup(priv);
1599 ath9k_hw_reset_tsf(priv->ah);
1600 ath9k_htc_ps_restore(priv);
1601 mutex_unlock(&priv->mutex);
1604 static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
1605 struct ieee80211_vif *vif,
1606 enum ieee80211_ampdu_mlme_action action,
1607 struct ieee80211_sta *sta,
1608 u16 tid, u16 *ssn, u8 buf_size)
1610 struct ath9k_htc_priv *priv = hw->priv;
1611 struct ath9k_htc_sta *ista;
1612 int ret = 0;
1614 mutex_lock(&priv->mutex);
1615 ath9k_htc_ps_wakeup(priv);
1617 switch (action) {
1618 case IEEE80211_AMPDU_RX_START:
1619 break;
1620 case IEEE80211_AMPDU_RX_STOP:
1621 break;
1622 case IEEE80211_AMPDU_TX_START:
1623 ret = ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid);
1624 if (!ret)
1625 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1626 break;
1627 case IEEE80211_AMPDU_TX_STOP:
1628 ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid);
1629 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1630 break;
1631 case IEEE80211_AMPDU_TX_OPERATIONAL:
1632 ista = (struct ath9k_htc_sta *) sta->drv_priv;
1633 spin_lock_bh(&priv->tx.tx_lock);
1634 ista->tid_state[tid] = AGGR_OPERATIONAL;
1635 spin_unlock_bh(&priv->tx.tx_lock);
1636 break;
1637 default:
1638 ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n");
1641 ath9k_htc_ps_restore(priv);
1642 mutex_unlock(&priv->mutex);
1644 return ret;
1647 static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw)
1649 struct ath9k_htc_priv *priv = hw->priv;
1651 mutex_lock(&priv->mutex);
1652 spin_lock_bh(&priv->beacon_lock);
1653 priv->op_flags |= OP_SCANNING;
1654 spin_unlock_bh(&priv->beacon_lock);
1655 cancel_work_sync(&priv->ps_work);
1656 ath9k_htc_stop_ani(priv);
1657 mutex_unlock(&priv->mutex);
1660 static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
1662 struct ath9k_htc_priv *priv = hw->priv;
1664 mutex_lock(&priv->mutex);
1665 spin_lock_bh(&priv->beacon_lock);
1666 priv->op_flags &= ~OP_SCANNING;
1667 spin_unlock_bh(&priv->beacon_lock);
1668 ath9k_htc_ps_wakeup(priv);
1669 ath9k_htc_vif_reconfig(priv);
1670 ath9k_htc_ps_restore(priv);
1671 mutex_unlock(&priv->mutex);
1674 static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1676 return 0;
1679 static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw,
1680 u8 coverage_class)
1682 struct ath9k_htc_priv *priv = hw->priv;
1684 mutex_lock(&priv->mutex);
1685 ath9k_htc_ps_wakeup(priv);
1686 priv->ah->coverage_class = coverage_class;
1687 ath9k_hw_init_global_settings(priv->ah);
1688 ath9k_htc_ps_restore(priv);
1689 mutex_unlock(&priv->mutex);
1693 * Currently, this is used only for selecting the minimum rate
1694 * for management frames, rate selection for data frames remain
1695 * unaffected.
1697 static int ath9k_htc_set_bitrate_mask(struct ieee80211_hw *hw,
1698 struct ieee80211_vif *vif,
1699 const struct cfg80211_bitrate_mask *mask)
1701 struct ath9k_htc_priv *priv = hw->priv;
1702 struct ath_common *common = ath9k_hw_common(priv->ah);
1703 struct ath9k_htc_target_rate_mask tmask;
1704 struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1705 int ret = 0;
1706 u8 cmd_rsp;
1708 memset(&tmask, 0, sizeof(struct ath9k_htc_target_rate_mask));
1710 tmask.vif_index = avp->index;
1711 tmask.band = IEEE80211_BAND_2GHZ;
1712 tmask.mask = cpu_to_be32(mask->control[IEEE80211_BAND_2GHZ].legacy);
1714 WMI_CMD_BUF(WMI_BITRATE_MASK_CMDID, &tmask);
1715 if (ret) {
1716 ath_err(common,
1717 "Unable to set 2G rate mask for "
1718 "interface at idx: %d\n", avp->index);
1719 goto out;
1722 tmask.band = IEEE80211_BAND_5GHZ;
1723 tmask.mask = cpu_to_be32(mask->control[IEEE80211_BAND_5GHZ].legacy);
1725 WMI_CMD_BUF(WMI_BITRATE_MASK_CMDID, &tmask);
1726 if (ret) {
1727 ath_err(common,
1728 "Unable to set 5G rate mask for "
1729 "interface at idx: %d\n", avp->index);
1730 goto out;
1733 ath_dbg(common, CONFIG, "Set bitrate masks: 0x%x, 0x%x\n",
1734 mask->control[IEEE80211_BAND_2GHZ].legacy,
1735 mask->control[IEEE80211_BAND_5GHZ].legacy);
1736 out:
1737 return ret;
1741 static int ath9k_htc_get_stats(struct ieee80211_hw *hw,
1742 struct ieee80211_low_level_stats *stats)
1744 struct ath9k_htc_priv *priv = hw->priv;
1745 struct ath_hw *ah = priv->ah;
1746 struct ath9k_mib_stats *mib_stats = &ah->ah_mibStats;
1748 stats->dot11ACKFailureCount = mib_stats->ackrcv_bad;
1749 stats->dot11RTSFailureCount = mib_stats->rts_bad;
1750 stats->dot11FCSErrorCount = mib_stats->fcs_bad;
1751 stats->dot11RTSSuccessCount = mib_stats->rts_good;
1753 return 0;
1756 struct ieee80211_ops ath9k_htc_ops = {
1757 .tx = ath9k_htc_tx,
1758 .start = ath9k_htc_start,
1759 .stop = ath9k_htc_stop,
1760 .add_interface = ath9k_htc_add_interface,
1761 .remove_interface = ath9k_htc_remove_interface,
1762 .config = ath9k_htc_config,
1763 .configure_filter = ath9k_htc_configure_filter,
1764 .sta_add = ath9k_htc_sta_add,
1765 .sta_remove = ath9k_htc_sta_remove,
1766 .conf_tx = ath9k_htc_conf_tx,
1767 .bss_info_changed = ath9k_htc_bss_info_changed,
1768 .set_key = ath9k_htc_set_key,
1769 .get_tsf = ath9k_htc_get_tsf,
1770 .set_tsf = ath9k_htc_set_tsf,
1771 .reset_tsf = ath9k_htc_reset_tsf,
1772 .ampdu_action = ath9k_htc_ampdu_action,
1773 .sw_scan_start = ath9k_htc_sw_scan_start,
1774 .sw_scan_complete = ath9k_htc_sw_scan_complete,
1775 .set_rts_threshold = ath9k_htc_set_rts_threshold,
1776 .rfkill_poll = ath9k_htc_rfkill_poll_state,
1777 .set_coverage_class = ath9k_htc_set_coverage_class,
1778 .set_bitrate_mask = ath9k_htc_set_bitrate_mask,
1779 .get_stats = ath9k_htc_get_stats,