Annotation of 43BSDReno/sys/tahoe/in_cksum.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1982, 1988 Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution is only permitted until one year after the first shipment
                      6:  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
                      7:  * binary forms are permitted provided that: (1) source distributions retain
                      8:  * this entire copyright notice and comment, and (2) distributions including
                      9:  * binaries display the following acknowledgement:  This product includes
                     10:  * software developed by the University of California, Berkeley and its
                     11:  * contributors'' in the documentation or other materials provided with the
                     12:  * distribution and in all advertising materials mentioning features or use
                     13:  * of this software.  Neither the name of the University nor the names of
                     14:  * its contributors may be used to endorse or promote products derived from
                     15:  * this software without specific prior written permission.
                     16:  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
                     17:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
                     18:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     19:  *
                     20:  *     @(#)in_cksum.c  7.5 (Berkeley) 6/28/90
                     21:  */
                     22: 
                     23: #include "param.h"
                     24: #include "mbuf.h"
                     25: 
                     26: /*
                     27:  * Checksum routine for Internet Protocol family headers (CCI Version).
                     28:  *
                     29:  * This routine is very heavily used in the network
                     30:  * code and should be modified for each CPU to be as fast as possible.
                     31:  */
                     32: 
                     33: #define ADDCARRY(x)  { if ((x) > 65535) (x) -= 65535; }
                     34: #define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);}
                     35: 
                     36: #define ADD(n) asm("adwc n (r10),r9")
                     37: #define MOP    asm("adwc $0,r9")
                     38: #define BOTCH  asm("addl2 r7,r9")
                     39: 
                     40: in_cksum(m, len)
                     41:        register struct mbuf *m;
                     42:        register int len;
                     43: {
                     44:        register u_short *w;            /* On CCI, known to be r10 */
                     45:        register int sum = 0;           /* On CCI, known to be r9 */
                     46:        register int mlen = 0;
                     47: #ifndef lint
                     48:        register int ClearCarry = 0;    /* On CCI, known to be r7; see BOTCH */
                     49: #endif
                     50:        int byte_swapped = 0;
                     51: 
                     52:        union {
                     53:                char    c[2];
                     54:                u_short s;
                     55:        } s_util;
                     56:        union {
                     57:                u_short s[2];
                     58:                long    l;
                     59:        } l_util;
                     60: 
                     61:        for (;m && len; m = m->m_next) {
                     62:                if (m->m_len == 0)
                     63:                        continue;
                     64:                w = mtod(m, u_short *);
                     65:                if (mlen == -1) {
                     66:                        /*
                     67:                         * The first byte of this mbuf is the continuation
                     68:                         * of a word spanning between this mbuf and the
                     69:                         * last mbuf.
                     70:                         *
                     71:                         * s_util.c[0] is already saved when scanning previous 
                     72:                         * mbuf.  sum was REDUCEd when we found mlen == -1.
                     73:                         */
                     74:                        s_util.c[1] = *(char *)w;
                     75:                        sum += s_util.s;
                     76:                        w = (u_short *)((char *)w + 1);
                     77:                        mlen = m->m_len - 1;
                     78:                        len--;
                     79:                } else
                     80:                        mlen = m->m_len;
                     81:                if (len < mlen)
                     82:                        mlen = len;
                     83:                len -= mlen;
                     84:                /*
                     85:                 * Force to long boundary so we do longword aligned
                     86:                 * memory operations.
                     87:                 */
                     88:                if (3 & (int) w) {
                     89:                        REDUCE;
                     90:                        if ((1 & (int) w) && (mlen > 0)) {
                     91:                                sum <<= 8;
                     92:                                s_util.c[0] = *(char *)w;
                     93:                                w = (u_short *)((char *)w + 1);
                     94:                                mlen--;
                     95:                                byte_swapped = 1;
                     96:                        }
                     97:                        if ((2 & (int) w) && (mlen >= 2)) {
                     98:                                sum += *w++;
                     99:                                mlen -= 2;
                    100:                        }
                    101:                }
                    102:                /*
                    103:                 * Do as much of the checksum as possible 32 bits at at time.
                    104:                 * In fact, this loop is unrolled to make overhead from
                    105:                 * branches &c small.
                    106:                 */
                    107:                while ((mlen -= 32) >= 0) {
                    108:                        /*
                    109:                         * The loop construct clears carry for us
                    110:                         * on vaxen, however, on the CCI machine subtracting
                    111:                         * a small postive number from a larger one doesn't.
                    112:                         * 
                    113:                         * Doing a bicpsw is very slow (slows down the routine
                    114:                         * by a factor of 2); explicitly adding an immediate
                    115:                         * 0 to a register is optimized out; so we fake out
                    116:                         * the optimizer and add a register whose contents
                    117:                         * is always zero.
                    118:                         */
                    119:                        BOTCH;
                    120:                        ADD(0); ADD(4); ADD(8); ADD(12);
                    121:                        ADD(16); ADD(20); ADD(24); ADD(28);
                    122:                        MOP; w += 16;
                    123:                }
                    124:                mlen += 32;
                    125:                while ((mlen -= 8) >= 0) {
                    126:                        BOTCH;
                    127:                        ADD(0); ADD(4);
                    128:                        MOP;
                    129:                        w += 4;
                    130:                }
                    131:                mlen += 8;
                    132:                if (mlen == 0 && byte_swapped == 0)
                    133:                        continue;       /* worth 1% maybe ?? */
                    134:                REDUCE;
                    135:                while ((mlen -= 2) >= 0) {
                    136:                        sum += *w++;
                    137:                }
                    138:                if (byte_swapped) {
                    139:                        sum <<= 8;
                    140:                        byte_swapped = 0;
                    141:                        if (mlen == -1) {
                    142:                                s_util.c[1] = *(char *)w;
                    143:                                sum += s_util.s;
                    144:                                mlen = 0;
                    145:                        } else
                    146:                                mlen = -1;
                    147:                } else if (mlen == -1)
                    148:                        /*
                    149:                         * This mbuf has odd number of bytes. 
                    150:                         * There could be a word split betwen
                    151:                         * this mbuf and the next mbuf.
                    152:                         * Save the last byte (to prepend to next mbuf).
                    153:                         */
                    154:                        s_util.c[0] = *(char *)w;
                    155:        }
                    156:        if (len)
                    157:                printf("cksum: out of data\n");
                    158:        if (mlen == -1) {
                    159:                /* The last mbuf has odd # of bytes. Follow the
                    160:                   standard (the odd byte is shifted left by 8 bits) */
                    161:                s_util.c[1] = 0;
                    162:                sum += s_util.s;
                    163:        }
                    164:        REDUCE;
                    165:        return (~sum & 0xffff);
                    166: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.