diff --git a/Makefile b/Makefile index ee9bd81d..47ae62f3 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ include $(PROJECT_ROOT)/make/leaf.cfg CFLAGS += -ffreestanding CFLAGS += -I . CFLAGS += -I rtemsbsd +CFLAGS += -I freebsd/$(RTEMS_CPU)/include CFLAGS += -I contrib/altq CFLAGS += -I contrib/pf CFLAGS += -B $(INSTALL_BASE) @@ -14,6 +15,7 @@ CFLAGS += -w CFLAGS += -std=gnu99 C_FILES = \ + freebsd/kern/kern_subr.c \ freebsd/net/bridgestp.c \ freebsd/net/ieee8023ad_lacp.c \ freebsd/net/if_atmsubr.c \ @@ -66,7 +68,6 @@ C_FILES = \ freebsd/netinet/if_ether.c \ freebsd/netinet/igmp.c \ freebsd/netinet/in.c \ - freebsd/netinet/in_cksum.c \ freebsd/netinet/in_gif.c \ freebsd/netinet/in_mcast.c \ freebsd/netinet/in_pcb.c \ @@ -272,7 +273,6 @@ C_FILES = \ freebsd/kern/init_main.c \ freebsd/kern/kern_mbuf.c \ freebsd/kern/kern_module.c \ - freebsd/kern/kern_subr.c \ freebsd/kern/kern_sysctl.c \ freebsd/kern/subr_bus.c \ freebsd/kern/subr_kobj.c \ @@ -304,7 +304,9 @@ C_FILES = \ freebsd/dev/usb/controller/usb_controller.c \ freebsd/cam/cam.c \ freebsd/cam/scsi/scsi_all.c \ - freebsd/dev/usb/storage/umass.c \ + freebsd/dev/usb/storage/umass.c +# RTEMS Project Owned Files +C_FILES += \ rtemsbsd/dev/usb/controller/ohci_lpc3250.c \ rtemsbsd/src/rtems-bsd-cam.c \ rtemsbsd/src/rtems-bsd-nexus.c \ @@ -337,6 +339,12 @@ C_FILES = \ rtemsbsd/src/rtems-bsd-sysctlbyname.c \ rtemsbsd/src/rtems-bsd-sysctlnametomib.c \ rtemsbsd/src/rtems-bsd-uma.c + +ifeq ($(RTEMS_CPU),powerpc) +C_FILES += \ + freebsd/powerpc/powerpc/in_cksum.c +endif + C_O_FILES = $(C_FILES:%.c=%.o) C_DEP_FILES = $(C_FILES:%.c=%.dep) diff --git a/freebsd-to-rtems.py b/freebsd-to-rtems.py index 8f809714..87091c57 100755 --- a/freebsd-to-rtems.py +++ b/freebsd-to-rtems.py @@ -48,6 +48,7 @@ isDryRun = False isEarlyExit = False isOnlyMakefile = False tempFile = "/tmp/tmp_FBRT" +filesChanged = 0 def usage(): print "freebsd-to-rtems.py [args]" @@ -150,6 +151,21 @@ def mapContribPath(path): path = m.group(1) + m.group(3) + m.group(2) + m.group(4) return path +# Move target dependent files under a machine directory +def mapCPUDependentPath(path): + return path.replace("include/", "include/freebsd/machine/") + +# compare and overwrite destination file only if different +def copyIfDifferent(new, old): + global filesChanged + if not os.path.exists(old) or \ + filecmp.cmp(new, old, shallow=False) == False: + shutil.move(new, old) + filesChanged += 1 + # print "Move " + new + " to " + old + return True + return False + # generate an empty file as a place holder def installEmptyFile(src): global tempFile @@ -185,21 +201,14 @@ def revertFixIncludes(data): data = re.sub('#([ \t]*)include <' + PREFIX + '/', '#\\1include <', data) return data -# compare and overwrite destination file only if different -def copyIfDifferent(new, old): - if filecmp.cmp(new, old, shallow=False) == False: - shutil.move(new, old) - # print "Move " + new + " to " + old - return True - return False - - # Copy a header file from FreeBSD to the RTEMS BSD tree -def installHeaderFile(org): +def installHeaderFile(org, target): global tempFile src = FreeBSD_DIR + '/' + org dst = RTEMS_DIR + '/' + PREFIX + '/' + org # + org.replace('rtems/', '') dst = mapContribPath(dst) + if target != "generic": + dst = mapCPUDependentPath(dst) if isDryRun == True: if isVerbose == True: print "Install Header - " + src + " => " + dst @@ -245,7 +254,7 @@ def installSourceFile(org): print "Install Source - " + src + " => " + dst # Revert a header file from the RTEMS BSD tree to the FreeBSD tree -def revertHeaderFile(org): +def revertHeaderFile(org, target): src = RTEMS_DIR + '/' + PREFIX + '/' + org.replace('rtems/', '') src = mapContribPath(src) dst = FreeBSD_DIR + '/' + org @@ -257,6 +266,9 @@ def revertHeaderFile(org): os.makedirs(os.path.dirname(dst)) except OSError: pass + if target != "generic": + print "Do not yet know how to revert target dependent files" + sys.exit(1) data = open(src).read() out = open(dst, 'w') if org.find('rtems') == -1: @@ -292,7 +304,8 @@ def deleteOutputDirectory(): if isDryRun == True: return try: - shutil.rmtree(RTEMS_DIR) + print "Deleting output directory needs to be more precise" + #shutil.rmtree(RTEMS_DIR) except OSError: pass @@ -313,21 +326,22 @@ class ModuleManager: installEmptyFile(f) for m in self.modules: for f in m.headerFiles: - installHeaderFile(f) + installHeaderFile(f, m.target) for f in m.sourceFiles: installSourceFile(f) def revertFiles(self): for m in self.modules: for f in m.headerFiles: - revertHeaderFile(f) + revertHeaderFile(f, m.target) for f in m.sourceFiles: revertSourceFile(f) def createMakefile(self): - if isVerbose == True: - print "Create Makefile" + global tempFile if isDryRun == True: + if isVerbose == True: + print "Create Makefile" return data = 'include config.inc\n' \ '\n' \ @@ -338,6 +352,7 @@ class ModuleManager: 'CFLAGS += -ffreestanding \n' \ 'CFLAGS += -I . \n' \ 'CFLAGS += -I rtemsbsd \n' \ + 'CFLAGS += -I freebsd/$(RTEMS_CPU)/include \n' \ 'CFLAGS += -I contrib/altq \n' \ 'CFLAGS += -I contrib/pf \n' \ 'CFLAGS += -B $(INSTALL_BASE) \n' \ @@ -346,15 +361,32 @@ class ModuleManager: '\n' data += 'C_FILES =' for m in self.modules: - for f in m.sourceFiles: - f = PREFIX + '/' + f - f = mapContribPath(f) - data += ' \\\n\t' + f + if m.target == "generic": + for f in m.sourceFiles: + f = PREFIX + '/' + f + f = mapContribPath(f) + data += ' \\\n\t' + f + data += '\n' + data += '# RTEMS Project Owned Files\n' + data += 'C_FILES +=' for f in rtems_sourceFiles: - f = 'rtemsbsd/' + f - data += ' \\\n\t' + f + data += ' \\\n\trtemsbsd/' + f + data += '\n' + data += '\n' + for m in self.modules: + if m.target != "generic": + data += "ifeq ($(RTEMS_CPU)," + m.target + ")\n" + data += "C_FILES +=" + for f in m.sourceFiles: + f = PREFIX + '/' + f + f = mapContribPath(f) + data += ' \\\n\t' + f + data += '\n' + data += 'endif\n' + - data += '\nC_O_FILES = $(C_FILES:%.c=%.o)\n' \ + data += '\n' \ + 'C_O_FILES = $(C_FILES:%.c=%.o)\n' \ 'C_DEP_FILES = $(C_FILES:%.c=%.dep)\n' \ '\n' \ 'LIB = libbsd.a\n' \ @@ -380,18 +412,26 @@ class ModuleManager: '\trm -f $(LIB) $(C_O_FILES) $(C_DEP_FILES)\n' \ '\n' \ '-include $(C_DEP_FILES)\n' - out = open(RTEMS_DIR + '/Makefile', 'w') + out = open(tempFile, 'w') out.write(data) out.close() + makefile = RTEMS_DIR + '/Makefile' + if copyIfDifferent(tempFile, makefile) == True: + if isVerbose == True: + print "Create Makefile" # Module - logical group of related files we can perform actions on class Module: def __init__(self, name): self.name = name + self.target = "generic" self.headerFiles = [] self.sourceFiles = [] self.dependencies = [] + def setTarget(self, value): + self.target = value + def addHeaderFiles(self, files): self.headerFiles.extend(files) for file in files: @@ -403,7 +443,8 @@ class Module: def addSourceFiles(self, files): self.sourceFiles.extend(files) for file in files: - if file[-2] != '.' or file[-1] != 'c': + if file[-2] != '.' or \ + (file[-1] != 'c' and file[-1] != 'S'): print "*** " + file + " does not end in .c" print "*** Move it to a header file list" sys.exit(2) @@ -417,7 +458,6 @@ class Module: mm = ModuleManager() rtems_headerFiles = [ - 'rtems/machine/in_cksum.h', # logically a net file 'rtems/machine/atomic.h', 'rtems/machine/_bus.h', 'rtems/machine/bus.h', @@ -996,7 +1036,6 @@ devUsbBase.addSourceFiles( #'kern/kern_mib.c', 'kern/kern_mbuf.c', 'kern/kern_module.c', - 'kern/kern_subr.c', 'kern/kern_sysctl.c', 'kern/subr_bus.c', 'kern/subr_kobj.c', @@ -1059,7 +1098,6 @@ devNet.addSourceFiles( ) netDeps = Module('netDeps') -# logically machine/in_cksum.h is part of this group but RTEMS provides its own netDeps.addHeaderFiles( [ 'security/mac/mac_framework.h', @@ -1147,6 +1185,7 @@ net.addHeaderFiles( ) net.addSourceFiles( [ + 'kern/kern_subr.c', 'net/bridgestp.c', 'net/ieee8023ad_lacp.c', 'net/if_atmsubr.c', @@ -1271,6 +1310,7 @@ netinet.addHeaderFiles( 'netinet/libalias/alias_sctp.h', ] ) +# in_cksum.c is architecture dependent netinet.addSourceFiles( [ 'netinet/accf_data.c', @@ -1280,7 +1320,6 @@ netinet.addSourceFiles( 'netinet/if_ether.c', 'netinet/igmp.c', 'netinet/in.c', - 'netinet/in_cksum.c', 'netinet/in_gif.c', 'netinet/in_mcast.c', 'netinet/in_pcb.c', @@ -1639,6 +1678,7 @@ altq.addSourceFiles( ] ) +# contrib/pf Module pf = Module('pf') pf.addHeaderFiles( [ @@ -1664,6 +1704,78 @@ pf.addSourceFiles( ] ) +# ARM Architecture Specific Files Module +armDependent = Module('armDependent') +armDependent.setTarget("arm") +armDependent.addHeaderFiles( + [ + 'arm/include/in_cksum.h', + ] +) +armDependent.addSourceFiles( + [ + 'arm/arm/in_cksum.c', + 'arm/arm/in_cksum_arm.S', + ] +) + +# i386 Architecture Specific Files Module +i386Dependent = Module('i386Dependent') +i386Dependent.setTarget("i386") +i386Dependent.addHeaderFiles( + [ + 'i386/include/in_cksum.h', + ] +) +i386Dependent.addSourceFiles( + [ + 'i386/i386/in_cksum.c', + ] +) + +# MIPS Architecture Specific Files Module +mipsDependent = Module('mipsDependent') +mipsDependent.setTarget("mips") +mipsDependent.addHeaderFiles( + [ + 'mips/include/in_cksum.h', + ] +) +mipsDependent.addSourceFiles( + [ + 'mips/mips/in_cksum.c', + ] +) + +# PowerPC Architecture Specific Files Module +powerpcDependent = Module('powerpcDependent') +powerpcDependent.setTarget("powerpc") +powerpcDependent.addHeaderFiles( + [ + 'powerpc/include/in_cksum.h', + ] +) +powerpcDependent.addSourceFiles( + [ + 'powerpc/powerpc/in_cksum.c', + ] +) + +# SPARC64 Architecture Specific Files Module +sparc64Dependent = Module('cpu_dependent') +sparc64Dependent.setTarget("powerpc") +sparc64Dependent.addHeaderFiles( + [ + 'sparc64/include/in_cksum.h', + ] +) +sparc64Dependent.addSourceFiles( + [ + 'sparc64/sparc64/in_cksum.c', + ] +) + +# Add Empty Files mm.addEmptyFiles( [ 'cam/cam_queue.h', @@ -1731,7 +1843,6 @@ mm.addModule(altq) mm.addModule(pf) mm.addModule(devNet) -# mm.addModule(rtems) mm.addModule(local) mm.addModule(devUsbBase) mm.addModule(devUsb) @@ -1740,9 +1851,15 @@ mm.addModule(devUsbController) mm.addModule(cam) mm.addModule(devUsbStorage) - #mm.addModule(devUsbNet) +# Now add CPU Architecture Dependent Modules +#mm.addModule(armDependent) +#mm.addModule(i386Dependent) +#mm.addModule(mipsDependent) +mm.addModule(powerpcDependent) +#mm.addModule(sparc64Dependent) + # Perform the actual file manipulation if isForward == True: if isOnlyMakefile == False: @@ -1751,3 +1868,7 @@ if isForward == True: else: mm.revertFiles() +if filesChanged == 1: + print str(filesChanged) + " file was changed." +else: + print str(filesChanged) + " files were changed." diff --git a/freebsd/powerpc/include/freebsd/machine/in_cksum.h b/freebsd/powerpc/include/freebsd/machine/in_cksum.h new file mode 100644 index 00000000..25634a6e --- /dev/null +++ b/freebsd/powerpc/include/freebsd/machine/in_cksum.h @@ -0,0 +1,76 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from tahoe: in_cksum.c 1.2 86/01/05 + * from: @(#)in_cksum.c 1.3 (Berkeley) 1/19/91 + * from: Id: in_cksum.c,v 1.8 1995/12/03 18:35:19 bde Exp + * $FreeBSD$ + */ + +#ifndef _MACHINE_IN_CKSUM_HH_ +#define _MACHINE_IN_CKSUM_HH_ 1 + +#include + +#define in_cksum(m, len) in_cksum_skip(m, len, 0) + +/* + * It it useful to have an Internet checksum routine which is inlineable + * and optimized specifically for the task of computing IP header checksums + * in the normal case (where there are no options and the header length is + * therefore always exactly five 32-bit words. + */ +#ifdef __CC_SUPPORTS___INLINE + +static __inline void +in_cksum_update(struct ip *ip) +{ + int __tmpsum; + __tmpsum = (int)ntohs(ip->ip_sum) + 256; + ip->ip_sum = htons(__tmpsum + (__tmpsum >> 16)); +} + +#else + +#define in_cksum_update(ip) \ + do { \ + int __tmpsum; \ + __tmpsum = (int)ntohs(ip->ip_sum) + 256; \ + ip->ip_sum = htons(__tmpsum + (__tmpsum >> 16)); \ + } while(0) + +#endif + +#ifdef _KERNEL +u_int in_cksum_hdr(const struct ip *ip); +u_short in_addword(u_short sum, u_short b); +u_short in_pseudo(u_int sum, u_int b, u_int c); +u_short in_cksum_skip(struct mbuf *m, int len, int skip); +#endif + +#endif /* _MACHINE_IN_CKSUM_HH_ */ diff --git a/freebsd/powerpc/powerpc/in_cksum.c b/freebsd/powerpc/powerpc/in_cksum.c new file mode 100644 index 00000000..ede39fc3 --- /dev/null +++ b/freebsd/powerpc/powerpc/in_cksum.c @@ -0,0 +1,257 @@ +#include + +/* $FreeBSD$ */ +/* $NetBSD: in_cksum.c,v 1.7 1997/09/02 13:18:15 thorpej Exp $ */ + +/*- + * Copyright (c) 1988, 1992, 1993 + * The Regents of the University of California. All rights reserved. + * Copyright (c) 1996 + * Matt Thomas + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)in_cksum.c 8.1 (Berkeley) 6/10/93 + */ + +#include /* RCS ID & Copyright macro defns */ + +#include +#include +#include +#include +#include +#include +#include + +/* + * Checksum routine for Internet Protocol family headers + * (Portable Alpha version). + * + * This routine is very heavily used in the network + * code and should be modified for each CPU to be as fast as possible. + */ + +#define ADDCARRY(x) (x > 65535 ? x -= 65535 : x) +#define REDUCE32 \ + { \ + q_util.q = sum; \ + sum = q_util.s[0] + q_util.s[1] + q_util.s[2] + q_util.s[3]; \ + } +#define REDUCE16 \ + { \ + q_util.q = sum; \ + l_util.l = q_util.s[0] + q_util.s[1] + q_util.s[2] + q_util.s[3]; \ + sum = l_util.s[0] + l_util.s[1]; \ + ADDCARRY(sum); \ + } + +static const u_int32_t in_masks[] = { +#if 0 + /*0 bytes*/ /*1 byte*/ /*2 bytes*/ /*3 bytes*/ + 0x00000000, 0x000000FF, 0x0000FFFF, 0x00FFFFFF, /* offset 0 */ + 0x00000000, 0x0000FF00, 0x00FFFF00, 0xFFFFFF00, /* offset 1 */ + 0x00000000, 0x00FF0000, 0xFFFF0000, 0xFFFF0000, /* offset 2 */ + 0x00000000, 0xFF000000, 0xFF000000, 0xFF000000, /* offset 3 */ +#else + /*0 bytes*/ /*1 byte*/ /*2 bytes*/ /*3 bytes*/ + 0x00000000, 0xFF000000, 0xFFFF0000, 0xFFFFFF00, /* offset 0 */ + 0x00000000, 0x00FF0000, 0x00FFFF00, 0x00FFFFFF, /* offset 1 */ + 0x00000000, 0x0000FF00, 0x0000FFFF, 0x0000FFFF, /* offset 2 */ + 0x00000000, 0x000000FF, 0x000000FF, 0x000000FF, /* offset 3 */ +#endif +}; + +union l_util { + u_int16_t s[2]; + u_int32_t l; +}; +union q_util { + u_int16_t s[4]; + u_int32_t l[2]; + u_int64_t q; +}; + +static u_int64_t +in_cksumdata(const void *buf, int len) +{ + const u_int32_t *lw = (const u_int32_t *) buf; + u_int64_t sum = 0; + u_int64_t prefilled; + int offset; + union q_util q_util; + + if ((3 & (long) lw) == 0 && len == 20) { + sum = (u_int64_t) lw[0] + lw[1] + lw[2] + lw[3] + lw[4]; + REDUCE32; + return sum; + } + + if ((offset = 3 & (long) lw) != 0) { + const u_int32_t *masks = in_masks + (offset << 2); + lw = (u_int32_t *) (((long) lw) - offset); + sum = *lw++ & masks[len >= 3 ? 3 : len]; + len -= 4 - offset; + if (len <= 0) { + REDUCE32; + return sum; + } + } +#if 0 + /* + * Force to cache line boundary. + */ + offset = 32 - (0x1f & (long) lw); + if (offset < 32 && len > offset) { + len -= offset; + if (4 & offset) { + sum += (u_int64_t) lw[0]; + lw += 1; + } + if (8 & offset) { + sum += (u_int64_t) lw[0] + lw[1]; + lw += 2; + } + if (16 & offset) { + sum += (u_int64_t) lw[0] + lw[1] + lw[2] + lw[3]; + lw += 4; + } + } +#endif + /* + * access prefilling to start load of next cache line. + * then add current cache line + * save result of prefilling for loop iteration. + */ + prefilled = lw[0]; + while ((len -= 32) >= 4) { + u_int64_t prefilling = lw[8]; + sum += prefilled + lw[1] + lw[2] + lw[3] + + lw[4] + lw[5] + lw[6] + lw[7]; + lw += 8; + prefilled = prefilling; + } + if (len >= 0) { + sum += prefilled + lw[1] + lw[2] + lw[3] + + lw[4] + lw[5] + lw[6] + lw[7]; + lw += 8; + } else { + len += 32; + } + while ((len -= 16) >= 0) { + sum += (u_int64_t) lw[0] + lw[1] + lw[2] + lw[3]; + lw += 4; + } + len += 16; + while ((len -= 4) >= 0) { + sum += (u_int64_t) *lw++; + } + len += 4; + if (len > 0) + sum += (u_int64_t) (in_masks[len] & *lw); + REDUCE32; + return sum; +} + +u_short +in_addword(u_short a, u_short b) +{ + u_int64_t sum = a + b; + + ADDCARRY(sum); + return (sum); +} + +u_short +#ifdef __rtems__ +/* prototype does not match in FreeBSD code */ +in_pseudo(u_int a, u_int b, u_int c) +#else +in_pseudo(u_int32_t a, u_int32_t b, u_int32_t c) +#endif +{ + u_int64_t sum; + union q_util q_util; + union l_util l_util; + + sum = (u_int64_t) a + b + c; + REDUCE16; + return (sum); +} + +u_short +in_cksum_skip(struct mbuf *m, int len, int skip) +{ + u_int64_t sum = 0; + int mlen = 0; + int clen = 0; + caddr_t addr; + union q_util q_util; + union l_util l_util; + + len -= skip; + for (; skip && m; m = m->m_next) { + if (m->m_len > skip) { + mlen = m->m_len - skip; + addr = mtod(m, caddr_t) + skip; + goto skip_start; + } else { + skip -= m->m_len; + } + } + + for (; m && len; m = m->m_next) { + if (m->m_len == 0) + continue; + mlen = m->m_len; + addr = mtod(m, caddr_t); +skip_start: + if (len < mlen) + mlen = len; + + if ((clen ^ (int) addr) & 1) + sum += in_cksumdata(addr, mlen) << 8; + else + sum += in_cksumdata(addr, mlen); + + clen += mlen; + len -= mlen; + } + REDUCE16; + return (~sum & 0xffff); +} + +u_int in_cksum_hdr(const struct ip *ip) +{ + u_int64_t sum = in_cksumdata(ip, sizeof(struct ip)); + union q_util q_util; + union l_util l_util; + REDUCE16; + return (~sum & 0xffff); +}