This source file includes following definitions.
- csum_partial_copy_from_user
- csum_and_copy_from_user
- csum_and_copy_to_user
- csum_fold
- ip_fast_csum
- csum_tcpudp_nofold
- ip_compute_csum
- csum_ipv6_magic
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 #ifndef _ASM_CHECKSUM_H
  13 #define _ASM_CHECKSUM_H
  14 
  15 #ifdef CONFIG_GENERIC_CSUM
  16 #include <asm-generic/checksum.h>
  17 #else
  18 
  19 #include <linux/in6.h>
  20 
  21 #include <linux/uaccess.h>
  22 
  23 
  24 
  25 
  26 
  27 
  28 
  29 
  30 
  31 
  32 
  33 
  34 
  35 __wsum csum_partial(const void *buff, int len, __wsum sum);
  36 
  37 __wsum __csum_partial_copy_kernel(const void *src, void *dst,
  38                                   int len, __wsum sum, int *err_ptr);
  39 
  40 __wsum __csum_partial_copy_from_user(const void *src, void *dst,
  41                                      int len, __wsum sum, int *err_ptr);
  42 __wsum __csum_partial_copy_to_user(const void *src, void *dst,
  43                                    int len, __wsum sum, int *err_ptr);
  44 
  45 
  46 
  47 
  48 static inline
  49 __wsum csum_partial_copy_from_user(const void __user *src, void *dst, int len,
  50                                    __wsum sum, int *err_ptr)
  51 {
  52         might_fault();
  53         if (uaccess_kernel())
  54                 return __csum_partial_copy_kernel((__force void *)src, dst,
  55                                                   len, sum, err_ptr);
  56         else
  57                 return __csum_partial_copy_from_user((__force void *)src, dst,
  58                                                      len, sum, err_ptr);
  59 }
  60 
  61 #define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER
  62 static inline
  63 __wsum csum_and_copy_from_user(const void __user *src, void *dst,
  64                                int len, __wsum sum, int *err_ptr)
  65 {
  66         if (access_ok(src, len))
  67                 return csum_partial_copy_from_user(src, dst, len, sum,
  68                                                    err_ptr);
  69         if (len)
  70                 *err_ptr = -EFAULT;
  71 
  72         return sum;
  73 }
  74 
  75 
  76 
  77 
  78 #define HAVE_CSUM_COPY_USER
  79 static inline
  80 __wsum csum_and_copy_to_user(const void *src, void __user *dst, int len,
  81                              __wsum sum, int *err_ptr)
  82 {
  83         might_fault();
  84         if (access_ok(dst, len)) {
  85                 if (uaccess_kernel())
  86                         return __csum_partial_copy_kernel(src,
  87                                                           (__force void *)dst,
  88                                                           len, sum, err_ptr);
  89                 else
  90                         return __csum_partial_copy_to_user(src,
  91                                                            (__force void *)dst,
  92                                                            len, sum, err_ptr);
  93         }
  94         if (len)
  95                 *err_ptr = -EFAULT;
  96 
  97         return (__force __wsum)-1; 
  98 }
  99 
 100 
 101 
 102 
 103 
 104 __wsum csum_partial_copy_nocheck(const void *src, void *dst,
 105                                        int len, __wsum sum);
 106 #define csum_partial_copy_nocheck csum_partial_copy_nocheck
 107 
 108 
 109 
 110 
 111 static inline __sum16 csum_fold(__wsum csum)
 112 {
 113         u32 sum = (__force u32)csum;
 114 
 115         sum += (sum << 16);
 116         csum = (sum < csum);
 117         sum >>= 16;
 118         sum += csum;
 119 
 120         return (__force __sum16)~sum;
 121 }
 122 #define csum_fold csum_fold
 123 
 124 
 125 
 126 
 127 
 128 
 129 
 130 
 131 static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
 132 {
 133         const unsigned int *word = iph;
 134         const unsigned int *stop = word + ihl;
 135         unsigned int csum;
 136         int carry;
 137 
 138         csum = word[0];
 139         csum += word[1];
 140         carry = (csum < word[1]);
 141         csum += carry;
 142 
 143         csum += word[2];
 144         carry = (csum < word[2]);
 145         csum += carry;
 146 
 147         csum += word[3];
 148         carry = (csum < word[3]);
 149         csum += carry;
 150 
 151         word += 4;
 152         do {
 153                 csum += *word;
 154                 carry = (csum < *word);
 155                 csum += carry;
 156                 word++;
 157         } while (word != stop);
 158 
 159         return csum_fold(csum);
 160 }
 161 #define ip_fast_csum ip_fast_csum
 162 
 163 static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
 164                                         __u32 len, __u8 proto,
 165                                         __wsum sum)
 166 {
 167         __asm__(
 168         "       .set    push            # csum_tcpudp_nofold\n"
 169         "       .set    noat            \n"
 170 #ifdef CONFIG_32BIT
 171         "       addu    %0, %2          \n"
 172         "       sltu    $1, %0, %2      \n"
 173         "       addu    %0, $1          \n"
 174 
 175         "       addu    %0, %3          \n"
 176         "       sltu    $1, %0, %3      \n"
 177         "       addu    %0, $1          \n"
 178 
 179         "       addu    %0, %4          \n"
 180         "       sltu    $1, %0, %4      \n"
 181         "       addu    %0, $1          \n"
 182 #endif
 183 #ifdef CONFIG_64BIT
 184         "       daddu   %0, %2          \n"
 185         "       daddu   %0, %3          \n"
 186         "       daddu   %0, %4          \n"
 187         "       dsll32  $1, %0, 0       \n"
 188         "       daddu   %0, $1          \n"
 189         "       sltu    $1, %0, $1      \n"
 190         "       dsra32  %0, %0, 0       \n"
 191         "       addu    %0, $1          \n"
 192 #endif
 193         "       .set    pop"
 194         : "=r" (sum)
 195         : "0" ((__force unsigned long)daddr),
 196           "r" ((__force unsigned long)saddr),
 197 #ifdef __MIPSEL__
 198           "r" ((proto + len) << 8),
 199 #else
 200           "r" (proto + len),
 201 #endif
 202           "r" ((__force unsigned long)sum));
 203 
 204         return sum;
 205 }
 206 #define csum_tcpudp_nofold csum_tcpudp_nofold
 207 
 208 
 209 
 210 
 211 
 212 static inline __sum16 ip_compute_csum(const void *buff, int len)
 213 {
 214         return csum_fold(csum_partial(buff, len, 0));
 215 }
 216 
 217 #define _HAVE_ARCH_IPV6_CSUM
 218 static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
 219                                           const struct in6_addr *daddr,
 220                                           __u32 len, __u8 proto,
 221                                           __wsum sum)
 222 {
 223         __wsum tmp;
 224 
 225         __asm__(
 226         "       .set    push            # csum_ipv6_magic\n"
 227         "       .set    noreorder       \n"
 228         "       .set    noat            \n"
 229         "       addu    %0, %5          # proto (long in network byte order)\n"
 230         "       sltu    $1, %0, %5      \n"
 231         "       addu    %0, $1          \n"
 232 
 233         "       addu    %0, %6          # csum\n"
 234         "       sltu    $1, %0, %6      \n"
 235         "       lw      %1, 0(%2)       # four words source address\n"
 236         "       addu    %0, $1          \n"
 237         "       addu    %0, %1          \n"
 238         "       sltu    $1, %0, %1      \n"
 239 
 240         "       lw      %1, 4(%2)       \n"
 241         "       addu    %0, $1          \n"
 242         "       addu    %0, %1          \n"
 243         "       sltu    $1, %0, %1      \n"
 244 
 245         "       lw      %1, 8(%2)       \n"
 246         "       addu    %0, $1          \n"
 247         "       addu    %0, %1          \n"
 248         "       sltu    $1, %0, %1      \n"
 249 
 250         "       lw      %1, 12(%2)      \n"
 251         "       addu    %0, $1          \n"
 252         "       addu    %0, %1          \n"
 253         "       sltu    $1, %0, %1      \n"
 254 
 255         "       lw      %1, 0(%3)       \n"
 256         "       addu    %0, $1          \n"
 257         "       addu    %0, %1          \n"
 258         "       sltu    $1, %0, %1      \n"
 259 
 260         "       lw      %1, 4(%3)       \n"
 261         "       addu    %0, $1          \n"
 262         "       addu    %0, %1          \n"
 263         "       sltu    $1, %0, %1      \n"
 264 
 265         "       lw      %1, 8(%3)       \n"
 266         "       addu    %0, $1          \n"
 267         "       addu    %0, %1          \n"
 268         "       sltu    $1, %0, %1      \n"
 269 
 270         "       lw      %1, 12(%3)      \n"
 271         "       addu    %0, $1          \n"
 272         "       addu    %0, %1          \n"
 273         "       sltu    $1, %0, %1      \n"
 274 
 275         "       addu    %0, $1          # Add final carry\n"
 276         "       .set    pop"
 277         : "=&r" (sum), "=&r" (tmp)
 278         : "r" (saddr), "r" (daddr),
 279           "0" (htonl(len)), "r" (htonl(proto)), "r" (sum));
 280 
 281         return csum_fold(sum);
 282 }
 283 
 284 #include <asm-generic/checksum.h>
 285 #endif 
 286 
 287 #endif