> Date: Fri, 23 May 2014 10:40:49 +0200
> From: Martin Pieuchot <[email protected]>
> 
> Diff below splits the functions that allocate memory for the various
> ring to do it only once, in bge_attach(), instead of doing it every
> time bge_init() is called, possibly in the watchdog function.
> 
> Tested with a "Broadcom BCM5714" rev 0xa3, BCM5715 A3 (0x9003).
> 
> Comments?  Ok?

I think that's a step backwards.  If an interface is unconfigured it
should not consume any resources (such as memory) that are not needed.


> Index: if_bge.c
> ===================================================================
> RCS file: /home/ncvs/src/sys/dev/pci/if_bge.c,v
> retrieving revision 1.354
> diff -u -p -r1.354 if_bge.c
> --- if_bge.c  22 Apr 2014 11:54:46 -0000      1.354
> +++ if_bge.c  21 May 2014 14:52:03 -0000
> @@ -166,18 +166,24 @@ int bge_read_eeprom(struct bge_softc *, 
>  void bge_iff(struct bge_softc *);
>  
>  int bge_newbuf_jumbo(struct bge_softc *, int);
> +int bge_alloc_rx_ring_jumbo(struct bge_softc *);
>  int bge_init_rx_ring_jumbo(struct bge_softc *);
>  void bge_fill_rx_ring_jumbo(struct bge_softc *);
>  void bge_free_rx_ring_jumbo(struct bge_softc *);
> +void bge_drain_rx_ring_jumbo(struct bge_softc *);
>  
>  int bge_newbuf(struct bge_softc *, int);
> +int bge_alloc_rx_ring_std(struct bge_softc *);
>  int bge_init_rx_ring_std(struct bge_softc *);
>  void bge_rxtick(void *);
>  void bge_fill_rx_ring_std(struct bge_softc *);
>  void bge_free_rx_ring_std(struct bge_softc *);
> +void bge_drain_rx_ring_std(struct bge_softc *);
>  
> +int bge_alloc_tx_ring(struct bge_softc *);
>  void bge_free_tx_ring(struct bge_softc *);
>  int bge_init_tx_ring(struct bge_softc *);
> +void bge_drain_tx_ring(struct bge_softc *);
>  
>  void bge_chipinit(struct bge_softc *);
>  int bge_blockinit(struct bge_softc *);
> @@ -1238,13 +1244,10 @@ bge_newbuf_jumbo(struct bge_softc *sc, i
>   * the NIC.
>   */
>  int
> -bge_init_rx_ring_std(struct bge_softc *sc)
> +bge_alloc_rx_ring_std(struct bge_softc *sc)
>  {
>       int i;
>  
> -     if (ISSET(sc->bge_flags, BGE_RXRING_VALID))
> -             return (0);
> -
>       for (i = 0; i < BGE_STD_RX_RING_CNT; i++) {
>               if (bus_dmamap_create(sc->bge_dmatag, MCLBYTES, 1, MCLBYTES, 0,
>                   BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
> @@ -1257,12 +1260,6 @@ bge_init_rx_ring_std(struct bge_softc *s
>                   sizeof(struct bge_rx_bd));
>       }
>  
> -     sc->bge_std = BGE_STD_RX_RING_CNT - 1;
> -     sc->bge_std_cnt = 0;
> -     bge_fill_rx_ring_std(sc);
> -
> -     SET(sc->bge_flags, BGE_RXRING_VALID);
> -
>       return (0);
>  
>  uncreate:
> @@ -1273,6 +1270,21 @@ uncreate:
>       return (1);
>  }
>  
> +int
> +bge_init_rx_ring_std(struct bge_softc *sc)
> +{
> +     if (ISSET(sc->bge_flags, BGE_RXRING_VALID))
> +             return (0);
> +
> +     sc->bge_std = BGE_STD_RX_RING_CNT - 1;
> +     sc->bge_std_cnt = 0;
> +     bge_fill_rx_ring_std(sc);
> +
> +     SET(sc->bge_flags, BGE_RXRING_VALID);
> +
> +     return (0);
> +}
> +
>  void
>  bge_rxtick(void *arg)
>  {
> @@ -1321,6 +1333,21 @@ void
>  bge_free_rx_ring_std(struct bge_softc *sc)
>  {
>       bus_dmamap_t dmap;
> +     int i;
> +
> +     for (i = 0; i < BGE_STD_RX_RING_CNT; i++) {
> +             dmap = sc->bge_cdata.bge_rx_std_map[i];
> +             bus_dmamap_destroy(sc->bge_dmatag, dmap);
> +             sc->bge_cdata.bge_rx_std_map[i] = NULL;
> +             bzero(&sc->bge_rdata->bge_rx_std_ring[i],
> +                 sizeof(struct bge_rx_bd));
> +     }
> +}
> +
> +void
> +bge_drain_rx_ring_std(struct bge_softc *sc)
> +{
> +     bus_dmamap_t dmap;
>       struct mbuf *m;
>       int i;
>  
> @@ -1337,24 +1364,16 @@ bge_free_rx_ring_std(struct bge_softc *s
>                       m_freem(m);
>                       sc->bge_cdata.bge_rx_std_chain[i] = NULL;
>               }
> -             bus_dmamap_destroy(sc->bge_dmatag, dmap);
> -             sc->bge_cdata.bge_rx_std_map[i] = NULL;
> -             bzero(&sc->bge_rdata->bge_rx_std_ring[i],
> -                 sizeof(struct bge_rx_bd));
>       }
>  
>       CLR(sc->bge_flags, BGE_RXRING_VALID);
>  }
>  
>  int
> -bge_init_rx_ring_jumbo(struct bge_softc *sc)
> +bge_alloc_rx_ring_jumbo(struct bge_softc *sc)
>  {
> -     volatile struct bge_rcb *rcb;
>       int i;
>  
> -     if (ISSET(sc->bge_flags, BGE_JUMBO_RXRING_VALID))
> -             return (0);
> -
>       for (i = 0; i < BGE_JUMBO_RX_RING_CNT; i++) {
>               if (bus_dmamap_create(sc->bge_dmatag, BGE_JLEN, 4, BGE_JLEN, 0,
>                   BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
> @@ -1367,6 +1386,24 @@ bge_init_rx_ring_jumbo(struct bge_softc 
>                   sizeof(struct bge_ext_rx_bd));
>       }
>  
> +     return (0);
> +
> +uncreate:
> +     while (--i) {
> +             bus_dmamap_destroy(sc->bge_dmatag,
> +                 sc->bge_cdata.bge_rx_jumbo_map[i]);
> +     }
> +     return (1);
> +}
> +
> +int
> +bge_init_rx_ring_jumbo(struct bge_softc *sc)
> +{
> +     volatile struct bge_rcb *rcb;
> +
> +     if (ISSET(sc->bge_flags, BGE_JUMBO_RXRING_VALID))
> +             return (0);
> +
>       sc->bge_jumbo = BGE_JUMBO_RX_RING_CNT - 1;
>       sc->bge_jumbo_cnt = 0;
>       bge_fill_rx_ring_jumbo(sc);
> @@ -1379,13 +1416,6 @@ bge_init_rx_ring_jumbo(struct bge_softc 
>       CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_MAXLEN_FLAGS, rcb->bge_maxlen_flags);
>  
>       return (0);
> -
> -uncreate:
> -     while (--i) {
> -             bus_dmamap_destroy(sc->bge_dmatag,
> -                 sc->bge_cdata.bge_rx_jumbo_map[i]);
> -     }
> -     return (1);
>  }
>  
>  void
> @@ -1420,6 +1450,21 @@ void
>  bge_free_rx_ring_jumbo(struct bge_softc *sc)
>  {
>       bus_dmamap_t dmap;
> +     int i;
> +
> +     for (i = 0; i < BGE_JUMBO_RX_RING_CNT; i++) {
> +             dmap = sc->bge_cdata.bge_rx_jumbo_map[i];
> +             bus_dmamap_destroy(sc->bge_dmatag, dmap);
> +             sc->bge_cdata.bge_rx_jumbo_map[i] = NULL;
> +             bzero(&sc->bge_rdata->bge_rx_jumbo_ring[i],
> +                 sizeof(struct bge_ext_rx_bd));
> +     }
> +}
> +
> +void
> +bge_drain_rx_ring_jumbo(struct bge_softc *sc)
> +{
> +     bus_dmamap_t dmap;
>       struct mbuf *m;
>       int i;
>  
> @@ -1436,20 +1481,15 @@ bge_free_rx_ring_jumbo(struct bge_softc 
>                       m_freem(m);
>                       sc->bge_cdata.bge_rx_jumbo_chain[i] = NULL;
>               }
> -             bus_dmamap_destroy(sc->bge_dmatag, dmap);
> -             sc->bge_cdata.bge_rx_jumbo_map[i] = NULL;
> -             bzero(&sc->bge_rdata->bge_rx_jumbo_ring[i],
> -                 sizeof(struct bge_ext_rx_bd));
>       }
>  
>       CLR(sc->bge_flags, BGE_JUMBO_RXRING_VALID);
>  }
>  
>  void
> -bge_free_tx_ring(struct bge_softc *sc)
> +bge_drain_tx_ring(struct bge_softc *sc)
>  {
>       int i;
> -     struct txdmamap_pool_entry *dma;
>  
>       if (!(sc->bge_flags & BGE_TXRING_VALID))
>               return;
> @@ -1466,39 +1506,28 @@ bge_free_tx_ring(struct bge_softc *sc)
>                   sizeof(struct bge_tx_bd));
>       }
>  
> +     sc->bge_flags &= ~BGE_TXRING_VALID;
> +}
> +
> +void
> +bge_free_tx_ring(struct bge_softc *sc)
> +{
> +     struct txdmamap_pool_entry *dma;
> +
>       while ((dma = SLIST_FIRST(&sc->txdma_list))) {
>               SLIST_REMOVE_HEAD(&sc->txdma_list, link);
>               bus_dmamap_destroy(sc->bge_dmatag, dma->dmamap);
>               free(dma, M_DEVBUF);
>       }
> -
> -     sc->bge_flags &= ~BGE_TXRING_VALID;
>  }
>  
>  int
> -bge_init_tx_ring(struct bge_softc *sc)
> +bge_alloc_tx_ring(struct bge_softc *sc)
>  {
>       int i;
>       bus_dmamap_t dmamap;
>       struct txdmamap_pool_entry *dma;
>  
> -     if (sc->bge_flags & BGE_TXRING_VALID)
> -             return (0);
> -
> -     sc->bge_txcnt = 0;
> -     sc->bge_tx_saved_considx = 0;
> -
> -     /* Initialize transmit producer index for host-memory send ring. */
> -     sc->bge_tx_prodidx = 0;
> -     bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, sc->bge_tx_prodidx);
> -     if (BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5700_BX)
> -             bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, sc->bge_tx_prodidx);
> -
> -     /* NIC-memory send ring not used; initialize to zero. */
> -     bge_writembx(sc, BGE_MBX_TX_NIC_PROD0_LO, 0);
> -     if (BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5700_BX)
> -             bge_writembx(sc, BGE_MBX_TX_NIC_PROD0_LO, 0);
> -
>       SLIST_INIT(&sc->txdma_list);
>       for (i = 0; i < BGE_TX_RING_CNT; i++) {
>               if (bus_dmamap_create(sc->bge_dmatag, BGE_JLEN,
> @@ -1506,7 +1535,7 @@ bge_init_tx_ring(struct bge_softc *sc)
>                   &dmamap))
>                       return (ENOBUFS);
>               if (dmamap == NULL)
> -                     panic("dmamap NULL in bge_init_tx_ring");
> +                     panic("dmamap NULL in %s", __func__);
>               dma = malloc(sizeof(*dma), M_DEVBUF, M_NOWAIT);
>               if (dma == NULL) {
>                       printf("%s: can't alloc txdmamap_pool_entry\n",
> @@ -1518,6 +1547,29 @@ bge_init_tx_ring(struct bge_softc *sc)
>               SLIST_INSERT_HEAD(&sc->txdma_list, dma, link);
>       }
>  
> +     return (0);
> +}
> +
> +int
> +bge_init_tx_ring(struct bge_softc *sc)
> +{
> +     if (sc->bge_flags & BGE_TXRING_VALID)
> +             return (0);
> +
> +     sc->bge_txcnt = 0;
> +     sc->bge_tx_saved_considx = 0;
> +
> +     /* Initialize transmit producer index for host-memory send ring. */
> +     sc->bge_tx_prodidx = 0;
> +     bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, sc->bge_tx_prodidx);
> +     if (BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5700_BX)
> +             bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, sc->bge_tx_prodidx);
> +
> +     /* NIC-memory send ring not used; initialize to zero. */
> +     bge_writembx(sc, BGE_MBX_TX_NIC_PROD0_LO, 0);
> +     if (BGE_CHIPREV(sc->bge_chipid) == BGE_CHIPREV_5700_BX)
> +             bge_writembx(sc, BGE_MBX_TX_NIC_PROD0_LO, 0);
> +
>       sc->bge_flags |= BGE_TXRING_VALID;
>  
>       return (0);
> @@ -3077,6 +3129,15 @@ bge_attach(struct device *parent, struct
>               goto fail_6;
>       }
>  
> +     if (bge_alloc_rx_ring_std(sc))
> +             goto fail_6;
> +
> +     if (BGE_IS_JUMBO_CAPABLE(sc) && bge_alloc_rx_ring_jumbo(sc))
> +             goto fail_7;
> +
> +     if (bge_alloc_tx_ring(sc))
> +             goto fail_8;
> +
>       /*
>        * A Broadcom chip was detected. Inform the world.
>        */
> @@ -3127,6 +3188,15 @@ bge_attach(struct device *parent, struct
>       timeout_set(&sc->bge_rxtimeout, bge_rxtick, sc);
>       return;
>  
> +fail_8:
> +     bge_free_tx_ring(sc);
> +
> +     if (BGE_IS_JUMBO_CAPABLE(sc))
> +             bge_free_rx_ring_jumbo(sc);
> +
> +fail_7:
> +     bge_free_rx_ring_std(sc);
> +
>  fail_6:
>       bus_dmamap_unload(sc->bge_dmatag, sc->bge_ring_map);
>  
> @@ -4586,15 +4656,15 @@ bge_stop(struct bge_softc *sc)
>        */
>       BGE_CLRBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP);
>  
> -     /* Free the RX lists. */
> -     bge_free_rx_ring_std(sc);
> +     /* Drain the RX lists. */
> +     bge_drain_rx_ring_std(sc);
>  
> -     /* Free jumbo RX list. */
> +     /* Drain jumbo RX list. */
>       if (BGE_IS_JUMBO_CAPABLE(sc))
> -             bge_free_rx_ring_jumbo(sc);
> +             bge_drain_rx_ring_jumbo(sc);
>  
> -     /* Free TX buffers. */
> -     bge_free_tx_ring(sc);
> +     /* Drain TX buffers. */
> +     bge_drain_tx_ring(sc);
>  
>       /*
>        * Isolate/power down the PHY, but leave the media selection
> 
> 

Reply via email to