All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 01/12] ath9k_hw: fall back to OTP ROM when platform data has no valid eeprom data
@ 2012-07-12 15:04 Felix Fietkau
  2012-07-12 15:04 ` [PATCH v2 02/12] ath9k: validate rx antenna settings Felix Fietkau
  0 siblings, 1 reply; 23+ messages in thread
From: Felix Fietkau @ 2012-07-12 15:04 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, mcgrof

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.c |   14 ++++++++++++--
 1 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 25de6f9..3cddd78 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -3260,10 +3260,20 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
 	int it;
 	u16 checksum, mchecksum;
 	struct ath_common *common = ath9k_hw_common(ah);
+	struct ar9300_eeprom *eep;
 	eeprom_read_op read;
 
-	if (ath9k_hw_use_flash(ah))
-		return ar9300_eeprom_restore_flash(ah, mptr, mdata_size);
+	if (ath9k_hw_use_flash(ah)) {
+		u8 txrx;
+
+		ar9300_eeprom_restore_flash(ah, mptr, mdata_size);
+
+		/* check if eeprom contains valid data */
+		eep = (struct ar9300_eeprom *) mptr;
+		txrx = eep->baseEepHeader.txrxMask;
+		if (txrx != 0 && txrx != 0xff)
+			return 0;
+	}
 
 	word = kzalloc(2048, GFP_KERNEL);
 	if (!word)
-- 
1.7.3.2


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

* [PATCH v2 02/12] ath9k: validate rx antenna settings
  2012-07-12 15:04 [PATCH v2 01/12] ath9k_hw: fall back to OTP ROM when platform data has no valid eeprom data Felix Fietkau
@ 2012-07-12 15:04 ` Felix Fietkau
  2012-07-12 15:04   ` [PATCH v2 03/12] ath9k_hw: enable ANI on AR934x Felix Fietkau
  0 siblings, 1 reply; 23+ messages in thread
From: Felix Fietkau @ 2012-07-12 15:04 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, mcgrof

Many chips are not able to deal with non-consecutive rx antenna selections
and respond with calibration errors, reset errors, etc.
When an antenna is selected as a tx antenna, also flag it for rx to avoid
chip issues.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/main.c |   19 ++++++++++++++++++-
 1 files changed, 18 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 248e5b2..724f415 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1912,12 +1912,29 @@ static u32 fill_chainmask(u32 cap, u32 new)
 	return filled;
 }
 
+static bool validate_antenna_mask(struct ath_hw *ah, u32 val)
+{
+	switch (val & 0x7) {
+	case 0x1:
+	case 0x3:
+	case 0x7:
+		return true;
+	case 0x2:
+		return (ah->caps.rx_chainmask == 1);
+	default:
+		return false;
+	}
+}
+
 static int ath9k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
 {
 	struct ath_softc *sc = hw->priv;
 	struct ath_hw *ah = sc->sc_ah;
 
-	if (!rx_ant || !tx_ant)
+	if (ah->caps.rx_chainmask != 1)
+		rx_ant |= tx_ant;
+
+	if (!validate_antenna_mask(ah, rx_ant) || !tx_ant)
 		return -EINVAL;
 
 	sc->ant_rx = rx_ant;
-- 
1.7.3.2


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

* [PATCH v2 03/12] ath9k_hw: enable ANI on AR934x
  2012-07-12 15:04 ` [PATCH v2 02/12] ath9k: validate rx antenna settings Felix Fietkau
@ 2012-07-12 15:04   ` Felix Fietkau
  2012-07-12 15:04     ` [PATCH v2 04/12] ath9k_hw: fix tx gain tables for AR934x Felix Fietkau
  0 siblings, 1 reply; 23+ messages in thread
From: Felix Fietkau @ 2012-07-12 15:04 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, mcgrof

It has been tested and works properly

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/hw.c |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index c1659d0..69a2e03 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -671,10 +671,6 @@ static int __ath9k_hw_init(struct ath_hw *ah)
 	if (!AR_SREV_9300_20_OR_LATER(ah))
 		ah->ani_function &= ~ATH9K_ANI_MRC_CCK;
 
-	/* disable ANI for 9340 */
-	if (AR_SREV_9340(ah))
-		ah->config.enable_ani = false;
-
 	ath9k_hw_init_mode_regs(ah);
 
 	if (!ah->is_pciexpress)
-- 
1.7.3.2


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

* [PATCH v2 04/12] ath9k_hw: fix tx gain tables for AR934x
  2012-07-12 15:04   ` [PATCH v2 03/12] ath9k_hw: enable ANI on AR934x Felix Fietkau
@ 2012-07-12 15:04     ` Felix Fietkau
  2012-07-12 15:04       ` [PATCH v2 05/12] ath9k_hw: remove redundant arguments to INIT_INI_ARRAY Felix Fietkau
  0 siblings, 1 reply; 23+ messages in thread
From: Felix Fietkau @ 2012-07-12 15:04 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, mcgrof

Use the EEPROM information to choose the right tx gain table

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ar9003_hw.c |   29 ++++++++++++++++++++++-----
 1 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 41e88c6..718241d 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -561,8 +561,8 @@ static void ar9003_tx_gain_table_mode1(struct ath_hw *ah)
 			5);
 	else if (AR_SREV_9340(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
-			ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
+			ar9340Modes_high_ob_db_tx_gain_table_1p0,
+			ARRAY_SIZE(ar9340Modes_high_ob_db_tx_gain_table_1p0),
 			5);
 	else if (AR_SREV_9485_11(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
@@ -605,8 +605,8 @@ static void ar9003_tx_gain_table_mode2(struct ath_hw *ah)
 			5);
 	else if (AR_SREV_9340(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
-			ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
+			ar9340Modes_low_ob_db_tx_gain_table_1p0,
+			ARRAY_SIZE(ar9340Modes_low_ob_db_tx_gain_table_1p0),
 			5);
 	else if (AR_SREV_9485_11(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
@@ -639,8 +639,8 @@ static void ar9003_tx_gain_table_mode3(struct ath_hw *ah)
 			5);
 	else if (AR_SREV_9340(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
-			ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
+			ar9340Modes_high_power_tx_gain_table_1p0,
+			ARRAY_SIZE(ar9340Modes_high_power_tx_gain_table_1p0),
 			5);
 	else if (AR_SREV_9485_11(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
@@ -659,6 +659,20 @@ static void ar9003_tx_gain_table_mode3(struct ath_hw *ah)
 			5);
 }
 
+static void ar9003_tx_gain_table_mode4(struct ath_hw *ah)
+{
+	if (AR_SREV_9340(ah))
+		INIT_INI_ARRAY(&ah->iniModesTxGain,
+			ar9340Modes_mixed_ob_db_tx_gain_table_1p0,
+			ARRAY_SIZE(ar9340Modes_mixed_ob_db_tx_gain_table_1p0),
+			5);
+	else if (AR_SREV_9580(ah))
+		INIT_INI_ARRAY(&ah->iniModesTxGain,
+			ar9580_1p0_mixed_ob_db_tx_gain_table,
+			ARRAY_SIZE(ar9580_1p0_mixed_ob_db_tx_gain_table),
+			5);
+}
+
 static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
 {
 	switch (ar9003_hw_get_tx_gain_idx(ah)) {
@@ -675,6 +689,9 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
 	case 3:
 		ar9003_tx_gain_table_mode3(ah);
 		break;
+	case 4:
+		ar9003_tx_gain_table_mode4(ah);
+		break;
 	}
 }
 
-- 
1.7.3.2


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

* [PATCH v2 05/12] ath9k_hw: remove redundant arguments to INIT_INI_ARRAY
  2012-07-12 15:04     ` [PATCH v2 04/12] ath9k_hw: fix tx gain tables for AR934x Felix Fietkau
@ 2012-07-12 15:04       ` Felix Fietkau
  2012-07-12 15:04         ` [PATCH v2 06/12] ath9k/ath9k_htc: fix txop limit handling Felix Fietkau
  2012-07-15 17:53         ` [PATCH v2 05/12] ath9k_hw: remove redundant arguments to INIT_INI_ARRAY Felix Fietkau
  0 siblings, 2 replies; 23+ messages in thread
From: Felix Fietkau @ 2012-07-12 15:04 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, mcgrof

The row/column sizes can be derived from the array argument within the macro
itself, which is less error prone. In a few cases the supplied column size
was actually wrong.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ar9002_hw.c |  154 +++------
 drivers/net/wireless/ath/ath9k/ar9003_hw.c |  541 ++++++++--------------------
 drivers/net/wireless/ath/ath9k/calib.h     |    6 +-
 3 files changed, 199 insertions(+), 502 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index edf21ea..2b56a1f 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -26,101 +26,70 @@
 static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
 {
 	if (AR_SREV_9271(ah)) {
-		INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271,
-			       ARRAY_SIZE(ar9271Modes_9271), 5);
-		INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271,
-			       ARRAY_SIZE(ar9271Common_9271), 2);
-		INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg,
-			       ARRAY_SIZE(ar9271Modes_9271_ANI_reg), 5);
+		INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271);
+		INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271);
+		INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg);
 		return;
 	}
 
 	if (ah->config.pcie_clock_req)
 		INIT_INI_ARRAY(&ah->iniPcieSerdes,
-			   ar9280PciePhy_clkreq_off_L1_9280,
-			   ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280), 2);
+			   ar9280PciePhy_clkreq_off_L1_9280);
 	else
 		INIT_INI_ARRAY(&ah->iniPcieSerdes,
-			   ar9280PciePhy_clkreq_always_on_L1_9280,
-			   ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2);
+			   ar9280PciePhy_clkreq_always_on_L1_9280);
 
 	if (AR_SREV_9287_11_OR_LATER(ah)) {
-		INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1,
-				ARRAY_SIZE(ar9287Modes_9287_1_1), 5);
-		INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_1,
-				ARRAY_SIZE(ar9287Common_9287_1_1), 2);
+		INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1);
+		INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_1);
 	} else if (AR_SREV_9285_12_OR_LATER(ah)) {
-		INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
-			       ARRAY_SIZE(ar9285Modes_9285_1_2), 5);
-		INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2,
-			       ARRAY_SIZE(ar9285Common_9285_1_2), 2);
+		INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2);
+		INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2);
 	} else if (AR_SREV_9280_20_OR_LATER(ah)) {
-		INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2,
-			       ARRAY_SIZE(ar9280Modes_9280_2), 5);
-		INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2,
-			       ARRAY_SIZE(ar9280Common_9280_2), 2);
+		INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2);
+		INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2);
 
 		INIT_INI_ARRAY(&ah->iniModesFastClock,
-			       ar9280Modes_fast_clock_9280_2,
-			       ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3);
+			       ar9280Modes_fast_clock_9280_2);
 	} else if (AR_SREV_9160_10_OR_LATER(ah)) {
-		INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160,
-			       ARRAY_SIZE(ar5416Modes_9160), 5);
-		INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160,
-			       ARRAY_SIZE(ar5416Common_9160), 2);
+		INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160);
+		INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160);
 		if (AR_SREV_9160_11(ah)) {
 			INIT_INI_ARRAY(&ah->iniAddac,
-				       ar5416Addac_9160_1_1,
-				       ARRAY_SIZE(ar5416Addac_9160_1_1), 2);
+				       ar5416Addac_9160_1_1);
 		} else {
-			INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160,
-				       ARRAY_SIZE(ar5416Addac_9160), 2);
+			INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160);
 		}
 	} else if (AR_SREV_9100_OR_LATER(ah)) {
-		INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100,
-			       ARRAY_SIZE(ar5416Modes_9100), 5);
-		INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100,
-			       ARRAY_SIZE(ar5416Common_9100), 2);
-		INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100,
-			       ARRAY_SIZE(ar5416Bank6_9100), 3);
-		INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100,
-			       ARRAY_SIZE(ar5416Addac_9100), 2);
+		INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100);
+		INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100);
+		INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100);
+		INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100);
 	} else {
-		INIT_INI_ARRAY(&ah->iniModes, ar5416Modes,
-			       ARRAY_SIZE(ar5416Modes), 5);
-		INIT_INI_ARRAY(&ah->iniCommon, ar5416Common,
-			       ARRAY_SIZE(ar5416Common), 2);
-		INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC,
-			       ARRAY_SIZE(ar5416Bank6TPC), 3);
-		INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac,
-			       ARRAY_SIZE(ar5416Addac), 2);
+		INIT_INI_ARRAY(&ah->iniModes, ar5416Modes);
+		INIT_INI_ARRAY(&ah->iniCommon, ar5416Common);
+		INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC);
+		INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac);
 	}
 
 	if (!AR_SREV_9280_20_OR_LATER(ah)) {
 		/* Common for AR5416, AR913x, AR9160 */
-		INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain,
-			       ARRAY_SIZE(ar5416BB_RfGain), 3);
-
-		INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0,
-			       ARRAY_SIZE(ar5416Bank0), 2);
-		INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1,
-			       ARRAY_SIZE(ar5416Bank1), 2);
-		INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2,
-			       ARRAY_SIZE(ar5416Bank2), 2);
-		INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3,
-			       ARRAY_SIZE(ar5416Bank3), 3);
-		INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7,
-			       ARRAY_SIZE(ar5416Bank7), 2);
+		INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain);
+
+		INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0);
+		INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1);
+		INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2);
+		INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3);
+		INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7);
 
 		/* Common for AR5416, AR9160 */
 		if (!AR_SREV_9100(ah))
-			INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6,
-				       ARRAY_SIZE(ar5416Bank6), 3);
+			INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6);
 
 		/* Common for AR913x, AR9160 */
 		if (!AR_SREV_5416(ah))
-			INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100,
-				       ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
+			INIT_INI_ARRAY(&ah->iniBank6TPC,
+				      ar5416Bank6TPC_9100);
 	}
 
 	/* iniAddac needs to be modified for these chips */
@@ -143,13 +112,9 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
 	}
 	if (AR_SREV_9287_11_OR_LATER(ah)) {
 		INIT_INI_ARRAY(&ah->iniCckfirNormal,
-		       ar9287Common_normal_cck_fir_coeff_9287_1_1,
-		       ARRAY_SIZE(ar9287Common_normal_cck_fir_coeff_9287_1_1),
-		       2);
+		       ar9287Common_normal_cck_fir_coeff_9287_1_1);
 		INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
-		       ar9287Common_japan_2484_cck_fir_coeff_9287_1_1,
-		       ARRAY_SIZE(ar9287Common_japan_2484_cck_fir_coeff_9287_1_1),
-		       2);
+		       ar9287Common_japan_2484_cck_fir_coeff_9287_1_1);
 	}
 }
 
@@ -163,20 +128,16 @@ static void ar9280_20_hw_init_rxgain_ini(struct ath_hw *ah)
 
 		if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF)
 			INIT_INI_ARRAY(&ah->iniModesRxGain,
-			ar9280Modes_backoff_13db_rxgain_9280_2,
-			ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2), 5);
+				       ar9280Modes_backoff_13db_rxgain_9280_2);
 		else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF)
 			INIT_INI_ARRAY(&ah->iniModesRxGain,
-			ar9280Modes_backoff_23db_rxgain_9280_2,
-			ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 5);
+				       ar9280Modes_backoff_23db_rxgain_9280_2);
 		else
 			INIT_INI_ARRAY(&ah->iniModesRxGain,
-			ar9280Modes_original_rxgain_9280_2,
-			ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 5);
+				       ar9280Modes_original_rxgain_9280_2);
 	} else {
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-			ar9280Modes_original_rxgain_9280_2,
-			ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 5);
+			       ar9280Modes_original_rxgain_9280_2);
 	}
 }
 
@@ -186,16 +147,13 @@ static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah, u32 txgain_type)
 	    AR5416_EEP_MINOR_VER_19) {
 		if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER)
 			INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9280Modes_high_power_tx_gain_9280_2,
-			ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 5);
+				       ar9280Modes_high_power_tx_gain_9280_2);
 		else
 			INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9280Modes_original_tx_gain_9280_2,
-			ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 5);
+				       ar9280Modes_original_tx_gain_9280_2);
 	} else {
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-		ar9280Modes_original_tx_gain_9280_2,
-		ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 5);
+			       ar9280Modes_original_tx_gain_9280_2);
 	}
 }
 
@@ -203,12 +161,10 @@ static void ar9271_hw_init_txgain_ini(struct ath_hw *ah, u32 txgain_type)
 {
 	if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER)
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			       ar9271Modes_high_power_tx_gain_9271,
-			       ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 5);
+			       ar9271Modes_high_power_tx_gain_9271);
 	else
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			       ar9271Modes_normal_power_tx_gain_9271,
-			       ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 5);
+			       ar9271Modes_normal_power_tx_gain_9271);
 }
 
 static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah)
@@ -217,8 +173,7 @@ static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah)
 
 	if (AR_SREV_9287_11_OR_LATER(ah))
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-		ar9287Modes_rx_gain_9287_1_1,
-		ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1), 5);
+			       ar9287Modes_rx_gain_9287_1_1);
 	else if (AR_SREV_9280_20(ah))
 		ar9280_20_hw_init_rxgain_ini(ah);
 
@@ -226,8 +181,7 @@ static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah)
 		ar9271_hw_init_txgain_ini(ah, txgain_type);
 	} else if (AR_SREV_9287_11_OR_LATER(ah)) {
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-		ar9287Modes_tx_gain_9287_1_1,
-		ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 5);
+			       ar9287Modes_tx_gain_9287_1_1);
 	} else if (AR_SREV_9280_20(ah)) {
 		ar9280_20_hw_init_txgain_ini(ah, txgain_type);
 	} else if (AR_SREV_9285_12_OR_LATER(ah)) {
@@ -235,26 +189,18 @@ static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah)
 		if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) {
 			if (AR_SREV_9285E_20(ah)) {
 				INIT_INI_ARRAY(&ah->iniModesTxGain,
-				ar9285Modes_XE2_0_high_power,
-				ARRAY_SIZE(
-				  ar9285Modes_XE2_0_high_power), 5);
+					       ar9285Modes_XE2_0_high_power);
 			} else {
 				INIT_INI_ARRAY(&ah->iniModesTxGain,
-				ar9285Modes_high_power_tx_gain_9285_1_2,
-				ARRAY_SIZE(
-				  ar9285Modes_high_power_tx_gain_9285_1_2), 5);
+					ar9285Modes_high_power_tx_gain_9285_1_2);
 			}
 		} else {
 			if (AR_SREV_9285E_20(ah)) {
 				INIT_INI_ARRAY(&ah->iniModesTxGain,
-				ar9285Modes_XE2_0_normal_power,
-				ARRAY_SIZE(
-				  ar9285Modes_XE2_0_normal_power), 5);
+					       ar9285Modes_XE2_0_normal_power);
 			} else {
 				INIT_INI_ARRAY(&ah->iniModesTxGain,
-				ar9285Modes_original_tx_gain_9285_1_2,
-				ARRAY_SIZE(
-				  ar9285Modes_original_tx_gain_9285_1_2), 5);
+					ar9285Modes_original_tx_gain_9285_1_2);
 			}
 		}
 	}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 718241d..1e8a4da 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -44,462 +44,310 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
 		ar9462_2p0_baseband_core_txfir_coeff_japan_2484
 	if (AR_SREV_9330_11(ah)) {
 		/* mac */
-		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
-				ar9331_1p1_mac_core,
-				ARRAY_SIZE(ar9331_1p1_mac_core), 2);
+				ar9331_1p1_mac_core);
 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
-				ar9331_1p1_mac_postamble,
-				ARRAY_SIZE(ar9331_1p1_mac_postamble), 5);
+				ar9331_1p1_mac_postamble);
 
 		/* bb */
-		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
-				ar9331_1p1_baseband_core,
-				ARRAY_SIZE(ar9331_1p1_baseband_core), 2);
+				ar9331_1p1_baseband_core);
 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
-				ar9331_1p1_baseband_postamble,
-				ARRAY_SIZE(ar9331_1p1_baseband_postamble), 5);
+				ar9331_1p1_baseband_postamble);
 
 		/* radio */
-		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
-				ar9331_1p1_radio_core,
-				ARRAY_SIZE(ar9331_1p1_radio_core), 2);
-		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], NULL, 0, 0);
+				ar9331_1p1_radio_core);
 
 		/* soc */
 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
-				ar9331_1p1_soc_preamble,
-				ARRAY_SIZE(ar9331_1p1_soc_preamble), 2);
-		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
+				ar9331_1p1_soc_preamble);
 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
-				ar9331_1p1_soc_postamble,
-				ARRAY_SIZE(ar9331_1p1_soc_postamble), 2);
+				ar9331_1p1_soc_postamble);
 
 		/* rx/tx gain */
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-				ar9331_common_rx_gain_1p1,
-				ARRAY_SIZE(ar9331_common_rx_gain_1p1), 2);
+				ar9331_common_rx_gain_1p1);
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9331_modes_lowest_ob_db_tx_gain_1p1,
-			ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p1),
-			5);
+				ar9331_modes_lowest_ob_db_tx_gain_1p1);
 
 		/* additional clock settings */
 		if (ah->is_clk_25mhz)
 			INIT_INI_ARRAY(&ah->iniAdditional,
-					ar9331_1p1_xtal_25M,
-					ARRAY_SIZE(ar9331_1p1_xtal_25M), 2);
+					ar9331_1p1_xtal_25M);
 		else
 			INIT_INI_ARRAY(&ah->iniAdditional,
-					ar9331_1p1_xtal_40M,
-					ARRAY_SIZE(ar9331_1p1_xtal_40M), 2);
+					ar9331_1p1_xtal_40M);
 	} else if (AR_SREV_9330_12(ah)) {
 		/* mac */
-		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
-				ar9331_1p2_mac_core,
-				ARRAY_SIZE(ar9331_1p2_mac_core), 2);
+				ar9331_1p2_mac_core);
 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
-				ar9331_1p2_mac_postamble,
-				ARRAY_SIZE(ar9331_1p2_mac_postamble), 5);
+				ar9331_1p2_mac_postamble);
 
 		/* bb */
-		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
-				ar9331_1p2_baseband_core,
-				ARRAY_SIZE(ar9331_1p2_baseband_core), 2);
+				ar9331_1p2_baseband_core);
 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
-				ar9331_1p2_baseband_postamble,
-				ARRAY_SIZE(ar9331_1p2_baseband_postamble), 5);
+				ar9331_1p2_baseband_postamble);
 
 		/* radio */
-		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
-				ar9331_1p2_radio_core,
-				ARRAY_SIZE(ar9331_1p2_radio_core), 2);
-		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], NULL, 0, 0);
+				ar9331_1p2_radio_core);
 
 		/* soc */
 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
-				ar9331_1p2_soc_preamble,
-				ARRAY_SIZE(ar9331_1p2_soc_preamble), 2);
-		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
+				ar9331_1p2_soc_preamble);
 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
-				ar9331_1p2_soc_postamble,
-				ARRAY_SIZE(ar9331_1p2_soc_postamble), 2);
+				ar9331_1p2_soc_postamble);
 
 		/* rx/tx gain */
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-				ar9331_common_rx_gain_1p2,
-				ARRAY_SIZE(ar9331_common_rx_gain_1p2), 2);
+				ar9331_common_rx_gain_1p2);
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9331_modes_lowest_ob_db_tx_gain_1p2,
-			ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p2),
-			5);
+				ar9331_modes_lowest_ob_db_tx_gain_1p2);
 
 		/* additional clock settings */
 		if (ah->is_clk_25mhz)
 			INIT_INI_ARRAY(&ah->iniAdditional,
-					ar9331_1p2_xtal_25M,
-					ARRAY_SIZE(ar9331_1p2_xtal_25M), 2);
+					ar9331_1p2_xtal_25M);
 		else
 			INIT_INI_ARRAY(&ah->iniAdditional,
-					ar9331_1p2_xtal_40M,
-					ARRAY_SIZE(ar9331_1p2_xtal_40M), 2);
+					ar9331_1p2_xtal_40M);
 	} else if (AR_SREV_9340(ah)) {
 		/* mac */
-		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
-				ar9340_1p0_mac_core,
-				ARRAY_SIZE(ar9340_1p0_mac_core), 2);
+				ar9340_1p0_mac_core);
 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
-				ar9340_1p0_mac_postamble,
-				ARRAY_SIZE(ar9340_1p0_mac_postamble), 5);
+				ar9340_1p0_mac_postamble);
 
 		/* bb */
-		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
-				ar9340_1p0_baseband_core,
-				ARRAY_SIZE(ar9340_1p0_baseband_core), 2);
+				ar9340_1p0_baseband_core);
 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
-				ar9340_1p0_baseband_postamble,
-				ARRAY_SIZE(ar9340_1p0_baseband_postamble), 5);
+				ar9340_1p0_baseband_postamble);
 
 		/* radio */
-		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
-				ar9340_1p0_radio_core,
-				ARRAY_SIZE(ar9340_1p0_radio_core), 2);
+				ar9340_1p0_radio_core);
 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
-				ar9340_1p0_radio_postamble,
-				ARRAY_SIZE(ar9340_1p0_radio_postamble), 5);
+				ar9340_1p0_radio_postamble);
 
 		/* soc */
 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
-				ar9340_1p0_soc_preamble,
-				ARRAY_SIZE(ar9340_1p0_soc_preamble), 2);
-		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
+				ar9340_1p0_soc_preamble);
 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
-				ar9340_1p0_soc_postamble,
-				ARRAY_SIZE(ar9340_1p0_soc_postamble), 5);
+				ar9340_1p0_soc_postamble);
 
 		/* rx/tx gain */
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-				ar9340Common_wo_xlna_rx_gain_table_1p0,
-				ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0),
-				5);
+				ar9340Common_wo_xlna_rx_gain_table_1p0);
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-				ar9340Modes_high_ob_db_tx_gain_table_1p0,
-				ARRAY_SIZE(ar9340Modes_high_ob_db_tx_gain_table_1p0),
-				5);
+				ar9340Modes_high_ob_db_tx_gain_table_1p0);
 
 		INIT_INI_ARRAY(&ah->iniModesFastClock,
-				ar9340Modes_fast_clock_1p0,
-				ARRAY_SIZE(ar9340Modes_fast_clock_1p0),
-				3);
+				ar9340Modes_fast_clock_1p0);
 
 		if (!ah->is_clk_25mhz)
 			INIT_INI_ARRAY(&ah->iniAdditional,
-				       ar9340_1p0_radio_core_40M,
-				       ARRAY_SIZE(ar9340_1p0_radio_core_40M),
-				       2);
+				       ar9340_1p0_radio_core_40M);
 	} else if (AR_SREV_9485_11(ah)) {
 		/* mac */
-		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
-				ar9485_1_1_mac_core,
-				ARRAY_SIZE(ar9485_1_1_mac_core), 2);
+				ar9485_1_1_mac_core);
 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
-				ar9485_1_1_mac_postamble,
-				ARRAY_SIZE(ar9485_1_1_mac_postamble), 5);
+				ar9485_1_1_mac_postamble);
 
 		/* bb */
-		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], ar9485_1_1,
-				ARRAY_SIZE(ar9485_1_1), 2);
+		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], ar9485_1_1);
 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
-				ar9485_1_1_baseband_core,
-				ARRAY_SIZE(ar9485_1_1_baseband_core), 2);
+				ar9485_1_1_baseband_core);
 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
-				ar9485_1_1_baseband_postamble,
-				ARRAY_SIZE(ar9485_1_1_baseband_postamble), 5);
+				ar9485_1_1_baseband_postamble);
 
 		/* radio */
-		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
-				ar9485_1_1_radio_core,
-				ARRAY_SIZE(ar9485_1_1_radio_core), 2);
+				ar9485_1_1_radio_core);
 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
-				ar9485_1_1_radio_postamble,
-				ARRAY_SIZE(ar9485_1_1_radio_postamble), 2);
+				ar9485_1_1_radio_postamble);
 
 		/* soc */
 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
-				ar9485_1_1_soc_preamble,
-				ARRAY_SIZE(ar9485_1_1_soc_preamble), 2);
-		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
-		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], NULL, 0, 0);
+				ar9485_1_1_soc_preamble);
 
 		/* rx/tx gain */
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-				ar9485Common_wo_xlna_rx_gain_1_1,
-				ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), 2);
+				ar9485Common_wo_xlna_rx_gain_1_1);
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-				ar9485_modes_lowest_ob_db_tx_gain_1_1,
-				ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
-				5);
+				ar9485_modes_lowest_ob_db_tx_gain_1_1);
 
 		/* Load PCIE SERDES settings from INI */
 
 		/* Awake Setting */
 
 		INIT_INI_ARRAY(&ah->iniPcieSerdes,
-				ar9485_1_1_pcie_phy_clkreq_disable_L1,
-				ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
-				2);
+				ar9485_1_1_pcie_phy_clkreq_disable_L1);
 
 		/* Sleep Setting */
 
 		INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
-				ar9485_1_1_pcie_phy_clkreq_disable_L1,
-				ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
-				2);
+				ar9485_1_1_pcie_phy_clkreq_disable_L1);
 	} else if (AR_SREV_9462_20(ah)) {
 
-		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
-		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_2p0_mac_core,
-				ARRAY_SIZE(ar9462_2p0_mac_core), 2);
+		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_2p0_mac_core);
 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
-				ar9462_2p0_mac_postamble,
-				ARRAY_SIZE(ar9462_2p0_mac_postamble), 5);
+				ar9462_2p0_mac_postamble);
 
-		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
-				ar9462_2p0_baseband_core,
-				ARRAY_SIZE(ar9462_2p0_baseband_core), 2);
+				ar9462_2p0_baseband_core);
 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
-				ar9462_2p0_baseband_postamble,
-				ARRAY_SIZE(ar9462_2p0_baseband_postamble), 5);
+				ar9462_2p0_baseband_postamble);
 
-		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
-				ar9462_2p0_radio_core,
-				ARRAY_SIZE(ar9462_2p0_radio_core), 2);
+				ar9462_2p0_radio_core);
 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
-				ar9462_2p0_radio_postamble,
-				ARRAY_SIZE(ar9462_2p0_radio_postamble), 5);
+				ar9462_2p0_radio_postamble);
 		INIT_INI_ARRAY(&ah->ini_radio_post_sys2ant,
-				ar9462_2p0_radio_postamble_sys2ant,
-				ARRAY_SIZE(ar9462_2p0_radio_postamble_sys2ant),
-				5);
+				ar9462_2p0_radio_postamble_sys2ant);
 
 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
-				ar9462_2p0_soc_preamble,
-				ARRAY_SIZE(ar9462_2p0_soc_preamble), 2);
-		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
+				ar9462_2p0_soc_preamble);
 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
-				ar9462_2p0_soc_postamble,
-				ARRAY_SIZE(ar9462_2p0_soc_postamble), 5);
+				ar9462_2p0_soc_postamble);
 
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-				ar9462_common_rx_gain_table_2p0,
-				ARRAY_SIZE(ar9462_common_rx_gain_table_2p0), 2);
+				ar9462_common_rx_gain_table_2p0);
 
 		/* Awake -> Sleep Setting */
 		INIT_INI_ARRAY(&ah->iniPcieSerdes,
-				PCIE_PLL_ON_CREQ_DIS_L1_2P0,
-				ARRAY_SIZE(PCIE_PLL_ON_CREQ_DIS_L1_2P0),
-				2);
+				PCIE_PLL_ON_CREQ_DIS_L1_2P0);
 		/* Sleep -> Awake Setting */
 		INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
-				PCIE_PLL_ON_CREQ_DIS_L1_2P0,
-				ARRAY_SIZE(PCIE_PLL_ON_CREQ_DIS_L1_2P0),
-				2);
+				PCIE_PLL_ON_CREQ_DIS_L1_2P0);
 
 		/* Fast clock modal settings */
 		INIT_INI_ARRAY(&ah->iniModesFastClock,
-				ar9462_modes_fast_clock_2p0,
-				ARRAY_SIZE(ar9462_modes_fast_clock_2p0), 3);
+				ar9462_modes_fast_clock_2p0);
 
 		INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
-				AR9462_BB_CTX_COEFJ(2p0),
-				ARRAY_SIZE(AR9462_BB_CTX_COEFJ(2p0)), 2);
+				AR9462_BB_CTX_COEFJ(2p0));
 
-		INIT_INI_ARRAY(&ah->ini_japan2484, AR9462_BBC_TXIFR_COEFFJ,
-				ARRAY_SIZE(AR9462_BBC_TXIFR_COEFFJ), 2);
+		INIT_INI_ARRAY(&ah->ini_japan2484, AR9462_BBC_TXIFR_COEFFJ);
 	} else if (AR_SREV_9550(ah)) {
 		/* mac */
-		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
-				ar955x_1p0_mac_core,
-				ARRAY_SIZE(ar955x_1p0_mac_core), 2);
+				ar955x_1p0_mac_core);
 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
-				ar955x_1p0_mac_postamble,
-				ARRAY_SIZE(ar955x_1p0_mac_postamble), 5);
+				ar955x_1p0_mac_postamble);
 
 		/* bb */
-		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
-				ar955x_1p0_baseband_core,
-				ARRAY_SIZE(ar955x_1p0_baseband_core), 2);
+				ar955x_1p0_baseband_core);
 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
-				ar955x_1p0_baseband_postamble,
-				ARRAY_SIZE(ar955x_1p0_baseband_postamble), 5);
+				ar955x_1p0_baseband_postamble);
 
 		/* radio */
-		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
-				ar955x_1p0_radio_core,
-				ARRAY_SIZE(ar955x_1p0_radio_core), 2);
+				ar955x_1p0_radio_core);
 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
-				ar955x_1p0_radio_postamble,
-				ARRAY_SIZE(ar955x_1p0_radio_postamble), 5);
+				ar955x_1p0_radio_postamble);
 
 		/* soc */
 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
-				ar955x_1p0_soc_preamble,
-				ARRAY_SIZE(ar955x_1p0_soc_preamble), 2);
-		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
+				ar955x_1p0_soc_preamble);
 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
-				ar955x_1p0_soc_postamble,
-				ARRAY_SIZE(ar955x_1p0_soc_postamble), 5);
+				ar955x_1p0_soc_postamble);
 
 		/* rx/tx gain */
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-			ar955x_1p0_common_wo_xlna_rx_gain_table,
-			ARRAY_SIZE(ar955x_1p0_common_wo_xlna_rx_gain_table),
-			2);
+			ar955x_1p0_common_wo_xlna_rx_gain_table);
 		INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds,
-			ar955x_1p0_common_wo_xlna_rx_gain_bounds,
-			ARRAY_SIZE(ar955x_1p0_common_wo_xlna_rx_gain_bounds),
-			5);
+			ar955x_1p0_common_wo_xlna_rx_gain_bounds);
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-				ar955x_1p0_modes_xpa_tx_gain_table,
-				ARRAY_SIZE(ar955x_1p0_modes_xpa_tx_gain_table),
-				9);
+				ar955x_1p0_modes_xpa_tx_gain_table);
 
 		/* Fast clock modal settings */
 		INIT_INI_ARRAY(&ah->iniModesFastClock,
-				ar955x_1p0_modes_fast_clock,
-				ARRAY_SIZE(ar955x_1p0_modes_fast_clock), 3);
+				ar955x_1p0_modes_fast_clock);
 	} else if (AR_SREV_9580(ah)) {
 		/* mac */
-		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
-				ar9580_1p0_mac_core,
-				ARRAY_SIZE(ar9580_1p0_mac_core), 2);
+				ar9580_1p0_mac_core);
 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
-				ar9580_1p0_mac_postamble,
-				ARRAY_SIZE(ar9580_1p0_mac_postamble), 5);
+				ar9580_1p0_mac_postamble);
 
 		/* bb */
-		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
-				ar9580_1p0_baseband_core,
-				ARRAY_SIZE(ar9580_1p0_baseband_core), 2);
+				ar9580_1p0_baseband_core);
 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
-				ar9580_1p0_baseband_postamble,
-				ARRAY_SIZE(ar9580_1p0_baseband_postamble), 5);
+				ar9580_1p0_baseband_postamble);
 
 		/* radio */
-		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
-				ar9580_1p0_radio_core,
-				ARRAY_SIZE(ar9580_1p0_radio_core), 2);
+				ar9580_1p0_radio_core);
 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
-				ar9580_1p0_radio_postamble,
-				ARRAY_SIZE(ar9580_1p0_radio_postamble), 5);
+				ar9580_1p0_radio_postamble);
 
 		/* soc */
 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
-				ar9580_1p0_soc_preamble,
-				ARRAY_SIZE(ar9580_1p0_soc_preamble), 2);
-		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
+				ar9580_1p0_soc_preamble);
 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
-				ar9580_1p0_soc_postamble,
-				ARRAY_SIZE(ar9580_1p0_soc_postamble), 5);
+				ar9580_1p0_soc_postamble);
 
 		/* rx/tx gain */
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-				ar9580_1p0_rx_gain_table,
-				ARRAY_SIZE(ar9580_1p0_rx_gain_table), 2);
+				ar9580_1p0_rx_gain_table);
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-				ar9580_1p0_low_ob_db_tx_gain_table,
-				ARRAY_SIZE(ar9580_1p0_low_ob_db_tx_gain_table),
-				5);
+				ar9580_1p0_low_ob_db_tx_gain_table);
 
 		INIT_INI_ARRAY(&ah->iniModesFastClock,
-				ar9580_1p0_modes_fast_clock,
-				ARRAY_SIZE(ar9580_1p0_modes_fast_clock),
-				3);
+				ar9580_1p0_modes_fast_clock);
 	} else {
 		/* mac */
-		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
-				ar9300_2p2_mac_core,
-				ARRAY_SIZE(ar9300_2p2_mac_core), 2);
+				ar9300_2p2_mac_core);
 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
-				ar9300_2p2_mac_postamble,
-				ARRAY_SIZE(ar9300_2p2_mac_postamble), 5);
+				ar9300_2p2_mac_postamble);
 
 		/* bb */
-		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
-				ar9300_2p2_baseband_core,
-				ARRAY_SIZE(ar9300_2p2_baseband_core), 2);
+				ar9300_2p2_baseband_core);
 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
-				ar9300_2p2_baseband_postamble,
-				ARRAY_SIZE(ar9300_2p2_baseband_postamble), 5);
+				ar9300_2p2_baseband_postamble);
 
 		/* radio */
-		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
-				ar9300_2p2_radio_core,
-				ARRAY_SIZE(ar9300_2p2_radio_core), 2);
+				ar9300_2p2_radio_core);
 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
-				ar9300_2p2_radio_postamble,
-				ARRAY_SIZE(ar9300_2p2_radio_postamble), 5);
+				ar9300_2p2_radio_postamble);
 
 		/* soc */
 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
-				ar9300_2p2_soc_preamble,
-				ARRAY_SIZE(ar9300_2p2_soc_preamble), 2);
-		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
+				ar9300_2p2_soc_preamble);
 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
-				ar9300_2p2_soc_postamble,
-				ARRAY_SIZE(ar9300_2p2_soc_postamble), 5);
+				ar9300_2p2_soc_postamble);
 
 		/* rx/tx gain */
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-				ar9300Common_rx_gain_table_2p2,
-				ARRAY_SIZE(ar9300Common_rx_gain_table_2p2), 2);
+				ar9300Common_rx_gain_table_2p2);
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-				ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
-				ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
-				5);
+				ar9300Modes_lowest_ob_db_tx_gain_table_2p2);
 
 		/* Load PCIE SERDES settings from INI */
 
 		/* Awake Setting */
 
 		INIT_INI_ARRAY(&ah->iniPcieSerdes,
-				ar9300PciePhy_pll_on_clkreq_disable_L1_2p2,
-				ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2),
-				2);
+				ar9300PciePhy_pll_on_clkreq_disable_L1_2p2);
 
 		/* Sleep Setting */
 
 		INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
-				ar9300PciePhy_pll_on_clkreq_disable_L1_2p2,
-				ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2),
-				2);
+				ar9300PciePhy_pll_on_clkreq_disable_L1_2p2);
 
 		/* Fast clock modal settings */
 		INIT_INI_ARRAY(&ah->iniModesFastClock,
-				ar9300Modes_fast_clock_2p2,
-				ARRAY_SIZE(ar9300Modes_fast_clock_2p2),
-				3);
+				ar9300Modes_fast_clock_2p2);
 	}
 }
 
@@ -507,170 +355,110 @@ static void ar9003_tx_gain_table_mode0(struct ath_hw *ah)
 {
 	if (AR_SREV_9330_12(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9331_modes_lowest_ob_db_tx_gain_1p2,
-			ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p2),
-			5);
+			ar9331_modes_lowest_ob_db_tx_gain_1p2);
 	else if (AR_SREV_9330_11(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9331_modes_lowest_ob_db_tx_gain_1p1,
-			ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p1),
-			5);
+			ar9331_modes_lowest_ob_db_tx_gain_1p1);
 	else if (AR_SREV_9340(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
-			ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
-			5);
+			ar9340Modes_lowest_ob_db_tx_gain_table_1p0);
 	else if (AR_SREV_9485_11(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9485_modes_lowest_ob_db_tx_gain_1_1,
-			ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
-			5);
+			ar9485_modes_lowest_ob_db_tx_gain_1_1);
 	else if (AR_SREV_9550(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar955x_1p0_modes_xpa_tx_gain_table,
-			ARRAY_SIZE(ar955x_1p0_modes_xpa_tx_gain_table),
-			9);
+			ar955x_1p0_modes_xpa_tx_gain_table);
 	else if (AR_SREV_9580(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9580_1p0_lowest_ob_db_tx_gain_table,
-			ARRAY_SIZE(ar9580_1p0_lowest_ob_db_tx_gain_table),
-			5);
+			ar9580_1p0_lowest_ob_db_tx_gain_table);
 	else if (AR_SREV_9462_20(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9462_modes_low_ob_db_tx_gain_table_2p0,
-			ARRAY_SIZE(ar9462_modes_low_ob_db_tx_gain_table_2p0),
-			5);
+			ar9462_modes_low_ob_db_tx_gain_table_2p0);
 	else
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
-			ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
-			5);
+			ar9300Modes_lowest_ob_db_tx_gain_table_2p2);
 }
 
 static void ar9003_tx_gain_table_mode1(struct ath_hw *ah)
 {
 	if (AR_SREV_9330_12(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9331_modes_high_ob_db_tx_gain_1p2,
-			ARRAY_SIZE(ar9331_modes_high_ob_db_tx_gain_1p2),
-			5);
+			ar9331_modes_high_ob_db_tx_gain_1p2);
 	else if (AR_SREV_9330_11(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9331_modes_high_ob_db_tx_gain_1p1,
-			ARRAY_SIZE(ar9331_modes_high_ob_db_tx_gain_1p1),
-			5);
+			ar9331_modes_high_ob_db_tx_gain_1p1);
 	else if (AR_SREV_9340(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9340Modes_high_ob_db_tx_gain_table_1p0,
-			ARRAY_SIZE(ar9340Modes_high_ob_db_tx_gain_table_1p0),
-			5);
+			ar9340Modes_high_ob_db_tx_gain_table_1p0);
 	else if (AR_SREV_9485_11(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9485Modes_high_ob_db_tx_gain_1_1,
-			ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1),
-			5);
+			ar9485Modes_high_ob_db_tx_gain_1_1);
 	else if (AR_SREV_9580(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9580_1p0_high_ob_db_tx_gain_table,
-			ARRAY_SIZE(ar9580_1p0_high_ob_db_tx_gain_table),
-			5);
+			ar9580_1p0_high_ob_db_tx_gain_table);
 	else if (AR_SREV_9550(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar955x_1p0_modes_no_xpa_tx_gain_table,
-			ARRAY_SIZE(ar955x_1p0_modes_no_xpa_tx_gain_table),
-			9);
+			ar955x_1p0_modes_no_xpa_tx_gain_table);
 	else if (AR_SREV_9462_20(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9462_modes_high_ob_db_tx_gain_table_2p0,
-			ARRAY_SIZE(ar9462_modes_high_ob_db_tx_gain_table_2p0),
-			5);
+			ar9462_modes_high_ob_db_tx_gain_table_2p0);
 	else
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9300Modes_high_ob_db_tx_gain_table_2p2,
-			ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2),
-			5);
+			ar9300Modes_high_ob_db_tx_gain_table_2p2);
 }
 
 static void ar9003_tx_gain_table_mode2(struct ath_hw *ah)
 {
 	if (AR_SREV_9330_12(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9331_modes_low_ob_db_tx_gain_1p2,
-			ARRAY_SIZE(ar9331_modes_low_ob_db_tx_gain_1p2),
-			5);
+			ar9331_modes_low_ob_db_tx_gain_1p2);
 	else if (AR_SREV_9330_11(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9331_modes_low_ob_db_tx_gain_1p1,
-			ARRAY_SIZE(ar9331_modes_low_ob_db_tx_gain_1p1),
-			5);
+			ar9331_modes_low_ob_db_tx_gain_1p1);
 	else if (AR_SREV_9340(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9340Modes_low_ob_db_tx_gain_table_1p0,
-			ARRAY_SIZE(ar9340Modes_low_ob_db_tx_gain_table_1p0),
-			5);
+			ar9340Modes_low_ob_db_tx_gain_table_1p0);
 	else if (AR_SREV_9485_11(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9485Modes_low_ob_db_tx_gain_1_1,
-			ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1),
-			5);
+			ar9485Modes_low_ob_db_tx_gain_1_1);
 	else if (AR_SREV_9580(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9580_1p0_low_ob_db_tx_gain_table,
-			ARRAY_SIZE(ar9580_1p0_low_ob_db_tx_gain_table),
-			5);
+			ar9580_1p0_low_ob_db_tx_gain_table);
 	else
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9300Modes_low_ob_db_tx_gain_table_2p2,
-			ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2),
-			5);
+			ar9300Modes_low_ob_db_tx_gain_table_2p2);
 }
 
 static void ar9003_tx_gain_table_mode3(struct ath_hw *ah)
 {
 	if (AR_SREV_9330_12(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9331_modes_high_power_tx_gain_1p2,
-			ARRAY_SIZE(ar9331_modes_high_power_tx_gain_1p2),
-			5);
+			ar9331_modes_high_power_tx_gain_1p2);
 	else if (AR_SREV_9330_11(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9331_modes_high_power_tx_gain_1p1,
-			ARRAY_SIZE(ar9331_modes_high_power_tx_gain_1p1),
-			5);
+			ar9331_modes_high_power_tx_gain_1p1);
 	else if (AR_SREV_9340(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9340Modes_high_power_tx_gain_table_1p0,
-			ARRAY_SIZE(ar9340Modes_high_power_tx_gain_table_1p0),
-			5);
+			ar9340Modes_high_power_tx_gain_table_1p0);
 	else if (AR_SREV_9485_11(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9485Modes_high_power_tx_gain_1_1,
-			ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1),
-			5);
+			ar9485Modes_high_power_tx_gain_1_1);
 	else if (AR_SREV_9580(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9580_1p0_high_power_tx_gain_table,
-			ARRAY_SIZE(ar9580_1p0_high_power_tx_gain_table),
-			5);
+			ar9580_1p0_high_power_tx_gain_table);
 	else
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9300Modes_high_power_tx_gain_table_2p2,
-			ARRAY_SIZE(ar9300Modes_high_power_tx_gain_table_2p2),
-			5);
+			ar9300Modes_high_power_tx_gain_table_2p2);
 }
 
 static void ar9003_tx_gain_table_mode4(struct ath_hw *ah)
 {
 	if (AR_SREV_9340(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9340Modes_mixed_ob_db_tx_gain_table_1p0,
-			ARRAY_SIZE(ar9340Modes_mixed_ob_db_tx_gain_table_1p0),
-			5);
+			ar9340Modes_mixed_ob_db_tx_gain_table_1p0);
 	else if (AR_SREV_9580(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-			ar9580_1p0_mixed_ob_db_tx_gain_table,
-			ARRAY_SIZE(ar9580_1p0_mixed_ob_db_tx_gain_table),
-			5);
+			ar9580_1p0_mixed_ob_db_tx_gain_table);
 }
 
 static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
@@ -699,104 +487,67 @@ static void ar9003_rx_gain_table_mode0(struct ath_hw *ah)
 {
 	if (AR_SREV_9330_12(ah))
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-				ar9331_common_rx_gain_1p2,
-				ARRAY_SIZE(ar9331_common_rx_gain_1p2),
-				2);
+				ar9331_common_rx_gain_1p2);
 	else if (AR_SREV_9330_11(ah))
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-				ar9331_common_rx_gain_1p1,
-				ARRAY_SIZE(ar9331_common_rx_gain_1p1),
-				2);
+				ar9331_common_rx_gain_1p1);
 	else if (AR_SREV_9340(ah))
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-				ar9340Common_rx_gain_table_1p0,
-				ARRAY_SIZE(ar9340Common_rx_gain_table_1p0),
-				2);
+				ar9340Common_rx_gain_table_1p0);
 	else if (AR_SREV_9485_11(ah))
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-				ar9485Common_wo_xlna_rx_gain_1_1,
-				ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
-				2);
+				ar9485Common_wo_xlna_rx_gain_1_1);
 	else if (AR_SREV_9550(ah)) {
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-				ar955x_1p0_common_rx_gain_table,
-				ARRAY_SIZE(ar955x_1p0_common_rx_gain_table),
-				2);
+				ar955x_1p0_common_rx_gain_table);
 		INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds,
-				ar955x_1p0_common_rx_gain_bounds,
-				ARRAY_SIZE(ar955x_1p0_common_rx_gain_bounds),
-				5);
+				ar955x_1p0_common_rx_gain_bounds);
 	} else if (AR_SREV_9580(ah))
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-				ar9580_1p0_rx_gain_table,
-				ARRAY_SIZE(ar9580_1p0_rx_gain_table),
-				2);
+				ar9580_1p0_rx_gain_table);
 	else if (AR_SREV_9462_20(ah))
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-				ar9462_common_rx_gain_table_2p0,
-				ARRAY_SIZE(ar9462_common_rx_gain_table_2p0),
-				2);
+				ar9462_common_rx_gain_table_2p0);
 	else
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-				ar9300Common_rx_gain_table_2p2,
-				ARRAY_SIZE(ar9300Common_rx_gain_table_2p2),
-				2);
+				ar9300Common_rx_gain_table_2p2);
 }
 
 static void ar9003_rx_gain_table_mode1(struct ath_hw *ah)
 {
 	if (AR_SREV_9330_12(ah))
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-			ar9331_common_wo_xlna_rx_gain_1p2,
-			ARRAY_SIZE(ar9331_common_wo_xlna_rx_gain_1p2),
-			2);
+			ar9331_common_wo_xlna_rx_gain_1p2);
 	else if (AR_SREV_9330_11(ah))
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-			ar9331_common_wo_xlna_rx_gain_1p1,
-			ARRAY_SIZE(ar9331_common_wo_xlna_rx_gain_1p1),
-			2);
+			ar9331_common_wo_xlna_rx_gain_1p1);
 	else if (AR_SREV_9340(ah))
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-			ar9340Common_wo_xlna_rx_gain_table_1p0,
-			ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0),
-			2);
+			ar9340Common_wo_xlna_rx_gain_table_1p0);
 	else if (AR_SREV_9485_11(ah))
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-			ar9485Common_wo_xlna_rx_gain_1_1,
-			ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
-			2);
+			ar9485Common_wo_xlna_rx_gain_1_1);
 	else if (AR_SREV_9462_20(ah))
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-			ar9462_common_wo_xlna_rx_gain_table_2p0,
-			ARRAY_SIZE(ar9462_common_wo_xlna_rx_gain_table_2p0),
-			2);
+			ar9462_common_wo_xlna_rx_gain_table_2p0);
 	else if (AR_SREV_9550(ah)) {
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-			ar955x_1p0_common_wo_xlna_rx_gain_table,
-			ARRAY_SIZE(ar955x_1p0_common_wo_xlna_rx_gain_table),
-			2);
+			ar955x_1p0_common_wo_xlna_rx_gain_table);
 		INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds,
-			ar955x_1p0_common_wo_xlna_rx_gain_bounds,
-			ARRAY_SIZE(ar955x_1p0_common_wo_xlna_rx_gain_bounds),
-			5);
+			ar955x_1p0_common_wo_xlna_rx_gain_bounds);
 	} else if (AR_SREV_9580(ah))
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-			ar9580_1p0_wo_xlna_rx_gain_table,
-			ARRAY_SIZE(ar9580_1p0_wo_xlna_rx_gain_table),
-			2);
+			ar9580_1p0_wo_xlna_rx_gain_table);
 	else
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-			ar9300Common_wo_xlna_rx_gain_table_2p2,
-			ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2),
-			2);
+			ar9300Common_wo_xlna_rx_gain_table_2p2);
 }
 
 static void ar9003_rx_gain_table_mode2(struct ath_hw *ah)
 {
 	if (AR_SREV_9462_20(ah))
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-			       ar9462_common_mixed_rx_gain_table_2p0,
-			       ARRAY_SIZE(ar9462_common_mixed_rx_gain_table_2p0), 2);
+			       ar9462_common_mixed_rx_gain_table_2p0);
 }
 
 static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
index 3b33996..1060c19 100644
--- a/drivers/net/wireless/ath/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -30,10 +30,10 @@ struct ar5416IniArray {
 	u32 ia_columns;
 };
 
-#define INIT_INI_ARRAY(iniarray, array, rows, columns) do {	\
+#define INIT_INI_ARRAY(iniarray, array) do {	\
 		(iniarray)->ia_array = (u32 *)(array);		\
-		(iniarray)->ia_rows = (rows);			\
-		(iniarray)->ia_columns = (columns);		\
+		(iniarray)->ia_rows = ARRAY_SIZE(array);	\
+		(iniarray)->ia_columns = ARRAY_SIZE(array[0]);	\
 	} while (0)
 
 #define INI_RA(iniarray, row, column) \
-- 
1.7.3.2


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

* [PATCH v2 06/12] ath9k/ath9k_htc: fix txop limit handling
  2012-07-12 15:04       ` [PATCH v2 05/12] ath9k_hw: remove redundant arguments to INIT_INI_ARRAY Felix Fietkau
@ 2012-07-12 15:04         ` Felix Fietkau
  2012-07-12 15:04           ` [PATCH v2 07/12] ath9k: make per-WMM-AC queue sizes configurable via debugfs Felix Fietkau
  2012-07-15 17:53         ` [PATCH v2 05/12] ath9k_hw: remove redundant arguments to INIT_INI_ARRAY Felix Fietkau
  1 sibling, 1 reply; 23+ messages in thread
From: Felix Fietkau @ 2012-07-12 15:04 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, mcgrof

In all those years apparently nobody noticed that the txop limit programmed
into the chip was off by a factor of 32 (!), probably because the VI and VO
queues aren't used that much aside from mgmt frames on VO.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/htc_drv_main.c |    2 +-
 drivers/net/wireless/ath/ath9k/main.c         |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 374c32e..fe2bfff 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -1351,7 +1351,7 @@ static int ath9k_htc_conf_tx(struct ieee80211_hw *hw,
 	qi.tqi_aifs = params->aifs;
 	qi.tqi_cwmin = params->cw_min;
 	qi.tqi_cwmax = params->cw_max;
-	qi.tqi_burstTime = params->txop;
+	qi.tqi_burstTime = params->txop * 32;
 
 	qnum = get_hw_qnum(queue, priv->hwq_map);
 
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 724f415..aac213b 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1377,7 +1377,7 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw,
 	qi.tqi_aifs = params->aifs;
 	qi.tqi_cwmin = params->cw_min;
 	qi.tqi_cwmax = params->cw_max;
-	qi.tqi_burstTime = params->txop;
+	qi.tqi_burstTime = params->txop * 32;
 
 	ath_dbg(common, CONFIG,
 		"Configure tx [queue/halq] [%d/%d], aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
-- 
1.7.3.2


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

* [PATCH v2 07/12] ath9k: make per-WMM-AC queue sizes configurable via debugfs
  2012-07-12 15:04         ` [PATCH v2 06/12] ath9k/ath9k_htc: fix txop limit handling Felix Fietkau
@ 2012-07-12 15:04           ` Felix Fietkau
  2012-07-12 15:04             ` [PATCH v2 08/12] ath9k: fix aggregate size limit based on queue TXOP limit Felix Fietkau
  0 siblings, 1 reply; 23+ messages in thread
From: Felix Fietkau @ 2012-07-12 15:04 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, mcgrof

Prepare for using different queue size defaults for each AC.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ath9k.h |    1 +
 drivers/net/wireless/ath/ath9k/debug.c |    8 ++++++++
 drivers/net/wireless/ath/ath9k/init.c  |    1 +
 drivers/net/wireless/ath/ath9k/xmit.c  |    6 ++++--
 4 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 79840d6..10568c0 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -297,6 +297,7 @@ struct ath_tx {
 	struct ath_txq txq[ATH9K_NUM_TX_QUEUES];
 	struct ath_descdma txdma;
 	struct ath_txq *txq_map[WME_NUM_AC];
+	u32 txq_max_pending[WME_NUM_AC];
 };
 
 struct ath_rx_edma {
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 5c3192f..b9ea067 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1556,6 +1556,14 @@ int ath9k_init_debug(struct ath_hw *ah)
 			    &fops_interrupt);
 	debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc,
 			    &fops_xmit);
+	debugfs_create_u32("qlen_bk", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
+			   &sc->tx.txq_max_pending[WME_AC_BK]);
+	debugfs_create_u32("qlen_be", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
+			   &sc->tx.txq_max_pending[WME_AC_BE]);
+	debugfs_create_u32("qlen_vi", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
+			   &sc->tx.txq_max_pending[WME_AC_VI]);
+	debugfs_create_u32("qlen_vo", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
+			   &sc->tx.txq_max_pending[WME_AC_VO]);
 	debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy, sc,
 			    &fops_stations);
 	debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc,
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 9dfce1a..f1cc38a 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -434,6 +434,7 @@ static int ath9k_init_queues(struct ath_softc *sc)
 	for (i = 0; i < WME_NUM_AC; i++) {
 		sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i);
 		sc->tx.txq_map[i]->mac80211_qnum = i;
+		sc->tx.txq_max_pending[i] = ATH_MAX_QDEPTH;
 	}
 	return 0;
 }
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index cafb4a0..571d773 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1988,7 +1988,8 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
 
 	ath_txq_lock(sc, txq);
 	if (txq == sc->tx.txq_map[q] &&
-	    ++txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) {
+	    ++txq->pending_frames > sc->tx.txq_max_pending[q] &&
+	    !txq->stopped) {
 		ieee80211_stop_queue(sc->hw, q);
 		txq->stopped = true;
 	}
@@ -2047,7 +2048,8 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
 		if (WARN_ON(--txq->pending_frames < 0))
 			txq->pending_frames = 0;
 
-		if (txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) {
+		if (txq->stopped &&
+		    txq->pending_frames < sc->tx.txq_max_pending[q]) {
 			ieee80211_wake_queue(sc->hw, q);
 			txq->stopped = false;
 		}
-- 
1.7.3.2


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

* [PATCH v2 08/12] ath9k: fix aggregate size limit based on queue TXOP limit
  2012-07-12 15:04           ` [PATCH v2 07/12] ath9k: make per-WMM-AC queue sizes configurable via debugfs Felix Fietkau
@ 2012-07-12 15:04             ` Felix Fietkau
  2012-07-12 15:04               ` [PATCH v2 09/12] ath9k_hw: apply XPA timing control values from EEPROM Felix Fietkau
  2012-07-14  6:04               ` [PATCH v2 08/12] ath9k: fix aggregate size limit based on queue TXOP limit Sujith Manoharan
  0 siblings, 2 replies; 23+ messages in thread
From: Felix Fietkau @ 2012-07-12 15:04 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, mcgrof

If the aggregate size exceeds the TXOP limit, it leads to lots of unnecessary
hardware and software retries.

The previous 4ms frame limit table was completely undocumented, the commit
that updated it only vaguely referenced and equation from the standard,
but I've been unable to replicate its results.

Fix this by using a formula based on the code in ath_pkt_duration, which is
more likely to be correct for this case.

Reported-by: Dave Täht <dave.taht@gmail.com>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ath9k.h |    2 +
 drivers/net/wireless/ath/ath9k/main.c  |    1 +
 drivers/net/wireless/ath/ath9k/xmit.c  |   73 +++++++++++++++++++-------------
 3 files changed, 46 insertions(+), 30 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 10568c0..6f74f74 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -298,6 +298,7 @@ struct ath_tx {
 	struct ath_descdma txdma;
 	struct ath_txq *txq_map[WME_NUM_AC];
 	u32 txq_max_pending[WME_NUM_AC];
+	u16 max_aggr_framelen[WME_NUM_AC][4][32];
 };
 
 struct ath_rx_edma {
@@ -342,6 +343,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs);
 void ath_tx_cleanup(struct ath_softc *sc);
 int ath_txq_update(struct ath_softc *sc, int qnum,
 		   struct ath9k_tx_queue_info *q);
+void ath_update_max_aggr_framelen(struct ath_softc *sc, int queue, int txop);
 int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
 		 struct ath_tx_control *txctl);
 void ath_tx_tasklet(struct ath_softc *sc);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index aac213b..9d75c88 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1384,6 +1384,7 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw,
 		queue, txq->axq_qnum, params->aifs, params->cw_min,
 		params->cw_max, params->txop);
 
+	ath_update_max_aggr_framelen(sc, queue, qi.tqi_burstTime);
 	ret = ath_txq_update(sc, txq->axq_qnum, &qi);
 	if (ret)
 		ath_err(common, "TXQ Update failed\n");
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 571d773..0a735bd 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -29,6 +29,8 @@
 #define HT_LTF(_ns)             (4 * (_ns))
 #define SYMBOL_TIME(_ns)        ((_ns) << 2) /* ns * 4 us */
 #define SYMBOL_TIME_HALFGI(_ns) (((_ns) * 18 + 4) / 5)  /* ns * 3.6 us */
+#define TIME_SYMBOLS(t)         ((t) >> 2)
+#define TIME_SYMBOLS_HALFGI(t)  (((t) * 5 - 4) / 18)
 #define NUM_SYMBOLS_PER_USEC(_usec) (_usec >> 2)
 #define NUM_SYMBOLS_PER_USEC_HALFGI(_usec) (((_usec*5)-4)/18)
 
@@ -74,33 +76,6 @@ enum {
 	MCS_HT40_SGI,
 };
 
-static int ath_max_4ms_framelen[4][32] = {
-	[MCS_HT20] = {
-		3212,  6432,  9648,  12864,  19300,  25736,  28952,  32172,
-		6424,  12852, 19280, 25708,  38568,  51424,  57852,  64280,
-		9628,  19260, 28896, 38528,  57792,  65532,  65532,  65532,
-		12828, 25656, 38488, 51320,  65532,  65532,  65532,  65532,
-	},
-	[MCS_HT20_SGI] = {
-		3572,  7144,  10720,  14296,  21444,  28596,  32172,  35744,
-		7140,  14284, 21428,  28568,  42856,  57144,  64288,  65532,
-		10700, 21408, 32112,  42816,  64228,  65532,  65532,  65532,
-		14256, 28516, 42780,  57040,  65532,  65532,  65532,  65532,
-	},
-	[MCS_HT40] = {
-		6680,  13360,  20044,  26724,  40092,  53456,  60140,  65532,
-		13348, 26700,  40052,  53400,  65532,  65532,  65532,  65532,
-		20004, 40008,  60016,  65532,  65532,  65532,  65532,  65532,
-		26644, 53292,  65532,  65532,  65532,  65532,  65532,  65532,
-	},
-	[MCS_HT40_SGI] = {
-		7420,  14844,  22272,  29696,  44544,  59396,  65532,  65532,
-		14832, 29668,  44504,  59340,  65532,  65532,  65532,  65532,
-		22232, 44464,  65532,  65532,  65532,  65532,  65532,  65532,
-		29616, 59232,  65532,  65532,  65532,  65532,  65532,  65532,
-	}
-};
-
 /*********************/
 /* Aggregation logic */
 /*********************/
@@ -650,6 +625,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
 	struct ieee80211_tx_rate *rates;
 	u32 max_4ms_framelen, frmlen;
 	u16 aggr_limit, bt_aggr_limit, legacy = 0;
+	int q = tid->ac->txq->mac80211_qnum;
 	int i;
 
 	skb = bf->bf_mpdu;
@@ -658,8 +634,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
 
 	/*
 	 * Find the lowest frame length among the rate series that will have a
-	 * 4ms transmit duration.
-	 * TODO - TXOP limit needs to be considered.
+	 * 4ms (or TXOP limited) transmit duration.
 	 */
 	max_4ms_framelen = ATH_AMPDU_LIMIT_MAX;
 
@@ -682,7 +657,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
 		if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI)
 			modeidx++;
 
-		frmlen = ath_max_4ms_framelen[modeidx][rates[i].idx];
+		frmlen = sc->tx.max_aggr_framelen[q][modeidx][rates[i].idx];
 		max_4ms_framelen = min(max_4ms_framelen, frmlen);
 	}
 
@@ -929,6 +904,44 @@ static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, int pktlen,
 	return duration;
 }
 
+static int ath_max_framelen(int usec, int mcs, bool ht40, bool sgi)
+{
+	int streams = HT_RC_2_STREAMS(mcs);
+	int symbols, bits;
+	int bytes = 0;
+
+	symbols = sgi ? TIME_SYMBOLS_HALFGI(usec) : TIME_SYMBOLS(usec);
+	bits = symbols * bits_per_symbol[mcs % 8][ht40] * streams;
+	bits -= OFDM_PLCP_BITS;
+	bytes = bits / 8;
+	bytes -= L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
+	if (bytes > 65532)
+		bytes = 65532;
+
+	return bytes;
+}
+
+void ath_update_max_aggr_framelen(struct ath_softc *sc, int queue, int txop)
+{
+	u16 *cur_ht20, *cur_ht20_sgi, *cur_ht40, *cur_ht40_sgi;
+	int mcs;
+
+	/* 4ms is the default (and maximum) duration */
+	if (!txop || txop > 4096)
+		txop = 4096;
+
+	cur_ht20 = sc->tx.max_aggr_framelen[queue][MCS_HT20];
+	cur_ht20_sgi = sc->tx.max_aggr_framelen[queue][MCS_HT20_SGI];
+	cur_ht40 = sc->tx.max_aggr_framelen[queue][MCS_HT40];
+	cur_ht40_sgi = sc->tx.max_aggr_framelen[queue][MCS_HT40_SGI];
+	for (mcs = 0; mcs < 32; mcs++) {
+		cur_ht20[mcs] = ath_max_framelen(txop, mcs, false, false);
+		cur_ht20_sgi[mcs] = ath_max_framelen(txop, mcs, false, true);
+		cur_ht40[mcs] = ath_max_framelen(txop, mcs, true, false);
+		cur_ht40_sgi[mcs] = ath_max_framelen(txop, mcs, true, true);
+	}
+}
+
 static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
 			     struct ath_tx_info *info, int len)
 {
-- 
1.7.3.2


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

* [PATCH v2 09/12] ath9k_hw: apply XPA timing control values from EEPROM
  2012-07-12 15:04             ` [PATCH v2 08/12] ath9k: fix aggregate size limit based on queue TXOP limit Felix Fietkau
@ 2012-07-12 15:04               ` Felix Fietkau
  2012-07-12 15:04                 ` [PATCH v2 10/12] ath9k_hw: clean up AR9003 EEPROM code Felix Fietkau
  2012-07-14  6:04               ` [PATCH v2 08/12] ath9k: fix aggregate size limit based on queue TXOP limit Sujith Manoharan
  1 sibling, 1 reply; 23+ messages in thread
From: Felix Fietkau @ 2012-07-12 15:04 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, mcgrof

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.c |   23 +++++++++++++++++++++++
 1 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 3cddd78..86e4be4 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -3962,9 +3962,32 @@ static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, u16 freq)
 		      AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF, value);
 }
 
+static void ar9003_hw_xpa_timing_control_apply(struct ath_hw *ah, bool is_2ghz)
+{
+	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+	u8 xpa_ctl;
+
+	if (!(eep->baseEepHeader.featureEnable & 0x80))
+		return;
+
+	if (!AR_SREV_9300(ah) && !AR_SREV_9340(ah) && !AR_SREV_9580(ah))
+		return;
+
+	if (is_2ghz) {
+		xpa_ctl = eep->modalHeader2G.txFrameToXpaOn;
+		REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
+			      AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON, xpa_ctl);
+	} else {
+		xpa_ctl = eep->modalHeader5G.txFrameToXpaOn;
+		REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
+			      AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON, xpa_ctl);
+	}
+}
+
 static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
 					     struct ath9k_channel *chan)
 {
+	ar9003_hw_xpa_timing_control_apply(ah, IS_CHAN_2GHZ(chan));
 	ar9003_hw_xpa_bias_level_apply(ah, IS_CHAN_2GHZ(chan));
 	ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan));
 	ar9003_hw_drive_strength_apply(ah);
-- 
1.7.3.2


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

* [PATCH v2 10/12] ath9k_hw: clean up AR9003 EEPROM code
  2012-07-12 15:04               ` [PATCH v2 09/12] ath9k_hw: apply XPA timing control values from EEPROM Felix Fietkau
@ 2012-07-12 15:04                 ` Felix Fietkau
  2012-07-12 15:04                   ` [PATCH v2 11/12] ath9k_hw: apply XLNA bias settings from EEPROM Felix Fietkau
  0 siblings, 1 reply; 23+ messages in thread
From: Felix Fietkau @ 2012-07-12 15:04 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, mcgrof

- add an inline function for getting the correct modal EEPROM struct
- remove unnecessary indirection through ath9k_hw_ar9300_get_eeprom
  access the relevant fields directly

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.c |  116 +++++++-----------------
 drivers/net/wireless/ath/ath9k/eeprom.h        |    4 -
 2 files changed, 35 insertions(+), 85 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 86e4be4..4d90265 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -2971,14 +2971,6 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
 		return (pBase->txrxMask >> 4) & 0xf;
 	case EEP_RX_MASK:
 		return pBase->txrxMask & 0xf;
-	case EEP_DRIVE_STRENGTH:
-#define AR9300_EEP_BASE_DRIV_STRENGTH	0x1
-		return pBase->miscConfiguration & AR9300_EEP_BASE_DRIV_STRENGTH;
-	case EEP_INTERNAL_REGULATOR:
-		/* Bit 4 is internal regulator flag */
-		return (pBase->featureEnable & 0x10) >> 4;
-	case EEP_SWREG:
-		return le32_to_cpu(pBase->swreg);
 	case EEP_PAPRD:
 		return !!(pBase->featureEnable & BIT(5));
 	case EEP_CHAIN_MASK_REDUCE:
@@ -2989,8 +2981,6 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
 		return eep->modalHeader5G.antennaGain;
 	case EEP_ANTENNA_GAIN_2G:
 		return eep->modalHeader2G.antennaGain;
-	case EEP_QUICK_DROP:
-		return pBase->miscConfiguration & BIT(1);
 	default:
 		return 0;
 	}
@@ -3503,19 +3493,20 @@ static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
 	return 0;
 }
 
-static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, bool is2ghz)
+static struct ar9300_modal_eep_header *ar9003_modal_header(struct ath_hw *ah,
+							   bool is2ghz)
 {
 	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
 
 	if (is2ghz)
-		return eep->modalHeader2G.xpaBiasLvl;
+		return &eep->modalHeader2G;
 	else
-		return eep->modalHeader5G.xpaBiasLvl;
+		return &eep->modalHeader5G;
 }
 
 static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
 {
-	int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz);
+	int bias = ar9003_modal_header(ah, is2ghz)->xpaBiasLvl;
 
 	if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah))
 		REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
@@ -3531,57 +3522,26 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
 	}
 }
 
-static u16 ar9003_switch_com_spdt_get(struct ath_hw *ah, bool is_2ghz)
+static u16 ar9003_switch_com_spdt_get(struct ath_hw *ah, bool is2ghz)
 {
-	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
-	__le16 val;
-
-	if (is_2ghz)
-		val = eep->modalHeader2G.switchcomspdt;
-	else
-		val = eep->modalHeader5G.switchcomspdt;
-	return le16_to_cpu(val);
+	return le16_to_cpu(ar9003_modal_header(ah, is2ghz)->switchcomspdt);
 }
 
 
 static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
 {
-	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
-	__le32 val;
-
-	if (is2ghz)
-		val = eep->modalHeader2G.antCtrlCommon;
-	else
-		val = eep->modalHeader5G.antCtrlCommon;
-	return le32_to_cpu(val);
+	return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon);
 }
 
 static u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz)
 {
-	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
-	__le32 val;
-
-	if (is2ghz)
-		val = eep->modalHeader2G.antCtrlCommon2;
-	else
-		val = eep->modalHeader5G.antCtrlCommon2;
-	return le32_to_cpu(val);
+	return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon2);
 }
 
-static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah,
-					int chain,
+static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah, int chain,
 					bool is2ghz)
 {
-	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
-	__le16 val = 0;
-
-	if (chain >= 0 && chain < AR9300_MAX_CHAINS) {
-		if (is2ghz)
-			val = eep->modalHeader2G.antCtrlChain[chain];
-		else
-			val = eep->modalHeader5G.antCtrlChain[chain];
-	}
-
+	__le16 val = ar9003_modal_header(ah, is2ghz)->antCtrlChain[chain];
 	return le16_to_cpu(val);
 }
 
@@ -3691,11 +3651,12 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
 
 static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
 {
+	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+	struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
 	int drive_strength;
 	unsigned long reg;
 
-	drive_strength = ath9k_hw_ar9300_get_eeprom(ah, EEP_DRIVE_STRENGTH);
-
+	drive_strength = pBase->miscConfiguration & BIT(0);
 	if (!drive_strength)
 		return;
 
@@ -3825,11 +3786,11 @@ static bool is_pmu_set(struct ath_hw *ah, u32 pmu_reg, int pmu_set)
 
 void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
 {
-	int internal_regulator =
-		ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR);
+	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+	struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
 	u32 reg_val;
 
-	if (internal_regulator) {
+	if (pBase->featureEnable & BIT(4)) {
 		if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
 			int reg_pmu_set;
 
@@ -3873,11 +3834,11 @@ void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
 			if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
 				return;
 		} else if (AR_SREV_9462(ah)) {
-			reg_val = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG);
+			reg_val = le32_to_cpu(pBase->swreg);
 			REG_WRITE(ah, AR_PHY_PMU1, reg_val);
 		} else {
 			/* Internal regulator is ON. Write swreg register. */
-			reg_val = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG);
+			reg_val = le32_to_cpu(pBase->swreg);
 			REG_WRITE(ah, AR_RTC_REG_CONTROL1,
 				  REG_READ(ah, AR_RTC_REG_CONTROL1) &
 				  (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
@@ -3931,10 +3892,11 @@ static void ar9003_hw_apply_tuning_caps(struct ath_hw *ah)
 static void ar9003_hw_quick_drop_apply(struct ath_hw *ah, u16 freq)
 {
 	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
-	int quick_drop = ath9k_hw_ar9300_get_eeprom(ah, EEP_QUICK_DROP);
+	struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
+	int quick_drop;
 	s32 t[3], f[3] = {5180, 5500, 5785};
 
-	if (!quick_drop)
+	if (!(pBase->miscConfiguration & BIT(1)))
 		return;
 
 	if (freq < 4000)
@@ -3948,13 +3910,11 @@ static void ar9003_hw_quick_drop_apply(struct ath_hw *ah, u16 freq)
 	REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, quick_drop);
 }
 
-static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, u16 freq)
+static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, bool is2ghz)
 {
-	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
 	u32 value;
 
-	value = (freq < 4000) ? eep->modalHeader2G.txEndToXpaOff :
-				eep->modalHeader5G.txEndToXpaOff;
+	value = ar9003_modal_header(ah, is2ghz)->txEndToXpaOff;
 
 	REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
 		      AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF, value);
@@ -3962,7 +3922,7 @@ static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, u16 freq)
 		      AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF, value);
 }
 
-static void ar9003_hw_xpa_timing_control_apply(struct ath_hw *ah, bool is_2ghz)
+static void ar9003_hw_xpa_timing_control_apply(struct ath_hw *ah, bool is2ghz)
 {
 	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
 	u8 xpa_ctl;
@@ -3973,23 +3933,22 @@ static void ar9003_hw_xpa_timing_control_apply(struct ath_hw *ah, bool is_2ghz)
 	if (!AR_SREV_9300(ah) && !AR_SREV_9340(ah) && !AR_SREV_9580(ah))
 		return;
 
-	if (is_2ghz) {
-		xpa_ctl = eep->modalHeader2G.txFrameToXpaOn;
+	xpa_ctl = ar9003_modal_header(ah, is2ghz)->txFrameToXpaOn;
+	if (is2ghz)
 		REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
 			      AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON, xpa_ctl);
-	} else {
-		xpa_ctl = eep->modalHeader5G.txFrameToXpaOn;
+	else
 		REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL,
 			      AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON, xpa_ctl);
-	}
 }
 
 static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
 					     struct ath9k_channel *chan)
 {
-	ar9003_hw_xpa_timing_control_apply(ah, IS_CHAN_2GHZ(chan));
-	ar9003_hw_xpa_bias_level_apply(ah, IS_CHAN_2GHZ(chan));
-	ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan));
+	bool is2ghz = IS_CHAN_2GHZ(chan);
+	ar9003_hw_xpa_timing_control_apply(ah, is2ghz);
+	ar9003_hw_xpa_bias_level_apply(ah, is2ghz);
+	ar9003_hw_ant_ctrl_apply(ah, is2ghz);
 	ar9003_hw_drive_strength_apply(ah);
 	ar9003_hw_atten_apply(ah, chan);
 	ar9003_hw_quick_drop_apply(ah, chan->channel);
@@ -3997,7 +3956,7 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
 		ar9003_hw_internal_regulator_apply(ah);
 	if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah))
 		ar9003_hw_apply_tuning_caps(ah);
-	ar9003_hw_txend_to_xpa_off_apply(ah, chan->channel);
+	ar9003_hw_txend_to_xpa_off_apply(ah, is2ghz);
 }
 
 static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah,
@@ -5133,14 +5092,9 @@ s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah)
 	return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */
 }
 
-u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz)
+u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is2ghz)
 {
-	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
-
-	if (is_2ghz)
-		return eep->modalHeader2G.spurChans;
-	else
-		return eep->modalHeader5G.spurChans;
+	return ar9003_modal_header(ah, is2ghz)->spurChans;
 }
 
 unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index 33acb92..484b313 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -241,16 +241,12 @@ enum eeprom_param {
 	EEP_TEMPSENSE_SLOPE,
 	EEP_TEMPSENSE_SLOPE_PAL_ON,
 	EEP_PWR_TABLE_OFFSET,
-	EEP_DRIVE_STRENGTH,
-	EEP_INTERNAL_REGULATOR,
-	EEP_SWREG,
 	EEP_PAPRD,
 	EEP_MODAL_VER,
 	EEP_ANT_DIV_CTL1,
 	EEP_CHAIN_MASK_REDUCE,
 	EEP_ANTENNA_GAIN_2G,
 	EEP_ANTENNA_GAIN_5G,
-	EEP_QUICK_DROP
 };
 
 enum ar5416_rates {
-- 
1.7.3.2


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

* [PATCH v2 11/12] ath9k_hw: apply XLNA bias settings from EEPROM
  2012-07-12 15:04                 ` [PATCH v2 10/12] ath9k_hw: clean up AR9003 EEPROM code Felix Fietkau
@ 2012-07-12 15:04                   ` Felix Fietkau
  2012-07-12 15:04                     ` [PATCH v2 12/12] ath9k_hw: fix SREV checks for applying tuning caps " Felix Fietkau
  0 siblings, 1 reply; 23+ messages in thread
