diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/ar9003_eeprom.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 388 |
1 files changed, 381 insertions, 7 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index ace8d2678b18..b883b174385b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -41,6 +41,20 @@ | |||
41 | #define LE16(x) __constant_cpu_to_le16(x) | 41 | #define LE16(x) __constant_cpu_to_le16(x) |
42 | #define LE32(x) __constant_cpu_to_le32(x) | 42 | #define LE32(x) __constant_cpu_to_le32(x) |
43 | 43 | ||
44 | /* Local defines to distinguish between extension and control CTL's */ | ||
45 | #define EXT_ADDITIVE (0x8000) | ||
46 | #define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE) | ||
47 | #define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE) | ||
48 | #define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE) | ||
49 | #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */ | ||
50 | #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 9 /* 10*log10(3)*2 */ | ||
51 | #define PWRINCR_3_TO_1_CHAIN 9 /* 10*log(3)*2 */ | ||
52 | #define PWRINCR_3_TO_2_CHAIN 3 /* floor(10*log(3/2)*2) */ | ||
53 | #define PWRINCR_2_TO_1_CHAIN 6 /* 10*log(2)*2 */ | ||
54 | |||
55 | #define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */ | ||
56 | #define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */ | ||
57 | |||
44 | static const struct ar9300_eeprom ar9300_default = { | 58 | static const struct ar9300_eeprom ar9300_default = { |
45 | .eepromVersion = 2, | 59 | .eepromVersion = 2, |
46 | .templateVersion = 2, | 60 | .templateVersion = 2, |
@@ -609,6 +623,14 @@ static const struct ar9300_eeprom ar9300_default = { | |||
609 | } | 623 | } |
610 | }; | 624 | }; |
611 | 625 | ||
626 | static u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz) | ||
627 | { | ||
628 | if (fbin == AR9300_BCHAN_UNUSED) | ||
629 | return fbin; | ||
630 | |||
631 | return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin)); | ||
632 | } | ||
633 | |||
612 | static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah) | 634 | static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah) |
613 | { | 635 | { |
614 | return 0; | 636 | return 0; |
@@ -1417,9 +1439,9 @@ static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray) | |||
1417 | #undef POW_SM | 1439 | #undef POW_SM |
1418 | } | 1440 | } |
1419 | 1441 | ||
1420 | static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq) | 1442 | static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq, |
1443 | u8 *targetPowerValT2) | ||
1421 | { | 1444 | { |
1422 | u8 targetPowerValT2[ar9300RateSize]; | ||
1423 | /* XXX: hard code for now, need to get from eeprom struct */ | 1445 | /* XXX: hard code for now, need to get from eeprom struct */ |
1424 | u8 ht40PowerIncForPdadc = 0; | 1446 | u8 ht40PowerIncForPdadc = 0; |
1425 | bool is2GHz = false; | 1447 | bool is2GHz = false; |
@@ -1553,9 +1575,6 @@ static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq) | |||
1553 | "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]); | 1575 | "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]); |
1554 | i++; | 1576 | i++; |
1555 | } | 1577 | } |
1556 | |||
1557 | /* Write target power array to registers */ | ||
1558 | ar9003_hw_tx_power_regwrite(ah, targetPowerValT2); | ||
1559 | } | 1578 | } |
1560 | 1579 | ||
1561 | static int ar9003_hw_cal_pier_get(struct ath_hw *ah, | 1580 | static int ar9003_hw_cal_pier_get(struct ath_hw *ah, |
@@ -1799,14 +1818,369 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency) | |||
1799 | return 0; | 1818 | return 0; |
1800 | } | 1819 | } |
1801 | 1820 | ||
1821 | static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep, | ||
1822 | int idx, | ||
1823 | int edge, | ||
1824 | bool is2GHz) | ||
1825 | { | ||
1826 | struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G; | ||
1827 | struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G; | ||
1828 | |||
1829 | if (is2GHz) | ||
1830 | return ctl_2g[idx].ctlEdges[edge].tPower; | ||
1831 | else | ||
1832 | return ctl_5g[idx].ctlEdges[edge].tPower; | ||
1833 | } | ||
1834 | |||
1835 | static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep, | ||
1836 | int idx, | ||
1837 | unsigned int edge, | ||
1838 | u16 freq, | ||
1839 | bool is2GHz) | ||
1840 | { | ||
1841 | struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G; | ||
1842 | struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G; | ||
1843 | |||
1844 | u8 *ctl_freqbin = is2GHz ? | ||
1845 | &eep->ctl_freqbin_2G[idx][0] : | ||
1846 | &eep->ctl_freqbin_5G[idx][0]; | ||
1847 | |||
1848 | if (is2GHz) { | ||
1849 | if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq && | ||
1850 | ctl_2g[idx].ctlEdges[edge - 1].flag) | ||
1851 | return ctl_2g[idx].ctlEdges[edge - 1].tPower; | ||
1852 | } else { | ||
1853 | if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq && | ||
1854 | ctl_5g[idx].ctlEdges[edge - 1].flag) | ||
1855 | return ctl_5g[idx].ctlEdges[edge - 1].tPower; | ||
1856 | } | ||
1857 | |||
1858 | return AR9300_MAX_RATE_POWER; | ||
1859 | } | ||
1860 | |||
1861 | /* | ||
1862 | * Find the maximum conformance test limit for the given channel and CTL info | ||
1863 | */ | ||
1864 | static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep, | ||
1865 | u16 freq, int idx, bool is2GHz) | ||
1866 | { | ||
1867 | u16 twiceMaxEdgePower = AR9300_MAX_RATE_POWER; | ||
1868 | u8 *ctl_freqbin = is2GHz ? | ||
1869 | &eep->ctl_freqbin_2G[idx][0] : | ||
1870 | &eep->ctl_freqbin_5G[idx][0]; | ||
1871 | u16 num_edges = is2GHz ? | ||
1872 | AR9300_NUM_BAND_EDGES_2G : AR9300_NUM_BAND_EDGES_5G; | ||
1873 | unsigned int edge; | ||
1874 | |||
1875 | /* Get the edge power */ | ||
1876 | for (edge = 0; | ||
1877 | (edge < num_edges) && (ctl_freqbin[edge] != AR9300_BCHAN_UNUSED); | ||
1878 | edge++) { | ||
1879 | /* | ||
1880 | * If there's an exact channel match or an inband flag set | ||
1881 | * on the lower channel use the given rdEdgePower | ||
1882 | */ | ||
1883 | if (freq == ath9k_hw_fbin2freq(ctl_freqbin[edge], is2GHz)) { | ||
1884 | twiceMaxEdgePower = | ||
1885 | ar9003_hw_get_direct_edge_power(eep, idx, | ||
1886 | edge, is2GHz); | ||
1887 | break; | ||
1888 | } else if ((edge > 0) && | ||
1889 | (freq < ath9k_hw_fbin2freq(ctl_freqbin[edge], | ||
1890 | is2GHz))) { | ||
1891 | twiceMaxEdgePower = | ||
1892 | ar9003_hw_get_indirect_edge_power(eep, idx, | ||
1893 | edge, freq, | ||
1894 | is2GHz); | ||
1895 | /* | ||
1896 | * Leave loop - no more affecting edges possible in | ||
1897 | * this monotonic increasing list | ||
1898 | */ | ||
1899 | break; | ||
1900 | } | ||
1901 | } | ||
1902 | return twiceMaxEdgePower; | ||
1903 | } | ||
1904 | |||
1905 | static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah, | ||
1906 | struct ath9k_channel *chan, | ||
1907 | u8 *pPwrArray, u16 cfgCtl, | ||
1908 | u8 twiceAntennaReduction, | ||
1909 | u8 twiceMaxRegulatoryPower, | ||
1910 | u16 powerLimit) | ||
1911 | { | ||
1912 | struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); | ||
1913 | struct ath_common *common = ath9k_hw_common(ah); | ||
1914 | struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep; | ||
1915 | u16 twiceMaxEdgePower = AR9300_MAX_RATE_POWER; | ||
1916 | static const u16 tpScaleReductionTable[5] = { | ||
1917 | 0, 3, 6, 9, AR9300_MAX_RATE_POWER | ||
1918 | }; | ||
1919 | int i; | ||
1920 | int16_t twiceLargestAntenna; | ||
1921 | u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; | ||
1922 | u16 ctlModesFor11a[] = { | ||
1923 | CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 | ||
1924 | }; | ||
1925 | u16 ctlModesFor11g[] = { | ||
1926 | CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, | ||
1927 | CTL_11G_EXT, CTL_2GHT40 | ||
1928 | }; | ||
1929 | u16 numCtlModes, *pCtlMode, ctlMode, freq; | ||
1930 | struct chan_centers centers; | ||
1931 | u8 *ctlIndex; | ||
1932 | u8 ctlNum; | ||
1933 | u16 twiceMinEdgePower; | ||
1934 | bool is2ghz = IS_CHAN_2GHZ(chan); | ||
1935 | |||
1936 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
1937 | |||
1938 | /* Compute TxPower reduction due to Antenna Gain */ | ||
1939 | if (is2ghz) | ||
1940 | twiceLargestAntenna = pEepData->modalHeader2G.antennaGain; | ||
1941 | else | ||
1942 | twiceLargestAntenna = pEepData->modalHeader5G.antennaGain; | ||
1943 | |||
1944 | twiceLargestAntenna = (int16_t)min((twiceAntennaReduction) - | ||
1945 | twiceLargestAntenna, 0); | ||
1946 | |||
1947 | /* | ||
1948 | * scaledPower is the minimum of the user input power level | ||
1949 | * and the regulatory allowed power level | ||
1950 | */ | ||
1951 | maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna; | ||
1952 | |||
1953 | if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) { | ||
1954 | maxRegAllowedPower -= | ||
1955 | (tpScaleReductionTable[(regulatory->tp_scale)] * 2); | ||
1956 | } | ||
1957 | |||
1958 | scaledPower = min(powerLimit, maxRegAllowedPower); | ||
1959 | |||
1960 | /* | ||
1961 | * Reduce scaled Power by number of chains active to get | ||
1962 | * to per chain tx power level | ||
1963 | */ | ||
1964 | switch (ar5416_get_ntxchains(ah->txchainmask)) { | ||
1965 | case 1: | ||
1966 | break; | ||
1967 | case 2: | ||
1968 | scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; | ||
1969 | break; | ||
1970 | case 3: | ||
1971 | scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; | ||
1972 | break; | ||
1973 | } | ||
1974 | |||
1975 | scaledPower = max((u16)0, scaledPower); | ||
1976 | |||
1977 | /* | ||
1978 | * Get target powers from EEPROM - our baseline for TX Power | ||
1979 | */ | ||
1980 | if (is2ghz) { | ||
1981 | /* Setup for CTL modes */ | ||
1982 | /* CTL_11B, CTL_11G, CTL_2GHT20 */ | ||
1983 | numCtlModes = | ||
1984 | ARRAY_SIZE(ctlModesFor11g) - | ||
1985 | SUB_NUM_CTL_MODES_AT_2G_40; | ||
1986 | pCtlMode = ctlModesFor11g; | ||
1987 | if (IS_CHAN_HT40(chan)) | ||
1988 | /* All 2G CTL's */ | ||
1989 | numCtlModes = ARRAY_SIZE(ctlModesFor11g); | ||
1990 | } else { | ||
1991 | /* Setup for CTL modes */ | ||
1992 | /* CTL_11A, CTL_5GHT20 */ | ||
1993 | numCtlModes = ARRAY_SIZE(ctlModesFor11a) - | ||
1994 | SUB_NUM_CTL_MODES_AT_5G_40; | ||
1995 | pCtlMode = ctlModesFor11a; | ||
1996 | if (IS_CHAN_HT40(chan)) | ||
1997 | /* All 5G CTL's */ | ||
1998 | numCtlModes = ARRAY_SIZE(ctlModesFor11a); | ||
1999 | } | ||
2000 | |||
2001 | /* | ||
2002 | * For MIMO, need to apply regulatory caps individually across | ||
2003 | * dynamically running modes: CCK, OFDM, HT20, HT40 | ||
2004 | * | ||
2005 | * The outer loop walks through each possible applicable runtime mode. | ||
2006 | * The inner loop walks through each ctlIndex entry in EEPROM. | ||
2007 | * The ctl value is encoded as [7:4] == test group, [3:0] == test mode. | ||
2008 | */ | ||
2009 | for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) { | ||
2010 | bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) || | ||
2011 | (pCtlMode[ctlMode] == CTL_2GHT40); | ||
2012 | if (isHt40CtlMode) | ||
2013 | freq = centers.synth_center; | ||
2014 | else if (pCtlMode[ctlMode] & EXT_ADDITIVE) | ||
2015 | freq = centers.ext_center; | ||
2016 | else | ||
2017 | freq = centers.ctl_center; | ||
2018 | |||
2019 | ath_print(common, ATH_DBG_REGULATORY, | ||
2020 | "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, " | ||
2021 | "EXT_ADDITIVE %d\n", | ||
2022 | ctlMode, numCtlModes, isHt40CtlMode, | ||
2023 | (pCtlMode[ctlMode] & EXT_ADDITIVE)); | ||
2024 | |||
2025 | /* walk through each CTL index stored in EEPROM */ | ||
2026 | if (is2ghz) { | ||
2027 | ctlIndex = pEepData->ctlIndex_2G; | ||
2028 | ctlNum = AR9300_NUM_CTLS_2G; | ||
2029 | } else { | ||
2030 | ctlIndex = pEepData->ctlIndex_5G; | ||
2031 | ctlNum = AR9300_NUM_CTLS_5G; | ||
2032 | } | ||
2033 | |||
2034 | for (i = 0; (i < ctlNum) && ctlIndex[i]; i++) { | ||
2035 | ath_print(common, ATH_DBG_REGULATORY, | ||
2036 | "LOOP-Ctlidx %d: cfgCtl 0x%2.2x " | ||
2037 | "pCtlMode 0x%2.2x ctlIndex 0x%2.2x " | ||
2038 | "chan %dn", | ||
2039 | i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i], | ||
2040 | chan->channel); | ||
2041 | |||
2042 | /* | ||
2043 | * compare test group from regulatory | ||
2044 | * channel list with test mode from pCtlMode | ||
2045 | * list | ||
2046 | */ | ||
2047 | if ((((cfgCtl & ~CTL_MODE_M) | | ||
2048 | (pCtlMode[ctlMode] & CTL_MODE_M)) == | ||
2049 | ctlIndex[i]) || | ||
2050 | (((cfgCtl & ~CTL_MODE_M) | | ||
2051 | (pCtlMode[ctlMode] & CTL_MODE_M)) == | ||
2052 | ((ctlIndex[i] & CTL_MODE_M) | | ||
2053 | SD_NO_CTL))) { | ||
2054 | twiceMinEdgePower = | ||
2055 | ar9003_hw_get_max_edge_power(pEepData, | ||
2056 | freq, i, | ||
2057 | is2ghz); | ||
2058 | |||
2059 | if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) | ||
2060 | /* | ||
2061 | * Find the minimum of all CTL | ||
2062 | * edge powers that apply to | ||
2063 | * this channel | ||
2064 | */ | ||
2065 | twiceMaxEdgePower = | ||
2066 | min(twiceMaxEdgePower, | ||
2067 | twiceMinEdgePower); | ||
2068 | else { | ||
2069 | /* specific */ | ||
2070 | twiceMaxEdgePower = | ||
2071 | twiceMinEdgePower; | ||
2072 | break; | ||
2073 | } | ||
2074 | } | ||
2075 | } | ||
2076 | |||
2077 | minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower); | ||
2078 | |||
2079 | ath_print(common, ATH_DBG_REGULATORY, | ||
2080 | "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d " | ||
2081 | "sP %d minCtlPwr %d\n", | ||
2082 | ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower, | ||
2083 | scaledPower, minCtlPower); | ||
2084 | |||
2085 | /* Apply ctl mode to correct target power set */ | ||
2086 | switch (pCtlMode[ctlMode]) { | ||
2087 | case CTL_11B: | ||
2088 | for (i = ALL_TARGET_LEGACY_1L_5L; | ||
2089 | i <= ALL_TARGET_LEGACY_11S; i++) | ||
2090 | pPwrArray[i] = | ||
2091 | (u8)min((u16)pPwrArray[i], | ||
2092 | minCtlPower); | ||
2093 | break; | ||
2094 | case CTL_11A: | ||
2095 | case CTL_11G: | ||
2096 | for (i = ALL_TARGET_LEGACY_6_24; | ||
2097 | i <= ALL_TARGET_LEGACY_54; i++) | ||
2098 | pPwrArray[i] = | ||
2099 | (u8)min((u16)pPwrArray[i], | ||
2100 | minCtlPower); | ||
2101 | break; | ||
2102 | case CTL_5GHT20: | ||
2103 | case CTL_2GHT20: | ||
2104 | for (i = ALL_TARGET_HT20_0_8_16; | ||
2105 | i <= ALL_TARGET_HT20_21; i++) | ||
2106 | pPwrArray[i] = | ||
2107 | (u8)min((u16)pPwrArray[i], | ||
2108 | minCtlPower); | ||
2109 | pPwrArray[ALL_TARGET_HT20_22] = | ||
2110 | (u8)min((u16)pPwrArray[ALL_TARGET_HT20_22], | ||
2111 | minCtlPower); | ||
2112 | pPwrArray[ALL_TARGET_HT20_23] = | ||
2113 | (u8)min((u16)pPwrArray[ALL_TARGET_HT20_23], | ||
2114 | minCtlPower); | ||
2115 | break; | ||
2116 | case CTL_5GHT40: | ||
2117 | case CTL_2GHT40: | ||
2118 | for (i = ALL_TARGET_HT40_0_8_16; | ||
2119 | i <= ALL_TARGET_HT40_23; i++) | ||
2120 | pPwrArray[i] = | ||
2121 | (u8)min((u16)pPwrArray[i], | ||
2122 | minCtlPower); | ||
2123 | break; | ||
2124 | default: | ||
2125 | break; | ||
2126 | } | ||
2127 | } /* end ctl mode checking */ | ||
2128 | } | ||
2129 | |||
1802 | static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, | 2130 | static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, |
1803 | struct ath9k_channel *chan, u16 cfgCtl, | 2131 | struct ath9k_channel *chan, u16 cfgCtl, |
1804 | u8 twiceAntennaReduction, | 2132 | u8 twiceAntennaReduction, |
1805 | u8 twiceMaxRegulatoryPower, | 2133 | u8 twiceMaxRegulatoryPower, |
1806 | u8 powerLimit) | 2134 | u8 powerLimit) |
1807 | { | 2135 | { |
1808 | ah->txpower_limit = powerLimit; | 2136 | struct ath_common *common = ath9k_hw_common(ah); |
1809 | ar9003_hw_set_target_power_eeprom(ah, chan->channel); | 2137 | u8 targetPowerValT2[ar9300RateSize]; |
2138 | unsigned int i = 0; | ||
2139 | |||
2140 | ar9003_hw_set_target_power_eeprom(ah, chan->channel, targetPowerValT2); | ||
2141 | ar9003_hw_set_power_per_rate_table(ah, chan, | ||
2142 | targetPowerValT2, cfgCtl, | ||
2143 | twiceAntennaReduction, | ||
2144 | twiceMaxRegulatoryPower, | ||
2145 | powerLimit); | ||
2146 | |||
2147 | while (i < ar9300RateSize) { | ||
2148 | ath_print(common, ATH_DBG_EEPROM, | ||
2149 | "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); | ||
2150 | i++; | ||
2151 | ath_print(common, ATH_DBG_EEPROM, | ||
2152 | "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); | ||
2153 | i++; | ||
2154 | ath_print(common, ATH_DBG_EEPROM, | ||
2155 | "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); | ||
2156 | i++; | ||
2157 | ath_print(common, ATH_DBG_EEPROM, | ||
2158 | "TPC[%02d] 0x%08x\n\n", i, targetPowerValT2[i]); | ||
2159 | i++; | ||
2160 | } | ||
2161 | |||
2162 | /* Write target power array to registers */ | ||
2163 | ar9003_hw_tx_power_regwrite(ah, targetPowerValT2); | ||
2164 | |||
2165 | /* | ||
2166 | * This is the TX power we send back to driver core, | ||
2167 | * and it can use to pass to userspace to display our | ||
2168 | * currently configured TX power setting. | ||
2169 | * | ||
2170 | * Since power is rate dependent, use one of the indices | ||
2171 | * from the AR9300_Rates enum to select an entry from | ||
2172 | * targetPowerValT2[] to report. Currently returns the | ||
2173 | * power for HT40 MCS 0, HT20 MCS 0, or OFDM 6 Mbps | ||
2174 | * as CCK power is less interesting (?). | ||
2175 | */ | ||
2176 | i = ALL_TARGET_LEGACY_6_24; /* legacy */ | ||
2177 | if (IS_CHAN_HT40(chan)) | ||
2178 | i = ALL_TARGET_HT40_0_8_16; /* ht40 */ | ||
2179 | else if (IS_CHAN_HT20(chan)) | ||
2180 | i = ALL_TARGET_HT20_0_8_16; /* ht20 */ | ||
2181 | |||
2182 | ah->txpower_limit = targetPowerValT2[i]; | ||
2183 | |||
1810 | ar9003_hw_calibration_apply(ah, chan->channel); | 2184 | ar9003_hw_calibration_apply(ah, chan->channel); |
1811 | } | 2185 | } |
1812 | 2186 | ||