summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjmatthew <jmatthew@openbsd.org>2016-05-05 23:01:28 +0000
committerjmatthew <jmatthew@openbsd.org>2016-05-05 23:01:28 +0000
commit7edf5b0a3ee7fbef82e4e72869c50cbf1da9d652 (patch)
treed86340289e3bdbfdfbb55fdb93e08dfd2ca24cbf
parentshow what we're doing when reordering libraries, otherwise the text (diff)
downloadwireguard-openbsd-7edf5b0a3ee7fbef82e4e72869c50cbf1da9d652.tar.xz
wireguard-openbsd-7edf5b0a3ee7fbef82e4e72869c50cbf1da9d652.zip
r1.10 of if_bnx.c effectively removed the limit on the number of segments in
the tx dma maps, apparently to allow heavily fragmented packets to be sent. The tx ring accounting in bnx_start assumed that the longest fragment chain we'd see was BNX_MAX_SEGMENTS, so sending a heavily fragmented packet when the ring was already full could cause it to overflow. In the 10 years since r1.10, we've started defragmenting packets if they won't fit in the dma map, so we can limit the maps to BNX_MAX_SEGMENTS again. While we're here, ensure there's always at least one slot on the tx ring free, for consistency between drivers. Fixes packet corruption seen by otto@ ok mpi@ dlg@
-rw-r--r--sys/dev/pci/if_bnx.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/sys/dev/pci/if_bnx.c b/sys/dev/pci/if_bnx.c
index e1e4d030c74..8b3267adb14 100644
--- a/sys/dev/pci/if_bnx.c
+++ b/sys/dev/pci/if_bnx.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bnx.c,v 1.121 2016/04/13 10:34:32 mpi Exp $ */
+/* $OpenBSD: if_bnx.c,v 1.122 2016/05/05 23:01:28 jmatthew Exp $ */
/*-
* Copyright (c) 2006 Broadcom Corporation
@@ -2417,7 +2417,7 @@ bnx_dma_alloc(struct bnx_softc *sc)
*/
for (i = 0; i < TOTAL_TX_BD; i++) {
if (bus_dmamap_create(sc->bnx_dmatag,
- MCLBYTES * BNX_MAX_SEGMENTS, USABLE_TX_BD,
+ MCLBYTES * BNX_MAX_SEGMENTS, BNX_MAX_SEGMENTS,
MCLBYTES, 0, BUS_DMA_NOWAIT, &sc->tx_mbuf_map[i])) {
printf(": Could not create Tx mbuf %d DMA map!\n", 1);
rc = ENOMEM;
@@ -4892,7 +4892,8 @@ bnx_start(struct ifnet *ifp)
*/
used = 0;
while (1) {
- if (sc->used_tx_bd + used + BNX_MAX_SEGMENTS >= sc->max_tx_bd) {
+ if (sc->used_tx_bd + used + BNX_MAX_SEGMENTS + 1 >=
+ sc->max_tx_bd) {
DBPRINT(sc, BNX_INFO_SEND, "TX chain is closed for "
"business! Total tx_bd used = %d\n",
sc->used_tx_bd + used);