summaryrefslogtreecommitdiffstats
path: root/sys/dev/ixl/ixl_txrx.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ixl/ixl_txrx.c')
-rw-r--r--sys/dev/ixl/ixl_txrx.c73
1 files changed, 35 insertions, 38 deletions
diff --git a/sys/dev/ixl/ixl_txrx.c b/sys/dev/ixl/ixl_txrx.c
index 5cf54fa..b329dc4 100644
--- a/sys/dev/ixl/ixl_txrx.c
+++ b/sys/dev/ixl/ixl_txrx.c
@@ -217,22 +217,27 @@ static inline bool
ixl_tso_detect_sparse(struct mbuf *mp)
{
struct mbuf *m;
- int num = 0, mss;
- bool ret = FALSE;
+ int num, mss;
+ num = 0;
mss = mp->m_pkthdr.tso_segsz;
+
+ /* Exclude first mbuf; assume it contains all headers */
for (m = mp->m_next; m != NULL; m = m->m_next) {
- num++;
- mss -= m->m_len;
- if (mss < 1)
- break;
- if (m->m_next == NULL)
+ if (m == NULL)
break;
+ num++;
+ mss -= m->m_len % mp->m_pkthdr.tso_segsz;
+
+ if (mss < 1) {
+ if (num > IXL_SPARSE_CHAIN)
+ return (true);
+ num = (mss == 0) ? 0 : 1;
+ mss += mp->m_pkthdr.tso_segsz;
+ }
}
- if (num > IXL_SPARSE_CHAIN)
- ret = TRUE;
- return (ret);
+ return (false);
}
@@ -311,18 +316,12 @@ ixl_xmit(struct ixl_queue *que, struct mbuf **m_headp)
error = bus_dmamap_load_mbuf_sg(tag, map,
*m_headp, segs, &nsegs, BUS_DMA_NOWAIT);
- if (error == ENOMEM) {
- que->tx_dmamap_failed++;
- return (error);
- } else if (error != 0) {
+ if (error != 0) {
que->tx_dmamap_failed++;
m_freem(*m_headp);
*m_headp = NULL;
return (error);
}
- } else if (error == ENOMEM) {
- que->tx_dmamap_failed++;
- return (error);
} else if (error != 0) {
que->tx_dmamap_failed++;
m_freem(*m_headp);
@@ -403,8 +402,7 @@ ixl_xmit(struct ixl_queue *que, struct mbuf **m_headp)
wr32(hw, txr->tail, i);
/* Mark outstanding work */
- if (que->busy == 0)
- que->busy = 1;
+ atomic_store_rel_32(&txr->watchdog_timer, IXL_WATCHDOG);
return (0);
xmit_fail:
@@ -523,12 +521,14 @@ ixl_init_tx_ring(struct ixl_queue *que)
txr->next_avail = 0;
txr->next_to_clean = 0;
+ /* Reset watchdog status */
+ txr->watchdog_timer = 0;
+
#ifdef IXL_FDIR
/* Initialize flow director */
txr->atr_rate = ixl_atr_rate;
txr->atr_count = 0;
#endif
-
/* Free any existing tx mbufs. */
buf = txr->buffers;
for (int i = 0; i < que->num_desc; i++, buf++) {
@@ -817,7 +817,11 @@ ixl_tso_setup(struct ixl_queue *que, struct mbuf *mp)
type = I40E_TX_DESC_DTYPE_CONTEXT;
cmd = I40E_TX_CTX_DESC_TSO;
- /* ERJ: this must not be less than 64 */
+ /* TSO MSS must not be less than 64 */
+ if (mp->m_pkthdr.tso_segsz < IXL_MIN_TSO_MSS) {
+ que->mss_too_small++;
+ mp->m_pkthdr.tso_segsz = IXL_MIN_TSO_MSS;
+ }
mss = mp->m_pkthdr.tso_segsz;
type_cmd_tso_mss = ((u64)type << I40E_TXD_CTX_QW1_DTYPE_SHIFT) |
@@ -877,7 +881,7 @@ ixl_txeof(struct ixl_queue *que)
/* These are not the descriptors you seek, move along :) */
if (txr->avail == que->num_desc) {
- que->busy = 0;
+ atomic_store_rel_32(&txr->watchdog_timer, 0);
return FALSE;
}
@@ -956,25 +960,10 @@ ixl_txeof(struct ixl_queue *que)
/*
- ** Hang detection, we know there's
- ** work outstanding or the first return
- ** would have been taken, so indicate an
- ** unsuccessful pass, in local_timer if
- ** the value is too great the queue will
- ** be considered hung. If anything has been
- ** cleaned then reset the state.
- */
- if ((processed == 0) && (que->busy != IXL_QUEUE_HUNG))
- ++que->busy;
-
- if (processed)
- que->busy = 1; /* Note this turns off HUNG */
-
- /*
* If there are no pending descriptors, clear the timeout.
*/
if (txr->avail == que->num_desc) {
- que->busy = 0;
+ atomic_store_rel_32(&txr->watchdog_timer, 0);
return FALSE;
}
@@ -1752,8 +1741,16 @@ next_desc:
/*
* Flush any outstanding LRO work
*/
+#if __FreeBSD_version >= 1100105
tcp_lro_flush_all(lro);
+#else
+ struct lro_entry *queued;
+ while ((queued = SLIST_FIRST(&lro->lro_active)) != NULL) {
+ SLIST_REMOVE_HEAD(&lro->lro_active, next);
+ tcp_lro_flush(lro, queued);
+ }
#endif
+#endif /* defined(INET6) || defined(INET) */
IXL_RX_UNLOCK(rxr);
return (FALSE);
OpenPOWER on IntegriCloud