From: Felix Fietkau Date: Sat, 17 Sep 2011 16:02:56 +0000 (+0000) Subject: ath9k: add some cleanup patches and rework tx power handling X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=b81588bd0866017338b35434afa0232fd9df6ba7;p=openwrt%2Fstaging%2Fmans0n.git ath9k: add some cleanup patches and rework tx power handling SVN-Revision: 28253 --- diff --git a/package/mac80211/patches/531-ath9k_cur_txpower.patch b/package/mac80211/patches/531-ath9k_cur_txpower.patch index 9a2ce9e43a..894d780420 100644 --- a/package/mac80211/patches/531-ath9k_cur_txpower.patch +++ b/package/mac80211/patches/531-ath9k_cur_txpower.patch @@ -17,19 +17,3 @@ } 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 index 0000000000..8723e50410 --- /dev/null +++ b/package/mac80211/patches/580-ath9k_cleanup_set_interrupt.patch @@ -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 index 0000000000..9d92aba8b2 --- /dev/null +++ b/package/mac80211/patches/581-ath9k_cleanup_txpower_handling.patch @@ -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, ¢ers); +- +- /* 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, ¢ers); + +- 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, ¢ers); +- +- /* 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, ¢ers); + +- 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 index 0000000000..c2f61c2582 --- /dev/null +++ b/package/mac80211/patches/582-ath9k_remove_current_rd_ext.patch @@ -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 index 0000000000..feaa30d934 --- /dev/null +++ b/package/mac80211/patches/583-ath9k_remove_eep_reg_1.patch @@ -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,