brintos

brintos / linux-shallow public Read only

0
0
Text · 10.6 KiB · f9209b8 Raw
377 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 4  Broadcom B43 wireless driver5 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 20void 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 44static 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 59static 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 73static 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 82static 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	else92		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 97static 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 105static 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 113static 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		else121			b43_write_nst(dev, b43_tab_noisescaleg2);122	} else {123		b43_write_nst(dev, b43_tab_noisescaleg1);124	}125}126 127static 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 136static 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 155static 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 173static void b43_wa_crs_thr(struct b43_wldev *dev)174{175	b43_phy_maskset(dev, B43_PHY_CRS0, ~0x03C0, 0xD000);176}177 178static void b43_wa_crs_blank(struct b43_wldev *dev)179{180	b43_phy_write(dev, B43_PHY_OFDM(0x2C), 0x005A);181}182 183static void b43_wa_cck_shiftbits(struct b43_wldev *dev)184{185	b43_phy_write(dev, B43_PHY_CCKSHIFTBITS, 0x0026);186}187 188static 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 205static 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 211static 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 289static 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 294static 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 300static 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 332void 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 rev1339			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}377