📄 mp_init.c
字号:
/*++
Copyright (c) 1999 Microsoft Corporation
Module Name:
mp_init.c
Abstract:
This module contains miniport initialization related routines
Revision History:
Who When What
-------- -------- ----------------------------------------------
DChen 11-01-99 created
Notes:
--*/
#include "precomp.h"
#if DBG
#define _FILENUMBER 'TINI'
#endif
typedef struct _MP_REG_ENTRY
{
NDIS_STRING RegName; // variable name text
BOOLEAN bRequired; // 1 -> required, 0 -> optional
UINT FieldOffset; // offset to MP_ADAPTER field
UINT FieldSize; // size (in bytes) of the field
UINT Default; // default value to use
UINT Min; // minimum value allowed
UINT Max; // maximum value allowed
} MP_REG_ENTRY, *PMP_REG_ENTRY;
MP_REG_ENTRY NICRegTable[] = {
// reg value name Offset in MP_ADAPTER Field size Default Value Min Max
#if DBG
{NDIS_STRING_CONST("Debug"), 0, MP_OFFSET(Debug), MP_SIZE(Debug), MP_WARN, 0, 0xffffffff},
#endif
{NDIS_STRING_CONST("NumRfd"), 0, MP_OFFSET(NumRfd), MP_SIZE(NumRfd), 32, NIC_MIN_RFDS, NIC_MAX_RFDS},
{NDIS_STRING_CONST("NumTcb"), 0, MP_OFFSET(NumTcb), MP_SIZE(NumTcb), NIC_DEF_TCBS, 1, NIC_MAX_TCBS},
{NDIS_STRING_CONST("NumCoalesce"), 0, MP_OFFSET(NumBuffers), MP_SIZE(NumBuffers), 8, 1, 32},
{NDIS_STRING_CONST("PhyAddress"), 0, MP_OFFSET(PhyAddress), MP_SIZE(PhyAddress), 0xFF, 0, 0xFF},
{NDIS_STRING_CONST("Connector"), 0, MP_OFFSET(Connector), MP_SIZE(Connector), 0, 0, 0x2},
{NDIS_STRING_CONST("TxFifo"), 0, MP_OFFSET(AiTxFifo), MP_SIZE(AiTxFifo), DEFAULT_TX_FIFO_LIMIT, 0, 15},
{NDIS_STRING_CONST("RxFifo"), 0, MP_OFFSET(AiRxFifo), MP_SIZE(AiRxFifo), DEFAULT_RX_FIFO_LIMIT, 0, 15},
{NDIS_STRING_CONST("TxDmaCount"), 0, MP_OFFSET(AiTxDmaCount), MP_SIZE(AiTxDmaCount), 0, 0, 63},
{NDIS_STRING_CONST("RxDmaCount"), 0, MP_OFFSET(AiRxDmaCount), MP_SIZE(AiRxDmaCount), 0, 0, 63},
{NDIS_STRING_CONST("UnderrunRetry"), 0, MP_OFFSET(AiUnderrunRetry), MP_SIZE(AiUnderrunRetry), DEFAULT_UNDERRUN_RETRY, 0, 3},
{NDIS_STRING_CONST("Threshold"), 0, MP_OFFSET(AiThreshold), MP_SIZE(AiThreshold), 200, 0, 200},
{NDIS_STRING_CONST("MWIEnable"), 0, MP_OFFSET(MWIEnable), MP_SIZE(MWIEnable), 1, 0, 1},
{NDIS_STRING_CONST("Congest"), 0, MP_OFFSET(Congest), MP_SIZE(Congest), 0, 0, 0x1},
{NDIS_STRING_CONST("SpeedDuplex"), 0, MP_OFFSET(SpeedDuplex), MP_SIZE(SpeedDuplex), 0, 0, 4}
};
#define NIC_NUM_REG_PARAMS (sizeof (NICRegTable) / sizeof(MP_REG_ENTRY))
#if LBFO
NDIS_STRING strBundleId = NDIS_STRING_CONST("BundleId");
#endif
NDIS_STATUS MpFindAdapter(
IN PMP_ADAPTER Adapter,
IN NDIS_HANDLE WrapperConfigurationContext
)
/*++
Routine Description:
Find the adapter and get all the assigned resources
Arguments:
Adapter Pointer to our adapter
Return Value:
NDIS_STATUS_SUCCESS
NDIS_STATUS_ADAPTER_NOT_FOUND (event is logged as well)
--*/
{
NDIS_STATUS Status = NDIS_STATUS_ADAPTER_NOT_FOUND;
ULONG ErrorCode = 0;
ULONG ErrorValue = 0;
ULONG ulResult;
UCHAR buffer[NIC_PCI_E100_HDR_LENGTH ];
PPCI_COMMON_CONFIG pPciConfig = (PPCI_COMMON_CONFIG) buffer;
USHORT usPciCommand;
UCHAR resBuf[NIC_RESOURCE_BUF_SIZE];
PNDIS_RESOURCE_LIST resList = (PNDIS_RESOURCE_LIST)resBuf;
UINT bufSize = NIC_RESOURCE_BUF_SIZE;
PCM_PARTIAL_RESOURCE_DESCRIPTOR pResDesc;
ULONG index;
BOOLEAN bResPort = FALSE, bResInterrupt = FALSE, bResMemory = FALSE;
DBGPRINT(MP_TRACE, ("---> MpFindAdapter\n"));
do
{
//
// Make sure the adpater is present
//
ulResult = NdisReadPciSlotInformation(
Adapter->AdapterHandle,
0, // not used
FIELD_OFFSET(PCI_COMMON_CONFIG, VendorID),
buffer,
NIC_PCI_E100_HDR_LENGTH );
if (ulResult != NIC_PCI_E100_HDR_LENGTH )
{
DBGPRINT(MP_ERROR,
("NdisReadPciSlotInformation (PCI_COMMON_CONFIG) ulResult=%d\n", ulResult));
ErrorCode = NDIS_ERROR_CODE_ADAPTER_NOT_FOUND;
ErrorValue = ERRLOG_READ_PCI_SLOT_FAILED;
break;
}
//
// Right type of adapter?
//
if (pPciConfig->VendorID != NIC_PCI_VENDOR_ID ||
pPciConfig->DeviceID != NIC_PCI_DEVICE_ID)
{
DBGPRINT(MP_ERROR, ("VendorID/DeviceID don't match - %x/%x\n",
pPciConfig->VendorID, pPciConfig->DeviceID));
ErrorCode = NDIS_ERROR_CODE_ADAPTER_NOT_FOUND;
ErrorValue = ERRLOG_VENDOR_DEVICE_NOMATCH;
break;
}
DBGPRINT(MP_INFO, ("Adapter is found - VendorID/DeviceID=%x/%x\n",
pPciConfig->VendorID, pPciConfig->DeviceID));
// save info from config space
Adapter->RevsionID = pPciConfig->RevisionID;
Adapter->SubVendorID = pPciConfig->u.type0.SubVendorID;
Adapter->SubSystemID = pPciConfig->u.type0.SubSystemID;
MpExtractPMInfoFromPciSpace (Adapter, (PUCHAR)pPciConfig);
// --- HW_START
usPciCommand = pPciConfig->Command;
if ((usPciCommand & PCI_ENABLE_WRITE_AND_INVALIDATE) && (Adapter->MWIEnable))
Adapter->MWIEnable = TRUE;
else
Adapter->MWIEnable = FALSE;
// Enable bus matering if it isn't enabled by the BIOS
if (!(usPciCommand & PCI_ENABLE_BUS_MASTER))
{
DBGPRINT(MP_WARN, ("Bus master is not enabled by BIOS! usPciCommand=%x\n",
usPciCommand));
usPciCommand |= CMD_BUS_MASTER;
ulResult = NdisWritePciSlotInformation(
Adapter->AdapterHandle,
0,
FIELD_OFFSET(PCI_COMMON_CONFIG, Command),
&usPciCommand,
sizeof(USHORT));
if (ulResult != sizeof(USHORT))
{
DBGPRINT(MP_ERROR,
("NdisWritePciSlotInformation (Command) ulResult=%d\n", ulResult));
ErrorCode = NDIS_ERROR_CODE_ADAPTER_NOT_FOUND;
ErrorValue = ERRLOG_WRITE_PCI_SLOT_FAILED;
break;
}
ulResult = NdisReadPciSlotInformation(
Adapter->AdapterHandle,
0,
FIELD_OFFSET(PCI_COMMON_CONFIG, Command),
&usPciCommand,
sizeof(USHORT));
if (ulResult != sizeof(USHORT))
{
DBGPRINT(MP_ERROR,
("NdisReadPciSlotInformation (Command) ulResult=%d\n", ulResult));
ErrorCode = NDIS_ERROR_CODE_ADAPTER_NOT_FOUND;
ErrorValue = ERRLOG_READ_PCI_SLOT_FAILED;
break;
}
if (!(usPciCommand & PCI_ENABLE_BUS_MASTER))
{
DBGPRINT(MP_ERROR, ("Failed to enable bus master! usPciCommand=%x\n",
usPciCommand));
ErrorCode = NDIS_ERROR_CODE_ADAPTER_DISABLED;
ErrorValue = ERRLOG_BUS_MASTER_DISABLED;
break;
}
}
DBGPRINT(MP_INFO, ("Bus master is enabled. usPciCommand=%x\n", usPciCommand));
// --- HW_END
//
// Adapter is found. Now get the assigned resources
//
NdisMQueryAdapterResources(
&Status,
WrapperConfigurationContext,
resList,
&bufSize);
if (Status != NDIS_STATUS_SUCCESS)
{
ErrorCode = NDIS_ERROR_CODE_RESOURCE_CONFLICT;
ErrorValue = ERRLOG_QUERY_ADAPTER_RESOURCES;
break;
}
for (index=0; index < resList->Count; index++)
{
pResDesc = &resList->PartialDescriptors[index];
switch(pResDesc->Type)
{
case CmResourceTypePort:
Adapter->IoBaseAddress = NdisGetPhysicalAddressLow(pResDesc->u.Port.Start);
Adapter->IoRange = pResDesc->u.Port.Length;
bResPort = TRUE;
DBGPRINT(MP_INFO, ("IoBaseAddress = 0x%x\n", Adapter->IoBaseAddress));
DBGPRINT(MP_INFO, ("IoRange = x%x\n", Adapter->IoRange));
break;
case CmResourceTypeInterrupt:
Adapter->InterruptLevel = pResDesc->u.Interrupt.Level;
bResInterrupt = TRUE;
DBGPRINT(MP_INFO, ("InterruptLevel = x%x\n", Adapter->InterruptLevel));
break;
case CmResourceTypeMemory:
// Our CSR memory space should be 0x1000, other memory is for
// flash address, a boot ROM address, etc.
if (pResDesc->u.Memory.Length == 0x1000)
{
Adapter->MemPhysAddress = pResDesc->u.Memory.Start;
bResMemory = TRUE;
DBGPRINT(MP_INFO,
("MemPhysAddress(Low) = 0x%0x\n", NdisGetPhysicalAddressLow(Adapter->MemPhysAddress)));
DBGPRINT(MP_INFO,
("MemPhysAddress(High) = 0x%0x\n", NdisGetPhysicalAddressHigh(Adapter->MemPhysAddress)));
}
break;
}
}
if (!bResPort || !bResInterrupt || !bResMemory)
{
Status = NDIS_STATUS_RESOURCE_CONFLICT;
ErrorCode = NDIS_ERROR_CODE_RESOURCE_CONFLICT;
if (!bResPort)
{
ErrorValue = ERRLOG_NO_IO_RESOURCE;
}
else if (!bResInterrupt)
{
ErrorValue = ERRLOG_NO_INTERRUPT_RESOURCE;
}
else
{
ErrorValue = ERRLOG_NO_MEMORY_RESOURCE;
}
break;
}
Status = NDIS_STATUS_SUCCESS;
} while (FALSE);
if (Status != NDIS_STATUS_SUCCESS)
{
NdisWriteErrorLogEntry(
Adapter->AdapterHandle,
ErrorCode,
1,
ErrorValue);
}
DBGPRINT_S(Status, ("<--- MpFindAdapter, Status=%x\n", Status));
return Status;
}
NDIS_STATUS NICReadAdapterInfo(
IN PMP_ADAPTER Adapter)
/*++
Routine Description:
Read the mac addresss from the adapter
Arguments:
Adapter Pointer to our adapter
Return Value:
NDIS_STATUS_SUCCESS
NDIS_STATUS_INVALID_ADDRESS
--*/
{
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
USHORT usValue;
int i;
DBGPRINT(MP_TRACE, ("--> NICReadAdapterInfo\n"));
Adapter->EepromAddressSize =
GetEEpromAddressSize(GetEEpromSize(Adapter->PortOffset));
DBGPRINT(MP_WARN, ("EepromAddressSize = %d\n", Adapter->EepromAddressSize));
//
// Read node address from the EEPROM
//
for (i=0; i< ETH_LENGTH_OF_ADDRESS; i += 2)
{
usValue = ReadEEprom(Adapter->PortOffset,
(USHORT)(EEPROM_NODE_ADDRESS_BYTE_0 + (i/2)),
Adapter->EepromAddressSize);
*((PUSHORT)(&Adapter->PermanentAddress[i])) = usValue;
}
DBGPRINT(MP_INFO, ("Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
Adapter->PermanentAddress[0], Adapter->PermanentAddress[1],
Adapter->PermanentAddress[2], Adapter->PermanentAddress[3],
Adapter->PermanentAddress[4], Adapter->PermanentAddress[5]));
if (ETH_IS_MULTICAST(Adapter->PermanentAddress) ||
ETH_IS_BROADCAST(Adapter->PermanentAddress))
{
DBGPRINT(MP_ERROR, ("Permanent address is invalid\n"));
NdisWriteErrorLogEntry(
Adapter->AdapterHandle,
NDIS_ERROR_CODE_NETWORK_ADDRESS,
0);
Status = NDIS_STATUS_INVALID_ADDRESS;
}
else
{
if (!Adapter->bOverrideAddress)
{
ETH_COPY_NETWORK_ADDRESS(Adapter->CurrentAddress, Adapter->PermanentAddress);
}
DBGPRINT(MP_INFO, ("Current Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
Adapter->CurrentAddress[0], Adapter->CurrentAddress[1],
Adapter->CurrentAddress[2], Adapter->CurrentAddress[3],
Adapter->CurrentAddress[4], Adapter->CurrentAddress[5]));
}
DBGPRINT_S(Status, ("<-- NICReadAdapterInfo, Status=%x\n", Status));
return Status;
}
NDIS_STATUS MpAllocAdapterBlock(
OUT PMP_ADAPTER *pAdapter)
/*++
Routine Description:
Allocate MP_ADAPTER data block and do some initialization
Arguments:
Adapter Pointer to receive pointer to our adapter
Return Value:
NDIS_STATUS_SUCCESS
NDIS_STATUS_FAILURE
--*/
{
PMP_ADAPTER Adapter;
NDIS_STATUS Status;
DBGPRINT(MP_TRACE, ("--> NICAllocAdapter\n"));
*pAdapter = NULL;
do
{
// Allocate MP_ADAPTER block
Status = MP_ALLOCMEMTAG(&Adapter, sizeof(MP_ADAPTER));
if (Status != NDIS_STATUS_SUCCESS)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -