📄 ethernet.c
字号:
/////////////////////////////////////////////////////////////////////////////////
// OEMEthSendFrame
// Send Ethernet frame.
//
// Return Value:
// TRUE if frame successfully sent, FALSE otherwise.
//
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 (!NIC_FTbl->NIC_SendFrame(pData, dwLength))
return TRUE;
else
EdbgOutputDebugString("!OEMEthSendFrame failure, retry %u\n",retries);
}
return FALSE;
}
void EthLaunch (DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr, const ROMHDR *pRomHdr)
{
EDBG_OS_CONFIG_DATA *pCfgData;
EDBG_ADDR EshellHostAddr;
// wait for the jump command from eshell unless user specify jump directly
if (TRUE) {
EdbgOutputDebugString ("Download successful! Jumping to image at %Xh...\r\n", dwLaunchAddr);
if (!(pCfgData = EbootWaitForHostConnect (&MyAddr, &EshellHostAddr))) {
EdbgOutputDebugString ("EbootWaitForHostConenct failed, spin forever\r\n");
SPIN_FOREVER;
}
// update service information
if (pCfgData->Flags & EDBG_FL_DBGMSG) {
EdbgOutputDebugString("Enabling debug messages over Ethernet, IP: %s, port:%u\n",
inet_ntoa(pCfgData->DbgMsgIPAddr),ntohs(pCfgData->DbgMsgPort));
memcpy(&pDriverGlobals->DbgHostAddr.wMAC,&EshellHostAddr.wMAC,6);
pDriverGlobals->DbgHostAddr.dwIP = pCfgData->DbgMsgIPAddr;
pDriverGlobals->DbgHostAddr.wPort = pCfgData->DbgMsgPort;
}
if (pCfgData->Flags & EDBG_FL_PPSH) {
EdbgOutputDebugString("Enabling CESH over Ethernet, IP: %s, port:%u\n",
inet_ntoa(pCfgData->PpshIPAddr),ntohs(pCfgData->PpshPort));
memcpy(&pDriverGlobals->PpshHostAddr.wMAC,&EshellHostAddr.wMAC,6);
pDriverGlobals->PpshHostAddr.dwIP = pCfgData->PpshIPAddr;
pDriverGlobals->PpshHostAddr.wPort = pCfgData->PpshPort;
}
if (pCfgData->Flags & EDBG_FL_KDBG) {
EdbgOutputDebugString("Enabling KDBG over Ethernet, IP: %s, port:%u\n",
inet_ntoa(pCfgData->KdbgIPAddr),ntohs(pCfgData->KdbgPort));
memcpy(&pDriverGlobals->KdbgHostAddr.wMAC,&EshellHostAddr.wMAC,6);
pDriverGlobals->KdbgHostAddr.dwIP = pCfgData->KdbgIPAddr;
pDriverGlobals->KdbgHostAddr.wPort = pCfgData->KdbgPort;
}
pDriverGlobals->etherFlags = pCfgData->Flags;
memcpy(&pDriverGlobals->DownloadHostAddr,&EshellHostAddr,sizeof(EDBG_ADDR));
}
// Update address info, in driver globals, and in EEPROM if necessary
pDriverGlobals->EbootMagicNum = PUZZLE_BOOT_MAGIC_NUM;
memcpy (&pDriverGlobals->PuzzleAddr, &MyAddr, sizeof(MyAddr));
pDriverGlobals->SubnetMask = dwSubnetMask;
// update EEPROM IP/subnet information
EnableFlash();
UpdateFlashIPData(MyAddr.dwIP, dwSubnetMask);
DisableFlash();
// If dwLaunchAddr isn't specified, we're jumping into a previously
// downloaded image or to a ROM-based image. In either case, we'll check
// flash for the start address of the image last downloaded.
//
// Conversely, if dwLaunchAddr is non-zero, store the address in flash in
// case we reexecute this image without a download.
//
if (dwLaunchAddr)
{
EnableFlash();
UpdateFlashLaunchAddrData(dwLaunchAddr);
DisableFlash();
}
else
{
DEVICE_NETWORK_INFO FlashNetworkInfo;
memcpy(&FlashNetworkInfo, (const void *)DEVICE_NETWORK_INFO_LOCATION,
sizeof(DEVICE_NETWORK_INFO));
if (FlashNetworkInfo.dwSignature != VALID_INFO_SIGNATURE)
{
EdbgOutputDebugString("ERROR: Launch address not found in flash - unable to jump to image.\r\n");
SPIN_FOREVER;
}
else
{
dwLaunchAddr = FlashNetworkInfo.dwLaunchAddr;
EdbgOutputDebugString("INFO: Launch address retrieved from flash (0x%x).\r\n", dwLaunchAddr);
}
}
if (pRomHdr && (pDriverGlobals->etherFlags & EDBG_FL_CLEANBOOT)) {
EdbgOutputDebugString ("CLEANBOOT Clearing RAM from %Xh-%Xh.\r\n", pRomHdr->ulRAMStart, pRomHdr->ulRAMEnd);
memset ((LPVOID)pRomHdr->ulRAMStart, 0, pRomHdr->ulRAMEnd - pRomHdr->ulRAMStart);
}
// point of no return -- off to the OS
JumpTo(dwLaunchAddr, (ULONG)NULL);
// never reached
SPIN_FOREVER;
}
DWORD EthPreDownload (void)
{
BOOL fGotJumpImg = FALSE;
DWORD DHCPLeaseTime = 0, *pDHCPLeaseTime = &DHCPLeaseTime;
UCHAR uDIPs;
// If DIP switch 4 is set, jump straight to the exist image.
uDIPs = ReadSwitches();
// Polarity is reversed, so this is actually testing the "Off" position
if (!(uDIPs & 0x08)) {
EdbgOutputDebugString("\r\nSwitch 4 on, jumping directly to flash image...\r\n");
fNoWait = TRUE;
return BL_JUMP;
}
fNoWait = FALSE;
#if 0
// ask user if static IP is desired
if (AskUser (&MyAddr, &dwSubnetMask)) {
pDHCPLeaseTime = NULL; // the pDHCPLeaseTime parameter is overloaded.
// NULL indicates static IP
pDriverGlobals->eth.EdbgFlags = EDBG_FLAGS_STATIC_IP;
}
#endif // 0
// initialize TFTP transport
//
// NOTE: Passing NULL for the device name tells EbootSendBootme() to
// create a device name based on the MAC address provided (like
// ShowDeviceName()).
//
if (!EbootInitEtherTransport (&MyAddr, &dwSubnetMask, &fGotJumpImg, pDHCPLeaseTime,
EBOOT_VERSION_MAJOR, EBOOT_VERSION_MINOR, PLATFORM_STRING, NULL, CPU_ID, 0)) {
EdbgOutputDebugString("EbootInitEtherTransport Failed\r\n");
return BL_ERROR;
}
// update DHCP lease time
pDriverGlobals->DHCPLeaseTime = DHCPLeaseTime;
return fGotJumpImg? BL_JUMP : BL_DOWNLOAD;
}
DWORD OEMEthGetSecs( void )
{
// GetCounter returns resolution in second.
return (GetCounter());
}
/////////////////////////////////////////////////////////////////////////////////
// EdbgOutputDebugString is used extensively in eboot.lib and ne2kdbg.lib.
//
void
localDEBUGMSG (const char *sz, ...)
{
;
// Do nothing !!!
}
/////////////////////////////////////////////////////////////////////////////////
// Used by NE2000 Libarary.
// Look at comment in hal\kernel\halether.c on reason.
void
localEdbgOutputDebugString(const char *sz, ...)
{
;
// Do nothing !!!
}
/////////////////////////////////////////////////////////////////////////////////
// We don't have LEDs, but need to provide the function as
// eboot.lib and ne2kdbg.lib need this.
void SC_WriteDebugLED(WORD wIndex, DWORD dwPattern)
{
return;
}
/////////////////////////////////////////////////////////////////////////////////
// DoGetMac()
// Allow user to key in hard coded MAC address for the device...
// This will be stored together with IP and subnet mask in
// DEVICE_NETWORK_INFO structure in flash...
BOOL DoGetMac(PUSHORT pMAC)
{
CHAR Buffer[15];
ULONG i;
EdbgOutputDebugString("\r\nPlease enter the MAC address assigned to this board (format nnnnnnnnnnnn).\r\nThe MAC address should be a unique value on your network!!!: \r\n");
//
// Get input line
// convert to lower case
//
GetStringFromSerial(Buffer, 15);
EdbgOutputDebugString("\r\n");
for (i=0 ; i<15 ; i++)
Buffer[i] = TO_LOWER(Buffer[i]);
//
// Check that length is 6 bytes (12 nibbles)
//
if (strlen(Buffer) != 12)
{
EdbgOutputDebugString("ERROR: Invalid length %d. MAC address should be 12 nibbles\r\n",strlen(Buffer));
return(FALSE);
}
//
// convert atoi and validate
//
for (i = 0; i < 12; i++)
{
if ((Buffer[i] >= '0') && (Buffer[i] <= '9'))
{
Buffer[i] -= '0';
}
else if ((Buffer[i] >= 'a') && (Buffer[i] <= 'f'))
{
Buffer[i] = Buffer[i] - 'a' + 10;
}
else
{
EdbgOutputDebugString("ERROR: Invalid character %c in string\r\n",Buffer[i]);
return(FALSE);
}
}
//
// place MAC address in Device Structure
//
pMAC[0] = (Buffer[2] << 12) |
(Buffer[3] << 8) |
(Buffer[0] << 4) |
(Buffer[1]);
pMAC[1] = (Buffer[6] << 12) |
(Buffer[7] << 8) |
(Buffer[4] << 4) |
(Buffer[5]);
pMAC[2] = (Buffer[10] << 12) |
(Buffer[11] << 8) |
(Buffer[8] << 4) |
(Buffer[9]);
return(TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -