📄 lo.c
字号:
if (feedthrough < min_feedth) { lo->tx_bias = tx_bias; lo->tx_magn = tx_magn; min_feedth = feedthrough; } if (lo->tx_bias == 0) break; } b43_radio_write16(dev, 0x52, (b43_radio_read16(dev, 0x52) & 0xFF00) | lo->tx_bias | lo-> tx_magn); } } else { lo->tx_magn = 0; lo->tx_bias = 0; b43_radio_write16(dev, 0x52, b43_radio_read16(dev, 0x52) & 0xFFF0); /* TX bias == 0 */ }}static void lo_read_power_vector(struct b43_wldev *dev){ struct b43_phy *phy = &dev->phy; struct b43_txpower_lo_control *lo = phy->lo_control; u16 i; u64 tmp; u64 power_vector = 0; int rf_offset, bb_offset; struct b43_loctl *loctl; for (i = 0; i < 8; i += 2) { tmp = b43_shm_read16(dev, B43_SHM_SHARED, 0x310 + i); /* Clear the top byte. We get holes in the bitmap... */ tmp &= 0xFF; power_vector |= (tmp << (i * 8)); /* Clear the vector on the device. */ b43_shm_write16(dev, B43_SHM_SHARED, 0x310 + i, 0); } if (power_vector) lo->power_vector = power_vector; power_vector = lo->power_vector; for (i = 0; i < 64; i++) { if (power_vector & ((u64) 1ULL << i)) { /* Now figure out which b43_loctl corresponds * to this bit. */ rf_offset = i / lo->rfatt_list.len; bb_offset = i % lo->rfatt_list.len; //FIXME? loctl = b43_get_lo_g_ctl(dev, &lo->rfatt_list.list[rf_offset], &lo->bbatt_list.list[bb_offset]); /* And mark it as "used", as the device told us * through the bitmap it is using it. */ loctl->used = 1; } }}/* 802.11/LO/GPHY/MeasuringGains */static void lo_measure_gain_values(struct b43_wldev *dev, s16 max_rx_gain, int use_trsw_rx){ struct b43_phy *phy = &dev->phy; u16 tmp; if (max_rx_gain < 0) max_rx_gain = 0; if (has_loopback_gain(phy)) { int trsw_rx = 0; int trsw_rx_gain; if (use_trsw_rx) { trsw_rx_gain = phy->trsw_rx_gain / 2; if (max_rx_gain >= trsw_rx_gain) { trsw_rx_gain = max_rx_gain - trsw_rx_gain; trsw_rx = 0x20; } } else trsw_rx_gain = max_rx_gain; if (trsw_rx_gain < 9) { phy->lna_lod_gain = 0; } else { phy->lna_lod_gain = 1; trsw_rx_gain -= 8; } trsw_rx_gain = limit_value(trsw_rx_gain, 0, 0x2D); phy->pga_gain = trsw_rx_gain / 3; if (phy->pga_gain >= 5) { phy->pga_gain -= 5; phy->lna_gain = 2; } else phy->lna_gain = 0; } else { phy->lna_gain = 0; phy->trsw_rx_gain = 0x20; if (max_rx_gain >= 0x14) { phy->lna_lod_gain = 1; phy->pga_gain = 2; } else if (max_rx_gain >= 0x12) { phy->lna_lod_gain = 1; phy->pga_gain = 1; } else if (max_rx_gain >= 0xF) { phy->lna_lod_gain = 1; phy->pga_gain = 0; } else { phy->lna_lod_gain = 0; phy->pga_gain = 0; } } tmp = b43_radio_read16(dev, 0x7A); if (phy->lna_lod_gain == 0) tmp &= ~0x0008; else tmp |= 0x0008; b43_radio_write16(dev, 0x7A, tmp);}struct lo_g_saved_values { u8 old_channel; /* Core registers */ u16 reg_3F4; u16 reg_3E2; /* PHY registers */ u16 phy_lo_mask; u16 phy_extg_01; u16 phy_dacctl_hwpctl; u16 phy_dacctl; u16 phy_base_14; u16 phy_hpwr_tssictl; u16 phy_analogover; u16 phy_analogoverval; u16 phy_rfover; u16 phy_rfoverval; u16 phy_classctl; u16 phy_base_3E; u16 phy_crs0; u16 phy_pgactl; u16 phy_base_2A; u16 phy_syncctl; u16 phy_base_30; u16 phy_base_06; /* Radio registers */ u16 radio_43; u16 radio_7A; u16 radio_52;};static void lo_measure_setup(struct b43_wldev *dev, struct lo_g_saved_values *sav){ struct ssb_sprom *sprom = &dev->dev->bus->sprom; struct b43_phy *phy = &dev->phy; struct b43_txpower_lo_control *lo = phy->lo_control; u16 tmp; if (b43_has_hardware_pctl(phy)) { sav->phy_lo_mask = b43_phy_read(dev, B43_PHY_LO_MASK); sav->phy_extg_01 = b43_phy_read(dev, B43_PHY_EXTG(0x01)); sav->phy_dacctl_hwpctl = b43_phy_read(dev, B43_PHY_DACCTL); sav->phy_base_14 = b43_phy_read(dev, B43_PHY_BASE(0x14)); sav->phy_hpwr_tssictl = b43_phy_read(dev, B43_PHY_HPWR_TSSICTL); b43_phy_write(dev, B43_PHY_HPWR_TSSICTL, b43_phy_read(dev, B43_PHY_HPWR_TSSICTL) | 0x100); b43_phy_write(dev, B43_PHY_EXTG(0x01), b43_phy_read(dev, B43_PHY_EXTG(0x01)) | 0x40); b43_phy_write(dev, B43_PHY_DACCTL, b43_phy_read(dev, B43_PHY_DACCTL) | 0x40); b43_phy_write(dev, B43_PHY_BASE(0x14), b43_phy_read(dev, B43_PHY_BASE(0x14)) | 0x200); } if (phy->type == B43_PHYTYPE_B && phy->radio_ver == 0x2050 && phy->radio_rev < 6) { b43_phy_write(dev, B43_PHY_BASE(0x16), 0x410); b43_phy_write(dev, B43_PHY_BASE(0x17), 0x820); } if (!lo->rebuild && b43_has_hardware_pctl(phy)) lo_read_power_vector(dev); if (phy->rev >= 2) { sav->phy_analogover = b43_phy_read(dev, B43_PHY_ANALOGOVER); sav->phy_analogoverval = b43_phy_read(dev, B43_PHY_ANALOGOVERVAL); sav->phy_rfover = b43_phy_read(dev, B43_PHY_RFOVER); sav->phy_rfoverval = b43_phy_read(dev, B43_PHY_RFOVERVAL); sav->phy_classctl = b43_phy_read(dev, B43_PHY_CLASSCTL); sav->phy_base_3E = b43_phy_read(dev, B43_PHY_BASE(0x3E)); sav->phy_crs0 = b43_phy_read(dev, B43_PHY_CRS0); b43_phy_write(dev, B43_PHY_CLASSCTL, b43_phy_read(dev, B43_PHY_CLASSCTL) & 0xFFFC); b43_phy_write(dev, B43_PHY_CRS0, b43_phy_read(dev, B43_PHY_CRS0) & 0x7FFF); b43_phy_write(dev, B43_PHY_ANALOGOVER, b43_phy_read(dev, B43_PHY_ANALOGOVER) | 0x0003); b43_phy_write(dev, B43_PHY_ANALOGOVERVAL, b43_phy_read(dev, B43_PHY_ANALOGOVERVAL) & 0xFFFC); if (phy->type == B43_PHYTYPE_G) { if ((phy->rev >= 7) && (sprom->r1.boardflags_lo & B43_BFL_EXTLNA)) { b43_phy_write(dev, B43_PHY_RFOVER, 0x933); } else { b43_phy_write(dev, B43_PHY_RFOVER, 0x133); } } else { b43_phy_write(dev, B43_PHY_RFOVER, 0); } b43_phy_write(dev, B43_PHY_BASE(0x3E), 0); } sav->reg_3F4 = b43_read16(dev, 0x3F4); sav->reg_3E2 = b43_read16(dev, 0x3E2); sav->radio_43 = b43_radio_read16(dev, 0x43); sav->radio_7A = b43_radio_read16(dev, 0x7A); sav->phy_pgactl = b43_phy_read(dev, B43_PHY_PGACTL); sav->phy_base_2A = b43_phy_read(dev, B43_PHY_BASE(0x2A)); sav->phy_syncctl = b43_phy_read(dev, B43_PHY_SYNCCTL); sav->phy_dacctl = b43_phy_read(dev, B43_PHY_DACCTL); if (!has_tx_magnification(phy)) { sav->radio_52 = b43_radio_read16(dev, 0x52); sav->radio_52 &= 0x00F0; } if (phy->type == B43_PHYTYPE_B) { sav->phy_base_30 = b43_phy_read(dev, B43_PHY_BASE(0x30)); sav->phy_base_06 = b43_phy_read(dev, B43_PHY_BASE(0x06)); b43_phy_write(dev, B43_PHY_BASE(0x30), 0x00FF); b43_phy_write(dev, B43_PHY_BASE(0x06), 0x3F3F); } else { b43_write16(dev, 0x3E2, b43_read16(dev, 0x3E2) | 0x8000); } b43_write16(dev, 0x3F4, b43_read16(dev, 0x3F4) & 0xF000); tmp = (phy->type == B43_PHYTYPE_G) ? B43_PHY_LO_MASK : B43_PHY_BASE(0x2E); b43_phy_write(dev, tmp, 0x007F); tmp = sav->phy_syncctl; b43_phy_write(dev, B43_PHY_SYNCCTL, tmp & 0xFF7F); tmp = sav->radio_7A; b43_radio_write16(dev, 0x007A, tmp & 0xFFF0); b43_phy_write(dev, B43_PHY_BASE(0x2A), 0x8A3); if (phy->type == B43_PHYTYPE_G || (phy->type == B43_PHYTYPE_B && phy->radio_ver == 0x2050 && phy->radio_rev >= 6)) { b43_phy_write(dev, B43_PHY_BASE(0x2B), 0x1003); } else b43_phy_write(dev, B43_PHY_BASE(0x2B), 0x0802); if (phy->rev >= 2) b43_dummy_transmission(dev); b43_radio_selectchannel(dev, 6, 0); b43_radio_read16(dev, 0x51); /* dummy read */ if (phy->type == B43_PHYTYPE_G) b43_phy_write(dev, B43_PHY_BASE(0x2F), 0); if (lo->rebuild) lo_measure_txctl_values(dev); if (phy->type == B43_PHYTYPE_G && phy->rev >= 3) { b43_phy_write(dev, B43_PHY_LO_MASK, 0xC078); } else { if (phy->type == B43_PHYTYPE_B) b43_phy_write(dev, B43_PHY_BASE(0x2E), 0x8078); else b43_phy_write(dev, B43_PHY_LO_MASK, 0x8078); }}static void lo_measure_restore(struct b43_wldev *dev, struct lo_g_saved_values *sav){ struct b43_phy *phy = &dev->phy; struct b43_txpower_lo_control *lo = phy->lo_control; u16 tmp; if (phy->rev >= 2) { b43_phy_write(dev, B43_PHY_PGACTL, 0xE300); tmp = (phy->pga_gain << 8); b43_phy_write(dev, B43_PHY_RFOVERVAL, tmp | 0xA0); udelay(5); b43_phy_write(dev, B43_PHY_RFOVERVAL, tmp | 0xA2); udelay(2); b43_phy_write(dev, B43_PHY_RFOVERVAL, tmp | 0xA3); } else { tmp = (phy->pga_gain | 0xEFA0); b43_phy_write(dev, B43_PHY_PGACTL, tmp); } if (b43_has_hardware_pctl(phy)) { b43_gphy_dc_lt_init(dev); } else { if (lo->rebuild) b43_lo_g_adjust_to(dev, 3, 2, 0); else b43_lo_g_adjust(dev); } if (phy->type == B43_PHYTYPE_G) { if (phy->rev >= 3) b43_phy_write(dev, B43_PHY_BASE(0x2E), 0xC078); else b43_phy_write(dev, B43_PHY_BASE(0x2E), 0x8078); if (phy->rev >= 2) b43_phy_write(dev, B43_PHY_BASE(0x2F), 0x0202); else b43_phy_write(dev, B43_PHY_BASE(0x2F), 0x0101); } b43_write16(dev, 0x3F4, sav->reg_3F4); b43_phy_write(dev, B43_PHY_PGACTL, sav->phy_pgactl); b43_phy_write(dev, B43_PHY_BASE(0x2A), sav->phy_base_2A); b43_phy_write(dev, B43_PHY_SYNCCTL, sav->phy_syncctl); b43_phy_write(dev, B43_PHY_DACCTL, sav->phy_dacctl); b43_radio_write16(dev, 0x43, sav->radio_43); b43_radio_write16(dev, 0x7A, sav->radio_7A); if (!has_tx_magnification(phy)) { tmp = sav->radio_52; b43_radio_write16(dev, 0x52, (b43_radio_read16(dev, 0x52) & 0xFF0F) | tmp); } b43_write16(dev, 0x3E2, sav->reg_3E2); if (phy->type == B43_PHYTYPE_B && phy->radio_ver == 0x2050 && phy->radio_rev <= 5) { b43_phy_write(dev, B43_PHY_BASE(0x30), sav->phy_base_30); b43_phy_write(dev, B43_PHY_BASE(0x06), sav->phy_base_06); } if (phy->rev >= 2) { b43_phy_write(dev, B43_PHY_ANALOGOVER, sav->phy_analogover); b43_phy_write(dev, B43_PHY_ANALOGOVERVAL, sav->phy_analogoverval); b43_phy_write(dev, B43_PHY_CLASSCTL, sav->phy_classctl); b43_phy_write(dev, B43_PHY_RFOVER, sav->phy_rfover); b43_phy_write(dev, B43_PHY_RFOVERVAL, sav->phy_rfoverval); b43_phy_write(dev, B43_PHY_BASE(0x3E), sav->phy_base_3E); b43_phy_write(dev, B43_PHY_CRS0, sav->phy_crs0); } if (b43_has_hardware_pctl(phy)) { tmp = (sav->phy_lo_mask & 0xBFFF); b43_phy_write(dev, B43_PHY_LO_MASK, tmp); b43_phy_write(dev, B43_PHY_EXTG(0x01), sav->phy_extg_01); b43_phy_write(dev, B43_PHY_DACCTL, sav->phy_dacctl_hwpctl); b43_phy_write(dev, B43_PHY_BASE(0x14), sav->phy_base_14); b43_phy_write(dev, B43_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl); } b43_radio_selectchannel(dev, sav->old_channel, 1);}struct b43_lo_g_statemachine { int current_state; int nr_measured; int state_val_multiplier; u16 lowest_feedth; struct b43_loctl min_loctl;};/* Loop over each possible value in this state. */static int lo_probe_possible_loctls(struct b43_wldev *dev, struct b43_loctl *probe_loctl, struct b43_lo_g_statemachine *d){ struct b43_phy *phy = &dev->phy; struct b43_txpower_lo_control *lo = phy->lo_control; struct b43_loctl test_loctl; struct b43_loctl orig_loctl; struct b43_loctl prev_loctl = { .i = -100, .q = -100, }; int i; int begin, end; int found_lower = 0; u16 feedth; static const struct b43_loctl modifiers[] = { {.i = 1,.q = 1,}, {.i = 1,.q = 0,}, {.i = 1,.q = -1,}, {.i = 0,.q = -1,}, {.i = -1,.q = -1,}, {.i = -1,.q = 0,}, {.i = -1,.q = 1,}, {.i = 0,.q = 1,}, }; if (d->current_state == 0) { begin = 1; end = 8; } else if (d->current_state % 2 == 0) { begin = d->current_state - 1; end = d->current_state + 1; } else { begin = d->current_state - 2; end = d->current_state + 2; } if (begin < 1) begin += 8; if (end > 8) end -= 8; memcpy(&orig_loctl, probe_loctl, sizeof(struct b43_loctl)); i = begin; d->current_state = i; while (1) { B43_WARN_ON(!(i >= 1 && i <= 8)); memcpy(&test_loctl, &orig_loctl, sizeof(struct b43_loctl)); test_loctl.i += modifiers[i - 1].i * d->state_val_multiplier; test_loctl.q += modifiers[i - 1].q * d->state_val_multiplier; if ((test_loctl.i != prev_loctl.i ||
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -