Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003 
0004   Broadcom B43 wireless driver
0005 
0006   PHY workarounds.
0007 
0008   Copyright (c) 2005-2007 Stefano Brivio <stefano.brivio@polimi.it>
0009   Copyright (c) 2005-2007 Michael Buesch <m@bues.ch>
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) /* RSSI lookup table */
0045 {
0046     int i;
0047 
0048     if (0 /* FIXME: For APHY.rev=2 this might be needed */) {
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) /* Fine frequency table */
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) /* Noise figure table */
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) /* Rotor table */
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) /* Noise scale table */
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) /* ADV retard table */
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) /* Min sigma square table */
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); /* Dummy read */
0287 }
0288 
0289 static void b43_wa_tr_ltov(struct b43_wldev *dev) /* TR Lookup Table Original Values */
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://XXX review rev1
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 { /* No N PHY support so far, LP PHY is in phy_lp.c */
0372         B43_WARN_ON(1);
0373     }
0374 
0375     b43_wa_cpll_nonpilot(dev);
0376 }