import of upstream 2.4.34.4 from kernel.org
[linux-2.4.git] / arch / cris / lib / old_checksum.c
1 /*
2  * INET         An implementation of the TCP/IP protocol suite for the LINUX
3  *              operating system.  INET is implemented using the  BSD Socket
4  *              interface as the means of communication with the user level.
5  *
6  *              IP/TCP/UDP checksumming routines
7  *
8  * Authors:     Jorge Cwik, <jorge@laser.satlink.net>
9  *              Arnt Gulbrandsen, <agulbra@nvg.unit.no>
10  *              Tom May, <ftom@netcom.com>
11  *              Lots of code moved from tcp.c and ip.c; see those files
12  *              for more names.
13  *
14  *              This program is free software; you can redistribute it and/or
15  *              modify it under the terms of the GNU General Public License
16  *              as published by the Free Software Foundation; either version
17  *              2 of the License, or (at your option) any later version.
18  */
19
20 #include <net/checksum.h>
21
22 #undef PROFILE_CHECKSUM
23
24 #ifdef PROFILE_CHECKSUM
25 /* these are just for profiling the checksum code with an oscillioscope.. uh */
26 #if 0
27 #define BITOFF *((unsigned char *)0xb0000030) = 0xff
28 #define BITON *((unsigned char *)0xb0000030) = 0x0
29 #endif
30 #include <asm/io.h>
31 #define CBITON LED_ACTIVE_SET(1)
32 #define CBITOFF LED_ACTIVE_SET(0)
33 #define BITOFF
34 #define BITON
35 #else
36 #define BITOFF
37 #define BITON
38 #define CBITOFF
39 #define CBITON
40 #endif
41
42 /*
43  * computes a partial checksum, e.g. for TCP/UDP fragments
44  */
45
46 #include <asm/delay.h>
47
48 unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
49 {
50   /*
51    * Experiments with ethernet and slip connections show that buff
52    * is aligned on either a 2-byte or 4-byte boundary.
53    */
54   const unsigned char *endMarker = buff + len;
55   const unsigned char *marker = endMarker - (len % 16);
56 #if 0
57   if((int)buff & 0x3)
58     printk("unaligned buff %p\n", buff);
59   __delay(900); /* extra delay of 90 us to test performance hit */
60 #endif
61   BITON;
62   while (buff < marker) {
63     sum += *((unsigned short *)buff)++;
64     sum += *((unsigned short *)buff)++;
65     sum += *((unsigned short *)buff)++;
66     sum += *((unsigned short *)buff)++;
67     sum += *((unsigned short *)buff)++;
68     sum += *((unsigned short *)buff)++;
69     sum += *((unsigned short *)buff)++;
70     sum += *((unsigned short *)buff)++;
71   }
72   marker = endMarker - (len % 2);
73   while(buff < marker) {
74     sum += *((unsigned short *)buff)++;
75   }
76   if(endMarker - buff > 0) {
77     sum += *buff;                 /* add extra byte seperately */
78   }
79   BITOFF;
80   return(sum);
81 }
82
83 #if 0
84
85 /*
86  * copy while checksumming, otherwise like csum_partial
87  */
88
89 unsigned int csum_partial_copy(const unsigned char *src, unsigned char *dst, 
90                                   int len, unsigned int sum)
91 {
92   const unsigned char *endMarker;
93   const unsigned char *marker;
94   printk("csum_partial_copy len %d.\n", len);
95 #if 0
96   if((int)src & 0x3)
97     printk("unaligned src %p\n", src);
98   if((int)dst & 0x3)
99     printk("unaligned dst %p\n", dst);
100   __delay(1800); /* extra delay of 90 us to test performance hit */
101 #endif
102   endMarker = src + len;
103   marker = endMarker - (len % 16);
104   CBITON;
105   while(src < marker) {
106     sum += (*((unsigned short *)dst)++ = *((unsigned short *)src)++);
107     sum += (*((unsigned short *)dst)++ = *((unsigned short *)src)++);
108     sum += (*((unsigned short *)dst)++ = *((unsigned short *)src)++);
109     sum += (*((unsigned short *)dst)++ = *((unsigned short *)src)++);
110     sum += (*((unsigned short *)dst)++ = *((unsigned short *)src)++);
111     sum += (*((unsigned short *)dst)++ = *((unsigned short *)src)++);
112     sum += (*((unsigned short *)dst)++ = *((unsigned short *)src)++);
113     sum += (*((unsigned short *)dst)++ = *((unsigned short *)src)++);
114   }
115   marker = endMarker - (len % 2);
116   while(src < marker) {
117     sum += (*((unsigned short *)dst)++ = *((unsigned short *)src)++);
118   }
119   if(endMarker - src > 0) {
120     sum += (*dst = *src);                 /* add extra byte seperately */
121   }
122   CBITOFF;
123   return(sum);
124 }
125
126 #endif