|
|
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.