📄 nic_init.c
字号:
//
if (pPciConfig->VendorID != NIC_PCI_VENDOR_ID ||
pPciConfig->DeviceID != NIC_PCI_DEVICE_ID)
{
DebugPrint(ERROR, DBG_INIT,
"VendorID/DeviceID don't match - %x/%x\n",
pPciConfig->VendorID, pPciConfig->DeviceID);
//return STATUS_DEVICE_DOES_NOT_EXIST;
}
//
// save info from config space
//
FdoData->RevsionID = pPciConfig->RevisionID;
FdoData->SubVendorID = pPciConfig->u.type0.SubVendorID;
FdoData->SubSystemID = pPciConfig->u.type0.SubSystemID;
NICExtractPMInfoFromPciSpace (FdoData, (PUCHAR)pPciConfig);
usPciCommand = pPciConfig->Command;
if ((usPciCommand & PCI_ENABLE_WRITE_AND_INVALIDATE) && (FdoData->MWIEnable)){
FdoData->MWIEnable = TRUE;
} else {
FdoData->MWIEnable = FALSE;
}
DebugPrint(TRACE, DBG_INIT, "<-- NICGetDeviceInformation\n");
return status;
}
NTSTATUS
NICReadAdapterInfo(
IN PFDO_DATA FdoData
)
/*++
Routine Description:
Read the mac addresss from the adapter
Arguments:
FdoData Pointer to our device context
Return Value:
NTSTATUS code
--*/
{
NTSTATUS status = STATUS_SUCCESS;
USHORT usValue;
int i;
DebugPrint(TRACE, DBG_INIT, "--> NICReadAdapterInfo\n");
FdoData->EepromAddressSize = GetEEpromAddressSize(
GetEEpromSize(FdoData, (PUCHAR)FdoData->IoBaseAddress));
DebugPrint(LOUD, DBG_INIT, "EepromAddressSize = %d\n",
FdoData->EepromAddressSize);
//
// Read node address from the EEPROM
//
for (i=0; i< ETH_LENGTH_OF_ADDRESS; i += 2)
{
usValue = ReadEEprom(FdoData, (PUCHAR)FdoData->IoBaseAddress,
(USHORT)(EEPROM_NODE_ADDRESS_BYTE_0 + (i/2)),
FdoData->EepromAddressSize);
*((PUSHORT)(&FdoData->PermanentAddress[i])) = usValue;
}
DebugPrint(INFO, DBG_INIT,
"Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
FdoData->PermanentAddress[0], FdoData->PermanentAddress[1],
FdoData->PermanentAddress[2], FdoData->PermanentAddress[3],
FdoData->PermanentAddress[4], FdoData->PermanentAddress[5]);
if (ETH_IS_MULTICAST(FdoData->PermanentAddress) ||
ETH_IS_BROADCAST(FdoData->PermanentAddress))
{
DebugPrint(ERROR, DBG_INIT, "Permanent address is invalid\n");
status = STATUS_INVALID_ADDRESS;
}
else
{
if (!FdoData->bOverrideAddress)
{
ETH_COPY_NETWORK_ADDRESS(FdoData->CurrentAddress, FdoData->PermanentAddress);
}
DebugPrint(INFO, DBG_INIT,
"Current Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
FdoData->CurrentAddress[0], FdoData->CurrentAddress[1],
FdoData->CurrentAddress[2], FdoData->CurrentAddress[3],
FdoData->CurrentAddress[4], FdoData->CurrentAddress[5]);
}
DebugPrint(TRACE, DBG_INIT, "<-- NICReadAdapterInfo, status=%x\n",
status);
return status;
}
NTSTATUS
NICAllocAdapterMemory(
IN PFDO_DATA FdoData
)
/*++
Routine Description:
Allocate all the memory blocks for send, receive and others
Arguments:
FdoData Pointer to our adapter
Return Value:
--*/
{
NTSTATUS status = STATUS_SUCCESS;
PUCHAR pMem;
ULONG MemPhys;
PDMA_ADAPTER DmaAdapterObject;
DmaAdapterObject = FdoData->DmaAdapterObject;
DebugPrint(TRACE, DBG_INIT, "--> NICAllocAdapterMemory\n");
DebugPrint(LOUD, DBG_INIT, "NumTcb=%d\n", FdoData->NumTcb);
FdoData->NumTbd = FdoData->NumTcb * NIC_MAX_PHYS_BUF_COUNT;
do
{
#if defined(DMA_VER2)
ExInitializeNPagedLookasideList(&FdoData->SGListLookasideList,
NULL,
NULL,
0,
FdoData->ScatterGatherListSize,
PCIDRV_POOL_TAG,
0);
MP_SET_FLAG(FdoData, fMP_ADAPTER_SEND_SGL_LOOKASIDE);
#endif
//
// Send + Misc
//
//
// Allocate MP_TCB's
//
FdoData->MpTcbMemSize = FdoData->NumTcb * sizeof(MP_TCB);
pMem = ExAllocatePoolWithTag(NonPagedPool,
FdoData->MpTcbMemSize, PCIDRV_POOL_TAG);
if (NULL == pMem )
{
status = STATUS_INSUFFICIENT_RESOURCES;
DebugPrint(ERROR, DBG_INIT, "Failed to allocate MP_TCB's\n");
break;
}
RtlZeroMemory(pMem, FdoData->MpTcbMemSize);
FdoData->MpTcbMem = pMem;
// HW_START
//
// Allocate shared memory for send
//
FdoData->HwSendMemAllocSize = FdoData->NumTcb * (sizeof(TXCB_STRUC) +
NIC_MAX_PHYS_BUF_COUNT * sizeof(TBD_STRUC));
FdoData->HwSendMemAllocVa = FdoData->AllocateCommonBuffer(
DmaAdapterObject,
FdoData->HwSendMemAllocSize,
&FdoData->HwSendMemAllocPa,
FALSE // NOT CACHED
);
if (!FdoData->HwSendMemAllocVa)
{
DebugPrint(ERROR, DBG_INIT,
"Failed to allocate send memory\n");
status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
RtlZeroMemory(FdoData->HwSendMemAllocVa,
FdoData->HwSendMemAllocSize);
//
// Allocate shared memory for other uses
//
FdoData->HwMiscMemAllocSize =
sizeof(SELF_TEST_STRUC) + ALIGN_16 +
sizeof(DUMP_AREA_STRUC) + ALIGN_16 +
sizeof(NON_TRANSMIT_CB) + ALIGN_16 +
sizeof(ERR_COUNT_STRUC) + ALIGN_16;
//
// Allocate the shared memory for the command block data structures.
//
FdoData->HwMiscMemAllocVa = FdoData->AllocateCommonBuffer(
DmaAdapterObject,
FdoData->HwMiscMemAllocSize,
&FdoData->HwMiscMemAllocPa,
FALSE // NOT CACHED
);
if (!FdoData->HwMiscMemAllocVa)
{
DebugPrint(ERROR, DBG_INIT,
"Failed to allocate misc memory\n");
status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
RtlZeroMemory(FdoData->HwMiscMemAllocVa,
FdoData->HwMiscMemAllocSize);
pMem = FdoData->HwMiscMemAllocVa;
MemPhys = FdoData->HwMiscMemAllocPa.LowPart ;
FdoData->SelfTest = (PSELF_TEST_STRUC)MP_ALIGNMEM(pMem, ALIGN_16);
FdoData->SelfTestPhys = MP_ALIGNMEM_PHYS(MemPhys, ALIGN_16);
pMem = (PUCHAR)FdoData->SelfTest + sizeof(SELF_TEST_STRUC);
MemPhys = FdoData->SelfTestPhys + sizeof(SELF_TEST_STRUC);
FdoData->NonTxCmdBlock = (PNON_TRANSMIT_CB)MP_ALIGNMEM(pMem, ALIGN_16);
FdoData->NonTxCmdBlockPhys = MP_ALIGNMEM_PHYS(MemPhys, ALIGN_16);
pMem = (PUCHAR)FdoData->NonTxCmdBlock + sizeof(NON_TRANSMIT_CB);
MemPhys = FdoData->NonTxCmdBlockPhys + sizeof(NON_TRANSMIT_CB);
FdoData->DumpSpace = (PDUMP_AREA_STRUC)MP_ALIGNMEM(pMem, ALIGN_16);
FdoData->DumpSpacePhys = MP_ALIGNMEM_PHYS(MemPhys, ALIGN_16);
pMem = (PUCHAR)FdoData->DumpSpace + sizeof(DUMP_AREA_STRUC);
MemPhys = FdoData->DumpSpacePhys + sizeof(DUMP_AREA_STRUC);
FdoData->StatsCounters = (PERR_COUNT_STRUC)MP_ALIGNMEM(pMem, ALIGN_16);
FdoData->StatsCounterPhys = MP_ALIGNMEM_PHYS(MemPhys, ALIGN_16);
// HW_END
//
// Recv
//
ExInitializeNPagedLookasideList(
&FdoData->RecvLookaside,
NULL,
NULL,
0,
sizeof(MP_RFD),
PCIDRV_POOL_TAG,
0);
MP_SET_FLAG(FdoData, fMP_ADAPTER_RECV_LOOKASIDE);
// set the max number of RFDs
// disable the RFD grow/shrink scheme if user specifies a NumRfd value
// larger than NIC_MAX_GROW_RFDS
FdoData->MaxNumRfd = max(FdoData->NumRfd, NIC_MAX_GROW_RFDS);
DebugPrint(LOUD, DBG_INIT, "NumRfd = %d\n", FdoData->NumRfd);
DebugPrint(LOUD, DBG_INIT, "MaxNumRfd = %d\n",
FdoData->MaxNumRfd);
//
// The driver should allocate more data than sizeof(RFD_STRUC) to allow the
// driver to align the data(after ethernet header) at 8 byte boundary
//
FdoData->HwRfdSize = sizeof(RFD_STRUC) + MORE_DATA_FOR_ALIGN;
status = STATUS_SUCCESS;
} while (FALSE);
DebugPrint(TRACE, DBG_INIT,
"<-- NICAllocAdapterMemory, status=%x\n", status);
return status;
}
VOID
NICFreeAdapterMemory(
IN PFDO_DATA FdoData
)
/*++
Routine Description:
Free all the resources and MP_ADAPTER data block
Arguments:
FdoData Pointer to our adapter
Return Value:
None
--*/
{
PMP_RFD pMpRfd;
DebugPrint(TRACE, DBG_INIT, "--> NICFreeAdapterMemory\n");
// No active and waiting sends
ASSERT(FdoData->nBusySend == 0);
ASSERT(FdoData->nWaitSend == 0);
ASSERT(IsListEmpty(&FdoData->SendQueueHead));
#if defined(DMA_VER2)
if(MP_TEST_FLAG(FdoData, fMP_ADAPTER_SEND_SGL_LOOKASIDE))
{
ExDeleteNPagedLookasideList(&FdoData->SGListLookasideList);
MP_CLEAR_FLAG(FdoData, fMP_ADAPTER_SEND_SGL_LOOKASIDE);
}
#endif
ASSERT(FdoData->nReadyRecv == FdoData->CurrNumRfd);
while (!IsListEmpty(&FdoData->RecvList))
{
pMpRfd = (PMP_RFD)RemoveHeadList(&FdoData->RecvList);
NICFreeRfd(FdoData, pMpRfd);
}
if (MP_TEST_FLAG(FdoData, fMP_ADAPTER_RECV_LOOKASIDE))
{
ExDeleteNPagedLookasideList(&FdoData->RecvLookaside);
MP_CLEAR_FLAG(FdoData, fMP_ADAPTER_RECV_LOOKASIDE);
}
// Free the shared memory for HW_TCB structures
if (FdoData->HwSendMemAllocVa)
{
FdoData->FreeCommonBuffer(
FdoData->DmaAdapterObject,
FdoData->HwSendMemAllocSize,
FdoData->HwSendMemAllocPa,
FdoData->HwSendMemAllocVa,
FALSE);
FdoData->HwSendMemAllocVa = NULL;
}
// Free the shared memory for other command data structures
if (FdoData->HwMiscMemAllocVa)
{
FdoData->FreeCommonBuffer(
FdoData->DmaAdapterObject,
FdoData->HwMiscMemAllocSize,
FdoData->HwMiscMemAllocPa,
FdoData->HwMiscMemAllocVa,
FALSE);
FdoData->HwMiscMemAllocVa = NULL;
FdoData->SelfTest = NULL;
FdoData->StatsCounters = NULL;
FdoData->NonTxCmdBlock = NULL;
FdoData->DumpSpace = NULL;
}
// Free the memory for MP_TCB structures
if (FdoData->MpTcbMem)
{
ExFreePoolWithTag(FdoData->MpTcbMem, PCIDRV_POOL_TAG);
FdoData->MpTcbMem = NULL;
}
//Free all the wake up patterns on this adapter
NICRemoveAllWakeUpPatterns(FdoData);
DebugPrint(TRACE, DBG_INIT, "<-- NICFreeAdapterMemory\n");
}
VOID
NICInitSend(
IN PFDO_DATA FdoData
)
/*++
Routine Description:
Initialize send data structures. Can be called at DISPATCH_LEVEL.
Arguments:
FdoData Pointer to our adapter
Return Value:
None
--*/
{
PMP_TCB pMpTcb;
PHW_TCB pHwTcb;
ULONG HwTcbPhys;
LONG TcbCount;
PTBD_STRUC pHwTbd;
ULONG HwTbdPhys;
DebugPrint(TRACE, DBG_INIT, "--> NICInitSend\n");
FdoData->TransmitIdle = TRUE;
FdoData->ResumeWait = TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -