[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

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