add a generic ip_fast_csum for non-x86 platform
Signed-off-by: Jianbo Liu <jianbo.liu@linaro.org>master
parent
10606dd2b3
commit
b1ccaa8bf9
|
@ -63,6 +63,7 @@ struct ____cacheline_aligned ps_context {
|
|||
#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)
|
||||
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
|
||||
{
|
||||
unsigned int sum;
|
||||
|
@ -92,6 +93,60 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
|
|||
: "memory");
|
||||
return (__sum16)sum;
|
||||
}
|
||||
#else
|
||||
#define __force
|
||||
typedef unsigned int u32;
|
||||
|
||||
static inline __sum16 csum_fold(__wsum csum)
|
||||
{
|
||||
u32 sum = (__force u32)csum;;
|
||||
|
||||
sum += (sum << 16);
|
||||
csum = (sum < csum);
|
||||
sum >>= 16;
|
||||
sum += csum;
|
||||
|
||||
return (__force __sum16)~sum;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a version of ip_compute_csum() optimized for IP headers,
|
||||
* which always checksum on 4 octet boundaries.
|
||||
*
|
||||
* By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
|
||||
* Arnt Gulbrandsen.
|
||||
*/
|
||||
static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
|
||||
{
|
||||
const unsigned int *word = iph;
|
||||
const unsigned int *stop = word + ihl;
|
||||
unsigned int csum;
|
||||
int carry;
|
||||
|
||||
csum = word[0];
|
||||
csum += word[1];
|
||||
carry = (csum < word[1]);
|
||||
csum += carry;
|
||||
|
||||
csum += word[2];
|
||||
carry = (csum < word[2]);
|
||||
csum += carry;
|
||||
|
||||
csum += word[3];
|
||||
carry = (csum < word[3]);
|
||||
csum += carry;
|
||||
|
||||
word += 4;
|
||||
do {
|
||||
csum += *word;
|
||||
carry = (csum < *word);
|
||||
csum += carry;
|
||||
word++;
|
||||
} while (word != stop);
|
||||
|
||||
return csum_fold(csum);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
|
|
Loading…
Reference in New Issue