diff options
author | Simon Glass <sjg@chromium.org> | 2019-12-06 21:41:39 -0700 |
---|---|---|
committer | Bin Meng <bmeng.cn@gmail.com> | 2019-12-15 11:43:57 +0800 |
commit | d721001fd6d4162738578ba03c94c1198a5ef462 (patch) | |
tree | e34fa7081a828277e9b9b6fbc0ed0b4269bd26f6 /lib/net_utils.c | |
parent | 6dd4b014329dc1f3e3e9a3c7c9055b1e0c4da3c3 (diff) | |
download | u-boot-d721001fd6d4162738578ba03c94c1198a5ef462.tar.gz |
net: Move the checksum functions to lib/
These functions are used by code outside the network support, so move them
to lib/ to be more accessible.
Without this, the functions are only accessible in SPL/TPL only if
CONFIG_SPL/TPL_NET are defined. Many boards do not enable those option but
still want to do checksums in this format.
Fix up a few code-style nits while we are here.
Signed-off-by: Simon Glass <sjg@chromium.org>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Diffstat (limited to 'lib/net_utils.c')
-rw-r--r-- | lib/net_utils.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/lib/net_utils.c b/lib/net_utils.c index ed5044c3de..8af7782970 100644 --- a/lib/net_utils.c +++ b/lib/net_utils.c @@ -56,3 +56,51 @@ void string_to_enetaddr(const char *addr, uint8_t *enetaddr) addr = (*end) ? end + 1 : end; } } + +uint compute_ip_checksum(const void *vptr, uint nbytes) +{ + int sum, oddbyte; + const unsigned short *ptr = vptr; + + sum = 0; + while (nbytes > 1) { + sum += *ptr++; + nbytes -= 2; + } + if (nbytes == 1) { + oddbyte = 0; + ((u8 *)&oddbyte)[0] = *(u8 *)ptr; + ((u8 *)&oddbyte)[1] = 0; + sum += oddbyte; + } + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >> 16); + sum = ~sum & 0xffff; + + return sum; +} + +uint add_ip_checksums(uint offset, uint sum, uint new) +{ + ulong checksum; + + sum = ~sum & 0xffff; + new = ~new & 0xffff; + if (offset & 1) { + /* + * byte-swap the sum if it came from an odd offset; since the + * computation is endian-independent this works. + */ + new = ((new >> 8) & 0xff) | ((new << 8) & 0xff00); + } + checksum = sum + new; + if (checksum > 0xffff) + checksum -= 0xffff; + + return (~checksum) & 0xffff; +} + +int ip_checksum_ok(const void *addr, uint nbytes) +{ + return !(compute_ip_checksum(addr, nbytes) & 0xfffe); +} |