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

📄 at91emacend.c

📁 VxWorks BSP for AT91RM92
💻 C
📖 第 1 页 / 共 5 页
字号:
#define	EMAC_END_DBG_HASH		    0x0080

#define EMAC_END_DBG_ERR            0x8000

int	at91EmacEndDebug  = EMAC_END_DBG_ERR;

/* interrupt statistics */
int at91EmacEndIntCount = 0; /* amount of interrupts */
int at91EmacEndIntRCOM  = 0; /* Receive Complete statistics */
int at91EmacEndIntTCOM  = 0; /* Transmit Complete statistics */
int at91EmacEndIntTUND  = 0; /* Tx Buffer underrun statistics */
int at91EmacEndIntRTRY  = 0; /* Transmit Retry limit statistics */
int at91EmacEndIntRBNA  = 0; /* Bufffer Not Avalaible statistics */
int at91EmacEndIntROVR  = 0; /* RX overrun statistics */

/* send/receive stats */
int at91EmacEndNumSend = 0;  /* Number of packet sent */
int at91EmacEndNumRecv = 0;  /* Number of packet received */

int at91EmacEndNumTXRetry = 0; /* number of packet not queued in the driver */

/* watermarks */
int at91EmacEndMaxLoopRecv = 0; /* watermarks in receive loop (at91EmacEndHandleRcvInt()) */

#define EMAC_END_LOG(FLG, X0, X1, X2, X3, X4, X5, X6)                  \
	if (at91EmacEndDebug & FLG)                                        \
            logMsg(X0, X1, X2, X3, X4, X5, X6);

#define EMAC_END_LOG_DELAY(FLG)                  \
	if (at91EmacEndDebug & FLG)                  \
            taskDelay(sysClkRateGet()/10);

#define EMAC_END_PRINT(FLG,X)                                                \
	if (at91EmacEndDebug & FLG) printf X;

#else /*EMAC_END_DBG*/

#define EMAC_END_LOG(DBG_SW, X0, X1, X2, X3, X4, X5, X6)
#define EMAC_END_LOG_DELAY(DBG_SW)
#define EMAC_END_PRINT(DBG_SW,X)

#endif /*EMAC_END_DBG*/

/* LOCALS */

/* forward static functions */

LOCAL void	    at91EmacEndReset	     (EMAC_END_DEVICE *pDrvCtrl);
LOCAL void	    at91EmacEndInt	         (EMAC_END_DEVICE *pDrvCtrl);
LOCAL void	    at91EmacEndHandleRcvInt (EMAC_END_DEVICE *pDrvCtrl);
LOCAL STATUS	at91EmacEndRecv	     (EMAC_END_DEVICE *pDrvCtrl, char* pData, int len);
LOCAL void	    at91EmacEndConfig	     (EMAC_END_DEVICE *pDrvCtrl);

/* END Specific interfaces. */


/*
 * Declare our function table.  This is static across all device
 * instances.
 */

LOCAL NET_FUNCS at91EmacEndFuncTable =
    {
    (FUNCPTR) at91EmacEndStart,		/* Function to start the device. */
    (FUNCPTR) at91EmacEndStop,		    /* Function to stop the device. */
    (FUNCPTR) at91EmacEndUnload,		/* Unloading function for the driver. */
    (FUNCPTR) at91EmacEndIoctl,		/* Ioctl function for the driver. */
    (FUNCPTR) at91EmacEndSend,		    /* Send function for the driver. */
    (FUNCPTR) at91EmacEndMCastAdd,		/* Multicast add function for the driver. */
    (FUNCPTR) at91EmacEndMCastDel,		/* Multicast delete function for the driver. */
    (FUNCPTR) at91EmacEndMCastGet,		/* Multicast retrieve function for the driver. */
    (FUNCPTR) at91EmacEndPollSend,		/* Polling send function */
    (FUNCPTR) at91EmacEndPollRcv,		/* Polling receive function */
    endEtherAddressForm,		/* put address info into a NET_BUFFER */
    endEtherPacketDataGet,	 	/* get pointer to data in NET_BUFFER */
    endEtherPacketAddrGet  		/* Get packet addresses. */
    };

/*******************************************************************************
*
* at91EmacEndLoad - 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 the initString.
*
* The string contains the target specific parameters like this:
*
* "register 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 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 empty.
*/

END_OBJ* at91EmacEndLoad
    (
    char* initString		/* String to be parsed by the driver. */
    )
    {
    EMAC_END_DEVICE 	*pDrvCtrl;

    EMAC_END_LOG (EMAC_END_DBG_LOAD, "Loading at91EmacEnd...\n", 1, 2, 3, 4, 5, 6);

    if (initString == NULL)
        {
        EMAC_END_LOG (EMAC_END_DBG_LOAD, "at91EmacEndLoad: NULL initStr\r\n",
		0,0,0,0,0,0);
        return NULL;
        }
    
    if (initString[0] == EOS)
        {
        bcopy ((char *)EMAC_END_DEV_NAME, initString, EMAC_END_DEV_LEN);
        return NULL;
        }

    /* else initString is not blank, pass two ... */

    /* allocate the device structure */

    pDrvCtrl = (EMAC_END_DEVICE *)calloc (sizeof (EMAC_END_DEVICE), 1);

    if (pDrvCtrl == NULL)
        {
        goto errorExit;
        }

    /* parse the init string, filling in the device structure */

    if (at91EmacEndParse (pDrvCtrl, initString) == ERROR)
        {
        goto errorExit;
        }
    
    /* reset the device (ensure that the device is not enable when alloacting memory */
    
    at91EmacEndReset (pDrvCtrl);
    
    /* Perform memory allocation/distribution */
    
    if (at91EmacEndMemInit (pDrvCtrl) == ERROR)
        {
        goto errorExit;
        }

    /* Ask the BSP for the ethernet address. */
    
    SYS_ENET_ADDR_GET(pDrvCtrl);

	/* set the MAC address - must write the low first */
	
    EMAC_REG(EMAC_SA1L) = (pDrvCtrl->enetAddr[3] << 24) |
                          (pDrvCtrl->enetAddr[2] << 16) |
                          (pDrvCtrl->enetAddr[1] << 8)  |
                           pDrvCtrl->enetAddr[0];
	EMAC_REG(EMAC_SA1H) = (pDrvCtrl->enetAddr[5] << 8) | pDrvCtrl->enetAddr[4];

    /* initialize the END and MIB2 parts of the structure */

    if (END_OBJ_INIT (&pDrvCtrl->end, NULL, EMAC_END_DEV_NAME,
                      pDrvCtrl->unit, &at91EmacEndFuncTable,
                      "END AT91RM9200 EMAC Driver.") == ERROR
     || END_MIB_INIT (&pDrvCtrl->end, M2_ifType_ethernet_csmacd,
                      &pDrvCtrl->enetAddr[0], 6, ETHERMTU,
                      END_SPEED)
		    == ERROR)
        {
        goto errorExit;
        }

    /* reconfigure the device */
    
    at91EmacEndConfig (pDrvCtrl);

    /* set the flags to indicate readiness */

    END_OBJ_READY (&pDrvCtrl->end,
		    IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST);

    EMAC_END_LOG (EMAC_END_DBG_LOAD, "Done loading EMAC...", 1, 2, 3, 4, 5, 6);

    EMAC_END_LOG_DELAY(EMAC_END_DBG_LOAD);

    return (&pDrvCtrl->end);

errorExit:
    if (pDrvCtrl != NULL)
        {
        free ((char *)pDrvCtrl);
        }

    return NULL;
    }

/*******************************************************************************
*
* at91EmacEndParse - parse the init string
*
* Parse the input string.  Fill in values in the driver control structure.
*
* The muxLib.o module automatically prepends the unit number to the user's
* initialization string from the BSP (configNet.h).
*
* .IP <unit>
* Device unit number, a small integer.
* .IP <vecNum>
* Interrupt vector number
* .IP <intLvl>
* Interrupt level
* .IP <txNum>
* TX buffers
* .IP <rxNum>
* RX buffers
* .IP <userFlag>
* user flags
* .LP
*
* RETURNS: OK or ERROR for invalid arguments.
*/

LOCAL STATUS at91EmacEndParse
    (
    EMAC_END_DEVICE *   pDrvCtrl,	    /* device pointer */
    char *              initString		/* information string */
    )
    {
    char*	tok;
    char*	pHolder = NULL;

    /* Parse the initString */
    
    /* Unit number. (from muxLib.o) */

    tok = strtok_r (initString, ":", &pHolder);

    if (tok == NULL)
        return ERROR;

    pDrvCtrl->unit = atoi (tok);

    /* 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;
    
    /* Transmit buffer descriptor */

    pDrvCtrl->ilevel = atoi (tok);

    tok = strtok_r (NULL, ":", &pHolder);
    if (tok == NULL)
        return ERROR;
    
    pDrvCtrl->txNum = atoi (tok);

    /* Receive buffer descriptor */
    
    tok = strtok_r (NULL, ":", &pHolder);
    
    if (tok == NULL)
        return ERROR;
    
    pDrvCtrl->rxNum = atoi (tok);

    /* user flags. */

    tok = strtok_r (NULL, ":", &pHolder);
    
    if (tok == NULL)
        return ERROR;
    
    pDrvCtrl->flags = strtoul (tok, NULL, 16);


    if (!pDrvCtrl->txNum
        || pDrvCtrl->txNum < EMAC_END_TX_MIN || pDrvCtrl->txNum > EMAC_END_TX_MAX)
    	{
    	pDrvCtrl->txNum = EMAC_END_TX_DEF_NUM;
    	}

    if (!pDrvCtrl->rxNum
        || pDrvCtrl->rxNum < EMAC_END_RX_MIN || pDrvCtrl->rxNum > EMAC_END_RX_MAX)
    	{
    	pDrvCtrl->rxNum = EMAC_END_RX_DEF_NUM;
    	}

#ifdef EMAC_RX_BUFFER_IN_SRAM
    /*
     * use internal SRAM for RX buffers and descriptors
     * ensures that the receive descriptors start on a 64byte boundary
     * (errata #11)
     */
    
    pDrvCtrl->rxNum = NUM_RXBDS;
#endif /* EMAC_RX_BUFFER_IN_SRAM */

    EMAC_END_LOG (EMAC_END_DBG_LOAD,
                  ("at91EmacEndParse: unit=%d ivec=%d ilevel=%d txNum=%d rxNum=%d userFlags=0x%x\n"),
                  pDrvCtrl->unit,
                  pDrvCtrl->ivec,
                  pDrvCtrl->ilevel,
                  pDrvCtrl->txNum,
                  pDrvCtrl->rxNum,
                  pDrvCtrl->flags);


    EMAC_END_LOG (EMAC_END_DBG_LOAD, "at91EmacEndParse: Processed all arugments\n", 1, 2, 3, 4, 5, 6);

    return OK;
    }

