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

📄 if_fei.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
        {        /* This device was not the cause of the shared int */         return;         }     /* clear chip level interrupt pending */    pDrvCtrl->pCSR->scbStatus = (event&SCB_S_STATMASK);     /* board level interrupt acknowledge */    BOARD_INT_ACK(unit);#ifdef	FEI_DEBUG    if (feiDebug)        logMsg ("feiInt: event 0x%x, scbStatus 0x%x\n", event, 	     pDrvCtrl->pCSR->scbStatus, 0, 0, 0, 0);#endif	/* FEI_DEBUG */    /* handle receive interrupts */    if ( (event & SCB_S_FR) && !(pDrvCtrl->pCSR->scbCommand & SCB_C_M)) 	{        I82557_INT_DISABLE;        pDrvCtrl->rxHandle = TRUE;        (void) netJobAdd ((FUNCPTR) feiHandleRecvInt, (int) pDrvCtrl,            0, 0, 0, 0);        }    }    /********************************************************************************* feiHandleRecvInt - service task-level interrupts for receive frames** This routine is run in netTask's context.  The ISR scheduled* this routine so that it could handle receive packets at task level.** RETURNS: N/A*/LOCAL void feiHandleRecvInt    (    DRV_CTRL *	pDrvCtrl    )    {    RFD *	pRFD = pDrvCtrl->pRFD;    RFD *	pRFDNew;    int		unit = pDrvCtrl->idr.ac_if.if_unit;    while (pRFD->rfdStatus & RFD_S_COMPLETE)   /* while packets to process */        {        pDrvCtrl->rxHandle = TRUE;             /* interlock with eiInt() */	if (!(pRFD->rfdStatus & RFD_S_OK))	    pDrvCtrl->idr.ac_if.if_ierrors++;	else	    {	    if (feiReceive (pDrvCtrl, pRFD) == ERROR)		{		/* buffer loaning was done */                pRFDNew = pDrvCtrl->pRFDL;                pDrvCtrl->pRFDL = pRFDNew->pPrev;		LINK_WR (&pRFD->pPrev->link, 		    LOCAL_TO_SYS_ADDR(unit,(UINT32)pRFDNew));		LINK_WR (&pRFDNew->link, LINK_RD (&pRFD->link));		pRFDNew->pPrev = pRFD->pPrev;		pRFD = (RFD *) SYS_TO_LOCAL_ADDR(unit,		    (UINT32)LINK_RD (&pRFD->link));		pRFD->pPrev = pRFDNew;		pRFD = pRFDNew;		}	    }        pRFD->rfdStatus = 0;        pRFD->rfdCommand = RFD_C_EL;            /* chip can have it.... */	pRFD->pPrev->rfdCommand &= ~RFD_C_EL;   /* hook frame into CBL */        pRFD = (RFD *) SYS_TO_LOCAL_ADDR(unit,(UINT32)LINK_RD (&pRFD->link) )            ;   /* bump to next RFD in ring */        pDrvCtrl->pCSR->scbStatus &= (SCB_S_FR | SCB_S_RNR);        }    pDrvCtrl->pRFD = pRFD;                      /* keep track of current RFD */    /* kick receiver (if needed) */    if ((pDrvCtrl->pCSR->scbStatus & SCB_S_RUMASK) != SCB_S_RURDY)        {        if (feiSCBCommand (pDrvCtrl, SCB_C_RUSTART, TRUE,                     (UINT32 *)LOCAL_TO_SYS_ADDR(unit, (UINT32)pRFD)) == ERROR)            {	    pDrvCtrl->rxHandle = FALSE;            return;	    }        while ((pDrvCtrl->pCSR->scbCommand)&SCB_C_RUMASK)            ;      /* wait for RUSTART accept */        }    pDrvCtrl->rxHandle = FALSE;    /* re-enable receiver interrupts */    I82557_INT_ENABLE;    }/********************************************************************************* feiReceive - pass a received frame to the next layer up** Strips the Ethernet header and passes the packet to the appropriate* protocol.  The return value indicates if buffer loaning was used to hold* the data.  A return value of OK means that loaning was not done.** RETURNS: OK, or ERROR if buffer-loaning the RFD.*/LOCAL STATUS feiReceive    (    DRV_CTRL *	pDrvCtrl,    RFD *	pRFD    )    {    struct ether_header *	pEh;    u_char *	pData;    int		len;    UINT16	etherType;    MBUF *	pMbuf = NULL;    STATUS	retVal = OK;    len = pRFD->actualCnt & 0x3fff;	/* get frame length */    pEh = (struct ether_header *)pRFD->enetHdr;	/* get ptr to ethernet header */    pDrvCtrl->idr.ac_if.if_ipackets++;          /* bump statistic */    /* call hook routine if one is connected */    if ((etherInputHookRtn != NULL) && ((*etherInputHookRtn)	(& pDrvCtrl->idr.ac_if, (char *) pEh, len)))        return (OK);    len -= EH_SIZE;    if (len <= 0)	{	pDrvCtrl->idr.ac_if.if_ierrors++;           /* bump error stat */        pDrvCtrl->idr.ac_if.if_ipackets--;          /* fix statistic */	return (OK);	}    pData = (u_char *) pRFD->enetData;    etherType = ntohs (pEh->ether_type);    if ((pDrvCtrl->pRFDL != NULL) && (USE_CLUSTER (len)) &&        ((pMbuf = build_cluster (pData, len, (struct ifnet *) &pDrvCtrl->idr, 				 MC_FEI, &pRFD->refCnt, (FUNCPTR) feiLoanFree, 				 (int) pDrvCtrl, (int) pRFD, NULL)) 		 != NULL))        retVal = ERROR;			/* we loaned a frame */    else        pMbuf = copy_to_mbufs (pData, len, 0, 			       (struct ifnet *) &pDrvCtrl->idr);    if (pMbuf != NULL)	{#ifdef BSD43_DRIVER        do_protocol_with_type (etherType, pMbuf, &pDrvCtrl->idr, len);#else        do_protocol (pEh, pMbuf, &pDrvCtrl->idr, len);#endif	}    else	{	pDrvCtrl->idr.ac_if.if_ierrors++;           /* bump error stat */        pDrvCtrl->idr.ac_if.if_ipackets--;          /* fix statistic */	}    return (retVal);    }/********************************************************************************* feiLoanFree - return a loaned receive frame descriptor** This routine is called by the protocol code when it has completed use of* an RFD that we loaned to it.** RETURNS: N/A*/LOCAL void feiLoanFree    (    DRV_CTRL *	pDrvCtrl,    RFD *	pRFD    )    {    pRFD->refCnt = 0;			/* should already be zero... */    pRFD->pPrev = pDrvCtrl->pRFDL;    pDrvCtrl->pRFDL = pRFD;    }/********************************************************************************* feiNOP - format and issue a NOP command** RETURNS: OK, or ERROR if the NOP command failed.*/LOCAL STATUS feiNOP    (    int		unit    )    {    if (!(feiAction (unit, CFD_C_NOP) & CFD_S_OK))	return (ERROR);    return (OK);    }/********************************************************************************* feiDiag - format and issue a diagnostic command** RETURNS: OK, or ERROR if the diagnostic command failed.*/LOCAL STATUS feiDiag    (    int		unit    )    {    UINT16	stat;    if (((stat = feiAction (unit, CFD_C_DIAG)) &        (CFD_S_OK | CFD_S_DIAG_F)) != CFD_S_OK)        {#ifdef  FEI_DEBUG        if (feiDebug)            printf ("if_fei.c: 82557 diagnostics failed, cfdStatus 0x%x\n",                stat);#endif  /* FEI_DEBUG */        return (ERROR);        }    return (OK);    }/********************************************************************************* feiConfig - format and issue a config command** RETURNS: OK, or ERROR if the config command failed.*/LOCAL STATUS feiConfig    (    int unit    )    {    DRV_CTRL *	pDrvCtrl = & drvCtrl [unit];    CFD *	pCFD = pDrvCtrl->pCFD;    /* set to config values recommeded by the i82557 User's Manual */    pCFD->cfdConfig.ccByte0  = 0x16;    pCFD->cfdConfig.ccByte1  = 0x88;  /* 0x08;  */    pCFD->cfdConfig.ccByte2  = 0x00;    pCFD->cfdConfig.ccByte3  = 0x00;    pCFD->cfdConfig.ccByte4  = 0x00;   /* 0x00; */    pCFD->cfdConfig.ccByte5  = 0x00;   /* 0x80; */    pCFD->cfdConfig.ccByte6  = 0x38;   /* save bad frame,no TNO 0x3a; */    pCFD->cfdConfig.ccByte7  = 0x03;       pCFD->cfdConfig.ccByte8  = 0x01;	/* MII operation */    pCFD->cfdConfig.ccByte9  = 0x00;    pCFD->cfdConfig.ccByte10 = 0x2e;    pCFD->cfdConfig.ccByte11 = 0x00;        pCFD->cfdConfig.ccByte12 = 0x60;    pCFD->cfdConfig.ccByte13 = 0x00;    pCFD->cfdConfig.ccByte14 = 0xf2;    if (pDrvCtrl->idr.ac_if.if_flags & IFF_PROMISC)        pCFD->cfdConfig.ccByte15 = 0x49;     /* 0x49;  */    else        pCFD->cfdConfig.ccByte15 = 0x48;     /* 0x49 PROMISC;  */    pCFD->cfdConfig.ccByte16 = 0x00;    pCFD->cfdConfig.ccByte17 = 0x40;    pCFD->cfdConfig.ccByte18 = 0xf2;if (pDrvCtrl->board.phyDpx != PHY_HALF_DPX)    pCFD->cfdConfig.ccByte19 = 0x80;else    pCFD->cfdConfig.ccByte19 = 0x00; /*c0 force full deplex    0x80;   */    pCFD->cfdConfig.ccByte20 = 0x3f;    pCFD->cfdConfig.ccByte21 = 0x05;    if (!(feiAction (unit, CFD_C_CONFIG) & CFD_S_OK))	return (ERROR);    return (OK);    }/********************************************************************************* feiIASetup - format and issue an interface address command** RETURNS: OK, or ERROR if the address command failed.*/LOCAL STATUS feiIASetup    (    int unit    )    {    DRV_CTRL *	pDrvCtrl = & drvCtrl [unit];    bcopy ((char *) pDrvCtrl->idr.ac_enaddr,	(char *) pDrvCtrl->pCFD->cfdIASetup.ciAddress, 6);    if (!(feiAction (unit, CFD_C_IASETUP) & CFD_S_OK))	return (ERROR);    return (OK);    }/********************************************************************************* feiAction - execute the specified action command** This routine executes the specified action** We do the command contained in the CFD synchronously, so that we know* it's complete upon return.** RETURNS: The status return of the action command, or 0 on failure.*/LOCAL UINT16 feiAction    (    int		unit,    UINT16	action    )    {    DRV_CTRL *	pDrvCtrl = & drvCtrl [unit];    CFD *	pCFD = pDrvCtrl->pCFD;    UINT16	retVal = 0;    int		ix;    UINT8       state;    if (!(pCFD->cfdStatus & CFD_S_COMPLETE))	/* next CFD free ? */	return (0);    /* fill in CFD */    pCFD->cfdStatus = 0;			/* clear status */    pCFD->cfdCommand = action | CFD_C_SUSP;	/* fill in action */    pCFD->pPrev->cfdCommand &= ~CFD_C_SUSP;	/* hook into CBL */    pDrvCtrl->pCFD = (CFD *) SYS_TO_LOCAL_ADDR(unit,	(UINT32)LINK_RD(&pCFD->link) ); /* bump current CFD */    /* check CU operation -- kick if needed */    if ((((state = pDrvCtrl->pCSR->scbStatus) & SCB_S_CUMASK) != SCB_S_CUACTIVE)        && (pCFD->cfdStatus == 0))        {        if (state == SCB_S_CUIDLE)            {            if (feiSCBCommand (pDrvCtrl, SCB_C_CUSTART, TRUE,                (UINT32 *) LOCAL_TO_SYS_ADDR(unit,(UINT32)pCFD) ) == ERROR)                {#ifdef  FEI_DEBUG                if (feiDebug)                    printf ("feiAction: feiSCBCommand failed\n");#endif  /* FEI_DEBUG */                goto errorAction;                }            }        else            {            if (feiSCBCommand (pDrvCtrl, SCB_C_CURESUME, FALSE, 0x0) == ERROR)                {#ifdef  FEI_DEBUG                if (feiDebug)                    printf ("feiAction: feiSCBCommand failed\n");#endif  /* FEI_DEBUG */                goto errorAction;                }            }        }    /* wait for command to complete */    for (ix = (FEI_ACTION_TMO * feiClkRate); --ix;)	{        if ((retVal = pCFD->cfdStatus) & CFD_S_COMPLETE)            break;	taskDelay (1);        }    if (!ix)	{#ifdef	FEI_DEBUG         printf ("feiAction: command 0x%x, CFD status 0x%x\n", action,	     pCFD->cfdStatus);#endif	/* FEI_DEBUG */        retVal = 0;        goto errorAction;	}    /* put CFD back to a TxCB - mirrors feiattach() */errorAction:    pCFD->cfdStatus = CFD_S_COMPLETE | CFD_S_OK;    LINK_WR (&pCFD->cfdTcb.pTBD, 0xffffffff); /* no TBDs used */    pCFD->cfdTcb.txThresh = pDrvCtrl->board.tcbTxThresh;    pCFD->cfdTcb.tbdNum = 0;    return (retVal);    }/********************************************************************************* feiSCBCommand - deliver a command to the 82557 via the SCB** This function causes the device to execute a command. An error status is* returned if the command field does not return to zero, from a previous* command, in a reasonable amount of time.** RETURNS: OK, or ERROR if the command field appears to be frozen.*/LOCAL STATUS feiSCBCommand    (    DRV_CTRL *	pDrvCtrl,    UINT8	cmd,    BOOL	addrValid,    UINT32 *	addr    )    {    int		ix;    for (ix = 0x8000; --ix;)	{	if ((pDrvCtrl->pCSR->scbCommand & SCB_CR_MASK) == 0)	    break;        }    if (!ix)	{#ifdef  FEI_DEBUG        if (feiDebug)            printf ("feiSCBCommand: command 0x%x failed, scb 0x%x\n", cmd,                pDrvCtrl->pCSR->scbCommand);#endif  /* FEI_DEBUG */        return (ERROR);        }    if (addrValid)			/* optionally fill the GP */

⌨️ 快捷键说明

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