OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2010 Atheros Communications Inc. | 2 * Copyright (c) 2010 Atheros Communications Inc. |
3 * | 3 * |
4 * Permission to use, copy, modify, and/or distribute this software for any | 4 * Permission to use, copy, modify, and/or distribute this software for any |
5 * purpose with or without fee is hereby granted, provided that the above | 5 * purpose with or without fee is hereby granted, provided that the above |
6 * copyright notice and this permission notice appear in all copies. | 6 * copyright notice and this permission notice appear in all copies. |
7 * | 7 * |
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
(...skipping 4632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4643 pPwrArray[i] = | 4643 pPwrArray[i] = |
4644 (u8)min((u16)pPwrArray[i], | 4644 (u8)min((u16)pPwrArray[i], |
4645 minCtlPower); | 4645 minCtlPower); |
4646 break; | 4646 break; |
4647 default: | 4647 default: |
4648 break; | 4648 break; |
4649 } | 4649 } |
4650 } /* end ctl mode checking */ | 4650 } /* end ctl mode checking */ |
4651 } | 4651 } |
4652 | 4652 |
| 4653 static inline u8 mcsidx_to_tgtpwridx(unsigned int mcs_idx, u8 base_pwridx) |
| 4654 { |
| 4655 u8 mod_idx = mcs_idx % 8; |
| 4656 |
| 4657 if (mod_idx <= 3) |
| 4658 return mod_idx ? (base_pwridx + 1) : base_pwridx; |
| 4659 else |
| 4660 return base_pwridx + 4 * (mcs_idx / 8) + mod_idx - 2; |
| 4661 } |
| 4662 |
4653 static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, | 4663 static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, |
4654 struct ath9k_channel *chan, u16 cfgCtl, | 4664 struct ath9k_channel *chan, u16 cfgCtl, |
4655 u8 twiceAntennaReduction, | 4665 u8 twiceAntennaReduction, |
4656 u8 twiceMaxRegulatoryPower, | 4666 u8 twiceMaxRegulatoryPower, |
4657 u8 powerLimit) | 4667 u8 powerLimit) |
4658 { | 4668 { |
4659 struct ath_common *common = ath9k_hw_common(ah); | 4669 struct ath_common *common = ath9k_hw_common(ah); |
| 4670 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; |
| 4671 struct ar9300_modal_eep_header *modal_hdr; |
4660 u8 targetPowerValT2[ar9300RateSize]; | 4672 u8 targetPowerValT2[ar9300RateSize]; |
4661 » unsigned int i = 0; | 4673 » u8 target_power_val_t2_eep[ar9300RateSize]; |
| 4674 » unsigned int i = 0, paprd_scale_factor = 0; |
| 4675 » u8 pwr_idx, min_pwridx = 0; |
4662 | 4676 |
4663 ar9003_hw_set_target_power_eeprom(ah, chan->channel, targetPowerValT2); | 4677 ar9003_hw_set_target_power_eeprom(ah, chan->channel, targetPowerValT2); |
| 4678 |
| 4679 if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) { |
| 4680 if (IS_CHAN_2GHZ(chan)) |
| 4681 modal_hdr = &eep->modalHeader2G; |
| 4682 else |
| 4683 modal_hdr = &eep->modalHeader5G; |
| 4684 |
| 4685 ah->paprd_ratemask = |
| 4686 le32_to_cpu(modal_hdr->papdRateMaskHt20) & |
| 4687 AR9300_PAPRD_RATE_MASK; |
| 4688 |
| 4689 ah->paprd_ratemask_ht40 = |
| 4690 le32_to_cpu(modal_hdr->papdRateMaskHt40) & |
| 4691 AR9300_PAPRD_RATE_MASK; |
| 4692 |
| 4693 paprd_scale_factor = ar9003_get_paprd_scale_factor(ah, chan); |
| 4694 min_pwridx = IS_CHAN_HT40(chan) ? ALL_TARGET_HT40_0_8_16 : |
| 4695 ALL_TARGET_HT20_0_8_16; |
| 4696 |
| 4697 if (!ah->paprd_table_write_done) { |
| 4698 memcpy(target_power_val_t2_eep, targetPowerValT2, |
| 4699 sizeof(targetPowerValT2)); |
| 4700 for (i = 0; i < 24; i++) { |
| 4701 pwr_idx = mcsidx_to_tgtpwridx(i, min_pwridx); |
| 4702 if (ah->paprd_ratemask & (1 << i)) { |
| 4703 if (targetPowerValT2[pwr_idx] && |
| 4704 targetPowerValT2[pwr_idx] == |
| 4705 target_power_val_t2_eep[pwr_idx]) |
| 4706 targetPowerValT2[pwr_idx] -= |
| 4707 paprd_scale_factor; |
| 4708 } |
| 4709 } |
| 4710 } |
| 4711 memcpy(target_power_val_t2_eep, targetPowerValT2, |
| 4712 sizeof(targetPowerValT2)); |
| 4713 } |
| 4714 |
4664 ar9003_hw_set_power_per_rate_table(ah, chan, | 4715 ar9003_hw_set_power_per_rate_table(ah, chan, |
4665 targetPowerValT2, cfgCtl, | 4716 targetPowerValT2, cfgCtl, |
4666 twiceAntennaReduction, | 4717 twiceAntennaReduction, |
4667 twiceMaxRegulatoryPower, | 4718 twiceMaxRegulatoryPower, |
4668 powerLimit); | 4719 powerLimit); |
4669 | 4720 |
| 4721 if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) { |
| 4722 for (i = 0; i < ar9300RateSize; i++) { |
| 4723 if ((ah->paprd_ratemask & (1 << i)) && |
| 4724 (abs(targetPowerValT2[i] - |
| 4725 target_power_val_t2_eep[i]) > |
| 4726 paprd_scale_factor)) { |
| 4727 ah->paprd_ratemask &= ~(1 << i); |
| 4728 ath_print(common, ATH_DBG_EEPROM, |
| 4729 "paprd disabled for mcs %d\n", i); |
| 4730 } |
| 4731 } |
| 4732 } |
| 4733 |
4670 while (i < ar9300RateSize) { | 4734 while (i < ar9300RateSize) { |
4671 ath_print(common, ATH_DBG_EEPROM, | 4735 ath_print(common, ATH_DBG_EEPROM, |
4672 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); | 4736 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); |
4673 i++; | 4737 i++; |
4674 ath_print(common, ATH_DBG_EEPROM, | 4738 ath_print(common, ATH_DBG_EEPROM, |
4675 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); | 4739 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); |
4676 i++; | 4740 i++; |
4677 ath_print(common, ATH_DBG_EEPROM, | 4741 ath_print(common, ATH_DBG_EEPROM, |
4678 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); | 4742 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); |
4679 i++; | 4743 i++; |
(...skipping 18 matching lines...) Expand all Loading... |
4698 */ | 4762 */ |
4699 i = ALL_TARGET_LEGACY_6_24; /* legacy */ | 4763 i = ALL_TARGET_LEGACY_6_24; /* legacy */ |
4700 if (IS_CHAN_HT40(chan)) | 4764 if (IS_CHAN_HT40(chan)) |
4701 i = ALL_TARGET_HT40_0_8_16; /* ht40 */ | 4765 i = ALL_TARGET_HT40_0_8_16; /* ht40 */ |
4702 else if (IS_CHAN_HT20(chan)) | 4766 else if (IS_CHAN_HT20(chan)) |
4703 i = ALL_TARGET_HT20_0_8_16; /* ht20 */ | 4767 i = ALL_TARGET_HT20_0_8_16; /* ht20 */ |
4704 | 4768 |
4705 ah->txpower_limit = targetPowerValT2[i]; | 4769 ah->txpower_limit = targetPowerValT2[i]; |
4706 | 4770 |
4707 ar9003_hw_calibration_apply(ah, chan->channel); | 4771 ar9003_hw_calibration_apply(ah, chan->channel); |
| 4772 |
| 4773 if (IS_CHAN_2GHZ(chan)) { |
| 4774 if (IS_CHAN_HT40(chan)) |
| 4775 i = ALL_TARGET_HT40_0_8_16; |
| 4776 else |
| 4777 i = ALL_TARGET_HT20_0_8_16; |
| 4778 } else { |
| 4779 if (IS_CHAN_HT40(chan)) |
| 4780 i = ALL_TARGET_HT40_7; |
| 4781 else |
| 4782 i = ALL_TARGET_HT20_7; |
| 4783 } |
| 4784 ah->paprd_target_power = targetPowerValT2[i]; |
4708 } | 4785 } |
4709 | 4786 |
4710 static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah, | 4787 static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah, |
4711 u16 i, bool is2GHz) | 4788 u16 i, bool is2GHz) |
4712 { | 4789 { |
4713 return AR_NO_SPUR; | 4790 return AR_NO_SPUR; |
4714 } | 4791 } |
4715 | 4792 |
4716 s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah) | 4793 s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah) |
4717 { | 4794 { |
4718 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | 4795 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; |
4719 | 4796 |
4720 return (eep->baseEepHeader.txrxgain >> 4) & 0xf; /* bits 7:4 */ | 4797 return (eep->baseEepHeader.txrxgain >> 4) & 0xf; /* bits 7:4 */ |
4721 } | 4798 } |
4722 | 4799 |
4723 s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah) | 4800 s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah) |
4724 { | 4801 { |
4725 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | 4802 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; |
4726 | 4803 |
4727 return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */ | 4804 return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */ |
4728 } | 4805 } |
4729 | 4806 |
| 4807 unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah, |
| 4808 struct ath9k_channel *chan) |
| 4809 { |
| 4810 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; |
| 4811 |
| 4812 if (IS_CHAN_2GHZ(chan)) |
| 4813 return MS(le32_to_cpu(eep->modalHeader2G.papdRateMaskHt20), |
| 4814 AR9300_PAPRD_SCALE_1); |
| 4815 else { |
| 4816 if (chan->channel >= 5700) |
| 4817 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20), |
| 4818 AR9300_PAPRD_SCALE_1); |
| 4819 else if (chan->channel >= 5400) |
| 4820 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt4
0), |
| 4821 AR9300_PAPRD_SCALE_2); |
| 4822 else |
| 4823 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt4
0), |
| 4824 AR9300_PAPRD_SCALE_1); |
| 4825 } |
| 4826 } |
| 4827 |
4730 const struct eeprom_ops eep_ar9300_ops = { | 4828 const struct eeprom_ops eep_ar9300_ops = { |
4731 .check_eeprom = ath9k_hw_ar9300_check_eeprom, | 4829 .check_eeprom = ath9k_hw_ar9300_check_eeprom, |
4732 .get_eeprom = ath9k_hw_ar9300_get_eeprom, | 4830 .get_eeprom = ath9k_hw_ar9300_get_eeprom, |
4733 .fill_eeprom = ath9k_hw_ar9300_fill_eeprom, | 4831 .fill_eeprom = ath9k_hw_ar9300_fill_eeprom, |
4734 .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver, | 4832 .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver, |
4735 .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev, | 4833 .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev, |
4736 .get_num_ant_config = ath9k_hw_ar9300_get_num_ant_config, | 4834 .get_num_ant_config = ath9k_hw_ar9300_get_num_ant_config, |
4737 .get_eeprom_antenna_cfg = ath9k_hw_ar9300_get_eeprom_antenna_cfg, | 4835 .get_eeprom_antenna_cfg = ath9k_hw_ar9300_get_eeprom_antenna_cfg, |
4738 .set_board_values = ath9k_hw_ar9300_set_board_values, | 4836 .set_board_values = ath9k_hw_ar9300_set_board_values, |
4739 .set_addac = ath9k_hw_ar9300_set_addac, | 4837 .set_addac = ath9k_hw_ar9300_set_addac, |
4740 .set_txpower = ath9k_hw_ar9300_set_txpower, | 4838 .set_txpower = ath9k_hw_ar9300_set_txpower, |
4741 .get_spur_channel = ath9k_hw_ar9300_get_spur_channel | 4839 .get_spur_channel = ath9k_hw_ar9300_get_spur_channel |
4742 }; | 4840 }; |
OLD | NEW |