summaryrefslogtreecommitdiffstats
path: root/sys/pci/if_rl.c
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>2003-08-10 02:41:18 +0000
committerwpaul <wpaul@FreeBSD.org>2003-08-10 02:41:18 +0000
commitf150f539a814c1b031f421cf460b6848f23845c3 (patch)
tree2f7e4f2b4bbc7e9057e8330a869444a42f251fdb /sys/pci/if_rl.c
parentaf325fd3af882a05dc76b02119f41725de0dd5ec (diff)
downloadFreeBSD-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/if_rl.c')
-rw-r--r--sys/pci/if_rl.c18
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);
OpenPOWER on IntegriCloud