diff options
author | wpaul <wpaul@FreeBSD.org> | 2001-07-10 23:07:15 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 2001-07-10 23:07:15 +0000 |
commit | f397ddead2ee55b3b7beb2b794ba5fd172d1646e (patch) | |
tree | b88ddae1e9d4b0eededa455286d313e3b9603dd2 /sys/dev/nge | |
parent | ecbac42d619c707d6a486fce56cdff49cd9c5367 (diff) | |
download | FreeBSD-src-f397ddead2ee55b3b7beb2b794ba5fd172d1646e.zip FreeBSD-src-f397ddead2ee55b3b7beb2b794ba5fd172d1646e.tar.gz |
Two optimizations:
1) Bite the bullet, and allow unaligned accesses without buffer copies
on the i386 platform. According to some tests run by Andrew Gallatin,
the buffer copy performance hit is greater than the unaligned access
performance hit (especially with jumbo frames). We still need to copy
everywhere else.
2) Enable interrupt moderation with a 100us timeout.
Submitted by: Andrew Gallatin <no longer at duke.edu>
MFC after: 1 week
Diffstat (limited to 'sys/dev/nge')
-rw-r--r-- | sys/dev/nge/if_nge.c | 45 |
1 files changed, 35 insertions, 10 deletions
diff --git a/sys/dev/nge/if_nge.c b/sys/dev/nge/if_nge.c index 2bad1c6..4900fdf 100644 --- a/sys/dev/nge/if_nge.c +++ b/sys/dev/nge/if_nge.c @@ -1286,17 +1286,34 @@ static void nge_rxeof(sc) * only gigE chip I know of with alignment constraints * on receive buffers. RX buffers must be 64-bit aligned. */ - m0 = m_devget(mtod(m, char *), total_len, ETHER_ALIGN, ifp, - NULL); - nge_newbuf(sc, cur_rx, m); - if (m0 == NULL) { - printf("nge%d: no receive buffers " - "available -- packet dropped!\n", - sc->nge_unit); - ifp->if_ierrors++; - continue; +#ifdef __i386__ + /* + * By popular demand, ignore the alignment problems + * on the Intel x86 platform. The performance hit + * incurred due to unaligned accesses is much smaller + * than the hit produced by forcing buffer copies all + * the time, especially with jumbo frames. We still + * need to fix up the alignment everywhere else though. + */ + if (nge_newbuf(sc, cur_rx, NULL) == ENOBUFS) { +#endif + m0 = m_devget(mtod(m, char *), total_len, + ETHER_ALIGN, ifp, NULL); + nge_newbuf(sc, cur_rx, m); + if (m0 == NULL) { + printf("nge%d: no receive buffers " + "available -- packet dropped!\n", + sc->nge_unit); + ifp->if_ierrors++; + continue; + } + m = m0; +#ifdef __i386__ + } else { + m->m_pkthdr.rcvif = ifp; + m->m_pkthdr.len = m->m_len = total_len; } - m = m0; +#endif ifp->if_ipackets++; eh = mtod(m, struct ether_header *); @@ -1786,6 +1803,14 @@ static void nge_init(xsc) NGE_CFG_PHYINTR_LNK|NGE_CFG_PHYINTR_DUP|NGE_CFG_EXTSTS_ENB); /* + * Configure interrupt holdoff (moderation). We can + * have the chip delay interrupt delivery for a certain + * period. Units are in 100us, and the max setting + * is 25500us (0xFF x 100us). Default is a 100us holdoff. + */ + CSR_WRITE_4(sc, NGE_IHR, 0x01); + + /* * Enable interrupts. */ CSR_WRITE_4(sc, NGE_IMR, NGE_INTRS); |