📄 ethernet.c
字号:
#include <windows.h>
#include <halether.h>
#include <nkintr.h>
#include <alt_def.h>
#include "vrc5074.h"
#include "ether.h"
#include <bootldr.h>
#include <eglobal.h>
#include "firmware.h"
#include "consts.h"
#include "rev.h"
#include "pciinit.h"
void GetStringFromSerial(PUCHAR pBuffer, USHORT nLen);
BOOL DEC21140SetMACAddress(PUSHORT pMacAddr);
VOID UpdateFlashLaunchAddrData(DWORD dwLaunchAddr);
/////////////////////////////////////////////////////////////////////////////////
// Global var used by this file.
// Depending on which NIC deteceted, we'll update this table accordingly...
//
ULONG aulNicID[]= {
#ifdef NECNIC_SUPPORT
0x802910EC, // NEC
#endif // NECNIC_SUPPORT
0x00091011, // DEC21140
0x00191011, // DEC21143
(ULONG)NULL // End of List
};
typedef struct _NIC_FTBL
{
BOOL (*NIC_Init) (BYTE *pbBaseAddress, ULONG dwMemOffset, USHORT MacAddr[3]);
void (*NIC_EnableInts) (void);
void (*NIC_DisableInts) (void);
DWORD (*NIC_GetPendingInts) (void);
UINT16 (*NIC_GetFrame) (BYTE *pbData, UINT16 *pwLength);
UINT16 (*NIC_OtherGetFrame) (BYTE *pbData, UINT16 *pwLength);
UINT16 (*NIC_SendFrame) (BYTE *pbData, DWORD dwLength);
BOOL (*NIC_InitDMABuffer) (DWORD dwStartAddress, DWORD dwLength);
DWORD (*NIC_QueryBufferSize) (void);
DWORD (*NIC_QueryDescriptorSize) (void);
} NIC_FTBL, *PNIC_FTBL;
#ifdef NECNIC_SUPPORT
NIC_FTBL NE2000FTbl =
{
NE2000Init,
NE2000EnableInts,
NE2000DisableInts,
NE2000GetPendingInts,
NE2000GetFrame,
NULL,
NE2000SendFrame,
NULL, // NE2000 Does not need these functions...
NULL,
NULL
};
#endif // NECNIC_SUPPORT
NIC_FTBL DEC21140FTbl =
{
DEC21140Init,
DEC21140EnableInts,
NULL,
DEC21140GetPendingInts,
NULL,
DEC21140GetFrame,
DEC21140SendFrame,
DEC21140InitDMABuffer,
DEC21140QueryBufferSize,
DEC21140QueryDescriptorSize
};
PNIC_FTBL NIC_FTbl;
static EDBG_ADDR MyAddr; // IP address
static DWORD dwSubnetMask; // subnet mask
static BOOL fNoWait; // wait for desktop?
//DWORD EdbgDebugZone = ZONE_DHCP;
DWORD EdbgDebugZone = 0xffffffff;
BOOL bDecChip = FALSE;
BOOL bUseEtherDebug = FALSE;
VOID ShowMACAddress(PBYTE pMACAddr)
{
int i;
EdbgOutputDebugString("MAC Address = ");
for (i=0; i<6; i++)
EdbgOutputDebugString("%B",*pMACAddr++);
EdbgOutputDebugString("\n");
}
VOID ShowDeviceName(VOID)
{
UCHAR DevNumBuf[20];
_itoa(ntohs(MyAddr.wMAC[2]), DevNumBuf, 10);
EdbgOutputDebugString("Device Name = %s%s\r\n", PLATFORM_STRING, DevNumBuf);
}
#define NIC_DESCRIPTORS_HEAD 0xA3BE0000
#define NIC_BUFFER_SIZE 0x00200000
BOOL EthInit(VOID)
{
DWORD EtherCardIoAddress; // I/O Address of Ether LAN Card.
ULONG ulBus;
ULONG ulDevice;
ULONG ulFunction;
ULONG IoAdr;
ULONG dwIntr;
ULONG *pulID = &aulNicID[0];
PDEVICE_NETWORK_INFO pLocalDeviceNetworkInfo = NULL;
// search for network adapters, the search order is NE2000, and finally
// on board DEC2114x. the order is set by the NIC ID array
while( *pulID != (ULONG)NULL)
{
if(PciInitSearchForDevice(*pulID, &ulBus, &ulDevice, &ulFunction))
{
// network adapter found
IoAdr = PCIConfig_Read(ulBus, ulDevice, ulFunction, 0x10) & 0xFFFFFFFE;
dwIntr = PCIConfig_Read(ulBus, ulDevice, ulFunction, 0x3C) & 0xFF;
if (*pulID == 0x00191011)
{
// wake up DEC21143
PCIConfig_Write(ulBus, ulDevice, ulFunction, 0x40, 0);
}
break;
}
pulID++;
}
if (*pulID == (ULONG)NULL)
return FALSE; // no network adapter found
// First stop, here is base I/O address.
EtherCardIoAddress = KSEG1_BASE | PCI_IO_BASE | IoAdr;
if (*pulID == 0x20001022)
{
EdbgOutputDebugString("AMD NIC not supported yet\n");
return FALSE;
}
else
if (*pulID==0x00091011 || *pulID==0x00191011)
{
////////////////////////////////////////////////////////////////////////
//
// DEC 2114x NIC.
//
EdbgOutputDebugString ("Debug Ethernet Card = DEC21140.\r\n");
NIC_FTbl = &DEC21140FTbl;
bDecChip = TRUE;
bUseEtherDebug = TRUE;
// Get the MAC address for Boston (it's stored in system flash).
//
pLocalDeviceNetworkInfo =
(PDEVICE_NETWORK_INFO) DEVICE_NETWORK_INFO_LOCATION;
if (pLocalDeviceNetworkInfo->dwSignature == VALID_INFO_SIGNATURE &&
pLocalDeviceNetworkInfo->dwMACSignature == VALID_MAC_ADDRESS)
{
MyAddr.wMAC[0] = pLocalDeviceNetworkInfo->wMAC[0];
MyAddr.wMAC[1] = pLocalDeviceNetworkInfo->wMAC[1];
MyAddr.wMAC[2] = pLocalDeviceNetworkInfo->wMAC[2];
// Call into the DEC21140 driver and give it the MAC (it'll need it
// to set up perfect filtering).
DEC21140SetMACAddress(MyAddr.wMAC);
}
else
{
EdbgOutputDebugString ("ERROR: No MAC address assigned to the DEC21140...\r\n");
return(FALSE);
}
// Initialize the NIC DMA buffer.
//
if (!NIC_FTbl->NIC_InitDMABuffer(NIC_DESCRIPTORS_HEAD, NIC_BUFFER_SIZE))
{
EdbgOutputDebugString ("ERROR: Failed to initialize NIC DMA buffer...\r\n");
return(FALSE);
}
// Initialize the NIC. Note we're passing NULL for the MAC address.
// This signals the public DEC21140 driver not to look for the MAC
// itself, since it doesn't know how to find it on Boston.
//
if (!(NIC_FTbl->NIC_Init((PBYTE)EtherCardIoAddress, 0, NULL)))
{
EdbgOutputDebugString ("ERROR: Failed to initialize NIC...\r\n");
return(FALSE);
}
}
else
{
#ifdef NECNIC_SUPPORT
EdbgOutputDebugString("Debug Ethernet Card = NE2000 Compatible.\r\n");
NIC_FTbl = &NE2000FTbl;
bDecChip = FALSE;
bUseEtherDebug = FALSE;
/////////////////////////////////////////////////////////////////////////
// Initialize Ether Card.
// The NE2000 library supports 8930 compatible NIC.
// The function will also read the card's MAC address.
if (!NIC_FTbl->NIC_Init((PBYTE)EtherCardIoAddress, 0, MyAddr.wMAC))
return FALSE;
#else
EdbgOutputDebugString("NE2000 NIC not support yet\n");
return FALSE;
#endif // NECNIC_SUPPORT
}
/////////////////////////////////////////////////////////////////////////
// SHOW MAC address...
//
ShowDeviceName();
ShowMACAddress((PBYTE)(MyAddr.wMAC));
pDriverGlobals->EtherIoAddr = (USHORT)IoAdr;
/////////////////////////////////////////////////////////////////////////
// Interrupt can only be:
// 9 = On board DEC21140 or any ether PCI card (either NE2000 or DEC21140).
// 10 = PCI slot 2
// 11 = PCI slot 3.
// So, use the MSB to indicate which type of card we use...
// If DEC21140 type, MSB = 00
// If NE2000 type, MSB = 01
#ifdef AMDNIC_SUPPORT
if (NIC_FTbl == &AMD79C970FTbl)
dwIntr |= AMD_DEBUG;
else
#endif // AMDNIC_SUPPORT
#ifdef NECNIC_SUPPORT
if (NIC_FTbl == &NE2000FTbl)
dwIntr |= NE2000_DEBUG;
else
#endif // NECNIC_SUPPORT
dwIntr |= DEC21140_DEBUG;
pDriverGlobals->EtherIntrNumber = (USHORT) (dwIntr);
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////////
// OEMEthGetFrame
// Check to see if a frame has been received, and if so copy to buffer. An optimization
// which may be performed in the Ethernet driver is to filter out all received broadcast
// packets except for ARPs. This is done in the NE2000 library.
//
// Return Value:
// Return TRUE if frame has been received, FALSE if not.
//
BOOL
OEMEthGetFrame(
BYTE *pData, // OUT - Receives frame data
UINT16 *pwLength) // IN - Length of Rx buffer
// OUT - Number of bytes received
{
if (bDecChip)
return NIC_FTbl->NIC_OtherGetFrame(pData, pwLength);
return NIC_FTbl->NIC_GetFrame(pData, pwLength);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -