fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / include / asm-s390 / checksum.h
index 471f2af..0a3cd7e 100644 (file)
  *
  * it's best to have buff aligned on a 32-bit boundary
  */
-static inline unsigned int
-csum_partial(const unsigned char * buff, int len, unsigned int sum)
+static inline __wsum
+csum_partial(const void *buff, int len, __wsum sum)
 {
-       /*
-        * Experiments with ethernet and slip connections show that buf
-        * is aligned on either a 2-byte or 4-byte boundary.
-        */
-#ifndef __s390x__
-       register_pair rp;
+       register unsigned long reg2 asm("2") = (unsigned long) buff;
+       register unsigned long reg3 asm("3") = (unsigned long) len;
 
-       rp.subreg.even = (unsigned long) buff;
-       rp.subreg.odd = (unsigned long) len;
-       __asm__ __volatile__ (
-               "0:  cksm %0,%1\n"      /* do checksum on longs */
-               "    jo   0b\n"
-               : "+&d" (sum), "+&a" (rp) : : "cc", "memory" );
-#else /* __s390x__ */
-        __asm__ __volatile__ (
-                "    lgr  2,%1\n"    /* address in gpr 2 */
-                "    lgfr 3,%2\n"    /* length in gpr 3 */
-                "0:  cksm %0,2\n"    /* do checksum on longs */
-                "    jo   0b\n"
-                : "+&d" (sum)
-                : "d" (buff), "d" (len)
-                : "cc", "memory", "2", "3" );
-#endif /* __s390x__ */
-       return sum;
-}
-
-/*
- * csum_partial as an inline function
- */
-static inline unsigned int 
-csum_partial_inline(const unsigned char * buff, int len, unsigned int sum)
-{
-#ifndef __s390x__
-       register_pair rp;
-
-       rp.subreg.even = (unsigned long) buff;
-       rp.subreg.odd = (unsigned long) len;
-       __asm__ __volatile__ (
-               "0:  cksm %0,%1\n"    /* do checksum on longs */
-               "    jo   0b\n"
-                : "+&d" (sum), "+&a" (rp) : : "cc", "memory" );
-#else /* __s390x__ */
-       __asm__ __volatile__ (
-               "    lgr  2,%1\n"    /* address in gpr 2 */
-               "    lgfr 3,%2\n"    /* length in gpr 3 */
-               "0:  cksm %0,2\n"    /* do checksum on longs */
-               "    jo   0b\n"
-                : "+&d" (sum)
-               : "d" (buff), "d" (len)
-                : "cc", "memory", "2", "3" );
-#endif /* __s390x__ */
+       asm volatile(
+               "0:     cksm    %0,%1\n"        /* do checksum on longs */
+               "       jo      0b\n"
+               : "+d" (sum), "+d" (reg2), "+d" (reg3) : : "cc", "memory");
        return sum;
 }
 
@@ -93,9 +49,9 @@ csum_partial_inline(const unsigned char * buff, int len, unsigned int sum)
  * Copy from userspace and compute checksum.  If we catch an exception
  * then zero the rest of the buffer.
  */
-static inline unsigned int
-csum_partial_copy_from_user(const char __user *src, char *dst,
-                                          int len, unsigned int sum,
+static inline __wsum
+csum_partial_copy_from_user(const void __user *src, void *dst,
+                                          int len, __wsum sum,
                                           int *err_ptr)
 {
        int missing;
@@ -110,41 +66,40 @@ csum_partial_copy_from_user(const char __user *src, char *dst,
 }
 
 
-static inline unsigned int
-csum_partial_copy_nocheck (const char *src, char *dst, int len, unsigned int sum)
+static inline __wsum
+csum_partial_copy_nocheck (const void *src, void *dst, int len, __wsum sum)
 {
         memcpy(dst,src,len);
-        return csum_partial_inline(dst, len, sum);
+       return csum_partial(dst, len, sum);
 }
 
 /*
  *      Fold a partial checksum without adding pseudo headers
  */
-static inline unsigned short
-csum_fold(unsigned int sum)
+static inline __sum16 csum_fold(__wsum sum)
 {
 #ifndef __s390x__
        register_pair rp;
 
-       __asm__ __volatile__ (
-               "    slr  %N1,%N1\n" /* %0 = H L */
-               "    lr   %1,%0\n"   /* %0 = H L, %1 = H L 0 0 */
-               "    srdl %1,16\n"   /* %0 = H L, %1 = 0 H L 0 */
-               "    alr  %1,%N1\n"  /* %0 = H L, %1 = L H L 0 */
-               "    alr  %0,%1\n"   /* %0 = H+L+C L+H */
-               "    srl  %0,16\n"   /* %0 = H+L+C */
-               : "+&d" (sum), "=d" (rp) : : "cc" );
+       asm volatile(
+               "       slr     %N1,%N1\n"      /* %0 = H L */
+               "       lr      %1,%0\n"        /* %0 = H L, %1 = H L 0 0 */
+               "       srdl    %1,16\n"        /* %0 = H L, %1 = 0 H L 0 */
+               "       alr     %1,%N1\n"       /* %0 = H L, %1 = L H L 0 */
+               "       alr     %0,%1\n"        /* %0 = H+L+C L+H */
+               "       srl     %0,16\n"        /* %0 = H+L+C */
+               : "+&d" (sum), "=d" (rp) : : "cc");
 #else /* __s390x__ */
-       __asm__ __volatile__ (
-               "    sr   3,3\n"   /* %0 = H*65536 + L */
-               "    lr   2,%0\n"  /* %0 = H L, R2/R3 = H L / 0 0 */
-               "    srdl 2,16\n"  /* %0 = H L, R2/R3 = 0 H / L 0 */
-               "    alr  2,3\n"   /* %0 = H L, R2/R3 = L H / L 0 */
-               "    alr  %0,2\n"  /* %0 = H+L+C L+H */
-                "    srl  %0,16\n" /* %0 = H+L+C */
+       asm volatile(
+               "       sr      3,3\n"          /* %0 = H*65536 + L */
+               "       lr      2,%0\n"         /* %0 = H L, 2/3 = H L / 0 0 */
+               "       srdl    2,16\n"         /* %0 = H L, 2/3 = 0 H / L 0 */
+               "       alr     2,3\n"          /* %0 = H L, 2/3 = L H / L 0 */
+               "       alr     %0,2\n"         /* %0 = H+L+C L+H */
+               "       srl     %0,16\n"        /* %0 = H+L+C */
                : "+&d" (sum) : : "cc", "2", "3");
 #endif /* __s390x__ */
-       return ((unsigned short) ~sum);
+       return (__force __sum16) ~sum;
 }
 
 /*
@@ -152,85 +107,62 @@ csum_fold(unsigned int sum)
  *     which always checksum on 4 octet boundaries.
  *
  */
-static inline unsigned short
-ip_fast_csum(unsigned char *iph, unsigned int ihl)
+static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
 {
-       unsigned long sum;
-#ifndef __s390x__
-       register_pair rp;
-
-       rp.subreg.even = (unsigned long) iph;
-       rp.subreg.odd = (unsigned long) ihl*4;
-        __asm__ __volatile__ (
-               "    sr   %0,%0\n"   /* set sum to zero */
-                "0:  cksm %0,%1\n"   /* do checksum on longs */
-                "    jo   0b\n"
-                : "=&d" (sum), "+&a" (rp) : : "cc", "memory" );
-#else /* __s390x__ */
-        __asm__ __volatile__ (
-               "    slgr %0,%0\n"   /* set sum to zero */
-                "    lgr  2,%1\n"    /* address in gpr 2 */
-                "    lgfr 3,%2\n"    /* length in gpr 3 */
-                "0:  cksm %0,2\n"    /* do checksum on ints */
-                "    jo   0b\n"
-                : "=&d" (sum)
-                : "d" (iph), "d" (ihl*4)
-                : "cc", "memory", "2", "3" );
-#endif /* __s390x__ */
-        return csum_fold(sum);
+       return csum_fold(csum_partial(iph, ihl*4, 0));
 }
 
 /*
  * computes the checksum of the TCP/UDP pseudo-header
  * returns a 32-bit checksum
  */
-static inline unsigned int 
-csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr,
+static inline __wsum
+csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
                    unsigned short len, unsigned short proto,
-                   unsigned int sum)
+                   __wsum sum)
 {
 #ifndef __s390x__
-       __asm__ __volatile__ (
-                "    alr   %0,%1\n"  /* sum += saddr */
-                "    brc   12,0f\n"
-               "    ahi   %0,1\n"   /* add carry */
+       asm volatile(
+               "       alr     %0,%1\n" /* sum += saddr */
+               "       brc     12,0f\n"
+               "       ahi     %0,1\n"  /* add carry */
                "0:"
-               : "+&d" (sum) : "d" (saddr) : "cc" );
-       __asm__ __volatile__ (
-                "    alr   %0,%1\n"  /* sum += daddr */
-                "    brc   12,1f\n"
-                "    ahi   %0,1\n"   /* add carry */
+               : "+&d" (sum) : "d" (saddr) : "cc");
+       asm volatile(
+               "       alr     %0,%1\n" /* sum += daddr */
+               "       brc     12,1f\n"
+               "       ahi     %0,1\n"  /* add carry */
                "1:"
-               : "+&d" (sum) : "d" (daddr) : "cc" );
-       __asm__ __volatile__ (
-                "    alr   %0,%1\n"  /* sum += (len<<16) + (proto<<8) */
-               "    brc   12,2f\n"
-               "    ahi   %0,1\n"   /* add carry */
+               : "+&d" (sum) : "d" (daddr) : "cc");
+       asm volatile(
+               "       alr     %0,%1\n" /* sum += len + proto */
+               "       brc     12,2f\n"
+               "       ahi     %0,1\n"  /* add carry */
                "2:"
                : "+&d" (sum)
-               : "d" (((unsigned int) len<<16) + (unsigned int) proto)
-               : "cc" );
+               : "d" (len + proto)
+               : "cc");
 #else /* __s390x__ */
-       __asm__ __volatile__ (
-                "    lgfr  %0,%0\n"
-                "    algr  %0,%1\n"  /* sum += saddr */
-                "    brc   12,0f\n"
-               "    aghi  %0,1\n"   /* add carry */
-               "0:  algr  %0,%2\n"  /* sum += daddr */
-                "    brc   12,1f\n"
-                "    aghi  %0,1\n"   /* add carry */
-               "1:  algfr %0,%3\n"  /* sum += (len<<16) + proto */
-               "    brc   12,2f\n"
-               "    aghi  %0,1\n"   /* add carry */
-               "2:  srlg  0,%0,32\n"
-                "    alr   %0,0\n"   /* fold to 32 bits */
-                "    brc   12,3f\n"
-                "    ahi   %0,1\n"   /* add carry */
-                "3:  llgfr %0,%0"
+       asm volatile(
+               "       lgfr    %0,%0\n"
+               "       algr    %0,%1\n"  /* sum += saddr */
+               "       brc     12,0f\n"
+               "       aghi    %0,1\n"   /* add carry */
+               "0:     algr    %0,%2\n"  /* sum += daddr */
+               "       brc     12,1f\n"
+               "       aghi    %0,1\n"   /* add carry */
+               "1:     algfr   %0,%3\n"  /* sum += len + proto */
+               "       brc     12,2f\n"
+               "       aghi    %0,1\n"   /* add carry */
+               "2:     srlg    0,%0,32\n"
+               "       alr     %0,0\n"   /* fold to 32 bits */
+               "       brc     12,3f\n"
+               "       ahi     %0,1\n"   /* add carry */
+               "3:     llgfr   %0,%0"
                : "+&d" (sum)
                : "d" (saddr), "d" (daddr),
-                 "d" (((unsigned int) len<<16) + (unsigned int) proto)
-               : "cc", "0" );
+                 "d" (len + proto)
+               : "cc", "0");
 #endif /* __s390x__ */
        return sum;
 }
@@ -240,10 +172,10 @@ csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr,
  * returns a 16-bit checksum, already complemented
  */
 
-static inline unsigned short int
-csum_tcpudp_magic(unsigned long saddr, unsigned long daddr,
+static inline __sum16
+csum_tcpudp_magic(__be32 saddr, __be32 daddr,
                   unsigned short len, unsigned short proto,
-                  unsigned int sum)
+                  __wsum sum)
 {
        return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
 }
@@ -253,8 +185,7 @@ csum_tcpudp_magic(unsigned long saddr, unsigned long daddr,
  * in icmp.c
  */
 
-static inline unsigned short
-ip_compute_csum(unsigned char * buff, int len)
+static inline __sum16 ip_compute_csum(const void *buff, int len)
 {
        return csum_fold(csum_partial(buff, len, 0));
 }