diff options
author | wpaul <wpaul@FreeBSD.org> | 2003-09-11 06:56:46 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 2003-09-11 06:56:46 +0000 |
commit | d4a3ccea7c9aa74a42d1df6d9a635c2b8054eaf5 (patch) | |
tree | 1f97f1d0d087d2e14ccbbed21f5e267a05ff56b1 /sys/dev/re | |
parent | 5d369f4c62f70ea67230f7be1aa4b7a62be2586b (diff) | |
download | FreeBSD-src-d4a3ccea7c9aa74a42d1df6d9a635c2b8054eaf5.zip FreeBSD-src-d4a3ccea7c9aa74a42d1df6d9a635c2b8054eaf5.tar.gz |
- For the 8169 chips, read the station address by forcing an EEPROM
autoload and then copying the contends of the station address
registers. For some reason, reading the EEPROM on the 8169S doesn't
work right. This gets around the problem, and allows us to read
the station address correctly on the 8169S.
- Insert a delay after initiating packet transmition in re_diag() to
allow lots of time for the frame to echo back to the host, and wait
for both the 'RX complete' and 'timeout expired' bits in the ISR
register to be set.
- Deal more intelligently with the fact that the frame length
field in the RX descriptor is a different width on the 8139C+
than it is on the 8169/8169S/8110S
- For the 8169, you have to set bit 17 in the TX config register
to enter digital loopback mode, but for the 8139C+, you have to
set both bits 17 and 18. Take this into account so that re_diag()
works properly for both types of chips.
Diffstat (limited to 'sys/dev/re')
-rw-r--r-- | sys/dev/re/if_re.c | 86 |
1 files changed, 59 insertions, 27 deletions
diff --git a/sys/dev/re/if_re.c b/sys/dev/re/if_re.c index af763eb..6e21d67 100644 --- a/sys/dev/re/if_re.c +++ b/sys/dev/re/if_re.c @@ -740,14 +740,17 @@ re_diag(sc) /* Queue the packet, start transmission */ IF_HANDOFF(&ifp->if_snd, m0, ifp); + CSR_WRITE_2(sc, RL_ISR, 0xFFFF); re_start(ifp); m0 = NULL; /* Wait for it to propagate through the chip */ + DELAY(100000); for (i = 0; i < RL_TIMEOUT; i++) { status = CSR_READ_2(sc, RL_ISR); - if (status & RL_ISR_RX_OK) + if ((status & (RL_ISR_TIMEOUT_EXPIRED|RL_ISR_RX_OK)) == + (RL_ISR_TIMEOUT_EXPIRED|RL_ISR_RX_OK)) break; DELAY(10); } @@ -1155,22 +1158,56 @@ re_attach(dev) /* Reset the adapter. */ re_reset(sc); - CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_PROGRAM); - sc->rl_eecmd_read = RL_EECMD_READ_6BIT; - re_read_eeprom(sc, (caddr_t)&re_did, 0, 1, 0); - if (re_did != 0x8129) - sc->rl_eecmd_read = RL_EECMD_READ_8BIT; - /* - * Get station address from the EEPROM. - */ - re_read_eeprom(sc, (caddr_t)as, RL_EE_EADDR, 3, 0); - for (i = 0; i < 3; i++) { - eaddr[(i * 2) + 0] = as[i] & 0xff; - eaddr[(i * 2) + 1] = as[i] >> 8; + hw_rev = re_hwrevs; + hwrev = CSR_READ_4(sc, RL_TXCFG) & RL_TXCFG_HWREV; + while (hw_rev->rl_desc != NULL) { + if (hw_rev->rl_rev == hwrev) { + sc->rl_type = hw_rev->rl_type; + break; + } + hw_rev++; } - CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF); + if (sc->rl_type == RL_8169) { + + /* Set RX length mask */ + + sc->rl_rxlenmask = RL_RDESC_STAT_GFRAGLEN; + + /* Force station address autoload from the EEPROM */ + + CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_AUTOLOAD); + for (i = 0; i < RL_TIMEOUT; i++) { + if (!(CSR_READ_1(sc, RL_EECMD) & RL_EEMODE_AUTOLOAD)) + break; + DELAY(100); + } + if (i == RL_TIMEOUT) + printf ("re%d: eeprom autoload timed out\n", unit); + + for (i = 0; i < ETHER_ADDR_LEN; i++) + eaddr[i] = CSR_READ_1(sc, RL_IDR0 + i); + } else { + + /* Set RX length mask */ + + sc->rl_rxlenmask = RL_RDESC_STAT_FRAGLEN; + + sc->rl_eecmd_read = RL_EECMD_READ_6BIT; + re_read_eeprom(sc, (caddr_t)&re_did, 0, 1, 0); + if (re_did != 0x8129) + sc->rl_eecmd_read = RL_EECMD_READ_8BIT; + + /* + * Get station address from the EEPROM. + */ + re_read_eeprom(sc, (caddr_t)as, RL_EE_EADDR, 3, 0); + for (i = 0; i < 3; i++) { + eaddr[(i * 2) + 0] = as[i] & 0xff; + eaddr[(i * 2) + 1] = as[i] >> 8; + } + } /* * A RealTek chip was detected. Inform the world. @@ -1180,16 +1217,6 @@ re_attach(dev) sc->rl_unit = unit; bcopy(eaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN); - hw_rev = re_hwrevs; - hwrev = CSR_READ_4(sc, RL_TXCFG) & RL_TXCFG_HWREV; - while (hw_rev->rl_desc != NULL) { - if (hw_rev->rl_rev == hwrev) { - sc->rl_type = hw_rev->rl_type; - break; - } - hw_rev++; - } - /* * Allocate the parent bus DMA tag appropriate for PCI. */ @@ -2071,9 +2098,14 @@ re_init(xsc) /* * Set the initial TX and RX configuration. */ - if (sc->rl_testmode) - CSR_WRITE_4(sc, RL_TXCFG, RL_TXCFG_CONFIG|RL_LOOPTEST_ON); - else + if (sc->rl_testmode) { + if (sc->rl_type == RL_8169) + CSR_WRITE_4(sc, RL_TXCFG, + RL_TXCFG_CONFIG|RL_LOOPTEST_ON); + else + CSR_WRITE_4(sc, RL_TXCFG, + RL_TXCFG_CONFIG|RL_LOOPTEST_ON_CPLUS); + } else CSR_WRITE_4(sc, RL_TXCFG, RL_TXCFG_CONFIG); CSR_WRITE_4(sc, RL_RXCFG, RL_RXCFG_CONFIG); |