From 58b587ee61090b4b3c8c0092cdb60a980b86096a Mon Sep 17 00:00:00 2001
From: nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Date: Fri, 8 Jul 2011 17:19:21 +0000
Subject: ath9k: add more fixes for half/quarter rate support

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@27562 3c298f89-4303-0410-b956-a3cf2f4a3e73
---
 .../patches/543-ath9k_fix_mac_clock_div.patch      | 16 ++++
 .../patches/544-ath9k_fix_ar9287_mac_clock.patch   | 14 ++++
 .../patches/545-ath9k_timing_settings.patch        | 91 ++++++++++++++++++++++
 .../546-ath9k_cleanup_ar9287_settings.patch        | 78 +++++++++++++++++++
 .../547-ath9k_half_quarter_set_channel_frac.patch  | 13 ++++
 .../548-ath9k_half_quarter_synth_delay.patch       | 14 ++++
 .../patches/549-ath9k_shift_reg_delay.patch        | 14 ++++
 7 files changed, 240 insertions(+)
 create mode 100644 package/mac80211/patches/543-ath9k_fix_mac_clock_div.patch
 create mode 100644 package/mac80211/patches/544-ath9k_fix_ar9287_mac_clock.patch
 create mode 100644 package/mac80211/patches/545-ath9k_timing_settings.patch
 create mode 100644 package/mac80211/patches/546-ath9k_cleanup_ar9287_settings.patch
 create mode 100644 package/mac80211/patches/547-ath9k_half_quarter_set_channel_frac.patch
 create mode 100644 package/mac80211/patches/548-ath9k_half_quarter_synth_delay.patch
 create mode 100644 package/mac80211/patches/549-ath9k_shift_reg_delay.patch

(limited to 'package/mac80211')

diff --git a/package/mac80211/patches/543-ath9k_fix_mac_clock_div.patch b/package/mac80211/patches/543-ath9k_fix_mac_clock_div.patch
new file mode 100644
index 000000000..f76c54229
--- /dev/null
+++ b/package/mac80211/patches/543-ath9k_fix_mac_clock_div.patch
@@ -0,0 +1,16 @@
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -100,6 +100,13 @@ static void ath9k_hw_set_clockrate(struc
+ 	if (conf_is_ht40(conf))
+ 		clockrate *= 2;
+ 
++	if (ah->curchan) {
++		if (IS_CHAN_HALF_RATE(ah->curchan))
++			clockrate /= 2;
++		if (IS_CHAN_QUARTER_RATE(ah->curchan))
++			clockrate /= 4;
++	}
++
+ 	common->clockrate = clockrate;
+ }
+ 
diff --git a/package/mac80211/patches/544-ath9k_fix_ar9287_mac_clock.patch b/package/mac80211/patches/544-ath9k_fix_ar9287_mac_clock.patch
new file mode 100644
index 000000000..f749f1d62
--- /dev/null
+++ b/package/mac80211/patches/544-ath9k_fix_ar9287_mac_clock.patch
@@ -0,0 +1,14 @@
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -88,7 +88,10 @@ static void ath9k_hw_set_clockrate(struc
+ 	struct ath_common *common = ath9k_hw_common(ah);
+ 	unsigned int clockrate;
+ 
+-	if (!ah->curchan) /* should really check for CCK instead */
++	/* AR9287 v1.3+ uses async FIFO and runs the MAC at 117 MHz */
++	if (AR_SREV_9287(ah) && AR_SREV_9287_13_OR_LATER(ah))
++		clockrate = 117;
++	else if (!ah->curchan) /* should really check for CCK instead */
+ 		clockrate = ATH9K_CLOCK_RATE_CCK;
+ 	else if (conf->channel->band == IEEE80211_BAND_2GHZ)
+ 		clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM;
diff --git a/package/mac80211/patches/545-ath9k_timing_settings.patch b/package/mac80211/patches/545-ath9k_timing_settings.patch
new file mode 100644
index 000000000..90a575a68
--- /dev/null
+++ b/package/mac80211/patches/545-ath9k_timing_settings.patch
@@ -0,0 +1,91 @@
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -951,25 +951,60 @@ static bool ath9k_hw_set_global_txtimeou
+ 
+ void ath9k_hw_init_global_settings(struct ath_hw *ah)
+ {
+-	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
++	struct ath_common *common = ath9k_hw_common(ah);
++	struct ieee80211_conf *conf = &common->hw->conf;
++	const struct ath9k_channel *chan = ah->curchan;
+ 	int acktimeout;
+ 	int slottime;
+ 	int sifstime;
++	int rx_lat = 0, tx_lat = 0, eifs = 0;
++	u32 reg;
+ 
+ 	ath_dbg(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n",
+ 		ah->misc_mode);
+ 
++	if (!chan)
++		return;
++
+ 	if (ah->misc_mode != 0)
+ 		REG_SET_BIT(ah, AR_PCU_MISC, ah->misc_mode);
+ 
+-	if (conf->channel && conf->channel->band == IEEE80211_BAND_5GHZ)
+-		sifstime = 16;
+-	else
+-		sifstime = 10;
++	rx_lat = 37;
++	tx_lat = 54;
++
++	if (IS_CHAN_HALF_RATE(chan)) {
++		eifs = 175;
++		rx_lat *= 2;
++		tx_lat *= 2;
++		if (IS_CHAN_A_FAST_CLOCK(ah, chan))
++		    tx_lat += 11;
++
++		slottime = 13;
++		sifstime = 32;
++	} else if (IS_CHAN_QUARTER_RATE(chan)) {
++		eifs = 340;
++		rx_lat *= 4;
++		tx_lat *= 4;
++		if (IS_CHAN_A_FAST_CLOCK(ah, chan))
++		    tx_lat += 22;
++
++		slottime = 21;
++		sifstime = 64;
++	} else {
++		eifs = REG_READ(ah, AR_D_GBL_IFS_EIFS);
++		reg = REG_READ(ah, AR_USEC);
++		rx_lat = MS(reg, AR_USEC_RX_LAT);
++		tx_lat = MS(reg, AR_USEC_TX_LAT);
++
++		slottime = ah->slottime;
++		if (IS_CHAN_5GHZ(chan))
++			sifstime = 16;
++		else
++			sifstime = 10;
++	}
+ 
+ 	/* As defined by IEEE 802.11-2007 17.3.8.6 */
+-	slottime = ah->slottime + 3 * ah->coverage_class;
+-	acktimeout = slottime + sifstime;
++	acktimeout = slottime + sifstime + 3 * ah->coverage_class;
+ 
+ 	/*
+ 	 * Workaround for early ACK timeouts, add an offset to match the
+@@ -981,11 +1016,19 @@ void ath9k_hw_init_global_settings(struc
+ 	if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ)
+ 		acktimeout += 64 - sifstime - ah->slottime;
+ 
+-	ath9k_hw_setslottime(ah, ah->slottime);
++	ath9k_hw_setslottime(ah, slottime);
+ 	ath9k_hw_set_ack_timeout(ah, acktimeout);
+ 	ath9k_hw_set_cts_timeout(ah, acktimeout);
+ 	if (ah->globaltxtimeout != (u32) -1)
+ 		ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout);
++
++	REG_WRITE(ah, AR_D_GBL_IFS_EIFS, ath9k_hw_mac_to_clks(ah, eifs));
++	REG_RMW(ah, AR_USEC,
++		(common->clockrate - 1) |
++		SM(rx_lat, AR_USEC_RX_LAT) |
++		SM(tx_lat, AR_USEC_TX_LAT),
++		AR_USEC_TX_LAT | AR_USEC_RX_LAT | AR_USEC_USEC);
++
+ }
+ EXPORT_SYMBOL(ath9k_hw_init_global_settings);
+ 
diff --git a/package/mac80211/patches/546-ath9k_cleanup_ar9287_settings.patch b/package/mac80211/patches/546-ath9k_cleanup_ar9287_settings.patch
new file mode 100644
index 000000000..4fe210a65
--- /dev/null
+++ b/package/mac80211/patches/546-ath9k_cleanup_ar9287_settings.patch
@@ -0,0 +1,78 @@
+--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
++++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+@@ -499,45 +499,6 @@ void ar9002_hw_enable_async_fifo(struct 
+ 	}
+ }
+ 
+-/*
+- * If Async FIFO is enabled, the following counters change as MAC now runs
+- * at 117 Mhz instead of 88/44MHz when async FIFO is disabled.
+- *
+- * The values below tested for ht40 2 chain.
+- * Overwrite the delay/timeouts initialized in process ini.
+- */
+-void ar9002_hw_update_async_fifo(struct ath_hw *ah)
+-{
+-	if (AR_SREV_9287_13_OR_LATER(ah)) {
+-		REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
+-			  AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR);
+-		REG_WRITE(ah, AR_D_GBL_IFS_SLOT,
+-			  AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR);
+-		REG_WRITE(ah, AR_D_GBL_IFS_EIFS,
+-			  AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR);
+-
+-		REG_WRITE(ah, AR_TIME_OUT, AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR);
+-		REG_WRITE(ah, AR_USEC, AR_USEC_ASYNC_FIFO_DUR);
+-
+-		REG_SET_BIT(ah, AR_MAC_PCU_LOGIC_ANALYZER,
+-			    AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768);
+-		REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN,
+-			      AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL);
+-	}
+-}
+-
+-/*
+- * We don't enable WEP aggregation on mac80211 but we keep this
+- * around for HAL unification purposes.
+- */
+-void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah)
+-{
+-	if (AR_SREV_9287_13_OR_LATER(ah)) {
+-		REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
+-			    AR_PCU_MISC_MODE2_ENABLE_AGGWEP);
+-	}
+-}
+-
+ /* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */
+ void ar9002_hw_attach_ops(struct ath_hw *ah)
+ {
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -1633,9 +1633,13 @@ int ath9k_hw_reset(struct ath_hw *ah, st
+ 
+ 	ath9k_hw_init_global_settings(ah);
+ 
+-	if (!AR_SREV_9300_20_OR_LATER(ah)) {
+-		ar9002_hw_update_async_fifo(ah);
+-		ar9002_hw_enable_wep_aggregation(ah);
++	if (AR_SREV_9287(ah) && AR_SREV_9287_13_OR_LATER(ah)) {
++		REG_SET_BIT(ah, AR_MAC_PCU_LOGIC_ANALYZER,
++			    AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768);
++		REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN,
++			      AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL);
++		REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
++			    AR_PCU_MISC_MODE2_ENABLE_AGGWEP);
+ 	}
+ 
+ 	REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM);
+--- a/drivers/net/wireless/ath/ath9k/hw.h
++++ b/drivers/net/wireless/ath/ath9k/hw.h
+@@ -984,8 +984,6 @@ void ath9k_hw_get_delta_slope_vals(struc
+ void ar9002_hw_cck_chan14_spread(struct ath_hw *ah);
+ int ar9002_hw_rf_claim(struct ath_hw *ah);
+ void ar9002_hw_enable_async_fifo(struct ath_hw *ah);
+-void ar9002_hw_update_async_fifo(struct ath_hw *ah);
+-void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah);
+ 
+ /*
+  * Code specific to AR9003, we stuff these here to avoid callbacks
diff --git a/package/mac80211/patches/547-ath9k_half_quarter_set_channel_frac.patch b/package/mac80211/patches/547-ath9k_half_quarter_set_channel_frac.patch
new file mode 100644
index 000000000..cb215b8c6
--- /dev/null
+++ b/package/mac80211/patches/547-ath9k_half_quarter_set_channel_frac.patch
@@ -0,0 +1,13 @@
+--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
++++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
+@@ -111,7 +111,9 @@ static int ar9002_hw_set_channel(struct 
+ 
+ 		switch (ah->eep_ops->get_eeprom(ah, EEP_FRAC_N_5G)) {
+ 		case 0:
+-			if ((freq % 20) == 0)
++			if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan))
++				aModeRefSel = 0;
++			else if ((freq % 20) == 0)
+ 				aModeRefSel = 3;
+ 			else if ((freq % 10) == 0)
+ 				aModeRefSel = 2;
diff --git a/package/mac80211/patches/548-ath9k_half_quarter_synth_delay.patch b/package/mac80211/patches/548-ath9k_half_quarter_synth_delay.patch
new file mode 100644
index 000000000..6429d1907
--- /dev/null
+++ b/package/mac80211/patches/548-ath9k_half_quarter_synth_delay.patch
@@ -0,0 +1,14 @@
+--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
++++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+@@ -627,6 +627,11 @@ static void ar5008_hw_init_bb(struct ath
+ 	else
+ 		synthDelay /= 10;
+ 
++	if (IS_CHAN_HALF_RATE(chan))
++		synthDelay *= 2;
++	else if (IS_CHAN_QUARTER_RATE(chan))
++		synthDelay *= 4;
++
+ 	REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
+ 
+ 	udelay(synthDelay + BASE_ACTIVATE_DELAY);
diff --git a/package/mac80211/patches/549-ath9k_shift_reg_delay.patch b/package/mac80211/patches/549-ath9k_shift_reg_delay.patch
new file mode 100644
index 000000000..3676ae42a
--- /dev/null
+++ b/package/mac80211/patches/549-ath9k_shift_reg_delay.patch
@@ -0,0 +1,14 @@
+--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
++++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
+@@ -131,8 +131,9 @@ static int ar9002_hw_set_channel(struct 
+ 			channelSel = CHANSEL_5G(freq);
+ 
+ 			/* RefDivA setting */
+-			REG_RMW_FIELD(ah, AR_AN_SYNTH9,
+-				      AR_AN_SYNTH9_REFDIVA, refDivA);
++			ath9k_hw_analog_shift_rmw(ah, AR_AN_SYNTH9,
++				      AR_AN_SYNTH9_REFDIVA,
++				      AR_AN_SYNTH9_REFDIVA_S, refDivA);
+ 
+ 		}
+ 
-- 
cgit v1.2.3