FreeBSD/sys/dev/le/if_le_lebuffer.c
/*
 * It turns out that using bus_space(9) to access the buffers and the
 * descriptors yields way more throughput than accessing them via the
 * KVA returned by rman_get_virtual(9). The descriptor rings can be
 * accessed using 8-bit up to 64-bit operations while the buffers can
 * be only accessed using 8-bit and 16-bit operations.
 * NB:	For whatever reason setting LE_C3_BSWP has no effect with at
 *	least the 501-2981 (although their 'busmaster-regval' property
 *	indicates to set LE_C3_BSWP also for these cards), so we need
 *	to manually byte swap access to the buffers, i.e. the accesses
 *	going through the RX/TX FIFOs.
 */
It turns out that using bus_space(9) to access the buffers and the
descriptors yields way more throughput than accessing them via the
KVA returned by rman_get_virtual(9). The descriptor rings can be
accessed using 8-bit up to 64-bit operations while the buffers can
be only accessed using 8-bit and 16-bit operations.
NB:  For whatever reason setting LE_C3_BSWP has no effect with at
least the 501-2981 (although their 'busmaster-regval' property
indicates to set LE_C3_BSWP also for these cards), so we need
to manually byte swap access to the buffers, i.e. the accesses
going through the RX/TX FIFOs.
It turns out that using bus_space ( 9 ) to access the buffers and the descriptors yields way more throughput than accessing them via the KVA returned by rman_get_virtual ( 9 ) . The descriptor rings can be accessed using 8 - bit up to 64 - bit operations while the buffers can be only accessed using 8 - bit and 16 - bit operations . NB : For whatever reason setting LE_C3_BSWP has no effect with at least the 501 - 2981 ( although their ' busmaster - regval ' property indicates to set LE_C3_BSWP also for these cards ) so we need to manually byte swap access to the buffers i . e . the accesses going through the RX / TX FIFOs .
static void
le_lebuffer_copytodesc(struct lance_softc *sc, void *fromv, int off, int len)
{
	struct le_lebuffer_softc *lesc = (struct le_lebuffer_softc *)sc;
	caddr_t from = fromv;
	for (; len >= 8; len -= 8, off += 8, from += 8)
		bus_write_8(lesc->sc_bres, off, be64dec(from));
	for (; len >= 4; len -= 4, off += 4, from += 4)
		bus_write_4(lesc->sc_bres, off, be32dec(from));
	for (; len >= 2; len -= 2, off += 2, from += 2)
		bus_write_2(lesc->sc_bres, off, be16dec(from));
	if (len == 1)
		bus_write_1(lesc->sc_bres, off, *from);
}
static void le_lebuffer_copytodesc ( struct lance_softc * sc , void * fromv , int off , int len ) { struct le_lebuffer_softc * lesc = ( struct le_lebuffer_softc * ) sc ; caddr_t from = fromv ; for ( ; len >= 8 ; len -= 8 , off += 8 , from += 8 ) bus_write_8 ( lesc -> sc_bres , off , be64dec ( from ) ) ; for ( ; len >= 4 ; len -= 4 , off += 4 , from += 4 ) bus_write_4 ( lesc -> sc_bres , off , be32dec ( from ) ) ; for ( ; len >= 2 ; len -= 2 , off += 2 , from += 2 ) bus_write_2 ( lesc -> sc_bres , off , be16dec ( from ) ) ; if ( len == 1 ) bus_write_1 ( lesc -> sc_bres , off , * from ) ; }
It turns out that using bus_space(9) to access the buffers and the
 descriptors yields way more throughput than accessing them via the
 KVA returned by rman_get_virtual(9).
It turns out that using bus_space ( 9 ) to access the buffers and the descriptors yields way more throughput than accessing them via the KVA returned by rman_get_virtual ( 9 ) .