linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias
@ 2009-10-19  6:33 Luis R. Rodriguez
  2009-10-19  6:33 ` [RFT 01/15] ath9k_hw: modify the rf control register for ar9271 revision 1.0 Luis R. Rodriguez
                   ` (15 more replies)
  0 siblings, 16 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-10-19  6:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez

This series started off to extend support for ar9271 on ath9k_hw
but after review of the phy related code I noticed a fix for
AR5416 was only partially being implemented and used for all
chipsets. This series then adds the changes I've noticed so far
required for ar9271 but also fixes and completes the orientation
fix for AR5416 (force bias). Since I'm touching phy.c I also extend
documentation for it.

I don't have AR9285 cards with me but I do have an AR5416 cardbus
card -- I'd appreciate it if someone can give this a test on AR9285
but also more AR5416 cards -- this should help with TX on of AR5416
and AR5418 on the 2.4 GHz band.

Reports on issues or performance differences are greatly appreciated;
the only issue I'd expect you'd see on non AR5416 hardware is a BUG_ON()
which would be very obvious to notice and the performance enhancements
should be seen on AR5416 for TX -- not yet sure exactly under what
circumstances.

Luis R. Rodriguez (15):
  ath9k_hw: modify the rf control register for ar9271 revision 1.0
  ath9k_hw: update register initialization/reset values for ar9271
  ath9k_hw: change the way we initialize the pll for ar9271
  ath9k_hw: start documenting 802.11n RF anlong front ends
  ath9k_hw: bail out early on ath9k_hw_init_rf()
  ath9k_hw: simplify rf attach and rename to
    ath9k_hw_rf_alloc_ext_banks()
  ath9k_hw: simplify ath9k_hw_rf_alloc_ext_banks()
  ath9k_hw: rename ath9k_hw_rf_free() to ath9k_hw_rf_free_ext_banks()
  ath9k_hw: make both analog channel change routines return int
  ath9k_hw: use a callback for frequency change
  ath9k_hw: order phy.c code and integrate spur mitigation
  ath9k_hw: make spur mitigation a callback
  ath9k_hw: remove unused modesIndex param from ath9k_hw_write_regs()
  ath9k_hw: Fix and complete force bias for AR5416
  ath9k_hw: make ath9k_phy_modify_rx_buffer() static

 drivers/net/wireless/ath/ath9k/eeprom_4k.c |    4 +
 drivers/net/wireless/ath/ath9k/hw.c        |  580 ++-------------
 drivers/net/wireless/ath/ath9k/hw.h        |   20 +-
 drivers/net/wireless/ath/ath9k/initvals.h  |   29 +-
 drivers/net/wireless/ath/ath9k/phy.c       | 1100 ++++++++++++++++++++++------
 drivers/net/wireless/ath/ath9k/phy.h       |   24 +-
 drivers/net/wireless/ath/ath9k/reg.h       |    3 +
 7 files changed, 1013 insertions(+), 747 deletions(-)


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [RFT 01/15] ath9k_hw: modify the rf control register for ar9271 revision 1.0
  2009-10-19  6:33 [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias Luis R. Rodriguez
@ 2009-10-19  6:33 ` Luis R. Rodriguez
  2009-10-19  6:33 ` [RFT 02/15] ath9k_hw: update register initialization/reset values for ar9271 Luis R. Rodriguez
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-10-19  6:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/eeprom_4k.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index 58167d8..68db166 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -1112,6 +1112,10 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
 
 	REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
 		      pModal->txEndToRxOn);
