www.pudn.com > S2410_eboot.rar > ether.c


// 
// 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. 
// 
 
#include  
#include  
#include  
#include "loader.h" 
#include  
 
#define FROM_BCD(n)		((((n) >> 4) * 10) + ((n) & 0xf)) 
#define TO_BCD(n)       ((((n) / 10) << 4) | ((n) % 10)) 
 
extern PDRIVER_GLOBALS pDriverGlobals; 
 
// 
// Function pointers to the support library functions of the currently installed debug ethernet controller. 
// 
PFN_EDBG_INIT             pfnEDbgInit; 
PFN_EDBG_ENABLE_INTS      pfnEDbgEnableInts; 
PFN_EDBG_DISABLE_INTS     pfnEDbgDisableInts; 
PFN_EDBG_GET_PENDING_INTS pfnEDbgGetPendingInts; 
PFN_EDBG_GET_FRAME        pfnEDbgGetFrame; 
PFN_EDBG_SEND_FRAME       pfnEDbgSendFrame; 
PFN_EDBG_READ_EEPROM      pfnEDbgReadEEPROM; 
PFN_EDBG_WRITE_EEPROM     pfnEDbgWriteEEPROM; 
PFN_EDBG_SET_OPTIONS      pfnEDbgSetOptions; 
 
BOOL    CS8900DBG_Init(PBYTE iobase, DWORD membase, USHORT MacAddr[3]); 
UINT16  CS8900DBG_GetFrame(PBYTE pbData, UINT16 *pwLength); 
UINT16  CS8900DBG_SendFrame(PBYTE pbData, DWORD dwLength); 
 
/* 
    @func   BOOL | InitEthDevice | Initializes the Ethernet device to be used for download. 
    @rdesc  TRUE = Success, FALSE = Failure. 
    @comm     
    @xref    
*/ 
BOOL InitEthDevice(PBOOT_CFG  pBootCfg) 
{ 
	USHORT wMAC[3]; 
	PBYTE  pBaseIOAddress = NULL; 
	DWORD  dwMultiplier = 0; 
	  
	// Boot CS8900. 
	// 
	if (!pBaseIOAddress) 
	{ 
		// Use the MAC address programmed into flash by the user. 
		// 
		memcpy(wMAC, pBootCfg->EdbgAddr.wMAC, 6); 
					   
	    pfnEDbgInit      = CS8900DBG_Init; 
	    pfnEDbgGetFrame  = CS8900DBG_GetFrame; 
	    pfnEDbgSendFrame = CS8900DBG_SendFrame; 
 
		pBaseIOAddress  = (PBYTE)CS8900DBG_IOBASE; 
		dwMultiplier    = CS8900DBG_MEMBASE; 
 
		memcpy(pDriverGlobals->eth.TargetAddr.wMAC, pBootCfg->EdbgAddr.wMAC, 6); 
		pDriverGlobals->misc.EbootDevice = (UCHAR)DOWNLOAD_DEVICE_CS8900;  
	} 
 
    // Initialize the built-in Ethenet controller. 
    // 
    if (!pfnEDbgInit((PBYTE)pBaseIOAddress, dwMultiplier, wMAC)) 
    { 
        EdbgOutputDebugString("ERROR: InitEthDevice: Failed to initialize Ethernet controller.\r\n"); 
        return(FALSE); 
    } 
 
    // Make sure MAC address has been programmed. 
	// 
    if (!wMAC[0] && !wMAC[1] && !wMAC[2]) 
	{ 
        EdbgOutputDebugString("ERROR: InitEthDevice: Invalid MAC address read from NIC.\r\n"); 
        return(FALSE); 
    } 
 
    memcpy(&pDriverGlobals->eth.TargetAddr.wMAC, &wMAC, (3 * sizeof(USHORT))); 
 
	return(TRUE); 
} 
 
 
/* 
    @func   BOOL | OEMGetRealTime | Returns the current wall-clock time from the RTC. 
    @rdesc  TRUE = Success, FALSE = Failure. 
    @comm     
    @xref    
*/ 
static BOOL OEMGetRealTime(LPSYSTEMTIME lpst)  
{ 
	volatile RTCreg *s2410RTC = (RTCreg *)RTC_BASE; 
 
	do 
	{ 
		lpst->wYear			= FROM_BCD(s2410RTC->rBCDYEAR) + 2000 ; 
		lpst->wMonth		= FROM_BCD(s2410RTC->rBCDMON   & 0x1f); 
		lpst->wDay			= FROM_BCD(s2410RTC->rBCDDAY   & 0x3f); 
 
		lpst->wDayOfWeek	= (s2410RTC->rBCDDATE - 1); 
	 
		lpst->wHour			= FROM_BCD(s2410RTC->rBCDHOUR  & 0x3f); 
		lpst->wMinute		= FROM_BCD(s2410RTC->rBCDMIN   & 0x7f); 
		lpst->wSecond		= FROM_BCD(s2410RTC->rBCDSEC   & 0x7f); 
		lpst->wMilliseconds	= 0; 
	} 
	while(!(lpst->wSecond)); 
 
	return(TRUE); 
} 
 
 
/* 
    @func   DWORD | OEMEthGetSecs | Returns a free-running seconds count. 
    @rdesc  Number of elapsed seconds since last roll-over. 
    @comm     
    @xref    
*/ 
DWORD OEMEthGetSecs(void) 
{ 
    SYSTEMTIME sTime; 
 
    OEMGetRealTime(&sTime); 
    return((60UL * (60UL * (24UL * (31UL * sTime.wMonth + sTime.wDay) + sTime.wHour) + sTime.wMinute)) + sTime.wSecond); 
} 
 
 
/* 
    @func   BOOL | OEMEthGetFrame | Reads data from the Ethernet device. 
    @rdesc  TRUE = Success, FALSE = Failure. 
    @comm     
    @xref    
*/ 
BOOL OEMEthGetFrame(PUCHAR pData, PUSHORT pwLength) 
{ 
    return pfnEDbgGetFrame(pData, pwLength); 
} 
 
 
/* 
    @func   BOOL | OEMEthSendFrame | Writes data to an Ethernet device. 
    @rdesc  TRUE = Success, FALSE = Failure. 
    @comm     
    @xref    
*/ 
BOOL OEMEthSendFrame(PUCHAR pData, DWORD dwLength) 
{ 
    BYTE Retries = 0; 
 
    while(Retries++ < 4) 
    { 
        if (!pfnEDbgSendFrame(pData, dwLength)) 
                return(TRUE); 
 
        EdbgOutputDebugString("INFO: OEMEthSendFrame: retrying send (%u)\r\n", Retries); 
    } 
 
    return(FALSE); 
}