⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 le1veisr.c

📁 Zalink50114----TDMoIP芯片驱动源码
💻 C
字号:
/* le1veIsr.c - LE1VE (TDMoIP) interrupt service routine  file
*
* Copyright     2004-2007 ZTE, Inc.
* author:       ZhengQishan
* date:         2004.03
*
* modification history
*------------------------------
*
*/
#include "le1veLib.h"
#include "zl5011x.h"
#include "zl5011xAddrmap.h"
#include "zl5011xAdmMap.h"
#include "zl5011xPacMap.h"
#include "zl5011xInterrupts.h"
#include "zl5011xPac.h"
#include "le1veFpgaLib.h"
#include "zl5011xRdWr.h"
#include "zl5011xDpr.h"

extern void Ros_PortStateSend(int unit,int lport,int state);
extern int                   SysCtrlUpFlag ;

LOCAL int le1veFeiPhyIntHandleFlag = 0;

#define    LE1VE_ETHERNET_PHY_LED_STATUS 0x7c40
#define    CPLD_INT_STAUS_REG       0x7c18 
#define    CPLD_INT_CONTROL_REG     0x7c1c 

#define    LE1VE_FPGA_INT			0x01
#define    LE1VE_FRAME_INT          0x02
#define    LE1VE_ETHERNET_PHY_INT   0x04
#define    LE1VE_ZL5011X_CPU_INT0   0x08
#define    LE1VE_ZL5011X_CPU_INT1   0x10

#if 0
LOCAL void zl5011xInt1Handler(zl5011xParamsS * pZl5011xParamss);
#endif

extern zl5011xParamsS *le1ve_Zl5011xParams[];
extern void lce1fPm4354IntHandle(int slotNum);
void zl5011xQueueUpIntHandler(zl5011xParamsS *pZl5011xParams, zl5011xIsrSourcesE intSource);

void le1veFeiPhyIntHandle(int slot);

LOCAL void le1ve_CpldAllIntEnable(int slot)
{
    UINT32 value;
    volatile UINT32 *pBaseAddr;
	
    /*Disable CPLD的中断*/
    pBaseAddr = (volatile UINT32 *)(IF_CARD_CPU_REG_BASE(slot) + CPLD_INT_CONTROL_REG);
    value = Drv_Swap32(*pBaseAddr);
    *pBaseAddr = Drv_Swap32(value & ( ~(LE1VE_FRAME_INT  |LE1VE_ETHERNET_PHY_INT | LE1VE_ZL5011X_CPU_INT0 | LE1VE_ZL5011X_CPU_INT1) ));
}

LOCAL void le1ve_CpldIntEnable(int slot,  UINT32 mask)
{
    UINT32 value;
    volatile UINT32 *pBaseAddr;
	
    /*Disable CPLD的中断*/
    pBaseAddr = (volatile UINT32 *)(IF_CARD_CPU_REG_BASE(slot) + CPLD_INT_CONTROL_REG);
    value = Drv_Swap32(*pBaseAddr);
    *pBaseAddr = Drv_Swap32(value & ( ~(mask) ));
}

LOCAL void le1ve_CpldAllIntDisable(int slot)
{
    UINT32 value;
    volatile UINT32 *pBaseAddr;
	
    /*使能CPLD的中断*/
    pBaseAddr = (volatile UINT32 *)(IF_CARD_CPU_REG_BASE(slot) + CPLD_INT_CONTROL_REG);
    value = Drv_Swap32(*pBaseAddr);
    *pBaseAddr = Drv_Swap32(value | ( (LE1VE_FRAME_INT |LE1VE_ETHERNET_PHY_INT  | LE1VE_ZL5011X_CPU_INT0 | LE1VE_ZL5011X_CPU_INT1) ));
}


LOCAL void le1veIntHandle(zl5011xParamsS * pZl5011xParamss)
{
    int slot;
    char intValue, value;
    volatile char *pBaseAddr;

    slot = pZl5011xParamss->slotNum;

    /*Disable Interrupt*/
    le1ve_CpldAllIntDisable(slot);
	
    pBaseAddr = (volatile char *)(IF_CARD_CPU_REG_BASE(slot) + CPLD_INT_STAUS_REG);
	intValue = *pBaseAddr;

    /*logMsg("CPLD int status: 0x%x\n", intValue ,2,3,4,5,6);*/
    if (0 == (intValue & LE1VE_FRAME_INT))
    	lce1fPm4354IntHandle(slot);
	
    if (0 == (intValue & LE1VE_ZL5011X_CPU_INT0))
    {
    	 ZL5011X_REG_READ(slot, ZL5011X_ADM_MOD_CONSTAT, (UINT32 *)&value);
    	 ZL5011X_REG_WRITE(slot, ZL5011X_ADM_MOD_CONSTAT, (value & (~ZL5011X_ENABLE_INT_0)) );
    }
	
    if (0 == (intValue & LE1VE_ZL5011X_CPU_INT1))
    {
        zl5011xIsrApiHandler();
    	/*zl5011xInt1Handler(pZl5011xParamss);*/
    }
	
    if ((0 == (intValue & LE1VE_ETHERNET_PHY_INT))  && (le1veFeiPhyIntHandleFlag == 0) )
    {
        if (OK == fwdJobAdd((FUNCPTR)le1veFeiPhyIntHandle, slot, 0, 0,0,0))
        {
		le1veFeiPhyIntHandleFlag = 1;
		le1ve_CpldIntEnable(slot, LE1VE_ETHERNET_PHY_INT);
        }
    }

    /*Enable Framer Interrupt*/
    le1ve_CpldIntEnable(slot, LE1VE_FRAME_INT);
}


void le1veFeiPhyLineStatus(int slot, UINT8 *pStatus)
{
    UINT8 *pBaseAddr;
    UINT8 value;
    
    pBaseAddr = (unsigned char *)(IF_CARD_CPU_REG_BASE(slot) + LE1VE_ETHERNET_PHY_LED_STATUS);
    value = *pBaseAddr;

    if (0 == (value & 0x2)) /*LINK UP */
    {
        *pStatus = 0x10;
    }	
    else  /*LINK Down*/
    {
        *pStatus = 0;
    }
}
#if 0
/*add by shf to init zl5011x int
  在zl5011x中有两种中断api和app.app中断处理过程可以由用户实现,本版本中没有
  实现。api中断用于rtp统计,CET处理,需要被初始化,由于我们硬件上将中断信号
  连接到了cpld,需要伪中断处理。
  我们在接口板初始化的进入处,一次初始化。以后对每一个e1ve,t1ve板使用adddevice
  添加数据结构
  修改了zl5011x中断初始化和中断删除两个函数*/
STATUS le1vezl5011xIntInit(int slot)
{
    zl5011xParamsS *pzl5011xParams;
    zl5011xIsrInitialiseS isrInitialise;
    zlStatusE status = ZL5011X_OK;
    if(le1ve_Zl5011xParams[slot-1] == NULL)
        return ZL5011X_ERROR;
    pzl5011xParams = le1ve_Zl5011xParams[slot-1];
    /* initialise the ISR's */
    if (status == ZL5011X_OK)
    {
       status = zl5011xIsrInitialiseStructInit(pzl5011xParams, &isrInitialise);
       /*使用我们自己的中断,只打开api中断,*/
       isrInitialise.apiPhysIntr =FAKE_INT;/*不真正的连接中断*/
      
       if (status == ZL5011X_OK)
       {
          /*中断初始化过程被修改,用假中断号,并未真正连接*/
          status = zl5011xIsrInitialise(pzl5011xParams, &isrInitialise);
          printf("le1vezl5011xIntInit %d\n",status);

       }
    }
    return status;
}
#endif
void le1veFeiPhyIntHandle(int slot)
{
    UINT8 *pBaseAddr;
    UINT8 value;
    int linkState;
    
    /*过滤中断*/
    taskDelay(1);
    pBaseAddr = (UINT8 *)(IF_CARD_CPU_REG_BASE(slot) + LE1VE_ETHERNET_PHY_LED_STATUS);
    value = *pBaseAddr;

    if (0 == (value & 0x2)) /*LINK UP */
    {
        linkState = 1;
    }
    else  /*LINK Down*/
    {
        linkState = 0;
    }
    if ( SysCtrlUpFlag == 1)
    {
    	Ros_PortStateSend(slot, 5, linkState);
    }

    le1veFeiPhyIntHandleFlag = 0;

   /* Enable Ethernet Phy interrupt */
   le1ve_CpldIntEnable(slot, LE1VE_ETHERNET_PHY_INT);
}
/*
int 0 - phy int 
int 1 - api int
*/
#if 0
LOCAL void zl5011xInt1Handler(zl5011xParamsS * pZl5011xParamss)
{
    int portNum;
    zlStatusE status = ZL5011X_OK;
    Uint32T temp, index= 0;
    Uint32T admIntrStatus= 0;
    Uint32T intContext= 0;
    Uint32T rollOverFlags= 0;
    zl5011xInterruptQueueDataS intr;

#ifdef _DEBUG
   Uint32T tempTraceFnFilter;
   Uint32T tempTraceCtxtFnFilter;
   Uint32T tempTraceCtxtFilter;

   if (zl5011xTraceIsrEnable == ZL5011X_FALSE)
   {
      /* disable the trace during the interrupt handler */
      tempTraceFnFilter = zl5011xTraceFnFilter;
      tempTraceCtxtFnFilter = zl5011xTraceCtxtFnFilter;
      tempTraceCtxtFilter = zl5011xTraceCtxtFilter;

      zl5011xTraceFnFilter = 0;
      zl5011xTraceCtxtFnFilter = 0;
      zl5011xTraceCtxtFilter = 0;
   }
#endif

   ZL5011X_TRACE(ZL5011X_ISR_FN_ID, "zl5011xIsrApiHandler:", 0,0,0,0,0,0);

	(void)zl5011xAdmGetInterruptStatus(pZl5011xParamss, &admIntrStatus);

	/* mask out any interrupts that are not for this interrupt pin */
	admIntrStatus &= pZl5011xParamss->interruptMasks.admMasks[ZL5011X_INTERRUPT_ONE];
	
	/* check if the PAC interrupt is active */
	if ((admIntrStatus & (ZL5011X_1BIT_MASK << ZL5011X_WAN_CLK_INTERRUPT)) != 0)
	{
		(void)zl5011xPacGetStatus(pZl5011xParamss, &temp);


        #if 0
		if ((temp & (ZL5011X_1BIT_MASK << ZL5011X_PAC_ASYNC_INT)) != 0)
		{
			if (zl5011xCetMsgQid != NULL)
			{
				(void)zl5011xHandleCetIntr(zl5011xParams);
			}
		}
		#endif
		if ((temp & ~(ZL5011X_1BIT_MASK << ZL5011X_PAC_ASYNC_INT)) != 0)
		{
			intr.interruptSource = ZL5011X_WAN_CLK_INTERRUPT;
			intr.activeInterrupts = temp & ~(ZL5011X_1BIT_MASK << ZL5011X_PAC_ASYNC_INT);

			/* call the user's function -  zl5011xDprHandler */
			fwdJobAdd ((FUNCPTR)zl5011xQueueUpIntHandler, (int)pZl5011xParamss, (int)intr.interruptSource, 0, 0, 0);
			/*(void)zl5011xIsrQueueUpInterrupts(pZl5011xParamss, &intr);*/
		}

		/* if the slew rate interrupt is enabled then need to mask it out, since it may
		be set again immediately. The other interrupts are status changes, so only
		need to reset the interrupt */

		if ((temp & (ZL5011X_1BIT_MASK << ZL5011X_DPLL_SLEW_RATE_INT)) != 0)
		{
			(void)zl5011xPacDisableInterrupts(pZl5011xParamss, ZL5011X_1BIT_MASK << ZL5011X_DPLL_SLEW_RATE_INT);
		}

		/* Now clear any interrupts that were active */
		(void)zl5011xPacClearInterrupts(pZl5011xParamss, temp);
	}

    /* check RTP counter interrupt */
    if ((admIntrStatus & (ZL5011X_1BIT_MASK << ZL5011X_RTP_STATS_INTERRUPT)) != 0)
    {
        /* find out which context it is for */
        status = zl5011xRtpGetInterruptStatus(pZl5011xParamss,
        &intContext, &rollOverFlags);

        if (status ==ZL5011X_OK)
        {
            status = zl5011xRtpUpdateStatistics(pZl5011xParamss, intContext, rollOverFlags);
        }
    }

    /* check MAC interrupt */
    if ((admIntrStatus & (ZL5011X_1BIT_MASK << ZL5011X_MAC_IF_INTERRUPT)) != 0)
    {
        /* test which port */
        for( portNum= 0; portNum < pZl5011xParamss->devLimits.lanNumLanPorts; portNum++)
        {
            (void)zl5011xPkiUpdateCounters(pZl5011xParamss, portNum);
        }

        /* check if a PCS int is active */
        intr.interruptSource = ZL5011X_MAC_IF_INTERRUPT;
        (void)zl5011xPkiGetPcsStatus(pZl5011xParamss, &(intr.activeInterrupts));

        if (intr.activeInterrupts != 0)
        {
            /* only send a message if an interrupt is set */
            (void)zl5011xIsrQueueUpInterrupts(pZl5011xParamss, &intr);
        }
    }

    /* clear interrupts in this device */
    (void)zl5011xAdmClearInterruptSource( pZl5011xParamss, admIntrStatus);



#ifdef _DEBUG
   if (zl5011xTraceIsrEnable == ZL5011X_FALSE)
   {
      /* restore the trace variables now that the interrupt has finished */
      zl5011xTraceFnFilter = tempTraceFnFilter;
      zl5011xTraceCtxtFnFilter = tempTraceCtxtFnFilter;
      zl5011xTraceCtxtFilter = tempTraceCtxtFilter;
   }
#endif
}
#endif

void le1veIntConnect(int slot)
{   
    b_cintConnect(slot - 1, (VOIDFUNCPTR)le1veIntHandle, (int)le1ve_Zl5011xParams[slot - 1]);
    b_cintEnable(slot -1);
    
    /*使能CPLD的中断*/
    le1ve_CpldAllIntEnable(slot);
}

#if 0
void zl5011xQueueUpIntHandler(zl5011xParamsS *pZl5011xParams, zl5011xIsrSourcesE intSource)
{
    ;
}
#endif


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -