diff options
author | RA-Jay Hung <Jay_Hung@ralinktech.com> | 2011-02-20 07:55:25 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-02-21 15:39:59 -0500 |
commit | e90c54b2358559bd305ff08096e077d2a7f02bf3 (patch) | |
tree | 705409ec7f3d72a880cef20c133b739aad335ffe /drivers/net/wireless/rt2x00 | |
parent | d96aa640967ab10641a0a389a4a1569efa54ac72 (diff) |
rt2x00: Fix rt2800 txpower setting to correct value
TX_PWR_CFG_* setting need to consider below cases
-compesate 20M/40M tx power delta for 2.4/5GHZ band
-limit maximum EIRP tx power to power_level of
regulatory requirement
Signed-off-by: RA-Jay Hung <jay_hung@ralinktech.com>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800.h | 39 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800lib.c | 236 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00.h | 1 |
3 files changed, 199 insertions, 77 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index ef8f605d1081..457887c85937 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h | |||
@@ -1703,11 +1703,14 @@ struct mac_iveiv_entry { | |||
1703 | */ | 1703 | */ |
1704 | 1704 | ||
1705 | /* | 1705 | /* |
1706 | * BBP 1: TX Antenna & Power | 1706 | * BBP 1: TX Antenna & Power Control |
1707 | * POWER: 0 - normal, 1 - drop tx power by 6dBm, 2 - drop tx power by 12dBm, | 1707 | * POWER_CTRL: |
1708 | * 3 - increase tx power by 6dBm | 1708 | * 0 - normal, |
1709 | */ | 1709 | * 1 - drop tx power by 6dBm, |
1710 | #define BBP1_TX_POWER FIELD8(0x07) | 1710 | * 2 - drop tx power by 12dBm, |
1711 | * 3 - increase tx power by 6dBm | ||
1712 | */ | ||
1713 | #define BBP1_TX_POWER_CTRL FIELD8(0x07) | ||
1711 | #define BBP1_TX_ANTENNA FIELD8(0x18) | 1714 | #define BBP1_TX_ANTENNA FIELD8(0x18) |
1712 | 1715 | ||
1713 | /* | 1716 | /* |
@@ -2001,23 +2004,26 @@ struct mac_iveiv_entry { | |||
2001 | #define EEPROM_RSSI_A2_LNA_A2 FIELD16(0xff00) | 2004 | #define EEPROM_RSSI_A2_LNA_A2 FIELD16(0xff00) |
2002 | 2005 | ||
2003 | /* | 2006 | /* |
2004 | * EEPROM Maximum TX power values | 2007 | * EEPROM EIRP Maximum TX power values(unit: dbm) |
2005 | */ | 2008 | */ |
2006 | #define EEPROM_MAX_TX_POWER 0x0027 | 2009 | #define EEPROM_EIRP_MAX_TX_POWER 0x0027 |
2007 | #define EEPROM_MAX_TX_POWER_24GHZ FIELD16(0x00ff) | 2010 | #define EEPROM_EIRP_MAX_TX_POWER_2GHZ FIELD16(0x00ff) |
2008 | #define EEPROM_MAX_TX_POWER_5GHZ FIELD16(0xff00) | 2011 | #define EEPROM_EIRP_MAX_TX_POWER_5GHZ FIELD16(0xff00) |
2009 | 2012 | ||
2010 | /* | 2013 | /* |
2011 | * EEPROM TXpower delta: 20MHZ AND 40 MHZ use different power. | 2014 | * EEPROM TXpower delta: 20MHZ AND 40 MHZ use different power. |
2012 | * This is delta in 40MHZ. | 2015 | * This is delta in 40MHZ. |
2013 | * VALUE: Tx Power dalta value (MAX=4) | 2016 | * VALUE: Tx Power dalta value, MAX=4(unit: dbm) |
2014 | * TYPE: 1: Plus the delta value, 0: minus the delta value | 2017 | * TYPE: 1: Plus the delta value, 0: minus the delta value |
2015 | * TXPOWER: Enable: | 2018 | * ENABLE: enable tx power compensation for 40BW |
2016 | */ | 2019 | */ |
2017 | #define EEPROM_TXPOWER_DELTA 0x0028 | 2020 | #define EEPROM_TXPOWER_DELTA 0x0028 |
2018 | #define EEPROM_TXPOWER_DELTA_VALUE FIELD16(0x003f) | 2021 | #define EEPROM_TXPOWER_DELTA_VALUE_2G FIELD16(0x003f) |
2019 | #define EEPROM_TXPOWER_DELTA_TYPE FIELD16(0x0040) | 2022 | #define EEPROM_TXPOWER_DELTA_TYPE_2G FIELD16(0x0040) |
2020 | #define EEPROM_TXPOWER_DELTA_TXPOWER FIELD16(0x0080) | 2023 | #define EEPROM_TXPOWER_DELTA_ENABLE_2G FIELD16(0x0080) |
2024 | #define EEPROM_TXPOWER_DELTA_VALUE_5G FIELD16(0x3f00) | ||
2025 | #define EEPROM_TXPOWER_DELTA_TYPE_5G FIELD16(0x4000) | ||
2026 | #define EEPROM_TXPOWER_DELTA_ENABLE_5G FIELD16(0x8000) | ||
2021 | 2027 | ||
2022 | /* | 2028 | /* |
2023 | * EEPROM TXPOWER 802.11BG | 2029 | * EEPROM TXPOWER 802.11BG |
@@ -2215,4 +2221,9 @@ struct mac_iveiv_entry { | |||
2215 | #define TXPOWER_A_TO_DEV(__txpower) \ | 2221 | #define TXPOWER_A_TO_DEV(__txpower) \ |
2216 | clamp_t(char, __txpower, MIN_A_TXPOWER, MAX_A_TXPOWER) | 2222 | clamp_t(char, __txpower, MIN_A_TXPOWER, MAX_A_TXPOWER) |
2217 | 2223 | ||
2224 | /* | ||
2225 | * Board's maximun TX power limitation | ||
2226 | */ | ||
2227 | #define EIRP_MAX_TX_POWER_LIMIT 0x50 | ||
2228 | |||
2218 | #endif /* RT2800_H */ | 2229 | #endif /* RT2800_H */ |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index c62b4a593eb8..ab41f9e18ca9 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -1684,30 +1684,116 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |||
1684 | rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, ®); | 1684 | rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, ®); |
1685 | } | 1685 | } |
1686 | 1686 | ||
1687 | static int rt2800_get_txpower_bw_comp(struct rt2x00_dev *rt2x00dev, | ||
1688 | enum ieee80211_band band) | ||
1689 | { | ||
1690 | u16 eeprom; | ||
1691 | u8 comp_en; | ||
1692 | u8 comp_type; | ||
1693 | int comp_value; | ||
1694 | |||
1695 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_DELTA, &eeprom); | ||
1696 | |||
1697 | if (eeprom == 0xffff) | ||
1698 | return 0; | ||
1699 | |||
1700 | if (band == IEEE80211_BAND_2GHZ) { | ||
1701 | comp_en = rt2x00_get_field16(eeprom, | ||
1702 | EEPROM_TXPOWER_DELTA_ENABLE_2G); | ||
1703 | if (comp_en) { | ||
1704 | comp_type = rt2x00_get_field16(eeprom, | ||
1705 | EEPROM_TXPOWER_DELTA_TYPE_2G); | ||
1706 | comp_value = rt2x00_get_field16(eeprom, | ||
1707 | EEPROM_TXPOWER_DELTA_VALUE_2G); | ||
1708 | if (!comp_type) | ||
1709 | comp_value = -comp_value; | ||
1710 | } | ||
1711 | } else { | ||
1712 | comp_en = rt2x00_get_field16(eeprom, | ||
1713 | EEPROM_TXPOWER_DELTA_ENABLE_5G); | ||
1714 | if (comp_en) { | ||
1715 | comp_type = rt2x00_get_field16(eeprom, | ||
1716 | EEPROM_TXPOWER_DELTA_TYPE_5G); | ||
1717 | comp_value = rt2x00_get_field16(eeprom, | ||
1718 | EEPROM_TXPOWER_DELTA_VALUE_5G); | ||
1719 | if (!comp_type) | ||
1720 | comp_value = -comp_value; | ||
1721 | } | ||
1722 | } | ||
1723 | |||
1724 | return comp_value; | ||
1725 | } | ||
1726 | |||
1727 | static u8 rt2800_compesate_txpower(struct rt2x00_dev *rt2x00dev, | ||
1728 | int is_rate_b, | ||
1729 | enum ieee80211_band band, | ||
1730 | int power_level, | ||
1731 | u8 txpower) | ||
1732 | { | ||
1733 | u32 reg; | ||
1734 | u16 eeprom; | ||
1735 | u8 criterion; | ||
1736 | u8 eirp_txpower; | ||
1737 | u8 eirp_txpower_criterion; | ||
1738 | u8 reg_limit; | ||
1739 | int bw_comp = 0; | ||
1740 | |||
1741 | if (!((band == IEEE80211_BAND_5GHZ) && is_rate_b)) | ||
1742 | return txpower; | ||
1743 | |||
1744 | if (test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags)) | ||
1745 | bw_comp = rt2800_get_txpower_bw_comp(rt2x00dev, band); | ||
1746 | |||
1747 | if (test_bit(CONFIG_SUPPORT_POWER_LIMIT, &rt2x00dev->flags)) { | ||
1748 | /* | ||
1749 | * Check if eirp txpower exceed txpower_limit. | ||
1750 | * We use OFDM 6M as criterion and its eirp txpower | ||
1751 | * is stored at EEPROM_EIRP_MAX_TX_POWER. | ||
1752 | * .11b data rate need add additional 4dbm | ||
1753 | * when calculating eirp txpower. | ||
1754 | */ | ||
1755 | rt2800_register_read(rt2x00dev, TX_PWR_CFG_0, ®); | ||
1756 | criterion = rt2x00_get_field32(reg, TX_PWR_CFG_0_6MBS); | ||
1757 | |||
1758 | rt2x00_eeprom_read(rt2x00dev, | ||
1759 | EEPROM_EIRP_MAX_TX_POWER, &eeprom); | ||
1760 | |||
1761 | if (band == IEEE80211_BAND_2GHZ) | ||
1762 | eirp_txpower_criterion = rt2x00_get_field16(eeprom, | ||
1763 | EEPROM_EIRP_MAX_TX_POWER_2GHZ); | ||
1764 | else | ||
1765 | eirp_txpower_criterion = rt2x00_get_field16(eeprom, | ||
1766 | EEPROM_EIRP_MAX_TX_POWER_5GHZ); | ||
1767 | |||
1768 | eirp_txpower = eirp_txpower_criterion + (txpower - criterion) + | ||
1769 | (is_rate_b ? 4 : 0) + bw_comp; | ||
1770 | |||
1771 | reg_limit = (eirp_txpower > power_level) ? | ||
1772 | (eirp_txpower - power_level) : 0; | ||
1773 | } else | ||
1774 | reg_limit = 0; | ||
1775 | |||
1776 | return txpower + bw_comp - reg_limit; | ||
1777 | } | ||
1778 | |||
1687 | static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, | 1779 | static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, |
1688 | const int max_txpower) | 1780 | struct ieee80211_conf *conf) |
1689 | { | 1781 | { |
1690 | u8 txpower; | 1782 | u8 txpower; |
1691 | u8 max_value = (u8)max_txpower; | ||
1692 | u16 eeprom; | 1783 | u16 eeprom; |
1693 | int i; | 1784 | int i, is_rate_b; |
1694 | u32 reg; | 1785 | u32 reg; |
1695 | u8 r1; | 1786 | u8 r1; |
1696 | u32 offset; | 1787 | u32 offset; |
1788 | enum ieee80211_band band = conf->channel->band; | ||
1789 | int power_level = conf->power_level; | ||
1697 | 1790 | ||
1698 | /* | 1791 | /* |
1699 | * set to normal tx power mode: +/- 0dBm | 1792 | * set to normal bbp tx power control mode: +/- 0dBm |
1700 | */ | 1793 | */ |
1701 | rt2800_bbp_read(rt2x00dev, 1, &r1); | 1794 | rt2800_bbp_read(rt2x00dev, 1, &r1); |
1702 | rt2x00_set_field8(&r1, BBP1_TX_POWER, 0); | 1795 | rt2x00_set_field8(&r1, BBP1_TX_POWER_CTRL, 0); |
1703 | rt2800_bbp_write(rt2x00dev, 1, r1); | 1796 | rt2800_bbp_write(rt2x00dev, 1, r1); |
1704 | |||
1705 | /* | ||
1706 | * The eeprom contains the tx power values for each rate. These | ||
1707 | * values map to 100% tx power. Each 16bit word contains four tx | ||
1708 | * power values and the order is the same as used in the TX_PWR_CFG | ||
1709 | * registers. | ||
1710 | */ | ||
1711 | offset = TX_PWR_CFG_0; | 1797 | offset = TX_PWR_CFG_0; |
1712 | 1798 | ||
1713 | for (i = 0; i < EEPROM_TXPOWER_BYRATE_SIZE; i += 2) { | 1799 | for (i = 0; i < EEPROM_TXPOWER_BYRATE_SIZE; i += 2) { |
@@ -1721,73 +1807,99 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, | |||
1721 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i, | 1807 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i, |
1722 | &eeprom); | 1808 | &eeprom); |
1723 | 1809 | ||
1724 | /* TX_PWR_CFG_0: 1MBS, TX_PWR_CFG_1: 24MBS, | 1810 | is_rate_b = i ? 0 : 1; |
1811 | /* | ||
1812 | * TX_PWR_CFG_0: 1MBS, TX_PWR_CFG_1: 24MBS, | ||
1725 | * TX_PWR_CFG_2: MCS4, TX_PWR_CFG_3: MCS12, | 1813 | * TX_PWR_CFG_2: MCS4, TX_PWR_CFG_3: MCS12, |
1726 | * TX_PWR_CFG_4: unknown */ | 1814 | * TX_PWR_CFG_4: unknown |
1815 | */ | ||
1727 | txpower = rt2x00_get_field16(eeprom, | 1816 | txpower = rt2x00_get_field16(eeprom, |
1728 | EEPROM_TXPOWER_BYRATE_RATE0); | 1817 | EEPROM_TXPOWER_BYRATE_RATE0); |
1729 | rt2x00_set_field32(®, TX_PWR_CFG_RATE0, | 1818 | txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, |
1730 | min(txpower, max_value)); | 1819 | power_level, txpower); |
1820 | rt2x00_set_field32(®, TX_PWR_CFG_RATE0, txpower); | ||
1731 | 1821 | ||
1732 | /* TX_PWR_CFG_0: 2MBS, TX_PWR_CFG_1: 36MBS, | 1822 | /* |
1823 | * TX_PWR_CFG_0: 2MBS, TX_PWR_CFG_1: 36MBS, | ||
1733 | * TX_PWR_CFG_2: MCS5, TX_PWR_CFG_3: MCS13, | 1824 | * TX_PWR_CFG_2: MCS5, TX_PWR_CFG_3: MCS13, |
1734 | * TX_PWR_CFG_4: unknown */ | 1825 | * TX_PWR_CFG_4: unknown |
1826 | */ | ||
1735 | txpower = rt2x00_get_field16(eeprom, | 1827 | txpower = rt2x00_get_field16(eeprom, |
1736 | EEPROM_TXPOWER_BYRATE_RATE1); | 1828 | EEPROM_TXPOWER_BYRATE_RATE1); |
1737 | rt2x00_set_field32(®, TX_PWR_CFG_RATE1, | 1829 | txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, |
1738 | min(txpower, max_value)); | 1830 | power_level, txpower); |
1831 | rt2x00_set_field32(®, TX_PWR_CFG_RATE1, txpower); | ||
1739 | 1832 | ||
1740 | /* TX_PWR_CFG_0: 55MBS, TX_PWR_CFG_1: 48MBS, | 1833 | /* |
1834 | * TX_PWR_CFG_0: 5.5MBS, TX_PWR_CFG_1: 48MBS, | ||
1741 | * TX_PWR_CFG_2: MCS6, TX_PWR_CFG_3: MCS14, | 1835 | * TX_PWR_CFG_2: MCS6, TX_PWR_CFG_3: MCS14, |
1742 | * TX_PWR_CFG_4: unknown */ | 1836 | * TX_PWR_CFG_4: unknown |
1837 | */ | ||
1743 | txpower = rt2x00_get_field16(eeprom, | 1838 | txpower = rt2x00_get_field16(eeprom, |
1744 | EEPROM_TXPOWER_BYRATE_RATE2); | 1839 | EEPROM_TXPOWER_BYRATE_RATE2); |
1745 | rt2x00_set_field32(®, TX_PWR_CFG_RATE2, | 1840 | txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, |
1746 | min(txpower, max_value)); | 1841 | power_level, txpower); |
1842 | rt2x00_set_field32(®, TX_PWR_CFG_RATE2, txpower); | ||
1747 | 1843 | ||
1748 | /* TX_PWR_CFG_0: 11MBS, TX_PWR_CFG_1: 54MBS, | 1844 | /* |
1845 | * TX_PWR_CFG_0: 11MBS, TX_PWR_CFG_1: 54MBS, | ||
1749 | * TX_PWR_CFG_2: MCS7, TX_PWR_CFG_3: MCS15, | 1846 | * TX_PWR_CFG_2: MCS7, TX_PWR_CFG_3: MCS15, |
1750 | * TX_PWR_CFG_4: unknown */ | 1847 | * TX_PWR_CFG_4: unknown |
1848 | */ | ||
1751 | txpower = rt2x00_get_field16(eeprom, | 1849 | txpower = rt2x00_get_field16(eeprom, |
1752 | EEPROM_TXPOWER_BYRATE_RATE3); | 1850 | EEPROM_TXPOWER_BYRATE_RATE3); |
1753 | rt2x00_set_field32(®, TX_PWR_CFG_RATE3, | 1851 | txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, |
1754 | min(txpower, max_value)); | 1852 | power_level, txpower); |
1853 | rt2x00_set_field32(®, TX_PWR_CFG_RATE3, txpower); | ||
1755 | 1854 | ||
1756 | /* read the next four txpower values */ | 1855 | /* read the next four txpower values */ |
1757 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i + 1, | 1856 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i + 1, |
1758 | &eeprom); | 1857 | &eeprom); |
1759 | 1858 | ||
1760 | /* TX_PWR_CFG_0: 6MBS, TX_PWR_CFG_1: MCS0, | 1859 | is_rate_b = 0; |
1860 | /* | ||
1861 | * TX_PWR_CFG_0: 6MBS, TX_PWR_CFG_1: MCS0, | ||
1761 | * TX_PWR_CFG_2: MCS8, TX_PWR_CFG_3: unknown, | 1862 | * TX_PWR_CFG_2: MCS8, TX_PWR_CFG_3: unknown, |
1762 | * TX_PWR_CFG_4: unknown */ | 1863 | * TX_PWR_CFG_4: unknown |
1864 | */ | ||
1763 | txpower = rt2x00_get_field16(eeprom, | 1865 | txpower = rt2x00_get_field16(eeprom, |
1764 | EEPROM_TXPOWER_BYRATE_RATE0); | 1866 | EEPROM_TXPOWER_BYRATE_RATE0); |
1765 | rt2x00_set_field32(®, TX_PWR_CFG_RATE4, | 1867 | txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, |
1766 | min(txpower, max_value)); | 1868 | power_level, txpower); |
1869 | rt2x00_set_field32(®, TX_PWR_CFG_RATE4, txpower); | ||
1767 | 1870 | ||
1768 | /* TX_PWR_CFG_0: 9MBS, TX_PWR_CFG_1: MCS1, | 1871 | /* |
1872 | * TX_PWR_CFG_0: 9MBS, TX_PWR_CFG_1: MCS1, | ||
1769 | * TX_PWR_CFG_2: MCS9, TX_PWR_CFG_3: unknown, | 1873 | * TX_PWR_CFG_2: MCS9, TX_PWR_CFG_3: unknown, |
1770 | * TX_PWR_CFG_4: unknown */ | 1874 | * TX_PWR_CFG_4: unknown |
1875 | */ | ||
1771 | txpower = rt2x00_get_field16(eeprom, | 1876 | txpower = rt2x00_get_field16(eeprom, |
1772 | EEPROM_TXPOWER_BYRATE_RATE1); | 1877 | EEPROM_TXPOWER_BYRATE_RATE1); |
1773 | rt2x00_set_field32(®, TX_PWR_CFG_RATE5, | 1878 | txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, |
1774 | min(txpower, max_value)); | 1879 | power_level, txpower); |
1880 | rt2x00_set_field32(®, TX_PWR_CFG_RATE5, txpower); | ||
1775 | 1881 | ||
1776 | /* TX_PWR_CFG_0: 12MBS, TX_PWR_CFG_1: MCS2, | 1882 | /* |
1883 | * TX_PWR_CFG_0: 12MBS, TX_PWR_CFG_1: MCS2, | ||
1777 | * TX_PWR_CFG_2: MCS10, TX_PWR_CFG_3: unknown, | 1884 | * TX_PWR_CFG_2: MCS10, TX_PWR_CFG_3: unknown, |
1778 | * TX_PWR_CFG_4: unknown */ | 1885 | * TX_PWR_CFG_4: unknown |
1886 | */ | ||
1779 | txpower = rt2x00_get_field16(eeprom, | 1887 | txpower = rt2x00_get_field16(eeprom, |
1780 | EEPROM_TXPOWER_BYRATE_RATE2); | 1888 | EEPROM_TXPOWER_BYRATE_RATE2); |
1781 | rt2x00_set_field32(®, TX_PWR_CFG_RATE6, | 1889 | txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, |
1782 | min(txpower, max_value)); | 1890 | power_level, txpower); |
1891 | rt2x00_set_field32(®, TX_PWR_CFG_RATE6, txpower); | ||
1783 | 1892 | ||
1784 | /* TX_PWR_CFG_0: 18MBS, TX_PWR_CFG_1: MCS3, | 1893 | /* |
1894 | * TX_PWR_CFG_0: 18MBS, TX_PWR_CFG_1: MCS3, | ||
1785 | * TX_PWR_CFG_2: MCS11, TX_PWR_CFG_3: unknown, | 1895 | * TX_PWR_CFG_2: MCS11, TX_PWR_CFG_3: unknown, |
1786 | * TX_PWR_CFG_4: unknown */ | 1896 | * TX_PWR_CFG_4: unknown |
1897 | */ | ||
1787 | txpower = rt2x00_get_field16(eeprom, | 1898 | txpower = rt2x00_get_field16(eeprom, |
1788 | EEPROM_TXPOWER_BYRATE_RATE3); | 1899 | EEPROM_TXPOWER_BYRATE_RATE3); |
1789 | rt2x00_set_field32(®, TX_PWR_CFG_RATE7, | 1900 | txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, |
1790 | min(txpower, max_value)); | 1901 | power_level, txpower); |
1902 | rt2x00_set_field32(®, TX_PWR_CFG_RATE7, txpower); | ||
1791 | 1903 | ||
1792 | rt2800_register_write(rt2x00dev, offset, reg); | 1904 | rt2800_register_write(rt2x00dev, offset, reg); |
1793 | 1905 | ||
@@ -1846,11 +1958,13 @@ void rt2800_config(struct rt2x00_dev *rt2x00dev, | |||
1846 | /* Always recalculate LNA gain before changing configuration */ | 1958 | /* Always recalculate LNA gain before changing configuration */ |
1847 | rt2800_config_lna_gain(rt2x00dev, libconf); | 1959 | rt2800_config_lna_gain(rt2x00dev, libconf); |
1848 | 1960 | ||
1849 | if (flags & IEEE80211_CONF_CHANGE_CHANNEL) | 1961 | if (flags & IEEE80211_CONF_CHANGE_CHANNEL) { |
1850 | rt2800_config_channel(rt2x00dev, libconf->conf, | 1962 | rt2800_config_channel(rt2x00dev, libconf->conf, |
1851 | &libconf->rf, &libconf->channel); | 1963 | &libconf->rf, &libconf->channel); |
1964 | rt2800_config_txpower(rt2x00dev, libconf->conf); | ||
1965 | } | ||
1852 | if (flags & IEEE80211_CONF_CHANGE_POWER) | 1966 | if (flags & IEEE80211_CONF_CHANGE_POWER) |
1853 | rt2800_config_txpower(rt2x00dev, libconf->conf->power_level); | 1967 | rt2800_config_txpower(rt2x00dev, libconf->conf); |
1854 | if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS) | 1968 | if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS) |
1855 | rt2800_config_retry_limit(rt2x00dev, libconf); | 1969 | rt2800_config_retry_limit(rt2x00dev, libconf); |
1856 | if (flags & IEEE80211_CONF_CHANGE_PS) | 1970 | if (flags & IEEE80211_CONF_CHANGE_PS) |
@@ -3040,13 +3154,6 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
3040 | default_lna_gain); | 3154 | default_lna_gain); |
3041 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word); | 3155 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word); |
3042 | 3156 | ||
3043 | rt2x00_eeprom_read(rt2x00dev, EEPROM_MAX_TX_POWER, &word); | ||
3044 | if (rt2x00_get_field16(word, EEPROM_MAX_TX_POWER_24GHZ) == 0xff) | ||
3045 | rt2x00_set_field16(&word, EEPROM_MAX_TX_POWER_24GHZ, MAX_G_TXPOWER); | ||
3046 | if (rt2x00_get_field16(word, EEPROM_MAX_TX_POWER_5GHZ) == 0xff) | ||
3047 | rt2x00_set_field16(&word, EEPROM_MAX_TX_POWER_5GHZ, MAX_A_TXPOWER); | ||
3048 | rt2x00_eeprom_write(rt2x00dev, EEPROM_MAX_TX_POWER, word); | ||
3049 | |||
3050 | return 0; | 3157 | return 0; |
3051 | } | 3158 | } |
3052 | EXPORT_SYMBOL_GPL(rt2800_validate_eeprom); | 3159 | EXPORT_SYMBOL_GPL(rt2800_validate_eeprom); |
@@ -3162,6 +3269,15 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
3162 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &rt2x00dev->led_mcu_reg); | 3269 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &rt2x00dev->led_mcu_reg); |
3163 | #endif /* CONFIG_RT2X00_LIB_LEDS */ | 3270 | #endif /* CONFIG_RT2X00_LIB_LEDS */ |
3164 | 3271 | ||
3272 | /* | ||
3273 | * Check if support EIRP tx power limit feature. | ||
3274 | */ | ||
3275 | rt2x00_eeprom_read(rt2x00dev, EEPROM_EIRP_MAX_TX_POWER, &eeprom); | ||
3276 | |||
3277 | if (rt2x00_get_field16(eeprom, EEPROM_EIRP_MAX_TX_POWER_2GHZ) < | ||
3278 | EIRP_MAX_TX_POWER_LIMIT) | ||
3279 | __set_bit(CONFIG_SUPPORT_POWER_LIMIT, &rt2x00dev->flags); | ||
3280 | |||
3165 | return 0; | 3281 | return 0; |
3166 | } | 3282 | } |
3167 | EXPORT_SYMBOL_GPL(rt2800_init_eeprom); | 3283 | EXPORT_SYMBOL_GPL(rt2800_init_eeprom); |
@@ -3314,7 +3430,6 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
3314 | char *default_power1; | 3430 | char *default_power1; |
3315 | char *default_power2; | 3431 | char *default_power2; |
3316 | unsigned int i; | 3432 | unsigned int i; |
3317 | unsigned short max_power; | ||
3318 | u16 eeprom; | 3433 | u16 eeprom; |
3319 | 3434 | ||
3320 | /* | 3435 | /* |
@@ -3439,26 +3554,21 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
3439 | 3554 | ||
3440 | spec->channels_info = info; | 3555 | spec->channels_info = info; |
3441 | 3556 | ||
3442 | rt2x00_eeprom_read(rt2x00dev, EEPROM_MAX_TX_POWER, &eeprom); | ||
3443 | max_power = rt2x00_get_field16(eeprom, EEPROM_MAX_TX_POWER_24GHZ); | ||
3444 | default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1); | 3557 | default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1); |
3445 | default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2); | 3558 | default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2); |
3446 | 3559 | ||
3447 | for (i = 0; i < 14; i++) { | 3560 | for (i = 0; i < 14; i++) { |
3448 | info[i].max_power = max_power; | 3561 | info[i].default_power1 = default_power1[i]; |
3449 | info[i].default_power1 = TXPOWER_G_FROM_DEV(default_power1[i]); | 3562 | info[i].default_power2 = default_power2[i]; |
3450 | info[i].default_power2 = TXPOWER_G_FROM_DEV(default_power2[i]); | ||
3451 | } | 3563 | } |
3452 | 3564 | ||
3453 | if (spec->num_channels > 14) { | 3565 | if (spec->num_channels > 14) { |
3454 | max_power = rt2x00_get_field16(eeprom, EEPROM_MAX_TX_POWER_5GHZ); | ||
3455 | default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1); | 3566 | default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1); |
3456 | default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2); | 3567 | default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2); |
3457 | 3568 | ||
3458 | for (i = 14; i < spec->num_channels; i++) { | 3569 | for (i = 14; i < spec->num_channels; i++) { |
3459 | info[i].max_power = max_power; | 3570 | info[i].default_power1 = default_power1[i]; |
3460 | info[i].default_power1 = TXPOWER_A_FROM_DEV(default_power1[i]); | 3571 | info[i].default_power2 = default_power2[i]; |
3461 | info[i].default_power2 = TXPOWER_A_FROM_DEV(default_power2[i]); | ||
3462 | } | 3572 | } |
3463 | } | 3573 | } |
3464 | 3574 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index fd28836a0072..64c6ef52fe56 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -667,6 +667,7 @@ enum rt2x00_flags { | |||
667 | */ | 667 | */ |
668 | CONFIG_SUPPORT_HW_BUTTON, | 668 | CONFIG_SUPPORT_HW_BUTTON, |
669 | CONFIG_SUPPORT_HW_CRYPTO, | 669 | CONFIG_SUPPORT_HW_CRYPTO, |
670 | CONFIG_SUPPORT_POWER_LIMIT, | ||
670 | DRIVER_SUPPORT_CONTROL_FILTERS, | 671 | DRIVER_SUPPORT_CONTROL_FILTERS, |
671 | DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, | 672 | DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, |
672 | DRIVER_SUPPORT_PRE_TBTT_INTERRUPT, | 673 | DRIVER_SUPPORT_PRE_TBTT_INTERRUPT, |