summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMarcus Glocker <mglocker@cvs.openbsd.org>2007-04-04 19:36:43 +0000
committerMarcus Glocker <mglocker@cvs.openbsd.org>2007-04-04 19:36:43 +0000
commitba84249e327ad09882f745e51b0a9f331cfe2675 (patch)
treedae51a4e193356692d38a8373c2b6dda3146be1c /sys
parentd0bfb79e24e4ef4620f6c86b17140807520bbdf1 (diff)
Debugging. Fix a lot wrong registers. Fix a couple of /* XXX */ and
/* TODO */ for the radio / PHY init.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ic/bcw.c449
-rw-r--r--sys/dev/ic/bcwreg.h3
-rw-r--r--sys/dev/ic/bcwvar.h4
3 files changed, 304 insertions, 152 deletions
diff --git a/sys/dev/ic/bcw.c b/sys/dev/ic/bcw.c
index b5dfa699671..5ba9ff51e01 100644
--- a/sys/dev/ic/bcw.c
+++ b/sys/dev/ic/bcw.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bcw.c,v 1.86 2007/04/01 19:15:48 mglocker Exp $ */
+/* $OpenBSD: bcw.c,v 1.87 2007/04/04 19:36:41 mglocker Exp $ */
/*
* Copyright (c) 2007 Marcus Glocker <mglocker@openbsd.org>
@@ -80,7 +80,7 @@ int bcw_phy_read16(struct bcw_softc *, uint16_t);
void bcw_ram_write(struct bcw_softc *, uint16_t, uint32_t);
int bcw_lv(int, int, int);
void bcw_dummy_transmission(struct bcw_softc *);
-struct bcw_lopair * bcw_get_lopair(struct bcw_softc *sc, uint16_t,
+struct bcw_lopair * bcw_get_lopair(struct bcw_softc *, uint16_t,
uint16_t);
void bcw_stack_save(uint32_t *, size_t *, uint8_t, uint16_t,
uint16_t);
@@ -89,6 +89,7 @@ int bcw_using_pio(struct bcw_softc *);
void bcw_rate_memory_write(struct bcw_softc *, uint16_t,
int);
void bcw_rate_memory_init(struct bcw_softc *);
+uint16_t bcw_flip_4bit(uint16_t);
/*
* 80211
@@ -190,10 +191,11 @@ void bcw_phy_lo_write(struct bcw_softc *,
struct bcw_lopair * bcw_phy_find_lopair(struct bcw_softc *, uint16_t,
uint16_t, uint16_t);
struct bcw_lopair * bcw_phy_current_lopair(struct bcw_softc *);
-void bcw_phy_prepare_init(struct bcw_softc *);
void bcw_phy_set_antenna_diversity(struct bcw_softc *);
void bcw_phy_calibrate(struct bcw_softc *);
int bcw_phy_connect(struct bcw_softc *, int);
+void bcw_phy_lock(struct bcw_softc *);
+void bcw_phy_unlock(struct bcw_softc *);
/*
* Radio
@@ -231,12 +233,13 @@ uint16_t bcw_radio_get_txgain_baseband(uint16_t);
uint16_t bcw_radio_get_txgain_freq_power_amp(uint16_t);
uint16_t bcw_radio_get_txgain_dac(uint16_t);
uint16_t bcw_radio_freq_r3a_value(uint16_t);
-void bcw_radio_prepare_init(struct bcw_softc *);
int bcw_radio_set_interf_mitigation(struct bcw_softc *,
int);
int bcw_radio_interf_mitigation_enable(struct bcw_softc *,
int);
void bcw_radio_set_txantenna(struct bcw_softc *, uint32_t);
+void bcw_radio_lock(struct bcw_softc *);
+void bcw_radio_unlock(struct bcw_softc *);
/*
* ILT
@@ -252,6 +255,9 @@ void bcw_pc_crystal_off(struct bcw_softc *);
int bcw_pc_init(struct bcw_softc *);
int bcw_pc_set_clock(struct bcw_softc *, uint16_t);
void bcw_pc_saving_ctl_bits(struct bcw_softc *, int, int);
+uint16_t bcw_pc_powerup_delay(struct bcw_softc *);
+int bcw_pc_clock_freqlimit(struct bcw_softc *, int);
+int bcw_pc_get_slowclocksrc(struct bcw_softc *);
/*
* XMIT
@@ -273,6 +279,11 @@ struct cfdriver bcw_cd = {
bcw_stack_save(stack, &stackidx, 0x3, (offset), \
bcw_ilt_read(sc, (offset))); \
} while (0)
+#define BCW_RADIO_STACKSAVE(offset) \
+ do { \
+ bcw_stack_save(stack, &stackidx, 0x2, (offset), \
+ bcw_radio_read16(sc, (offset))); \
+ } while (0)
/*
* Table for bcw_radio_calibrationvalue()
@@ -727,6 +738,19 @@ bcw_lv(int number, int min, int max)
return (number);
}
+uint16_t
+bcw_flip_4bit(uint16_t val)
+{
+ uint16_t flip = 0;
+
+ flip |= (val & 0x0001) << 3;
+ flip |= (val & 0x0002) << 1;
+ flip |= (val & 0x0004) >> 1;
+ flip |= (val & 0x0008) >> 3;
+
+ return (flip);
+}
+
/*
* Dummy Transmission
*
@@ -756,7 +780,7 @@ bcw_dummy_transmission(struct bcw_softc *sc)
buffer[0] = 0x6e840b00;
break;
default:
- /* XXX assert? */
+ /* XXX panic()? */
return;
}
@@ -815,14 +839,10 @@ bcw_stack_save(uint32_t *_stackptr, size_t *stackidx, uint8_t id,
{
uint32_t *stackptr = &(_stackptr[*stackidx]);
- /* XXX assert() */
-
*stackptr = offset;
*stackptr |= ((uint32_t)id) << 12;
*stackptr |= ((uint32_t)val) << 16;
(*stackidx)++;
-
- /* XXX assert() */
}
uint16_t
@@ -830,8 +850,6 @@ bcw_stack_restore(uint32_t *stackptr, uint8_t id, uint16_t offset)
{
size_t i;
- /* XXX assert() */
-
for (i = 0; i < BCW_INTERFSTACK_SIZE; i++, stackptr++) {
if ((*stackptr & 0x00000fff) != offset)
continue;
@@ -840,8 +858,6 @@ bcw_stack_restore(uint32_t *stackptr, uint8_t id, uint16_t offset)
return (((*stackptr & 0xffff0000) >> 16));
}
- /* XXX assert() */
-
return (0);
}
@@ -899,7 +915,7 @@ bcw_rate_memory_init(struct bcw_softc *sc)
bcw_rate_memory_write(sc,
ieee80211_std_rateset_11b.rs_rates[3], 0);
default:
- /* XXX assert() */
+ /* XXX panic()? */
break;
}
}
@@ -963,8 +979,6 @@ bcw_attach(struct bcw_softc *sc)
if (core_id == BCW_CORE_COMMON) {
sc->sc_havecommon = 1;
- /* XXX do early init of sc_core[0] here */
-
/* powercontrol init is done if a common core exists */
bcw_pc_init(sc);
@@ -1054,6 +1068,8 @@ bcw_attach(struct bcw_softc *sc)
bcw_pc_set_clock(sc, BCW_PCTL_CLK_FAST);
+ bcw_phy_connect(sc, 0);
+
/*
* Get SPROM values and save them where they belong
*/
@@ -1209,7 +1225,7 @@ bcw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
#ifdef INET
case AF_INET:
//bcw_init(ifp);
- /* XXX arp_ifinit(&sc->bcw_ac, ifa); */
+ //arp_ifinit(&sc->bcw_ac, ifa); /* XXX */
break;
#endif /* INET */
default:
@@ -1500,7 +1516,8 @@ bcw_intr(void *arg)
if (reason & BCW_INTR_PS) {
printf("handle PS intr\n");
bcw_pc_saving_ctl_bits(sc, -1, -1);
- }
+ } else
+ printf("INTR ALERT!!!\n");
bcw_intr_enable(sc, BCW_INTR_INITIAL);
@@ -1542,13 +1559,40 @@ bcw_init(struct ifnet *ifp)
{
struct bcw_softc *sc = ifp->if_softc;
//struct ieee80211com *ic = &sc->sc_ic;
- int error;
+ int i, error;
uint32_t coremask = 0;
+ /* initialize PHY values */
+ sc->sc_phy_antenna_diversity = 0xffff;
+ memset(sc->sc_phy_minlowsig, 0xff, sizeof(sc->sc_phy_minlowsig));
+ memset(sc->sc_phy_minlowsigpos, 0, sizeof(sc->sc_phy_minlowsigpos));
+ sc->sc_phy_calibrated = 0;
+ sc->sc_phy_is_locked = 0;
sc->sc_phy_lopairs = malloc(sizeof(struct bcw_lopair) * BCW_LO_COUNT,
M_DEVBUF, M_NOWAIT);
- bcw_phy_prepare_init(sc); /* XXX probably unpack function */
- bcw_radio_prepare_init(sc); /* XXX probably unpack function */
+ if (sc->sc_phy_lopairs)
+ memset(sc->sc_phy_lopairs, 0, sizeof(struct bcw_lopair) *
+ BCW_LO_COUNT);
+ memset(sc->sc_phy_loopback_gain, 0, sizeof(sc->sc_phy_loopback_gain));
+
+ /* initialize Radio values */
+ sc->sc_radio_baseband_atten =
+ bcw_radio_default_baseband_atten(sc);
+ sc->sc_radio_radio_atten =
+ bcw_radio_default_radio_atten(sc);
+ sc->sc_radio_txctl1 = bcw_radio_default_txctl1(sc);
+ sc->sc_radio_txctl2 = 0xffff;
+ sc->sc_radio_txpwr_offset = 0;
+ sc->sc_radio_nrssislope = 0;
+ for (i = 0; i < BCW_ARRAY_SIZE(sc->sc_radio_nrssi); i++)
+ sc->sc_radio_nrssi[i] = -1000;
+ for (i = 0; i < BCW_ARRAY_SIZE(sc->sc_radio_nrssi_lt); i++)
+ sc->sc_radio_nrssi_lt[i] = i;
+ sc->sc_radio_lofcal = 0xffff;
+ sc->sc_radio_initval = 0xffff;
+ sc->sc_radio_aci_enable = 0;
+ sc->sc_radio_aci_wlan_automatic = 0;
+ sc->sc_radio_aci_hw_rssi = 0;
bcw_change_core(sc, sc->sc_core_80211->index);
@@ -2192,10 +2236,6 @@ bcw_core_enable(struct bcw_softc *sc, uint32_t core_flags)
BCW_WRITE(sc, BCW_CIR_SBTMSTATELOW, sbtmstatelow);
delay(1);
- /* TODO sc->sc_current_core_enabled = 1; */
-
- /* XXX assert() */
-
return (0);
}
@@ -2653,7 +2693,7 @@ bcw_gpio_init(struct bcw_softc *sc)
mask |= 0x0060;
set |= 0x0060;
}
- if (0) { /* FIXME conditional unknown */
+ if (0) { /* XXX conditional unknown */
BCW_WRITE16(sc, BCW_MMIO_GPIO_MASK,
BCW_READ16(sc, BCW_MMIO_GPIO_MASK) | 0x0100);
mask |= 0x0180;
@@ -2666,7 +2706,7 @@ bcw_gpio_init(struct bcw_softc *sc)
set |= 0x0200;
}
if (sc->sc_chip_rev >= 2)
- mask |= 0x0010; /* FIXME this is redundant */
+ mask |= 0x0010; /* XXX this is redundant */
/*
* TODO bcw_change_core_to_gpio()
@@ -2696,6 +2736,7 @@ int
bcw_chip_init(struct bcw_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = &sc->sc_ic.ic_if;
uint8_t limit;
uint16_t val16;
uint32_t val32;
@@ -2766,23 +2807,20 @@ bcw_chip_init(struct bcw_softc *sc)
BCW_WRITE(sc, 0x41e, 0);
}
- BCW_WRITE(sc, 0x5c, 0xa);
+ bcw_shm_write16(sc, BCW_SHM_SHARED, 0x5c, 0xa);
BCW_WRITE(sc, 0x0100, 0x01000000);
+
if (sc->sc_core[sc->sc_currentcore].rev < 5)
BCW_WRITE(sc, 0x010c, 0x01000000);
val32 = BCW_READ(sc, BCW_MMIO_SBF);
- val32 &= ~BCW_SBF_ADHOC;
+ val32 &= ~BCW_SBF_AP;
BCW_WRITE(sc, BCW_MMIO_SBF, val32);
val32 = BCW_READ(sc, BCW_MMIO_SBF);
val32 |= BCW_SBF_ADHOC;
BCW_WRITE(sc, BCW_MMIO_SBF, val32);
- val32 = BCW_READ(sc, BCW_MMIO_SBF);
- val32 |= 0x100000;
- BCW_WRITE(sc, BCW_MMIO_SBF, val32);
-
if (bcw_using_pio(sc)) {
BCW_WRITE(sc, 0x0210, 0x00000100);
BCW_WRITE(sc, 0x0230, 0x00000100);
@@ -2794,7 +2832,11 @@ bcw_chip_init(struct bcw_softc *sc)
/* probe response timeout value */
bcw_shm_write16(sc, BCW_SHM_SHARED, 0x0074, 0);
- BCW_WRITE(sc, 0x400, 0x8);
+ bcw_shm_write16(sc, BCW_SHM_SHARED, 0x400, 0x8);
+
+ /* TODO slot timing */
+
+ bcw_set_opmode(ifp);
if (sc->sc_core[sc->sc_currentcore].rev < 3) {
BCW_WRITE16(sc, 0x060e, 0);
@@ -2805,6 +2847,7 @@ bcw_chip_init(struct bcw_softc *sc)
BCW_WRITE(sc, 0x0188, 0x80000000);
BCW_WRITE(sc, 0x018c, 0x02000000);
}
+
BCW_WRITE(sc, BCW_MMIO_GIR, 0x00004000);
BCW_WRITE(sc, BCW_MMIO_DMA0_INT_MASK, 0x0001dc00);
BCW_WRITE(sc, BCW_MMIO_DMA1_INT_MASK, 0x0000dc00);
@@ -2817,6 +2860,10 @@ bcw_chip_init(struct bcw_softc *sc)
val32 |= 0x00100000;
BCW_WRITE(sc, BCW_CIR_SBTMSTATELOW, val32);
+ if (sc->sc_core[sc->sc_currentcore].rev >= 5)
+ BCW_WRITE16(sc, BCW_MMIO_POWERUP_DELAY,
+ bcw_pc_powerup_delay(sc));
+
val16 = sc->sc_core[sc->sc_currentcore].rev;
bcw_shm_write16(sc, BCW_SHM_SHARED, 0x16, val16);
@@ -2858,6 +2905,10 @@ bcw_bs_init(struct bcw_softc *sc)
bcw_phy_init(sc);
+ bcw_phy_set_antenna_diversity(sc);
+
+ bcw_radio_set_txantenna(sc, BCW_RADIO_TXANTENNA_DEFAULT);
+
/* minimum contention window */
if (sc->sc_phy_type == BCW_PHY_TYPEB)
bcw_shm_write32(sc, BCW_SHM_80211, 0x0003, 0x0000001f);
@@ -3307,7 +3358,7 @@ bcw_phy_initg(struct bcw_softc *sc)
bcw_phy_write16(sc, 0x0814, 0);
bcw_phy_write16(sc, 0x0815, 0);
if (sc->sc_phy_rev == 2)
- bcw_phy_write16(sc, 0x0811, 0x0000);
+ bcw_phy_write16(sc, 0x0811, 0);
else if (sc->sc_phy_rev >= 3)
bcw_phy_write16(sc, 0x0811, 0x0400);
bcw_phy_write16(sc, 0x0015, 0x00c0);
@@ -3373,10 +3424,8 @@ bcw_phy_initg(struct bcw_softc *sc)
bcw_radio_calc_nrssi_threshold(sc);
} else if (sc->sc_phy_connected) {
if (sc->sc_radio_nrssi[0] == -1000) {
- /* XXX assert() */
bcw_radio_calc_nrssi_slope(sc);
} else {
- /* XXX assert() */
bcw_radio_calc_nrssi_threshold(sc);
}
}
@@ -3788,7 +3837,7 @@ bcw_phy_inita(struct bcw_softc *sc)
bcw_phy_write16(sc, 0x007a, 0xf111);
if (sc->sc_phy_savedpctlreg == 0xffff) {
- bcw_radio_write16(sc, 0x0019, 0x0000);
+ bcw_radio_write16(sc, 0x0019, 0);
bcw_radio_write16(sc, 0x0017, 0x0020);
tval = bcw_ilt_read(sc, 0x3001);
@@ -3928,7 +3977,7 @@ bcw_phy_setupa(struct bcw_softc *sc)
bcw_ilt_write(sc, 0x3c03, 0x0014);
break;
default:
- /* XXX assert? */
+ /* XXX panic()? */
break;
}
}
@@ -3938,8 +3987,6 @@ bcw_phy_setupg(struct bcw_softc *sc)
{
uint16_t i;
- /* XXX assert? */
-
if (sc->sc_phy_rev == 1) {
bcw_phy_write16(sc, 0x0406, 0x4f19);
bcw_phy_write16(sc, BCW_PHY_G_CRS, (bcw_phy_read16(sc,
@@ -4294,8 +4341,6 @@ bcw_phy_init_pctl(struct bcw_softc *sc)
uint16_t saved_batt = 0, saved_ratt = 0, saved_txctl1 = 0;
int must_reset_txpower = 0;
- /* XXX assert() */
-
if (sc->sc_board_vendor == PCI_VENDOR_BROADCOM &&
sc->sc_board_type == 0x0416)
return;
@@ -4415,7 +4460,7 @@ bcw_phy_estimate_powerout(struct bcw_softc *sc, int8_t tssi)
//dbm = sc->sc_phy_tssi2dbm[tmp]; /* XXX "/
break;
default:
- /* XXX assert() */
+ /* XXX panic()? */
break;
}
@@ -4551,17 +4596,17 @@ bcw_phy_xmitpower(struct bcw_softc *sc)
baseband_attenuation = bcw_lv(baseband_attenuation, 0, 11);
radio_attenuation = bcw_lv(radio_attenuation, 0, 9);
- /* TODO bcw_phy_lock() */
- /* TODO bcw_radio_lock() */
+ bcw_phy_lock(sc);
+ bcw_radio_lock(sc);
bcw_radio_set_txpower_bg(sc, baseband_attenuation,
radio_attenuation, txpower);
bcw_phy_lo_mark_current_used(sc);
- /* TODO bcw_radio_unlock() */
- /* TODO bcw_phy_unlock() */
+ bcw_radio_unlock(sc);
+ bcw_phy_unlock(sc);
break;
}
default:
- /* XXX assert() */
+ /* XXX panic()? */
break;
}
}
@@ -4572,7 +4617,7 @@ bcw_phy_lo_b_r15_loop(struct bcw_softc *sc)
int i;
uint16_t r = 0;
- /* XXX splnet() ? */
+ /* XXX splnet()? */
for (i = 0; i < 10; i++) {
bcw_phy_write16(sc, 0x0015, 0xafa0);
delay(1);
@@ -4582,8 +4627,7 @@ bcw_phy_lo_b_r15_loop(struct bcw_softc *sc)
delay(40);
r += bcw_phy_read16(sc, 0x002c);
}
- /* XXX splnet() ? */
- /* XXX bcm43xx_voluntary_preempt() ? */
+ /* XXX splnet()? */
return (r);
}
@@ -4707,7 +4751,6 @@ bcw_phy_lo_g_state(struct bcw_softc *sc, struct bcw_lopair *in_pair,
lowest_deviation = bcw_phy_lo_g_singledeviation(sc, r27);
do {
found_lower = 0;
- /* XXX assert() */
if (state == 0) {
begin = 1;
end = 8;
@@ -4727,7 +4770,6 @@ bcw_phy_lo_g_state(struct bcw_softc *sc, struct bcw_lopair *in_pair,
tmp_pair.high = lowest_transition.high;
tmp_pair.low = lowest_transition.low;
while (1) {
- /* XXX assert() */
transition.high = tmp_pair.high +
transitions[j - 1].high;
transition.low = tmp_pair.low +
@@ -4867,7 +4909,6 @@ bcw_phy_lo_g_measure(struct bcw_softc *sc)
bcw_radio_write16(sc, 0x43, i);
bcw_radio_write16(sc, 0x52, sc->sc_radio_txctl2);
delay(10);
- /* XXX bcm43xx_voluntary_preempt() ? */
bcw_phy_set_baseband_atten(sc, j * 2);
@@ -4888,7 +4929,7 @@ bcw_phy_lo_g_measure(struct bcw_softc *sc)
if (is_initializing) {
tmp_control = bcw_get_lopair(sc, i - 9, j * 2);
memcpy(&control, tmp_control, sizeof(control));
- tmp = (i - 9) * 2 + j - 5; /* FIXME */
+ tmp = (i - 9) * 2 + j - 5; /* XXX */
r27 = 0;
r31 = 0;
if (tmp > 14) {
@@ -4908,9 +4949,8 @@ bcw_phy_lo_g_measure(struct bcw_softc *sc)
}
bcw_radio_write16(sc, 0x043, i - 9);
bcw_radio_write16(sc, 0x052, sc->sc_radio_txctl2 |
- (3 << 4)); /* FIXME */
+ (3 << 4)); /* XXX */
delay(10);
- /* XXX bcm43xx_voluntary_preempt() */
bcw_phy_set_baseband_atten(sc, j * 2);
@@ -4920,7 +4960,7 @@ bcw_phy_lo_g_measure(struct bcw_softc *sc)
bcw_radio_write16(sc, 0x7a, tmp);
tmp_control = bcw_get_lopair(sc, i, j * 2);
- /* XXX bcm43xx_phy_lo_g_state() */
+ bcw_phy_lo_g_state(sc, &control, tmp_control, r27);
}
}
@@ -4933,7 +4973,6 @@ bcw_phy_lo_g_measure(struct bcw_softc *sc)
bcw_phy_write16(sc, 0x0812, (r27 << 8) | 0xa2);
delay(2);
bcw_phy_write16(sc, 0x0812, (r27 << 8) | 0xa3);
- /* XXX bcm43xx_voluntary_preempt() */
} else
bcw_phy_write16(sc, 0x0015, r27 | 0xefa0);
bcw_phy_lo_adjust(sc, is_initializing);
@@ -5003,7 +5042,8 @@ bcw_phy_lo_g_deviation_subval(struct bcw_softc *sc, uint16_t control)
uint16_t r;
//unsigned long flags;
- /* XXX splnet ? */
+ /* XXX splnet()? */
+
if (sc->sc_phy_connected) {
bcw_phy_write16(sc, 0x15, 0xe300);
control <<= 8;
@@ -5025,8 +5065,7 @@ bcw_phy_lo_g_deviation_subval(struct bcw_softc *sc, uint16_t control)
}
r = bcw_phy_read16(sc, 0x002d);
- /* XXX splnet ? */
- /* XXX bcm43xx_voluntary_preempt() ? */
+ /* XXX splnet()? */
return (r);
}
@@ -5083,8 +5122,6 @@ bcw_phy_find_lopair(struct bcw_softc *sc, uint16_t baseband_atten,
if (baseband_atten > 6)
baseband_atten = 6;
- /* XXX assert() */
-
if (tx == 3)
return (bcw_get_lopair(sc, radio_atten, baseband_atten));
@@ -5099,24 +5136,6 @@ bcw_phy_current_lopair(struct bcw_softc *sc)
}
void
-bcw_phy_prepare_init(struct bcw_softc *sc)
-{
- sc->sc_phy_antenna_diversity = 0xffff;
- memset(sc->sc_phy_minlowsig, 0xff, sizeof(sc->sc_phy_minlowsig));
- memset(sc->sc_phy_minlowsigpos, 0, sizeof(sc->sc_phy_minlowsigpos));
-
- /* flags */
- sc->sc_phy_calibrated = 0;
- sc->sc_phy_is_locked = 0;
-
- if (sc->sc_phy_lopairs)
- memset(sc->sc_phy_lopairs, 0, sizeof(struct bcw_lopair) *
- BCW_LO_COUNT);
-
- memset(sc->sc_phy_loopback_gain, 0, sizeof(sc->sc_phy_loopback_gain));
-}
-
-void
bcw_phy_set_antenna_diversity(struct bcw_softc *sc)
{
uint16_t antennadiv;
@@ -5126,10 +5145,9 @@ bcw_phy_set_antenna_diversity(struct bcw_softc *sc)
if (antennadiv == 0xffff)
antennadiv = 3;
- /* XXX assert() */
- ucodeflags = bcw_shm_read16(sc, BCW_SHM_SHARED, BCW_UCODEFLAGS_OFFSET);
- bcw_shm_write16(sc, BCW_SHM_SHARED, BCW_UCODEFLAGS_OFFSET,
+ ucodeflags = bcw_shm_read32(sc, BCW_SHM_SHARED, BCW_UCODEFLAGS_OFFSET);
+ bcw_shm_write32(sc, BCW_SHM_SHARED, BCW_UCODEFLAGS_OFFSET,
ucodeflags & ~BCW_UCODEFLAG_AUTODIV);
switch (sc->sc_phy_type) {
@@ -5198,7 +5216,7 @@ bcw_phy_set_antenna_diversity(struct bcw_softc *sc)
}
break;
case BCW_PHY_TYPEB:
- if (1) /* XXX current_core->rev */
+ if (sc->sc_core[sc->sc_currentcore].rev == 2)
val = (3 << 7);
else
val = (antennadiv << 7);
@@ -5206,14 +5224,14 @@ bcw_phy_set_antenna_diversity(struct bcw_softc *sc)
0xfe7f) | val);
break;
default:
- /* XXX assert() */
+ /* XXX panic()? */
break;
}
if (antennadiv >= 2) {
- ucodeflags = bcw_shm_read16(sc, BCW_SHM_SHARED,
+ ucodeflags = bcw_shm_read32(sc, BCW_SHM_SHARED,
BCW_UCODEFLAGS_OFFSET);
- bcw_shm_write16(sc, BCW_SHM_SHARED,
+ bcw_shm_write32(sc, BCW_SHM_SHARED,
BCW_UCODEFLAGS_OFFSET, ucodeflags |
BCW_UCODEFLAG_AUTODIV);
}
@@ -5274,6 +5292,42 @@ out:
return (0);
}
+void
+bcw_phy_lock(struct bcw_softc *sc)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+
+ if (BCW_READ(sc, BCW_MMIO_SBF) == 0) {
+ sc->sc_phy_is_locked = 0;
+ return;
+ }
+
+ if (sc->sc_core[sc->sc_currentcore].rev < 3)
+ bcw_mac_disable(sc);
+ else {
+ if (ic->ic_opmode != IEEE80211_M_HOSTAP)
+ bcw_pc_saving_ctl_bits(sc, -1, -1);
+ }
+
+ sc->sc_phy_is_locked = 1;
+}
+
+void
+bcw_phy_unlock(struct bcw_softc *sc)
+{
+ struct ieee80211com *ic = &sc->sc_ic;
+
+ if (sc->sc_core[sc->sc_currentcore].rev < 3) {
+ if (sc->sc_phy_is_locked)
+ bcw_mac_enable(sc);
+ } else {
+ if (ic->ic_opmode != IEEE80211_M_HOSTAP)
+ bcw_pc_saving_ctl_bits(sc, -1, -1);
+ }
+
+ sc->sc_phy_is_locked = 0;
+}
+
/*
* Radio
*/
@@ -5283,8 +5337,9 @@ bcw_radio_get(struct bcw_softc *sc)
uint32_t val;
/*
+ * XXX
* Query the RadioID register, on a 4317 use a lookup instead
- * XXX Different PHYs have different radio register layouts, so
+ * Different PHYs have different radio register layouts, so
* a wrapper func should be written.
* Getting the RadioID is the only 32bit operation done with the
* Radio registers, and requires seperate 16bit reads from the low
@@ -5520,7 +5575,7 @@ bcw_radio_calc_nrssi_threshold(struct bcw_softc *sc)
}
break;
default:
- /* XXX assert() */
+ /* XXX panic()? */
return;
}
}
@@ -5847,7 +5902,7 @@ bcw_radio_calibrationvalue(struct bcw_softc *sc)
{
uint16_t reg, index, r;
- r = bcw_radio_read16(sc, 0x0060);
+ reg = bcw_radio_read16(sc, 0x0060);
index = (reg & 0x001e) >> 1;
r = rcc_table[index] << 1;
r |= (reg & 0x0001);
@@ -5899,8 +5954,6 @@ bcw_radio_set_txpower_bg(struct bcw_softc *sc, uint16_t baseband_atten,
sc->sc_radio_radio_atten = radio_atten;
sc->sc_radio_txctl1 = txpower;
- /* XXX assert() */
-
bcw_phy_set_baseband_atten(sc, baseband_atten);
bcw_radio_write16(sc, 0x0043, radio_atten);
bcw_shm_write16(sc, BCW_SHM_SHARED, 0x0064, radio_atten);
@@ -5996,7 +6049,7 @@ bcw_radio_init2050(struct bcw_softc *sc)
delay(10);
if (sc->sc_phy_connected)
bcw_phy_write16(sc, 0x0812, 0x30b2);
- bcw_phy_write16(sc, 0x0015, 0xfff0);
+ bcw_phy_write16(sc, 0x0015, 0xefb0);
delay(10);
if (sc->sc_phy_connected)
bcw_phy_write16(sc, 0x0812, 0x30b2);
@@ -6015,8 +6068,7 @@ bcw_radio_init2050(struct bcw_softc *sc)
bcw_phy_write16(sc, 0x0058, 0);
for (i = 0; i < 16; i++) {
- /* XXX flip_4bit(i) */
- bcw_radio_write16(sc, 0x0078, i << 1 | 0x0020);
+ bcw_radio_write16(sc, 0x0078, (bcw_flip_4bit(i) << 1) | 0x0020);
backup[13] = bcw_radio_read16(sc, 0x0078);
delay(10);
@@ -6121,8 +6173,6 @@ bcw_radio_init2060(struct bcw_softc *sc)
error = bcw_radio_select_channel(sc, BCW_RADIO_DEFAULT_CHANNEL_A, 0);
- /* XXX assert() */
-
delay(1000);
}
@@ -6214,8 +6264,6 @@ bcw_radio_select_channel(struct bcw_softc *sc, uint8_t channel, int spw)
uint16_t
bcw_radio_chan2freq_a(uint8_t channel)
{
- /* XXX assert() */
-
return (5000 + 5 * channel);
}
@@ -6394,8 +6442,6 @@ bcw_radio_get_txgain_baseband(uint16_t txpower)
{
uint16_t r;
- /* XXX assert(txpower <= 63); ? */
-
if (txpower >= 54)
r = 2;
else if (txpower >= 49)
@@ -6413,8 +6459,6 @@ bcw_radio_get_txgain_freq_power_amp(uint16_t txpower)
{
uint16_t r;
- /* XXX assert(txpower <= 63); ? */
-
if (txpower >= 32)
r = 0;
else if (txpower >= 25)
@@ -6434,8 +6478,6 @@ bcw_radio_get_txgain_dac(uint16_t txpower)
{
uint16_t r;
- /* XXX assert(txpower <= 63); ? */
-
if (txpower >= 54)
r = txpower - 53;
else if (txpower >= 49)
@@ -6473,35 +6515,6 @@ bcw_radio_freq_r3a_value(uint16_t frequency)
return (val);
}
-void
-bcw_radio_prepare_init(struct bcw_softc *sc)
-{
- int i;
-
- /* set default attenuation values */
- sc->sc_radio_baseband_atten =
- bcw_radio_default_baseband_atten(sc);
- sc->sc_radio_radio_atten =
- bcw_radio_default_radio_atten(sc);
- sc->sc_radio_txctl1 = bcw_radio_default_txctl1(sc);
- sc->sc_radio_txctl2 = 0xffff;
- sc->sc_radio_txpwr_offset = 0;
-
- /* nrssi */
- sc->sc_radio_nrssislope = 0;
- for (i = 0; i < BCW_ARRAY_SIZE(sc->sc_radio_nrssi); i++)
- sc->sc_radio_nrssi[i] = -1000;
- for (i = 0; i < BCW_ARRAY_SIZE(sc->sc_radio_nrssi_lt); i++)
- sc->sc_radio_nrssi_lt[i] = i;
-
- sc->sc_radio_lofcal = 0xffff;
- sc->sc_radio_initval = 0xffff;
-
- sc->sc_radio_aci_enable = 0;
- sc->sc_radio_aci_wlan_automatic = 0;
- sc->sc_radio_aci_hw_rssi = 0;
-}
-
int
bcw_radio_set_interf_mitigation(struct bcw_softc *sc, int mode)
{
@@ -6558,14 +6571,14 @@ bcw_radio_interf_mitigation_enable(struct bcw_softc *sc, int mode)
bcw_phy_read16(sc, BCW_PHY_G_CRS) & ~0x4000);
break;
}
- /* XXX radio_stacksave() */
+ BCW_RADIO_STACKSAVE(0x0078);
tmp = (bcw_radio_read16(sc, 0x0078) & 0x001e);
- flipped = tmp; /* XXX flip_4bit(tmp) */
+ flipped = bcw_flip_4bit(tmp);
if (flipped < 10 && flipped >= 8)
flipped = 7;
else if (flipped >= 10)
flipped -= 3;
- flipped = flipped; /* XXX flip_4bit(flipped) */
+ flipped = bcw_flip_4bit(flipped);
flipped = (flipped << 1) | 0x0020;
bcw_radio_write16(sc, 0x0078, flipped);
@@ -6743,7 +6756,7 @@ bcw_radio_interf_mitigation_enable(struct bcw_softc *sc, int mode)
bcw_radio_calc_nrssi_slope(sc);
break;
default:
- /* XXX assert () */
+ /* XXX panic()? */
break;
}
@@ -6764,6 +6777,28 @@ bcw_radio_set_txantenna(struct bcw_softc *sc, uint32_t val)
bcw_shm_write16(sc, BCW_SHM_SHARED, 0x0054, tmp | val);
}
+void
+bcw_radio_lock(struct bcw_softc *sc)
+{
+ uint32_t status;
+
+ status = BCW_READ(sc, BCW_MMIO_SBF);
+ status |= BCW_SBF_RADIOREG_LOCK;
+ BCW_WRITE(sc, BCW_MMIO_SBF, status);
+ delay(10);
+}
+
+void
+bcw_radio_unlock(struct bcw_softc *sc)
+{
+ uint32_t status;
+
+ BCW_READ16(sc, 0x3e0);
+ status = BCW_READ(sc, BCW_MMIO_SBF);
+ status &= ~BCW_SBF_RADIOREG_LOCK;
+ BCW_WRITE(sc, BCW_MMIO_SBF, status);
+}
+
/*
* ILT
*/
@@ -6823,6 +6858,7 @@ bcw_pc_crystal_off(struct bcw_softc *sc)
uint32_t val;
/* TODO return if radio is hardware disabled */
+
if (sc->sc_chip_rev < 5)
return;
if (sc->sc_sprom.boardflags & BCW_BF_XTAL)
@@ -6843,7 +6879,7 @@ bcw_pc_crystal_off(struct bcw_softc *sc)
int
bcw_pc_init(struct bcw_softc *sc)
{
- //int maxfreq;
+ int maxfreq;
int error;
if ((error = bcw_change_core(sc, 0)))
@@ -6864,13 +6900,11 @@ bcw_pc_init(struct bcw_softc *sc)
(BCW_READ(sc, BCW_CHIPCOMMON_SYSCLKCTL) & 0x0000ffff) |
0x40000);
} else {
- /* TODO get maxfreq */
-#if 0
+ maxfreq = bcw_pc_clock_freqlimit(sc, 1);
BCW_WRITE(sc, BCW_CHIPCOMMON_PLLONDELAY,
(maxfreq * 150 + 99999) / 1000000);
BCW_WRITE(sc, BCW_CHIPCOMMON_FREFSELDELAY,
(maxfreq * 15 + 99999) / 100000);
-#endif
}
if ((error = bcw_change_core(sc, sc->sc_lastcore)))
@@ -6956,6 +6990,127 @@ bcw_pc_saving_ctl_bits(struct bcw_softc *sc, int bit25, int bit26)
}
}
+uint16_t
+bcw_pc_powerup_delay(struct bcw_softc *sc)
+{
+ uint16_t delay = 0;
+ uint32_t pllondelay;
+ int minfreq;
+
+ /* TODO just for PCI bus type */
+
+ if (!(sc->sc_chip_common_capa & BCW_CAPABILITIES_PCTL))
+ return (0);
+
+ bcw_change_core(sc, 0);
+
+ minfreq = bcw_pc_clock_freqlimit(sc, 0);
+ pllondelay = BCW_READ(sc, BCW_CHIPCOMMON_PLLONDELAY);
+ delay = (((pllondelay + 2) * 1000000) + (minfreq - 1)) / minfreq;
+
+ bcw_change_core(sc, sc->sc_lastcore);
+
+ return (delay);
+}
+
+int
+bcw_pc_clock_freqlimit(struct bcw_softc *sc, int getmax)
+{
+ int limit, clocksrc, divisor;
+ uint32_t tmp;
+
+ clocksrc = bcw_pc_get_slowclocksrc(sc);
+
+ if (sc->sc_core[sc->sc_currentcore].rev < 6) {
+ switch (clocksrc) {
+ case 0:
+ divisor = 64;
+ break;
+ case 1:
+ divisor = 32;
+ break;
+ default:
+ /* XXX panic()? */
+ divisor = 1;
+ }
+ } else if (sc->sc_core[sc->sc_currentcore].rev < 10) {
+ switch (clocksrc) {
+ case 2:
+ divisor = 1;
+ break;
+ case 1:
+ case 0:
+ tmp = BCW_READ(sc, 0xb8);
+ divisor = ((tmp & 0xffff0000) >> 16) + 1;
+ divisor *= 4;
+ break;
+ default:
+ /* XXX panic()? */
+ divisor = 1;
+ }
+ } else {
+ tmp = BCW_READ(sc, 0xb8);
+ divisor = ((tmp & 0xffff0000) >> 16) + 1;
+ divisor *= 4;
+ }
+
+ switch (clocksrc) {
+ case 2:
+ if (getmax)
+ limit = 43000;
+ else
+ limit = 25000;
+ break;
+ case 1:
+ if (getmax)
+ limit = 20200000;
+ else
+ limit = 19800000;
+ break;
+ case 0:
+ if (getmax)
+ limit = 34000000;
+ else
+ limit = 25000000;
+ break;
+ default:
+ /* panic()? */
+ limit = 0;
+ }
+
+ limit /= divisor;
+
+ return (limit);
+
+}
+
+int
+bcw_pc_get_slowclocksrc(struct bcw_softc *sc)
+{
+ uint32_t tmp;
+
+ if (sc->sc_core[sc->sc_currentcore].rev < 6) {
+ /* TODO check bus type */
+ tmp = (sc->sc_conf_read)(sc, BCW_PCTL_OUT);
+ if (tmp & 0x10)
+ return (0);
+ return (1);
+ }
+
+ if (sc->sc_core[sc->sc_currentcore].rev < 10) {
+ tmp = BCW_READ(sc, 0xb8); /* XXX */
+ tmp &= 0x7;
+ if (tmp == 0)
+ return (2);
+ if (tmp == 1)
+ return (1);
+ if (tmp == 2)
+ return (0);
+ }
+
+ return (1);
+}
+
/*
* XMIT
*/
@@ -6971,8 +7126,6 @@ bcw_xmit_plcp_get_ratecode_cck(const uint8_t bitrate)
else if (ieee80211_std_rateset_11b.rs_rates[3] == bitrate)
return (0x6e);
- /* XXX assert() */
-
return (0);
}
@@ -6996,7 +7149,5 @@ bcw_xmit_plcp_get_ratecode_ofdm(const uint8_t bitrate)
else if (ieee80211_std_rateset_11g.rs_rates[7] == bitrate)
return (0xc);
- /* XXX assert() */
-
return (0);
}
diff --git a/sys/dev/ic/bcwreg.h b/sys/dev/ic/bcwreg.h
index 099a0c7ad9f..751d7002755 100644
--- a/sys/dev/ic/bcwreg.h
+++ b/sys/dev/ic/bcwreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bcwreg.h,v 1.26 2007/03/31 23:50:59 mglocker Exp $ */
+/* $OpenBSD: bcwreg.h,v 1.27 2007/04/04 19:36:42 mglocker Exp $ */
/*
* Copyright (c) 2007 Marcus Glocker <mglocker@openbsd.org>
@@ -72,6 +72,7 @@
#define BCW_MMIO_MACFILTER_DATA 0x422
#define BCW_MMIO_GPIO_CONTROL 0x49c
#define BCW_MMIO_GPIO_MASK 0x49e
+#define BCW_MMIO_POWERUP_DELAY 0x6a8
/*
* SPROM registers are 16 bit and based at MMIO offset 0x1000
diff --git a/sys/dev/ic/bcwvar.h b/sys/dev/ic/bcwvar.h
index d69bf02a497..2f6ce9bca53 100644
--- a/sys/dev/ic/bcwvar.h
+++ b/sys/dev/ic/bcwvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bcwvar.h,v 1.36 2007/04/01 11:58:00 mglocker Exp $ */
+/* $OpenBSD: bcwvar.h,v 1.37 2007/04/04 19:36:42 mglocker Exp $ */
/*
* Copyright (c) 2007 Marcus Glocker <mglocker@openbsd.org>
@@ -57,7 +57,7 @@ enum {
BCW_LED_MODE_BG,
BCW_LED_TRANSFER,
BCW_LED_APTRANSFER,
- BCW_LED_WEIRD, /* FIXME */
+ BCW_LED_WEIRD, /* XXX */
BCW_LED_ASSOC,
BCW_LED_INACTIVE,