summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/pci/if_ix.c64
-rw-r--r--sys/dev/pci/if_ix.h4
2 files changed, 22 insertions, 46 deletions
diff --git a/sys/dev/pci/if_ix.c b/sys/dev/pci/if_ix.c
index c8f0ea399e1..7621a85bacb 100644
--- a/sys/dev/pci/if_ix.c
+++ b/sys/dev/pci/if_ix.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ix.c,v 1.130 2015/12/18 22:47:18 kettenis Exp $ */
+/* $OpenBSD: if_ix.c,v 1.131 2015/12/31 19:07:37 kettenis Exp $ */
/******************************************************************************
@@ -376,28 +376,21 @@ ixgbe_start(struct ifnet * ifp)
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
for (;;) {
- m_head = ifq_deq_begin(&ifp->if_snd);
+ /* Check that we have the minimal number of TX descriptors. */
+ if (txr->tx_avail <= IXGBE_TX_OP_THRESHOLD) {
+ ifq_set_oactive(&ifp->if_snd);
+ break;
+ }
+
+ m_head = ifq_dequeue(&ifp->if_snd);
if (m_head == NULL)
break;
if (ixgbe_encap(txr, m_head)) {
- ifq_deq_rollback(&ifp->if_snd, m_head);
- ifq_set_oactive(&ifp->if_snd);
- /*
- * Make sure there are still packets on the
- * ring. The interrupt handler may have
- * cleaned up the ring before we were able to
- * set the IF_OACTIVE flag.
- */
- if (txr->tx_avail == sc->num_tx_desc) {
- ifq_clr_oactive(&ifp->if_snd);
- continue;
- }
- break;
+ m_freem(m_head);
+ continue;
}
- ifq_deq_commit(&ifp->if_snd, m_head);
-
#if NBPFILTER > 0
if (ifp->if_bpf)
bpf_mtap_ether(ifp->if_bpf, m_head, BPF_DIRECTION_OUT);
@@ -894,9 +887,8 @@ ixgbe_intr(void *arg)
if (reg_eicr & IXGBE_EICR_LSC) {
KERNEL_LOCK();
ixgbe_update_link_status(sc);
- if (!IFQ_IS_EMPTY(&ifp->if_snd))
- ixgbe_start(ifp);
KERNEL_UNLOCK();
+ ifq_start(&ifp->if_snd);
}
/* ... more link status change */
@@ -1059,10 +1051,6 @@ ixgbe_encap(struct tx_ring *txr, struct mbuf *m_head)
cmd_type_len |= IXGBE_ADVTXD_DCMD_VLE;
#endif
- /* Check that we have least the minimal number of TX descriptors. */
- if (txr->tx_avail <= IXGBE_TX_OP_THRESHOLD)
- return (ENOBUFS);
-
/*
* Important to capture the first descriptor
* used because it will contain the index of
@@ -1092,10 +1080,7 @@ ixgbe_encap(struct tx_ring *txr, struct mbuf *m_head)
}
/* Make certain there are enough descriptors */
- if (map->dm_nsegs > txr->tx_avail - 2) {
- error = ENOBUFS;
- goto xmit_fail;
- }
+ KASSERT(map->dm_nsegs <= txr->tx_avail - 2);
/*
* Set the appropriate offload context
@@ -1153,7 +1138,6 @@ ixgbe_encap(struct tx_ring *txr, struct mbuf *m_head)
xmit_fail:
bus_dmamap_unload(txr->txdma.dma_tag, txbuf->map);
return (error);
-
}
void
@@ -1296,7 +1280,6 @@ ixgbe_stop(void *arg)
/* Tell the stack that the interface is no longer active */
ifp->if_flags &= ~IFF_RUNNING;
- ifq_clr_oactive(&ifp->if_snd);
INIT_DEBUGOUT("ixgbe_stop: begin\n");
ixgbe_disable_intr(sc);
@@ -1315,10 +1298,13 @@ ixgbe_stop(void *arg)
/* reprogram the RAR[0] in case user changed it. */
ixgbe_set_rar(&sc->hw, 0, sc->hw.mac.addr, 0, IXGBE_RAH_AV);
+ ifq_barrier(&ifp->if_snd);
intr_barrier(sc->tag);
KASSERT((ifp->if_flags & IFF_RUNNING) == 0);
+ ifq_clr_oactive(&ifp->if_snd);
+
/* Should we really clear all structures on stop? */
ixgbe_free_transmit_structures(sc);
ixgbe_free_receive_structures(sc);
@@ -1389,11 +1375,9 @@ ixgbe_identify_hardware(struct ix_softc *sc)
}
/* Pick up the 82599 and VF settings */
- if (sc->hw.mac.type != ixgbe_mac_82598EB) {
+ if (sc->hw.mac.type != ixgbe_mac_82598EB)
sc->hw.phy.smart_speed = ixgbe_smart_speed;
- sc->num_segs = IXGBE_82599_SCATTER;
- } else
- sc->num_segs = IXGBE_82598_SCATTER;
+ sc->num_segs = IXGBE_82599_SCATTER;
}
/*********************************************************************
@@ -1547,6 +1531,7 @@ ixgbe_setup_interface(struct ix_softc *sc)
strlcpy(ifp->if_xname, sc->dev.dv_xname, IFNAMSIZ);
ifp->if_softc = sc;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+ ifp->if_xflags = IFXF_MPSAFE;
ifp->if_ioctl = ixgbe_ioctl;
ifp->if_start = ixgbe_start;
ifp->if_timer = 0;
@@ -2439,17 +2424,8 @@ ixgbe_txeof(struct tx_ring *txr)
if (num_avail == sc->num_tx_desc)
ifp->if_timer = 0;
- /*
- * If we have enough room, clear IFF_OACTIVE to tell the stack that
- * it is OK to send packets.
- */
- if (ifq_is_oactive(&ifp->if_snd) &&
- num_avail > IXGBE_TX_OP_THRESHOLD) {
- ifq_clr_oactive(&ifp->if_snd);
- KERNEL_LOCK();
- ixgbe_start(ifp);
- KERNEL_UNLOCK();
- }
+ if (ifq_is_oactive(&ifp->if_snd))
+ ifq_restart(&ifp->if_snd);
return TRUE;
}
diff --git a/sys/dev/pci/if_ix.h b/sys/dev/pci/if_ix.h
index 0c11746a80c..28c044c33db 100644
--- a/sys/dev/pci/if_ix.h
+++ b/sys/dev/pci/if_ix.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ix.h,v 1.30 2015/12/18 19:08:36 kettenis Exp $ */
+/* $OpenBSD: if_ix.h,v 1.31 2015/12/31 19:07:37 kettenis Exp $ */
/******************************************************************************
@@ -80,7 +80,7 @@
* Thise parameter controls the minimum number of available transmit
* descriptors needed before we attempt transmission of a packet.
*/
-#define IXGBE_TX_OP_THRESHOLD (sc->num_tx_desc / 32)
+#define IXGBE_TX_OP_THRESHOLD (sc->num_segs + 2)
#define IXGBE_MAX_FRAME_SIZE 9216