0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include "b43.h"
0015 #include "main.h"
0016 #include "tables.h"
0017 #include "phy_common.h"
0018 #include "wa.h"
0019
0020 void b43_wa_initgains(struct b43_wldev *dev)
0021 {
0022 struct b43_phy *phy = &dev->phy;
0023
0024 b43_phy_write(dev, B43_PHY_LNAHPFCTL, 0x1FF9);
0025 b43_phy_mask(dev, B43_PHY_LPFGAINCTL, 0xFF0F);
0026 if (phy->rev <= 2)
0027 b43_ofdmtab_write16(dev, B43_OFDMTAB_LPFGAIN, 0, 0x1FBF);
0028 b43_radio_write16(dev, 0x0002, 0x1FBF);
0029
0030 b43_phy_write(dev, 0x0024, 0x4680);
0031 b43_phy_write(dev, 0x0020, 0x0003);
0032 b43_phy_write(dev, 0x001D, 0x0F40);
0033 b43_phy_write(dev, 0x001F, 0x1C00);
0034 if (phy->rev <= 3)
0035 b43_phy_maskset(dev, 0x002A, 0x00FF, 0x0400);
0036 else if (phy->rev == 5) {
0037 b43_phy_maskset(dev, 0x002A, 0x00FF, 0x1A00);
0038 b43_phy_write(dev, 0x00CC, 0x2121);
0039 }
0040 if (phy->rev >= 3)
0041 b43_phy_write(dev, 0x00BA, 0x3ED5);
0042 }
0043
0044 static void b43_wa_rssi_lt(struct b43_wldev *dev)
0045 {
0046 int i;
0047
0048 if (0 ) {
0049 for (i = 0; i < 8; i++)
0050 b43_ofdmtab_write16(dev, B43_OFDMTAB_RSSI, i, i + 8);
0051 for (i = 8; i < 16; i++)
0052 b43_ofdmtab_write16(dev, B43_OFDMTAB_RSSI, i, i - 8);
0053 } else {
0054 for (i = 0; i < 64; i++)
0055 b43_ofdmtab_write16(dev, B43_OFDMTAB_RSSI, i, i);
0056 }
0057 }
0058
0059 static void b43_wa_analog(struct b43_wldev *dev)
0060 {
0061 u16 ofdmrev;
0062
0063 ofdmrev = b43_phy_read(dev, B43_PHY_VERSION_OFDM) & B43_PHYVER_VERSION;
0064 if (ofdmrev > 2) {
0065 b43_phy_write(dev, B43_PHY_PWRDOWN, 0x1000);
0066 } else {
0067 b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 3, 0x1044);
0068 b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 4, 0x7201);
0069 b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 6, 0x0040);
0070 }
0071 }
0072
0073 static void b43_wa_fft(struct b43_wldev *dev)
0074 {
0075 int i;
0076
0077 for (i = 0; i < B43_TAB_FINEFREQG_SIZE; i++)
0078 b43_ofdmtab_write16(dev, B43_OFDMTAB_DACRFPABB, i,
0079 b43_tab_finefreqg[i]);
0080 }
0081
0082 static void b43_wa_nft(struct b43_wldev *dev)
0083 {
0084 struct b43_phy *phy = &dev->phy;
0085 int i;
0086
0087 if (phy->rev == 1)
0088 for (i = 0; i < B43_TAB_NOISEG1_SIZE; i++)
0089 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i,
0090 b43_tab_noiseg1[i]);
0091 else
0092 for (i = 0; i < B43_TAB_NOISEG2_SIZE; i++)
0093 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i,
0094 b43_tab_noiseg2[i]);
0095 }
0096
0097 static void b43_wa_rt(struct b43_wldev *dev)
0098 {
0099 int i;
0100
0101 for (i = 0; i < B43_TAB_ROTOR_SIZE; i++)
0102 b43_ofdmtab_write32(dev, B43_OFDMTAB_ROTOR, i, b43_tab_rotor[i]);
0103 }
0104
0105 static void b43_write_nst(struct b43_wldev *dev, const u16 *nst)
0106 {
0107 int i;
0108
0109 for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
0110 b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, i, nst[i]);
0111 }
0112
0113 static void b43_wa_nst(struct b43_wldev *dev)
0114 {
0115 struct b43_phy *phy = &dev->phy;
0116
0117 if (phy->rev >= 6) {
0118 if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN)
0119 b43_write_nst(dev, b43_tab_noisescaleg3);
0120 else
0121 b43_write_nst(dev, b43_tab_noisescaleg2);
0122 } else {
0123 b43_write_nst(dev, b43_tab_noisescaleg1);
0124 }
0125 }
0126
0127 static void b43_wa_art(struct b43_wldev *dev)
0128 {
0129 int i;
0130
0131 for (i = 0; i < B43_TAB_RETARD_SIZE; i++)
0132 b43_ofdmtab_write32(dev, B43_OFDMTAB_ADVRETARD,
0133 i, b43_tab_retard[i]);
0134 }
0135
0136 static void b43_wa_msst(struct b43_wldev *dev)
0137 {
0138 struct b43_phy *phy = &dev->phy;
0139 int i;
0140 const u16 *tab;
0141
0142 if (phy->type == B43_PHYTYPE_G) {
0143 tab = b43_tab_sigmasqr2;
0144 } else {
0145 B43_WARN_ON(1);
0146 return;
0147 }
0148
0149 for (i = 0; i < B43_TAB_SIGMASQR_SIZE; i++) {
0150 b43_ofdmtab_write16(dev, B43_OFDMTAB_MINSIGSQ,
0151 i, tab[i]);
0152 }
0153 }
0154
0155 static void b43_wa_crs_ed(struct b43_wldev *dev)
0156 {
0157 struct b43_phy *phy = &dev->phy;
0158
0159 if (phy->rev == 1) {
0160 b43_phy_write(dev, B43_PHY_CRSTHRES1_R1, 0x4F19);
0161 } else if (phy->rev == 2) {
0162 b43_phy_write(dev, B43_PHY_CRSTHRES1, 0x1861);
0163 b43_phy_write(dev, B43_PHY_CRSTHRES2, 0x0271);
0164 b43_phy_set(dev, B43_PHY_ANTDWELL, 0x0800);
0165 } else {
0166 b43_phy_write(dev, B43_PHY_CRSTHRES1, 0x0098);
0167 b43_phy_write(dev, B43_PHY_CRSTHRES2, 0x0070);
0168 b43_phy_write(dev, B43_PHY_OFDM(0xC9), 0x0080);
0169 b43_phy_set(dev, B43_PHY_ANTDWELL, 0x0800);
0170 }
0171 }
0172
0173 static void b43_wa_crs_thr(struct b43_wldev *dev)
0174 {
0175 b43_phy_maskset(dev, B43_PHY_CRS0, ~0x03C0, 0xD000);
0176 }
0177
0178 static void b43_wa_crs_blank(struct b43_wldev *dev)
0179 {
0180 b43_phy_write(dev, B43_PHY_OFDM(0x2C), 0x005A);
0181 }
0182
0183 static void b43_wa_cck_shiftbits(struct b43_wldev *dev)
0184 {
0185 b43_phy_write(dev, B43_PHY_CCKSHIFTBITS, 0x0026);
0186 }
0187
0188 static void b43_wa_wrssi_offset(struct b43_wldev *dev)
0189 {
0190 int i;
0191
0192 if (dev->phy.rev == 1) {
0193 for (i = 0; i < 16; i++) {
0194 b43_ofdmtab_write16(dev, B43_OFDMTAB_WRSSI_R1,
0195 i, 0x0020);
0196 }
0197 } else {
0198 for (i = 0; i < 32; i++) {
0199 b43_ofdmtab_write16(dev, B43_OFDMTAB_WRSSI,
0200 i, 0x0820);
0201 }
0202 }
0203 }
0204
0205 static void b43_wa_txpuoff_rxpuon(struct b43_wldev *dev)
0206 {
0207 b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_0F, 2, 15);
0208 b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_0F, 3, 20);
0209 }
0210
0211 static void b43_wa_altagc(struct b43_wldev *dev)
0212 {
0213 struct b43_phy *phy = &dev->phy;
0214
0215 if (phy->rev == 1) {
0216 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 0, 254);
0217 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 1, 13);
0218 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 2, 19);
0219 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 3, 25);
0220 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 0, 0x2710);
0221 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 1, 0x9B83);
0222 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 2, 0x9B83);
0223 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 3, 0x0F8D);
0224 b43_phy_write(dev, B43_PHY_LMS, 4);
0225 } else {
0226 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0, 254);
0227 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 1, 13);
0228 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 2, 19);
0229 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 3, 25);
0230 }
0231
0232 b43_phy_maskset(dev, B43_PHY_CCKSHIFTBITS_WA, 0x00FF, 0x5700);
0233 b43_phy_maskset(dev, B43_PHY_OFDM(0x1A), ~0x007F, 0x000F);
0234 b43_phy_maskset(dev, B43_PHY_OFDM(0x1A), ~0x3F80, 0x2B80);
0235 b43_phy_maskset(dev, B43_PHY_ANTWRSETT, 0xF0FF, 0x0300);
0236 b43_radio_set(dev, 0x7A, 0x0008);
0237 b43_phy_maskset(dev, B43_PHY_N1P1GAIN, ~0x000F, 0x0008);
0238 b43_phy_maskset(dev, B43_PHY_P1P2GAIN, ~0x0F00, 0x0600);
0239 b43_phy_maskset(dev, B43_PHY_N1N2GAIN, ~0x0F00, 0x0700);
0240 b43_phy_maskset(dev, B43_PHY_N1P1GAIN, ~0x0F00, 0x0100);
0241 if (phy->rev == 1) {
0242 b43_phy_maskset(dev, B43_PHY_N1N2GAIN, ~0x000F, 0x0007);
0243 }
0244 b43_phy_maskset(dev, B43_PHY_OFDM(0x88), ~0x00FF, 0x001C);
0245 b43_phy_maskset(dev, B43_PHY_OFDM(0x88), ~0x3F00, 0x0200);
0246 b43_phy_maskset(dev, B43_PHY_OFDM(0x96), ~0x00FF, 0x001C);
0247 b43_phy_maskset(dev, B43_PHY_OFDM(0x89), ~0x00FF, 0x0020);
0248 b43_phy_maskset(dev, B43_PHY_OFDM(0x89), ~0x3F00, 0x0200);
0249 b43_phy_maskset(dev, B43_PHY_OFDM(0x82), ~0x00FF, 0x002E);
0250 b43_phy_maskset(dev, B43_PHY_OFDM(0x96), 0x00FF, 0x1A00);
0251 b43_phy_maskset(dev, B43_PHY_OFDM(0x81), ~0x00FF, 0x0028);
0252 b43_phy_maskset(dev, B43_PHY_OFDM(0x81), 0x00FF, 0x2C00);
0253 if (phy->rev == 1) {
0254 b43_phy_write(dev, B43_PHY_PEAK_COUNT, 0x092B);
0255 b43_phy_maskset(dev, B43_PHY_OFDM(0x1B), ~0x001E, 0x0002);
0256 } else {
0257 b43_phy_mask(dev, B43_PHY_OFDM(0x1B), ~0x001E);
0258 b43_phy_write(dev, B43_PHY_OFDM(0x1F), 0x287A);
0259 b43_phy_maskset(dev, B43_PHY_LPFGAINCTL, ~0x000F, 0x0004);
0260 if (phy->rev >= 6) {
0261 b43_phy_write(dev, B43_PHY_OFDM(0x22), 0x287A);
0262 b43_phy_maskset(dev, B43_PHY_LPFGAINCTL, 0x0FFF, 0x3000);
0263 }
0264 }
0265 b43_phy_maskset(dev, B43_PHY_DIVSRCHIDX, 0x8080, 0x7874);
0266 b43_phy_write(dev, B43_PHY_OFDM(0x8E), 0x1C00);
0267 if (phy->rev == 1) {
0268 b43_phy_maskset(dev, B43_PHY_DIVP1P2GAIN, ~0x0F00, 0x0600);
0269 b43_phy_write(dev, B43_PHY_OFDM(0x8B), 0x005E);
0270 b43_phy_maskset(dev, B43_PHY_ANTWRSETT, ~0x00FF, 0x001E);
0271 b43_phy_write(dev, B43_PHY_OFDM(0x8D), 0x0002);
0272 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 0, 0);
0273 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 1, 7);
0274 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 2, 16);
0275 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 3, 28);
0276 } else {
0277 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 0, 0);
0278 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 1, 7);
0279 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 2, 16);
0280 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 3, 28);
0281 }
0282 if (phy->rev >= 6) {
0283 b43_phy_mask(dev, B43_PHY_OFDM(0x26), ~0x0003);
0284 b43_phy_mask(dev, B43_PHY_OFDM(0x26), ~0x1000);
0285 }
0286 b43_phy_read(dev, B43_PHY_VERSION_OFDM);
0287 }
0288
0289 static void b43_wa_tr_ltov(struct b43_wldev *dev)
0290 {
0291 b43_gtab_write(dev, B43_GTAB_ORIGTR, 0, 0x7654);
0292 }
0293
0294 static void b43_wa_cpll_nonpilot(struct b43_wldev *dev)
0295 {
0296 b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_11, 0, 0);
0297 b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_11, 1, 0);
0298 }
0299
0300 static void b43_wa_boards_g(struct b43_wldev *dev)
0301 {
0302 struct ssb_sprom *sprom = dev->dev->bus_sprom;
0303 struct b43_phy *phy = &dev->phy;
0304
0305 if (dev->dev->board_vendor != SSB_BOARDVENDOR_BCM ||
0306 dev->dev->board_type != SSB_BOARD_BU4306 ||
0307 dev->dev->board_rev != 0x17) {
0308 if (phy->rev < 2) {
0309 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 1, 0x0002);
0310 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 2, 0x0001);
0311 } else {
0312 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 1, 0x0002);
0313 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 2, 0x0001);
0314 if ((sprom->boardflags_lo & B43_BFL_EXTLNA) &&
0315 (phy->rev >= 7)) {
0316 b43_phy_mask(dev, B43_PHY_EXTG(0x11), 0xF7FF);
0317 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0020, 0x0001);
0318 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0021, 0x0001);
0319 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0022, 0x0001);
0320 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0023, 0x0000);
0321 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0000, 0x0000);
0322 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0003, 0x0002);
0323 }
0324 }
0325 }
0326 if (sprom->boardflags_lo & B43_BFL_FEM) {
0327 b43_phy_write(dev, B43_PHY_GTABCTL, 0x3120);
0328 b43_phy_write(dev, B43_PHY_GTABDATA, 0xC480);
0329 }
0330 }
0331
0332 void b43_wa_all(struct b43_wldev *dev)
0333 {
0334 struct b43_phy *phy = &dev->phy;
0335
0336 if (phy->type == B43_PHYTYPE_G) {
0337 switch (phy->rev) {
0338 case 1:
0339 b43_wa_crs_ed(dev);
0340 b43_wa_crs_thr(dev);
0341 b43_wa_crs_blank(dev);
0342 b43_wa_cck_shiftbits(dev);
0343 b43_wa_fft(dev);
0344 b43_wa_nft(dev);
0345 b43_wa_rt(dev);
0346 b43_wa_nst(dev);
0347 b43_wa_art(dev);
0348 b43_wa_wrssi_offset(dev);
0349 b43_wa_altagc(dev);
0350 break;
0351 case 2:
0352 case 6:
0353 case 7:
0354 case 8:
0355 case 9:
0356 b43_wa_tr_ltov(dev);
0357 b43_wa_crs_ed(dev);
0358 b43_wa_rssi_lt(dev);
0359 b43_wa_nft(dev);
0360 b43_wa_nst(dev);
0361 b43_wa_msst(dev);
0362 b43_wa_wrssi_offset(dev);
0363 b43_wa_altagc(dev);
0364 b43_wa_analog(dev);
0365 b43_wa_txpuoff_rxpuon(dev);
0366 break;
0367 default:
0368 B43_WARN_ON(1);
0369 }
0370 b43_wa_boards_g(dev);
0371 } else {
0372 B43_WARN_ON(1);
0373 }
0374
0375 b43_wa_cpll_nonpilot(dev);
0376 }