| @@ -49,27 +49,27 @@ | | | @@ -49,27 +49,27 @@ |
49 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | | 49 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
50 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | | 50 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
51 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 51 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
52 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 52 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
53 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 53 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
54 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 54 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
55 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 55 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
56 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 56 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
57 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 57 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
58 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 58 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
59 | * POSSIBILITY OF SUCH DAMAGE. | | 59 | * POSSIBILITY OF SUCH DAMAGE. |
60 | */ | | 60 | */ |
61 | /*$FreeBSD: head/sys/dev/ixgbe/ix_txrx.c 301538 2016-06-07 04:51:50Z sephe $*/ | | 61 | /*$FreeBSD: head/sys/dev/ixgbe/ix_txrx.c 301538 2016-06-07 04:51:50Z sephe $*/ |
62 | /*$NetBSD: ix_txrx.c,v 1.26 2017/06/13 09:35:12 msaitoh Exp $*/ | | 62 | /*$NetBSD: ix_txrx.c,v 1.27 2017/06/13 09:37:22 msaitoh Exp $*/ |
63 | | | 63 | |
64 | #include "opt_inet.h" | | 64 | #include "opt_inet.h" |
65 | #include "opt_inet6.h" | | 65 | #include "opt_inet6.h" |
66 | | | 66 | |
67 | #include "ixgbe.h" | | 67 | #include "ixgbe.h" |
68 | | | 68 | |
69 | #ifdef DEV_NETMAP | | 69 | #ifdef DEV_NETMAP |
70 | #include <net/netmap.h> | | 70 | #include <net/netmap.h> |
71 | #include <sys/selinfo.h> | | 71 | #include <sys/selinfo.h> |
72 | #include <dev/netmap/netmap_kern.h> | | 72 | #include <dev/netmap/netmap_kern.h> |
73 | | | 73 | |
74 | extern int ix_crcstrip; | | 74 | extern int ix_crcstrip; |
75 | #endif | | 75 | #endif |
| @@ -1436,41 +1436,30 @@ ixgbe_allocate_receive_buffers(struct rx | | | @@ -1436,41 +1436,30 @@ ixgbe_allocate_receive_buffers(struct rx |
1436 | } | | 1436 | } |
1437 | } | | 1437 | } |
1438 | | | 1438 | |
1439 | return (0); | | 1439 | return (0); |
1440 | | | 1440 | |
1441 | fail: | | 1441 | fail: |
1442 | /* Frees all, but can handle partial completion */ | | 1442 | /* Frees all, but can handle partial completion */ |
1443 | ixgbe_free_receive_structures(adapter); | | 1443 | ixgbe_free_receive_structures(adapter); |
1444 | return (error); | | 1444 | return (error); |
1445 | } | | 1445 | } |
1446 | | | 1446 | |
1447 | static void | | 1447 | static void |
1448 | ixgbe_free_receive_ring(struct rx_ring *rxr) | | 1448 | ixgbe_free_receive_ring(struct rx_ring *rxr) |
1449 | { | | 1449 | { |
1450 | struct ixgbe_rx_buf *rxbuf; | | | |
1451 | | | 1450 | |
1452 | for (int i = 0; i < rxr->num_desc; i++) { | | 1451 | for (int i = 0; i < rxr->num_desc; i++) { |
1453 | rxbuf = &rxr->rx_buffers[i]; | | 1452 | ixgbe_rx_discard(rxr, i); |
1454 | if (rxbuf->buf != NULL) { | | | |
1455 | bus_dmamap_sync(rxr->ptag->dt_dmat, rxbuf->pmap, | | | |
1456 | 0, rxbuf->buf->m_pkthdr.len, | | | |
1457 | BUS_DMASYNC_POSTREAD); | | | |
1458 | ixgbe_dmamap_unload(rxr->ptag, rxbuf->pmap); | | | |
1459 | rxbuf->buf->m_flags |= M_PKTHDR; | | | |
1460 | m_freem(rxbuf->buf); | | | |
1461 | rxbuf->buf = NULL; | | | |
1462 | rxbuf->flags = 0; | | | |
1463 | } | | | |
1464 | } | | 1453 | } |
1465 | } | | 1454 | } |
1466 | | | 1455 | |
1467 | /********************************************************************* | | 1456 | /********************************************************************* |
1468 | * | | 1457 | * |
1469 | * Initialize a receive ring and its buffers. | | 1458 | * Initialize a receive ring and its buffers. |
1470 | * | | 1459 | * |
1471 | **********************************************************************/ | | 1460 | **********************************************************************/ |
1472 | static int | | 1461 | static int |
1473 | ixgbe_setup_receive_ring(struct rx_ring *rxr) | | 1462 | ixgbe_setup_receive_ring(struct rx_ring *rxr) |
1474 | { | | 1463 | { |
1475 | struct adapter *adapter; | | 1464 | struct adapter *adapter; |
1476 | struct ixgbe_rx_buf *rxbuf; | | 1465 | struct ixgbe_rx_buf *rxbuf; |
| @@ -1622,27 +1611,29 @@ ixgbe_setup_receive_structures(struct ad | | | @@ -1622,27 +1611,29 @@ ixgbe_setup_receive_structures(struct ad |
1622 | for (j = 0; j < adapter->num_queues; j++, rxr++) | | 1611 | for (j = 0; j < adapter->num_queues; j++, rxr++) |
1623 | if (ixgbe_setup_receive_ring(rxr)) | | 1612 | if (ixgbe_setup_receive_ring(rxr)) |
1624 | goto fail; | | 1613 | goto fail; |
1625 | | | 1614 | |
1626 | return (0); | | 1615 | return (0); |
1627 | fail: | | 1616 | fail: |
1628 | /* | | 1617 | /* |
1629 | * Free RX buffers allocated so far, we will only handle | | 1618 | * Free RX buffers allocated so far, we will only handle |
1630 | * the rings that completed, the failing case will have | | 1619 | * the rings that completed, the failing case will have |
1631 | * cleaned up for itself. 'j' failed, so its the terminus. | | 1620 | * cleaned up for itself. 'j' failed, so its the terminus. |
1632 | */ | | 1621 | */ |
1633 | for (int i = 0; i < j; ++i) { | | 1622 | for (int i = 0; i < j; ++i) { |
1634 | rxr = &adapter->rx_rings[i]; | | 1623 | rxr = &adapter->rx_rings[i]; |
| | | 1624 | IXGBE_RX_LOCK(rxr); |
1635 | ixgbe_free_receive_ring(rxr); | | 1625 | ixgbe_free_receive_ring(rxr); |
| | | 1626 | IXGBE_RX_UNLOCK(rxr); |
1636 | } | | 1627 | } |
1637 | | | 1628 | |
1638 | return (ENOBUFS); | | 1629 | return (ENOBUFS); |
1639 | } | | 1630 | } |
1640 | | | 1631 | |
1641 | | | 1632 | |
1642 | /********************************************************************* | | 1633 | /********************************************************************* |
1643 | * | | 1634 | * |
1644 | * Free all receive rings. | | 1635 | * Free all receive rings. |
1645 | * | | 1636 | * |
1646 | **********************************************************************/ | | 1637 | **********************************************************************/ |
1647 | void | | 1638 | void |
1648 | ixgbe_free_receive_structures(struct adapter *adapter) | | 1639 | ixgbe_free_receive_structures(struct adapter *adapter) |
| @@ -1676,35 +1667,27 @@ ixgbe_free_receive_structures(struct ada | | | @@ -1676,35 +1667,27 @@ ixgbe_free_receive_structures(struct ada |
1676 | **********************************************************************/ | | 1667 | **********************************************************************/ |
1677 | static void | | 1668 | static void |
1678 | ixgbe_free_receive_buffers(struct rx_ring *rxr) | | 1669 | ixgbe_free_receive_buffers(struct rx_ring *rxr) |
1679 | { | | 1670 | { |
1680 | struct adapter *adapter = rxr->adapter; | | 1671 | struct adapter *adapter = rxr->adapter; |
1681 | struct ixgbe_rx_buf *rxbuf; | | 1672 | struct ixgbe_rx_buf *rxbuf; |
1682 | | | 1673 | |
1683 | INIT_DEBUGOUT("ixgbe_free_receive_buffers: begin"); | | 1674 | INIT_DEBUGOUT("ixgbe_free_receive_buffers: begin"); |
1684 | | | 1675 | |
1685 | /* Cleanup any existing buffers */ | | 1676 | /* Cleanup any existing buffers */ |
1686 | if (rxr->rx_buffers != NULL) { | | 1677 | if (rxr->rx_buffers != NULL) { |
1687 | for (int i = 0; i < adapter->num_rx_desc; i++) { | | 1678 | for (int i = 0; i < adapter->num_rx_desc; i++) { |
1688 | rxbuf = &rxr->rx_buffers[i]; | | 1679 | rxbuf = &rxr->rx_buffers[i]; |
1689 | if (rxbuf->buf != NULL) { | | 1680 | ixgbe_rx_discard(rxr, i); |
1690 | bus_dmamap_sync(rxr->ptag->dt_dmat, | | | |
1691 | rxbuf->pmap, 0, rxbuf->buf->m_pkthdr.len, | | | |
1692 | BUS_DMASYNC_POSTREAD); | | | |
1693 | ixgbe_dmamap_unload(rxr->ptag, rxbuf->pmap); | | | |
1694 | rxbuf->buf->m_flags |= M_PKTHDR; | | | |
1695 | m_freem(rxbuf->buf); | | | |
1696 | } | | | |
1697 | rxbuf->buf = NULL; | | | |
1698 | if (rxbuf->pmap != NULL) { | | 1681 | if (rxbuf->pmap != NULL) { |
1699 | ixgbe_dmamap_destroy(rxr->ptag, rxbuf->pmap); | | 1682 | ixgbe_dmamap_destroy(rxr->ptag, rxbuf->pmap); |
1700 | rxbuf->pmap = NULL; | | 1683 | rxbuf->pmap = NULL; |
1701 | } | | 1684 | } |
1702 | } | | 1685 | } |
1703 | if (rxr->rx_buffers != NULL) { | | 1686 | if (rxr->rx_buffers != NULL) { |
1704 | free(rxr->rx_buffers, M_DEVBUF); | | 1687 | free(rxr->rx_buffers, M_DEVBUF); |
1705 | rxr->rx_buffers = NULL; | | 1688 | rxr->rx_buffers = NULL; |
1706 | } | | 1689 | } |
1707 | } | | 1690 | } |
1708 | | | 1691 | |
1709 | if (rxr->ptag != NULL) { | | 1692 | if (rxr->ptag != NULL) { |
1710 | ixgbe_dma_tag_destroy(rxr->ptag); | | 1693 | ixgbe_dma_tag_destroy(rxr->ptag); |
| @@ -1762,31 +1745,34 @@ ixgbe_rx_discard(struct rx_ring *rxr, in | | | @@ -1762,31 +1745,34 @@ ixgbe_rx_discard(struct rx_ring *rxr, in |
1762 | | | 1745 | |
1763 | rbuf = &rxr->rx_buffers[i]; | | 1746 | rbuf = &rxr->rx_buffers[i]; |
1764 | | | 1747 | |
1765 | | | 1748 | |
1766 | /* | | 1749 | /* |
1767 | ** With advanced descriptors the writeback | | 1750 | ** With advanced descriptors the writeback |
1768 | ** clobbers the buffer addrs, so its easier | | 1751 | ** clobbers the buffer addrs, so its easier |
1769 | ** to just free the existing mbufs and take | | 1752 | ** to just free the existing mbufs and take |
1770 | ** the normal refresh path to get new buffers | | 1753 | ** the normal refresh path to get new buffers |
1771 | ** and mapping. | | 1754 | ** and mapping. |
1772 | */ | | 1755 | */ |
1773 | | | 1756 | |
1774 | if (rbuf->fmp != NULL) {/* Partial chain ? */ | | 1757 | if (rbuf->fmp != NULL) {/* Partial chain ? */ |
1775 | rbuf->fmp->m_flags |= M_PKTHDR; | | 1758 | bus_dmamap_sync(rxr->ptag->dt_dmat, rbuf->pmap, 0, |
| | | 1759 | rbuf->buf->m_pkthdr.len, BUS_DMASYNC_POSTREAD); |
1776 | m_freem(rbuf->fmp); | | 1760 | m_freem(rbuf->fmp); |
1777 | rbuf->fmp = NULL; | | 1761 | rbuf->fmp = NULL; |
1778 | rbuf->buf = NULL; /* rbuf->buf is part of fmp's chain */ | | 1762 | rbuf->buf = NULL; /* rbuf->buf is part of fmp's chain */ |
1779 | } else if (rbuf->buf) { | | 1763 | } else if (rbuf->buf) { |
| | | 1764 | bus_dmamap_sync(rxr->ptag->dt_dmat, rbuf->pmap, 0, |
| | | 1765 | rbuf->buf->m_pkthdr.len, BUS_DMASYNC_POSTREAD); |
1780 | m_free(rbuf->buf); | | 1766 | m_free(rbuf->buf); |
1781 | rbuf->buf = NULL; | | 1767 | rbuf->buf = NULL; |
1782 | } | | 1768 | } |
1783 | ixgbe_dmamap_unload(rxr->ptag, rbuf->pmap); | | 1769 | ixgbe_dmamap_unload(rxr->ptag, rbuf->pmap); |
1784 | | | 1770 | |
1785 | rbuf->flags = 0; | | 1771 | rbuf->flags = 0; |
1786 | | | 1772 | |
1787 | return; | | 1773 | return; |
1788 | } | | 1774 | } |
1789 | | | 1775 | |
1790 | | | 1776 | |
1791 | /********************************************************************* | | 1777 | /********************************************************************* |
1792 | * | | 1778 | * |
| @@ -1860,26 +1846,29 @@ ixgbe_rxeof(struct ix_queue *que) | | | @@ -1860,26 +1846,29 @@ ixgbe_rxeof(struct ix_queue *que) |
1860 | eop = ((staterr & IXGBE_RXD_STAT_EOP) != 0); | | 1846 | eop = ((staterr & IXGBE_RXD_STAT_EOP) != 0); |
1861 | | | 1847 | |
1862 | /* Make sure bad packets are discarded */ | | 1848 | /* Make sure bad packets are discarded */ |
1863 | if (eop && (staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK) != 0) { | | 1849 | if (eop && (staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK) != 0) { |
1864 | #if __FreeBSD_version >= 1100036 | | 1850 | #if __FreeBSD_version >= 1100036 |
1865 | if (IXGBE_IS_VF(adapter)) | | 1851 | if (IXGBE_IS_VF(adapter)) |
1866 | if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); | | 1852 | if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); |
1867 | #endif | | 1853 | #endif |
1868 | rxr->rx_discarded.ev_count++; | | 1854 | rxr->rx_discarded.ev_count++; |
1869 | ixgbe_rx_discard(rxr, i); | | 1855 | ixgbe_rx_discard(rxr, i); |
1870 | goto next_desc; | | 1856 | goto next_desc; |
1871 | } | | 1857 | } |
1872 | | | 1858 | |
| | | 1859 | bus_dmamap_sync(rxr->ptag->dt_dmat, rbuf->pmap, 0, |
| | | 1860 | rbuf->buf->m_pkthdr.len, BUS_DMASYNC_POSTREAD); |
| | | 1861 | |
1873 | /* | | 1862 | /* |
1874 | ** On 82599 which supports a hardware | | 1863 | ** On 82599 which supports a hardware |
1875 | ** LRO (called HW RSC), packets need | | 1864 | ** LRO (called HW RSC), packets need |
1876 | ** not be fragmented across sequential | | 1865 | ** not be fragmented across sequential |
1877 | ** descriptors, rather the next descriptor | | 1866 | ** descriptors, rather the next descriptor |
1878 | ** is indicated in bits of the descriptor. | | 1867 | ** is indicated in bits of the descriptor. |
1879 | ** This also means that we might proceses | | 1868 | ** This also means that we might proceses |
1880 | ** more than one packet at a time, something | | 1869 | ** more than one packet at a time, something |
1881 | ** that has never been true before, it | | 1870 | ** that has never been true before, it |
1882 | ** required eliminating global chain pointers | | 1871 | ** required eliminating global chain pointers |
1883 | ** in favor of what we are doing here. -jfv | | 1872 | ** in favor of what we are doing here. -jfv |
1884 | */ | | 1873 | */ |
1885 | if (!eop) { | | 1874 | if (!eop) { |