Make the members of the descriptors volatile, because the NIC and
the host share them. Before breaking out of the loop over descriptors in gem_rint(), DMA-resynchronize the first Rx descriptor we found that does not belong to the host. We must avoid a cached descriptor "covering" a descriptor in RAM, because the cached descriptor may say that the descriptor still belongs to the NIC, when that is not true, and the driver will hang. XXX I believe this driver only works by luck on hosts that both XXX have a cacheline size greater than the size of a descriptor XXX (16 bytes) and lack DMA/cache coherency. I need to add some XXX trickery to make sure that we don't scribble over the NIC's XXX changes to a descriptor when we flush a cached descriptor to XXX RAM with bus_dmamap_sync(9).
This commit is contained in:
parent
7898b5e0a8
commit
b7dea03346
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: gem.c,v 1.55 2007/04/12 05:56:01 dyoung Exp $ */
|
||||
/* $NetBSD: gem.c,v 1.56 2007/04/12 06:14:40 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
*
|
||||
@ -34,7 +34,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: gem.c,v 1.55 2007/04/12 05:56:01 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: gem.c,v 1.56 2007/04/12 06:14:40 dyoung Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "bpfilter.h"
|
||||
@ -1473,6 +1473,7 @@ gem_rint(sc)
|
||||
rxstat = GEM_DMA_READ(sc, sc->sc_rxdescs[i].gd_flags);
|
||||
|
||||
if (rxstat & GEM_RD_OWN) {
|
||||
GEM_CDRXSYNC(sc, i, BUS_DMASYNC_PREREAD);
|
||||
/*
|
||||
* We have processed all of the receive buffers.
|
||||
*/
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: gemreg.h,v 1.9 2006/11/24 13:01:07 martin Exp $ */
|
||||
/* $NetBSD: gemreg.h,v 1.10 2007/04/12 06:14:47 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
*
|
||||
@ -583,8 +583,8 @@
|
||||
* GEM descriptor table structures.
|
||||
*/
|
||||
struct gem_desc {
|
||||
uint64_t gd_flags;
|
||||
uint64_t gd_addr;
|
||||
volatile uint64_t gd_flags;
|
||||
volatile uint64_t gd_addr;
|
||||
};
|
||||
|
||||
/* Transmit flags */
|
||||
|
Loading…
Reference in New Issue
Block a user