1 /* 2 * Copyright (c) 1982, 1988 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 this notice is preserved and that due credit is given 7 * to the University of California at Berkeley. The name of the University 8 * may not be used to endorse or promote products derived from this 9 * software without specific prior written permission. This software 10 * is provided ``as is'' without express or implied warranty. 11 * 12 * @(#)in_cksum.c 1.4 (Berkeley) 03/02/88 13 */ 14 #include "types.h" 15 #include "mbuf.h" 16 17 /* 18 * Checksum routine for Internet Protocol family headers (CCI Version). 19 * 20 * This routine is very heavily used in the network 21 * code and should be modified for each CPU to be as fast as possible. 22 */ 23 24 #define ADDCARRY(x) (x > 65535 ? x -= 65535 : x) 25 #define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);} 26 27 #define ADD(n) asm("adwc n (r10),r9") 28 #define MOP asm("adwc $0,r9") 29 #define BOTCH asm("addl2 r7,r9") 30 31 in_cksum(m, len) 32 register struct mbuf *m; 33 register int len; 34 { 35 register u_short *w; /* On CCI, known to be r10 */ 36 register int sum = 0; /* On CCI, known to be r9 */ 37 register int mlen = 0; 38 register int ClearCarry = 0; /* On CCI, known to be r7 */ 39 int byte_swapped = 0; 40 41 union { 42 char c[2]; 43 u_short s; 44 } s_util; 45 union { 46 u_short s[2]; 47 long l; 48 } l_util; 49 50 for (;m && len; m = m->m_next) { 51 if (m->m_len == 0) 52 continue; 53 w = mtod(m, u_short *); 54 if (mlen == -1) { 55 /* 56 * The first byte of this mbuf is the continuation 57 * of a word spanning between this mbuf and the 58 * last mbuf. 59 * 60 * s_util.c[0] is already saved when scanning previous 61 * mbuf. sum was REDUCEd when we found mlen == -1. 62 */ 63 s_util.c[1] = *(char *)w; 64 sum += s_util.s; 65 w = (u_short *)((char *)w + 1); 66 mlen = m->m_len - 1; 67 len--; 68 } else 69 mlen = m->m_len; 70 if (len < mlen) 71 mlen = len; 72 len -= mlen; 73 /* 74 * Force to long boundary so we do longword aligned 75 * memory operations. 76 */ 77 if (3 & (int) w) { 78 REDUCE; 79 if ((1 & (int) w) && (mlen > 0)) { 80 sum <<= 8; 81 s_util.c[0] = *(char *)w; 82 w = (u_short *)((char *)w + 1); 83 mlen--; 84 byte_swapped = 1; 85 } 86 if ((2 & (int) w) && (mlen >= 2)) { 87 sum += *w++; 88 mlen -= 2; 89 } 90 } 91 /* 92 * Do as much of the checksum as possible 32 bits at at time. 93 * In fact, this loop is unrolled to make overhead from 94 * branches &c small. 95 */ 96 while ((mlen -= 32) >= 0) { 97 /* 98 * The loop construct clears carry for us 99 * on vaxen, however, on the CCI machine subtracting 100 * a small postive number from a larger one doesn't. 101 * 102 * Doing a bicpsw is very slow (slows down the routine 103 * by a factor of 2); explicitly adding an immediate 104 * 0 to a register is optimized out; so we fake out 105 * the optimizer and add a register whose contents 106 * is always zero. 107 */ 108 BOTCH; 109 ADD(0); ADD(4); ADD(8); ADD(12); 110 ADD(16); ADD(20); ADD(24); ADD(28); 111 MOP; w += 16; 112 } 113 mlen += 32; 114 while ((mlen -= 8) >= 0) { 115 BOTCH; 116 ADD(0); ADD(4); 117 MOP; 118 w += 4; 119 } 120 mlen += 8; 121 if (mlen == 0 && byte_swapped == 0) 122 continue; /* worth 1% maybe ?? */ 123 REDUCE; 124 while ((mlen -= 2) >= 0) { 125 sum += *w++; 126 } 127 if (byte_swapped) { 128 sum <<= 8; 129 byte_swapped = 0; 130 if (mlen == -1) { 131 s_util.c[1] = *(char *)w; 132 sum += s_util.s; 133 mlen = 0; 134 } else 135 mlen = -1; 136 } else if (mlen == -1) 137 /* 138 * This mbuf has odd number of bytes. 139 * There could be a word split betwen 140 * this mbuf and the next mbuf. 141 * Save the last byte (to prepend to next mbuf). 142 */ 143 s_util.c[0] = *(char *)w; 144 } 145 if (len) 146 printf("cksum: out of data\n"); 147 if (mlen == -1) { 148 /* The last mbuf has odd # of bytes. Follow the 149 standard (the odd byte is shifted left by 8 bits) */ 150 s_util.c[1] = 0; 151 sum += s_util.s; 152 } 153 REDUCE; 154 return (~sum & 0xffff); 155 } 156