/*
 *  Copyright (c) 2009 Mindspeed Technologies, Inc.
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; either version 2
 *  of the License, or (at your option) any later version.

 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.

 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 *
 */


#ifndef _MODULE_MC4_H_
#define _MODULE_MC4_H_

#include "types.h"
#include "modules.h"
#include "channels.h"
#include "multicast.h"

#define MC4_MAX_LISTENERS_PER_GROUP MCx_MAX_LISTENERS_PER_GROUP 

#define MC4_NUM_HASH_ENTRIES 16

#define INVALID_IDX (-1)
typedef struct tMC4_context {

  	unsigned char ttl_check_rule;
}MC4_context;


#if defined (COMCERTO_2000)

#if defined (COMCERTO_2000_CONTROL)

/** Control path MC4 HW entry */
typedef struct _thw_MC4Entry {
	U32 	flags;
	U32 	dma_addr;
	U32 next;
	U32 src_addr;
	U32 dst_addr;
	/* common portion */
	MCxEntry mcdest;
	U16 status;
	U8 rtpqos_slot;
	U8 padding;  //structure size must be a multiple of 8 bytes for EFET transfers

	/* These fields are only used by host software, so keep them at the end of the structure */
	struct dlist_head 	list;
	struct _tMC4Entry	*sw_entry;	/**< pointer to the software flow entry */
	unsigned long		removal_time;
}hw_MC4Entry, *Phw_MC4Entry;

/** Control path MC4 SW entry */
typedef struct _tMC4Entry {
	struct slist_entry list;
	U32 src_addr;
	U32 dst_addr;
	/* common portion */
	MCxEntry mcdest;
	U16 status;
	U8 rtpqos_slot;
	U8 padding;  //structure size must be a multiple of 8 bytes for EFET transfers

	hw_MC4Entry *hw_entry;
}MC4Entry, *PMC4Entry;


#else
/** Data path MC4 entry */
typedef struct _tMC4Entry {
	U32 	flags;
	U32 	dma_addr;
	U32 	next;
	U32 src_addr;
	U32 dst_addr;
	/* common portion */
	MCxEntry mcdest;
	U16 status;
	U8 rtpqos_slot;
	U8 padding;  //structure size must be a multiple of 8 bytes for EFET transfers
}MC4Entry, *PMC4Entry;
#endif

#else /* COMCERTO 1000 */
typedef struct _tMC4Entry {
	struct slist_entry list;
	U32 src_addr;
	U32 dst_addr;
	/* common portion */
	MCxEntry mcdest;
	U16 status;
	U8 rtpqos_slot;
	U8 padding;  //structure size must be a multiple of 8 bytes for EFET transfers
}MC4Entry, *PMC4Entry;
#endif



/***********************************
* MC4 API Command and Entry structures
*
************************************/
typedef struct _tMC4Output {
	U32		timer;
	U8		output_device_str[11];
	U8 		shaper_mask;
	U8              uc_bit:1,
                        q_bit:1,
                        rsvd:6;
	U8              uc_mac[6];
	U8              queue;
	U8		new_output_device_str[11];
	U8		if_bit:1,
			unused:7;
}MC4Output, *PMC4Output;

typedef struct _tMC4Command {
	U16		action;
	U8		src_addr_mask;
	U8 		mode : 1,
	     		queue : 5,
	     		rsvd : 2;
	U32		src_addr;
	U32		dst_addr;
	U32		num_output;
	MC4Output output_list[MCx_MAX_LISTENERS_IN_QUERY];
}MC4Command, *PMC4Command;
#define MC4_MIN_COMMAND_SIZE	32 /* with one listener entry using 1 interface name */


extern struct tMC4_context gMC4Ctx;
#if !defined(COMCERTO_2000) || defined(COMCERTO_2000_CONTROL)
extern struct slist_head mc4_table_memory[MC4_NUM_HASH_ENTRIES];
#else
extern PVOID mc4_table_memory[MC4_NUM_HASH_ENTRIES];
#endif

BOOL mc4_init(void);
void mc4_exit(void);
void M_MC4_process_packet(PMetadata mtd) __attribute__((section ("fast_path")));
#if !defined(COMCERTO_2000)
void M_mc4_entry(void) __attribute__((section ("fast_path")));
#endif

void MC4_interface_purge(U32 if_index);

int MC4_handle_MULTICAST(U16 *p, U16 Length);
int MC4_handle_RESET (void);
int MC4_check_entry(struct tMetadata *mtd);


static inline u32 HASH_MC4(u32 destaddr)  // pass in IPv4 dest addr
{
	u32 hash;
	destaddr = ntohl(destaddr);
	hash = destaddr + (destaddr >> 16);
	hash = hash ^ (hash >> 4) ^ (hash >> 8) ^ (hash >> 12);
	return hash & (MC4_NUM_HASH_ENTRIES - 1);
}

#ifdef COMCERTO_2000_CLASS
/** Searches multicast forwarding table for match based on source and destination IPv4 addresses.
 * @param[in] srca	IPv4 source address
 * @param[in] dsta	IPv4 destination address
 * @return pointer to matching entry, or NULL if no entry found.
 */
static __inline MC4Entry *MC4_rule_search_class(ipv4_hdr_t *ipv4_hdr)
{
	PMC4Entry dmem_entry;
	volatile PMC4Entry ddr_entry;
	U32 srca = READ_UNALIGNED_INT(ipv4_hdr->SourceAddress);
	U32 dsta = READ_UNALIGNED_INT(ipv4_hdr->DestinationAddress);
	U32 hash_key = HASH_MC4(dsta);

	ddr_entry = mc4_table_memory[hash_key];
	dmem_entry = (PVOID)(CLASS_ROUTE0_BASE_ADDR);
	while (ddr_entry) {
		efet_memcpy(dmem_entry, ddr_entry, sizeof(MC4Entry));
		while (dmem_entry->flags & HASH_ENTRY_UPDATING)
		{
			while (ddr_entry->flags & HASH_ENTRY_UPDATING) ;
			efet_memcpy(dmem_entry, ddr_entry, sizeof(MC4Entry));
		}

		if (dsta == dmem_entry->dst_addr)
		{
			// We have to check for a null mask because the shift instruction is limited to 31 bits on esiRISC
			if ((dmem_entry->mcdest.src_mask_len == 0) || !(ntohl(srca ^  dmem_entry->src_addr)>>(32 - dmem_entry->mcdest.src_mask_len))) {
				return dmem_entry;
			}
		}
		ddr_entry = (PMC4Entry) dmem_entry->next;
	}

	return NULL;
}
#else
/** Searches multicast forwarding table for match based on source and destination IPv4 addresses.
 * @param[in] srca	IPv4 source address
 * @param[in] dsta	IPv4 destination address
 * @return pointer to matching entry, or NULL if no entry found.
 */
static __inline MC4Entry *MC4_rule_search(U32 srca, U32 dsta)
{
	PMC4Entry this_entry;
	struct slist_entry *entry;
	U32 hash_key;

	hash_key = HASH_MC4(dsta);
	slist_for_each(this_entry, entry, &mc4_table_memory[hash_key], list)
	{
	  	if (dsta == this_entry->dst_addr)
	    	{
	      		if (!(ntohl(srca ^  this_entry->src_addr)>>(32 - this_entry->mcdest.src_mask_len))) {
				return this_entry;
	      		}
	    	}
	}

  	return NULL;
}
#endif

#endif /* _MODULE_MC4_H_ */
