1 /* 2 3 Broadcom B43 wireless driver 4 5 PHY workarounds. 6 7 Copyright (c) 2005-2007 Stefano Brivio <stefano.brivio@polimi.it> 8 Copyright (c) 2005-2007 Michael Buesch <m@bues.ch> 9 10 This program is free software; you can redistribute it and/or modify 11 it under the terms of the GNU General Public License as published by 12 the Free Software Foundation; either version 2 of the License, or 13 (at your option) any later version. 14 15 This program is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with this program; see the file COPYING. If not, write to 22 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, 23 Boston, MA 02110-1301, USA. 24 25 */ 26 27 #include "b43.h" 28 #include "main.h" 29 #include "tables.h" 30 #include "phy_common.h" 31 #include "wa.h" 32 33 static void b43_wa_papd(struct b43_wldev *dev) 34 { 35 u16 backup; 36 37 backup = b43_ofdmtab_read16(dev, B43_OFDMTAB_PWRDYN2, 0); 38 b43_ofdmtab_write16(dev, B43_OFDMTAB_PWRDYN2, 0, 7); 39 b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_APHY, 0, 0); 40 b43_dummy_transmission(dev, true, true); 41 b43_ofdmtab_write16(dev, B43_OFDMTAB_PWRDYN2, 0, backup); 42 } 43 44 static void b43_wa_auxclipthr(struct b43_wldev *dev) 45 { 46 b43_phy_write(dev, B43_PHY_OFDM(0x8E), 0x3800); 47 } 48 49 static void b43_wa_afcdac(struct b43_wldev *dev) 50 { 51 b43_phy_write(dev, 0x0035, 0x03FF); 52 b43_phy_write(dev, 0x0036, 0x0400); 53 } 54 55 static void b43_wa_txdc_offset(struct b43_wldev *dev) 56 { 57 b43_ofdmtab_write16(dev, B43_OFDMTAB_DC, 0, 0x0051); 58 } 59 60 void b43_wa_initgains(struct b43_wldev *dev) 61 { 62 struct b43_phy *phy = &dev->phy; 63 64 b43_phy_write(dev, B43_PHY_LNAHPFCTL, 0x1FF9); 65 b43_phy_mask(dev, B43_PHY_LPFGAINCTL, 0xFF0F); 66 if (phy->rev <= 2) 67 b43_ofdmtab_write16(dev, B43_OFDMTAB_LPFGAIN, 0, 0x1FBF); 68 b43_radio_write16(dev, 0x0002, 0x1FBF); 69 70 b43_phy_write(dev, 0x0024, 0x4680); 71 b43_phy_write(dev, 0x0020, 0x0003); 72 b43_phy_write(dev, 0x001D, 0x0F40); 73 b43_phy_write(dev, 0x001F, 0x1C00); 74 if (phy->rev <= 3) 75 b43_phy_maskset(dev, 0x002A, 0x00FF, 0x0400); 76 else if (phy->rev == 5) { 77 b43_phy_maskset(dev, 0x002A, 0x00FF, 0x1A00); 78 b43_phy_write(dev, 0x00CC, 0x2121); 79 } 80 if (phy->rev >= 3) 81 b43_phy_write(dev, 0x00BA, 0x3ED5); 82 } 83 84 static void b43_wa_divider(struct b43_wldev *dev) 85 { 86 b43_phy_mask(dev, 0x002B, ~0x0100); 87 b43_phy_write(dev, 0x008E, 0x58C1); 88 } 89 90 static void b43_wa_gt(struct b43_wldev *dev) /* Gain table. */ 91 { 92 if (dev->phy.rev <= 2) { 93 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 0, 15); 94 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 1, 31); 95 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 2, 42); 96 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 3, 48); 97 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 4, 58); 98 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 0, 19); 99 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 1, 19); 100 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 2, 19); 101 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 3, 19); 102 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 4, 21); 103 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 5, 21); 104 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 6, 25); 105 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN1, 0, 3); 106 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN1, 1, 3); 107 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN1, 2, 7); 108 } else { 109 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 0, 19); 110 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 1, 19); 111 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 2, 19); 112 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 3, 19); 113 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 4, 21); 114 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 5, 21); 115 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 6, 25); 116 } 117 } 118 119 static void b43_wa_rssi_lt(struct b43_wldev *dev) /* RSSI lookup table */ 120 { 121 int i; 122 123 if (0 /* FIXME: For APHY.rev=2 this might be needed */) { 124 for (i = 0; i < 8; i++) 125 b43_ofdmtab_write16(dev, B43_OFDMTAB_RSSI, i, i + 8); 126 for (i = 8; i < 16; i++) 127 b43_ofdmtab_write16(dev, B43_OFDMTAB_RSSI, i, i - 8); 128 } else { 129 for (i = 0; i < 64; i++) 130 b43_ofdmtab_write16(dev, B43_OFDMTAB_RSSI, i, i); 131 } 132 } 133 134 static void b43_wa_analog(struct b43_wldev *dev) 135 { 136 struct b43_phy *phy = &dev->phy; 137 u16 ofdmrev; 138 139 ofdmrev = b43_phy_read(dev, B43_PHY_VERSION_OFDM) & B43_PHYVER_VERSION; 140 if (ofdmrev > 2) { 141 if (phy->type == B43_PHYTYPE_A) 142 b43_phy_write(dev, B43_PHY_PWRDOWN, 0x1808); 143 else 144 b43_phy_write(dev, B43_PHY_PWRDOWN, 0x1000); 145 } else { 146 b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 3, 0x1044); 147 b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 4, 0x7201); 148 b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 6, 0x0040); 149 } 150 } 151 152 static void b43_wa_dac(struct b43_wldev *dev) 153 { 154 if (dev->phy.analog == 1) 155 b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 1, 156 (b43_ofdmtab_read16(dev, B43_OFDMTAB_DAC, 1) & ~0x0034) | 0x0008); 157 else 158 b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 1, 159 (b43_ofdmtab_read16(dev, B43_OFDMTAB_DAC, 1) & ~0x0078) | 0x0010); 160 } 161 162 static void b43_wa_fft(struct b43_wldev *dev) /* Fine frequency table */ 163 { 164 int i; 165 166 if (dev->phy.type == B43_PHYTYPE_A) 167 for (i = 0; i < B43_TAB_FINEFREQA_SIZE; i++) 168 b43_ofdmtab_write16(dev, B43_OFDMTAB_DACRFPABB, i, b43_tab_finefreqa[i]); 169 else 170 for (i = 0; i < B43_TAB_FINEFREQG_SIZE; i++) 171 b43_ofdmtab_write16(dev, B43_OFDMTAB_DACRFPABB, i, b43_tab_finefreqg[i]); 172 } 173 174 static void b43_wa_nft(struct b43_wldev *dev) /* Noise figure table */ 175 { 176 struct b43_phy *phy = &dev->phy; 177 int i; 178 179 if (phy->type == B43_PHYTYPE_A) { 180 if (phy->rev == 2) 181 for (i = 0; i < B43_TAB_NOISEA2_SIZE; i++) 182 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i, b43_tab_noisea2[i]); 183 else 184 for (i = 0; i < B43_TAB_NOISEA3_SIZE; i++) 185 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i, b43_tab_noisea3[i]); 186 } else { 187 if (phy->rev == 1) 188 for (i = 0; i < B43_TAB_NOISEG1_SIZE; i++) 189 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i, b43_tab_noiseg1[i]); 190 else 191 for (i = 0; i < B43_TAB_NOISEG2_SIZE; i++) 192 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i, b43_tab_noiseg2[i]); 193 } 194 } 195 196 static void b43_wa_rt(struct b43_wldev *dev) /* Rotor table */ 197 { 198 int i; 199 200 for (i = 0; i < B43_TAB_ROTOR_SIZE; i++) 201 b43_ofdmtab_write32(dev, B43_OFDMTAB_ROTOR, i, b43_tab_rotor[i]); 202 } 203 204 static void b43_write_null_nst(struct b43_wldev *dev) 205 { 206 int i; 207 208 for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++) 209 b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, i, 0); 210 } 211 212 static void b43_write_nst(struct b43_wldev *dev, const u16 *nst) 213 { 214 int i; 215 216 for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++) 217 b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, i, nst[i]); 218 } 219 220 static void b43_wa_nst(struct b43_wldev *dev) /* Noise scale table */ 221 { 222 struct b43_phy *phy = &dev->phy; 223 224 if (phy->type == B43_PHYTYPE_A) { 225 if (phy->rev <= 1) 226 b43_write_null_nst(dev); 227 else if (phy->rev == 2) 228 b43_write_nst(dev, b43_tab_noisescalea2); 229 else if (phy->rev == 3) 230 b43_write_nst(dev, b43_tab_noisescalea3); 231 else 232 b43_write_nst(dev, b43_tab_noisescaleg3); 233 } else { 234 if (phy->rev >= 6) { 235 if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN) 236 b43_write_nst(dev, b43_tab_noisescaleg3); 237 else 238 b43_write_nst(dev, b43_tab_noisescaleg2); 239 } else { 240 b43_write_nst(dev, b43_tab_noisescaleg1); 241 } 242 } 243 } 244 245 static void b43_wa_art(struct b43_wldev *dev) /* ADV retard table */ 246 { 247 int i; 248 249 for (i = 0; i < B43_TAB_RETARD_SIZE; i++) 250 b43_ofdmtab_write32(dev, B43_OFDMTAB_ADVRETARD, 251 i, b43_tab_retard[i]); 252 } 253 254 static void b43_wa_txlna_gain(struct b43_wldev *dev) 255 { 256 b43_ofdmtab_write16(dev, B43_OFDMTAB_DC, 13, 0x0000); 257 } 258 259 static void b43_wa_crs_reset(struct b43_wldev *dev) 260 { 261 b43_phy_write(dev, 0x002C, 0x0064); 262 } 263 264 static void b43_wa_2060txlna_gain(struct b43_wldev *dev) 265 { 266 b43_hf_write(dev, b43_hf_read(dev) | 267 B43_HF_2060W); 268 } 269 270 static void b43_wa_lms(struct b43_wldev *dev) 271 { 272 b43_phy_maskset(dev, 0x0055, 0xFFC0, 0x0004); 273 } 274 275 static void b43_wa_mixedsignal(struct b43_wldev *dev) 276 { 277 b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 1, 3); 278 } 279 280 static void b43_wa_msst(struct b43_wldev *dev) /* Min sigma square table */ 281 { 282 struct b43_phy *phy = &dev->phy; 283 int i; 284 const u16 *tab; 285 286 if (phy->type == B43_PHYTYPE_A) { 287 tab = b43_tab_sigmasqr1; 288 } else if (phy->type == B43_PHYTYPE_G) { 289 tab = b43_tab_sigmasqr2; 290 } else { 291 B43_WARN_ON(1); 292 return; 293 } 294 295 for (i = 0; i < B43_TAB_SIGMASQR_SIZE; i++) { 296 b43_ofdmtab_write16(dev, B43_OFDMTAB_MINSIGSQ, 297 i, tab[i]); 298 } 299 } 300 301 static void b43_wa_iqadc(struct b43_wldev *dev) 302 { 303 if (dev->phy.analog == 4) 304 b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 0, 305 b43_ofdmtab_read16(dev, B43_OFDMTAB_DAC, 0) & ~0xF000); 306 } 307 308 static void b43_wa_crs_ed(struct b43_wldev *dev) 309 { 310 struct b43_phy *phy = &dev->phy; 311 312 if (phy->rev == 1) { 313 b43_phy_write(dev, B43_PHY_CRSTHRES1_R1, 0x4F19); 314 } else if (phy->rev == 2) { 315 b43_phy_write(dev, B43_PHY_CRSTHRES1, 0x1861); 316 b43_phy_write(dev, B43_PHY_CRSTHRES2, 0x0271); 317 b43_phy_set(dev, B43_PHY_ANTDWELL, 0x0800); 318 } else { 319 b43_phy_write(dev, B43_PHY_CRSTHRES1, 0x0098); 320 b43_phy_write(dev, B43_PHY_CRSTHRES2, 0x0070); 321 b43_phy_write(dev, B43_PHY_OFDM(0xC9), 0x0080); 322 b43_phy_set(dev, B43_PHY_ANTDWELL, 0x0800); 323 } 324 } 325 326 static void b43_wa_crs_thr(struct b43_wldev *dev) 327 { 328 b43_phy_maskset(dev, B43_PHY_CRS0, ~0x03C0, 0xD000); 329 } 330 331 static void b43_wa_crs_blank(struct b43_wldev *dev) 332 { 333 b43_phy_write(dev, B43_PHY_OFDM(0x2C), 0x005A); 334 } 335 336 static void b43_wa_cck_shiftbits(struct b43_wldev *dev) 337 { 338 b43_phy_write(dev, B43_PHY_CCKSHIFTBITS, 0x0026); 339 } 340 341 static void b43_wa_wrssi_offset(struct b43_wldev *dev) 342 { 343 int i; 344 345 if (dev->phy.rev == 1) { 346 for (i = 0; i < 16; i++) { 347 b43_ofdmtab_write16(dev, B43_OFDMTAB_WRSSI_R1, 348 i, 0x0020); 349 } 350 } else { 351 for (i = 0; i < 32; i++) { 352 b43_ofdmtab_write16(dev, B43_OFDMTAB_WRSSI, 353 i, 0x0820); 354 } 355 } 356 } 357 358 static void b43_wa_txpuoff_rxpuon(struct b43_wldev *dev) 359 { 360 b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_0F, 2, 15); 361 b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_0F, 3, 20); 362 } 363 364 static void b43_wa_altagc(struct b43_wldev *dev) 365 { 366 struct b43_phy *phy = &dev->phy; 367 368 if (phy->rev == 1) { 369 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 0, 254); 370 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 1, 13); 371 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 2, 19); 372 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 3, 25); 373 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 0, 0x2710); 374 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 1, 0x9B83); 375 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 2, 0x9B83); 376 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 3, 0x0F8D); 377 b43_phy_write(dev, B43_PHY_LMS, 4); 378 } else { 379 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0, 254); 380 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 1, 13); 381 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 2, 19); 382 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 3, 25); 383 } 384 385 b43_phy_maskset(dev, B43_PHY_CCKSHIFTBITS_WA, 0x00FF, 0x5700); 386 b43_phy_maskset(dev, B43_PHY_OFDM(0x1A), ~0x007F, 0x000F); 387 b43_phy_maskset(dev, B43_PHY_OFDM(0x1A), ~0x3F80, 0x2B80); 388 b43_phy_maskset(dev, B43_PHY_ANTWRSETT, 0xF0FF, 0x0300); 389 b43_radio_set(dev, 0x7A, 0x0008); 390 b43_phy_maskset(dev, B43_PHY_N1P1GAIN, ~0x000F, 0x0008); 391 b43_phy_maskset(dev, B43_PHY_P1P2GAIN, ~0x0F00, 0x0600); 392 b43_phy_maskset(dev, B43_PHY_N1N2GAIN, ~0x0F00, 0x0700); 393 b43_phy_maskset(dev, B43_PHY_N1P1GAIN, ~0x0F00, 0x0100); 394 if (phy->rev == 1) { 395 b43_phy_maskset(dev, B43_PHY_N1N2GAIN, ~0x000F, 0x0007); 396 } 397 b43_phy_maskset(dev, B43_PHY_OFDM(0x88), ~0x00FF, 0x001C); 398 b43_phy_maskset(dev, B43_PHY_OFDM(0x88), ~0x3F00, 0x0200); 399 b43_phy_maskset(dev, B43_PHY_OFDM(0x96), ~0x00FF, 0x001C); 400 b43_phy_maskset(dev, B43_PHY_OFDM(0x89), ~0x00FF, 0x0020); 401 b43_phy_maskset(dev, B43_PHY_OFDM(0x89), ~0x3F00, 0x0200); 402 b43_phy_maskset(dev, B43_PHY_OFDM(0x82), ~0x00FF, 0x002E); 403 b43_phy_maskset(dev, B43_PHY_OFDM(0x96), 0x00FF, 0x1A00); 404 b43_phy_maskset(dev, B43_PHY_OFDM(0x81), ~0x00FF, 0x0028); 405 b43_phy_maskset(dev, B43_PHY_OFDM(0x81), 0x00FF, 0x2C00); 406 if (phy->rev == 1) { 407 b43_phy_write(dev, B43_PHY_PEAK_COUNT, 0x092B); 408 b43_phy_maskset(dev, B43_PHY_OFDM(0x1B), ~0x001E, 0x0002); 409 } else { 410 b43_phy_mask(dev, B43_PHY_OFDM(0x1B), ~0x001E); 411 b43_phy_write(dev, B43_PHY_OFDM(0x1F), 0x287A); 412 b43_phy_maskset(dev, B43_PHY_LPFGAINCTL, ~0x000F, 0x0004); 413 if (phy->rev >= 6) { 414 b43_phy_write(dev, B43_PHY_OFDM(0x22), 0x287A); 415 b43_phy_maskset(dev, B43_PHY_LPFGAINCTL, 0x0FFF, 0x3000); 416 } 417 } 418 b43_phy_maskset(dev, B43_PHY_DIVSRCHIDX, 0x8080, 0x7874); 419 b43_phy_write(dev, B43_PHY_OFDM(0x8E), 0x1C00); 420 if (phy->rev == 1) { 421 b43_phy_maskset(dev, B43_PHY_DIVP1P2GAIN, ~0x0F00, 0x0600); 422 b43_phy_write(dev, B43_PHY_OFDM(0x8B), 0x005E); 423 b43_phy_maskset(dev, B43_PHY_ANTWRSETT, ~0x00FF, 0x001E); 424 b43_phy_write(dev, B43_PHY_OFDM(0x8D), 0x0002); 425 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 0, 0); 426 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 1, 7); 427 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 2, 16); 428 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 3, 28); 429 } else { 430 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 0, 0); 431 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 1, 7); 432 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 2, 16); 433 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 3, 28); 434 } 435 if (phy->rev >= 6) { 436 b43_phy_mask(dev, B43_PHY_OFDM(0x26), ~0x0003); 437 b43_phy_mask(dev, B43_PHY_OFDM(0x26), ~0x1000); 438 } 439 b43_phy_read(dev, B43_PHY_VERSION_OFDM); /* Dummy read */ 440 } 441 442 static void b43_wa_tr_ltov(struct b43_wldev *dev) /* TR Lookup Table Original Values */ 443 { 444 b43_gtab_write(dev, B43_GTAB_ORIGTR, 0, 0x7654); 445 } 446 447 static void b43_wa_cpll_nonpilot(struct b43_wldev *dev) 448 { 449 b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_11, 0, 0); 450 b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_11, 1, 0); 451 } 452 453 static void b43_wa_rssi_adc(struct b43_wldev *dev) 454 { 455 if (dev->phy.analog == 4) 456 b43_phy_write(dev, 0x00DC, 0x7454); 457 } 458 459 static void b43_wa_boards_a(struct b43_wldev *dev) 460 { 461 if (dev->dev->board_vendor == SSB_BOARDVENDOR_BCM && 462 dev->dev->board_type == SSB_BOARD_BU4306 && 463 dev->dev->board_rev < 0x30) { 464 b43_phy_write(dev, 0x0010, 0xE000); 465 b43_phy_write(dev, 0x0013, 0x0140); 466 b43_phy_write(dev, 0x0014, 0x0280); 467 } else { 468 if (dev->dev->board_type == SSB_BOARD_MP4318 && 469 dev->dev->board_rev < 0x20) { 470 b43_phy_write(dev, 0x0013, 0x0210); 471 b43_phy_write(dev, 0x0014, 0x0840); 472 } else { 473 b43_phy_write(dev, 0x0013, 0x0140); 474 b43_phy_write(dev, 0x0014, 0x0280); 475 } 476 if (dev->phy.rev <= 4) 477 b43_phy_write(dev, 0x0010, 0xE000); 478 else 479 b43_phy_write(dev, 0x0010, 0x2000); 480 b43_ofdmtab_write16(dev, B43_OFDMTAB_DC, 1, 0x0039); 481 b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_APHY, 7, 0x0040); 482 } 483 } 484 485 static void b43_wa_boards_g(struct b43_wldev *dev) 486 { 487 struct ssb_sprom *sprom = dev->dev->bus_sprom; 488 struct b43_phy *phy = &dev->phy; 489 490 if (dev->dev->board_vendor != SSB_BOARDVENDOR_BCM || 491 dev->dev->board_type != SSB_BOARD_BU4306 || 492 dev->dev->board_rev != 0x17) { 493 if (phy->rev < 2) { 494 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 1, 0x0002); 495 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 2, 0x0001); 496 } else { 497 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 1, 0x0002); 498 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 2, 0x0001); 499 if ((sprom->boardflags_lo & B43_BFL_EXTLNA) && 500 (phy->rev >= 7)) { 501 b43_phy_mask(dev, B43_PHY_EXTG(0x11), 0xF7FF); 502 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0020, 0x0001); 503 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0021, 0x0001); 504 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0022, 0x0001); 505 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0023, 0x0000); 506 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0000, 0x0000); 507 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0003, 0x0002); 508 } 509 } 510 } 511 if (sprom->boardflags_lo & B43_BFL_FEM) { 512 b43_phy_write(dev, B43_PHY_GTABCTL, 0x3120); 513 b43_phy_write(dev, B43_PHY_GTABDATA, 0xC480); 514 } 515 } 516 517 void b43_wa_all(struct b43_wldev *dev) 518 { 519 struct b43_phy *phy = &dev->phy; 520 521 if (phy->type == B43_PHYTYPE_A) { 522 switch (phy->rev) { 523 case 2: 524 b43_wa_papd(dev); 525 b43_wa_auxclipthr(dev); 526 b43_wa_afcdac(dev); 527 b43_wa_txdc_offset(dev); 528 b43_wa_initgains(dev); 529 b43_wa_divider(dev); 530 b43_wa_gt(dev); 531 b43_wa_rssi_lt(dev); 532 b43_wa_analog(dev); 533 b43_wa_dac(dev); 534 b43_wa_fft(dev); 535 b43_wa_nft(dev); 536 b43_wa_rt(dev); 537 b43_wa_nst(dev); 538 b43_wa_art(dev); 539 b43_wa_txlna_gain(dev); 540 b43_wa_crs_reset(dev); 541 b43_wa_2060txlna_gain(dev); 542 b43_wa_lms(dev); 543 break; 544 case 3: 545 b43_wa_papd(dev); 546 b43_wa_mixedsignal(dev); 547 b43_wa_rssi_lt(dev); 548 b43_wa_txdc_offset(dev); 549 b43_wa_initgains(dev); 550 b43_wa_dac(dev); 551 b43_wa_nft(dev); 552 b43_wa_nst(dev); 553 b43_wa_msst(dev); 554 b43_wa_analog(dev); 555 b43_wa_gt(dev); 556 b43_wa_txpuoff_rxpuon(dev); 557 b43_wa_txlna_gain(dev); 558 break; 559 case 5: 560 b43_wa_iqadc(dev); 561 case 6: 562 b43_wa_papd(dev); 563 b43_wa_rssi_lt(dev); 564 b43_wa_txdc_offset(dev); 565 b43_wa_initgains(dev); 566 b43_wa_dac(dev); 567 b43_wa_nft(dev); 568 b43_wa_nst(dev); 569 b43_wa_msst(dev); 570 b43_wa_analog(dev); 571 b43_wa_gt(dev); 572 b43_wa_txpuoff_rxpuon(dev); 573 b43_wa_txlna_gain(dev); 574 break; 575 case 7: 576 b43_wa_iqadc(dev); 577 b43_wa_papd(dev); 578 b43_wa_rssi_lt(dev); 579 b43_wa_txdc_offset(dev); 580 b43_wa_initgains(dev); 581 b43_wa_dac(dev); 582 b43_wa_nft(dev); 583 b43_wa_nst(dev); 584 b43_wa_msst(dev); 585 b43_wa_analog(dev); 586 b43_wa_gt(dev); 587 b43_wa_txpuoff_rxpuon(dev); 588 b43_wa_txlna_gain(dev); 589 b43_wa_rssi_adc(dev); 590 default: 591 B43_WARN_ON(1); 592 } 593 b43_wa_boards_a(dev); 594 } else if (phy->type == B43_PHYTYPE_G) { 595 switch (phy->rev) { 596 case 1://XXX review rev1 597 b43_wa_crs_ed(dev); 598 b43_wa_crs_thr(dev); 599 b43_wa_crs_blank(dev); 600 b43_wa_cck_shiftbits(dev); 601 b43_wa_fft(dev); 602 b43_wa_nft(dev); 603 b43_wa_rt(dev); 604 b43_wa_nst(dev); 605 b43_wa_art(dev); 606 b43_wa_wrssi_offset(dev); 607 b43_wa_altagc(dev); 608 break; 609 case 2: 610 case 6: 611 case 7: 612 case 8: 613 case 9: 614 b43_wa_tr_ltov(dev); 615 b43_wa_crs_ed(dev); 616 b43_wa_rssi_lt(dev); 617 b43_wa_nft(dev); 618 b43_wa_nst(dev); 619 b43_wa_msst(dev); 620 b43_wa_wrssi_offset(dev); 621 b43_wa_altagc(dev); 622 b43_wa_analog(dev); 623 b43_wa_txpuoff_rxpuon(dev); 624 break; 625 default: 626 B43_WARN_ON(1); 627 } 628 b43_wa_boards_g(dev); 629 } else { /* No N PHY support so far, LP PHY is in phy_lp.c */ 630 B43_WARN_ON(1); 631 } 632 633 b43_wa_cpll_nonpilot(dev); 634 } 635