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

📄 el3c90xend.c

📁 3C90X驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    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;    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);    /* Set the RX early threshold */    el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND,                         (EL_CMD_RX_SET_THRESH | (EL3C90X_BUFSIZ >>2)), NONE);    el3c90xCsrWriteWord (pDrvCtrl, EL_DMACTL, EL_DMACTL_UP_RX_EARLY, NONE);    /* Enable receiver and transmitter. */    el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_RX_ENABLE, NONE);    el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_TX_ENABLE, NONE);    /* Restore state of BMCR */    if (pDrvCtrl->pPhyDevType != NULL)        el3c90xPhyRegWrite(pDrvCtrl, PHY_BMCR, phyBMCR);    return;    }/********************************************************************************* el3c90xMemInit - initialize memory for the device** This function initiailizes memory for the device** RETURNS: OK or ERROR**/LOCAL STATUS el3c90xMemInit    (    EL3C90X_DEVICE * 	pDrvCtrl	/* device to be initialized */    )    {    int			memSize = 0;    memSize += (sizeof(EL_DESC_BLK) + 16);    if (pDrvCtrl->bufMtplr == NONE)        pDrvCtrl->bufMtplr = 2;    else if (pDrvCtrl->bufMtplr <= 0)            printf ( "elPci: invalid buffer multiplier\n");        pDrvCtrl->clDesc.clNum  = (EL_UPD_CNT + EL_DND_CNT) * pDrvCtrl->bufMtplr;    pDrvCtrl->mClCfg.clBlkNum = pDrvCtrl->clDesc.clNum;    pDrvCtrl->mClCfg.mBlkNum  = pDrvCtrl->mClCfg.clBlkNum * 2;    /* total memory size for mBlks and clBlks */        pDrvCtrl->mClCfg.memSize =        (pDrvCtrl->mClCfg.mBlkNum  *  (MSIZE + sizeof (long))) +        (pDrvCtrl->mClCfg.clBlkNum * (CL_BLK_SZ + sizeof (long)));    memSize += pDrvCtrl->mClCfg.memSize;    /* total memory size for all clusters */    pDrvCtrl->clDesc.clSize  = EL3C90X_BUFSIZ;    pDrvCtrl->clDesc.memSize =        (pDrvCtrl->clDesc.clNum * (pDrvCtrl->clDesc.clSize + 8)) + sizeof(int);    memSize += pDrvCtrl->clDesc.memSize;    if ((int)pDrvCtrl->memAdrs != NONE)        {        /* check if the give memory size if enough */        if (pDrvCtrl->memSize < memSize)            {            printf ( "elPci: memory size too small\n" );            return (ERROR);            }        pDrvCtrl->pDescMem = (char *)pDrvCtrl->memAdrs;        pDrvCtrl->mClCfg.memArea = (char *)((UINT32)(pDrvCtrl->pDescMem) +                                            sizeof(EL_DESC_BLK) + 16);        pDrvCtrl->clDesc.memArea = (pDrvCtrl->mClCfg.memArea +                                    pDrvCtrl->mClCfg.memSize);        /* assume pool is cache coherent, copy null structure */        pDrvCtrl->cacheFuncs = cacheNullFuncs;        DRV_LOG (DRV_DEBUG_LOAD, "Memory checks out\n", 1, 2, 3, 4, 5, 6);        }    else	/* allocate our own memory */        {        pDrvCtrl->flags |= EL_MEM_ALLOC_FLAG;        if (!CACHE_DMA_IS_WRITE_COHERENT ())            {            printf ( "elPci: device requires cache coherent memory\n" );            return (ERROR);            }                /* allocate memory for upload and download descriptors */        pDrvCtrl->pDescMem =            (char *) cacheDmaMalloc (sizeof(EL_DESC_BLK) + 16);        if (pDrvCtrl->pDescMem == NULL)            {            printf ( "elPci: system memory unavailable\n" );            return (ERROR);            }        /* allocate memory for mBlks and clBlks */        if ((pDrvCtrl->mClCfg.memArea =             (char *) memalign (sizeof(long), pDrvCtrl->mClCfg.memSize))            == NULL)            {            printf ( "elPci: system memory unavailable\n" );            goto elMemInitFail;            }        /* allocate memory for clusters */        pDrvCtrl->clDesc.memArea = cacheDmaMalloc (pDrvCtrl->clDesc.memSize);                    if ((int)pDrvCtrl->clDesc.memArea == NULL)            {            printf ( "elPci: system memory unavailable\n" );            goto elMemInitFail;            }        /* copy the DMA structure */        pDrvCtrl->cacheFuncs = cacheDmaFuncs;        }    pDrvCtrl->pDescBlk = (EL_DESC_BLK *)(((int)pDrvCtrl->pDescMem                                                  + 0x0f) & ~0x0f);    bzero ((char*)pDrvCtrl->pDescBlk, sizeof(EL_DESC_BLK));    /* allocate memory for net pool */        if ((pDrvCtrl->endObj.pNetPool = malloc (sizeof(NET_POOL))) == NULL)        {        printf ( "elPci: system memory unavailable\n" );        goto elMemInitFail;        }#ifdef DRV_DEBUG    pElXlPool = pDrvCtrl->endObj.pNetPool;#endif        /* initialize the device net pool */        if (netPoolInit (pDrvCtrl->endObj.pNetPool, &pDrvCtrl->mClCfg,                     &pDrvCtrl->clDesc, 1, NULL) == ERROR)        {        DRV_LOG (DRV_DEBUG_LOAD, "Could not init buffering\n",                 1, 2, 3, 4, 5, 6);        goto elMemInitFail;        }        /* Store the cluster pool id as others need it later. */    pDrvCtrl->pClPoolId = clPoolIdGet (pDrvCtrl->endObj.pNetPool,                                       EL3C90X_BUFSIZ, FALSE);    return (OK);    elMemInitFail:        {        if (pDrvCtrl->flags & EL_MEM_ALLOC_FLAG)            {            /* free the memory allocated for descriptors */                    if (pDrvCtrl->pDescMem != NULL)                cacheDmaFree (pDrvCtrl->pDescMem);            /* Free the memory allocated for mBlks and clBlks */            if (pDrvCtrl->mClCfg.memArea != NULL)                free (pDrvCtrl->mClCfg.memArea);            /* free the memory allocated for clusters */            if (pDrvCtrl->clDesc.memArea != NULL)                cacheDmaFree (pDrvCtrl->clDesc.memArea);            }        if (pDrvCtrl->endObj.pNetPool != NULL)            free (pDrvCtrl->endObj.pNetPool);        return (ERROR);        }    }

⌨️ 快捷键说明

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