From: Felix Fietkau @ 2012-07-12 15:04 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, mcgrof

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.c |   53 +++++++++++++++++++----
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.h |    3 +-
 drivers/net/wireless/ath/ath9k/ar9003_phy.h    |    5 ++
 3 files changed, 50 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 4d90265..c5f3c43 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -131,8 +131,9 @@ static const struct ar9300_eeprom ar9300_default = {
 		.thresh62 = 28,
 		.papdRateMaskHt20 = LE32(0x0cf0e0e0),
 		.papdRateMaskHt40 = LE32(0x6cf0e0e0),
+		.xlna_bias_strength = 0,
 		.futureModal = {
-			0, 0, 0, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0,
 		},
 	 },
 	.base_ext1 = {
@@ -331,8 +332,9 @@ static const struct ar9300_eeprom ar9300_default = {
 		.thresh62 = 28,
 		.papdRateMaskHt20 = LE32(0x0c80c080),
 		.papdRateMaskHt40 = LE32(0x0080c080),
+		.xlna_bias_strength = 0,
 		.futureModal = {
-			0, 0, 0, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0,
 		},
 	 },
 	.base_ext2 = {
@@ -704,8 +706,9 @@ static const struct ar9300_eeprom ar9300_x113 = {
 		.thresh62 = 28,
 		.papdRateMaskHt20 = LE32(0x0c80c080),
 		.papdRateMaskHt40 = LE32(0x0080c080),
+		.xlna_bias_strength = 0,
 		.futureModal = {
-			0, 0, 0, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0,
 		},
 	 },
 	 .base_ext1 = {
@@ -904,8 +907,9 @@ static const struct ar9300_eeprom ar9300_x113 = {
 		.thresh62 = 28,
 		.papdRateMaskHt20 = LE32(0x0cf0e0e0),
 		.papdRateMaskHt40 = LE32(0x6cf0e0e0),
+		.xlna_bias_strength = 0,
 		.futureModal = {
-			0, 0, 0, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0,
 		},
 	 },
 	.base_ext2 = {
@@ -1278,8 +1282,9 @@ static const struct ar9300_eeprom ar9300_h112 = {
 		.thresh62 = 28,
 		.papdRateMaskHt20 = LE32(0x0c80c080),
 		.papdRateMaskHt40 = LE32(0x0080c080),
+		.xlna_bias_strength = 0,
 		.futureModal = {
-			0, 0, 0, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0,
 		},
 	},
 	.base_ext1 = {
@@ -1478,8 +1483,9 @@ static const struct ar9300_eeprom ar9300_h112 = {
 		.thresh62 = 28,
 		.papdRateMaskHt20 = LE32(0x0cf0e0e0),
 		.papdRateMaskHt40 = LE32(0x6cf0e0e0),
+		.xlna_bias_strength = 0,
 		.futureModal = {
-			0, 0, 0, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0,
 		},
 	},
 	.base_ext2 = {
@@ -1852,8 +1858,9 @@ static const struct ar9300_eeprom ar9300_x112 = {
 		.thresh62 = 28,
 		.papdRateMaskHt20 = LE32(0x0c80c080),
 		.papdRateMaskHt40 = LE32(0x0080c080),
+		.xlna_bias_strength = 0,
 		.futureModal = {
-			0, 0, 0, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0,
 		},
 	},
 	.base_ext1 = {
@@ -2052,8 +2059,9 @@ static const struct ar9300_eeprom ar9300_x112 = {
 		.thresh62 = 28,
 		.papdRateMaskHt20 = LE32(0x0cf0e0e0),
 		.papdRateMaskHt40 = LE32(0x6cf0e0e0),
+		.xlna_bias_strength = 0,
 		.futureModal = {
-			0, 0, 0, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0,
 		},
 	},
 	.base_ext2 = {
@@ -2425,8 +2433,9 @@ static const struct ar9300_eeprom ar9300_h116 = {
 		.thresh62 = 28,
 		.papdRateMaskHt20 = LE32(0x0c80C080),
 		.papdRateMaskHt40 = LE32(0x0080C080),
+		.xlna_bias_strength = 0,
 		.futureModal = {
-			0, 0, 0, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0,
 		},
 	 },
 	 .base_ext1 = {
@@ -2625,8 +2634,9 @@ static const struct ar9300_eeprom ar9300_h116 = {
 		.thresh62 = 28,
 		.papdRateMaskHt20 = LE32(0x0cf0e0e0),
 		.papdRateMaskHt40 = LE32(0x6cf0e0e0),
+		.xlna_bias_strength = 0,
 		.futureModal = {
-			0, 0, 0, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0,
 		},
 	 },
 	.base_ext2 = {
@@ -3942,6 +3952,28 @@ static void ar9003_hw_xpa_timing_control_apply(struct ath_hw *ah, bool is2ghz)
 			      AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON, xpa_ctl);
 }
 
+static void ar9003_hw_xlna_bias_strength_apply(struct ath_hw *ah, bool is2ghz)
+{
+	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+	u8 bias;
+
+	if (!(eep->baseEepHeader.featureEnable & 0x40))
+		return;
+
+	if (!AR_SREV_9300(ah))
+		return;
+
+	bias = ar9003_modal_header(ah, is2ghz)->xlna_bias_strength;
+	REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
+		      bias & 0x3);
+	bias >>= 2;
+	REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
+		      bias & 0x3);
+	bias >>= 2;
+	REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS,
+		      bias & 0x3);
+}
+
 static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
 					     struct ath9k_channel *chan)
 {
@@ -3950,6 +3982,7 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
 	ar9003_hw_xpa_bias_level_apply(ah, is2ghz);
 	ar9003_hw_ant_ctrl_apply(ah, is2ghz);
 	ar9003_hw_drive_strength_apply(ah);
+	ar9003_hw_xlna_bias_strength_apply(ah, is2ghz);
 	ar9003_hw_atten_apply(ah, chan);
 	ar9003_hw_quick_drop_apply(ah, chan->channel);
 	if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) && !AR_SREV_9550(ah))
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
index 8396d15..3a1ff55 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
@@ -231,7 +231,8 @@ struct ar9300_modal_eep_header {
 	__le32 papdRateMaskHt20;
 	__le32 papdRateMaskHt40;
 	__le16 switchcomspdt;
-	u8 futureModal[8];
+	u8 xlna_bias_strength;
+	u8 futureModal[7];
 } __packed;
 
 struct ar9300_cal_data_per_freq_op_loop {
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
index 751c83b..7bfbaf0 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -633,6 +633,8 @@
 #define AR_PHY_65NM_CH0_BIAS2       0x160c4
 #define AR_PHY_65NM_CH0_BIAS4       0x160cc
 #define AR_PHY_65NM_CH0_RXTX4       0x1610c
+#define AR_PHY_65NM_CH1_RXTX4       0x1650c
+#define AR_PHY_65NM_CH2_RXTX4       0x1690c
 
 #define AR_CH0_TOP	(AR_SREV_9300(ah) ? 0x16288 : \
 				((AR_SREV_9462(ah) ? 0x1628c : 0x16280)))
@@ -876,6 +878,9 @@
 #define AR_PHY_65NM_CH0_RXTX4_THERM_ON          0x10000000
 #define AR_PHY_65NM_CH0_RXTX4_THERM_ON_S        28
 
+#define AR_PHY_65NM_RXTX4_XLNA_BIAS		0xC0000000
+#define AR_PHY_65NM_RXTX4_XLNA_BIAS_S		30
+
 /*
  * Channel 1 Register Map
  */
-- 
1.7.3.2


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

* [PATCH v2 12/12] ath9k_hw: fix SREV checks for applying tuning caps from EEPROM
  2012-07-12 15:04                   ` [PATCH v2 11/12] ath9k_hw: apply XLNA bias settings from EEPROM Felix Fietkau
@ 2012-07-12 15:04                     ` Felix Fietkau
  0 siblings, 0 replies; 23+ messages in thread
From: Felix Fietkau @ 2012-07-12 15:04 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, mcgrof

AR9485, AR9330 and AR9340 are the chips that this is *NOT* supposed to be
applied on.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index c5f3c43..b5c8450 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -3890,6 +3890,9 @@ static void ar9003_hw_apply_tuning_caps(struct ath_hw *ah)
 	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
 	u8 tuning_caps_param = eep->baseEepHeader.params_for_tuning_caps[0];
 
+	if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah))
+		return;
+
 	if (eep->baseEepHeader.featureEnable & 0x40) {
 		tuning_caps_param &= 0x7f;
 		REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPINDAC,
@@ -3987,8 +3990,7 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
 	ar9003_hw_quick_drop_apply(ah, chan->channel);
 	if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) && !AR_SREV_9550(ah))
 		ar9003_hw_internal_regulator_apply(ah);
-	if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah))
-		ar9003_hw_apply_tuning_caps(ah);
+	ar9003_hw_apply_tuning_caps(ah);
 	ar9003_hw_txend_to_xpa_off_apply(ah, is2ghz);
 }
 
-- 
1.7.3.2


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

* [PATCH v2 08/12] ath9k: fix aggregate size limit based on queue TXOP limit
  2012-07-12 15:04             ` [PATCH v2 08/12] ath9k: fix aggregate size limit based on queue TXOP limit Felix Fietkau
  2012-07-12 15:04               ` [PATCH v2 09/12] ath9k_hw: apply XPA timing control values from EEPROM Felix Fietkau
@ 2012-07-14  6:04               ` Sujith Manoharan
  2012-07-14 10:02                 ` Felix Fietkau
  1 sibling, 1 reply; 23+ messages in thread
From: Sujith Manoharan @ 2012-07-14  6:04 UTC (permalink / raw)
  To: Felix Fietkau; +Cc: linux-wireless, linville, rodrigue

Felix Fietkau wrote:
> @@ -1384,6 +1384,7 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw,
>  		queue, txq->axq_qnum, params->aifs, params->cw_min,
>  		params->cw_max, params->txop);
>  
> +	ath_update_max_aggr_framelen(sc, queue, qi.tqi_burstTime);
>  	ret = ath_txq_update(sc, txq->axq_qnum, &qi);
>  	if (ret)
>  		ath_err(common, "TXQ Update failed\n");

Wouldn't this break multi-interface operation ? This unconditionally
updates the aggr. limits of an existing interface when a new one is added.

Sujith

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

* Re: [PATCH v2 08/12] ath9k: fix aggregate size limit based on queue TXOP limit
  2012-07-14  6:04               ` [PATCH v2 08/12] ath9k: fix aggregate size limit based on queue TXOP limit Sujith Manoharan
@ 2012-07-14 10:02                 ` Felix Fietkau
  2012-07-15  2:21                   ` Manoharan, Sujith
  0 siblings, 1 reply; 23+ messages in thread
From: Felix Fietkau @ 2012-07-14 10:02 UTC (permalink / raw)
  To: Sujith Manoharan; +Cc: linux-wireless, linville, rodrigue

On 2012-07-14 8:04 AM, Sujith Manoharan wrote:
> Felix Fietkau wrote:
>> @@ -1384,6 +1384,7 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw,
>>  		queue, txq->axq_qnum, params->aifs, params->cw_min,
>>  		params->cw_max, params->txop);
>>  
>> +	ath_update_max_aggr_framelen(sc, queue, qi.tqi_burstTime);
>>  	ret = ath_txq_update(sc, txq->axq_qnum, &qi);
>>  	if (ret)
>>  		ath_err(common, "TXQ Update failed\n");
> 
> Wouldn't this break multi-interface operation ? This unconditionally
> updates the aggr. limits of an existing interface when a new one is added.
No, this doesn't break multi-interface. TXOP limit (like other WMM
settings) can only be configured per-wiphy, so the max. aggregation
lengths are per-wiphy as well.

- Felix

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

* RE: [PATCH v2 08/12] ath9k: fix aggregate size limit based on queue TXOP limit
  2012-07-14 10:02                 ` Felix Fietkau
@ 2012-07-15  2:21                   ` Manoharan, Sujith
  2012-07-15 11:21                     ` Felix Fietkau
  0 siblings, 1 reply; 23+ messages in thread
From: Manoharan, Sujith @ 2012-07-15  2:21 UTC (permalink / raw)
  To: Felix Fietkau; +Cc: linux-wireless, linville, Rodriguez, Luis

I believe mac80211 has a per-VIF idea of queue parameters (tx_conf in struct ieee80211_sub_if_data).
And we end up overwriting the parameters of the main interface. For example,

* Bringing up an AP interface:

ath: phy0: Configure tx [queue/halq] [0/0], aifs: 1, cw_min: 3, cw_max: 7, txop: 47
ath: phy0: Configure tx [queue/halq] [1/1], aifs: 1, cw_min: 7, cw_max: 15, txop: 94
ath: phy0: Configure tx [queue/halq] [2/2], aifs: 3, cw_min: 15, cw_max: 63, txop: 0
ath: phy0: Configure tx [queue/halq] [3/3], aifs: 7, cw_min: 15, cw_max: 1023, txop: 0

* Adding a new station interface (but not associated yet):

ath: phy0: Attach a VIF of type: 2

ath: phy0: Configure tx [queue/halq] [0/0], aifs: 2, cw_min: 31, cw_max: 1023, txop: 0
ath: phy0: Configure tx [queue/halq] [1/1], aifs: 2, cw_min: 31, cw_max: 1023, txop: 0
ath: phy0: Configure tx [queue/halq] [2/2], aifs: 2, cw_min: 31, cw_max: 1023, txop: 0
ath: phy0: Configure tx [queue/halq] [3/3], aifs: 2, cw_min: 31, cw_max: 1023, txop: 0

Sujith
________________________________________
From: Felix Fietkau [nbd@openwrt.org]
Sent: Saturday, July 14, 2012 3:32 PM
To: Manoharan, Sujith
Cc: linux-wireless@vger.kernel.org; linville@tuxdriver.com; Rodriguez, Luis
Subject: Re: [PATCH v2 08/12] ath9k: fix aggregate size limit based on queue TXOP limit

On 2012-07-14 8:04 AM, Sujith Manoharan wrote:
> Felix Fietkau wrote:
>> @@ -1384,6 +1384,7 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw,
>>              queue, txq->axq_qnum, params->aifs, params->cw_min,
>>              params->cw_max, params->txop);
>>
>> +    ath_update_max_aggr_framelen(sc, queue, qi.tqi_burstTime);
>>      ret = ath_txq_update(sc, txq->axq_qnum, &qi);
>>      if (ret)
>>              ath_err(common, "TXQ Update failed\n");
>
> Wouldn't this break multi-interface operation ? This unconditionally
> updates the aggr. limits of an existing interface when a new one is added.
No, this doesn't break multi-interface. TXOP limit (like other WMM
settings) can only be configured per-wiphy, so the max. aggregation
lengths are per-wiphy as well.

- Felix

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

