tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

DMA sync for bce(4) ring descriptors



Hi,

bce(4) doesn't properly sync it's ring descriptors,
this becomes apparent on MIPS.  I've been sitting on
this for quite a while, but I'd like someone to
bless this as being not-incorrect.

Attached is a patch, based mostly on how it's done in
nfe(4).

I've tested it on MIPS, but I don't have bce hardware in
an x86 box.

I'd also eventually like to have someone test a PCI bus
frontend and bus-independent backend split.

        Jonathan Kollasch
Index: if_bce.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_bce.c,v
retrieving revision 1.25
diff -u -r1.25 if_bce.c
--- if_bce.c    6 May 2009 09:25:15 -0000       1.25
+++ if_bce.c    27 May 2009 20:08:06 -0000
@@ -604,10 +604,25 @@
                        txsfree--;
                }
                /* sync descriptors being used */
-               bus_dmamap_sync(sc->bce_dmatag, sc->bce_ring_map,
-                         sizeof(struct bce_dma_slot) * txstart + PAGE_SIZE,
-                            sizeof(struct bce_dma_slot) * dmamap->dm_nsegs,
-                               BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+               if ( sc->bce_txsnext > txstart ) {
+                       bus_dmamap_sync(sc->bce_dmatag, sc->bce_ring_map,
+                           PAGE_SIZE + sizeof(struct bce_dma_slot) * txstart,
+                           sizeof(struct bce_dma_slot) * dmamap->dm_nsegs,
+                           BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+               } else {
+                       bus_dmamap_sync(sc->bce_dmatag, sc->bce_ring_map,
+                           PAGE_SIZE + sizeof(struct bce_dma_slot) * txstart,
+                           sizeof(struct bce_dma_slot) *
+                           (BCE_NTXDESC - txstart),
+                           BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+                       if ( sc->bce_txsnext != 0 ) {
+                               bus_dmamap_sync(sc->bce_dmatag,
+                                   sc->bce_ring_map, PAGE_SIZE,
+                                   sc->bce_txsnext *
+                                   sizeof(struct bce_dma_slot),
+                                   BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+                       }
+               }
 
                /* Give the packet to the chip. */
                bus_space_write_4(sc->bce_btag, sc->bce_bhandle, BCE_DMA_DPTR,


Home | Main Index | Thread Index | Old Index