Subject: [PATCH 03/22] ath9k_hw: Introduce a bool for 25mhz clock and populate it

pll configuration will differ for 25mhz clock.

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath9k/hw.c | 11 +++++++++++
drivers/net/wireless/ath/ath9k/hw.h | 2 ++
2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index d98b4c6..8b90b9c 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -481,6 +481,9 @@ static void ath9k_hw_attach_ops(struct ath_hw *ah)
/* Called for all hardware families */
static int __ath9k_hw_init(struct ath_hw *ah)
{
+#define AR9340_SOC_SEL_25M_40M 0xB80600B0
+#define AR9340_REF_CLK_40 (1 << 4) /* 0 - 25MHz 1 - 40 MHz */
+
struct ath_common *common = ath9k_hw_common(ah);
int r = 0;

@@ -508,6 +511,14 @@ static int __ath9k_hw_init(struct ath_hw *ah)

ath9k_hw_attach_ops(ah);

+ if (AR_SREV_9340(ah)) {
+ if (*((volatile u32 *) AR9340_SOC_SEL_25M_40M) &
+ AR9340_REF_CLK_40)
+ ah->is_clk_25mhz = false;
+ else
+ ah->is_clk_25mhz = true;
+ }
+
if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
ath_err(common, "Couldn't wakeup chip\n");
return -EIO;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index afdb006..721eb27 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -845,6 +845,8 @@ struct ath_hw {

/* Enterprise mode cap */
u32 ent_mode;
+
+ bool is_clk_25mhz;
};

static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah)
--
1.7.0.4



Subject: [PATCH 06/22] ath9k_hw: Initialize mode registers from initvals.h for AR9340

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath9k/ar9003_hw.c | 59 ++++++++++++++++++++++++++-
drivers/net/wireless/ath/ath9k/ar9003_phy.c | 3 +
drivers/net/wireless/ath/ath9k/hw.h | 1 +
3 files changed, 62 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index aebaad9..37af721 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -18,6 +18,7 @@
#include "ar9003_mac.h"
#include "ar9003_2p2_initvals.h"
#include "ar9485_initvals.h"
+#include "ar9340_initvals.h"

/* General hardware code for the AR9003 hadware family */

@@ -28,7 +29,63 @@
*/
static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
{
- if (AR_SREV_9485_11(ah)) {
+ if (AR_SREV_9340(ah)) {
+ /* mac */
+ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
+ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
+ ar9340_1p0_mac_core,
+ ARRAY_SIZE(ar9340_1p0_mac_core), 2);
+ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
+ ar9340_1p0_mac_postamble,
+ ARRAY_SIZE(ar9340_1p0_mac_postamble), 5);
+
+ /* bb */
+ INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
+ INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
+ ar9340_1p0_baseband_core,
+ ARRAY_SIZE(ar9340_1p0_baseband_core), 2);
+ INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
+ ar9340_1p0_baseband_postamble,
+ ARRAY_SIZE(ar9340_1p0_baseband_postamble), 5);
+
+ /* radio */
+ INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
+ INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
+ ar9340_1p0_radio_core,
+ ARRAY_SIZE(ar9340_1p0_radio_core), 2);
+ INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
+ ar9340_1p0_radio_postamble,
+ ARRAY_SIZE(ar9340_1p0_radio_postamble), 5);
+
+ /* soc */
+ INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
+ ar9340_1p0_soc_preamble,
+ ARRAY_SIZE(ar9340_1p0_soc_preamble), 2);
+ INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
+ INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
+ ar9340_1p0_soc_postamble,
+ ARRAY_SIZE(ar9340_1p0_soc_postamble), 5);
+
+ /* rx/tx gain */
+ INIT_INI_ARRAY(&ah->iniModesRxGain,
+ ar9340Common_wo_xlna_rx_gain_table_1p0,
+ ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0),
+ 5);
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
+ ar9340Modes_high_ob_db_tx_gain_table_1p0,
+ ARRAY_SIZE(ar9340Modes_high_ob_db_tx_gain_table_1p0),
+ 5);
+
+ INIT_INI_ARRAY(&ah->iniModesAdditional,
+ ar9340Modes_fast_clock_1p0,
+ ARRAY_SIZE(ar9340Modes_fast_clock_1p0),
+ 3);
+
+ INIT_INI_ARRAY(&ah->iniModesAdditional_40M,
+ ar9340_1p0_radio_core_40M,
+ ARRAY_SIZE(ar9340_1p0_radio_core_40M),
+ 2);
+ } else if (AR_SREV_9485_11(ah)) {
/* mac */
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index f01c31f..1544e57 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -646,6 +646,9 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
REG_WRITE_ARRAY(&ah->iniModesAdditional,
modesIndex, regWrites);

+ if (AR_SREV_9340(ah) && !ah->is_clk_25mhz)
+ REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites);
+
ar9003_hw_override_ini(ah);
ar9003_hw_set_channel_regs(ah, chan);
ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 7837a83..f821381 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -799,6 +799,7 @@ struct ath_hw {
struct ar5416IniArray iniPcieSerdes;
struct ar5416IniArray iniPcieSerdesLowPower;
struct ar5416IniArray iniModesAdditional;
+ struct ar5416IniArray iniModesAdditional_40M;
struct ar5416IniArray iniModesRxGain;
struct ar5416IniArray iniModesTxGain;
struct ar5416IniArray iniModes_9271_1_0_only;
--
1.7.0.4


Subject: [PATCH 11/22] ath9k_hw: Clean up rx/tx chain configuration before AGC/IQ cal

Use hw supported chains instead of hard coded values.

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath9k/ar9003_calib.c | 13 +++++--------
1 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index 4a4cd88..09f3aa7 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -940,21 +940,18 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
struct ath9k_channel *chan)
{
struct ath_common *common = ath9k_hw_common(ah);
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
int val;

val = REG_READ(ah, AR_ENT_OTP);
ath_dbg(common, ATH_DBG_CALIBRATE, "ath9k: AR_ENT_OTP 0x%x\n", val);

- if (AR_SREV_9485(ah))
- ar9003_hw_set_chain_masks(ah, 0x1, 0x1);
- else if (val & AR_ENT_OTP_CHAIN2_DISABLE)
+ /* Configure rx/tx chains before running AGC/TxiQ cals */
+ if (val & AR_ENT_OTP_CHAIN2_DISABLE)
ar9003_hw_set_chain_masks(ah, 0x3, 0x3);
else
- /*
- * 0x7 = 0b111 , AR9003 needs to be configured for 3-chain
- * mode before running AGC/TxIQ cals
- */
- ar9003_hw_set_chain_masks(ah, 0x7, 0x7);
+ ar9003_hw_set_chain_masks(ah, pCap->rx_chainmask,
+ pCap->tx_chainmask);

/* Do Tx IQ Calibration */
if (AR_SREV_9485(ah))
--
1.7.0.4


Subject: [PATCH 15/22] ath9k_hw: Configure tuning capacitance value for AR9340 as well

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

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 6e5baa7..262fb62 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -3755,7 +3755,7 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
ar9003_hw_atten_apply(ah, chan);
if (!AR_SREV_9340(ah))
ar9003_hw_internal_regulator_apply(ah);
- if (AR_SREV_9485(ah))
+ if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
ar9003_hw_apply_tuning_caps(ah);
}

--
1.7.0.4


Subject: [PATCH 17/22] ath9k_hw: Configure chain switch table and attenuation control only for active chains

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 44 ++++++++++++++----------
1 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 262fb62..fd9b8c4 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -3501,23 +3501,28 @@ static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah,

static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
{
+ int chain;
+ static const u32 switch_chain_reg[AR9300_MAX_CHAINS] = {
+ AR_PHY_SWITCH_CHAIN_0,
+ AR_PHY_SWITCH_CHAIN_1,
+ AR_PHY_SWITCH_CHAIN_2,
+ };
+
u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
+
REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value);

value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);

- value = ar9003_hw_ant_ctrl_chain_get(ah, 0, is2ghz);
- REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value);
-
- if (!AR_SREV_9485(ah)) {
- value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
- REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL,
- value);
-
- value = ar9003_hw_ant_ctrl_chain_get(ah, 2, is2ghz);
- REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL,
- value);
+ for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
+ if ((ah->rxchainmask & BIT(chain)) ||
+ (ah->txchainmask & BIT(chain))) {
+ value = ar9003_hw_ant_ctrl_chain_get(ah, chain,
+ is2ghz);
+ REG_RMW_FIELD(ah, switch_chain_reg[chain],
+ AR_SWITCH_TABLE_ALL, value);
+ }
}

if (AR_SREV_9485(ah)) {
@@ -3638,13 +3643,16 @@ static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan)

/* Test value. if 0 then attenuation is unused. Don't load anything. */
for (i = 0; i < 3; i++) {
- value = ar9003_hw_atten_chain_get(ah, i, chan);
- REG_RMW_FIELD(ah, ext_atten_reg[i],
- AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
-
- value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
- REG_RMW_FIELD(ah, ext_atten_reg[i],
- AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, value);
+ if (ah->txchainmask & BIT(i)) {
+ value = ar9003_hw_atten_chain_get(ah, i, chan);
+ REG_RMW_FIELD(ah, ext_atten_reg[i],
+ AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
+
+ value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
+ REG_RMW_FIELD(ah, ext_atten_reg[i],
+ AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
+ value);
+ }
}
}

--
1.7.0.4


Subject: [PATCH 14/22] ath9k_hw: Skip internal regulator configuration for AR9340

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

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 685ce91..6e5baa7 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -3753,7 +3753,8 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan));
ar9003_hw_drive_strength_apply(ah);
ar9003_hw_atten_apply(ah, chan);
- ar9003_hw_internal_regulator_apply(ah);
+ if (!AR_SREV_9340(ah))
+ ar9003_hw_internal_regulator_apply(ah);
if (AR_SREV_9485(ah))
ar9003_hw_apply_tuning_caps(ah);
}
--
1.7.0.4


Subject: Re: [PATCH 03/22] ath9k_hw: Introduce a bool for 25mhz clock and populate it

On Tue, Apr 12, 2011 at 08:21:36PM +0530, John W. Linville wrote:
> On Tue, Apr 12, 2011 at 08:03:06PM +0530, Vasanthakumar Thiagarajan wrote:
> > On Tue, Apr 12, 2011 at 07:30:36PM +0530, Vasanth Thiagarajan wrote:
> > > > > {
> > > > > +#define AR9340_SOC_SEL_25M_40M 0xB80600B0
> > > > > +#define AR9340_REF_CLK_40 (1<< 4) /* 0 - 25MHz 1 - 40 MHz */
> > > > > +
> > > > > struct ath_common *common = ath9k_hw_common(ah);
> > > > > int r = 0;
> > > > >
> > > > > @@ -508,6 +511,14 @@ static int __ath9k_hw_init(struct ath_hw *ah)
> > > > >
> > > > > ath9k_hw_attach_ops(ah);
> > > > >
> > > > > + if (AR_SREV_9340(ah)) {
> > > > > + if (*((volatile u32 *) AR9340_SOC_SEL_25M_40M)&
> > > > > + AR9340_REF_CLK_40)
> > > > > + ah->is_clk_25mhz = false;
> > > > > + else
> > > > > + ah->is_clk_25mhz = true;
> > > > > + }
> > > > > +
> > > > > if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
> > > > > ath_err(common, "Couldn't wakeup chip\n");
> > > > > return -EIO;
> > > > I think this flag should be passed down from the arch code through
> > > > platform data instead. Also, dereferencing volatile u32 pointers for
> > > > reading registers is somewhat hackish, readl or ioread32 would be better.
> > >
> > > Yeah, I was also not comfortable with this part of code. I'll fix
> > > that. thanks for the comments.
> >
> > Linville, ralf,
> >
> > The code change needs to be done in arch code also to fix this
> > cleanly. I'm not quite sure about the right way of submitting changes
> > in BSP and ath9k driver without possibly breaking the driver due to
> > the fact that the change in BSP may not be available along with
> > driver change soon in wireless-testing.
>
> Generally we can negotiate to take the related changes through one
> tree or the other. How does the arch change look?

arch change will look like

diff --git a/include/linux/ath9k_platform.h b/include/linux/ath9k_platform.h
index 020387a..f03f8bf 100644
--- a/include/linux/ath9k_platform.h
+++ b/include/linux/ath9k_platform.h
@@ -28,6 +28,7 @@ struct ath9k_platform_data {
int led_pin;
u32 gpio_mask;
u32 gpio_val;
+ bool is_clk_25mhz;
};

Vasanth

Subject: Re: [PATCH 03/22] ath9k_hw: Introduce a bool for 25mhz clock and populate it

On Tue, Apr 12, 2011 at 07:20:32PM +0530, Felix Fietkau wrote:
> On 2011-04-12 3:17 PM, Vasanthakumar Thiagarajan wrote:
> > pll configuration will differ for 25mhz clock.
> >
> > Signed-off-by: Vasanthakumar Thiagarajan<[email protected]>
> > ---
> > drivers/net/wireless/ath/ath9k/hw.c | 11 +++++++++++
> > drivers/net/wireless/ath/ath9k/hw.h | 2 ++
> > 2 files changed, 13 insertions(+), 0 deletions(-)
> >
> > diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
> > index d98b4c6..8b90b9c 100644
> > --- a/drivers/net/wireless/ath/ath9k/hw.c
> > +++ b/drivers/net/wireless/ath/ath9k/hw.c
> > @@ -481,6 +481,9 @@ static void ath9k_hw_attach_ops(struct ath_hw *ah)
> > /* Called for all hardware families */
> > static int __ath9k_hw_init(struct ath_hw *ah)
> > {
> > +#define AR9340_SOC_SEL_25M_40M 0xB80600B0
> > +#define AR9340_REF_CLK_40 (1<< 4) /* 0 - 25MHz 1 - 40 MHz */
> > +
> > struct ath_common *common = ath9k_hw_common(ah);
> > int r = 0;
> >
> > @@ -508,6 +511,14 @@ static int __ath9k_hw_init(struct ath_hw *ah)
> >
> > ath9k_hw_attach_ops(ah);
> >
> > + if (AR_SREV_9340(ah)) {
> > + if (*((volatile u32 *) AR9340_SOC_SEL_25M_40M)&
> > + AR9340_REF_CLK_40)
> > + ah->is_clk_25mhz = false;
> > + else
> > + ah->is_clk_25mhz = true;
> > + }
> > +
> > if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
> > ath_err(common, "Couldn't wakeup chip\n");
> > return -EIO;
> I think this flag should be passed down from the arch code through
> platform data instead. Also, dereferencing volatile u32 pointers for
> reading registers is somewhat hackish, readl or ioread32 would be better.

Yeah, I was also not comfortable with this part of code. I'll fix
that. thanks for the comments.

Vasanth

Subject: [PATCH 21/22] ath9k_hw: Disable INTR_HOST1_FATAL to avoid interrupt strom with ar9430

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath9k/hw.c | 6 +++++-
drivers/net/wireless/ath/ath9k/mac.c | 10 ++++++----
2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index aaf7f7a..072e0eb 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -804,12 +804,16 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
enum nl80211_iftype opmode)
{
+ u32 sync_default = AR_INTR_SYNC_DEFAULT;
u32 imr_reg = AR_IMR_TXERR |
AR_IMR_TXURN |
AR_IMR_RXERR |
AR_IMR_RXORN |
AR_IMR_BCNMISC;

+ if (AR_SREV_9340(ah))
+ sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
+
if (AR_SREV_9300_20_OR_LATER(ah)) {
imr_reg |= AR_IMR_RXOK_HP;
if (ah->config.rx_intr_mitigation)
@@ -840,7 +844,7 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,

if (!AR_SREV_9100(ah)) {
REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF);
- REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT);
+ REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default);
REG_WRITE(ah, AR_INTR_SYNC_MASK, 0);
}

diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 6f431cb..d86b839 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -793,10 +793,14 @@ EXPORT_SYMBOL(ath9k_hw_disable_interrupts);
void ath9k_hw_enable_interrupts(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
+ u32 sync_default = AR_INTR_SYNC_DEFAULT;

if (!(ah->imask & ATH9K_INT_GLOBAL))
return;

+ if (AR_SREV_9340(ah))
+ sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
+
ath_dbg(common, ATH_DBG_INTERRUPT, "enable IER\n");
REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
if (!AR_SREV_9100(ah)) {
@@ -805,10 +809,8 @@ void ath9k_hw_enable_interrupts(struct ath_hw *ah)
REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);


- REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
- AR_INTR_SYNC_DEFAULT);
- REG_WRITE(ah, AR_INTR_SYNC_MASK,
- AR_INTR_SYNC_DEFAULT);
+ REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default);
+ REG_WRITE(ah, AR_INTR_SYNC_MASK, sync_default);
}
ath_dbg(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
--
1.7.0.4


Subject: [PATCH 22/22] ath9k_hw: Enable AR9340 support

AR9340 is a AR9003 family built-in 2x2 wmac of ar934x SOCs. It is single band
in ar9341 SOC and dual band in ar9344/ar9342 SOCs.

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

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 072e0eb..49ec4da 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -563,6 +563,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
case AR_SREV_VERSION_9271:
case AR_SREV_VERSION_9300:
case AR_SREV_VERSION_9485:
+ case AR_SREV_VERSION_9340:
break;
default:
ath_err(common,
@@ -640,6 +641,7 @@ int ath9k_hw_init(struct ath_hw *ah)
case AR2427_DEVID_PCIE:
case AR9300_DEVID_PCIE:
case AR9300_DEVID_AR9485_PCIE:
+ case AR9300_DEVID_AR9340:
break;
default:
if (common->bus_ops->ath_bus_type == ATH_USB)
--
1.7.0.4


Subject: [PATCH 09/22] ath9k_hw: Read spur frequency information from eeprom for AR9340

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

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 1544e57..65c52b4 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -151,7 +151,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,
* is out-of-band and can be ignored.
*/

- if (AR_SREV_9485(ah)) {
+ if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) {
spur_fbin_ptr = ar9003_get_spur_chan_ptr(ah,
IS_CHAN_2GHZ(chan));
if (spur_fbin_ptr[0] == 0) /* No spur */
@@ -176,7 +176,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,

for (i = 0; i < max_spur_cnts; i++) {
negative = 0;
- if (AR_SREV_9485(ah))
+ if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i],
IS_CHAN_2GHZ(chan)) - synth_freq;
else
--
1.7.0.4


Subject: [PATCH 10/22] ath9k_hw: Configure RF channel freqency for AR9340

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath9k/ar9003_phy.c | 23 ++++++++++++++++++++---
1 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 65c52b4..1ec0d72 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -86,14 +86,31 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
channelSel = (freq * 4) / 120;
chan_frac = (((freq * 4) % 120) * 0x20000) / 120;
channelSel = (channelSel << 17) | chan_frac;
+ } else if (AR_SREV_9340(ah)) {
+ if (ah->is_clk_25mhz) {
+ u32 chan_frac;
+
+ channelSel = (freq * 2) / 75;
+ chan_frac = (((freq * 2) % 75) * 0x20000) / 75;
+ channelSel = (channelSel << 17) | chan_frac;
+ } else
+ channelSel = CHANSEL_2G(freq) >> 1;
} else
channelSel = CHANSEL_2G(freq);
/* Set to 2G mode */
bMode = 1;
} else {
- channelSel = CHANSEL_5G(freq);
- /* Doubler is ON, so, divide channelSel by 2. */
- channelSel >>= 1;
+ if (AR_SREV_9340(ah) && ah->is_clk_25mhz) {
+ u32 chan_frac;
+
+ channelSel = (freq * 2) / 75;
+ chan_frac = ((freq % 75) * 0x20000) / 75;
+ channelSel = (channelSel << 17) | chan_frac;
+ } else {
+ channelSel = CHANSEL_5G(freq);
+ /* Doubler is ON, so, divide channelSel by 2. */
+ channelSel >>= 1;
+ }
/* Set to 5G mode */
bMode = 0;
}
--
1.7.0.4


2011-04-12 13:50:38

by Felix Fietkau

[permalink] [raw]
Subject: Re: [PATCH 03/22] ath9k_hw: Introduce a bool for 25mhz clock and populate it

On 2011-04-12 3:17 PM, Vasanthakumar Thiagarajan wrote:
> pll configuration will differ for 25mhz clock.
>
> Signed-off-by: Vasanthakumar Thiagarajan<[email protected]>
> ---
> drivers/net/wireless/ath/ath9k/hw.c | 11 +++++++++++
> drivers/net/wireless/ath/ath9k/hw.h | 2 ++
> 2 files changed, 13 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
> index d98b4c6..8b90b9c 100644
> --- a/drivers/net/wireless/ath/ath9k/hw.c
> +++ b/drivers/net/wireless/ath/ath9k/hw.c
> @@ -481,6 +481,9 @@ static void ath9k_hw_attach_ops(struct ath_hw *ah)
> /* Called for all hardware families */
> static int __ath9k_hw_init(struct ath_hw *ah)
> {
> +#define AR9340_SOC_SEL_25M_40M 0xB80600B0
> +#define AR9340_REF_CLK_40 (1<< 4) /* 0 - 25MHz 1 - 40 MHz */
> +
> struct ath_common *common = ath9k_hw_common(ah);
> int r = 0;
>
> @@ -508,6 +511,14 @@ static int __ath9k_hw_init(struct ath_hw *ah)
>
> ath9k_hw_attach_ops(ah);
>
> + if (AR_SREV_9340(ah)) {
> + if (*((volatile u32 *) AR9340_SOC_SEL_25M_40M)&
> + AR9340_REF_CLK_40)
> + ah->is_clk_25mhz = false;
> + else
> + ah->is_clk_25mhz = true;
> + }
> +
> if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
> ath_err(common, "Couldn't wakeup chip\n");
> return -EIO;
I think this flag should be passed down from the arch code through
platform data instead. Also, dereferencing volatile u32 pointers for
reading registers is somewhat hackish, readl or ioread32 would be better.

- Felix

Subject: Re: [PATCH 03/22] ath9k_hw: Introduce a bool for 25mhz clock and populate it

On Tue, Apr 12, 2011 at 07:30:36PM +0530, Vasanth Thiagarajan wrote:
> > > {
> > > +#define AR9340_SOC_SEL_25M_40M 0xB80600B0
> > > +#define AR9340_REF_CLK_40 (1<< 4) /* 0 - 25MHz 1 - 40 MHz */
> > > +
> > > struct ath_common *common = ath9k_hw_common(ah);
> > > int r = 0;
> > >
> > > @@ -508,6 +511,14 @@ static int __ath9k_hw_init(struct ath_hw *ah)
> > >
> > > ath9k_hw_attach_ops(ah);
> > >
> > > + if (AR_SREV_9340(ah)) {
> > > + if (*((volatile u32 *) AR9340_SOC_SEL_25M_40M)&
> > > + AR9340_REF_CLK_40)
> > > + ah->is_clk_25mhz = false;
> > > + else
> > > + ah->is_clk_25mhz = true;
> > > + }
> > > +
> > > if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
> > > ath_err(common, "Couldn't wakeup chip\n");
> > > return -EIO;
> > I think this flag should be passed down from the arch code through
> > platform data instead. Also, dereferencing volatile u32 pointers for
> > reading registers is somewhat hackish, readl or ioread32 would be better.
>
> Yeah, I was also not comfortable with this part of code. I'll fix
> that. thanks for the comments.

Linville, ralf,

The code change needs to be done in arch code also to fix this
cleanly. I'm not quite sure about the right way of submitting changes
in BSP and ath9k driver without possibly breaking the driver due to
the fact that the change in BSP may not be available along with
driver change soon in wireless-testing.

Vasanth

Subject: [PATCH 07/22] ath9k_hw: Don't do ani initialization for AR9340

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

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 9e8a9c6..d154c5c 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -462,7 +462,7 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
return ecode;
}

- if (!AR_SREV_9100(ah)) {
+ if (!AR_SREV_9100(ah) && !AR_SREV_9340(ah)) {
ath9k_hw_ani_setup(ah);
ath9k_hw_ani_init(ah);
}
--
1.7.0.4


Subject: [PATCH 04/22] ath9k_hw: Configure pll control register accordingly for AR9340

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath9k/hw.c | 52 ++++++++++++++++++++++++++++++++--
drivers/net/wireless/ath/ath9k/hw.h | 2 +-
drivers/net/wireless/ath/ath9k/phy.h | 3 ++
drivers/net/wireless/ath/ath9k/reg.h | 4 ++-
4 files changed, 56 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 8b90b9c..9e8a9c6 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -725,15 +725,48 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
AR_CH0_BB_DPLL2_PLL_PWD, 0x0);
udelay(1000);

- REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3,
- AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL);
+ } else if (AR_SREV_9340(ah)) {
+ u32 regval, pll2_divint, pll2_divfrac, refdiv;
+
+ REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c);
+ udelay(1000);
+
+ REG_SET_BIT(ah, AR_PHY_PLL_MODE, 0x1 << 16);
+ udelay(100);
+
+ if (ah->is_clk_25mhz) {
+ pll2_divint = 0x54;
+ pll2_divfrac = 0x1eb85;
+ refdiv = 3;
+ } else {
+ pll2_divint = 88;
+ pll2_divfrac = 0;
+ refdiv = 5;
+ }
+
+ regval = REG_READ(ah, AR_PHY_PLL_MODE);
+ regval |= (0x1 << 16);
+ REG_WRITE(ah, AR_PHY_PLL_MODE, regval);
+ udelay(100);
+
+ REG_WRITE(ah, AR_PHY_PLL_CONTROL, (refdiv << 27) |
+ (pll2_divint << 18) | pll2_divfrac);
+ udelay(100);
+
+ regval = REG_READ(ah, AR_PHY_PLL_MODE);
+ regval = (regval & 0x80071fff) | (0x1 << 30) | (0x1 << 13) |
+ (0x4 << 26) | (0x18 << 19);
+ REG_WRITE(ah, AR_PHY_PLL_MODE, regval);
+ REG_WRITE(ah, AR_PHY_PLL_MODE,
+ REG_READ(ah, AR_PHY_PLL_MODE) & 0xfffeffff);
+ udelay(1000);
}

