ether.c
来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 297 行
C
297 行
//------------------------------------------------------------------------------
//
// Module Name:
// ether.c
//
// Abstract:
//
// Functions:
//
//------------------------------------------------------------------------------
#include <windows.h>
#include <halether.h>
#include <ceddk.h>
#include <ethdbg.h>
#include <nkintr.h>
#include <armintboot.h>
#include <platform.h>
#include "eboot.h"
//
// *** Must match config.bib values ***
#define ETHDMA_BUFF_BASE 0x4000 // Ethernet DMA buffer base address.
#define ETHDMA_BUFF_SIZE 0x20000 // Ethernet DMA buffer size.
typedef BOOL (*PFN_EDBG_INIT_DMABUF)(DWORD dwStartAddress, DWORD dwSize);
static PFN_EDBG_INIT pfnEDbgInit;
static PFN_EDBG_INIT_DMABUF pfnEDbgInitDMA;
static PFN_EDBG_GET_FRAME pfnEDbgGetFrame;
static PFN_EDBG_SEND_FRAME pfnEDbgSendFrame;
typedef struct vendorid
{
DWORD dwUpperMAC; // first 3 bytes of ethernet address
char *szAbbrev;
} VENDORID;
static const VENDORID VendorIds[] =
{
{0x00006E, "AE" }, // Artisoft
{0x000094, "AS" }, // ASANTE
{0x0000E8, "AC" }, // Accton Technology
{0x004005, "LS" }, // LinkSys
{0x004033, "AD" }, // Addtron Technology
{0x004092, "ASP"}, // ASP Computer Products
{0x00800F, "SMC"}, // SMC
{0x008048, "CPX"}, // Compex
{0x0080AD, "CN" }, // CNET Technologies
{0x0080C8, "DL" }, // D-Link
{0x00A0D2, "AT" }, // Allied TeleSyn
{0x00C00D, "ALR"}, // Advanced Logic Research
{0x00C06D, "BR" }, // Boca Research
{0x00C0DF, "GE" }, // Kye International GENIUS GE2000 series
{0x00C0F0, "KS" }, // Kingston
{0x4854E8, "WB" } // WinBond Electronics Corp
};
#define NUM_VENDORIDS (sizeof(VendorIds)/sizeof(VENDORID))
BOOL FindDebugNIC(PULONG pBaseAddr, PUCHAR pIRQ, PUCHAR pAdaptType);
int GetPCIConfig(ULONG bus, ULONG device, ULONG function, PCI_COMMON_CONFIG *pConfig);
BOOL
OEMEthGetFrame(
BYTE *pData, // OUT - Receives frame data
UINT16 *pwLength) // IN - Length of Rx buffer
// OUT - Number of bytes received
{
if (pfnEDbgGetFrame)
return(pfnEDbgGetFrame(pData, pwLength));
return(FALSE);
}
BOOL
OEMEthSendFrame(
BYTE *pData, // IN - Data buffer
DWORD dwLength) // IN - Length of buffer
{
int retries = 0;
// Let's be persistant here
while (retries++ < 4) {
if (!pfnEDbgSendFrame(pData, dwLength))
return TRUE;
else
EdbgOutputDebugString("ERROR: OEMEthSendFrame failure, retry %u\r\n", retries);
}
return(FALSE);
}
BOOL OEMEthHardwareInit(ETH_HARDWARE_INIT_ARGS *pInitArgs, EDBG_ADDR *pMyAddr)
{
HARP_BOOT_ARGS *pBootArgs = NULL;
// Form platform name string...
strncpy(pInitArgs->szPlatformString, "ARMINT", EDBG_MAX_DEV_NAMELEN);
//------------------------------------------------------------------
// This value should agree with DRIVER_GLOBALS_PHYSICAL_MEMORY_START
// in drv_glob.h PLUS DRIVER_GLOBALS_ZEROINIT_SIZE, 'cause that's
// where we put the ethernet debug info from Eboot for the OS to read.
//------------------------------------------------------------------
pInitArgs->pBootArgs = (HARP_BOOT_ARGS *)(0x00008000 + 0x800);
pBootArgs = pInitArgs->pBootArgs;
EdbgOutputDebugString("Boot Args @ 0x%x\r\n", pInitArgs->pBootArgs);
// Find debug NIC and get base address, IRQ, and NIC type.
if (!FindDebugNIC(&pBootArgs->dwEdbgBaseAddr, &pBootArgs->ucEdbgIRQ, &pBootArgs->ucEdbgAdapterType))
return(FALSE);
// Assign controller-specific callbacks.
switch (pBootArgs->ucEdbgAdapterType)
{
case EDBG_ADAPTER_NE2000:
pfnEDbgInit = NE2000Init;
pfnEDbgGetFrame = NE2000GetFrame;
pfnEDbgSendFrame = NE2000SendFrame;
break;
case EDBG_ADAPTER_SMC9000:
pfnEDbgInit = SMCInit;
pfnEDbgGetFrame = SMCGetFrame;
pfnEDbgSendFrame = SMCSendFrame;
break;
default:
EdbgOutputDebugString("ERROR: Unable to find network card.\r\n");
EdbgOutputDebugString("ERROR: Card Type = %d, Address = 0x%s.\r\n", pBootArgs->ucEdbgAdapterType, pBootArgs->dwEdbgBaseAddr);
return(FALSE);
}
// call driver specific initialization
if (!pfnEDbgInit((BYTE *)(PHYS_PCI_IO_BASE | pBootArgs->dwEdbgBaseAddr), 1, pMyAddr->wMAC))
{
EdbgOutputDebugString("ERROR: Failed to initialize NIC.\r\n");
return(FALSE);
}
return(TRUE);
}
DWORD OEMEthGetSecs(void)
{
// Returning counter value for Integrator RTC.
// WARNING: this assumes RTC CLK1HZ signal is
// set for 1 Hz = 1 tick/second.
return(*(DWORD *)INTEGRATOR_RTC_BASE);
}
BOOL FindDebugNIC(PULONG pBaseAddr, PUCHAR pIRQ, PUCHAR pAdaptType)
{
PCI_SLOT_NUMBER slotNumber;
PCI_COMMON_CONFIG pciConfig;
UCHAR bus, device, function;
ULONG length;
if (pBaseAddr == NULL || pIRQ == NULL)
return(FALSE);
for (bus = 0; bus < PCI_MAX_BUS; bus++)
{
for (device = 0; device < PCI_MAX_DEVICES; device++)
{
slotNumber.u.bits.DeviceNumber = device;
for (function = 0; function < PCI_MAX_FUNCTION; function++)
{
slotNumber.u.bits.FunctionNumber = function;
length = GetPCIConfig(bus, device, function, &pciConfig);
if (length == 0 || pciConfig.VendorID == 0xFFFF)
break;
if ((pciConfig.BaseClass == PCI_CLASS_NETWORK_CTLR) &&
(pciConfig.SubClass == PCI_SUBCLASS_NET_ETHERNET_CTLR))
{
// TODO - for the moment, we're assuming only one NIC and if we find it,
// it's the debug NIC (and an NE2000-compatible at that)...
*pIRQ = pciConfig.u.type0.InterruptLine;
*pBaseAddr = (pciConfig.u.type0.BaseAddresses[0] & 0xFFFFFFFC);
*pAdaptType = EDBG_ADAPTER_NE2000;
EdbgOutputDebugString("INFO: Found NIC (IRQ = 0x%x, BaseAddress = 0x%x)\r\n", *pIRQ, *pBaseAddr);
return(TRUE);
}
if (function == 0 && !(pciConfig.HeaderType & 0x80))
break;
}
if (length == 0)
break;
}
if (length == 0 && device == 0)
break;
}
EdbgOutputDebugString("INFO: No debug NIC found...\r\n");
return (FALSE);
}
// Stub LED display routine - called by NE2000 ethdbg driver.
VOID SC_WriteDebugLED(WORD wIndex, DWORD dwPattern)
{
return;
}
static void itoa10(int i, char *a)
{
char * p = a;
int c = 0;
int n = i;
char swap;
//
// Build the ascii string in reverse digit order
//
while (n)
{
*p = (char)(n % 10) + '0';
n /= 10;
p++;
c++;
}
*p = 0;
c--;
//
// Reverse the string in place to correct order
//
for (n = 0; n < c; n++, c--)
{
swap = a[n];
a[n] = a[c];
a[c] = swap;
}
}
static DWORD UpperDWFromMAC(EDBG_ADDR *pAddr)
{
DWORD ret;
//
// The WORDs in wMAC field are in net order, so we need to do some
// serious shifting around.
// A hex ethernet address of 12 34 56 78 9a bc is stored in wMAC array as
// wMAC[0] = 3412, wMAC[1] = 7856, wMAC[2] = bc9a.
// The 4 byte return value should look like 0x00123456
//
ret = (pAddr->wMAC[0] & 0x00ff) << 16;
ret |= pAddr->wMAC[0] & 0xff00;
ret |= pAddr->wMAC[1] & 0x00ff;
return ret;
}
void CreateDeviceName(EDBG_ADDR *pMyAddr, char *szBuf,
LPSTR szPlatformString)
{
int i;
DWORD dwUpperMAC;
EdbgOutputDebugString("CreateDeviceName\r\n");
dwUpperMAC = UpperDWFromMAC(pMyAddr);
EdbgOutputDebugString("UpperDWORD = 0x%X\r\n", dwUpperMAC);
strcpy(szBuf, szPlatformString);
szBuf += strlen(szBuf);
for (i = 0; i < NUM_VENDORIDS; i++)
{
if (dwUpperMAC == VendorIds[i].dwUpperMAC)
{
strcat(szBuf,VendorIds[i].szAbbrev);
szBuf += strlen(szBuf);
break;
}
}
itoa10(((pMyAddr->wMAC[2]>>8) | ((pMyAddr->wMAC[2] & 0x00ff) << 8)),
szBuf);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?