aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/ixl/ixl_txrx.c
diff options
context:
space:
mode:
authorEric Joyner <erj@FreeBSD.org>2017-02-10 01:04:11 +0000
committerEric Joyner <erj@FreeBSD.org>2017-02-10 01:04:11 +0000
commitcb6b8299fdda0ccd5c9c9b0d29cd9c005f6d780b (patch)
tree3179310eb492a68ec5315d5970f3ed824adc1dca /sys/dev/ixl/ixl_txrx.c
parente628e1b919cbfce77767eb2e6e91c917250d09bf (diff)
downloadsrc-cb6b8299fdda0ccd5c9c9b0d29cd9c005f6d780b.tar.gz
src-cb6b8299fdda0ccd5c9c9b0d29cd9c005f6d780b.zip
ixl(4): Update to 1.7.12-k
Refresh upstream driver before impending conversion to iflib. Major new features: - Support for Fortville-based 25G adapters - Support for I2C reads/writes (To prevent getting or sending corrupt data, you should set dev.ixl.0.debug.disable_fw_link_management=1 when using I2C [this will disable link!], then set it to 0 when done. The driver implements the SIOCGI2C ioctl, so ifconfig -v works for reading I2C data, but there are read_i2c and write_i2c sysctls under the .debug sysctl tree [the latter being useful for upper page support in QSFP+]). - Addition of an iWARP client interface (so the future iWARP driver for X722 devices can communicate with the base driver). - Compiling this option in is enabled by default, with "options IXL_IW" in GENERIC. Differential Revision: https://reviews.freebsd.org/D9227 Reviewed by: sbruno MFC after: 2 weeks Sponsored by: Intel Corporation
Notes
Notes: svn path=/head/; revision=313497
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 9a7fae3b055f..7e168dd511bd 100644
--- a/sys/dev/ixl/ixl_txrx.c
+++ b/sys/dev/ixl/ixl_txrx.c
@@ -218,22 +218,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);
}
@@ -312,18 +317,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);
@@ -404,8 +403,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:
@@ -524,12 +522,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++) {
@@ -818,7 +818,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) |
@@ -878,7 +882,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;
}
@@ -957,25 +961,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;
}
@@ -1753,8 +1742,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);