add a generic ip_fast_csum for non-x86 platform

Signed-off-by: Jianbo Liu <jianbo.liu@linaro.org>
master
Jianbo Liu 2016-12-14 15:55:20 +08:00
parent 10606dd2b3
commit b1ccaa8bf9
1 changed files with 55 additions and 0 deletions

View File

@ -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__ */