Mon Mar 16 09:58:51 2009 UTC ()
Add a dumb RX hardware TCPv4/UDPv4 checksum support.


(tsutsui)
diff -r1.33 -r1.34 src/sys/arch/sgimips/mace/if_mec.c

cvs diff -r1.33 -r1.34 src/sys/arch/sgimips/mace/if_mec.c (expand / switch to unified diff)

--- src/sys/arch/sgimips/mace/if_mec.c 2008/08/23 18:44:51 1.33
+++ src/sys/arch/sgimips/mace/if_mec.c 2009/03/16 09:58:51 1.34
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: if_mec.c,v 1.33 2008/08/23 18:44:51 tsutsui Exp $ */ 1/* $NetBSD: if_mec.c,v 1.34 2009/03/16 09:58:51 tsutsui Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2004, 2008 Izumi Tsutsui. All rights reserved. 4 * Copyright (c) 2004, 2008 Izumi Tsutsui. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 14 *
@@ -51,52 +51,58 @@ @@ -51,52 +51,58 @@
51 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 51 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
52 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 52 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
53 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 53 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
54 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 54 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
55 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 55 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
56 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 56 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
57 */ 57 */
58 58
59/* 59/*
60 * MACE MAC-110 Ethernet driver 60 * MACE MAC-110 Ethernet driver
61 */ 61 */
62 62
63#include <sys/cdefs.h> 63#include <sys/cdefs.h>
64__KERNEL_RCSID(0, "$NetBSD: if_mec.c,v 1.33 2008/08/23 18:44:51 tsutsui Exp $"); 64__KERNEL_RCSID(0, "$NetBSD: if_mec.c,v 1.34 2009/03/16 09:58:51 tsutsui Exp $");
65 65
66#include "opt_ddb.h" 66#include "opt_ddb.h"
67#include "bpfilter.h" 67#include "bpfilter.h"
68#include "rnd.h" 68#include "rnd.h"
69 69
70#include <sys/param.h> 70#include <sys/param.h>
71#include <sys/systm.h> 71#include <sys/systm.h>
72#include <sys/device.h> 72#include <sys/device.h>
73#include <sys/callout.h> 73#include <sys/callout.h>
74#include <sys/mbuf.h> 74#include <sys/mbuf.h>
75#include <sys/malloc.h> 75#include <sys/malloc.h>
76#include <sys/kernel.h> 76#include <sys/kernel.h>
77#include <sys/socket.h> 77#include <sys/socket.h>
78#include <sys/ioctl.h> 78#include <sys/ioctl.h>
79#include <sys/errno.h> 79#include <sys/errno.h>
80 80
81#if NRND > 0 81#if NRND > 0
82#include <sys/rnd.h> 82#include <sys/rnd.h>
83#endif 83#endif
84 84
85#include <net/if.h> 85#include <net/if.h>
86#include <net/if_dl.h> 86#include <net/if_dl.h>
87#include <net/if_media.h> 87#include <net/if_media.h>
88#include <net/if_ether.h> 88#include <net/if_ether.h>
89 89
 90#include <netinet/in.h>
 91#include <netinet/in_systm.h>
 92#include <netinet/ip.h>
 93#include <netinet/tcp.h>
 94#include <netinet/udp.h>
 95
90#if NBPFILTER > 0 96#if NBPFILTER > 0
91#include <net/bpf.h> 97#include <net/bpf.h>
92#endif 98#endif
93 99
94#include <machine/bus.h> 100#include <machine/bus.h>
95#include <machine/intr.h> 101#include <machine/intr.h>
96#include <machine/machtype.h> 102#include <machine/machtype.h>
97 103
98#include <dev/mii/mii.h> 104#include <dev/mii/mii.h>
99#include <dev/mii/miivar.h> 105#include <dev/mii/miivar.h>
100 106
101#include <sgimips/mace/macevar.h> 107#include <sgimips/mace/macevar.h>
102#include <sgimips/mace/if_mecreg.h> 108#include <sgimips/mace/if_mecreg.h>
@@ -229,26 +235,27 @@ struct mec_rxdesc { @@ -229,26 +235,27 @@ struct mec_rxdesc {
229#define MEC_RXSTAT_VIOLATION 0x0000000000010000 /* code violation (?) */ 235#define MEC_RXSTAT_VIOLATION 0x0000000000010000 /* code violation (?) */
230#define MEC_RXSTAT_UNUSED2 0x0000000000020000 /* unknown (?) */ 236#define MEC_RXSTAT_UNUSED2 0x0000000000020000 /* unknown (?) */
231#define MEC_RXSTAT_CRCERROR 0x0000000000040000 /* CRC error */ 237#define MEC_RXSTAT_CRCERROR 0x0000000000040000 /* CRC error */
232#define MEC_RXSTAT_MULTICAST 0x0000000000080000 /* multicast packet */ 238#define MEC_RXSTAT_MULTICAST 0x0000000000080000 /* multicast packet */
233#define MEC_RXSTAT_BROADCAST 0x0000000000100000 /* broadcast packet */ 239#define MEC_RXSTAT_BROADCAST 0x0000000000100000 /* broadcast packet */
234#define MEC_RXSTAT_INVALID 0x0000000000200000 /* invalid preamble */ 240#define MEC_RXSTAT_INVALID 0x0000000000200000 /* invalid preamble */
235#define MEC_RXSTAT_LONGEVENT 0x0000000000400000 /* long packet */ 241#define MEC_RXSTAT_LONGEVENT 0x0000000000400000 /* long packet */
236#define MEC_RXSTAT_BADPACKET 0x0000000000800000 /* bad packet */ 242#define MEC_RXSTAT_BADPACKET 0x0000000000800000 /* bad packet */
237#define MEC_RXSTAT_CAREVENT 0x0000000001000000 /* carrier event */ 243#define MEC_RXSTAT_CAREVENT 0x0000000001000000 /* carrier event */
238#define MEC_RXSTAT_MATCHMCAST 0x0000000002000000 /* match multicast */ 244#define MEC_RXSTAT_MATCHMCAST 0x0000000002000000 /* match multicast */
239#define MEC_RXSTAT_MATCHMAC 0x0000000004000000 /* match MAC */ 245#define MEC_RXSTAT_MATCHMAC 0x0000000004000000 /* match MAC */
240#define MEC_RXSTAT_SEQNUM 0x00000000f8000000 /* sequence number */ 246#define MEC_RXSTAT_SEQNUM 0x00000000f8000000 /* sequence number */
241#define MEC_RXSTAT_CKSUM 0x0000ffff00000000ULL /* IP checksum */ 247#define MEC_RXSTAT_CKSUM 0x0000ffff00000000ULL /* IP checksum */
 248#define RXSTAT_CKSUM(x) (((uint64_t)(x) & MEC_RXSTAT_CKSUM) >> 32)
242#define MEC_RXSTAT_UNUSED1 0x7fff000000000000ULL /* should be zero */ 249#define MEC_RXSTAT_UNUSED1 0x7fff000000000000ULL /* should be zero */
243#define MEC_RXSTAT_RECEIVED 0x8000000000000000ULL /* set to 1 on RX */ 250#define MEC_RXSTAT_RECEIVED 0x8000000000000000ULL /* set to 1 on RX */
244 uint64_t rxd_pad1[MEC_RXD_NRXPAD]; 251 uint64_t rxd_pad1[MEC_RXD_NRXPAD];
245 uint8_t rxd_buf[MEC_RXD_BUFSIZE]; 252 uint8_t rxd_buf[MEC_RXD_BUFSIZE];
246}; 253};
247 254
248/* 255/*
249 * control structures for DMA ops 256 * control structures for DMA ops
250 */ 257 */
251struct mec_control_data { 258struct mec_control_data {
252 /* 259 /*
253 * TX descriptors and buffers 260 * TX descriptors and buffers
254 */ 261 */
@@ -396,26 +403,28 @@ static void mec_statchg(device_t); @@ -396,26 +403,28 @@ static void mec_statchg(device_t);
396 403
397static void enaddr_aton(const char *, uint8_t *); 404static void enaddr_aton(const char *, uint8_t *);
398 405
399static int mec_init(struct ifnet * ifp); 406static int mec_init(struct ifnet * ifp);
400static void mec_start(struct ifnet *); 407static void mec_start(struct ifnet *);
401static void mec_watchdog(struct ifnet *); 408static void mec_watchdog(struct ifnet *);
402static void mec_tick(void *); 409static void mec_tick(void *);
403static int mec_ioctl(struct ifnet *, u_long, void *); 410static int mec_ioctl(struct ifnet *, u_long, void *);
404static void mec_reset(struct mec_softc *); 411static void mec_reset(struct mec_softc *);
405static void mec_setfilter(struct mec_softc *); 412static void mec_setfilter(struct mec_softc *);
406static int mec_intr(void *arg); 413static int mec_intr(void *arg);
407static void mec_stop(struct ifnet *, int); 414static void mec_stop(struct ifnet *, int);
408static void mec_rxintr(struct mec_softc *); 415static void mec_rxintr(struct mec_softc *);
 416static void mec_rxcsum(struct mec_softc *, struct mbuf *, uint16_t,
 417 uint32_t);
409static void mec_txintr(struct mec_softc *, uint32_t); 418static void mec_txintr(struct mec_softc *, uint32_t);
410static void mec_shutdown(void *); 419static void mec_shutdown(void *);
411 420
412CFATTACH_DECL_NEW(mec, sizeof(struct mec_softc), 421CFATTACH_DECL_NEW(mec, sizeof(struct mec_softc),
413 mec_match, mec_attach, NULL, NULL); 422 mec_match, mec_attach, NULL, NULL);
414 423
415static int mec_matched = 0; 424static int mec_matched = 0;
416 425
417static int 426static int
418mec_match(device_t parent, cfdata_t cf, void *aux) 427mec_match(device_t parent, cfdata_t cf, void *aux)
419{ 428{
420 429
421 /* allow only one device */ 430 /* allow only one device */
@@ -598,26 +607,29 @@ mec_attach(device_t parent, device_t sel @@ -598,26 +607,29 @@ mec_attach(device_t parent, device_t sel
598 } 607 }
599 608
600 strcpy(ifp->if_xname, device_xname(self)); 609 strcpy(ifp->if_xname, device_xname(self));
601 ifp->if_softc = sc; 610 ifp->if_softc = sc;
602 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 611 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
603 ifp->if_ioctl = mec_ioctl; 612 ifp->if_ioctl = mec_ioctl;
604 ifp->if_start = mec_start; 613 ifp->if_start = mec_start;
605 ifp->if_watchdog = mec_watchdog; 614 ifp->if_watchdog = mec_watchdog;
606 ifp->if_init = mec_init; 615 ifp->if_init = mec_init;
607 ifp->if_stop = mec_stop; 616 ifp->if_stop = mec_stop;
608 ifp->if_mtu = ETHERMTU; 617 ifp->if_mtu = ETHERMTU;
609 IFQ_SET_READY(&ifp->if_snd); 618 IFQ_SET_READY(&ifp->if_snd);
610 619
 620 /* mec has dumb RX cksum support */
 621 ifp->if_capabilities = IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx;
 622
611 /* We can support 802.1Q VLAN-sized frames. */ 623 /* We can support 802.1Q VLAN-sized frames. */
612 sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU; 624 sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;
613 625
614 /* attach the interface */ 626 /* attach the interface */
615 if_attach(ifp); 627 if_attach(ifp);
616 ether_ifattach(ifp, sc->sc_enaddr); 628 ether_ifattach(ifp, sc->sc_enaddr);
617 629
618 /* establish interrupt */ 630 /* establish interrupt */
619 cpu_intr_establish(maa->maa_intr, maa->maa_intrmask, mec_intr, sc); 631 cpu_intr_establish(maa->maa_intr, maa->maa_intrmask, mec_intr, sc);
620 632
621#if NRND > 0 633#if NRND > 0
622 rnd_attach_source(&sc->sc_rnd_source, device_xname(self), 634 rnd_attach_source(&sc->sc_rnd_source, device_xname(self),
623 RND_TYPE_NET, 0); 635 RND_TYPE_NET, 0);
@@ -1646,26 +1658,27 @@ mec_intr(void *arg) @@ -1646,26 +1658,27 @@ mec_intr(void *arg)
1646} 1658}
1647 1659
1648static void 1660static void
1649mec_rxintr(struct mec_softc *sc) 1661mec_rxintr(struct mec_softc *sc)
1650{ 1662{
1651 bus_space_tag_t st = sc->sc_st; 1663 bus_space_tag_t st = sc->sc_st;
1652 bus_space_handle_t sh = sc->sc_sh; 1664 bus_space_handle_t sh = sc->sc_sh;
1653 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1665 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1654 struct mbuf *m; 1666 struct mbuf *m;
1655 struct mec_rxdesc *rxd; 1667 struct mec_rxdesc *rxd;
1656 uint64_t rxstat; 1668 uint64_t rxstat;
1657 u_int len; 1669 u_int len;
1658 int i; 1670 int i;
 1671 uint32_t crc;
1659 1672
1660 DPRINTF(MEC_DEBUG_RXINTR, ("mec_rxintr: called\n")); 1673 DPRINTF(MEC_DEBUG_RXINTR, ("mec_rxintr: called\n"));
1661 1674
1662 for (i = sc->sc_rxptr;; i = MEC_NEXTRX(i)) { 1675 for (i = sc->sc_rxptr;; i = MEC_NEXTRX(i)) {
1663 rxd = &sc->sc_rxdesc[i]; 1676 rxd = &sc->sc_rxdesc[i];
1664 1677
1665 MEC_RXSTATSYNC(sc, i, BUS_DMASYNC_POSTREAD); 1678 MEC_RXSTATSYNC(sc, i, BUS_DMASYNC_POSTREAD);
1666 rxstat = rxd->rxd_stat; 1679 rxstat = rxd->rxd_stat;
1667 1680
1668 DPRINTF(MEC_DEBUG_RXINTR, 1681 DPRINTF(MEC_DEBUG_RXINTR,
1669 ("mec_rxintr: rxstat = 0x%016llx, rxptr = %d\n", 1682 ("mec_rxintr: rxstat = 0x%016llx, rxptr = %d\n",
1670 rxstat, i)); 1683 rxstat, i));
1671 DPRINTF(MEC_DEBUG_RXINTR, ("mec_rxintr: rxfifo = 0x%08x\n", 1684 DPRINTF(MEC_DEBUG_RXINTR, ("mec_rxintr: rxfifo = 0x%08x\n",
@@ -1730,59 +1743,157 @@ mec_rxintr(struct mec_softc *sc) @@ -1730,59 +1743,157 @@ mec_rxintr(struct mec_softc *sc)
1730 if ((m->m_flags & M_EXT) == 0) { 1743 if ((m->m_flags & M_EXT) == 0) {
1731 printf("%s: unable to allocate RX cluster\n", 1744 printf("%s: unable to allocate RX cluster\n",
1732 device_xname(sc->sc_dev)); 1745 device_xname(sc->sc_dev));
1733 m_freem(m); 1746 m_freem(m);
1734 m = NULL; 1747 m = NULL;
1735 goto dropit; 1748 goto dropit;
1736 } 1749 }
1737 } 1750 }
1738 1751
1739 /* 1752 /*
1740 * Note MEC chip seems to insert 2 byte padding at the top of 1753 * Note MEC chip seems to insert 2 byte padding at the top of
1741 * RX buffer, but we copy whole buffer to avoid unaligned copy. 1754 * RX buffer, but we copy whole buffer to avoid unaligned copy.
1742 */ 1755 */
1743 MEC_RXBUFSYNC(sc, i, len, BUS_DMASYNC_POSTREAD); 1756 MEC_RXBUFSYNC(sc, i, len + ETHER_CRC_LEN, BUS_DMASYNC_POSTREAD);
1744 memcpy(mtod(m, void *), rxd->rxd_buf, MEC_ETHER_ALIGN + len); 1757 memcpy(mtod(m, void *), rxd->rxd_buf, MEC_ETHER_ALIGN + len);
 1758 crc = be32dec(rxd->rxd_buf + MEC_ETHER_ALIGN + len);
1745 MEC_RXBUFSYNC(sc, i, ETHER_MAX_LEN, BUS_DMASYNC_PREREAD); 1759 MEC_RXBUFSYNC(sc, i, ETHER_MAX_LEN, BUS_DMASYNC_PREREAD);
1746 m->m_data += MEC_ETHER_ALIGN; 1760 m->m_data += MEC_ETHER_ALIGN;
1747 1761
1748 /* put RX buffer into FIFO again */ 1762 /* put RX buffer into FIFO again */
1749 rxd->rxd_stat = 0; 1763 rxd->rxd_stat = 0;
1750 MEC_RXSTATSYNC(sc, i, BUS_DMASYNC_PREREAD); 1764 MEC_RXSTATSYNC(sc, i, BUS_DMASYNC_PREREAD);
1751 bus_space_write_8(st, sh, MEC_MCL_RX_FIFO, MEC_CDRXADDR(sc, i)); 1765 bus_space_write_8(st, sh, MEC_MCL_RX_FIFO, MEC_CDRXADDR(sc, i));
1752 1766
1753 m->m_pkthdr.rcvif = ifp; 1767 m->m_pkthdr.rcvif = ifp;
1754 m->m_pkthdr.len = m->m_len = len; 1768 m->m_pkthdr.len = m->m_len = len;
 1769 if ((ifp->if_csum_flags_rx & (M_CSUM_TCPv4|M_CSUM_UDPv4)) != 0)
 1770 mec_rxcsum(sc, m, RXSTAT_CKSUM(rxstat), crc);
1755 1771
1756 ifp->if_ipackets++; 1772 ifp->if_ipackets++;
1757 1773
1758#if NBPFILTER > 0 1774#if NBPFILTER > 0
1759 /* 1775 /*
1760 * Pass this up to any BPF listeners, but only 1776 * Pass this up to any BPF listeners, but only
1761 * pass it up the stack if it's for us. 1777 * pass it up the stack if it's for us.
1762 */ 1778 */
1763 if (ifp->if_bpf) 1779 if (ifp->if_bpf)
1764 bpf_mtap(ifp->if_bpf, m); 1780 bpf_mtap(ifp->if_bpf, m);
1765#endif 1781#endif
1766 1782
1767 /* Pass it on. */ 1783 /* Pass it on. */
1768 (*ifp->if_input)(ifp, m); 1784 (*ifp->if_input)(ifp, m);
1769 } 1785 }
1770 1786
1771 /* update RX pointer */ 1787 /* update RX pointer */
1772 sc->sc_rxptr = i; 1788 sc->sc_rxptr = i;
1773} 1789}
1774 1790
1775static void 1791static void
 1792mec_rxcsum(struct mec_softc *sc, struct mbuf *m, uint16_t rxcsum, uint32_t crc)
 1793{
 1794 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
 1795 struct ether_header *eh;
 1796 struct ip *ip;
 1797 struct udphdr *uh;
 1798 u_int len, pktlen, hlen;
 1799 uint32_t csum_data, dsum;
 1800 int csum_flags;
 1801 const uint16_t *dp;
 1802
 1803 csum_data = 0;
 1804 csum_flags = 0;
 1805
 1806 len = m->m_len;
 1807 if (len < ETHER_HDR_LEN + sizeof(struct ip))
 1808 goto out;
 1809 pktlen = len - ETHER_HDR_LEN;
 1810 eh = mtod(m, struct ether_header *);
 1811 if (ntohs(eh->ether_type) != ETHERTYPE_IP)
 1812 goto out;
 1813 ip = (struct ip *)((uint8_t *)eh + ETHER_HDR_LEN);
 1814 if (ip->ip_v != IPVERSION)
 1815 goto out;
 1816
 1817 hlen = ip->ip_hl << 2;
 1818 if (hlen < sizeof(struct ip))
 1819 goto out;
 1820
 1821 /*
 1822 * Bail if too short, has random trailing garbage, truncated,
 1823 * fragment, or has ethernet pad.
 1824 */
 1825 if (ntohs(ip->ip_len) < hlen ||
 1826 ntohs(ip->ip_len) != pktlen ||
 1827 (ntohs(ip->ip_off) & (IP_MF | IP_OFFMASK)) != 0)
 1828 goto out;
 1829
 1830 switch (ip->ip_p) {
 1831 case IPPROTO_TCP:
 1832 if ((ifp->if_csum_flags_rx & M_CSUM_TCPv4) == 0 ||
 1833 pktlen < (hlen + sizeof(struct tcphdr)))
 1834 goto out;
 1835 csum_flags = M_CSUM_TCPv4 | M_CSUM_DATA | M_CSUM_NO_PSEUDOHDR;
 1836 break;
 1837 case IPPROTO_UDP:
 1838 if ((ifp->if_csum_flags_rx & M_CSUM_UDPv4) == 0 ||
 1839 pktlen < (hlen + sizeof(struct udphdr)))
 1840 goto out;
 1841 uh = (struct udphdr *)((uint8_t *)ip + hlen);
 1842 if (uh->uh_sum == 0)
 1843 goto out; /* no checksum */
 1844 csum_flags = M_CSUM_UDPv4 | M_CSUM_DATA | M_CSUM_NO_PSEUDOHDR;
 1845 break;
 1846 default:
 1847 goto out;
 1848 }
 1849
 1850 /*
 1851 * The computed checksum includes Ethernet header, IP headers,
 1852 * and CRC, so we have to deduct them.
 1853 * Note IP header cksum should be 0xffff so we don't have to
 1854 * dedecut them.
 1855 */
 1856 dsum = 0;
 1857
 1858 /* deduct Ethernet header */
 1859 dp = (const uint16_t *)eh;
 1860 for (hlen = 0; hlen < (ETHER_HDR_LEN / sizeof(uint16_t)); hlen++)
 1861 dsum += ntohs(*dp++);
 1862
 1863 /* deduct CRC */
 1864 if (len & 1) {
 1865 dsum += (crc >> 24) & 0x00ff;
 1866 dsum += (crc >> 8) & 0xffff;
 1867 dsum += (crc << 8) & 0xff00;
 1868 } else {
 1869 dsum += (crc >> 16) & 0xffff;
 1870 dsum += (crc >> 0) & 0xffff;
 1871 }
 1872 while (dsum >> 16)
 1873 dsum = (dsum >> 16) + (dsum & 0xffff);
 1874
 1875 csum_data = rxcsum;
 1876 csum_data += (uint16_t)~dsum;
 1877
 1878 while (csum_data >> 16)
 1879 csum_data = (csum_data >> 16) + (csum_data & 0xffff);
 1880
 1881 out:
 1882 m->m_pkthdr.csum_flags = csum_flags;
 1883 m->m_pkthdr.csum_data = csum_data;
 1884}
 1885
 1886static void
1776mec_txintr(struct mec_softc *sc, uint32_t txptr) 1887mec_txintr(struct mec_softc *sc, uint32_t txptr)
1777{ 1888{
1778 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1889 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1779 struct mec_txdesc *txd; 1890 struct mec_txdesc *txd;
1780 struct mec_txsoft *txs; 1891 struct mec_txsoft *txs;
1781 bus_dmamap_t dmamap; 1892 bus_dmamap_t dmamap;
1782 uint64_t txstat; 1893 uint64_t txstat;
1783 int i; 1894 int i;
1784 u_int col; 1895 u_int col;
1785 1896
1786 DPRINTF(MEC_DEBUG_TXINTR, ("mec_txintr: called\n")); 1897 DPRINTF(MEC_DEBUG_TXINTR, ("mec_txintr: called\n"));
1787 1898
1788 for (i = sc->sc_txdirty; i != txptr && sc->sc_txpending != 0; 1899 for (i = sc->sc_txdirty; i != txptr && sc->sc_txpending != 0;