ath9k: add some cleanup patches and rework tx power handling
authorFelix Fietkau <nbd@openwrt.org>
Sat, 17 Sep 2011 16:02:56 +0000 (16:02 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Sat, 17 Sep 2011 16:02:56 +0000 (16:02 +0000)
SVN-Revision: 28253

package/mac80211/patches/531-ath9k_cur_txpower.patch
package/mac80211/patches/580-ath9k_cleanup_set_interrupt.patch [new file with mode: 0644]
package/mac80211/patches/581-ath9k_cleanup_txpower_handling.patch [new file with mode: 0644]
package/mac80211/patches/582-ath9k_remove_current_rd_ext.patch [new file with mode: 0644]
package/mac80211/patches/583-ath9k_remove_eep_reg_1.patch [new file with mode: 0644]

index 9a2ce9e43a20bcd650589d28b38ec4138b364002..894d7804205806c9451949389f8eb84a89d212f2 100644 (file)
        }
  
        if (disable_radio) {
---- a/drivers/net/wireless/ath/ath9k/common.c
-+++ b/drivers/net/wireless/ath/ath9k/common.c
-@@ -161,10 +161,12 @@ EXPORT_SYMBOL(ath9k_cmn_count_streams);
- void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow,
-                           u16 new_txpow, u16 *txpower)
- {
-+      struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
-+
-       if (cur_txpow != new_txpow) {
-               ath9k_hw_set_txpowerlimit(ah, new_txpow, false);
-               /* read back in case value is clamped */
--              *txpower = ath9k_hw_regulatory(ah)->power_limit;
-+              *txpower = min_t(u16, reg->power_limit, reg->max_power_level);
-       }
- }
- EXPORT_SYMBOL(ath9k_cmn_update_txpow);
diff --git a/package/mac80211/patches/580-ath9k_cleanup_set_interrupt.patch b/package/mac80211/patches/580-ath9k_cleanup_set_interrupt.patch
new file mode 100644 (file)
index 0000000..8723e50
--- /dev/null
@@ -0,0 +1,155 @@
+--- a/drivers/net/wireless/ath/ath9k/beacon.c
++++ b/drivers/net/wireless/ath/ath9k/beacon.c
+@@ -515,7 +515,7 @@ static void ath_beacon_config_ap(struct 
+       sc->sc_flags |= SC_OP_TSF_RESET;
+       ath9k_beacon_init(sc, nexttbtt, intval);
+       sc->beacon.bmisscnt = 0;
+-      ath9k_hw_set_interrupts(ah, ah->imask);
++      ath9k_hw_set_interrupts(ah);
+       ath9k_hw_enable_interrupts(ah);
+ }
+@@ -643,7 +643,7 @@ static void ath_beacon_config_sta(struct
+       ath9k_hw_set_sta_beacon_timers(ah, &bs);
+       ah->imask |= ATH9K_INT_BMISS;
+-      ath9k_hw_set_interrupts(ah, ah->imask);
++      ath9k_hw_set_interrupts(ah);
+       ath9k_hw_enable_interrupts(ah);
+ }
+@@ -679,7 +679,7 @@ static void ath_beacon_config_adhoc(stru
+       ath9k_beacon_init(sc, nexttbtt, intval);
+       sc->beacon.bmisscnt = 0;
+-      ath9k_hw_set_interrupts(ah, ah->imask);
++      ath9k_hw_set_interrupts(ah);
+       ath9k_hw_enable_interrupts(ah);
+ }
+@@ -821,11 +821,11 @@ void ath9k_set_beaconing_status(struct a
+       if (status) {
+               /* Re-enable beaconing */
+               ah->imask |= ATH9K_INT_SWBA;
+-              ath9k_hw_set_interrupts(ah, ah->imask);
++              ath9k_hw_set_interrupts(ah);
+       } else {
+               /* Disable SWBA interrupt */
+               ah->imask &= ~ATH9K_INT_SWBA;
+-              ath9k_hw_set_interrupts(ah, ah->imask);
++              ath9k_hw_set_interrupts(ah);
+               tasklet_kill(&sc->bcon_tasklet);
+               ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq);
+       }
+--- a/drivers/net/wireless/ath/ath9k/gpio.c
++++ b/drivers/net/wireless/ath/ath9k/gpio.c
+@@ -151,7 +151,7 @@ static void ath9k_gen_timer_start(struct
+       if ((ah->imask & ATH9K_INT_GENTIMER) == 0) {
+               ath9k_hw_disable_interrupts(ah);
+               ah->imask |= ATH9K_INT_GENTIMER;
+-              ath9k_hw_set_interrupts(ah, ah->imask);
++              ath9k_hw_set_interrupts(ah);
+               ath9k_hw_enable_interrupts(ah);
+       }
+ }
+@@ -166,7 +166,7 @@ static void ath9k_gen_timer_stop(struct 
+       if (timer_table->timer_mask.val == 0) {
+               ath9k_hw_disable_interrupts(ah);
+               ah->imask &= ~ATH9K_INT_GENTIMER;
+-              ath9k_hw_set_interrupts(ah, ah->imask);
++              ath9k_hw_set_interrupts(ah);
+               ath9k_hw_enable_interrupts(ah);
+       }
+ }
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -273,7 +273,7 @@ static bool ath_complete_reset(struct at
+       ath9k_cmn_update_txpow(ah, sc->curtxpow,
+                              sc->config.txpowlimit, &sc->curtxpow);
+-      ath9k_hw_set_interrupts(ah, ah->imask);
++      ath9k_hw_set_interrupts(ah);
+       ath9k_hw_enable_interrupts(ah);
+       if (!(sc->sc_flags & (SC_OP_OFFCHANNEL)) && start) {
+@@ -833,7 +833,7 @@ irqreturn_t ath_isr(int irq, void *dev)
+       if (status & ATH9K_INT_RXEOL) {
+               ah->imask &= ~(ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
+-              ath9k_hw_set_interrupts(ah, ah->imask);
++              ath9k_hw_set_interrupts(ah);
+       }
+       if (status & ATH9K_INT_MIB) {
+@@ -1409,7 +1409,7 @@ static void ath9k_calculate_summary_stat
+               ah->imask &= ~ATH9K_INT_TSFOOR;
+       }
+-      ath9k_hw_set_interrupts(ah, ah->imask);
++      ath9k_hw_set_interrupts(ah);
+       /* Set up ANI */
+       if (iter_data.naps > 0) {
+@@ -1566,7 +1566,7 @@ static void ath9k_enable_ps(struct ath_s
+       if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
+               if ((ah->imask & ATH9K_INT_TIM_TIMER) == 0) {
+                       ah->imask |= ATH9K_INT_TIM_TIMER;
+-                      ath9k_hw_set_interrupts(ah, ah->imask);
++                      ath9k_hw_set_interrupts(ah);
+               }
+               ath9k_hw_setrxabort(ah, 1);
+       }
+@@ -1586,7 +1586,7 @@ static void ath9k_disable_ps(struct ath_
+                                 PS_WAIT_FOR_TX_ACK);
+               if (ah->imask & ATH9K_INT_TIM_TIMER) {
+                       ah->imask &= ~ATH9K_INT_TIM_TIMER;
+-                      ath9k_hw_set_interrupts(ah, ah->imask);
++                      ath9k_hw_set_interrupts(ah);
+               }
+       }
+--- a/drivers/net/wireless/ath/ath9k/recv.c
++++ b/drivers/net/wireless/ath/ath9k/recv.c
+@@ -1977,7 +1977,7 @@ requeue:
+       if (!(ah->imask & ATH9K_INT_RXEOL)) {
+               ah->imask |= (ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
+-              ath9k_hw_set_interrupts(ah, ah->imask);
++              ath9k_hw_set_interrupts(ah);
+       }
+       return 0;
+--- a/drivers/net/wireless/ath/ath9k/mac.c
++++ b/drivers/net/wireless/ath/ath9k/mac.c
+@@ -827,9 +827,9 @@ void ath9k_hw_enable_interrupts(struct a
+ }
+ EXPORT_SYMBOL(ath9k_hw_enable_interrupts);
+-void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
++void ath9k_hw_set_interrupts(struct ath_hw *ah)
+ {
+-      enum ath9k_int omask = ah->imask;
++      enum ath9k_int ints = ah->imask;
+       u32 mask, mask2;
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
+       struct ath_common *common = ath9k_hw_common(ah);
+@@ -837,7 +837,7 @@ void ath9k_hw_set_interrupts(struct ath_
+       if (!(ints & ATH9K_INT_GLOBAL))
+               ath9k_hw_disable_interrupts(ah);
+-      ath_dbg(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
++      ath_dbg(common, ATH_DBG_INTERRUPT, "New interrupt mask 0x%x\n", ints);
+       mask = ints & ATH9K_INT_COMMON;
+       mask2 = 0;
+--- a/drivers/net/wireless/ath/ath9k/mac.h
++++ b/drivers/net/wireless/ath/ath9k/mac.h
+@@ -734,7 +734,7 @@ int ath9k_hw_beaconq_setup(struct ath_hw
+ /* Interrupt Handling */
+ bool ath9k_hw_intrpend(struct ath_hw *ah);
+-void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints);
++void ath9k_hw_set_interrupts(struct ath_hw *ah);
+ void ath9k_hw_enable_interrupts(struct ath_hw *ah);
+ void ath9k_hw_disable_interrupts(struct ath_hw *ah);
diff --git a/package/mac80211/patches/581-ath9k_cleanup_txpower_handling.patch b/package/mac80211/patches/581-ath9k_cleanup_txpower_handling.patch
new file mode 100644 (file)
index 0000000..9d92aba
--- /dev/null
@@ -0,0 +1,627 @@
+--- a/drivers/net/wireless/ath/ath.h
++++ b/drivers/net/wireless/ath/ath.h
+@@ -71,7 +71,6 @@ struct ath_regulatory {
+       char alpha2[2];
+       u16 country_code;
+       u16 max_power_level;
+-      u32 tp_scale;
+       u16 current_rd;
+       u16 current_rd_ext;
+       int16_t power_limit;
+--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+@@ -3040,6 +3040,10 @@ static u32 ath9k_hw_ar9300_get_eeprom(st
+               return (pBase->miscConfiguration >> 0x3) & 0x1;
+       case EEP_ANT_DIV_CTL1:
+               return eep->base_ext1.ant_div_control;
++      case EEP_ANTENNA_GAIN_5G:
++              return eep->modalHeader5G.antennaGain;
++      case EEP_ANTENNA_GAIN_2G:
++              return eep->modalHeader2G.antennaGain;
+       default:
+               return 0;
+       }
+@@ -4727,20 +4731,14 @@ static u16 ar9003_hw_get_max_edge_power(
+ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
+                                              struct ath9k_channel *chan,
+                                              u8 *pPwrArray, u16 cfgCtl,
+-                                             u8 twiceAntennaReduction,
+-                                             u8 twiceMaxRegulatoryPower,
++                                             u8 antenna_reduction,
+                                              u16 powerLimit)
+ {
+-      struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+       struct ath_common *common = ath9k_hw_common(ah);
+       struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep;
+       u16 twiceMaxEdgePower = MAX_RATE_POWER;
+-      static const u16 tpScaleReductionTable[5] = {
+-              0, 3, 6, 9, MAX_RATE_POWER
+-      };
+       int i;
+-      int16_t  twiceLargestAntenna;
+-      u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
++      u16 scaledPower = 0, minCtlPower;
+       static const u16 ctlModesFor11a[] = {
+               CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
+       };
+@@ -4758,28 +4756,7 @@ static void ar9003_hw_set_power_per_rate
+       bool is2ghz = IS_CHAN_2GHZ(chan);
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+-
+-      /* Compute TxPower reduction due to Antenna Gain */
+-      if (is2ghz)
+-              twiceLargestAntenna = pEepData->modalHeader2G.antennaGain;
+-      else
+-              twiceLargestAntenna = pEepData->modalHeader5G.antennaGain;
+-
+-      twiceLargestAntenna = (int16_t)min((twiceAntennaReduction) -
+-                              twiceLargestAntenna, 0);
+-
+-      /*
+-       * scaledPower is the minimum of the user input power level
+-       * and the regulatory allowed power level
+-       */
+-      maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
+-
+-      if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
+-              maxRegAllowedPower -=
+-                      (tpScaleReductionTable[(regulatory->tp_scale)] * 2);
+-      }
+-
+-      scaledPower = min(powerLimit, maxRegAllowedPower);
++      scaledPower = powerLimit - antenna_reduction;
+       /*
+        * Reduce scaled Power by number of chains active to get
+@@ -4966,7 +4943,6 @@ static inline u8 mcsidx_to_tgtpwridx(uns
+ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
+                                       struct ath9k_channel *chan, u16 cfgCtl,
+                                       u8 twiceAntennaReduction,
+-                                      u8 twiceMaxRegulatoryPower,
+                                       u8 powerLimit, bool test)
+ {
+       struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+@@ -5019,7 +4995,6 @@ static void ath9k_hw_ar9300_set_txpower(
+       ar9003_hw_set_power_per_rate_table(ah, chan,
+                                          targetPowerValT2, cfgCtl,
+                                          twiceAntennaReduction,
+-                                         twiceMaxRegulatoryPower,
+                                          powerLimit);
+       if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -429,7 +429,6 @@ static void ath9k_hw_init_defaults(struc
+       regulatory->country_code = CTRY_DEFAULT;
+       regulatory->power_limit = MAX_RATE_POWER;
+-      regulatory->tp_scale = ATH9K_TP_SCALE_MAX;
+       ah->hw_version.magic = AR5416_MAGIC;
+       ah->hw_version.subvendorid = 0;
+@@ -1396,9 +1395,7 @@ static bool ath9k_hw_chip_reset(struct a
+ static bool ath9k_hw_channel_change(struct ath_hw *ah,
+                                   struct ath9k_channel *chan)
+ {
+-      struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+       struct ath_common *common = ath9k_hw_common(ah);
+-      struct ieee80211_channel *channel = chan->chan;
+       u32 qnum;
+       int r;
+@@ -1423,14 +1420,7 @@ static bool ath9k_hw_channel_change(stru
+               return false;
+       }
+       ath9k_hw_set_clockrate(ah);
+-
+-      ah->eep_ops->set_txpower(ah, chan,
+-                           ath9k_regd_get_ctl(regulatory, chan),
+-                           channel->max_antenna_gain * 2,
+-                           channel->max_power * 2,
+-                           min((u32) MAX_RATE_POWER,
+-                           (u32) regulatory->power_limit), false);
+-
++      ath9k_hw_apply_txpower(ah, chan);
+       ath9k_hw_rfbus_done(ah);
+       if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
+@@ -2466,23 +2456,56 @@ bool ath9k_hw_disable(struct ath_hw *ah)
+ }
+ EXPORT_SYMBOL(ath9k_hw_disable);
++static int get_antenna_gain(struct ath_hw *ah, struct ath9k_channel *chan)
++{
++      enum eeprom_param gain_param;
++
++      if (IS_CHAN_2GHZ(chan))
++              gain_param = EEP_ANTENNA_GAIN_2G;
++      else
++              gain_param = EEP_ANTENNA_GAIN_5G;
++
++      return ah->eep_ops->get_eeprom(ah, gain_param);
++}
++
++void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan)
++{
++      struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
++      struct ieee80211_channel *channel;
++      int chan_pwr, new_pwr, max_gain;
++      int ant_gain, ant_reduction = 0;
++
++      if (!chan)
++              return;
++
++      channel = chan->chan;
++      chan_pwr = min_t(int, channel->max_power * 2, MAX_RATE_POWER);
++      new_pwr = min_t(int, chan_pwr, reg->power_limit);
++      max_gain = new_pwr - chan_pwr + channel->max_antenna_gain * 2;
++
++      ant_gain = get_antenna_gain(ah, chan);
++      if (ant_gain > max_gain)
++              ant_reduction = ant_gain - max_gain;
++
++      ah->eep_ops->set_txpower(ah, chan,
++                               ath9k_regd_get_ctl(reg, chan),
++                               ant_reduction, new_pwr, false);
++}
++
+ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test)
+ {
+-      struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
++      struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
+       struct ath9k_channel *chan = ah->curchan;
+       struct ieee80211_channel *channel = chan->chan;
+-      int reg_pwr = min_t(int, MAX_RATE_POWER, limit);
+-      int chan_pwr = channel->max_power * 2;
++      reg->power_limit = min_t(int, limit, MAX_RATE_POWER);
+       if (test)
+-              reg_pwr = chan_pwr = MAX_RATE_POWER;
++              channel->max_power = MAX_RATE_POWER / 2;
+-      regulatory->power_limit = reg_pwr;
++      ath9k_hw_apply_txpower(ah, chan);
+-      ah->eep_ops->set_txpower(ah, chan,
+-                               ath9k_regd_get_ctl(regulatory, chan),
+-                               channel->max_antenna_gain * 2,
+-                               chan_pwr, reg_pwr, test);
++      if (test)
++              channel->max_power = DIV_ROUND_UP(reg->max_power_level, 2);
+ }
+ EXPORT_SYMBOL(ath9k_hw_set_txpowerlimit);
+--- a/drivers/net/wireless/ath/ath9k/hw.h
++++ b/drivers/net/wireless/ath/ath9k/hw.h
+@@ -389,14 +389,6 @@ enum ath9k_power_mode {
+       ATH9K_PM_UNDEFINED
+ };
+-enum ath9k_tp_scale {
+-      ATH9K_TP_SCALE_MAX = 0,
+-      ATH9K_TP_SCALE_50,
+-      ATH9K_TP_SCALE_25,
+-      ATH9K_TP_SCALE_12,
+-      ATH9K_TP_SCALE_MIN
+-};
+-
+ enum ser_reg_mode {
+       SER_REG_MODE_OFF = 0,
+       SER_REG_MODE_ON = 1,
+@@ -964,6 +956,7 @@ void ath9k_hw_htc_resetinit(struct ath_h
+ /* PHY */
+ void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
+                                  u32 *coef_mantissa, u32 *coef_exponent);
++void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan);
+ /*
+  * Code Specific to AR5008, AR9001 or AR9002,
+--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
++++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+@@ -350,6 +350,8 @@ static u32 ath9k_hw_4k_get_eeprom(struct
+               return pModal->antdiv_ctl1;
+       case EEP_TXGAIN_TYPE:
+               return pBase->txGainType;
++      case EEP_ANTENNA_GAIN_2G:
++              return pModal->antennaGainCh[0];
+       default:
+               return 0;
+       }
+@@ -462,8 +464,7 @@ static void ath9k_hw_set_4k_power_per_ra
+                                                struct ath9k_channel *chan,
+                                                int16_t *ratesArray,
+                                                u16 cfgCtl,
+-                                               u16 AntennaReduction,
+-                                               u16 twiceMaxRegulatoryPower,
++                                               u16 antenna_reduction,
+                                                u16 powerLimit)
+ {
+ #define CMP_TEST_GRP \
+@@ -472,20 +473,16 @@ static void ath9k_hw_set_4k_power_per_ra
+       || (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \
+           ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))
+-      struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+       int i;
+-      int16_t twiceLargestAntenna;
+       u16 twiceMinEdgePower;
+       u16 twiceMaxEdgePower = MAX_RATE_POWER;
+-      u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
++      u16 scaledPower = 0, minCtlPower;
+       u16 numCtlModes;
+       const u16 *pCtlMode;
+       u16 ctlMode, freq;
+       struct chan_centers centers;
+       struct cal_ctl_data_4k *rep;
+       struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
+-      static const u16 tpScaleReductionTable[5] =
+-              { 0, 3, 6, 9, MAX_RATE_POWER };
+       struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
+               0, { 0, 0, 0, 0}
+       };
+@@ -503,19 +500,7 @@ static void ath9k_hw_set_4k_power_per_ra
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+-      twiceLargestAntenna = pEepData->modalHeader.antennaGainCh[0];
+-      twiceLargestAntenna = (int16_t)min(AntennaReduction -
+-                                         twiceLargestAntenna, 0);
+-
+-      maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
+-      if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
+-              maxRegAllowedPower -=
+-                      (tpScaleReductionTable[(regulatory->tp_scale)] * 2);
+-      }
+-
+-      scaledPower = min(powerLimit, maxRegAllowedPower);
+-      scaledPower = max((u16)0, scaledPower);
+-
++      scaledPower = powerLimit - antenna_reduction;
+       numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40;
+       pCtlMode = ctlModesFor11g;
+@@ -671,7 +656,6 @@ static void ath9k_hw_4k_set_txpower(stru
+                                   struct ath9k_channel *chan,
+                                   u16 cfgCtl,
+                                   u8 twiceAntennaReduction,
+-                                  u8 twiceMaxRegulatoryPower,
+                                   u8 powerLimit, bool test)
+ {
+       struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+@@ -691,7 +675,6 @@ static void ath9k_hw_4k_set_txpower(stru
+       ath9k_hw_set_4k_power_per_rate_table(ah, chan,
+                                            &ratesArray[0], cfgCtl,
+                                            twiceAntennaReduction,
+-                                           twiceMaxRegulatoryPower,
+                                            powerLimit);
+       ath9k_hw_set_4k_power_cal_table(ah, chan);
+--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
++++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+@@ -336,6 +336,9 @@ static u32 ath9k_hw_ar9287_get_eeprom(st
+                       return pBase->tempSensSlopePalOn;
+               else
+                       return 0;
++      case EEP_ANTENNA_GAIN_2G:
++              return max_t(u8, pModal->antennaGainCh[0],
++                               pModal->antennaGainCh[1]);
+       default:
+               return 0;
+       }
+@@ -554,8 +557,7 @@ static void ath9k_hw_set_ar9287_power_pe
+                                                    struct ath9k_channel *chan,
+                                                    int16_t *ratesArray,
+                                                    u16 cfgCtl,
+-                                                   u16 AntennaReduction,
+-                                                   u16 twiceMaxRegulatoryPower,
++                                                   u16 antenna_reduction,
+                                                    u16 powerLimit)
+ {
+ #define CMP_CTL \
+@@ -569,12 +571,8 @@ static void ath9k_hw_set_ar9287_power_pe
+ #define REDUCE_SCALED_POWER_BY_TWO_CHAIN     6
+ #define REDUCE_SCALED_POWER_BY_THREE_CHAIN   10
+-      struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+       u16 twiceMaxEdgePower = MAX_RATE_POWER;
+-      static const u16 tpScaleReductionTable[5] =
+-              { 0, 3, 6, 9, MAX_RATE_POWER };
+       int i;
+-      int16_t twiceLargestAntenna;
+       struct cal_ctl_data_ar9287 *rep;
+       struct cal_target_power_leg targetPowerOfdm = {0, {0, 0, 0, 0} },
+                                   targetPowerCck = {0, {0, 0, 0, 0} };
+@@ -582,7 +580,7 @@ static void ath9k_hw_set_ar9287_power_pe
+                                   targetPowerCckExt = {0, {0, 0, 0, 0} };
+       struct cal_target_power_ht targetPowerHt20,
+                                   targetPowerHt40 = {0, {0, 0, 0, 0} };
+-      u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
++      u16 scaledPower = 0, minCtlPower;
+       static const u16 ctlModesFor11g[] = {
+               CTL_11B, CTL_11G, CTL_2GHT20,
+               CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40
+@@ -597,24 +595,7 @@ static void ath9k_hw_set_ar9287_power_pe
+       tx_chainmask = ah->txchainmask;
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+-
+-      /* Compute TxPower reduction due to Antenna Gain */
+-      twiceLargestAntenna = max(pEepData->modalHeader.antennaGainCh[0],
+-                                pEepData->modalHeader.antennaGainCh[1]);
+-      twiceLargestAntenna = (int16_t)min((AntennaReduction) -
+-                                         twiceLargestAntenna, 0);
+-
+-      /*
+-       * scaledPower is the minimum of the user input power level
+-       * and the regulatory allowed power level.
+-       */
+-      maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
+-
+-      if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX)
+-              maxRegAllowedPower -=
+-                      (tpScaleReductionTable[(regulatory->tp_scale)] * 2);
+-
+-      scaledPower = min(powerLimit, maxRegAllowedPower);
++      scaledPower = powerLimit - antenna_reduction;
+       /*
+        * Reduce scaled Power by number of chains active
+@@ -815,7 +796,6 @@ static void ath9k_hw_set_ar9287_power_pe
+ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
+                                       struct ath9k_channel *chan, u16 cfgCtl,
+                                       u8 twiceAntennaReduction,
+-                                      u8 twiceMaxRegulatoryPower,
+                                       u8 powerLimit, bool test)
+ {
+       struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+@@ -834,7 +814,6 @@ static void ath9k_hw_ar9287_set_txpower(
+       ath9k_hw_set_ar9287_power_per_rate_table(ah, chan,
+                                                &ratesArray[0], cfgCtl,
+                                                twiceAntennaReduction,
+-                                               twiceMaxRegulatoryPower,
+                                                powerLimit);
+       ath9k_hw_set_ar9287_power_cal_table(ah, chan);
+--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
++++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
+@@ -400,6 +400,7 @@ static u32 ath9k_hw_def_get_eeprom(struc
+       struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+       struct modal_eep_header *pModal = eep->modalHeader;
+       struct base_eep_header *pBase = &eep->baseEepHeader;
++      int band = 0;
+       switch (param) {
+       case EEP_NFTHRESH_5:
+@@ -467,6 +468,14 @@ static u32 ath9k_hw_def_get_eeprom(struc
+                       return pBase->pwr_table_offset;
+               else
+                       return AR5416_PWR_TABLE_OFFSET_DB;
++      case EEP_ANTENNA_GAIN_2G:
++              band = 1;
++              /* fall through */
++      case EEP_ANTENNA_GAIN_5G:
++              return max_t(u8, max_t(u8,
++                      pModal[band].antennaGainCh[0],
++                      pModal[band].antennaGainCh[1]),
++                      pModal[band].antennaGainCh[2]);
+       default:
+               return 0;
+       }
+@@ -986,21 +995,15 @@ static void ath9k_hw_set_def_power_per_r
+                                                 struct ath9k_channel *chan,
+                                                 int16_t *ratesArray,
+                                                 u16 cfgCtl,
+-                                                u16 AntennaReduction,
+-                                                u16 twiceMaxRegulatoryPower,
++                                                u16 antenna_reduction,
+                                                 u16 powerLimit)
+ {
+ #define REDUCE_SCALED_POWER_BY_TWO_CHAIN     6  /* 10*log10(2)*2 */
+ #define REDUCE_SCALED_POWER_BY_THREE_CHAIN   9 /* 10*log10(3)*2 */
+-      struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+       struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
+       u16 twiceMaxEdgePower = MAX_RATE_POWER;
+-      static const u16 tpScaleReductionTable[5] =
+-              { 0, 3, 6, 9, MAX_RATE_POWER };
+-
+       int i;
+-      int16_t twiceLargestAntenna;
+       struct cal_ctl_data *rep;
+       struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
+               0, { 0, 0, 0, 0}
+@@ -1012,7 +1015,7 @@ static void ath9k_hw_set_def_power_per_r
+       struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
+               0, {0, 0, 0, 0}
+       };
+-      u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
++      u16 scaledPower = 0, minCtlPower;
+       static const u16 ctlModesFor11a[] = {
+               CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
+       };
+@@ -1031,27 +1034,7 @@ static void ath9k_hw_set_def_power_per_r
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+-      twiceLargestAntenna = max(
+-              pEepData->modalHeader
+-                      [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
+-              pEepData->modalHeader
+-                      [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
+-
+-      twiceLargestAntenna = max((u8)twiceLargestAntenna,
+-                                pEepData->modalHeader
+-                                [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
+-
+-      twiceLargestAntenna = (int16_t)min(AntennaReduction -
+-                                         twiceLargestAntenna, 0);
+-
+-      maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
+-
+-      if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
+-              maxRegAllowedPower -=
+-                      (tpScaleReductionTable[(regulatory->tp_scale)] * 2);
+-      }
+-
+-      scaledPower = min(powerLimit, maxRegAllowedPower);
++      scaledPower = powerLimit - antenna_reduction;
+       switch (ar5416_get_ntxchains(tx_chainmask)) {
+       case 1:
+@@ -1256,7 +1239,6 @@ static void ath9k_hw_def_set_txpower(str
+                                   struct ath9k_channel *chan,
+                                   u16 cfgCtl,
+                                   u8 twiceAntennaReduction,
+-                                  u8 twiceMaxRegulatoryPower,
+                                   u8 powerLimit, bool test)
+ {
+ #define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
+@@ -1278,7 +1260,6 @@ static void ath9k_hw_def_set_txpower(str
+       ath9k_hw_set_def_power_per_rate_table(ah, chan,
+                                              &ratesArray[0], cfgCtl,
+                                              twiceAntennaReduction,
+-                                             twiceMaxRegulatoryPower,
+                                              powerLimit);
+       ath9k_hw_set_def_power_cal_table(ah, chan);
+--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
++++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+@@ -763,10 +763,8 @@ static void ar5008_hw_set_channel_regs(s
+ static int ar5008_hw_process_ini(struct ath_hw *ah,
+                                struct ath9k_channel *chan)
+ {
+-      struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+       struct ath_common *common = ath9k_hw_common(ah);
+       int i, regWrites = 0;
+-      struct ieee80211_channel *channel = chan->chan;
+       u32 modesIndex, freqIndex;
+       switch (chan->chanmode) {
+@@ -903,14 +901,7 @@ static int ar5008_hw_process_ini(struct 
+       ar5008_hw_set_channel_regs(ah, chan);
+       ar5008_hw_init_chain_masks(ah);
+       ath9k_olc_init(ah);
+-
+-      /* Set TX power */
+-      ah->eep_ops->set_txpower(ah, chan,
+-                               ath9k_regd_get_ctl(regulatory, chan),
+-                               channel->max_antenna_gain * 2,
+-                               channel->max_power * 2,
+-                               min((u32) MAX_RATE_POWER,
+-                               (u32) regulatory->power_limit), false);
++      ath9k_hw_apply_txpower(ah, chan);
+       /* Write analog registers */
+       if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
+--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
+@@ -19,7 +19,6 @@
+ void ar9003_paprd_enable(struct ath_hw *ah, bool val)
+ {
+-      struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+       struct ath9k_channel *chan = ah->curchan;
+       struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+@@ -54,13 +53,7 @@ void ar9003_paprd_enable(struct ath_hw *
+       if (val) {
+               ah->paprd_table_write_done = true;
+-
+-              ah->eep_ops->set_txpower(ah, chan,
+-                              ath9k_regd_get_ctl(regulatory, chan),
+-                              chan->chan->max_antenna_gain * 2,
+-                              chan->chan->max_power * 2,
+-                              min((u32) MAX_RATE_POWER,
+-                              (u32) regulatory->power_limit), false);
++              ath9k_hw_apply_txpower(ah, chan);
+       }
+       REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0,
+--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+@@ -628,9 +628,7 @@ static void ar9003_hw_prog_ini(struct at
+ static int ar9003_hw_process_ini(struct ath_hw *ah,
+                                struct ath9k_channel *chan)
+ {
+-      struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+       unsigned int regWrites = 0, i;
+-      struct ieee80211_channel *channel = chan->chan;
+       u32 modesIndex;
+       switch (chan->chanmode) {
+@@ -683,14 +681,7 @@ static int ar9003_hw_process_ini(struct 
+       ar9003_hw_override_ini(ah);
+       ar9003_hw_set_channel_regs(ah, chan);
+       ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
+-
+-      /* Set TX power */
+-      ah->eep_ops->set_txpower(ah, chan,
+-                               ath9k_regd_get_ctl(regulatory, chan),
+-                               channel->max_antenna_gain * 2,
+-                               channel->max_power * 2,
+-                               min((u32) MAX_RATE_POWER,
+-                               (u32) regulatory->power_limit), false);
++      ath9k_hw_apply_txpower(ah, chan);
+       return 0;
+ }
+--- a/drivers/net/wireless/ath/ath9k/common.c
++++ b/drivers/net/wireless/ath/ath9k/common.c
+@@ -161,10 +161,12 @@ EXPORT_SYMBOL(ath9k_cmn_count_streams);
+ void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow,
+                           u16 new_txpow, u16 *txpower)
+ {
+-      if (cur_txpow != new_txpow) {
++      struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
++
++      if (reg->power_limit != new_txpow) {
+               ath9k_hw_set_txpowerlimit(ah, new_txpow, false);
+               /* read back in case value is clamped */
+-              *txpower = ath9k_hw_regulatory(ah)->power_limit;
++              *txpower = reg->max_power_level;
+       }
+ }
+ EXPORT_SYMBOL(ath9k_cmn_update_txpow);
+--- a/drivers/net/wireless/ath/ath9k/eeprom.h
++++ b/drivers/net/wireless/ath/ath9k/eeprom.h
+@@ -253,7 +253,9 @@ enum eeprom_param {
+       EEP_PAPRD,
+       EEP_MODAL_VER,
+       EEP_ANT_DIV_CTL1,
+-      EEP_CHAIN_MASK_REDUCE
++      EEP_CHAIN_MASK_REDUCE,
++      EEP_ANTENNA_GAIN_2G,
++      EEP_ANTENNA_GAIN_5G
+ };
+ enum ar5416_rates {
+@@ -657,8 +659,7 @@ struct eeprom_ops {
+       void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan);
+       void (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan,
+                          u16 cfgCtl, u8 twiceAntennaReduction,
+-                         u8 twiceMaxRegulatoryPower, u8 powerLimit,
+-                         bool test);
++                         u8 powerLimit, bool test);
+       u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz);
+ };
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -626,7 +626,6 @@ static void ath9k_init_band_txpower(stru
+       struct ieee80211_supported_band *sband;
+       struct ieee80211_channel *chan;
+       struct ath_hw *ah = sc->sc_ah;
+-      struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
+       int i;
+       sband = &sc->sbands[band];
+@@ -635,7 +634,6 @@ static void ath9k_init_band_txpower(stru
+               ah->curchan = &ah->channels[chan->hw_value];
+               ath9k_cmn_update_ichannel(ah->curchan, chan, NL80211_CHAN_HT20);
+               ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true);
+-              chan->max_power = reg->max_power_level / 2;
+       }
+ }
diff --git a/package/mac80211/patches/582-ath9k_remove_current_rd_ext.patch b/package/mac80211/patches/582-ath9k_remove_current_rd_ext.patch
new file mode 100644 (file)
index 0000000..c2f61c2
--- /dev/null
@@ -0,0 +1,34 @@
+--- a/drivers/net/wireless/ath/ath.h
++++ b/drivers/net/wireless/ath/ath.h
+@@ -72,7 +72,6 @@ struct ath_regulatory {
+       u16 country_code;
+       u16 max_power_level;
+       u16 current_rd;
+-      u16 current_rd_ext;
+       int16_t power_limit;
+       struct reg_dmn_pair_mapping *regpair;
+ };
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -2047,11 +2047,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw
+       eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0);
+       regulatory->current_rd = eeval;
+-      eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_1);
+-      if (AR_SREV_9285_12_OR_LATER(ah))
+-              eeval |= AR9285_RDEXT_DEFAULT;
+-      regulatory->current_rd_ext = eeval;
+-
+       if (ah->opmode != NL80211_IFTYPE_AP &&
+           ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) {
+               if (regulatory->current_rd == 0x64 ||
+--- a/drivers/net/wireless/ath/carl9170/main.c
++++ b/drivers/net/wireless/ath/carl9170/main.c
+@@ -1912,7 +1912,6 @@ static int carl9170_parse_eeprom(struct 
+               ar->hw->channel_change_time = 80 * 1000;
+       regulatory->current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]);
+-      regulatory->current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]);
+       /* second part of wiphy init */
+       SET_IEEE80211_PERM_ADDR(ar->hw, ar->eeprom.mac_address);
diff --git a/package/mac80211/patches/583-ath9k_remove_eep_reg_1.patch b/package/mac80211/patches/583-ath9k_remove_eep_reg_1.patch
new file mode 100644 (file)
index 0000000..feaa30d
--- /dev/null
@@ -0,0 +1,54 @@
+--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
++++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
+@@ -415,8 +415,6 @@ static u32 ath9k_hw_def_get_eeprom(struc
+               return get_unaligned_be16(pBase->macAddr + 4);
+       case EEP_REG_0:
+               return pBase->regDmn[0];
+-      case EEP_REG_1:
+-              return pBase->regDmn[1];
+       case EEP_OP_CAP:
+               return pBase->deviceCap;
+       case EEP_OP_MODE:
+--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
++++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+@@ -322,8 +322,6 @@ static u32 ath9k_hw_4k_get_eeprom(struct
+               return get_unaligned_be16(pBase->macAddr + 4);
+       case EEP_REG_0:
+               return pBase->regDmn[0];
+-      case EEP_REG_1:
+-              return pBase->regDmn[1];
+       case EEP_OP_CAP:
+               return pBase->deviceCap;
+       case EEP_OP_MODE:
+--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
++++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+@@ -308,8 +308,6 @@ static u32 ath9k_hw_ar9287_get_eeprom(st
+               return get_unaligned_be16(pBase->macAddr + 4);
+       case EEP_REG_0:
+               return pBase->regDmn[0];
+-      case EEP_REG_1:
+-              return pBase->regDmn[1];
+       case EEP_OP_CAP:
+               return pBase->deviceCap;
+       case EEP_OP_MODE:
+--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+@@ -3014,8 +3014,6 @@ static u32 ath9k_hw_ar9300_get_eeprom(st
+               return get_unaligned_be16(eep->macAddr + 4);
+       case EEP_REG_0:
+               return le16_to_cpu(pBase->regDmn[0]);
+-      case EEP_REG_1:
+-              return le16_to_cpu(pBase->regDmn[1]);
+       case EEP_OP_CAP:
+               return pBase->deviceCap;
+       case EEP_OP_MODE:
+--- a/drivers/net/wireless/ath/ath9k/eeprom.h
++++ b/drivers/net/wireless/ath/ath9k/eeprom.h
+@@ -225,7 +225,6 @@ enum eeprom_param {
+       EEP_MAC_MID,
+       EEP_MAC_LSW,
+       EEP_REG_0,
+-      EEP_REG_1,
+       EEP_OP_CAP,
+       EEP_OP_MODE,
+       EEP_RF_SILENT,