+
+	if (AR_SREV_9271_10(ah))
+		REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
+			      pModal->txEndToRxOn);
 	REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
 		      pModal->thresh62);
 	REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62,
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFT 02/15] ath9k_hw: update register initialization/reset values for ar9271
  2009-10-19  6:33 [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias Luis R. Rodriguez
  2009-10-19  6:33 ` [RFT 01/15] ath9k_hw: modify the rf control register for ar9271 revision 1.0 Luis R. Rodriguez
@ 2009-10-19  6:33 ` Luis R. Rodriguez
  2009-10-19  6:33 ` [RFT 03/15] ath9k_hw: change the way we initialize the pll " Luis R. Rodriguez
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-10-19  6:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez, Stephen Chen

This update the register initialization/reset values (aka initvals)
for ar9271 based on the last recommended values on 2009-06-04 by our
systems engineering team.

The changes account for:

  * Supporting ar9271 1.0 and ar9271 1.1 together, the difference
    is bb_spectral_scan_ena, for 1.0 we'll set this to 0x1.

  * Ensuring we get the correct noise floor values -115 ~ -118
    when we enable bb_enable_ant_div_lnadiv=0 and
    mc_tx_def_ant_sel=1. Previous to this we would get noise
    floor values in the range -50 ~ -80. To fix settings for
    the registers:

     - bb_ch1_xatten1_db
     - bb_ch1_xatten2_db
     - bb_ch1_xatten1_margin
     - bb_ch1_xatten2_margin
     - bb_ch1_gain_force
     - bb_ch1_xatten2_hyst_margin
     - bb_ch1_xatten1_hyst_margin
     - bb_ch1_max_oc_gain

  * 0x8120[2] mc_mic_new_location_enable is changed to 0x1. The MAC team
    suggest to set this value.

  * 0x9910[0] bb_spectral_scan_ena is changed to 0x0.
    For ar9271 1.1 we don't need to enable this bit.

Cc: Stephen Chen <Stephen.Chen@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c       |   15 +++++++++++----
 drivers/net/wireless/ath/ath9k/hw.h       |    1 +
 drivers/net/wireless/ath/ath9k/initvals.h |   29 +++++++++++++++++------------
 3 files changed, 29 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index cab17c6..6df00ab 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -662,10 +662,13 @@ static void ath9k_hw_init_cal_settings(struct ath_hw *ah)
 static void ath9k_hw_init_mode_regs(struct ath_hw *ah)
 {
 	if (AR_SREV_9271(ah)) {
-		INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271_1_0,
-			       ARRAY_SIZE(ar9271Modes_9271_1_0), 6);
-		INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271_1_0,
-			       ARRAY_SIZE(ar9271Common_9271_1_0), 2);
+		INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271,
+			       ARRAY_SIZE(ar9271Modes_9271), 6);
+		INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271,
+			       ARRAY_SIZE(ar9271Common_9271), 2);
+		INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only,
+			       ar9271Modes_9271_1_0_only,
+			       ARRAY_SIZE(ar9271Modes_9271_1_0_only), 6);
 		return;
 	}
 
@@ -1491,6 +1494,10 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
 
 	ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites);
 
+	if (AR_SREV_9271_10(ah))
+		REG_WRITE_ARRAY(&ah->iniModes_9271_1_0_only,
+				modesIndex, regWrites);
+
 	if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
 		REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex,
 				regWrites);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index cdaec52..0b3fc4e 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -596,6 +596,7 @@ struct ath_hw {
 	struct ar5416IniArray iniModesAdditional;
 	struct ar5416IniArray iniModesRxGain;
 	struct ar5416IniArray iniModesTxGain;
+	struct ar5416IniArray iniModes_9271_1_0_only;
 	struct ar5416IniArray iniCckfirNormal;
 	struct ar5416IniArray iniCckfirJapan2484;
 
diff --git a/drivers/net/wireless/ath/ath9k/initvals.h b/drivers/net/wireless/ath/ath9k/initvals.h
index 3ee6658..8a3bf3a 100644
--- a/drivers/net/wireless/ath/ath9k/initvals.h
+++ b/drivers/net/wireless/ath/ath9k/initvals.h
@@ -6379,8 +6379,8 @@ static const u_int32_t ar9287PciePhy_clkreq_off_L1_9287_1_1[][2] = {
 };
 
 
-/* AR9271 initialization values automaticaly created: 03/23/09 */
-static const u_int32_t ar9271Modes_9271_1_0[][6] = {
+/* AR9271 initialization values automaticaly created: 06/04/09 */
+static const u_int32_t ar9271Modes_9271[][6] = {
     { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
     { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
     { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
@@ -6390,8 +6390,8 @@ static const u_int32_t ar9271Modes_9271_1_0[][6] = {
     { 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 },
     { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
     { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
-    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
-    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
+    { 0x00009824, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e },
+    { 0x00009828, 0x3a020001, 0x3a020001, 0x3a020001, 0x3a020001, 0x3a020001 },
     { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
     { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
     { 0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e },
@@ -6405,6 +6405,7 @@ static const u_int32_t ar9271Modes_9271_1_0[][6] = {
     { 0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
     { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 },
     { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 },
+    { 0x00009910, 0x30002310, 0x30002310, 0x30002310, 0x30002310, 0x30002310 },
     { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
     { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
     { 0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d },
@@ -6415,7 +6416,7 @@ static const u_int32_t ar9271Modes_9271_1_0[][6] = {
     { 0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 },
     { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
     { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
-    { 0x000099c8, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329 },
+    { 0x000099c8, 0x6af6532f, 0x6af6532f, 0x6af6532f, 0x6af6532f, 0x6af6532f },
     { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
     { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
     { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
@@ -6704,7 +6705,7 @@ static const u_int32_t ar9271Modes_9271_1_0[][6] = {
     { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
 };
 
-static const u_int32_t ar9271Common_9271_1_0[][2] = {
+static const u_int32_t ar9271Common_9271[][2] = {
     { 0x0000000c, 0x00000000 },
     { 0x00000030, 0x00020045 },
     { 0x00000034, 0x00000005 },
@@ -6800,7 +6801,7 @@ static const u_int32_t ar9271Common_9271_1_0[][2] = {
     { 0x0000803c, 0x00000000 },
     { 0x00008048, 0x00000000 },
     { 0x00008054, 0x00000000 },
-    { 0x00008058, 0x02000000 },
+    { 0x00008058, 0x00000000 },
     { 0x0000805c, 0x000fc78f },
     { 0x00008060, 0x0000000f },
     { 0x00008064, 0x00000000 },
@@ -6831,7 +6832,7 @@ static const u_int32_t ar9271Common_9271_1_0[][2] = {
     { 0x00008110, 0x00000168 },
     { 0x00008118, 0x000100aa },
     { 0x0000811c, 0x00003210 },
-    { 0x00008120, 0x08f04814 },
+    { 0x00008120, 0x08f04810 },
     { 0x00008124, 0x00000000 },
     { 0x00008128, 0x00000000 },
     { 0x0000812c, 0x00000000 },
@@ -6878,7 +6879,7 @@ static const u_int32_t ar9271Common_9271_1_0[][2] = {
     { 0x00008258, 0x00000000 },
     { 0x0000825c, 0x400000ff },
     { 0x00008260, 0x00080922 },
-    { 0x00008264, 0xa8a00010 },
+    { 0x00008264, 0x88a00010 },
     { 0x00008270, 0x00000000 },
     { 0x00008274, 0x40000000 },
     { 0x00008278, 0x003e4180 },
@@ -6910,7 +6911,7 @@ static const u_int32_t ar9271Common_9271_1_0[][2] = {
     { 0x00007814, 0x924934a8 },
     { 0x0000781c, 0x00000000 },
     { 0x00007820, 0x00000c04 },
-    { 0x00007824, 0x00d86bff },
+    { 0x00007824, 0x00d8abff },
     { 0x00007828, 0x66964300 },
     { 0x0000782c, 0x8db6d961 },
     { 0x00007830, 0x8db6d96c },
@@ -6944,7 +6945,6 @@ static const u_int32_t ar9271Common_9271_1_0[][2] = {
     { 0x00009904, 0x00000000 },
     { 0x00009908, 0x00000000 },
     { 0x0000990c, 0x00000000 },
-    { 0x00009910, 0x30002310 },
     { 0x0000991c, 0x10000fff },
     { 0x00009920, 0x04900000 },
     { 0x00009928, 0x00000001 },
@@ -6958,7 +6958,7 @@ static const u_int32_t ar9271Common_9271_1_0[][2] = {
     { 0x00009954, 0x5f3ca3de },
     { 0x00009958, 0x0108ecff },
     { 0x00009968, 0x000003ce },
-    { 0x00009970, 0x192bb515 },
+    { 0x00009970, 0x192bb514 },
     { 0x00009974, 0x00000000 },
     { 0x00009978, 0x00000001 },
     { 0x0000997c, 0x00000000 },
@@ -7045,3 +7045,8 @@ static const u_int32_t ar9271Common_9271_1_0[][2] = {
     { 0x0000d380, 0x7f3c7bba },
     { 0x0000d384, 0xf3307ff0 },
 };
+
+static const u_int32_t ar9271Modes_9271_1_0_only[][6] = {
+    { 0x00009910, 0x30002311, 0x30002311, 0x30002311, 0x30002311, 0x30002311 },
+    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
+};
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFT 03/15] ath9k_hw: change the way we initialize the pll for ar9271
  2009-10-19  6:33 [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias Luis R. Rodriguez
  2009-10-19  6:33 ` [RFT 01/15] ath9k_hw: modify the rf control register for ar9271 revision 1.0 Luis R. Rodriguez
  2009-10-19  6:33 ` [RFT 02/15] ath9k_hw: update register initialization/reset values for ar9271 Luis R. Rodriguez
@ 2009-10-19  6:33 ` Luis R. Rodriguez
  2009-10-19  6:33 ` [RFT 04/15] ath9k_hw: start documenting 802.11n RF anlong front ends Luis R. Rodriguez
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-10-19  6:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez

We adjust the core clock for ar9271 to 117 MHz; this also
requires us to adjust the baud divider based on the targetted
baud rate.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c  |   36 ++++++++++++++++++++++++++++++++++
 drivers/net/wireless/ath/ath9k/reg.h |    3 ++
 2 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 6df00ab..f67d3a4 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1040,6 +1040,22 @@ static void ath9k_hw_init_qos(struct ath_hw *ah)
 	REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
 }
 
+static void ath9k_hw_change_target_baud(struct ath_hw *ah, u32 freq, u32 baud)
+{
+	u32 lcr;
+	u32 baud_divider = freq * 1000 * 1000 / 16 / baud;
+
+	lcr = REG_READ(ah , 0x5100c);
+	lcr |= 0x80;
+
+	REG_WRITE(ah, 0x5100c, lcr);
+	REG_WRITE(ah, 0x51004, (baud_divider >> 8));
+	REG_WRITE(ah, 0x51000, (baud_divider & 0xff));
+
+	lcr &= ~0x80;
+	REG_WRITE(ah, 0x5100c, lcr);
+}
+
 static void ath9k_hw_init_pll(struct ath_hw *ah,
 			      struct ath9k_channel *chan)
 {
@@ -1103,6 +1119,26 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
 	}
 	REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
 
+	/* Switch the core clock for ar9271 to 117Mhz */
+	if (AR_SREV_9271(ah)) {
+		if ((pll == 0x142c) || (pll == 0x2850) ) {
+			udelay(500);
+			/* set CLKOBS to output AHB clock */
+			REG_WRITE(ah, 0x7020, 0xe);
+			/*
+			 * 0x304: 117Mhz, ahb_ratio: 1x1
+			 * 0x306: 40Mhz, ahb_ratio: 1x1
+			 */
+			REG_WRITE(ah, 0x50040, 0x304);
+			/*
+			 * makes adjustments for the baud dividor to keep the
+			 * targetted baud rate based on the used core clock.
+			 */
+			ath9k_hw_change_target_baud(ah, AR9271_CORE_CLOCK,
+						    AR9271_TARGET_BAUD_RATE);
+		}
+	}
+
 	udelay(RTC_PLL_SETTLE_DELAY);
 
 	REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index ceed009..061e12c 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -1704,4 +1704,7 @@ enum {
 #define AR_KEYTABLE_MAC0(_n)    (AR_KEYTABLE(_n) + 24)
 #define AR_KEYTABLE_MAC1(_n)    (AR_KEYTABLE(_n) + 28)
 
+#define AR9271_CORE_CLOCK	117   /* clock to 117Mhz */
+#define AR9271_TARGET_BAUD_RATE	19200 /* 115200 */
+
 #endif
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFT 04/15] ath9k_hw: start documenting 802.11n RF anlong front ends
  2009-10-19  6:33 [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias Luis R. Rodriguez
                   ` (2 preceding siblings ...)
  2009-10-19  6:33 ` [RFT 03/15] ath9k_hw: change the way we initialize the pll " Luis R. Rodriguez
@ 2009-10-19  6:33 ` Luis R. Rodriguez
  2009-10-19  6:33 ` [RFT 05/15] ath9k_hw: bail out early on ath9k_hw_init_rf() Luis R. Rodriguez
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-10-19  6:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez

Document what we can about the RF analog front ends (radios)
of Atheros 802.11n devices. What should be clearer now is the
what we do for old pre AR5416 and AR5418 MAC based devices in
comparison to the modern sigle-chip 802.11n solutions.

All devices after AR9280 are single chip and require less
programming -- the RF registers no longer need to be initialized
as they all have the RF analog front end embedded together with
the MAC/BB; this includes the AR9271. Older devices such as the
ones with the AR5416 MACs (PCI) or AR5418 MACs (PCI-E) have an
external 2.4 GHz AR2133 radio or a dual band 2.4 GHz / 5 GHz
AR5133 radio. These external radios require additional programming
of the RF registers.

Clarify which parts are for what devices and which code is
shared. This patch has no functional changes.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.h  |    9 ++
 drivers/net/wireless/ath/ath9k/phy.c |  166 +++++++++++++++++++++++++++++++++-
 2 files changed, 170 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 0b3fc4e..8fe64cf 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -148,6 +148,15 @@ enum wireless_mode {
 	ATH9K_MODE_MAX,
 };
 
+/**
+ * ath9k_ant_setting - transmit antenna settings
+ *
+ * Configures the antenna setting to use for transmit.
+ *
+ * @ATH9K_ANT_VARIABLE: this means transmit on all active antennas
+ * @ATH9K_ANT_FIXED_A: this means transmit on the first antenna only
+ * @ATH9K_ANT_FIXED_B: this means transmit on the second antenna only
+ */
 enum ath9k_ant_setting {
 	ATH9K_ANT_VARIABLE = 0,
 	ATH9K_ANT_FIXED_A,
diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c
index 72a17c4..9e51503 100644
--- a/drivers/net/wireless/ath/ath9k/phy.c
+++ b/drivers/net/wireless/ath/ath9k/phy.c
@@ -14,8 +14,44 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+/**
+ * DOC: Programming Atheros 802.11n analog front end radios
+ *
+ * AR5416 MAC based PCI devices and AR518 MAC based PCI-Express
+ * devices have either an external AR2133 analog front end radio for single
+ * band 2.4 GHz communication or an AR5133 analog front end radio for dual
+ * band 2.4 GHz / 5 GHz communication.
+ *
+ * All devices after the AR5416 and AR5418 family starting with the AR9280
+ * have their analog front radios, MAC/BB and host PCIe/USB interface embedded
+ * into a single-chip and require less programming.
+ *
+ * The following single-chips exist with a respective embedded radio:
+ *
+ * AR9280 - 11n dual-band 2x2 MIMO for PCIe
+ * AR9281 - 11n single-band 1x2 MIMO for PCIe
+ * AR9285 - 11n single-band 1x1 for PCIe
+ * AR9287 - 11n single-band 2x2 MIMO for PCIe
+ *
+ * AR9220 - 11n dual-band 2x2 MIMO for PCI
+ * AR9223 - 11n single-band 2x2 MIMO for PCI
+ *
+ * AR9287 - 11n single-band 1x1 MIMO for USB
+ */
+
 #include "hw.h"
 
+/**
+ * ath9k_hw_write_regs - ??
+ *
+ * @ah: atheros hardware structure
+ * @modesIndex:
+ * @freqIndex:
+ * @regWrites:
+ *
+ * Used for both the chipsets with an external AR2133/AR5133 radios and
+ * single-chip devices.
+ */
 void
 ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex, u32 freqIndex,
 		    int regWrites)
@@ -23,6 +59,15 @@ ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex, u32 freqIndex,
 	REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites);
 }
 
+/**
+ * ath9k_hw_set_channel - tune to a channel on the external AR2133/AR5133 radios
+ * @ah: atheros hardware stucture
+ * @chan:
+ *
+ * For the external AR2133/AR5133 radios, takes the MHz channel value and set
+ * the channel value. Assumes writes enabled to analog bus and bank6 register
+ * cache in ah->analogBank6Data.
+ */
 bool
 ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
 {
@@ -97,6 +142,27 @@ ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
 	return true;
 }
 
+/**
+ * ath9k_hw_ar9280_set_channel - set channel on single-chip device
+ * @ah: atheros hardware structure
+ * @chan:
+ *
+ * This is the function to change channel on single-chip devices, that is
+ * all devices after ar9280.
+ *
+ * This function takes the channel value in MHz and sets
+ * hardware channel value. Assumes writes have been enabled to analog bus.
+ *
+ * Actual Expression,
+ *
+ * For 2GHz channel,
+ * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
+ * (freq_ref = 40MHz)
+ *
+ * For 5GHz channel,
+ * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10)
+ * (freq_ref = 40MHz/(24>>amodeRefSel))
+ */
 void ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
 				 struct ath9k_channel *chan)
 {
@@ -111,7 +177,7 @@ void ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
 	reg32 = REG_READ(ah, AR_PHY_SYNTH_CONTROL);
 	reg32 &= 0xc0000000;
 
-	if (freq < 4800) {
+	if (freq < 4800) { /* 2 GHz, fractional mode */
 		u32 txctl;
 		int regWrites = 0;
 
@@ -122,6 +188,7 @@ void ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
 
 		if (AR_SREV_9287_11_OR_LATER(ah)) {
 			if (freq == 2484) {
+				/* Enable channel spreading for channel 14 */
 				REG_WRITE_ARRAY(&ah->iniCckfirJapan2484,
 						1, regWrites);
 			} else {
@@ -155,10 +222,15 @@ void ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
 		case 1:
 		default:
 			aModeRefSel = 0;
+			/*
+			 * Enable 2G (fractional) mode for channels
+			 * which are 5MHz spaced.
+			 */
 			fracMode = 1;
 			refDivA = 1;
 			channelSel = (freq * 0x8000) / 15;
 
+			/* RefDivA setting */
 			REG_RMW_FIELD(ah, AR_AN_SYNTH9,
 				      AR_AN_SYNTH9_REFDIVA, refDivA);
 
@@ -182,6 +254,17 @@ void ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
 	ah->curchan_rad_index = -1;
 }
 
+/**
+ * ath9k_phy_modify_rx_buffer() - perform analog swizzling of parameters
+ * @rfbuf:
+ * @reg32:
+ * @numBits:
+ * @firstBit:
+ * @column:
+ *
+ * Performs analog "swizzling" of parameters into their location.
+ * Used on external AR2133/AR5133 radios.
+ */
 static void
 ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
 			   u32 numBits, u32 firstBit,
@@ -209,6 +292,18 @@ ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
 	}
 }
 
+/* *
+ * ath9k_hw_set_rf_regs - programs rf registers based on EEPROM
+ * @ah: atheros hardware structure
+ * @chan:
+ * @modesIndex:
+ *
+ * Used for the external AR2133/AR5133 radios.
+ *
+ * Reads the EEPROM header info from the device structure and programs
+ * all rf registers. This routine requires access to the analog
+ * rf device. This is not required for single-chip devices.
+ */
 bool
 ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
 		     u16 modesIndex)
@@ -218,17 +313,27 @@ ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
 	u32 ob2GHz = 0, db2GHz = 0;
 	int regWrites = 0;
 
+	/*
+	 * Software does not need to program bank data
+	 * for single chip devices, that is AR9280 or anything
+	 * after that.
+	 */
 	if (AR_SREV_9280_10_OR_LATER(ah))
 		return true;
 
+	/* Setup rf parameters */
 	eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV);
 
+	/* Setup Bank 0 Write */
 	RF_BANK_SETUP(ah->analogBank0Data, &ah->iniBank0, 1);
 
+	/* Setup Bank 1 Write */
 	RF_BANK_SETUP(ah->analogBank1Data, &ah->iniBank1, 1);
 
+	/* Setup Bank 2 Write */
 	RF_BANK_SETUP(ah->analogBank2Data, &ah->iniBank2, 1);
 
+	/* Setup Bank 6 Write */
 	RF_BANK_SETUP(ah->analogBank3Data, &ah->iniBank3,
 		      modesIndex);
 	{
@@ -239,6 +344,7 @@ ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
 		}
 	}
 
+	/* Only the 5 or 2 GHz OB/DB need to be set for a mode */
 	if (eepMinorRev >= 2) {
 		if (IS_CHAN_2GHZ(chan)) {
 			ob2GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_2);
@@ -257,8 +363,10 @@ ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
 		}
 	}
 
+	/* Setup Bank 7 Setup */
 	RF_BANK_SETUP(ah->analogBank7Data, &ah->iniBank7, 1);
 
+	/* Write Analog registers */
 	REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data,
 			   regWrites);
 	REG_WRITE_RF_ARRAY(&ah->iniBank1, ah->analogBank1Data,
@@ -275,6 +383,11 @@ ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
 	return true;
 }
 
+/**
+ * ath9k_hw_rf_free - Free memory for analog bank scratch buffers
+ * @ah: atheros hardware struture
+ * For the external AR2133/AR5133 radios.
+ */
 void
 ath9k_hw_rf_free(struct ath_hw *ah)
 {
@@ -295,6 +408,13 @@ ath9k_hw_rf_free(struct ath_hw *ah)
 #undef ATH_FREE_BANK
 }
 
+/**
+ * ath9k_hw_init_rf - initialize external radio structures
+ * @ah: atheros hardware structure
+ * @status:
+ *
+ * Only required for older devices with external AR2133/AR5133 radios.
+ */
 bool ath9k_hw_init_rf(struct ath_hw *ah, int *status)
 {
 	struct ath_common *common = ath9k_hw_common(ah);
@@ -360,6 +480,33 @@ bool ath9k_hw_init_rf(struct ath_hw *ah, int *status)
 	return true;
 }
 
+/**
+ * ath9k_hw_decrease_chain_power()
+ *
+ * @ah: atheros hardware structure
+ * @chan:
+ *
+ * Only used on the AR5416 and AR5418 with the external AR2133/AR5133 radios.
+ *
+ * Sets a chain internal RF path to the lowest output power. Any
+ * further writes to bank6 after this setting will override these
+ * changes. Thus this function must be the last function in the
+ * sequence to modify bank 6.
+ *
+ * This function must be called after ar5416SetRfRegs() which is
+ * called from ath9k_hw_process_ini() due to swizzling of bank 6.
+ * Depends on ah->analogBank6Data being initialized by
+ * ath9k_hw_set_rf_regs()
+ *
+ * Additional additive reduction in power -
+ * change chain's switch table so chain's tx state is actually the rx
+ * state value. May produce different results in 2GHz/5GHz as well as
+ * board to board but in general should be a reduction.
+ *
+ * Activated by #ifdef ALTER_SWITCH.  Not tried yet.  If so, must be
+ * called after ah->eep_ops->set_board_values() due to RMW of
+ * PHY_SWITCH_CHAIN_0.
+ */
 void
 ath9k_hw_decrease_chain_power(struct ath_hw *ah, struct ath9k_channel *chan)
 {
@@ -371,26 +518,35 @@ ath9k_hw_decrease_chain_power(struct ath_hw *ah, struct ath9k_channel *chan)
 	case ATH9K_ANT_FIXED_A:
 		bank6SelMask =
 		    (ah->config.antenna_switch_swap & ANTSWAP_AB) ?
-			REDUCE_CHAIN_0 : REDUCE_CHAIN_1;
+			REDUCE_CHAIN_0 : /* swapped, reduce chain 0 */
+			REDUCE_CHAIN_1; /* normal, select chain 1/2 to reduce */
 		break;
 	case ATH9K_ANT_FIXED_B:
 		bank6SelMask =
 		    (ah->config.antenna_switch_swap & ANTSWAP_AB) ?
-			REDUCE_CHAIN_1 : REDUCE_CHAIN_0;
+			REDUCE_CHAIN_1 : /* swapped, reduce chain 1/2 */
+			REDUCE_CHAIN_0; /* normal, select chain 0 to reduce */
 		break;
 	case ATH9K_ANT_VARIABLE:
-		return;
+		return; /* do not change anything */
 		break;
 	default:
-		return;
+		return; /* do not change anything */
 		break;
 	}
 
 	for (i = 0; i < ah->iniBank6.ia_rows; i++)
 		bank6Temp[i] = ah->analogBank6Data[i];
 
+	/* Write Bank 5 to switch Bank 6 write to selected chain only */
 	REG_WRITE(ah, AR_PHY_BASE + 0xD8, bank6SelMask);
 
+	/*
+	 * Modify Bank6 selected chain to use lowest amplification.
+	 * Modifies the parameters to a value of 1.
+	 * Depends on existing bank 6 values to be cached in
+	 * ah->analogBank6Data
+	 */
 	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 189, 0);
 	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 190, 0);
 	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 191, 0);
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFT 05/15] ath9k_hw: bail out early on ath9k_hw_init_rf()
  2009-10-19  6:33 [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias Luis R. Rodriguez
                   ` (3 preceding siblings ...)
  2009-10-19  6:33 ` [RFT 04/15] ath9k_hw: start documenting 802.11n RF anlong front ends Luis R. Rodriguez
@ 2009-10-19  6:33 ` Luis R. Rodriguez
  2009-10-19  6:33 ` [RFT 06/15] ath9k_hw: simplify rf attach and rename to ath9k_hw_rf_alloc_ext_banks() Luis R. Rodriguez
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-10-19  6:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez

We a huge branch for old hardware and nothing for newer
hardware. Instead of doing this just bail out early for
newer hardware.

This patch has no functional changes.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/phy.c |  109 +++++++++++++++++-----------------
 1 files changed, 55 insertions(+), 54 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c
index 9e51503..bd4fb07 100644
--- a/drivers/net/wireless/ath/ath9k/phy.c
+++ b/drivers/net/wireless/ath/ath9k/phy.c
@@ -419,62 +419,63 @@ bool ath9k_hw_init_rf(struct ath_hw *ah, int *status)
 {
 	struct ath_common *common = ath9k_hw_common(ah);
 
-	if (!AR_SREV_9280_10_OR_LATER(ah)) {
-		ah->analogBank0Data =
-		    kzalloc((sizeof(u32) *
-			     ah->iniBank0.ia_rows), GFP_KERNEL);
-		ah->analogBank1Data =
-		    kzalloc((sizeof(u32) *
-			     ah->iniBank1.ia_rows), GFP_KERNEL);
-		ah->analogBank2Data =
-		    kzalloc((sizeof(u32) *
-			     ah->iniBank2.ia_rows), GFP_KERNEL);
-		ah->analogBank3Data =
-		    kzalloc((sizeof(u32) *
-			     ah->iniBank3.ia_rows), GFP_KERNEL);
-		ah->analogBank6Data =
-		    kzalloc((sizeof(u32) *
-			     ah->iniBank6.ia_rows), GFP_KERNEL);
-		ah->analogBank6TPCData =
-		    kzalloc((sizeof(u32) *
-			     ah->iniBank6TPC.ia_rows), GFP_KERNEL);
-		ah->analogBank7Data =
-		    kzalloc((sizeof(u32) *
-			     ah->iniBank7.ia_rows), GFP_KERNEL);
-
-		if (ah->analogBank0Data == NULL
-		    || ah->analogBank1Data == NULL
-		    || ah->analogBank2Data == NULL
-		    || ah->analogBank3Data == NULL
-		    || ah->analogBank6Data == NULL
-		    || ah->analogBank6TPCData == NULL
-		    || ah->analogBank7Data == NULL) {
-			ath_print(common, ATH_DBG_FATAL,
-				  "Cannot allocate RF banks\n");
-			*status = -ENOMEM;
-			return false;
-		}
+	if (AR_SREV_9280_10_OR_LATER(ah))
+		return true;
 
-		ah->addac5416_21 =
-		    kzalloc((sizeof(u32) *
-			     ah->iniAddac.ia_rows *
-			     ah->iniAddac.ia_columns), GFP_KERNEL);
-		if (ah->addac5416_21 == NULL) {
-			ath_print(common, ATH_DBG_FATAL,
-				  "Cannot allocate addac5416_21\n");
-			*status = -ENOMEM;
-			return false;
-		}
+	ah->analogBank0Data =
+	    kzalloc((sizeof(u32) *
+		     ah->iniBank0.ia_rows), GFP_KERNEL);
+	ah->analogBank1Data =
+	    kzalloc((sizeof(u32) *
+		     ah->iniBank1.ia_rows), GFP_KERNEL);
+	ah->analogBank2Data =
+	    kzalloc((sizeof(u32) *
+		     ah->iniBank2.ia_rows), GFP_KERNEL);
+	ah->analogBank3Data =
+	    kzalloc((sizeof(u32) *
+		     ah->iniBank3.ia_rows), GFP_KERNEL);
+	ah->analogBank6Data =
+	    kzalloc((sizeof(u32) *
+		     ah->iniBank6.ia_rows), GFP_KERNEL);
+	ah->analogBank6TPCData =
+	    kzalloc((sizeof(u32) *
+		     ah->iniBank6TPC.ia_rows), GFP_KERNEL);
+	ah->analogBank7Data =
+	    kzalloc((sizeof(u32) *
+		     ah->iniBank7.ia_rows), GFP_KERNEL);
+
+	if (ah->analogBank0Data == NULL
+	    || ah->analogBank1Data == NULL
+	    || ah->analogBank2Data == NULL
+	    || ah->analogBank3Data == NULL
+	    || ah->analogBank6Data == NULL
+	    || ah->analogBank6TPCData == NULL
+	    || ah->analogBank7Data == NULL) {
+		ath_print(common, ATH_DBG_FATAL,
+			  "Cannot allocate RF banks\n");
+		*status = -ENOMEM;
+		return false;
+	}
 
-		ah->bank6Temp =
-		    kzalloc((sizeof(u32) *
-			     ah->iniBank6.ia_rows), GFP_KERNEL);
-		if (ah->bank6Temp == NULL) {
-			ath_print(common, ATH_DBG_FATAL,
-				  "Cannot allocate bank6Temp\n");
-			*status = -ENOMEM;
-			return false;
-		}
+	ah->addac5416_21 =
+	    kzalloc((sizeof(u32) *
+		     ah->iniAddac.ia_rows *
+		     ah->iniAddac.ia_columns), GFP_KERNEL);
+	if (ah->addac5416_21 == NULL) {
+		ath_print(common, ATH_DBG_FATAL,
+			  "Cannot allocate addac5416_21\n");
+		*status = -ENOMEM;
+		return false;
+	}
+
+	ah->bank6Temp =
+	    kzalloc((sizeof(u32) *
+		     ah->iniBank6.ia_rows), GFP_KERNEL);
+	if (ah->bank6Temp == NULL) {
+		ath_print(common, ATH_DBG_FATAL,
+			  "Cannot allocate bank6Temp\n");
+		*status = -ENOMEM;
+		return false;
 	}
 
 	return true;
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFT 06/15] ath9k_hw: simplify rf attach and rename to ath9k_hw_rf_alloc_ext_banks()
  2009-10-19  6:33 [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias Luis R. Rodriguez
                   ` (4 preceding siblings ...)
  2009-10-19  6:33 ` [RFT 05/15] ath9k_hw: bail out early on ath9k_hw_init_rf() Luis R. Rodriguez
@ 2009-10-19  6:33 ` Luis R. Rodriguez
  2009-10-19  6:33 ` [RFT 07/15] ath9k_hw: simplify ath9k_hw_rf_alloc_ext_banks() Luis R. Rodriguez
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-10-19  6:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez

ath9k_hw_rfattach() was just calling a helper and this helper was
doing nothing for single-chip devices, and for non single-chip devices
it is just allocating memory for banks to program the RF registers
at a later time. Simplify this by having the hw initialization call
the rf bank allocation directly for external radios.

Also, propagate an -ENOMEM properly now upon failure.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c  |   27 +++++++++------------------
 drivers/net/wireless/ath/ath9k/phy.c |   19 +++++++------------
 drivers/net/wireless/ath/ath9k/phy.h |    3 +--
 3 files changed, 17 insertions(+), 32 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index f67d3a4..694629b 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -454,21 +454,6 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
 	ah->power_mode = ATH9K_PM_UNDEFINED;
 }
 
-static int ath9k_hw_rfattach(struct ath_hw *ah)
-{
-	bool rfStatus = false;
-	int ecode = 0;
-
-	rfStatus = ath9k_hw_init_rf(ah, &ecode);
-	if (!rfStatus) {
-		ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
-			  "RF setup failed, status: %u\n", ecode);
-		return ecode;
-	}
-
-	return 0;
-}
-
 static int ath9k_hw_rf_claim(struct ath_hw *ah)
 {
 	u32 val;
@@ -585,9 +570,15 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
 		  ah->eep_ops->get_eeprom_ver(ah),
 		  ah->eep_ops->get_eeprom_rev(ah));
 
-	ecode = ath9k_hw_rfattach(ah);
-	if (ecode != 0)
-		return ecode;
+        if (!AR_SREV_9280_10_OR_LATER(ah)) {
+		ecode = ath9k_hw_rf_alloc_ext_banks(ah);
+		if (ecode) {
+			ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
+				  "Failed allocating banks for "
+				  "external radio\n");
+			return ecode;
+		}
+	}
 
 	if (!AR_SREV_9100(ah)) {
 		ath9k_hw_ani_setup(ah);
diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c
index bd4fb07..f3136b2 100644
--- a/drivers/net/wireless/ath/ath9k/phy.c
+++ b/drivers/net/wireless/ath/ath9k/phy.c
@@ -409,18 +409,16 @@ ath9k_hw_rf_free(struct ath_hw *ah)
 }
 
 /**
- * ath9k_hw_init_rf - initialize external radio structures
+ * ath9k_hw_rf_alloc_ext_banks - allocates banks for external radio programming
  * @ah: atheros hardware structure
- * @status:
  *
  * Only required for older devices with external AR2133/AR5133 radios.
  */
-bool ath9k_hw_init_rf(struct ath_hw *ah, int *status)
+int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah)
 {
 	struct ath_common *common = ath9k_hw_common(ah);
 
-	if (AR_SREV_9280_10_OR_LATER(ah))
-		return true;
+	BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
 
 	ah->analogBank0Data =
 	    kzalloc((sizeof(u32) *
@@ -453,8 +451,7 @@ bool ath9k_hw_init_rf(struct ath_hw *ah, int *status)
 	    || ah->analogBank7Data == NULL) {
 		ath_print(common, ATH_DBG_FATAL,
 			  "Cannot allocate RF banks\n");
-		*status = -ENOMEM;
-		return false;
+		return -ENOMEM;
 	}
 
 	ah->addac5416_21 =
@@ -464,8 +461,7 @@ bool ath9k_hw_init_rf(struct ath_hw *ah, int *status)
 	if (ah->addac5416_21 == NULL) {
 		ath_print(common, ATH_DBG_FATAL,
 			  "Cannot allocate addac5416_21\n");
-		*status = -ENOMEM;
-		return false;
+		return -ENOMEM;
 	}
 
 	ah->bank6Temp =
@@ -474,11 +470,10 @@ bool ath9k_hw_init_rf(struct ath_hw *ah, int *status)
 	if (ah->bank6Temp == NULL) {
 		ath_print(common, ATH_DBG_FATAL,
 			  "Cannot allocate bank6Temp\n");
-		*status = -ENOMEM;
-		return false;
+		return -ENOMEM;
 	}
 
-	return true;
+	return 0;
 }
 
 /**
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index 140fef7..fa1dce4 100644
--- a/drivers/net/wireless/ath/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -29,8 +29,7 @@ bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
 			  u16 modesIndex);
 void ath9k_hw_decrease_chain_power(struct ath_hw *ah,
 				   struct ath9k_channel *chan);
-bool ath9k_hw_init_rf(struct ath_hw *ah,
-		      int *status);
+int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah);
 
 #define AR_PHY_BASE     0x9800
 #define AR_PHY(_n)      (AR_PHY_BASE + ((_n)<<2))
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFT 07/15] ath9k_hw: simplify ath9k_hw_rf_alloc_ext_banks()
  2009-10-19  6:33 [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias Luis R. Rodriguez
                   ` (5 preceding siblings ...)
  2009-10-19  6:33 ` [RFT 06/15] ath9k_hw: simplify rf attach and rename to ath9k_hw_rf_alloc_ext_banks() Luis R. Rodriguez
@ 2009-10-19  6:33 ` Luis R. Rodriguez
  2009-10-19  6:33 ` [RFT 08/15] ath9k_hw: rename ath9k_hw_rf_free() to ath9k_hw_rf_free_ext_banks() Luis R. Rodriguez
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-10-19  6:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez

This is calling an allocation and checking for it, simplify
this process in a macro.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/phy.c |   72 +++++++++------------------------
 1 files changed, 20 insertions(+), 52 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c
index f3136b2..923ea0b 100644
--- a/drivers/net/wireless/ath/ath9k/phy.c
+++ b/drivers/net/wireless/ath/ath9k/phy.c
@@ -416,64 +416,32 @@ ath9k_hw_rf_free(struct ath_hw *ah)
  */
 int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah)
 {
+#define ATH_ALLOC_BANK(bank, size) do { \
+		bank = kzalloc((sizeof(u32) * size), GFP_KERNEL); \
+		if (!bank) { \
+			ath_print(common, ATH_DBG_FATAL, \
+				  "Cannot allocate RF banks\n"); \
+			return -ENOMEM; \
+		} \
+	} while (0);
+
 	struct ath_common *common = ath9k_hw_common(ah);
 
 	BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
 
-	ah->analogBank0Data =
-	    kzalloc((sizeof(u32) *
-		     ah->iniBank0.ia_rows), GFP_KERNEL);
-	ah->analogBank1Data =
-	    kzalloc((sizeof(u32) *
-		     ah->iniBank1.ia_rows), GFP_KERNEL);
-	ah->analogBank2Data =
-	    kzalloc((sizeof(u32) *
-		     ah->iniBank2.ia_rows), GFP_KERNEL);
-	ah->analogBank3Data =
-	    kzalloc((sizeof(u32) *
-		     ah->iniBank3.ia_rows), GFP_KERNEL);
-	ah->analogBank6Data =
-	    kzalloc((sizeof(u32) *
-		     ah->iniBank6.ia_rows), GFP_KERNEL);
-	ah->analogBank6TPCData =
-	    kzalloc((sizeof(u32) *
-		     ah->iniBank6TPC.ia_rows), GFP_KERNEL);
-	ah->analogBank7Data =
-	    kzalloc((sizeof(u32) *
-		     ah->iniBank7.ia_rows), GFP_KERNEL);
-
-	if (ah->analogBank0Data == NULL
-	    || ah->analogBank1Data == NULL
-	    || ah->analogBank2Data == NULL
-	    || ah->analogBank3Data == NULL
-	    || ah->analogBank6Data == NULL
-	    || ah->analogBank6TPCData == NULL
-	    || ah->analogBank7Data == NULL) {
-		ath_print(common, ATH_DBG_FATAL,
-			  "Cannot allocate RF banks\n");
-		return -ENOMEM;
-	}
-
-	ah->addac5416_21 =
-	    kzalloc((sizeof(u32) *
-		     ah->iniAddac.ia_rows *
-		     ah->iniAddac.ia_columns), GFP_KERNEL);
-	if (ah->addac5416_21 == NULL) {
-		ath_print(common, ATH_DBG_FATAL,
-			  "Cannot allocate addac5416_21\n");
-		return -ENOMEM;
-	}
-
-	ah->bank6Temp =
-	    kzalloc((sizeof(u32) *
-		     ah->iniBank6.ia_rows), GFP_KERNEL);
-	if (ah->bank6Temp == NULL) {
-		ath_print(common, ATH_DBG_FATAL,
-			  "Cannot allocate bank6Temp\n");
-		return -ENOMEM;
-	}
+	ATH_ALLOC_BANK(ah->analogBank0Data, ah->iniBank0.ia_rows);
+	ATH_ALLOC_BANK(ah->analogBank1Data, ah->iniBank1.ia_rows);
+	ATH_ALLOC_BANK(ah->analogBank2Data, ah->iniBank2.ia_rows);
+	ATH_ALLOC_BANK(ah->analogBank3Data, ah->iniBank3.ia_rows);
+	ATH_ALLOC_BANK(ah->analogBank6Data, ah->iniBank6.ia_rows);
+	ATH_ALLOC_BANK(ah->analogBank6TPCData, ah->iniBank6TPC.ia_rows);
+	ATH_ALLOC_BANK(ah->analogBank7Data, ah->iniBank7.ia_rows);
+	ATH_ALLOC_BANK(ah->addac5416_21,
+		       ah->iniAddac.ia_rows * ah->iniAddac.ia_columns);
+	ATH_ALLOC_BANK(ah->bank6Temp, ah->iniBank6.ia_rows);
 
 	return 0;
+#undef ATH_ALLOC_BANK
 }
 
 /**
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFT 08/15] ath9k_hw: rename ath9k_hw_rf_free() to ath9k_hw_rf_free_ext_banks()
  2009-10-19  6:33 [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias Luis R. Rodriguez
                   ` (6 preceding siblings ...)
  2009-10-19  6:33 ` [RFT 07/15] ath9k_hw: simplify ath9k_hw_rf_alloc_ext_banks() Luis R. Rodriguez
@ 2009-10-19  6:33 ` Luis R. Rodriguez
  2009-10-19  6:33 ` [RFT 09/15] ath9k_hw: make both analog channel change routines return int Luis R. Rodriguez
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-10-19  6:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez

This clarifies this is only required for external radios.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c  |    3 ++-
 drivers/net/wireless/ath/ath9k/hw.h  |    1 -
 drivers/net/wireless/ath/ath9k/phy.c |    9 ++++++---
 drivers/net/wireless/ath/ath9k/phy.h |    2 ++
 4 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 694629b..5a08b97 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1282,7 +1282,8 @@ void ath9k_hw_detach(struct ath_hw *ah)
 	ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
 
 free_hw:
-	ath9k_hw_rf_free(ah);
+	if (!AR_SREV_9280_10_OR_LATER(ah))
+		ath9k_hw_rf_free_ext_banks(ah);
 	kfree(ah);
 	ah = NULL;
 }
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 8fe64cf..f9eb57b 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -628,7 +628,6 @@ static inline struct ath_regulatory *ath9k_hw_regulatory(struct ath_hw *ah)
 const char *ath9k_hw_probe(u16 vendorid, u16 devid);
 void ath9k_hw_detach(struct ath_hw *ah);
 int ath9k_hw_init(struct ath_hw *ah);
-void ath9k_hw_rf_free(struct ath_hw *ah);
 int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 		   bool bChannelChange);
 void ath9k_hw_fill_cap_info(struct ath_hw *ah);
diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c
index 923ea0b..d50b5ff 100644
--- a/drivers/net/wireless/ath/ath9k/phy.c
+++ b/drivers/net/wireless/ath/ath9k/phy.c
@@ -384,18 +384,20 @@ ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
 }
 
 /**
- * ath9k_hw_rf_free - Free memory for analog bank scratch buffers
+ * ath9k_hw_rf_free_ext_banks - Free memory for analog bank scratch buffers
  * @ah: atheros hardware struture
- * For the external AR2133/AR5133 radios.
+ * For the external AR2133/AR5133 radios banks.
  */
 void
-ath9k_hw_rf_free(struct ath_hw *ah)
+ath9k_hw_rf_free_ext_banks(struct ath_hw *ah)
 {
 #define ATH_FREE_BANK(bank) do { \
 		kfree(bank); \
 		bank = NULL; \
 	} while (0);
 
+	BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
+
 	ATH_FREE_BANK(ah->analogBank0Data);
 	ATH_FREE_BANK(ah->analogBank1Data);
 	ATH_FREE_BANK(ah->analogBank2Data);
@@ -405,6 +407,7 @@ ath9k_hw_rf_free(struct ath_hw *ah)
 	ATH_FREE_BANK(ah->analogBank7Data);
 	ATH_FREE_BANK(ah->addac5416_21);
 	ATH_FREE_BANK(ah->bank6Temp);
+
 #undef ATH_FREE_BANK
 }
 
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index fa1dce4..c083bbf 100644
--- a/drivers/net/wireless/ath/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -29,6 +29,8 @@ bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
 			  u16 modesIndex);
 void ath9k_hw_decrease_chain_power(struct ath_hw *ah,
 				   struct ath9k_channel *chan);
+
+void ath9k_hw_rf_free_ext_banks(struct ath_hw *ah);
 int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah);
 
 #define AR_PHY_BASE     0x9800
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFT 09/15] ath9k_hw: make both analog channel change routines return int
  2009-10-19  6:33 [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias Luis R. Rodriguez
                   ` (7 preceding siblings ...)
  2009-10-19  6:33 ` [RFT 08/15] ath9k_hw: rename ath9k_hw_rf_free() to ath9k_hw_rf_free_ext_banks() Luis R. Rodriguez
@ 2009-10-19  6:33 ` Luis R. Rodriguez
  2009-10-19  6:33 ` [RFT 10/15] ath9k_hw: use a callback for frequency change Luis R. Rodriguez
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-10-19  6:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez

This allows us to later define a callback for both.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c  |   24 +++++++++++++-----------
 drivers/net/wireless/ath/ath9k/phy.c |   14 +++++++-------
 drivers/net/wireless/ath/ath9k/phy.h |    7 ++-----
 3 files changed, 22 insertions(+), 23 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 5a08b97..e27be74 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1867,6 +1867,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
 	struct ath_common *common = ath9k_hw_common(ah);
 	struct ieee80211_channel *channel = chan->chan;
 	u32 synthDelay, qnum;
+	int r;
 
 	for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
 		if (ath9k_hw_numtxpending(ah, qnum)) {
@@ -1887,14 +1888,14 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
 
 	ath9k_hw_set_regs(ah, chan);
 
-	if (AR_SREV_9280_10_OR_LATER(ah)) {
-		ath9k_hw_ar9280_set_channel(ah, chan);
-	} else {
-		if (!(ath9k_hw_set_channel(ah, chan))) {
-			ath_print(common, ATH_DBG_FATAL,
-				  "Failed to set channel\n");
-			return false;
-		}
+	if (AR_SREV_9280_10_OR_LATER(ah))
+		r = ath9k_hw_ar9280_set_channel(ah, chan);
+	else
+		r = ath9k_hw_set_channel(ah, chan);
+	if (r) {
+		ath_print(common, ATH_DBG_FATAL,
+			  "Failed to set channel\n");
+		return false;
 	}
 
 	ah->eep_ops->set_txpower(ah, chan,
@@ -2533,10 +2534,11 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 	REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
 
 	if (AR_SREV_9280_10_OR_LATER(ah))
-		ath9k_hw_ar9280_set_channel(ah, chan);
+		r = ath9k_hw_ar9280_set_channel(ah, chan);
 	else
-		if (!(ath9k_hw_set_channel(ah, chan)))
-			return -EIO;
+		r = ath9k_hw_set_channel(ah, chan);
+	if (r)
+		return r;
 
 	for (i = 0; i < AR_NUM_DCU; i++)
 		REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c
index d50b5ff..bfcb9af 100644
--- a/drivers/net/wireless/ath/ath9k/phy.c
+++ b/drivers/net/wireless/ath/ath9k/phy.c
@@ -68,8 +68,7 @@ ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex, u32 freqIndex,
  * the channel value. Assumes writes enabled to analog bus and bank6 register
  * cache in ah->analogBank6Data.
  */
-bool
-ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
+int ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
 {
 	struct ath_common *common = ath9k_hw_common(ah);
 	u32 channelSel = 0;
@@ -94,7 +93,7 @@ ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
 		} else {
 			ath_print(common, ATH_DBG_FATAL,
 				  "Invalid channel %u MHz\n", freq);
-			return false;
+			return -EINVAL;
 		}
 
 		channelSel = (channelSel << 2) & 0xff;
@@ -127,7 +126,7 @@ ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
 	} else {
 		ath_print(common, ATH_DBG_FATAL,
 			  "Invalid channel %u MHz\n", freq);
-		return false;
+		return -EINVAL;
 	}
 
 	reg32 =
@@ -139,7 +138,7 @@ ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
 	ah->curchan = chan;
 	ah->curchan_rad_index = -1;
 
-	return true;
+	return 0;
 }
 
 /**
@@ -163,8 +162,7 @@ ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
  * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10)
  * (freq_ref = 40MHz/(24>>amodeRefSel))
  */
-void ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
-				 struct ath9k_channel *chan)
+int ath9k_hw_ar9280_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
 {
 	u16 bMode, fracMode, aModeRefSel = 0;
 	u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0;
@@ -252,6 +250,8 @@ void ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
 
 	ah->curchan = chan;
 	ah->curchan_rad_index = -1;
+
+	return 0;
 }
 
 /**
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index c083bbf..a0b484e 100644
--- a/drivers/net/wireless/ath/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -17,11 +17,8 @@
 #ifndef PHY_H
 #define PHY_H
 
-void ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
-				 struct ath9k_channel
-				 *chan);
-bool ath9k_hw_set_channel(struct ath_hw *ah,
-			  struct ath9k_channel *chan);
+int ath9k_hw_ar9280_set_channel(struct ath_hw *ah, struct ath9k_channel *chan);
+int ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan);
 void ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex,
 			 u32 freqIndex, int regWrites);
 bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFT 10/15] ath9k_hw: use a callback for frequency change
  2009-10-19  6:33 [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias Luis R. Rodriguez
                   ` (8 preceding siblings ...)
  2009-10-19  6:33 ` [RFT 09/15] ath9k_hw: make both analog channel change routines return int Luis R. Rodriguez
@ 2009-10-19  6:33 ` Luis R. Rodriguez
  2009-10-19  6:33 ` [RFT 11/15] ath9k_hw: order phy.c code and integrate spur mitigation Luis R. Rodriguez
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-10-19  6:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez

This avoids a branch on every channel change.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c |   15 ++++++---------
 drivers/net/wireless/ath/ath9k/hw.h |    4 +++-
 2 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index e27be74..e0d696d 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -951,8 +951,11 @@ int ath9k_hw_init(struct ath_hw *ah)
 	ath9k_hw_init_cal_settings(ah);
 
 	ah->ani_function = ATH9K_ANI_ALL;
-	if (AR_SREV_9280_10_OR_LATER(ah))
+	if (AR_SREV_9280_10_OR_LATER(ah)) {
 		ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
+		ah->ath9k_hw_rf_set_freq = &ath9k_hw_ar9280_set_channel;
+	} else
+		ah->ath9k_hw_rf_set_freq = &ath9k_hw_set_channel;
 
 	ath9k_hw_init_mode_regs(ah);
 
@@ -1888,10 +1891,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
 
 	ath9k_hw_set_regs(ah, chan);
 
-	if (AR_SREV_9280_10_OR_LATER(ah))
-		r = ath9k_hw_ar9280_set_channel(ah, chan);
-	else
-		r = ath9k_hw_set_channel(ah, chan);
+	r = ah->ath9k_hw_rf_set_freq(ah, chan);
 	if (r) {
 		ath_print(common, ATH_DBG_FATAL,
 			  "Failed to set channel\n");
@@ -2533,10 +2533,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 
 	REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
 
-	if (AR_SREV_9280_10_OR_LATER(ah))
-		r = ath9k_hw_ar9280_set_channel(ah, chan);
-	else
-		r = ath9k_hw_set_channel(ah, chan);
+	r = ah->ath9k_hw_rf_set_freq(ah, chan);
 	if (r)
 		return r;
 
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index f9eb57b..7c97e5f 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -548,7 +548,9 @@ struct ath_hw {
 		DONT_USE_32KHZ,
 	} enable_32kHz_clock;
 
-	/* RF */
+	/* Callback for radio frequency change */
+	int (*ath9k_hw_rf_set_freq)(struct ath_hw *ah, struct ath9k_channel *chan);
+	/* Used to program the radio on non single-chip devices */
 	u32 *analogBank0Data;
 	u32 *analogBank1Data;
 	u32 *analogBank2Data;
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFT 11/15] ath9k_hw: order phy.c code and integrate spur mitigation
  2009-10-19  6:33 [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias Luis R. Rodriguez
                   ` (9 preceding siblings ...)
  2009-10-19  6:33 ` [RFT 10/15] ath9k_hw: use a callback for frequency change Luis R. Rodriguez
@ 2009-10-19  6:33 ` Luis R. Rodriguez
  2009-10-19  6:33 ` [RFT 12/15] ath9k_hw: make spur mitigation a callback Luis R. Rodriguez
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-10-19  6:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez

This reorders phy.c routines in the order in the order in which they are used
and also moves the spur mitigation helpers for each type of chip into phy.c
as they are RF related.

This patch has no functional changes.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c  |  453 --------------------
 drivers/net/wireless/ath/ath9k/phy.c |  779 +++++++++++++++++++++++++++-------
 drivers/net/wireless/ath/ath9k/phy.h |   19 +-
 3 files changed, 637 insertions(+), 614 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index e0d696d..68f5bbc 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -30,8 +30,6 @@ static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan);
 static u32 ath9k_hw_ini_fixup(struct ath_hw *ah,
 			      struct ar5416_eeprom_def *pEepData,
 			      u32 reg, u32 value);
-static void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
-static void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
 
 MODULE_AUTHOR("Atheros Communications");
 MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
@@ -1929,457 +1927,6 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
 	return true;
 }
 
-static void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-	int bb_spur = AR_NO_SPUR;
-	int freq;
-	int bin, cur_bin;
-	int bb_spur_off, spur_subchannel_sd;
-	int spur_freq_sd;
-	int spur_delta_phase;
-	int denominator;
-	int upper, lower, cur_vit_mask;
-	int tmp, newVal;
-	int i;
-	int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
-			  AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
-	};
-	int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
-			 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
-	};
-	int inc[4] = { 0, 100, 0, 0 };
-	struct chan_centers centers;
-
-	int8_t mask_m[123];
-	int8_t mask_p[123];
-	int8_t mask_amt;
-	int tmp_mask;
-	int cur_bb_spur;
-	bool is2GHz = IS_CHAN_2GHZ(chan);
-
-	memset(&mask_m, 0, sizeof(int8_t) * 123);
-	memset(&mask_p, 0, sizeof(int8_t) * 123);
-
-	ath9k_hw_get_channel_centers(ah, chan, &centers);
-	freq = centers.synth_center;
-
-	ah->config.spurmode = SPUR_ENABLE_EEPROM;
-	for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
-		cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
-
-		if (is2GHz)
-			cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
-		else
-			cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
-
-		if (AR_NO_SPUR == cur_bb_spur)
-			break;
-		cur_bb_spur = cur_bb_spur - freq;
-
-		if (IS_CHAN_HT40(chan)) {
-			if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
-			    (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
-				bb_spur = cur_bb_spur;
-				break;
-			}
-		} else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
-			   (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
-			bb_spur = cur_bb_spur;
-			break;
-		}
-	}
-
-	if (AR_NO_SPUR == bb_spur) {
-		REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
-			    AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
-		return;
-	} else {
-		REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
-			    AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
-	}
-
-	bin = bb_spur * 320;
-
-	tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
-
-	newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
-			AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
-			AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
-			AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
-	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal);
-
-	newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
-		  AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
-		  AR_PHY_SPUR_REG_MASK_RATE_SELECT |
-		  AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
-		  SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
-	REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
-
-	if (IS_CHAN_HT40(chan)) {
-		if (bb_spur < 0) {
-			spur_subchannel_sd = 1;
-			bb_spur_off = bb_spur + 10;
-		} else {
-			spur_subchannel_sd = 0;
-			bb_spur_off = bb_spur - 10;
-		}
-	} else {
-		spur_subchannel_sd = 0;
-		bb_spur_off = bb_spur;
-	}
-
-	if (IS_CHAN_HT40(chan))
-		spur_delta_phase =
-			((bb_spur * 262144) /
-			 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
-	else
-		spur_delta_phase =
-			((bb_spur * 524288) /
-			 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
-
-	denominator = IS_CHAN_2GHZ(chan) ? 44 : 40;
-	spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
-
-	newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
-		  SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
-		  SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
-	REG_WRITE(ah, AR_PHY_TIMING11, newVal);
-
-	newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
-	REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);
-
-	cur_bin = -6000;
-	upper = bin + 100;
-	lower = bin - 100;
-
-	for (i = 0; i < 4; i++) {
-		int pilot_mask = 0;
-		int chan_mask = 0;
-		int bp = 0;
-		for (bp = 0; bp < 30; bp++) {
-			if ((cur_bin > lower) && (cur_bin < upper)) {
-				pilot_mask = pilot_mask | 0x1 << bp;
-				chan_mask = chan_mask | 0x1 << bp;
-			}
-			cur_bin += 100;
-		}
-		cur_bin += inc[i];
-		REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
-		REG_WRITE(ah, chan_mask_reg[i], chan_mask);
-	}
-
-	cur_vit_mask = 6100;
-	upper = bin + 120;
-	lower = bin - 120;
-
-	for (i = 0; i < 123; i++) {
-		if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
-
-			/* workaround for gcc bug #37014 */
-			volatile int tmp_v = abs(cur_vit_mask - bin);
-
-			if (tmp_v < 75)
-				mask_amt = 1;
-			else
-				mask_amt = 0;
-			if (cur_vit_mask < 0)
-				mask_m[abs(cur_vit_mask / 100)] = mask_amt;
-			else
-				mask_p[cur_vit_mask / 100] = mask_amt;
-		}
-		cur_vit_mask -= 100;
-	}
-
-	tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
-		| (mask_m[48] << 26) | (mask_m[49] << 24)
-		| (mask_m[50] << 22) | (mask_m[51] << 20)
-		| (mask_m[52] << 18) | (mask_m[53] << 16)
-		| (mask_m[54] << 14) | (mask_m[55] << 12)
-		| (mask_m[56] << 10) | (mask_m[57] << 8)
-		| (mask_m[58] << 6) | (mask_m[59] << 4)
-		| (mask_m[60] << 2) | (mask_m[61] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
-	REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
-
-	tmp_mask = (mask_m[31] << 28)
-		| (mask_m[32] << 26) | (mask_m[33] << 24)
-		| (mask_m[34] << 22) | (mask_m[35] << 20)
-		| (mask_m[36] << 18) | (mask_m[37] << 16)
-		| (mask_m[48] << 14) | (mask_m[39] << 12)
-		| (mask_m[40] << 10) | (mask_m[41] << 8)
-		| (mask_m[42] << 6) | (mask_m[43] << 4)
-		| (mask_m[44] << 2) | (mask_m[45] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
-
-	tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
-		| (mask_m[18] << 26) | (mask_m[18] << 24)
-		| (mask_m[20] << 22) | (mask_m[20] << 20)
-		| (mask_m[22] << 18) | (mask_m[22] << 16)
-		| (mask_m[24] << 14) | (mask_m[24] << 12)
-		| (mask_m[25] << 10) | (mask_m[26] << 8)
-		| (mask_m[27] << 6) | (mask_m[28] << 4)
-		| (mask_m[29] << 2) | (mask_m[30] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
-
-	tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
-		| (mask_m[2] << 26) | (mask_m[3] << 24)
-		| (mask_m[4] << 22) | (mask_m[5] << 20)
-		| (mask_m[6] << 18) | (mask_m[7] << 16)
-		| (mask_m[8] << 14) | (mask_m[9] << 12)
-		| (mask_m[10] << 10) | (mask_m[11] << 8)
-		| (mask_m[12] << 6) | (mask_m[13] << 4)
-		| (mask_m[14] << 2) | (mask_m[15] << 0);
-	REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
-
-	tmp_mask = (mask_p[15] << 28)
-		| (mask_p[14] << 26) | (mask_p[13] << 24)
-		| (mask_p[12] << 22) | (mask_p[11] << 20)
-		| (mask_p[10] << 18) | (mask_p[9] << 16)
-		| (mask_p[8] << 14) | (mask_p[7] << 12)
-		| (mask_p[6] << 10) | (mask_p[5] << 8)
-		| (mask_p[4] << 6) | (mask_p[3] << 4)
-		| (mask_p[2] << 2) | (mask_p[1] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
-
-	tmp_mask = (mask_p[30] << 28)
-		| (mask_p[29] << 26) | (mask_p[28] << 24)
-		| (mask_p[27] << 22) | (mask_p[26] << 20)
-		| (mask_p[25] << 18) | (mask_p[24] << 16)
-		| (mask_p[23] << 14) | (mask_p[22] << 12)
-		| (mask_p[21] << 10) | (mask_p[20] << 8)
-		| (mask_p[19] << 6) | (mask_p[18] << 4)
-		| (mask_p[17] << 2) | (mask_p[16] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
-
-	tmp_mask = (mask_p[45] << 28)
-		| (mask_p[44] << 26) | (mask_p[43] << 24)
-		| (mask_p[42] << 22) | (mask_p[41] << 20)
-		| (mask_p[40] << 18) | (mask_p[39] << 16)
-		| (mask_p[38] << 14) | (mask_p[37] << 12)
-		| (mask_p[36] << 10) | (mask_p[35] << 8)
-		| (mask_p[34] << 6) | (mask_p[33] << 4)
-		| (mask_p[32] << 2) | (mask_p[31] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
-
-	tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
-		| (mask_p[59] << 26) | (mask_p[58] << 24)
-		| (mask_p[57] << 22) | (mask_p[56] << 20)
-		| (mask_p[55] << 18) | (mask_p[54] << 16)
-		| (mask_p[53] << 14) | (mask_p[52] << 12)
-		| (mask_p[51] << 10) | (mask_p[50] << 8)
-		| (mask_p[49] << 6) | (mask_p[48] << 4)
-		| (mask_p[47] << 2) | (mask_p[46] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
-}
-
-static void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-	int bb_spur = AR_NO_SPUR;
-	int bin, cur_bin;
-	int spur_freq_sd;
-	int spur_delta_phase;
-	int denominator;
-	int upper, lower, cur_vit_mask;
-	int tmp, new;
-	int i;
-	int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
-			  AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
-	};
-	int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
-			 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
-	};
-	int inc[4] = { 0, 100, 0, 0 };
-
-	int8_t mask_m[123];
-	int8_t mask_p[123];
-	int8_t mask_amt;
-	int tmp_mask;
-	int cur_bb_spur;
-	bool is2GHz = IS_CHAN_2GHZ(chan);
-
-	memset(&mask_m, 0, sizeof(int8_t) * 123);
-	memset(&mask_p, 0, sizeof(int8_t) * 123);
-
-	for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
-		cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
-		if (AR_NO_SPUR == cur_bb_spur)
-			break;
-		cur_bb_spur = cur_bb_spur - (chan->channel * 10);
-		if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) {
-			bb_spur = cur_bb_spur;
-			break;
-		}
-	}
-
-	if (AR_NO_SPUR == bb_spur)
-		return;
-
-	bin = bb_spur * 32;
-
-	tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
-	new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
-		     AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
-		     AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
-		     AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
-
-	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new);
-
-	new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
-	       AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
-	       AR_PHY_SPUR_REG_MASK_RATE_SELECT |
-	       AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
-	       SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
-	REG_WRITE(ah, AR_PHY_SPUR_REG, new);
-
-	spur_delta_phase = ((bb_spur * 524288) / 100) &
-		AR_PHY_TIMING11_SPUR_DELTA_PHASE;
-
-	denominator = IS_CHAN_2GHZ(chan) ? 440 : 400;
-	spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff;
-
-	new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
-	       SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
-	       SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
-	REG_WRITE(ah, AR_PHY_TIMING11, new);
-
-	cur_bin = -6000;
-	upper = bin + 100;
-	lower = bin - 100;
-
-	for (i = 0; i < 4; i++) {
-		int pilot_mask = 0;
-		int chan_mask = 0;
-		int bp = 0;
-		for (bp = 0; bp < 30; bp++) {
-			if ((cur_bin > lower) && (cur_bin < upper)) {
-				pilot_mask = pilot_mask | 0x1 << bp;
-				chan_mask = chan_mask | 0x1 << bp;
-			}
-			cur_bin += 100;
-		}
-		cur_bin += inc[i];
-		REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
-		REG_WRITE(ah, chan_mask_reg[i], chan_mask);
-	}
-
-	cur_vit_mask = 6100;
-	upper = bin + 120;
-	lower = bin - 120;
-
-	for (i = 0; i < 123; i++) {
-		if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
-
-			/* workaround for gcc bug #37014 */
-			volatile int tmp_v = abs(cur_vit_mask - bin);
-
-			if (tmp_v < 75)
-				mask_amt = 1;
-			else
-				mask_amt = 0;
-			if (cur_vit_mask < 0)
-				mask_m[abs(cur_vit_mask / 100)] = mask_amt;
-			else
-				mask_p[cur_vit_mask / 100] = mask_amt;
-		}
-		cur_vit_mask -= 100;
-	}
-
-	tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
-		| (mask_m[48] << 26) | (mask_m[49] << 24)
-		| (mask_m[50] << 22) | (mask_m[51] << 20)
-		| (mask_m[52] << 18) | (mask_m[53] << 16)
-		| (mask_m[54] << 14) | (mask_m[55] << 12)
-		| (mask_m[56] << 10) | (mask_m[57] << 8)
-		| (mask_m[58] << 6) | (mask_m[59] << 4)
-		| (mask_m[60] << 2) | (mask_m[61] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
-	REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
-
-	tmp_mask = (mask_m[31] << 28)
-		| (mask_m[32] << 26) | (mask_m[33] << 24)
-		| (mask_m[34] << 22) | (mask_m[35] << 20)
-		| (mask_m[36] << 18) | (mask_m[37] << 16)
-		| (mask_m[48] << 14) | (mask_m[39] << 12)
-		| (mask_m[40] << 10) | (mask_m[41] << 8)
-		| (mask_m[42] << 6) | (mask_m[43] << 4)
-		| (mask_m[44] << 2) | (mask_m[45] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
-
-	tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
-		| (mask_m[18] << 26) | (mask_m[18] << 24)
-		| (mask_m[20] << 22) | (mask_m[20] << 20)
-		| (mask_m[22] << 18) | (mask_m[22] << 16)
-		| (mask_m[24] << 14) | (mask_m[24] << 12)
-		| (mask_m[25] << 10) | (mask_m[26] << 8)
-		| (mask_m[27] << 6) | (mask_m[28] << 4)
-		| (mask_m[29] << 2) | (mask_m[30] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
-
-	tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
-		| (mask_m[2] << 26) | (mask_m[3] << 24)
-		| (mask_m[4] << 22) | (mask_m[5] << 20)
-		| (mask_m[6] << 18) | (mask_m[7] << 16)
-		| (mask_m[8] << 14) | (mask_m[9] << 12)
-		| (mask_m[10] << 10) | (mask_m[11] << 8)
-		| (mask_m[12] << 6) | (mask_m[13] << 4)
-		| (mask_m[14] << 2) | (mask_m[15] << 0);
-	REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
-
-	tmp_mask = (mask_p[15] << 28)
-		| (mask_p[14] << 26) | (mask_p[13] << 24)
-		| (mask_p[12] << 22) | (mask_p[11] << 20)
-		| (mask_p[10] << 18) | (mask_p[9] << 16)
-		| (mask_p[8] << 14) | (mask_p[7] << 12)
-		| (mask_p[6] << 10) | (mask_p[5] << 8)
-		| (mask_p[4] << 6) | (mask_p[3] << 4)
-		| (mask_p[2] << 2) | (mask_p[1] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
-
-	tmp_mask = (mask_p[30] << 28)
-		| (mask_p[29] << 26) | (mask_p[28] << 24)
-		| (mask_p[27] << 22) | (mask_p[26] << 20)
-		| (mask_p[25] << 18) | (mask_p[24] << 16)
-		| (mask_p[23] << 14) | (mask_p[22] << 12)
-		| (mask_p[21] << 10) | (mask_p[20] << 8)
-		| (mask_p[19] << 6) | (mask_p[18] << 4)
-		| (mask_p[17] << 2) | (mask_p[16] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
-
-	tmp_mask = (mask_p[45] << 28)
-		| (mask_p[44] << 26) | (mask_p[43] << 24)
-		| (mask_p[42] << 22) | (mask_p[41] << 20)
-		| (mask_p[40] << 18) | (mask_p[39] << 16)
-		| (mask_p[38] << 14) | (mask_p[37] << 12)
-		| (mask_p[36] << 10) | (mask_p[35] << 8)
-		| (mask_p[34] << 6) | (mask_p[33] << 4)
-		| (mask_p[32] << 2) | (mask_p[31] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
-
-	tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
-		| (mask_p[59] << 26) | (mask_p[58] << 24)
-		| (mask_p[57] << 22) | (mask_p[56] << 20)
-		| (mask_p[55] << 18) | (mask_p[54] << 16)
-		| (mask_p[53] << 14) | (mask_p[52] << 12)
-		| (mask_p[51] << 10) | (mask_p[50] << 8)
-		| (mask_p[49] << 6) | (mask_p[48] << 4)
-		| (mask_p[47] << 2) | (mask_p[46] << 0);
-	REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
-	REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
-}
-
 static void ath9k_enable_rfkill(struct ath_hw *ah)
 {
 	REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c
index bfcb9af..8e4c3bd 100644
--- a/drivers/net/wireless/ath/ath9k/phy.c
+++ b/drivers/net/wireless/ath/ath9k/phy.c
@@ -52,96 +52,13 @@
  * Used for both the chipsets with an external AR2133/AR5133 radios and
  * single-chip devices.
  */
-void
-ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex, u32 freqIndex,
-		    int regWrites)
+void ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex,
+			 u32 freqIndex, int regWrites)
 {
 	REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites);
 }
 
 /**
- * ath9k_hw_set_channel - tune to a channel on the external AR2133/AR5133 radios
- * @ah: atheros hardware stucture
- * @chan:
- *
- * For the external AR2133/AR5133 radios, takes the MHz channel value and set
- * the channel value. Assumes writes enabled to analog bus and bank6 register
- * cache in ah->analogBank6Data.
- */
-int ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-	struct ath_common *common = ath9k_hw_common(ah);
-	u32 channelSel = 0;
-	u32 bModeSynth = 0;
-	u32 aModeRefSel = 0;
-	u32 reg32 = 0;
-	u16 freq;
-	struct chan_centers centers;
-
-	ath9k_hw_get_channel_centers(ah, chan, &centers);
-	freq = centers.synth_center;
-
-	if (freq < 4800) {
-		u32 txctl;
-
-		if (((freq - 2192) % 5) == 0) {
-			channelSel = ((freq - 672) * 2 - 3040) / 10;
-			bModeSynth = 0;
-		} else if (((freq - 2224) % 5) == 0) {
-			channelSel = ((freq - 704) * 2 - 3040) / 10;
-			bModeSynth = 1;
-		} else {
-			ath_print(common, ATH_DBG_FATAL,
-				  "Invalid channel %u MHz\n", freq);
-			return -EINVAL;
-		}
-
-		channelSel = (channelSel << 2) & 0xff;
-		channelSel = ath9k_hw_reverse_bits(channelSel, 8);
-
-		txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
-		if (freq == 2484) {
-
-			REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
-				  txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
-		} else {
-			REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
-				  txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
-		}
-
-	} else if ((freq % 20) == 0 && freq >= 5120) {
-		channelSel =
-		    ath9k_hw_reverse_bits(((freq - 4800) / 20 << 2), 8);
-		aModeRefSel = ath9k_hw_reverse_bits(1, 2);
-	} else if ((freq % 10) == 0) {
-		channelSel =
-		    ath9k_hw_reverse_bits(((freq - 4800) / 10 << 1), 8);
-		if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah))
-			aModeRefSel = ath9k_hw_reverse_bits(2, 2);
-		else
-			aModeRefSel = ath9k_hw_reverse_bits(1, 2);
-	} else if ((freq % 5) == 0) {
-		channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8);
-		aModeRefSel = ath9k_hw_reverse_bits(1, 2);
-	} else {
-		ath_print(common, ATH_DBG_FATAL,
-			  "Invalid channel %u MHz\n", freq);
-		return -EINVAL;
-	}
-
-	reg32 =
-	    (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) |
-	    (1 << 5) | 0x1;
-
-	REG_WRITE(ah, AR_PHY(0x37), reg32);
-
-	ah->curchan = chan;
-	ah->curchan_rad_index = -1;
-
-	return 0;
-}
-
-/**
  * ath9k_hw_ar9280_set_channel - set channel on single-chip device
  * @ah: atheros hardware structure
  * @chan:
@@ -255,6 +172,622 @@ int ath9k_hw_ar9280_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
 }
 
 /**
+ * ath9k_hw_9280_spur_mitigate - convert baseband spur frequency
+ * @ah: atheros hardware structure
+ * @chan:
+ *
+ * For single-chip solutions. Converts to baseband spur frequency given the
+ * input channel frequency and compute register settings below.
+ */
+void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+	int bb_spur = AR_NO_SPUR;
+	int freq;
+	int bin, cur_bin;
+	int bb_spur_off, spur_subchannel_sd;
+	int spur_freq_sd;
+	int spur_delta_phase;
+	int denominator;
+	int upper, lower, cur_vit_mask;
+	int tmp, newVal;
+	int i;
+	int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
+			  AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
+	};
+	int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
+			 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
+	};
+	int inc[4] = { 0, 100, 0, 0 };
+	struct chan_centers centers;
+
+	int8_t mask_m[123];
+	int8_t mask_p[123];
+	int8_t mask_amt;
+	int tmp_mask;
+	int cur_bb_spur;
+	bool is2GHz = IS_CHAN_2GHZ(chan);
+
+	memset(&mask_m, 0, sizeof(int8_t) * 123);
+	memset(&mask_p, 0, sizeof(int8_t) * 123);
+
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+	freq = centers.synth_center;
+
+	ah->config.spurmode = SPUR_ENABLE_EEPROM;
+	for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+		cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
+
+		if (is2GHz)
+			cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
+		else
+			cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
+
+		if (AR_NO_SPUR == cur_bb_spur)
+			break;
+		cur_bb_spur = cur_bb_spur - freq;
+
+		if (IS_CHAN_HT40(chan)) {
+			if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
+			    (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
+				bb_spur = cur_bb_spur;
+				break;
+			}
+		} else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
+			   (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
+			bb_spur = cur_bb_spur;
+			break;
+		}
+	}
+
+	if (AR_NO_SPUR == bb_spur) {
+		REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
+			    AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
+		return;
+	} else {
+		REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
+			    AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
+	}
+
+	bin = bb_spur * 320;
+
+	tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
+
+	newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
+			AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
+			AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
+			AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
+	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal);
+
+	newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
+		  AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
+		  AR_PHY_SPUR_REG_MASK_RATE_SELECT |
+		  AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
+		  SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
+	REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
+
+	if (IS_CHAN_HT40(chan)) {
+		if (bb_spur < 0) {
+			spur_subchannel_sd = 1;
+			bb_spur_off = bb_spur + 10;
+		} else {
+			spur_subchannel_sd = 0;
+			bb_spur_off = bb_spur - 10;
+		}
+	} else {
+		spur_subchannel_sd = 0;
+		bb_spur_off = bb_spur;
+	}
+
+	if (IS_CHAN_HT40(chan))
+		spur_delta_phase =
+			((bb_spur * 262144) /
+			 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
+	else
+		spur_delta_phase =
+			((bb_spur * 524288) /
+			 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
+
+	denominator = IS_CHAN_2GHZ(chan) ? 44 : 40;
+	spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
+
+	newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
+		  SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
+		  SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
+	REG_WRITE(ah, AR_PHY_TIMING11, newVal);
+
+	newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
+	REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);
+
+	cur_bin = -6000;
+	upper = bin + 100;
+	lower = bin - 100;
+
+	for (i = 0; i < 4; i++) {
+		int pilot_mask = 0;
+		int chan_mask = 0;
+		int bp = 0;
+		for (bp = 0; bp < 30; bp++) {
+			if ((cur_bin > lower) && (cur_bin < upper)) {
+				pilot_mask = pilot_mask | 0x1 << bp;
+				chan_mask = chan_mask | 0x1 << bp;
+			}
+			cur_bin += 100;
+		}
+		cur_bin += inc[i];
+		REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
+		REG_WRITE(ah, chan_mask_reg[i], chan_mask);
+	}
+
+	cur_vit_mask = 6100;
+	upper = bin + 120;
+	lower = bin - 120;
+
+	for (i = 0; i < 123; i++) {
+		if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
+
+			/* workaround for gcc bug #37014 */
+			volatile int tmp_v = abs(cur_vit_mask - bin);
+
+			if (tmp_v < 75)
+				mask_amt = 1;
+			else
+				mask_amt = 0;
+			if (cur_vit_mask < 0)
+				mask_m[abs(cur_vit_mask / 100)] = mask_amt;
+			else
+				mask_p[cur_vit_mask / 100] = mask_amt;
+		}
+		cur_vit_mask -= 100;
+	}
+
+	tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
+		| (mask_m[48] << 26) | (mask_m[49] << 24)
+		| (mask_m[50] << 22) | (mask_m[51] << 20)
+		| (mask_m[52] << 18) | (mask_m[53] << 16)
+		| (mask_m[54] << 14) | (mask_m[55] << 12)
+		| (mask_m[56] << 10) | (mask_m[57] << 8)
+		| (mask_m[58] << 6) | (mask_m[59] << 4)
+		| (mask_m[60] << 2) | (mask_m[61] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
+	REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
+
+	tmp_mask = (mask_m[31] << 28)
+		| (mask_m[32] << 26) | (mask_m[33] << 24)
+		| (mask_m[34] << 22) | (mask_m[35] << 20)
+		| (mask_m[36] << 18) | (mask_m[37] << 16)
+		| (mask_m[48] << 14) | (mask_m[39] << 12)
+		| (mask_m[40] << 10) | (mask_m[41] << 8)
+		| (mask_m[42] << 6) | (mask_m[43] << 4)
+		| (mask_m[44] << 2) | (mask_m[45] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
+
+	tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
+		| (mask_m[18] << 26) | (mask_m[18] << 24)
+		| (mask_m[20] << 22) | (mask_m[20] << 20)
+		| (mask_m[22] << 18) | (mask_m[22] << 16)
+		| (mask_m[24] << 14) | (mask_m[24] << 12)
+		| (mask_m[25] << 10) | (mask_m[26] << 8)
+		| (mask_m[27] << 6) | (mask_m[28] << 4)
+		| (mask_m[29] << 2) | (mask_m[30] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
+
+	tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
+		| (mask_m[2] << 26) | (mask_m[3] << 24)
+		| (mask_m[4] << 22) | (mask_m[5] << 20)
+		| (mask_m[6] << 18) | (mask_m[7] << 16)
+		| (mask_m[8] << 14) | (mask_m[9] << 12)
+		| (mask_m[10] << 10) | (mask_m[11] << 8)
+		| (mask_m[12] << 6) | (mask_m[13] << 4)
+		| (mask_m[14] << 2) | (mask_m[15] << 0);
+	REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
+
+	tmp_mask = (mask_p[15] << 28)
+		| (mask_p[14] << 26) | (mask_p[13] << 24)
+		| (mask_p[12] << 22) | (mask_p[11] << 20)
+		| (mask_p[10] << 18) | (mask_p[9] << 16)
+		| (mask_p[8] << 14) | (mask_p[7] << 12)
+		| (mask_p[6] << 10) | (mask_p[5] << 8)
+		| (mask_p[4] << 6) | (mask_p[3] << 4)
+		| (mask_p[2] << 2) | (mask_p[1] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
+
+	tmp_mask = (mask_p[30] << 28)
+		| (mask_p[29] << 26) | (mask_p[28] << 24)
+		| (mask_p[27] << 22) | (mask_p[26] << 20)
+		| (mask_p[25] << 18) | (mask_p[24] << 16)
+		| (mask_p[23] << 14) | (mask_p[22] << 12)
+		| (mask_p[21] << 10) | (mask_p[20] << 8)
+		| (mask_p[19] << 6) | (mask_p[18] << 4)
+		| (mask_p[17] << 2) | (mask_p[16] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
+
+	tmp_mask = (mask_p[45] << 28)
+		| (mask_p[44] << 26) | (mask_p[43] << 24)
+		| (mask_p[42] << 22) | (mask_p[41] << 20)
+		| (mask_p[40] << 18) | (mask_p[39] << 16)
+		| (mask_p[38] << 14) | (mask_p[37] << 12)
+		| (mask_p[36] << 10) | (mask_p[35] << 8)
+		| (mask_p[34] << 6) | (mask_p[33] << 4)
+		| (mask_p[32] << 2) | (mask_p[31] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
+
+	tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
+		| (mask_p[59] << 26) | (mask_p[58] << 24)
+		| (mask_p[57] << 22) | (mask_p[56] << 20)
+		| (mask_p[55] << 18) | (mask_p[54] << 16)
+		| (mask_p[53] << 14) | (mask_p[52] << 12)
+		| (mask_p[51] << 10) | (mask_p[50] << 8)
+		| (mask_p[49] << 6) | (mask_p[48] << 4)
+		| (mask_p[47] << 2) | (mask_p[46] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
+}
+
+/* All code below is for non single-chip solutions */
+
+/**
+ * ath9k_hw_set_channel - tune to a channel on the external AR2133/AR5133 radios
+ * @ah: atheros hardware stucture
+ * @chan:
+ *
+ * For the external AR2133/AR5133 radios, takes the MHz channel value and set
+ * the channel value. Assumes writes enabled to analog bus and bank6 register
+ * cache in ah->analogBank6Data.
+ */
+int ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+	u32 channelSel = 0;
+	u32 bModeSynth = 0;
+	u32 aModeRefSel = 0;
+	u32 reg32 = 0;
+	u16 freq;
+	struct chan_centers centers;
+
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+	freq = centers.synth_center;
+
+	if (freq < 4800) {
+		u32 txctl;
+
+		if (((freq - 2192) % 5) == 0) {
+			channelSel = ((freq - 672) * 2 - 3040) / 10;
+			bModeSynth = 0;
+		} else if (((freq - 2224) % 5) == 0) {
+			channelSel = ((freq - 704) * 2 - 3040) / 10;
+			bModeSynth = 1;
+		} else {
+			ath_print(common, ATH_DBG_FATAL,
+				  "Invalid channel %u MHz\n", freq);
+			return -EINVAL;
+		}
+
+		channelSel = (channelSel << 2) & 0xff;
+		channelSel = ath9k_hw_reverse_bits(channelSel, 8);
+
+		txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
+		if (freq == 2484) {
+
+			REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
+				  txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
+		} else {
+			REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
+				  txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
+		}
+
+	} else if ((freq % 20) == 0 && freq >= 5120) {
+		channelSel =
+		    ath9k_hw_reverse_bits(((freq - 4800) / 20 << 2), 8);
+		aModeRefSel = ath9k_hw_reverse_bits(1, 2);
+	} else if ((freq % 10) == 0) {
+		channelSel =
+		    ath9k_hw_reverse_bits(((freq - 4800) / 10 << 1), 8);
+		if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah))
+			aModeRefSel = ath9k_hw_reverse_bits(2, 2);
+		else
+			aModeRefSel = ath9k_hw_reverse_bits(1, 2);
+	} else if ((freq % 5) == 0) {
+		channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8);
+		aModeRefSel = ath9k_hw_reverse_bits(1, 2);
+	} else {
+		ath_print(common, ATH_DBG_FATAL,
+			  "Invalid channel %u MHz\n", freq);
+		return -EINVAL;
+	}
+
+	reg32 =
+	    (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) |
+	    (1 << 5) | 0x1;
+
+	REG_WRITE(ah, AR_PHY(0x37), reg32);
+
+	ah->curchan = chan;
+	ah->curchan_rad_index = -1;
+
+	return 0;
+}
+
+/**
+ * ath9k_hw_spur_mitigate - convert baseband spur frequency for external radios
+ * @ah: atheros hardware structure
+ * @chan:
+ *
+ * For non single-chip solutions. Converts to baseband spur frequency given the
+ * input channel frequency and compute register settings below.
+ */
+void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+	int bb_spur = AR_NO_SPUR;
+	int bin, cur_bin;
+	int spur_freq_sd;
+	int spur_delta_phase;
+	int denominator;
+	int upper, lower, cur_vit_mask;
+	int tmp, new;
+	int i;
+	int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
+			  AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
+	};
+	int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
+			 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
+	};
+	int inc[4] = { 0, 100, 0, 0 };
+
+	int8_t mask_m[123];
+	int8_t mask_p[123];
+	int8_t mask_amt;
+	int tmp_mask;
+	int cur_bb_spur;
+	bool is2GHz = IS_CHAN_2GHZ(chan);
+
+	memset(&mask_m, 0, sizeof(int8_t) * 123);
+	memset(&mask_p, 0, sizeof(int8_t) * 123);
+
+	for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+		cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
+		if (AR_NO_SPUR == cur_bb_spur)
+			break;
+		cur_bb_spur = cur_bb_spur - (chan->channel * 10);
+		if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) {
+			bb_spur = cur_bb_spur;
+			break;
+		}
+	}
+
+	if (AR_NO_SPUR == bb_spur)
+		return;
+
+	bin = bb_spur * 32;
+
+	tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
+	new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
+		     AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
+		     AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
+		     AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
+
+	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new);
+
+	new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
+	       AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
+	       AR_PHY_SPUR_REG_MASK_RATE_SELECT |
+	       AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
+	       SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
+	REG_WRITE(ah, AR_PHY_SPUR_REG, new);
+
+	spur_delta_phase = ((bb_spur * 524288) / 100) &
+		AR_PHY_TIMING11_SPUR_DELTA_PHASE;
+
+	denominator = IS_CHAN_2GHZ(chan) ? 440 : 400;
+	spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff;
+
+	new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
+	       SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
+	       SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
+	REG_WRITE(ah, AR_PHY_TIMING11, new);
+
+	cur_bin = -6000;
+	upper = bin + 100;
+	lower = bin - 100;
+
+	for (i = 0; i < 4; i++) {
+		int pilot_mask = 0;
+		int chan_mask = 0;
+		int bp = 0;
+		for (bp = 0; bp < 30; bp++) {
+			if ((cur_bin > lower) && (cur_bin < upper)) {
+				pilot_mask = pilot_mask | 0x1 << bp;
+				chan_mask = chan_mask | 0x1 << bp;
+			}
+			cur_bin += 100;
+		}
+		cur_bin += inc[i];
+		REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
+		REG_WRITE(ah, chan_mask_reg[i], chan_mask);
+	}
+
+	cur_vit_mask = 6100;
+	upper = bin + 120;
+	lower = bin - 120;
+
+	for (i = 0; i < 123; i++) {
+		if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
+
+			/* workaround for gcc bug #37014 */
+			volatile int tmp_v = abs(cur_vit_mask - bin);
+
+			if (tmp_v < 75)
+				mask_amt = 1;
+			else
+				mask_amt = 0;
+			if (cur_vit_mask < 0)
+				mask_m[abs(cur_vit_mask / 100)] = mask_amt;
+			else
+				mask_p[cur_vit_mask / 100] = mask_amt;
+		}
+		cur_vit_mask -= 100;
+	}
+
+	tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
+		| (mask_m[48] << 26) | (mask_m[49] << 24)
+		| (mask_m[50] << 22) | (mask_m[51] << 20)
+		| (mask_m[52] << 18) | (mask_m[53] << 16)
+		| (mask_m[54] << 14) | (mask_m[55] << 12)
+		| (mask_m[56] << 10) | (mask_m[57] << 8)
+		| (mask_m[58] << 6) | (mask_m[59] << 4)
+		| (mask_m[60] << 2) | (mask_m[61] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
+	REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
+
+	tmp_mask = (mask_m[31] << 28)
+		| (mask_m[32] << 26) | (mask_m[33] << 24)
+		| (mask_m[34] << 22) | (mask_m[35] << 20)
+		| (mask_m[36] << 18) | (mask_m[37] << 16)
+		| (mask_m[48] << 14) | (mask_m[39] << 12)
+		| (mask_m[40] << 10) | (mask_m[41] << 8)
+		| (mask_m[42] << 6) | (mask_m[43] << 4)
+		| (mask_m[44] << 2) | (mask_m[45] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
+
+	tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
+		| (mask_m[18] << 26) | (mask_m[18] << 24)
+		| (mask_m[20] << 22) | (mask_m[20] << 20)
+		| (mask_m[22] << 18) | (mask_m[22] << 16)
+		| (mask_m[24] << 14) | (mask_m[24] << 12)
+		| (mask_m[25] << 10) | (mask_m[26] << 8)
+		| (mask_m[27] << 6) | (mask_m[28] << 4)
+		| (mask_m[29] << 2) | (mask_m[30] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
+
+	tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
+		| (mask_m[2] << 26) | (mask_m[3] << 24)
+		| (mask_m[4] << 22) | (mask_m[5] << 20)
+		| (mask_m[6] << 18) | (mask_m[7] << 16)
+		| (mask_m[8] << 14) | (mask_m[9] << 12)
+		| (mask_m[10] << 10) | (mask_m[11] << 8)
+		| (mask_m[12] << 6) | (mask_m[13] << 4)
+		| (mask_m[14] << 2) | (mask_m[15] << 0);
+	REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
+
+	tmp_mask = (mask_p[15] << 28)
+		| (mask_p[14] << 26) | (mask_p[13] << 24)
+		| (mask_p[12] << 22) | (mask_p[11] << 20)
+		| (mask_p[10] << 18) | (mask_p[9] << 16)
+		| (mask_p[8] << 14) | (mask_p[7] << 12)
+		| (mask_p[6] << 10) | (mask_p[5] << 8)
+		| (mask_p[4] << 6) | (mask_p[3] << 4)
+		| (mask_p[2] << 2) | (mask_p[1] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
+
+	tmp_mask = (mask_p[30] << 28)
+		| (mask_p[29] << 26) | (mask_p[28] << 24)
+		| (mask_p[27] << 22) | (mask_p[26] << 20)
+		| (mask_p[25] << 18) | (mask_p[24] << 16)
+		| (mask_p[23] << 14) | (mask_p[22] << 12)
+		| (mask_p[21] << 10) | (mask_p[20] << 8)
+		| (mask_p[19] << 6) | (mask_p[18] << 4)
+		| (mask_p[17] << 2) | (mask_p[16] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
+
+	tmp_mask = (mask_p[45] << 28)
+		| (mask_p[44] << 26) | (mask_p[43] << 24)
+		| (mask_p[42] << 22) | (mask_p[41] << 20)
+		| (mask_p[40] << 18) | (mask_p[39] << 16)
+		| (mask_p[38] << 14) | (mask_p[37] << 12)
+		| (mask_p[36] << 10) | (mask_p[35] << 8)
+		| (mask_p[34] << 6) | (mask_p[33] << 4)
+		| (mask_p[32] << 2) | (mask_p[31] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
+
+	tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
+		| (mask_p[59] << 26) | (mask_p[58] << 24)
+		| (mask_p[57] << 22) | (mask_p[56] << 20)
+		| (mask_p[55] << 18) | (mask_p[54] << 16)
+		| (mask_p[53] << 14) | (mask_p[52] << 12)
+		| (mask_p[51] << 10) | (mask_p[50] << 8)
+		| (mask_p[49] << 6) | (mask_p[48] << 4)
+		| (mask_p[47] << 2) | (mask_p[46] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
+}
+
+/**
+ * ath9k_hw_rf_alloc_ext_banks - allocates banks for external radio programming
+ * @ah: atheros hardware structure
+ *
+ * Only required for older devices with external AR2133/AR5133 radios.
+ */
+int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah)
+{
+#define ATH_ALLOC_BANK(bank, size) do { \
+		bank = kzalloc((sizeof(u32) * size), GFP_KERNEL); \
+		if (!bank) { \
+			ath_print(common, ATH_DBG_FATAL, \
+				  "Cannot allocate RF banks\n"); \
+			return -ENOMEM; \
+		} \
+	} while (0);
+
+	struct ath_common *common = ath9k_hw_common(ah);
+
+	BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
+
+	ATH_ALLOC_BANK(ah->analogBank0Data, ah->iniBank0.ia_rows);
+	ATH_ALLOC_BANK(ah->analogBank1Data, ah->iniBank1.ia_rows);
+	ATH_ALLOC_BANK(ah->analogBank2Data, ah->iniBank2.ia_rows);
+	ATH_ALLOC_BANK(ah->analogBank3Data, ah->iniBank3.ia_rows);
+	ATH_ALLOC_BANK(ah->analogBank6Data, ah->iniBank6.ia_rows);
+	ATH_ALLOC_BANK(ah->analogBank6TPCData, ah->iniBank6TPC.ia_rows);
+	ATH_ALLOC_BANK(ah->analogBank7Data, ah->iniBank7.ia_rows);
+	ATH_ALLOC_BANK(ah->addac5416_21,
+		       ah->iniAddac.ia_rows * ah->iniAddac.ia_columns);
+	ATH_ALLOC_BANK(ah->bank6Temp, ah->iniBank6.ia_rows);
+
+	return 0;
+#undef ATH_ALLOC_BANK
+}
+
+
+/**
+ * ath9k_hw_rf_free_ext_banks - Free memory for analog bank scratch buffers
+ * @ah: atheros hardware struture
+ * For the external AR2133/AR5133 radios banks.
+ */
+void
+ath9k_hw_rf_free_ext_banks(struct ath_hw *ah)
+{
+#define ATH_FREE_BANK(bank) do { \
+		kfree(bank); \
+		bank = NULL; \
+	} while (0);
+
+	BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
+
+	ATH_FREE_BANK(ah->analogBank0Data);
+	ATH_FREE_BANK(ah->analogBank1Data);
+	ATH_FREE_BANK(ah->analogBank2Data);
+	ATH_FREE_BANK(ah->analogBank3Data);
+	ATH_FREE_BANK(ah->analogBank6Data);
+	ATH_FREE_BANK(ah->analogBank6TPCData);
+	ATH_FREE_BANK(ah->analogBank7Data);
+	ATH_FREE_BANK(ah->addac5416_21);
+	ATH_FREE_BANK(ah->bank6Temp);
+
+#undef ATH_FREE_BANK
+}
+
+/**
  * ath9k_phy_modify_rx_buffer() - perform analog swizzling of parameters
  * @rfbuf:
  * @reg32:
@@ -265,10 +798,9 @@ int ath9k_hw_ar9280_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
  * Performs analog "swizzling" of parameters into their location.
  * Used on external AR2133/AR5133 radios.
  */
-static void
-ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
-			   u32 numBits, u32 firstBit,
-			   u32 column)
+static void ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
+				       u32 numBits, u32 firstBit,
+				       u32 column)
 {
 	u32 tmp32, mask, arrayEntry, lastBit;
 	int32_t bitPosition, bitsLeft;
@@ -304,9 +836,8 @@ ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
  * all rf registers. This routine requires access to the analog
  * rf device. This is not required for single-chip devices.
  */
-bool
-ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
-		     u16 modesIndex)
+bool ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
+			  u16 modesIndex)
 {
 	u32 eepMinorRev;
 	u32 ob5GHz = 0, db5GHz = 0;
@@ -384,70 +915,6 @@ ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
 }
 
 /**
- * ath9k_hw_rf_free_ext_banks - Free memory for analog bank scratch buffers
- * @ah: atheros hardware struture
- * For the external AR2133/AR5133 radios banks.
- */
-void
-ath9k_hw_rf_free_ext_banks(struct ath_hw *ah)
-{
-#define ATH_FREE_BANK(bank) do { \
-		kfree(bank); \
-		bank = NULL; \
-	} while (0);
-
-	BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
-
-	ATH_FREE_BANK(ah->analogBank0Data);
-	ATH_FREE_BANK(ah->analogBank1Data);
-	ATH_FREE_BANK(ah->analogBank2Data);
-	ATH_FREE_BANK(ah->analogBank3Data);
-	ATH_FREE_BANK(ah->analogBank6Data);
-	ATH_FREE_BANK(ah->analogBank6TPCData);
-	ATH_FREE_BANK(ah->analogBank7Data);
-	ATH_FREE_BANK(ah->addac5416_21);
-	ATH_FREE_BANK(ah->bank6Temp);
-
-#undef ATH_FREE_BANK
-}
-
-/**
- * ath9k_hw_rf_alloc_ext_banks - allocates banks for external radio programming
- * @ah: atheros hardware structure
- *
- * Only required for older devices with external AR2133/AR5133 radios.
- */
-int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah)
-{
-#define ATH_ALLOC_BANK(bank, size) do { \
-		bank = kzalloc((sizeof(u32) * size), GFP_KERNEL); \
-		if (!bank) { \
-			ath_print(common, ATH_DBG_FATAL, \
-				  "Cannot allocate RF banks\n"); \
-			return -ENOMEM; \
-		} \
-	} while (0);
-
-	struct ath_common *common = ath9k_hw_common(ah);
-
-	BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
-
-	ATH_ALLOC_BANK(ah->analogBank0Data, ah->iniBank0.ia_rows);
-	ATH_ALLOC_BANK(ah->analogBank1Data, ah->iniBank1.ia_rows);
-	ATH_ALLOC_BANK(ah->analogBank2Data, ah->iniBank2.ia_rows);
-	ATH_ALLOC_BANK(ah->analogBank3Data, ah->iniBank3.ia_rows);
-	ATH_ALLOC_BANK(ah->analogBank6Data, ah->iniBank6.ia_rows);
-	ATH_ALLOC_BANK(ah->analogBank6TPCData, ah->iniBank6TPC.ia_rows);
-	ATH_ALLOC_BANK(ah->analogBank7Data, ah->iniBank7.ia_rows);
-	ATH_ALLOC_BANK(ah->addac5416_21,
-		       ah->iniAddac.ia_rows * ah->iniAddac.ia_columns);
-	ATH_ALLOC_BANK(ah->bank6Temp, ah->iniBank6.ia_rows);
-
-	return 0;
-#undef ATH_ALLOC_BANK
-}
-
-/**
  * ath9k_hw_decrease_chain_power()
  *
  * @ah: atheros hardware structure
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index a0b484e..4420f80 100644
--- a/drivers/net/wireless/ath/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -17,19 +17,28 @@
 #ifndef PHY_H
 #define PHY_H
 
-int ath9k_hw_ar9280_set_channel(struct ath_hw *ah, struct ath9k_channel *chan);
-int ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan);
+/* Common between single chip and non single-chip solutions */
 void ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex,
 			 u32 freqIndex, int regWrites);
+
+/* Single chip radio settings */
+int ath9k_hw_ar9280_set_channel(struct ath_hw *ah, struct ath9k_channel *chan);
+void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
+
+/* Routines below are for non single-chip solutions */
+int ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan);
+void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
+
+int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah);
+void ath9k_hw_rf_free_ext_banks(struct ath_hw *ah);
+
 bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
 			  struct ath9k_channel *chan,
 			  u16 modesIndex);
+
 void ath9k_hw_decrease_chain_power(struct ath_hw *ah,
 				   struct ath9k_channel *chan);
 
-void ath9k_hw_rf_free_ext_banks(struct ath_hw *ah);
-int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah);
-
 #define AR_PHY_BASE     0x9800
 #define AR_PHY(_n)      (AR_PHY_BASE + ((_n)<<2))
 
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFT 12/15] ath9k_hw: make spur mitigation a callback
  2009-10-19  6:33 [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias Luis R. Rodriguez
                   ` (10 preceding siblings ...)
  2009-10-19  6:33 ` [RFT 11/15] ath9k_hw: order phy.c code and integrate spur mitigation Luis R. Rodriguez
@ 2009-10-19  6:33 ` Luis R. Rodriguez
  2009-10-19  6:33 ` [RFT 13/15] ath9k_hw: remove unused modesIndex param from ath9k_hw_write_regs() Luis R. Rodriguez
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-10-19  6:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez

This only differs between single-chip solutions and non single-chip
solutions.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c |   17 ++++++-----------
 drivers/net/wireless/ath/ath9k/hw.h |    5 +++++
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 68f5bbc..65c106b 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -952,8 +952,11 @@ int ath9k_hw_init(struct ath_hw *ah)
 	if (AR_SREV_9280_10_OR_LATER(ah)) {
 		ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
 		ah->ath9k_hw_rf_set_freq = &ath9k_hw_ar9280_set_channel;
-	} else
+		ah->ath9k_hw_spur_mitigate_freq = &ath9k_hw_9280_spur_mitigate;
+	} else {
 		ah->ath9k_hw_rf_set_freq = &ath9k_hw_set_channel;
+		ah->ath9k_hw_spur_mitigate_freq = &ath9k_hw_spur_mitigate;
+	}
 
 	ath9k_hw_init_mode_regs(ah);
 
@@ -1916,10 +1919,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
 	if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
 		ath9k_hw_set_delta_slope(ah, chan);
 
-	if (AR_SREV_9280_10_OR_LATER(ah))
-		ath9k_hw_9280_spur_mitigate(ah, chan);
-	else
-		ath9k_hw_spur_mitigate(ah, chan);
+	ah->ath9k_hw_spur_mitigate_freq(ah, chan);
 
 	if (!chan->oneTimeCalsDone)
 		chan->oneTimeCalsDone = true;
@@ -2052,13 +2052,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 	if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
 		ath9k_hw_set_delta_slope(ah, chan);
 
-	if (AR_SREV_9280_10_OR_LATER(ah))
-		ath9k_hw_9280_spur_mitigate(ah, chan);
-	else
-		ath9k_hw_spur_mitigate(ah, chan);
-
+	ah->ath9k_hw_spur_mitigate_freq(ah, chan);
 	ah->eep_ops->set_board_values(ah, chan);
-
 	ath9k_hw_decrease_chain_power(ah, chan);
 
 	REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr));
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 7c97e5f..936ef5b 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -550,6 +550,11 @@ struct ath_hw {
 
 	/* Callback for radio frequency change */
 	int (*ath9k_hw_rf_set_freq)(struct ath_hw *ah, struct ath9k_channel *chan);
+
+	/* Callback for baseband spur frequency */
+	void (*ath9k_hw_spur_mitigate_freq)(struct ath_hw *ah,
+					    struct ath9k_channel *chan);
+
 	/* Used to program the radio on non single-chip devices */
 	u32 *analogBank0Data;
 	u32 *analogBank1Data;
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFT 13/15] ath9k_hw: remove unused modesIndex param from ath9k_hw_write_regs()
  2009-10-19  6:33 [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias Luis R. Rodriguez
                   ` (11 preceding siblings ...)
  2009-10-19  6:33 ` [RFT 12/15] ath9k_hw: make spur mitigation a callback Luis R. Rodriguez
@ 2009-10-19  6:33 ` Luis R. Rodriguez
  2009-10-19  6:33 ` [RFT 14/15] ath9k_hw: Fix and complete force bias for AR5416 Luis R. Rodriguez
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-10-19  6:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c  |    2 +-
 drivers/net/wireless/ath/ath9k/phy.c |    4 +---
 drivers/net/wireless/ath/ath9k/phy.h |    3 +--
 3 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 65c106b..d435369 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1524,7 +1524,7 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
 		DO_DELAY(regWrites);
 	}
 
-	ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites);
+	ath9k_hw_write_regs(ah, freqIndex, regWrites);
 
 	if (AR_SREV_9271_10(ah))
 		REG_WRITE_ARRAY(&ah->iniModes_9271_1_0_only,
diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c
index 8e4c3bd..a15532e 100644
--- a/drivers/net/wireless/ath/ath9k/phy.c
+++ b/drivers/net/wireless/ath/ath9k/phy.c
@@ -45,15 +45,13 @@
  * ath9k_hw_write_regs - ??
  *
  * @ah: atheros hardware structure
- * @modesIndex:
  * @freqIndex:
  * @regWrites:
  *
  * Used for both the chipsets with an external AR2133/AR5133 radios and
  * single-chip devices.
  */
-void ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex,
-			 u32 freqIndex, int regWrites)
+void ath9k_hw_write_regs(struct ath_hw *ah, u32 freqIndex, int regWrites)
 {
 	REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites);
 }
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index 4420f80..a9b9a7d 100644
--- a/drivers/net/wireless/ath/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -18,8 +18,7 @@
 #define PHY_H
 
 /* Common between single chip and non single-chip solutions */
-void ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex,
-			 u32 freqIndex, int regWrites);
+void ath9k_hw_write_regs(struct ath_hw *ah, u32 freqIndex, int regWrites);
 
 /* Single chip radio settings */
 int ath9k_hw_ar9280_set_channel(struct ath_hw *ah, struct ath9k_channel *chan);
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFT 14/15] ath9k_hw: Fix and complete force bias for AR5416
  2009-10-19  6:33 [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias Luis R. Rodriguez
                   ` (12 preceding siblings ...)
  2009-10-19  6:33 ` [RFT 13/15] ath9k_hw: remove unused modesIndex param from ath9k_hw_write_regs() Luis R. Rodriguez
@ 2009-10-19  6:33 ` Luis R. Rodriguez
  2009-10-19  6:33 ` [RFT 15/15] ath9k_hw: make ath9k_phy_modify_rx_buffer() static Luis R. Rodriguez
  2009-10-22  3:42 ` [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias Luis R. Rodriguez
  15 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-10-19  6:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez

Force bias is a fix for usage of AR5416 radios on the 2.4 GHz band
for orientation sensitivity. This was only partially implemented
with the ath9k_hw_decrease_chain_power() but first -- this was being
called for all chipsets which is not correct and second -- it was
missing the actual orientation code.

We now ensure to only enable force bias only for AR5416 and BUG_ON()
on other chipsets. Although ath9k_hw_decrease_chain_power() was enabled
for newer chipsets I suspect that it never ran unless the EEPROM had
ATH9K_ANT_FIXED_A or ATH9K_ANT_FIXED_B for antenna diversity.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/hw.c  |    4 +-
 drivers/net/wireless/ath/ath9k/phy.c |   70 ++++++++++++++++++++++++++++++++++
 2 files changed, 73 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index d435369..db95876 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2054,7 +2054,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 
 	ah->ath9k_hw_spur_mitigate_freq(ah, chan);
 	ah->eep_ops->set_board_values(ah, chan);
-	ath9k_hw_decrease_chain_power(ah, chan);
+
+	if (AR_SREV_5416(ah))
+		ath9k_hw_decrease_chain_power(ah, chan);
 
 	REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr));
 	REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(common->macaddr + 4)
diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c
index a15532e..df55e28 100644
--- a/drivers/net/wireless/ath/ath9k/phy.c
+++ b/drivers/net/wireless/ath/ath9k/phy.c
@@ -41,6 +41,10 @@
 
 #include "hw.h"
 
+static void ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
+				       u32 numBits, u32 firstBit,
+				       u32 column);
+
 /**
  * ath9k_hw_write_regs - ??
  *
@@ -429,6 +433,67 @@ void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
 
 /* All code below is for non single-chip solutions */
 
+/*
+ * Fix on 2.4 GHz band for orientation sensitivity issue by increasing
+ * rf_pwd_icsyndiv.
+ *
+ * Theoretical Rules:
+ *   if 2 GHz band
+ *      if forceBiasAuto
+ *         if synth_freq < 2412
+ *            bias = 0
+ *         else if 2412 <= synth_freq <= 2422
+ *            bias = 1
+ *         else // synth_freq > 2422
+ *            bias = 2
+ *      else if forceBias > 0
+ *         bias = forceBias & 7
+ *      else
+ *         no change, use value from ini file
+ *   else
+ *      no change, invalid band
+ *
+ *  1st Mod:
+ *    2422 also uses value of 2
+ *    <approved>
+ *
+ *  2nd Mod:
+ *    Less than 2412 uses value of 0, 2412 and above uses value of 2
+ */
+static void ath9k_hw_force_bias(struct ath_hw *ah, u16 synth_freq)
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+	u32 tmp_reg;
+	int reg_writes = 0;
+	u32 new_bias = 0;
+
+	if (!AR_SREV_5416(ah) || synth_freq >= 3000) {
+		return;
+	}
+
+	BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
+
+	if (synth_freq < 2412)
+		new_bias = 0;
+	else if (synth_freq < 2422)
+		new_bias = 1;
+	else
+		new_bias = 2;
+
+	/* pre-reverse this field */
+	tmp_reg = ath9k_hw_reverse_bits(new_bias, 3);
+
+	ath_print(common, ATH_DBG_CONFIG,
+		  "Force rf_pwd_icsyndiv to %1d on %4d\n",
+		  new_bias, synth_freq);
+
+	/* swizzle rf_pwd_icsyndiv */
+	ath9k_phy_modify_rx_buffer(ah->analogBank6Data, tmp_reg, 3, 181, 3);
+
+	/* write Bank 6 with new params */
+	REG_WRITE_RF_ARRAY(&ah->iniBank6, ah->analogBank6Data, reg_writes);
+}
+
 /**
  * ath9k_hw_set_channel - tune to a channel on the external AR2133/AR5133 radios
  * @ah: atheros hardware stucture
@@ -499,6 +564,9 @@ int ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
 		return -EINVAL;
 	}
 
+	ath9k_hw_force_bias(ah, freq);
+	ath9k_hw_decrease_chain_power(ah, chan);
+
 	reg32 =
 	    (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) |
 	    (1 << 5) | 0x1;
@@ -946,6 +1014,8 @@ ath9k_hw_decrease_chain_power(struct ath_hw *ah, struct ath9k_channel *chan)
 	u32 bank6SelMask;
 	u32 *bank6Temp = ah->bank6Temp;
 
+	BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
+
 	switch (ah->config.diversity_control) {
 	case ATH9K_ANT_FIXED_A:
 		bank6SelMask =
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFT 15/15] ath9k_hw: make ath9k_phy_modify_rx_buffer() static
  2009-10-19  6:33 [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias Luis R. Rodriguez
                   ` (13 preceding siblings ...)
  2009-10-19  6:33 ` [RFT 14/15] ath9k_hw: Fix and complete force bias for AR5416 Luis R. Rodriguez
@ 2009-10-19  6:33 ` Luis R. Rodriguez
  2009-10-22  3:42 ` [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias Luis R. Rodriguez
  15 siblings, 0 replies; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-10-19  6:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: ath9k-devel, Luis R. Rodriguez

To do this we reorder callers in order in which they are called.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
 drivers/net/wireless/ath/ath9k/phy.c |  256 +++++++++++++++++-----------------
 1 files changed, 126 insertions(+), 130 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c
index df55e28..13ab4d7 100644
--- a/drivers/net/wireless/ath/ath9k/phy.c
+++ b/drivers/net/wireless/ath/ath9k/phy.c
@@ -41,10 +41,6 @@
 
 #include "hw.h"
 
-static void ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
-				       u32 numBits, u32 firstBit,
-				       u32 column);
-
 /**
  * ath9k_hw_write_regs - ??
  *
@@ -433,6 +429,43 @@ void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
 
 /* All code below is for non single-chip solutions */
 
