1: /*
   2:  * Copyright (c) 1985, 1986 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  *
   6:  *	@(#)ns_cksum.c	7.1 (Berkeley) 6/5/86
   7:  */
   8: #include "types.h"
   9: #include "mbuf.h"
  10: 
  11: 
  12: /*
  13:  * Checksum routine for Network Systems Protocol Packets (VAX Version).
  14:  *
  15:  * This routine is very heavily used in the network
  16:  * code and should be modified for each CPU to be as fast as possible.
  17:  */
  18: 
  19: u_short
  20: ns_cksum(m, len)
  21:     register struct mbuf *m;
  22:     register int len;
  23: {
  24:     register u_short *w;        /* on vax, known to be r9 */
  25:     register int sum = 0;       /* on vax, known to be r8 */
  26:     register int low = 0;       /* on vax, known to be r7 */
  27:     register int mlen = low;    /* want 0, shuts lint up about low */
  28: 
  29:     for (;;) {
  30:         /*
  31: 		 * Each trip around loop adds in
  32: 		 * word from one mbuf segment.
  33: 		 */
  34:         w = mtod(m, u_short *);
  35:         if (mlen == -1) {
  36:             /*
  37: 			 * There is a byte left from the last segment;
  38: 			 * add it into the checksum.  Don't have to worry
  39: 			 * about a carry-out here because we make sure
  40: 			 * that high part of (32 bit) sum is small below.
  41: 			 */
  42:             sum += *(u_char *)w << 8;
  43:             sum += sum;
  44:             w = (u_short *)((char *)w + 1);
  45:             mlen = m->m_len - 1;
  46:             len--;
  47:         } else
  48:             mlen = m->m_len;
  49:         m = m->m_next;
  50:         if (len < mlen)
  51:             mlen = len;
  52:         len -= mlen;
  53:         /*
  54: 		 * Force to long boundary so we do longword aligned
  55: 		 * memory operations.  It is too hard to do byte
  56: 		 * adjustment, do only word adjustment.
  57: 		 */
  58:         if (((int)w&0x2) && mlen >= 2) {
  59:             sum += *w++;
  60:             sum += sum;
  61:             mlen -= 2;
  62:         }
  63:         /*
  64: 		 *
  65: 		 * We can do a 16 bit ones complement sum using
  66: 		 * 32 bit arithmetic registers for adding,
  67: 		 * with carries from the low added
  68: 		 * into the high (by normal carry-chaining)
  69: 		 * so long as we fold back before 16 carries have occured.
  70: 		 *
  71: 		 */
  72:         while ((mlen -= 32) >= 0) {
  73:             /*asm("bicpsw $1");		 clears carry */
  74: #undef ADD
  75: #define ADD asm("movw (r9)+,r7")asm("addl2 r7,r8")asm("addl2 r8,r8")
  76: #define FOLD { asm("ashl $-16,r8,r0")asm(" addw2 r0,r8"); \
  77:           asm("adwc $0,r8")asm(" movzwl r8,r8"); }
  78:             FOLD;
  79:             ADD; ADD; ADD; ADD; ADD; ADD; ADD; ADD;
  80:             FOLD;
  81:             ADD; ADD; ADD; ADD; ADD; ADD; ADD; ADD;
  82:         }
  83:         mlen += 32;
  84:         while ((mlen -= 8) >= 0) {
  85:             /*asm("bicpsw $1");		 clears carry */
  86:             FOLD;
  87:             ADD; ADD; ADD; ADD;
  88:         }
  89:         mlen += 8;
  90:         /*
  91: 		 * Now eliminate the possibility of carry-out's by
  92: 		 * folding back to a 16 bit number (adding high and
  93: 		 * low parts together.)  Then mop up trailing words
  94: 		 * and maybe an odd byte.
  95: 		 */
  96:         FOLD;
  97:         while ((mlen -= 2) >= 0) {
  98:             ADD;
  99:         }
 100:         if (mlen == -1) {
 101:             sum += *(u_char *)w;
 102:         }
 103:         if (len == 0)
 104:             break;
 105:         /*
 106: 		 * Locate the next block with some data.
 107: 		 * If there is a word split across a boundary we
 108: 		 * will wrap to the top with mlen == -1 and
 109: 		 * then add it in shifted appropriately.
 110: 		 */
 111:         for (;;) {
 112:             if (m == 0) {
 113:                 printf("idpcksum: out of data\n");
 114:                 goto done;
 115:             }
 116:             if (m->m_len)
 117:                 break;
 118:             m = m->m_next;
 119:         }
 120:     }
 121: done:
 122:     /*
 123: 	 * Add together high and low parts of sum
 124: 	 * and carry to get cksum.
 125: 	 * Have to be careful to not drop the last
 126: 	 * carry here.
 127: 	 */
 128:     FOLD;
 129: 
 130:     if(sum==0xffff) sum = 0;
 131:     return (sum);
 132: }

Defined functions

Defined macros

ADD defined in line 75; used 22 times
FOLD defined in line 76; used 5 times
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 952
Valid CSS Valid XHTML 1.0 Strict