pll = ath9k_hw_compute_pll_control(ah, chan);

REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);

- if (AR_SREV_9485(ah))
+ if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
udelay(1000);

/* Switch the core clock for ar9271 to 117Mhz */
@@ -745,6 +778,19 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
udelay(RTC_PLL_SETTLE_DELAY);

REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
+
+ if (AR_SREV_9340(ah)) {
+ if (ah->is_clk_25mhz) {
+ REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1);
+ REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7);
+ REG_WRITE(ah, AR_SLP32_INC, 0x0001e7ae);
+ } else {
+ REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x261 << 1);
+ REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400);
+ REG_WRITE(ah, AR_SLP32_INC, 0x0001e800);
+ }
+ udelay(100);
+ }
}

static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 721eb27..7837a83 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -122,7 +122,7 @@
#define AR_GPIO_BIT(_gpio) (1 << (_gpio))

#define BASE_ACTIVATE_DELAY 100
-#define RTC_PLL_SETTLE_DELAY 100
+#define RTC_PLL_SETTLE_DELAY (AR_SREV_9340(ah) ? 1000 : 100)
#define COEF_SCALE_S 24
#define HT40_CHANNEL_CENTER_SHIFT 10

diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index 8e5fe9d..9441bf8 100644
--- a/drivers/net/wireless/ath/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -45,4 +45,7 @@
#define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000
#define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20

