📄 smsc9118.c
字号:
}
if (pAdapter->ulPacketFilter & (DWORD)NDIS_PACKET_TYPE_MULTICAST)
{
dwReg |= MAC_CR_HPFILT_;
}
Lan_SetMacRegDW(dwLanBase, MAC_CR, dwReg);
}
void UpdateFilterAndMacReg(CPCSMSC9118_ADAPTER pAdapter)
{
const DWORD dwLanBase = pAdapter->lan9118_data.dwLanBase;
// Now safe to change multicasts hash registers
Lan_SetMacRegDW(dwLanBase, HASHL, pAdapter->ucNicMulticastRegs[0]);
Lan_SetMacRegDW(dwLanBase, HASHH, pAdapter->ucNicMulticastRegs[1]);
Smsc9118SetMacFilter(pAdapter);
}
/*----------------------------------------------------------------------------
Smsc9118QueryInformation
NDIS miniport function
*/
NDIS_STATUS
Smsc9118QueryInformation (IN NDIS_HANDLE hMiniportAdapterContext,
IN NDIS_OID Oid,
IN PVOID pInformationBuffer,
IN ULONG ulInformationBufferLength,
OUT PULONG pulBytesWritten,
OUT PULONG pulBytesNeeded)
{
PSMSC9118_ADAPTER const pAdapter = (PSMSC9118_ADAPTER)(hMiniportAdapterContext);
NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
NDIS_HARDWARE_STATUS HardwareStatus = NdisHardwareStatusReady;
ULONG ulGeneric;
USHORT usGeneric;
UCHAR ucGenericArray[6];
ULONG ulMoveBytes = (DWORD)sizeof(ULONG);
NDIS_DEVICE_POWER_STATE PowerState; //power management
const NDIS_MEDIUM Medium = NdisMedium802_3;
const UCHAR VendorString[] = "SMSC9118 Ethernet Controller.";
const void *pMoveSource = (PVOID)(&ulGeneric);
#ifdef NDIS50_MINIPORT
NDIS_PNP_CAPABILITIES NdisPnpCapabilities;
#endif
SMSC_TRACE1(DBG_INIT,"+Smsc9118QueryInformation[0x%x]\r\n", Oid);
SMSC_ASSERT(sizeof(ULONG) == 4U); /*lint !e506 !e944 !e774 */
switch (Oid)
{
case OID_GEN_MAC_OPTIONS:
SMSC_TRACE0(DBG_INIT," OID_GEN_MAC_OPTIONS\r\n");
ulGeneric = (ULONG)(NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
NDIS_MAC_OPTION_NO_LOOPBACK);
break;
case OID_GEN_SUPPORTED_LIST:
SMSC_TRACE0(DBG_INIT," OID_GEN_SUPPORTED_LIST\r\n");
pMoveSource = (PVOID)(Smsc9118SupportedOids);
ulMoveBytes = (DWORD)sizeof (Smsc9118SupportedOids);
break;
case OID_GEN_HARDWARE_STATUS:
SMSC_TRACE0(DBG_INIT," OID_GEN_HARDWARE_STATUS\r\n");
HardwareStatus = NdisHardwareStatusReady;
pMoveSource = (PVOID)(&HardwareStatus);
ulMoveBytes = (DWORD)sizeof (NDIS_HARDWARE_STATUS);
break;
case OID_GEN_MEDIA_SUPPORTED:
SMSC_TRACE0(DBG_INIT," OID_GEN_MEDIA_SUPPORTED\r\n");
pMoveSource = (PVOID) (&Medium);
ulMoveBytes = (DWORD)sizeof (NDIS_MEDIUM);
break;
case OID_GEN_MEDIA_IN_USE:
SMSC_TRACE0(DBG_INIT," OID_GEN_MEDIA_IN_USE\r\n");
pMoveSource = (PVOID) (&Medium);
ulMoveBytes = (DWORD)sizeof (NDIS_MEDIUM);
break;
case OID_GEN_CURRENT_LOOKAHEAD:
SMSC_TRACE0(DBG_INIT," OID_GEN_CURRENT_LOOKAHEAD\r\n");
ulGeneric = (DWORD)pAdapter->ulMaxLookAhead;
break;
case OID_GEN_MAXIMUM_LOOKAHEAD:
SMSC_TRACE0(DBG_INIT," OID_GEN_MAXIMUM_LOOKAHEAD\r\n");
ulGeneric = (DWORD)MAX_LOOKAHEAD;
break;
case OID_GEN_RECEIVE_BLOCK_SIZE:
SMSC_TRACE0(DBG_INIT," OID_GEN_RECEIVE_BLOCK_SIZE\r\n");
ulGeneric = (ULONG)MAX_PACKET;
break;
case OID_GEN_MAXIMUM_FRAME_SIZE:
SMSC_TRACE0(DBG_INIT," OID_GEN_MAXIMUM_FRAME_SIZE\r\n");
ulGeneric = (ULONG)(1514U - ETHER_HEADER_SIZE);
break;
case OID_GEN_MAXIMUM_TOTAL_SIZE:
SMSC_TRACE0(DBG_INIT," OID_GEN_MAXIMUM_TOTAL_SIZE\r\n");
ulGeneric = 1514UL;
break;
case OID_GEN_LINK_SPEED:
SMSC_TRACE0(DBG_INIT," OID_GEN_LINK_SPEED\r\n");
ulGeneric = 1000000UL;
break;
case OID_GEN_TRANSMIT_BUFFER_SPACE:
SMSC_TRACE0(DBG_INIT," OID_GEN_TRANSMIT_BUFFER_SPACE\r\n");
ulGeneric = TX_DATA_FIFO_SIZE;
break;
case OID_GEN_RECEIVE_BUFFER_SPACE:
SMSC_TRACE0(DBG_INIT," OID_GEN_RECEIVE_BUFFER_SPACE\r\n");
ulGeneric = RX_DATA_FIFO_SIZE;
break;
case OID_GEN_TRANSMIT_BLOCK_SIZE:
SMSC_TRACE0(DBG_INIT," OID_GEN_TRANSMIT_BLOCK_SIZE\r\n");
ulGeneric = (ULONG)MAX_PACKET;
break;
case OID_GEN_VENDOR_ID:
SMSC_TRACE0(DBG_INIT," OID_GEN_VENDOR_ID\r\n");
NdisMoveMemory ((PVOID)&ulGeneric, pAdapter->ucStationAddress, 3U);
ulGeneric &= 0xFFFFFF00UL;
ulGeneric |= 0x01UL;
pMoveSource = (PVOID)(&ulGeneric);
ulMoveBytes = (DWORD)sizeof (ulGeneric);
break;
case OID_GEN_VENDOR_DESCRIPTION:
SMSC_TRACE0(DBG_INIT," OID_GEN_VENDOR_DESCRIPTION\r\n");
pMoveSource = VendorString;
ulMoveBytes = (DWORD)sizeof (VendorString);
break;
case OID_GEN_DRIVER_VERSION:
SMSC_TRACE0(DBG_INIT," OID_GEN_DRIVER_VERSION\r\n");
usGeneric = (USHORT)((SMSC9118_NDIS_MAJOR_VERSION << 8) | SMSC9118_NDIS_MINOR_VERSION);
pMoveSource = (PVOID)(&usGeneric);
ulMoveBytes = (DWORD)sizeof (usGeneric);
break;
case OID_802_3_PERMANENT_ADDRESS:
SMSC_TRACE0(DBG_INIT," OID_802_3_PERMANENT_ADDRESS\r\n");
NdisMoveMemory ((PCHAR)ucGenericArray, pAdapter->ucStationAddress, ETHER_LENGTH_OF_ADDRESS);
pMoveSource = (PVOID)ucGenericArray;
ulMoveBytes = (DWORD)sizeof (pAdapter->ucStationAddress);
break;
case OID_802_3_CURRENT_ADDRESS:
SMSC_TRACE0(DBG_INIT," OID_802_3_CURRENT_ADDRESS\r\n");
NdisMoveMemory ((PCHAR)ucGenericArray, pAdapter->ucStationAddress, ETHER_LENGTH_OF_ADDRESS);
pMoveSource = (PVOID)ucGenericArray;
ulMoveBytes = (DWORD)sizeof (pAdapter->ucStationAddress);
break;
case OID_802_3_MULTICAST_LIST:
SMSC_TRACE0(DBG_INIT," OID_802_3_MULTICAST_LIST\r\n");
pMoveSource = (PVOID)(pAdapter->ucAddresses);
ulMoveBytes = (DWORD)(DEFAULT_MULTICASTLISTMAX*ETHER_LENGTH_OF_ADDRESS);
break;
case OID_802_3_MAXIMUM_LIST_SIZE:
SMSC_TRACE0(DBG_INIT," OID_802_3_MAXIMUM_LIST_SIZE\r\n");
ulGeneric = (DWORD)DEFAULT_MULTICASTLISTMAX;
break;
case OID_GEN_XMIT_OK:
SMSC_TRACE0(DBG_INIT," OID_GEN_XMIT_OK\r\n");
ulGeneric = (pAdapter->ulFramesXmitGood);
break;
case OID_GEN_RCV_OK:
SMSC_TRACE0(DBG_INIT," OID_GEN_RCV_OK\r\n");
ulGeneric = (pAdapter->ulFramesRcvGood);
break;
case OID_GEN_XMIT_ERROR:
SMSC_TRACE0(DBG_INIT," OID_GEN_XMIT_ERROR\r\n");
ulGeneric = (pAdapter->ulFramesXmitBad);
break;
case OID_GEN_RCV_ERROR:
SMSC_TRACE0(DBG_INIT," OID_GEN_RCV_ERROR\r\n");
ulGeneric = (pAdapter->ulFramesRcvBad);
break;
case OID_GEN_RCV_NO_BUFFER:
SMSC_TRACE0(DBG_INIT," OID_GEN_RCV_NO_BUFFER\r\n");
ulGeneric = (pAdapter->ulMissedPackets);
break;
case OID_GEN_MEDIA_CONNECT_STATUS:
SMSC_TRACE0(DBG_INIT," OID_GEN_MEDIA_CONNECT_STATUS\r\n");
if (LinkIndicate(pAdapter) == LINK_NO_LINK)
{
ulGeneric = (ULONG)NdisMediaStateDisconnected; /*lint !e930 */
}
else
{
ulGeneric = (ULONG)NdisMediaStateConnected; /*lint !e930 */
}
break;
case OID_GEN_MAXIMUM_SEND_PACKETS:
SMSC_TRACE0(DBG_INIT," OID_GEN_MAXIMUM_SEND_PACKETS\r\n");
ulGeneric = MAX_NUM_PACKETS_PER_SEND;
break;
case OID_GEN_VENDOR_DRIVER_VERSION:
usGeneric = (USHORT)DRIVER_VERSION;
pMoveSource = (PVOID)(&usGeneric);
ulMoveBytes = (DWORD)sizeof (usGeneric);
break;
case OID_802_3_RCV_ERROR_ALIGNMENT:
SMSC_TRACE0(DBG_INIT," OID_802_3_RCV_ERROR_ALIGNMENT\r\n");
ulGeneric = (pAdapter->ulFrameAlignmentErrors);
break;
case OID_802_3_XMIT_ONE_COLLISION:
SMSC_TRACE0(DBG_INIT," OID_802_3_XMIT_ONE_COLLISION\r\n");
ulGeneric = (pAdapter->ulFramesXmitOneCollision);
break;
case OID_802_3_XMIT_MORE_COLLISIONS:
SMSC_TRACE0(DBG_INIT," OID_802_3_XMIT_MORE_COLLISIONS\r\n");
ulGeneric = (pAdapter->ulFramesXmitManyCollisions);
break;
//
// Power Management
//
case OID_PNP_CAPABILITIES:
SMSC_TRACE0(DBG_POWER," OID_PNP_CAPABILITIES\r\n");
NdisZeroMemory(&NdisPnpCapabilities, sizeof(NdisPnpCapabilities));
NdisPnpCapabilities.WakeUpCapabilities.MinPatternWakeUp = NdisDeviceStateD1;
NdisPnpCapabilities.WakeUpCapabilities.MinLinkChangeWakeUp = NdisDeviceStateD1;
NdisPnpCapabilities.WakeUpCapabilities.MinMagicPacketWakeUp = NdisDeviceStateD1;
pMoveSource = (PVOID)&NdisPnpCapabilities;
ulMoveBytes = (DWORD)sizeof(NdisPnpCapabilities);
break;
case OID_PNP_QUERY_POWER:
SMSC_TRACE0(DBG_POWER," OID_PNP_QUERY_POWER\r\n");
PowerState = *(PDEVICE_POWER_STATE)pInformationBuffer;
if(PowerState == NdisDeviceStateD0) {
SMSC_TRACE0(DBG_POWER, "Device Power State = NdisDeviceStateD0.\r\n");
}
else if(PowerState == NdisDeviceStateD1) {
SMSC_TRACE0(DBG_POWER, "Device Power State = NdisDeviceStateD1.\r\n");
}
else if(PowerState == NdisDeviceStateD2) {
SMSC_TRACE0(DBG_POWER, "Device Power State = NdisDeviceStateD2.\r\n");
}
else if(PowerState == NdisDeviceStateD3) {
SMSC_TRACE0(DBG_POWER, "Device Power State = NdisDeviceStateD3.\r\n");
}
else {
SMSC_TRACE0(DBG_POWER, "Unkown Device Power State.\r\n");
}
break;
case OID_PNP_ENABLE_WAKE_UP:
SMSC_TRACE0(DBG_POWER," OID_PNP_ENABLE_WAKE_UP (QUERY)\r\n");
ulGeneric = pAdapter->dwWakeUpSource;
if((ulGeneric & (DWORD)(NDIS_PNP_WAKE_UP_LINK_CHANGE | NDIS_PNP_WAKE_UP_MAGIC_PACKET | NDIS_PNP_WAKE_UP_PATTERN_MATCH)) ==
(DWORD)(NDIS_PNP_WAKE_UP_LINK_CHANGE | NDIS_PNP_WAKE_UP_MAGIC_PACKET | NDIS_PNP_WAKE_UP_PATTERN_MATCH)
)
{
SMSC_WARNING0("NDIS_PNP_WAKE_UP_LINK_CHANGE is set with NDIS_PNP_WAKE_UP_MAGIC_PACKET, NDIS_PNP_WAKE_UP_PATTERN_MATCH.\r\n");
}
break;
case OID_NDIS_SMSC_DUMP_ALL_REGS:
DumpAllRegs(pAdapter);
break;
default:
SMSC_TRACE0(DBG_INIT," Unrecognized OID\r\n");
StatusToReturn = NDIS_STATUS_INVALID_OID;
break;
}
if (StatusToReturn == NDIS_STATUS_SUCCESS)
{
if (ulMoveBytes > ulInformationBufferLength)
{
SMSC_WARNING0(" Invalid Buffer Length\r\n");
*pulBytesNeeded = ulMoveBytes;
StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
}
else
{
SMSC_TRACE0(DBG_INIT," Information Moved Successfully\r\n");
if ((ulMoveBytes > 0x00UL) && (pInformationBuffer != NULL)) {
NdisMoveMemory (pInformationBuffer, pMoveSource, (UINT)ulMoveBytes);
(*pulBytesWritten) += ulMoveBytes;
}
}
}
// Make Lint Happy
ulInformationBufferLength = ulInformationBufferLength;
SMSC_TRACE0(DBG_INIT,"-Smsc9118QueryInformation\r\n");
return (StatusToReturn);
}
/*----------------------------------------------------------------------------
ComputeCrc
Calculate CRC32 for multicast function.
*/
DWORD ComputeCrc(IN const CPUCHAR pBuffer, IN const UINT uiLength)
{
UINT i;
DWORD crc = 0xFFFFFFFFUL;
DWORD result = 0UL;
const DWORD poly = 0xEDB88320UL;
SMSC_TRACE0(DBG_INIT,"+ComputeCrc\r\n");
SMSC_TRACE1(DBG_INIT,"uiLength=%d\r\n", uiLength);
for(i=0U; i<uiLength; i++)
{
int bit;
DWORD data=((DWORD)pBuffer[i]);
for(bit=0; bit<8; bit++)
{
const DWORD p = (crc^((DWORD)data))&1UL;
crc >>= 1;
if(p != 0UL) {
crc ^= poly;
}
data >>=1;
}
}
result=((crc&0x01UL)<<5)|
((crc&0x02UL)<<3)|
((crc&0x04UL)<<1)|
((crc&0x08UL)>>1)|
((crc&0x10UL)>>3)|
((crc&0x20UL)>>5);
SMSC_TRACE0(DBG_INIT,"-ComputeCrc\r\n");
return (result);
}
/*----------------------------------------------------------------------------
GetMulticastBit
Calculate multicase table.
*/
VOID
GetMulticastBit(IN const UCHAR * const ucAddress, OUT PUCHAR const pTable, OUT PULONG const pValue)
{
DWORD uiBitNumber;
SMSC_TRACE0(DBG_INIT,"+GetMulticastBit\r\n");
uiBitNumber = ComputeCrc(ucAddress, (UINT)ETHER_LENGTH_OF_ADDRESS);
*pTable = (UCHAR)(((uiBitNumber & 0x20UL) >> 5) & 1UL);
*pValue = (DWORD)(1UL << (uiBitNumber & 0x1FUL));
SMSC_TRACE0(DBG_INIT,"-GetMulticastBit\r\n");
}
void DisableMacRxEn(CPCSMSC9118_ADAPTER pAdapter)
{
volatile DWORD dwReg;
// Disable RX
dwReg = Lan_GetMacRegDW(pAdapter->lan9118_data.dwLanBase, MAC_CR);
if (dwReg & MAC_CR_RXEN_)
{
volatile long counter;
SetRegDW(pAdapter->lan9118_data.dwLanBase, INT_STS, INT_STS_RXSTOP_INT_);
dwReg = Lan_GetMacRegDW(pAdapter->lan9118_data.dwLanBase, MAC_CR);
dwReg &= ~MAC_CR_RXEN_;
Lan_SetMacRegDW(pAdapter->lan9118_data.dwLanBase, MAC_CR, dwReg);
counter = (long)GetRegDW(pAdapter->lan9118_data.dwLanBase, FREE_RUN);
while (!((dwReg=GetRegDW(pAdapter->lan9118_data.dwLanBase, INT_STS)) & INT_STS_RXSTOP_INT_))
{
if (((long)GetRegDW(pAdapter->lan9118_data.dwLanBase, FREE_RUN) - counter) > (25L*2000L))
{
break;
}
}
SetRegDW(pAdapter->lan9118_data.dwLanBase, INT_STS, INT_STS_RXSTOP_INT_);
}
}
void DelayUsingFreeRun(CPCSMSC9118_ADAPTER pAdapter, const LONG uSec)
{
volatile long counter;
counter = (long)GetRegDW(pAdapter->lan9118_data.dwLanBase, FREE_RUN);
while (((long)GetRegDW(pAdapter->lan9118_data.dwLanBase, FREE_RUN) - counter) < (25L*uSec))
{
}
}
void EnableMacRxEn(CPCSMSC9118_ADAPTER pAdapter)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -