static void b43_phy_ht_tx_power_ctl_idle_tssi(struct b43_wldev *dev) { struct b43_phy_ht *phy_ht = dev->phy.ht; static const u16 base[] = { 0x840, 0x860, 0x880 }; u16 save_regs[3][3]; s32 rssi_buf[6]; int core; for (core = 0; core < 3; core++) { save_regs[core][1] = b43_phy_read(dev, base[core] + 6); save_regs[core][2] = b43_phy_read(dev, base[core] + 7); save_regs[core][0] = b43_phy_read(dev, base[core] + 0); b43_phy_write(dev, base[core] + 6, 0); b43_phy_mask(dev, base[core] + 7, ~0xF); /* 0xF? Or just 0x6? */ b43_phy_set(dev, base[core] + 0, 0x0400); b43_phy_set(dev, base[core] + 0, 0x1000); } b43_phy_ht_tx_tone(dev); udelay(20); b43_phy_ht_poll_rssi(dev, HT_RSSI_TSSI_2G, rssi_buf, 1); b43_phy_ht_stop_playback(dev); b43_phy_ht_reset_cca(dev); phy_ht->idle_tssi[0] = rssi_buf[0] & 0xff; phy_ht->idle_tssi[1] = rssi_buf[2] & 0xff; phy_ht->idle_tssi[2] = rssi_buf[4] & 0xff; for (core = 0; core < 3; core++) { b43_phy_write(dev, base[core] + 0, save_regs[core][0]); b43_phy_write(dev, base[core] + 6, save_regs[core][1]); b43_phy_write(dev, base[core] + 7, save_regs[core][2]); } }
static void b43_phy_ww(struct b43_wldev *dev) { u16 b, curr_s, best_s = 0xFFFF; int i; b43_phy_write(dev, B43_PHY_CRS0, b43_phy_read(dev, B43_PHY_CRS0) & ~B43_PHY_CRS0_EN); b43_phy_write(dev, B43_PHY_OFDM(0x1B), b43_phy_read(dev, B43_PHY_OFDM(0x1B)) | 0x1000); b43_phy_write(dev, B43_PHY_OFDM(0x82), (b43_phy_read(dev, B43_PHY_OFDM(0x82)) & 0xF0FF) | 0x0300); b43_radio_write16(dev, 0x0009, b43_radio_read16(dev, 0x0009) | 0x0080); b43_radio_write16(dev, 0x0012, (b43_radio_read16(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_write16(dev, 0x0004, b43_radio_read16(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_write16(dev, 0x0004, b43_radio_read16(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_write(dev, B43_PHY_OFDM(0xBB), (b43_phy_read(dev, B43_PHY_OFDM(0xBB)) & 0xF000) | 0x0053); b43_phy_write(dev, B43_PHY_OFDM61, (b43_phy_read(dev, B43_PHY_OFDM61) & 0xFE1F) | 0x0120); b43_phy_write(dev, B43_PHY_OFDM(0x13), (b43_phy_read(dev, B43_PHY_OFDM(0x13)) & 0x0FFF) | 0x3000); b43_phy_write(dev, B43_PHY_OFDM(0x14), (b43_phy_read(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_write(dev, B43_PHY_CRS0, b43_phy_read(dev, B43_PHY_CRS0) | B43_PHY_CRS0_EN); }
u32 b43_lcntab_read(struct b43_wldev *dev, u32 offset) { u32 type, value; type = offset & B43_LCNTAB_TYPEMASK; offset &= ~B43_LCNTAB_TYPEMASK; B43_WARN_ON(offset > 0xFFFF); switch (type) { case B43_LCNTAB_8BIT: b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset); value = b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO) & 0xFF; break; case B43_LCNTAB_16BIT: b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset); value = b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO); break; case B43_LCNTAB_32BIT: b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset); value = b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO); value |= (b43_phy_read(dev, B43_PHY_LCN_TABLE_DATAHI) << 16); break; default: B43_WARN_ON(1); value = 0; } return value; }
static void b43_aphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna) {//TODO struct b43_phy *phy = &dev->phy; u64 hf; u16 tmp; int autodiv = 0; if (antenna == B43_ANTENNA_AUTO0 || antenna == B43_ANTENNA_AUTO1) autodiv = 1; hf = b43_hf_read(dev); hf &= ~B43_HF_ANTDIVHELP; b43_hf_write(dev, hf); tmp = b43_phy_read(dev, B43_PHY_BBANDCFG); tmp &= ~B43_PHY_BBANDCFG_RXANT; tmp |= (autodiv ? B43_ANTENNA_AUTO0 : antenna) << B43_PHY_BBANDCFG_RXANT_SHIFT; b43_phy_write(dev, B43_PHY_BBANDCFG, tmp); if (autodiv) { tmp = b43_phy_read(dev, B43_PHY_ANTDWELL); if (antenna == B43_ANTENNA_AUTO0) tmp &= ~B43_PHY_ANTDWELL_AUTODIV1; else tmp |= B43_PHY_ANTDWELL_AUTODIV1; b43_phy_write(dev, B43_PHY_ANTDWELL, tmp); } if (phy->rev < 3) { tmp = b43_phy_read(dev, B43_PHY_ANTDWELL); tmp = (tmp & 0xFF00) | 0x24; b43_phy_write(dev, B43_PHY_ANTDWELL, tmp); } else { tmp = b43_phy_read(dev, B43_PHY_OFDM61); tmp |= 0x10; b43_phy_write(dev, B43_PHY_OFDM61, tmp); if (phy->analog == 3) { b43_phy_write(dev, B43_PHY_CLIPPWRDOWNT, 0x1D); b43_phy_write(dev, B43_PHY_ADIVRELATED, 8); } else { b43_phy_write(dev, B43_PHY_CLIPPWRDOWNT, 0x3A); tmp = b43_phy_read(dev, B43_PHY_ADIVRELATED); tmp = (tmp & 0xFF00) | 8; b43_phy_write(dev, B43_PHY_ADIVRELATED, tmp); } } hf |= B43_HF_ANTDIVHELP; b43_hf_write(dev, hf); }
u32 b43_ofdmtab_read32(struct b43_wldev *dev, u16 table, u16 offset) { u32 ret; b43_phy_write(dev, B43_PHY_OTABLECTL, table + offset); ret = b43_phy_read(dev, B43_PHY_OTABLEQ); ret <<= 16; ret |= b43_phy_read(dev, B43_PHY_OTABLEI); return ret; }
/* wlc_lcnphy_toggle_afe_pwdn */ static void b43_phy_lcn_afe_set_unset(struct b43_wldev *dev) { u16 afe_ctl2 = b43_phy_read(dev, B43_PHY_LCN_AFE_CTL2); u16 afe_ctl1 = b43_phy_read(dev, B43_PHY_LCN_AFE_CTL1); b43_phy_write(dev, B43_PHY_LCN_AFE_CTL2, afe_ctl2 | 0x1); b43_phy_write(dev, B43_PHY_LCN_AFE_CTL1, afe_ctl1 | 0x1); b43_phy_write(dev, B43_PHY_LCN_AFE_CTL2, afe_ctl2 & ~0x1); b43_phy_write(dev, B43_PHY_LCN_AFE_CTL1, afe_ctl1 & ~0x1); b43_phy_write(dev, B43_PHY_LCN_AFE_CTL2, afe_ctl2); b43_phy_write(dev, B43_PHY_LCN_AFE_CTL1, afe_ctl1); }
u16 b43_ofdmtab_read16(struct b43_wldev *dev, u16 table, u16 offset) { assert_sizes(); b43_phy_write(dev, B43_PHY_OTABLECTL, table + offset); return b43_phy_read(dev, B43_PHY_OTABLEI); }
static u16 lo_measure_feedthrough(struct b43_wldev *dev, u16 lna, u16 pga, u16 trsw_rx) { struct b43_phy *phy = &dev->phy; u16 rfover; u16 feedthrough; if (phy->gmode) { lna <<= B43_PHY_RFOVERVAL_LNA_SHIFT; pga <<= B43_PHY_RFOVERVAL_PGA_SHIFT; B43_WARN_ON(lna & ~B43_PHY_RFOVERVAL_LNA); B43_WARN_ON(pga & ~B43_PHY_RFOVERVAL_PGA); /*FIXME This assertion fails B43_WARN_ON(trsw_rx & ~(B43_PHY_RFOVERVAL_TRSWRX | B43_PHY_RFOVERVAL_BW)); */ trsw_rx &= (B43_PHY_RFOVERVAL_TRSWRX | B43_PHY_RFOVERVAL_BW); /* Construct the RF Override Value */ rfover = B43_PHY_RFOVERVAL_UNK; rfover |= pga; rfover |= lna; rfover |= trsw_rx; if ((dev->dev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) && phy->rev > 6) rfover |= B43_PHY_RFOVERVAL_EXTLNA; b43_phy_write(dev, B43_PHY_PGACTL, 0xE300); b43_phy_write(dev, B43_PHY_RFOVERVAL, rfover); udelay(10); rfover |= B43_PHY_RFOVERVAL_BW_LBW; b43_phy_write(dev, B43_PHY_RFOVERVAL, rfover); udelay(10); rfover |= B43_PHY_RFOVERVAL_BW_LPF; b43_phy_write(dev, B43_PHY_RFOVERVAL, rfover); udelay(10); b43_phy_write(dev, B43_PHY_PGACTL, 0xF300); } else { pga |= B43_PHY_PGACTL_UNKNOWN; b43_phy_write(dev, B43_PHY_PGACTL, pga); udelay(10); pga |= B43_PHY_PGACTL_LOWBANDW; b43_phy_write(dev, B43_PHY_PGACTL, pga); udelay(10); pga |= B43_PHY_PGACTL_LPF; b43_phy_write(dev, B43_PHY_PGACTL, pga); } udelay(21); feedthrough = b43_phy_read(dev, B43_PHY_LO_LEAKAGE); /* This is a good place to check if we need to relax a bit, * as this is the main function called regularly * in the LO calibration. */ cond_resched(); return feedthrough; }
/* wlc_lcnphy_set_dac_gain */ static void b43_phy_lcn_set_dac_gain(struct b43_wldev *dev, u16 dac_gain) { u16 dac_ctrl; dac_ctrl = b43_phy_read(dev, 0x439); dac_ctrl = dac_ctrl & 0xc7f; dac_ctrl = dac_ctrl | (dac_gain << 7); b43_phy_maskset(dev, 0x439, ~0xfff, dac_ctrl); }
void b43_phy_inita(struct b43_wldev *dev) { struct ssb_bus *bus = dev->dev->bus; struct b43_phy *phy = &dev->phy; /* This lowlevel A-PHY init is also called from G-PHY init. * So we must not access phy->a, if called from G-PHY code. */ B43_WARN_ON((phy->type != B43_PHYTYPE_A) && (phy->type != B43_PHYTYPE_G)); might_sleep(); if (phy->rev >= 6) { if (phy->type == B43_PHYTYPE_A) b43_phy_write(dev, B43_PHY_OFDM(0x1B), b43_phy_read(dev, B43_PHY_OFDM(0x1B)) & ~0x1000); if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN) b43_phy_write(dev, B43_PHY_ENCORE, b43_phy_read(dev, B43_PHY_ENCORE) | 0x0010); else b43_phy_write(dev, B43_PHY_ENCORE, b43_phy_read(dev, B43_PHY_ENCORE) & ~0x1010); } b43_wa_all(dev); if (phy->type == B43_PHYTYPE_A) { if (phy->gmode && (phy->rev < 3)) b43_phy_write(dev, 0x0034, b43_phy_read(dev, 0x0034) | 0x0001); b43_phy_rssiagc(dev, 0); b43_phy_write(dev, B43_PHY_CRS0, b43_phy_read(dev, B43_PHY_CRS0) | B43_PHY_CRS0_EN); b43_radio_init2060(dev); if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && ((bus->boardinfo.type == SSB_BOARD_BU4306) || (bus->boardinfo.type == SSB_BOARD_BU4309))) { ; //TODO: A PHY LO } if (phy->rev >= 3) b43_phy_ww(dev); hardware_pctl_init_aphy(dev); //TODO: radar detection } if ((phy->type == B43_PHYTYPE_G) && (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)) { b43_phy_write(dev, B43_PHY_OFDM(0x6E), (b43_phy_read(dev, B43_PHY_OFDM(0x6E)) & 0xE000) | 0x3CF); } }
void b43_phy_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set) { if (dev->phy.ops->phy_maskset) { assert_mac_suspended(dev); dev->phy.ops->phy_maskset(dev, offset, mask, set); } else { b43_phy_write(dev, offset, (b43_phy_read(dev, offset) & mask) | set); } }
static void b43_phy_ht_force_rf_sequence(struct b43_wldev *dev, u16 rf_seq) { u8 i; u16 save_seq_mode = b43_phy_read(dev, B43_PHY_HT_RF_SEQ_MODE); b43_phy_set(dev, B43_PHY_HT_RF_SEQ_MODE, 0x3); b43_phy_set(dev, B43_PHY_HT_RF_SEQ_TRIG, rf_seq); for (i = 0; i < 200; i++) { if (!(b43_phy_read(dev, B43_PHY_HT_RF_SEQ_STATUS) & rf_seq)) { i = 0; break; } msleep(1); } if (i) b43err(dev->wl, "Forcing RF sequence timeout\n"); b43_phy_write(dev, B43_PHY_HT_RF_SEQ_MODE, save_seq_mode); }
u32 b43_ofdmtab_read32(struct b43_wldev *dev, u16 table, u16 offset) { struct b43_phy_g *gphy = dev->phy.g; u32 ret; u16 addr; addr = table + offset; if ((gphy->ofdmtab_addr_direction != B43_OFDMTAB_DIRECTION_READ) || (addr - 1 != gphy->ofdmtab_addr)) { /* The hardware has a different address in memory. Update it. */ b43_phy_write(dev, B43_PHY_OTABLECTL, addr); gphy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_READ; } gphy->ofdmtab_addr = addr; ret = b43_phy_read(dev, B43_PHY_OTABLEQ); ret <<= 16; ret |= b43_phy_read(dev, B43_PHY_OTABLEI); return ret; }
static void b43_aphy_op_software_rfkill(struct b43_wldev *dev, enum rfkill_state state) { struct b43_phy *phy = &dev->phy; if (state == RFKILL_STATE_UNBLOCKED) { if (phy->radio_on) return; b43_radio_write16(dev, 0x0004, 0x00C0); b43_radio_write16(dev, 0x0005, 0x0008); b43_phy_write(dev, 0x0010, b43_phy_read(dev, 0x0010) & 0xFFF7); b43_phy_write(dev, 0x0011, b43_phy_read(dev, 0x0011) & 0xFFF7); b43_radio_init2060(dev); } else { b43_radio_write16(dev, 0x0004, 0x00FF); b43_radio_write16(dev, 0x0005, 0x00FB); b43_phy_write(dev, 0x0010, b43_phy_read(dev, 0x0010) | 0x0008); b43_phy_write(dev, 0x0011, b43_phy_read(dev, 0x0011) | 0x0008); } }
static void b43_phy_ht_run_samples(struct b43_wldev *dev, u16 samps, u16 loops, u16 wait) { struct b43_phy_ht *phy_ht = dev->phy.ht; u16 save_seq_mode; int i; for (i = 0; i < 3; i++) { if (phy_ht->bb_mult_save[i] < 0) phy_ht->bb_mult_save[i] = b43_httab_read(dev, B43_HTTAB16(13, 0x63 + i * 4)); } b43_phy_write(dev, B43_PHY_HT_SAMP_DEP_CNT, samps - 1); if (loops != 0xFFFF) loops--; b43_phy_write(dev, B43_PHY_HT_SAMP_LOOP_CNT, loops); b43_phy_write(dev, B43_PHY_HT_SAMP_WAIT_CNT, wait); save_seq_mode = b43_phy_read(dev, B43_PHY_HT_RF_SEQ_MODE); b43_phy_set(dev, B43_PHY_HT_RF_SEQ_MODE, B43_PHY_HT_RF_SEQ_MODE_CA_OVER); /* TODO: find out mask bits! Do we need more function arguments? */ b43_phy_mask(dev, B43_PHY_HT_SAMP_CMD, ~0); b43_phy_mask(dev, B43_PHY_HT_SAMP_CMD, ~0); b43_phy_mask(dev, B43_PHY_HT_IQLOCAL_CMDGCTL, ~0); b43_phy_set(dev, B43_PHY_HT_SAMP_CMD, 0x1); for (i = 0; i < 100; i++) { if (!(b43_phy_read(dev, B43_PHY_HT_RF_SEQ_STATUS) & 1)) { i = 0; break; } udelay(10); } if (i) b43err(dev->wl, "run samples timeout\n"); b43_phy_write(dev, B43_PHY_HT_RF_SEQ_MODE, save_seq_mode); }
static void b43_nphy_reset_cca(struct b43_wldev *dev) { u16 bbcfg; ssb_write32(dev->dev, SSB_TMSLOW, ssb_read32(dev->dev, SSB_TMSLOW) | SSB_TMSLOW_FGC); bbcfg = b43_phy_read(dev, B43_NPHY_BBCFG); b43_phy_set(dev, B43_NPHY_BBCFG, B43_NPHY_BBCFG_RSTCCA); b43_phy_write(dev, B43_NPHY_BBCFG, bbcfg & ~B43_NPHY_BBCFG_RSTCCA); ssb_write32(dev->dev, SSB_TMSLOW, ssb_read32(dev->dev, SSB_TMSLOW) & ~SSB_TMSLOW_FGC); }
static void b43_phy_ht_tx_power_ctl(struct b43_wldev *dev, bool enable) { struct b43_phy_ht *phy_ht = dev->phy.ht; u16 en_bits = B43_PHY_HT_TXPCTL_CMD_C1_COEFF | B43_PHY_HT_TXPCTL_CMD_C1_HWPCTLEN | B43_PHY_HT_TXPCTL_CMD_C1_PCTLEN; static const u16 cmd_regs[3] = { B43_PHY_HT_TXPCTL_CMD_C1, B43_PHY_HT_TXPCTL_CMD_C2, B43_PHY_HT_TXPCTL_CMD_C3 }; static const u16 status_regs[3] = { B43_PHY_HT_TX_PCTL_STATUS_C1, B43_PHY_HT_TX_PCTL_STATUS_C2, B43_PHY_HT_TX_PCTL_STATUS_C3 }; int i; if (!enable) { if (b43_phy_read(dev, B43_PHY_HT_TXPCTL_CMD_C1) & en_bits) { /* We disable enabled TX pwr ctl, save it's state */ for (i = 0; i < 3; i++) phy_ht->tx_pwr_idx[i] = b43_phy_read(dev, status_regs[i]); } b43_phy_mask(dev, B43_PHY_HT_TXPCTL_CMD_C1, ~en_bits); } else { b43_phy_set(dev, B43_PHY_HT_TXPCTL_CMD_C1, en_bits); if (b43_current_band(dev->wl) == NL80211_BAND_5GHZ) { for (i = 0; i < 3; i++) b43_phy_write(dev, cmd_regs[i], 0x32); } for (i = 0; i < 3; i++) if (phy_ht->tx_pwr_idx[i] <= B43_PHY_HT_TXPCTL_CMD_C1_INIT) b43_phy_write(dev, cmd_regs[i], phy_ht->tx_pwr_idx[i]); } phy_ht->tx_pwr_ctl = enable; }
static void b43_phy_ht_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, u8 nsamp) { u16 phy_regs_values[12]; static const u16 phy_regs_to_save[] = { B43_PHY_HT_AFE_C1, B43_PHY_HT_AFE_C1_OVER, 0x848, 0x841, B43_PHY_HT_AFE_C2, B43_PHY_HT_AFE_C2_OVER, 0x868, 0x861, B43_PHY_HT_AFE_C3, B43_PHY_HT_AFE_C3_OVER, 0x888, 0x881, }; u16 tmp[3]; int i; for (i = 0; i < 12; i++) phy_regs_values[i] = b43_phy_read(dev, phy_regs_to_save[i]); b43_phy_ht_rssi_select(dev, 5, type); for (i = 0; i < 6; i++) buf[i] = 0; for (i = 0; i < nsamp; i++) { tmp[0] = b43_phy_read(dev, B43_PHY_HT_RSSI_C1); tmp[1] = b43_phy_read(dev, B43_PHY_HT_RSSI_C2); tmp[2] = b43_phy_read(dev, B43_PHY_HT_RSSI_C3); buf[0] += ((s8)((tmp[0] & 0x3F) << 2)) >> 2; buf[1] += ((s8)(((tmp[0] >> 8) & 0x3F) << 2)) >> 2; buf[2] += ((s8)((tmp[1] & 0x3F) << 2)) >> 2; buf[3] += ((s8)(((tmp[1] >> 8) & 0x3F) << 2)) >> 2; buf[4] += ((s8)((tmp[2] & 0x3F) << 2)) >> 2; buf[5] += ((s8)(((tmp[2] >> 8) & 0x3F) << 2)) >> 2; } for (i = 0; i < 12; i++) b43_phy_write(dev, phy_regs_to_save[i], phy_regs_values[i]); }
static void b43_phy_ht_reset_cca(struct b43_wldev *dev) { u16 bbcfg; b43_phy_force_clock(dev, true); bbcfg = b43_phy_read(dev, B43_PHY_HT_BBCFG); b43_phy_write(dev, B43_PHY_HT_BBCFG, bbcfg | B43_PHY_HT_BBCFG_RSTCCA); udelay(1); b43_phy_write(dev, B43_PHY_HT_BBCFG, bbcfg & ~B43_PHY_HT_BBCFG_RSTCCA); b43_phy_force_clock(dev, false); b43_phy_ht_force_rf_sequence(dev, B43_PHY_HT_RF_SEQ_TRIG_RST2RX); }
void b43_lcntab_read_bulk(struct b43_wldev *dev, u32 offset, unsigned int nr_elements, void *_data) { u32 type; u8 *data = _data; unsigned int i; type = offset & B43_LCNTAB_TYPEMASK; offset &= ~B43_LCNTAB_TYPEMASK; B43_WARN_ON(offset > 0xFFFF); b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset); for (i = 0; i < nr_elements; i++) { switch (type) { case B43_LCNTAB_8BIT: *data = b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO) & 0xFF; data++; break; case B43_LCNTAB_16BIT: *((u16 *)data) = b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO); data += 2; break; case B43_LCNTAB_32BIT: *((u32 *)data) = b43_phy_read(dev, B43_PHY_LCN_TABLE_DATAHI); *((u32 *)data) <<= 16; *((u32 *)data) |= b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO); data += 4; break; default: B43_WARN_ON(1); } } }
void b43_phy_inita(struct b43_wldev *dev) { struct ssb_bus *bus = dev->dev->bus; struct b43_phy *phy = &dev->phy; B43_WARN_ON((phy->type != B43_PHYTYPE_A) && (phy->type != B43_PHYTYPE_G)); might_sleep(); if (phy->rev >= 6) { if (phy->type == B43_PHYTYPE_A) b43_phy_mask(dev, B43_PHY_OFDM(0x1B), ~0x1000); if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN) b43_phy_set(dev, B43_PHY_ENCORE, 0x0010); else b43_phy_mask(dev, B43_PHY_ENCORE, ~0x1010); } b43_wa_all(dev); if (phy->type == B43_PHYTYPE_A) { if (phy->gmode && (phy->rev < 3)) b43_phy_set(dev, 0x0034, 0x0001); b43_phy_rssiagc(dev, 0); b43_phy_set(dev, B43_PHY_CRS0, B43_PHY_CRS0_EN); b43_radio_init2060(dev); if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && ((bus->boardinfo.type == SSB_BOARD_BU4306) || (bus->boardinfo.type == SSB_BOARD_BU4309))) { ; } if (phy->rev >= 3) b43_phy_ww(dev); hardware_pctl_init_aphy(dev); } if ((phy->type == B43_PHYTYPE_G) && (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)) { b43_phy_maskset(dev, B43_PHY_OFDM(0x6E), 0xE000, 0x3CF); } }
static u16 b43_phy_ht_classifier(struct b43_wldev *dev, u16 mask, u16 val) { u16 tmp; u16 allowed = B43_PHY_HT_CLASS_CTL_CCK_EN | B43_PHY_HT_CLASS_CTL_OFDM_EN | B43_PHY_HT_CLASS_CTL_WAITED_EN; tmp = b43_phy_read(dev, B43_PHY_HT_CLASS_CTL); tmp &= allowed; tmp &= ~mask; tmp |= (val & mask); b43_phy_maskset(dev, B43_PHY_HT_CLASS_CTL, ~allowed, tmp); return tmp; }
static u16 lo_b_r15_loop(struct b43_wldev *dev) { int i; u16 ret = 0; for (i = 0; i < 10; i++) { b43_phy_write(dev, 0x0015, 0xAFA0); udelay(1); b43_phy_write(dev, 0x0015, 0xEFA0); udelay(10); b43_phy_write(dev, 0x0015, 0xFFA0); udelay(40); ret += b43_phy_read(dev, 0x002C); } return ret; }
static void b43_wa_analog(struct b43_wldev *dev) { struct b43_phy *phy = &dev->phy; u16 ofdmrev; ofdmrev = b43_phy_read(dev, B43_PHY_VERSION_OFDM) & B43_PHYVER_VERSION; if (ofdmrev > 2) { if (phy->type == B43_PHYTYPE_A) b43_phy_write(dev, B43_PHY_PWRDOWN, 0x1808); else b43_phy_write(dev, B43_PHY_PWRDOWN, 0x1000); } else { b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 3, 0x1044); b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 4, 0x7201); b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 6, 0x0040); } }
static void b43_phy_ht_channel_setup(struct b43_wldev *dev, const struct b43_phy_ht_channeltab_e_phy *e, struct ieee80211_channel *new_channel) { bool old_band_5ghz; u8 i; old_band_5ghz = b43_phy_read(dev, B43_PHY_HT_BANDCTL) & 0; /* FIXME */ if (new_channel->band == IEEE80211_BAND_5GHZ && !old_band_5ghz) { /* TODO */ } else if (new_channel->band == IEEE80211_BAND_2GHZ && old_band_5ghz) { /* TODO */ } b43_phy_write(dev, B43_PHY_HT_BW1, e->bw1); b43_phy_write(dev, B43_PHY_HT_BW2, e->bw2); b43_phy_write(dev, B43_PHY_HT_BW3, e->bw3); b43_phy_write(dev, B43_PHY_HT_BW4, e->bw4); b43_phy_write(dev, B43_PHY_HT_BW5, e->bw5); b43_phy_write(dev, B43_PHY_HT_BW6, e->bw6); /* TODO: some ops on PHY regs 0x0B0 and 0xC0A */ /* TODO: separated function? */ for (i = 0; i < 3; i++) { u16 mask; u32 tmp = b43_httab_read(dev, B43_HTTAB32(26, 0xE8)); if (0) /* FIXME */ mask = 0x2 << (i * 4); else mask = 0; b43_phy_mask(dev, B43_PHY_EXTG(0x108), mask); b43_httab_write(dev, B43_HTTAB16(7, 0x110 + i), tmp >> 16); b43_httab_write(dev, B43_HTTAB8(13, 0x63 + (i * 4)), tmp & 0xFF); b43_httab_write(dev, B43_HTTAB8(13, 0x73 + (i * 4)), tmp & 0xFF); } b43_phy_write(dev, 0x017e, 0x3830); }
static void b43_phy_ht_pa_override(struct b43_wldev *dev, bool enable) { struct b43_phy_ht *htphy = dev->phy.ht; static const u16 regs[3] = { B43_PHY_HT_RF_CTL_INT_C1, B43_PHY_HT_RF_CTL_INT_C2, B43_PHY_HT_RF_CTL_INT_C3 }; int i; if (enable) { for (i = 0; i < 3; i++) b43_phy_write(dev, regs[i], htphy->rf_ctl_int_save[i]); } else { for (i = 0; i < 3; i++) htphy->rf_ctl_int_save[i] = b43_phy_read(dev, regs[i]); /* TODO: Does 5GHz band use different value (not 0x0400)? */ for (i = 0; i < 3; i++) b43_phy_write(dev, regs[i], 0x0400); } }
u16 b43_ofdmtab_read16(struct b43_wldev *dev, u16 table, u16 offset) { struct b43_phy_g *gphy = dev->phy.g; u16 addr; addr = table + offset; if ((gphy->ofdmtab_addr_direction != B43_OFDMTAB_DIRECTION_READ) || (addr - 1 != gphy->ofdmtab_addr)) { b43_phy_write(dev, B43_PHY_OTABLECTL, addr); gphy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_READ; } gphy->ofdmtab_addr = addr; return b43_phy_read(dev, B43_PHY_OTABLEI); assert_sizes(); }
u16 b43_ofdmtab_read16(struct b43_wldev *dev, u16 table, u16 offset) { struct b43_phy_g *gphy = dev->phy.g; u16 addr; addr = table + offset; if ((gphy->ofdmtab_addr_direction != B43_OFDMTAB_DIRECTION_READ) || (addr - 1 != gphy->ofdmtab_addr)) { /* The hardware has a different address in memory. Update it. */ b43_phy_write(dev, B43_PHY_OTABLECTL, addr); gphy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_READ; } gphy->ofdmtab_addr = addr; return b43_phy_read(dev, B43_PHY_OTABLEI); /* Some compiletime assertions... */ assert_sizes(); }
static void b43_aphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna) {//TODO struct b43_phy *phy = &dev->phy; u16 tmp; int autodiv = 0; if (antenna == B43_ANTENNA_AUTO0 || antenna == B43_ANTENNA_AUTO1) autodiv = 1; b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_ANTDIVHELP); b43_phy_maskset(dev, B43_PHY_BBANDCFG, ~B43_PHY_BBANDCFG_RXANT, (autodiv ? B43_ANTENNA_AUTO1 : antenna) << B43_PHY_BBANDCFG_RXANT_SHIFT); if (autodiv) { tmp = b43_phy_read(dev, B43_PHY_ANTDWELL); if (antenna == B43_ANTENNA_AUTO1) tmp &= ~B43_PHY_ANTDWELL_AUTODIV1; else tmp |= B43_PHY_ANTDWELL_AUTODIV1; b43_phy_write(dev, B43_PHY_ANTDWELL, tmp); } if (phy->rev < 3) b43_phy_maskset(dev, B43_PHY_ANTDWELL, 0xFF00, 0x24); else { b43_phy_set(dev, B43_PHY_OFDM61, 0x10); if (phy->rev == 3) { b43_phy_write(dev, B43_PHY_CLIPPWRDOWNT, 0x1D); b43_phy_write(dev, B43_PHY_ADIVRELATED, 8); } else { b43_phy_write(dev, B43_PHY_CLIPPWRDOWNT, 0x3A); b43_phy_maskset(dev, B43_PHY_ADIVRELATED, 0xFF00, 8); } } b43_hf_write(dev, b43_hf_read(dev) | B43_HF_ANTDIVHELP); }
static void b43_phy_ht_stop_playback(struct b43_wldev *dev) { struct b43_phy_ht *phy_ht = dev->phy.ht; u16 tmp; int i; tmp = b43_phy_read(dev, B43_PHY_HT_SAMP_STAT); if (tmp & 0x1) b43_phy_set(dev, B43_PHY_HT_SAMP_CMD, B43_PHY_HT_SAMP_CMD_STOP); else if (tmp & 0x2) b43_phy_mask(dev, B43_PHY_HT_IQLOCAL_CMDGCTL, 0x7FFF); b43_phy_mask(dev, B43_PHY_HT_SAMP_CMD, ~0x0004); for (i = 0; i < 3; i++) { if (phy_ht->bb_mult_save[i] >= 0) { b43_httab_write(dev, B43_HTTAB16(13, 0x63 + i * 4), phy_ht->bb_mult_save[i]); b43_httab_write(dev, B43_HTTAB16(13, 0x67 + i * 4), phy_ht->bb_mult_save[i]); } } }