Fix a bug in calculation of checksum deduction: - To get 16 bit one's complement value from uint32_t variable, higher 16 bits should be ignored. - RFC 1624 describes methods to recalculate checksum field in headers, i.e. one's complement of one's complement sum that could be 0x0000, but we don't have to use the strategy to deduct one's complement sum itself which won't be zero but should be 0xffff. Found on debugging mec(4) on sgimips O2.diff -r1.82 -r1.83 src/sys/dev/ic/gem.c
(tsutsui)
--- src/sys/dev/ic/gem.c 2009/03/14 21:04:19 1.82
+++ src/sys/dev/ic/gem.c 2009/03/16 12:02:00 1.83
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: gem.c,v 1.82 2009/03/14 21:04:19 dsl Exp $ */ | 1 | /* $NetBSD: gem.c,v 1.83 2009/03/16 12:02:00 tsutsui Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * | 4 | * | |
5 | * Copyright (C) 2001 Eduardo Horvath. | 5 | * Copyright (C) 2001 Eduardo Horvath. | |
6 | * Copyright (c) 2001-2003 Thomas Moestl | 6 | * Copyright (c) 2001-2003 Thomas Moestl | |
7 | * All rights reserved. | 7 | * All rights reserved. | |
8 | * | 8 | * | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -27,27 +27,27 @@ | @@ -27,27 +27,27 @@ | |||
27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
29 | * SUCH DAMAGE. | 29 | * SUCH DAMAGE. | |
30 | * | 30 | * | |
31 | */ | 31 | */ | |
32 | 32 | |||
33 | /* | 33 | /* | |
34 | * Driver for Apple GMAC, Sun ERI and Sun GEM Ethernet controllers | 34 | * Driver for Apple GMAC, Sun ERI and Sun GEM Ethernet controllers | |
35 | * See `GEM Gigabit Ethernet ASIC Specification' | 35 | * See `GEM Gigabit Ethernet ASIC Specification' | |
36 | * http://www.sun.com/processors/manuals/ge.pdf | 36 | * http://www.sun.com/processors/manuals/ge.pdf | |
37 | */ | 37 | */ | |
38 | 38 | |||
39 | #include <sys/cdefs.h> | 39 | #include <sys/cdefs.h> | |
40 | __KERNEL_RCSID(0, "$NetBSD: gem.c,v 1.82 2009/03/14 21:04:19 dsl Exp $"); | 40 | __KERNEL_RCSID(0, "$NetBSD: gem.c,v 1.83 2009/03/16 12:02:00 tsutsui Exp $"); | |
41 | 41 | |||
42 | #include "opt_inet.h" | 42 | #include "opt_inet.h" | |
43 | #include "bpfilter.h" | 43 | #include "bpfilter.h" | |
44 | 44 | |||
45 | #include <sys/param.h> | 45 | #include <sys/param.h> | |
46 | #include <sys/systm.h> | 46 | #include <sys/systm.h> | |
47 | #include <sys/callout.h> | 47 | #include <sys/callout.h> | |
48 | #include <sys/mbuf.h> | 48 | #include <sys/mbuf.h> | |
49 | #include <sys/syslog.h> | 49 | #include <sys/syslog.h> | |
50 | #include <sys/malloc.h> | 50 | #include <sys/malloc.h> | |
51 | #include <sys/kernel.h> | 51 | #include <sys/kernel.h> | |
52 | #include <sys/socket.h> | 52 | #include <sys/socket.h> | |
53 | #include <sys/ioctl.h> | 53 | #include <sys/ioctl.h> | |
@@ -1834,29 +1834,28 @@ gem_rint(struct gem_softc *sc) | @@ -1834,29 +1834,28 @@ gem_rint(struct gem_softc *sc) | |||
1834 | optsum = 0; | 1834 | optsum = 0; | |
1835 | temp = hlen - sizeof(struct ip); | 1835 | temp = hlen - sizeof(struct ip); | |
1836 | opts = (uint16_t *) ((char *) ip + | 1836 | opts = (uint16_t *) ((char *) ip + | |
1837 | sizeof(struct ip)); | 1837 | sizeof(struct ip)); | |
1838 | 1838 | |||
1839 | while (temp > 1) { | 1839 | while (temp > 1) { | |
1840 | optsum += ntohs(*opts++); | 1840 | optsum += ntohs(*opts++); | |
1841 | temp -= 2; | 1841 | temp -= 2; | |
1842 | } | 1842 | } | |
1843 | while (optsum >> 16) | 1843 | while (optsum >> 16) | |
1844 | optsum = (optsum >> 16) + | 1844 | optsum = (optsum >> 16) + | |
1845 | (optsum & 0xffff); | 1845 | (optsum & 0xffff); | |
1846 | 1846 | |||
1847 | /* Deduct ip opts sum from hwsum (rfc 1624). */ | 1847 | /* Deduct ip opts sum from hwsum. */ | |
1848 | m->m_pkthdr.csum_data = | 1848 | m->m_pkthdr.csum_data += (uint16_t)~optsum; | |
1849 | ~((~m->m_pkthdr.csum_data) - ~optsum); | |||
1850 | 1849 | |||
1851 | while (m->m_pkthdr.csum_data >> 16) | 1850 | while (m->m_pkthdr.csum_data >> 16) | |
1852 | m->m_pkthdr.csum_data = | 1851 | m->m_pkthdr.csum_data = | |
1853 | (m->m_pkthdr.csum_data >> 16) + | 1852 | (m->m_pkthdr.csum_data >> 16) + | |
1854 | (m->m_pkthdr.csum_data & | 1853 | (m->m_pkthdr.csum_data & | |
1855 | 0xffff); | 1854 | 0xffff); | |
1856 | } | 1855 | } | |
1857 | 1856 | |||
1858 | m->m_pkthdr.csum_flags |= M_CSUM_DATA | | 1857 | m->m_pkthdr.csum_flags |= M_CSUM_DATA | | |
1859 | M_CSUM_NO_PSEUDOHDR; | 1858 | M_CSUM_NO_PSEUDOHDR; | |
1860 | } else | 1859 | } else | |
1861 | swcsum: | 1860 | swcsum: | |
1862 | m->m_pkthdr.csum_flags = 0; | 1861 | m->m_pkthdr.csum_flags = 0; |
--- src/sys/dev/ic/hme.c 2009/03/14 21:04:20 1.72
+++ src/sys/dev/ic/hme.c 2009/03/16 12:02:00 1.73
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: hme.c,v 1.72 2009/03/14 21:04:20 dsl Exp $ */ | 1 | /* $NetBSD: hme.c,v 1.73 2009/03/16 12:02:00 tsutsui Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 1999 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 1999 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Paul Kranenburg. | 8 | * by Paul Kranenburg. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -24,27 +24,27 @@ | @@ -24,27 +24,27 @@ | |||
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
29 | * POSSIBILITY OF SUCH DAMAGE. | 29 | * POSSIBILITY OF SUCH DAMAGE. | |
30 | */ | 30 | */ | |
31 | 31 | |||
32 | /* | 32 | /* | |
33 | * HME Ethernet module driver. | 33 | * HME Ethernet module driver. | |
34 | */ | 34 | */ | |
35 | 35 | |||
36 | #include <sys/cdefs.h> | 36 | #include <sys/cdefs.h> | |
37 | __KERNEL_RCSID(0, "$NetBSD: hme.c,v 1.72 2009/03/14 21:04:20 dsl Exp $"); | 37 | __KERNEL_RCSID(0, "$NetBSD: hme.c,v 1.73 2009/03/16 12:02:00 tsutsui Exp $"); | |
38 | 38 | |||
39 | /* #define HMEDEBUG */ | 39 | /* #define HMEDEBUG */ | |
40 | 40 | |||
41 | #include "opt_inet.h" | 41 | #include "opt_inet.h" | |
42 | #include "bpfilter.h" | 42 | #include "bpfilter.h" | |
43 | #include "rnd.h" | 43 | #include "rnd.h" | |
44 | 44 | |||
45 | #include <sys/param.h> | 45 | #include <sys/param.h> | |
46 | #include <sys/systm.h> | 46 | #include <sys/systm.h> | |
47 | #include <sys/kernel.h> | 47 | #include <sys/kernel.h> | |
48 | #include <sys/mbuf.h> | 48 | #include <sys/mbuf.h> | |
49 | #include <sys/syslog.h> | 49 | #include <sys/syslog.h> | |
50 | #include <sys/socket.h> | 50 | #include <sys/socket.h> | |
@@ -787,29 +787,28 @@ hme_get(struct hme_softc *sc, int ri, u_ | @@ -787,29 +787,28 @@ hme_get(struct hme_softc *sc, int ri, u_ | |||
787 | uint32_t optsum; | 787 | uint32_t optsum; | |
788 | 788 | |||
789 | optsum = 0; | 789 | optsum = 0; | |
790 | temp = hlen - sizeof(struct ip); | 790 | temp = hlen - sizeof(struct ip); | |
791 | opts = (uint16_t *)((char *)ip + sizeof(struct ip)); | 791 | opts = (uint16_t *)((char *)ip + sizeof(struct ip)); | |
792 | 792 | |||
793 | while (temp > 1) { | 793 | while (temp > 1) { | |
794 | optsum += ntohs(*opts++); | 794 | optsum += ntohs(*opts++); | |
795 | temp -= 2; | 795 | temp -= 2; | |
796 | } | 796 | } | |
797 | while (optsum >> 16) | 797 | while (optsum >> 16) | |
798 | optsum = (optsum >> 16) + (optsum & 0xffff); | 798 | optsum = (optsum >> 16) + (optsum & 0xffff); | |
799 | 799 | |||
800 | /* Deduct the ip opts sum from the hwsum (rfc 1624). */ | 800 | /* Deduct the ip opts sum from the hwsum. */ | |
801 | m0->m_pkthdr.csum_data = ~((~m0->m_pkthdr.csum_data) - | 801 | m0->m_pkthdr.csum_data += (uint16_t)~optsum; | |
802 | ~optsum); | |||
803 | 802 | |||
804 | while (m0->m_pkthdr.csum_data >> 16) | 803 | while (m0->m_pkthdr.csum_data >> 16) | |
805 | m0->m_pkthdr.csum_data = | 804 | m0->m_pkthdr.csum_data = | |
806 | (m0->m_pkthdr.csum_data >> 16) + | 805 | (m0->m_pkthdr.csum_data >> 16) + | |
807 | (m0->m_pkthdr.csum_data & 0xffff); | 806 | (m0->m_pkthdr.csum_data & 0xffff); | |
808 | } | 807 | } | |
809 | 808 | |||
810 | m0->m_pkthdr.csum_flags |= M_CSUM_DATA | M_CSUM_NO_PSEUDOHDR; | 809 | m0->m_pkthdr.csum_flags |= M_CSUM_DATA | M_CSUM_NO_PSEUDOHDR; | |
811 | } else | 810 | } else | |
812 | swcsum: | 811 | swcsum: | |
813 | m0->m_pkthdr.csum_flags = 0; | 812 | m0->m_pkthdr.csum_flags = 0; | |
814 | #endif | 813 | #endif | |
815 | 814 |