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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [include/] [asm-arm/] [checksum.h] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1276 phoenix
/*
2
 *  linux/include/asm-arm/checksum.h
3
 *
4
 * IP checksum routines
5
 *
6
 * Copyright (C) Original authors of ../asm-i386/checksum.h
7
 * Copyright (C) 1996-1999 Russell King
8
 */
9
#ifndef __ASM_ARM_CHECKSUM_H
10
#define __ASM_ARM_CHECKSUM_H
11
 
12
/*
13
 * computes the checksum of a memory block at buff, length len,
14
 * and adds in "sum" (32-bit)
15
 *
16
 * returns a 32-bit number suitable for feeding into itself
17
 * or csum_tcpudp_magic
18
 *
19
 * this function must be called with even lengths, except
20
 * for the last fragment, which may be odd
21
 *
22
 * it's best to have buff aligned on a 32-bit boundary
23
 */
24
unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
25
 
26
/*
27
 * the same as csum_partial, but copies from src while it
28
 * checksums, and handles user-space pointer exceptions correctly, when needed.
29
 *
30
 * here even more important to align src and dst on a 32-bit (or even
31
 * better 64-bit) boundary
32
 */
33
 
34
unsigned int
35
csum_partial_copy_nocheck(const char *src, char *dst, int len, int sum);
36
 
37
unsigned int
38
csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *err_ptr);
39
 
40
/*
41
 * These are the old (and unsafe) way of doing checksums, a warning message will be
42
 * printed if they are used and an exception occurs.
43
 *
44
 * these functions should go away after some time.
45
 */
46
#define csum_partial_copy(src,dst,len,sum)      csum_partial_copy_nocheck(src,dst,len,sum)
47
 
48
/*
49
 *      This is a version of ip_compute_csum() optimized for IP headers,
50
 *      which always checksum on 4 octet boundaries.
51
 */
52
static inline unsigned short
53
ip_fast_csum(unsigned char * iph, unsigned int ihl)
54
{
55
        unsigned int sum, tmp1;
56
 
57
        __asm__ __volatile__(
58
        "ldr    %0, [%1], #4            @ ip_fast_csum          \n\
59
        ldr     %3, [%1], #4                                    \n\
60
        sub     %2, %2, #5                                      \n\
61
        adds    %0, %0, %3                                      \n\
62
        ldr     %3, [%1], #4                                    \n\
63
        adcs    %0, %0, %3                                      \n\
64
        ldr     %3, [%1], #4                                    \n\
65
1:      adcs    %0, %0, %3                                      \n\
66
        ldr     %3, [%1], #4                                    \n\
67
        tst     %2, #15                 @ do this carefully     \n\
68
        subne   %2, %2, #1              @ without destroying    \n\
69
        bne     1b                      @ the carry flag        \n\
70
        adcs    %0, %0, %3                                      \n\
71
        adc     %0, %0, #0                                      \n\
72
        adds    %0, %0, %0, lsl #16                             \n\
73
        addcs   %0, %0, #0x10000                                \n\
74
        mvn     %0, %0                                          \n\
75
        mov     %0, %0, lsr #16"
76
        : "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (tmp1)
77
        : "1" (iph), "2" (ihl)
78
        : "cc");
79
        return sum;
80
}
81
 
82
/*
83
 *      Fold a partial checksum without adding pseudo headers
84
 */
85
static inline unsigned int
86
csum_fold(unsigned int sum)
87
{
88
        __asm__(
89
        "adds   %0, %1, %1, lsl #16     @ csum_fold             \n\
90
        addcs   %0, %0, #0x10000"
91
        : "=r" (sum)
92
        : "r" (sum)
93
        : "cc");
94
        return (~sum) >> 16;
95
}
96
 
97
static inline unsigned int
98
csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len,
99
                   unsigned int proto, unsigned int sum)
100
{
101
        __asm__(
102
        "adds   %0, %1, %2              @ csum_tcpudp_nofold    \n\
103
        adcs    %0, %0, %3                                      \n\
104
        adcs    %0, %0, %4                                      \n\
105
        adcs    %0, %0, %5                                      \n\
106
        adc     %0, %0, #0"
107
        : "=&r"(sum)
108
        : "r" (sum), "r" (daddr), "r" (saddr), "r" (ntohs(len) << 16), "Ir" (proto << 8)
109
        : "cc");
110
        return sum;
111
}
112
/*
113
 * computes the checksum of the TCP/UDP pseudo-header
114
 * returns a 16-bit checksum, already complemented
115
 */
116
static inline unsigned short int
117
csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len,
118
                  unsigned int proto, unsigned int sum)
119
{
120
        __asm__(
121
        "adds   %0, %1, %2              @ csum_tcpudp_magic     \n\
122
        adcs    %0, %0, %3                                      \n\
123
        adcs    %0, %0, %4                                      \n\
124
        adcs    %0, %0, %5                                      \n\
125
        adc     %0, %0, #0                                      \n\
126
        adds    %0, %0, %0, lsl #16                             \n\
127
        addcs   %0, %0, #0x10000                                \n\
128
        mvn     %0, %0"
129
        : "=&r"(sum)
130
        : "r" (sum), "r" (daddr), "r" (saddr), "r" (ntohs(len)), "Ir" (proto << 8)
131
        : "cc");
132
        return sum >> 16;
133
}
134
 
135
 
136
/*
137
 * this routine is used for miscellaneous IP-like checksums, mainly
138
 * in icmp.c
139
 */
140
static inline unsigned short
141
ip_compute_csum(unsigned char * buff, int len)
142
{
143
        return csum_fold(csum_partial(buff, len, 0));
144
}
145
 
146
#define _HAVE_ARCH_IPV6_CSUM
147
extern unsigned long
148
__csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr, __u32 len,
149
                __u32 proto, unsigned int sum);
150
 
151
static inline unsigned short int
152
csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr, __u32 len,
153
                unsigned short proto, unsigned int sum)
154
{
155
        return csum_fold(__csum_ipv6_magic(saddr, daddr, htonl(len),
156
                                           htonl(proto), sum));
157
}
158
#endif

powered by: WebSVN 2.1.0

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