sitara_depot/components/free_rtos/ethernet_ip/eth_checksum.c

111 lines
2.6 KiB
C

/*
* 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;
}