* Re: [PATCH v2 08/12] ath9k: fix aggregate size limit based on queue TXOP limit
  2012-07-15  2:21                   ` Manoharan, Sujith
@ 2012-07-15 11:21                     ` Felix Fietkau
  2012-07-16  8:15                       ` Sujith Manoharan
  0 siblings, 1 reply; 23+ messages in thread
From: Felix Fietkau @ 2012-07-15 11:21 UTC (permalink / raw)
  To: Manoharan, Sujith; +Cc: linux-wireless, linville, Rodriguez, Luis

On 2012-07-15 4:21 AM, Manoharan, Sujith wrote:
> I believe mac80211 has a per-VIF idea of queue parameters (tx_conf in struct ieee80211_sub_if_data).
> And we end up overwriting the parameters of the main interface. For example,
> 
> * Bringing up an AP interface:
> 
> ath: phy0: Configure tx [queue/halq] [0/0], aifs: 1, cw_min: 3, cw_max: 7, txop: 47
> ath: phy0: Configure tx [queue/halq] [1/1], aifs: 1, cw_min: 7, cw_max: 15, txop: 94
> ath: phy0: Configure tx [queue/halq] [2/2], aifs: 3, cw_min: 15, cw_max: 63, txop: 0
> ath: phy0: Configure tx [queue/halq] [3/3], aifs: 7, cw_min: 15, cw_max: 1023, txop: 0
> 
> * Adding a new station interface (but not associated yet):
> 
> ath: phy0: Attach a VIF of type: 2
> 
> ath: phy0: Configure tx [queue/halq] [0/0], aifs: 2, cw_min: 31, cw_max: 1023, txop: 0
> ath: phy0: Configure tx [queue/halq] [1/1], aifs: 2, cw_min: 31, cw_max: 1023, txop: 0
> ath: phy0: Configure tx [queue/halq] [2/2], aifs: 2, cw_min: 31, cw_max: 1023, txop: 0
> ath: phy0: Configure tx [queue/halq] [3/3], aifs: 2, cw_min: 31, cw_max: 1023, txop: 0
Yes, but ath9k only has global queue settings, not per-vif ones, so I'm
not sure what can be done about the issue of overwriting queue settings.

Either way, it's important for the aggregation limit to be in sync with
the hardware queue TXOP limit, so I believe this patch is correct.

- Felix

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

* Re: [PATCH v2 05/12] ath9k_hw: remove redundant arguments to INIT_INI_ARRAY
  2012-07-12 15:04       ` [PATCH v2 05/12] ath9k_hw: remove redundant arguments to INIT_INI_ARRAY Felix Fietkau
  2012-07-12 15:04         ` [PATCH v2 06/12] ath9k/ath9k_htc: fix txop limit handling Felix Fietkau
@ 2012-07-15 17:53         ` Felix Fietkau
  1 sibling, 0 replies; 23+ messages in thread
From: Felix Fietkau @ 2012-07-15 17:53 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, mcgrof

On 2012-07-12 5:04 PM, Felix Fietkau wrote:
> The row/column sizes can be derived from the array argument within the macro
> itself, which is less error prone. In a few cases the supplied column size
> was actually wrong.
This patch no longer applies since Mohammed Shafi's WoW work was merged.
I'll send a v3.

- Felix

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

* Re: [PATCH v2 08/12] ath9k: fix aggregate size limit based on queue TXOP limit
  2012-07-15 11:21                     ` Felix Fietkau
@ 2012-07-16  8:15                       ` Sujith Manoharan
  2012-07-16 10:19                         ` Felix Fietkau
  0 siblings, 1 reply; 23+ messages in thread
From: Sujith Manoharan @ 2012-07-16  8:15 UTC (permalink / raw)
  To: Felix Fietkau
  Cc: Manoharan, Sujith, linux-wireless, linville, Rodriguez, Luis

Felix Fietkau wrote:
> Yes, but ath9k only has global queue settings, not per-vif ones, so I'm
> not sure what can be done about the issue of overwriting queue settings.

Yeah, me neither.

> Either way, it's important for the aggregation limit to be in sync with
> the hardware queue TXOP limit, so I believe this patch is correct.

Except that earlier it was a global, static table. I am curious, which part
of the standard deals with limiting AMPDU size based on txop ? I searched a bit
and got lost.

Sujith

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

* Re: [PATCH v2 08/12] ath9k: fix aggregate size limit based on queue TXOP limit
  2012-07-16  8:15                       ` Sujith Manoharan
@ 2012-07-16 10:19                         ` Felix Fietkau
  2012-07-16 18:28                           ` Sujith Manoharan
  0 siblings, 1 reply; 23+ messages in thread
From: Felix Fietkau @ 2012-07-16 10:19 UTC (permalink / raw)
  To: Sujith Manoharan; +Cc: linux-wireless, linville, Rodriguez, Luis

On 2012-07-16 10:15 AM, Sujith Manoharan wrote:
> Felix Fietkau wrote:
>> Yes, but ath9k only has global queue settings, not per-vif ones, so I'm
>> not sure what can be done about the issue of overwriting queue settings.
> 
> Yeah, me neither.
> 
>> Either way, it's important for the aggregation limit to be in sync with
>> the hardware queue TXOP limit, so I believe this patch is correct.
> 
> Except that earlier it was a global, static table. I am curious, which part
> of the standard deals with limiting AMPDU size based on txop ? I searched a bit
> and got lost.
The standard does not say anything specifically about A-MPDU, but it
does say this:

When the TXOP limit is nonzero, a STA shall fragment an individually
addressed MSDU so that the transmission of the first MPDU of the TXOP
does not cause the TXOP limit to be exceeded at the PHY rate selected
for the initial transmission attempt of that MPDU. The TXOP limit may be
exceeded, when using a lower PHY rate than selected for the initial
transmission attempt of the first MPDU, for a retransmission of an MPDU,
for the initial transmission of an MPDU if any previous MPDU in the
current MSDU has been retransmitted, or for group addressed MSDUs. When
the TXOP limit is exceeded due to the retransmission of an MPDU at a
reduced PHY rate, the STA shall not transmit more than one MPDU in the TXOP.

Since 3 ms for VI (default) is still a lot and this queue is meant to
have lower latency compared to BE/BK, I decided to not add any special
rules to treat retransmissions differently.
I'm not sure if it's absolutely required to reduce the A-MPDU
transmission duration here, but even if it isn't, it's still a good idea
for reducing latency, and it does look like it reduces the amount of
retransmissions under load.

The only other queue that has a TXOP limit set by default is the VO
queue, but that one can be ignored since it doesn't do aggregation.

- Felix

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

* Re: [PATCH v2 08/12] ath9k: fix aggregate size limit based on queue TXOP limit
  2012-07-16 10:19                         ` Felix Fietkau
@ 2012-07-16 18:28                           ` Sujith Manoharan
  2012-07-16 19:24                             ` Felix Fietkau
  0 siblings, 1 reply; 23+ messages in thread
From: Sujith Manoharan @ 2012-07-16 18:28 UTC (permalink / raw)
  To: Felix Fietkau; +Cc: Sujith Manoharan, linux-wireless, linville, Rodriguez, Luis

Felix Fietkau wrote:
> The standard does not say anything specifically about A-MPDU, but it
> does say this:
> 
> When the TXOP limit is nonzero, a STA shall fragment an individually
> addressed MSDU so that the transmission of the first MPDU of the TXOP
> does not cause the TXOP limit to be exceeded at the PHY rate selected
> for the initial transmission attempt of that MPDU. The TXOP limit may be
> exceeded, when using a lower PHY rate than selected for the initial
> transmission attempt of the first MPDU, for a retransmission of an MPDU,
> for the initial transmission of an MPDU if any previous MPDU in the
> current MSDU has been retransmitted, or for group addressed MSDUs. When
> the TXOP limit is exceeded due to the retransmission of an MPDU at a
> reduced PHY rate, the STA shall not transmit more than one MPDU in the TXOP.

Um, am not sure how this passage relates to number of subframe calculation in an
aggregate ?

Sujith

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

* Re: [PATCH v2 08/12] ath9k: fix aggregate size limit based on queue TXOP limit
  2012-07-16 18:28                           ` Sujith Manoharan
@ 2012-07-16 19:24                             ` Felix Fietkau
  2012-07-17 11:35                               ` Sujith Manoharan
  0 siblings, 1 reply; 23+ messages in thread
From: Felix Fietkau @ 2012-07-16 19:24 UTC (permalink / raw)
  To: Sujith Manoharan; +Cc: linux-wireless, linville, Rodriguez, Luis

On 2012-07-16 8:28 PM, Sujith Manoharan wrote:
> Felix Fietkau wrote:
>> The standard does not say anything specifically about A-MPDU, but it
>> does say this:
>> 
>> When the TXOP limit is nonzero, a STA shall fragment an individually
>> addressed MSDU so that the transmission of the first MPDU of the TXOP
>> does not cause the TXOP limit to be exceeded at the PHY rate selected
>> for the initial transmission attempt of that MPDU. The TXOP limit may be
>> exceeded, when using a lower PHY rate than selected for the initial
>> transmission attempt of the first MPDU, for a retransmission of an MPDU,
>> for the initial transmission of an MPDU if any previous MPDU in the
>> current MSDU has been retransmitted, or for group addressed MSDUs. When
>> the TXOP limit is exceeded due to the retransmission of an MPDU at a
>> reduced PHY rate, the STA shall not transmit more than one MPDU in the TXOP.
> 
> Um, am not sure how this passage relates to number of subframe calculation in an
> aggregate ?
The way I understand this, the TXOP limit is meant to limit the duration
of a single transmission on the channel. An aggregate is transmitted in
one go, there's no SIFS or extra PHY headers inbetween, just short
delimiters. So an A-MPDU should be treated pretty much like an MPDU
here, its transmission duration should not exceed the TXOP limit.

- Felix

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

* Re: [PATCH v2 08/12] ath9k: fix aggregate size limit based on queue TXOP limit
  2012-07-16 19:24                             ` Felix Fietkau
@ 2012-07-17 11:35                               ` Sujith Manoharan
  2012-07-17 11:54                                 ` Felix Fietkau
  0 siblings, 1 reply; 23+ messages in thread
From: Sujith Manoharan @ 2012-07-17 11:35 UTC (permalink / raw)
  To: Felix Fietkau; +Cc: Sujith Manoharan, linux-wireless, linville, Rodriguez, Luis

Felix Fietkau wrote:
> The way I understand this, the TXOP limit is meant to limit the duration
> of a single transmission on the channel. An aggregate is transmitted in
> one go, there's no SIFS or extra PHY headers inbetween, just short
> delimiters. So an A-MPDU should be treated pretty much like an MPDU
> here, its transmission duration should not exceed the TXOP limit.

Yeah, makes sense.

But we need to handle multiple interfaces, otherwise this would break
modes like P2P. For example, bring up a P2P-GO and setup a HT20 network,
and then bring up a new station interface - this would unconditionally
update the aggr. limits of the existing network. This wasn't the case earlier
since the limits were being maintained globally and were common to all interfaces
and addition/removal of new interfaces would not change the aggr. limits.

Sujith

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

* Re: [PATCH v2 08/12] ath9k: fix aggregate size limit based on queue TXOP limit
  2012-07-17 11:35                               ` Sujith Manoharan
@ 2012-07-17 11:54                                 ` Felix Fietkau
  0 siblings, 0 replies; 23+ messages in thread
From: Felix Fietkau @ 2012-07-17 11:54 UTC (permalink / raw)
  To: Sujith Manoharan; +Cc: linux-wireless, linville, Rodriguez, Luis

On 2012-07-17 1:35 PM, Sujith Manoharan wrote:
> Felix Fietkau wrote:
>> The way I understand this, the TXOP limit is meant to limit the duration
>> of a single transmission on the channel. An aggregate is transmitted in
>> one go, there's no SIFS or extra PHY headers inbetween, just short
>> delimiters. So an A-MPDU should be treated pretty much like an MPDU
>> here, its transmission duration should not exceed the TXOP limit.
> 
> Yeah, makes sense.
> 
> But we need to handle multiple interfaces, otherwise this would break
> modes like P2P. For example, bring up a P2P-GO and setup a HT20 network,
> and then bring up a new station interface - this would unconditionally
> update the aggr. limits of the existing network. This wasn't the case earlier
> since the limits were being maintained globally and were common to all interfaces
> and addition/removal of new interfaces would not change the aggr. limits.
Before my patch, the aggr limits were always broken for the VI queue.
Now they're just sometimes broken :)

- Felix

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

end of thread, other threads:[~2012-07-17 11:54 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-12 15:04 [PATCH v2 01/12] ath9k_hw: fall back to OTP ROM when platform data has no valid eeprom data Felix Fietkau
2012-07-12 15:04 ` [PATCH v2 02/12] ath9k: validate rx antenna settings Felix Fietkau
2012-07-12 15:04   ` [PATCH v2 03/12] ath9k_hw: enable ANI on AR934x Felix Fietkau
2012-07-12 15:04     ` [PATCH v2 04/12] ath9k_hw: fix tx gain tables for AR934x Felix Fietkau
2012-07-12 15:04       ` [PATCH v2 05/12] ath9k_hw: remove redundant arguments to INIT_INI_ARRAY Felix Fietkau
2012-07-12 15:04         ` [PATCH v2 06/12] ath9k/ath9k_htc: fix txop limit handling Felix Fietkau
2012-07-12 15:04           ` [PATCH v2 07/12] ath9k: make per-WMM-AC queue sizes configurable via debugfs Felix Fietkau
2012-07-12 15:04             ` [PATCH v2 08/12] ath9k: fix aggregate size limit based on queue TXOP limit Felix Fietkau
2012-07-12 15:04               ` [PATCH v2 09/12] ath9k_hw: apply XPA timing control values from EEPROM Felix Fietkau
2012-07-12 15:04                 ` [PATCH v2 10/12] ath9k_hw: clean up AR9003 EEPROM code Felix Fietkau
2012-07-12 15:04                   ` [PATCH v2 11/12] ath9k_hw: apply XLNA bias settings from EEPROM Felix Fietkau
2012-07-12 15:04                     ` [PATCH v2 12/12] ath9k_hw: fix SREV checks for applying tuning caps " Felix Fietkau
2012-07-14  6:04               ` [PATCH v2 08/12] ath9k: fix aggregate size limit based on queue TXOP limit Sujith Manoharan
2012-07-14 10:02                 ` Felix Fietkau
2012-07-15  2:21                   ` Manoharan, Sujith
2012-07-15 11:21                     ` Felix Fietkau
2012-07-16  8:15                       ` Sujith Manoharan
2012-07-16 10:19                         ` Felix Fietkau
2012-07-16 18:28                           ` Sujith Manoharan
2012-07-16 19:24                             ` Felix Fietkau
2012-07-17 11:35                               ` Sujith Manoharan
2012-07-17 11:54                                 ` Felix Fietkau
2012-07-15 17:53         ` [PATCH v2 05/12] ath9k_hw: remove redundant arguments to INIT_INI_ARRAY Felix Fietkau

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.