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


#include "types.h"
#include "system.h"
#include "fpp.h"
#include "multicast.h"

#ifdef COMCERTO_2000_CLASS
/** Prepend L2 headers, excluding the outermost one in case of QinQ.
 * This behavior is needed on C2k because the hardware will take care of modifying
 * the last header, as long as it only means changing the src MAC address and/or VLAN tag.
 * @param mtd
 * @param pmcl
 */
U32 mc_prepend_upper_header(PMetadata mtd, PMCListener pmcl, U16 **srcMac, real_vlan_hdr_t *vlan_tag, U8 flags)
{
	U16 ethertype = l2_get_tid(pmcl->family);
	U16 vlanid = 0;
	U16 srcMac_orig[3];
	U16 *pkt_src_mac;
	struct itf *itf = pmcl->itf;
	int res = 0;

	pkt_src_mac = (U16 *) (mtd->data + BaseOffset + ETHER_ADDR_LEN);
	COPY_MACADDR(srcMac_orig, pkt_src_mac);

	if (itf->type & IF_TYPE_PPPOE)
	{
		M_pppoe_encapsulate(mtd, (pPPPoE_Info)itf, ethertype, 1);
		ethertype = ETHERTYPE_PPPOE_END;
		itf = itf->phys;
	}

#ifdef CFG_MACVLAN
	if (itf->type & IF_TYPE_MACVLAN)
	{
		*srcMac = ((PMacvlanEntry)itf)->MACaddr;
		itf = itf->phys;
	}
#endif

	/* We can add but not remove VLANs in hardware, so:
	 * . if we must add a VLAN tag, we store its value to program the HW later (so we'll be able to handle listeners
	 * with or without VLAN tags).
	 * . if we must add 2 VLAN tags (QinQ), we add the inner one and store the value of the second to program the HW later
	 * (so we'll be able to handle listeners with one or 2 tags).
	 * => This means we cannot handle regular ethernet and QinQ listeners in hardware for the same packet.
	 */
	if (itf->type & IF_TYPE_VLAN)
	{
		vlanid = ((PVlanEntry) itf)->VlanId;

		/* QinQ */
		if (itf->phys->type & IF_TYPE_VLAN)
		{
			res = 1;
			M_vlan_encapsulate(mtd, (PVlanEntry)itf, ethertype, 1);
			ethertype = ETHERTYPE_VLAN_END;
			itf = itf->phys;
			vlanid = ((PVlanEntry) itf)->VlanId;
		}
		itf = itf->phys;
	}

	if (vlanid)
	{
		fill_real_vlan_header(vlan_tag, ETHERTYPE_VLAN_END, vlanid, mtd->vlan_pbits);
	}

	mtd->length += ETH_HEADER_SIZE;
	mtd->offset -= ETH_HEADER_SIZE;

#ifdef CFG_MACVLAN
	if (itf->type & IF_TYPE_MACVLAN)
	{
		*srcMac = ((PMacvlanEntry)itf)->MACaddr;
		itf = itf->phys;
	}
	else
#endif
	if (!*srcMac)
		*srcMac = (U16 *) ((struct physical_port *)itf)->mac_addr;


	mtd->output_port = ((struct physical_port *)itf)->id;

	if((IS_WIFI_PORT(mtd->output_port)) && ((flags & MC_MODE_MASK) == MC_MODE_ROUTED) )
		COPY_MACHEADER(mtd->data + mtd->offset, pmcl->dstmac, *srcMac, ethertype);
	else
		COPY_MACHEADER(mtd->data + mtd->offset, pmcl->dstmac, srcMac_orig, ethertype);

	return res;
}


/** Clone and send a packet.
 * Device-specific (C2000), should only be called by mc_clone_and_send.
 * @param[in] mtd				Metadata for the packet to be sent
 * @param[in] mcdest			Multicast destination entry to send the packet to
 * @param[in] first_listener	First output destination
 */
void __mc_clone_and_send(PMetadata mtd, PMCxEntry mcdest, PMCListener first_listener)
{
	U32 n = mcdest->num_listeners;
	U8 no_of_mc_uc_lis = mcdest->num_mc_uc_listeners;
#ifdef CFG_WIFI_OFFLOAD
	U8 no_of_wifi_mc_lis = mcdest->num_wifi_mc_listeners;
#else
	U8 no_of_wifi_mc_lis = 0;
#endif
	U32 packet_start;
	U16 *src_mac = NULL;
	int i=0;
	int j=0;
	int first_is_vlan = 0;
	real_vlan_hdr_t vlan_tag;
	struct itf *itf;
	class_tx_hdr_mc_t *tx_hdr;
	u16 hif_hdr_len = 0;
	U32 queue_mod = DSCP_to_Qmod[mtd->priv_mcast_dscp];
	void *ddr_ptr=NULL;
	void *ddr_start=NULL;
	void *dmem_addr;
	U16 orig_mtd_offset;
	U16 orig_mtd_length;
	int mc_uc_or_wifi_mc_lisidx=0;
	U8 send_last_mc_uc_or_wifi_pkt_by_ro=FALSE;
	U8 get_first_mc_lis_idx=FALSE;
	u32 phy;

	vlan_tag.tag = 0;

	// TODO We need enough headroom for additional descriptors, otherwise send to exception path.

	/* Assume all listeners will have the same L2 headers after first ETH/VLAN fields.
	 * This assumption is no longer required on the C1k with the use of itf structs, but still is on the C2k.
	 */
	if (mcdest->flags & MC_ACP_LISTENER)
	{
		mtd->priv_mcast_refcnt = n+1; // For C2k, priv_mcast_refcnt will be the total number of clones, i.e. one more than the C1k value.
	} else
	{
		mtd->priv_mcast_refcnt = n; // For C2k, priv_mcast_refcnt will be the total number of clones, i.e. one more than the C1k value.
	}


	/* Packet is sent by RO for
		    1. MC listeners that are not WiFi listeners or
		    2. (MC-UC listener Or WiFi MC Listener when n==1) or
		    3. (Last MC-UC listener or WiFi MC listener when no MC non-WiFi listeners are present) */

	if(no_of_mc_uc_lis + no_of_wifi_mc_lis) {

		/* Condition: IF all listeners are MC-UC listeners or WiFi MC Listeners, send last one by RO if ACP is not programmed
		   Otherwise point to first MC listener that is not WiFi listener to send by RO */
		if((no_of_mc_uc_lis + no_of_wifi_mc_lis) == n) {
			if(!(mcdest->flags & MC_ACP_LISTENER)) {
				if((no_of_mc_uc_lis + no_of_wifi_mc_lis) ==1)
				{
					goto send_by_ro;
				}
				i = no_of_mc_uc_lis + no_of_wifi_mc_lis -1;
				send_last_mc_uc_or_wifi_pkt_by_ro = TRUE;
			}
			else
				i=n;
		}
		else
			get_first_mc_lis_idx = TRUE;

		orig_mtd_offset = mtd->offset;
		orig_mtd_length = mtd->length;

		for(j=0; j < n; j++) {
			/* Only process MC-UC Listeners and WiFi MC Listeners*/
			if(!mcdest->listeners[j].uc_bit && !(IS_WIFI_PORT(mcdest->listeners[j].output_port))) {
				if(get_first_mc_lis_idx) {
					i = j;
					get_first_mc_lis_idx = FALSE;
				}
				continue;
			}

			__l2_prepend_header(mtd, mcdest->listeners[j].itf, mcdest->listeners[j].dstmac, l2_get_tid(mcdest->listeners[j].family), 1);

#ifdef CFG_WIFI_OFFLOAD
			if (IS_WIFI_PORT(mtd->output_port))
			{
				mtd->queue = queue_mod;
			}
			else
#endif
				mtd->queue = mcdest->listeners[j].queue_base + queue_mod;

			// Allocate BMU2 buffer sepcific to each listener
			do
			{
				ddr_ptr = (void *)readl(BMU2_BASE_ADDR + BMU_ALLOC_CTRL);
			} while (ddr_ptr == NULL);

			dmem_addr = mtd->data + mtd->offset;

			ddr_start = ddr_ptr + ddr_offset(mtd, dmem_addr);

			class_mtd_copy_to_ddr(mtd, ddr_start, mtd->length, CLASS_GP_DMEM_BUF,
						CLASS_GP_DMEM_BUF_SIZE);

			send_to_tx_direct(mtd->output_port, mtd->queue, dmem_addr, ddr_start, 0, mtd->length, 0, mtd->flags);

			/* Now let the mtd->offset & mtd->length point back to IP */
			mtd->offset = orig_mtd_offset;
			mtd->length = orig_mtd_length;
	
			mtd->priv_mcast_refcnt--;
			mc_uc_or_wifi_mc_lisidx++;

			if(send_last_mc_uc_or_wifi_pkt_by_ro && (mc_uc_or_wifi_mc_lisidx == (no_of_mc_uc_lis + no_of_wifi_mc_lis -1)))
				goto send_by_ro;
		}
	}

send_by_ro:

	/* Restart of processing for RO Block */
	
	if (mcdest->flags & MC_ACP_LISTENER) 
	{
			// We need to keep the packet unmodified to send to the host, so we only update pointers without touching data.
		mtd->length += mtd->offset - BaseOffset;
		mtd->offset = BaseOffset;
		mtd->queue = queue_mod;
		mtd->output_port = get_expt_tx_output_port(mtd->input_port);
		if (is_vlan(mtd)) //the hwparse structure should not be corrupt yet at this stage
			first_is_vlan = 1;
		hif_hdr_len = hif_tx_prepare(mtd);
		packet_start = (U32)mtd->data + mtd->offset - hif_hdr_len;
	}
#ifdef CFG_WIFI_OFFLOAD
	else if((i < n) && (IS_WIFI_PORT(mcdest->listeners[i].output_port)))
	{
		mtd->queue = queue_mod;
		first_is_vlan = mc_prepend_upper_header(mtd, &mcdest->listeners[i], &src_mac, &vlan_tag, mcdest->flags);
		hif_hdr_len = hif_tx_prepare(mtd);
		packet_start = (U32)mtd->data + mtd->offset - hif_hdr_len;
	}
#endif	
	else
	{
		/* Assign queue & repl_mask for first_listener */
		mtd->queue = mcdest->listeners[i].queue_base + queue_mod;
		mtd->repl_msk = mcdest->listeners[i].shaper_mask;
		first_is_vlan = mc_prepend_upper_header(mtd, &mcdest->listeners[i], &src_mac, &vlan_tag, mcdest->flags);
		packet_start = (U32)mtd->data + mtd->offset;
	}

	phy = get_tx_phy(mtd->output_port);

	// First clone
	tx_hdr = (class_tx_hdr_mc_t *)(ALIGN64(packet_start) - sizeof(class_tx_hdr_mc_t));

	tx_hdr->start_data_off = packet_start - ((U32) tx_hdr);
	/* FIXME this only works if lmem_hdr_size == ddr_hdr_size, otherwise we need to add (ddr_hdr_size - lmem_hdr_size) */
	/* (src_addr & 0xff) is the offset from the 256 byte aligned packet slot */
	tx_hdr->start_buf_off = ((U32) tx_hdr) & 0xff;
	tx_hdr->queueno = mtd->queue;
	tx_hdr->act_phyno = (0 << 4) | (phy & 0xfU);
	if ((mcdest->flags & MC_ACP_LISTENER)
#ifdef CFG_WIFI_OFFLOAD
		|| ((i < n) && (IS_WIFI_PORT(mcdest->listeners[i].output_port)))
#endif
	)
	{
		tx_hdr->pkt_length = mtd->length + hif_hdr_len;
		/* Now that we created the first clone, correct offset for the following clones that
		 * do not need the ACP metadata.
		 */
		packet_start += hif_hdr_len;
		/* If WiFi Listener is processed as first clone, point to next listener */
		if(!(mcdest->flags & MC_ACP_LISTENER))
			i++;
	}
	else
	{
		tx_hdr->pkt_length = mtd->length;
		if ((mcdest->flags & MC_MODE_MASK) == MC_MODE_ROUTED) {
			tx_hdr->act_phyno |= ACT_SRC_MAC_REPLACE;
			//src_mac already updated by mc_prepend_upper_header
			tx_hdr->src_mac_msb = src_mac[0];
			tx_hdr->src_mac_lsb = (src_mac[1] << 16) + src_mac[2];
		}
		i++;

	}

	tx_hdr->vlanid = vlan_tag.tag;
	if  (vlan_tag.tag)
	{
		tx_hdr->act_phyno |= ACT_VLAN_ADD;
	}

	/*Skip this tx_hdr if physical port tx is not enabled */
	if((mtd->output_port < GEM_PORTS) && (!IS_TX_ENABLED(mtd->output_port)) &&
			(!(mcdest->flags & MC_ACP_LISTENER))) {
		mtd->priv_mcast_refcnt--;
		PESTATUS_INCR_DROP();
		drop_counter[CLASS_DROP_TX_DISABLE]++;
		tx_hdr++;
	}


	for(;i < n;i++)
	{
		if(mcdest->listeners[i].uc_bit || (IS_WIFI_PORT(mcdest->listeners[i].output_port)))
			continue;

		tx_hdr--;
		tx_hdr->start_data_off = packet_start - (U32) tx_hdr;
		tx_hdr->start_buf_off = ((U32) tx_hdr) & 0xff;
		tx_hdr->pkt_length = mtd->length;
		tx_hdr->act_phyno = 0;

		// Shaper mask can be specified per listener
		//mtd->repl_msk = mcdest->listeners[i].shaper_mask; /* FIXME. Where is repl_msk used in PFE */

		// Now get to the bottom of the itf list to retrieve MAC, output port, and VLAN (if present)
		itf = mcdest->listeners[i].itf;
		vlan_tag.tag = 0;
		src_mac = NULL;
		while (itf->phys)
		{
#ifdef CFG_MACVLAN
			if (itf->type & IF_TYPE_MACVLAN)
				src_mac = ((PMacvlanEntry)itf)->MACaddr;
			else
#endif
			if (itf->type == IF_TYPE_VLAN)
			{
				if (vlan_tag.tag) // This means we're in QinQ mode, so only solution is to add the 2nd tag
					tx_hdr->act_phyno |= ACT_VLAN_ADD;
				fill_real_vlan_header(&vlan_tag, ETHERTYPE_VLAN_END, ((VlanEntry *)itf)->VlanId, mtd->vlan_pbits);
			}
			itf = itf->phys;
		}
		tx_hdr->vlanid = vlan_tag.tag;
		if (vlan_tag.tag)
		{
			if ((tx_hdr->act_phyno & ACT_VLAN_ADD) == 0) // We're not in QinQ mode
			{
				if (first_is_vlan)
					tx_hdr->act_phyno |= ACT_VLAN_REPLACE;
				else
					tx_hdr->act_phyno |= ACT_VLAN_ADD;
			}
		}
		phy = (((struct physical_port *)itf)->id & 0xfU);

		tx_hdr->act_phyno |= __get_tx_phy(phy);
		tx_hdr->queueno = mcdest->listeners[i].queue_base + queue_mod; // the queue number can be specified per listener
		if (!src_mac)
			src_mac = (U16 *) ((struct physical_port *)itf)->mac_addr;
		if ((mcdest->flags & MC_MODE_MASK) == MC_MODE_ROUTED) {
			tx_hdr->act_phyno |= ACT_SRC_MAC_REPLACE;
			tx_hdr->src_mac_msb = src_mac[0];
			tx_hdr->src_mac_lsb = (src_mac[1] << 16) + src_mac[2];
		}

		if (first_is_vlan && !vlan_tag.tag) {
					PRINTF("MCAST entry not supported, skipping\n");
					tx_hdr++;
					mtd->priv_mcast_refcnt--;
		}

		/*Skip this tx_hdr if physical port tx is not enabled */
		if((phy < GEM_PORTS) && (!IS_TX_ENABLED(phy)))	{
			tx_hdr++;
			mtd->priv_mcast_refcnt--;
			PESTATUS_INCR_DROP();
			drop_counter[CLASS_DROP_TX_DISABLE]++;

		}

	}

	// mtd->priv_mcast_refcnt now holds number of copies to be made by RO.
	if( mtd->priv_mcast_refcnt ) {
		send_to_tx_mcast(mtd, tx_hdr);
	}else {
		__free_packet(mtd);
	}
}

#endif /* COMCERTO_2000_CLASS */

#if defined(COMCERTO_2000_CLASS)||defined(COMCERTO_100)||defined(COMCERTO_1000)
/** Clone a packet and send copies to the relevant output interfaces.
 * The actual cloning operation is heavily device-dependent, so that function simply calls
 * __mc_clone_and_send after setting up common fields in the metadata structure.
 * @param[in] mtd		Metadata for the packet to be sent
 * @param[in] mcdest	Multicast destination entry to send the packet to
 */
void mc_clone_and_send(PMetadata mtd, PMCxEntry mcdest)
{
	PMCListener first_listener;

	mtd->priv_mcast_flags = 0;
	first_listener = &mcdest->listeners[0];
	if ((mcdest->flags & MC_MODE_BRIDGED) != 0)
		mtd->priv_mcast_flags |= MC_BRIDGED;

	__mc_clone_and_send(mtd, mcdest, first_listener);
}
#endif

#ifdef COMCERTO_1000
extern	unsigned char Image$$aram_mdma0$$Length[];
extern	unsigned char Image$$aram_mdma0$$ZI$$Length[];
extern	unsigned char Image$$aram_mdma0$$Base[];

#define MDMA0_DEV_MEMSIZE ((U32)Image$$aram_mdma0$$Length + (U32)Image$$aram_mdma0$$ZI$$Length)
#define MDMA0_DEV_MEMADDR Image$$aram_mdma0$$Base

