|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1985, 1986 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that the above copyright notice and this paragraph are ! 7: * duplicated in all such forms and that any documentation, ! 8: * advertising materials, and other materials related to such ! 9: * distribution and use acknowledge that the software was developed ! 10: * by the University of California, Berkeley. The name of the ! 11: * University may not be used to endorse or promote products derived ! 12: * from this software without specific prior written permission. ! 13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 16: * ! 17: * @(#)ns_cksum.c 7.3 (Berkeley) 6/29/88 ! 18: */ ! 19: ! 20: #include "types.h" ! 21: #include "mbuf.h" ! 22: ! 23: ! 24: /* ! 25: * Checksum routine for Network Systems Protocol Packets (VAX Version). ! 26: * ! 27: * This routine is very heavily used in the network ! 28: * code and should be modified for each CPU to be as fast as possible. ! 29: */ ! 30: ! 31: u_short ! 32: ns_cksum(m, len) ! 33: register struct mbuf *m; ! 34: register int len; ! 35: { ! 36: register u_short *w; /* on vax, known to be r9 */ ! 37: register int sum = 0; /* on vax, known to be r8 */ ! 38: register int low = 0; /* on vax, known to be r7 */ ! 39: register int mlen = low; /* want 0, shuts lint up about low */ ! 40: ! 41: for (;;) { ! 42: /* ! 43: * Each trip around loop adds in ! 44: * word from one mbuf segment. ! 45: */ ! 46: w = mtod(m, u_short *); ! 47: if (mlen == -1) { ! 48: /* ! 49: * There is a byte left from the last segment; ! 50: * add it into the checksum. Don't have to worry ! 51: * about a carry-out here because we make sure ! 52: * that high part of (32 bit) sum is small below. ! 53: */ ! 54: sum += *(u_char *)w << 8; ! 55: sum += sum; ! 56: w = (u_short *)((char *)w + 1); ! 57: mlen = m->m_len - 1; ! 58: len--; ! 59: } else ! 60: mlen = m->m_len; ! 61: m = m->m_next; ! 62: if (len < mlen) ! 63: mlen = len; ! 64: len -= mlen; ! 65: /* ! 66: * Force to long boundary so we do longword aligned ! 67: * memory operations. It is too hard to do byte ! 68: * adjustment, do only word adjustment. ! 69: */ ! 70: if (((int)w&0x2) && mlen >= 2) { ! 71: sum += *w++; ! 72: sum += sum; ! 73: mlen -= 2; ! 74: } ! 75: /* ! 76: * ! 77: * We can do a 16 bit ones complement sum using ! 78: * 32 bit arithmetic registers for adding, ! 79: * with carries from the low added ! 80: * into the high (by normal carry-chaining) ! 81: * so long as we fold back before 16 carries have occured. ! 82: * ! 83: */ ! 84: while ((mlen -= 32) >= 0) { ! 85: /*asm("bicpsw $1"); clears carry */ ! 86: #undef ADD ! 87: #define ADD asm("movw (r9)+,r7")asm("addl2 r7,r8")asm("addl2 r8,r8") ! 88: #define FOLD { asm("ashl $-16,r8,r0")asm(" addw2 r0,r8"); \ ! 89: asm("adwc $0,r8")asm(" movzwl r8,r8"); } ! 90: FOLD; ! 91: ADD; ADD; ADD; ADD; ADD; ADD; ADD; ADD; ! 92: FOLD; ! 93: ADD; ADD; ADD; ADD; ADD; ADD; ADD; ADD; ! 94: } ! 95: mlen += 32; ! 96: while ((mlen -= 8) >= 0) { ! 97: /*asm("bicpsw $1"); clears carry */ ! 98: FOLD; ! 99: ADD; ADD; ADD; ADD; ! 100: } ! 101: mlen += 8; ! 102: /* ! 103: * Now eliminate the possibility of carry-out's by ! 104: * folding back to a 16 bit number (adding high and ! 105: * low parts together.) Then mop up trailing words ! 106: * and maybe an odd byte. ! 107: */ ! 108: FOLD; ! 109: while ((mlen -= 2) >= 0) { ! 110: ADD; ! 111: } ! 112: if (mlen == -1) { ! 113: sum += *(u_char *)w; ! 114: } ! 115: if (len == 0) ! 116: break; ! 117: /* ! 118: * Locate the next block with some data. ! 119: * If there is a word split across a boundary we ! 120: * will wrap to the top with mlen == -1 and ! 121: * then add it in shifted appropriately. ! 122: */ ! 123: for (;;) { ! 124: if (m == 0) { ! 125: printf("idpcksum: out of data\n"); ! 126: goto done; ! 127: } ! 128: if (m->m_len) ! 129: break; ! 130: m = m->m_next; ! 131: } ! 132: } ! 133: done: ! 134: /* ! 135: * Add together high and low parts of sum ! 136: * and carry to get cksum. ! 137: * Have to be careful to not drop the last ! 138: * carry here. ! 139: */ ! 140: FOLD; ! 141: ! 142: if(sum==0xffff) sum = 0; ! 143: return (sum); ! 144: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.