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

📄 el3c90xend.c

📁 3C90X驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/********************************************************************************* el3c90xDevStop - stop the device** This function stops the adapter and frees up any M_BLKS allocated to the* upload and download descriptors.** RETURNS: N/A*/LOCAL void el3c90xDevStop    (    EL3C90X_DEVICE * 	pDrvCtrl /* pointer to the device control structure */    )    {    register int	ix;    el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_RX_DISABLE, NONE);    el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_STATS_DISABLE, NONE);    el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_INTR_ENB, NONE);    el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_RX_DISCARD, NONE);    el3c90xWait(pDrvCtrl);    el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_TX_DISABLE, NONE);    el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_COAX_STOP, NONE);    el3c90xWait(pDrvCtrl);    el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_RX_RESET, NONE);    el3c90xWait(pDrvCtrl);    el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_TX_RESET, NONE);    el3c90xWait(pDrvCtrl);    el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND,                         (EL_CMD_INTR_ACK | EL_STAT_INTLATCH), NONE);    /* free the mblks in the upload descriptor lists */        for (ix = 0; ix < EL_UPD_CNT; ix++)        {        if (pDrvCtrl->rxTxChain.rxChain [ix].pMblk != NULL)            {            netMblkClChainFree(pDrvCtrl->rxTxChain.rxChain [ix].pMblk);            pDrvCtrl->rxTxChain.rxChain [ix].pMblk = NULL;            }	}    bzero ((char *)&pDrvCtrl->pDescBlk->rxDescs,           sizeof(pDrvCtrl->pDescBlk->rxDescs));    /* free the download descriptors */    for (ix = 0; ix < EL_DND_CNT; ix++)        {        if (pDrvCtrl->rxTxChain.txChain [ix].pMblk != NULL)            {            netMblkClChainFree(pDrvCtrl->rxTxChain.txChain[ix].pMblk);            pDrvCtrl->rxTxChain.txChain [ix].pMblk = NULL;            }	}    bzero ((char *)&pDrvCtrl->pDescBlk->txDescs,           sizeof(pDrvCtrl->pDescBlk->txDescs));    return;    }/********************************************************************************* el3c90xReset - reset  the device** This function call resets the device completely** RETURNS: N/A*/LOCAL void el3c90xReset    (    EL3C90X_DEVICE * pDrvCtrl    )    {    /* issue the reset command */        el3c90xCsrWriteWord(pDrvCtrl, EL_COMMAND, EL_CMD_RESET, EL_WIN_0);    el3c90xWait(pDrvCtrl);	/* wait for the command to complete */    /* wait for a while */    SYS_DELAY(1000);    return;    }/********************************************************************************* el3c90xIntEnable - enable board to cause interrupts** Because the board has maskable status, this routine can simply set the* mask to all ones.  We set all the bits symbolically; the effect is the* same.  Note that the interrupt latch is not maskable; if none of the other* mask bits are set, no interrupts will occur at all.  Only those interrupts* whose status bits are enabled will actually occur.  Note that the "intMask"* field in the device control structure is really the status mask.** RETURNS: N/A.*/LOCAL void el3c90xIntEnable    (    EL3C90X_DEVICE * pDrvCtrl	/* device structure */    )    {    UINT16  status;    status = el3c90xCsrReadWord (pDrvCtrl, EL_STATUS, NONE);    status &= 0x00ff;    el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, (EL_CMD_INTR_ACK | status),                         NONE);    el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, (EL_CMD_INTR_ENB | EL_INTRS),                         NONE);    }/********************************************************************************* el3c90xIntDisable - prevent board from causing interrupts** This routine simply sets all the interrupt mask bits to zero.* It is intended for guarding board-critical sections.** RETURNS: N/A.*/LOCAL void el3c90xIntDisable    (    EL3C90X_DEVICE * pDrvCtrl	/* device structure */    )    {    UINT16  status;    el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_INTR_ENB, NONE);    status = el3c90xCsrReadWord (pDrvCtrl, EL_STATUS, NONE);    status &= 0x00ff;    el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, (EL_CMD_INTR_ACK | status),                         NONE);    }/********************************************************************************* el3c90xPollStart - start polled mode operations** This function starts polled mode operation.** The device interrupts are disabled, the current mode flag is switched* to indicate Polled mode and the device is reconfigured.** RETURNS: OK or ERROR.*/LOCAL STATUS el3c90xPollStart    (    EL3C90X_DEVICE * pDrvCtrl	/* device to be polled */    )    {    int         oldLevel;        oldLevel = intLock ();          /* disable ints during update */    pDrvCtrl->flags |= EL_POLLING;    intUnlock (oldLevel);   /* now el3c90xInt won't get confused */    el3c90xIntDisable (pDrvCtrl);    ENDLOGMSG (("STARTED\n", 1, 2, 3, 4, 5, 6));    return (OK);    }/********************************************************************************* el3c90xPollStop - stop polled mode operations** This function terminates polled mode operation.  The device returns to* interrupt mode.** The device interrupts are enabled, the current mode flag is switched* to indicate interrupt mode and the device is then reconfigured for* interrupt operation.** RETURNS: OK or ERROR.*/LOCAL STATUS el3c90xPollStop    (    EL3C90X_DEVICE * pDrvCtrl	/* device structure */    )    {    int         oldLevel;    oldLevel = intLock ();	/* disable ints during register updates */    pDrvCtrl->flags &= ~EL_POLLING;    intUnlock (oldLevel);    el3c90xIntEnable (pDrvCtrl);    ENDLOGMSG (("STOPPED\n", 1, 2, 3, 4, 5, 6));    return (OK);    }/********************************************************************************* el3c90xUpdInit - initialize the upload descriptor list** This function initializes the upload descriptors and allocates M_BLKs for* them. Note that we arrange the descriptors in a closed ring, so that the* last descriptor points back to the first.** RETURNS: OK or ENOBUFS*/LOCAL int el3c90xUpdInit    (    EL3C90X_DEVICE * pDrvCtrl	/* pointer to the device control structure */    )    {    EL_RX_TX_CHAIN *	pRxTxChain;    EL_DESC_BLK	*	pDescBlk;    int			ix;    pRxTxChain = &pDrvCtrl->rxTxChain;    pDescBlk = pDrvCtrl->pDescBlk;    for (ix = 0; ix < EL_UPD_CNT; ix++)        {        pRxTxChain->rxChain [ix].pDesc =            (EL_SIMPLE_DESC *)&pDescBlk->rxDescs [ix];			        if (el3c90xUpdFill(pDrvCtrl, &pRxTxChain->rxChain [ix]) == ENOBUFS)            return(ENOBUFS);                if (ix == (EL_UPD_CNT - 1))            {            pRxTxChain->rxChain [ix].pNextChain = &pRxTxChain->rxChain [0];            pDescBlk->rxDescs [ix].nextDesc =                PCI_SWAP                (                (UINT32)EL3C90X_CACHE_VIRT_TO_PHYS (&pDescBlk->rxDescs [0])                );            }        else            {            pRxTxChain->rxChain [ix].pNextChain =                &pRxTxChain->rxChain [ix + 1];            pDescBlk->rxDescs [ix].nextDesc =                PCI_SWAP((UINT32)EL3C90X_CACHE_VIRT_TO_PHYS                         (&pDescBlk->rxDescs [ix + 1]));            }	}    pRxTxChain->pRxHead = &pRxTxChain->rxChain [0];    return (OK);    }/********************************************************************************* el3c90xDndInit - initialize the download descriptor list** This function initializes the download descriptor list** RETURNS: OK*/LOCAL int el3c90xDndInit    (    EL3C90X_DEVICE * pDrvCtrl	/* pointer to the device control structure */    )    {    EL_RX_TX_CHAIN *	pRxTxChain;    EL_DESC_BLK	*	pDescBlk;    int			ix;    pRxTxChain = &pDrvCtrl->rxTxChain;    pDescBlk = pDrvCtrl->pDescBlk;        for (ix = 0; ix < EL_DND_CNT; ix++)        {        pRxTxChain->txChain [ix].pDesc = &pDescBlk->txDescs [ix];        if (ix == (EL_DND_CNT - 1))            pRxTxChain->txChain [ix].pNextChain = NULL;        else            pRxTxChain->txChain[ix].pNextChain = &pRxTxChain->txChain [ix + 1];	}    pRxTxChain->pTxFree = &pRxTxChain->txChain [0];    pRxTxChain->pTxTail = pRxTxChain->pTxHead = NULL;    return(0);    }/********************************************************************************* el3c90xHashGet - get a hash filter bit position** This routine is taken from the 3Com Etherlink XL manual,* chapter 10 pg 156. It calculates a CRC of the supplied multicast* group address and returns the lower 8 bits, which are used* as the multicast filter position.* Note: the 3c905B currently only supports a 64-bit hash table,* which means we really only need 6 bits, but the manual indicates* that future chip revisions will have a 256-bit hash table,* hence the routine is set up to calculate 8 bits of position* info in case we need it some day.* Note II, The Sequel: _CURRENT_ versions of the 3c905B have a* 256 bit hash table. This means we have to use all 8 bits regardless.* On older cards, the upper 2 bits will be ignored. Grrrr....** RETURNS: filter bit position*/LOCAL UINT8 el3c90xHashGet    (    char * 	addr    )    {    UINT32	crc;    UINT32	carry;    int		ix;    int		jx;    UINT8	ch;    /* Compute CRC for the address value. */    crc = 0xFFFFFFFF; /* initial value */    for (ix = 0; ix < 6; ix++)        {        ch = *(addr + ix);        for (jx = 0; jx < 8; jx++)            {            carry = ((crc & 0x80000000) ? 1 : 0) ^ (ch & 0x01);            crc <<= 1;            ch >>= 1;            if (carry)                crc = (crc ^ 0x04c11db6) | carry;            }        }    /* return the filter bit position */    return (crc & 0x000000FF);    }/********************************************************************************* el3c90xFilterSet - set the multicast filter** NICs older than the 3c905B have only one multicast option, which* is to enable reception of all multicast frames.** RETURNS: N/A*/LOCAL void el3c90xFilterSet    (    EL3C90X_DEVICE * pDrvCtrl	/* device to be re-configured */    )    {    UINT8		rxFilt;    rxFilt = el3c90xCsrReadByte(pDrvCtrl, EL_W5_RX_FILTER, EL_WIN_5);    if (END_FLAGS_GET (&pDrvCtrl->endObj) & IFF_ALLMULTI)        {        rxFilt |= EL_RXFILTER_ALLMULTI;        el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND,                             (EL_CMD_RX_SET_FILT | rxFilt), NONE);        return;        }    /* Set up address filter for multicasting.      * Multicast bit is set if the address list has one or more entries     * Multicasting is disabled if the address list is empty     */    if (END_MULTI_LST_CNT (&pDrvCtrl->endObj) > 0)	{	ENDLOGMSG (("Setting multicast mode on!\n", 1, 2, 3, 4, 5, 6));        rxFilt |= EL_RXFILTER_ALLMULTI;	}    else	{	ENDLOGMSG (("Setting multcast mode off!\n", 1, 2, 3, 4, 5, 6));        rxFilt &= ~EL_RXFILTER_ALLMULTI;	}    el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND,                         (EL_CMD_RX_SET_FILT | rxFilt), NONE);    return;    }/********************************************************************************* el3c90xHashFilterSet - set the hash filter for 3c90xB adapters.** This function programs the hash fileter for the 3c905B adapters.** RETURNS: N/A*/LOCAL void el3c90xHashFilterSet    (    EL3C90X_DEVICE * pDrvCtrl	/* device to be re-configured */    )    {    ETHER_MULTI * 	pCurr;    UINT8		rxFilt;    int			ix;    int			hash = 0;    int			mcnt = 0;    rxFilt = el3c90xCsrReadByte(pDrvCtrl, EL_W5_RX_FILTER, EL_WIN_5);    if (END_FLAGS_GET (&pDrvCtrl->endObj) & IFF_ALLMULTI)        {        rxFilt |= EL_RXFILTER_ALLMULTI;        el3c90xCsrWriteWord (pDrv

⌨️ 快捷键说明

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