#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 */
