📄 phy.c
字号:
& 0xFF9F) | 0x0040); if (phy->radio_ver == 0x2050 && phy->radio_rev == 2) { b43legacy_radio_write16(dev, 0x0052, 0x0000); b43legacy_radio_write16(dev, 0x0043, (b43legacy_radio_read16(dev, 0x0043) & 0xFFF0) | 0x0009); loop1_cnt = 9; } else if (phy->radio_rev == 8) { b43legacy_radio_write16(dev, 0x0043, 0x000F); loop1_cnt = 15; } else loop1_cnt = 0; b43legacy_phy_set_baseband_attenuation(dev, 11); if (phy->rev >= 3) b43legacy_phy_write(dev, 0x080F, 0xC020); else b43legacy_phy_write(dev, 0x080F, 0x8020); b43legacy_phy_write(dev, 0x0810, 0x0000); b43legacy_phy_write(dev, 0x002B, (b43legacy_phy_read(dev, 0x002B) & 0xFFC0) | 0x0001); b43legacy_phy_write(dev, 0x002B, (b43legacy_phy_read(dev, 0x002B) & 0xC0FF) | 0x0800); b43legacy_phy_write(dev, 0x0811, b43legacy_phy_read(dev, 0x0811) | 0x0100); b43legacy_phy_write(dev, 0x0812, b43legacy_phy_read(dev, 0x0812) & 0xCFFF); if (dev->dev->bus->sprom.r1.boardflags_lo & B43legacy_BFL_EXTLNA) { if (phy->rev >= 7) { b43legacy_phy_write(dev, 0x0811, b43legacy_phy_read(dev, 0x0811) | 0x0800); b43legacy_phy_write(dev, 0x0812, b43legacy_phy_read(dev, 0x0812) | 0x8000); } } b43legacy_radio_write16(dev, 0x007A, b43legacy_radio_read16(dev, 0x007A) & 0x00F7); for (i = 0; i < loop1_cnt; i++) { b43legacy_radio_write16(dev, 0x0043, loop1_cnt); b43legacy_phy_write(dev, 0x0812, (b43legacy_phy_read(dev, 0x0812) & 0xF0FF) | (i << 8)); b43legacy_phy_write(dev, 0x0015, (b43legacy_phy_read(dev, 0x0015) & 0x0FFF) | 0xA000); b43legacy_phy_write(dev, 0x0015, (b43legacy_phy_read(dev, 0x0015) & 0x0FFF) | 0xF000); udelay(20); if (b43legacy_phy_read(dev, 0x002D) >= 0x0DFC) break; } loop1_done = i; loop1_omitted = loop1_cnt - loop1_done; loop2_done = 0; if (loop1_done >= 8) { b43legacy_phy_write(dev, 0x0812, b43legacy_phy_read(dev, 0x0812) | 0x0030); for (i = loop1_done - 8; i < 16; i++) { b43legacy_phy_write(dev, 0x0812, (b43legacy_phy_read(dev, 0x0812) & 0xF0FF) | (i << 8)); b43legacy_phy_write(dev, 0x0015, (b43legacy_phy_read(dev, 0x0015) & 0x0FFF) | 0xA000); b43legacy_phy_write(dev, 0x0015, (b43legacy_phy_read(dev, 0x0015) & 0x0FFF) | 0xF000); udelay(20); if (b43legacy_phy_read(dev, 0x002D) >= 0x0DFC) break; } } if (phy->rev != 1) { b43legacy_phy_write(dev, 0x0814, backup_phy[4]); b43legacy_phy_write(dev, 0x0815, backup_phy[5]); } b43legacy_phy_write(dev, 0x005A, backup_phy[6]); b43legacy_phy_write(dev, 0x0059, backup_phy[7]); b43legacy_phy_write(dev, 0x0058, backup_phy[8]); b43legacy_phy_write(dev, 0x000A, backup_phy[9]); b43legacy_phy_write(dev, 0x0003, backup_phy[10]); b43legacy_phy_write(dev, 0x080F, backup_phy[11]); b43legacy_phy_write(dev, 0x0810, backup_phy[12]); b43legacy_phy_write(dev, 0x002B, backup_phy[13]); b43legacy_phy_write(dev, 0x0015, backup_phy[14]); b43legacy_phy_set_baseband_attenuation(dev, backup_bband); b43legacy_radio_write16(dev, 0x0052, backup_radio[0]); b43legacy_radio_write16(dev, 0x0043, backup_radio[1]); b43legacy_radio_write16(dev, 0x007A, backup_radio[2]); b43legacy_phy_write(dev, 0x0811, backup_phy[2] | 0x0003); udelay(10); b43legacy_phy_write(dev, 0x0811, backup_phy[2]); b43legacy_phy_write(dev, 0x0812, backup_phy[3]); b43legacy_phy_write(dev, 0x0429, backup_phy[0]); b43legacy_phy_write(dev, 0x0001, backup_phy[1]); phy->loopback_gain[0] = ((loop1_done * 6) - (loop1_omitted * 4)) - 11; phy->loopback_gain[1] = (24 - (3 * loop2_done)) * 2;}static void b43legacy_phy_initg(struct b43legacy_wldev *dev){ struct b43legacy_phy *phy = &dev->phy; u16 tmp; if (phy->rev == 1) b43legacy_phy_initb5(dev); else b43legacy_phy_initb6(dev); if (phy->rev >= 2 || phy->gmode) b43legacy_phy_inita(dev); if (phy->rev >= 2) { b43legacy_phy_write(dev, 0x0814, 0x0000); b43legacy_phy_write(dev, 0x0815, 0x0000); } if (phy->rev == 2) { b43legacy_phy_write(dev, 0x0811, 0x0000); b43legacy_phy_write(dev, 0x0015, 0x00C0); } if (phy->rev > 5) { b43legacy_phy_write(dev, 0x0811, 0x0400); b43legacy_phy_write(dev, 0x0015, 0x00C0); } if (phy->rev >= 2 || phy->gmode) { tmp = b43legacy_phy_read(dev, 0x0400) & 0xFF; if (tmp == 3 || tmp == 5) { b43legacy_phy_write(dev, 0x04C2, 0x1816); b43legacy_phy_write(dev, 0x04C3, 0x8006); if (tmp == 5) b43legacy_phy_write(dev, 0x04CC, (b43legacy_phy_read(dev, 0x04CC) & 0x00FF) | 0x1F00); } b43legacy_phy_write(dev, 0x047E, 0x0078); } if (phy->radio_rev == 8) { b43legacy_phy_write(dev, 0x0801, b43legacy_phy_read(dev, 0x0801) | 0x0080); b43legacy_phy_write(dev, 0x043E, b43legacy_phy_read(dev, 0x043E) | 0x0004); } if (phy->rev >= 2 && phy->gmode) b43legacy_calc_loopback_gain(dev); if (phy->radio_rev != 8) { if (phy->initval == 0xFFFF) phy->initval = b43legacy_radio_init2050(dev); else b43legacy_radio_write16(dev, 0x0078, phy->initval); } if (phy->txctl2 == 0xFFFF) b43legacy_phy_lo_g_measure(dev); else { if (phy->radio_ver == 0x2050 && phy->radio_rev == 8) b43legacy_radio_write16(dev, 0x0052, (phy->txctl1 << 4) | phy->txctl2); else b43legacy_radio_write16(dev, 0x0052, (b43legacy_radio_read16(dev, 0x0052) & 0xFFF0) | phy->txctl1); if (phy->rev >= 6) b43legacy_phy_write(dev, 0x0036, (b43legacy_phy_read(dev, 0x0036) & 0x0FFF) | (phy->txctl2 << 12)); if (dev->dev->bus->sprom.r1.boardflags_lo & B43legacy_BFL_PACTRL) b43legacy_phy_write(dev, 0x002E, 0x8075); else b43legacy_phy_write(dev, 0x002E, 0x807F); if (phy->rev < 2) b43legacy_phy_write(dev, 0x002F, 0x0101); else b43legacy_phy_write(dev, 0x002F, 0x0202); } if (phy->gmode || phy->rev >= 2) { b43legacy_phy_lo_adjust(dev, 0); b43legacy_phy_write(dev, 0x080F, 0x8078); } if (!(dev->dev->bus->sprom.r1.boardflags_lo & B43legacy_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()) */ b43legacy_nrssi_hw_update(dev, 0xFFFF); b43legacy_calc_nrssi_threshold(dev); } else if (phy->gmode || phy->rev >= 2) { if (phy->nrssi[0] == -1000) { B43legacy_WARN_ON(phy->nrssi[1] != -1000); b43legacy_calc_nrssi_slope(dev); } else { B43legacy_WARN_ON(phy->nrssi[1] == -1000); b43legacy_calc_nrssi_threshold(dev); } } if (phy->radio_rev == 8) b43legacy_phy_write(dev, 0x0805, 0x3230); b43legacy_phy_init_pctl(dev); if (dev->dev->bus->chip_id == 0x4306 && dev->dev->bus->chip_package == 2) { b43legacy_phy_write(dev, 0x0429, b43legacy_phy_read(dev, 0x0429) & 0xBFFF); b43legacy_phy_write(dev, 0x04C3, b43legacy_phy_read(dev, 0x04C3) & 0x7FFF); }}static u16 b43legacy_phy_lo_b_r15_loop(struct b43legacy_wldev *dev){ int i; u16 ret = 0; unsigned long flags; local_irq_save(flags); for (i = 0; i < 10; i++) { b43legacy_phy_write(dev, 0x0015, 0xAFA0); udelay(1); b43legacy_phy_write(dev, 0x0015, 0xEFA0); udelay(10); b43legacy_phy_write(dev, 0x0015, 0xFFA0); udelay(40); ret += b43legacy_phy_read(dev, 0x002C); } local_irq_restore(flags); b43legacy_voluntary_preempt(); return ret;}void b43legacy_phy_lo_b_measure(struct b43legacy_wldev *dev){ struct b43legacy_phy *phy = &dev->phy; u16 regstack[12] = { 0 }; u16 mls; u16 fval; int i; int j; regstack[0] = b43legacy_phy_read(dev, 0x0015); regstack[1] = b43legacy_radio_read16(dev, 0x0052) & 0xFFF0; if (phy->radio_ver == 0x2053) { regstack[2] = b43legacy_phy_read(dev, 0x000A); regstack[3] = b43legacy_phy_read(dev, 0x002A); regstack[4] = b43legacy_phy_read(dev, 0x0035); regstack[5] = b43legacy_phy_read(dev, 0x0003); regstack[6] = b43legacy_phy_read(dev, 0x0001); regstack[7] = b43legacy_phy_read(dev, 0x0030); regstack[8] = b43legacy_radio_read16(dev, 0x0043); regstack[9] = b43legacy_radio_read16(dev, 0x007A); regstack[10] = b43legacy_read16(dev, 0x03EC); regstack[11] = b43legacy_radio_read16(dev, 0x0052) & 0x00F0; b43legacy_phy_write(dev, 0x0030, 0x00FF); b43legacy_write16(dev, 0x03EC, 0x3F3F); b43legacy_phy_write(dev, 0x0035, regstack[4] & 0xFF7F); b43legacy_radio_write16(dev, 0x007A, regstack[9] & 0xFFF0); } b43legacy_phy_write(dev, 0x0015, 0xB000); b43legacy_phy_write(dev, 0x002B, 0x0004); if (phy->radio_ver == 0x2053) { b43legacy_phy_write(dev, 0x002B, 0x0203); b43legacy_phy_write(dev, 0x002A, 0x08A3); } phy->minlowsig[0] = 0xFFFF; for (i = 0; i < 4; i++) { b43legacy_radio_write16(dev, 0x0052, regstack[1] | i); b43legacy_phy_lo_b_r15_loop(dev); } for (i = 0; i < 10; i++) { b43legacy_radio_write16(dev, 0x0052, regstack[1] | i); mls = b43legacy_phy_lo_b_r15_loop(dev) / 10; if (mls < phy->minlowsig[0]) { phy->minlowsig[0] = mls; phy->minlowsigpos[0] = i; } } b43legacy_radio_write16(dev, 0x0052, regstack[1] | phy->minlowsigpos[0]); phy->minlowsig[1] = 0xFFFF; for (i = -4; i < 5; i += 2) { for (j = -4; j < 5; j += 2) { if (j < 0) fval = (0x0100 * i) + j + 0x0100; else fval = (0x0100 * i) + j; b43legacy_phy_write(dev, 0x002F, fval); mls = b43legacy_phy_lo_b_r15_loop(dev) / 10; if (mls < phy->minlowsig[1]) { phy->minlowsig[1] = mls; phy->minlowsigpos[1] = fval; } } } phy->minlowsigpos[1] += 0x0101; b43legacy_phy_write(dev, 0x002F, phy->minlowsigpos[1]); if (phy->radio_ver == 0x2053) { b43legacy_phy_write(dev, 0x000A, regstack[2]); b43legacy_phy_write(dev, 0x002A, regstack[3]); b43legacy_phy_write(dev, 0x0035, regstack[4]); b43legacy_phy_write(dev, 0x0003, regstack[5]); b43legacy_phy_write(dev, 0x0001, regstack[6]); b43legacy_phy_write(dev, 0x0030, regstack[7]); b43legacy_radio_write16(dev, 0x0043, regstack[8]); b43legacy_radio_write16(dev, 0x007A, regstack[9]); b43legacy_radio_write16(dev, 0x0052, (b43legacy_radio_read16(dev, 0x0052) & 0x000F) | regstack[11]); b43legacy_write16(dev, 0x03EC, regstack[10]); } b43legacy_phy_write(dev, 0x0015, regstack[0]);}static inlineu16 b43legacy_phy_lo_g_deviation_subval(struct b43legacy_wldev *dev, u16 control){ struct b43legacy_phy *phy = &dev->phy; u16 ret; unsigned long flags; local_irq_save(flags); if (phy->gmode) { b43legacy_phy_write(dev, 0x15, 0xE300); control <<= 8; b43legacy_phy_write(dev, 0x0812, control | 0x00B0); udelay(5); b43legacy_phy_write(dev, 0x0812, control | 0x00B2); udelay(2); b43legacy_phy_write(dev, 0x0812, control | 0x00B3); udelay(4); b43legacy_phy_write(dev, 0x0015, 0xF300); udelay(8); } else { b43legacy_phy_write(dev, 0x0015, control | 0xEFA0); udelay(2); b43legacy_phy_write(dev, 0x0015, control | 0xEFE0); udelay(4); b43legacy_phy_write(dev, 0x0015, control | 0xFFE0); udelay(8); } ret = b43legacy_phy_read(dev, 0x002D); local_irq_restore(flags); b43legacy_voluntary_preempt(); return ret;}static u32 b43legacy_phy_lo_g_singledeviation(struct b43legacy_wldev *dev, u16 control){ int i; u32 ret = 0; for (i = 0; i < 8; i++) ret += b43legacy_phy_lo_g_deviation_subval(dev, control); return ret;}/* Write the LocalOscillator CONTROL */static inlinevoid b43legacy_lo_write(struct b43legacy_wldev *dev, struct b43legacy_lopair *pair){ u16 value; value = (u8)(pair->low); value |= ((u8)(pair->high)) << 8;#ifdef CONFIG_B43LEGACY_DEBUG /* Sanity check. */ if (pair->low < -8 || pair->low > 8 || pair->high < -8 || pair->high > 8) { struct b43legacy_phy *phy = &dev->phy; b43legacydbg(dev->wl, "WARNING: Writing invalid LOpair " "(low: %d, high: %d, index: %lu)\n", pair->low, pair->high, (unsigned long)(pair - phy->_lo_pairs)); dump_stack(); }#endif b43legacy_phy_write(dev, B43legacy_PHY_G_LO_CONTROL, value);}static inlinestruct b43legacy_lopair *b43legacy_find_lopair(struct b43legacy_wldev *dev, u16 bbatt, u16 rfatt, u16 tx){ static const u8 dict[10] = { 11, 10, 11, 12, 13, 12, 13, 12, 13, 12 }; struct b43legacy_phy *phy = &dev->phy; if (bbatt > 6) bbatt = 6; B43legacy_WARN_ON(rfatt >= 10); if (tx == 3) return b43legacy_get_lopair(phy, rfatt, bbatt); return b43legacy_get_lopair(phy, dict[rfatt], bbatt);}static inlinestruct b43legacy_lopair *b43legacy_current_lopair(struct b43legacy_wldev *dev){ struct b43legacy_phy *phy = &dev->phy; return b43legacy_find_lopair(dev, phy->bbatt, phy->rfatt, phy->txctl1);}/* Adjust B/G LO */void b43legacy_phy_lo_adjust(struct b43legacy_wldev *dev, int fixed)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -