2010-10-03 17:07:26

by Felix Fietkau

[permalink] [raw]
Subject: [PATCH 1/4] ath9k_hw: clean up calibration flags

The calibration actual calibration flags are only used by the per chip family
source files, so it makes more sense to define them in those files instead
of globally. That way the code has to test for less flags.

Also instead of using a separate callback for testing whether a particular
calibration type is supported, simply adjust ah->supp_cals in the calibration
init which is called right after the hardware reset, before any of the
calibrations are run.

Signed-off-by: Felix Fietkau <[email protected]>
---
drivers/net/wireless/ath/ath9k/ar9002_calib.c | 51 ++++++++++---------------
drivers/net/wireless/ath/ath9k/ar9003_calib.c | 36 ++++-------------
drivers/net/wireless/ath/ath9k/calib.c | 2 +-
drivers/net/wireless/ath/ath9k/calib.h | 9 +----
drivers/net/wireless/ath/ath9k/hw-ops.h | 6 ---
drivers/net/wireless/ath/ath9k/hw.h | 4 +-
6 files changed, 31 insertions(+), 77 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index f2da119..f0525fb 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -20,6 +20,13 @@

#define AR9285_CLCAL_REDO_THRESH 1

+enum ar9002_cal_types {
+ ADC_GAIN_CAL = BIT(0),
+ ADC_DC_CAL = BIT(1),
+ IQ_MISMATCH_CAL = BIT(2),
+};
+
+
static void ar9002_hw_setup_calibration(struct ath_hw *ah,
struct ath9k_cal_list *currCal)
{
@@ -45,8 +52,6 @@ static void ar9002_hw_setup_calibration(struct ath_hw *ah,
ath_print(common, ATH_DBG_CALIBRATE,
"starting ADC DC Calibration\n");
break;
- case TEMP_COMP_CAL:
- break; /* Not supported */
}

REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
@@ -91,25 +96,6 @@ static bool ar9002_hw_per_calibration(struct ath_hw *ah,
return iscaldone;
}

-/* Assumes you are talking about the currently configured channel */
-static bool ar9002_hw_iscal_supported(struct ath_hw *ah,
- enum ath9k_cal_types calType)
-{
- struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
-
- switch (calType & ah->supp_cals) {
- case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */
- return true;
- case ADC_GAIN_CAL:
- case ADC_DC_CAL:
- if (!(conf->channel->band == IEEE80211_BAND_2GHZ &&
- conf_is_ht20(conf)))
- return true;
- break;
- }
- return false;
-}
-
static void ar9002_hw_iqcal_collect(struct ath_hw *ah)
{
int i;
@@ -872,24 +858,28 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)

/* Enable IQ, ADC Gain and ADC DC offset CALs */
if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
- if (ar9002_hw_iscal_supported(ah, ADC_GAIN_CAL)) {
+ ah->supp_cals = IQ_MISMATCH_CAL;
+
+ if (AR_SREV_9160_10_OR_LATER(ah) &&
+ !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan))) {
+ ah->supp_cals |= ADC_GAIN_CAL | ADC_DC_CAL;
+
+
INIT_CAL(&ah->adcgain_caldata);
INSERT_CAL(ah, &ah->adcgain_caldata);
ath_print(common, ATH_DBG_CALIBRATE,
"enabling ADC Gain Calibration.\n");
- }
- if (ar9002_hw_iscal_supported(ah, ADC_DC_CAL)) {
+
INIT_CAL(&ah->adcdc_caldata);
INSERT_CAL(ah, &ah->adcdc_caldata);
ath_print(common, ATH_DBG_CALIBRATE,
"enabling ADC DC Calibration.\n");
}
- if (ar9002_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
- INIT_CAL(&ah->iq_caldata);
- INSERT_CAL(ah, &ah->iq_caldata);
- ath_print(common, ATH_DBG_CALIBRATE,
- "enabling IQ Calibration.\n");
- }
+
+ INIT_CAL(&ah->iq_caldata);
+ INSERT_CAL(ah, &ah->iq_caldata);
+ ath_print(common, ATH_DBG_CALIBRATE,
+ "enabling IQ Calibration.\n");

ah->cal_list_curr = ah->cal_list;

@@ -980,7 +970,6 @@ void ar9002_hw_attach_calib_ops(struct ath_hw *ah)
priv_ops->init_cal_settings = ar9002_hw_init_cal_settings;
priv_ops->init_cal = ar9002_hw_init_cal;
priv_ops->setup_calibration = ar9002_hw_setup_calibration;
- priv_ops->iscal_supported = ar9002_hw_iscal_supported;

ops->calibrate = ar9002_hw_calibrate;
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index b41f5cd..9e6edff 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -18,6 +18,11 @@
#include "hw-ops.h"
#include "ar9003_phy.h"

+enum ar9003_cal_types {
+ IQ_MISMATCH_CAL = BIT(0),
+ TEMP_COMP_CAL = BIT(1),
+};
+
static void ar9003_hw_setup_calibration(struct ath_hw *ah,
struct ath9k_cal_list *currCal)
{
@@ -50,10 +55,6 @@ static void ar9003_hw_setup_calibration(struct ath_hw *ah,
ath_print(common, ATH_DBG_CALIBRATE,
"starting Temperature Compensation Calibration\n");
break;
- case ADC_GAIN_CAL:
- case ADC_DC_CAL:
- /* Not yet */
- break;
}
}

@@ -313,27 +314,6 @@ static const struct ath9k_percal_data iq_cal_single_sample = {
static void ar9003_hw_init_cal_settings(struct ath_hw *ah)
{
ah->iq_caldata.calData = &iq_cal_single_sample;
- ah->supp_cals = IQ_MISMATCH_CAL;
-}
-
-static bool ar9003_hw_iscal_supported(struct ath_hw *ah,
- enum ath9k_cal_types calType)
-{
- switch (calType & ah->supp_cals) {
- case IQ_MISMATCH_CAL:
- /*
- * XXX: Run IQ Mismatch for non-CCK only
- * Note that CHANNEL_B is never set though.
- */
- return true;
- case ADC_GAIN_CAL:
- case ADC_DC_CAL:
- return false;
- case TEMP_COMP_CAL:
- return true;
- }
-
- return false;
}

/*
@@ -772,15 +752,16 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,

/* Initialize list pointers */
ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
+ ah->supp_cals = IQ_MISMATCH_CAL;

- if (ar9003_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
+ if (ah->supp_cals & IQ_MISMATCH_CAL) {
INIT_CAL(&ah->iq_caldata);
INSERT_CAL(ah, &ah->iq_caldata);
ath_print(common, ATH_DBG_CALIBRATE,
"enabling IQ Calibration.\n");
}

- if (ar9003_hw_iscal_supported(ah, TEMP_COMP_CAL)) {
+ if (ah->supp_cals & TEMP_COMP_CAL) {
INIT_CAL(&ah->tempCompCalData);
INSERT_CAL(ah, &ah->tempCompCalData);
ath_print(common, ATH_DBG_CALIBRATE,
@@ -807,7 +788,6 @@ void ar9003_hw_attach_calib_ops(struct ath_hw *ah)
priv_ops->init_cal_settings = ar9003_hw_init_cal_settings;
priv_ops->init_cal = ar9003_hw_init_cal;
priv_ops->setup_calibration = ar9003_hw_setup_calibration;
- priv_ops->iscal_supported = ar9003_hw_iscal_supported;

ops->calibrate = ar9003_hw_calibrate;
}
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 6351e76..6c38c72 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -186,7 +186,7 @@ bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
return true;
}

- if (!ath9k_hw_iscal_supported(ah, currCal->calData->calType))
+ if (!(ah->supp_cals & currCal->calData->calType))
return true;

ath_print(common, ATH_DBG_CALIBRATE,
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
index 1fa56c9..b8973eb 100644
--- a/drivers/net/wireless/ath/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -58,13 +58,6 @@ struct ar5416IniArray {
} \
} while (0)

-enum ath9k_cal_types {
- ADC_GAIN_CAL = 0x2,
- ADC_DC_CAL = 0x4,
- IQ_MISMATCH_CAL = 0x8,
- TEMP_COMP_CAL = 0x10,
-};
-
enum ath9k_cal_state {
CAL_INACTIVE,
CAL_WAITING,
@@ -79,7 +72,7 @@ enum ath9k_cal_state {
#define PER_MAX_LOG_COUNT 10

struct ath9k_percal_data {
- enum ath9k_cal_types calType;
+ u32 calType;
u32 calNumSamples;
u32 calCountMax;
void (*calCollect) (struct ath_hw *);
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index ffecbad..9c4dd0e 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -276,12 +276,6 @@ static inline void ath9k_hw_setup_calibration(struct ath_hw *ah,
ath9k_hw_private_ops(ah)->setup_calibration(ah, currCal);
}

-static inline bool ath9k_hw_iscal_supported(struct ath_hw *ah,
- enum ath9k_cal_types calType)
-{
- return ath9k_hw_private_ops(ah)->iscal_supported(ah, calType);
-}
-
static inline void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
{
ath9k_hw_private_ops(ah)->ani_reset(ah, is_scanning);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 235cb53..246c707 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -535,8 +535,6 @@ struct ath_hw_private_ops {
bool (*macversion_supported)(u32 macversion);
void (*setup_calibration)(struct ath_hw *ah,
struct ath9k_cal_list *currCal);
- bool (*iscal_supported)(struct ath_hw *ah,
- enum ath9k_cal_types calType);

/* PHY ops */
int (*rf_set_freq)(struct ath_hw *ah,
@@ -689,7 +687,7 @@ struct ath_hw {
u32 atim_window;

/* Calibration */
- enum ath9k_cal_types supp_cals;
+ u32 supp_cals;
struct ath9k_cal_list iq_caldata;
struct ath9k_cal_list adcgain_caldata;
struct ath9k_cal_list adcdc_caldata;
--
1.7.2.2



2010-10-03 17:07:26

by Felix Fietkau

[permalink] [raw]
Subject: [PATCH 2/4] ath9k_hw: merge codepaths that access the cycle counter registers

The cycle counters are used by ANI to determine the amount of time that the
radio spent not receiving or transmitting. They're also used for debugging
purposes if the baseband watchdog on AR9003 detects a lockup.
In the future, we want to use these counters to determine the medium utilization
and export this information via survey. For that, we need to make sure that
the counter is only accessed from one place, which also ensures that
wraparounds won't occur at inconvenient points in time.

Signed-off-by: Felix Fietkau <[email protected]>
---
drivers/net/wireless/ath/ath9k/ani.c | 119 +++++++++++----------------
drivers/net/wireless/ath/ath9k/ani.h | 13 ++-
drivers/net/wireless/ath/ath9k/ar5008_phy.c | 9 +--
drivers/net/wireless/ath/ath9k/ar9003_phy.c | 14 ++--
drivers/net/wireless/ath/ath9k/hw.h | 2 +
5 files changed, 65 insertions(+), 92 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 0496f96..9936297 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -549,47 +549,15 @@ static u8 ath9k_hw_chan_2_clockrate_mhz(struct ath_hw *ah)

static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah)
{
- struct ar5416AniState *aniState;
- struct ath_common *common = ath9k_hw_common(ah);
- u32 txFrameCount, rxFrameCount, cycleCount;
- int32_t listenTime;
-
- txFrameCount = REG_READ(ah, AR_TFCNT);
- rxFrameCount = REG_READ(ah, AR_RFCNT);
- cycleCount = REG_READ(ah, AR_CCCNT);
-
- aniState = ah->curani;
- if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) {
- listenTime = 0;
- ah->stats.ast_ani_lzero++;
- ath_print(common, ATH_DBG_ANI,
- "1st call: aniState->cycleCount=%d\n",
- aniState->cycleCount);
- } else {
- int32_t ccdelta = cycleCount - aniState->cycleCount;
- int32_t rfdelta = rxFrameCount - aniState->rxFrameCount;
- int32_t tfdelta = txFrameCount - aniState->txFrameCount;
- int32_t clock_rate;
-
- /*
- * convert HW counter values to ms using mode
- * specifix clock rate
- */
- clock_rate = ath9k_hw_chan_2_clockrate_mhz(ah) * 1000;;
+ int32_t listen_time;
+ int32_t clock_rate;

- listenTime = (ccdelta - rfdelta - tfdelta) / clock_rate;
+ ath9k_hw_update_cycle_counters(ah);
+ clock_rate = ath9k_hw_chan_2_clockrate_mhz(ah) * 1000;
+ listen_time = ah->listen_time / clock_rate;
+ ah->listen_time = 0;

- ath_print(common, ATH_DBG_ANI,
- "cyclecount=%d, rfcount=%d, "
- "tfcount=%d, listenTime=%d CLOCK_RATE=%d\n",
- ccdelta, rfdelta, tfdelta, listenTime, clock_rate);
- }
-
- aniState->cycleCount = cycleCount;
- aniState->txFrameCount = txFrameCount;
- aniState->rxFrameCount = rxFrameCount;
-
- return listenTime;
+ return listen_time;
}

static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
@@ -1041,45 +1009,52 @@ void ath9k_hw_disable_mib_counters(struct ath_hw *ah)
}
EXPORT_SYMBOL(ath9k_hw_disable_mib_counters);

-u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah,
- u32 *rxc_pcnt,
- u32 *rxf_pcnt,
- u32 *txf_pcnt)
+void ath9k_hw_update_cycle_counters(struct ath_hw *ah)
{
- struct ath_common *common = ath9k_hw_common(ah);
- static u32 cycles, rx_clear, rx_frame, tx_frame;
- u32 good = 1;
+ struct ath_cycle_counters cc;
+ bool clear;

- u32 rc = REG_READ(ah, AR_RCCNT);
- u32 rf = REG_READ(ah, AR_RFCNT);
- u32 tf = REG_READ(ah, AR_TFCNT);
- u32 cc = REG_READ(ah, AR_CCCNT);
+ memcpy(&cc, &ah->cc, sizeof(cc));

- if (cycles == 0 || cycles > cc) {
- ath_print(common, ATH_DBG_ANI,
- "cycle counter wrap. ExtBusy = 0\n");
- good = 0;
- } else {
- u32 cc_d = cc - cycles;
- u32 rc_d = rc - rx_clear;
- u32 rf_d = rf - rx_frame;
- u32 tf_d = tf - tx_frame;
-
- if (cc_d != 0) {
- *rxc_pcnt = rc_d * 100 / cc_d;
- *rxf_pcnt = rf_d * 100 / cc_d;
- *txf_pcnt = tf_d * 100 / cc_d;
- } else {
- good = 0;
- }
+ /* freeze counters */
+ REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
+
+ ah->cc.cycles = REG_READ(ah, AR_CCCNT);
+ if (ah->cc.cycles < cc.cycles) {
+ clear = true;
+ goto skip;
}

- cycles = cc;
- rx_frame = rf;
- rx_clear = rc;
- tx_frame = tf;
+ ah->cc.rx_clear = REG_READ(ah, AR_RCCNT);
+ ah->cc.rx_frame = REG_READ(ah, AR_RFCNT);
+ ah->cc.tx_frame = REG_READ(ah, AR_TFCNT);
+
+ /* prevent wraparound */
+ if (ah->cc.cycles & BIT(31))
+ clear = true;
+
+#define CC_DELTA(_field, _reg) ah->cc_delta._field += ah->cc._field - cc._field
+ CC_DELTA(cycles, AR_CCCNT);
+ CC_DELTA(rx_frame, AR_RFCNT);
+ CC_DELTA(rx_clear, AR_RCCNT);
+ CC_DELTA(tx_frame, AR_TFCNT);
+#undef CC_DELTA
+
+ ah->listen_time += (ah->cc.cycles - cc.cycles) -
+ ((ah->cc.rx_frame - cc.rx_frame) +
+ (ah->cc.tx_frame - cc.tx_frame));
+
+skip:
+ if (clear) {
+ REG_WRITE(ah, AR_CCCNT, 0);
+ REG_WRITE(ah, AR_RFCNT, 0);
+ REG_WRITE(ah, AR_RCCNT, 0);
+ REG_WRITE(ah, AR_TFCNT, 0);
+ memset(&ah->cc, 0, sizeof(ah->cc));
+ }

- return good;
+ /* unfreeze counters */
+ REG_WRITE(ah, AR_MIBC, 0);
}

/*
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
index f4d0a4d..15f9d67 100644
--- a/drivers/net/wireless/ath/ath9k/ani.h
+++ b/drivers/net/wireless/ath/ath9k/ani.h
@@ -93,6 +93,13 @@ struct ath9k_mib_stats {
u32 beacons;
};

+struct ath_cycle_counters {
+ u32 cycles;
+ u32 rx_frame;
+ u32 rx_clear;
+ u32 tx_frame;
+};
+
/* INI default values for ANI registers */
struct ath9k_ani_default {
u16 m1ThreshLow;
@@ -130,9 +137,6 @@ struct ar5416AniState {
int32_t rssiThrLow;
int32_t rssiThrHigh;
u32 noiseFloor;
- u32 txFrameCount;
- u32 rxFrameCount;
- u32 cycleCount;
u32 ofdmPhyErrCount;
u32 cckPhyErrCount;
u32 ofdmPhyErrBase;
@@ -166,8 +170,7 @@ struct ar5416Stats {

void ath9k_enable_mib_counters(struct ath_hw *ah);
void ath9k_hw_disable_mib_counters(struct ath_hw *ah);
-u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt,
- u32 *rxf_pcnt, u32 *txf_pcnt);
+void ath9k_hw_update_cycle_counters(struct ath_hw *ah);
void ath9k_hw_ani_setup(struct ath_hw *ah);
void ath9k_hw_ani_init(struct ath_hw *ah);
int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 3937cfd..74b4213 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -1227,8 +1227,7 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah,
aniState->firstepLevel,
aniState->listenTime);
ath_print(common, ATH_DBG_ANI,
- "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
- aniState->cycleCount,
+ "ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
aniState->ofdmPhyErrCount,
aniState->cckPhyErrCount);

@@ -1480,15 +1479,13 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,

ath_print(common, ATH_DBG_ANI,
"ANI parameters: SI=%d, ofdmWS=%s FS=%d "
- "MRCcck=%s listenTime=%d CC=%d listen=%d "
+ "MRCcck=%s listenTime=%d "
"ofdmErrs=%d cckErrs=%d\n",
aniState->spurImmunityLevel,
!aniState->ofdmWeakSigDetectOff ? "on" : "off",
aniState->firstepLevel,
!aniState->mrcCCKOff ? "on" : "off",
aniState->listenTime,
- aniState->cycleCount,
- aniState->listenTime,
aniState->ofdmPhyErrCount,
aniState->cckPhyErrCount);
return true;
@@ -1581,8 +1578,6 @@ static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah)
aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG;
aniState->mrcCCKOff = true; /* not available on pre AR9003 */
-
- aniState->cycleCount = 0;
}

static void ar5008_hw_set_nf_limits(struct ath_hw *ah)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index a491854..e15574c 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -1005,15 +1005,13 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,

ath_print(common, ATH_DBG_ANI,
"ANI parameters: SI=%d, ofdmWS=%s FS=%d "
- "MRCcck=%s listenTime=%d CC=%d listen=%d "
+ "MRCcck=%s listenTime=%d "
"ofdmErrs=%d cckErrs=%d\n",
aniState->spurImmunityLevel,
!aniState->ofdmWeakSigDetectOff ? "on" : "off",
aniState->firstepLevel,
!aniState->mrcCCKOff ? "on" : "off",
aniState->listenTime,
- aniState->cycleCount,
- aniState->listenTime,
aniState->ofdmPhyErrCount,
aniState->cckPhyErrCount);
return true;
@@ -1116,8 +1114,6 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG;
aniState->mrcCCKOff = !ATH9K_ANI_ENABLE_MRC_CCK;
-
- aniState->cycleCount = 0;
}

void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
@@ -1232,7 +1228,7 @@ void ar9003_hw_bb_watchdog_read(struct ath_hw *ah)
void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
- u32 rxc_pcnt = 0, rxf_pcnt = 0, txf_pcnt = 0, status;
+ u32 status;

if (likely(!(common->debug_mask & ATH_DBG_RESET)))
return;
@@ -1261,11 +1257,13 @@ void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah)
"** BB mode: BB_gen_controls=0x%08x **\n",
REG_READ(ah, AR_PHY_GEN_CTRL));

- if (ath9k_hw_GetMibCycleCountsPct(ah, &rxc_pcnt, &rxf_pcnt, &txf_pcnt))
+ ath9k_hw_update_cycle_counters(ah);
+#define PCT(_field) (ah->cc_delta._field * 100 / ah->cc_delta.cycles)
+ if (ah->cc_delta.cycles)
ath_print(common, ATH_DBG_RESET,
"** BB busy times: rx_clear=%d%%, "
"rx_frame=%d%%, tx_frame=%d%% **\n",
- rxc_pcnt, rxf_pcnt, txf_pcnt);
+ PCT(rx_clear), PCT(rx_frame), PCT(tx_frame));

ath_print(common, ATH_DBG_RESET,
"==== BB update: done ====\n\n");
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 246c707..87dbb85 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -765,6 +765,8 @@ struct ath_hw {
int coarse_low[5];
int firpwr[5];
enum ath9k_ani_cmd ani_function;
+ struct ath_cycle_counters cc, cc_delta;
+ int32_t listen_time;

/* Bluetooth coexistance */
struct ath_btcoex_hw btcoex_hw;
--
1.7.2.2


2010-10-04 11:53:38

by Felix Fietkau

[permalink] [raw]
Subject: Re: [PATCH 3/4] ath9k_hw: clean up register write buffering

On 2010-10-04 10:56 AM, Rajkumar Manoharan wrote:
> On Sun, Oct 03, 2010 at 10:37:18PM +0530, Felix Fietkau wrote:
>> static void ath9k_regwrite_flush(void *hw_priv)
>> {
>> struct ath_hw *ah = (struct ath_hw *) hw_priv;
>> @@ -397,6 +388,9 @@ static void ath9k_regwrite_flush(void *hw_priv)
>> u32 rsp_status;
>> int r;
>>
>> + if (!atomic_dec_and_test(&priv->wmi->mwrite_cnt))
>> + return;
>> +
> FMU, Assume that mwrite_cnt > 1 and a reg_read happens after a flush whose value
> depends on issued reg_write, the above check skips reg_write.
> The buffered commands only issued either mwrite_cnt reaches zero or
> buffer reaches MAX limit.
OK, makes sense, I'll resend.

- Felix

Subject: Re: [PATCH 2/4] ath9k_hw: merge codepaths that access the cycle counter registers

> + /* freeze counters */
> + REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
> +
> + ah->cc.cycles = REG_READ(ah, AR_CCCNT);
> + if (ah->cc.cycles < cc.cycles) {
> + clear = true;
> + goto skip;
> }
>
> - cycles = cc;
> - rx_frame = rf;
> - rx_clear = rc;
> - tx_frame = tf;
> + ah->cc.rx_clear = REG_READ(ah, AR_RCCNT);
> + ah->cc.rx_frame = REG_READ(ah, AR_RFCNT);
> + ah->cc.tx_frame = REG_READ(ah, AR_TFCNT);
> +
> + /* prevent wraparound */
> + if (ah->cc.cycles & BIT(31))
> + clear = true;

This does not look right, previous if should take care of
any wrap around.

> +
> +#define CC_DELTA(_field, _reg) ah->cc_delta._field += ah->cc._field - cc._field
_reg is not used.

>
> +skip:
> + if (clear) {
> + REG_WRITE(ah, AR_CCCNT, 0);
> + REG_WRITE(ah, AR_RFCNT, 0);
> + REG_WRITE(ah, AR_RCCNT, 0);
> + REG_WRITE(ah, AR_TFCNT, 0);

should be able to do with single write in AR_MIBC.

> + /* unfreeze counters */
> + REG_WRITE(ah, AR_MIBC, 0);

Please configure the relevant bit to unfreeze the counters.

Vasanth

2010-10-05 04:39:02

by Senthil Balasubramanian

[permalink] [raw]
Subject: Re: [PATCH v2 3/4] ath9k_hw: clean up register write buffering

On Mon, Oct 04, 2010 at 10:52:38PM +0530, Felix Fietkau wrote:
> Merge those two ops and also ensure that the flush is only issued after
> all codepaths are done buffering.
I guess this comment is not applicable anymore with this patch and can be
removed.

2010-10-05 09:59:14

by Bruno Randolf

[permalink] [raw]
Subject: Re: [PATCH 2/4] ath9k_hw: merge codepaths that access the cycle counter registers

On Mon October 4 2010 21:51:40 Felix Fietkau wrote:
> On 2010-10-04 2:24 PM, Vasanthakumar Thiagarajan wrote:
> >> >> + /* unfreeze counters */
> >> >> + REG_WRITE(ah, AR_MIBC, 0);
> >> >
> >> > Please configure the relevant bit to unfreeze the counters.
> >>
> >> What do you mean?
> >
> > AR_MIBC does more than just freeze/unfreeze the counters, though I
> > dont see any issues with setting the whole register to zero, it
> > looks buggy. Please configure only the relevant bit to
> > freeze/unfreeze the counters.
>
> Other places in the code set it to zero as well, though sometimes
> written in a weird way. I also checked the specs, there is no bit that's
> supposed to be active at this point.

hi!

i just sent a patch series, which moves that function to common, to be shared
between ath5k and ath9k. i implemented it in a rather simple way, i admit, but
it hope that it is sufficient anyways. the patch series should also include
what is left from this patch. could you please check and let me know what you
think?

thanks,
bruno

2010-10-03 19:10:51

by Felix Fietkau

[permalink] [raw]
Subject: Re: [PATCH 4/4] ath9k_hw: fix regression in ANI listen time calculation

On 2010-10-03 9:08 PM, Felix Fietkau wrote:
> On 2010-10-03 7:24 PM, Luis R. Rodriguez wrote:
>> On Sun, Oct 3, 2010 at 10:07 AM, Felix Fietkau <[email protected]> wrote:
>>> wireless-testing
>>> commit 37e5bf6535a4d697fb9fa6f268a8354a612cbc00
>>> Author: Luis R. Rodriguez <[email protected]>
>>> Date: Sat Jun 12 00:33:40 2010 -0400
>>>
>>> ath9k_hw: fix clock rate calculations for ANI
>>>
>>> This commit accidentally broke clock rate calculation by doubling the
>>> calculated clock rate
>>>
>>> Signed-off-by: Felix Fietkau <[email protected]>
>>
>> Thanks, are you aware of the impact, is this a stable regression fix?
> I just checked, looks like this is a stable fix. The impact is that ANI
> will probably pick settings with higher numbers of OFDM/CCK misdetects.
> I'll resend with Cc: stable
Never mind. It's not a stable fix after all, git-describe confused me ;)

- Felix

2010-10-06 20:45:06

by John W. Linville

[permalink] [raw]
Subject: Re: [PATCH v3 3/4] ath9k_hw: clean up register write buffering

On Tue, Oct 05, 2010 at 12:03:42PM +0200, Felix Fietkau wrote:
> Throughout the code, DISABLE_REGWRITE_BUFFER is always called right after
> REGWRITE_BUFFER_FLUSH. Since that's unlikely to change any time soon, that
> makes keeping those ops separate rather pointless, as it only increases
> code size and line number counts.
>
> Signed-off-by: Felix Fietkau <[email protected]>
> ---
> drivers/net/wireless/ath/ath.h | 4 +---
> drivers/net/wireless/ath/ath9k/ani.c | 6 ------
> drivers/net/wireless/ath/ath9k/ar5008_phy.c | 9 ++-------
> drivers/net/wireless/ath/ath9k/ar9002_calib.c | 1 -
> drivers/net/wireless/ath/ath9k/ar9002_hw.c | 4 ----
> drivers/net/wireless/ath/ath9k/ar9002_phy.c | 1 -
> drivers/net/wireless/ath/ath9k/calib.c | 1 -
> drivers/net/wireless/ath/ath9k/eeprom_4k.c | 2 --
> drivers/net/wireless/ath/ath9k/htc_drv_init.c | 12 ++----------
> drivers/net/wireless/ath/ath9k/hw.c | 14 --------------
> drivers/net/wireless/ath/ath9k/hw.h | 10 ++--------
> drivers/net/wireless/ath/ath9k/mac.c | 4 ----
> 12 files changed, 7 insertions(+), 61 deletions(-)
>
> v2: removed mwrite_cnt test
> v3: removed comment about it from description

Several patch hunks are buggered...examples:

> diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
> index 9936297..61e7a48 100644
> --- a/drivers/net/wireless/ath/ath9k/ani.c
> +++ b/drivers/net/wireless/ath/ath9k/ani.c
> @@ -180,7 +180,6 @@ static void ath9k_ani_restart_old(struct ath_hw *ah)
> REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
> REGWRITE_BUFFER_FLUSH(ah);
> - DISABLE_REGWRITE_BUFFER(ah);
> ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
> @@ -215,7 +214,6 @@ static void ath9k_ani_restart_new(struct ath_hw *ah)
> REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
> REGWRITE_BUFFER_FLUSH(ah);
> - DISABLE_REGWRITE_BUFFER(ah);
> ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
> @@ -643,7 +641,6 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
> REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
> REGWRITE_BUFFER_FLUSH(ah);
> - DISABLE_REGWRITE_BUFFER(ah);
> }
> /*

I applied the v2 version, but w/ the modification to the commit log.

John
--
John W. Linville Someday the world will need a hero, and you
[email protected] might be all we have. Be ready.

2010-10-04 11:36:49

by Felix Fietkau

[permalink] [raw]
Subject: Re: [PATCH 2/4] ath9k_hw: merge codepaths that access the cycle counter registers

On 2010-10-04 8:34 AM, Vasanthakumar Thiagarajan wrote:
>> + /* freeze counters */
>> + REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
>> +
>> + ah->cc.cycles = REG_READ(ah, AR_CCCNT);
>> + if (ah->cc.cycles < cc.cycles) {
>> + clear = true;
>> + goto skip;
>> }
>>
>> - cycles = cc;
>> - rx_frame = rf;
>> - rx_clear = rc;
>> - tx_frame = tf;
>> + ah->cc.rx_clear = REG_READ(ah, AR_RCCNT);
>> + ah->cc.rx_frame = REG_READ(ah, AR_RFCNT);
>> + ah->cc.tx_frame = REG_READ(ah, AR_TFCNT);
>> +
>> + /* prevent wraparound */
>> + if (ah->cc.cycles & BIT(31))
>> + clear = true;
>
> This does not look right, previous if should take care of
> any wrap around.
This is not for correcting an existing wraparound. This is for making
sure that a wraparound never occurs.

>> +
>> +#define CC_DELTA(_field, _reg) ah->cc_delta._field += ah->cc._field - cc._field
> _reg is not used.
>
>>
>> +skip:
>> + if (clear) {
>> + REG_WRITE(ah, AR_CCCNT, 0);
>> + REG_WRITE(ah, AR_RFCNT, 0);
>> + REG_WRITE(ah, AR_RCCNT, 0);
>> + REG_WRITE(ah, AR_TFCNT, 0);
>
> should be able to do with single write in AR_MIBC.
No, the clear bit in AR_MIBC does not clear these counters. I tested that.

>> + /* unfreeze counters */
>> + REG_WRITE(ah, AR_MIBC, 0);
>
> Please configure the relevant bit to unfreeze the counters.
What do you mean?

- Felix

2010-10-04 08:17:13

by Adrian Chadd

[permalink] [raw]
Subject: Re: [PATCH 2/4] ath9k_hw: merge codepaths that access the cycle counter registers

On 4 October 2010 14:34, Vasanthakumar Thiagarajan <[email protected]> wrote:

>> +
>> + ? ? /* prevent wraparound */
>> + ? ? if (ah->cc.cycles & BIT(31))
>> + ? ? ? ? ? ? clear = true;
>
> This does not look right, previous if should take care of
> any wrap around.

I was just in this area of the FreeBSD ath HAL code last week.

I wonder why you don't just poll the values periodically and store
them in a history array. Would you need to handle wrap-around if
you're already polling the values every 100ms?


Adrian

2010-10-03 17:07:26

by Felix Fietkau

[permalink] [raw]
Subject: [PATCH 3/4] ath9k_hw: clean up register write buffering

Throughout the code, DISABLE_REGWRITE_BUFFER is always called right after
REGWRITE_BUFFER_FLUSH. Since that's unlikely to change any time soon, that
makes keeping those ops separate rather pointless, as it only increases
code size and line number counts.
Merge those two ops and also ensure that the flush is only issued after
all codepaths are done buffering.

Signed-off-by: Felix Fietkau <[email protected]>
---
drivers/net/wireless/ath/ath.h | 4 +---
drivers/net/wireless/ath/ath9k/ani.c | 6 ------
drivers/net/wireless/ath/ath9k/ar5008_phy.c | 9 ++-------
drivers/net/wireless/ath/ath9k/ar9002_calib.c | 1 -
drivers/net/wireless/ath/ath9k/ar9002_hw.c | 4 ----
drivers/net/wireless/ath/ath9k/ar9002_phy.c | 1 -
drivers/net/wireless/ath/ath9k/calib.c | 1 -
drivers/net/wireless/ath/ath9k/eeprom_4k.c | 2 --
drivers/net/wireless/ath/ath9k/htc_drv_init.c | 13 +++----------
drivers/net/wireless/ath/ath9k/hw.c | 14 --------------
drivers/net/wireless/ath/ath9k/hw.h | 10 ++--------
drivers/net/wireless/ath/ath9k/mac.c | 4 ----
12 files changed, 8 insertions(+), 61 deletions(-)

diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index 5894fcc..cee0191 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -102,14 +102,12 @@ enum ath_cipher {
* @read: Register read
* @write: Register write
* @enable_write_buffer: Enable multiple register writes
- * @disable_write_buffer: Disable multiple register writes
- * @write_flush: Flush buffered register writes
+ * @write_flush: flush buffered register writes and disable buffering
*/
struct ath_ops {
unsigned int (*read)(void *, u32 reg_offset);
void (*write)(void *, u32 val, u32 reg_offset);
void (*enable_write_buffer)(void *);
- void (*disable_write_buffer)(void *);
void (*write_flush) (void *);
};

diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 9936297..61e7a48 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -180,7 +180,6 @@ static void ath9k_ani_restart_old(struct ath_hw *ah)
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);

@@ -215,7 +214,6 @@ static void ath9k_ani_restart_new(struct ath_hw *ah)
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);

@@ -643,7 +641,6 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}

/*
@@ -737,7 +734,6 @@ static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning)
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}

static void ath9k_hw_ani_monitor_old(struct ath_hw *ah,
@@ -991,7 +987,6 @@ void ath9k_enable_mib_counters(struct ath_hw *ah)
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}

/* Freeze the MIB counters, get the stats and then clear them */
@@ -1261,7 +1256,6 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

ath9k_enable_mib_counters(ah);

diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 74b4213..da07f8d 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -615,14 +615,11 @@ static void ar5008_hw_init_chain_masks(struct ath_hw *ah)
rx_chainmask = ah->rxchainmask;
tx_chainmask = ah->txchainmask;

- ENABLE_REGWRITE_BUFFER(ah);

switch (rx_chainmask) {
case 0x5:
- DISABLE_REGWRITE_BUFFER(ah);
REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
AR_PHY_SWAP_ALT_CHAIN);
- ENABLE_REGWRITE_BUFFER(ah);
case 0x3:
if (ah->hw_version.macVersion == AR_SREV_REVISION_5416_10) {
REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
@@ -632,17 +629,18 @@ static void ar5008_hw_init_chain_masks(struct ath_hw *ah)
case 0x1:
case 0x2:
case 0x7:
+ ENABLE_REGWRITE_BUFFER(ah);
REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
break;
default:
+ ENABLE_REGWRITE_BUFFER(ah);
break;
}

REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

if (tx_chainmask == 0x5) {
REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
@@ -728,7 +726,6 @@ static void ar5008_hw_set_channel_regs(struct ath_hw *ah,
REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}


@@ -820,7 +817,6 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
}

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

if (AR_SREV_9280(ah) || AR_SREV_9287_11_OR_LATER(ah))
REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites);
@@ -851,7 +847,6 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
}

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

if (AR_SREV_9271(ah)) {
if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == 1)
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index f0525fb..15f62cd 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -522,7 +522,6 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
REG_WRITE(ah, regList[i][0], regList[i][1]);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}

