~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/include/asm-parisc/checksum.h

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #ifndef _PARISC_CHECKSUM_H
  2 #define _PARISC_CHECKSUM_H
  3 
  4 /*
  5  * computes the checksum of a memory block at buff, length len,
  6  * and adds in "sum" (32-bit)
  7  *
  8  * returns a 32-bit number suitable for feeding into itself
  9  * or csum_tcpudp_magic
 10  *
 11  * this function must be called with even lengths, except
 12  * for the last fragment, which may be odd
 13  *
 14  * it's best to have buff aligned on a 32-bit boundary
 15  */
 16 extern unsigned int csum_partial(const unsigned char *, int, unsigned int);
 17 
 18 /*
 19  * the same as csum_partial, but copies from src while it
 20  * checksums
 21  *
 22  * here even more important to align src and dst on a 32-bit (or even
 23  * better 64-bit) boundary
 24  */
 25 extern unsigned int csum_partial_copy(const char *, char *, int, unsigned int);
 26 
 27 /*
 28  * the same as csum_partial, but copies from user space
 29  *
 30  * this is obsolete and will go away.
 31  */
 32 #define csum_partial_copy_fromuser csum_partial_copy
 33 
 34 /*
 35  * this is a new version of the above that records errors it finds in *errp,
 36  * but continues and zeros the rest of the buffer.
 37  */
 38 unsigned int csum_partial_copy_from_user(const char *src, char *dst, int len, unsigned int sum, int *errp);
 39 
 40 /*
 41  *      Note: when you get a NULL pointer exception here this means someone
 42  *      passed in an incorrect kernel address to one of these functions. 
 43  *      
 44  *      If you use these functions directly please don't forget the 
 45  *      verify_area().
 46  */
 47 extern __inline__
 48 unsigned int csum_partial_copy_nocheck (const char *src, char *dst,
 49                                         int len, int sum)
 50 {
 51         return csum_partial_copy (src, dst, len, sum);
 52 }
 53 
 54 /*
 55  *      Optimized for IP headers, which always checksum on 4 octet boundaries.
 56  *
 57  *      Written by Randolph Chung <tausq@debian.org>
 58  */
 59 static inline unsigned short ip_fast_csum(unsigned char * iph,
 60                                           unsigned int ihl) {
 61         unsigned int sum;
 62 
 63 
 64         __asm__ __volatile__ ("
 65         ldws,ma         4(%1), %0
 66         addi            -4, %2, %2
 67         comib,>=        0, %2, 2f
 68         
 69         ldws,ma         4(%1), %%r19
 70         add             %0, %%r19, %0
 71         ldws,ma         4(%1), %%r19
 72         addc            %0, %%r19, %0
 73         ldws,ma         4(%1), %%r19
 74         addc            %0, %%r19, %0
 75 1:      ldws,ma         4(%1), %%r19
 76         addib,<>        -1, %2, 1b
 77         addc            %0, %%r19, %0
 78         addc            %0, %%r0, %0
 79 
 80         zdepi           -1, 31, 16, %%r19
 81         and             %0, %%r19, %%r20
 82         extru           %0, 15, 16, %%r21
 83         add             %%r20, %%r21, %0
 84         and             %0, %%r19, %%r20
 85         extru           %0, 15, 16, %%r21
 86         add             %%r20, %%r21, %0
 87         subi            -1, %0, %0
 88 2:
 89         "
 90         : "=r" (sum), "=r" (iph), "=r" (ihl)
 91         : "1" (iph), "2" (ihl)
 92         : "r19", "r20", "r21" );
 93 
 94         return(sum);
 95 }
 96 
 97 /*
 98  *      Fold a partial checksum
 99  */
100 static inline unsigned int csum_fold(unsigned int sum)
101 {
102         sum = (sum & 0xffff) + (sum >> 16);
103         sum = (sum & 0xffff) + (sum >> 16);
104         return ~sum;
105 }
106  
107 static inline unsigned long csum_tcpudp_nofold(unsigned long saddr,
108                                                unsigned long daddr,
109                                                unsigned short len,
110                                                unsigned short proto,
111                                                unsigned int sum) 
112 {
113         __asm__("
114                 add  %1, %0, %0
115                 addc %2, %0, %0
116                 addc %3, %0, %0
117                 addc %%r0, %0, %0 "
118                 : "=r" (sum)
119                 : "r" (daddr), "r"(saddr), "r"((proto<<16)+len), ""(sum));
120     return sum;
121 }
122 
123 /*
124  * computes the checksum of the TCP/UDP pseudo-header
125  * returns a 16-bit checksum, already complemented
126  */
127 static inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
128                                                    unsigned long daddr,
129                                                    unsigned short len,
130                                                    unsigned short proto,
131                                                    unsigned int sum) 
132 {
133         return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
134 }
135 
136 /*
137  * this routine is used for miscellaneous IP-like checksums, mainly
138  * in icmp.c
139  */
140 static inline unsigned short ip_compute_csum(unsigned char * buf, int len) {
141          return csum_fold (csum_partial(buf, len, 0));
142 }
143 
144 #define _HAVE_ARCH_IPV6_CSUM
145 static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
146                                                      struct in6_addr *daddr,
147                                                      __u16 len,
148                                                      unsigned short proto,
149                                                      unsigned int sum) 
150 {
151         BUG();
152         return csum_fold(sum);
153 }
154 
155 /* 
156  *      Copy and checksum to user
157  */
158 #define HAVE_CSUM_COPY_USER
159 static __inline__ unsigned int csum_and_copy_to_user (const char *src, char *dst,
160                                     int len, int sum, int *err_ptr)
161 {
162         /* code stolen from include/asm-mips64 */
163         sum = csum_partial(src, len, sum);
164          
165         if (copy_to_user(dst, src, len)) {
166                 *err_ptr = -EFAULT;
167                 return -1;
168         }
169 
170         return sum;
171 }
172 
173 #endif
174 
175 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.