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

📄 mb86960end.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        {        DRV_LOG(DRV_DEBUG_LOAD,                "system memory unavailable\n", 1, 2, 3, 4, 5, 6);        return (ERROR);        }        /* Initialize the memory pool. */    if (netPoolInit(pDrvCtrl->end.pNetPool, &fnMclBlkCfg,                    &fnClDescTbl[0], fnClDescTblNumEnt, NULL) == ERROR)        {        DRV_LOG (DRV_DEBUG_LOAD, "Could not init buffering\n",                 1, 2, 3, 4, 5, 6);        return (ERROR);        }#ifdef DRV_DEBUG    mb86960NetPool = *pDrvCtrl->end.pNetPool;#endif    /* Store the cluster pool id as others need it later. */        pDrvCtrl->pClPoolId = clPoolIdGet (pDrvCtrl->end.pNetPool, 				      sizeof(struct rx_frame), FALSE);    DRV_LOG (DRV_DEBUG_LOAD, "Memory setup complete\n", 1, 2, 3, 4, 5, 6);    return OK;    }/********************************************************************************* mb86960Start - start the device** This function calls BSP functions to connect interrupts and start the* device running in interrupt mode.** RETURNS: OK or ERROR if ISR is not connected.**/LOCAL STATUS mb86960Start    (    MB86960_END_CTRL * pDrvCtrl		/* device to be started */    )    {    STATUS result;    SYS_INT_CONNECT (pDrvCtrl, mb86960Int, (int)pDrvCtrl, &result);    if (result == ERROR) 	return ERROR;    DRV_LOG (DRV_DEBUG_LOAD, "Interrupt connected.\n", 1, 2, 3, 4, 5, 6);        /* Enable specific interrupts. */    SYS_OUT_SHORT ((pDrvCtrl->devBaseAddr + NICE_INTRMASK), NORM_INTRMASK);        /* mark the interface -- up */        END_FLAGS_SET (&pDrvCtrl->end, (IFF_UP | IFF_RUNNING));    SYS_INT_ENABLE (pDrvCtrl);    DRV_LOG (DRV_DEBUG_LOAD, "interrupt enabled.\n", 1, 2, 3, 4, 5, 6);    return (OK);    }/********************************************************************************* mb86960Int - handle controller interrupt** This routine is called at interrupt level in response to an interrupt from* the controller.** RETURNS: N/A.*/LOCAL void mb86960Int    (    MB86960_END_CTRL  * pDrvCtrl  /* interrupting device */    )    {    char	* pDev;		/* ptr to the device regs */    u_short	event;    u_short	reg;    pDev    = pDrvCtrl->devBaseAddr;            SYS_IN_SHORT((pDev + NICE_STATUS), event);    SYS_IN_SHORT((pDev + NICE_INTRMASK), reg);        DRV_LOG (DRV_DEBUG_INT, "i=0x%x:\n", event, 2, 3, 4, 5, 6);    /* Handle receiver overflow event. */    if (event & DLCR1_OVR_FLO)	{	overFlowCnt++; 	/* bump the counter */ 	SYS_OUT_SHORT ((pDev + NICE_STATUS), DLCR1_OVR_FLO); 	return; 	}     /* Handle the receiver event, only if it was enabled. */    if ((reg & DLCR3_RX_PKT) && (event & DLCR1_RX_PKT))        {        SYS_OUT_SHORT ((pDev + NICE_INTRMASK), NO_RX_INTRMASK);  /* disable */        netJobAdd ((FUNCPTR)mb86960HandleRcvInt, (int)pDrvCtrl, 0,0,0,0);        }    /* ACK the interrupts */    SYS_OUT_SHORT ((pDev + NICE_STATUS), event);    }/********************************************************************************* mb86960HandleRcvInt - task level interrupt service for input packets** This routine is called at task level indirectly by the interrupt* service routine to do any message received processing.** RETURNS: N/A.*/LOCAL void mb86960HandleRcvInt    (    MB86960_END_CTRL * pDrvCtrl	/* interrupting device */    )    {    char * pDev = pDrvCtrl->devBaseAddr;    MB86960_RX_FRAME * pCluster;    MB86960_RX_FRAME  temp;    STATUS retCode;    pDrvCtrl->flags |= LS_RCV_HANDLING_FLAG;    while (mb86960RxMore (pDrvCtrl))        {        /*         * We implicitly are loaning here, if copying is necessary this         * step may be skipped, but the data must be copied before being         * passed up to the protocols.         */            pCluster = (MB86960_RX_FRAME *) netClusterGet(pDrvCtrl->end.pNetPool, 						pDrvCtrl->pClPoolId);        if (pCluster == NULL)            {	    dropCnt++;	    DRV_LOG (DRV_DEBUG_RX, "Cannot loan!\n", 1, 2, 3, 4, 5, 6);	    mb86960PacketGet (pDrvCtrl, &temp);	    END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);            }        else	    {	    retCode = mb86960PacketGet (pDrvCtrl, pCluster);	    if (retCode != ERROR)		{                (void) mb86960Recv (pDrvCtrl, pCluster);		}		    else		{		END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);		break;		}            }        }    pDrvCtrl->flags &= ~LS_RCV_HANDLING_FLAG;        /* Turn the receive interrupts on again. */    SYS_OUT_SHORT ((pDev + NICE_INTRMASK), NORM_INTRMASK);    }/********************************************************************************* mb86960RxMore - indicates more packets in the buffer** This routine indicates that there are more packets left in the buffer** RETURNS: TRUE or FALSE*/LOCAL BOOL mb86960RxMore     (    MB86960_END_CTRL * pDrvCtrl	/* interrupting device */    )    {    u_short 	mode;    char *	pDev;		/* ptr to the device regs */    pDev = pDrvCtrl->devBaseAddr; /* get ptr to device */    SYS_IN_SHORT ((pDev + NICE_MODE), mode);    if (mode & DLCR5_BUF_EMPTY)        return (FALSE);    else        return (TRUE);    } /********************************************************************************* mb86960PacketGet - get next received message** Get next received message.  Returns NULL if none are ready.** RETURNS: OK or ERROR.*/LOCAL STATUS mb86960PacketGet    (    MB86960_END_CTRL  * pDrvCtrl,	/* device structure */    MB86960_RX_FRAME * 	pRxFrame	/* pointer to an rx frame struct */    )    {    int			loopy;		/* loop counter */    char *		pDev;		/* ptr to the device regs */    u_short *		pDest;		/* ptr to destination */    pDev = pDrvCtrl->devBaseAddr;            /* get ptr to device */    /* Fill our local copy of the Rx header from the device's buffer. */    SYS_IN_SHORT((pDev + NICE_PORT), pRxFrame->rxHdr.status);    SYS_IN_SHORT((pDev + NICE_PORT), pRxFrame->rxHdr.len);        /* swap bytes if needed */    pRxFrame->rxHdr.len = MB86960_SWAP_SHORT(pRxFrame->rxHdr.len);    /* Clear the status bit for packet ready. */    SYS_OUT_SHORT ((pDev + NICE_STATUS), DLCR1_RX_PKT);    /* Sanity check the packet info. */    if  ((!(pRxFrame->rxHdr.status & RX_HDR_STAT_GOOD))  ||         (pRxFrame->rxHdr.len < ETHERSMALL) || 	 (pRxFrame->rxHdr.len > (ETHERMTU + SIZEOF_ETHERHEADER)))        {       /*  END_FLAGS_CLR (&pDrvCtrl->end, (IFF_UP | IFF_RUNNING));   */        return (ERROR);        }        /* Fill our frame buffer from the device's buffer. */    pDest = (u_short *) &pRxFrame->enetHdr;     /* stuff ptr */    for (loopy = pRxFrame->rxHdr.len; loopy > 0; loopy -= sizeof (u_short))	{        SYS_IN_SHORT((pDev + NICE_PORT), *pDest++);        }    return (OK);    }/********************************************************************************* mb86960Recv - process the next incoming packet** Handle one incoming packet.  The packet is checked for errors.** RETURNS: OK  */LOCAL STATUS mb86960Recv    (    MB86960_END_CTRL * pDrvCtrl,	/* device structure */    MB86960_RX_FRAME * 	pCluster		/* pointer to header structure */    )    {    int         len;    M_BLK_ID 	pMblk;    CL_BLK_ID	pClBlk;        len = pCluster->rxHdr.len;       /* obtain data length */    /* Grab a cluster block to marry to the cluster we received. */    if ((pClBlk = netClBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT)) == NULL)        {        netClFree (pDrvCtrl->end.pNetPool, (char *) pCluster);	DRV_LOG (DRV_DEBUG_RX, "Out of Cluster Blocks!\n", 1, 2, 3, 4, 5, 6);	END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);	goto cleanRXD;        }        /*     * OK we've got a spare, let's get an M_BLK_ID and marry it to the     * one in the ring.     */    if ((pMblk = mBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT, MT_DATA)) == NULL)        {        netClBlkFree (pDrvCtrl->end.pNetPool, pClBlk);         netClFree (pDrvCtrl->end.pNetPool, (char *) pCluster);	DRV_LOG (DRV_DEBUG_RX, "Out of M Blocks!\n", 1, 2, 3, 4, 5, 6);	END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);	goto cleanRXD;        }        /* Add one to our unicast data. */    END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1);    /* Join the cluster to the MBlock */    netClBlkJoin (pClBlk, (char *) pCluster, len, NULL, 0, 0, 0);    netMblkClJoin (pMblk, pClBlk);    pMblk->mBlkHdr.mData = (char *) MB86960_FRAME_DATA_ADDR_GET(pCluster);    pMblk->mBlkHdr.mLen  = len;    pMblk->mBlkHdr.mFlags |= M_PKTHDR;    pMblk->mBlkPktHdr.len = len;    DRV_LOG (DRV_DEBUG_RX, "Calling upper layer!\n", 1, 2, 3, 4, 5, 6);    /* Call the upper layer's receive routine. */    END_RCV_RTN_CALL(&pDrvCtrl->end, pMblk);cleanRXD:    return (OK);    }/********************************************************************************* mb86960Send - the driver send routine** This routine takes a M_BLK_ID sends off the data in the M_BLK_ID.* The buffer must already have the addressing information properly installed* in it.  This is done by a higher layer.  The last arguments are a free* routine to be called when the device is done with the buffer and a pointer* to the argument to pass to the free routine.  ** RETURNS: OK or ERROR.*/LOCAL STATUS mb86960Send    (    MB86960_END_CTRL * pDrvCtrl,	/* device ptr */    M_BLK_ID  pMblk			/* data to send */    )    {    int   oldLevel;    STATUS  status;    DRV_LOG(DRV_DEBUG_TX, "Begin mb86960Send pDrvCtrl %p pMblk %p\n", 	    (int ) pDrvCtrl, (int ) pMblk, 0, 0, 0, 0);    if ((END_FLAGS_GET(&pDrvCtrl->end) & (IFF_UP | IFF_RUNNING)) !=        (IFF_UP | IFF_RUNNING))        {        DRV_LOG(DRV_DEBUG_TX, "Device is NOT UP and RUNNING\n", 0, 0,                0, 0, 0, 0);        return (ERROR);        }    /*     * Obtain exclusive access to transmitter.  This is necessary because     * we might have more than one stack transmitting at once.     */    if (!(pDrvCtrl->flags & LS_POLLING))	semTake (pDrvCtrl->txSem, WAIT_FOREVER);    /* place a transmit request */    if (!(pDrvCtrl->flags & LS_POLLING))        oldLevel = intLock ();   /* now mb86960Int won't get confused */          /* send packet out over interface */    if ((status = mb89680Transmit (pDrvCtrl, pMblk)) == ERROR)        {        DRV_LOG(DRV_DEBUG_TX, "FAILED mb89680Transmit\n", 1, 2, 3, 4, 5, 6);        /* update statistics */        END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_ERRS, +1);        if (!(pDrvCtrl->flags & LS_POLLING))	    {            intUnlock (oldLevel);   /* now mb86960Int won't get confused */	    semGive (pDrvCtrl->txSem);	    }                netMblkClChainFree (pMblk);	return (ERROR);        }        if (!(pDrvCtrl->flags & LS_POLLING))        intUnlock (oldLevel);   /* now mb86960Int won't get confused */        /* Advance our management index */    if (!(pDrvCtrl->flags & LS_POLLING))	semGive (pDrvCtrl->txSem);        /* Bump the statistic counter. */    END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1);    /*     * Cleanup.  The driver must either free the packet now or     * set up a structure so it can be freed later after a transmit     * interrupt occurs.     */    netMblkClChainFree (pMblk);    return (OK);    }/********************************************************************************* mb89680Transmit - kick start the transmitter after generic ether_output** This routine is responsible for tranmitting packets over physical media.* The data to be sent out is held in a chain of mbufs. The data in each mbuf * fragment must be copied to the device's packet buffer.** RETURNS: OK, or ERROR*/LOCAL STATUS mb89680Transmit    (    MB86960_END_CTRL * pDrvCtrl,	/* pointer to driver control struct */    M_BLK_ID pMblk			/* pointer to am Mblk */    )    {    int		pktLen;		/* total length of packet */    int		dataLen;	/* real length of data portion */    int		loopy;		/* loop counter */    char	* nicePort;	/* ptr to the nice buffer port */    u_short	* pSource;	/* ptr to source of data byte */    u_short     temp;    static char	privateBuf [ETHERMTU];    /* get ptr to the buffer port */    nicePort = pDrvCtrl->devBaseAddr + NICE_PORT;    /*     * This driver maintains transmit resources internally. The      * CPU cannot retrieve or examine them.     */         dataLen = netMblkToBufCopy (pMblk, privateBuf, NULL);    /* Ensure we send a legal size frame. */    pktLen = max (ETHERSMALL, dataLen);    /* taking care of short packets, pad with 0s */    if (dataLen < ETHERSMALL)        for (loopy = dataLen; loopy < pktLen; loopy++)            privateBuf [loopy] = 0;    /* Tell the device the length; in little endian order */        SYS_OUT_SHORT  (nicePort, MB86960_SWAP_SHORT(pktLen));    pSource = (u_short *)privateBuf;    for (loopy = pktLen; loopy > 0 ; loopy -= sizeof (u_short))        {        SYS_OUT_SHORT (nicePort, *pSource);        pSource++;         }    if (pktLen % sizeof (u_short))	/* packet size is odd */        {        unsigned short lastByte;        lastByte = 0;        ( (char *) (&lastByte))[0] = ((char *) (pSource))[0];        SYS_OUT_SHORT (nicePort, lastByte);        }    /* See if transmitter is free and start it orelse  wait.  */    FOREVER         {        SYS_IN_SHORT((pDrvCtrl->devBaseAddr + NICE_TRANSMIT), temp);	if ((temp & (0x7f << 8)) == 0)	    break;        }    SYS_OUT_SHORT((pDrvCtrl->devBaseAddr + NICE_TRANSMIT), KICK_TRANSMIT);    return (OK);    }/********************************************************************************* mb86960Ioctl - the driver I/O control routine** Process an ioctl request.** RETURNS: A command specific response, usually OK or ERROR.*/LOCAL int mb86960Ioctl    (    MB86960_END_CTRL * pDrvCtrl,	/* device receiving command */    int cmd,				/* ioctl command code */    caddr_t data			/* command argument */    )    {    int error = 0;    long value;    switch (cmd)        {        case EIOCSADDR:	    if (data == NULL)		return (EINVAL);            bcopy ((char *)data, (char *)END_HADDR(&pDrvCtrl->end),		   END_HADDR_LEN(&pDrvCtrl->end));            break;        case EIOCGADDR:	    if (data == NULL)		return (EINVAL);            bcopy ((char *)END_HADDR(&pDrvCtrl->end), (char *)data,		    END_HADDR_LEN(&pDrvCtrl->end));            break;        case EIOCSFLAGS:	    value = (long)data;	    if (value < 0)		{		value = -(--value);		END_FLAGS_CLR (&pDrvCtrl->end, value);		}	    else		{		END_FLAGS_SET (&pDrvCtrl->end, value);		}	    mb86960Config (pDrvCtrl);            break;        case EIOCGFLAGS:	    *(int *)data = END_FLAGS_GET(&pDrvCtrl->end);            break;	case EIOCPOLLSTART:

⌨️ 快捷键说明

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