/* Tune the hardware to a new channel. */ static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel) { const struct b43_nphy_channeltab_entry *tabent; tabent = b43_nphy_get_chantabent(dev, channel); if (!tabent) return -ESRCH; //FIXME enable/disable band select upper20 in RXCTL if (0 /*FIXME 5Ghz*/) b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, 0x20); else b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, 0x50); b43_chantab_radio_upload(dev, tabent); udelay(50); b43_radio_write16(dev, B2055_VCO_CAL10, 5); b43_radio_write16(dev, B2055_VCO_CAL10, 45); b43_radio_write16(dev, B2055_VCO_CAL10, 65); udelay(300); if (0 /*FIXME 5Ghz*/) b43_phy_set(dev, B43_NPHY_BANDCTL, B43_NPHY_BANDCTL_5GHZ); else b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ); b43_chantab_phy_upload(dev, tabent); b43_nphy_tx_power_fix(dev); return 0; }
/* wlc_lcnphy_bu_tweaks */ static void b43_phy_lcn_bu_tweaks(struct b43_wldev *dev) { b43_phy_set(dev, 0x805, 0x1); b43_phy_maskset(dev, 0x42f, ~0x7, 0x3); b43_phy_maskset(dev, 0x030, ~0x7, 0x3); b43_phy_write(dev, 0x414, 0x1e10); b43_phy_write(dev, 0x415, 0x0640); b43_phy_maskset(dev, 0x4df, (u16) ~0xff00, 0xf700); b43_phy_set(dev, 0x44a, 0x44); b43_phy_write(dev, 0x44a, 0x80); b43_phy_maskset(dev, 0x434, ~0xff, 0xfd); b43_phy_maskset(dev, 0x420, ~0xff, 0x10); if (dev->dev->bus_sprom->board_rev >= 0x1204) b43_radio_set(dev, 0x09b, 0xf0); b43_phy_write(dev, 0x7d6, 0x0902); b43_phy_maskset(dev, 0x429, ~0xf, 0x9); b43_phy_maskset(dev, 0x429, ~(0x3f << 4), 0xe << 4); if (dev->phy.rev == 1) { b43_phy_maskset(dev, 0x423, ~0xff, 0x46); b43_phy_maskset(dev, 0x411, ~0xff, 1); b43_phy_set(dev, 0x434, 0xff); /* FIXME: update to wl */ /* TODO: wl operates on PHY 0x416, brcmsmac is outdated here */ b43_phy_maskset(dev, 0x656, ~0xf, 2); b43_phy_set(dev, 0x44d, 4); b43_radio_set(dev, 0x0f7, 0x4); b43_radio_mask(dev, 0x0f1, ~0x3); b43_radio_maskset(dev, 0x0f2, ~0xf8, 0x90); b43_radio_maskset(dev, 0x0f3, ~0x3, 0x2); b43_radio_maskset(dev, 0x0f3, ~0xf0, 0xa0); b43_radio_set(dev, 0x11f, 0x2); b43_phy_lcn_clear_tx_power_offsets(dev); /* TODO: something more? */ } }
/* Calibrate resistors in LPF of PLL? */ static void b43_radio_2059_rcal(struct b43_wldev *dev) { /* Enable */ b43_radio_set(dev, R2059_C3 | R2059_RCAL_CONFIG, 0x1); usleep_range(10, 20); b43_radio_set(dev, R2059_C3 | 0x0BF, 0x1); b43_radio_maskset(dev, R2059_C3 | 0x19B, 0x3, 0x2); /* Start */ b43_radio_set(dev, R2059_C3 | R2059_RCAL_CONFIG, 0x2); usleep_range(100, 200); /* Stop */ b43_radio_mask(dev, R2059_C3 | R2059_RCAL_CONFIG, ~0x2); if (!b43_radio_wait_value(dev, R2059_C3 | R2059_RCAL_STATUS, 1, 1, 100, 1000000)) b43err(dev->wl, "Radio 0x2059 rcal timeout\n"); /* Disable */ b43_radio_mask(dev, R2059_C3 | R2059_RCAL_CONFIG, ~0x1); b43_radio_set(dev, 0xa, 0x60); }
static void b43_radio_init2060(struct b43_wldev *dev) { b43_radio_write16(dev, 0x0004, 0x00C0); b43_radio_write16(dev, 0x0005, 0x0008); b43_radio_write16(dev, 0x0009, 0x0040); b43_radio_write16(dev, 0x0005, 0x00AA); b43_radio_write16(dev, 0x0032, 0x008F); b43_radio_write16(dev, 0x0006, 0x008F); b43_radio_write16(dev, 0x0034, 0x008F); b43_radio_write16(dev, 0x002C, 0x0007); b43_radio_write16(dev, 0x0082, 0x0080); b43_radio_write16(dev, 0x0080, 0x0000); b43_radio_write16(dev, 0x003F, 0x00DA); b43_radio_mask(dev, 0x0005, ~0x0008); b43_radio_mask(dev, 0x0081, ~0x0010); b43_radio_mask(dev, 0x0081, ~0x0020); b43_radio_mask(dev, 0x0081, ~0x0020); msleep(1); /* delay 400usec */ b43_radio_maskset(dev, 0x0081, ~0x0020, 0x0010); msleep(1); /* delay 400usec */ b43_radio_maskset(dev, 0x0005, ~0x0008, 0x0008); b43_radio_mask(dev, 0x0085, ~0x0010); b43_radio_mask(dev, 0x0005, ~0x0008); b43_radio_mask(dev, 0x0081, ~0x0040); b43_radio_maskset(dev, 0x0081, ~0x0040, 0x0040); b43_radio_write16(dev, 0x0005, (b43_radio_read16(dev, 0x0081) & ~0x0008) | 0x0008); b43_phy_write(dev, 0x0063, 0xDDC6); b43_phy_write(dev, 0x0069, 0x07BE); b43_phy_write(dev, 0x006A, 0x0000); aphy_channel_switch(dev, dev->phy.ops->get_default_chan(dev)); msleep(1); }
static void b43_phy_ww(struct b43_wldev *dev) { u16 b, curr_s, best_s = 0xFFFF; int i; b43_phy_mask(dev, B43_PHY_CRS0, ~B43_PHY_CRS0_EN); b43_phy_set(dev, B43_PHY_OFDM(0x1B), 0x1000); b43_phy_maskset(dev, B43_PHY_OFDM(0x82), 0xF0FF, 0x0300); b43_radio_set(dev, 0x0009, 0x0080); b43_radio_maskset(dev, 0x0012, 0xFFFC, 0x0002); b43_wa_initgains(dev); b43_phy_write(dev, B43_PHY_OFDM(0xBA), 0x3ED5); b = b43_phy_read(dev, B43_PHY_PWRDOWN); b43_phy_write(dev, B43_PHY_PWRDOWN, (b & 0xFFF8) | 0x0005); b43_radio_set(dev, 0x0004, 0x0004); for (i = 0x10; i <= 0x20; i++) { b43_radio_write16(dev, 0x0013, i); curr_s = b43_phy_read(dev, B43_PHY_OTABLEQ) & 0x00FF; if (!curr_s) { best_s = 0x0000; break; } else if (curr_s >= 0x0080) curr_s = 0x0100 - curr_s; if (curr_s < best_s) best_s = curr_s; } b43_phy_write(dev, B43_PHY_PWRDOWN, b); b43_radio_mask(dev, 0x0004, 0xFFFB); b43_radio_write16(dev, 0x0013, best_s); b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 0, 0xFFEC); b43_phy_write(dev, B43_PHY_OFDM(0xB7), 0x1E80); b43_phy_write(dev, B43_PHY_OFDM(0xB6), 0x1C00); b43_phy_write(dev, B43_PHY_OFDM(0xB5), 0x0EC0); b43_phy_write(dev, B43_PHY_OFDM(0xB2), 0x00C0); b43_phy_write(dev, B43_PHY_OFDM(0xB9), 0x1FFF); b43_phy_maskset(dev, B43_PHY_OFDM(0xBB), 0xF000, 0x0053); b43_phy_maskset(dev, B43_PHY_OFDM61, 0xFE1F, 0x0120); b43_phy_maskset(dev, B43_PHY_OFDM(0x13), 0x0FFF, 0x3000); b43_phy_maskset(dev, B43_PHY_OFDM(0x14), 0x0FFF, 0x3000); b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 6, 0x0017); for (i = 0; i < 6; i++) b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, i, 0x000F); b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0D, 0x000E); b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0E, 0x0011); b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0F, 0x0013); b43_phy_write(dev, B43_PHY_OFDM(0x33), 0x5030); b43_phy_set(dev, B43_PHY_CRS0, B43_PHY_CRS0_EN); }
static void b43_radio_init2055_post(struct b43_wldev *dev) { struct ssb_sprom *sprom = &(dev->dev->bus->sprom); struct ssb_boardinfo *binfo = &(dev->dev->bus->boardinfo); int i; u16 val; b43_radio_mask(dev, B2055_MASTER1, 0xFFF3); msleep(1); if ((sprom->revision != 4) || !(sprom->boardflags_hi & B43_BFH_RSSIINV)) { if ((binfo->vendor != PCI_VENDOR_ID_BROADCOM) || (binfo->type != 0x46D) || (binfo->rev < 0x41)) { b43_radio_mask(dev, B2055_C1_RX_BB_REG, 0x7F); b43_radio_mask(dev, B2055_C1_RX_BB_REG, 0x7F); msleep(1); } } b43_radio_maskset(dev, B2055_RRCCAL_NOPTSEL, 0x3F, 0x2C); msleep(1); b43_radio_write16(dev, B2055_CAL_MISC, 0x3C); msleep(1); b43_radio_mask(dev, B2055_CAL_MISC, 0xFFBE); msleep(1); b43_radio_set(dev, B2055_CAL_LPOCTL, 0x80); msleep(1); b43_radio_set(dev, B2055_CAL_MISC, 0x1); msleep(1); b43_radio_set(dev, B2055_CAL_MISC, 0x40); msleep(1); for (i = 0; i < 100; i++) { val = b43_radio_read16(dev, B2055_CAL_COUT2); if (val & 0x80) break; udelay(10); } msleep(1); b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F); msleep(1); nphy_channel_switch(dev, dev->phy.channel); b43_radio_write16(dev, B2055_C1_RX_BB_LPF, 0x9); b43_radio_write16(dev, B2055_C2_RX_BB_LPF, 0x9); b43_radio_write16(dev, B2055_C1_RX_BB_MIDACHP, 0x83); b43_radio_write16(dev, B2055_C2_RX_BB_MIDACHP, 0x83); }
/* wlc_lcnphy_radio_2064_channel_tune_4313 */ static void b43_radio_2064_channel_setup(struct b43_wldev *dev) { u16 save[2]; b43_radio_set(dev, 0x09d, 0x4); b43_radio_write(dev, 0x09e, 0xf); /* Channel specific values in theory, in practice always the same */ b43_radio_write(dev, 0x02a, 0xb); b43_radio_maskset(dev, 0x030, ~0x3, 0xa); b43_radio_maskset(dev, 0x091, ~0x3, 0); b43_radio_maskset(dev, 0x038, ~0xf, 0x7); b43_radio_maskset(dev, 0x030, ~0xc, 0x8); b43_radio_maskset(dev, 0x05e, ~0xf, 0x8); b43_radio_maskset(dev, 0x05e, ~0xf0, 0x80); b43_radio_write(dev, 0x06c, 0x80); save[0] = b43_radio_read(dev, 0x044); save[1] = b43_radio_read(dev, 0x12b); b43_radio_set(dev, 0x044, 0x7); b43_radio_set(dev, 0x12b, 0xe); /* TODO */ b43_radio_write(dev, 0x040, 0xfb); b43_radio_write(dev, 0x041, 0x9a); b43_radio_write(dev, 0x042, 0xa3); b43_radio_write(dev, 0x043, 0x0c); /* TODO */ b43_radio_set(dev, 0x044, 0x0c); udelay(1); b43_radio_write(dev, 0x044, save[0]); b43_radio_write(dev, 0x12b, save[1]); if (dev->phy.rev == 1) { /* brcmsmac uses outdated 0x3 for 0x038 */ b43_radio_write(dev, 0x038, 0x0); b43_radio_write(dev, 0x091, 0x7); } }
static void aphy_channel_switch(struct b43_wldev *dev, unsigned int channel) { u16 freq, r8, tmp; freq = channel2freq_a(channel); r8 = b43_radio_read16(dev, 0x0008); b43_write16(dev, 0x03F0, freq); b43_radio_write16(dev, 0x0008, r8); //TODO: write max channel TX power? to Radio 0x2D tmp = b43_radio_read16(dev, 0x002E); tmp &= 0x0080; //TODO: OR tmp with the Power out estimation for this channel? b43_radio_write16(dev, 0x002E, tmp); if (freq >= 4920 && freq <= 5500) { /* * r8 = (((freq * 15 * 0xE1FC780F) >> 32) / 29) & 0x0F; * = (freq * 0.025862069 */ r8 = 3 * freq / 116; /* is equal to r8 = freq * 0.025862 */ } b43_radio_write16(dev, 0x0007, (r8 << 4) | r8); b43_radio_write16(dev, 0x0020, (r8 << 4) | r8); b43_radio_write16(dev, 0x0021, (r8 << 4) | r8); b43_radio_maskset(dev, 0x0022, 0x000F, (r8 << 4)); b43_radio_write16(dev, 0x002A, (r8 << 4)); b43_radio_write16(dev, 0x002B, (r8 << 4)); b43_radio_maskset(dev, 0x0008, 0x00F0, (r8 << 4)); b43_radio_maskset(dev, 0x0029, 0xFF0F, 0x00B0); b43_radio_write16(dev, 0x0035, 0x00AA); b43_radio_write16(dev, 0x0036, 0x0085); b43_radio_maskset(dev, 0x003A, 0xFF20, freq_r3A_value(freq)); b43_radio_mask(dev, 0x003D, 0x00FF); b43_radio_maskset(dev, 0x0081, 0xFF7F, 0x0080); b43_radio_mask(dev, 0x0035, 0xFFEF); b43_radio_maskset(dev, 0x0035, 0xFFEF, 0x0010); b43_radio_set_tx_iq(dev); //TODO: TSSI2dbm workaround //FIXME b43_phy_xmitpower(dev); }
static void aphy_channel_switch(struct b43_wldev *dev, unsigned int channel) { u16 freq, r8, tmp; freq = channel2freq_a(channel); r8 = b43_radio_read16(dev, 0x0008); b43_write16(dev, 0x03F0, freq); b43_radio_write16(dev, 0x0008, r8); tmp = b43_radio_read16(dev, 0x002E); tmp &= 0x0080; b43_radio_write16(dev, 0x002E, tmp); if (freq >= 4920 && freq <= 5500) { r8 = 3 * freq / 116; } b43_radio_write16(dev, 0x0007, (r8 << 4) | r8); b43_radio_write16(dev, 0x0020, (r8 << 4) | r8); b43_radio_write16(dev, 0x0021, (r8 << 4) | r8); b43_radio_maskset(dev, 0x0022, 0x000F, (r8 << 4)); b43_radio_write16(dev, 0x002A, (r8 << 4)); b43_radio_write16(dev, 0x002B, (r8 << 4)); b43_radio_maskset(dev, 0x0008, 0x00F0, (r8 << 4)); b43_radio_maskset(dev, 0x0029, 0xFF0F, 0x00B0); b43_radio_write16(dev, 0x0035, 0x00AA); b43_radio_write16(dev, 0x0036, 0x0085); b43_radio_maskset(dev, 0x003A, 0xFF20, freq_r3A_value(freq)); b43_radio_mask(dev, 0x003D, 0x00FF); b43_radio_maskset(dev, 0x0081, 0xFF7F, 0x0080); b43_radio_mask(dev, 0x0035, 0xFFEF); b43_radio_maskset(dev, 0x0035, 0xFFEF, 0x0010); b43_radio_set_tx_iq(dev); }
static void b43_radio_2059_init(struct b43_wldev *dev) { const u16 routing[] = { R2059_SYN, R2059_TXRX0, R2059_RXRX1 }; const u16 radio_values[3][2] = { { 0x61, 0xE9 }, { 0x69, 0xD5 }, { 0x73, 0x99 }, }; u16 i, j; b43_radio_write(dev, R2059_ALL | 0x51, 0x0070); b43_radio_write(dev, R2059_ALL | 0x5a, 0x0003); for (i = 0; i < ARRAY_SIZE(routing); i++) b43_radio_set(dev, routing[i] | 0x146, 0x3); b43_radio_set(dev, 0x2e, 0x0078); b43_radio_set(dev, 0xc0, 0x0080); msleep(2); b43_radio_mask(dev, 0x2e, ~0x0078); b43_radio_mask(dev, 0xc0, ~0x0080); if (1) { /* FIXME */ b43_radio_set(dev, R2059_RXRX1 | 0x4, 0x1); udelay(10); b43_radio_set(dev, R2059_RXRX1 | 0x0BF, 0x1); b43_radio_maskset(dev, R2059_RXRX1 | 0x19B, 0x3, 0x2); b43_radio_set(dev, R2059_RXRX1 | 0x4, 0x2); udelay(100); b43_radio_mask(dev, R2059_RXRX1 | 0x4, ~0x2); for (i = 0; i < 10000; i++) { if (b43_radio_read(dev, R2059_RXRX1 | 0x145) & 1) { i = 0; break; } udelay(100); } if (i) b43err(dev->wl, "radio 0x945 timeout\n"); b43_radio_mask(dev, R2059_RXRX1 | 0x4, ~0x1); b43_radio_set(dev, 0xa, 0x60); for (i = 0; i < 3; i++) { b43_radio_write(dev, 0x17F, radio_values[i][0]); b43_radio_write(dev, 0x13D, 0x6E); b43_radio_write(dev, 0x13E, radio_values[i][1]); b43_radio_write(dev, 0x13C, 0x55); for (j = 0; j < 10000; j++) { if (b43_radio_read(dev, 0x140) & 2) { j = 0; break; } udelay(500); } if (j) b43err(dev->wl, "radio 0x140 timeout\n"); b43_radio_write(dev, 0x13C, 0x15); } b43_radio_mask(dev, 0x17F, ~0x1); } b43_radio_mask(dev, 0x11, ~0x0008); }