/**************************************************************
$Workfile:   portmap.c  $
***************************************************************
**
** FIRMWARE, Copyright (C) 2000-2002
** Ikanos Communications, Fremont, CA
** All rights reserved.
**
** The information and contents of this file are the
** proprietary information of Ikanos Communication and may not
** be disclosed or used without the formal written approval of
** Ikanos Communication
**
$Revision: 1.1 $
$Date: 2006/10/16 04:34:50 $
***************************************************************/

/*************************************************************

	this header file defines the definitions, structures, and functions prototypes
	for portmapping functions

	The numbering scheme used in the application:
		
		linenum:	The global line index: 				1-MAX_NUM_OF_PORTS 		
		ininum:		The INI index=linenum-1				0-MAX_NUM_OF_PORTS-1
		
		bmenum:   	The bme index  						1-MAX_NUM_OF_BMES
		portnum:  	The port index within the BME:	 	1-MAX_PORTS_PER_BME
		
	Note: INI port index start from 0					 = lineNum-1.																
	
*************************************************************/
#include "ipos.h"
#include "appconfig.h"
#include "apperrCode.h"
#include "portmap.h"
#include "bmeconfig.h"
#include "pprofile.h"


extern sys_port_mapping 	sysPortMap[IPOS_MAX_PORTS];

extern ipos_port_profile sPortProfiles[MAX_PORT_PROFILES]; /* user defined variable port profiles */


/* the BME bandplan setting for this routine	*/

U32		sysBmeBandPlanMask[MAX_NUM_OF_BMES+1];

void setUtopiaAddr()
{
int i=0;
int profilenum=0;



#ifdef P2CO
for (i=0;i<IPOS_MAX_PORTS;i++)
{
	//printf ("Profile %d IntPercent: %d\n", profilenum, sPortProfiles[profilenum].PortProvParms.InterleavedPercentage);
	profilenum=ProfileMapping[i+1];
	if (sPortProfiles[profilenum].PortProvParms.InterleavedPercentage==100)
	{
		sysPortMap[i].uaFast=i;
		sysPortMap[i].uaSlow=i+IPOS_MAX_PORTS;
	}
	else 
	{
		sysPortMap[i].uaSlow=i;
		sysPortMap[i].uaFast=i+IPOS_MAX_PORTS;
	}
}

#else
for (i=0;i<IPOS_MAX_PORTS;i++)
{
profilenum=ProfileMapping[i+1];

#ifdef CO_4P_BOARD			

	if (sPortProfiles[profilenum].PortProvParms.InterleavedPercentage==100)
		{
		sysPortMap[i].uaFast=i*2;
		sysPortMap[i].uaSlow=(i*2)+1;
		}
	else 
		{
		sysPortMap[i].uaSlow=i*2;
		sysPortMap[i].uaFast=(i*2)+1;
		}
#else
	//printf ("Profile %d IntPercent: %d\n", profilenum, sPortProfiles[profilenum].PortProvParms.InterleavedPercentage);
	if (sPortProfiles[profilenum].PortProvParms.InterleavedPercentage==100)
		{
		sysPortMap[i].uaFast=i;
		sysPortMap[i].uaSlow=i+IPOS_MAX_PORTS;
		}
	else 
		{
		sysPortMap[i].uaSlow=i;
		sysPortMap[i].uaFast=i+IPOS_MAX_PORTS;

		}
#endif

}
#endif //P2CO


}



/************************************************************ 

	set the port mapping: input:  bandPlan, number of the BME
						  output: IPOS_SUCCESS or IPOS_ERROR_CODE  

************************************************************/

int	setPortMap(int bmeNum,int bandPlan)
{

	int	i;
	if(bmeNum>MAX_NUM_OF_BMES) 
	{
		return	APP_ERROR_BME_NUM;
	}
	
	sysBmeBandPlanMask[bmeNum]=1;
	
	for(i=0;i<bandPlan;i++)
	{

		sysBmeBandPlanMask[bmeNum]<<=1;

	}
	return IPOS_SUCCESS;
}

/************************************************************ 

	get the portId from the lineNum

	
	   
************************************************************/
int		getBmePortId( int	lineNum, ipos_port_id *pid)
{
	if(lineNum<=0||lineNum>MAX_NUM_OF_PORTS)
	{
		return	APP_ERROR_LINE_NUM;

	}

	*pid= sysPortMap[lineNum-1].pid;
	if((sysBmeBandPlanMask[pid->bmeNum] & sysPortMap[lineNum-1].bmBandPlan)==0)
	{
		return	PM_ERROR_NOT_VALID;
	}
	return	IPOS_SUCCESS;

}


/************************************************************ 

	get the line number from the portId


************************************************************/

int		getLineNum(ipos_port_id pid, int *lineNum)
{

	int i;
	int	portNum,bmeNum;	

	if(pid.bmeNum<=0||pid.bmeNum>MAX_NUM_OF_BMES||pid.portNum<=0||pid.portNum>MAX_PORTS_PER_BME)
	{

		return	APP_ERROR_PORT_ID;
	}


	for(i=0;i<MAX_NUM_OF_PORTS;i++)
	{

		bmeNum=sysPortMap[i].pid.bmeNum;
		portNum=sysPortMap[i].pid.portNum;
		
		if(pid.bmeNum==bmeNum && pid.portNum==portNum)
		{
			*lineNum=sysPortMap[i].lineNum;		/* get the line number	*/

			if((sysBmeBandPlanMask[pid.bmeNum]&sysPortMap[i].bmBandPlan)==0)
			{
				return	PM_ERROR_NOT_VALID;
			}
			return 	IPOS_SUCCESS; 

		}

	}

	return	APP_ERROR_PORT_ID;
}


/************************************************************ 

	get INI phy from the line number 


************************************************************/


int		getIniPhy(int lineNum, int	*iniNum)
{

	ipos_port_id	pid;
	
	if(lineNum<=0||lineNum>MAX_NUM_OF_PORTS)
	{
		return	APP_ERROR_LINE_NUM;

	}

	*iniNum=sysPortMap[lineNum-1].iniNum;

	if(getBmePortId(lineNum, &pid)!=IPOS_SUCCESS)
	{
		return	PM_ERROR_NOT_VALID;
	}
	return	IPOS_SUCCESS;
}


/************************************************************ 

	get UTOPIA slow from the line number 


************************************************************/
int		getUtopiaSlow(int lineNum, int *uaSlow)
{

	ipos_port_id	pid;


	if(lineNum<=0||lineNum>MAX_NUM_OF_PORTS)
	{
		return	APP_ERROR_LINE_NUM;

	}

	*uaSlow=sysPortMap[lineNum-1].uaSlow;
	if(getBmePortId(lineNum, &pid)!=IPOS_SUCCESS)
	{
		return	PM_ERROR_NOT_VALID;
	}
	return	IPOS_SUCCESS;


}



/************************************************************ 

	get UTOPIA fast from the line number 


************************************************************/
int		getUtopiaFast(int lineNum, int *uaFast)
{

	ipos_port_id	pid;

	if(lineNum<=0||lineNum>MAX_NUM_OF_PORTS)
	{
		return	APP_ERROR_LINE_NUM;

	}

	*uaFast=sysPortMap[lineNum-1].uaFast;
	if(getBmePortId(lineNum, &pid)!=IPOS_SUCCESS)
	{
		return	PM_ERROR_NOT_VALID;
	}
	
	return	IPOS_SUCCESS;

}

/************************************************************ 

	Check if for a particular band plan, the corresponding port
  is valid or not.

************************************************************/
int	MatchBandPlan(ipos_port_id pid, int bandPlan)
{
  int i, uiBandPlanMask;

  uiBandPlanMask = 1;

	for(i=0;i<bandPlan;i++)
	{
		uiBandPlanMask <<= 1;
	}
  if (uiBandPlanMask & sysPortMap[pid.portNum - 1].bmBandPlan)
  	return IPOS_SUCCESS;
  else
    return PM_ERROR_NOT_VALID;
}

/************************************************************ 
	get the line number from the portId
************************************************************/

int		getIniMap(ipos_port_id pid, int *IniIndex, int *IniSlow, int *IniFast)
{

	int i;
	int	portNum,bmeNum;	
  int profilenum=0;
	int lineNum=0;


	getLineNum (pid,&lineNum);
	profilenum=ProfileMapping[lineNum];

	if(pid.bmeNum<=0||pid.bmeNum>MAX_NUM_OF_BMES||pid.portNum<=0||pid.portNum>MAX_PORTS_PER_BME)
	{

		return	APP_ERROR_PORT_ID;
	}

	for(i=0;i<MAX_NUM_OF_PORTS;i++)
	{

		bmeNum=sysPortMap[i].pid.bmeNum;
		portNum=sysPortMap[i].pid.portNum;
		
		if(pid.bmeNum==bmeNum && pid.portNum==portNum)
		{
      *IniIndex = sysPortMap[i].iniNum;

     	if (sPortProfiles[profilenum].PortProvParms.InterleavedPercentage==100)
      {
        *IniFast =  sysPortMap[i].uaFast;
        *IniSlow =  sysPortMap[i].uaFast;
      }
      else if (sPortProfiles[profilenum].PortProvParms.InterleavedPercentage==0)
      {
        *IniSlow = sysPortMap[i].uaSlow;
        *IniFast = sysPortMap[i].uaSlow;
      }
      else
      {
        *IniFast = sysPortMap[i].uaFast;
        *IniSlow = sysPortMap[i].uaSlow;
      }

   /*   printf ("\nprofilenum %i inter % %i slow %i fast %i",profilenum,
		sPortProfiles[profilenum].PortProvParms.InterleavedPercentage,
		*IniSlow,*IniFast);
*/
		  return 	IPOS_SUCCESS; 
		}
	}
	return	APP_ERROR_PORT_ID;
}
