diff options
author | wpaul <wpaul@FreeBSD.org> | 2003-08-10 02:41:18 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 2003-08-10 02:41:18 +0000 |
commit | f150f539a814c1b031f421cf460b6848f23845c3 (patch) | |
tree | 2f7e4f2b4bbc7e9057e8330a869444a42f251fdb /sys/pci | |
parent | af325fd3af882a05dc76b02119f41725de0dd5ec (diff) | |
download | FreeBSD-src-f150f539a814c1b031f421cf460b6848f23845c3.zip FreeBSD-src-f150f539a814c1b031f421cf460b6848f23845c3.tar.gz |
Grrr. There is a gratuitous difference in the RX descriptor status
word between the 8139C+ and the 8169. The 8139C+ has a 'frame alignment
error bit' (bit 27) but the 8169 does not. Rather than simply mark this
bit as reserved, RealTek removed it completely and shifted the remaining
status bits one space to the left. This was causing rl_rxeofcplus()
to misparse the error and checksum bits.
To workaround this, rl_rxeofcplus() now shifts the rxstat word one
bit to the right before testing any of the status bits (but after
the frame length has been extracted).
Diffstat (limited to 'sys/pci')
-rw-r--r-- | sys/pci/if_rl.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/sys/pci/if_rl.c b/sys/pci/if_rl.c index e0ab4c4..130aba0 100644 --- a/sys/pci/if_rl.c +++ b/sys/pci/if_rl.c @@ -1819,6 +1819,24 @@ rl_rxeofcplus(sc) bus_dmamap_unload(sc->rl_ldata.rl_mtag, sc->rl_ldata.rl_rx_dmamap[i]); + /* + * NOTE: For some reason that I can't comprehend, + * the RealTek engineers decided not to implement + * the 'frame alignment error' bit in the 8169's + * status word. Unfortunately, rather than simply + * mark the bit as 'reserved,' they took it away + * completely and shifted the other status bits + * over one slot. The OWN, EOR, FS and LS bits are + * still in the same places, as is the frame length + * field. We have already extracted the frame length + * and checked the OWN bit, so to work around this + * problem, we shift the status bits one space to + * the right so that we can evaluate everything else + * correctly. + */ + if (sc->rl_type == RL_8169) + rxstat >>= 1; + if (rxstat & RL_RDESC_STAT_RXERRSUM) { ifp->if_ierrors++; rl_newbuf(sc, i, m); |