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.
19 #ifdef CONFIG_ATH9K_HTC_DEBUGFS
20 static struct dentry
*ath9k_debugfs_root
;
27 void ath_update_txpow(struct ath9k_htc_priv
*priv
)
29 struct ath_hw
*ah
= priv
->ah
;
31 if (priv
->curtxpow
!= priv
->txpowlimit
) {
32 ath9k_hw_set_txpowerlimit(ah
, priv
->txpowlimit
, false);
33 /* read back in case value is clamped */
34 priv
->curtxpow
= ath9k_hw_regulatory(ah
)->power_limit
;
38 /* HACK Alert: Use 11NG for 2.4, use 11NA for 5 */
39 static enum htc_phymode
ath9k_htc_get_curmode(struct ath9k_htc_priv
*priv
,
40 struct ath9k_channel
*ichan
)
42 enum htc_phymode mode
;
46 switch (ichan
->chanmode
) {
49 case CHANNEL_G_HT40PLUS
:
50 case CHANNEL_G_HT40MINUS
:
55 case CHANNEL_A_HT40PLUS
:
56 case CHANNEL_A_HT40MINUS
:
66 bool ath9k_htc_setpower(struct ath9k_htc_priv
*priv
,
67 enum ath9k_power_mode mode
)
71 mutex_lock(&priv
->htc_pm_lock
);
72 ret
= ath9k_hw_setpower(priv
->ah
, mode
);
73 mutex_unlock(&priv
->htc_pm_lock
);
78 void ath9k_htc_ps_wakeup(struct ath9k_htc_priv
*priv
)
80 mutex_lock(&priv
->htc_pm_lock
);
81 if (++priv
->ps_usecount
!= 1)
83 ath9k_hw_setpower(priv
->ah
, ATH9K_PM_AWAKE
);
86 mutex_unlock(&priv
->htc_pm_lock
);
89 void ath9k_htc_ps_restore(struct ath9k_htc_priv
*priv
)
91 mutex_lock(&priv
->htc_pm_lock
);
92 if (--priv
->ps_usecount
!= 0)
96 ath9k_hw_setpower(priv
->ah
, ATH9K_PM_FULL_SLEEP
);
97 else if (priv
->ps_enabled
)
98 ath9k_hw_setpower(priv
->ah
, ATH9K_PM_NETWORK_SLEEP
);
101 mutex_unlock(&priv
->htc_pm_lock
);
104 void ath9k_ps_work(struct work_struct
*work
)
106 struct ath9k_htc_priv
*priv
=
107 container_of(work
, struct ath9k_htc_priv
,
109 ath9k_htc_setpower(priv
, ATH9K_PM_AWAKE
);
111 /* The chip wakes up after receiving the first beacon
112 while network sleep is enabled. For the driver to
113 be in sync with the hw, set the chip to awake and
114 only then set it to sleep.
116 ath9k_htc_setpower(priv
, ATH9K_PM_NETWORK_SLEEP
);
119 void ath9k_htc_reset(struct ath9k_htc_priv
*priv
)
121 struct ath_hw
*ah
= priv
->ah
;
122 struct ath_common
*common
= ath9k_hw_common(ah
);
123 struct ieee80211_channel
*channel
= priv
->hw
->conf
.channel
;
124 struct ath9k_hw_cal_data
*caldata
;
125 enum htc_phymode mode
;
130 mutex_lock(&priv
->mutex
);
131 ath9k_htc_ps_wakeup(priv
);
133 if (priv
->op_flags
& OP_ASSOCIATED
)
134 cancel_delayed_work_sync(&priv
->ath9k_ani_work
);
136 ieee80211_stop_queues(priv
->hw
);
138 WMI_CMD(WMI_DISABLE_INTR_CMDID
);
139 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID
);
140 WMI_CMD(WMI_STOP_RECV_CMDID
);
142 caldata
= &priv
->caldata
[channel
->hw_value
];
143 ret
= ath9k_hw_reset(ah
, ah
->curchan
, caldata
, false);
146 "Unable to reset device (%u Mhz) reset status %d\n",
147 channel
->center_freq
, ret
);
150 ath_update_txpow(priv
);
152 WMI_CMD(WMI_START_RECV_CMDID
);
153 ath9k_host_rx_init(priv
);
155 mode
= ath9k_htc_get_curmode(priv
, ah
->curchan
);
156 htc_mode
= cpu_to_be16(mode
);
157 WMI_CMD_BUF(WMI_SET_MODE_CMDID
, &htc_mode
);
159 WMI_CMD(WMI_ENABLE_INTR_CMDID
);
160 htc_start(priv
->htc
);
162 if (priv
->op_flags
& OP_ASSOCIATED
) {
163 ath9k_htc_beacon_config(priv
, priv
->vif
);
167 ieee80211_wake_queues(priv
->hw
);
169 ath9k_htc_ps_restore(priv
);
170 mutex_unlock(&priv
->mutex
);
173 static int ath9k_htc_set_channel(struct ath9k_htc_priv
*priv
,
174 struct ieee80211_hw
*hw
,
175 struct ath9k_channel
*hchan
)
177 struct ath_hw
*ah
= priv
->ah
;
178 struct ath_common
*common
= ath9k_hw_common(ah
);
179 struct ieee80211_conf
*conf
= &common
->hw
->conf
;
181 struct ieee80211_channel
*channel
= hw
->conf
.channel
;
182 struct ath9k_hw_cal_data
*caldata
;
183 enum htc_phymode mode
;
188 if (priv
->op_flags
& OP_INVALID
)
191 fastcc
= !!(hw
->conf
.flags
& IEEE80211_CONF_OFFCHANNEL
);
193 ath9k_htc_ps_wakeup(priv
);
195 WMI_CMD(WMI_DISABLE_INTR_CMDID
);
196 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID
);
197 WMI_CMD(WMI_STOP_RECV_CMDID
);
199 ath_dbg(common
, ATH_DBG_CONFIG
,
200 "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n",
201 priv
->ah
->curchan
->channel
,
202 channel
->center_freq
, conf_is_ht(conf
), conf_is_ht40(conf
),
205 caldata
= &priv
->caldata
[channel
->hw_value
];
206 ret
= ath9k_hw_reset(ah
, hchan
, caldata
, fastcc
);
209 "Unable to reset channel (%u Mhz) reset status %d\n",
210 channel
->center_freq
, ret
);
214 ath_update_txpow(priv
);
216 WMI_CMD(WMI_START_RECV_CMDID
);
220 ath9k_host_rx_init(priv
);
222 mode
= ath9k_htc_get_curmode(priv
, hchan
);
223 htc_mode
= cpu_to_be16(mode
);
224 WMI_CMD_BUF(WMI_SET_MODE_CMDID
, &htc_mode
);
228 WMI_CMD(WMI_ENABLE_INTR_CMDID
);
232 htc_start(priv
->htc
);
234 ath9k_htc_ps_restore(priv
);
238 static void __ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv
*priv
)
240 struct ath_common
*common
= ath9k_hw_common(priv
->ah
);
241 struct ath9k_htc_target_vif hvif
;
245 memset(&hvif
, 0, sizeof(struct ath9k_htc_target_vif
));
246 memcpy(&hvif
.myaddr
, common
->macaddr
, ETH_ALEN
);
247 hvif
.index
= 0; /* Should do for now */
248 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID
, &hvif
);
252 static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv
*priv
)
254 struct ath_common
*common
= ath9k_hw_common(priv
->ah
);
255 struct ath9k_htc_target_vif hvif
;
256 struct ath9k_htc_target_sta tsta
;
263 if (priv
->nstations
>= ATH9K_HTC_MAX_STA
)
270 memset(&hvif
, 0, sizeof(struct ath9k_htc_target_vif
));
271 memcpy(&hvif
.myaddr
, common
->macaddr
, ETH_ALEN
);
273 hvif
.opmode
= cpu_to_be32(HTC_M_MONITOR
);
274 priv
->ah
->opmode
= NL80211_IFTYPE_MONITOR
;
275 hvif
.index
= priv
->nvifs
;
277 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID
, &hvif
);
284 * Associate a station with the interface for packet injection.
287 memset(&tsta
, 0, sizeof(struct ath9k_htc_target_sta
));
289 memcpy(&tsta
.macaddr
, common
->macaddr
, ETH_ALEN
);
292 tsta
.sta_index
= priv
->nstations
;
293 tsta
.vif_index
= hvif
.index
;
294 tsta
.maxampdu
= 0xffff;
296 WMI_CMD_BUF(WMI_NODE_CREATE_CMDID
, &tsta
);
298 ath_err(common
, "Unable to add station entry for monitor mode\n");
305 * Set chainmask etc. on the target.
307 ret
= ath9k_htc_update_cap_target(priv
);
309 ath_dbg(common
, ATH_DBG_CONFIG
,
310 "Failed to update capability in target\n");
312 priv
->ah
->is_monitoring
= true;
318 * Remove the interface from the target.
320 __ath9k_htc_remove_monitor_interface(priv
);
324 static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv
*priv
)
326 struct ath_common
*common
= ath9k_hw_common(priv
->ah
);
330 __ath9k_htc_remove_monitor_interface(priv
);
332 sta_idx
= 0; /* Only single interface, for now */
334 WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID
, &sta_idx
);
336 ath_err(common
, "Unable to remove station entry for monitor mode\n");
341 priv
->ah
->is_monitoring
= false;
346 static int ath9k_htc_add_station(struct ath9k_htc_priv
*priv
,
347 struct ieee80211_vif
*vif
,
348 struct ieee80211_sta
*sta
)
350 struct ath_common
*common
= ath9k_hw_common(priv
->ah
);
351 struct ath9k_htc_target_sta tsta
;
352 struct ath9k_htc_vif
*avp
= (struct ath9k_htc_vif
*) vif
->drv_priv
;
353 struct ath9k_htc_sta
*ista
;
357 if (priv
->nstations
>= ATH9K_HTC_MAX_STA
)
360 memset(&tsta
, 0, sizeof(struct ath9k_htc_target_sta
));
363 ista
= (struct ath9k_htc_sta
*) sta
->drv_priv
;
364 memcpy(&tsta
.macaddr
, sta
->addr
, ETH_ALEN
);
365 memcpy(&tsta
.bssid
, common
->curbssid
, ETH_ALEN
);
366 tsta
.associd
= common
->curaid
;
369 ista
->index
= priv
->nstations
;
371 memcpy(&tsta
.macaddr
, vif
->addr
, ETH_ALEN
);
375 tsta
.sta_index
= priv
->nstations
;
376 tsta
.vif_index
= avp
->index
;
377 tsta
.maxampdu
= 0xffff;
378 if (sta
&& sta
->ht_cap
.ht_supported
)
379 tsta
.flags
= cpu_to_be16(ATH_HTC_STA_HT
);
381 WMI_CMD_BUF(WMI_NODE_CREATE_CMDID
, &tsta
);
385 "Unable to add station entry for: %pM\n",
391 ath_dbg(common
, ATH_DBG_CONFIG
,
392 "Added a station entry for: %pM (idx: %d)\n",
393 sta
->addr
, tsta
.sta_index
);
399 static int ath9k_htc_remove_station(struct ath9k_htc_priv
*priv
,
400 struct ieee80211_vif
*vif
,
401 struct ieee80211_sta
*sta
)
403 struct ath_common
*common
= ath9k_hw_common(priv
->ah
);
404 struct ath9k_htc_sta
*ista
;
409 ista
= (struct ath9k_htc_sta
*) sta
->drv_priv
;
410 sta_idx
= ista
->index
;
415 WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID
, &sta_idx
);
419 "Unable to remove station entry for: %pM\n",
425 ath_dbg(common
, ATH_DBG_CONFIG
,
426 "Removed a station entry for: %pM (idx: %d)\n",
433 int ath9k_htc_update_cap_target(struct ath9k_htc_priv
*priv
)
435 struct ath9k_htc_cap_target tcap
;
439 memset(&tcap
, 0, sizeof(struct ath9k_htc_cap_target
));
441 /* FIXME: Values are hardcoded */
442 tcap
.flags
= 0x240c40;
443 tcap
.flags_ext
= 0x80601000;
444 tcap
.ampdu_limit
= 0xffff0000;
445 tcap
.ampdu_subframes
= 20;
446 tcap
.tx_chainmask_legacy
= priv
->ah
->caps
.tx_chainmask
;
448 tcap
.tx_chainmask
= priv
->ah
->caps
.tx_chainmask
;
450 WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID
, &tcap
);
455 static void ath9k_htc_setup_rate(struct ath9k_htc_priv
*priv
,
456 struct ieee80211_sta
*sta
,
457 struct ath9k_htc_target_rate
*trate
)
459 struct ath9k_htc_sta
*ista
= (struct ath9k_htc_sta
*) sta
->drv_priv
;
460 struct ieee80211_supported_band
*sband
;
464 sband
= priv
->hw
->wiphy
->bands
[priv
->hw
->conf
.channel
->band
];
466 for (i
= 0, j
= 0; i
< sband
->n_bitrates
; i
++) {
467 if (sta
->supp_rates
[sband
->band
] & BIT(i
)) {
468 trate
->rates
.legacy_rates
.rs_rates
[j
]
469 = (sband
->bitrates
[i
].bitrate
* 2) / 10;
473 trate
->rates
.legacy_rates
.rs_nrates
= j
;
475 if (sta
->ht_cap
.ht_supported
) {
476 for (i
= 0, j
= 0; i
< 77; i
++) {
477 if (sta
->ht_cap
.mcs
.rx_mask
[i
/8] & (1<<(i
%8)))
478 trate
->rates
.ht_rates
.rs_rates
[j
++] = i
;
479 if (j
== ATH_HTC_RATE_MAX
)
482 trate
->rates
.ht_rates
.rs_nrates
= j
;
484 caps
= WLAN_RC_HT_FLAG
;
485 if (sta
->ht_cap
.mcs
.rx_mask
[1])
486 caps
|= WLAN_RC_DS_FLAG
;
487 if ((sta
->ht_cap
.cap
& IEEE80211_HT_CAP_SUP_WIDTH_20_40
) &&
488 (conf_is_ht40(&priv
->hw
->conf
)))
489 caps
|= WLAN_RC_40_FLAG
;
490 if (conf_is_ht40(&priv
->hw
->conf
) &&
491 (sta
->ht_cap
.cap
& IEEE80211_HT_CAP_SGI_40
))
492 caps
|= WLAN_RC_SGI_FLAG
;
493 else if (conf_is_ht20(&priv
->hw
->conf
) &&
494 (sta
->ht_cap
.cap
& IEEE80211_HT_CAP_SGI_20
))
495 caps
|= WLAN_RC_SGI_FLAG
;
498 trate
->sta_index
= ista
->index
;
500 trate
->capflags
= cpu_to_be32(caps
);
503 static int ath9k_htc_send_rate_cmd(struct ath9k_htc_priv
*priv
,
504 struct ath9k_htc_target_rate
*trate
)
506 struct ath_common
*common
= ath9k_hw_common(priv
->ah
);
510 WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID
, trate
);
513 "Unable to initialize Rate information on target\n");
519 static void ath9k_htc_init_rate(struct ath9k_htc_priv
*priv
,
520 struct ieee80211_sta
*sta
)
522 struct ath_common
*common
= ath9k_hw_common(priv
->ah
);
523 struct ath9k_htc_target_rate trate
;
526 memset(&trate
, 0, sizeof(struct ath9k_htc_target_rate
));
527 ath9k_htc_setup_rate(priv
, sta
, &trate
);
528 ret
= ath9k_htc_send_rate_cmd(priv
, &trate
);
530 ath_dbg(common
, ATH_DBG_CONFIG
,
531 "Updated target sta: %pM, rate caps: 0x%X\n",
532 sta
->addr
, be32_to_cpu(trate
.capflags
));
535 static void ath9k_htc_update_rate(struct ath9k_htc_priv
*priv
,
536 struct ieee80211_vif
*vif
,
537 struct ieee80211_bss_conf
*bss_conf
)
539 struct ath_common
*common
= ath9k_hw_common(priv
->ah
);
540 struct ath9k_htc_target_rate trate
;
541 struct ieee80211_sta
*sta
;
544 memset(&trate
, 0, sizeof(struct ath9k_htc_target_rate
));
547 sta
= ieee80211_find_sta(vif
, bss_conf
->bssid
);
552 ath9k_htc_setup_rate(priv
, sta
, &trate
);
555 ret
= ath9k_htc_send_rate_cmd(priv
, &trate
);
557 ath_dbg(common
, ATH_DBG_CONFIG
,
558 "Updated target sta: %pM, rate caps: 0x%X\n",
559 bss_conf
->bssid
, be32_to_cpu(trate
.capflags
));
562 static int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv
*priv
,
563 struct ieee80211_vif
*vif
,
564 struct ieee80211_sta
*sta
,
565 enum ieee80211_ampdu_mlme_action action
,
568 struct ath_common
*common
= ath9k_hw_common(priv
->ah
);
569 struct ath9k_htc_target_aggr aggr
;
570 struct ath9k_htc_sta
*ista
;
574 if (tid
>= ATH9K_HTC_MAX_TID
)
577 memset(&aggr
, 0, sizeof(struct ath9k_htc_target_aggr
));
578 ista
= (struct ath9k_htc_sta
*) sta
->drv_priv
;
580 aggr
.sta_index
= ista
->index
;
581 aggr
.tidno
= tid
& 0xf;
582 aggr
.aggr_enable
= (action
== IEEE80211_AMPDU_TX_START
) ? true : false;
584 WMI_CMD_BUF(WMI_TX_AGGR_ENABLE_CMDID
, &aggr
);
586 ath_dbg(common
, ATH_DBG_CONFIG
,
587 "Unable to %s TX aggregation for (%pM, %d)\n",
588 (aggr
.aggr_enable
) ? "start" : "stop", sta
->addr
, tid
);
590 ath_dbg(common
, ATH_DBG_CONFIG
,
591 "%s TX aggregation for (%pM, %d)\n",
592 (aggr
.aggr_enable
) ? "Starting" : "Stopping",
595 spin_lock_bh(&priv
->tx_lock
);
596 ista
->tid_state
[tid
] = (aggr
.aggr_enable
&& !ret
) ? AGGR_START
: AGGR_STOP
;
597 spin_unlock_bh(&priv
->tx_lock
);
606 #ifdef CONFIG_ATH9K_HTC_DEBUGFS
608 static int ath9k_debugfs_open(struct inode
*inode
, struct file
*file
)
610 file
->private_data
= inode
->i_private
;
614 static ssize_t
read_file_tgt_stats(struct file
*file
, char __user
*user_buf
,
615 size_t count
, loff_t
*ppos
)
617 struct ath9k_htc_priv
*priv
= file
->private_data
;
618 struct ath9k_htc_target_stats cmd_rsp
;
620 unsigned int len
= 0;
623 memset(&cmd_rsp
, 0, sizeof(cmd_rsp
));
625 WMI_CMD(WMI_TGT_STATS_CMDID
);
630 len
+= snprintf(buf
+ len
, sizeof(buf
) - len
,
631 "%19s : %10u\n", "TX Short Retries",
632 be32_to_cpu(cmd_rsp
.tx_shortretry
));
633 len
+= snprintf(buf
+ len
, sizeof(buf
) - len
,
634 "%19s : %10u\n", "TX Long Retries",
635 be32_to_cpu(cmd_rsp
.tx_longretry
));
636 len
+= snprintf(buf
+ len
, sizeof(buf
) - len
,
637 "%19s : %10u\n", "TX Xretries",
638 be32_to_cpu(cmd_rsp
.tx_xretries
));
639 len
+= snprintf(buf
+ len
, sizeof(buf
) - len
,
640 "%19s : %10u\n", "TX Unaggr. Xretries",
641 be32_to_cpu(cmd_rsp
.ht_txunaggr_xretry
));
642 len
+= snprintf(buf
+ len
, sizeof(buf
) - len
,
643 "%19s : %10u\n", "TX Xretries (HT)",
644 be32_to_cpu(cmd_rsp
.ht_tx_xretries
));
645 len
+= snprintf(buf
+ len
, sizeof(buf
) - len
,
646 "%19s : %10u\n", "TX Rate", priv
->debug
.txrate
);
648 if (len
> sizeof(buf
))
651 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
654 static const struct file_operations fops_tgt_stats
= {
655 .read
= read_file_tgt_stats
,
656 .open
= ath9k_debugfs_open
,
657 .owner
= THIS_MODULE
,
658 .llseek
= default_llseek
,
661 static ssize_t
read_file_xmit(struct file
*file
, char __user
*user_buf
,
662 size_t count
, loff_t
*ppos
)
664 struct ath9k_htc_priv
*priv
= file
->private_data
;
666 unsigned int len
= 0;
668 len
+= snprintf(buf
+ len
, sizeof(buf
) - len
,
669 "%20s : %10u\n", "Buffers queued",
670 priv
->debug
.tx_stats
.buf_queued
);
671 len
+= snprintf(buf
+ len
, sizeof(buf
) - len
,
672 "%20s : %10u\n", "Buffers completed",
673 priv
->debug
.tx_stats
.buf_completed
);
674 len
+= snprintf(buf
+ len
, sizeof(buf
) - len
,
675 "%20s : %10u\n", "SKBs queued",
676 priv
->debug
.tx_stats
.skb_queued
);
677 len
+= snprintf(buf
+ len
, sizeof(buf
) - len
,
678 "%20s : %10u\n", "SKBs completed",
679 priv
->debug
.tx_stats
.skb_completed
);
680 len
+= snprintf(buf
+ len
, sizeof(buf
) - len
,
681 "%20s : %10u\n", "SKBs dropped",
682 priv
->debug
.tx_stats
.skb_dropped
);
684 len
+= snprintf(buf
+ len
, sizeof(buf
) - len
,
685 "%20s : %10u\n", "BE queued",
686 priv
->debug
.tx_stats
.queue_stats
[WME_AC_BE
]);
687 len
+= snprintf(buf
+ len
, sizeof(buf
) - len
,
688 "%20s : %10u\n", "BK queued",
689 priv
->debug
.tx_stats
.queue_stats
[WME_AC_BK
]);
690 len
+= snprintf(buf
+ len
, sizeof(buf
) - len
,
691 "%20s : %10u\n", "VI queued",
692 priv
->debug
.tx_stats
.queue_stats
[WME_AC_VI
]);
693 len
+= snprintf(buf
+ len
, sizeof(buf
) - len
,
694 "%20s : %10u\n", "VO queued",
695 priv
->debug
.tx_stats
.queue_stats
[WME_AC_VO
]);
697 if (len
> sizeof(buf
))
700 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
703 static const struct file_operations fops_xmit
= {
704 .read
= read_file_xmit
,
705 .open
= ath9k_debugfs_open
,
706 .owner
= THIS_MODULE
,
707 .llseek
= default_llseek
,
710 static ssize_t
read_file_recv(struct file
*file
, char __user
*user_buf
,
711 size_t count
, loff_t
*ppos
)
713 struct ath9k_htc_priv
*priv
= file
->private_data
;
715 unsigned int len
= 0;
717 len
+= snprintf(buf
+ len
, sizeof(buf
) - len
,
718 "%20s : %10u\n", "SKBs allocated",
719 priv
->debug
.rx_stats
.skb_allocated
);
720 len
+= snprintf(buf
+ len
, sizeof(buf
) - len
,
721 "%20s : %10u\n", "SKBs completed",
722 priv
->debug
.rx_stats
.skb_completed
);
723 len
+= snprintf(buf
+ len
, sizeof(buf
) - len
,
724 "%20s : %10u\n", "SKBs Dropped",
725 priv
->debug
.rx_stats
.skb_dropped
);
727 if (len
> sizeof(buf
))
730 return simple_read_from_buffer(user_buf
, count
, ppos
, buf
, len
);
733 static const struct file_operations fops_recv
= {
734 .read
= read_file_recv
,
735 .open
= ath9k_debugfs_open
,
736 .owner
= THIS_MODULE
,
737 .llseek
= default_llseek
,
740 int ath9k_htc_init_debug(struct ath_hw
*ah
)
742 struct ath_common
*common
= ath9k_hw_common(ah
);
743 struct ath9k_htc_priv
*priv
= (struct ath9k_htc_priv
*) common
->priv
;
745 if (!ath9k_debugfs_root
)
748 priv
->debug
.debugfs_phy
= debugfs_create_dir(wiphy_name(priv
->hw
->wiphy
),
750 if (!priv
->debug
.debugfs_phy
)
753 priv
->debug
.debugfs_tgt_stats
= debugfs_create_file("tgt_stats", S_IRUSR
,
754 priv
->debug
.debugfs_phy
,
755 priv
, &fops_tgt_stats
);
756 if (!priv
->debug
.debugfs_tgt_stats
)
760 priv
->debug
.debugfs_xmit
= debugfs_create_file("xmit", S_IRUSR
,
761 priv
->debug
.debugfs_phy
,
763 if (!priv
->debug
.debugfs_xmit
)
766 priv
->debug
.debugfs_recv
= debugfs_create_file("recv", S_IRUSR
,
767 priv
->debug
.debugfs_phy
,
769 if (!priv
->debug
.debugfs_recv
)
775 ath9k_htc_exit_debug(ah
);
779 void ath9k_htc_exit_debug(struct ath_hw
*ah
)
781 struct ath_common
*common
= ath9k_hw_common(ah
);
782 struct ath9k_htc_priv
*priv
= (struct ath9k_htc_priv
*) common
->priv
;
784 debugfs_remove(priv
->debug
.debugfs_recv
);
785 debugfs_remove(priv
->debug
.debugfs_xmit
);
786 debugfs_remove(priv
->debug
.debugfs_tgt_stats
);
787 debugfs_remove(priv
->debug
.debugfs_phy
);
790 int ath9k_htc_debug_create_root(void)
792 ath9k_debugfs_root
= debugfs_create_dir(KBUILD_MODNAME
, NULL
);
793 if (!ath9k_debugfs_root
)
799 void ath9k_htc_debug_remove_root(void)
801 debugfs_remove(ath9k_debugfs_root
);
802 ath9k_debugfs_root
= NULL
;
805 #endif /* CONFIG_ATH9K_HTC_DEBUGFS */
811 void ath_start_ani(struct ath9k_htc_priv
*priv
)
813 struct ath_common
*common
= ath9k_hw_common(priv
->ah
);
814 unsigned long timestamp
= jiffies_to_msecs(jiffies
);
816 common
->ani
.longcal_timer
= timestamp
;
817 common
->ani
.shortcal_timer
= timestamp
;
818 common
->ani
.checkani_timer
= timestamp
;
820 ieee80211_queue_delayed_work(common
->hw
, &priv
->ath9k_ani_work
,
821 msecs_to_jiffies(ATH_ANI_POLLINTERVAL
));
824 void ath9k_ani_work(struct work_struct
*work
)
826 struct ath9k_htc_priv
*priv
=
827 container_of(work
, struct ath9k_htc_priv
,
828 ath9k_ani_work
.work
);
829 struct ath_hw
*ah
= priv
->ah
;
830 struct ath_common
*common
= ath9k_hw_common(ah
);
831 bool longcal
= false;
832 bool shortcal
= false;
833 bool aniflag
= false;
834 unsigned int timestamp
= jiffies_to_msecs(jiffies
);
835 u32 cal_interval
, short_cal_interval
;
837 short_cal_interval
= ATH_STA_SHORT_CALINTERVAL
;
839 /* Only calibrate if awake */
840 if (ah
->power_mode
!= ATH9K_PM_AWAKE
)
843 /* Long calibration runs independently of short calibration. */
844 if ((timestamp
- common
->ani
.longcal_timer
) >= ATH_LONG_CALINTERVAL
) {
846 ath_dbg(common
, ATH_DBG_ANI
, "longcal @%lu\n", jiffies
);
847 common
->ani
.longcal_timer
= timestamp
;
850 /* Short calibration applies only while caldone is false */
851 if (!common
->ani
.caldone
) {
852 if ((timestamp
- common
->ani
.shortcal_timer
) >=
853 short_cal_interval
) {
855 ath_dbg(common
, ATH_DBG_ANI
,
856 "shortcal @%lu\n", jiffies
);
857 common
->ani
.shortcal_timer
= timestamp
;
858 common
->ani
.resetcal_timer
= timestamp
;
861 if ((timestamp
- common
->ani
.resetcal_timer
) >=
862 ATH_RESTART_CALINTERVAL
) {
863 common
->ani
.caldone
= ath9k_hw_reset_calvalid(ah
);
864 if (common
->ani
.caldone
)
865 common
->ani
.resetcal_timer
= timestamp
;
869 /* Verify whether we must check ANI */
870 if ((timestamp
- common
->ani
.checkani_timer
) >= ATH_ANI_POLLINTERVAL
) {
872 common
->ani
.checkani_timer
= timestamp
;
875 /* Skip all processing if there's nothing to do. */
876 if (longcal
|| shortcal
|| aniflag
) {
878 ath9k_htc_ps_wakeup(priv
);
880 /* Call ANI routine if necessary */
882 ath9k_hw_ani_monitor(ah
, ah
->curchan
);
884 /* Perform calibration if necessary */
885 if (longcal
|| shortcal
)
886 common
->ani
.caldone
=
887 ath9k_hw_calibrate(ah
, ah
->curchan
,
888 common
->rx_chainmask
,
891 ath9k_htc_ps_restore(priv
);
896 * Set timer interval based on previous results.
897 * The interval must be the shortest necessary to satisfy ANI,
898 * short calibration and long calibration.
900 cal_interval
= ATH_LONG_CALINTERVAL
;
901 if (priv
->ah
->config
.enable_ani
)
902 cal_interval
= min(cal_interval
, (u32
)ATH_ANI_POLLINTERVAL
);
903 if (!common
->ani
.caldone
)
904 cal_interval
= min(cal_interval
, (u32
)short_cal_interval
);
906 ieee80211_queue_delayed_work(common
->hw
, &priv
->ath9k_ani_work
,
907 msecs_to_jiffies(cal_interval
));
910 /**********************/
911 /* mac80211 Callbacks */
912 /**********************/
914 static int ath9k_htc_tx(struct ieee80211_hw
*hw
, struct sk_buff
*skb
)
916 struct ieee80211_hdr
*hdr
;
917 struct ath9k_htc_priv
*priv
= hw
->priv
;
918 int padpos
, padsize
, ret
;
920 hdr
= (struct ieee80211_hdr
*) skb
->data
;
922 /* Add the padding after the header if this is not already done */
923 padpos
= ath9k_cmn_padpos(hdr
->frame_control
);
924 padsize
= padpos
& 3;
925 if (padsize
&& skb
->len
> padpos
) {
926 if (skb_headroom(skb
) < padsize
)
928 skb_push(skb
, padsize
);
929 memmove(skb
->data
, skb
->data
+ padsize
, padpos
);
932 ret
= ath9k_htc_tx_start(priv
, skb
);
934 if (ret
== -ENOMEM
) {
935 ath_dbg(ath9k_hw_common(priv
->ah
), ATH_DBG_XMIT
,
936 "Stopping TX queues\n");
937 ieee80211_stop_queues(hw
);
938 spin_lock_bh(&priv
->tx_lock
);
939 priv
->tx_queues_stop
= true;
940 spin_unlock_bh(&priv
->tx_lock
);
942 ath_dbg(ath9k_hw_common(priv
->ah
), ATH_DBG_XMIT
,
951 dev_kfree_skb_any(skb
);
955 static int ath9k_htc_start(struct ieee80211_hw
*hw
)
957 struct ath9k_htc_priv
*priv
= hw
->priv
;
958 struct ath_hw
*ah
= priv
->ah
;
959 struct ath_common
*common
= ath9k_hw_common(ah
);
960 struct ieee80211_channel
*curchan
= hw
->conf
.channel
;
961 struct ath9k_channel
*init_channel
;
963 enum htc_phymode mode
;
967 mutex_lock(&priv
->mutex
);
969 ath_dbg(common
, ATH_DBG_CONFIG
,
970 "Starting driver with initial channel: %d MHz\n",
971 curchan
->center_freq
);
973 /* Ensure that HW is awake before flushing RX */
974 ath9k_htc_setpower(priv
, ATH9K_PM_AWAKE
);
975 WMI_CMD(WMI_FLUSH_RECV_CMDID
);
977 /* setup initial channel */
978 init_channel
= ath9k_cmn_get_curchannel(hw
, ah
);
980 ath9k_hw_htc_resetinit(ah
);
981 ret
= ath9k_hw_reset(ah
, init_channel
, ah
->caldata
, false);
984 "Unable to reset hardware; reset status %d (freq %u MHz)\n",
985 ret
, curchan
->center_freq
);
986 mutex_unlock(&priv
->mutex
);
990 ath_update_txpow(priv
);
992 mode
= ath9k_htc_get_curmode(priv
, init_channel
);
993 htc_mode
= cpu_to_be16(mode
);
994 WMI_CMD_BUF(WMI_SET_MODE_CMDID
, &htc_mode
);
995 WMI_CMD(WMI_ATH_INIT_CMDID
);
996 WMI_CMD(WMI_START_RECV_CMDID
);
998 ath9k_host_rx_init(priv
);
1000 priv
->op_flags
&= ~OP_INVALID
;
1001 htc_start(priv
->htc
);
1003 spin_lock_bh(&priv
->tx_lock
);
1004 priv
->tx_queues_stop
= false;
1005 spin_unlock_bh(&priv
->tx_lock
);
1007 ieee80211_wake_queues(hw
);
1009 if (ah
->btcoex_hw
.scheme
== ATH_BTCOEX_CFG_3WIRE
) {
1010 ath9k_hw_btcoex_set_weight(ah
, AR_BT_COEX_WGHT
,
1011 AR_STOMP_LOW_WLAN_WGHT
);
1012 ath9k_hw_btcoex_enable(ah
);
1013 ath_htc_resume_btcoex_work(priv
);
1015 mutex_unlock(&priv
->mutex
);
1020 static void ath9k_htc_stop(struct ieee80211_hw
*hw
)
1022 struct ath9k_htc_priv
*priv
= hw
->priv
;
1023 struct ath_hw
*ah
= priv
->ah
;
1024 struct ath_common
*common
= ath9k_hw_common(ah
);
1028 /* Cancel all the running timers/work .. */
1029 cancel_work_sync(&priv
->fatal_work
);
1030 cancel_work_sync(&priv
->ps_work
);
1031 cancel_delayed_work_sync(&priv
->ath9k_led_blink_work
);
1032 ath9k_led_stop_brightness(priv
);
1034 mutex_lock(&priv
->mutex
);
1036 if (priv
->op_flags
& OP_INVALID
) {
1037 ath_dbg(common
, ATH_DBG_ANY
, "Device not present\n");
1038 mutex_unlock(&priv
->mutex
);
1042 ath9k_htc_ps_wakeup(priv
);
1043 htc_stop(priv
->htc
);
1044 WMI_CMD(WMI_DISABLE_INTR_CMDID
);
1045 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID
);
1046 WMI_CMD(WMI_STOP_RECV_CMDID
);
1047 skb_queue_purge(&priv
->tx_queue
);
1049 /* Remove monitor interface here */
1050 if (ah
->opmode
== NL80211_IFTYPE_MONITOR
) {
1051 if (ath9k_htc_remove_monitor_interface(priv
))
1052 ath_err(common
, "Unable to remove monitor interface\n");
1054 ath_dbg(common
, ATH_DBG_CONFIG
,
1055 "Monitor interface removed\n");
1058 if (ah
->btcoex_hw
.enabled
) {
1059 ath9k_hw_btcoex_disable(ah
);
1060 if (ah
->btcoex_hw
.scheme
== ATH_BTCOEX_CFG_3WIRE
)
1061 ath_htc_cancel_btcoex_work(priv
);
1064 ath9k_hw_phy_disable(ah
);
1065 ath9k_hw_disable(ah
);
1066 ath9k_htc_ps_restore(priv
);
1067 ath9k_htc_setpower(priv
, ATH9K_PM_FULL_SLEEP
);
1069 priv
->op_flags
|= OP_INVALID
;
1071 ath_dbg(common
, ATH_DBG_CONFIG
, "Driver halt\n");
1072 mutex_unlock(&priv
->mutex
);
1075 static int ath9k_htc_add_interface(struct ieee80211_hw
*hw
,
1076 struct ieee80211_vif
*vif
)
1078 struct ath9k_htc_priv
*priv
= hw
->priv
;
1079 struct ath9k_htc_vif
*avp
= (void *)vif
->drv_priv
;
1080 struct ath_common
*common
= ath9k_hw_common(priv
->ah
);
1081 struct ath9k_htc_target_vif hvif
;
1085 mutex_lock(&priv
->mutex
);
1087 /* Only one interface for now */
1088 if (priv
->nvifs
> 0) {
1093 ath9k_htc_ps_wakeup(priv
);
1094 memset(&hvif
, 0, sizeof(struct ath9k_htc_target_vif
));
1095 memcpy(&hvif
.myaddr
, vif
->addr
, ETH_ALEN
);
1097 switch (vif
->type
) {
1098 case NL80211_IFTYPE_STATION
:
1099 hvif
.opmode
= cpu_to_be32(HTC_M_STA
);
1101 case NL80211_IFTYPE_ADHOC
:
1102 hvif
.opmode
= cpu_to_be32(HTC_M_IBSS
);
1106 "Interface type %d not yet supported\n", vif
->type
);
1111 ath_dbg(common
, ATH_DBG_CONFIG
,
1112 "Attach a VIF of type: %d\n", vif
->type
);
1114 priv
->ah
->opmode
= vif
->type
;
1116 /* Index starts from zero on the target */
1117 avp
->index
= hvif
.index
= priv
->nvifs
;
1118 hvif
.rtsthreshold
= cpu_to_be16(2304);
1119 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID
, &hvif
);
1126 * We need a node in target to tx mgmt frames
1127 * before association.
1129 ret
= ath9k_htc_add_station(priv
, vif
, NULL
);
1133 ret
= ath9k_htc_update_cap_target(priv
);
1135 ath_dbg(common
, ATH_DBG_CONFIG
,
1136 "Failed to update capability in target\n");
1140 ath9k_htc_ps_restore(priv
);
1141 mutex_unlock(&priv
->mutex
);
1146 static void ath9k_htc_remove_interface(struct ieee80211_hw
*hw
,
1147 struct ieee80211_vif
*vif
)
1149 struct ath9k_htc_priv
*priv
= hw
->priv
;
1150 struct ath_common
*common
= ath9k_hw_common(priv
->ah
);
1151 struct ath9k_htc_vif
*avp
= (void *)vif
->drv_priv
;
1152 struct ath9k_htc_target_vif hvif
;
1156 ath_dbg(common
, ATH_DBG_CONFIG
, "Detach Interface\n");
1158 mutex_lock(&priv
->mutex
);
1159 ath9k_htc_ps_wakeup(priv
);
1161 memset(&hvif
, 0, sizeof(struct ath9k_htc_target_vif
));
1162 memcpy(&hvif
.myaddr
, vif
->addr
, ETH_ALEN
);
1163 hvif
.index
= avp
->index
;
1164 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID
, &hvif
);
1167 ath9k_htc_remove_station(priv
, vif
, NULL
);
1170 ath9k_htc_ps_restore(priv
);
1171 mutex_unlock(&priv
->mutex
);
1174 static int ath9k_htc_config(struct ieee80211_hw
*hw
, u32 changed
)
1176 struct ath9k_htc_priv
*priv
= hw
->priv
;
1177 struct ath_common
*common
= ath9k_hw_common(priv
->ah
);
1178 struct ieee80211_conf
*conf
= &hw
->conf
;
1180 mutex_lock(&priv
->mutex
);
1182 if (changed
& IEEE80211_CONF_CHANGE_IDLE
) {
1183 bool enable_radio
= false;
1184 bool idle
= !!(conf
->flags
& IEEE80211_CONF_IDLE
);
1186 mutex_lock(&priv
->htc_pm_lock
);
1187 if (!idle
&& priv
->ps_idle
)
1188 enable_radio
= true;
1189 priv
->ps_idle
= idle
;
1190 mutex_unlock(&priv
->htc_pm_lock
);
1193 ath_dbg(common
, ATH_DBG_CONFIG
,
1194 "not-idle: enabling radio\n");
1195 ath9k_htc_setpower(priv
, ATH9K_PM_AWAKE
);
1196 ath9k_htc_radio_enable(hw
);
1201 * Monitor interface should be added before
1202 * IEEE80211_CONF_CHANGE_CHANNEL is handled.
1204 if (changed
& IEEE80211_CONF_CHANGE_MONITOR
) {
1205 if (conf
->flags
& IEEE80211_CONF_MONITOR
) {
1206 if (ath9k_htc_add_monitor_interface(priv
))
1207 ath_err(common
, "Failed to set monitor mode\n");
1209 ath_dbg(common
, ATH_DBG_CONFIG
,
1210 "HW opmode set to Monitor mode\n");
1214 if (changed
& IEEE80211_CONF_CHANGE_CHANNEL
) {
1215 struct ieee80211_channel
*curchan
= hw
->conf
.channel
;
1216 int pos
= curchan
->hw_value
;
1218 ath_dbg(common
, ATH_DBG_CONFIG
, "Set channel: %d MHz\n",
1219 curchan
->center_freq
);
1221 ath9k_cmn_update_ichannel(&priv
->ah
->channels
[pos
],
1223 hw
->conf
.channel_type
);
1225 if (ath9k_htc_set_channel(priv
, hw
, &priv
->ah
->channels
[pos
]) < 0) {
1226 ath_err(common
, "Unable to set channel\n");
1227 mutex_unlock(&priv
->mutex
);
1233 if (changed
& IEEE80211_CONF_CHANGE_PS
) {
1234 if (conf
->flags
& IEEE80211_CONF_PS
) {
1235 ath9k_htc_setpower(priv
, ATH9K_PM_NETWORK_SLEEP
);
1236 priv
->ps_enabled
= true;
1238 priv
->ps_enabled
= false;
1239 cancel_work_sync(&priv
->ps_work
);
1240 ath9k_htc_setpower(priv
, ATH9K_PM_AWAKE
);
1244 if (changed
& IEEE80211_CONF_CHANGE_POWER
) {
1245 priv
->txpowlimit
= 2 * conf
->power_level
;
1246 ath_update_txpow(priv
);
1249 if (changed
& IEEE80211_CONF_CHANGE_IDLE
) {
1250 mutex_lock(&priv
->htc_pm_lock
);
1251 if (!priv
->ps_idle
) {
1252 mutex_unlock(&priv
->htc_pm_lock
);
1255 mutex_unlock(&priv
->htc_pm_lock
);
1257 ath_dbg(common
, ATH_DBG_CONFIG
,
1258 "idle: disabling radio\n");
1259 ath9k_htc_radio_disable(hw
);
1263 mutex_unlock(&priv
->mutex
);
1267 #define SUPPORTED_FILTERS \
1268 (FIF_PROMISC_IN_BSS | \
1273 FIF_BCN_PRBRESP_PROMISC | \
1277 static void ath9k_htc_configure_filter(struct ieee80211_hw
*hw
,
1278 unsigned int changed_flags
,
1279 unsigned int *total_flags
,
1282 struct ath9k_htc_priv
*priv
= hw
->priv
;
1285 mutex_lock(&priv
->mutex
);
1286 ath9k_htc_ps_wakeup(priv
);
1288 changed_flags
&= SUPPORTED_FILTERS
;
1289 *total_flags
&= SUPPORTED_FILTERS
;
1291 priv
->rxfilter
= *total_flags
;
1292 rfilt
= ath9k_htc_calcrxfilter(priv
);
1293 ath9k_hw_setrxfilter(priv
->ah
, rfilt
);
1295 ath_dbg(ath9k_hw_common(priv
->ah
), ATH_DBG_CONFIG
,
1296 "Set HW RX filter: 0x%x\n", rfilt
);
1298 ath9k_htc_ps_restore(priv
);
1299 mutex_unlock(&priv
->mutex
);
1302 static int ath9k_htc_sta_add(struct ieee80211_hw
*hw
,
1303 struct ieee80211_vif
*vif
,
1304 struct ieee80211_sta
*sta
)
1306 struct ath9k_htc_priv
*priv
= hw
->priv
;
1309 mutex_lock(&priv
->mutex
);
1310 ath9k_htc_ps_wakeup(priv
);
1311 ret
= ath9k_htc_add_station(priv
, vif
, sta
);
1313 ath9k_htc_init_rate(priv
, sta
);
1314 ath9k_htc_ps_restore(priv
);
1315 mutex_unlock(&priv
->mutex
);
1320 static int ath9k_htc_sta_remove(struct ieee80211_hw
*hw
,
1321 struct ieee80211_vif
*vif
,
1322 struct ieee80211_sta
*sta
)
1324 struct ath9k_htc_priv
*priv
= hw
->priv
;
1327 mutex_lock(&priv
->mutex
);
1328 ath9k_htc_ps_wakeup(priv
);
1329 ret
= ath9k_htc_remove_station(priv
, vif
, sta
);
1330 ath9k_htc_ps_restore(priv
);
1331 mutex_unlock(&priv
->mutex
);
1336 static int ath9k_htc_conf_tx(struct ieee80211_hw
*hw
, u16 queue
,
1337 const struct ieee80211_tx_queue_params
*params
)
1339 struct ath9k_htc_priv
*priv
= hw
->priv
;
1340 struct ath_common
*common
= ath9k_hw_common(priv
->ah
);
1341 struct ath9k_tx_queue_info qi
;
1344 if (queue
>= WME_NUM_AC
)
1347 mutex_lock(&priv
->mutex
);
1348 ath9k_htc_ps_wakeup(priv
);
1350 memset(&qi
, 0, sizeof(struct ath9k_tx_queue_info
));
1352 qi
.tqi_aifs
= params
->aifs
;
1353 qi
.tqi_cwmin
= params
->cw_min
;
1354 qi
.tqi_cwmax
= params
->cw_max
;
1355 qi
.tqi_burstTime
= params
->txop
;
1357 qnum
= get_hw_qnum(queue
, priv
->hwq_map
);
1359 ath_dbg(common
, ATH_DBG_CONFIG
,
1360 "Configure tx [queue/hwq] [%d/%d], aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
1361 queue
, qnum
, params
->aifs
, params
->cw_min
,
1362 params
->cw_max
, params
->txop
);
1364 ret
= ath_htc_txq_update(priv
, qnum
, &qi
);
1366 ath_err(common
, "TXQ Update failed\n");
1370 if ((priv
->ah
->opmode
== NL80211_IFTYPE_ADHOC
) &&
1371 (qnum
== priv
->hwq_map
[WME_AC_BE
]))
1372 ath9k_htc_beaconq_config(priv
);
1374 ath9k_htc_ps_restore(priv
);
1375 mutex_unlock(&priv
->mutex
);
1380 static int ath9k_htc_set_key(struct ieee80211_hw
*hw
,
1381 enum set_key_cmd cmd
,
1382 struct ieee80211_vif
*vif
,
1383 struct ieee80211_sta
*sta
,
1384 struct ieee80211_key_conf
*key
)
1386 struct ath9k_htc_priv
*priv
= hw
->priv
;
1387 struct ath_common
*common
= ath9k_hw_common(priv
->ah
);
1390 if (htc_modparam_nohwcrypt
)
1393 mutex_lock(&priv
->mutex
);
1394 ath_dbg(common
, ATH_DBG_CONFIG
, "Set HW Key\n");
1395 ath9k_htc_ps_wakeup(priv
);
1399 ret
= ath_key_config(common
, vif
, sta
, key
);
1401 key
->hw_key_idx
= ret
;
1402 /* push IV and Michael MIC generation to stack */
1403 key
->flags
|= IEEE80211_KEY_FLAG_GENERATE_IV
;
1404 if (key
->cipher
== WLAN_CIPHER_SUITE_TKIP
)
1405 key
->flags
|= IEEE80211_KEY_FLAG_GENERATE_MMIC
;
1406 if (priv
->ah
->sw_mgmt_crypto
&&
1407 key
->cipher
== WLAN_CIPHER_SUITE_CCMP
)
1408 key
->flags
|= IEEE80211_KEY_FLAG_SW_MGMT
;
1413 ath_key_delete(common
, key
);
1419 ath9k_htc_ps_restore(priv
);
1420 mutex_unlock(&priv
->mutex
);
1425 static void ath9k_htc_bss_info_changed(struct ieee80211_hw
*hw
,
1426 struct ieee80211_vif
*vif
,
1427 struct ieee80211_bss_conf
*bss_conf
,
1430 struct ath9k_htc_priv
*priv
= hw
->priv
;
1431 struct ath_hw
*ah
= priv
->ah
;
1432 struct ath_common
*common
= ath9k_hw_common(ah
);
1434 mutex_lock(&priv
->mutex
);
1435 ath9k_htc_ps_wakeup(priv
);
1437 if (changed
& BSS_CHANGED_ASSOC
) {
1438 common
->curaid
= bss_conf
->assoc
?
1440 ath_dbg(common
, ATH_DBG_CONFIG
, "BSS Changed ASSOC %d\n",
1443 if (bss_conf
->assoc
) {
1444 priv
->op_flags
|= OP_ASSOCIATED
;
1445 ath_start_ani(priv
);
1447 priv
->op_flags
&= ~OP_ASSOCIATED
;
1448 cancel_delayed_work_sync(&priv
->ath9k_ani_work
);
1452 if (changed
& BSS_CHANGED_BSSID
) {
1454 memcpy(common
->curbssid
, bss_conf
->bssid
, ETH_ALEN
);
1455 ath9k_hw_write_associd(ah
);
1457 ath_dbg(common
, ATH_DBG_CONFIG
,
1458 "BSSID: %pM aid: 0x%x\n",
1459 common
->curbssid
, common
->curaid
);
1462 if ((changed
& BSS_CHANGED_BEACON_INT
) ||
1463 (changed
& BSS_CHANGED_BEACON
) ||
1464 ((changed
& BSS_CHANGED_BEACON_ENABLED
) &&
1465 bss_conf
->enable_beacon
)) {
1466 priv
->op_flags
|= OP_ENABLE_BEACON
;
1467 ath9k_htc_beacon_config(priv
, vif
);
1470 if ((changed
& BSS_CHANGED_BEACON_ENABLED
) &&
1471 !bss_conf
->enable_beacon
) {
1472 priv
->op_flags
&= ~OP_ENABLE_BEACON
;
1473 ath9k_htc_beacon_config(priv
, vif
);
1476 if (changed
& BSS_CHANGED_ERP_PREAMBLE
) {
1477 ath_dbg(common
, ATH_DBG_CONFIG
, "BSS Changed PREAMBLE %d\n",
1478 bss_conf
->use_short_preamble
);
1479 if (bss_conf
->use_short_preamble
)
1480 priv
->op_flags
|= OP_PREAMBLE_SHORT
;
1482 priv
->op_flags
&= ~OP_PREAMBLE_SHORT
;
1485 if (changed
& BSS_CHANGED_ERP_CTS_PROT
) {
1486 ath_dbg(common
, ATH_DBG_CONFIG
, "BSS Changed CTS PROT %d\n",
1487 bss_conf
->use_cts_prot
);
1488 if (bss_conf
->use_cts_prot
&&
1489 hw
->conf
.channel
->band
!= IEEE80211_BAND_5GHZ
)
1490 priv
->op_flags
|= OP_PROTECT_ENABLE
;
1492 priv
->op_flags
&= ~OP_PROTECT_ENABLE
;
1495 if (changed
& BSS_CHANGED_ERP_SLOT
) {
1496 if (bss_conf
->use_short_slot
)
1501 ath9k_hw_init_global_settings(ah
);
1504 if (changed
& BSS_CHANGED_HT
)
1505 ath9k_htc_update_rate(priv
, vif
, bss_conf
);
1507 ath9k_htc_ps_restore(priv
);
1508 mutex_unlock(&priv
->mutex
);
1511 static u64
ath9k_htc_get_tsf(struct ieee80211_hw
*hw
)
1513 struct ath9k_htc_priv
*priv
= hw
->priv
;
1516 mutex_lock(&priv
->mutex
);
1517 ath9k_htc_ps_wakeup(priv
);
1518 tsf
= ath9k_hw_gettsf64(priv
->ah
);
1519 ath9k_htc_ps_restore(priv
);
1520 mutex_unlock(&priv
->mutex
);
1525 static void ath9k_htc_set_tsf(struct ieee80211_hw
*hw
, u64 tsf
)
1527 struct ath9k_htc_priv
*priv
= hw
->priv
;
1529 mutex_lock(&priv
->mutex
);
1530 ath9k_htc_ps_wakeup(priv
);
1531 ath9k_hw_settsf64(priv
->ah
, tsf
);
1532 ath9k_htc_ps_restore(priv
);
1533 mutex_unlock(&priv
->mutex
);
1536 static void ath9k_htc_reset_tsf(struct ieee80211_hw
*hw
)
1538 struct ath9k_htc_priv
*priv
= hw
->priv
;
1540 mutex_lock(&priv
->mutex
);
1541 ath9k_htc_ps_wakeup(priv
);
1542 ath9k_hw_reset_tsf(priv
->ah
);
1543 ath9k_htc_ps_restore(priv
);
1544 mutex_unlock(&priv
->mutex
);
1547 static int ath9k_htc_ampdu_action(struct ieee80211_hw
*hw
,
1548 struct ieee80211_vif
*vif
,
1549 enum ieee80211_ampdu_mlme_action action
,
1550 struct ieee80211_sta
*sta
,
1553 struct ath9k_htc_priv
*priv
= hw
->priv
;
1554 struct ath9k_htc_sta
*ista
;
1558 case IEEE80211_AMPDU_RX_START
:
1560 case IEEE80211_AMPDU_RX_STOP
:
1562 case IEEE80211_AMPDU_TX_START
:
1563 ret
= ath9k_htc_tx_aggr_oper(priv
, vif
, sta
, action
, tid
);
1565 ieee80211_start_tx_ba_cb_irqsafe(vif
, sta
->addr
, tid
);
1567 case IEEE80211_AMPDU_TX_STOP
:
1568 ath9k_htc_tx_aggr_oper(priv
, vif
, sta
, action
, tid
);
1569 ieee80211_stop_tx_ba_cb_irqsafe(vif
, sta
->addr
, tid
);
1571 case IEEE80211_AMPDU_TX_OPERATIONAL
:
1572 ista
= (struct ath9k_htc_sta
*) sta
->drv_priv
;
1573 spin_lock_bh(&priv
->tx_lock
);
1574 ista
->tid_state
[tid
] = AGGR_OPERATIONAL
;
1575 spin_unlock_bh(&priv
->tx_lock
);
1578 ath_err(ath9k_hw_common(priv
->ah
), "Unknown AMPDU action\n");
1584 static void ath9k_htc_sw_scan_start(struct ieee80211_hw
*hw
)
1586 struct ath9k_htc_priv
*priv
= hw
->priv
;
1588 mutex_lock(&priv
->mutex
);
1589 spin_lock_bh(&priv
->beacon_lock
);
1590 priv
->op_flags
|= OP_SCANNING
;
1591 spin_unlock_bh(&priv
->beacon_lock
);
1592 cancel_work_sync(&priv
->ps_work
);
1593 if (priv
->op_flags
& OP_ASSOCIATED
)
1594 cancel_delayed_work_sync(&priv
->ath9k_ani_work
);
1595 mutex_unlock(&priv
->mutex
);
1598 static void ath9k_htc_sw_scan_complete(struct ieee80211_hw
*hw
)
1600 struct ath9k_htc_priv
*priv
= hw
->priv
;
1602 mutex_lock(&priv
->mutex
);
1603 ath9k_htc_ps_wakeup(priv
);
1604 spin_lock_bh(&priv
->beacon_lock
);
1605 priv
->op_flags
&= ~OP_SCANNING
;
1606 spin_unlock_bh(&priv
->beacon_lock
);
1607 if (priv
->op_flags
& OP_ASSOCIATED
) {
1608 ath9k_htc_beacon_config(priv
, priv
->vif
);
1609 ath_start_ani(priv
);
1611 ath9k_htc_ps_restore(priv
);
1612 mutex_unlock(&priv
->mutex
);
1615 static int ath9k_htc_set_rts_threshold(struct ieee80211_hw
*hw
, u32 value
)
1620 static void ath9k_htc_set_coverage_class(struct ieee80211_hw
*hw
,
1623 struct ath9k_htc_priv
*priv
= hw
->priv
;
1625 mutex_lock(&priv
->mutex
);
1626 ath9k_htc_ps_wakeup(priv
);
1627 priv
->ah
->coverage_class
= coverage_class
;
1628 ath9k_hw_init_global_settings(priv
->ah
);
1629 ath9k_htc_ps_restore(priv
);
1630 mutex_unlock(&priv
->mutex
);
1633 struct ieee80211_ops ath9k_htc_ops
= {
1635 .start
= ath9k_htc_start
,
1636 .stop
= ath9k_htc_stop
,
1637 .add_interface
= ath9k_htc_add_interface
,
1638 .remove_interface
= ath9k_htc_remove_interface
,
1639 .config
= ath9k_htc_config
,
1640 .configure_filter
= ath9k_htc_configure_filter
,
1641 .sta_add
= ath9k_htc_sta_add
,
1642 .sta_remove
= ath9k_htc_sta_remove
,
1643 .conf_tx
= ath9k_htc_conf_tx
,
1644 .bss_info_changed
= ath9k_htc_bss_info_changed
,
1645 .set_key
= ath9k_htc_set_key
,
1646 .get_tsf
= ath9k_htc_get_tsf
,
1647 .set_tsf
= ath9k_htc_set_tsf
,
1648 .reset_tsf
= ath9k_htc_reset_tsf
,
1649 .ampdu_action
= ath9k_htc_ampdu_action
,
1650 .sw_scan_start
= ath9k_htc_sw_scan_start
,
1651 .sw_scan_complete
= ath9k_htc_sw_scan_complete
,
1652 .set_rts_threshold
= ath9k_htc_set_rts_threshold
,
1653 .rfkill_poll
= ath9k_htc_rfkill_poll_state
,
1654 .set_coverage_class
= ath9k_htc_set_coverage_class
,