sitara_depot/components/free_rtos/ethernet_ip/eth_checksum.c

111 lines
2.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* eth_checksum.c
*
* Created on: 13 мар. 2023 г.
* Author: sychev
*/
#include "free_rtos/ethernet_ip/eth_checksum.h"
#include "free_rtos/base/swap.h"
uint16_t eth_calcChksum(uint32_t sum, uint8_t * const data, uint16_t len)
{
uint16_t i;
uint16_t size = len - 1;
if ( !len )
return 0;
for ( i = 0; i < size; i+=2 )
sum += ((uint16_t)data[i] << 8) + data[i+1];
if (len & 0x01)
sum += (uint16_t)data[i] << 8;
while ( sum >> 16 )
sum = (sum & 0xFFFF) + (sum >> 16);
return ~sum;
}
uint16_t eth_calcChksum2(uint32_t sum, uint8_t * const hdata, uint16_t hlen, uint8_t * const data, uint16_t len)
{
uint16_t i;
uint16_t hsize = hlen - 1;
uint16_t size = len - 1;
if ( (hlen == 0) || (len == 0) )
return 0;
for ( i = 0; i < hsize; i+=2 )
sum += ((uint16_t)hdata[i] << 8) + hdata[i+1];
if (hlen & 0x01)
sum += (uint16_t)hdata[i] << 8;
for ( i = 0; i < size; i+=2 )
sum += ((uint16_t)data[i] << 8) + data[i+1];
if (len & 0x01)
sum += (uint16_t)data[i] << 8;
while ( sum >> 16 )
sum = (sum & 0xFFFF) + (sum >> 16);
return ~sum;
}
inline uint32_t calcSum(void * buffer, uint32_t sum, void * const data, uint16_t len) {
uint32_t * buffer_start32 = (uint32_t*)buffer;
uint32_t * data_start32 = (uint32_t*)data;
uint32_t * data_end32 = data_start32 + len/sizeof(uint32_t);
uint32_t remainder = len%sizeof(uint32_t);
uint32_t value;
while(data_start32 < data_end32) {
value = *data_start32++;
*buffer_start32++ = value;
value = __rev16(value);
sum += (value&0xFFFF) + (value>>16);
}
uint16_t * buffer_start16 = (uint16_t*)buffer_start32;
uint16_t * data_start16 = (uint16_t*)data_start32;
if(remainder > 1) {
value = *data_start16++;
*buffer_start16++ = value;
value = __rev16(value);
sum += value;
}
uint8_t * buffer_start8 = (uint8_t*)buffer_start16;
uint8_t * data_start8 = (uint8_t*)data_start16;
if(remainder == 1) {
value = *data_start8++;
*buffer_start8++ = value;
value = __rev16(value);
sum += value;
}
return sum;
}
uint16_t eth_calcChksum3(void * buffer, uint32_t sum, void * const hdata, uint16_t hlen, void * const data, uint16_t len)
{
if(hdata != 0) {
sum = calcSum(buffer, sum, hdata, hlen);
}
if(data != 0) {
sum = calcSum((uint8_t*)buffer + hlen, sum, data, len);
}
while (sum >> 16) {
sum = (sum & 0xFFFF) + (sum >> 16);
}
return ~sum;
}