diff options
author | Rafał Miłecki <zajec5@gmail.com> | 2012-07-24 13:18:20 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-08-06 14:56:32 -0400 |
commit | d11d354b7b02aac09a20a8157bf990670f169f6f (patch) | |
tree | 8bf20263212a60e5718036a4053142f52fdcdc4d /drivers/net | |
parent | fa0f2b38607e19a77096173a8d592cff6f10b32e (diff) |
b43: N-PHY: add PHY rev7+ workarounds
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/b43/phy_n.c | 328 |
1 files changed, 326 insertions, 2 deletions
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 40bb63d4c39e..e49d847c59f8 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c | |||
@@ -1860,12 +1860,334 @@ static void b43_nphy_gain_ctl_workarounds_rev1_2(struct b43_wldev *dev) | |||
1860 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */ | 1860 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */ |
1861 | static void b43_nphy_gain_ctl_workarounds(struct b43_wldev *dev) | 1861 | static void b43_nphy_gain_ctl_workarounds(struct b43_wldev *dev) |
1862 | { | 1862 | { |
1863 | if (dev->phy.rev >= 3) | 1863 | if (dev->phy.rev >= 7) |
1864 | ; /* TODO */ | ||
1865 | else if (dev->phy.rev >= 3) | ||
1864 | b43_nphy_gain_ctl_workarounds_rev3plus(dev); | 1866 | b43_nphy_gain_ctl_workarounds_rev3plus(dev); |
1865 | else | 1867 | else |
1866 | b43_nphy_gain_ctl_workarounds_rev1_2(dev); | 1868 | b43_nphy_gain_ctl_workarounds_rev1_2(dev); |
1867 | } | 1869 | } |
1868 | 1870 | ||
1871 | /* http://bcm-v4.sipsolutions.net/PHY/N/Read_Lpf_Bw_Ctl */ | ||
1872 | static u16 b43_nphy_read_lpf_ctl(struct b43_wldev *dev, u16 offset) | ||
1873 | { | ||
1874 | if (!offset) | ||
1875 | offset = (dev->phy.is_40mhz) ? 0x159 : 0x154; | ||
1876 | return b43_ntab_read(dev, B43_NTAB16(7, offset)) & 0x7; | ||
1877 | } | ||
1878 | |||
1879 | static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev) | ||
1880 | { | ||
1881 | struct ssb_sprom *sprom = dev->dev->bus_sprom; | ||
1882 | struct b43_phy *phy = &dev->phy; | ||
1883 | |||
1884 | u8 rx2tx_events_ipa[9] = { 0x0, 0x1, 0x2, 0x8, 0x5, 0x6, 0xF, 0x3, | ||
1885 | 0x1F }; | ||
1886 | u8 rx2tx_delays_ipa[9] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 }; | ||
1887 | |||
1888 | u16 ntab7_15e_16e[] = { 0x10f, 0x10f }; | ||
1889 | u8 ntab7_138_146[] = { 0x11, 0x11 }; | ||
1890 | u8 ntab7_133[] = { 0x77, 0x11, 0x11 }; | ||
1891 | |||
1892 | u16 lpf_20, lpf_40, lpf_11b; | ||
1893 | u16 bcap_val, bcap_val_11b, bcap_val_11n_20, bcap_val_11n_40; | ||
1894 | u16 scap_val, scap_val_11b, scap_val_11n_20, scap_val_11n_40; | ||
1895 | bool rccal_ovrd = false; | ||
1896 | |||
1897 | u16 rx2tx_lut_20_11b, rx2tx_lut_20_11n, rx2tx_lut_40_11n; | ||
1898 | u16 bias, conv, filt; | ||
1899 | |||
1900 | u32 tmp32; | ||
1901 | u8 core; | ||
1902 | |||
1903 | if (phy->rev == 7) { | ||
1904 | b43_phy_set(dev, B43_NPHY_FINERX2_CGC, 0x10); | ||
1905 | b43_phy_maskset(dev, B43_NPHY_FREQGAIN0, 0xFF80, 0x0020); | ||
1906 | b43_phy_maskset(dev, B43_NPHY_FREQGAIN0, 0x80FF, 0x2700); | ||
1907 | b43_phy_maskset(dev, B43_NPHY_FREQGAIN1, 0xFF80, 0x002E); | ||
1908 | b43_phy_maskset(dev, B43_NPHY_FREQGAIN1, 0x80FF, 0x3300); | ||
1909 | b43_phy_maskset(dev, B43_NPHY_FREQGAIN2, 0xFF80, 0x0037); | ||
1910 | b43_phy_maskset(dev, B43_NPHY_FREQGAIN2, 0x80FF, 0x3A00); | ||
1911 | b43_phy_maskset(dev, B43_NPHY_FREQGAIN3, 0xFF80, 0x003C); | ||
1912 | b43_phy_maskset(dev, B43_NPHY_FREQGAIN3, 0x80FF, 0x3E00); | ||
1913 | b43_phy_maskset(dev, B43_NPHY_FREQGAIN4, 0xFF80, 0x003E); | ||
1914 | b43_phy_maskset(dev, B43_NPHY_FREQGAIN4, 0x80FF, 0x3F00); | ||
1915 | b43_phy_maskset(dev, B43_NPHY_FREQGAIN5, 0xFF80, 0x0040); | ||
1916 | b43_phy_maskset(dev, B43_NPHY_FREQGAIN5, 0x80FF, 0x4000); | ||
1917 | b43_phy_maskset(dev, B43_NPHY_FREQGAIN6, 0xFF80, 0x0040); | ||
1918 | b43_phy_maskset(dev, B43_NPHY_FREQGAIN6, 0x80FF, 0x4000); | ||
1919 | b43_phy_maskset(dev, B43_NPHY_FREQGAIN7, 0xFF80, 0x0040); | ||
1920 | b43_phy_maskset(dev, B43_NPHY_FREQGAIN7, 0x80FF, 0x4000); | ||
1921 | } | ||
1922 | if (phy->rev <= 8) { | ||
1923 | b43_phy_write(dev, 0x23F, 0x1B0); | ||
1924 | b43_phy_write(dev, 0x240, 0x1B0); | ||
1925 | } | ||
1926 | if (phy->rev >= 8) | ||
1927 | b43_phy_maskset(dev, B43_NPHY_TXTAILCNT, ~0xFF, 0x72); | ||
1928 | |||
1929 | b43_ntab_write(dev, B43_NTAB16(8, 0x00), 2); | ||
1930 | b43_ntab_write(dev, B43_NTAB16(8, 0x10), 2); | ||
1931 | tmp32 = b43_ntab_read(dev, B43_NTAB32(30, 0)); | ||
1932 | tmp32 &= 0xffffff; | ||
1933 | b43_ntab_write(dev, B43_NTAB32(30, 0), tmp32); | ||
1934 | b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x15e), 2, ntab7_15e_16e); | ||
1935 | b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x16e), 2, ntab7_15e_16e); | ||
1936 | |||
1937 | if (b43_nphy_ipa(dev)) | ||
1938 | b43_nphy_set_rf_sequence(dev, 0, rx2tx_events_ipa, | ||
1939 | rx2tx_delays_ipa, ARRAY_SIZE(rx2tx_events_ipa)); | ||
1940 | |||
1941 | b43_phy_maskset(dev, 0x299, 0x3FFF, 0x4000); | ||
1942 | b43_phy_maskset(dev, 0x29D, 0x3FFF, 0x4000); | ||
1943 | |||
1944 | lpf_20 = b43_nphy_read_lpf_ctl(dev, 0x154); | ||
1945 | lpf_40 = b43_nphy_read_lpf_ctl(dev, 0x159); | ||
1946 | lpf_11b = b43_nphy_read_lpf_ctl(dev, 0x152); | ||
1947 | if (b43_nphy_ipa(dev)) { | ||
1948 | if ((phy->radio_rev == 5 && phy->is_40mhz) || | ||
1949 | phy->radio_rev == 7 || phy->radio_rev == 8) { | ||
1950 | bcap_val = b43_radio_read(dev, 0x16b); | ||
1951 | scap_val = b43_radio_read(dev, 0x16a); | ||
1952 | scap_val_11b = scap_val; | ||
1953 | bcap_val_11b = bcap_val; | ||
1954 | if (phy->radio_rev == 5 && phy->is_40mhz) { | ||
1955 | scap_val_11n_20 = scap_val; | ||
1956 | bcap_val_11n_20 = bcap_val; | ||
1957 | scap_val_11n_40 = bcap_val_11n_40 = 0xc; | ||
1958 | rccal_ovrd = true; | ||
1959 | } else { /* Rev 7/8 */ | ||
1960 | lpf_20 = 4; | ||
1961 | lpf_11b = 1; | ||
1962 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { | ||
1963 | scap_val_11n_20 = 0xc; | ||
1964 | bcap_val_11n_20 = 0xc; | ||
1965 | scap_val_11n_40 = 0xa; | ||
1966 | bcap_val_11n_40 = 0xa; | ||
1967 | } else { | ||
1968 | scap_val_11n_20 = 0x14; | ||
1969 | bcap_val_11n_20 = 0x14; | ||
1970 | scap_val_11n_40 = 0xf; | ||
1971 | bcap_val_11n_40 = 0xf; | ||
1972 | } | ||
1973 | rccal_ovrd = true; | ||
1974 | } | ||
1975 | } | ||
1976 | } else { | ||
1977 | if (phy->radio_rev == 5) { | ||
1978 | lpf_20 = 1; | ||
1979 | lpf_40 = 3; | ||
1980 | bcap_val = b43_radio_read(dev, 0x16b); | ||
1981 | scap_val = b43_radio_read(dev, 0x16a); | ||
1982 | scap_val_11b = scap_val; | ||
1983 | bcap_val_11b = bcap_val; | ||
1984 | scap_val_11n_20 = 0x11; | ||
1985 | scap_val_11n_40 = 0x11; | ||
1986 | bcap_val_11n_20 = 0x13; | ||
1987 | bcap_val_11n_40 = 0x13; | ||
1988 | rccal_ovrd = true; | ||
1989 | } | ||
1990 | } | ||
1991 | if (rccal_ovrd) { | ||
1992 | rx2tx_lut_20_11b = (bcap_val_11b << 8) | | ||
1993 | (scap_val_11b << 3) | | ||
1994 | lpf_11b; | ||
1995 | rx2tx_lut_20_11n = (bcap_val_11n_20 << 8) | | ||
1996 | (scap_val_11n_20 << 3) | | ||
1997 | lpf_20; | ||
1998 | rx2tx_lut_40_11n = (bcap_val_11n_40 << 8) | | ||
1999 | (scap_val_11n_40 << 3) | | ||
2000 | lpf_40; | ||
2001 | for (core = 0; core < 2; core++) { | ||
2002 | b43_ntab_write(dev, B43_NTAB16(7, 0x152 + core * 16), | ||
2003 | rx2tx_lut_20_11b); | ||
2004 | b43_ntab_write(dev, B43_NTAB16(7, 0x153 + core * 16), | ||
2005 | rx2tx_lut_20_11n); | ||
2006 | b43_ntab_write(dev, B43_NTAB16(7, 0x154 + core * 16), | ||
2007 | rx2tx_lut_20_11n); | ||
2008 | b43_ntab_write(dev, B43_NTAB16(7, 0x155 + core * 16), | ||
2009 | rx2tx_lut_40_11n); | ||
2010 | b43_ntab_write(dev, B43_NTAB16(7, 0x156 + core * 16), | ||
2011 | rx2tx_lut_40_11n); | ||
2012 | b43_ntab_write(dev, B43_NTAB16(7, 0x157 + core * 16), | ||
2013 | rx2tx_lut_40_11n); | ||
2014 | b43_ntab_write(dev, B43_NTAB16(7, 0x158 + core * 16), | ||
2015 | rx2tx_lut_40_11n); | ||
2016 | b43_ntab_write(dev, B43_NTAB16(7, 0x159 + core * 16), | ||
2017 | rx2tx_lut_40_11n); | ||
2018 | } | ||
2019 | /* b43_nphy_rf_control_override_rev7(dev, 16, 1, 3, 0, 2); */ | ||
2020 | } | ||
2021 | b43_phy_write(dev, 0x32F, 0x3); | ||
2022 | if (phy->radio_rev == 4 || phy->radio_rev == 6) | ||
2023 | ; /* b43_nphy_rf_control_override_rev7(dev, 4, 1, 3, 0, 0); */ | ||
2024 | |||
2025 | if (phy->radio_rev == 3 || phy->radio_rev == 4 || phy->radio_rev == 6) { | ||
2026 | if (sprom->revision && | ||
2027 | sprom->boardflags2_hi & B43_BFH2_IPALVLSHIFT_3P3) { | ||
2028 | b43_radio_write(dev, 0x5, 0x05); | ||
2029 | b43_radio_write(dev, 0x6, 0x30); | ||
2030 | b43_radio_write(dev, 0x7, 0x00); | ||
2031 | b43_radio_set(dev, 0x4f, 0x1); | ||
2032 | b43_radio_set(dev, 0xd4, 0x1); | ||
2033 | bias = 0x1f; | ||
2034 | conv = 0x6f; | ||
2035 | filt = 0xaa; | ||
2036 | } else { | ||
2037 | bias = 0x2b; | ||
2038 | conv = 0x7f; | ||
2039 | filt = 0xee; | ||
2040 | } | ||
2041 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { | ||
2042 | for (core = 0; core < 2; core++) { | ||
2043 | if (core == 0) { | ||
2044 | b43_radio_write(dev, 0x5F, bias); | ||
2045 | b43_radio_write(dev, 0x64, conv); | ||
2046 | b43_radio_write(dev, 0x66, filt); | ||
2047 | } else { | ||
2048 | b43_radio_write(dev, 0xE8, bias); | ||
2049 | b43_radio_write(dev, 0xE9, conv); | ||
2050 | b43_radio_write(dev, 0xEB, filt); | ||
2051 | } | ||
2052 | } | ||
2053 | } | ||
2054 | } | ||
2055 | |||
2056 | if (b43_nphy_ipa(dev)) { | ||
2057 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { | ||
2058 | if (phy->radio_rev == 3 || phy->radio_rev == 4 || | ||
2059 | phy->radio_rev == 6) { | ||
2060 | for (core = 0; core < 2; core++) { | ||
2061 | if (core == 0) | ||
2062 | b43_radio_write(dev, 0x51, | ||
2063 | 0x7f); | ||
2064 | else | ||
2065 | b43_radio_write(dev, 0xd6, | ||
2066 | 0x7f); | ||
2067 | } | ||
2068 | } | ||
2069 | if (phy->radio_rev == 3) { | ||
2070 | for (core = 0; core < 2; core++) { | ||
2071 | if (core == 0) { | ||
2072 | b43_radio_write(dev, 0x64, | ||
2073 | 0x13); | ||
2074 | b43_radio_write(dev, 0x5F, | ||
2075 | 0x1F); | ||
2076 | b43_radio_write(dev, 0x66, | ||
2077 | 0xEE); | ||
2078 | b43_radio_write(dev, 0x59, | ||
2079 | 0x8A); | ||
2080 | b43_radio_write(dev, 0x80, | ||
2081 | 0x3E); | ||
2082 | } else { | ||
2083 | b43_radio_write(dev, 0x69, | ||
2084 | 0x13); | ||
2085 | b43_radio_write(dev, 0xE8, | ||
2086 | 0x1F); | ||
2087 | b43_radio_write(dev, 0xEB, | ||
2088 | 0xEE); | ||
2089 | b43_radio_write(dev, 0xDE, | ||
2090 | 0x8A); | ||
2091 | b43_radio_write(dev, 0x105, | ||
2092 | 0x3E); | ||
2093 | } | ||
2094 | } | ||
2095 | } else if (phy->radio_rev == 7 || phy->radio_rev == 8) { | ||
2096 | if (!phy->is_40mhz) { | ||
2097 | b43_radio_write(dev, 0x5F, 0x14); | ||
2098 | b43_radio_write(dev, 0xE8, 0x12); | ||
2099 | } else { | ||
2100 | b43_radio_write(dev, 0x5F, 0x16); | ||
2101 | b43_radio_write(dev, 0xE8, 0x16); | ||
2102 | } | ||
2103 | } | ||
2104 | } else { | ||
2105 | u16 freq = phy->channel_freq; | ||
2106 | if ((freq >= 5180 && freq <= 5230) || | ||
2107 | (freq >= 5745 && freq <= 5805)) { | ||
2108 | b43_radio_write(dev, 0x7D, 0xFF); | ||
2109 | b43_radio_write(dev, 0xFE, 0xFF); | ||
2110 | } | ||
2111 | } | ||
2112 | } else { | ||
2113 | if (phy->radio_rev != 5) { | ||
2114 | for (core = 0; core < 2; core++) { | ||
2115 | if (core == 0) { | ||
2116 | b43_radio_write(dev, 0x5c, 0x61); | ||
2117 | b43_radio_write(dev, 0x51, 0x70); | ||
2118 | } else { | ||
2119 | b43_radio_write(dev, 0xe1, 0x61); | ||
2120 | b43_radio_write(dev, 0xd6, 0x70); | ||
2121 | } | ||
2122 | } | ||
2123 | } | ||
2124 | } | ||
2125 | |||
2126 | if (phy->radio_rev == 4) { | ||
2127 | b43_ntab_write(dev, B43_NTAB16(8, 0x05), 0x20); | ||
2128 | b43_ntab_write(dev, B43_NTAB16(8, 0x15), 0x20); | ||
2129 | for (core = 0; core < 2; core++) { | ||
2130 | if (core == 0) { | ||
2131 | b43_radio_write(dev, 0x1a1, 0x00); | ||
2132 | b43_radio_write(dev, 0x1a2, 0x3f); | ||
2133 | b43_radio_write(dev, 0x1a6, 0x3f); | ||
2134 | } else { | ||
2135 | b43_radio_write(dev, 0x1a7, 0x00); | ||
2136 | b43_radio_write(dev, 0x1ab, 0x3f); | ||
2137 | b43_radio_write(dev, 0x1ac, 0x3f); | ||
2138 | } | ||
2139 | } | ||
2140 | } else { | ||
2141 | b43_phy_set(dev, B43_NPHY_AFECTL_C1, 0x4); | ||
2142 | b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x4); | ||
2143 | b43_phy_set(dev, B43_NPHY_AFECTL_C2, 0x4); | ||
2144 | b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x4); | ||
2145 | |||
2146 | b43_phy_mask(dev, B43_NPHY_AFECTL_C1, ~0x1); | ||
2147 | b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x1); | ||
2148 | b43_phy_mask(dev, B43_NPHY_AFECTL_C2, ~0x1); | ||
2149 | b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x1); | ||
2150 | b43_ntab_write(dev, B43_NTAB16(8, 0x05), 0x20); | ||
2151 | b43_ntab_write(dev, B43_NTAB16(8, 0x15), 0x20); | ||
2152 | |||
2153 | b43_phy_mask(dev, B43_NPHY_AFECTL_C1, ~0x4); | ||
2154 | b43_phy_mask(dev, B43_NPHY_AFECTL_OVER1, ~0x4); | ||
2155 | b43_phy_mask(dev, B43_NPHY_AFECTL_C2, ~0x4); | ||
2156 | b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, ~0x4); | ||
2157 | } | ||
2158 | |||
2159 | b43_phy_write(dev, B43_NPHY_ENDROP_TLEN, 0x2); | ||
2160 | |||
2161 | b43_ntab_write(dev, B43_NTAB32(16, 0x100), 20); | ||
2162 | b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x138), 2, ntab7_138_146); | ||
2163 | b43_ntab_write(dev, B43_NTAB16(7, 0x141), 0x77); | ||
2164 | b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x133), 3, ntab7_133); | ||
2165 | b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x146), 2, ntab7_138_146); | ||
2166 | b43_ntab_write(dev, B43_NTAB16(7, 0x123), 0x77); | ||
2167 | b43_ntab_write(dev, B43_NTAB16(7, 0x12A), 0x77); | ||
2168 | |||
2169 | if (!phy->is_40mhz) { | ||
2170 | b43_ntab_write(dev, B43_NTAB32(16, 0x03), 0x18D); | ||
2171 | b43_ntab_write(dev, B43_NTAB32(16, 0x7F), 0x18D); | ||
2172 | } else { | ||
2173 | b43_ntab_write(dev, B43_NTAB32(16, 0x03), 0x14D); | ||
2174 | b43_ntab_write(dev, B43_NTAB32(16, 0x7F), 0x14D); | ||
2175 | } | ||
2176 | |||
2177 | b43_nphy_gain_ctl_workarounds(dev); | ||
2178 | |||
2179 | /* TODO | ||
2180 | b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x08), 4, | ||
2181 | aux_adc_vmid_rev7_core0); | ||
2182 | b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x18), 4, | ||
2183 | aux_adc_vmid_rev7_core1); | ||
2184 | b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x0C), 4, | ||
2185 | aux_adc_gain_rev7); | ||
2186 | b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x1C), 4, | ||
2187 | aux_adc_gain_rev7); | ||
2188 | */ | ||
2189 | } | ||
2190 | |||
1869 | static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev) | 2191 | static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev) |
1870 | { | 2192 | { |
1871 | struct b43_phy_n *nphy = dev->phy.n; | 2193 | struct b43_phy_n *nphy = dev->phy.n; |
@@ -2097,7 +2419,9 @@ static void b43_nphy_workarounds(struct b43_wldev *dev) | |||
2097 | b43_phy_set(dev, B43_NPHY_IQFLIP, | 2419 | b43_phy_set(dev, B43_NPHY_IQFLIP, |
2098 | B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2); | 2420 | B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2); |
2099 | 2421 | ||
2100 | if (dev->phy.rev >= 3) | 2422 | if (dev->phy.rev >= 7) |
2423 | b43_nphy_workarounds_rev7plus(dev); | ||
2424 | else if (dev->phy.rev >= 3) | ||
2101 | b43_nphy_workarounds_rev3plus(dev); | 2425 | b43_nphy_workarounds_rev3plus(dev); |
2102 | else | 2426 | else |
2103 | b43_nphy_workarounds_rev1_2(dev); | 2427 | b43_nphy_workarounds_rev1_2(dev); |