ath9k_htc: Fix max A-MPDU size handling
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / net / wireless / ath / ath9k / htc_drv_main.c
blobfbc238a0b203d5bd420bada9f08d2682a4822703
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 /*************/
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 = HTC_MODE_AUTO;
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 return mode;
51 bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
52 enum ath9k_power_mode mode)
54 bool ret;
56 mutex_lock(&priv->htc_pm_lock);
57 ret = ath9k_hw_setpower(priv->ah, mode);
58 mutex_unlock(&priv->htc_pm_lock);
60 return ret;
63 void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv)
65 mutex_lock(&priv->htc_pm_lock);
66 if (++priv->ps_usecount != 1)
67 goto unlock;
68 ath9k_hw_setpower(priv->ah, ATH9K_PM_AWAKE);
70 unlock:
71 mutex_unlock(&priv->htc_pm_lock);
74 void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv)
76 mutex_lock(&priv->htc_pm_lock);
77 if (--priv->ps_usecount != 0)
78 goto unlock;
80 if (priv->ps_idle)
81 ath9k_hw_setpower(priv->ah, ATH9K_PM_FULL_SLEEP);
82 else if (priv->ps_enabled)
83 ath9k_hw_setpower(priv->ah, ATH9K_PM_NETWORK_SLEEP);
85 unlock:
86 mutex_unlock(&priv->htc_pm_lock);
89 void ath9k_ps_work(struct work_struct *work)
91 struct ath9k_htc_priv *priv =
92 container_of(work, struct ath9k_htc_priv,
93 ps_work);
94 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
96 /* The chip wakes up after receiving the first beacon
97 while network sleep is enabled. For the driver to
98 be in sync with the hw, set the chip to awake and
99 only then set it to sleep.
101 ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP);
104 static void ath9k_htc_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
106 struct ath9k_htc_priv *priv = data;
107 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
109 if ((vif->type == NL80211_IFTYPE_AP) && bss_conf->enable_beacon)
110 priv->reconfig_beacon = true;
112 if (bss_conf->assoc) {
113 priv->rearm_ani = true;
114 priv->reconfig_beacon = true;
118 static void ath9k_htc_vif_reconfig(struct ath9k_htc_priv *priv)
120 priv->rearm_ani = false;
121 priv->reconfig_beacon = false;
123 ieee80211_iterate_active_interfaces_atomic(priv->hw,
124 ath9k_htc_vif_iter, priv);
125 if (priv->rearm_ani)
126 ath9k_htc_start_ani(priv);
128 if (priv->reconfig_beacon) {
129 ath9k_htc_ps_wakeup(priv);
130 ath9k_htc_beacon_reconfig(priv);
131 ath9k_htc_ps_restore(priv);
135 static void ath9k_htc_bssid_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
137 struct ath9k_vif_iter_data *iter_data = data;
138 int i;
140 for (i = 0; i < ETH_ALEN; i++)
141 iter_data->mask[i] &= ~(iter_data->hw_macaddr[i] ^ mac[i]);
144 static void ath9k_htc_set_bssid_mask(struct ath9k_htc_priv *priv,
145 struct ieee80211_vif *vif)
147 struct ath_common *common = ath9k_hw_common(priv->ah);
148 struct ath9k_vif_iter_data iter_data;
151 * Use the hardware MAC address as reference, the hardware uses it
152 * together with the BSSID mask when matching addresses.
154 iter_data.hw_macaddr = common->macaddr;
155 memset(&iter_data.mask, 0xff, ETH_ALEN);
157 if (vif)
158 ath9k_htc_bssid_iter(&iter_data, vif->addr, vif);
160 /* Get list of all active MAC addresses */
161 ieee80211_iterate_active_interfaces_atomic(priv->hw, ath9k_htc_bssid_iter,
162 &iter_data);
164 memcpy(common->bssidmask, iter_data.mask, ETH_ALEN);
165 ath_hw_setbssidmask(common);
168 static void ath9k_htc_set_opmode(struct ath9k_htc_priv *priv)
170 if (priv->num_ibss_vif)
171 priv->ah->opmode = NL80211_IFTYPE_ADHOC;
172 else if (priv->num_ap_vif)
173 priv->ah->opmode = NL80211_IFTYPE_AP;
174 else
175 priv->ah->opmode = NL80211_IFTYPE_STATION;
177 ath9k_hw_setopmode(priv->ah);
180 void ath9k_htc_reset(struct ath9k_htc_priv *priv)
182 struct ath_hw *ah = priv->ah;
183 struct ath_common *common = ath9k_hw_common(ah);
184 struct ieee80211_channel *channel = priv->hw->conf.channel;
185 struct ath9k_hw_cal_data *caldata = NULL;
186 enum htc_phymode mode;
187 __be16 htc_mode;
188 u8 cmd_rsp;
189 int ret;
191 mutex_lock(&priv->mutex);
192 ath9k_htc_ps_wakeup(priv);
194 ath9k_htc_stop_ani(priv);
195 ieee80211_stop_queues(priv->hw);
197 del_timer_sync(&priv->tx.cleanup_timer);
198 ath9k_htc_tx_drain(priv);
200 WMI_CMD(WMI_DISABLE_INTR_CMDID);
201 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
202 WMI_CMD(WMI_STOP_RECV_CMDID);
204 ath9k_wmi_event_drain(priv);
206 caldata = &priv->caldata;
207 ret = ath9k_hw_reset(ah, ah->curchan, caldata, false);
208 if (ret) {
209 ath_err(common,
210 "Unable to reset device (%u Mhz) reset status %d\n",
211 channel->center_freq, ret);
214 ath9k_cmn_update_txpow(ah, priv->curtxpow, priv->txpowlimit,
215 &priv->curtxpow);
217 WMI_CMD(WMI_START_RECV_CMDID);
218 ath9k_host_rx_init(priv);
220 mode = ath9k_htc_get_curmode(priv, ah->curchan);
221 htc_mode = cpu_to_be16(mode);
222 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
224 WMI_CMD(WMI_ENABLE_INTR_CMDID);
225 htc_start(priv->htc);
226 ath9k_htc_vif_reconfig(priv);
227 ieee80211_wake_queues(priv->hw);
229 mod_timer(&priv->tx.cleanup_timer,
230 jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
232 ath9k_htc_ps_restore(priv);
233 mutex_unlock(&priv->mutex);
236 static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
237 struct ieee80211_hw *hw,
238 struct ath9k_channel *hchan)
240 struct ath_hw *ah = priv->ah;
241 struct ath_common *common = ath9k_hw_common(ah);
242 struct ieee80211_conf *conf = &common->hw->conf;
243 bool fastcc;
244 struct ieee80211_channel *channel = hw->conf.channel;
245 struct ath9k_hw_cal_data *caldata = NULL;
246 enum htc_phymode mode;
247 __be16 htc_mode;
248 u8 cmd_rsp;
249 int ret;
251 if (priv->op_flags & OP_INVALID)
252 return -EIO;
254 fastcc = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL);
256 ath9k_htc_ps_wakeup(priv);
258 del_timer_sync(&priv->tx.cleanup_timer);
259 ath9k_htc_tx_drain(priv);
261 WMI_CMD(WMI_DISABLE_INTR_CMDID);
262 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
263 WMI_CMD(WMI_STOP_RECV_CMDID);
265 ath9k_wmi_event_drain(priv);
267 ath_dbg(common, ATH_DBG_CONFIG,
268 "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n",
269 priv->ah->curchan->channel,
270 channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf),
271 fastcc);
273 if (!fastcc)
274 caldata = &priv->caldata;
276 ret = ath9k_hw_reset(ah, hchan, caldata, fastcc);
277 if (ret) {
278 ath_err(common,
279 "Unable to reset channel (%u Mhz) reset status %d\n",
280 channel->center_freq, ret);
281 goto err;
284 ath9k_cmn_update_txpow(ah, priv->curtxpow, priv->txpowlimit,
285 &priv->curtxpow);
287 WMI_CMD(WMI_START_RECV_CMDID);
288 if (ret)
289 goto err;
291 ath9k_host_rx_init(priv);
293 mode = ath9k_htc_get_curmode(priv, hchan);
294 htc_mode = cpu_to_be16(mode);
295 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
296 if (ret)
297 goto err;
299 WMI_CMD(WMI_ENABLE_INTR_CMDID);
300 if (ret)
301 goto err;
303 htc_start(priv->htc);
305 if (!(priv->op_flags & OP_SCANNING) &&
306 !(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL))
307 ath9k_htc_vif_reconfig(priv);
309 mod_timer(&priv->tx.cleanup_timer,
310 jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
312 err:
313 ath9k_htc_ps_restore(priv);
314 return ret;
318 * Monitor mode handling is a tad complicated because the firmware requires
319 * an interface to be created exclusively, while mac80211 doesn't associate
320 * an interface with the mode.
322 * So, for now, only one monitor interface can be configured.
324 static void __ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
326 struct ath_common *common = ath9k_hw_common(priv->ah);
327 struct ath9k_htc_target_vif hvif;
328 int ret = 0;
329 u8 cmd_rsp;
331 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
332 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
333 hvif.index = priv->mon_vif_idx;
334 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
335 if (ret) {
336 ath_err(common, "Unable to remove monitor interface at idx: %d\n",
337 priv->mon_vif_idx);
340 priv->nvifs--;
341 priv->vif_slot &= ~(1 << priv->mon_vif_idx);
344 static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
346 struct ath_common *common = ath9k_hw_common(priv->ah);
347 struct ath9k_htc_target_vif hvif;
348 struct ath9k_htc_target_sta tsta;
349 int ret = 0, sta_idx;
350 u8 cmd_rsp;
352 if ((priv->nvifs >= ATH9K_HTC_MAX_VIF) ||
353 (priv->nstations >= ATH9K_HTC_MAX_STA)) {
354 ret = -ENOBUFS;
355 goto err_vif;
358 sta_idx = ffz(priv->sta_slot);
359 if ((sta_idx < 0) || (sta_idx > ATH9K_HTC_MAX_STA)) {
360 ret = -ENOBUFS;
361 goto err_vif;
365 * Add an interface.
367 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
368 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
370 hvif.opmode = HTC_M_MONITOR;
371 hvif.index = ffz(priv->vif_slot);
373 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
374 if (ret)
375 goto err_vif;
378 * Assign the monitor interface index as a special case here.
379 * This is needed when the interface is brought down.
381 priv->mon_vif_idx = hvif.index;
382 priv->vif_slot |= (1 << hvif.index);
385 * Set the hardware mode to monitor only if there are no
386 * other interfaces.
388 if (!priv->nvifs)
389 priv->ah->opmode = NL80211_IFTYPE_MONITOR;
391 priv->nvifs++;
394 * Associate a station with the interface for packet injection.
396 memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta));
398 memcpy(&tsta.macaddr, common->macaddr, ETH_ALEN);
400 tsta.is_vif_sta = 1;
401 tsta.sta_index = sta_idx;
402 tsta.vif_index = hvif.index;
403 tsta.maxampdu = cpu_to_be16(0xffff);
405 WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
406 if (ret) {
407 ath_err(common, "Unable to add station entry for monitor mode\n");
408 goto err_sta;
411 priv->sta_slot |= (1 << sta_idx);
412 priv->nstations++;
413 priv->vif_sta_pos[priv->mon_vif_idx] = sta_idx;
414 priv->ah->is_monitoring = true;
416 ath_dbg(common, ATH_DBG_CONFIG,
417 "Attached a monitor interface at idx: %d, sta idx: %d\n",
418 priv->mon_vif_idx, sta_idx);
420 return 0;
422 err_sta:
424 * Remove the interface from the target.
426 __ath9k_htc_remove_monitor_interface(priv);
427 err_vif:
428 ath_dbg(common, ATH_DBG_FATAL, "Unable to attach a monitor interface\n");
430 return ret;
433 static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
435 struct ath_common *common = ath9k_hw_common(priv->ah);
436 int ret = 0;
437 u8 cmd_rsp, sta_idx;
439 __ath9k_htc_remove_monitor_interface(priv);
441 sta_idx = priv->vif_sta_pos[priv->mon_vif_idx];
443 WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx);
444 if (ret) {
445 ath_err(common, "Unable to remove station entry for monitor mode\n");
446 return ret;
449 priv->sta_slot &= ~(1 << sta_idx);
450 priv->nstations--;
451 priv->ah->is_monitoring = false;
453 ath_dbg(common, ATH_DBG_CONFIG,
454 "Removed a monitor interface at idx: %d, sta idx: %d\n",
455 priv->mon_vif_idx, sta_idx);
457 return 0;
460 static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
461 struct ieee80211_vif *vif,
462 struct ieee80211_sta *sta)
464 struct ath_common *common = ath9k_hw_common(priv->ah);
465 struct ath9k_htc_target_sta tsta;
466 struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
467 struct ath9k_htc_sta *ista;
468 int ret, sta_idx;
469 u8 cmd_rsp;
470 u16 maxampdu;
472 if (priv->nstations >= ATH9K_HTC_MAX_STA)
473 return -ENOBUFS;
475 sta_idx = ffz(priv->sta_slot);
476 if ((sta_idx < 0) || (sta_idx > ATH9K_HTC_MAX_STA))
477 return -ENOBUFS;
479 memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta));
481 if (sta) {
482 ista = (struct ath9k_htc_sta *) sta->drv_priv;
483 memcpy(&tsta.macaddr, sta->addr, ETH_ALEN);
484 memcpy(&tsta.bssid, common->curbssid, ETH_ALEN);
485 tsta.is_vif_sta = 0;
486 ista->index = sta_idx;
487 } else {
488 memcpy(&tsta.macaddr, vif->addr, ETH_ALEN);
489 tsta.is_vif_sta = 1;
492 tsta.sta_index = sta_idx;
493 tsta.vif_index = avp->index;
495 if (!sta) {
496 tsta.maxampdu = cpu_to_be16(0xffff);
497 } else {
498 maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
499 sta->ht_cap.ampdu_factor);
500 tsta.maxampdu = cpu_to_be16(maxampdu);
503 if (sta && sta->ht_cap.ht_supported)
504 tsta.flags = cpu_to_be16(ATH_HTC_STA_HT);
506 WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
507 if (ret) {
508 if (sta)
509 ath_err(common,
510 "Unable to add station entry for: %pM\n",
511 sta->addr);
512 return ret;
515 if (sta) {
516 ath_dbg(common, ATH_DBG_CONFIG,
517 "Added a station entry for: %pM (idx: %d)\n",
518 sta->addr, tsta.sta_index);
519 } else {
520 ath_dbg(common, ATH_DBG_CONFIG,
521 "Added a station entry for VIF %d (idx: %d)\n",
522 avp->index, tsta.sta_index);
525 priv->sta_slot |= (1 << sta_idx);
526 priv->nstations++;
527 if (!sta)
528 priv->vif_sta_pos[avp->index] = sta_idx;
530 return 0;
533 static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
534 struct ieee80211_vif *vif,
535 struct ieee80211_sta *sta)
537 struct ath_common *common = ath9k_hw_common(priv->ah);
538 struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
539 struct ath9k_htc_sta *ista;
540 int ret;
541 u8 cmd_rsp, sta_idx;
543 if (sta) {
544 ista = (struct ath9k_htc_sta *) sta->drv_priv;
545 sta_idx = ista->index;
546 } else {
547 sta_idx = priv->vif_sta_pos[avp->index];
550 WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx);
551 if (ret) {
552 if (sta)
553 ath_err(common,
554 "Unable to remove station entry for: %pM\n",
555 sta->addr);
556 return ret;
559 if (sta) {
560 ath_dbg(common, ATH_DBG_CONFIG,
561 "Removed a station entry for: %pM (idx: %d)\n",
562 sta->addr, sta_idx);
563 } else {
564 ath_dbg(common, ATH_DBG_CONFIG,
565 "Removed a station entry for VIF %d (idx: %d)\n",
566 avp->index, sta_idx);
569 priv->sta_slot &= ~(1 << sta_idx);
570 priv->nstations--;
572 return 0;
575 int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv,
576 u8 enable_coex)
578 struct ath9k_htc_cap_target tcap;
579 int ret;
580 u8 cmd_rsp;
582 memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target));
584 tcap.ampdu_limit = cpu_to_be32(0xffff);
585 tcap.ampdu_subframes = priv->hw->max_tx_aggregation_subframes;
586 tcap.enable_coex = enable_coex;
587 tcap.tx_chainmask = priv->ah->caps.tx_chainmask;
589 WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap);
591 return ret;
594 static void ath9k_htc_setup_rate(struct ath9k_htc_priv *priv,
595 struct ieee80211_sta *sta,
596 struct ath9k_htc_target_rate *trate)
598 struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
599 struct ieee80211_supported_band *sband;
600 u32 caps = 0;
601 int i, j;
603 sband = priv->hw->wiphy->bands[priv->hw->conf.channel->band];
605 for (i = 0, j = 0; i < sband->n_bitrates; i++) {
606 if (sta->supp_rates[sband->band] & BIT(i)) {
607 trate->rates.legacy_rates.rs_rates[j]
608 = (sband->bitrates[i].bitrate * 2) / 10;
609 j++;
612 trate->rates.legacy_rates.rs_nrates = j;
614 if (sta->ht_cap.ht_supported) {
615 for (i = 0, j = 0; i < 77; i++) {
616 if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8)))
617 trate->rates.ht_rates.rs_rates[j++] = i;
618 if (j == ATH_HTC_RATE_MAX)
619 break;
621 trate->rates.ht_rates.rs_nrates = j;
623 caps = WLAN_RC_HT_FLAG;
624 if (sta->ht_cap.mcs.rx_mask[1])
625 caps |= WLAN_RC_DS_FLAG;
626 if ((sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
627 (conf_is_ht40(&priv->hw->conf)))
628 caps |= WLAN_RC_40_FLAG;
629 if (conf_is_ht40(&priv->hw->conf) &&
630 (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40))
631 caps |= WLAN_RC_SGI_FLAG;
632 else if (conf_is_ht20(&priv->hw->conf) &&
633 (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20))
634 caps |= WLAN_RC_SGI_FLAG;
637 trate->sta_index = ista->index;
638 trate->isnew = 1;
639 trate->capflags = cpu_to_be32(caps);
642 static int ath9k_htc_send_rate_cmd(struct ath9k_htc_priv *priv,
643 struct ath9k_htc_target_rate *trate)
645 struct ath_common *common = ath9k_hw_common(priv->ah);
646 int ret;
647 u8 cmd_rsp;
649 WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, trate);
650 if (ret) {
651 ath_err(common,
652 "Unable to initialize Rate information on target\n");
655 return ret;
658 static void ath9k_htc_init_rate(struct ath9k_htc_priv *priv,
659 struct ieee80211_sta *sta)
661 struct ath_common *common = ath9k_hw_common(priv->ah);
662 struct ath9k_htc_target_rate trate;
663 int ret;
665 memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
666 ath9k_htc_setup_rate(priv, sta, &trate);
667 ret = ath9k_htc_send_rate_cmd(priv, &trate);
668 if (!ret)
669 ath_dbg(common, ATH_DBG_CONFIG,
670 "Updated target sta: %pM, rate caps: 0x%X\n",
671 sta->addr, be32_to_cpu(trate.capflags));
674 static void ath9k_htc_update_rate(struct ath9k_htc_priv *priv,
675 struct ieee80211_vif *vif,
676 struct ieee80211_bss_conf *bss_conf)
678 struct ath_common *common = ath9k_hw_common(priv->ah);
679 struct ath9k_htc_target_rate trate;
680 struct ieee80211_sta *sta;
681 int ret;
683 memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
685 rcu_read_lock();
686 sta = ieee80211_find_sta(vif, bss_conf->bssid);
687 if (!sta) {
688 rcu_read_unlock();
689 return;
691 ath9k_htc_setup_rate(priv, sta, &trate);
692 rcu_read_unlock();
694 ret = ath9k_htc_send_rate_cmd(priv, &trate);
695 if (!ret)
696 ath_dbg(common, ATH_DBG_CONFIG,
697 "Updated target sta: %pM, rate caps: 0x%X\n",
698 bss_conf->bssid, be32_to_cpu(trate.capflags));
701 static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv,
702 struct ieee80211_vif *vif,
703 struct ieee80211_sta *sta,
704 enum ieee80211_ampdu_mlme_action action,
705 u16 tid)
707 struct ath_common *common = ath9k_hw_common(priv->ah);
708 struct ath9k_htc_target_aggr aggr;
709 struct ath9k_htc_sta *ista;
710 int ret = 0;
711 u8 cmd_rsp;
713 if (tid >= ATH9K_HTC_MAX_TID)
714 return -EINVAL;
716 memset(&aggr, 0, sizeof(struct ath9k_htc_target_aggr));
717 ista = (struct ath9k_htc_sta *) sta->drv_priv;
719 aggr.sta_index = ista->index;
720 aggr.tidno = tid & 0xf;
721 aggr.aggr_enable = (action == IEEE80211_AMPDU_TX_START) ? true : false;
723 WMI_CMD_BUF(WMI_TX_AGGR_ENABLE_CMDID, &aggr);
724 if (ret)
725 ath_dbg(common, ATH_DBG_CONFIG,
726 "Unable to %s TX aggregation for (%pM, %d)\n",
727 (aggr.aggr_enable) ? "start" : "stop", sta->addr, tid);
728 else
729 ath_dbg(common, ATH_DBG_CONFIG,
730 "%s TX aggregation for (%pM, %d)\n",
731 (aggr.aggr_enable) ? "Starting" : "Stopping",
732 sta->addr, tid);
734 spin_lock_bh(&priv->tx.tx_lock);
735 ista->tid_state[tid] = (aggr.aggr_enable && !ret) ? AGGR_START : AGGR_STOP;
736 spin_unlock_bh(&priv->tx.tx_lock);
738 return ret;
741 /*******/
742 /* ANI */
743 /*******/
745 void ath9k_htc_start_ani(struct ath9k_htc_priv *priv)
747 struct ath_common *common = ath9k_hw_common(priv->ah);
748 unsigned long timestamp = jiffies_to_msecs(jiffies);
750 common->ani.longcal_timer = timestamp;
751 common->ani.shortcal_timer = timestamp;
752 common->ani.checkani_timer = timestamp;
754 priv->op_flags |= OP_ANI_RUNNING;
756 ieee80211_queue_delayed_work(common->hw, &priv->ani_work,
757 msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
760 void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv)
762 cancel_delayed_work_sync(&priv->ani_work);
763 priv->op_flags &= ~OP_ANI_RUNNING;
766 void ath9k_htc_ani_work(struct work_struct *work)
768 struct ath9k_htc_priv *priv =
769 container_of(work, struct ath9k_htc_priv, ani_work.work);
770 struct ath_hw *ah = priv->ah;
771 struct ath_common *common = ath9k_hw_common(ah);
772 bool longcal = false;
773 bool shortcal = false;
774 bool aniflag = false;
775 unsigned int timestamp = jiffies_to_msecs(jiffies);
776 u32 cal_interval, short_cal_interval;
778 short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ?
779 ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL;
781 /* Only calibrate if awake */
782 if (ah->power_mode != ATH9K_PM_AWAKE)
783 goto set_timer;
785 /* Long calibration runs independently of short calibration. */
786 if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
787 longcal = true;
788 ath_dbg(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
789 common->ani.longcal_timer = timestamp;
792 /* Short calibration applies only while caldone is false */
793 if (!common->ani.caldone) {
794 if ((timestamp - common->ani.shortcal_timer) >=
795 short_cal_interval) {
796 shortcal = true;
797 ath_dbg(common, ATH_DBG_ANI,
798 "shortcal @%lu\n", jiffies);
799 common->ani.shortcal_timer = timestamp;
800 common->ani.resetcal_timer = timestamp;
802 } else {
803 if ((timestamp - common->ani.resetcal_timer) >=
804 ATH_RESTART_CALINTERVAL) {
805 common->ani.caldone = ath9k_hw_reset_calvalid(ah);
806 if (common->ani.caldone)
807 common->ani.resetcal_timer = timestamp;
811 /* Verify whether we must check ANI */
812 if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
813 aniflag = true;
814 common->ani.checkani_timer = timestamp;
817 /* Skip all processing if there's nothing to do. */
818 if (longcal || shortcal || aniflag) {
820 ath9k_htc_ps_wakeup(priv);
822 /* Call ANI routine if necessary */
823 if (aniflag)
824 ath9k_hw_ani_monitor(ah, ah->curchan);
826 /* Perform calibration if necessary */
827 if (longcal || shortcal)
828 common->ani.caldone =
829 ath9k_hw_calibrate(ah, ah->curchan,
830 common->rx_chainmask,
831 longcal);
833 ath9k_htc_ps_restore(priv);
836 set_timer:
838 * Set timer interval based on previous results.
839 * The interval must be the shortest necessary to satisfy ANI,
840 * short calibration and long calibration.
842 cal_interval = ATH_LONG_CALINTERVAL;
843 if (priv->ah->config.enable_ani)
844 cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
845 if (!common->ani.caldone)
846 cal_interval = min(cal_interval, (u32)short_cal_interval);
848 ieee80211_queue_delayed_work(common->hw, &priv->ani_work,
849 msecs_to_jiffies(cal_interval));
852 /**********************/
853 /* mac80211 Callbacks */
854 /**********************/
856 static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
858 struct ieee80211_hdr *hdr;
859 struct ath9k_htc_priv *priv = hw->priv;
860 struct ath_common *common = ath9k_hw_common(priv->ah);
861 int padpos, padsize, ret, slot;
863 hdr = (struct ieee80211_hdr *) skb->data;
865 /* Add the padding after the header if this is not already done */
866 padpos = ath9k_cmn_padpos(hdr->frame_control);
867 padsize = padpos & 3;
868 if (padsize && skb->len > padpos) {
869 if (skb_headroom(skb) < padsize) {
870 ath_dbg(common, ATH_DBG_XMIT, "No room for padding\n");
871 goto fail_tx;
873 skb_push(skb, padsize);
874 memmove(skb->data, skb->data + padsize, padpos);
877 slot = ath9k_htc_tx_get_slot(priv);
878 if (slot < 0) {
879 ath_dbg(common, ATH_DBG_XMIT, "No free TX slot\n");
880 goto fail_tx;
883 ret = ath9k_htc_tx_start(priv, skb, slot, false);
884 if (ret != 0) {
885 ath_dbg(common, ATH_DBG_XMIT, "Tx failed\n");
886 goto clear_slot;
889 ath9k_htc_check_stop_queues(priv);
891 return;
893 clear_slot:
894 ath9k_htc_tx_clear_slot(priv, slot);
895 fail_tx:
896 dev_kfree_skb_any(skb);
899 static int ath9k_htc_start(struct ieee80211_hw *hw)
901 struct ath9k_htc_priv *priv = hw->priv;
902 struct ath_hw *ah = priv->ah;
903 struct ath_common *common = ath9k_hw_common(ah);
904 struct ieee80211_channel *curchan = hw->conf.channel;
905 struct ath9k_channel *init_channel;
906 int ret = 0;
907 enum htc_phymode mode;
908 __be16 htc_mode;
909 u8 cmd_rsp;
911 mutex_lock(&priv->mutex);
913 ath_dbg(common, ATH_DBG_CONFIG,
914 "Starting driver with initial channel: %d MHz\n",
915 curchan->center_freq);
917 /* Ensure that HW is awake before flushing RX */
918 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
919 WMI_CMD(WMI_FLUSH_RECV_CMDID);
921 /* setup initial channel */
922 init_channel = ath9k_cmn_get_curchannel(hw, ah);
924 ath9k_hw_htc_resetinit(ah);
925 ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
926 if (ret) {
927 ath_err(common,
928 "Unable to reset hardware; reset status %d (freq %u MHz)\n",
929 ret, curchan->center_freq);
930 mutex_unlock(&priv->mutex);
931 return ret;
934 ath9k_cmn_update_txpow(ah, priv->curtxpow, priv->txpowlimit,
935 &priv->curtxpow);
937 mode = ath9k_htc_get_curmode(priv, init_channel);
938 htc_mode = cpu_to_be16(mode);
939 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
940 WMI_CMD(WMI_ATH_INIT_CMDID);
941 WMI_CMD(WMI_START_RECV_CMDID);
943 ath9k_host_rx_init(priv);
945 ret = ath9k_htc_update_cap_target(priv, 0);
946 if (ret)
947 ath_dbg(common, ATH_DBG_CONFIG,
948 "Failed to update capability in target\n");
950 priv->op_flags &= ~OP_INVALID;
951 htc_start(priv->htc);
953 spin_lock_bh(&priv->tx.tx_lock);
954 priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP;
955 spin_unlock_bh(&priv->tx.tx_lock);
957 ieee80211_wake_queues(hw);
959 mod_timer(&priv->tx.cleanup_timer,
960 jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
962 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) {
963 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
964 AR_STOMP_LOW_WLAN_WGHT);
965 ath9k_hw_btcoex_enable(ah);
966 ath_htc_resume_btcoex_work(priv);
968 mutex_unlock(&priv->mutex);
970 return ret;
973 static void ath9k_htc_stop(struct ieee80211_hw *hw)
975 struct ath9k_htc_priv *priv = hw->priv;
976 struct ath_hw *ah = priv->ah;
977 struct ath_common *common = ath9k_hw_common(ah);
978 int ret __attribute__ ((unused));
979 u8 cmd_rsp;
981 mutex_lock(&priv->mutex);
983 if (priv->op_flags & OP_INVALID) {
984 ath_dbg(common, ATH_DBG_ANY, "Device not present\n");
985 mutex_unlock(&priv->mutex);
986 return;
989 ath9k_htc_ps_wakeup(priv);
991 WMI_CMD(WMI_DISABLE_INTR_CMDID);
992 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
993 WMI_CMD(WMI_STOP_RECV_CMDID);
995 tasklet_kill(&priv->rx_tasklet);
997 del_timer_sync(&priv->tx.cleanup_timer);
998 ath9k_htc_tx_drain(priv);
999 ath9k_wmi_event_drain(priv);
1001 mutex_unlock(&priv->mutex);
1003 /* Cancel all the running timers/work .. */
1004 cancel_work_sync(&priv->fatal_work);
1005 cancel_work_sync(&priv->ps_work);
1006 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
1007 ath9k_htc_stop_ani(priv);
1008 ath9k_led_stop_brightness(priv);
1010 mutex_lock(&priv->mutex);
1012 if (ah->btcoex_hw.enabled) {
1013 ath9k_hw_btcoex_disable(ah);
1014 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
1015 ath_htc_cancel_btcoex_work(priv);
1018 /* Remove a monitor interface if it's present. */
1019 if (priv->ah->is_monitoring)
1020 ath9k_htc_remove_monitor_interface(priv);
1022 ath9k_hw_phy_disable(ah);
1023 ath9k_hw_disable(ah);
1024 ath9k_htc_ps_restore(priv);
1025 ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
1027 priv->op_flags |= OP_INVALID;
1029 ath_dbg(common, ATH_DBG_CONFIG, "Driver halt\n");
1030 mutex_unlock(&priv->mutex);
1033 static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1034 struct ieee80211_vif *vif)
1036 struct ath9k_htc_priv *priv = hw->priv;
1037 struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1038 struct ath_common *common = ath9k_hw_common(priv->ah);
1039 struct ath9k_htc_target_vif hvif;
1040 int ret = 0;
1041 u8 cmd_rsp;
1043 mutex_lock(&priv->mutex);
1045 if (priv->nvifs >= ATH9K_HTC_MAX_VIF) {
1046 mutex_unlock(&priv->mutex);
1047 return -ENOBUFS;
1050 if (priv->num_ibss_vif ||
1051 (priv->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) {
1052 ath_err(common, "IBSS coexistence with other modes is not allowed\n");
1053 mutex_unlock(&priv->mutex);
1054 return -ENOBUFS;
1057 if (((vif->type == NL80211_IFTYPE_AP) ||
1058 (vif->type == NL80211_IFTYPE_ADHOC)) &&
1059 ((priv->num_ap_vif + priv->num_ibss_vif) >= ATH9K_HTC_MAX_BCN_VIF)) {
1060 ath_err(common, "Max. number of beaconing interfaces reached\n");
1061 mutex_unlock(&priv->mutex);
1062 return -ENOBUFS;
1065 ath9k_htc_ps_wakeup(priv);
1066 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
1067 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
1069 switch (vif->type) {
1070 case NL80211_IFTYPE_STATION:
1071 hvif.opmode = HTC_M_STA;
1072 break;
1073 case NL80211_IFTYPE_ADHOC:
1074 hvif.opmode = HTC_M_IBSS;
1075 break;
1076 case NL80211_IFTYPE_AP:
1077 hvif.opmode = HTC_M_HOSTAP;
1078 break;
1079 default:
1080 ath_err(common,
1081 "Interface type %d not yet supported\n", vif->type);
1082 ret = -EOPNOTSUPP;
1083 goto out;
1086 /* Index starts from zero on the target */
1087 avp->index = hvif.index = ffz(priv->vif_slot);
1088 hvif.rtsthreshold = cpu_to_be16(2304);
1089 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
1090 if (ret)
1091 goto out;
1094 * We need a node in target to tx mgmt frames
1095 * before association.
1097 ret = ath9k_htc_add_station(priv, vif, NULL);
1098 if (ret) {
1099 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
1100 goto out;
1103 ath9k_htc_set_bssid_mask(priv, vif);
1105 priv->vif_slot |= (1 << avp->index);
1106 priv->nvifs++;
1108 INC_VIF(priv, vif->type);
1110 if ((vif->type == NL80211_IFTYPE_AP) ||
1111 (vif->type == NL80211_IFTYPE_ADHOC))
1112 ath9k_htc_assign_bslot(priv, vif);
1114 ath9k_htc_set_opmode(priv);
1116 if ((priv->ah->opmode == NL80211_IFTYPE_AP) &&
1117 !(priv->op_flags & OP_ANI_RUNNING)) {
1118 ath9k_hw_set_tsfadjust(priv->ah, 1);
1119 ath9k_htc_start_ani(priv);
1122 ath_dbg(common, ATH_DBG_CONFIG,
1123 "Attach a VIF of type: %d at idx: %d\n", vif->type, avp->index);
1125 out:
1126 ath9k_htc_ps_restore(priv);
1127 mutex_unlock(&priv->mutex);
1129 return ret;
1132 static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
1133 struct ieee80211_vif *vif)
1135 struct ath9k_htc_priv *priv = hw->priv;
1136 struct ath_common *common = ath9k_hw_common(priv->ah);
1137 struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1138 struct ath9k_htc_target_vif hvif;
1139 int ret = 0;
1140 u8 cmd_rsp;
1142 mutex_lock(&priv->mutex);
1143 ath9k_htc_ps_wakeup(priv);
1145 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
1146 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
1147 hvif.index = avp->index;
1148 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
1149 if (ret) {
1150 ath_err(common, "Unable to remove interface at idx: %d\n",
1151 avp->index);
1153 priv->nvifs--;
1154 priv->vif_slot &= ~(1 << avp->index);
1156 ath9k_htc_remove_station(priv, vif, NULL);
1158 DEC_VIF(priv, vif->type);
1160 if ((vif->type == NL80211_IFTYPE_AP) ||
1161 (vif->type == NL80211_IFTYPE_ADHOC))
1162 ath9k_htc_remove_bslot(priv, vif);
1164 ath9k_htc_set_opmode(priv);
1167 * Stop ANI only if there are no associated station interfaces.
1169 if ((vif->type == NL80211_IFTYPE_AP) && (priv->num_ap_vif == 0)) {
1170 priv->rearm_ani = false;
1171 ieee80211_iterate_active_interfaces_atomic(priv->hw,
1172 ath9k_htc_vif_iter, priv);
1173 if (!priv->rearm_ani)
1174 ath9k_htc_stop_ani(priv);
1177 ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface at idx: %d\n", avp->index);
1179 ath9k_htc_ps_restore(priv);
1180 mutex_unlock(&priv->mutex);
1183 static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
1185 struct ath9k_htc_priv *priv = hw->priv;
1186 struct ath_common *common = ath9k_hw_common(priv->ah);
1187 struct ieee80211_conf *conf = &hw->conf;
1189 mutex_lock(&priv->mutex);
1191 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1192 bool enable_radio = false;
1193 bool idle = !!(conf->flags & IEEE80211_CONF_IDLE);
1195 mutex_lock(&priv->htc_pm_lock);
1196 if (!idle && priv->ps_idle)
1197 enable_radio = true;
1198 priv->ps_idle = idle;
1199 mutex_unlock(&priv->htc_pm_lock);
1201 if (enable_radio) {
1202 ath_dbg(common, ATH_DBG_CONFIG,
1203 "not-idle: enabling radio\n");
1204 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
1205 ath9k_htc_radio_enable(hw);
1210 * Monitor interface should be added before
1211 * IEEE80211_CONF_CHANGE_CHANNEL is handled.
1213 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
1214 if ((conf->flags & IEEE80211_CONF_MONITOR) &&
1215 !priv->ah->is_monitoring)
1216 ath9k_htc_add_monitor_interface(priv);
1217 else if (priv->ah->is_monitoring)
1218 ath9k_htc_remove_monitor_interface(priv);
1221 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1222 struct ieee80211_channel *curchan = hw->conf.channel;
1223 int pos = curchan->hw_value;
1225 ath_dbg(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
1226 curchan->center_freq);
1228 ath9k_cmn_update_ichannel(&priv->ah->channels[pos],
1229 hw->conf.channel,
1230 hw->conf.channel_type);
1232 if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) {
1233 ath_err(common, "Unable to set channel\n");
1234 mutex_unlock(&priv->mutex);
1235 return -EINVAL;
1240 if (changed & IEEE80211_CONF_CHANGE_PS) {
1241 if (conf->flags & IEEE80211_CONF_PS) {
1242 ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP);
1243 priv->ps_enabled = true;
1244 } else {
1245 priv->ps_enabled = false;
1246 cancel_work_sync(&priv->ps_work);
1247 ath9k_htc_setpower(priv, ATH9K_PM_AWAKE);
1251 if (changed & IEEE80211_CONF_CHANGE_POWER) {
1252 priv->txpowlimit = 2 * conf->power_level;
1253 ath9k_cmn_update_txpow(priv->ah, priv->curtxpow,
1254 priv->txpowlimit, &priv->curtxpow);
1257 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
1258 mutex_lock(&priv->htc_pm_lock);
1259 if (!priv->ps_idle) {
1260 mutex_unlock(&priv->htc_pm_lock);
1261 goto out;
1263 mutex_unlock(&priv->htc_pm_lock);
1265 ath_dbg(common, ATH_DBG_CONFIG,
1266 "idle: disabling radio\n");
1267 ath9k_htc_radio_disable(hw);
1270 out:
1271 mutex_unlock(&priv->mutex);
1272 return 0;
1275 #define SUPPORTED_FILTERS \
1276 (FIF_PROMISC_IN_BSS | \
1277 FIF_ALLMULTI | \
1278 FIF_CONTROL | \
1279 FIF_PSPOLL | \
1280 FIF_OTHER_BSS | \
1281 FIF_BCN_PRBRESP_PROMISC | \
1282 FIF_PROBE_REQ | \
1283 FIF_FCSFAIL)
1285 static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
1286 unsigned int changed_flags,
1287 unsigned int *total_flags,
1288 u64 multicast)
1290 struct ath9k_htc_priv *priv = hw->priv;
1291 u32 rfilt;
1293 mutex_lock(&priv->mutex);
1294 ath9k_htc_ps_wakeup(priv);
1296 changed_flags &= SUPPORTED_FILTERS;
1297 *total_flags &= SUPPORTED_FILTERS;
1299 priv->rxfilter = *total_flags;
1300 rfilt = ath9k_htc_calcrxfilter(priv);
1301 ath9k_hw_setrxfilter(priv->ah, rfilt);
1303 ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_CONFIG,
1304 "Set HW RX filter: 0x%x\n", rfilt);
1306 ath9k_htc_ps_restore(priv);
1307 mutex_unlock(&priv->mutex);
1310 static int ath9k_htc_sta_add(struct ieee80211_hw *hw,
1311 struct ieee80211_vif *vif,
1312 struct ieee80211_sta *sta)
1314 struct ath9k_htc_priv *priv = hw->priv;
1315 int ret;
1317 mutex_lock(&priv->mutex);
1318 ath9k_htc_ps_wakeup(priv);
1319 ret = ath9k_htc_add_station(priv, vif, sta);
1320 if (!ret)
1321 ath9k_htc_init_rate(priv, sta);
1322 ath9k_htc_ps_restore(priv);
1323 mutex_unlock(&priv->mutex);
1325 return ret;
1328 static int ath9k_htc_sta_remove(struct ieee80211_hw *hw,
1329 struct ieee80211_vif *vif,
1330 struct ieee80211_sta *sta)
1332 struct ath9k_htc_priv *priv = hw->priv;
1333 struct ath9k_htc_sta *ista;
1334 int ret;
1336 mutex_lock(&priv->mutex);
1337 ath9k_htc_ps_wakeup(priv);
1338 ista = (struct ath9k_htc_sta *) sta->drv_priv;
1339 htc_sta_drain(priv->htc, ista->index);
1340 ret = ath9k_htc_remove_station(priv, vif, sta);
1341 ath9k_htc_ps_restore(priv);
1342 mutex_unlock(&priv->mutex);
1344 return ret;
1347 static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, u16 queue,
1348 const struct ieee80211_tx_queue_params *params)
1350 struct ath9k_htc_priv *priv = hw->priv;
1351 struct ath_common *common = ath9k_hw_common(priv->ah);
1352 struct ath9k_tx_queue_info qi;
1353 int ret = 0, qnum;
1355 if (queue >= WME_NUM_AC)
1356 return 0;
1358 mutex_lock(&priv->mutex);
1359 ath9k_htc_ps_wakeup(priv);
1361 memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
1363 qi.tqi_aifs = params->aifs;
1364 qi.tqi_cwmin = params->cw_min;
1365 qi.tqi_cwmax = params->cw_max;
1366 qi.tqi_burstTime = params->txop;
1368 qnum = get_hw_qnum(queue, priv->hwq_map);
1370 ath_dbg(common, ATH_DBG_CONFIG,
1371 "Configure tx [queue/hwq] [%d/%d], aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
1372 queue, qnum, params->aifs, params->cw_min,
1373 params->cw_max, params->txop);
1375 ret = ath_htc_txq_update(priv, qnum, &qi);
1376 if (ret) {
1377 ath_err(common, "TXQ Update failed\n");
1378 goto out;
1381 if ((priv->ah->opmode == NL80211_IFTYPE_ADHOC) &&
1382 (qnum == priv->hwq_map[WME_AC_BE]))
1383 ath9k_htc_beaconq_config(priv);
1384 out:
1385 ath9k_htc_ps_restore(priv);
1386 mutex_unlock(&priv->mutex);
1388 return ret;
1391 static int ath9k_htc_set_key(struct ieee80211_hw *hw,
1392 enum set_key_cmd cmd,
1393 struct ieee80211_vif *vif,
1394 struct ieee80211_sta *sta,
1395 struct ieee80211_key_conf *key)
1397 struct ath9k_htc_priv *priv = hw->priv;
1398 struct ath_common *common = ath9k_hw_common(priv->ah);
1399 int ret = 0;
1401 if (htc_modparam_nohwcrypt)
1402 return -ENOSPC;
1404 mutex_lock(&priv->mutex);
1405 ath_dbg(common, ATH_DBG_CONFIG, "Set HW Key\n");
1406 ath9k_htc_ps_wakeup(priv);
1408 switch (cmd) {
1409 case SET_KEY:
1410 ret = ath_key_config(common, vif, sta, key);
1411 if (ret >= 0) {
1412 key->hw_key_idx = ret;
1413 /* push IV and Michael MIC generation to stack */
1414 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1415 if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
1416 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1417 if (priv->ah->sw_mgmt_crypto &&
1418 key->cipher == WLAN_CIPHER_SUITE_CCMP)
1419 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
1420 ret = 0;
1422 break;
1423 case DISABLE_KEY:
1424 ath_key_delete(common, key);
1425 break;
1426 default:
1427 ret = -EINVAL;
1430 ath9k_htc_ps_restore(priv);
1431 mutex_unlock(&priv->mutex);
1433 return ret;
1436 static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
1437 struct ieee80211_vif *vif,
1438 struct ieee80211_bss_conf *bss_conf,
1439 u32 changed)
1441 struct ath9k_htc_priv *priv = hw->priv;
1442 struct ath_hw *ah = priv->ah;
1443 struct ath_common *common = ath9k_hw_common(ah);
1444 bool set_assoc;
1446 mutex_lock(&priv->mutex);
1447 ath9k_htc_ps_wakeup(priv);
1450 * Set the HW AID/BSSID only for the first station interface
1451 * or in IBSS mode.
1453 set_assoc = !!((priv->ah->opmode == NL80211_IFTYPE_ADHOC) ||
1454 ((priv->ah->opmode == NL80211_IFTYPE_STATION) &&
1455 (priv->num_sta_vif == 1)));
1458 if (changed & BSS_CHANGED_ASSOC) {
1459 if (set_assoc) {
1460 ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
1461 bss_conf->assoc);
1463 common->curaid = bss_conf->assoc ?
1464 bss_conf->aid : 0;
1466 if (bss_conf->assoc)
1467 ath9k_htc_start_ani(priv);
1468 else
1469 ath9k_htc_stop_ani(priv);
1473 if (changed & BSS_CHANGED_BSSID) {
1474 if (set_assoc) {
1475 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1476 ath9k_hw_write_associd(ah);
1478 ath_dbg(common, ATH_DBG_CONFIG,
1479 "BSSID: %pM aid: 0x%x\n",
1480 common->curbssid, common->curaid);
1484 if ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon) {
1485 ath_dbg(common, ATH_DBG_CONFIG,
1486 "Beacon enabled for BSS: %pM\n", bss_conf->bssid);
1487 ath9k_htc_set_tsfadjust(priv, vif);
1488 priv->op_flags |= OP_ENABLE_BEACON;
1489 ath9k_htc_beacon_config(priv, vif);
1492 if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) {
1494 * Disable SWBA interrupt only if there are no
1495 * AP/IBSS interfaces.
1497 if ((priv->num_ap_vif <= 1) || priv->num_ibss_vif) {
1498 ath_dbg(common, ATH_DBG_CONFIG,
1499 "Beacon disabled for BSS: %pM\n",
1500 bss_conf->bssid);
1501 priv->op_flags &= ~OP_ENABLE_BEACON;
1502 ath9k_htc_beacon_config(priv, vif);
1506 if (changed & BSS_CHANGED_BEACON_INT) {
1508 * Reset the HW TSF for the first AP interface.
1510 if ((priv->ah->opmode == NL80211_IFTYPE_AP) &&
1511 (priv->nvifs == 1) &&
1512 (priv->num_ap_vif == 1) &&
1513 (vif->type == NL80211_IFTYPE_AP)) {
1514 priv->op_flags |= OP_TSF_RESET;
1516 ath_dbg(common, ATH_DBG_CONFIG,
1517 "Beacon interval changed for BSS: %pM\n",
1518 bss_conf->bssid);
1519 ath9k_htc_beacon_config(priv, vif);
1522 if (changed & BSS_CHANGED_ERP_SLOT) {
1523 if (bss_conf->use_short_slot)
1524 ah->slottime = 9;
1525 else
1526 ah->slottime = 20;
1528 ath9k_hw_init_global_settings(ah);
1531 if (changed & BSS_CHANGED_HT)
1532 ath9k_htc_update_rate(priv, vif, bss_conf);
1534 ath9k_htc_ps_restore(priv);
1535 mutex_unlock(&priv->mutex);
1538 static u64 ath9k_htc_get_tsf(struct ieee80211_hw *hw)
1540 struct ath9k_htc_priv *priv = hw->priv;
1541 u64 tsf;
1543 mutex_lock(&priv->mutex);
1544 ath9k_htc_ps_wakeup(priv);
1545 tsf = ath9k_hw_gettsf64(priv->ah);
1546 ath9k_htc_ps_restore(priv);
1547 mutex_unlock(&priv->mutex);
1549 return tsf;
1552 static void ath9k_htc_set_tsf(struct ieee80211_hw *hw, u64 tsf)
1554 struct ath9k_htc_priv *priv = hw->priv;
1556 mutex_lock(&priv->mutex);
1557 ath9k_htc_ps_wakeup(priv);
1558 ath9k_hw_settsf64(priv->ah, tsf);
1559 ath9k_htc_ps_restore(priv);
1560 mutex_unlock(&priv->mutex);
1563 static void ath9k_htc_reset_tsf(struct ieee80211_hw *hw)
1565 struct ath9k_htc_priv *priv = hw->priv;
1567 mutex_lock(&priv->mutex);
1568 ath9k_htc_ps_wakeup(priv);
1569 ath9k_hw_reset_tsf(priv->ah);
1570 ath9k_htc_ps_restore(priv);
1571 mutex_unlock(&priv->mutex);
1574 static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
1575 struct ieee80211_vif *vif,
1576 enum ieee80211_ampdu_mlme_action action,
1577 struct ieee80211_sta *sta,
1578 u16 tid, u16 *ssn, u8 buf_size)
1580 struct ath9k_htc_priv *priv = hw->priv;
1581 struct ath9k_htc_sta *ista;
1582 int ret = 0;
1584 mutex_lock(&priv->mutex);
1586 switch (action) {
1587 case IEEE80211_AMPDU_RX_START:
1588 break;
1589 case IEEE80211_AMPDU_RX_STOP:
1590 break;
1591 case IEEE80211_AMPDU_TX_START:
1592 ret = ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid);
1593 if (!ret)
1594 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1595 break;
1596 case IEEE80211_AMPDU_TX_STOP:
1597 ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid);
1598 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1599 break;
1600 case IEEE80211_AMPDU_TX_OPERATIONAL:
1601 ista = (struct ath9k_htc_sta *) sta->drv_priv;
1602 spin_lock_bh(&priv->tx.tx_lock);
1603 ista->tid_state[tid] = AGGR_OPERATIONAL;
1604 spin_unlock_bh(&priv->tx.tx_lock);
1605 break;
1606 default:
1607 ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n");
1610 mutex_unlock(&priv->mutex);
1612 return ret;
1615 static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw)
1617 struct ath9k_htc_priv *priv = hw->priv;
1619 mutex_lock(&priv->mutex);
1620 spin_lock_bh(&priv->beacon_lock);
1621 priv->op_flags |= OP_SCANNING;
1622 spin_unlock_bh(&priv->beacon_lock);
1623 cancel_work_sync(&priv->ps_work);
1624 ath9k_htc_stop_ani(priv);
1625 mutex_unlock(&priv->mutex);
1628 static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
1630 struct ath9k_htc_priv *priv = hw->priv;
1632 mutex_lock(&priv->mutex);
1633 spin_lock_bh(&priv->beacon_lock);
1634 priv->op_flags &= ~OP_SCANNING;
1635 spin_unlock_bh(&priv->beacon_lock);
1636 ath9k_htc_ps_wakeup(priv);
1637 ath9k_htc_vif_reconfig(priv);
1638 ath9k_htc_ps_restore(priv);
1639 mutex_unlock(&priv->mutex);
1642 static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1644 return 0;
1647 static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw,
1648 u8 coverage_class)
1650 struct ath9k_htc_priv *priv = hw->priv;
1652 mutex_lock(&priv->mutex);
1653 ath9k_htc_ps_wakeup(priv);
1654 priv->ah->coverage_class = coverage_class;
1655 ath9k_hw_init_global_settings(priv->ah);
1656 ath9k_htc_ps_restore(priv);
1657 mutex_unlock(&priv->mutex);
1660 struct ieee80211_ops ath9k_htc_ops = {
1661 .tx = ath9k_htc_tx,
1662 .start = ath9k_htc_start,
1663 .stop = ath9k_htc_stop,
1664 .add_interface = ath9k_htc_add_interface,
1665 .remove_interface = ath9k_htc_remove_interface,
1666 .config = ath9k_htc_config,
1667 .configure_filter = ath9k_htc_configure_filter,
1668 .sta_add = ath9k_htc_sta_add,
1669 .sta_remove = ath9k_htc_sta_remove,
1670 .conf_tx = ath9k_htc_conf_tx,
1671 .bss_info_changed = ath9k_htc_bss_info_changed,
1672 .set_key = ath9k_htc_set_key,
1673 .get_tsf = ath9k_htc_get_tsf,
1674 .set_tsf = ath9k_htc_set_tsf,
1675 .reset_tsf = ath9k_htc_reset_tsf,
1676 .ampdu_action = ath9k_htc_ampdu_action,
1677 .sw_scan_start = ath9k_htc_sw_scan_start,
1678 .sw_scan_complete = ath9k_htc_sw_scan_complete,
1679 .set_rts_threshold = ath9k_htc_set_rts_threshold,
1680 .rfkill_poll = ath9k_htc_rfkill_poll_state,
1681 .set_coverage_class = ath9k_htc_set_coverage_class,