Prepared for checksum-on-copy (task #6849):

- Added option LWIP_CHECKSUM_ON_COPY;
- Added function + define lwip_chksum_copy to create checksum when copying data
This commit is contained in:
goldsimon 2010-03-14 11:23:37 +00:00
parent 4e764017c1
commit 84ed9de21a
3 changed files with 61 additions and 18 deletions

View File

@ -42,6 +42,7 @@
#include "lwip/def.h" #include "lwip/def.h"
#include <stddef.h> #include <stddef.h>
#include <string.h>
/* These are some reference implementations of the checksum algorithm, with the /* These are some reference implementations of the checksum algorithm, with the
* aim of being simple, correct and fully portable. Checksumming is the * aim of being simple, correct and fully portable. Checksumming is the
@ -65,18 +66,6 @@
# define LWIP_CHKSUM_ALGORITHM 0 # define LWIP_CHKSUM_ALGORITHM 0
#endif #endif
/** Like the name says... */
#if LWIP_PLATFORM_BYTESWAP && (BYTE_ORDER == LITTLE_ENDIAN)
/* little endian and PLATFORM_BYTESWAP defined */
#define SWAP_BYTES_IN_WORD(w) LWIP_PLATFORM_HTONS(w)
#else
/* can't use htons on big endian (or PLATFORM_BYTESWAP not defined)... */
#define SWAP_BYTES_IN_WORD(w) ((w & 0xff) << 8) | ((w & 0xff00) >> 8)
#endif
/** Split an u32_t in two u16_ts and add them up */
#define FOLD_U32T(u) ((u >> 16) + (u & 0x0000ffffUL))
#if (LWIP_CHKSUM_ALGORITHM == 1) /* Version #1 */ #if (LWIP_CHKSUM_ALGORITHM == 1) /* Version #1 */
/** /**
* lwip checksum * lwip checksum
@ -339,8 +328,6 @@ inet_chksum_pseudo(struct pbuf *p,
* @param proto_len length of the ip data part (used for checksum of pseudo header) * @param proto_len length of the ip data part (used for checksum of pseudo header)
* @return checksum (as u16_t) to be saved directly in the protocol header * @return checksum (as u16_t) to be saved directly in the protocol header
*/ */
/* Currently only used by UDPLITE, although this could change in the future. */
#if LWIP_UDPLITE
u16_t u16_t
inet_chksum_pseudo_partial(struct pbuf *p, inet_chksum_pseudo_partial(struct pbuf *p,
ip_addr_t *src, ip_addr_t *dest, ip_addr_t *src, ip_addr_t *dest,
@ -394,7 +381,6 @@ inet_chksum_pseudo_partial(struct pbuf *p,
LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc)); LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc));
return (u16_t)~(acc & 0xffffUL); return (u16_t)~(acc & 0xffffUL);
} }
#endif /* LWIP_UDPLITE */
/* inet_chksum: /* inet_chksum:
* *
@ -442,3 +428,23 @@ inet_chksum_pbuf(struct pbuf *p)
} }
return (u16_t)~(acc & 0xffffUL); return (u16_t)~(acc & 0xffffUL);
} }
/* These are some implementations for LWIP_CHKSUM_COPY, which copies data
* like MEMCPY but generates a checksum at the same time. Since this is a
* performance-sensitive function, you might want to create your own version
* in assembly targeted at your hardware by defining it in lwipopts.h:
* #define LWIP_CHKSUM_COPY(dst, src, len) your_chksum_copy(dst, src, len)
*/
#if (LWIP_CHKSUM_COPY_ALGORITHM == 1) /* Version #1 */
/** Safe but slow: first call MEMCPY, then call LWIP_CHKSUM.
* For architectures with big caches, data might still be in cache when
* generating the checksum after copying.
*/
u16_t
lwip_chksum_copy(void *dst, const void *src, u16_t len)
{
MEMCPY(dst, src, len);
return LWIP_CHKSUM(dst, len);
}
#endif /* (LWIP_CHKSUM_COPY_ALGORITHM == 1) */

