root/include/asm-mips/checksum.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. ip_fast_csum
  2. csum_tcpudp_magic
  3. csum_fold
  4. ip_compute_csum

   1 /*
   2  * include/asm-mips/checksum.h
   3  *
   4  * This file is subject to the terms and conditions of the GNU General Public
   5  * License.  See the file "COPYING" in the main directory of this archive
   6  * for more details.
   7  *
   8  * Copyright (C) 1995 by Ralf Baechle
   9  */
  10 #ifndef __ASM_MIPS_CHECKSUM_H
  11 #define __ASM_MIPS_CHECKSUM_H
  12 
  13 /*
  14  * computes the checksum of a memory block at buff, length len,
  15  * and adds in "sum" (32-bit)
  16  *
  17  * returns a 32-bit number suitable for feeding into itself
  18  * or csum_tcpudp_magic
  19  *
  20  * this function must be called with even lengths, except
  21  * for the last fragment, which may be odd
  22  *
  23  * it's best to have buff aligned on a 32-bit boundary
  24  */
  25 unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
  26 
  27 /*
  28  * the same as csum_partial, but copies from src while it
  29  * checksums
  30  *
  31  * here even more important to align src and dst on a 32-bit (or even
  32  * better 64-bit) boundary
  33  */
  34 unsigned int csum_partial_copy(const char *src, char *dst, int len, int sum);
  35 
  36 /*
  37  * the same as csum_partial, but copies from user space (but on the alpha
  38  * we have just one address space, so this is identical to the above)
  39  */
  40 #define csum_partial_copy_fromuser csum_partial_copy
  41   
  42 /*
  43  *      This is a version of ip_compute_csum() optimized for IP headers,
  44  *      which always checksum on 4 octet boundaries.
  45  *
  46  *      By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
  47  *      Arnt Gulbrandsen.
  48  */
  49 static inline unsigned short ip_fast_csum(unsigned char * iph,
     /* [previous][next][first][last][top][bottom][index][help] */
  50                                           unsigned int ihl)
  51 {
  52         unsigned short int sum;
  53         unsigned long   dummy1, dummy2;
  54 
  55         /*
  56          * This is optimized for 32-bit MIPS processors.
  57          * I tried it in plain C but the generated code looks to bad to
  58          * use with old first generation MIPS CPUs.
  59          * Using 64-bit code could even further improve these routines.
  60          */
  61         __asm__("
  62         .set    noreorder
  63         .set    noat
  64         lw      %0,(%3)
  65         subu    %1,4
  66         blez    %1,2f
  67         sll     %1,%4,2                 # delay slot
  68         lw      %2,4(%3)
  69         addu    %1,%3                   # delay slot
  70         addu    %0,%2
  71         sltu    $1,%0,%2
  72         lw      %2,8(%3)
  73         addu    %0,$1
  74         addu    %0,%2
  75         sltu    $1,%0,%2
  76         lw      %2,12(%3)
  77         addu    %0,$1
  78         addu    %0,%2
  79         sltu    $1,%0,%2
  80         addu    %0,$1
  81 1:      lw      %2,16(%3)
  82         addu    %1,4
  83         addu    %0,%2
  84         sltu    $1,%0,%2
  85         bne     %1,%3,1b
  86         addu    %0,$1                   # delay slot
  87         srl     $1,%0,16
  88         addu    %0,$1
  89         sltu    $1,%0,$1
  90         addu    %0,$1
  91         nor     %0,$0,%0
  92         andi    %0,0xffff
  93 2:      .set    at
  94         .set    reorder"
  95         : "=r" (sum), "=r" (dummy1), "=r" (dummy2)
  96         : "r" (iph), "r"(ihl)
  97         : "$1");
  98 
  99         return sum;
 100 }
 101 
 102 /*
 103  * computes the checksum of the TCP/UDP pseudo-header
 104  * returns a 16-bit checksum, already complemented
 105  */
 106 static inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
     /* [previous][next][first][last][top][bottom][index][help] */
 107                                                    unsigned long daddr,
 108                                                    unsigned short len,
 109                                                    unsigned short proto,
 110                                                    unsigned int sum)
 111 {
 112     __asm__("
 113         .set    noat
 114         addu    %0,%2
 115         sltu    $1,%0,%2
 116         addu    %0,$1
 117         addu    %0,%3
 118         sltu    $1,%0,%3
 119         addu    %0,$1
 120         addu    %0,%4
 121         sltu    $1,%0,%4
 122         addu    %0,$1
 123         srl     $1,%0,16
 124         addu    %0,$1
 125         sltu    $1,%0,$1
 126         addu    %0,$1
 127         nor     %0,$0,%0
 128         andi    %0,0xffff
 129         .set    at"
 130         : "=r" (sum)
 131         : "0" (daddr), "r"(saddr), "r"((ntohs(len)<<16)+proto*256), "r"(sum)
 132         : "$1");
 133 
 134         return (unsigned short)sum;
 135 }
 136 
 137 /*
 138  *      Fold a partial checksum without adding pseudo headers
 139  */
 140 static inline unsigned short int csum_fold(unsigned int sum)
     /* [previous][next][first][last][top][bottom][index][help] */
 141 {
 142     __asm__("
 143         .set    noat
 144         srl     $1,%0,16
 145         addu    %0,$1
 146         sltu    $1,%0,$1
 147         nor     %0,$0,%0
 148         andi    %0,0xffff
 149         .set    at"
 150         : "=r"(sum)
 151         : "0" (sum)
 152         : "$1");
 153 
 154         return sum;
 155 }
 156  
 157 /*
 158  * this routine is used for miscellaneous IP-like checksums, mainly
 159  * in icmp.c
 160  */
 161 static inline unsigned short ip_compute_csum(unsigned char * buff, int len) {
     /* [previous][next][first][last][top][bottom][index][help] */
 162     unsigned short int sum;
 163 
 164     __asm__("
 165         .set    noat
 166         srl     $1,%0,16
 167         addu    %0,$1
 168         sltu    $1,%0,$1
 169         nor     %0,$0,%0
 170         andi    %0,0xffff
 171         .set    at"
 172         : "=r"(sum)
 173         : "r" (csum_partial(buff, len, 0))
 174         : "$1");
 175 
 176         return sum;
 177 }
 178 
 179 #endif /* __ASM_MIPS_CHECKSUM_H */

/* [previous][next][first][last][top][bottom][index][help] */