Deleted Added
full compact
if_re.c (165957) if_re.c (166057)
1/*-
2 * Copyright (c) 1997, 1998-2003
3 * Bill Paul <wpaul@windriver.com>. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 17 unchanged lines hidden (view full) ---

26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1997, 1998-2003
3 * Bill Paul <wpaul@windriver.com>. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 17 unchanged lines hidden (view full) ---

26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: head/sys/dev/re/if_re.c 165957 2007-01-11 20:31:35Z wpaul $");
34__FBSDID("$FreeBSD: head/sys/dev/re/if_re.c 166057 2007-01-16 20:35:23Z marius $");
35
36/*
37 * RealTek 8139C+/8169/8169S/8110S/8168/8111/8101E PCI NIC driver
38 *
39 * Written by Bill Paul <wpaul@windriver.com>
40 * Senior Networking Software Engineer
41 * Wind River Systems
42 */

--- 1439 unchanged lines hidden (view full) ---

1482 * this, we leave some empty space at the start of each buffer
1483 * and for non-x86 hosts, we copy the buffer back six bytes
1484 * to achieve word alignment. This is slightly more efficient
1485 * than allocating a new buffer, copying the contents, and
1486 * discarding the old buffer.
1487 */
1488 m_adj(m, RE_ETHER_ALIGN);
1489#endif
35
36/*
37 * RealTek 8139C+/8169/8169S/8110S/8168/8111/8101E PCI NIC driver
38 *
39 * Written by Bill Paul <wpaul@windriver.com>
40 * Senior Networking Software Engineer
41 * Wind River Systems
42 */

--- 1439 unchanged lines hidden (view full) ---

1482 * this, we leave some empty space at the start of each buffer
1483 * and for non-x86 hosts, we copy the buffer back six bytes
1484 * to achieve word alignment. This is slightly more efficient
1485 * than allocating a new buffer, copying the contents, and
1486 * discarding the old buffer.
1487 */
1488 m_adj(m, RE_ETHER_ALIGN);
1489#endif
1490 arg.sc = sc;
1491 arg.rl_idx = idx;
1492 arg.rl_maxsegs = 1;
1493 arg.rl_flags = 0;
1494 arg.rl_ring = sc->rl_ldata.rl_rx_list;
1495
1496 error = bus_dmamap_load_mbuf(sc->rl_ldata.rl_mtag,
1497 sc->rl_ldata.rl_rx_dmamap[idx], m, re_dma_map_desc,
1498 &arg, BUS_DMA_NOWAIT);
1499 if (error || arg.rl_maxsegs != 1) {
1500 if (n != NULL)
1501 m_freem(n);
1490 arg.rl_idx = idx;
1491 arg.rl_maxsegs = 1;
1492 arg.rl_flags = 0;
1493 arg.rl_ring = sc->rl_ldata.rl_rx_list;
1494
1495 error = bus_dmamap_load_mbuf(sc->rl_ldata.rl_mtag,
1496 sc->rl_ldata.rl_rx_dmamap[idx], m, re_dma_map_desc,
1497 &arg, BUS_DMA_NOWAIT);
1498 if (error || arg.rl_maxsegs != 1) {
1499 if (n != NULL)
1500 m_freem(n);
1501 if (arg.rl_maxsegs == 0)
1502 bus_dmamap_unload(sc->rl_ldata.rl_mtag,
1503 sc->rl_ldata.rl_rx_dmamap[idx]);
1502 return (ENOMEM);
1503 }
1504
1505 sc->rl_ldata.rl_rx_list[idx].rl_cmdstat |= htole32(RL_RDESC_CMD_OWN);
1506 sc->rl_ldata.rl_rx_mbuf[idx] = m;
1507
1508 bus_dmamap_sync(sc->rl_ldata.rl_mtag,
1509 sc->rl_ldata.rl_rx_dmamap[idx],

--- 266 unchanged lines hidden (view full) ---

1776 struct ifnet *ifp;
1777 u_int32_t txstat;
1778 int idx;
1779
1780 ifp = sc->rl_ifp;
1781 idx = sc->rl_ldata.rl_tx_considx;
1782
1783 /* Invalidate the TX descriptor list */
1504 return (ENOMEM);
1505 }
1506
1507 sc->rl_ldata.rl_rx_list[idx].rl_cmdstat |= htole32(RL_RDESC_CMD_OWN);
1508 sc->rl_ldata.rl_rx_mbuf[idx] = m;
1509
1510 bus_dmamap_sync(sc->rl_ldata.rl_mtag,
1511 sc->rl_ldata.rl_rx_dmamap[idx],

--- 266 unchanged lines hidden (view full) ---

1778 struct ifnet *ifp;
1779 u_int32_t txstat;
1780 int idx;
1781
1782 ifp = sc->rl_ifp;
1783 idx = sc->rl_ldata.rl_tx_considx;
1784
1785 /* Invalidate the TX descriptor list */
1784
1785 bus_dmamap_sync(sc->rl_ldata.rl_tx_list_tag,
1786 sc->rl_ldata.rl_tx_list_map,
1787 BUS_DMASYNC_POSTREAD);
1788
1789 while (sc->rl_ldata.rl_tx_free < RL_TX_DESC_CNT) {
1786 bus_dmamap_sync(sc->rl_ldata.rl_tx_list_tag,
1787 sc->rl_ldata.rl_tx_list_map,
1788 BUS_DMASYNC_POSTREAD);
1789
1790 while (sc->rl_ldata.rl_tx_free < RL_TX_DESC_CNT) {
1790
1791 txstat = le32toh(sc->rl_ldata.rl_tx_list[idx].rl_cmdstat);
1792 if (txstat & RL_TDESC_CMD_OWN)
1793 break;
1794
1795 sc->rl_ldata.rl_tx_list[idx].rl_bufaddr_lo = 0;
1796
1797 /*
1798 * We only stash mbufs in the last descriptor
1799 * in a fragment chain, which also happens to
1800 * be the only place where the TX status bits
1801 * are valid.
1802 */
1791 txstat = le32toh(sc->rl_ldata.rl_tx_list[idx].rl_cmdstat);
1792 if (txstat & RL_TDESC_CMD_OWN)
1793 break;
1794
1795 sc->rl_ldata.rl_tx_list[idx].rl_bufaddr_lo = 0;
1796
1797 /*
1798 * We only stash mbufs in the last descriptor
1799 * in a fragment chain, which also happens to
1800 * be the only place where the TX status bits
1801 * are valid.
1802 */
1803
1804 if (txstat & RL_TDESC_CMD_EOF) {
1805 m_freem(sc->rl_ldata.rl_tx_mbuf[idx]);
1806 sc->rl_ldata.rl_tx_mbuf[idx] = NULL;
1807 bus_dmamap_unload(sc->rl_ldata.rl_mtag,
1808 sc->rl_ldata.rl_tx_dmamap[idx]);
1809 if (txstat & (RL_TDESC_STAT_EXCESSCOL|
1810 RL_TDESC_STAT_COLCNT))
1811 ifp->if_collisions++;
1812 if (txstat & RL_TDESC_STAT_TXERRSUM)
1813 ifp->if_oerrors++;
1814 else
1815 ifp->if_opackets++;
1816 }
1817 sc->rl_ldata.rl_tx_free++;
1818 RL_DESC_INC(idx);
1819 }
1803 if (txstat & RL_TDESC_CMD_EOF) {
1804 m_freem(sc->rl_ldata.rl_tx_mbuf[idx]);
1805 sc->rl_ldata.rl_tx_mbuf[idx] = NULL;
1806 bus_dmamap_unload(sc->rl_ldata.rl_mtag,
1807 sc->rl_ldata.rl_tx_dmamap[idx]);
1808 if (txstat & (RL_TDESC_STAT_EXCESSCOL|
1809 RL_TDESC_STAT_COLCNT))
1810 ifp->if_collisions++;
1811 if (txstat & RL_TDESC_STAT_TXERRSUM)
1812 ifp->if_oerrors++;
1813 else
1814 ifp->if_opackets++;
1815 }
1816 sc->rl_ldata.rl_tx_free++;
1817 RL_DESC_INC(idx);
1818 }
1819 sc->rl_ldata.rl_tx_considx = idx;
1820
1821 /* No changes made to the TX ring, so no flush needed */
1822
1820
1821 /* No changes made to the TX ring, so no flush needed */
1822
1823 if (sc->rl_ldata.rl_tx_free) {
1824 sc->rl_ldata.rl_tx_considx = idx;
1823 if (sc->rl_ldata.rl_tx_free > RL_TX_DESC_THLD)
1825 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1824 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1826 sc->rl_watchdog_timer = 0;
1827 }
1828
1825
1829 /*
1830 * Some chips will ignore a second TX request issued while an
1831 * existing transmission is in progress. If the transmitter goes
1832 * idle but there are still packets waiting to be sent, we need
1833 * to restart the channel here to flush them out. This only seems
1834 * to be required with the PCIe devices.
1835 */
1826 if (sc->rl_ldata.rl_tx_free < RL_TX_DESC_CNT) {
1827 /*
1828 * Some chips will ignore a second TX request issued
1829 * while an existing transmission is in progress. If
1830 * the transmitter goes idle but there are still
1831 * packets waiting to be sent, we need to restart the
1832 * channel here to flush them out. This only seems to
1833 * be required with the PCIe devices.
1834 */
1835 CSR_WRITE_1(sc, sc->rl_txstart, RL_TXSTART_START);
1836
1836
1837 if (sc->rl_ldata.rl_tx_free < RL_TX_DESC_CNT)
1838 CSR_WRITE_1(sc, sc->rl_txstart, RL_TXSTART_START);
1839
1840#ifdef RE_TX_MODERATION
1837#ifdef RE_TX_MODERATION
1841 /*
1842 * If not all descriptors have been released reaped yet,
1843 * reload the timer so that we will eventually get another
1844 * interrupt that will cause us to re-enter this routine.
1845 * This is done in case the transmitter has gone idle.
1846 */
1847 if (sc->rl_ldata.rl_tx_free != RL_TX_DESC_CNT)
1838 /*
1839 * If not all descriptors have been reaped yet, reload
1840 * the timer so that we will eventually get another
1841 * interrupt that will cause us to re-enter this routine.
1842 * This is done in case the transmitter has gone idle.
1843 */
1848 CSR_WRITE_4(sc, RL_TIMERCNT, 1);
1849#endif
1844 CSR_WRITE_4(sc, RL_TIMERCNT, 1);
1845#endif
1850
1846 } else
1847 sc->rl_watchdog_timer = 0;
1851}
1852
1853static void
1854re_tick(xsc)
1855 void *xsc;
1856{
1857 struct rl_softc *sc;
1858 struct mii_data *mii;

--- 164 unchanged lines hidden (view full) ---

2023{
2024 struct mbuf *m_new = NULL;
2025 struct rl_dmaload_arg arg;
2026 bus_dmamap_t map;
2027 int error;
2028
2029 RL_LOCK_ASSERT(sc);
2030
1848}
1849
1850static void
1851re_tick(xsc)
1852 void *xsc;
1853{
1854 struct rl_softc *sc;
1855 struct mii_data *mii;

--- 164 unchanged lines hidden (view full) ---

2020{
2021 struct mbuf *m_new = NULL;
2022 struct rl_dmaload_arg arg;
2023 bus_dmamap_t map;
2024 int error;
2025
2026 RL_LOCK_ASSERT(sc);
2027
2031 if (sc->rl_ldata.rl_tx_free <= 4)
2028 if (sc->rl_ldata.rl_tx_free <= RL_TX_DESC_THLD)
2032 return (EFBIG);
2033
2034 /*
2035 * Set up checksum offload. Note: checksum offload bits must
2036 * appear in all descriptors of a multi-descriptor transmit
2037 * attempt. This is according to testing done with an 8169
2038 * chip. This is a requirement.
2039 */

--- 8 unchanged lines hidden (view full) ---

2048 if ((*m_head)->m_pkthdr.csum_flags & CSUM_IP)
2049 arg.rl_flags |= RL_TDESC_CMD_IPCSUM;
2050 if ((*m_head)->m_pkthdr.csum_flags & CSUM_TCP)
2051 arg.rl_flags |= RL_TDESC_CMD_TCPCSUM;
2052 if ((*m_head)->m_pkthdr.csum_flags & CSUM_UDP)
2053 arg.rl_flags |= RL_TDESC_CMD_UDPCSUM;
2054 }
2055
2029 return (EFBIG);
2030
2031 /*
2032 * Set up checksum offload. Note: checksum offload bits must
2033 * appear in all descriptors of a multi-descriptor transmit
2034 * attempt. This is according to testing done with an 8169
2035 * chip. This is a requirement.
2036 */

--- 8 unchanged lines hidden (view full) ---

2045 if ((*m_head)->m_pkthdr.csum_flags & CSUM_IP)
2046 arg.rl_flags |= RL_TDESC_CMD_IPCSUM;
2047 if ((*m_head)->m_pkthdr.csum_flags & CSUM_TCP)
2048 arg.rl_flags |= RL_TDESC_CMD_TCPCSUM;
2049 if ((*m_head)->m_pkthdr.csum_flags & CSUM_UDP)
2050 arg.rl_flags |= RL_TDESC_CMD_UDPCSUM;
2051 }
2052
2056 arg.sc = sc;
2057 arg.rl_idx = *idx;
2058 arg.rl_maxsegs = sc->rl_ldata.rl_tx_free;
2053 arg.rl_idx = *idx;
2054 arg.rl_maxsegs = sc->rl_ldata.rl_tx_free;
2059 if (arg.rl_maxsegs > 4)
2060 arg.rl_maxsegs -= 4;
2055 if (arg.rl_maxsegs > RL_TX_DESC_THLD)
2056 arg.rl_maxsegs -= RL_TX_DESC_THLD;
2061 arg.rl_ring = sc->rl_ldata.rl_tx_list;
2062
2063 map = sc->rl_ldata.rl_tx_dmamap[*idx];
2064
2065 /*
2066 * With some of the RealTek chips, using the checksum offload
2067 * support in conjunction with the autopadding feature results
2068 * in the transmission of corrupt frames. For example, if we
2069 * need to send a really small IP fragment that's less than 60
2070 * bytes in size, and IP header checksumming is enabled, the
2071 * resulting ethernet frame that appears on the wire will
2072 * have garbled payload. To work around this, if TX checksum
2073 * offload is enabled, we always manually pad short frames out
2074 * to the minimum ethernet frame size. We do this by pretending
2075 * the mbuf chain has too many fragments so the coalescing code
2076 * below can assemble the packet into a single buffer that's
2077 * padded out to the mininum frame size.
2078 */
2057 arg.rl_ring = sc->rl_ldata.rl_tx_list;
2058
2059 map = sc->rl_ldata.rl_tx_dmamap[*idx];
2060
2061 /*
2062 * With some of the RealTek chips, using the checksum offload
2063 * support in conjunction with the autopadding feature results
2064 * in the transmission of corrupt frames. For example, if we
2065 * need to send a really small IP fragment that's less than 60
2066 * bytes in size, and IP header checksumming is enabled, the
2067 * resulting ethernet frame that appears on the wire will
2068 * have garbled payload. To work around this, if TX checksum
2069 * offload is enabled, we always manually pad short frames out
2070 * to the minimum ethernet frame size. We do this by pretending
2071 * the mbuf chain has too many fragments so the coalescing code
2072 * below can assemble the packet into a single buffer that's
2073 * padded out to the mininum frame size.
2074 */
2079
2080 if (arg.rl_flags && (*m_head)->m_pkthdr.len < RL_MIN_FRAMELEN)
2081 error = EFBIG;
2082 else
2083 error = bus_dmamap_load_mbuf(sc->rl_ldata.rl_mtag, map,
2084 *m_head, re_dma_map_desc, &arg, BUS_DMA_NOWAIT);
2085
2086 if (error && error != EFBIG) {
2087 device_printf(sc->rl_dev, "can't map mbuf (error %d)\n", error);
2088 return (ENOBUFS);
2089 }
2090
2091 /* Too many segments to map, coalesce into a single mbuf */
2092
2093 if (error || arg.rl_maxsegs == 0) {
2075 if (arg.rl_flags && (*m_head)->m_pkthdr.len < RL_MIN_FRAMELEN)
2076 error = EFBIG;
2077 else
2078 error = bus_dmamap_load_mbuf(sc->rl_ldata.rl_mtag, map,
2079 *m_head, re_dma_map_desc, &arg, BUS_DMA_NOWAIT);
2080
2081 if (error && error != EFBIG) {
2082 device_printf(sc->rl_dev, "can't map mbuf (error %d)\n", error);
2083 return (ENOBUFS);
2084 }
2085
2086 /* Too many segments to map, coalesce into a single mbuf */
2087
2088 if (error || arg.rl_maxsegs == 0) {
2089 if (arg.rl_maxsegs == 0)
2090 bus_dmamap_unload(sc->rl_ldata.rl_mtag, map);
2094 m_new = m_defrag(*m_head, M_DONTWAIT);
2091 m_new = m_defrag(*m_head, M_DONTWAIT);
2095 if (m_new == NULL)
2092 if (m_new == NULL) {
2093 m_freem(*m_head);
2094 *m_head = NULL;
2096 return (ENOBUFS);
2095 return (ENOBUFS);
2097 else
2098 *m_head = m_new;
2096 }
2097 *m_head = m_new;
2099
2100 /*
2101 * Manually pad short frames, and zero the pad space
2102 * to avoid leaking data.
2103 */
2098
2099 /*
2100 * Manually pad short frames, and zero the pad space
2101 * to avoid leaking data.
2102 */
2104
2105 if (m_new->m_pkthdr.len < RL_MIN_FRAMELEN) {
2106 bzero(mtod(m_new, char *) + m_new->m_pkthdr.len,
2107 RL_MIN_FRAMELEN - m_new->m_pkthdr.len);
2108 m_new->m_pkthdr.len += RL_MIN_FRAMELEN -
2109 m_new->m_pkthdr.len;
2110 m_new->m_len = m_new->m_pkthdr.len;
2111 }
2112
2103 if (m_new->m_pkthdr.len < RL_MIN_FRAMELEN) {
2104 bzero(mtod(m_new, char *) + m_new->m_pkthdr.len,
2105 RL_MIN_FRAMELEN - m_new->m_pkthdr.len);
2106 m_new->m_pkthdr.len += RL_MIN_FRAMELEN -
2107 m_new->m_pkthdr.len;
2108 m_new->m_len = m_new->m_pkthdr.len;
2109 }
2110
2113 arg.sc = sc;
2114 arg.rl_idx = *idx;
2111 /* Note that we'll run over RL_TX_DESC_THLD here. */
2115 arg.rl_maxsegs = sc->rl_ldata.rl_tx_free;
2112 arg.rl_maxsegs = sc->rl_ldata.rl_tx_free;
2116 arg.rl_ring = sc->rl_ldata.rl_tx_list;
2117
2118 error = bus_dmamap_load_mbuf(sc->rl_ldata.rl_mtag, map,
2119 *m_head, re_dma_map_desc, &arg, BUS_DMA_NOWAIT);
2113 error = bus_dmamap_load_mbuf(sc->rl_ldata.rl_mtag, map,
2114 *m_head, re_dma_map_desc, &arg, BUS_DMA_NOWAIT);
2120 if (error) {
2121 device_printf(sc->rl_dev, "can't map mbuf (error %d)\n",
2122 error);
2115 if (error || arg.rl_maxsegs == 0) {
2116 device_printf(sc->rl_dev,
2117 "can't map defragmented mbuf (error %d)\n", error);
2118 m_freem(m_new);
2119 *m_head = NULL;
2120 if (arg.rl_maxsegs == 0)
2121 bus_dmamap_unload(sc->rl_ldata.rl_mtag, map);
2123 return (EFBIG);
2124 }
2125 }
2126
2127 /*
2128 * Insure that the map for this transmission
2129 * is placed at the array index of the last descriptor
2130 * in this chain. (Swap last and first dmamaps.)

--- 65 unchanged lines hidden (view full) ---

2196 idx = sc->rl_ldata.rl_tx_prodidx;
2197
2198 while (sc->rl_ldata.rl_tx_mbuf[idx] == NULL) {
2199 IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
2200 if (m_head == NULL)
2201 break;
2202
2203 if (re_encap(sc, &m_head, &idx)) {
2122 return (EFBIG);
2123 }
2124 }
2125
2126 /*
2127 * Insure that the map for this transmission
2128 * is placed at the array index of the last descriptor
2129 * in this chain. (Swap last and first dmamaps.)

--- 65 unchanged lines hidden (view full) ---

2195 idx = sc->rl_ldata.rl_tx_prodidx;
2196
2197 while (sc->rl_ldata.rl_tx_mbuf[idx] == NULL) {
2198 IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
2199 if (m_head == NULL)
2200 break;
2201
2202 if (re_encap(sc, &m_head, &idx)) {
2203 if (m_head == NULL)
2204 break;
2204 IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
2205 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
2206 break;
2207 }
2208
2209 /*
2210 * If there's a BPF listener, bounce a copy of this frame
2211 * to him.

--- 15 unchanged lines hidden (view full) ---

2227 /* Flush the TX descriptors */
2228
2229 bus_dmamap_sync(sc->rl_ldata.rl_tx_list_tag,
2230 sc->rl_ldata.rl_tx_list_map,
2231 BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
2232
2233 sc->rl_ldata.rl_tx_prodidx = idx;
2234
2205 IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
2206 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
2207 break;
2208 }
2209
2210 /*
2211 * If there's a BPF listener, bounce a copy of this frame
2212 * to him.

--- 15 unchanged lines hidden (view full) ---

2228 /* Flush the TX descriptors */
2229
2230 bus_dmamap_sync(sc->rl_ldata.rl_tx_list_tag,
2231 sc->rl_ldata.rl_tx_list_map,
2232 BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
2233
2234 sc->rl_ldata.rl_tx_prodidx = idx;
2235
2235 /*
2236 * RealTek put the TX poll request register in a different
2237 * location on the 8169 gigE chip. I don't know why.
2238 */
2239
2240 CSR_WRITE_1(sc, sc->rl_txstart, RL_TXSTART_START);
2241
2242#ifdef RE_TX_MODERATION
2243 /*
2244 * Use the countdown timer for interrupt moderation.
2245 * 'TX done' interrupts are disabled. Instead, we reset the
2246 * countdown timer, which will begin counting until it hits
2247 * the value in the TIMERINT register, and then trigger an

--- 478 unchanged lines hidden ---
2236 CSR_WRITE_1(sc, sc->rl_txstart, RL_TXSTART_START);
2237
2238#ifdef RE_TX_MODERATION
2239 /*
2240 * Use the countdown timer for interrupt moderation.
2241 * 'TX done' interrupts are disabled. Instead, we reset the
2242 * countdown timer, which will begin counting until it hits
2243 * the value in the TIMERINT register, and then trigger an

--- 478 unchanged lines hidden ---