ath9k: add more fixes for half/quarter rate support
authorFelix Fietkau <nbd@openwrt.org>
Fri, 8 Jul 2011 17:19:21 +0000 (17:19 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Fri, 8 Jul 2011 17:19:21 +0000 (17:19 +0000)
SVN-Revision: 27562

package/mac80211/patches/543-ath9k_fix_mac_clock_div.patch [new file with mode: 0644]
package/mac80211/patches/544-ath9k_fix_ar9287_mac_clock.patch [new file with mode: 0644]
package/mac80211/patches/545-ath9k_timing_settings.patch [new file with mode: 0644]
package/mac80211/patches/546-ath9k_cleanup_ar9287_settings.patch [new file with mode: 0644]
package/mac80211/patches/547-ath9k_half_quarter_set_channel_frac.patch [new file with mode: 0644]
package/mac80211/patches/548-ath9k_half_quarter_synth_delay.patch [new file with mode: 0644]
package/mac80211/patches/549-ath9k_shift_reg_delay.patch [new file with mode: 0644]

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 (file)
index 0000000..f76c542
--- /dev/null
@@ -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 (file)
index 0000000..f749f1d
--- /dev/null
@@ -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 (file)
index 0000000..90a575a
--- /dev/null
@@ -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 (file)
index 0000000..4fe210a
--- /dev/null
@@ -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 (file)
index 0000000..cb215b8
--- /dev/null
@@ -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 (file)
index 0000000..6429d19
--- /dev/null
@@ -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 (file)
index 0000000..3676ae4
--- /dev/null
@@ -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);
+               }