📄 phy.c
字号:
b43_radio_write16(dev, 0x005C, 0x00B0); b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A) | 0x0007); b43_radio_selectchannel(dev, old_channel, 0); b43_phy_write(dev, 0x0014, 0x0080); b43_phy_write(dev, 0x0032, 0x00CA); b43_phy_write(dev, 0x002A, 0x88A3); b43_set_txpower_g(dev, &phy->bbatt, &phy->rfatt, phy->tx_control); if (phy->radio_ver == 0x2050) b43_radio_write16(dev, 0x005D, 0x000D); b43_write16(dev, 0x03E4, (b43_read16(dev, 0x03E4) & 0xFFC0) | 0x0004);}static void b43_phy_initb6(struct b43_wldev *dev){ struct b43_phy *phy = &dev->phy; u16 offset, val; u8 old_channel; b43_phy_write(dev, 0x003E, 0x817A); b43_radio_write16(dev, 0x007A, (b43_radio_read16(dev, 0x007A) | 0x0058)); if (phy->radio_rev == 4 || phy->radio_rev == 5) { b43_radio_write16(dev, 0x51, 0x37); b43_radio_write16(dev, 0x52, 0x70); b43_radio_write16(dev, 0x53, 0xB3); b43_radio_write16(dev, 0x54, 0x9B); b43_radio_write16(dev, 0x5A, 0x88); b43_radio_write16(dev, 0x5B, 0x88); b43_radio_write16(dev, 0x5D, 0x88); b43_radio_write16(dev, 0x5E, 0x88); b43_radio_write16(dev, 0x7D, 0x88); b43_hf_write(dev, b43_hf_read(dev) | B43_HF_TSSIRPSMW); } B43_WARN_ON(phy->radio_rev == 6 || phy->radio_rev == 7); /* We had code for these revs here... */ if (phy->radio_rev == 8) { b43_radio_write16(dev, 0x51, 0); b43_radio_write16(dev, 0x52, 0x40); b43_radio_write16(dev, 0x53, 0xB7); b43_radio_write16(dev, 0x54, 0x98); b43_radio_write16(dev, 0x5A, 0x88); b43_radio_write16(dev, 0x5B, 0x6B); b43_radio_write16(dev, 0x5C, 0x0F); if (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_ALTIQ) { b43_radio_write16(dev, 0x5D, 0xFA); b43_radio_write16(dev, 0x5E, 0xD8); } else { b43_radio_write16(dev, 0x5D, 0xF5); b43_radio_write16(dev, 0x5E, 0xB8); } b43_radio_write16(dev, 0x0073, 0x0003); b43_radio_write16(dev, 0x007D, 0x00A8); b43_radio_write16(dev, 0x007C, 0x0001); b43_radio_write16(dev, 0x007E, 0x0008); } val = 0x1E1F; for (offset = 0x0088; offset < 0x0098; offset++) { b43_phy_write(dev, offset, val); val -= 0x0202; } val = 0x3E3F; for (offset = 0x0098; offset < 0x00A8; offset++) { b43_phy_write(dev, offset, val); val -= 0x0202; } val = 0x2120; for (offset = 0x00A8; offset < 0x00C8; offset++) { b43_phy_write(dev, offset, (val & 0x3F3F)); val += 0x0202; } if (phy->type == B43_PHYTYPE_G) { b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A) | 0x0020); b43_radio_write16(dev, 0x0051, b43_radio_read16(dev, 0x0051) | 0x0004); b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) | 0x0100); b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) | 0x2000); b43_phy_write(dev, 0x5B, 0); b43_phy_write(dev, 0x5C, 0); } old_channel = phy->channel; if (old_channel >= 8) b43_radio_selectchannel(dev, 1, 0); else b43_radio_selectchannel(dev, 13, 0); b43_radio_write16(dev, 0x0050, 0x0020); b43_radio_write16(dev, 0x0050, 0x0023); udelay(40); if (phy->radio_rev < 6 || phy->radio_rev == 8) { b43_radio_write16(dev, 0x7C, (b43_radio_read16(dev, 0x7C) | 0x0002)); b43_radio_write16(dev, 0x50, 0x20); } if (phy->radio_rev <= 2) { b43_radio_write16(dev, 0x7C, 0x20); b43_radio_write16(dev, 0x5A, 0x70); b43_radio_write16(dev, 0x5B, 0x7B); b43_radio_write16(dev, 0x5C, 0xB0); } b43_radio_write16(dev, 0x007A, (b43_radio_read16(dev, 0x007A) & 0x00F8) | 0x0007); b43_radio_selectchannel(dev, old_channel, 0); b43_phy_write(dev, 0x0014, 0x0200); if (phy->radio_rev >= 6) b43_phy_write(dev, 0x2A, 0x88C2); else b43_phy_write(dev, 0x2A, 0x8AC0); b43_phy_write(dev, 0x0038, 0x0668); b43_set_txpower_g(dev, &phy->bbatt, &phy->rfatt, phy->tx_control); if (phy->radio_rev <= 5) { b43_phy_write(dev, 0x5D, (b43_phy_read(dev, 0x5D) & 0xFF80) | 0x0003); } if (phy->radio_rev <= 2) b43_radio_write16(dev, 0x005D, 0x000D); if (phy->analog == 4) { b43_write16(dev, 0x3E4, 9); b43_phy_write(dev, 0x61, b43_phy_read(dev, 0x61) & 0x0FFF); } else { b43_phy_write(dev, 0x0002, (b43_phy_read(dev, 0x0002) & 0xFFC0) | 0x0004); } if (phy->type == B43_PHYTYPE_B) { b43_write16(dev, 0x03E6, 0x8140); b43_phy_write(dev, 0x0016, 0x0410); b43_phy_write(dev, 0x0017, 0x0820); b43_phy_write(dev, 0x0062, 0x0007); b43_radio_init2050(dev); b43_lo_g_measure(dev); if (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_RSSI) { b43_calc_nrssi_slope(dev); b43_calc_nrssi_threshold(dev); } b43_phy_init_pctl(dev); } else if (phy->type == B43_PHYTYPE_G) b43_write16(dev, 0x03E6, 0x0);}static void b43_calc_loopback_gain(struct b43_wldev *dev){ struct b43_phy *phy = &dev->phy; u16 backup_phy[16] = { 0 }; u16 backup_radio[3]; u16 backup_bband; u16 i, j, loop_i_max; u16 trsw_rx; u16 loop1_outer_done, loop1_inner_done; backup_phy[0] = b43_phy_read(dev, B43_PHY_CRS0); backup_phy[1] = b43_phy_read(dev, B43_PHY_CCKBBANDCFG); backup_phy[2] = b43_phy_read(dev, B43_PHY_RFOVER); backup_phy[3] = b43_phy_read(dev, B43_PHY_RFOVERVAL); if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */ backup_phy[4] = b43_phy_read(dev, B43_PHY_ANALOGOVER); backup_phy[5] = b43_phy_read(dev, B43_PHY_ANALOGOVERVAL); } backup_phy[6] = b43_phy_read(dev, B43_PHY_BASE(0x5A)); backup_phy[7] = b43_phy_read(dev, B43_PHY_BASE(0x59)); backup_phy[8] = b43_phy_read(dev, B43_PHY_BASE(0x58)); backup_phy[9] = b43_phy_read(dev, B43_PHY_BASE(0x0A)); backup_phy[10] = b43_phy_read(dev, B43_PHY_BASE(0x03)); backup_phy[11] = b43_phy_read(dev, B43_PHY_LO_MASK); backup_phy[12] = b43_phy_read(dev, B43_PHY_LO_CTL); backup_phy[13] = b43_phy_read(dev, B43_PHY_BASE(0x2B)); backup_phy[14] = b43_phy_read(dev, B43_PHY_PGACTL); backup_phy[15] = b43_phy_read(dev, B43_PHY_LO_LEAKAGE); backup_bband = phy->bbatt.att; backup_radio[0] = b43_radio_read16(dev, 0x52); backup_radio[1] = b43_radio_read16(dev, 0x43); backup_radio[2] = b43_radio_read16(dev, 0x7A); b43_phy_write(dev, B43_PHY_CRS0, b43_phy_read(dev, B43_PHY_CRS0) & 0x3FFF); b43_phy_write(dev, B43_PHY_CCKBBANDCFG, b43_phy_read(dev, B43_PHY_CCKBBANDCFG) | 0x8000); b43_phy_write(dev, B43_PHY_RFOVER, b43_phy_read(dev, B43_PHY_RFOVER) | 0x0002); b43_phy_write(dev, B43_PHY_RFOVERVAL, b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xFFFD); b43_phy_write(dev, B43_PHY_RFOVER, b43_phy_read(dev, B43_PHY_RFOVER) | 0x0001); b43_phy_write(dev, B43_PHY_RFOVERVAL, b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xFFFE); if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */ b43_phy_write(dev, B43_PHY_ANALOGOVER, b43_phy_read(dev, B43_PHY_ANALOGOVER) | 0x0001); b43_phy_write(dev, B43_PHY_ANALOGOVERVAL, b43_phy_read(dev, B43_PHY_ANALOGOVERVAL) & 0xFFFE); b43_phy_write(dev, B43_PHY_ANALOGOVER, b43_phy_read(dev, B43_PHY_ANALOGOVER) | 0x0002); b43_phy_write(dev, B43_PHY_ANALOGOVERVAL, b43_phy_read(dev, B43_PHY_ANALOGOVERVAL) & 0xFFFD); } b43_phy_write(dev, B43_PHY_RFOVER, b43_phy_read(dev, B43_PHY_RFOVER) | 0x000C); b43_phy_write(dev, B43_PHY_RFOVERVAL, b43_phy_read(dev, B43_PHY_RFOVERVAL) | 0x000C); b43_phy_write(dev, B43_PHY_RFOVER, b43_phy_read(dev, B43_PHY_RFOVER) | 0x0030); b43_phy_write(dev, B43_PHY_RFOVERVAL, (b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xFFCF) | 0x10); b43_phy_write(dev, B43_PHY_BASE(0x5A), 0x0780); b43_phy_write(dev, B43_PHY_BASE(0x59), 0xC810); b43_phy_write(dev, B43_PHY_BASE(0x58), 0x000D); b43_phy_write(dev, B43_PHY_BASE(0x0A), b43_phy_read(dev, B43_PHY_BASE(0x0A)) | 0x2000); if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */ b43_phy_write(dev, B43_PHY_ANALOGOVER, b43_phy_read(dev, B43_PHY_ANALOGOVER) | 0x0004); b43_phy_write(dev, B43_PHY_ANALOGOVERVAL, b43_phy_read(dev, B43_PHY_ANALOGOVERVAL) & 0xFFFB); } b43_phy_write(dev, B43_PHY_BASE(0x03), (b43_phy_read(dev, B43_PHY_BASE(0x03)) & 0xFF9F) | 0x40); if (phy->radio_rev == 8) { b43_radio_write16(dev, 0x43, 0x000F); } else { b43_radio_write16(dev, 0x52, 0); b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43) & 0xFFF0) | 0x9); } b43_phy_set_baseband_attenuation(dev, 11); if (phy->rev >= 3) b43_phy_write(dev, B43_PHY_LO_MASK, 0xC020); else b43_phy_write(dev, B43_PHY_LO_MASK, 0x8020); b43_phy_write(dev, B43_PHY_LO_CTL, 0); b43_phy_write(dev, B43_PHY_BASE(0x2B), (b43_phy_read(dev, B43_PHY_BASE(0x2B)) & 0xFFC0) | 0x01); b43_phy_write(dev, B43_PHY_BASE(0x2B), (b43_phy_read(dev, B43_PHY_BASE(0x2B)) & 0xC0FF) | 0x800); b43_phy_write(dev, B43_PHY_RFOVER, b43_phy_read(dev, B43_PHY_RFOVER) | 0x0100); b43_phy_write(dev, B43_PHY_RFOVERVAL, b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xCFFF); if (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_EXTLNA) { if (phy->rev >= 7) { b43_phy_write(dev, B43_PHY_RFOVER, b43_phy_read(dev, B43_PHY_RFOVER) | 0x0800); b43_phy_write(dev, B43_PHY_RFOVERVAL, b43_phy_read(dev, B43_PHY_RFOVERVAL) | 0x8000); } } b43_radio_write16(dev, 0x7A, b43_radio_read16(dev, 0x7A) & 0x00F7); j = 0; loop_i_max = (phy->radio_rev == 8) ? 15 : 9; for (i = 0; i < loop_i_max; i++) { for (j = 0; j < 16; j++) { b43_radio_write16(dev, 0x43, i); b43_phy_write(dev, B43_PHY_RFOVERVAL, (b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xF0FF) | (j << 8)); b43_phy_write(dev, B43_PHY_PGACTL, (b43_phy_read(dev, B43_PHY_PGACTL) & 0x0FFF) | 0xA000); b43_phy_write(dev, B43_PHY_PGACTL, b43_phy_read(dev, B43_PHY_PGACTL) | 0xF000); udelay(20); if (b43_phy_read(dev, B43_PHY_LO_LEAKAGE) >= 0xDFC) goto exit_loop1; } } exit_loop1: loop1_outer_done = i; loop1_inner_done = j; if (j >= 8) { b43_phy_write(dev, B43_PHY_RFOVERVAL, b43_phy_read(dev, B43_PHY_RFOVERVAL) | 0x30); trsw_rx = 0x1B; for (j = j - 8; j < 16; j++) { b43_phy_write(dev, B43_PHY_RFOVERVAL, (b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xF0FF) | (j << 8)); b43_phy_write(dev, B43_PHY_PGACTL, (b43_phy_read(dev, B43_PHY_PGACTL) & 0x0FFF) | 0xA000); b43_phy_write(dev, B43_PHY_PGACTL, b43_phy_read(dev, B43_PHY_PGACTL) | 0xF000); udelay(20); trsw_rx -= 3; if (b43_phy_read(dev, B43_PHY_LO_LEAKAGE) >= 0xDFC) goto exit_loop2; } } else trsw_rx = 0x18; exit_loop2: if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */ b43_phy_write(dev, B43_PHY_ANALOGOVER, backup_phy[4]); b43_phy_write(dev, B43_PHY_ANALOGOVERVAL, backup_phy[5]); } b43_phy_write(dev, B43_PHY_BASE(0x5A), backup_phy[6]); b43_phy_write(dev, B43_PHY_BASE(0x59), backup_phy[7]); b43_phy_write(dev, B43_PHY_BASE(0x58), backup_phy[8]); b43_phy_write(dev, B43_PHY_BASE(0x0A), backup_phy[9]); b43_phy_write(dev, B43_PHY_BASE(0x03), backup_phy[10]); b43_phy_write(dev, B43_PHY_LO_MASK, backup_phy[11]); b43_phy_write(dev, B43_PHY_LO_CTL, backup_phy[12]); b43_phy_write(dev, B43_PHY_BASE(0x2B), backup_phy[13]); b43_phy_write(dev, B43_PHY_PGACTL, backup_phy[14]); b43_phy_set_baseband_attenuation(dev, backup_bband); b43_radio_write16(dev, 0x52, backup_radio[0]); b43_radio_write16(dev, 0x43, backup_radio[1]); b43_radio_write16(dev, 0x7A, backup_radio[2]); b43_phy_write(dev, B43_PHY_RFOVER, backup_phy[2] | 0x0003); udelay(10); b43_phy_write(dev, B43_PHY_RFOVER, backup_phy[2]); b43_phy_write(dev, B43_PHY_RFOVERVAL, backup_phy[3]); b43_phy_write(dev, B43_PHY_CRS0, backup_phy[0]); b43_phy_write(dev, B43_PHY_CCKBBANDCFG, backup_phy[1]); phy->max_lb_gain = ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11; phy->trsw_rx_gain = trsw_rx * 2;}static void b43_phy_initg(struct b43_wldev *dev){ struct b43_phy *phy = &dev->phy; u16 tmp; if (phy->rev == 1) b43_phy_initb5(dev); else b43_phy_initb6(dev); if (phy->rev >= 2 || phy->gmode) b43_phy_inita(dev); if (phy->rev >= 2) { b43_phy_write(dev, B43_PHY_ANALOGOVER, 0); b43_phy_write(dev, B43_PHY_ANALOGOVERVAL, 0); } if (phy->rev == 2) { b43_phy_write(dev, B43_PHY_RFOVER, 0); b43_phy_write(dev, B43_PHY_PGACTL, 0xC0); } if (phy->rev > 5) { b43_phy_write(dev, B43_PHY_RFOVER, 0x400); b43_phy_write(dev, B43_PHY_PGACTL, 0xC0); } if (phy->gmode || phy->rev >= 2) { tmp = b43_phy_read(dev, B43_PHY_VERSION_OFDM); tmp &= B43_PHYVER_VERSION; if (tmp == 3 || tmp == 5) { b43_phy_write(dev, B43_PHY_OFDM(0xC2), 0x1816); b43_phy_write(dev, B43_PHY_OFDM(0xC3), 0x8006); } if (tmp == 5) { b43_phy_write(dev, B43_PHY_OFDM(0xCC), (b43_phy_read(dev, B43_PHY_OFDM(0xCC)) & 0x00FF) | 0x1F00); } } if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2) b43_phy_write(dev, B43_PHY_OFDM(0x7E), 0x78); if (phy->radio_rev == 8) { b43_phy_write(dev, B43_PHY_EXTG(0x01), b43_phy_read(dev, B43_PHY_EXTG(0x01)) | 0x80); b43_phy_write(dev, B43_PHY_OFDM(0x3E), b43_phy_read(dev, B43_PHY_OFDM(0x3E)) | 0x4); } if (has_loopback_gain(phy)) b43_calc_loopback_gain(dev); if (phy->radio_rev != 8) { if (phy->initval == 0xFFFF) phy->initval = b43_radio_init2050(dev); else b43_radio_write16(dev, 0x0078, phy->initval); } if (phy->lo_control->tx_bias == 0xFF) { b43_lo_g_measure(dev); } else { if (has_tx_magnification(phy)) { b43_radio_write16(dev, 0x52, (b43_radio_read16(dev, 0x52) & 0xFF00) | phy->lo_control->tx_bias | phy-> lo_control->tx_magn); } else { b43_radio_write16(dev, 0x52, (b43_radio_read16(dev, 0x52) & 0xFFF0) | phy->lo_control->tx_bias); } if (phy->rev >= 6) { b43_phy_write(dev, B43_PHY_BASE(0x36), (b43_phy_read(dev, B43_PHY_BASE(0x36)) & 0x0FFF) | (phy->lo_control-> tx_bias << 12)); } if (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_PACTRL) b43_phy_write(dev, B43_PHY_BASE(0x2E), 0x8075); else b43_phy_write(dev, B43_PHY_BASE(0x2E), 0x807F); if (phy->rev < 2) b43_phy_write(dev, B43_PHY_BASE(0x2F), 0x101); else b43_phy_write(dev, B43_PHY_BASE(0x2F), 0x202); } if (phy->gmode || phy->rev >= 2) { b43_lo_g_adjust(dev); b43_phy_write(dev, B43_PHY_LO_MASK, 0x8078); } if (!(dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_RSSI)) { /* The specs state to update the NRSSI LT with * the value 0x7FFFFFFF here. I think that is some weird * compiler optimization in the original driver. * Essentially, what we do here is resetting all NRSSI LT * entries to -32 (see the limit_value() in nrssi_hw_update()) */ b43_nrssi_hw_update(dev, 0xFFFF); //FIXME? b43_calc_nrssi_threshold(dev); } else if (phy->gmode || phy->rev >= 2) { if (phy->nrssi[0] == -1000) { B43_WARN_ON(phy->nrssi[1] != -1000); b43_calc_nrssi_slope(dev); } else b43_calc_nrssi_threshold(dev); } if (phy->radio_rev == 8) b43_phy_write(dev, B43_PHY_EXTG(0x05), 0x3230); b43_phy_init_pctl(dev); /* FIXME: The spec says in the following if, the 0 should be replaced
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -