diff --git a/cpu/msp430/uip-ipchksum.c b/cpu/msp430/uip-ipchksum.c new file mode 100644 index 000000000..d401a261a --- /dev/null +++ b/cpu/msp430/uip-ipchksum.c @@ -0,0 +1,28 @@ +/*---------------------------------------------------------------------------*/ +#ifdef UIP_ARCH_IPCHKSUM +u16_t +uip_ipchksum(void) +{ + /* Assumes proper alignement of uip_buf. */ + u16_t *p = (u16_t *)&uip_buf[UIP_LLH_LEN]; + register u16_t sum; + + sum = p[0]; + asmv("add %[p], %[sum]": [sum] "+r" (sum): [p] "m" (p[1])); + asmv("addc %[p], %[sum]": [sum] "+r" (sum): [p] "m" (p[2])); + asmv("addc %[p], %[sum]": [sum] "+r" (sum): [p] "m" (p[3])); + asmv("addc %[p], %[sum]": [sum] "+r" (sum): [p] "m" (p[4])); + asmv("addc %[p], %[sum]": [sum] "+r" (sum): [p] "m" (p[5])); + asmv("addc %[p], %[sum]": [sum] "+r" (sum): [p] "m" (p[6])); + asmv("addc %[p], %[sum]": [sum] "+r" (sum): [p] "m" (p[7])); + asmv("addc %[p], %[sum]": [sum] "+r" (sum): [p] "m" (p[8])); + asmv("addc %[p], %[sum]": [sum] "+r" (sum): [p] "m" (p[9])); + + /* Finally, add the remaining carry bit. */ + asmv("addc #0, %[sum]": [sum] "+r" (sum)); + + /* Return sum in network byte order. */ + return (sum == 0) ? 0xffff : sum; +} +#endif +/*---------------------------------------------------------------------------*/