+/**
+ * ath9k_phy_modify_rx_buffer() - perform analog swizzling of parameters
+ * @rfbuf:
+ * @reg32:
+ * @numBits:
+ * @firstBit:
+ * @column:
+ *
+ * Performs analog "swizzling" of parameters into their location.
+ * Used on external AR2133/AR5133 radios.
+ */
+static void ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
+				       u32 numBits, u32 firstBit,
+				       u32 column)
+{
+	u32 tmp32, mask, arrayEntry, lastBit;
+	int32_t bitPosition, bitsLeft;
+
+	tmp32 = ath9k_hw_reverse_bits(reg32, numBits);
+	arrayEntry = (firstBit - 1) / 8;
+	bitPosition = (firstBit - 1) % 8;
+	bitsLeft = numBits;
+	while (bitsLeft > 0) {
+		lastBit = (bitPosition + bitsLeft > 8) ?
+		    8 : bitPosition + bitsLeft;
+		mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) <<
+		    (column * 8);
+		rfBuf[arrayEntry] &= ~mask;
+		rfBuf[arrayEntry] |= ((tmp32 << bitPosition) <<
+				      (column * 8)) & mask;
+		bitsLeft -= 8 - bitPosition;
+		tmp32 = tmp32 >> (8 - bitPosition);
+		bitPosition = 0;
+		arrayEntry++;
+	}
+}
+
 /*
  * Fix on 2.4 GHz band for orientation sensitivity issue by increasing
  * rf_pwd_icsyndiv.
@@ -495,6 +528,95 @@ static void ath9k_hw_force_bias(struct ath_hw *ah, u16 synth_freq)
 }
 
 /**
+ * ath9k_hw_decrease_chain_power()
+ *
+ * @ah: atheros hardware structure
+ * @chan:
+ *
+ * Only used on the AR5416 and AR5418 with the external AR2133/AR5133 radios.
+ *
+ * Sets a chain internal RF path to the lowest output power. Any
+ * further writes to bank6 after this setting will override these
+ * changes. Thus this function must be the last function in the
+ * sequence to modify bank 6.
+ *
+ * This function must be called after ar5416SetRfRegs() which is
+ * called from ath9k_hw_process_ini() due to swizzling of bank 6.
+ * Depends on ah->analogBank6Data being initialized by
+ * ath9k_hw_set_rf_regs()
+ *
+ * Additional additive reduction in power -
+ * change chain's switch table so chain's tx state is actually the rx
+ * state value. May produce different results in 2GHz/5GHz as well as
+ * board to board but in general should be a reduction.
+ *
+ * Activated by #ifdef ALTER_SWITCH.  Not tried yet.  If so, must be
+ * called after ah->eep_ops->set_board_values() due to RMW of
+ * PHY_SWITCH_CHAIN_0.
+ */
+void ath9k_hw_decrease_chain_power(struct ath_hw *ah,
+				   struct ath9k_channel *chan)
+{
+	int i, regWrites = 0;
+	u32 bank6SelMask;
+	u32 *bank6Temp = ah->bank6Temp;
+
+	BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
+
+	switch (ah->config.diversity_control) {
+	case ATH9K_ANT_FIXED_A:
+		bank6SelMask =
+		    (ah->config.antenna_switch_swap & ANTSWAP_AB) ?
+			REDUCE_CHAIN_0 : /* swapped, reduce chain 0 */
+			REDUCE_CHAIN_1; /* normal, select chain 1/2 to reduce */
+		break;
+	case ATH9K_ANT_FIXED_B:
+		bank6SelMask =
+		    (ah->config.antenna_switch_swap & ANTSWAP_AB) ?
+			REDUCE_CHAIN_1 : /* swapped, reduce chain 1/2 */
+			REDUCE_CHAIN_0; /* normal, select chain 0 to reduce */
+		break;
+	case ATH9K_ANT_VARIABLE:
+		return; /* do not change anything */
+		break;
+	default:
+		return; /* do not change anything */
+		break;
+	}
+
+	for (i = 0; i < ah->iniBank6.ia_rows; i++)
+		bank6Temp[i] = ah->analogBank6Data[i];
+
+	/* Write Bank 5 to switch Bank 6 write to selected chain only */
+	REG_WRITE(ah, AR_PHY_BASE + 0xD8, bank6SelMask);
+
+	/*
+	 * Modify Bank6 selected chain to use lowest amplification.
+	 * Modifies the parameters to a value of 1.
+	 * Depends on existing bank 6 values to be cached in
+	 * ah->analogBank6Data
+	 */
+	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 189, 0);
+	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 190, 0);
+	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 191, 0);
+	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 192, 0);
+	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 193, 0);
+	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 222, 0);
+	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 245, 0);
+	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 246, 0);
+	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 247, 0);
+
+	REG_WRITE_RF_ARRAY(&ah->iniBank6, bank6Temp, regWrites);
+
+	REG_WRITE(ah, AR_PHY_BASE + 0xD8, 0x00000053);
+#ifdef ALTER_SWITCH
+	REG_WRITE(ah, PHY_SWITCH_CHAIN_0,
+		  (REG_READ(ah, PHY_SWITCH_CHAIN_0) & ~0x38)
+		  | ((REG_READ(ah, PHY_SWITCH_CHAIN_0) >> 3) & 0x38));
+#endif
+}
+
+/**
  * ath9k_hw_set_channel - tune to a channel on the external AR2133/AR5133 radios
  * @ah: atheros hardware stucture
  * @chan:
@@ -853,43 +975,6 @@ ath9k_hw_rf_free_ext_banks(struct ath_hw *ah)
 #undef ATH_FREE_BANK
 }
 
-/**
- * ath9k_phy_modify_rx_buffer() - perform analog swizzling of parameters
- * @rfbuf:
- * @reg32:
- * @numBits:
- * @firstBit:
- * @column:
- *
- * Performs analog "swizzling" of parameters into their location.
- * Used on external AR2133/AR5133 radios.
- */
-static void ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
-				       u32 numBits, u32 firstBit,
-				       u32 column)
-{
-	u32 tmp32, mask, arrayEntry, lastBit;
-	int32_t bitPosition, bitsLeft;
-
-	tmp32 = ath9k_hw_reverse_bits(reg32, numBits);
-	arrayEntry = (firstBit - 1) / 8;
-	bitPosition = (firstBit - 1) % 8;
-	bitsLeft = numBits;
-	while (bitsLeft > 0) {
-		lastBit = (bitPosition + bitsLeft > 8) ?
-		    8 : bitPosition + bitsLeft;
-		mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) <<
-		    (column * 8);
-		rfBuf[arrayEntry] &= ~mask;
-		rfBuf[arrayEntry] |= ((tmp32 << bitPosition) <<
-				      (column * 8)) & mask;
-		bitsLeft -= 8 - bitPosition;
-		tmp32 = tmp32 >> (8 - bitPosition);
-		bitPosition = 0;
-		arrayEntry++;
-	}
-}
-
 /* *
  * ath9k_hw_set_rf_regs - programs rf registers based on EEPROM
  * @ah: atheros hardware structure
@@ -979,92 +1064,3 @@ bool ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
 
 	return true;
 }
-
-/**
- * ath9k_hw_decrease_chain_power()
- *
- * @ah: atheros hardware structure
- * @chan:
- *
- * Only used on the AR5416 and AR5418 with the external AR2133/AR5133 radios.
- *
- * Sets a chain internal RF path to the lowest output power. Any
- * further writes to bank6 after this setting will override these
- * changes. Thus this function must be the last function in the
- * sequence to modify bank 6.
- *
- * This function must be called after ar5416SetRfRegs() which is
- * called from ath9k_hw_process_ini() due to swizzling of bank 6.
- * Depends on ah->analogBank6Data being initialized by
- * ath9k_hw_set_rf_regs()
- *
- * Additional additive reduction in power -
- * change chain's switch table so chain's tx state is actually the rx
- * state value. May produce different results in 2GHz/5GHz as well as
- * board to board but in general should be a reduction.
- *
- * Activated by #ifdef ALTER_SWITCH.  Not tried yet.  If so, must be
- * called after ah->eep_ops->set_board_values() due to RMW of
- * PHY_SWITCH_CHAIN_0.
- */
-void
-ath9k_hw_decrease_chain_power(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-	int i, regWrites = 0;
-	u32 bank6SelMask;
-	u32 *bank6Temp = ah->bank6Temp;
-
-	BUG_ON(AR_SREV_9280_10_OR_LATER(ah));
-
-	switch (ah->config.diversity_control) {
-	case ATH9K_ANT_FIXED_A:
-		bank6SelMask =
-		    (ah->config.antenna_switch_swap & ANTSWAP_AB) ?
-			REDUCE_CHAIN_0 : /* swapped, reduce chain 0 */
-			REDUCE_CHAIN_1; /* normal, select chain 1/2 to reduce */
-		break;
-	case ATH9K_ANT_FIXED_B:
-		bank6SelMask =
-		    (ah->config.antenna_switch_swap & ANTSWAP_AB) ?
-			REDUCE_CHAIN_1 : /* swapped, reduce chain 1/2 */
-			REDUCE_CHAIN_0; /* normal, select chain 0 to reduce */
-		break;
-	case ATH9K_ANT_VARIABLE:
-		return; /* do not change anything */
-		break;
-	default:
-		return; /* do not change anything */
-		break;
-	}
-
-	for (i = 0; i < ah->iniBank6.ia_rows; i++)
-		bank6Temp[i] = ah->analogBank6Data[i];
-
-	/* Write Bank 5 to switch Bank 6 write to selected chain only */
-	REG_WRITE(ah, AR_PHY_BASE + 0xD8, bank6SelMask);
-
-	/*
-	 * Modify Bank6 selected chain to use lowest amplification.
-	 * Modifies the parameters to a value of 1.
-	 * Depends on existing bank 6 values to be cached in
-	 * ah->analogBank6Data
-	 */
-	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 189, 0);
-	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 190, 0);
-	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 191, 0);
-	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 192, 0);
-	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 193, 0);
-	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 222, 0);
-	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 245, 0);
-	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 246, 0);
-	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 247, 0);
-
-	REG_WRITE_RF_ARRAY(&ah->iniBank6, bank6Temp, regWrites);
-
-	REG_WRITE(ah, AR_PHY_BASE + 0xD8, 0x00000053);
-#ifdef ALTER_SWITCH
-	REG_WRITE(ah, PHY_SWITCH_CHAIN_0,
-		  (REG_READ(ah, PHY_SWITCH_CHAIN_0) & ~0x38)
-		  | ((REG_READ(ah, PHY_SWITCH_CHAIN_0) >> 3) & 0x38));
-#endif
-}
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias
  2009-10-19  6:33 [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias Luis R. Rodriguez
                   ` (14 preceding siblings ...)
  2009-10-19  6:33 ` [RFT 15/15] ath9k_hw: make ath9k_phy_modify_rx_buffer() static Luis R. Rodriguez
@ 2009-10-22  3:42 ` Luis R. Rodriguez
  2009-10-26 14:19   ` Luis R. Rodriguez
  15 siblings, 1 reply; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-10-22  3:42 UTC (permalink / raw)
  To: linux-wireless, Sujith; +Cc: ath9k-devel, Luis R. Rodriguez

On Mon, Oct 19, 2009 at 3:33 PM, Luis R. Rodriguez
<lrodriguez@atheros.com> wrote:
> This series started off to extend support for ar9271 on ath9k_hw
> but after review of the phy related code I noticed a fix for
> AR5416 was only partially being implemented and used for all
> chipsets. This series then adds the changes I've noticed so far
> required for ar9271 but also fixes and completes the orientation
> fix for AR5416 (force bias). Since I'm touching phy.c I also extend
> documentation for it.
>
> I don't have AR9285 cards with me but I do have an AR5416 cardbus
> card -- I'd appreciate it if someone can give this a test on AR9285
> but also more AR5416 cards -- this should help with TX on of AR5416
> and AR5418 on the 2.4 GHz band.
>
> Reports on issues or performance differences are greatly appreciated;
> the only issue I'd expect you'd see on non AR5416 hardware is a BUG_ON()
> which would be very obvious to notice and the performance enhancements
> should be seen on AR5416 for TX -- not yet sure exactly under what
> circumstances.
>
> Luis R. Rodriguez (15):
>  ath9k_hw: modify the rf control register for ar9271 revision 1.0
>  ath9k_hw: update register initialization/reset values for ar9271
>  ath9k_hw: change the way we initialize the pll for ar9271
>  ath9k_hw: start documenting 802.11n RF anlong front ends
>  ath9k_hw: bail out early on ath9k_hw_init_rf()
>  ath9k_hw: simplify rf attach and rename to
>    ath9k_hw_rf_alloc_ext_banks()
>  ath9k_hw: simplify ath9k_hw_rf_alloc_ext_banks()
>  ath9k_hw: rename ath9k_hw_rf_free() to ath9k_hw_rf_free_ext_banks()
>  ath9k_hw: make both analog channel change routines return int
>  ath9k_hw: use a callback for frequency change
>  ath9k_hw: order phy.c code and integrate spur mitigation
>  ath9k_hw: make spur mitigation a callback
>  ath9k_hw: remove unused modesIndex param from ath9k_hw_write_regs()
>  ath9k_hw: Fix and complete force bias for AR5416
>  ath9k_hw: make ath9k_phy_modify_rx_buffer() static

Omni-patch:

http://bombadil.infradead.org/~mcgrof/patches/all/all-2009-10-19.patch

  Luis

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias
  2009-10-22  3:42 ` [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias Luis R. Rodriguez
@ 2009-10-26 14:19   ` Luis R. Rodriguez
  2009-10-26 14:23     ` Luis R. Rodriguez
  0 siblings, 1 reply; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-10-26 14:19 UTC (permalink / raw)
  To: linux-wireless, Sujith; +Cc: ath9k-devel, Luis R. Rodriguez

On Wed, Oct 21, 2009 at 8:42 PM, Luis R. Rodriguez
<lrodriguez@atheros.com> wrote:
> On Mon, Oct 19, 2009 at 3:33 PM, Luis R. Rodriguez
> <lrodriguez@atheros.com> wrote:
>> This series started off to extend support for ar9271 on ath9k_hw
>> but after review of the phy related code I noticed a fix for
>> AR5416 was only partially being implemented and used for all
>> chipsets. This series then adds the changes I've noticed so far
>> required for ar9271 but also fixes and completes the orientation
>> fix for AR5416 (force bias). Since I'm touching phy.c I also extend
>> documentation for it.
>>
>> I don't have AR9285 cards with me but I do have an AR5416 cardbus
>> card -- I'd appreciate it if someone can give this a test on AR9285

Alright well I made it back to California and tested an AR9285 and
things are peachy so I will submit this now.

  Luis

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias
  2009-10-26 14:19   ` Luis R. Rodriguez
@ 2009-10-26 14:23     ` Luis R. Rodriguez
  2009-10-26 14:41       ` John W. Linville
  0 siblings, 1 reply; 20+ messages in thread
From: Luis R. Rodriguez @ 2009-10-26 14:23 UTC (permalink / raw)
  To: linux-wireless, Sujith, John W. Linville; +Cc: ath9k-devel, Luis R. Rodriguez

On Mon, Oct 26, 2009 at 7:19 AM, Luis R. Rodriguez
<lrodriguez@atheros.com> wrote:
> On Wed, Oct 21, 2009 at 8:42 PM, Luis R. Rodriguez
> <lrodriguez@atheros.com> wrote:
>> On Mon, Oct 19, 2009 at 3:33 PM, Luis R. Rodriguez
>> <lrodriguez@atheros.com> wrote:
>>> This series started off to extend support for ar9271 on ath9k_hw
>>> but after review of the phy related code I noticed a fix for
>>> AR5416 was only partially being implemented and used for all
>>> chipsets. This series then adds the changes I've noticed so far
>>> required for ar9271 but also fixes and completes the orientation
>>> fix for AR5416 (force bias). Since I'm touching phy.c I also extend
>>> documentation for it.
>>>
>>> I don't have AR9285 cards with me but I do have an AR5416 cardbus
>>> card -- I'd appreciate it if someone can give this a test on AR9285
>
> Alright well I made it back to California and tested an AR9285 and
> things are peachy so I will submit this now.

Johh, actually instead of resubmitting can you take these in as-is?
They should apply on top of the latest tree. Please let me know.

 Luis

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias
  2009-10-26 14:23     ` Luis R. Rodriguez
@ 2009-10-26 14:41       ` John W. Linville
  0 siblings, 0 replies; 20+ messages in thread
From: John W. Linville @ 2009-10-26 14:41 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: linux-wireless, Sujith, ath9k-devel

On Mon, Oct 26, 2009 at 07:23:44AM -0700, Luis R. Rodriguez wrote:
> On Mon, Oct 26, 2009 at 7:19 AM, Luis R. Rodriguez
> <lrodriguez@atheros.com> wrote:
> > On Wed, Oct 21, 2009 at 8:42 PM, Luis R. Rodriguez
> > <lrodriguez@atheros.com> wrote:
> >> On Mon, Oct 19, 2009 at 3:33 PM, Luis R. Rodriguez
> >> <lrodriguez@atheros.com> wrote:
> >>> This series started off to extend support for ar9271 on ath9k_hw
> >>> but after review of the phy related code I noticed a fix for
> >>> AR5416 was only partially being implemented and used for all
> >>> chipsets. This series then adds the changes I've noticed so far
> >>> required for ar9271 but also fixes and completes the orientation
> >>> fix for AR5416 (force bias). Since I'm touching phy.c I also extend
> >>> documentation for it.
> >>>
> >>> I don't have AR9285 cards with me but I do have an AR5416 cardbus
> >>> card -- I'd appreciate it if someone can give this a test on AR9285
> >
> > Alright well I made it back to California and tested an AR9285 and
> > things are peachy so I will submit this now.
> 
> Johh, actually instead of resubmitting can you take these in as-is?
> They should apply on top of the latest tree. Please let me know.

I'm a little buried ATM, but sure -- that'll be fine...

John
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2009-10-26 14:46 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-10-19  6:33 [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias Luis R. Rodriguez
2009-10-19  6:33 ` [RFT 01/15] ath9k_hw: modify the rf control register for ar9271 revision 1.0 Luis R. Rodriguez
2009-10-19  6:33 ` [RFT 02/15] ath9k_hw: update register initialization/reset values for ar9271 Luis R. Rodriguez
2009-10-19  6:33 ` [RFT 03/15] ath9k_hw: change the way we initialize the pll " Luis R. Rodriguez
2009-10-19  6:33 ` [RFT 04/15] ath9k_hw: start documenting 802.11n RF anlong front ends Luis R. Rodriguez
2009-10-19  6:33 ` [RFT 05/15] ath9k_hw: bail out early on ath9k_hw_init_rf() Luis R. Rodriguez
2009-10-19  6:33 ` [RFT 06/15] ath9k_hw: simplify rf attach and rename to ath9k_hw_rf_alloc_ext_banks() Luis R. Rodriguez
2009-10-19  6:33 ` [RFT 07/15] ath9k_hw: simplify ath9k_hw_rf_alloc_ext_banks() Luis R. Rodriguez
2009-10-19  6:33 ` [RFT 08/15] ath9k_hw: rename ath9k_hw_rf_free() to ath9k_hw_rf_free_ext_banks() Luis R. Rodriguez
2009-10-19  6:33 ` [RFT 09/15] ath9k_hw: make both analog channel change routines return int Luis R. Rodriguez
2009-10-19  6:33 ` [RFT 10/15] ath9k_hw: use a callback for frequency change Luis R. Rodriguez
2009-10-19  6:33 ` [RFT 11/15] ath9k_hw: order phy.c code and integrate spur mitigation Luis R. Rodriguez
2009-10-19  6:33 ` [RFT 12/15] ath9k_hw: make spur mitigation a callback Luis R. Rodriguez
2009-10-19  6:33 ` [RFT 13/15] ath9k_hw: remove unused modesIndex param from ath9k_hw_write_regs() Luis R. Rodriguez
2009-10-19  6:33 ` [RFT 14/15] ath9k_hw: Fix and complete force bias for AR5416 Luis R. Rodriguez
2009-10-19  6:33 ` [RFT 15/15] ath9k_hw: make ath9k_phy_modify_rx_buffer() static Luis R. Rodriguez
2009-10-22  3:42 ` [RFT 00/15] ath9k_hw ar9271 updates & AR5416 force bias Luis R. Rodriguez
2009-10-26 14:19   ` Luis R. Rodriguez
2009-10-26 14:23     ` Luis R. Rodriguez
2009-10-26 14:41       ` John W. Linville

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).