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

📄 el3c90xend.c

📁 操作系统vxworks平台下end设备的驱动程序,支持多种芯片,支持多种cpu
💻 C
📖 第 1 页 / 共 5 页
字号:
    pTxChain->pDesc->status |= PCI_SWAP (EL_TXSTAT_DL_INTR);    el3c90xDndEnqueue (pDrvCtrl, pTxChain);    END_TX_SEM_GIVE (&pDrvCtrl->endObj);    /* kick the reciever if blocked, parallel tasking */    el3c90xRxKick (pDrvCtrl);    return (OK);    }/******************************************************************************* el3c90xMCastAdd - 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 or ERROR.*/LOCAL STATUS el3c90xMCastAdd    (    void  * 	pEnd,	        /* device pointer */    char * 	pAddress	/* new address to add */    )    {    int 		error;    EL3C90X_DEVICE * 	pDrvCtrl;    VOID_TO_DRVCTRL (pEnd, pDrvCtrl);    if ((error = etherMultiAdd (&pDrvCtrl->endObj.multiList,		pAddress)) == ENETRESET)	el3c90xMcastConfig (pDrvCtrl);    return (OK);    }/******************************************************************************* el3c90xMCastDel - 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 or ERROR.*/LOCAL STATUS el3c90xMCastDel    (    void  * 	pEnd,	        /* device pointer */    char * 	pAddress	/* address to be deleted */    )    {    int 		error;    EL3C90X_DEVICE * 	pDrvCtrl;    VOID_TO_DRVCTRL (pEnd, pDrvCtrl);    if ((error = etherMultiDel (&pDrvCtrl->endObj.multiList,	     (char *)pAddress)) == ENETRESET)	el3c90xMcastConfig (pDrvCtrl);    return (OK);    }/******************************************************************************* el3c90xMCastGet - get the multicast address list for the device** This routine gets the multicast list of whatever the driver* is already listening for.** RETURNS: OK or ERROR.*/LOCAL STATUS el3c90xMCastGet    (    void  * 		pEnd,	        /* device pointer */    MULTI_TABLE * 	pTable		/* address table to be filled in */    )    {    EL3C90X_DEVICE * pDrvCtrl;    VOID_TO_DRVCTRL (pEnd, pDrvCtrl);    return (etherMultiGet (&pDrvCtrl->endObj.multiList, pTable));    }/********************************************************************************* el3c90xPollSend - routine to send a packet in polled mode.** This routine is called by a user to try and send a packet on the* device.** RETURNS: OK upon success.  EAGAIN if device is busy.*/LOCAL STATUS el3c90xPollSend    (    void  * 		pEnd,	        /* device pointer */    M_BLK_ID 		pMblk		/* packet to send */    )    {    EL3C90X_DEVICE * 	pDrvCtrl;    EL_DESC_CHAIN *	pTxChain = NULL;    VOID_TO_DRVCTRL (pEnd, pDrvCtrl);    DRV_LOG (DRV_DEBUG_POLL_TX, "PTX b\n", 1, 2, 3, 4, 5, 6);    /* check if download engine is still busy */    if (el3c90xCsrReadLong (pDrvCtrl, EL_DOWNLIST_PTR, NONE))        {        DRV_LOG (DRV_DEBUG_POLL_TX, "transmitter busy\n", 1, 2, 3, 4, 5, 6);                return (EAGAIN);        }    /* check if a download descriptor is available */    if ((pTxChain =  el3c90xDndGet (pDrvCtrl)) == NULL)        return (EAGAIN);    /* Pack the mBlk into the download descriptor. */    if (el3c90xDndMblkPack (pDrvCtrl, pTxChain, pMblk) == ERROR)        {        el3c90xDndFree (pDrvCtrl, pTxChain);        return (EAGAIN);        }#ifndef INCLUDE_RFC_1213    /* New RFC 2233 mib2 interface */    /* RFC 2233 mib2 counter update for outgoing packet */    if (pDrvCtrl->endObj.pMib2Tbl != NULL)        {        pDrvCtrl->endObj.pMib2Tbl->m2PktCountRtn(pDrvCtrl->endObj.pMib2Tbl,                                                 M2_PACKET_OUT,                                                 pMblk->mBlkHdr.mData,                                                 pMblk->mBlkHdr.mLen);        }#endif /* INCLUDE_RFC_1213 */    el3c90xCsrWriteLong (pDrvCtrl, EL_DOWNLIST_PTR,                         (UINT32)EL3C90X_CACHE_VIRT_TO_PHYS (pTxChain->pDesc),                         NONE);    /* wait until download has completed */        while (el3c90xCsrReadLong (pDrvCtrl, EL_DOWNLIST_PTR, NONE))        ;    el3c90xDndFree (pDrvCtrl, pTxChain);    DRV_LOG (DRV_DEBUG_POLL_TX, "PTX e\n", 1, 2, 3, 4, 5, 6);    return (OK);    }/********************************************************************************* el3c90xPollRcv - routine to receive a packet in polled mode.** This routine is called by a user to try and get a packet from the* device.** RETURNS: EGAIN or OK*/LOCAL STATUS el3c90xPollRcv    (    void  * 		pEnd,		/* device pointer */    M_BLK_ID 		pMblk		/* pointer to the mBlk chain */    )    {    EL_SIMPLE_DESC_CHAIN * 	pRxUpd;    EL3C90X_DEVICE * 		pDrvCtrl;    M_BLK_ID 			pMblkTemp;	/* pointer to the mBlk */    int				len;    DRV_LOG (DRV_DEBUG_POLL_RX, "PRX b\n", 1, 2, 3, 4, 5, 6);    VOID_TO_DRVCTRL (pEnd, pDrvCtrl);    el3c90xRxUnStall (pDrvCtrl);    /* get the next upload descriptor */        if ((pRxUpd = el3c90xNextUpdFetch (pDrvCtrl)) == NULL)        {        DRV_LOG (DRV_DEBUG_POLL_RX, "PRX no upd\n", 1, 2, 3, 4, 5, 6);        return (EAGAIN);        }    /* get the mBlk associated with the upd */        if ((pMblkTemp = el3c90xNextPktFetch (pDrvCtrl, pRxUpd)) == NULL)        return (EAGAIN);    /* copy the data into the given buffer */        len = netMblkToBufCopy (pMblkTemp, pMblk->mBlkHdr.mData, NULL);    netMblkClChainFree (pMblkTemp);    if ((pMblk->mBlkHdr.mLen < len) || (!(pMblk->mBlkHdr.mFlags & M_EXT)))	{        DRV_LOG (DRV_DEBUG_POLL_RX, "PRX bad mblk len:%d flags:%d\n",                 pMblk->mBlkHdr.mLen, pMblk->mBlkHdr.mFlags, 3, 4, 5, 6);	return (EAGAIN);	}    pMblk->mBlkHdr.mLen = len;    pMblk->mBlkHdr.mFlags |= M_PKTHDR;    pMblk->mBlkPktHdr.len = len;#ifndef INCLUDE_RFC_1213    /* New RFC 2233 mib2 interface */    /* RFC 2233 mib2 counter update for incoming packet */    if (pDrvCtrl->endObj.pMib2Tbl != NULL)        {        pDrvCtrl->endObj.pMib2Tbl->m2PktCountRtn(pDrvCtrl->endObj.pMib2Tbl,                                                 M2_PACKET_IN,                                                 pMblk->mBlkHdr.mData,                                                 pMblk->mBlkHdr.mLen);        }#endif /* INCLUDE_RFC_1213 */    DRV_LOG (DRV_DEBUG_POLL_RX, "PRX ok\n", 1, 2, 3, 4, 5, 6);    return (OK);    }/********************************************************************************* el3c90xInit - initialize the device** This routine initializes device and enables the device interrupts. It* initializes the descriptor rings** RETURNS: N/A*/LOCAL void el3c90xInit    (    EL3C90X_DEVICE * pDrvCtrl	/* pointer to the device control structure */    )    {    int			ix;    UINT16		rxFilt = 0;    UINT16		phyBMCR = 0;    int			flags;    /*     * hack for the 3c905B: the built-in autoneg logic's state     * gets reset by el3c90xInit() when we don't want it to. Try     * to preserve it. (For 3c905 cards with real external PHYs,     * the BMCR register doesn't change, but this doesn't hurt.)     */    if (pDrvCtrl->pPhyDevType != NULL)        phyBMCR = el3c90xPhyRegRead(pDrvCtrl, PHY_BMCR);    /* cancel pending I/O and free all RX/TX buffers. */    el3c90xDevStop(pDrvCtrl);    el3c90xWait(pDrvCtrl);    /* get the MAC address */    for (ix = 0; ix < EA_SIZE; ix++)        {        el3c90xCsrWriteByte (pDrvCtrl, EL_W2_STATION_ADDR_LO + ix,                             pDrvCtrl->enetAddr [ix], EL_WIN_2);	}    /* clear the station mask */    for (ix = 0; ix < 3; ix++)        el3c90xCsrWriteWord (pDrvCtrl, EL_W2_STATION_MASK_LO + (ix * 2), 0,                             EL_WIN_2);    /* reset TX and RX */    el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_RX_RESET, NONE);    el3c90xWait(pDrvCtrl);    el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_TX_RESET, NONE);    el3c90xWait(pDrvCtrl);    /* init circular upload descriptor list */        if (el3c90xUpdInit(pDrvCtrl) == ENOBUFS)        {        DRV_LOG (DRV_DEBUG_LOAD, "elPci%d: initialization failed: no "               "memory for rx buffers\n", pDrvCtrl->unit, 2, 3, 4, 5, 6);        el3c90xDevStop(pDrvCtrl);        return;	}    /* init download descriptors list */    el3c90xDndInit(pDrvCtrl);    /*     * set the TX freethresh value.     * note that this has no effect on 3c905B "cyclone"     * cards but is required for 3c900/3c905 "boomerang"     * cards in order to enable the download engine.     */    el3c90xCsrWriteByte (pDrvCtrl, EL_TX_FREETHRESH, (EL3C90X_BUFSIZ >> 8),                         NONE);    /*     * If this is a 3c905B, also set the tx reclaim threshold.     * This helps cut down on the number of tx reclaim errors     * that could happen on a busy network. The chip multiplies     * the register value by 16 to obtain the actual threshold     * in bytes, so we divide by 16 when setting the value here.     * The existing threshold value can be examined by reading     * the register at offset 9 in window 5.     */    if (pDrvCtrl->devType == EL_TYPE_905B)        {        el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND,                             (EL_CMD_SET_TX_RECLAIM | (EL3C90X_BUFSIZ >> 4)),                             NONE);        }    /* set RX filter bits. */    rxFilt = el3c90xCsrReadByte (pDrvCtrl, EL_W5_RX_FILTER, EL_WIN_5);    /* set the individual bit to receive frames for this host only. */    rxFilt |= EL_RXFILTER_INDIVIDUAL;    flags = END_FLAGS_GET (&pDrvCtrl->endObj);    /* if we want promiscuous mode, set the allframes bit. */    if (flags & IFF_PROMISC)        {        rxFilt |= EL_RXFILTER_ALLFRAMES;        el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND,                             (EL_CMD_RX_SET_FILT | rxFilt), NONE);	}    else        {        rxFilt &= ~EL_RXFILTER_ALLFRAMES;        el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND,                             (EL_CMD_RX_SET_FILT | rxFilt), NONE);	}    /* set capture broadcast bit to capture broadcast frames. */    if (flags & IFF_BROADCAST)        {        rxFilt |= EL_RXFILTER_BROADCAST;        el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND,                             (EL_CMD_RX_SET_FILT | rxFilt), NONE);	}    else        {        rxFilt &= ~EL_RXFILTER_BROADCAST;        el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND,                             (EL_CMD_RX_SET_FILT | rxFilt), NONE);	}    /* set the multicast filter etc */            el3c90xMcastConfig (pDrvCtrl);    /*     * load the upload descriptor pointer and start the upload engine     * Note that we have to do this after any RX resets have completed     * since the uplist register is cleared by a reset.     */    el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_UP_STALL, NONE);    el3c90xWait(pDrvCtrl);    el3c90xCsrWriteLong (pDrvCtrl, EL_UPLIST_PTR,                         (UINT32) EL3C90X_CACHE_VIRT_TO_PHYS                         (&pDrvCtrl->pDescBlk->rxDescs[0]), NONE);    el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_UP_UNSTALL, NONE);    /*     * if the coax transceiver is on, make sure to enable the DC-DC converter.     */    if (pDrvCtrl->xCvr == EL_XCVR_COAX)        el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_COAX_START, NONE);    else        el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_COAX_STOP, NONE);    /* Clear out the stats counters. */    el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_STATS_DISABLE, NONE);    el3c90xStatUpdate(pDrvCtrl);    el3c90xCsrWriteWord (pDrvCtrl, EL_W4_NET_DIAG,                         EL_NETDIAG_UPPER_BYTES_ENABLE, EL_WIN_4);    el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_STATS_ENABLE, NONE);    /* enable device interrupts */    el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_INTR_ACK|0xFF, NONE);    el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_STAT_ENB|EL_INTRS, NONE);    el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_INTR_ENB|EL_INTRS, NONE);

⌨️ 快捷键说明

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