summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordavidcs <davidcs@FreeBSD.org>2017-09-26 21:18:43 +0000
committerdavidcs <davidcs@FreeBSD.org>2017-09-26 21:18:43 +0000
commitcdfc7dbe7c904b06c48d3cd59fb0987cd565ffeb (patch)
tree07cef549c0c34b14a8e7f2fea3f4ec33f8cc427d
parent961709dc6d81de5d31d7d27b1a291e13cce47d3a (diff)
downloadFreeBSD-src-cdfc7dbe7c904b06c48d3cd59fb0987cd565ffeb.zip
FreeBSD-src-cdfc7dbe7c904b06c48d3cd59fb0987cd565ffeb.tar.gz
MFC r323824
1. ql_hw.c: In ql_hw_send() return EINVAL when TSO framelength exceeds max supported length by HW.(davidcs) 2. ql_os.c: In qla_send() call bus_dmamap_unload before freeing mbuf or recreating dmmamap.(davidcs) In qla_fp_taskqueue() Add additional checks for IFF_DRV_RUNNING Fix qla_clear_tx_buf() call bus_dmamap_sync() before freeing mbuf. Submitted by: David.Bachu@netapp.com
-rw-r--r--sys/dev/qlxgbe/ql_hw.c2
-rw-r--r--sys/dev/qlxgbe/ql_os.c21
2 files changed, 19 insertions, 4 deletions
diff --git a/sys/dev/qlxgbe/ql_hw.c b/sys/dev/qlxgbe/ql_hw.c
index 607f6c6..9a5ee20 100644
--- a/sys/dev/qlxgbe/ql_hw.c
+++ b/sys/dev/qlxgbe/ql_hw.c
@@ -2324,7 +2324,7 @@ ql_hw_send(qla_host_t *ha, bus_dma_segment_t *segs, int nsegs,
if (total_length > QLA_MAX_TSO_FRAME_SIZE) {
device_printf(dev, "%s: total length exceeds maxlen(%d)\n",
__func__, total_length);
- return (-1);
+ return (EINVAL);
}
eh = mtod(mp, struct ether_vlan_header *);
diff --git a/sys/dev/qlxgbe/ql_os.c b/sys/dev/qlxgbe/ql_os.c
index 20ee66f..7608e44 100644
--- a/sys/dev/qlxgbe/ql_os.c
+++ b/sys/dev/qlxgbe/ql_os.c
@@ -1292,6 +1292,7 @@ qla_send(qla_host_t *ha, struct mbuf **m_headp, uint32_t txr_idx,
ha->tx_ring[txr_idx].iscsi_pkt_count++;
ha->tx_ring[txr_idx].tx_buf[tx_idx].m_head = m_head;
} else {
+ bus_dmamap_unload(ha->tx_tag, map);
if (ret == EINVAL) {
if (m_head)
m_freem(m_head);
@@ -1377,7 +1378,8 @@ qla_fp_taskqueue(void *context, int pending)
goto qla_fp_taskqueue_exit;
}
- while (rx_pkts_left && !ha->stop_rcv) {
+ while (rx_pkts_left && !ha->stop_rcv &&
+ (ifp->if_drv_flags & IFF_DRV_RUNNING)) {
rx_pkts_left = ql_rcv_isr(ha, fp->txr_idx, 64);
#ifdef QL_ENABLE_ISCSI_TLV
@@ -1420,6 +1422,11 @@ qla_fp_taskqueue(void *context, int pending)
drbr_advance(ifp, fp->tx_br);
}
+ /* Send a copy of the frame to the BPF listener */
+ ETHER_BPF_MTAP(ifp, mp);
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ break;
+
mp = drbr_peek(ifp, fp->tx_br);
}
}
@@ -1682,16 +1689,24 @@ qla_clear_tx_buf(qla_host_t *ha, qla_tx_buf_t *txb)
{
QL_DPRINT2(ha, (ha->pci_dev, "%s: enter\n", __func__));
- if (txb->m_head && txb->map) {
+ if (txb->m_head) {
+ bus_dmamap_sync(ha->tx_tag, txb->map,
+ BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(ha->tx_tag, txb->map);
m_freem(txb->m_head);
txb->m_head = NULL;
+
+ bus_dmamap_destroy(ha->tx_tag, txb->map);
+ txb->map = NULL;
}
- if (txb->map)
+ if (txb->map) {
+ bus_dmamap_unload(ha->tx_tag, txb->map);
bus_dmamap_destroy(ha->tx_tag, txb->map);
+ txb->map = NULL;
+ }
QL_DPRINT2(ha, (ha->pci_dev, "%s: exit\n", __func__));
}
OpenPOWER on IntegriCloud