summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2005-09-23 23:01:22 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2005-09-23 23:01:22 +0000
commitc9245dbce4fb1d87a4891bdcf0a4e76b5e085649 (patch)
tree29b7e745f1c16168d43e1491d5ed3af75f7c4fdc
parent3a6c82dc20802f251d52c3cb62229b9746d0fde7 (diff)
Handle SI4126 operations differently on ADM8211B. This
is the final piece required to make ADM8211B based devices work. Based around what the Linux driver does. ok reyk@
-rw-r--r--sys/dev/ic/atw.c84
1 files changed, 77 insertions, 7 deletions
diff --git a/sys/dev/ic/atw.c b/sys/dev/ic/atw.c
index ab95fdcffe6..9d52832459f 100644
--- a/sys/dev/ic/atw.c
+++ b/sys/dev/ic/atw.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: atw.c,v 1.37 2005/09/22 00:27:18 jsg Exp $ */
+/* $OpenBSD: atw.c,v 1.38 2005/09/23 23:01:21 jsg Exp $ */
/* $NetBSD: atw.c,v 1.69 2004/07/23 07:07:55 dyoung Exp $ */
/*-
@@ -275,6 +275,7 @@ int atw_rf3000_write(struct atw_softc *, u_int, u_int);
/* Silicon Laboratories Si4126 RF/IF Synthesizer */
void atw_si4126_tune(struct atw_softc *, u_int);
void atw_si4126_write(struct atw_softc *, u_int, u_int);
+void atw_si4126_init(struct atw_softc *);
const struct atw_txthresh_tab atw_txthresh_tab_lo[] = ATW_TXTHRESH_TAB_LO_RATE;
const struct atw_txthresh_tab atw_txthresh_tab_hi[] = ATW_TXTHRESH_TAB_HI_RATE;
@@ -283,6 +284,16 @@ struct cfdriver atw_cd = {
NULL, "atw", DV_IFNET
};
+static const u_int atw_rfmd2958_ifn[] = {
+ 0x22bd, 0x22d2, 0x22e8, 0x22fe, 0x2314, 0x232a, 0x2340,
+ 0x2355, 0x236b, 0x2381, 0x2397, 0x23ad, 0x23c2, 0x23f7
+};
+
+static const u_int atw_rfmd2958_rf1r[] = {
+ 0x05d17, 0x3a2e8, 0x2e8ba, 0x22e8b, 0x1745d, 0x0ba2e, 0x00000,
+ 0x345d1, 0x28ba2, 0x1d174, 0x11745, 0x05d17, 0x3a2e8, 0x11745
+};
+
const char *atw_tx_state[] = {
"STOPPED",
"RUNNING - read descriptor",
@@ -1229,9 +1240,33 @@ atw_bbp_io_init(struct atw_softc *sc)
break;
}
ATW_WRITE(sc, ATW_MMIRADDR2, mmiraddr2);
+
+ atw_si4126_init(sc);
+
ATW_WRITE(sc, ATW_MACTEST, ATW_MACTEST_MMI_USETXCLK);
}
+void
+atw_si4126_init(struct atw_softc *sc)
+{
+ switch (sc->sc_rftype) {
+ case ATW_RFTYPE_RFMD:
+ if (sc->sc_rev >= ATW_REVISION_BA) {
+ atw_si4126_write(sc, 0x1f, 0x00000);
+ atw_si4126_write(sc, 0x0c, 0x3001f);
+ atw_si4126_write(sc, SI4126_GAIN, 0x29c03);
+ atw_si4126_write(sc, SI4126_RF1N, 0x1ff6f);
+ atw_si4126_write(sc, SI4126_RF2N, 0x29403);
+ atw_si4126_write(sc, SI4126_RF2R, 0x1456f);
+ atw_si4126_write(sc, 0x09, 0x10050);
+ atw_si4126_write(sc, SI4126_IFR, 0x3fff8);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
/*
* atw_init: [ ifnet interface function ]
*
@@ -1571,6 +1606,28 @@ atw_si4126_tune(struct atw_softc *sc, u_int chan)
atw_si4126_print(sc);
#endif /* ATW_SYNDEBUG */
+ if (sc->sc_rev >= ATW_REVISION_BA) {
+ atw_si4126_write(sc, SI4126_MAIN, 0x04007);
+ atw_si4126_write(sc, SI4126_POWER, 0x00033);
+ atw_si4126_write(sc, SI4126_IFN,
+ atw_rfmd2958_ifn[chan - 1]);
+ atw_si4126_write(sc, SI4126_RF1R,
+ atw_rfmd2958_rf1r[chan - 1]);
+#ifdef NOTYET
+ /* set TX POWER? */
+ atw_si4126_write(sc, 0x0a,
+ (sc->sc_srom[ATW_SR_CSR20] & mask) |
+ power << 9);
+#endif
+ /* set TX GAIN */
+ atw_si4126_write(sc, 0x09, 0x00050 |
+ sc->sc_srom[ATW_SR_TXPOWER(chan - 1)]);
+ /* wait 100us from power-up for RF, IF to settle */
+ DELAY(100);
+
+ return;
+ }
+
if (chan == 14)
mhz = 2484;
else
@@ -1706,7 +1763,8 @@ atw_rf3000_init(struct atw_softc *sc)
if (rc != 0)
goto out;
- /* XXX Reference driver remarks that Abocom sets this to 50.
+ /*
+ * XXX Reference driver remarks that Abocom sets this to 50.
* Meaning 0x50, I think.... 50 = 0x32, which would set a bit
* in the "reserved" area of register RF3000_OPTIONS1.
*/
@@ -1909,13 +1967,23 @@ void
atw_si4126_write(struct atw_softc *sc, u_int addr, u_int val)
{
uint32_t bits, mask, reg;
- const int nbits = 22;
+ int nbits;
- KASSERT((addr & ~PRESHIFT(SI4126_TWI_ADDR_MASK)) == 0);
- KASSERT((val & ~PRESHIFT(SI4126_TWI_DATA_MASK)) == 0);
+ if (sc->sc_rev >= ATW_REVISION_BA) {
+ nbits = 24;
+
+ val &= 0x3ffff;
+ addr &= 0x1f;
+ bits = val | (addr << 18);
+ } else {
+ nbits = 22;
- bits = LSHIFT(val, SI4126_TWI_DATA_MASK) |
- LSHIFT(addr, SI4126_TWI_ADDR_MASK);
+ KASSERT((addr & ~PRESHIFT(SI4126_TWI_ADDR_MASK)) == 0);
+ KASSERT((val & ~PRESHIFT(SI4126_TWI_DATA_MASK)) == 0);
+
+ bits = LSHIFT(val, SI4126_TWI_DATA_MASK) |
+ LSHIFT(addr, SI4126_TWI_ADDR_MASK);
+ }
reg = ATW_SYNRF_SELSYN;
/* reference driver: reset Si4126 serial bus to initial
@@ -2386,6 +2454,8 @@ atw_write_sup_rates(struct atw_softc *sc)
memcpy(&buf[1], ic->ic_bss->ni_rates.rs_rates,
ic->ic_bss->ni_rates.rs_nrates);
+ /* XXX deal with rev BA bug linux driver talks of? */
+
atw_write_sram(sc, ATW_SRAM_ADDR_SUPRATES, buf, sizeof(buf));
}