diff options
author | Brad Smith <brad@cvs.openbsd.org> | 2015-02-11 21:36:03 +0000 |
---|---|---|
committer | Brad Smith <brad@cvs.openbsd.org> | 2015-02-11 21:36:03 +0000 |
commit | 9b370c1f48bb430ca3516e17c24305a242ec7297 (patch) | |
tree | 11f3c70856be1b698ee18ed0a88ea2bc305e22fe /sys | |
parent | cb9b009251a7dbb748867c4252f03fe11242dd57 (diff) |
- Make use of m_defrag().
- Lower the max # of TX DMA segments from close to the whole ring down
to a more sensible value. From FreeBSD
- Move the TX ring full check out of and above the for loop.
- Use dm_nsegs to provide the total # of DMA segments instead of the
value from the for loop.
ok mikeb@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pci/if_sis.c | 35 | ||||
-rw-r--r-- | sys/dev/pci/if_sisreg.h | 3 |
2 files changed, 28 insertions, 10 deletions
diff --git a/sys/dev/pci/if_sis.c b/sys/dev/pci/if_sis.c index e1991124338..8e1b70d84ad 100644 --- a/sys/dev/pci/if_sis.c +++ b/sys/dev/pci/if_sis.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_sis.c,v 1.122 2015/01/06 04:05:43 brad Exp $ */ +/* $OpenBSD: if_sis.c,v 1.123 2015/02/11 21:36:02 brad Exp $ */ /* * Copyright (c) 1997, 1998, 1999 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. @@ -1168,13 +1168,13 @@ sis_attach(struct device *parent, struct device *self, void *aux) for (i = 0; i < SIS_TX_LIST_CNT; i++) { if (bus_dmamap_create(sc->sc_dmat, MCLBYTES, - SIS_TX_LIST_CNT - 3, MCLBYTES, 0, BUS_DMA_NOWAIT, + SIS_MAXTXSEGS, MCLBYTES, 0, BUS_DMA_NOWAIT, &sc->sis_ldata->sis_tx_list[i].map) != 0) { printf(": can't create tx map\n"); goto fail_2; } } - if (bus_dmamap_create(sc->sc_dmat, MCLBYTES, SIS_TX_LIST_CNT - 3, + if (bus_dmamap_create(sc->sc_dmat, MCLBYTES, SIS_MAXTXSEGS, MCLBYTES, 0, BUS_DMA_NOWAIT, &sc->sc_tx_sparemap) != 0) { printf(": can't create tx spare map\n"); goto fail_2; @@ -1598,13 +1598,32 @@ int sis_encap(struct sis_softc *sc, struct mbuf *m_head, u_int32_t *txidx) { struct sis_desc *f = NULL; - int frag, cur, i; bus_dmamap_t map; + int frag, cur, i, error; map = sc->sc_tx_sparemap; - if (bus_dmamap_load_mbuf(sc->sc_dmat, map, - m_head, BUS_DMA_NOWAIT) != 0) + + error = bus_dmamap_load_mbuf(sc->sc_dmat, map, m_head, + BUS_DMA_NOWAIT); + switch (error) { + case 0: + break; + + case EFBIG: + if (m_defrag(m_head, M_DONTWAIT) == 0 && + bus_dmamap_load_mbuf(sc->sc_dmat, map, m_head, + BUS_DMA_NOWAIT) == 0) + break; + + /* FALLTHROUGH */ + default: return (ENOBUFS); + } + + if ((SIS_TX_LIST_CNT - (sc->sis_cdata.sis_tx_cnt + map->dm_nsegs)) < 2) { + bus_dmamap_unload(sc->sc_dmat, map); + return (ENOBUFS); + } /* * Start packing the mbufs in this chain into @@ -1614,8 +1633,6 @@ sis_encap(struct sis_softc *sc, struct mbuf *m_head, u_int32_t *txidx) cur = frag = *txidx; for (i = 0; i < map->dm_nsegs; i++) { - if ((SIS_TX_LIST_CNT - (sc->sis_cdata.sis_tx_cnt + i)) < 2) - return(ENOBUFS); f = &sc->sis_ldata->sis_tx_list[frag]; f->sis_ctl = htole32(SIS_CMDSTS_MORE | map->dm_segs[i].ds_len); f->sis_ptr = htole32(map->dm_segs[i].ds_addr); @@ -1631,7 +1648,7 @@ sis_encap(struct sis_softc *sc, struct mbuf *m_head, u_int32_t *txidx) sc->sis_ldata->sis_tx_list[cur].sis_mbuf = m_head; sc->sis_ldata->sis_tx_list[cur].sis_ctl &= ~htole32(SIS_CMDSTS_MORE); sc->sis_ldata->sis_tx_list[*txidx].sis_ctl |= htole32(SIS_CMDSTS_OWN); - sc->sis_cdata.sis_tx_cnt += i; + sc->sis_cdata.sis_tx_cnt += map->dm_nsegs; *txidx = frag; bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap, diff --git a/sys/dev/pci/if_sisreg.h b/sys/dev/pci/if_sisreg.h index 6e54e88634f..9d9074e28fe 100644 --- a/sys/dev/pci/if_sisreg.h +++ b/sys/dev/pci/if_sisreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_sisreg.h,v 1.33 2014/07/08 05:35:18 dlg Exp $ */ +/* $OpenBSD: if_sisreg.h,v 1.34 2015/02/11 21:36:02 brad Exp $ */ /* * Copyright (c) 1997, 1998, 1999 * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved. @@ -376,6 +376,7 @@ struct sis_desc { #define SIS_TXSTAT_UNDERRUN 0x02000000 #define SIS_TXSTAT_TX_ABORT 0x04000000 +#define SIS_MAXTXSEGS 16 #define SIS_RX_LIST_CNT 64 #define SIS_TX_LIST_CNT 128 |