int multicast_init(void)
{
	static BOOL mc_init_done = FALSE;
	U32 tmp;
	mdma_lane *pcntx;
	MMRXdesc tmp_dsc,*prxdsc;

	if (mc_init_done)
		return 0;

	if (( MDMA0_TX_NUMDESCR * sizeof(MMTXdesc) + MDMA0_RX_NUMDESCR *sizeof(MMRXdesc)) >  MDMA0_DEV_MEMSIZE )
		return 1; // Not enough memory should probably hang a chip here.

	// Fill control structure in software.
	pcntx= &mdma_lane0_cntx;
	memset(pcntx,0,sizeof(mdma_lane0_cntx));
	tmp = (U32)  MDMA0_DEV_MEMADDR;
	pcntx->tx_cur = pcntx->tx_top =  (void*) tmp;
	pcntx->tx_bot = pcntx->tx_top + (MDMA0_TX_NUMDESCR - 1);
	pcntx->free_tx = MDMA0_TX_NUMDESCR;
	memset( pcntx->tx_top, 0,  MDMA0_TX_NUMDESCR * sizeof(MMTXdesc));

	tmp += MDMA0_TX_NUMDESCR * sizeof(MMTXdesc);

	pcntx->rx_cur = pcntx->rx_top =  (void*) tmp;
	pcntx->rx_bot = pcntx->rx_top + (MDMA0_RX_NUMDESCR - 1);
	pcntx->pending_rx = 0;
	prxdsc=pcntx->rx_cur;

	// Initialise rx rescriptors
	memset(&tmp_dsc,0,sizeof(tmp_dsc));
	tmp_dsc.rxctl = ( MMRX_BUF_ALLOC | ((BaseOffset + ETH_HDR_SIZE)<< MMRX_OFFSET_SHIFT));
	do {
		SFL_memcpy(prxdsc, &tmp_dsc, sizeof(*prxdsc));
		prxdsc +=1;
	} while(prxdsc != pcntx->rx_bot);
	tmp_dsc.rxctl |= 	MMRX_WRAP;
	SFL_memcpy(pcntx->rx_bot, &tmp_dsc,sizeof(*prxdsc));

	// hw bindings
	pcntx->txcnt = (V32*)  MDMA_TX0_PATH_CTR;
	pcntx->rxcnt = (V32*)  MDMA_RX0_PATH_CTR;
	// Enable mdma block and lane0
	*(V32*) 	MDMA_GLB_CTRL_CFG = 1;
	*(V32*)	MDMA_TX0_PATH_HEAD = (U32) pcntx->tx_top;
	*(V32*)	MDMA_RX0_PATH_HEAD = (U32) pcntx->rx_top;
	*(V32*)	MDMA_INT_MASK_REG &= ~0x33UL; // turn off interrupts from lane0
	//TODO mat-20081017 - is burst length needed?
	// default is 0x10
	//      *(V32*)	MDMA_AHB_CFG  = 	(*(V32*)MDMA_AHB_CFG & ~0x1f) | TBD 
	// I am purposly not touching lane1
	// It is safe as long work is not queued to it.

	mc_init_done = TRUE;
	return 0;
}

#endif /* COMCERTO_1000 */
