- return(~(sum + (sum >> 16)) & 0xffff);
-}
-
-/*
- * These routines are implemented as inline expansions
- * and are mentioned here for reference only
- *
- * htons and ntohs do byte reverse of a 16 bit integer
- * htonl and ntohl do byte reverse of a 32 bit integer
- */
-ocksum(m, len)
-register struct mbuf *m;
-register len;
-{
- register unsigned short *w;
- register unsigned long sum;
- register mlen;
-COUNT(OCKSUM);
-
- w = (unsigned short *)((int)m + m->m_off);
- mlen = m->m_len;
- sum = 0;
-
- for (; len > 0; len -= 2, mlen -= 2) {
-
-try: if (mlen > 1) { /* can get a word */
-
- if (len > 1) {
- sum += *(w++);
-
- } else /* trailing odd byte */
-
- sum += *((char *)w) & 0xff;
-
- } else if (mlen > 0) { /* last byte of mbuf */
-
- sum += *((char *)w) & 0xff;
-
- if (len > 1) {
-
- /* get next good mbuf for hi byte */
-
- while ((m = m->m_next) != 0 &&
- (mlen = m->m_len + 1) == 1);
- if (m != 0) {
- w = (unsigned short *)((int)m + m->m_off);
- sum += (*((char *)w) & 0xff) << 8;
- w = (unsigned short *)((int)w + 1);
- } else
- len = 0; /* force loop exit */
- }
-
- } else { /* end of mbuf, get next and try again */
-
- while ((m = m->m_next) != 0 && (mlen = m->m_len) == 0);
- if (m != 0) {
- w = (unsigned short *)((int)m + m->m_off);
- goto try;
- } else
- break;
- }
- }
-
- /* add in one's complement carry */
-
- sum = (sum + (sum >> 16)) & 0xffff;
- return(~sum & 0xffff);
+done:
+ /*
+ * Add together high and low parts of sum
+ * and carry to get cksum.
+ * Have to be careful to not drop the last
+ * carry here.
+ */
+ { asm("ashl $-16,r8,r0; addw2 r0,r8; adwc $0,r8");
+ asm("mcoml r8,r8; movzwl r8,r8"); }
+ return (sum);