aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorSujith Manoharan <Sujith.Manoharan@atheros.com>2011-02-20 21:19:38 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-02-23 16:25:27 -0500
commita236254c35f04a4d47c701ed3ec4a0b5dcb097b0 (patch)
tree13b0def186e5e9e312bcdb26a116fad4593b0728 /drivers/net
parentffbe7c83cb4a9d05ff49cdc8e2b02b88ccbae826 (diff)
ath9k_htc: Add ANI for AP mode
The time granularity for the ANI task is different for AP and station mode. Signed-off-by: Sujith Manoharan <Sujith.Manoharan@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h9
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c49
3 files changed, 43 insertions, 17 deletions
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index b21942818b1..5b0a21a1427 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -32,6 +32,7 @@
32#include "wmi.h" 32#include "wmi.h"
33 33
34#define ATH_STA_SHORT_CALINTERVAL 1000 /* 1 second */ 34#define ATH_STA_SHORT_CALINTERVAL 1000 /* 1 second */
35#define ATH_AP_SHORT_CALINTERVAL 100 /* 100 ms */
35#define ATH_ANI_POLLINTERVAL 100 /* 100 ms */ 36#define ATH_ANI_POLLINTERVAL 100 /* 100 ms */
36#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */ 37#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */
37#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ 38#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */
@@ -378,6 +379,7 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv);
378#define OP_LED_DEINIT BIT(5) 379#define OP_LED_DEINIT BIT(5)
379#define OP_BT_PRIORITY_DETECTED BIT(6) 380#define OP_BT_PRIORITY_DETECTED BIT(6)
380#define OP_BT_SCAN BIT(7) 381#define OP_BT_SCAN BIT(7)
382#define OP_ANI_RUNNING BIT(8)
381 383
382struct ath9k_htc_priv { 384struct ath9k_htc_priv {
383 struct device *dev; 385 struct device *dev;
@@ -429,7 +431,7 @@ struct ath9k_htc_priv {
429 struct ath9k_htc_rx rx; 431 struct ath9k_htc_rx rx;
430 struct tasklet_struct tx_tasklet; 432 struct tasklet_struct tx_tasklet;
431 struct sk_buff_head tx_queue; 433 struct sk_buff_head tx_queue;
432 struct delayed_work ath9k_ani_work; 434 struct delayed_work ani_work;
433 struct work_struct ps_work; 435 struct work_struct ps_work;
434 struct work_struct fatal_work; 436 struct work_struct fatal_work;
435 437
@@ -484,8 +486,9 @@ void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb,
484int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv); 486int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv);
485void ath9k_htc_station_work(struct work_struct *work); 487void ath9k_htc_station_work(struct work_struct *work);
486void ath9k_htc_aggr_work(struct work_struct *work); 488void ath9k_htc_aggr_work(struct work_struct *work);
487void ath9k_ani_work(struct work_struct *work); 489void ath9k_htc_ani_work(struct work_struct *work);
488void ath_start_ani(struct ath9k_htc_priv *priv); 490void ath9k_htc_start_ani(struct ath9k_htc_priv *priv);
491void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv);
489 492
490int ath9k_tx_init(struct ath9k_htc_priv *priv); 493int ath9k_tx_init(struct ath9k_htc_priv *priv);
491void ath9k_tx_tasklet(unsigned long data); 494void ath9k_tx_tasklet(unsigned long data);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index a7bc26d1bd6..52c6af2d634 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -679,7 +679,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
679 (unsigned long)priv); 679 (unsigned long)priv);
680 tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet, 680 tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet,
681 (unsigned long)priv); 681 (unsigned long)priv);
682 INIT_DELAYED_WORK(&priv->ath9k_ani_work, ath9k_ani_work); 682 INIT_DELAYED_WORK(&priv->ani_work, ath9k_htc_ani_work);
683 INIT_WORK(&priv->ps_work, ath9k_ps_work); 683 INIT_WORK(&priv->ps_work, ath9k_ps_work);
684 INIT_WORK(&priv->fatal_work, ath9k_fatal_work); 684 INIT_WORK(&priv->fatal_work, ath9k_fatal_work);
685 685
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 9733580579a..f384b358b48 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -124,7 +124,7 @@ static void ath9k_htc_vif_reconfig(struct ath9k_htc_priv *priv)
124 ieee80211_iterate_active_interfaces_atomic(priv->hw, 124 ieee80211_iterate_active_interfaces_atomic(priv->hw,
125 ath9k_htc_vif_iter, priv); 125 ath9k_htc_vif_iter, priv);
126 if (priv->rearm_ani) 126 if (priv->rearm_ani)
127 ath_start_ani(priv); 127 ath9k_htc_start_ani(priv);
128 128
129 if (priv->reconfig_beacon) { 129 if (priv->reconfig_beacon) {
130 ath9k_htc_ps_wakeup(priv); 130 ath9k_htc_ps_wakeup(priv);
@@ -192,7 +192,7 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv)
192 mutex_lock(&priv->mutex); 192 mutex_lock(&priv->mutex);
193 ath9k_htc_ps_wakeup(priv); 193 ath9k_htc_ps_wakeup(priv);
194 194
195 cancel_delayed_work_sync(&priv->ath9k_ani_work); 195 ath9k_htc_stop_ani(priv);
196 ieee80211_stop_queues(priv->hw); 196 ieee80211_stop_queues(priv->hw);
197 htc_stop(priv->htc); 197 htc_stop(priv->htc);
198 WMI_CMD(WMI_DISABLE_INTR_CMDID); 198 WMI_CMD(WMI_DISABLE_INTR_CMDID);
@@ -917,7 +917,7 @@ void ath9k_htc_debug_remove_root(void)
917/* ANI */ 917/* ANI */
918/*******/ 918/*******/
919 919
920void ath_start_ani(struct ath9k_htc_priv *priv) 920void ath9k_htc_start_ani(struct ath9k_htc_priv *priv)
921{ 921{
922 struct ath_common *common = ath9k_hw_common(priv->ah); 922 struct ath_common *common = ath9k_hw_common(priv->ah);
923 unsigned long timestamp = jiffies_to_msecs(jiffies); 923 unsigned long timestamp = jiffies_to_msecs(jiffies);
@@ -926,15 +926,22 @@ void ath_start_ani(struct ath9k_htc_priv *priv)
926 common->ani.shortcal_timer = timestamp; 926 common->ani.shortcal_timer = timestamp;
927 common->ani.checkani_timer = timestamp; 927 common->ani.checkani_timer = timestamp;
928 928
929 ieee80211_queue_delayed_work(common->hw, &priv->ath9k_ani_work, 929 priv->op_flags |= OP_ANI_RUNNING;
930
931 ieee80211_queue_delayed_work(common->hw, &priv->ani_work,
930 msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); 932 msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
931} 933}
932 934
933void ath9k_ani_work(struct work_struct *work) 935void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv)
936{
937 cancel_delayed_work_sync(&priv->ani_work);
938 priv->op_flags &= ~OP_ANI_RUNNING;
939}
940
941void ath9k_htc_ani_work(struct work_struct *work)
934{ 942{
935 struct ath9k_htc_priv *priv = 943 struct ath9k_htc_priv *priv =
936 container_of(work, struct ath9k_htc_priv, 944 container_of(work, struct ath9k_htc_priv, ani_work.work);
937 ath9k_ani_work.work);
938 struct ath_hw *ah = priv->ah; 945 struct ath_hw *ah = priv->ah;
939 struct ath_common *common = ath9k_hw_common(ah); 946 struct ath_common *common = ath9k_hw_common(ah);
940 bool longcal = false; 947 bool longcal = false;
@@ -943,7 +950,8 @@ void ath9k_ani_work(struct work_struct *work)
943 unsigned int timestamp = jiffies_to_msecs(jiffies); 950 unsigned int timestamp = jiffies_to_msecs(jiffies);
944 u32 cal_interval, short_cal_interval; 951 u32 cal_interval, short_cal_interval;
945 952
946 short_cal_interval = ATH_STA_SHORT_CALINTERVAL; 953 short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ?
954 ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL;
947 955
948 /* Only calibrate if awake */ 956 /* Only calibrate if awake */
949 if (ah->power_mode != ATH9K_PM_AWAKE) 957 if (ah->power_mode != ATH9K_PM_AWAKE)
@@ -1012,7 +1020,7 @@ set_timer:
1012 if (!common->ani.caldone) 1020 if (!common->ani.caldone)
1013 cal_interval = min(cal_interval, (u32)short_cal_interval); 1021 cal_interval = min(cal_interval, (u32)short_cal_interval);
1014 1022
1015 ieee80211_queue_delayed_work(common->hw, &priv->ath9k_ani_work, 1023 ieee80211_queue_delayed_work(common->hw, &priv->ani_work,
1016 msecs_to_jiffies(cal_interval)); 1024 msecs_to_jiffies(cal_interval));
1017} 1025}
1018 1026
@@ -1166,7 +1174,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
1166 cancel_work_sync(&priv->fatal_work); 1174 cancel_work_sync(&priv->fatal_work);
1167 cancel_work_sync(&priv->ps_work); 1175 cancel_work_sync(&priv->ps_work);
1168 cancel_delayed_work_sync(&priv->ath9k_led_blink_work); 1176 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
1169 cancel_delayed_work_sync(&priv->ath9k_ani_work); 1177 ath9k_htc_stop_ani(priv);
1170 ath9k_led_stop_brightness(priv); 1178 ath9k_led_stop_brightness(priv);
1171 1179
1172 mutex_lock(&priv->mutex); 1180 mutex_lock(&priv->mutex);
@@ -1271,6 +1279,10 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1271 INC_VIF(priv, vif->type); 1279 INC_VIF(priv, vif->type);
1272 ath9k_htc_set_opmode(priv); 1280 ath9k_htc_set_opmode(priv);
1273 1281
1282 if ((priv->ah->opmode == NL80211_IFTYPE_AP) &&
1283 !(priv->op_flags & OP_ANI_RUNNING))
1284 ath9k_htc_start_ani(priv);
1285
1274 ath_dbg(common, ATH_DBG_CONFIG, 1286 ath_dbg(common, ATH_DBG_CONFIG,
1275 "Attach a VIF of type: %d at idx: %d\n", vif->type, avp->index); 1287 "Attach a VIF of type: %d at idx: %d\n", vif->type, avp->index);
1276 1288
@@ -1307,6 +1319,17 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
1307 DEC_VIF(priv, vif->type); 1319 DEC_VIF(priv, vif->type);
1308 ath9k_htc_set_opmode(priv); 1320 ath9k_htc_set_opmode(priv);
1309 1321
1322 /*
1323 * Stop ANI only if there are no associated station interfaces.
1324 */
1325 if ((vif->type == NL80211_IFTYPE_AP) && (priv->num_ap_vif == 0)) {
1326 priv->rearm_ani = false;
1327 ieee80211_iterate_active_interfaces_atomic(priv->hw,
1328 ath9k_htc_vif_iter, priv);
1329 if (!priv->rearm_ani)
1330 ath9k_htc_stop_ani(priv);
1331 }
1332
1310 ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface at idx: %d\n", avp->index); 1333 ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface at idx: %d\n", avp->index);
1311 1334
1312 ath9k_htc_ps_restore(priv); 1335 ath9k_htc_ps_restore(priv);
@@ -1582,9 +1605,9 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
1582 bss_conf->assoc); 1605 bss_conf->assoc);
1583 1606
1584 if (bss_conf->assoc) 1607 if (bss_conf->assoc)
1585 ath_start_ani(priv); 1608 ath9k_htc_start_ani(priv);
1586 else 1609 else
1587 cancel_delayed_work_sync(&priv->ath9k_ani_work); 1610 ath9k_htc_stop_ani(priv);
1588 } 1611 }
1589 1612
1590 if (changed & BSS_CHANGED_BSSID) { 1613 if (changed & BSS_CHANGED_BSSID) {
@@ -1713,7 +1736,7 @@ static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw)
1713 priv->op_flags |= OP_SCANNING; 1736 priv->op_flags |= OP_SCANNING;
1714 spin_unlock_bh(&priv->beacon_lock); 1737 spin_unlock_bh(&priv->beacon_lock);
1715 cancel_work_sync(&priv->ps_work); 1738 cancel_work_sync(&priv->ps_work);
1716 cancel_delayed_work_sync(&priv->ath9k_ani_work); 1739 ath9k_htc_stop_ani(priv);
1717 mutex_unlock(&priv->mutex); 1740 mutex_unlock(&priv->mutex);
1718} 1741}
1719 1742