summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>2000-06-12 16:46:54 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>2000-06-12 16:46:54 +0000
commit13bc2520cdbb36586f73bb5d36de2150d397d76c (patch)
tree51bf96978c294c450446583b87f1ddc41692ec32 /sys/dev
parent3dba42d93e04d9037b970f300453dd4a1fe16190 (diff)
eeprom width detection code.
idea from netbsd tulip driver. there is problem w/ an983 card, but aaron@ said he'll work it out. aaron@ & jason@ ok.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ic/dc.c102
-rw-r--r--sys/dev/ic/dcreg.h3
2 files changed, 99 insertions, 6 deletions
diff --git a/sys/dev/ic/dc.c b/sys/dev/ic/dc.c
index 7b1cfd2f197..74e2c5cc32b 100644
--- a/sys/dev/ic/dc.c
+++ b/sys/dev/ic/dc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dc.c,v 1.2 2000/06/12 15:17:13 aaron Exp $ */
+/* $OpenBSD: dc.c,v 1.3 2000/06/12 16:46:53 mickey Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@@ -174,6 +174,7 @@ int dc_ifmedia_upd __P((struct ifnet *));
void dc_ifmedia_sts __P((struct ifnet *, struct ifmediareq *));
void dc_delay __P((struct dc_softc *));
+void dc_eeprom_width __P((struct dc_softc *));
void dc_eeprom_idle __P((struct dc_softc *));
void dc_eeprom_putbyte __P((struct dc_softc *, int));
void dc_eeprom_getword __P((struct dc_softc *, int, u_int16_t *));
@@ -221,6 +222,83 @@ void dc_delay(sc)
CSR_READ_4(sc, DC_BUSCTL);
}
+void dc_eeprom_width(sc)
+ struct dc_softc *sc;
+{
+ u_int16_t word;
+ int i;
+
+ /* Force EEPROM to idle state. */
+ dc_eeprom_idle(sc);
+
+ /* Enter EEPROM access mode. */
+ CSR_WRITE_4(sc, DC_SIO, DC_SIO_EESEL);
+ dc_delay(sc);
+ DC_SETBIT(sc, DC_SIO, DC_SIO_ROMCTL_READ);
+ dc_delay(sc);
+ DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_CLK);
+ dc_delay(sc);
+ DC_SETBIT(sc, DC_SIO, DC_SIO_EE_CS);
+ dc_delay(sc);
+
+ for (i = 3; i--;) {
+ if (6 & (1 << i))
+ DC_SETBIT(sc, DC_SIO, DC_SIO_EE_DATAIN);
+ else
+ DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_DATAIN);
+ dc_delay(sc);
+ DC_SETBIT(sc, DC_SIO, DC_SIO_EE_CLK);
+ dc_delay(sc);
+ DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_CLK);
+ dc_delay(sc);
+ }
+
+ for (i = 1; i <= 12; i++) {
+ DC_SETBIT(sc, DC_SIO, DC_SIO_EE_CLK);
+ dc_delay(sc);
+ if (!(CSR_READ_4(sc, DC_SIO) & DC_SIO_EE_DATAOUT)) {
+ DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_CLK);
+ dc_delay(sc);
+ break;
+ }
+ DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_CLK);
+ dc_delay(sc);
+ }
+
+ /* Turn off EEPROM access mode. */
+ dc_eeprom_idle(sc);
+
+ if (i < 4 || i > 12) {
+ printf("forcing eeprom width to 12, ");
+ sc->dc_romwidth = 6;
+ } else {
+ printf("eeprom width is %d, ", i);
+ sc->dc_romwidth = i;
+ }
+
+ /* Enter EEPROM access mode. */
+ CSR_WRITE_4(sc, DC_SIO, DC_SIO_EESEL);
+ dc_delay(sc);
+ DC_SETBIT(sc, DC_SIO, DC_SIO_ROMCTL_READ);
+ dc_delay(sc);
+ DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_CLK);
+ dc_delay(sc);
+ DC_SETBIT(sc, DC_SIO, DC_SIO_EE_CS);
+ dc_delay(sc);
+
+ printf("\n");
+ for (i = 0; i < 256; i++) {
+ if (DC_IS_PNIC(sc))
+ dc_eeprom_getword_pnic(sc, i, &word);
+ else
+ dc_eeprom_getword(sc, i, &word);
+ printf("%04x%s", word, ((i & 15) == 15)? "\n": " ");
+ }
+
+ /* Turn off EEPROM access mode. */
+ dc_eeprom_idle(sc);
+}
+
void dc_eeprom_idle(sc)
struct dc_softc *sc;
{
@@ -266,15 +344,27 @@ void dc_eeprom_putbyte(sc, addr)
* specifying the "read" opcode.
*/
if (DC_IS_CENTAUR(sc))
- d = addr | (DC_EECMD_READ << 2);
+ d = DC_EECMD_READ >> 4;
else
- d = addr | DC_EECMD_READ;
+ d = DC_EECMD_READ >> 6;
+
+ for (i = 3; i--; ) {
+ if (d & (1 << i))
+ DC_SETBIT(sc, DC_SIO, DC_SIO_EE_DATAIN);
+ else
+ DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_DATAIN);
+ dc_delay(sc);
+ DC_SETBIT(sc, DC_SIO, DC_SIO_EE_CLK);
+ dc_delay(sc);
+ DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_CLK);
+ dc_delay(sc);
+ }
/*
* Feed in each bit and strobe the clock.
*/
- for (i = 0x400; i; i >>= 1) {
- if (d & i) {
+ for (i = sc->dc_romwidth; i--;) {
+ if (addr & (1 << i)) {
SIO_SET(DC_SIO_EE_DATAIN);
} else {
SIO_CLR(DC_SIO_EE_DATAIN);
@@ -1215,6 +1305,8 @@ void dc_attach_common(sc)
struct ifnet *ifp;
int mac_offset;
+ dc_eeprom_width(sc);
+
/*
* Get station address from the EEPROM.
*/
diff --git a/sys/dev/ic/dcreg.h b/sys/dev/ic/dcreg.h
index 90431cb3022..559925a5664 100644
--- a/sys/dev/ic/dcreg.h
+++ b/sys/dev/ic/dcreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dcreg.h,v 1.4 2000/06/12 15:17:13 aaron Exp $ */
+/* $OpenBSD: dcreg.h,v 1.5 2000/06/12 16:46:53 mickey Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@@ -648,6 +648,7 @@ struct dc_softc {
u_int8_t dc_pmode;
u_int8_t dc_link;
u_int8_t dc_cachesize;
+ int dc_romwidth;
int dc_pnic_rx_bug_save;
unsigned char *dc_pnic_rx_buf;
int dc_if_flags;