root/drivers/net/wireless/broadcom/b43/wa.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. b43_wa_initgains
  2. b43_wa_rssi_lt
  3. b43_wa_analog
  4. b43_wa_fft
  5. b43_wa_nft
  6. b43_wa_rt
  7. b43_write_nst
  8. b43_wa_nst
  9. b43_wa_art
  10. b43_wa_msst
  11. b43_wa_crs_ed
  12. b43_wa_crs_thr
  13. b43_wa_crs_blank
  14. b43_wa_cck_shiftbits
  15. b43_wa_wrssi_offset
  16. b43_wa_txpuoff_rxpuon
  17. b43_wa_altagc
  18. b43_wa_tr_ltov
  19. b43_wa_cpll_nonpilot
  20. b43_wa_boards_g
  21. b43_wa_all

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3 
   4   Broadcom B43 wireless driver
   5 
   6   PHY workarounds.
   7 
   8   Copyright (c) 2005-2007 Stefano Brivio <stefano.brivio@polimi.it>
   9   Copyright (c) 2005-2007 Michael Buesch <m@bues.ch>
  10 
  11 
  12 */
  13 
  14 #include "b43.h"
  15 #include "main.h"
  16 #include "tables.h"
  17 #include "phy_common.h"
  18 #include "wa.h"
  19 
  20 void b43_wa_initgains(struct b43_wldev *dev)
  21 {
  22         struct b43_phy *phy = &dev->phy;
  23 
  24         b43_phy_write(dev, B43_PHY_LNAHPFCTL, 0x1FF9);
  25         b43_phy_mask(dev, B43_PHY_LPFGAINCTL, 0xFF0F);
  26         if (phy->rev <= 2)
  27                 b43_ofdmtab_write16(dev, B43_OFDMTAB_LPFGAIN, 0, 0x1FBF);
  28         b43_radio_write16(dev, 0x0002, 0x1FBF);
  29 
  30         b43_phy_write(dev, 0x0024, 0x4680);
  31         b43_phy_write(dev, 0x0020, 0x0003);
  32         b43_phy_write(dev, 0x001D, 0x0F40);
  33         b43_phy_write(dev, 0x001F, 0x1C00);
  34         if (phy->rev <= 3)
  35                 b43_phy_maskset(dev, 0x002A, 0x00FF, 0x0400);
  36         else if (phy->rev == 5) {
  37                 b43_phy_maskset(dev, 0x002A, 0x00FF, 0x1A00);
  38                 b43_phy_write(dev, 0x00CC, 0x2121);
  39         }
  40         if (phy->rev >= 3)
  41                 b43_phy_write(dev, 0x00BA, 0x3ED5);
  42 }
  43 
  44 static void b43_wa_rssi_lt(struct b43_wldev *dev) /* RSSI lookup table */
  45 {
  46         int i;
  47 
  48         if (0 /* FIXME: For APHY.rev=2 this might be needed */) {
  49                 for (i = 0; i < 8; i++)
  50                         b43_ofdmtab_write16(dev, B43_OFDMTAB_RSSI, i, i + 8);
  51                 for (i = 8; i < 16; i++)
  52                         b43_ofdmtab_write16(dev, B43_OFDMTAB_RSSI, i, i - 8);
  53         } else {
  54                 for (i = 0; i < 64; i++)
  55                         b43_ofdmtab_write16(dev, B43_OFDMTAB_RSSI, i, i);
  56         }
  57 }
  58 
  59 static void b43_wa_analog(struct b43_wldev *dev)
  60 {
  61         u16 ofdmrev;
  62 
  63         ofdmrev = b43_phy_read(dev, B43_PHY_VERSION_OFDM) & B43_PHYVER_VERSION;
  64         if (ofdmrev > 2) {
  65                 b43_phy_write(dev, B43_PHY_PWRDOWN, 0x1000);
  66         } else {
  67                 b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 3, 0x1044);
  68                 b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 4, 0x7201);
  69                 b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 6, 0x0040);
  70         }
  71 }
  72 
  73 static void b43_wa_fft(struct b43_wldev *dev) /* Fine frequency table */
  74 {
  75         int i;
  76 
  77         for (i = 0; i < B43_TAB_FINEFREQG_SIZE; i++)
  78                 b43_ofdmtab_write16(dev, B43_OFDMTAB_DACRFPABB, i,
  79                                     b43_tab_finefreqg[i]);
  80 }
  81 
  82 static void b43_wa_nft(struct b43_wldev *dev) /* Noise figure table */
  83 {
  84         struct b43_phy *phy = &dev->phy;
  85         int i;
  86 
  87         if (phy->rev == 1)
  88                 for (i = 0; i < B43_TAB_NOISEG1_SIZE; i++)
  89                         b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i,
  90                                             b43_tab_noiseg1[i]);
  91         else
  92                 for (i = 0; i < B43_TAB_NOISEG2_SIZE; i++)
  93                         b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i,
  94                                             b43_tab_noiseg2[i]);
  95 }
  96 
  97 static void b43_wa_rt(struct b43_wldev *dev) /* Rotor table */
  98 {
  99         int i;
 100 
 101         for (i = 0; i < B43_TAB_ROTOR_SIZE; i++)
 102                 b43_ofdmtab_write32(dev, B43_OFDMTAB_ROTOR, i, b43_tab_rotor[i]);
 103 }
 104 
 105 static void b43_write_nst(struct b43_wldev *dev, const u16 *nst)
 106 {
 107         int i;
 108 
 109         for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
 110                 b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, i, nst[i]);
 111 }
 112 
 113 static void b43_wa_nst(struct b43_wldev *dev) /* Noise scale table */
 114 {
 115         struct b43_phy *phy = &dev->phy;
 116 
 117         if (phy->rev >= 6) {
 118                 if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN)
 119                         b43_write_nst(dev, b43_tab_noisescaleg3);
 120                 else
 121                         b43_write_nst(dev, b43_tab_noisescaleg2);
 122         } else {
 123                 b43_write_nst(dev, b43_tab_noisescaleg1);
 124         }
 125 }
 126 
 127 static void b43_wa_art(struct b43_wldev *dev) /* ADV retard table */
 128 {
 129         int i;
 130 
 131         for (i = 0; i < B43_TAB_RETARD_SIZE; i++)
 132                         b43_ofdmtab_write32(dev, B43_OFDMTAB_ADVRETARD,
 133                                 i, b43_tab_retard[i]);
 134 }
 135 
 136 static void b43_wa_msst(struct b43_wldev *dev) /* Min sigma square table */
 137 {
 138         struct b43_phy *phy = &dev->phy;
 139         int i;
 140         const u16 *tab;
 141 
 142         if (phy->type == B43_PHYTYPE_G) {
 143                 tab = b43_tab_sigmasqr2;
 144         } else {
 145                 B43_WARN_ON(1);
 146                 return;
 147         }
 148 
 149         for (i = 0; i < B43_TAB_SIGMASQR_SIZE; i++) {
 150                 b43_ofdmtab_write16(dev, B43_OFDMTAB_MINSIGSQ,
 151                                         i, tab[i]);
 152         }
 153 }
 154 
 155 static void b43_wa_crs_ed(struct b43_wldev *dev)
 156 {
 157         struct b43_phy *phy = &dev->phy;
 158 
 159         if (phy->rev == 1) {
 160                 b43_phy_write(dev, B43_PHY_CRSTHRES1_R1, 0x4F19);
 161         } else if (phy->rev == 2) {
 162                 b43_phy_write(dev, B43_PHY_CRSTHRES1, 0x1861);
 163                 b43_phy_write(dev, B43_PHY_CRSTHRES2, 0x0271);
 164                 b43_phy_set(dev, B43_PHY_ANTDWELL, 0x0800);
 165         } else {
 166                 b43_phy_write(dev, B43_PHY_CRSTHRES1, 0x0098);
 167                 b43_phy_write(dev, B43_PHY_CRSTHRES2, 0x0070);
 168                 b43_phy_write(dev, B43_PHY_OFDM(0xC9), 0x0080);
 169                 b43_phy_set(dev, B43_PHY_ANTDWELL, 0x0800);
 170         }
 171 }
 172 
 173 static void b43_wa_crs_thr(struct b43_wldev *dev)
 174 {
 175         b43_phy_maskset(dev, B43_PHY_CRS0, ~0x03C0, 0xD000);
 176 }
 177 
 178 static void b43_wa_crs_blank(struct b43_wldev *dev)
 179 {
 180         b43_phy_write(dev, B43_PHY_OFDM(0x2C), 0x005A);
 181 }
 182 
 183 static void b43_wa_cck_shiftbits(struct b43_wldev *dev)
 184 {
 185         b43_phy_write(dev, B43_PHY_CCKSHIFTBITS, 0x0026);
 186 }
 187 
 188 static void b43_wa_wrssi_offset(struct b43_wldev *dev)
 189 {
 190         int i;
 191 
 192         if (dev->phy.rev == 1) {
 193                 for (i = 0; i < 16; i++) {
 194                         b43_ofdmtab_write16(dev, B43_OFDMTAB_WRSSI_R1,
 195                                                 i, 0x0020);
 196                 }
 197         } else {
 198                 for (i = 0; i < 32; i++) {
 199                         b43_ofdmtab_write16(dev, B43_OFDMTAB_WRSSI,
 200                                                 i, 0x0820);
 201                 }
 202         }
 203 }
 204 
 205 static void b43_wa_txpuoff_rxpuon(struct b43_wldev *dev)
 206 {
 207         b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_0F, 2, 15);
 208         b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_0F, 3, 20);
 209 }
 210 
 211 static void b43_wa_altagc(struct b43_wldev *dev)
 212 {
 213         struct b43_phy *phy = &dev->phy;
 214 
 215         if (phy->rev == 1) {
 216                 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 0, 254);
 217                 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 1, 13);
 218                 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 2, 19);
 219                 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 3, 25);
 220                 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 0, 0x2710);
 221                 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 1, 0x9B83);
 222                 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 2, 0x9B83);
 223                 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 3, 0x0F8D);
 224                 b43_phy_write(dev, B43_PHY_LMS, 4);
 225         } else {
 226                 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0, 254);
 227                 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 1, 13);
 228                 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 2, 19);
 229                 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 3, 25);
 230         }
 231 
 232         b43_phy_maskset(dev, B43_PHY_CCKSHIFTBITS_WA, 0x00FF, 0x5700);
 233         b43_phy_maskset(dev, B43_PHY_OFDM(0x1A), ~0x007F, 0x000F);
 234         b43_phy_maskset(dev, B43_PHY_OFDM(0x1A), ~0x3F80, 0x2B80);
 235         b43_phy_maskset(dev, B43_PHY_ANTWRSETT, 0xF0FF, 0x0300);
 236         b43_radio_set(dev, 0x7A, 0x0008);
 237         b43_phy_maskset(dev, B43_PHY_N1P1GAIN, ~0x000F, 0x0008);
 238         b43_phy_maskset(dev, B43_PHY_P1P2GAIN, ~0x0F00, 0x0600);
 239         b43_phy_maskset(dev, B43_PHY_N1N2GAIN, ~0x0F00, 0x0700);
 240         b43_phy_maskset(dev, B43_PHY_N1P1GAIN, ~0x0F00, 0x0100);
 241         if (phy->rev == 1) {
 242                 b43_phy_maskset(dev, B43_PHY_N1N2GAIN, ~0x000F, 0x0007);
 243         }
 244         b43_phy_maskset(dev, B43_PHY_OFDM(0x88), ~0x00FF, 0x001C);
 245         b43_phy_maskset(dev, B43_PHY_OFDM(0x88), ~0x3F00, 0x0200);
 246         b43_phy_maskset(dev, B43_PHY_OFDM(0x96), ~0x00FF, 0x001C);
 247         b43_phy_maskset(dev, B43_PHY_OFDM(0x89), ~0x00FF, 0x0020);
 248         b43_phy_maskset(dev, B43_PHY_OFDM(0x89), ~0x3F00, 0x0200);
 249         b43_phy_maskset(dev, B43_PHY_OFDM(0x82), ~0x00FF, 0x002E);
 250         b43_phy_maskset(dev, B43_PHY_OFDM(0x96), 0x00FF, 0x1A00);
 251         b43_phy_maskset(dev, B43_PHY_OFDM(0x81), ~0x00FF, 0x0028);
 252         b43_phy_maskset(dev, B43_PHY_OFDM(0x81), 0x00FF, 0x2C00);
 253         if (phy->rev == 1) {
 254                 b43_phy_write(dev, B43_PHY_PEAK_COUNT, 0x092B);
 255                 b43_phy_maskset(dev, B43_PHY_OFDM(0x1B), ~0x001E, 0x0002);
 256         } else {
 257                 b43_phy_mask(dev, B43_PHY_OFDM(0x1B), ~0x001E);
 258                 b43_phy_write(dev, B43_PHY_OFDM(0x1F), 0x287A);
 259                 b43_phy_maskset(dev, B43_PHY_LPFGAINCTL, ~0x000F, 0x0004);
 260                 if (phy->rev >= 6) {
 261                         b43_phy_write(dev, B43_PHY_OFDM(0x22), 0x287A);
 262                         b43_phy_maskset(dev, B43_PHY_LPFGAINCTL, 0x0FFF, 0x3000);
 263                 }
 264         }
 265         b43_phy_maskset(dev, B43_PHY_DIVSRCHIDX, 0x8080, 0x7874);
 266         b43_phy_write(dev, B43_PHY_OFDM(0x8E), 0x1C00);
 267         if (phy->rev == 1) {
 268                 b43_phy_maskset(dev, B43_PHY_DIVP1P2GAIN, ~0x0F00, 0x0600);
 269                 b43_phy_write(dev, B43_PHY_OFDM(0x8B), 0x005E);
 270                 b43_phy_maskset(dev, B43_PHY_ANTWRSETT, ~0x00FF, 0x001E);
 271                 b43_phy_write(dev, B43_PHY_OFDM(0x8D), 0x0002);
 272                 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 0, 0);
 273                 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 1, 7);
 274                 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 2, 16);
 275                 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 3, 28);
 276         } else {
 277                 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 0, 0);
 278                 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 1, 7);
 279                 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 2, 16);
 280                 b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 3, 28);
 281         }
 282         if (phy->rev >= 6) {
 283                 b43_phy_mask(dev, B43_PHY_OFDM(0x26), ~0x0003);
 284                 b43_phy_mask(dev, B43_PHY_OFDM(0x26), ~0x1000);
 285         }
 286         b43_phy_read(dev, B43_PHY_VERSION_OFDM); /* Dummy read */
 287 }
 288 
 289 static void b43_wa_tr_ltov(struct b43_wldev *dev) /* TR Lookup Table Original Values */
 290 {
 291         b43_gtab_write(dev, B43_GTAB_ORIGTR, 0, 0x7654);
 292 }
 293 
 294 static void b43_wa_cpll_nonpilot(struct b43_wldev *dev)
 295 {
 296         b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_11, 0, 0);
 297         b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_11, 1, 0);
 298 }
 299 
 300 static void b43_wa_boards_g(struct b43_wldev *dev)
 301 {
 302         struct ssb_sprom *sprom = dev->dev->bus_sprom;
 303         struct b43_phy *phy = &dev->phy;
 304 
 305         if (dev->dev->board_vendor != SSB_BOARDVENDOR_BCM ||
 306             dev->dev->board_type != SSB_BOARD_BU4306 ||
 307             dev->dev->board_rev != 0x17) {
 308                 if (phy->rev < 2) {
 309                         b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 1, 0x0002);
 310                         b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 2, 0x0001);
 311                 } else {
 312                         b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 1, 0x0002);
 313                         b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 2, 0x0001);
 314                         if ((sprom->boardflags_lo & B43_BFL_EXTLNA) &&
 315                             (phy->rev >= 7)) {
 316                                 b43_phy_mask(dev, B43_PHY_EXTG(0x11), 0xF7FF);
 317                                 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0020, 0x0001);
 318                                 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0021, 0x0001);
 319                                 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0022, 0x0001);
 320                                 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0023, 0x0000);
 321                                 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0000, 0x0000);
 322                                 b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0003, 0x0002);
 323                         }
 324                 }
 325         }
 326         if (sprom->boardflags_lo & B43_BFL_FEM) {
 327                 b43_phy_write(dev, B43_PHY_GTABCTL, 0x3120);
 328                 b43_phy_write(dev, B43_PHY_GTABDATA, 0xC480);
 329         }
 330 }
 331 
 332 void b43_wa_all(struct b43_wldev *dev)
 333 {
 334         struct b43_phy *phy = &dev->phy;
 335 
 336         if (phy->type == B43_PHYTYPE_G) {
 337                 switch (phy->rev) {
 338                 case 1://XXX review rev1
 339                         b43_wa_crs_ed(dev);
 340                         b43_wa_crs_thr(dev);
 341                         b43_wa_crs_blank(dev);
 342                         b43_wa_cck_shiftbits(dev);
 343                         b43_wa_fft(dev);
 344                         b43_wa_nft(dev);
 345                         b43_wa_rt(dev);
 346                         b43_wa_nst(dev);
 347                         b43_wa_art(dev);
 348                         b43_wa_wrssi_offset(dev);
 349                         b43_wa_altagc(dev);
 350                         break;
 351                 case 2:
 352                 case 6:
 353                 case 7:
 354                 case 8:
 355                 case 9:
 356                         b43_wa_tr_ltov(dev);
 357                         b43_wa_crs_ed(dev);
 358                         b43_wa_rssi_lt(dev);
 359                         b43_wa_nft(dev);
 360                         b43_wa_nst(dev);
 361                         b43_wa_msst(dev);
 362                         b43_wa_wrssi_offset(dev);
 363                         b43_wa_altagc(dev);
 364                         b43_wa_analog(dev);
 365                         b43_wa_txpuoff_rxpuon(dev);
 366                         break;
 367                 default:
 368                         B43_WARN_ON(1);
 369                 }
 370                 b43_wa_boards_g(dev);
 371         } else { /* No N PHY support so far, LP PHY is in phy_lp.c */
 372                 B43_WARN_ON(1);
 373         }
 374 
 375         b43_wa_cpll_nonpilot(dev);
 376 }

/* [<][>][^][v][top][bottom][index][help] */