[BACK]Return to in_cksum.c CVS log [TXT][DIR] Up to [local] / sys / arch / powerpc / powerpc

Annotation of sys/arch/powerpc/powerpc/in_cksum.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: in_cksum.c,v 1.7 2005/05/02 02:39:45 brad Exp $       */
        !             2: /*     $NetBSD: in_cksum.c,v 1.7 2003/07/15 02:54:48 lukem Exp $       */
        !             3:
        !             4: /*
        !             5:  * Copyright 2001 Wasabi Systems, Inc.
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * Written by Simon Burge and Eduardo Horvath for Wasabi Systems, Inc.
        !             9:  *
        !            10:  * Redistribution and use in source and binary forms, with or without
        !            11:  * modification, are permitted provided that the following conditions
        !            12:  * are met:
        !            13:  * 1. Redistributions of source code must retain the above copyright
        !            14:  *    notice, this list of conditions and the following disclaimer.
        !            15:  * 2. Redistributions in binary form must reproduce the above copyright
        !            16:  *    notice, this list of conditions and the following disclaimer in the
        !            17:  *    documentation and/or other materials provided with the distribution.
        !            18:  * 3. All advertising materials mentioning features or use of this software
        !            19:  *    must display the following acknowledgement:
        !            20:  *      This product includes software developed for the NetBSD Project by
        !            21:  *      Wasabi Systems, Inc.
        !            22:  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
        !            23:  *    or promote products derived from this software without specific prior
        !            24:  *    written permission.
        !            25:  *
        !            26:  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
        !            27:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
        !            28:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        !            29:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
        !            30:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        !            31:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        !            32:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
        !            33:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
        !            34:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        !            35:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            36:  * POSSIBILITY OF SUCH DAMAGE.
        !            37:  */
        !            38:
        !            39: #if 0
        !            40: #include <sys/cdefs.h>
        !            41: __KERNEL_RCSID(0, "$NetBSD: in_cksum.c,v 1.7 2003/07/15 02:54:48 lukem Exp $");
        !            42: #endif
        !            43:
        !            44: #include <sys/param.h>
        !            45: #include <sys/systm.h>
        !            46: #include <sys/mbuf.h>
        !            47: #include <sys/socketvar.h>
        !            48: #include <netinet/in.h>
        !            49: #include <netinet/in_systm.h>
        !            50: #include <netinet/ip.h>
        !            51: #include <netinet/ip_var.h>
        !            52:
        !            53: /*
        !            54:  * Checksum routine for Internet Protocol family headers.
        !            55:  *
        !            56:  * This routine is very heavily used in the network
        !            57:  * code and should be modified for each CPU to be as fast as possible.
        !            58:  *
        !            59:  * PowerPC version.
        !            60:  */
        !            61:
        !            62: #define        REDUCE1         sum = (sum & 0xffff) + (sum >> 16)
        !            63: /* Two REDUCE1s is faster than REDUCE1; if (sum > 65535) sum -= 65536; */
        !            64: #define        REDUCE          { REDUCE1; REDUCE1; }
        !            65:
        !            66: static __inline__ int
        !            67: in_cksum_internal(struct mbuf *m, int off, int len, u_int sum)
        !            68: {
        !            69:        uint8_t *w;
        !            70:        int mlen = 0;
        !            71:        int byte_swapped = 0;
        !            72:        int n;
        !            73:
        !            74:        union {
        !            75:                uint8_t  c[2];
        !            76:                uint16_t s;
        !            77:        } s_util;
        !            78:
        !            79:        for (;m && len; m = m->m_next) {
        !            80:                if (m->m_len == 0)
        !            81:                        continue;
        !            82:                w = mtod(m, uint8_t *) + off;
        !            83:
        !            84:                /*
        !            85:                 * 'off' can only be non-zero on the first pass of this
        !            86:                 * loop when mlen != -1, so we don't need to worry about
        !            87:                 * 'off' in the if clause below.
        !            88:                 */
        !            89:                if (mlen == -1) {
        !            90:                        /*
        !            91:                         * The first byte of this mbuf is the continuation
        !            92:                         * of a word spanning between this mbuf and the
        !            93:                         * last mbuf.
        !            94:                         *
        !            95:                         * s_util.c[0] is already saved when scanning previous
        !            96:                         * mbuf.
        !            97:                         */
        !            98:                        s_util.c[1] = *w++;
        !            99:                        sum += s_util.s;
        !           100:                        mlen = m->m_len - 1;
        !           101:                        len--;
        !           102:                } else {
        !           103:                        mlen = m->m_len - off;
        !           104:                        off = 0;
        !           105:                }
        !           106:                if (len < mlen)
        !           107:                        mlen = len;
        !           108:                len -= mlen;
        !           109:
        !           110:                /*
        !           111:                 * Force to a word boundary.
        !           112:                 */
        !           113:                if ((3 & (long) w) && (mlen > 0)) {
        !           114:                        if ((1 & (long) w)) {
        !           115:                                REDUCE;
        !           116:                                sum <<= 8;
        !           117:                                s_util.c[0] = *w++;
        !           118:                                mlen--;
        !           119:                                byte_swapped = 1;
        !           120:                        }
        !           121:                        if ((2 & (long) w) && (mlen > 1)) {
        !           122:                                /*
        !           123:                                 * Since the `sum' may contain full 32 bit
        !           124:                                 * value, we can't simply add any value.
        !           125:                                 */
        !           126:                                __asm __volatile(
        !           127:                                    "lhz 7,0(%1);"      /* load current data
        !           128:                                                           half word */
        !           129:                                    "addc %0,%0,7;"     /* add to sum */
        !           130:                                    "addze %0,%0;"      /* add carry bit */
        !           131:                                    : "+r"(sum)
        !           132:                                    : "b"(w)
        !           133:                                    : "7");             /* clobber r7 */
        !           134:                                w += 2;
        !           135:                                mlen -= 2;
        !           136:                        }
        !           137:                }
        !           138:
        !           139:                if (mlen >= 64) {
        !           140:                        n = mlen >> 6;
        !           141:                        __asm __volatile(
        !           142:                            "addic 0,0,0;"              /* clear carry */
        !           143:                            "mtctr %1;"                 /* load loop count */
        !           144:                            "1:"
        !           145:                            "lwz 7,4(%2);"              /* load current data
        !           146:                                                           word */
        !           147:                            "lwz 8,8(%2);"
        !           148:                            "lwz 9,12(%2);"
        !           149:                            "lwz 10,16(%2);"
        !           150:                            "adde %0,%0,7;"             /* add to sum */
        !           151:                            "adde %0,%0,8;"
        !           152:                            "adde %0,%0,9;"
        !           153:                            "adde %0,%0,10;"
        !           154:                            "lwz 7,20(%2);"
        !           155:                            "lwz 8,24(%2);"
        !           156:                            "lwz 9,28(%2);"
        !           157:                            "lwz 10,32(%2);"
        !           158:                            "adde %0,%0,7;"
        !           159:                            "adde %0,%0,8;"
        !           160:                            "adde %0,%0,9;"
        !           161:                            "adde %0,%0,10;"
        !           162:                            "lwz 7,36(%2);"
        !           163:                            "lwz 8,40(%2);"
        !           164:                            "lwz 9,44(%2);"
        !           165:                            "lwz 10,48(%2);"
        !           166:                            "adde %0,%0,7;"
        !           167:                            "adde %0,%0,8;"
        !           168:                            "adde %0,%0,9;"
        !           169:                            "adde %0,%0,10;"
        !           170:                            "lwz 7,52(%2);"
        !           171:                            "lwz 8,56(%2);"
        !           172:                            "lwz 9,60(%2);"
        !           173:                            "lwzu 10,64(%2);"
        !           174:                            "adde %0,%0,7;"
        !           175:                            "adde %0,%0,8;"
        !           176:                            "adde %0,%0,9;"
        !           177:                            "adde %0,%0,10;"
        !           178:                            "bdnz 1b;"                  /* loop */
        !           179:                            "addze %0,%0;"              /* add carry bit */
        !           180:                            : "+r"(sum)
        !           181:                            : "r"(n), "b"(w - 4)
        !           182:                            : "7", "8", "9", "10");     /* clobber r7, r8, r9,
        !           183:                                                           r10 */
        !           184:                        w += n * 64;
        !           185:                        mlen -= n * 64;
        !           186:                }
        !           187:
        !           188:                if (mlen >= 8) {
        !           189:                        n = mlen >> 3;
        !           190:                        __asm __volatile(
        !           191:                            "addic 0,0,0;"              /* clear carry */
        !           192:                            "mtctr %1;"                 /* load loop count */
        !           193:                            "1:"
        !           194:                            "lwz 7,4(%2);"              /* load current data
        !           195:                                                           word */
        !           196:                            "lwzu 8,8(%2);"
        !           197:                            "adde %0,%0,7;"             /* add to sum */
        !           198:                            "adde %0,%0,8;"
        !           199:                            "bdnz 1b;"                  /* loop */
        !           200:                            "addze %0,%0;"              /* add carry bit */
        !           201:                            : "+r"(sum)
        !           202:                            : "r"(n), "b"(w - 4)
        !           203:                            : "7", "8");                /* clobber r7, r8 */
        !           204:                        w += n * 8;
        !           205:                        mlen -= n * 8;
        !           206:                }
        !           207:
        !           208:                if (mlen == 0 && byte_swapped == 0)
        !           209:                        continue;
        !           210:                REDUCE;
        !           211:
        !           212:                while ((mlen -= 2) >= 0) {
        !           213:                        sum += *(uint16_t *)w;
        !           214:                        w += 2;
        !           215:                }
        !           216:
        !           217:                if (byte_swapped) {
        !           218:                        REDUCE;
        !           219:                        sum <<= 8;
        !           220:                        byte_swapped = 0;
        !           221:                        if (mlen == -1) {
        !           222:                                s_util.c[1] = *w;
        !           223:                                sum += s_util.s;
        !           224:                                mlen = 0;
        !           225:                        } else
        !           226:                                mlen = -1;
        !           227:                } else if (mlen == -1)
        !           228:                        s_util.c[0] = *w;
        !           229:        }
        !           230:        if (len)
        !           231:                printf("cksum: out of data\n");
        !           232:        if (mlen == -1) {
        !           233:                /* The last mbuf has odd # of bytes. Follow the
        !           234:                   standard (the odd byte may be shifted left by 8 bits
        !           235:                   or not as determined by endian-ness of the machine) */
        !           236:                s_util.c[1] = 0;
        !           237:                sum += s_util.s;
        !           238:        }
        !           239:        REDUCE;
        !           240:        return (~sum & 0xffff);
        !           241: }
        !           242:
        !           243: int
        !           244: in_cksum(struct mbuf *m, int len)
        !           245: {
        !           246:
        !           247:        return (in_cksum_internal(m, 0, len, 0));
        !           248: }
        !           249:
        !           250: int
        !           251: in4_cksum(struct mbuf *m, uint8_t nxt, int off, int len)
        !           252: {
        !           253:        uint16_t *w;
        !           254:        u_int sum = 0;
        !           255:        union {
        !           256:                struct ipovly ipov;
        !           257:                u_int16_t w[10];
        !           258:        } u;
        !           259:
        !           260:        if (nxt != 0) {
        !           261:                /* pseudo header */
        !           262:                memset(&u.ipov, 0, sizeof(u.ipov));
        !           263:                u.ipov.ih_len = htons(len);
        !           264:                u.ipov.ih_pr = nxt;
        !           265:                u.ipov.ih_src = mtod(m, struct ip *)->ip_src;
        !           266:                u.ipov.ih_dst = mtod(m, struct ip *)->ip_dst;
        !           267:                w = u.w;
        !           268:                /* assumes sizeof(ipov) == 20 */
        !           269:                sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3]; sum += w[4];
        !           270:                sum += w[5]; sum += w[6]; sum += w[7]; sum += w[8]; sum += w[9];
        !           271:        }
        !           272:
        !           273:        /* skip unnecessary part */
        !           274:        while (m && off > 0) {
        !           275:                if (m->m_len > off)
        !           276:                        break;
        !           277:                off -= m->m_len;
        !           278:                m = m->m_next;
        !           279:        }
        !           280:
        !           281:        return (in_cksum_internal(m, off, len, sum));
        !           282: }

CVSweb