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

📄 ln7990end.c

📁 7990驱动编程
💻 C
📖 第 1 页 / 共 5 页
字号:
#define	DRV_DEBUG_TX		0x0002#define DRV_DEBUG_INT		0x0004#define	DRV_DEBUG_POLL		(DRV_DEBUG_POLL_RX | DRV_DEBUG_POLL_TX)#define	DRV_DEBUG_POLL_RX	0x0008#define	DRV_DEBUG_POLL_TX	0x0010#define	DRV_DEBUG_LOAD		0x0020#define	DRV_DEBUG_IOCTL		0x0040#define DRV_DEBUG_POLL_REDIR	0x10000#define	DRV_DEBUG_LOG_NVRAM	0x20000#ifdef LOCAL#undef LOCAL#endif /* LOCAL */#define LOCAL ;int	ln7990Debug = DRV_DEBUG_OFF; /* Turn it off initially. */#include "nvLogLib.h"NET_POOL ln7990NetPool;#define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6)                        \	if ((ln7990Debug & FLG)&&(FLG & DRV_DEBUG_POLL))                \            nvLogMsg(X0, X1, X2, X3, X4, X5, X6);                       \        else if (ln7990Debug & FLG)                                     \            logMsg(X0, X1, X2, X3, X4, X5, X6);#define DRV_PRINT(FLG,X)                                                \	if (ln7990Debug & FLG) printf X;#else /*DRV_DEBUG*/#define DRV_LOG(DBG_SW, X0, X1, X2, X3, X4, X5, X6)#define DRV_PRINT(DBG_SW,X)#endif /*DRV_DEBUG*//***** LOCALS *****/LOCAL int lnTsize = LN_TMD_TLEN;    /* deflt xmit ring size as power of 2 */LOCAL int lnRsize = LN_RMD_RLEN;    /* deflt recv ring size as power of 2 */LOCAL BOOL lnKickStartTx = LN_KICKSTART_TX;/* forward static functions */LOCAL void	ln7990Reset (LN7990END_DEVICE *pDrvCtrl);LOCAL void	ln7990Int (LN7990END_DEVICE *pDrvCtrl);LOCAL void	ln7990HandleRecvInt (LN7990END_DEVICE *pDrvCtrl);LOCAL STATUS	ln7990Recv (LN7990END_DEVICE *pDrvCtrl, ln_rmd *rmd);LOCAL ln_rmd *	ln7990FullRMDGet (LN7990END_DEVICE *pDrvCtrl);LOCAL u_short	ln7990Csr0Read (LN7990END_DEVICE * pDrvCtrl);LOCAL void	ln7990CsrWrite (LN7990END_DEVICE * pDrvCtrl, int reg,				u_short value);LOCAL void	ln7990Restart (LN7990END_DEVICE *pDrvCtrl);LOCAL STATUS 	ln7990RestartSetup (LN7990END_DEVICE *pDrvCtrl);LOCAL void	ln7990Config (LN7990END_DEVICE *pDrvCtrl);LOCAL void	ln7990AddrFilterSet (LN7990END_DEVICE *pDrvCtrl);LOCAL void	ln7990ScrubTRing (LN7990END_DEVICE* pDrvCtrl);LOCAL void      ln7990HandleError (LN7990END_DEVICE  *pDrvCtrl);/* END Specific interfaces. *//* This is the only externally visible interface. */END_OBJ* 	ln7990EndLoad (char* initString);LOCAL STATUS	ln7990Start (LN7990END_DEVICE* pDrvCtrl);LOCAL STATUS	ln7990Stop (LN7990END_DEVICE* pDrvCtrl);LOCAL STATUS	ln7990Unload (LN7990END_DEVICE* pDrvCtrl);LOCAL int	ln7990Ioctl (LN7990END_DEVICE* pDrvCtrl, int cmd, caddr_t data);LOCAL STATUS	ln7990Send (LN7990END_DEVICE* pDrvCtrl, M_BLK_ID pBuf);			  LOCAL STATUS	ln7990MCastAddrAdd (LN7990END_DEVICE* pDrvCtrl, char* pAddress);LOCAL STATUS	ln7990MCastAddrDel (LN7990END_DEVICE* pDrvCtrl, char* pAddress);LOCAL STATUS	ln7990MCastAddrGet (LN7990END_DEVICE* pDrvCtrl,				    MULTI_TABLE* pTable);LOCAL STATUS	ln7990PollSend (LN7990END_DEVICE* pDrvCtrl, M_BLK_ID pBuf);LOCAL STATUS	ln7990PollReceive (LN7990END_DEVICE* pDrvCtrl, M_BLK_ID pBuf);LOCAL STATUS	ln7990PollStart (LN7990END_DEVICE* pDrvCtrl);LOCAL STATUS	ln7990PollStop (LN7990END_DEVICE* pDrvCtrl);LOCAL STATUS	ln7990InitParse ();LOCAL STATUS	ln7990InitMem ();/* * Declare our function table.  This is static across all driver * instances. */LOCAL NET_FUNCS lnFuncTable =    {    (FUNCPTR)ln7990Start,	/* Function to start the device. */    (FUNCPTR)ln7990Stop,	/* Function to stop the device. */    (FUNCPTR)ln7990Unload,	/* Unloading function for the driver. */    (FUNCPTR)ln7990Ioctl,	/* Ioctl function for the driver. */    (FUNCPTR)ln7990Send,	/* Send function for the driver. */    (FUNCPTR)ln7990MCastAddrAdd,/* Multicast address add */    (FUNCPTR)ln7990MCastAddrDel,/* Multicast address delete */    (FUNCPTR)ln7990MCastAddrGet,/* Multicast table retrieve */    (FUNCPTR)ln7990PollSend,	/* Polling send function for the driver. */    (FUNCPTR)ln7990PollReceive,	/* Polling receive function for the driver. */    endEtherAddressForm,        /* Put address info into a packet.  */    endEtherPacketDataGet,      /* Get a pointer to packet data. */    endEtherPacketAddrGet       /* Get packet addresses. */    };/* external IMPORT's */#ifndef END_MACROSIMPORT int endMultiLstCnt (END_OBJ *);#endif/******************************************************************************** ln7990EndLoad - initialize the driver and device** This routine initializes the driver and the device to the operational state.* All of the device-specific parameters are passed in <initString>, which* expects a string of the following format:** <unit>:<CSR_reg_addr>:<RAP_reg_addr>:<int_vector>:<int_level>:<shmem_addr>:* <shmem_size>:<shmem_width>** This routine can be called in two modes. If it is called with an empty but* allocated string, it places the name of this device (that is, "ln") into * the <initString> and returns 0.** If the string is allocated and not empty, the routine attempts to load* the driver using the values specified in the string.** RETURNS: An END object pointer, or NULL on error, or 0 and the name of the* device if the <initString> was NULL.*/END_OBJ* ln7990EndLoad    (    char* initString		/* string to be parse by the driver */    )    {    LN7990END_DEVICE 	*pDrvCtrl;    DRV_LOG (DRV_DEBUG_LOAD, "Loading ln...\n", 1, 2, 3, 4, 5, 6);    if (initString == NULL)        return (NULL);        if (initString[0] == NULL)        {        bcopy((char *)LN_DEV_NAME, initString, LN_DEV_NAME_LEN);        return (0);        }        /* allocate the device structure */    pDrvCtrl = (LN7990END_DEVICE *)calloc (sizeof (LN7990END_DEVICE), 1);    if (pDrvCtrl == NULL)	goto errorExit;    /* parse the init string, filling in the device structure */    if (ln7990InitParse (pDrvCtrl, initString) == ERROR)	goto errorExit;    /* Have the BSP hand us our address. */    SYS_ENET_ADDR_GET(&(pDrvCtrl->enetAddr));    /* initialize the END and MIB2 parts of the structure */    if (END_OBJ_INIT (&pDrvCtrl->end, (DEV_OBJ *)pDrvCtrl, LN_DEV_NAME,		    pDrvCtrl->unit, &lnFuncTable,                      "AMD 7990 Lance Enhanced Network Driver") == ERROR     || END_MIB_INIT (&pDrvCtrl->end, M2_ifType_ethernet_csmacd,                      &pDrvCtrl->enetAddr[0], 6, ETHERMTU,                      LN_SPEED)		    == ERROR)	goto errorExit;    /* Perform memory allocation */    if (ln7990InitMem (pDrvCtrl) == ERROR)	goto errorExit;    /* Perform memory distribution and reset and reconfigure the device */    if (ln7990RestartSetup (pDrvCtrl) == ERROR)        goto errorExit;    /* set the flags to indicate readiness */    END_OBJ_READY (&pDrvCtrl->end,		    IFF_UP | IFF_RUNNING | IFF_NOTRAILERS | IFF_BROADCAST		    | IFF_MULTICAST | IFF_SIMPLEX);        DRV_LOG (DRV_DEBUG_LOAD, "Done loading ln7990...\n", 1, 2, 3, 4, 5, 6);    return (&pDrvCtrl->end);errorExit:    if (pDrvCtrl != NULL)	free ((char *)pDrvCtrl);    return NULL;    }/********************************************************************************* ln7990InitParse - parse the initialization string** Parse the input string.  Fill in values in the driver control structure.* The initialization string format is:* <unit>:<csrAdr>:<rapAdr>:<vecnum>:<intLvl>:<memAdrs>:<memSize>:<memWidth>:* <offset>:<csr3B>** .IP <unit>* Device unit number, a small integer.* .IP <csrAdr>* Address of CSR0 register.* .IP <rapAdr>* Address of RAP register.* .IP <vecNum>* Interrupt vector number (used with sysIntConnect() ).* .IP <intLvl>* Interrupt level.* .IP <memAdrs>* Memory pool address or NONE.* .IP <memSize>* Memory pool size or zero.* .IP <memWidth>* Memory system size, 1, 2, or 4 bytes (optional).* .IP <offset>* Memory offset for alignment.* .IP <csr3B>* CSR register 3B control value, normally 0x4 or 0x7.** RETURNS: OK, or ERROR if any arguments are invalid.*/STATUS ln7990InitParse    (    LN7990END_DEVICE * pDrvCtrl,    char * initString    )    {    char *	tok;    char *	pHolder = NULL;    long	address;        /* Parse the initString */    /* Unit number. */    tok = strtok_r (initString, ":", &pHolder);    if (tok == NULL)	return ERROR;    pDrvCtrl->unit = atoi (tok);    /* CSR address. */        tok = strtok_r (NULL, ":", &pHolder);    if (tok == NULL)	return ERROR;    address = strtoul (tok, NULL, 16);    pDrvCtrl->pCsr = (UINT16 *)address;    /* RAP address. */    tok = strtok_r (NULL, ":", &pHolder);    if (tok == NULL)	return ERROR;    address = strtoul (tok, NULL, 16);    pDrvCtrl->pRap = (UINT16 *)address;    /* Interrupt vector. */    tok = strtok_r (NULL, ":", &pHolder);    if (tok == NULL)	return ERROR;    pDrvCtrl->ivec = atoi (tok);    /* Interrupt level. */    tok = strtok_r (NULL, ":", &pHolder);    if (tok == NULL)	return ERROR;    pDrvCtrl->ilevel = atoi (tok);    /* Caller supplied memory address. */    tok = strtok_r (NULL, ":", &pHolder);    if (tok == NULL)	return ERROR;    pDrvCtrl->memAdrs = (char *)strtoul (tok, NULL, 16);    /* Caller supplied memory size. */    tok = strtok_r (NULL, ":", &pHolder);    if (tok == NULL)	return ERROR;    pDrvCtrl->memSize = strtoul (tok, NULL, 16);    /* Caller supplied memory width. */    tok = strtok_r (NULL, ":", &pHolder);    if (tok == NULL)	return ERROR;    pDrvCtrl->memWidth = atoi (tok);    /* Caller supplied alignment offset. */    tok = strtok_r (NULL, ":", &pHolder);    if (tok == NULL)	return ERROR;    pDrvCtrl->offset = atoi (tok);    /* Do we use csr3B? */    tok = strtok_r (NULL, ":", &pHolder);    if (tok == NULL)	return ERROR;    pDrvCtrl->csr3B = atoi (tok);    DRV_LOG (DRV_DEBUG_LOAD, "Processed all arugments\n", 1, 2, 3, 4, 5, 6);    return OK;    }/********************************************************************************* ln7990InitMem - initialize memory for Lance chip** Using data in the control structure, setup and initialize the memory* areas needed.  If the memory address is not already specified, then allocate* cache safe memory.** RETURNS: OK or ERROR.*/STATUS ln7990InitMem    (    LN7990END_DEVICE * pDrvCtrl	/* device to be initialized */    )    {    UINT	sz;           	/* temporary size holder */    int 	ix;    ln_rmd * 	pRmd;    void * 	pTemp;    char* 	pTempBuf;    /***** Establish size of shared memory region we require *****/    if ((int) pDrvCtrl->memAdrs != NONE)  /* specified memory pool */        {        /*         * With a specified memory pool we want to maximize         * lnRsize and lnTsize         */        sz = (pDrvCtrl->memSize - (RMD_SIZ + TMD_SIZ + sizeof (ln_ib)))               / ((2 * LN_BUFSIZ) + RMD_SIZ + TMD_SIZ);        sz >>= 1;               /* adjust for roundoff */        for (lnRsize = 0; sz != 0; lnRsize++, sz >>= 1)            ;        lnTsize = lnRsize;      /* lnTsize = lnRsize for convenience */        }    /* limit ring sizes to reasonable values */    lnRsize = max (lnRsize, 2);		/* 4 Rx buffers is reasonable min */    lnRsize = min (lnRsize, 7);		/* 128 Rx buffers is max for chip */    lnTsize = max (lnTsize, 2);		/* 4 Tx buffers is reasonable min */    lnTsize = min (lnTsize, 7);		/* 128 Tx buffers is max for chip */    /* Add it all up */    sz = (((1 << lnRsize) + 1) * RMD_SIZ) +        (((1 << lnTsize) + 1) * TMD_SIZ) +  IB_SIZ + 24;    /***** Establish a region of shared memory *****/    /* OK. We now know how much shared memory we need.  If the caller     * provides a specific memory region, we check to see if the provided     * region is large enough for our needs.  If the caller did not     * provide a specific region, then we attempt to allocate the memory     * from the system, using the cache aware allocation system call.     */    switch ((int) pDrvCtrl->memAdrs)        {        default :       /* caller provided memory */            if (pDrvCtrl->memSize < sz)     /* not enough space */                {		DRV_LOG (DRV_DEBUG_LOAD, "ln7990: not enough memory provided\n"                         "ln7990: need %ul got %d\n",                         pDrvCtrl->memSize, sz, 3, 4, 5, 6);                return (NULL);                }	    /* set the beginning of pool */            pDrvCtrl->pShMem = pDrvCtrl->memAdrs;            /* 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);            break;        case NONE :     /* get our own memory */            /* Because the structures that are shared between the device             * and the driver may share cache lines, the possibility exists             * that the driver could flush a cache line for a structure and             * wipe out an asynchronous change by the device to a neighboring             * structure. Therefore, this driver cannot operate with memory             * that is not write coherent.  We check for the availability of             * such memory here, and abort if the system did not give us what             * we need.             */            if (!CACHE_DMA_IS_WRITE_COHERENT ())                {                printf ("ln: device requires cache coherent memory\n");                return (ERROR);                }            pDrvCtrl->pShMem = (char *) cacheDmaMalloc (sz);            if ((int)pDrvCtrl->pShMem == NULL)                {                printf ("ln: system memory unavailable\n");                return (ERROR);                }            /* copy the DMA structure */            pDrvCtrl->cacheFuncs = cacheDmaFuncs;

⌨️ 快捷键说明

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