#include "global.h"
/*
 * Word aligned linear buffer checksum routine.	 Called from mbuf checksum
 * routine with simple args.  Intent is that this routine may be replaced
 * by assembly language routine for speed if so desired.
 * Speeded up by PE1CHL, assy is now not worthwile for 68000
 */
int16
lcsum(wp,len)
register int16 *wp;
register int16 len;
{
	int16 eac();
	register int32 sum = 0;
#ifdef	LITTLE_ENDIAN
	int16 result;
#endif

	switch (len & 0x0f)			/* handle length % 16 */
	{
	case 15:
		sum += *wp++;
	case 14:
		sum += *wp++;
	case 13:
		sum += *wp++;
	case 12:
		sum += *wp++;
	case 11:
		sum += *wp++;
	case 10:
		sum += *wp++;
	case 9:
		sum += *wp++;
	case 8:
		sum += *wp++;
	case 7:
		sum += *wp++;
	case 6:
		sum += *wp++;
	case 5:
		sum += *wp++;
	case 4:
		sum += *wp++;
	case 3:
		sum += *wp++;
	case 2:
		sum += *wp++;
	case 1:
		sum += *wp++;
		len &= ~0x0f;
	case 0:
		break;
	}

	if (len != 0)				/* still more blocks of 16? */
	do
	{
		sum += *wp++;			/* then add 16 words quickly */
		sum += *wp++;
		sum += *wp++;
		sum += *wp++;
		sum += *wp++;
		sum += *wp++;
		sum += *wp++;
		sum += *wp++;
		sum += *wp++;
		sum += *wp++;
		sum += *wp++;
		sum += *wp++;
		sum += *wp++;
		sum += *wp++;
		sum += *wp++;
		sum += *wp++;
	} while (len -= 16);			/* while more to go */

#ifdef	LITTLE_ENDIAN
	result = eac(sum);
	/* Swap the result because of the (char *) to (int *) type punning */
	result = (result << 8) | (result >> 8);
	return result;
#else
	return eac(sum);
#endif
}

