#include <common.h>
#include <malloc.h>
#include <galileo/gt64260R.h>
#include <galileo/core.h>
#include <asm/cache.h>
#include "eth.h"
#include "eth_addrtbl.h"

#define TRUE 1
#define FALSE 0

#define PRINTF printf

#ifdef CONFIG_GT_USE_MAC_HASH_TABLE

static u32 addressTableHashMode[GAL_ETH_DEVS] = { 0, };
static u32 addressTableHashSize[GAL_ETH_DEVS] = { 0, };
static addrTblEntry *addressTableBase[GAL_ETH_DEVS] = { 0, };
static void *realAddrTableBase[GAL_ETH_DEVS] = { 0, };

static const u32 hashLength[2] = {
	(0x8000),		/* 8K * 4 entries */
	(0x8000 / 16),		/* 512 * 4 entries */
};

/* Initialize the address table for a port, if needed */
unsigned int initAddressTable (u32 port, u32 hashMode, u32 hashSizeSelector)
{
	unsigned int tableBase;

	if (port < 0 || port >= GAL_ETH_DEVS) {
		printf ("%s: Invalid port number %d\n", __FUNCTION__, port);
		return 0;
	}

	if (hashMode > 1) {
		printf ("%s: Invalid Hash Mode %d\n", __FUNCTION__, port);
		return 0;
	}

	if (realAddrTableBase[port] &&
	    (addressTableHashSize[port] != hashSizeSelector)) {
		/* we have been here before,
		 * but now we want a different sized table
		 */
		free (realAddrTableBase[port]);
		realAddrTableBase[port] = 0;
		addressTableBase[port] = 0;

	}

	tableBase = (unsigned int) addressTableBase[port];
	/* we get called for every probe, so only do this once */
	if (!tableBase) {
		int bytes =
			hashLength[hashSizeSelector] * sizeof (addrTblEntry);

		tableBase = (unsigned int) realAddrTableBase[port] =
			malloc (bytes + 64);

		if (!tableBase) {
			printf ("%s: alloc memory failed \n", __FUNCTION__);
			return 0;
		}

		/* align to octal byte */
		if (tableBase & 63)
			tableBase = (tableBase + 63) & ~63;

		addressTableHashMode[port] = hashMode;
		addressTableHashSize[port] = hashSizeSelector;
		addressTableBase[port] = (addrTblEntry *) tableBase;

		memset ((void *) tableBase, 0, bytes);
	}

	return tableBase;
}

/*
 * ----------------------------------------------------------------------------
 * This function will calculate the hash function of the address.
 * depends on the hash mode and hash size.
 * Inputs
 * macH             - the 2 most significant bytes of the MAC address.
 * macL             - the 4 least significant bytes of the MAC address.
 * hashMode         - hash mode 0 or hash mode 1.
 * hashSizeSelector - indicates number of hash table entries (0=0x8000,1=0x800)
 * Outputs
 * return the calculated entry.
 */
u32 hashTableFunction (u32 macH, u32 macL, u32 HashSize, u32 hash_mode)
{
	u32 hashResult;
	u32 addrH;
	u32 addrL;
	u32 addr0;
	u32 addr1;
	u32 addr2;
	u32 addr3;
	u32 addrHSwapped;
	u32 addrLSwapped;


	addrH = NIBBLE_SWAPPING_16_BIT (macH);
	addrL = NIBBLE_SWAPPING_32_BIT (macL);

	addrHSwapped = FLIP_4_BITS (addrH & 0xf)
		+ ((FLIP_4_BITS ((addrH >> 4) & 0xf)) << 4)
		+ ((FLIP_4_BITS ((addrH >> 8) & 0xf)) << 8)
		+ ((FLIP_4_BITS ((addrH >> 12) & 0xf)) << 12);

	addrLSwapped = FLIP_4_BITS (addrL & 0xf)
		+ ((FLIP_4_BITS ((addrL >> 4) & 0xf)) << 4)
		+ ((FLIP_4_BITS ((addrL >> 8) & 0xf)) << 8)
		+ ((FLIP_4_BITS ((addrL >> 12) & 0xf)) << 12)
		+ ((FLIP_4_BITS ((addrL >> 16) & 0xf)) << 16)
		+ ((FLIP_4_BITS ((addrL >> 20) & 0xf)) << 20)
		+ ((FLIP_4_BITS ((addrL >> 24) & 0xf)) << 24)
		+ ((FLIP_4_BITS ((addrL >> 28) & 0xf)) << 28);

	addrH = addrHSwapped;
	addrL = addrLSwapped;

	if (hash_mode == 0) {
		addr0 = (addrL >> 2) & 0x03f;
		addr1 = (addrL & 0x003) | ((addrL >> 8) & 0x7f) << 2;
		addr2 = (addrL >> 15) & 0x1ff;
		addr3 = ((addrL >> 24) & 0x0ff) | ((addrH & 1) << 8);
	} else {
		addr0 = FLIP_6_BITS (addrL & 0x03f);
		addr1 = FLIP_9_BITS (((addrL >> 6) & 0x1ff));
		addr2 = FLIP_9_BITS ((addrL >> 15) & 0x1ff);
		addr3 = FLIP_9_BITS ((((addrL >> 24) & 0x0ff) |
				      ((addrH & 0x1) << 8)));
	}

	hashResult = (addr0 << 9) | (addr1 ^ addr2 ^ addr3);

	if (HashSize == _8K_TABLE) {
		hashResult = hashResult & 0xffff;
	} else {
		hashResult = hashResult & 0x07ff;
	}

	return (hashResult);
}


/*
 * ----------------------------------------------------------------------------
 * This function will add an entry to the address table.
 * depends on the hash mode and hash size that was initialized.
 * Inputs
 * port - ETHERNET port number.
 * macH - the 2 most significant bytes of the MAC address.
 * macL - the 4 least significant bytes of the MAC address.
 * skip - if 1, skip this address.
 * rd   - the RD field in the address table.
 * Outputs
 * address table entry is added.
 * TRUE if success.
 * FALSE if table full
 */
int addAddressTableEntry (u32 port, u32 macH, u32 macL, u32 rd, u32 skip)
{
	addrTblEntry *entry;
	u32 newHi;
	u32 newLo;
	u32 i;

	newLo = (((macH >> 4) & 0xf) << 15)
		| (((macH >> 0) & 0xf) << 11)
		| (((macH >> 12) & 0xf) << 7)
		| (((macH >> 8) & 0xf) << 3)
		| (((macL >> 20) & 0x1) << 31)
		| (((macL >> 16) & 0xf) << 27)
		| (((macL >> 28) & 0xf) << 23)
		| (((macL >> 24) & 0xf) << 19)
		| (skip << SKIP_BIT) | (rd << 2) | VALID;

	newHi = (((macL >> 4) & 0xf) << 15)
		| (((macL >> 0) & 0xf) << 11)
		| (((macL >> 12) & 0xf) << 7)
		| (((macL >> 8) & 0xf) << 3)
		| (((macL >> 21) & 0x7) << 0);

	/*
	 * Pick the appropriate table, start scanning for free/reusable
	 * entries at the index obtained by hashing the specified MAC address
	 */
	entry = addressTableBase[port];
	entry += hashTableFunction (macH, macL, addressTableHashSize[port],
				    addressTableHashMode[port]);
	for (i = 0; i < HOP_NUMBER; i++, entry++) {
		if (!(entry->lo & VALID) /*|| (entry->lo & SKIP) */ ) {
			break;
		} else {	/* if same address put in same position */
			if (((entry->lo & 0xfffffff8) == (newLo & 0xfffffff8))
			    && (entry->hi == newHi)) {
				break;
			}
		}
	}

	if (i == HOP_NUMBER) {
		PRINTF ("addGT64260addressTableEntry: table section is full\n");
		return (FALSE);
	}

	/*
	 * Update the selected entry
	 */
	entry->hi = newHi;
	entry->lo = newLo;
	DCACHE_FLUSH_N_SYNC ((u32) entry, MAC_ENTRY_SIZE);
	return (TRUE);
}

#endif /* CONFIG_GT_USE_MAC_HASH_TABLE */