static inline void ar9285_hw_pa_cal(struct ath_hw *ah, bool is_reset)
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index fde45082..78bdf0c 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -371,7 +371,6 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}

udelay(1000);
@@ -468,7 +467,6 @@ static int ar9002_hw_get_radiorev(struct ath_hw *ah)
REG_WRITE(ah, AR_PHY(0x20), 0x00010000);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;
val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
@@ -627,6 +625,4 @@ void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan)
}

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
-
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
index cd56c86..c00cdc6 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
@@ -415,7 +415,6 @@ static void ar9002_hw_spur_mitigate(struct ath_hw *ah,
REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}

static void ar9002_olc_init(struct ath_hw *ah)
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 6c38c72..6d50948 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -300,7 +300,6 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
}
}
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}


diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index d6eed1f..2a4fca4 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -500,7 +500,6 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
}

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
}

@@ -832,7 +831,6 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
}

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}

static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index b100db2..6835f9b 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -380,15 +380,6 @@ static void ath9k_enable_regwrite_buffer(void *hw_priv)
atomic_inc(&priv->wmi->mwrite_cnt);
}

-static void ath9k_disable_regwrite_buffer(void *hw_priv)
-{
- struct ath_hw *ah = (struct ath_hw *) hw_priv;
- struct ath_common *common = ath9k_hw_common(ah);
- struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
-
- atomic_dec(&priv->wmi->mwrite_cnt);
-}
-
static void ath9k_regwrite_flush(void *hw_priv)
{
struct ath_hw *ah = (struct ath_hw *) hw_priv;
@@ -397,6 +388,9 @@ static void ath9k_regwrite_flush(void *hw_priv)
u32 rsp_status;
int r;

+ if (!atomic_dec_and_test(&priv->wmi->mwrite_cnt))
+ return;
+
mutex_lock(&priv->wmi->multi_write_mutex);

if (priv->wmi->multi_write_idx) {
@@ -420,7 +414,6 @@ static const struct ath_ops ath9k_common_ops = {
.read = ath9k_regread,
.write = ath9k_regwrite,
.enable_write_buffer = ath9k_enable_regwrite_buffer,
- .disable_write_buffer = ath9k_disable_regwrite_buffer,
.write_flush = ath9k_regwrite_flush,
};

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 1b06604..98c9765 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -299,7 +299,6 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah)
REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}

/* This should work for all families including legacy */
@@ -676,7 +675,6 @@ static void ath9k_hw_init_qos(struct ath_hw *ah)
REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}

static void ath9k_hw_init_pll(struct ath_hw *ah,
@@ -741,7 +739,6 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
}

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

if (AR_SREV_9300_20_OR_LATER(ah)) {
REG_WRITE(ah, AR_INTR_PRIO_ASYNC_ENABLE, 0);
@@ -885,7 +882,6 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

/*
* Restore TX Trigger Level to its pre-reset value.
@@ -933,7 +929,6 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
}

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

if (AR_SREV_9300_20_OR_LATER(ah))
ath9k_hw_reset_txstatus_ring(ah);
@@ -1031,7 +1026,6 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
REG_WRITE(ah, AR_RTC_RC, rst_flags);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

udelay(50);

@@ -1070,7 +1064,6 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
udelay(2);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

if (!AR_SREV_9300_20_OR_LATER(ah))
udelay(2);
@@ -1374,7 +1367,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

r = ath9k_hw_rf_set_freq(ah, chan);
if (r)
@@ -1386,7 +1378,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

ah->intr_txqs = 0;
for (i = 0; i < ah->caps.total_queues; i++)
@@ -1434,7 +1425,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

/*
* For big endian systems turn on swapping for descriptors
@@ -1684,7 +1674,6 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period));

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

beacon_period &= ~ATH9K_BEACON_ENA;
if (beacon_period & ATH9K_BEACON_RESET_TSF) {
@@ -1712,7 +1701,6 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

REG_RMW_FIELD(ah, AR_RSSI_THR,
AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);
@@ -1758,7 +1746,6 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

REG_SET_BIT(ah, AR_TIMER_MODE,
AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN |
@@ -2176,7 +2163,6 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits)
REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
EXPORT_SYMBOL(ath9k_hw_setrxfilter);

diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 87dbb85..d558c51 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -70,19 +70,13 @@

#define ENABLE_REGWRITE_BUFFER(_ah) \
do { \
- if (AR_SREV_9271(_ah)) \
+ if (ath9k_hw_common(_ah)->ops->enable_write_buffer) \
ath9k_hw_common(_ah)->ops->enable_write_buffer((_ah)); \
} while (0)

-#define DISABLE_REGWRITE_BUFFER(_ah) \
- do { \
- if (AR_SREV_9271(_ah)) \
- ath9k_hw_common(_ah)->ops->disable_write_buffer((_ah)); \
- } while (0)
-
#define REGWRITE_BUFFER_FLUSH(_ah) \
do { \
- if (AR_SREV_9271(_ah)) \
+ if (ath9k_hw_common(_ah)->ops->write_flush) \
ath9k_hw_common(_ah)->ops->write_flush((_ah)); \
} while (0)

diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 3efda8a..e578459 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -40,7 +40,6 @@ static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}

u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
@@ -530,7 +529,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
}

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
REG_WRITE(ah, AR_DMISC(q),
@@ -553,7 +551,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
| AR_D_MISC_POST_FR_BKOFF_DIS);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

/*
* cwmin and cwmax should be 0 for beacon queue
@@ -585,7 +582,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
AR_D_MISC_ARB_LOCKOUT_CNTRL_S));

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

break;
case ATH9K_TX_QUEUE_PSPOLL:
--
1.7.2.2


2010-10-03 17:24:38

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 4/4] ath9k_hw: fix regression in ANI listen time calculation

On Sun, Oct 3, 2010 at 10:07 AM, Felix Fietkau <[email protected]> wrote:
>  wireless-testing
>  commit 37e5bf6535a4d697fb9fa6f268a8354a612cbc00
>  Author: Luis R. Rodriguez <[email protected]>
>  Date:   Sat Jun 12 00:33:40 2010 -0400
>
>    ath9k_hw: fix clock rate calculations for ANI
>
> This commit accidentally broke clock rate calculation by doubling the
> calculated clock rate
>
> Signed-off-by: Felix Fietkau <[email protected]>

Thanks, are you aware of the impact, is this a stable regression fix?

Luisa

2010-10-04 17:22:49

by Felix Fietkau

[permalink] [raw]
Subject: [PATCH v2 3/4] ath9k_hw: clean up register write buffering

Throughout the code, DISABLE_REGWRITE_BUFFER is always called right after
REGWRITE_BUFFER_FLUSH. Since that's unlikely to change any time soon, that
makes keeping those ops separate rather pointless, as it only increases
code size and line number counts.
Merge those two ops and also ensure that the flush is only issued after
all codepaths are done buffering.

Signed-off-by: Felix Fietkau <[email protected]>
---
drivers/net/wireless/ath/ath.h | 4 +---
drivers/net/wireless/ath/ath9k/ani.c | 6 ------
drivers/net/wireless/ath/ath9k/ar5008_phy.c | 9 ++-------
drivers/net/wireless/ath/ath9k/ar9002_calib.c | 1 -
drivers/net/wireless/ath/ath9k/ar9002_hw.c | 4 ----
drivers/net/wireless/ath/ath9k/ar9002_phy.c | 1 -
drivers/net/wireless/ath/ath9k/calib.c | 1 -
drivers/net/wireless/ath/ath9k/eeprom_4k.c | 2 --
drivers/net/wireless/ath/ath9k/htc_drv_init.c | 12 ++----------
drivers/net/wireless/ath/ath9k/hw.c | 14 --------------
drivers/net/wireless/ath/ath9k/hw.h | 10 ++--------
drivers/net/wireless/ath/ath9k/mac.c | 4 ----
12 files changed, 7 insertions(+), 61 deletions(-)

diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index 5894fcc..cee0191 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -102,14 +102,12 @@ enum ath_cipher {
* @read: Register read
* @write: Register write
* @enable_write_buffer: Enable multiple register writes
- * @disable_write_buffer: Disable multiple register writes
- * @write_flush: Flush buffered register writes
+ * @write_flush: flush buffered register writes and disable buffering
*/
struct ath_ops {
unsigned int (*read)(void *, u32 reg_offset);
void (*write)(void *, u32 val, u32 reg_offset);
void (*enable_write_buffer)(void *);
- void (*disable_write_buffer)(void *);
void (*write_flush) (void *);
};

diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 9936297..61e7a48 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -180,7 +180,6 @@ static void ath9k_ani_restart_old(struct ath_hw *ah)
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);

@@ -215,7 +214,6 @@ static void ath9k_ani_restart_new(struct ath_hw *ah)
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);

@@ -643,7 +641,6 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}

/*
@@ -737,7 +734,6 @@ static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning)
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}

static void ath9k_hw_ani_monitor_old(struct ath_hw *ah,
@@ -991,7 +987,6 @@ void ath9k_enable_mib_counters(struct ath_hw *ah)
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}

/* Freeze the MIB counters, get the stats and then clear them */
@@ -1261,7 +1256,6 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

ath9k_enable_mib_counters(ah);

diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 74b4213..da07f8d 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -615,14 +615,11 @@ static void ar5008_hw_init_chain_masks(struct ath_hw *ah)
rx_chainmask = ah->rxchainmask;
tx_chainmask = ah->txchainmask;

- ENABLE_REGWRITE_BUFFER(ah);

switch (rx_chainmask) {
case 0x5:
- DISABLE_REGWRITE_BUFFER(ah);
REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
AR_PHY_SWAP_ALT_CHAIN);
- ENABLE_REGWRITE_BUFFER(ah);
case 0x3:
if (ah->hw_version.macVersion == AR_SREV_REVISION_5416_10) {
REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
@@ -632,17 +629,18 @@ static void ar5008_hw_init_chain_masks(struct ath_hw *ah)
case 0x1:
case 0x2:
case 0x7:
+ ENABLE_REGWRITE_BUFFER(ah);
REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
break;
default:
+ ENABLE_REGWRITE_BUFFER(ah);
break;
}

REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

if (tx_chainmask == 0x5) {
REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
@@ -728,7 +726,6 @@ static void ar5008_hw_set_channel_regs(struct ath_hw *ah,
REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}


@@ -820,7 +817,6 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
}

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

if (AR_SREV_9280(ah) || AR_SREV_9287_11_OR_LATER(ah))
REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites);
@@ -851,7 +847,6 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
}

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

if (AR_SREV_9271(ah)) {
if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == 1)
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index f0525fb..15f62cd 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -522,7 +522,6 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
REG_WRITE(ah, regList[i][0], regList[i][1]);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}

static inline void ar9285_hw_pa_cal(struct ath_hw *ah, bool is_reset)
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index fde45082..78bdf0c 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -371,7 +371,6 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}

udelay(1000);
@@ -468,7 +467,6 @@ static int ar9002_hw_get_radiorev(struct ath_hw *ah)
REG_WRITE(ah, AR_PHY(0x20), 0x00010000);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;
val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
@@ -627,6 +625,4 @@ void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan)
}

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
-
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
index cd56c86..c00cdc6 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
@@ -415,7 +415,6 @@ static void ar9002_hw_spur_mitigate(struct ath_hw *ah,
REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}

static void ar9002_olc_init(struct ath_hw *ah)
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 6c38c72..6d50948 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -300,7 +300,6 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
}
}
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}


diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index d6eed1f..2a4fca4 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -500,7 +500,6 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
}

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
}

@@ -832,7 +831,6 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
}

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}

static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index b100db2..bbb54bc 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -380,15 +380,6 @@ static void ath9k_enable_regwrite_buffer(void *hw_priv)
atomic_inc(&priv->wmi->mwrite_cnt);
}

-static void ath9k_disable_regwrite_buffer(void *hw_priv)
-{
- struct ath_hw *ah = (struct ath_hw *) hw_priv;
- struct ath_common *common = ath9k_hw_common(ah);
- struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
-
- atomic_dec(&priv->wmi->mwrite_cnt);
-}
-
static void ath9k_regwrite_flush(void *hw_priv)
{
struct ath_hw *ah = (struct ath_hw *) hw_priv;
@@ -397,6 +388,8 @@ static void ath9k_regwrite_flush(void *hw_priv)
u32 rsp_status;
int r;

+ atomic_dec(&priv->wmi->mwrite_cnt);
+
mutex_lock(&priv->wmi->multi_write_mutex);

if (priv->wmi->multi_write_idx) {
@@ -420,7 +413,6 @@ static const struct ath_ops ath9k_common_ops = {
.read = ath9k_regread,
.write = ath9k_regwrite,
.enable_write_buffer = ath9k_enable_regwrite_buffer,
- .disable_write_buffer = ath9k_disable_regwrite_buffer,
.write_flush = ath9k_regwrite_flush,
};

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 1b06604..98c9765 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -299,7 +299,6 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah)
REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}

/* This should work for all families including legacy */
@@ -676,7 +675,6 @@ static void ath9k_hw_init_qos(struct ath_hw *ah)
REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}

static void ath9k_hw_init_pll(struct ath_hw *ah,
@@ -741,7 +739,6 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
}

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

if (AR_SREV_9300_20_OR_LATER(ah)) {
REG_WRITE(ah, AR_INTR_PRIO_ASYNC_ENABLE, 0);
@@ -885,7 +882,6 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

/*
* Restore TX Trigger Level to its pre-reset value.
@@ -933,7 +929,6 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
}

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

if (AR_SREV_9300_20_OR_LATER(ah))
ath9k_hw_reset_txstatus_ring(ah);
@@ -1031,7 +1026,6 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
REG_WRITE(ah, AR_RTC_RC, rst_flags);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

udelay(50);

@@ -1070,7 +1064,6 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
udelay(2);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

if (!AR_SREV_9300_20_OR_LATER(ah))
udelay(2);
@@ -1374,7 +1367,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

r = ath9k_hw_rf_set_freq(ah, chan);
if (r)
@@ -1386,7 +1378,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

ah->intr_txqs = 0;
for (i = 0; i < ah->caps.total_queues; i++)
@@ -1434,7 +1425,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

/*
* For big endian systems turn on swapping for descriptors
@@ -1684,7 +1674,6 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period));

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

beacon_period &= ~ATH9K_BEACON_ENA;
if (beacon_period & ATH9K_BEACON_RESET_TSF) {
@@ -1712,7 +1701,6 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

REG_RMW_FIELD(ah, AR_RSSI_THR,
AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);
@@ -1758,7 +1746,6 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

REG_SET_BIT(ah, AR_TIMER_MODE,
AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN |
@@ -2176,7 +2163,6 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits)
REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
EXPORT_SYMBOL(ath9k_hw_setrxfilter);

diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 87dbb85..d558c51 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -70,19 +70,13 @@

#define ENABLE_REGWRITE_BUFFER(_ah) \
do { \
- if (AR_SREV_9271(_ah)) \
+ if (ath9k_hw_common(_ah)->ops->enable_write_buffer) \
ath9k_hw_common(_ah)->ops->enable_write_buffer((_ah)); \
} while (0)

-#define DISABLE_REGWRITE_BUFFER(_ah) \
- do { \
- if (AR_SREV_9271(_ah)) \
- ath9k_hw_common(_ah)->ops->disable_write_buffer((_ah)); \
- } while (0)
-
#define REGWRITE_BUFFER_FLUSH(_ah) \
do { \
- if (AR_SREV_9271(_ah)) \
+ if (ath9k_hw_common(_ah)->ops->write_flush) \
ath9k_hw_common(_ah)->ops->write_flush((_ah)); \
} while (0)

diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 3efda8a..e578459 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -40,7 +40,6 @@ static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}

u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
@@ -530,7 +529,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
}

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
REG_WRITE(ah, AR_DMISC(q),
@@ -553,7 +551,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
| AR_D_MISC_POST_FR_BKOFF_DIS);

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

/*
* cwmin and cwmax should be 0 for beacon queue
@@ -585,7 +582,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
AR_D_MISC_ARB_LOCKOUT_CNTRL_S));

REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);

break;
case ATH9K_TX_QUEUE_PSPOLL:


2010-10-04 08:50:41

by Rajkumar Manoharan

[permalink] [raw]
Subject: Re: [PATCH 3/4] ath9k_hw: clean up register write buffering

On Sun, Oct 03, 2010 at 10:37:18PM +0530, Felix Fietkau wrote:
> static void ath9k_regwrite_flush(void *hw_priv)
> {
> struct ath_hw *ah = (struct ath_hw *) hw_priv;
> @@ -397,6 +388,9 @@ static void ath9k_regwrite_flush(void *hw_priv)
> u32 rsp_status;
> int r;
>
> + if (!atomic_dec_and_test(&priv->wmi->mwrite_cnt))
> + return;
> +
FMU, Assume that mwrite_cnt > 1 and a reg_read happens after a flush whose value
depends on issued reg_write, the above check skips reg_write.
The buffered commands only issued either mwrite_cnt reaches zero or
buffer reaches MAX limit.

>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html

2010-10-03 17:07:26

by Felix Fietkau

[permalink] [raw]
Subject: [PATCH 4/4] ath9k_hw: fix regression in ANI listen time calculation

wireless-testing
commit 37e5bf6535a4d697fb9fa6f268a8354a612cbc00
Author: Luis R. Rodriguez <[email protected]>
Date: Sat Jun 12 00:33:40 2010 -0400

ath9k_hw: fix clock rate calculations for ANI

This commit accidentally broke clock rate calculation by doubling the
calculated clock rate

Signed-off-by: Felix Fietkau <[email protected]>
---
drivers/net/wireless/ath/ath9k/ani.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 61e7a48..a1894d2 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -542,7 +542,7 @@ static u8 ath9k_hw_chan_2_clockrate_mhz(struct ath_hw *ah)
if (conf_is_ht40(conf))
return clockrate * 2;

- return clockrate * 2;
+ return clockrate;
}

static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah)
--
1.7.2.2


2010-10-04 12:51:47

by Felix Fietkau

[permalink] [raw]
Subject: Re: [PATCH 2/4] ath9k_hw: merge codepaths that access the cycle counter registers

On 2010-10-04 2:24 PM, Vasanthakumar Thiagarajan wrote:
>> >> + /* unfreeze counters */
>> >> + REG_WRITE(ah, AR_MIBC, 0);
>> >
>> > Please configure the relevant bit to unfreeze the counters.
>> What do you mean?
>
> AR_MIBC does more than just freeze/unfreeze the counters, though I
> dont see any issues with setting the whole register to zero, it
> looks buggy. Please configure only the relevant bit to
> freeze/unfreeze the counters.
Other places in the code set it to zero as well, though sometimes
written in a weird way. I also checked the specs, there is no bit that's
supposed to be active at this point.

- Felix

2010-10-03 19:08:24

by Felix Fietkau

[permalink] [raw]
Subject: Re: [PATCH 4/4] ath9k_hw: fix regression in ANI listen time calculation

On 2010-10-03 7:24 PM, Luis R. Rodriguez wrote:
> On Sun, Oct 3, 2010 at 10:07 AM, Felix Fietkau <[email protected]> wrote:
>> wireless-testing
>> commit 37e5bf6535a4d697fb9fa6f268a8354a612cbc00
>> Author: Luis R. Rodriguez <[email protected]>
>> Date: Sat Jun 12 00:33:40 2010 -0400
>>
>> ath9k_hw: fix clock rate calculations for ANI
>>
>> This commit accidentally broke clock rate calculation by doubling the
>> calculated clock rate
>>
>> Signed-off-by: Felix Fietkau <[email protected]>
>
> Thanks, are you aware of the impact, is this a stable regression fix?
I just checked, looks like this is a stable fix. The impact is that ANI
will probably pick settings with higher numbers of OFDM/CCK misdetects.
I'll resend with Cc: stable

- Felix

2010-10-05 10:03:46

by Felix Fietkau

[permalink] [raw]
Subject: [PATCH v3 3/4] ath9k_hw: clean up register write buffering

Throughout the code, DISABLE_REGWRITE_BUFFER is always called right after
REGWRITE_BUFFER_FLUSH. Since that's unlikely to change any time soon, that
makes keeping those ops separate rather pointless, as it only increases
code size and line number counts.

Signed-off-by: Felix Fietkau <[email protected]>
---
drivers/net/wireless/ath/ath.h | 4 +---
drivers/net/wireless/ath/ath9k/ani.c | 6 ------
drivers/net/wireless/ath/ath9k/ar5008_phy.c | 9 ++-------
drivers/net/wireless/ath/ath9k/ar9002_calib.c | 1 -
drivers/net/wireless/ath/ath9k/ar9002_hw.c | 4 ----
drivers/net/wireless/ath/ath9k/ar9002_phy.c | 1 -
drivers/net/wireless/ath/ath9k/calib.c | 1 -
drivers/net/wireless/ath/ath9k/eeprom_4k.c | 2 --
drivers/net/wireless/ath/ath9k/htc_drv_init.c | 12 ++----------
drivers/net/wireless/ath/ath9k/hw.c | 14 --------------
drivers/net/wireless/ath/ath9k/hw.h | 10 ++--------
drivers/net/wireless/ath/ath9k/mac.c | 4 ----
12 files changed, 7 insertions(+), 61 deletions(-)

v2: removed mwrite_cnt test
v3: removed comment about it from description

diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index 5894fcc..cee0191 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -102,14 +102,12 @@ enum ath_cipher {
* @read: Register read
* @write: Register write
* @enable_write_buffer: Enable multiple register writes
- * @disable_write_buffer: Disable multiple register writes
- * @write_flush: Flush buffered register writes
+ * @write_flush: flush buffered register writes and disable buffering
*/
struct ath_ops {
unsigned int (*read)(void *, u32 reg_offset);
void (*write)(void *, u32 val, u32 reg_offset);
void (*enable_write_buffer)(void *);
- void (*disable_write_buffer)(void *);
void (*write_flush) (void *);
};
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 9936297..61e7a48 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -180,7 +180,6 @@ static void ath9k_ani_restart_old(struct ath_hw *ah)
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
@@ -215,7 +214,6 @@ static void ath9k_ani_restart_new(struct ath_hw *ah)
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
@@ -643,7 +641,6 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
/*
@@ -737,7 +734,6 @@ static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning)
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
static void ath9k_hw_ani_monitor_old(struct ath_hw *ah,
@@ -991,7 +987,6 @@ void ath9k_enable_mib_counters(struct ath_hw *ah)
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
/* Freeze the MIB counters, get the stats and then clear them */
@@ -1261,7 +1256,6 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
ath9k_enable_mib_counters(ah);
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 74b4213..da07f8d 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -615,14 +615,11 @@ static void ar5008_hw_init_chain_masks(struct ath_hw *ah)
rx_chainmask = ah->rxchainmask;
tx_chainmask = ah->txchainmask;
- ENABLE_REGWRITE_BUFFER(ah);
switch (rx_chainmask) {
case 0x5:
- DISABLE_REGWRITE_BUFFER(ah);
REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
AR_PHY_SWAP_ALT_CHAIN);
- ENABLE_REGWRITE_BUFFER(ah);
case 0x3:
if (ah->hw_version.macVersion == AR_SREV_REVISION_5416_10) {
REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
@@ -632,17 +629,18 @@ static void ar5008_hw_init_chain_masks(struct ath_hw *ah)
case 0x1:
case 0x2:
case 0x7:
+ ENABLE_REGWRITE_BUFFER(ah);
REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
break;
default:
+ ENABLE_REGWRITE_BUFFER(ah);
break;
}
REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
if (tx_chainmask == 0x5) {
REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
@@ -728,7 +726,6 @@ static void ar5008_hw_set_channel_regs(struct ath_hw *ah,
REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
@@ -820,7 +817,6 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
}
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
if (AR_SREV_9280(ah) || AR_SREV_9287_11_OR_LATER(ah))
REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites);
@@ -851,7 +847,6 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
}
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
if (AR_SREV_9271(ah)) {
if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == 1)
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index f0525fb..15f62cd 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -522,7 +522,6 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
REG_WRITE(ah, regList[i][0], regList[i][1]);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
static inline void ar9285_hw_pa_cal(struct ath_hw *ah, bool is_reset)
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index fde45082..78bdf0c 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -371,7 +371,6 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
udelay(1000);
@@ -468,7 +467,6 @@ static int ar9002_hw_get_radiorev(struct ath_hw *ah)
REG_WRITE(ah, AR_PHY(0x20), 0x00010000);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;
val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
@@ -627,6 +625,4 @@ void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan)
}
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
-
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
index cd56c86..c00cdc6 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
@@ -415,7 +415,6 @@ static void ar9002_hw_spur_mitigate(struct ath_hw *ah,
REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
static void ar9002_olc_init(struct ath_hw *ah)
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 6c38c72..6d50948 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -300,7 +300,6 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
}
}
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index d6eed1f..2a4fca4 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -500,7 +500,6 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
}
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
}
@@ -832,7 +831,6 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
}
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index b100db2..bbb54bc 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -380,15 +380,6 @@ static void ath9k_enable_regwrite_buffer(void *hw_priv)
atomic_inc(&priv->wmi->mwrite_cnt);
}
-static void ath9k_disable_regwrite_buffer(void *hw_priv)
-{
- struct ath_hw *ah = (struct ath_hw *) hw_priv;
- struct ath_common *common = ath9k_hw_common(ah);
- struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
-
- atomic_dec(&priv->wmi->mwrite_cnt);
-}
-
static void ath9k_regwrite_flush(void *hw_priv)
{
struct ath_hw *ah = (struct ath_hw *) hw_priv;
@@ -397,6 +388,8 @@ static void ath9k_regwrite_flush(void *hw_priv)
u32 rsp_status;
int r;
+ atomic_dec(&priv->wmi->mwrite_cnt);
+
mutex_lock(&priv->wmi->multi_write_mutex);
if (priv->wmi->multi_write_idx) {
@@ -420,7 +413,6 @@ static const struct ath_ops ath9k_common_ops = {
.read = ath9k_regread,
.write = ath9k_regwrite,
.enable_write_buffer = ath9k_enable_regwrite_buffer,
- .disable_write_buffer = ath9k_disable_regwrite_buffer,
.write_flush = ath9k_regwrite_flush,
};
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 1b06604..98c9765 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -299,7 +299,6 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah)
REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
/* This should work for all families including legacy */
@@ -676,7 +675,6 @@ static void ath9k_hw_init_qos(struct ath_hw *ah)
REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
static void ath9k_hw_init_pll(struct ath_hw *ah,
@@ -741,7 +739,6 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
}
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
if (AR_SREV_9300_20_OR_LATER(ah)) {
REG_WRITE(ah, AR_INTR_PRIO_ASYNC_ENABLE, 0);
@@ -885,7 +882,6 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
/*
* Restore TX Trigger Level to its pre-reset value.
@@ -933,7 +929,6 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
}
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
if (AR_SREV_9300_20_OR_LATER(ah))
ath9k_hw_reset_txstatus_ring(ah);
@@ -1031,7 +1026,6 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
REG_WRITE(ah, AR_RTC_RC, rst_flags);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
udelay(50);
@@ -1070,7 +1064,6 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
udelay(2);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
if (!AR_SREV_9300_20_OR_LATER(ah))
udelay(2);
@@ -1374,7 +1367,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
r = ath9k_hw_rf_set_freq(ah, chan);
if (r)
@@ -1386,7 +1378,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
ah->intr_txqs = 0;
for (i = 0; i < ah->caps.total_queues; i++)
@@ -1434,7 +1425,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
/*
* For big endian systems turn on swapping for descriptors
@@ -1684,7 +1674,6 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period));
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
beacon_period &= ~ATH9K_BEACON_ENA;
if (beacon_period & ATH9K_BEACON_RESET_TSF) {
@@ -1712,7 +1701,6 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
REG_RMW_FIELD(ah, AR_RSSI_THR,
AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);
@@ -1758,7 +1746,6 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
REG_SET_BIT(ah, AR_TIMER_MODE,
AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN |
@@ -2176,7 +2163,6 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits)
REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
EXPORT_SYMBOL(ath9k_hw_setrxfilter);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 87dbb85..d558c51 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -70,19 +70,13 @@
#define ENABLE_REGWRITE_BUFFER(_ah) \
do { \
- if (AR_SREV_9271(_ah)) \
+ if (ath9k_hw_common(_ah)->ops->enable_write_buffer) \
ath9k_hw_common(_ah)->ops->enable_write_buffer((_ah)); \
} while (0)
-#define DISABLE_REGWRITE_BUFFER(_ah) \
- do { \
- if (AR_SREV_9271(_ah)) \
- ath9k_hw_common(_ah)->ops->disable_write_buffer((_ah)); \
- } while (0)
-
#define REGWRITE_BUFFER_FLUSH(_ah) \
do { \
- if (AR_SREV_9271(_ah)) \
+ if (ath9k_hw_common(_ah)->ops->write_flush) \
ath9k_hw_common(_ah)->ops->write_flush((_ah)); \
} while (0)
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 3efda8a..e578459 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -40,7 +40,6 @@ static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
}
u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
@@ -530,7 +529,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
}
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
REG_WRITE(ah, AR_DMISC(q),
@@ -553,7 +551,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
| AR_D_MISC_POST_FR_BKOFF_DIS);
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
/*
* cwmin and cwmax should be 0 for beacon queue
@@ -585,7 +582,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
REGWRITE_BUFFER_FLUSH(ah);
- DISABLE_REGWRITE_BUFFER(ah);
break;
case ATH9K_TX_QUEUE_PSPOLL:



Subject: Re: [PATCH 2/4] ath9k_hw: merge codepaths that access the cycle counter registers

On Mon, Oct 04, 2010 at 05:06:43PM +0530, Felix Fietkau wrote:
> On 2010-10-04 8:34 AM, Vasanthakumar Thiagarajan wrote:
> >> + /* freeze counters */
> >> + REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
> >> +
> >> + ah->cc.cycles = REG_READ(ah, AR_CCCNT);
> >> + if (ah->cc.cycles < cc.cycles) {
> >> + clear = true;
> >> + goto skip;
> >> }
> >>
> >> - cycles = cc;
> >> - rx_frame = rf;
> >> - rx_clear = rc;
> >> - tx_frame = tf;
> >> + ah->cc.rx_clear = REG_READ(ah, AR_RCCNT);
> >> + ah->cc.rx_frame = REG_READ(ah, AR_RFCNT);
> >> + ah->cc.tx_frame = REG_READ(ah, AR_TFCNT);
> >> +
> >> + /* prevent wraparound */
> >> + if (ah->cc.cycles & BIT(31))
> >> + clear = true;
> >
> > This does not look right, previous if should take care of
> > any wrap around.
> This is not for correcting an existing wraparound. This is for making
> sure that a wraparound never occurs.

ok.
>
> >> +
> >> +#define CC_DELTA(_field, _reg) ah->cc_delta._field += ah->cc._field - cc._field
> > _reg is not used.
> >
> >>
> >> +skip:
> >> + if (clear) {
> >> + REG_WRITE(ah, AR_CCCNT, 0);
> >> + REG_WRITE(ah, AR_RFCNT, 0);
> >> + REG_WRITE(ah, AR_RCCNT, 0);
> >> + REG_WRITE(ah, AR_TFCNT, 0);
> >
> > should be able to do with single write in AR_MIBC.
> No, the clear bit in AR_MIBC does not clear these counters. I tested that.

ok.
>
> >> + /* unfreeze counters */
> >> + REG_WRITE(ah, AR_MIBC, 0);
> >
> > Please configure the relevant bit to unfreeze the counters.
> What do you mean?

AR_MIBC does more than just freeze/unfreeze the counters, though I
dont see any issues with setting the whole register to zero, it
looks buggy. Please configure only the relevant bit to
freeze/unfreeze the counters.

Vasanth