diff options
author | Marcus Glocker <mglocker@cvs.openbsd.org> | 2007-02-22 21:26:50 +0000 |
---|---|---|
committer | Marcus Glocker <mglocker@cvs.openbsd.org> | 2007-02-22 21:26:50 +0000 |
commit | f8a51c05bd2fcb8d2015be35d5e937fe89379a17 (patch) | |
tree | 076c6c6df0c9e496bd12cf47b75831cd8ddd256e /sys | |
parent | d0973ea26dae06a93fed7d27cc9d2ca87fbda8a5 (diff) |
Add bcw_phy_lo_b_measure().
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/ic/bcw.c | 155 | ||||
-rw-r--r-- | sys/dev/ic/bcwvar.h | 4 |
2 files changed, 153 insertions, 6 deletions
diff --git a/sys/dev/ic/bcw.c b/sys/dev/ic/bcw.c index 446197dff37..5cd7fecd102 100644 --- a/sys/dev/ic/bcw.c +++ b/sys/dev/ic/bcw.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bcw.c,v 1.45 2007/02/22 19:25:45 mglocker Exp $ */ +/* $OpenBSD: bcw.c,v 1.46 2007/02/22 21:26:49 mglocker Exp $ */ /* * Copyright (c) 2006 Jon Simola <jsimola@gmail.com> @@ -131,6 +131,8 @@ void bcw_phy_agcsetup(struct bcw_softc *); void bcw_phy_init_pctl(struct bcw_softc *); void bcw_phy_init_noisescaletbl(struct bcw_softc *); void bcw_phy_set_baseband_atten(struct bcw_softc *, uint16_t); +uint16_t bcw_phy_lo_b_r15_loop(struct bcw_softc *); +void bcw_phy_lo_b_measure(struct bcw_softc *); void bcw_phy_lo_g_measure(struct bcw_softc *); void bcw_phy_lo_g_measure_txctl2(struct bcw_softc *); uint32_t bcw_phy_lo_g_singledeviation(struct bcw_softc *, uint16_t); @@ -154,6 +156,7 @@ void bcw_radio_calc_nrssi_offset(struct bcw_softc *); void bcw_radio_set_all_gains(struct bcw_softc *, int16_t, int16_t, int16_t); void bcw_radio_set_original_gains(struct bcw_softc *); +uint16_t bcw_radio_calibrationvalue(struct bcw_softc *); void bcw_radio_set_txpower_bg(struct bcw_softc *, uint16_t, uint16_t, uint16_t); void bcw_radio_spw(struct bcw_softc *, uint8_t); @@ -170,6 +173,16 @@ struct cfdriver bcw_cd = { }; /* + * Table for bcw_radio_calibrationvalue() + */ +const uint16_t rcc_table[16] = { + 0x0002, 0x0003, 0x0001, 0x000F, + 0x0006, 0x0007, 0x0005, 0x000F, + 0x000A, 0x000B, 0x0009, 0x000F, + 0x000E, 0x000F, 0x000D, 0x000F, +}; + +/* * ILT (Internal Lookup Table) */ const uint32_t bcw_ilt_rotor[BCW_ILT_ROTOR_SIZE] = { @@ -3316,7 +3329,7 @@ bcw_phy_initb2(struct bcw_softc *sc) bcw_phy_write16(sc, 0x0032, 0x00ca); bcw_phy_write16(sc, 0x0032, 0x00cc); bcw_phy_write16(sc, 0x0035, 0x07c2); - /* TODO bcw_phy_lo_b_measure() */ + bcw_phy_lo_b_measure(sc); bcw_phy_write16(sc, 0x0026, 0xcc00); if (sc->sc_radio_ver != 0x2050) bcw_phy_write16(sc, 0x0026, 0xce00); @@ -3361,7 +3374,7 @@ bcw_phy_initb4(struct bcw_softc *sc) bcw_phy_write16(sc, 0x0032, 0x00e0); bcw_phy_write16(sc, 0x0035, 0x07c2); - /* TODO bcw_phy_lo_b_measure() */ + bcw_phy_lo_b_measure(sc); bcw_phy_write16(sc, 0x0026, 0xcc00); if (sc->sc_radio_ver == 0x2050) @@ -3527,12 +3540,18 @@ bcw_phy_initb6(struct bcw_softc *sc) 0xffc0) | 0x0004); else BCW_WRITE16(sc, 0x03e4, 0x0009); - if (sc->sc_phy_type == BCW_PHY_TYPEG) { + if (sc->sc_phy_type == BCW_PHY_TYPEB) { BCW_WRITE16(sc, 0x03e6, 0x8140); bcw_phy_write16(sc, 0x0016, 0x0410); bcw_phy_write16(sc, 0x0017, 0x0820); bcw_phy_write16(sc, 0x0062, 0x0007); - /* TODO */ + (void)bcw_radio_calibrationvalue(sc); + bcw_phy_lo_b_measure(sc); + if (sc->sc_boardflags & BCW_BF_RSSI) { + bcw_radio_calc_nrssi_slope(sc); + bcw_radio_calc_nrssi_threshold(sc); + } + bcw_phy_init_pctl(sc); } else BCW_WRITE16(sc, 0x03e6, 0); } @@ -4131,6 +4150,118 @@ bcw_phy_set_baseband_atten(struct bcw_softc *sc, bcw_phy_write16(sc, 0x0060, val); } +uint16_t +bcw_phy_lo_b_r15_loop(struct bcw_softc *sc) +{ + int i; + uint16_t r = 0; + + /* XXX splnet() ? */ + for (i = 0; i < 10; i++) { + bcw_phy_write16(sc, 0x0015, 0xafa0); + delay(1); + bcw_phy_write16(sc, 0x0015, 0xefa0); + delay(10); + bcw_phy_write16(sc, 0x0015, 0xffa0); + delay(40); + r += bcw_phy_read16(sc, 0x002c); + } + /* XXX splnet() ? */ + /* XXX bcm43xx_voluntary_preempt() ? */ + + return (r); +} + +void +bcw_phy_lo_b_measure(struct bcw_softc *sc) +{ + uint16_t regstack[12] = { 0 }; + uint16_t mls; + uint16_t fval; + int i, j; + + regstack[0] = bcw_phy_read16(sc, 0x0015); + regstack[1] = bcw_radio_read16(sc, 0x0052) & 0xfff0; + + if (sc->sc_radio_ver == 0x2053) { + regstack[2] = bcw_phy_read16(sc, 0x000a); + regstack[3] = bcw_phy_read16(sc, 0x002a); + regstack[4] = bcw_phy_read16(sc, 0x0035); + regstack[5] = bcw_phy_read16(sc, 0x0003); + regstack[6] = bcw_phy_read16(sc, 0x0001); + regstack[7] = bcw_phy_read16(sc, 0x0030); + + regstack[8] = bcw_radio_read16(sc, 0x0043); + regstack[9] = bcw_radio_read16(sc, 0x007a); + regstack[10] = BCW_READ16(sc, 0x03ec); + regstack[11] = bcw_radio_read16(sc, 0x0052) & 0x00f0; + + bcw_phy_write16(sc, 0x0030, 0x00ff); + BCW_WRITE16(sc, 0x3ec, 0x3f3f); + bcw_phy_write16(sc, 0x0035, regstack[4] & 0xff7f); + bcw_radio_write16(sc, 0x007a, regstack[9] & 0xfff0); + } + bcw_phy_write16(sc, 0x0015, 0xb000); + bcw_phy_write16(sc, 0x002b, 0x0004); + + if (sc->sc_radio_ver == 0x2053) { + bcw_phy_write16(sc, 0x002b, 0x0203); + bcw_phy_write16(sc, 0x002a, 0x08a3); + } + + sc->sc_phy_minlowsig[0] = 0xffff; + + for (i = 0; i < 4; i++) { + bcw_radio_write16(sc, 0x0052, regstack[1] | i); + bcw_phy_lo_b_r15_loop(sc); + } + for (i = 0; i < 10; i++) { + bcw_radio_write16(sc, 0x0052, regstack[1] | i); + mls = bcw_phy_lo_b_r15_loop(sc) / 10; + if (mls < sc->sc_phy_minlowsig[0]) { + sc->sc_phy_minlowsig[0] = mls; + sc->sc_phy_minlowsigpos[0] = i; + } + } + bcw_radio_write16(sc, 0x0052, regstack[1] | sc->sc_phy_minlowsigpos[0]); + + sc->sc_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; + bcw_phy_write16(sc, 0x002f, fval); + mls = bcw_phy_lo_b_r15_loop(sc) / 10; + if (mls < sc->sc_phy_minlowsig[1]) { + sc->sc_phy_minlowsig[1] = mls; + sc->sc_phy_minlowsigpos[1] = fval; + } + } + } + sc->sc_phy_minlowsigpos[1] += 0x0101; + + bcw_phy_write16(sc, 0x002f, sc->sc_phy_minlowsigpos[1]); + if (sc->sc_radio_ver == 0x2053) { + bcw_phy_write16(sc, 0x000a, regstack[2]); + bcw_phy_write16(sc, 0x002a, regstack[3]); + bcw_phy_write16(sc, 0x0035, regstack[4]); + bcw_phy_write16(sc, 0x0003, regstack[5]); + bcw_phy_write16(sc, 0x0001, regstack[6]); + bcw_phy_write16(sc, 0x0030, regstack[7]); + + bcw_radio_write16(sc, 0x0043, regstack[8]); + bcw_radio_write16(sc, 0x007a, regstack[9]); + + bcw_radio_write16(sc, 0x0052, (bcw_radio_read16(sc, 0x0052) & + 0x000f) | regstack[11]); + BCW_WRITE16(sc, 0x03ec, regstack[10]); + } + bcw_phy_write16(sc, 0x0015, regstack[0]); +} + void bcw_phy_lo_g_measure(struct bcw_softc *sc) { @@ -4950,6 +5081,20 @@ bcw_radio_set_original_gains(struct bcw_softc *sc) bcw_dummy_transmission(sc); } +uint16_t +bcw_radio_calibrationvalue(struct bcw_softc *sc) +{ + uint16_t reg, index, r; + + r = bcw_radio_read16(sc, 0x0060); + index = (reg & 0x001e) >> 1; + r = rcc_table[index] << 1; + r |= (reg & 0x0001); + r |= 0x0020; + + return (r); +} + void bcw_radio_set_txpower_bg(struct bcw_softc *sc, uint16_t baseband_atten, uint16_t radio_atten, uint16_t txpower) diff --git a/sys/dev/ic/bcwvar.h b/sys/dev/ic/bcwvar.h index a97c3985d75..5d4e32be5bf 100644 --- a/sys/dev/ic/bcwvar.h +++ b/sys/dev/ic/bcwvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bcwvar.h,v 1.18 2007/02/22 19:25:45 mglocker Exp $ */ +/* $OpenBSD: bcwvar.h,v 1.19 2007/02/22 21:26:49 mglocker Exp $ */ /* * Copyright (c) 2006 Jon Simola <jsimola@gmail.com> @@ -237,6 +237,8 @@ struct bcw_softc { uint16_t sc_phy_loopback_gain[2]; struct bcw_lopair *sc_phy_lopairs; uint16_t sc_phy_savedpctlreg; + uint16_t sc_phy_minlowsig[2]; + uint16_t sc_phy_minlowsigpos[2]; // uint16_t sc_corerev; uint32_t sc_radio_mnf; uint16_t sc_radio_rev; |