dm9000.c

来自「该BSP是基于PXA270+WINCE的BSP」· C语言 代码 · 共 1,301 行 · 第 1/3 页

C
1,301
字号
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
//  File:  DM9000.c
//
#include <windows.h>
#include <ceddk.h>
#include <ethdbg.h>
#include <DM9000.h>

//extern void Wait(unsigned);

//------------------------------------------------------------------------------

#define DM9000A_EISA_NUMBER         0x630e
#define RETRY_COUNT                 0x00100000


//------------------------------------------------------------------------------
volatile DM9000_REGS *g_pDM9000;
volatile BYTE *g_pDM9000Frank;

static UINT16 g_hash[4];
static UINT32 g_filter;
DWORD dwConfigOptions;
//------------------------------------------------------------------------------

static UINT16 ReadPacketPage(UINT16 address);
static VOID WritePacketPage(UINT16 address, UINT16 data);
static UINT32 ComputeCRC(UINT8 *pBuffer, UINT32 length);

/*add by frank*/
#define DM9000_VID		0x0A46
#define	DM9000_PID		0x9000

#define	DM9000_ADDR_OFFSET		0x00

//-----------------------------------------------------
//#define	DM9000_DATA_OFFSET		0x02#define	DM9000_DATA_OFFSET		0x4000		///wzw 0x04//-----------------------------------------------------

typedef	enum {
	DM9_NCR = 0,
	DM9_NSR,	/* 0x01 */
	DM9_TXCR,	/* 0x02 */
	DM9_TXSR1,	/* 0x03 */
	DM9_TXSR2,	/* 0x04 */
	DM9_RXCR,	/* 0x05 */
	DM9_RXSR,	/* 0x06 */
	DM9_ROCR,	/* 0x07 */
	DM9_BACKTH,	/* 0x08 */
	DM9_PAUSETH,/* 0x09 */
	DM9_FLOW,	/* 0x0s */
	DM9_EPCNTL,	/* 0x0B */
	DM9_EPADDR,	/* 0x0c */
	DM9_EPLOW,	/* 0x0d */
	DM9_EPHIGH,	/* 0x0e */
	DM9_WCR,	/* 0x0f */
	
	DM9_PAR0 = 0x10,
	DM9_PAR1,	/* 0x11 */
	DM9_PAR2,	/* 0x12 */
	DM9_PAR3,	/* 0x13 */
	DM9_PAR4,	/* 0x14 */
	DM9_PAR5,	/* 0x15 */

	DM9_MAR0 = 0x16,
	DM9_MAR1,	/* 0x17 */
	DM9_MAR2,	/* 0x18 */
	DM9_MAR3,	/* 0x19 */
	DM9_MAR4,	/* 0x1a */
	DM9_MAR5,	/* 0x1b */
	DM9_MAR6,	/* 0x1c */
	DM9_MAR7,	/* 0x1d */
		
	DM9_GPCR = 0x1E,
	DM9_GPR,	/* 0x1f */

	DM9_TRAL = 0x22,
	DM9_TRAH = 0x23,
	
	DM9_VIDL = 0x28,
	DM9_VIDH,	/* 0x29 */
	DM9_PIDL,	/* 0x2a */
	DM9_PIDH,	/* 0x2b */
	DM9_SMCR = 0x2f,
	
	DM9_MRCMDX = 0xF0,
	DM9_MRCMD = 0xF2,
	DM9_MDRAH = 0xF4,
	DM9_MDRAL,	/* 0xf5 */
	

	DM9_MWCMDX = 0xF6,
	DM9_MWCMD = 0xF8,
	DM9_MDWAL = 0xFA,
	DM9_MDWAH = 0xFB,
	
	DM9_TXLENL = 0xFC,
	DM9_TXLENH,	/* 0xfd */

	DM9_ISR = 0xFE,
	DM9_IMR		/* 0xff */
		
} DM9000_REGISTER_TYPE;


typedef	unsigned long	U32;
typedef	unsigned long	*PU32;
typedef	unsigned short	U16;
typedef	unsigned short	*PU16;
typedef	unsigned char	U8;
typedef	unsigned char	*PU8;

#define	DIM(a)	(sizeof(a) / sizeof(a[0]))
#define	MINI(a,b)	(((a)<(b)) ? (a):(b))
#define	MAXI(a,b)	(((a)>(b)) ? (a):(b))

#define	MAKE_MASK(a)		MAKE_MASK1(a)
#define	MAKE_MASK1(a)		(1<<(a))
#define	MAKE_MASK2(a,b)		(MAKE_MASK1(a)|MAKE_MASK1(b))
#define	MAKE_MASK3(a,b,c)	(MAKE_MASK2(a,b)|MAKE_MASK1(c))
#define	MAKE_MASK4(a,b,c,d)	(MAKE_MASK2(a,b)|MAKE_MASK2(c,d))
#define	MAKE_MASK6(a,b,c,d,e,f)	\
	(MAKE_MASK4(a,b,c,d)|MAKE_MASK2(e,f))
#define	MAKE_MASK7(a,b,c,d,e,f,g)	\
	(MAKE_MASK4(a,b,c,d)|MAKE_MASK3(e,f,g))
#define	MAKE_MASK8(a,b,c,d,e,f,g,h)	\
	(MAKE_MASK4(a,b,c,d)|MAKE_MASK4(e,f,g,h))

#define	HIGH_BYTE(n)	(((n)&0xFF00)>>8)
#define	LOW_BYTE(n)		((n)&0x00FF)
#define	HIGH_WORD(n)	(((n)&0xFFFF0000)>>16)
#define	LOW_WORD(n)		((n)&0x0000FFFF)

#define	MAKE_WORD(l,h)	( ((h)<<8) | ((l)&0xff) )
#define	MAKE_DWORD(ll,lh,hl,hh)	\
	( (MAKE_WORD(hl,hh) << 16 ) | MAKE_WORD(ll,lh) )



U32 		m_uLastAddressPort = 0;
int		m_nIoMode;
int		m_nIoMaxPad;

/**/

#define	VALIDATE_ADDR_PORT(p) \
	if( m_uLastAddressPort != (p) ) \
		{ \
			/*OALMSG("Writ 0x%X  to port 0x%X \r\n", p, (g_pDM9000Frank + DM9000_ADDR_OFFSET) );*/	\
			*(U16*)(g_pDM9000Frank + DM9000_ADDR_OFFSET)  =(U16)(p);\
			m_uLastAddressPort = (p);\
		}


static U32	DeviceReadPort(	U32		uPort);
static U32	DeviceWritePort(U32		uPort,	U32		uValue);


static U32	DeviceReadPort(	U32		uPort)
{
	U16 	val;
	
	VALIDATE_ADDR_PORT(uPort)

	val = *(U16*)(g_pDM9000Frank + DM9000_DATA_OFFSET);

	val &= 0xffff;

	//OALMSG("Read port 0x%X is 0x%X\r\n", (g_pDM9000Frank + DM9000_DATA_OFFSET),val);	
	
	return (U32)val;
}

static U32	DeviceWritePort(
	U32		uPort,
	U32		uValue)
{
	VALIDATE_ADDR_PORT(uPort)

	//OALMSG("Writ 0x%X  to port 0x%X \r\n", uValue, (g_pDM9000Frank + DM9000_DATA_OFFSET) );

	*(U16*)(g_pDM9000Frank + DM9000_DATA_OFFSET) = 	(U16)uValue;

	return uValue;
}

DWORD DM9000AGetPendingInterrupts(void)
{
	OALMSG("+DM9000AGetPendingInterrupts\r\n");
	OALMSG("-DM9000AGetPendingInterrupts\r\n");

	return 0;
}

BOOL DM9000AReadEEPROM( UINT16 EEPROMAddress , UINT16 *pwVal)
{
	OALMSG("+DM9000AReadEEPROM\r\n");
	OALMSG("-DM9000AReadEEPROM\r\n");

	return FALSE;
}

BOOL DM9000AWriteEEPROM( UINT16 EEPROMAddress, UINT16 Data )
{
	OALMSG("+DM9000AWriteEEPROM\r\n");
	OALMSG("-DM9000AWriteEEPROM\r\n");

	return FALSE;
}

DWORD DM9000ASetOptions(DWORD dwOptions)
{
    DWORD dwOldOptions = dwConfigOptions;
    dwConfigOptions = dwOptions;
	OALMSG("+DM9000ASetOptions\r\n");
	OALMSG("-DM9000ASetOptions\r\n");
	
    return dwOldOptions;

}
void DebugDelay(int i)
{
	while(i--);
}


#if 0	
void DebugSegment7(unsigned long value)
{
#define CACHED_TO_UNCACHED_OFFSET		0x20000000
#define  SEGMENT7_BASE_PHYSICAL	 		0x12000000
#define SEGMENT7_BASE_C_VIRTUAL  	 		0x9E800000
#define SEGMENT7_BASE_U_VIRTUAL  	 		(SEGMENT7_BASE_C_VIRTUAL + CACHED_TO_UNCACHED_OFFSET)	

	volatile unsigned long *v_pSegment7=(volatile unsigned long *)SEGMENT7_BASE_U_VIRTUAL;
	unsigned char seg7table[16] = {
#if 0		
		//0  	1		2		3		4		5		6		7
		0xc0,	0xf9,	0xa4,	0xb0,	0x99,	0x92,	0x82,	0xf8,
		//8		9		a		b		c		d		e		f
		0x80,	0x90,	0x88,	0x83,	0xc5,	0xa1,	0x86,	0x8e
#else
		//0 		1		2		3		4		5		6		7
		0x24,	0xF5,	0x07,	0x45,	0xD4,	0x4C,	0x0C,	0xE4,
		//8 		9		a		b		c		d		e		f
		0x04,	0x44,	0x84,	0x1C,	0x2E,	0x15,	0x0E,	0x8e
#endif
	};

	unsigned char low = (unsigned char)(value &0xf);
	unsigned char high = (unsigned char)((value & 0xf0)>>4);

	unsigned new_value = (seg7table[high]<<8) + seg7table[low];

	if(value == 0xffFFffFF)
		new_value = 0xffff;

	*v_pSegment7 = new_value;
}
#endif

#if 0	
void DebugLed(void)
{
	typedef unsigned long		   XLLP_UINT32_T,  *P_XLLP_UINT32_T;
	typedef volatile XLLP_UINT32_T XLLP_VUINT32_T, *P_XLLP_VUINT32_T;
	/**
	  GPIO Register Definitions
	**/
	typedef struct 
	{
		XLLP_VUINT32_T GPLR0;			/* Level Detect Reg. Bank 0 */
		XLLP_VUINT32_T GPLR1;			/* Level Detect Reg. Bank 1 */
		XLLP_VUINT32_T GPLR2;			/* Level Detect Reg. Bank 2 */
		XLLP_VUINT32_T GPDR0;			/* Data Direction Reg. Bank 0 */
		XLLP_VUINT32_T GPDR1;			/* Data Direction Reg. Bank 1 */
		XLLP_VUINT32_T GPDR2;			/* Data Direction Reg. Bank 2 */
		XLLP_VUINT32_T GPSR0;			/* Pin Output Set Reg. Bank 0 */
		XLLP_VUINT32_T GPSR1;			/* Pin Output Set Reg. Bank 1 */
		XLLP_VUINT32_T GPSR2;			/* Pin Output Set Reg. Bank 2 */
		XLLP_VUINT32_T GPCR0;			/* Pin Output Clr Reg. Bank 0 */
		XLLP_VUINT32_T GPCR1;			/* Pin Output Clr Reg. Bank 1 */
		XLLP_VUINT32_T GPCR2;			/* Pin Output Clr Reg. Bank 2 */
		XLLP_VUINT32_T GRER0;			/* Ris. Edge Detect Enable Reg. Bank 0 */
		XLLP_VUINT32_T GRER1;			/* Ris. Edge Detect Enable Reg. Bank 1 */
		XLLP_VUINT32_T GRER2;			/* Ris. Edge Detect Enable Reg. Bank 2 */
		XLLP_VUINT32_T GFER0;			/* Fal. Edge Detect Enable Reg. Bank 0 */
		XLLP_VUINT32_T GFER1;			/* Fal. Edge Detect Enable Reg. Bank 1 */
		XLLP_VUINT32_T GFER2;			/* Fal. Edge Detect Enable Reg. Bank 2 */
		XLLP_VUINT32_T GEDR0;			/* Edge Detect Status Reg. Bank 0 */
		XLLP_VUINT32_T GEDR1;			/* Edge Detect Status Reg. Bank 1 */
		XLLP_VUINT32_T GEDR2;			/* Edge Detect Status Reg. Bank 2 */
		XLLP_VUINT32_T GAFR0_L; 		/* Alt. Function Select Reg.[  0:15 ] */
		XLLP_VUINT32_T GAFR0_U; 		/* Alt. Function Select Reg.[ 16:31 ] */
		XLLP_VUINT32_T GAFR1_L; 		/* Alt. Function Select Reg.[ 32:47 ] */
		XLLP_VUINT32_T GAFR1_U; 		/* Alt. Function Select Reg.[ 48:63 ] */
		XLLP_VUINT32_T GAFR2_L; 		/* Alt. Function Select Reg.[ 64:79 ] */
		XLLP_VUINT32_T GAFR2_U; 		/* Alt. Function Select Reg.[ 80:95 ] */
		XLLP_VUINT32_T GAFR3_L; 		/* Alt. Function Select Reg.[ 96:111] */
		XLLP_VUINT32_T GAFR3_U; 		/* Alt. Function Select Reg.[112:120] */
		XLLP_VUINT32_T RESERVED1[35];	/* addr. offset 0x074-0x0fc */
		XLLP_VUINT32_T GPLR3;			/* Level Detect Reg. Bank 3 */
		XLLP_VUINT32_T RESERVED2[2];	/* addr. offset 0x104-0x108 */
		XLLP_VUINT32_T GPDR3;			/* Data Direction Reg. Bank 3 */
		XLLP_VUINT32_T RESERVED3[2];	/* addr. offset 0x110-0x114 */
		XLLP_VUINT32_T GPSR3;			/* Pin Output Set Reg. Bank 3 */
		XLLP_VUINT32_T RESERVED4[2];	/* addr. offset 0x11c-0x120 */
		XLLP_VUINT32_T GPCR3;			/* Pin Output Clr Reg. Bank 3 */
		XLLP_VUINT32_T RESERVED5[2];	/* addr. offset 0x128-0x12c */
		XLLP_VUINT32_T GRER3;			/* Ris. Edge Detect Enable Reg. Bank 3 */
		XLLP_VUINT32_T RESERVED6[2];	/* addr. offset 0x134-0x138 */
		XLLP_VUINT32_T GFER3;			/* Fal. Edge Detect Enable Reg. Bank 3 */
		XLLP_VUINT32_T RESERVED7[2];	/* addr. offset 0x140-0x144 */
		XLLP_VUINT32_T GEDR3;			/* Edge Detect Status Reg. Bank 3 */
	
	} XLLP_GPIO_T, *P_XLLP_GPIO_T;

#define PERIF_BASE_C_VIRTUAL		0x84000000	
#define CACHED_TO_UNCACHED_OFFSET		0x20000000
#define PERIF_BASE_U_VIRTUAL		(PERIF_BASE_C_VIRTUAL+CACHED_TO_UNCACHED_OFFSET)
#define GPIO_OFFSET                     0x00E00000      // GPIO
#define GPIO_BASE_U_VIRTUAL             (PERIF_BASE_U_VIRTUAL + GPIO_OFFSET)

	volatile XLLP_GPIO_T *v_pGPIOReg;

	v_pGPIOReg = (volatile XLLP_GPIO_T *)GPIO_BASE_U_VIRTUAL;

	while(1)
	{
		int i=1;
		
		v_pGPIOReg->GPSR1 = 0x80;
		while(i<0xffffff)i++;
		
		v_pGPIOReg->GPCR1 = 0x80;		
		i=1;
		while(i<0xffffff)i++;
		
	}
}
#endif

//==================================================================================
//extern void Wait(UINT32 microSeconds);

//#include "bulverde_base_regs.h"
//#include <windows.h>
//#include <nkintr.h>
//#include <oal.h>
//
#include <bulverde.h>
//----------------------------------------------------------------------
//#include <windows.h>
//#include <oal_log.h>
#include <oal_memory.h>

VOID* mOALPAtoVA(U32 pa, int cached)
{
    OAL_ADDRESS_TABLE *pTable = g_oalAddressTable;
    VOID *va = NULL;

    // Search the table for address range
    while (pTable->size != 0) {
        if (
            pa >= pTable->PA && 
            pa <= (pTable->PA + (pTable->size << 20) - 1)
        ) break;                      // match found 
        pTable++;
    }

    // If address table entry is valid compute the VA
    if (pTable->size != 0) {
        va = (VOID *)(pTable->CA + (pa - pTable->PA));
        // If VA is uncached, set the uncached bit
        if (!cached) (U32)va |= OAL_MEMORY_CACHE_BIT;
    }

    return va;
}
//==================================================================================
void mWait(U32 microSeconds)
{
    volatile U32 *TimerOSCRAddress= (volatile U32 *) mOALPAtoVA((BULVERDE_BASE_REG_PA_OST + 0x10), FALSE);
    U32 Value, Time;

    Time   = *TimerOSCRAddress;
    Value = Time + (microSeconds * 4);
    if (Value < Time)    { 
        while (Time < *TimerOSCRAddress);
    }
    while (*TimerOSCRAddress <= Value);
}
//
//==================================================================================
	
BOOL	DevicePolling(
	U32		uPort,
	U32		uMask,
	U32		uExpected,
	U32		uInterval,	/* in millisecond */
	U32		uRetries)
{
	for(;uRetries;uRetries--)
	{
		if((DeviceReadPort(uPort) & uMask) == uExpected) break;
//-----------
		mWait(uInterval);
//		NdisStallExecution(uInterval);		
//		DebugDelay(1000);
//-----------
	} // of retry loop
	
	return (BOOL)uRetries;
}


U16	DeviceReadEeprom(	U32		uWordAddress)
{
	U16		highbyte,lowbyte;
	
	// assign the register offset
	DeviceWritePort(DM9_EPADDR,uWordAddress);

⌨️ 快捷键说明

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