diff options
author | davidcs <davidcs@FreeBSD.org> | 2017-09-26 21:18:43 +0000 |
---|---|---|
committer | davidcs <davidcs@FreeBSD.org> | 2017-09-26 21:18:43 +0000 |
commit | cdfc7dbe7c904b06c48d3cd59fb0987cd565ffeb (patch) | |
tree | 07cef549c0c34b14a8e7f2fea3f4ec33f8cc427d | |
parent | 961709dc6d81de5d31d7d27b1a291e13cce47d3a (diff) | |
download | FreeBSD-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.c | 2 | ||||
-rw-r--r-- | sys/dev/qlxgbe/ql_os.c | 21 |
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__)); } |