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

📄 iolicomend.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 5 页
字号:
    PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R13), (addrC >> 8));     /* Write the command opcode, and reserved field for the packet */     WRITE_R14_R15 (CMD_MC_SETUP);     /* Write 16 bit status field */     WRITE_R14_R15 (0x00);     /* Write the chain pointer */     WRITE_R14_R15 (0x00);     /* Write the byte count low and high bytes */     WRITE_R14_R15 (length & ~XMT_CHAIN);     /* copy data */    for (; length > 0 ; length -= 2)        {        PCMCIA_IO_WRITE((UINT)(pDrvCtrl->pcmcia.oliAddr + I595_R14), 					*pData--);        PCMCIA_IO_WRITE((UINT)(pDrvCtrl->pcmcia.oliAddr + I595_R15), 					*pData--);        }     /* Write the XMT base address register */     PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R10), addrC);    PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R11), (addrC >> 8));     /* Issue a MC_SETUP command to the 82595TX */     RUNCMD((UINT)(pDrvCtrl->pcmcia.oliAddr), CMD_MC_SETUP);     /* incr BD count */     pDrvCtrl->txBdNext = (pDrvCtrl->txBdNext + 1) % pDrvCtrl->txBdNum;     /* Spin until we've sent it. */     while (!(PCMCIA_IO_READ((int)(pDrvCtrl->pcmcia.oliAddr + I595_R1))                 & BNK0_EXE_IT));     /* clear execution interrupt */     PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R1), BNK0_EXE_IT);    /* clean the transmit queue */    iOlicomTxBdQueueClean(pDrvCtrl);     intUnlock (s);   /* now iOlicomInt won't get confused */        /* free the buffer */     NET_BUF_FREE (pFltrFrm);     /* Flush the write pipe */     CACHE_PIPE_FLUSH ();    /* release exclusive access */     END_TX_SEM_GIVE (&pDrvCtrl->endObj);     return (OK);    }/********************************************************************************* iOlicomPollReceive - routine to receive a packet in polled mode.** This routine is called by a user to try and get a packet from the* device. It returns EAGAIN if no packet is available. The caller must* supply a M_BLK_ID with enough space to contain the receiving packet. If* enough buffer is not available then EAGAIN is returned.** These routine should not call any kernel functions.** RETURNS: OK on success, EAGAIN on failure.*/ LOCAL STATUS iOlicomPollReceive    (    END_DEVICE *	pDrvCtrl,	/* pointer to END_DEVICE structure */    M_BLK  *		pMblk    )    {    char *	pPacket;    int		status;    int		length;    int		event;    int		start;    int		nextStop;    BOOL	gotOne=FALSE;    if ((pMblk->mBlkHdr.mFlags & M_EXT) != M_EXT)        return (EAGAIN);    /* Read the device status register */    status = PCMCIA_IO_READ((int)(pDrvCtrl->pcmcia.oliAddr + I595_R1));    /* If no interrupt then return. */    if (!(status & BNK0_RX_IT))	{	END_LOG_MSG (END_DEBUG_POLL_RX, "iOlicomPollReceive no rint\n",			 0, 0, 0, 0, 0, 0);        return (EAGAIN);	}    /*     * The RCV STOP register points to the last pair of bytes     * BEFORE the start of the next packet so we must add two     * bytes to reach the correct address.     */     start = PCMCIA_IO_READ((int)pDrvCtrl->pcmcia.oliAddr + I595_R6);    start |= (PCMCIA_IO_READ((int)pDrvCtrl->pcmcia.oliAddr + I595_R7) << 8);    start += 2;     /* Handle the roll over case */    if (start > RAM_RX_LIMIT)	start -= RAM_RX_BASE;     /* Set up address from where we wish to start reading data */     PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R12), start);    PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R13), (start >> 8));     /* The first word describes the state of reception.  */     event = PCMCIA_IO_READ((int)pDrvCtrl->pcmcia.oliAddr + I595_R14);    event |= (PCMCIA_IO_READ((int)pDrvCtrl->pcmcia.oliAddr + I595_R15) << 8);     /* The following bit will be set once the packet is complete in memory. */     if (event & RCV_EOF)        {         /* Collect the status of the packet */	status = PCMCIA_IO_READ((int)pDrvCtrl->pcmcia.oliAddr + I595_R14);	status |= (PCMCIA_IO_READ((int)pDrvCtrl->pcmcia.oliAddr + I595_R15)						 << 8);	/* get next packet pointer */ 	nextStop = PCMCIA_IO_READ((int)pDrvCtrl->pcmcia.oliAddr + I595_R14);	nextStop |= (PCMCIA_IO_READ((int)pDrvCtrl->pcmcia.oliAddr + I595_R15)						 << 8); 	/* The next stop value is 2 bytes back in the circular buffer */	nextStop -= 2;	/* Handle the roll over case */	if (nextStop < RAM_RX_BASE)	    nextStop += RAM_RX_BASE;        /* get packet length */ 	length = PCMCIA_IO_READ((int)pDrvCtrl->pcmcia.oliAddr + I595_R14);	length |= (PCMCIA_IO_READ((int)pDrvCtrl->pcmcia.oliAddr + I595_R15)						 << 8);          /* Check for errors */         if (!(status & RCV_OK) || ((length - SIZEOF_ETHERHEADER) <= 0))            {            /* bump input error packet counter */             END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);            }        else            {             /*             * We always read an even number of bytes from the controller,             * so adjust the length if necessary.             */             if ((length & ODD_MSK) != 0)                ++length;            /* Upper layer provides the buffer. */                    if (pMblk->mBlkHdr.mLen < length)                goto pollRecvExit;	    /* Deal with memory aligment */	    if (((int) pMblk->mBlkHdr.mData & 0x3) == 0)		pMblk->mBlkHdr.mData += pDrvCtrl->offset;	    pMblk->mBlkHdr.mFlags |= M_PKTHDR;	/* set the packet header */	    pMblk->mBlkPktHdr.len  = length;	/* set the total len */	    pMblk->mBlkHdr.mLen    = length;	/* set the data len */            /* copy data */            for (pPacket = pMblk->mBlkHdr.mData; length != 0; length -=2)                {                *pPacket++ = PCMCIA_IO_READ((int)                                (pDrvCtrl->pcmcia.oliAddr + I595_R14));                *pPacket++ = PCMCIA_IO_READ((int)                                (pDrvCtrl->pcmcia.oliAddr + I595_R15));                }	    gotOne = TRUE;            /* bump input packet counter */             END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1);            }        /* Update the STOP register from the next packet pointer */ 	PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R6), nextStop);	PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R7),						 (nextStop >> 8));	} pollRecvExit:    /* clear receive interrupts. */     PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R1), BNK0_RX_IT);     /* Flush the write pipe */    CACHE_PIPE_FLUSH ();    return (gotOne ? OK : EAGAIN);    }/********************************************************************************* iOlicomPollSend - routine to send a packet in polled mode.** This routine is called by a user to try and send a packet on the* device. It sends a packet directly on the network from the caller without* going through the normal processes of queuing a pacet on an output queue* and the waiting for the device to decide to transmit it.** If it detects a transmission error, the restart command is issued.** These routine should not call any kernel functions.** RETURNS: OK on success, EAGAIN on failure*/LOCAL STATUS iOlicomPollSend    (    END_DEVICE *	pDrvCtrl,	/* pointer to END_DEVICE structure */    M_BLK *		pMblk    )    {    TX_BD *	pTxBd;    char *	pBuf;    char *	pData;    ULONG	addrC;    int		len;    int		status;    if (DRV_FLAGS_ISSET(OLI_TX_STOP))        return (EAGAIN);    /* get a free transmit frame descriptor */     pTxBd = iOlicomTxBdGet (pDrvCtrl);    addrC = (ULONG) pTxBd->dataPointer;    /* get a free buffer */    pBuf = NET_BUF_ALLOC ();    if ((pTxBd == NULL) || (pBuf == NULL))        {        iOlicomTxBdQueueClean (pDrvCtrl);        if (pBuf)            NET_BUF_FREE (pBuf);        return (EAGAIN);        }   /* copy the MBLK */     len = netMblkToBufCopy (pMblk, pBuf, NULL);     /* Write the transmit buffer base address. */    PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R12), addrC);    PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R13), (addrC >> 8));     /* Write the command opcode, and reserved field for the packet */     PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R14), CMD_TRANSMIT);    PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R15), 					(CMD_TRANSMIT >> 8));     /* Write 16 bit status field */     PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R14), 0x00);    PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R15), 0x00);     /* Write the chain pointer */     PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R14), 0x00);    PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R15), 0x00);     /* Write the byte count low and high bytes */     PCMCIA_IO_WRITE((UINT)(pDrvCtrl->pcmcia.oliAddr + I595_R14),					 len & OCT_MSK);    PCMCIA_IO_WRITE((UINT)(pDrvCtrl->pcmcia.oliAddr + I595_R15),					 (len >> 8) & ~XMT_CHAIN_OCT);    /* copy data */    for (pData = pBuf; len > 0; len -= 2)        {        PCMCIA_IO_WRITE((UINT)(pDrvCtrl->pcmcia.oliAddr + I595_R14),					 *pData++);        PCMCIA_IO_WRITE((UINT)(pDrvCtrl->pcmcia.oliAddr + I595_R15),					 *pData++);        }    /* Write the XMT base address register */     PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R10), addrC);    PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R11), ( addrC >> 8));    /* Issue a XMT command to the 82595TX */     RUNCMD((UINT)(pDrvCtrl->pcmcia.oliAddr), CMD_TRANSMIT);    /* incr BD count */     pDrvCtrl->txBdNext = (pDrvCtrl->txBdNext + 1) % pDrvCtrl->txBdNum;     /* Bump the statistic counter. */     END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, +1);    /* Flush the write pipe */    CACHE_PIPE_FLUSH ();    /* Spin until we've sent it. */    while (!(PCMCIA_IO_READ((int)(pDrvCtrl->pcmcia.oliAddr + I595_R1))		 & BNK0_TX_IT));    /* clear transmit interrupt */    PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R1), BNK0_TX_IT);    /* Free the data immediately. */        NET_BUF_FREE (pBuf);    /* check for output errors */    addrC = (ULONG) pTxBd->dataPointer + 2;    PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R12), addrC);    PCMCIA_IO_WRITE((int)(pDrvCtrl->pcmcia.oliAddr + I595_R13), ( addrC >> 8));     status = PCMCIA_IO_READ((int)pDrvCtrl->pcmcia.oliAddr + I595_R14);    status |= (PCMCIA_IO_READ((int)pDrvCtrl->pcmcia.oliAddr + I595_R15) << 8);     if (!(status & XMT_OK))        return (EAGAIN);    /*     * we are allow to do this because transmit queue is empty when we     * start polling mode.     */     pDrvCtrl->txBdIndexC = pDrvCtrl->txBdNext;     return (OK);    }/******************************************************************************** iOlicomMCastAddrAdd - add a multicast address for the device** This routine adds a multicast address to whatever the driver* is already listening for.  It then resets the address filter.** RETURNS: OK on success, ERROR otherwise.*/LOCAL STATUS iOlicomMCastAddrAdd    (    END_DEVICE *	pDrvCtrl,	/* pointer to END_DEVICE structure */    char *		pAddress	/* address to add to the table */    )    {    int	error;    END_LOG_MSG (END_DEBUG_IOCTL, "iOlicomMCastAddrAdd\n", 0, 0, 0, 0, 0, 0);    if ((error = etherMultiAdd (&pDrvCtrl->endObj.multiList,		pAddress)) == ENETRESET)	    iOlicomConfig (pDrvCtrl);    return (OK);    }/******************************************************************************* iOlicomMCastAddrDel - delete a multicast address for the device** This routine removes a multicast address from whatever the driver* is listening for.  It then resets the address filter.** RETURNS: OK on success, ERROR otherwise.*/LOCAL STATUS iOlicomMCastAddrDel    (    END_DEVICE *	pDrvCtrl,	/* pointer to END_DEVICE structure */    char *		pAddress	/* address to delete from the table */    )    {    int	error;    END_LOG_MSG (END_DEBUG_IOCTL, "iOlicomMCastAddrDel\n", 0, 0, 0, 0, 0, 0);    if ((error = etherMultiDel (&pDrvCtrl->endObj.multiList,	     (char *)pAddress)) == ENETRESET)	    iOlicomConfig (pDrvCtrl);    return (OK);    }/******************************************************************************* iOlicomMCastAddrGet - get the multicast address list for the device** This routine gets the multicast list of whatever the driver* is already listening for.** RETURNS: OK on success, ERROR otherwise.*/LOCAL STATUS iOlicomMCastAddrGet    (    END_DEVICE *	pDrvCtrl,	/* pointer to END_DEVICE structure */    MULTI_TABLE *	pTable		/* table to fill in with addresses */    )    {    int	error;   

⌨️ 快捷键说明

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