On Tue, Jun 23, 2015 at 09:08:25PM -0600, Theo de Raadt wrote:
> > I looked into this last year but lost interest. It seems like the DMA buffer
> > is being placed past the UVM constraint for DMA ( eg > 4GB).
> 
> A configuration buffer is in the softc.  It should be allocated to be
> dma-reachable.
> 
> This driver is quite ugly.  Maybe the following diff works?
> 

It fixes the issue for me, with two changes below, otherwise OK.

But I still don't get any traffic with de(4) on Hyper-V here ...  or
just once in a while with dhclient .... but this seems to be a
different issue.

Reyk

> Index: if_de.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/if_de.c,v
> retrieving revision 1.120
> diff -u -p -u -r1.120 if_de.c
> --- if_de.c   15 May 2015 11:36:30 -0000      1.120
> +++ if_de.c   24 Jun 2015 00:05:05 -0000
> @@ -49,6 +49,7 @@
>  #include <sys/kernel.h>
>  #include <sys/device.h>
>  #include <sys/timeout.h>
> +#include <sys/pool.h>
>  
>  #include <net/if.h>
>  #include <net/if_media.h>
> @@ -2907,7 +2908,7 @@ tulip_addr_filter(tulip_softc_t * const 
>        * go into hash perfect mode (512 bit multicast
>        * hash and one perfect hardware).
>        */
> -     bzero(sc->tulip_setupdata, sizeof(sc->tulip_setupdata));
> +     bzero(sc->tulip_setupdata, TULIP_SETUP);
>       if (ac->ac_multirangecnt > 0) {
>           sc->tulip_flags |= TULIP_ALLMULTI;
>           sc->tulip_flags &= ~(TULIP_WANTHASHONLY|TULIP_WANTHASHPERFECT);
> @@ -4085,8 +4086,7 @@ tulip_txput_setup(tulip_softc_t * const 
>       sc->tulip_if.if_start = tulip_ifstart;
>       return;
>      }
> -    bcopy(sc->tulip_setupdata, sc->tulip_setupbuf,
> -       sizeof(sc->tulip_setupbuf));
> +    bcopy(sc->tulip_setupdata, sc->tulip_setupbuf, TULIP_SETUP);
>      /*
>       * Clear WANTSETUP and set DOINGSETUP.  Set know that WANTSETUP is
>       * set and DOINGSETUP is clear doing an XOR of the two will DTRT.
> @@ -4357,16 +4357,17 @@ tulip_busdma_init(tulip_softc_t * const 
>  {
>      int error = 0;
>  
> +    sc->tulip_setupbuf = dma_alloc(TULIP_SETUP, PR_WAITOK);
> +    sc->tulip_setupdata = malloc(TULIP_SETUP, M_DEVBUF, M_WAITOK);
> +
>      /*
>       * Allocate dmamap for setup descriptor
>       */
>      error = bus_dmamap_create(sc->tulip_dmatag, sizeof(sc->tulip_setupbuf), 
> 2,

Here is a missing TULIP_SETUP, it should be:

      error = bus_dmamap_create(sc->tulip_dmatag, TULIP_SETUP, 2,
        TULIP_SETUP, 0, BUS_DMA_NOWAIT, &sc->tulip_setupmap);

> -                           sizeof(sc->tulip_setupbuf), 0, BUS_DMA_NOWAIT,
> -                           &sc->tulip_setupmap);
> +     TULIP_SETUP, 0, BUS_DMA_NOWAIT, &sc->tulip_setupmap);
>      if (error == 0) {
>       error = bus_dmamap_load(sc->tulip_dmatag, sc->tulip_setupmap,
> -                             sc->tulip_setupbuf, sizeof(sc->tulip_setupbuf),
> -                             NULL, BUS_DMA_NOWAIT);
> +         sc->tulip_setupbuf, TULIP_SETUP, NULL, BUS_DMA_NOWAIT);
>       if (error)
>           bus_dmamap_destroy(sc->tulip_dmatag, sc->tulip_setupmap);
>      }
> Index: if_devar.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/if_devar.h,v
> retrieving revision 1.33
> diff -u -p -u -r1.33 if_devar.h
> --- if_devar.h        10 Feb 2015 03:51:58 -0000      1.33
> +++ if_devar.h        24 Jun 2015 00:04:36 -0000
> @@ -600,8 +600,10 @@ struct _tulip_softc_t {
>       * one is the one being sent while the other is the one being
>       * filled.
>       */
> -    u_int32_t tulip_setupbuf[192/sizeof(u_int32_t)];
> -    u_int32_t tulip_setupdata[192/sizeof(u_int32_t)];
> +#define TULIP_SETUP  (192 / sizeof(u_int32_t))

As mentioned in another mail, this should be changed to

#define TULIP_SETUP     192

> +    u_int32_t *tulip_setupbuf;
> +    u_int32_t *tulip_setupdata;
> +
>      char tulip_boardid[16];          /* buffer for board ID */
>      u_int8_t tulip_rombuf[128];
>      struct device *tulip_pci_busno;  /* needed for multiport boards */

Reply via email to