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

📄 el3c90xend.c

📁 3C90X驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
** RETURNS: OK or ERROR**/LOCAL STATUS el3c90xStart    (    void * pEnd	/* device to be started */    )    {    STATUS 		result;    EL3C90X_DEVICE * 	pDrvCtrl;    int			flags;    VOID_TO_DRVCTRL (pEnd, pDrvCtrl);        pDrvCtrl->txBlocked  = FALSE;    /* perform all initialization memory, ring buffer etc */        el3c90xInit(pDrvCtrl);        flags = END_FLAGS_GET (&pDrvCtrl->endObj);    flags |= IFF_RUNNING;    END_FLAGS_SET (&pDrvCtrl->endObj, flags);        SYS_INT_CONNECT (pDrvCtrl, el3c90xInt, (int)pDrvCtrl, &result);    if (result == ERROR)	return ERROR;    ENDLOGMSG (("Interrupt connected.\n", 1, 2, 3, 4, 5, 6));    SYS_INT_ENABLE (pDrvCtrl);    ENDLOGMSG (("interrupt enabled.\n", 1, 2, 3, 4, 5, 6));    return (OK);    }/********************************************************************************* el3c90xStop - stop the device** This function calls BSP functions to disconnect interrupts and stop* the device from operating in interrupt mode.** RETURNS: OK or ERROR.*/LOCAL STATUS el3c90xStop    (    void * pEnd	/* device to be stopped */    )    {    STATUS 		result = OK;    EL3C90X_DEVICE * 	pDrvCtrl;    VOID_TO_DRVCTRL (pEnd, pDrvCtrl);    END_FLAGS_CLR (&pDrvCtrl->endObj, IFF_UP | IFF_RUNNING);    el3c90xDevStop (pDrvCtrl);    SYS_INT_DISCONNECT (pDrvCtrl, el3c90xInt, (int)pDrvCtrl, &result);    if (result == ERROR)	{	ENDLOGMSG (("Could not diconnect interrupt!\n", 1, 2, 3, 4, 5, 6));	}    SYS_INT_DISABLE (pDrvCtrl);    return (result);    }/******************************************************************************** el3c90xUnload - unload a driver from the system** This function first brings down the device, and then frees any* stuff that was allocated by the driver in the load function.** RETURNS: OK or ERROR.*/LOCAL STATUS el3c90xUnload    (    void * pEnd		/* device to be unloaded */    )    {    EL3C90X_DEVICE * pDrvCtrl;    VOID_TO_DRVCTRL (pEnd, pDrvCtrl);        END_OBJECT_UNLOAD (&pDrvCtrl->endObj);    /* Free the shared DMA memory. */    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 clusters */        if (pDrvCtrl->clDesc.memArea != NULL)            cacheDmaFree (pDrvCtrl->clDesc.memArea);        /* Free the memory allocated for mBlks and clBlks */        if (pDrvCtrl->mClCfg.memArea != NULL)            free (pDrvCtrl->mClCfg.memArea);        }    if (pDrvCtrl->endObj.pNetPool != NULL)        free (pDrvCtrl->endObj.pNetPool);        return (OK);    }/********************************************************************************* el3c90xIoctl - the driver I/O control routine** Process an ioctl request.** RETURNS: A command specific response, OK or ERROR or EINVAL.*/LOCAL int el3c90xIoctl    (    void * 	pEnd,           /* device  ptr*/    int 	cmd,		/* ioctl command code */    caddr_t 	data		/* command argument */    )    {    int 		error = 0;    long 		value;    EL3C90X_DEVICE * 	pDrvCtrl;    VOID_TO_DRVCTRL (pEnd, pDrvCtrl);    switch (cmd)        {        case EIOCSADDR:	    if (data == NULL)		return (EINVAL);            bcopy ((char *)data, (char *)END_HADDR(&pDrvCtrl->endObj),		   END_HADDR_LEN(&pDrvCtrl->endObj));            break;        case EIOCGADDR:	    if (data == NULL)		return (EINVAL);            bcopy ((char *)END_HADDR(&pDrvCtrl->endObj), (char *)data,		    END_HADDR_LEN(&pDrvCtrl->endObj));            break;        case EIOCSFLAGS:	    value = (long)data;	    if (value < 0)		{		value = -(--value);		END_FLAGS_CLR (&pDrvCtrl->endObj, value);		}	    else		{		END_FLAGS_SET (&pDrvCtrl->endObj, value);		}            if (END_FLAGS_GET(&pDrvCtrl->endObj) & IFF_UP)                {                el3c90xInit (pDrvCtrl);		}            else                {                if (END_FLAGS_GET(&pDrvCtrl->endObj) & IFF_RUNNING)                    el3c90xDevStop (pDrvCtrl);		}            error = 0;            break;        case EIOCGFLAGS:	    *(int *)data = END_FLAGS_GET(&pDrvCtrl->endObj);            break;	case EIOCPOLLSTART:	    error = el3c90xPollStart(pDrvCtrl);	    break; 	case EIOCPOLLSTOP:	    error = el3c90xPollStop(pDrvCtrl); 	    break;        case EIOCGMIB2:            if (data == NULL)                return (EINVAL);            bcopy((char *)&pDrvCtrl->endObj.mib2Tbl, (char *)data,                  sizeof(pDrvCtrl->endObj.mib2Tbl));            break;        case EIOCGFBUF:            if (data == NULL)                return (EINVAL);            *(int *)data = EL_MIN_FBUF;            break;        case EIOCGMWIDTH:            if (data == NULL)                return (EINVAL);            break;        case EIOCGHDRLEN:            if (data == NULL)                return (EINVAL);            *(int *)data = EH_SIZE;            break;        default:            error = EINVAL;        }    return (error);    }/********************************************************************************* el3c90xSend - 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.** RETURNS: OK or END_ERR_BLOCK or ERROR.*/LOCAL STATUS el3c90xSend    (    void  * 		pEnd,	/* device ptr */    M_BLK_ID 		pMblk	/* data to send */    )    {    EL3C90X_DEVICE * 	pDrvCtrl;    EL_DESC_CHAIN *	pTxChain = NULL;    VOID_TO_DRVCTRL (pEnd, pDrvCtrl);    /* return if in polled mode */        if (pDrvCtrl->flags & EL_POLLING)        return (ERROR);    DRV_LOG (DRV_DEBUG_TX, "Send\n", 1, 2, 3, 4, 5, 6);    END_TX_SEM_TAKE (&pDrvCtrl->endObj, WAIT_FOREVER);    /* get a free download descriptor */        if ((pTxChain = el3c90xDndGet (pDrvCtrl)) == NULL)        {        DRV_LOG (DRV_DEBUG_TX, "Out of TMDs!\n", 1, 2, 3, 4, 5, 6);        pDrvCtrl->txBlocked = TRUE;        END_TX_SEM_GIVE (&pDrvCtrl->endObj);        return (END_ERR_BLOCK);        }    /* Pack the data into the descriptor. */    if (el3c90xDndSet(pDrvCtrl, pTxChain, pMblk) == ERROR)        {        netMblkClChainFree (pMblk); /* free the given mBlk chain */        el3c90xDndFree (pDrvCtrl, pTxChain);        END_TX_SEM_GIVE (&pDrvCtrl->endObj);        return (ERROR);        }    /* set the interrupt bit for the downloaded packet */    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);        }    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))        ;    netMblkClChainFree (pTxChain->pMblk);    el3c90xDndFree (pDrvCtrl, pTxChain);    DRV_LOG (DRV_DEBUG_POLL_TX, "PTX e\n", 1, 2, 3, 4, 5, 6);

⌨️ 快捷键说明

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