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

📄 at91emacend.c

📁 atmel9200 vxworks bsp
💻 C
📖 第 1 页 / 共 4 页
字号:
/* at91End.c - SNDS END network interface driver for Ethernet */

/* Copyright 1984-1997 Wind River Systems, Inc. */
#include "copyright_wrs.h"

/*
modification history
--------------------

*/

/*
DESCRIPTION

*/

/* includes */

#include "vxWorks.h"
#include "etherMultiLib.h"		/* multicast stuff. */
#include "end.h"				/* Common END structures. */
#include "endLib.h"
#include "lstLib.h"				/* Needed to maintain protocol list. */
#include "cacheLib.h"
#include "stdlib.h"
#include "stdio.h"
#include "intLib.h"
#include "iv.h"
#include "netLib.h"
#include "config.h"


#if defined(CPU_920T)
#include "arch/arm/mmuArmLib.h"
#include "private/vmLibP.h"
/*#include "dllLib.h"*/
#endif /* defined(720T/740T/920T/940T/946ES) */


/* defines */

/* Configuration items */
#define ENET_HDR_REAL_SIZ 	14
#define END_BUFSIZ      	( ETHERMTU + ENET_HDR_REAL_SIZ + 8 )
#define END_SPEED        	10000000
#define	AT91END_CL_SIZE		( ETHERMTU + ENET_HDR_REAL_SIZ + 8 )
#define END_MBLK_NUM			256
#define END_CL_NUM				(END_MBLK_NUM/2)


#define	RX_FD_NUM			32
#define	TX_FD_NUM			32

#define LS_POLLING          0x20

#define	AT91EMAC_MAX_MULTI	3

/*
 * Default macro definitions for BSP interface.
 * These macros can be redefined in a wrapper file, to generate
 * a new module with an optimized interface.
 */

/* Macro to connect interrupt handler to vector */



/* Macro to get the ethernet address from the BSP */

unsigned char at91EndEnetAddr[6] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};



#ifndef SYS_ENET_ADDR_GET
#   define SYS_ENET_ADDR_GET(pDevice) \
	{ \
	bcopy ((char *)at91EndEnetAddr, (char *)(&pDevice->enetAddr), 6); \
	}
#endif

/*
 * Macros to do a short (UINT16) access to the chip. Default
 * assumes a normal memory mapped device.
 */

/*A shortcut for getting the hardware address from the MIB II stuff. */

#define END_HADDR(pEnd)	\
		((pEnd)->mib2Tbl.ifPhysAddress.phyAddress)

#define END_HADDR_LEN(pEnd) \
		((pEnd)->mib2Tbl.ifPhysAddress.addrLength)

/* typedefs */

typedef struct _AT91_END_RECV_FD
{
	UINT32 bufaddr;
	UINT32 recvstatus;
}AT91_END_RECV_FD;


struct _AT91_END_TRAN_FD;

typedef struct _AT91_END_TRAN_FD
{
	char* bufaddr;
	UINT32 len;
	UINT32 owner;
}AT91_END_TRAN_FD;

typedef struct etherStatistics
{
	UINT32	 ESTAT_FRA; 	
	UINT32	 ESTAT_SCOL; 
	UINT32	 ESTAT_MCOL; 
	UINT32	 ESTAT_OK; 	
	UINT32	 ESTAT_SEQE; 
	UINT32	 ESTAT_ALE; 	
	UINT32	 ESTAT_DTE; 	
	UINT32	 ESTAT_LCOL; 
	UINT32	 ESTAT_ECOL; 
	UINT32	 ESTAT_CSE; 	
	UINT32	 ESTAT_TUE; 	
	UINT32	 ESTAT_CDE; 	
	UINT32	 ESTAT_ELR; 	
	UINT32	 ESTAT_RJB; 	
	UINT32	 ESTAT_USF; 	
	UINT32	 ESTAT_SQEE; 
	UINT32	 ESTAT_DRFC; 
} ETHER_STATISTICS;

#define  TXFIFOEMPTY	1
#define  TXFIFOFULL		2
#define  TXFIFONORMAL   3


/* The definition of the driver control structure */

/*
 *	for addrListLow and addrListHigh:
 *  ETH addr = E0 E1 E2 E3 E4 E5
 *	addrListLow( in byte address order ) = E3 E2 E1 E0
 *	addrListHigh( in byte address order ) = E5 E4
 *  so we can use htol and htos to convert the ETH address
 */
typedef struct _at91end_device
{
	END_OBJ    	end;			/* The class we inherit from. */
    int			unit;			/* unit number */
	int			level;		/* bdmaTx interrupt vector */
    long		flags;			/* Our local flags. */
	CL_POOL_ID  pClPoolId;
	UCHAR*		clPointBuf[ RX_FD_NUM ];

	UCHAR*		TranFifoBuf;
	UCHAR*		RecvFifoBuf;
	UINT32		TranPkgNumber;
	UINT32		TranPkgSize;
	AT91_END_TRAN_FD pTxBufStart[TX_FD_NUM];
	UINT32 TxPtr;		/* point to desc sending */
	UINT32 TxTailPtr;	/* point to desc may writing */
	UINT32 TXFifoStat;
	UINT32 NetJobDoing;

	AT91_END_RECV_FD* RecvBufDesc;
	UINT32		  rxBufPtr;

    	UCHAR		enetAddr[6];	/* ethernet address */
	UCHAR		netSpeed;		/* 10 or 100 */
	UCHAR		duplexMode;		/* HDX = 0. FDX = 1 */
	UCHAR		autoNeg;		/* 1 = autoneg enabled */
	BOOL		fdInitialized;	/* Set to TRUE after FD allocation */
	ETHER_STATISTICS	statistics;	/* Ethernet statistics counters */
	UINT32	addrListHigh[(AT91EMAC_MAX_MULTI+1)];	/* Array for storing addresses Max = 4, i.e. 32 long words */
	UINT32	addrListLow[(AT91EMAC_MAX_MULTI+1)];	/* Array for storing addresses Max = 4, i.e. 32 long words */
	UINT32	mcastAddrCount;	/* Number of valid multicast addresses */
} at91end_device;


/* globals*/

/*
 * This will only work if there is only a single unit, for multiple
 * unit device drivers these should be integrated into the at91end_device
 * structure.
 */

M_CL_CONFIG at91endMclConfig = 	/* network mbuf configuration table */
    {
    /* 
    no. mBlks		no. clBlks		memArea		memSize
    -----------		----------		-------		-------
    */
    0, 				0, 				NULL, 		0 
    };

CL_DESC at91endClDescTbl [] = 	/* network cluster pool configuration table */
    {
    /* 
    clusterSize		num		memArea		memSize
    -----------		----	-------		-------
    */
    {AT91END_CL_SIZE,	0,		NULL,		0}
    };

int endClDescTblNumEnt = (NELEMENTS(at91endClDescTbl));

/* new additions */


/* Definitions for the flags field */

#define END_PROMISCUOUS_FLAG	0x1
#define END_RCV_HANDLING_FLAG	0x2


/* DEBUG MACROS */

#undef  END_DEBUG
/*
#define END_DEBUG
*/

#ifdef END_DEBUG
#include "LogLib.h"			/* Needed to debug polled mode.  */
int endDebug = 1;
#define ENDLOGMSG(x) \
	if (endDebug) \
	    { \
	    logMsg x;\
	    }
#else
#define ENDLOGMSG(x)
#endif /* END_DEBUG */

/* LOCALS */

#ifdef INCLUDE_AT91EMAC_END

/* forward static functions */

LOCAL void		at91EmacReset			(at91end_device *pDrvCtrl);    /**/
LOCAL void		at91EndInt				(at91end_device *pDrvCtrl);    /**/


LOCAL void 		at91EndMacInitialize	(at91end_device *pDevice);	/**/
LOCAL STATUS	at91EndFdInitialize		(at91end_device *pDrvCrtl); /**/
LOCAL void 		at91EndFdFree			(at91end_device *pDrvCtrl); /**/


LOCAL void		at91EndHandleRcvInt 	(at91end_device *pDrvCtrl, UINT32 stat);/**/
LOCAL STATUS	at91EndRecv				(at91end_device *pDrvCtrl, UINT32 recvdescptr );/**/
LOCAL void		at91EndConfig			(at91end_device *pDrvCtrl);/**/
LOCAL UINT32	at91EndPhyRead 			(UINT32 phyRegAddr, UINT32 phyAddr);/**/
LOCAL void 		at91EndPhyWrite 		(UINT32 phyRegAddr, UINT32 phyAddr, UINT32 phyData);/**/
LOCAL void		at91EndAddrFilterSet			(at91end_device *pDrvCtrl);/**/

/* END Specific interfaces. */

/* This is the only externally visible interface. */

END_OBJ* 	at91EndLoad (char* initString);

LOCAL STATUS	at91EndStart		(at91end_device* pDrvCtrl);/**/
LOCAL STATUS	at91EndStop			(at91end_device* pDrvCtrl);/**/
LOCAL STATUS	at91EndUnload		();/**/
LOCAL int		at91EndIoctl		(at91end_device* pDrvCtrl, int cmd, caddr_t data);
LOCAL STATUS	at91EndSend			(at91end_device* pDrvCtrl, M_BLK_ID pBuf);/**/
			  
LOCAL STATUS	at91EndMCastAdd 	(at91end_device* pDrvCtrl, char* pAddress);/**/
LOCAL STATUS	at91EndMCastDel 	(at91end_device* pDrvCtrl, char* pAddress);/**/
LOCAL STATUS	at91EndMCastGet 	(at91end_device* pDrvCtrl, MULTI_TABLE* pTable);/**/
LOCAL STATUS	at91EndPollSend 	(at91end_device* pDrvCtrl, M_BLK_ID pBuf);/**/
LOCAL STATUS	at91EndPollRcv 		(at91end_device* pDrvCtrl, M_BLK_ID pBuf);/**/
LOCAL STATUS	at91EndPollStart 	(at91end_device* pDrvCtrl);/**/
LOCAL STATUS	at91EndPollStop 	(at91end_device* pDrvCtrl);/**/

LOCAL STATUS	at91EndParse		();/*---*/
LOCAL STATUS	at91EndMemInit		();/*---*/
LOCAL void FreeEndMemory(  at91end_device* pDrvCtrl );

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

LOCAL NET_FUNCS at91endFuncTable =
    {
    (STATUS (*) (END_OBJ*))at91EndStart,				/* Function to start the device. */
    (STATUS (*) (END_OBJ*))at91EndStop,				/* Function to stop the device. */
    (STATUS (*) (END_OBJ*))at91EndUnload,				/* Unloading function for the driver. */
    (int (*) (END_OBJ*, int, caddr_t))at91EndIoctl,				/* Ioctl function for the driver. */
	(STATUS (*) (END_OBJ* , M_BLK_ID))at91EndSend,				/* Send function for the driver. */
    (STATUS (*) (END_OBJ*, char*))at91EndMCastAdd,			/* Multicast address add function for the driver. */
    (STATUS (*) (END_OBJ*, char*))at91EndMCastDel,			/* Multicast address delete function for the driver. */
    (STATUS (*) (END_OBJ*, MULTI_TABLE*))at91EndMCastGet,			/* Multicast table retrieve function for the driver. */
    (STATUS (*) (END_OBJ*, M_BLK_ID))at91EndPollSend,			/* Polling send function for the driver. */
    (STATUS (*) (END_OBJ*, M_BLK_ID))at91EndPollRcv,				/* Polling receive function for the driver. */
    endEtherAddressForm,        /* Put address info into a packet.  */
    endEtherPacketDataGet,      /* Get a pointer to packet data. */
    endEtherPacketAddrGet       /* Get packet addresses. */
    };

/*******************************************************************************
*
* at91EndLoad - 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:
*
* "<unit>:<Speed>:<duplex>:<autoneg>"
*
* RETURNS: An END object pointer or NULL on error.
*/

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

    ENDLOGMSG (("Loading at91EndEnd...\n", 1, 2, 3, 4, 5, 6));

	if ( initString[0] == 0 )
	{
		strcpy (initString, "atemac");
		return (END_OBJ *)NULL;
	}

	/* allocate the device structure */

    pDrvCtrl = (at91end_device *)calloc (sizeof (at91end_device), 1);
    if ( pDrvCtrl == NULL )
		goto errorExit;
	
	bzero( (void*)pDrvCtrl, sizeof (at91end_device) );
	pDrvCtrl ->TXFifoStat = TXFIFOEMPTY;

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

    if ( at91EndParse ( pDrvCtrl, initString ) == ERROR )
		goto errorExit;

    pDrvCtrl->level = INT_LVL_EMAC;

    /* Ask the BSP to provide the ethernet address. */

    SYS_ENET_ADDR_GET( pDrvCtrl );

   /* initialize the END and MIB2 parts of the structure */
	strcpy (pDrvCtrl->end.devObject.name, "atemac");
	strcpy (pDrvCtrl->end.devObject.description, "AT91RM9200 EMAC END Driver");
	

    /*
     * The M2 element must come from m2Lib.h 
     * This at91End is set up for a DIX type ethernet device.
     */
    if ( END_OBJ_INIT ( &pDrvCtrl->end, (DEV_OBJ *)pDrvCtrl, "atemac",
                      pDrvCtrl->unit, &at91endFuncTable,
                      "AT91RM9200 EMAC END Driver" ) == ERROR
     || END_MIB_INIT (&pDrvCtrl->end, M2_ifType_ethernet_csmacd,
                      &pDrvCtrl->enetAddr[0], 6, ETHERMTU,
                      END_SPEED) == ERROR )
		goto errorExit;

    /* Perform memory allocation/distribution */

    if ( at91EndMemInit (pDrvCtrl) == ERROR )
		goto errorExit;

    /* reset and reconfigure the device */
    at91EndConfig (pDrvCtrl);

    /* set the flags to indicate readiness */
    END_OBJ_READY ( &pDrvCtrl->end, IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST );
	ENDLOGMSG (("Loading at91EndEnd success EXIT...\n", 1, 2, 3, 4, 5, 6));
	return ( &pDrvCtrl->end );

errorExit:
    if ( pDrvCtrl != NULL )
	{
		FreeEndMemory( pDrvCtrl );
		pDrvCtrl = NULL;
	}
	ENDLOGMSG (("Loading at91EndEnd Failure EXIT...\n", 1, 2, 3, 4, 5, 6));
    return NULL;
}

/*******************************************************************************
*
* at91EndParse - parse the init string
*
* Parse the input string.  Fill in values in the driver control structure.
*
* The initialization string format is:
* "<unit>:<Speed>:<duplex>:<autoneg>"
*
* .bS
* unit			Device unit number, a small integer.
* Speed			10 (10Mbps) or 100 (100 Mbps)
* duplex		0 (HDX) or 1 (FDX)
* autoneg		Autonegotiation disabled (0) or enabled (1)
* .bE
*
* RETURNS: OK or ERROR for invalid arguments.
*/

STATUS at91EndParse
(
	at91end_device * pDrvCtrl,	/* device pointer */
	char * initString		/* information string */
)
{
    char*	tok;
    char*	pHolder = NULL;
    
    /* Parse the initString */
	
	/* Unit number. */
    tok = strtok_r (initString, ":", &pHolder);
    if (tok == NULL)
		return ERROR;
    pDrvCtrl->unit = atoi (tok);
	
	/* netSpeed */
    tok = strtok_r (NULL, ":", &pHolder);
    if (tok == NULL)
		return ERROR;
    pDrvCtrl->netSpeed = atoi (tok);
	
	
	/* DuplexMode */
    tok = strtok_r (NULL, ":", &pHolder);
    if (tok == NULL)
		return ERROR;
    pDrvCtrl->duplexMode = atoi (tok);
	
	/* auto Negotiation */
    tok = strtok_r (NULL, ":", &pHolder);
    if (tok == NULL)
		return ERROR;
    pDrvCtrl->autoNeg = atoi (tok);
	
    return OK;
}

/*
 *	format AT91 Special address REG word
 */

LOCAL void FormatETHSpecialAddrWord( UINT32 *wordHigh, UINT32 *wordLow, BYTE *macadd )
{
	(*wordLow) = /*htonl( *((UINT32*)( pDevice->enetAddr )) );*/
		((UINT32)(macadd[3])<<24) | ((UINT32)(macadd[2])<<16) | ((UINT32)(macadd[1])<<8) | ((UINT32)(macadd[0]));
	(*wordHigh) = /*htons( *((UINT16*)( pDevice->enetAddr + 4 )) )*/
		((UINT32)(macadd[5])<<8) | ((UINT32)(macadd[4])) ;
	
}




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

⌨️ 快捷键说明

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