📄 smc.c
字号:
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (c) 1995-2000 Microsoft Corporation. All rights reserved.
Module Name:
Abstract:
Routines for the SMC9000 ethernet controller used for the Windows CE
debug ethernet services, and bootloaders.
Functions:
Notes:
These routines are called at system init and other times when system calls aren't allowed, so
they can't make any system calls.
--*/
// Note : The Odo SMC implementation sometimes encounters read errors if we
// optimize this routine. So for now I'm just going to turn of all
// optimizations.
#pragma optimize("", off)
#include <windows.h>
#include <ethdbg.h>
#include <halether.h>
#include "bvd1.h"
#include "bvd1bd.h"
#include "drv_glob.h"
#include "udp.h"
#include "xllp_ethernet.h"
DWORD dwConfigOptions;
BOOL SMCInit( BYTE *pbBaseAddress, DWORD dwMultiplier, USHORT MacAddr[3])
{
XllpEthernetSWInit((void *)pbBaseAddress);
return XllpEthernetHWSetup((P_XLLP_UINT16_T) MacAddr, TRUE, TRUE, XLLP_ETHERNET_LOOPBACK_DISABLE);
}
void SMCEnableInts()
{
XllpEthernetEnableRxInterrupt();
}
void SMCDisableInts()
{
XllpEthernetDisableRxInterrupt();
}
DWORD SMCGetPendingInterrupts()
{
return 0;
}
UINT16 SMCGetFrame( BYTE *pbData, UINT16 *pwLength )
{
*pwLength = 0;
XllpEthernetReceivePacket((P_XLLP_UINT32_T)pbData, (P_XLLP_INT32_T)pwLength);
if (*pwLength > 0)
return 1;
return 0;
}
UINT16 SMCSendFrame( BYTE *pbData, DWORD dwLength )
{
return (UINT16)(XllpEthernetTransmitPacket((P_XLLP_UINT16_T) pbData, (XLLP_UINT32_T) dwLength));
}
BOOL SMCReadEEPROM( UINT16 EEPROMAddress , UINT16 *pwVal)
{
return FALSE;
}
BOOL SMCWriteEEPROM( UINT16 EEPROMAddress, UINT16 Data )
{
return FALSE;
}
DWORD SMCSetOptions(DWORD dwOptions)
{
DWORD dwOldOptions = dwConfigOptions;
dwConfigOptions = dwOptions;
EdbgOutputDebugString("SMCSetOptions()\n");
return dwOldOptions;
}
void SMCCurrentPacketFilter(DWORD dwFilter)
{
EdbgOutputDebugString("SMCCurrentPacketFilter()\n");
}
BOOL SMCMulticastList(PUCHAR pucMulticastAddresses, DWORD dwNoOfAddresses)
{
EdbgOutputDebugString("SMCMulticastList()\n");
XllpEthernetSetMulticastList ((P_XLLP_UINT8_T) pucMulticastAddresses, (XLLP_UINT32_T) dwNoOfAddresses);
return TRUE;
}
#if 0
#if (WINCEOSVER >= 400)
////////////////////////////////////////////////////////////////////////////////
// SMCComputeCrc()
//
// Description:
//
// Runs the AUTODIN II CRC algorithm on buffer Buffer of length Length.
//
// Arguments:
//
// Buffer - the input buffer
// Length - the length of Buffer
//
// Return value:
//
// The 32-bit CRC value.
//
// Note:
//
// This function is adopted from netcard\ne2000 miniport driver.
//
ULONG
SMCComputeCrc(
IN PUCHAR Buffer,
IN UINT Length)
{
ULONG Crc, Carry;
UINT i, j;
UCHAR CurByte;
Crc = 0xffffffff;
for(i = 0; i < Length; i++)
{
CurByte = Buffer[i];
for(j = 0; j < 8; j++)
{
Carry = ((Crc & 0x80000000) ? 1 : 0) ^ (CurByte & 0x01);
Crc <<= 1;
CurByte >>= 1;
if(Carry)
{
Crc = (Crc ^ 0x04c11db6) | Carry;
}
}
}
return Crc;
} // SMCComputeCrc()
////////////////////////////////////////////////////////////////////////////////
// SMCMulticastList()
//
// Description:
//
// This function is used to insert multicast addresses to the h/w.
//
// Arguments:
//
// pucMulticastAddresses :: The list of multicast addressses.
// dwNoOfAddresses :: The number of addresses in the list.
//
// Return value:
//
// TRUE if successful, FALSE otherwise.
//
BOOL
SMCMulticastList(PUCHAR pucMulticastAddresses, DWORD dwNoOfAddresses)
{
UCHAR NicMulticastRegs[8]; // contents of card multicast registers
UINT i;
DWORD dwCRC;
EdbgOutputDebugString(
"SMC91C94:: SMCMulticastList() set [%d] multicast list addrs.\r\n",
dwNoOfAddresses);
for(i = 0 ; i < dwNoOfAddresses ; i++)
{
EdbgOutputDebugString(
"SMC9000:: Multicast[%d] = %x-%x-%x-%x-%x-%x\r\n",
i,
pucMulticastAddresses[6*i + 0],
pucMulticastAddresses[6*i + 1],
pucMulticastAddresses[6*i + 2],
pucMulticastAddresses[6*i + 3],
pucMulticastAddresses[6*i + 4],
pucMulticastAddresses[6*i + 5]);
}
//
// First turn all bits off.
//
memset (NicMulticastRegs, 0x00, sizeof(NicMulticastRegs));
//
// Now turn on the bit for each address in the multicast list.
//
for(i = 0 ; i < dwNoOfAddresses ; i++)
{
dwCRC = SMCComputeCrc(
&pucMulticastAddresses[6*i],
6);
//
// Here is what the spec says:
// The hash value is defined as the six MSB of the CRC of the
// destination addr.
// The three MSB determine the register to be used (MT0..MT7)
// The other three determine the bit within the register.
//
NicMulticastRegs[dwCRC >> 29] |= (1 << ((dwCRC >> 26) & 0x07));
}
EdbgOutputDebugString(
"SMC9000:: MulticastRegs = %x-%x-%x-%x-%x-%x-%x-%x\r\n",
NicMulticastRegs[0],
NicMulticastRegs[1],
NicMulticastRegs[2],
NicMulticastRegs[3],
NicMulticastRegs[4],
NicMulticastRegs[5],
NicMulticastRegs[6],
NicMulticastRegs[7]);
//
// Finally, burn that in the h/w..
//
WriteWord (BANKSEL_REG, BANK3);
WriteWord (MULTITAB_REG0, NicMulticastRegs[0]);
WriteWord (MULTITAB_REG1, NicMulticastRegs[2]);
WriteWord (MULTITAB_REG2, NicMulticastRegs[4]);
WriteWord (MULTITAB_REG3, NicMulticastRegs[6]);
return TRUE;
} // SMCMulticastList()
////////////////////////////////////////////////////////////////////////////////
// SMCCurrentPacketFilter()
//
// Description:
//
// This function is called to set the h/w filter.
// We support:
// PROMISCUOUS, ALL MULTICAST, BROADCAST, DIRECTED.
//
// Arguments:
//
// dwFilter:: The filter mode
//
// Return value:
//
// TRUE if successful, FALSE otherwise.
//
void
SMCCurrentPacketFilter(DWORD dwFilter)
{
//
// EDBG always receive directed and broadcast as a minimum.
// So our default will be RCR_REG_INIT..
//
WORD wRxControlReg = RCR_REG_INIT;
if(dwFilter & PACKET_TYPE_ALL_MULTICAST)
wRxControlReg |= 0x04;
if(dwFilter & PACKET_TYPE_PROMISCUOUS)
wRxControlReg |= 0x02;
//
// I think Broadcast is always received for smc9000, so we don't
// need to do anything to this flag..
//
EdbgOutputDebugString("SMC9000:: Set filter to : [0x%x]\r\n",
wRxControlReg);
WriteWord (BANKSEL_REG, BANK0);
WriteWord (RCR_REG, wRxControlReg);
} // SMCCurrentPacketFilter()
#endif //WINCEOSVER >= 400
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -