This change updates ath5k to do ANI adjustments every 100 ms
using the common ANI code in the ath module.

Signed-off-by: Bob Copeland <m...@bobcopeland.com>
---
 drivers/net/wireless/ath/ani.c          |    6 +++
 drivers/net/wireless/ath/ath5k/ath5k.h  |    4 ++
 drivers/net/wireless/ath/ath5k/attach.c |    7 +++
 drivers/net/wireless/ath/ath5k/base.c   |   69 +++++++++++++++++--------------
 drivers/net/wireless/ath/ath5k/pcu.c    |   24 +++++++++-
 drivers/net/wireless/ath/ath5k/phy.c    |   24 ++++++++--
 6 files changed, 95 insertions(+), 39 deletions(-)

diff --git a/drivers/net/wireless/ath/ani.c b/drivers/net/wireless/ath/ani.c
index c2a09fe..b9fb64e 100644
--- a/drivers/net/wireless/ath/ani.c
+++ b/drivers/net/wireless/ath/ani.c
@@ -107,6 +107,7 @@ static bool ath_hw_ani_control(struct ath_common *common,
                              m2CountThrLow[on]);
 
                /* FIXME not ath5k? */
+#if 0
                REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
                              AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
                              m1ThreshLow[on]);
@@ -119,6 +120,7 @@ static bool ath_hw_ani_control(struct ath_common *common,
                REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
                              AR_PHY_SFCORR_EXT_M2_THRESH,
                              m2Thresh[on]);
+#endif
 
                if (on)
                        REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
@@ -727,8 +729,12 @@ void ath_hw_procmibevent(struct ath_common *common)
        /* Reset these counters regardless */
        REG_WRITE(ah, AR_FILT_OFDM, 0);
        REG_WRITE(ah, AR_FILT_CCK, 0);
+
+       /* FIXME not ath5k? */
+#if 0
        if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING))
                REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR);
+#endif
 
        /* Clear the mib counters and save them in the stats */
        ath_hw_update_mibstats(common, &common->mib_stats);
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h 
b/drivers/net/wireless/ath/ath5k/ath5k.h
index 6a2a967..1da3875 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -203,6 +203,8 @@
 #define AR5K_TUNE_DEFAULT_TXPOWER              25
 #define AR5K_TUNE_TPC_TXPOWER                  false
 #define AR5K_TUNE_HWTXTRIES                    4
+/* ANI poll interval in ms */
+#define AR5K_TUNE_ANI_POLL_INTERVAL            100
 
 #define AR5K_INIT_CARR_SENSE_EN                        1
 
@@ -917,6 +919,7 @@ enum ath5k_int {
 enum ath5k_software_interrupt {
        AR5K_SWI_FULL_CALIBRATION = 0x01,
        AR5K_SWI_SHORT_CALIBRATION = 0x02,
+       AR5K_SWI_ANI_CALIBRATION = 0x03,
 };
 
 /*
@@ -1213,6 +1216,7 @@ extern int ath5k_hw_set_mcast_filter_idx(struct ath5k_hw 
*ah, u32 index);
 extern int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index);
 extern u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah);
 extern void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter);
+extern void ath5k_hw_set_rx_filter_phy_err(void *hw, bool enable);
 /* Beacon control functions */
 extern u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah);
 extern u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah);
diff --git a/drivers/net/wireless/ath/ath5k/attach.c 
b/drivers/net/wireless/ath/ath5k/attach.c
index 4228444..6b4071e 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -25,6 +25,7 @@
 #include "reg.h"
 #include "debug.h"
 #include "base.h"
+#include "../ani.h"
 
 /**
  * ath5k_hw_post - Power On Self Test helper function
@@ -336,6 +337,10 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
        /* turn on HW LEDs */
        ath5k_hw_set_ledstate(ah, AR5K_LED_INIT);
 
+       common->ani.ani_function = ATH_ANI_ALL;
+       ath_hw_ani_setup(common);
+       ath_hw_ani_init(common);
+
        return 0;
 err_free:
        kfree(ah);
@@ -351,6 +356,8 @@ void ath5k_hw_detach(struct ath5k_hw *ah)
 {
        ATH5K_TRACE(ah->ah_sc);
 
+       ath_hw_ani_disable(ath5k_hw_common(ah));
+
        __set_bit(ATH_STAT_INVALID, ah->ah_sc->status);
 
        if (ah->ah_rf_banks != NULL)
diff --git a/drivers/net/wireless/ath/ath5k/base.c 
b/drivers/net/wireless/ath/ath5k/base.c
index 8446863..e40757b 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -58,8 +58,9 @@
 #include "base.h"
 #include "reg.h"
 #include "debug.h"
+#include "../ani.h"
 
-static u8 ath5k_calinterval = 10; /* Calibrate PHY every 10 secs (TODO: Fixme) 
*/
+static u8 ath5k_calinterval = 30; /* Calibrate PHY every 30 secs */
 static int modparam_nohwcrypt;
 module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
 MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
@@ -455,6 +456,7 @@ static void ath5k_iowrite32(void *hw_priv, u32 val, u32 
reg_offset)
 static const struct ath_ops ath5k_common_ops = {
        .read = ath5k_ioread32,
        .write = ath5k_iowrite32,
+       .setrxfilter_phy_err = ath5k_hw_set_rx_filter_phy_err,
 };
 
 static int __devinit
@@ -600,6 +602,12 @@ ath5k_pci_probe(struct pci_dev *pdev,
        common->hw = hw;
        common->cachelsz = csz << 2; /* convert to bytes */
 
+       /* initial default for ANI */
+       common->ani.noise_floor = -95;
+
+    printk(KERN_DEBUG "ath5k: about to attach (ops: %p)\n",
+        common->ops);
+
        /* Initialize device */
        ret = ath5k_hw_attach(sc);
        if (ret) {
@@ -2381,6 +2389,9 @@ ath5k_init(struct ath5k_softc *sc)
         */
        ath5k_stop_locked(sc);
 
+       /* Set PHY calibration inteval */
+       ah->ah_cal_intval = ath5k_calinterval;
+
        /*
         * The basic interface to setting the hardware in a good
         * state is ``reset''.  On return the hardware is known to
@@ -2392,7 +2403,8 @@ ath5k_init(struct ath5k_softc *sc)
        sc->curband = &sc->sbands[sc->curchan->band];
        sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
                AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
-               AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_SWI;
+               AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_SWI |
+               AR5K_INT_MIB;
        ret = ath5k_reset(sc, NULL);
        if (ret)
                goto done;
@@ -2409,9 +2421,6 @@ ath5k_init(struct ath5k_softc *sc)
        /* Set ack to be sent at low bit-rates */
        ath5k_hw_set_ack_bitrate_high(ah, false);
 
-       /* Set PHY calibration inteval */
-       ah->ah_cal_intval = ath5k_calinterval;
-
        ret = 0;
 done:
        mmiowb();
@@ -2566,11 +2575,7 @@ ath5k_intr(int irq, void *dev_id)
                                tasklet_schedule(&sc->calib);
                        }
                        if (status & AR5K_INT_MIB) {
-                               /*
-                                * These stats are also used for ANI i think
-                                * so how about updating them more often ?
-                                */
-                               ath5k_hw_update_mib_counters(ah, &sc->ll_stats);
+                               ath_hw_procmibevent(ath5k_hw_common(ah));
                        }
                        if (status & AR5K_INT_GPIO)
                                tasklet_schedule(&sc->rf_kill.toggleq);
@@ -2604,36 +2609,38 @@ ath5k_tasklet_calibrate(unsigned long data)
        struct ath5k_softc *sc = (void *)data;
        struct ath5k_hw *ah = sc->ah;
 
-       /* Only full calibration for now */
-       if (ah->ah_swi_mask != AR5K_SWI_FULL_CALIBRATION)
+       /* Check for ani/full calibration */
+       if (!(ah->ah_swi_mask &
+             (AR5K_SWI_ANI_CALIBRATION | AR5K_SWI_FULL_CALIBRATION)))
                return;
 
-       /* Stop queues so that calibration
-        * doesn't interfere with tx */
-       ieee80211_stop_queues(sc->hw);
-
-       ATH5K_DBG(sc, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n",
-               ieee80211_frequency_to_channel(sc->curchan->center_freq),
-               sc->curchan->hw_value);
+       if (ah->ah_swi_mask & AR5K_SWI_ANI_CALIBRATION)
+               ath_hw_ani_monitor(ath5k_hw_common(ah));
 
-       if (ath5k_hw_gainf_calibrate(ah) == AR5K_RFGAIN_NEED_CHANGE) {
-               /*
-                * Rfgain is out of bounds, reset the chip
-                * to load new gain values.
-                */
-               ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "calibration, resetting\n");
-               ath5k_reset_wake(sc);
-       }
-       if (ath5k_hw_phy_calibrate(ah, sc->curchan))
-               ATH5K_ERR(sc, "calibration of channel %u failed\n",
+       if (ah->ah_swi_mask & AR5K_SWI_FULL_CALIBRATION) {
+               ATH5K_DBG(sc, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n",
                        ieee80211_frequency_to_channel(
-                               sc->curchan->center_freq));
+                               sc->curchan->center_freq),
+                               sc->curchan->hw_value);
 
+               if (ath5k_hw_gainf_calibrate(ah) == AR5K_RFGAIN_NEED_CHANGE) {
+                       /*
+                        * Rfgain is out of bounds, reset the chip
+                        * to load new gain values.
+                        */
+                       ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
+                               "calibration, resetting\n");
+                       ath5k_reset_wake(sc);
+               }
+               if (ath5k_hw_phy_calibrate(ah, sc->curchan))
+                       ATH5K_ERR(sc, "calibration of channel %u failed\n",
+                                       ieee80211_frequency_to_channel(
+                                               sc->curchan->center_freq));
+       }
        ah->ah_swi_mask = 0;
 
        /* Wake queues */
        ieee80211_wake_queues(sc->hw);
-
 }
 
 
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c 
b/drivers/net/wireless/ath/ath5k/pcu.c
index 64fc1eb..4d26c7a 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -30,6 +30,7 @@
 #include "reg.h"
 #include "debug.h"
 #include "base.h"
+#include "../ani.h"
 
 /*******************\
 * Generic functions *
@@ -337,11 +338,16 @@ void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const 
u8 *mask)
  * (ACK etc).
  *
  * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma
- * TODO: Init ANI here
  */
 void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
 {
+       struct ath_common *common = ath5k_hw_common(ah);
+
        ATH5K_TRACE(ah->ah_sc);
+
+       ath_enable_mib_counters(common);
+       ath_ani_reset(common, ah->ah_current_channel);
+
        AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
 }
 
@@ -352,11 +358,11 @@ void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
  *
  * Stops RX engine on PCU
  *
- * TODO: Detach ANI here
  */
 void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah)
 {
        ATH5K_TRACE(ah->ah_sc);
+       ath_hw_disable_mib_counters(ath5k_hw_common(ah));
        AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
 }
 
@@ -483,9 +489,21 @@ void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 
filter)
        /*Write PHY error filter register on 5212*/
        if (ah->ah_version == AR5K_AR5212)
                ath5k_hw_reg_write(ah, data, AR5K_PHY_ERR_FIL);
-
 }
+EXPORT_SYMBOL(ath5k_hw_set_rx_filter_phy_err);
 
+void ath5k_hw_set_rx_filter_phy_err(void *hw, bool enable)
+{
+       struct ath5k_hw *ah = hw;
+
+       u32 filt = ath5k_hw_get_rx_filter(ah);
+       if (enable)
+               filt |= AR5K_RX_FILTER_PHYERR;
+       else
+               filt &= ~AR5K_RX_FILTER_PHYERR;
+
+       ath5k_hw_set_rx_filter(ah, filt);
+}
 
 /****************\
 * Beacon control *
diff --git a/drivers/net/wireless/ath/ath5k/phy.c 
b/drivers/net/wireless/ath/ath5k/phy.c
index 72474c0..d6be62a 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -1107,23 +1107,37 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct 
ieee80211_channel *channel)
 void
 ath5k_hw_calibration_poll(struct ath5k_hw *ah)
 {
+       struct ath_common *common = ath5k_hw_common(ah);
+
        /* Calibration interval in jiffies */
-       unsigned long cal_intval;
+       unsigned long cal_intval, ani_intval;
 
        cal_intval = msecs_to_jiffies(ah->ah_cal_intval * 1000);
+       ani_intval = msecs_to_jiffies(AR5K_TUNE_ANI_POLL_INTERVAL);
 
-       /* Initialize timestamp if needed */
-       if (!ah->ah_cal_tstamp)
+       /* Initialize timestamps if needed */
+       if (!ah->ah_cal_tstamp || !common->ani.checkani_timer) {
                ah->ah_cal_tstamp = jiffies;
+               common->ani.checkani_timer = jiffies;
+       }
+
+       /* do ani if past ANI calibration window */
+       if (time_is_before_eq_jiffies(common->ani.checkani_timer +
+                                     ani_intval)) {
+               common->ani.checkani_timer = jiffies;
+               ah->ah_swi_mask |= AR5K_SWI_ANI_CALIBRATION;
+       }
 
        /* For now we always do full calibration
         * Mark software interrupt mask and fire software
         * interrupt (bit gets auto-cleared) */
        if (time_is_before_eq_jiffies(ah->ah_cal_tstamp + cal_intval)) {
                ah->ah_cal_tstamp = jiffies;
-               ah->ah_swi_mask = AR5K_SWI_FULL_CALIBRATION;
-               AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI);
+               ah->ah_swi_mask |= AR5K_SWI_FULL_CALIBRATION;
        }
+
+       /* fire software interrupt (bit gets auto-cleared) */
+       AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI);
 }
 
 static int sign_extend(int val, const int nbits)
-- 
1.6.3.3


_______________________________________________
ath5k-devel mailing list
ath5k-devel@lists.ath5k.org
https://lists.ath5k.org/mailman/listinfo/ath5k-devel

Reply via email to