View File

@ -37,6 +37,35 @@
#include "lwip/pbuf.h" #include "lwip/pbuf.h"
#include "lwip/ip_addr.h" #include "lwip/ip_addr.h"
/** Swap the bytes in an u16_t: much like htons() for little-endian */
#ifndef SWAP_BYTES_IN_WORD
#if LWIP_PLATFORM_BYTESWAP && (BYTE_ORDER == LITTLE_ENDIAN)
/* little endian and PLATFORM_BYTESWAP defined */
#define SWAP_BYTES_IN_WORD(w) LWIP_PLATFORM_HTONS(w)
#else /* LWIP_PLATFORM_BYTESWAP && (BYTE_ORDER == LITTLE_ENDIAN) */
/* can't use htons on big endian (or PLATFORM_BYTESWAP not defined)... */
#define SWAP_BYTES_IN_WORD(w) (((w) & 0xff) << 8) | (((w) & 0xff00) >> 8)
#endif /* LWIP_PLATFORM_BYTESWAP && (BYTE_ORDER == LITTLE_ENDIAN)*/
#endif /* SWAP_BYTES_IN_WORD */
/** Split an u32_t in two u16_ts and add them up */
#ifndef FOLD_U32T
#define FOLD_U32T(u) (((u) >> 16) + ((u) & 0x0000ffffUL))
#endif
#if LWIP_CHECKSUM_ON_COPY
/** Function-like macro: same as MEMCPY but returns the checksum of copied data
as u16_t */
#ifndef LWIP_CHKSUM_COPY
#define LWIP_CHKSUM_COPY(dst, src, len) lwip_chksum_copy(dst, src, len)
#ifndef LWIP_CHKSUM_COPY_ALGORITHM
#define LWIP_CHKSUM_COPY_ALGORITHM 1
#endif /* LWIP_CHKSUM_COPY_ALGORITHM */
#endif /* LWIP_CHKSUM_COPY */
#else /* LWIP_CHECKSUM_ON_COPY */
#define LWIP_CHKSUM_COPY_ALGORITHM 0
#endif /* LWIP_CHECKSUM_ON_COPY */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -46,11 +75,12 @@ u16_t inet_chksum_pbuf(struct pbuf *p);
u16_t inet_chksum_pseudo(struct pbuf *p, u16_t inet_chksum_pseudo(struct pbuf *p,
ip_addr_t *src, ip_addr_t *dest, ip_addr_t *src, ip_addr_t *dest,
u8_t proto, u16_t proto_len); u8_t proto, u16_t proto_len);
#if LWIP_UDPLITE
u16_t inet_chksum_pseudo_partial(struct pbuf *p, u16_t inet_chksum_pseudo_partial(struct pbuf *p,
ip_addr_t *src, ip_addr_t *dest, ip_addr_t *src, ip_addr_t *dest,
u8_t proto, u16_t proto_len, u16_t chksum_len); u8_t proto, u16_t proto_len, u16_t chksum_len);
#endif #if LWIP_CHKSUM_COPY_ALGORITHM
u16_t lwip_chksum_copy(void *dst, const void *src, u16_t len);
#endif /* LWIP_CHKSUM_COPY_ALGORITHM */
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -444,7 +444,6 @@
#define ETH_PAD_SIZE 0 #define ETH_PAD_SIZE 0
#endif #endif
/* /*
-------------------------------- --------------------------------
---------- IP options ---------- ---------- IP options ----------
@ -1708,6 +1707,14 @@
#define CHECKSUM_CHECK_TCP 1 #define CHECKSUM_CHECK_TCP 1
#endif #endif
/**
* LWIP_CHECKSUM_ON_COPY==1: Calculate checksum when copying data from
* application buffers to pbufs.
*/
#ifndef LWIP_CHECKSUM_ON_COPY
#define LWIP_CHECKSUM_ON_COPY 0
#endif
/* /*
--------------------------------------- ---------------------------------------
---------- Debugging options ---------- ---------- Debugging options ----------