OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [include/] [asm-mips/] [checksum.h] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
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,
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,
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)
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) {
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 */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.