Determine the size of the SROM by probing the chip using the standard Microwire
protocol. Eliminates the need for srom_quirks and some other trash.
This commit is contained in:
parent
064b1bd2e9
commit
5eee9ca94c
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: tulip.c,v 1.46 2000/03/06 21:02:01 thorpej Exp $ */
|
||||
/* $NetBSD: tulip.c,v 1.47 2000/03/07 00:39:17 mycroft Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
|
||||
@ -152,6 +152,7 @@ void tlp_stop __P((struct tulip_softc *, int));
|
||||
int tlp_add_rxbuf __P((struct tulip_softc *, int));
|
||||
void tlp_idle __P((struct tulip_softc *, u_int32_t));
|
||||
void tlp_srom_idle __P((struct tulip_softc *));
|
||||
int tlp_srom_size __P((struct tulip_softc *));
|
||||
|
||||
void tlp_filter_setup __P((struct tulip_softc *));
|
||||
void tlp_winb_filter_setup __P((struct tulip_softc *));
|
||||
@ -598,6 +599,9 @@ tlp_detach(sc)
|
||||
|
||||
shutdownhook_disestablish(sc->sc_sdhook);
|
||||
|
||||
if (sc->sc_srom)
|
||||
free(sc->sc_srom, M_DEVBUF);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -1899,7 +1903,7 @@ tlp_stop(sc, drain)
|
||||
#define SROM_EMIT(sc, x) \
|
||||
do { \
|
||||
TULIP_WRITE((sc), CSR_MIIROM, (x)); \
|
||||
delay(1); \
|
||||
delay(2); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
@ -1925,8 +1929,8 @@ tlp_srom_idle(sc)
|
||||
|
||||
SROM_EMIT(sc, miirom|MIIROM_SROMSK);
|
||||
|
||||
/* Strobe the clock 25 times. */
|
||||
for (i = 0; i < 25; i++) {
|
||||
/* Strobe the clock 32 times. */
|
||||
for (i = 0; i < 32; i++) {
|
||||
SROM_EMIT(sc, miirom);
|
||||
SROM_EMIT(sc, miirom|MIIROM_SROMSK);
|
||||
}
|
||||
@ -1940,21 +1944,16 @@ tlp_srom_idle(sc)
|
||||
}
|
||||
|
||||
/*
|
||||
* tlp_read_srom:
|
||||
* tlp_srom_size:
|
||||
*
|
||||
* Read the Tulip SROM.
|
||||
* Determine the number of address bits in the SROM.
|
||||
*/
|
||||
void
|
||||
tlp_read_srom(sc, word, wordcnt, data)
|
||||
int
|
||||
tlp_srom_size(sc)
|
||||
struct tulip_softc *sc;
|
||||
int word, wordcnt;
|
||||
u_int8_t *data;
|
||||
{
|
||||
u_int32_t miirom;
|
||||
u_int16_t datain;
|
||||
int i, x;
|
||||
|
||||
tlp_srom_idle(sc);
|
||||
int x;
|
||||
|
||||
/* Select the SROM. */
|
||||
miirom = MIIROM_SR;
|
||||
@ -1963,7 +1962,77 @@ tlp_read_srom(sc, word, wordcnt, data)
|
||||
miirom |= MIIROM_RD;
|
||||
SROM_EMIT(sc, miirom);
|
||||
|
||||
for (i = 0; i < wordcnt; i++) {
|
||||
/* Send CHIP SELECT for one clock tick. */
|
||||
miirom |= MIIROM_SROMCS;
|
||||
SROM_EMIT(sc, miirom);
|
||||
|
||||
/* Shift in the READ opcode. */
|
||||
for (x = 3; x > 0; x--) {
|
||||
if (TULIP_SROM_OPC_READ & (1 << (x - 1)))
|
||||
miirom |= MIIROM_SROMDI;
|
||||
else
|
||||
miirom &= ~MIIROM_SROMDI;
|
||||
SROM_EMIT(sc, miirom);
|
||||
SROM_EMIT(sc, miirom|MIIROM_SROMSK);
|
||||
SROM_EMIT(sc, miirom);
|
||||
}
|
||||
|
||||
/* Shift in address and look for dummy 0 bit. */
|
||||
for (x = 1; x <= 12; x++) {
|
||||
miirom &= ~MIIROM_SROMDI;
|
||||
SROM_EMIT(sc, miirom);
|
||||
SROM_EMIT(sc, miirom|MIIROM_SROMSK);
|
||||
if (!TULIP_ISSET(sc, CSR_MIIROM, MIIROM_SROMDO))
|
||||
break;
|
||||
SROM_EMIT(sc, miirom);
|
||||
}
|
||||
|
||||
/* Clear CHIP SELECT. */
|
||||
miirom &= ~MIIROM_SROMCS;
|
||||
SROM_EMIT(sc, miirom);
|
||||
|
||||
/* Deselect the SROM. */
|
||||
SROM_EMIT(sc, 0);
|
||||
|
||||
if (x > 12) {
|
||||
printf("failed to find SROM size\n");
|
||||
return (0);
|
||||
} else {
|
||||
printf("SROM size is 2^%d*16 (%d) bits\n", x, 1 << (x + 4));
|
||||
return (x);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* tlp_read_srom:
|
||||
*
|
||||
* Read the Tulip SROM.
|
||||
*/
|
||||
int
|
||||
tlp_read_srom(sc)
|
||||
struct tulip_softc *sc;
|
||||
{
|
||||
int size;
|
||||
u_int32_t miirom;
|
||||
u_int16_t datain;
|
||||
int i, x;
|
||||
|
||||
tlp_srom_idle(sc);
|
||||
|
||||
sc->sc_srom_addrbits = tlp_srom_size(sc);
|
||||
if (sc->sc_srom_addrbits == 0)
|
||||
return (0);
|
||||
size = TULIP_ROM_SIZE(sc->sc_srom_addrbits);
|
||||
sc->sc_srom = malloc(size, M_DEVBUF, M_NOWAIT);
|
||||
|
||||
/* Select the SROM. */
|
||||
miirom = MIIROM_SR;
|
||||
SROM_EMIT(sc, miirom);
|
||||
|
||||
miirom |= MIIROM_RD;
|
||||
SROM_EMIT(sc, miirom);
|
||||
|
||||
for (i = 0; i < size; i += 2) {
|
||||
/* Send CHIP SELECT for one clock tick. */
|
||||
miirom |= MIIROM_SROMCS;
|
||||
SROM_EMIT(sc, miirom);
|
||||
@ -1981,7 +2050,7 @@ tlp_read_srom(sc, word, wordcnt, data)
|
||||
|
||||
/* Shift in address. */
|
||||
for (x = sc->sc_srom_addrbits; x > 0; x--) {
|
||||
if ((word + i) & (1 << (x - 1)))
|
||||
if (i & (1 << x))
|
||||
miirom |= MIIROM_SROMDI;
|
||||
else
|
||||
miirom &= ~MIIROM_SROMDI;
|
||||
@ -1999,8 +2068,8 @@ tlp_read_srom(sc, word, wordcnt, data)
|
||||
datain |= (1 << (x - 1));
|
||||
SROM_EMIT(sc, miirom);
|
||||
}
|
||||
data[2 * i] = datain & 0xff;
|
||||
data[(2 * i) + 1] = datain >> 8;
|
||||
sc->sc_srom[i] = datain & 0xff;
|
||||
sc->sc_srom[i + 1] = datain >> 8;
|
||||
|
||||
/* Clear CHIP SELECT. */
|
||||
miirom &= ~MIIROM_SROMCS;
|
||||
@ -2012,6 +2081,18 @@ tlp_read_srom(sc, word, wordcnt, data)
|
||||
|
||||
/* ...and idle it. */
|
||||
tlp_srom_idle(sc);
|
||||
|
||||
#if 0
|
||||
printf("SROM CONTENTS:");
|
||||
for (i = 0; i < size; i++) {
|
||||
if ((i % 8) == 0)
|
||||
printf("\n\t");
|
||||
printf("0x%02x ", sc->sc_srom[i]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
#undef SROM_EMIT
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: tulipvar.h,v 1.28 2000/02/01 22:54:48 thorpej Exp $ */
|
||||
/* $NetBSD: tulipvar.h,v 1.29 2000/03/07 00:39:17 mycroft Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
|
||||
@ -276,7 +276,7 @@ struct tulip_softc {
|
||||
/*
|
||||
* Contents of the SROM.
|
||||
*/
|
||||
u_int8_t sc_srom[TULIP_MAX_ROM_SIZE];
|
||||
u_int8_t *sc_srom;
|
||||
int sc_srom_addrbits;
|
||||
|
||||
/*
|
||||
@ -502,7 +502,7 @@ void tlp_attach __P((struct tulip_softc *, const u_int8_t *));
|
||||
int tlp_activate __P((struct device *, enum devact));
|
||||
int tlp_detach __P((struct tulip_softc *));
|
||||
int tlp_intr __P((void *));
|
||||
void tlp_read_srom __P((struct tulip_softc *, int, int, u_int8_t *));
|
||||
int tlp_read_srom __P((struct tulip_softc *));
|
||||
int tlp_srom_crcok __P((const u_int8_t *));
|
||||
int tlp_isv_srom __P((const u_int8_t *));
|
||||
int tlp_isv_srom_enaddr __P((struct tulip_softc *, u_int8_t *));
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: if_tlp_pci.c,v 1.32 2000/01/26 16:51:11 thorpej Exp $ */
|
||||
/* $NetBSD: if_tlp_pci.c,v 1.33 2000/03/07 00:39:18 mycroft Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
|
||||
@ -246,26 +246,6 @@ const struct tlp_pci_quirks tlp_pci_21142_quirks[] = {
|
||||
{ NULL, { 0, 0, 0 } }
|
||||
};
|
||||
|
||||
/*
|
||||
* Even more disgusting... some 21143 implementations (namely Cobalt's)
|
||||
* which should have a 8-address-bit SROM actually only have a
|
||||
* 6-address-bit SROM (even though it's rev 4.1!). Broken! This
|
||||
* quirk detects that.
|
||||
*/
|
||||
#define TPSQ_NOMATCH 0
|
||||
#define TPSQ_CONTINUE 1
|
||||
#define TPSQ_READ_AGAIN_AND_CONTINUE 2
|
||||
|
||||
typedef int (*tlp_pci_srom_quirk_t) __P((struct tulip_pci_softc *));
|
||||
|
||||
int tlp_pci_cobalt_21143_srom_quirks __P((struct tulip_pci_softc *));
|
||||
int tlp_pci_21143_srom_quirks __P((struct tulip_pci_softc *));
|
||||
|
||||
tlp_pci_srom_quirk_t tlp_pci_21143_srom_quirks_list[] = {
|
||||
tlp_pci_cobalt_21143_srom_quirks,
|
||||
tlp_pci_21143_srom_quirks, /* MUST BE AT THE END */
|
||||
};
|
||||
|
||||
int tlp_pci_shared_intr __P((void *));
|
||||
|
||||
const struct tulip_pci_product *tlp_pci_lookup
|
||||
@ -393,13 +373,6 @@ tlp_pci_attach(parent, self, aux)
|
||||
*/
|
||||
sc->sc_regshift = 3;
|
||||
|
||||
/*
|
||||
* Some chips have a 128 byte SROM (6 address bits), and some
|
||||
* have a 512 byte SROM (8 address bits). Default to 6; we'll
|
||||
* adjust below.
|
||||
*/
|
||||
sc->sc_srom_addrbits = 6;
|
||||
|
||||
/*
|
||||
* Get revision info, and set some chip-specific variables.
|
||||
*/
|
||||
@ -568,12 +541,12 @@ tlp_pci_attach(parent, self, aux)
|
||||
/*
|
||||
* Read the contents of the Ethernet Address ROM/SROM.
|
||||
*/
|
||||
read_srom_again:
|
||||
memset(sc->sc_srom, 0, sizeof(sc->sc_srom));
|
||||
switch (sc->sc_chip) {
|
||||
case TULIP_CHIP_21040:
|
||||
sc->sc_srom_addrbits = 6;
|
||||
sc->sc_srom = malloc(TULIP_ROM_SIZE(6), M_DEVBUF, M_NOWAIT);
|
||||
TULIP_WRITE(sc, CSR_MIIROM, MIIROM_SROMCS);
|
||||
for (i = 0; i < TULIP_ROM_SIZE(sc->sc_srom_addrbits); i++) {
|
||||
for (i = 0; i < TULIP_ROM_SIZE(6); i++) {
|
||||
for (j = 0; j < 10000; j++) {
|
||||
val = TULIP_READ(sc, CSR_MIIROM);
|
||||
if ((val & MIIROM_DN) == 0)
|
||||
@ -586,16 +559,17 @@ tlp_pci_attach(parent, self, aux)
|
||||
case TULIP_CHIP_82C168:
|
||||
case TULIP_CHIP_82C169:
|
||||
{
|
||||
u_int16_t *rombuf = (u_int16_t *)sc->sc_srom;
|
||||
sc->sc_srom_addrbits = 2;
|
||||
sc->sc_srom = malloc(TULIP_ROM_SIZE(2), M_DEVBUF, M_NOWAIT);
|
||||
|
||||
/*
|
||||
* The Lite-On PNIC stores the Ethernet address in
|
||||
* the first 3 words of the EEPROM. EEPROM access
|
||||
* is not like the other Tulip chips.
|
||||
*/
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (i = 0; i < 6; i += 2) {
|
||||
TULIP_WRITE(sc, CSR_PNIC_SROMCTL,
|
||||
PNIC_SROMCTL_READ | i);
|
||||
PNIC_SROMCTL_READ | (i >> 1));
|
||||
for (j = 0; j < 500; j++) {
|
||||
delay(2);
|
||||
val = TULIP_READ(sc, CSR_MIIROM);
|
||||
@ -607,23 +581,17 @@ tlp_pci_attach(parent, self, aux)
|
||||
sc->sc_dev.dv_xname);
|
||||
return;
|
||||
}
|
||||
rombuf[i] = bswap16(val & PNIC_MIIROM_DATA);
|
||||
val &= PNIC_MIIROM_DATA;
|
||||
sc->sc_srom[i] = val >> 8;
|
||||
sc->sc_srom[i + 1] = val & 0xff;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
tlp_read_srom(sc, 0, TULIP_ROM_SIZE(sc->sc_srom_addrbits) >> 1,
|
||||
sc->sc_srom);
|
||||
#if 0
|
||||
printf("SROM CONTENTS:");
|
||||
for (i = 0; i < TULIP_ROM_SIZE(sc->sc_srom_addrbits); i++) {
|
||||
if ((i % 8) == 0)
|
||||
printf("\n\t");
|
||||
printf("0x%02x ", sc->sc_srom[i]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
if (tlp_read_srom(sc) == 0)
|
||||
goto cant_cope;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -643,11 +611,8 @@ tlp_pci_attach(parent, self, aux)
|
||||
/*
|
||||
* Parse the Ethernet Address ROM.
|
||||
*/
|
||||
if (tlp_parse_old_srom(sc, enaddr) == 0) {
|
||||
printf("%s: unable to decode Ethernet Address ROM\n",
|
||||
sc->sc_dev.dv_xname);
|
||||
return;
|
||||
}
|
||||
if (tlp_parse_old_srom(sc, enaddr) == 0)
|
||||
goto cant_cope;
|
||||
|
||||
/*
|
||||
* If we have a slaved ROM, adjust the Ethernet address.
|
||||
@ -682,11 +647,8 @@ tlp_pci_attach(parent, self, aux)
|
||||
* Not an ISV SROM; try the old DEC Ethernet Address
|
||||
* ROM format.
|
||||
*/
|
||||
if (tlp_parse_old_srom(sc, enaddr) == 0) {
|
||||
printf("%s: unable to decode Ethernet "
|
||||
"Address ROM\n", sc->sc_dev.dv_xname);
|
||||
return;
|
||||
}
|
||||
if (tlp_parse_old_srom(sc, enaddr) == 0)
|
||||
goto cant_cope;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -709,11 +671,8 @@ tlp_pci_attach(parent, self, aux)
|
||||
* Not an ISV SROM; try the old DEC Ethernet Address
|
||||
* ROM format.
|
||||
*/
|
||||
if (tlp_parse_old_srom(sc, enaddr) == 0) {
|
||||
printf("%s: unable to decode Ethernet "
|
||||
"Address ROM\n", sc->sc_dev.dv_xname);
|
||||
return;
|
||||
}
|
||||
if (tlp_parse_old_srom(sc, enaddr) == 0)
|
||||
goto cant_cope;
|
||||
} else {
|
||||
/*
|
||||
* We start out with the 2114x ISV media switch.
|
||||
@ -739,37 +698,12 @@ tlp_pci_attach(parent, self, aux)
|
||||
case TULIP_CHIP_21143:
|
||||
/* Check for new format SROM. */
|
||||
if (tlp_isv_srom_enaddr(sc, enaddr) == 0) {
|
||||
if (sc->sc_chip == TULIP_CHIP_21143) {
|
||||
tlp_pci_srom_quirk_t q;
|
||||
|
||||
/*
|
||||
* Check for SROM quirkiness.
|
||||
*/
|
||||
for (i = 0; sc->sc_srom_addrbits != 8; i++) {
|
||||
q = tlp_pci_21143_srom_quirks_list[i];
|
||||
switch ((*q)(psc)) {
|
||||
case TPSQ_NOMATCH:
|
||||
continue;
|
||||
|
||||
case TPSQ_CONTINUE:
|
||||
break;
|
||||
|
||||
case TPSQ_READ_AGAIN_AND_CONTINUE:
|
||||
goto read_srom_again;
|
||||
}
|
||||
break; /* for TPSQ_CONTINUE */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Not an ISV SROM; try the old DEC Ethernet Address
|
||||
* ROM format.
|
||||
*/
|
||||
if (tlp_parse_old_srom(sc, enaddr) == 0) {
|
||||
printf("%s: unable to decode Ethernet "
|
||||
"Address ROM\n", sc->sc_dev.dv_xname);
|
||||
return;
|
||||
}
|
||||
if (tlp_parse_old_srom(sc, enaddr) == 0)
|
||||
goto cant_cope;
|
||||
} else {
|
||||
/*
|
||||
* We start out with the 2114x ISV media switch.
|
||||
@ -1158,42 +1092,3 @@ tlp_pci_cobalt_21142_quirks(psc, enaddr)
|
||||
*/
|
||||
sc->sc_mediasw = &tlp_sio_mii_mediasw;
|
||||
}
|
||||
|
||||
int
|
||||
tlp_pci_cobalt_21143_srom_quirks(psc)
|
||||
struct tulip_pci_softc *psc;
|
||||
{
|
||||
struct tulip_softc *sc = &psc->sc_tulip;
|
||||
|
||||
/*
|
||||
* Check for broken Cobalt interface; pass 4.1 Tulip with
|
||||
* only 6-bit SROM and Ethernet address in first 6 bytes.
|
||||
*/
|
||||
if (sc->sc_srom[0] == 0x00 &&
|
||||
sc->sc_srom[1] == 0x10 &&
|
||||
sc->sc_srom[2] == 0xe0)
|
||||
return (TPSQ_CONTINUE);
|
||||
|
||||
return (TPSQ_NOMATCH);
|
||||
}
|
||||
|
||||
int
|
||||
tlp_pci_21143_srom_quirks(psc)
|
||||
struct tulip_pci_softc *psc;
|
||||
{
|
||||
struct tulip_softc *sc = &psc->sc_tulip;
|
||||
|
||||
/*
|
||||
* Pass 4.1 21143s are supposed to have an 8-address-bit SROM.
|
||||
* We need to read them again.
|
||||
*/
|
||||
if (sc->sc_rev >= 0x41) {
|
||||
sc->sc_srom_addrbits = 8;
|
||||
return (TPSQ_READ_AGAIN_AND_CONTINUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* ...otherwise, what we read is just fine.
|
||||
*/
|
||||
return (TPSQ_CONTINUE);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user