/*******************************************************************************
*
* at91EmacEndMemInit - initialize memory for the chip
*
* This routine is highly specific to the device.
*
* RETURNS: OK or ERROR.
*/

LOCAL STATUS at91EmacEndMemInit
    (
    EMAC_END_DEVICE * pDrvCtrl	/* device to be initialized */
    )
    {
    int i;

    if ((pDrvCtrl->end.pNetPool = malloc (sizeof(NET_POOL))) == NULL)
        {
        EMAC_END_LOG (EMAC_END_DBG_LOAD, "at91EmacEndMemInit: Could not allocate pNetPool\n", 1, 2, 3, 4, 5, 6);
        return (ERROR);
        }

    /* number of driver Descriptor/data buffers */
    at91EmacEndClDescTbl[0].clNum = pDrvCtrl->rxNum + EMAC_END_LOAN_NUM;

    /* Setup mbuf/cluster block pool with more mbufs than clBlks */
    at91EmacEndMclBlkConfig.clBlkNum = at91EmacEndClDescTbl[0].clNum;
    at91EmacEndMclBlkConfig.mBlkNum  = at91EmacEndMclBlkConfig.clBlkNum * 4;

    /* Calculate the total memory for all the M-Blks and CL-Blks. */
    at91EmacEndMclBlkConfig.memSize = (at91EmacEndMclBlkConfig.mBlkNum *
                                    (MSIZE + sizeof (long))) +
                                    (at91EmacEndMclBlkConfig.clBlkNum *
                                    (CL_BLK_SZ + sizeof(long)));

    /* allocate mbuf/Cluster blocks from normal memory */
    if ((at91EmacEndMclBlkConfig.memArea = (char *) memalign (sizeof(long), at91EmacEndMclBlkConfig.memSize)) == NULL)
        {
        EMAC_END_LOG (EMAC_END_DBG_LOAD, "at91EmacEndMemInit: Could not allocate memArea\n", 1, 2, 3, 4, 5, 6);
        return (ERROR);
        }

    /* Round cluster size up to a multiple of a cache line */
    at91EmacEndClDescTbl[0].clSize = ROUND_UP(at91EmacEndClDescTbl[0].clSize,_CACHE_ALIGN_SIZE);

    /* Calculate the memory size of all the clusters (including overhead). */
    at91EmacEndClDescTbl[0].memSize = (at91EmacEndClDescTbl[0].clNum
				    * (at91EmacEndClDescTbl[0].clSize + CL_OVERHEAD));

    /* Allocate the memory for the clusters from cache safe memory. */
    at91EmacEndClDescTbl[0].memArea = (char *) cacheDmaMalloc (at91EmacEndClDescTbl[0].memSize);

    /* cacheDmaMalloc memory is assumed to be cache line aligned ! */

    /* use cacheDmaFuncs for cacheDmaMalloc memory */

    pDrvCtrl->pCacheFuncs = &cacheDmaFuncs;

    if (at91EmacEndClDescTbl[0].memArea == NULL)
        {
        EMAC_END_LOG (EMAC_END_DBG_LOAD, "at91EmacEndMemInit: system memory unavailable\n", 1, 2, 3, 4, 5, 6);
        return (ERROR);
        }

    /* Initialize the memory pool. */
    if (netPoolInit(pDrvCtrl->end.pNetPool, &at91EmacEndMclBlkConfig,
                    &at91EmacEndClDescTbl[0], at91EmacEndClDescTblNumEnt, NULL) == ERROR)
        {
        EMAC_END_LOG (EMAC_END_DBG_LOAD, "at91EmacEndMemInit: Could not init buffering\n", 1, 2, 3, 4, 5, 6);
        return (ERROR);
        }

    if ((pDrvCtrl->pClPoolId = netClPoolIdGet (pDrvCtrl->end.pNetPool, EMAC_END_MAX_CL_LEN, FALSE)) == NULL)
        {
        EMAC_END_LOG (EMAC_END_DBG_LOAD, "at91EmacEndMemInit: Could not get cluster pool ID\n", 1, 2, 3, 4, 5, 6);
        return (ERROR);
        }
    
    /*
     * Tx buffer and descriptors (virtual descriptor for queuing send request)
     */

⌨️ 快捷键说明

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