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

Subversion Repositories or1k

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

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

Line No. Rev Author Line
1 1275 phoenix
#ifndef _X86_64_CHECKSUM_H
2
#define _X86_64_CHECKSUM_H
3
 
4
/*
5
 * Checksums for x86-64
6
 * Copyright 2002 by Andi Kleen, SuSE Labs
7
 * with some code from asm-i386/checksum.h
8
 */
9
 
10
#include <linux/compiler.h>
11
#include <asm/uaccess.h>
12
#include <asm/byteorder.h>
13
 
14
/**
15
 * csum_fold - Fold and invert a 32bit checksum.
16
 * sum: 32bit unfolded sum
17
 *
18
 * Fold a 32bit running checksum to 16bit and invert it. This is usually
19
 * the last step before putting a checksum into a packet.
20
 * Make sure not to mix with 64bit checksums.
21
 */
22
static inline unsigned int csum_fold(unsigned int sum)
23
{
24
        __asm__(
25
                "  addl %1,%0\n"
26
                "  adcl $0xffff,%0"
27
                : "=r" (sum)
28
                : "r" (sum << 16), "0" (sum & 0xffff0000)
29
        );
30
        return (~sum) >> 16;
31
}
32
 
33
/*
34
 *      This is a version of ip_compute_csum() optimized for IP headers,
35
 *      which always checksum on 4 octet boundaries.
36
 *
37
 *      By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
38
 *      Arnt Gulbrandsen.
39
 */
40
 
41
/**
42
 * ip_fast_csum - Compute the IPv4 header checksum efficiently.
43
 * iph: ipv4 header
44
 * ihl: length of header / 4
45
 */
46
static inline unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl)
47
{
48
        unsigned int sum;
49
 
50
        asm(    "  movl (%1), %0\n"
51
                "  subl $4, %2\n"
52
                "  jbe 2f\n"
53
                "  addl 4(%1), %0\n"
54
                "  adcl 8(%1), %0\n"
55
                "  adcl 12(%1), %0\n"
56
                "1: adcl 16(%1), %0\n"
57
                "  lea 4(%1), %1\n"
58
                "  decl %2\n"
59
                "  jne  1b\n"
60
                "  adcl $0, %0\n"
61
                "  movl %0, %2\n"
62
                "  shrl $16, %0\n"
63
                "  addw %w2, %w0\n"
64
                "  adcl $0, %0\n"
65
                "  notl %0\n"
66
                "2:"
67
        /* Since the input registers which are loaded with iph and ipl
68
           are modified, we must also specify them as outputs, or gcc
69
           will assume they contain their original values. */
70
        : "=r" (sum), "=r" (iph), "=r" (ihl)
71
        : "1" (iph), "2" (ihl)
72
        : "memory");
73
        return(sum);
74
}
75
 
76
/**
77
 * csum_tcpup_nofold - Compute an IPv4 pseudo header checksum.
78
 * @saddr: source address
79
 * @daddr: destination address
80
 * @len: length of packet
81
 * @proto: ip protocol of packet
82
 * @sum: initial sum to be added in (32bit unfolded)
83
 *
84
 * Returns the pseudo header checksum the input data. Result is
85
 * 32bit unfolded.
86
 */
87
static inline unsigned long
88
csum_tcpudp_nofold(unsigned saddr, unsigned daddr, unsigned short len,
89
                   unsigned short proto, unsigned int sum)
90
{
91
        asm("  addl %1, %0\n"
92
            "  adcl %2, %0\n"
93
            "  adcl %3, %0\n"
94
            "  adcl $0, %0\n"
95
                : "=r" (sum)
96
            : "g" (daddr), "g" (saddr), "g" ((ntohs(len)<<16)+proto*256), "0" (sum));
97
    return sum;
98
}
99
 
100
 
101
/**
102
 * csum_tcpup_magic - Compute an IPv4 pseudo header checksum.
103
 * @saddr: source address
104
 * @daddr: destination address
105
 * @len: length of packet
106
 * @proto: ip protocol of packet
107
 * @sum: initial sum to be added in (32bit unfolded)
108
 *
109
 * Returns the 16bit pseudo header checksum the input data already
110
 * complemented and ready to be filled in.
111
 */
112
static inline unsigned short int
113
csum_tcpudp_magic(unsigned long saddr, unsigned long daddr,
114
                  unsigned short len, unsigned short proto, unsigned int sum)
115
{
116
        return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
117
}
118
 
119
/**
120
 * csum_partial - Compute an internet checksum.
121
 * @buff: buffer to be checksummed
122
 * @len: length of buffer.
123
 * @sum: initial sum to be added in (32bit unfolded)
124
 *
125
 * Returns the 32bit unfolded internet checksum of the buffer.
126
 * Before filling it in it needs to be csum_fold()'ed.
127
 * buff should be aligned to a 64bit boundary if possible.
128
 */
129
extern unsigned int csum_partial(const unsigned char *buff, unsigned len, unsigned int sum);
130
 
131
#define  _HAVE_ARCH_COPY_AND_CSUM_FROM_USER 1
132
#define HAVE_CSUM_COPY_USER 1
133
 
134
 
135
/* Do not call this directly. Use the wrappers below */
136
extern unsigned long csum_partial_copy_generic(const char *src, const char *dst,
137
                                               unsigned len,
138
                                               unsigned sum,
139
                                               int *src_err_ptr, int *dst_err_ptr);
140
 
141
 
142
extern unsigned int csum_partial_copy_from_user(const char *src, char *dst,
143
                                       int len, unsigned int isum, int *errp);
144
extern unsigned int csum_partial_copy_to_user(const char *src, char *dst,
145
                                      int len, unsigned int isum, int *errp);
146
extern unsigned int csum_partial_copy_nocheck(const char *src, char *dst, int len,
147
                                              unsigned int sum);
148
 
149
/* Old names. To be removed. */
150
#define csum_and_copy_to_user csum_partial_copy_to_user
151
#define csum_and_copy_from_user csum_partial_copy_from_user
152
 
153
/**
154
 * ip_compute_csum - Compute an 16bit IP checksum.
155
 * @buff: buffer address.
156
 * @len: length of buffer.
157
 *
158
 * Returns the 16bit folded/inverted checksum of the passed buffer.
159
 * Ready to fill in.
160
 */
161
extern unsigned short ip_compute_csum(unsigned char * buff, int len);
162
 
163
/**
164
 * csum_ipv6_magic - Compute checksum of an IPv6 pseudo header.
165
 * @saddr: source address
166
 * @daddr: destination address
167
 * @len: length of packet
168
 * @proto: protocol of packet
169
 * @sum: initial sum (32bit unfolded) to be added in
170
 *
171
 * Computes an IPv6 pseudo header checksum. This sum is added the checksum
172
 * into UDP/TCP packets and contains some link layer information.
173
 * Returns the unfolded 32bit checksum.
174
 */
175
 
176
struct in6_addr;
177
 
178
#define _HAVE_ARCH_IPV6_CSUM 1
179
extern unsigned short
180
csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr,
181
                __u32 len, unsigned short proto, unsigned int sum);
182
 
183
static inline unsigned add32_with_carry(unsigned a, unsigned b)
184
{
185
        asm("addl %2,%0\n\t"
186
            "adcl $0,%0"
187
            : "=r" (a)
188
            : "0" (a), "r" (b));
189
        return a;
190
}
191
 
192
#endif
193
 

powered by: WebSVN 2.1.0

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