+#define AR_PHY_PLL_CONTROL 0x16180
+#define AR_PHY_PLL_MODE 0x16184
+
#endif
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 53285a1..fbc18d3 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -1182,6 +1182,7 @@ enum {
#define AR_RTC_PLL_REFDIV_5 0x000000c0
#define AR_RTC_PLL_CLKSEL 0x00000300
#define AR_RTC_PLL_CLKSEL_S 8
+#define AR_RTC_PLL_BYPASS 0x00010000

#define PLL3 0x16188
#define PLL3_DO_MEAS_MASK 0x40000000
@@ -1228,7 +1229,8 @@ enum {

/* RTC_DERIVED_* - only for AR9100 */

-#define AR_RTC_DERIVED_CLK (AR_RTC_BASE + 0x0038)
+#define AR_RTC_DERIVED_CLK \
+ (AR_SREV_9100(ah) ? (AR_RTC_BASE + 0x0038) : 0x7038)
#define AR_RTC_DERIVED_CLK_PERIOD 0x0000fffe
#define AR_RTC_DERIVED_CLK_PERIOD_S 1

--
1.7.0.4


Subject: [PATCH 18/22] ath9k_hw: Read iq calibration data only for active chains

Signed-off-by: Vasanthakumar Thiagarajan <[email protected]>
---
drivers/net/wireless/ath/ath9k/ar9003_calib.c | 24 +++++++++++++-----------
1 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index 09f3aa7..bceff49 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -185,17 +185,19 @@ static void ar9003_hw_iqcal_collect(struct ath_hw *ah)

/* Accumulate IQ cal measures for active chains */
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
- ah->totalPowerMeasI[i] +=
- REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
- ah->totalPowerMeasQ[i] +=
- REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
- ah->totalIqCorrMeas[i] +=
- (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
- ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
- "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
- ah->cal_samples, i, ah->totalPowerMeasI[i],
- ah->totalPowerMeasQ[i],
- ah->totalIqCorrMeas[i]);
+ if (ah->txchainmask & BIT(i)) {
+ ah->totalPowerMeasI[i] +=
+ REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
+ ah->totalPowerMeasQ[i] +=
+ REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
+ ah->totalIqCorrMeas[i] +=
+ (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
+ ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
+ "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
+ ah->cal_samples, i, ah->totalPowerMeasI[i],
+ ah->totalPowerMeasQ[i],
+ ah->totalIqCorrMeas[i]);
+ }
}
}

--
1.7.0.4


2011-04-12 15:00:32

by John W. Linville

[permalink] [raw]
Subject: Re: [PATCH 03/22] ath9k_hw: Introduce a bool for 25mhz clock and populate it

On Tue, Apr 12, 2011 at 08:03:06PM +0530, Vasanthakumar Thiagarajan wrote:
> On Tue, Apr 12, 2011 at 07:30:36PM +0530, Vasanth Thiagarajan wrote:
> > > > {
> > > > +#define AR9340_SOC_SEL_25M_40M 0xB80600B0
> > > > +#define AR9340_REF_CLK_40 (1<< 4) /* 0 - 25MHz 1 - 40 MHz */
> > > > +
> > > > struct ath_common *common = ath9k_hw_common(ah);
> > > > int r = 0;
> > > >
> > > > @@ -508,6 +511,14 @@ static int __ath9k_hw_init(struct ath_hw *ah)
> > > >
> > > > ath9k_hw_attach_ops(ah);
> > > >
> > > > + if (AR_SREV_9340(ah)) {
> > > > + if (*((volatile u32 *) AR9340_SOC_SEL_25M_40M)&
> > > > + AR9340_REF_CLK_40)
> > > > + ah->is_clk_25mhz = false;
> > > > + else
> > > > + ah->is_clk_25mhz = true;
> > > > + }
> > > > +
> > > > if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
> > > > ath_err(common, "Couldn't wakeup chip\n");
> > > > return -EIO;
> > > I think this flag should be passed down from the arch code through
> > > platform data instead. Also, dereferencing volatile u32 pointers for
> > > reading registers is somewhat hackish, readl or ioread32 would be better.
> >
> > Yeah, I was also not comfortable with this part of code. I'll fix
> > that. thanks for the comments.
>
> Linville, ralf,
>
> The code change needs to be done in arch code also to fix this
> cleanly. I'm not quite sure about the right way of submitting changes
> in BSP and ath9k driver without possibly breaking the driver due to
> the fact that the change in BSP may not be available along with
> driver change soon in wireless-testing.

Generally we can negotiate to take the related changes through one
tree or the other. How does the arch change look?

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