📄 mp_init.c
字号:
return Status;
}
VOID NICInitSend(
IN PMP_ADAPTER Adapter)
/*++
Routine Description:
Initialize send data structures
Arguments:
Adapter Pointer to our adapter
Return Value:
None
--*/
{
PMP_TCB pMpTcb;
PHW_TCB pHwTcb;
ULONG HwTcbPhys;
LONG TcbCount;
PTBD_STRUC pHwTbd;
ULONG HwTbdPhys;
DBGPRINT(MP_TRACE, ("--> NICInitSend\n"));
Adapter->TransmitIdle = TRUE;
Adapter->ResumeWait = TRUE;
// Setup the initial pointers to the SW and HW TCB data space
pMpTcb = (PMP_TCB) Adapter->MpTcbMem;
pHwTcb = (PHW_TCB) Adapter->HwSendMemAllocVa;
HwTcbPhys = NdisGetPhysicalAddressLow(Adapter->HwSendMemAllocPa);
// Setup the initial pointers to the TBD data space.
// TBDs are located immediately following the TCBs
pHwTbd = (PTBD_STRUC) (Adapter->HwSendMemAllocVa +
(sizeof(TXCB_STRUC) * Adapter->NumTcb));
HwTbdPhys = HwTcbPhys + (sizeof(TXCB_STRUC) * Adapter->NumTcb);
// Go through and set up each TCB
for (TcbCount = 0; TcbCount < Adapter->NumTcb; TcbCount++)
{
pMpTcb->HwTcb = pHwTcb; // save ptr to HW TCB
pMpTcb->HwTcbPhys = HwTcbPhys; // save HW TCB physical address
pMpTcb->HwTbd = pHwTbd; // save ptr to TBD array
pMpTcb->HwTbdPhys = HwTbdPhys; // save TBD array physical address
if (TcbCount)
pMpTcb->PrevHwTcb = pHwTcb - 1;
else
pMpTcb->PrevHwTcb = (PHW_TCB)((PUCHAR)Adapter->HwSendMemAllocVa +
((Adapter->NumTcb - 1) * sizeof(HW_TCB)));
pHwTcb->TxCbHeader.CbStatus = 0; // clear the status
pHwTcb->TxCbHeader.CbCommand = CB_EL_BIT | CB_TX_SF_BIT | CB_TRANSMIT;
// Set the link pointer in HW TCB to the next TCB in the chain.
// If this is the last TCB in the chain, then set it to the first TCB.
if (TcbCount < Adapter->NumTcb - 1)
{
pMpTcb->Next = pMpTcb + 1;
pHwTcb->TxCbHeader.CbLinkPointer = HwTcbPhys + sizeof(HW_TCB);
}
else
{
pMpTcb->Next = (PMP_TCB) Adapter->MpTcbMem;
pHwTcb->TxCbHeader.CbLinkPointer =
NdisGetPhysicalAddressLow(Adapter->HwSendMemAllocPa);
}
pHwTcb->TxCbThreshold = (UCHAR) Adapter->AiThreshold;
pHwTcb->TxCbTbdPointer = HwTbdPhys;
pMpTcb++;
pHwTcb++;
HwTcbPhys += sizeof(TXCB_STRUC);
pHwTbd = (PTBD_STRUC)((PUCHAR)pHwTbd + sizeof(TBD_STRUC) * NIC_MAX_PHYS_BUF_COUNT);
HwTbdPhys += sizeof(TBD_STRUC) * NIC_MAX_PHYS_BUF_COUNT;
}
// set the TCB head/tail indexes
// head is the olded one to free, tail is the next one to use
Adapter->CurrSendHead = (PMP_TCB) Adapter->MpTcbMem;
Adapter->CurrSendTail = (PMP_TCB) Adapter->MpTcbMem;
DBGPRINT(MP_TRACE, ("<-- NICInitSend, Status=%x\n"));
}
NDIS_STATUS NICInitRecv(
IN PMP_ADAPTER Adapter)
/*++
Routine Description:
Initialize receive data structures
Arguments:
Adapter Pointer to our adapter
Return Value:
NDIS_STATUS_SUCCESS
NDIS_STATUS_RESOURCES
--*/
{
NDIS_STATUS Status = NDIS_STATUS_RESOURCES;
PMP_RFD pMpRfd;
LONG RfdCount;
ULONG ErrorValue = 0;
DBGPRINT(MP_TRACE, ("--> NICInitRecv\n"));
// Setup each RFD
for (RfdCount = 0; RfdCount < Adapter->NumRfd; RfdCount++)
{
pMpRfd = NdisAllocateFromNPagedLookasideList(&Adapter->RecvLookaside);
if (!pMpRfd)
{
ErrorValue = ERRLOG_OUT_OF_LOOKASIDE_MEMORY;
continue;
}
//
// Allocate the shared memory for this RFD.
//
NdisMAllocateSharedMemory(
Adapter->AdapterHandle,
Adapter->HwRfdSize,
FALSE,
&pMpRfd->OriginalHwRfd,
&pMpRfd->OriginalHwRfdPa);
if (!pMpRfd->OriginalHwRfd)
{
ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
NdisFreeToNPagedLookasideList(&Adapter->RecvLookaside, pMpRfd);
continue;
}
//
// Get a 8-byts aligned memory from the original HwRfd
//
pMpRfd->HwRfd = (PHW_RFD)DATA_ALIGN(pMpRfd->OriginalHwRfd);
//
// Now HwRfd is already 8-bytes aligned, and the size of HwPfd header(not data part) is a multiple of 8,
// If we shift HwRfd 0xA bytes up, the Ethernet header size is 14 bytes long, then the data will be at
// 8 byte boundary.
//
pMpRfd->HwRfd = (PHW_RFD)((PUCHAR)(pMpRfd->HwRfd) + HWRFD_SHIFT_OFFSET);
//
// Update physical address accordingly
//
pMpRfd->HwRfdPa.QuadPart = pMpRfd->OriginalHwRfdPa.QuadPart + BYTES_SHIFT(pMpRfd->HwRfd, pMpRfd->OriginalHwRfd);
ErrorValue = NICAllocRfd(Adapter, pMpRfd);
if (ErrorValue)
{
NdisFreeToNPagedLookasideList(&Adapter->RecvLookaside, pMpRfd);
continue;
}
//
// Add this RFD to the RecvList
//
Adapter->CurrNumRfd++;
NICReturnRFD(Adapter, pMpRfd);
}
if (Adapter->CurrNumRfd > NIC_MIN_RFDS)
{
Status = NDIS_STATUS_SUCCESS;
}
//
// Adapter->CurrNumRfd < NIC_MIN_RFDs
//
if (Status != NDIS_STATUS_SUCCESS)
{
NdisWriteErrorLogEntry(
Adapter->AdapterHandle,
NDIS_ERROR_CODE_OUT_OF_RESOURCES,
1,
ErrorValue);
}
DBGPRINT_S(Status, ("<-- NICInitRecv, Status=%x\n", Status));
return Status;
}
ULONG NICAllocRfd(
IN PMP_ADAPTER Adapter,
IN PMP_RFD pMpRfd)
/*++
Routine Description:
Allocate NDIS_PACKET and NDIS_BUFFER associated with a RFD
Arguments:
Adapter Pointer to our adapter
pMpRfd pointer to a RFD
Return Value:
ERRLOG_OUT_OF_NDIS_PACKET
ERRLOG_OUT_OF_NDIS_BUFFER
--*/
{
NDIS_STATUS Status;
PHW_RFD pHwRfd;
ULONG ErrorValue = 0;
do
{
pHwRfd = pMpRfd->HwRfd;
pMpRfd->HwRfdPhys = NdisGetPhysicalAddressLow(pMpRfd->HwRfdPa);
pMpRfd->Flags = 0;
pMpRfd->NdisPacket = NULL;
pMpRfd->NdisBuffer = NULL;
NdisAllocatePacket(
&Status,
&pMpRfd->NdisPacket,
Adapter->RecvPacketPool);
if (Status != NDIS_STATUS_SUCCESS)
{
ASSERT(pMpRfd->NdisPacket == NULL);
ErrorValue = ERRLOG_OUT_OF_NDIS_PACKET;
break;
}
//
// point our buffer for receives at this Rfd
//
NdisAllocateBuffer(
&Status,
&pMpRfd->NdisBuffer,
Adapter->RecvBufferPool,
(PVOID)&pHwRfd->RfdBuffer.RxMacHeader,
NIC_MAX_PACKET_SIZE);
if (Status != NDIS_STATUS_SUCCESS)
{
ASSERT(pMpRfd->NdisBuffer == NULL);
ErrorValue = ERRLOG_OUT_OF_NDIS_BUFFER;
break;
}
// Init each RFD header
pHwRfd->RfdRbdPointer = DRIVER_NULL;
pHwRfd->RfdSize = NIC_MAX_PACKET_SIZE;
NDIS_SET_PACKET_HEADER_SIZE(pMpRfd->NdisPacket, NIC_HEADER_SIZE);
NdisChainBufferAtFront(pMpRfd->NdisPacket, pMpRfd->NdisBuffer);
//
// Save ptr to MP_RFD in the packet, used in MPReturnPackets
//
MP_SET_PACKET_RFD(pMpRfd->NdisPacket, pMpRfd);
} while (FALSE);
if (ErrorValue)
{
if (pMpRfd->NdisPacket)
{
NdisFreePacket(pMpRfd->NdisPacket);
}
if (pMpRfd->HwRfd)
{
//
// Free HwRfd, we need to free the original memory pointed by OriginalHwRfd.
//
NdisMFreeSharedMemory(
Adapter->AdapterHandle,
Adapter->HwRfdSize,
FALSE,
pMpRfd->OriginalHwRfd,
pMpRfd->OriginalHwRfdPa);
pMpRfd->HwRfd = NULL;
pMpRfd->OriginalHwRfd = NULL;
}
}
return ErrorValue;
}
VOID NICFreeRfd(
IN PMP_ADAPTER Adapter,
IN PMP_RFD pMpRfd)
/*++
Routine Description:
Free a RFD and assocaited NDIS_PACKET and NDIS_BUFFER
Arguments:
Adapter Pointer to our adapter
pMpRfd Pointer to a RFD
Return Value:
None
--*/
{
ASSERT(pMpRfd->NdisBuffer);
ASSERT(pMpRfd->NdisPacket);
ASSERT(pMpRfd->HwRfd);
NdisAdjustBufferLength(pMpRfd->NdisBuffer, NIC_MAX_PACKET_SIZE);
NdisFreeBuffer(pMpRfd->NdisBuffer);
NdisFreePacket(pMpRfd->NdisPacket);
pMpRfd->NdisBuffer = NULL;
pMpRfd->NdisPacket = NULL;
//
// Free HwRfd, we need to free the original memory pointed by OriginalHwRfd.
//
NdisMFreeSharedMemory(
Adapter->AdapterHandle,
Adapter->HwRfdSize,
FALSE,
pMpRfd->OriginalHwRfd,
pMpRfd->OriginalHwRfdPa);
pMpRfd->HwRfd = NULL;
pMpRfd->OriginalHwRfd = NULL;
NdisFreeToNPagedLookasideList(&Adapter->RecvLookaside, pMpRfd);
}
NDIS_STATUS NICSelfTest(
IN PMP_ADAPTER Adapter)
/*++
Routine Description:
Perform a NIC self-test
Arguments:
Adapter Pointer to our adapter
Return Value:
NDIS_STATUS_SUCCESS
NDIS_STATUS_DEVICE_FAILED
--*/
{
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
ULONG SelfTestCommandCode;
DBGPRINT(MP_TRACE, ("--> NICSelfTest\n"));
DBGPRINT(MP_INFO, ("SelfTest=%x, SelfTestPhys=%x\n",
Adapter->SelfTest, Adapter->SelfTestPhys));
//
// Issue a software reset to the adapter
//
HwSoftwareReset(Adapter);
//
// Execute The PORT Self Test Command On The 82558.
//
ASSERT(Adapter->SelfTestPhys != 0);
SelfTestCommandCode = Adapter->SelfTestPhys;
//
// Setup SELF TEST Command Code in D3 - D0
//
SelfTestCommandCode |= PORT_SELFTEST;
//
// Initialize the self-test signature and results DWORDS
//
Adapter->SelfTest->StSignature = 0;
Adapter->SelfTest->StResults = 0xffffffff;
//
// Do the port command
//
Adapter->CSRAddress->Port = SelfTestCommandCode;
MP_STALL_EXECUTION(NIC_DELAY_POST_SELF_TEST_MS);
//
// if The First Self Test DWORD Still Zero, We've timed out. If the second
// DWORD is not zero then we have an error.
//
if ((Adapter->SelfTest->StSignature == 0) || (Adapter->SelfTest->StResults != 0))
{
DBGPRINT(MP_ERROR, ("StSignature=%x, StResults=%x\n",
Adapter->SelfTest->StSignature, Adapter->SelfTest->StResults));
NdisWriteErrorLogEntry(
Adapter->AdapterHandle,
NDIS_ERROR_CODE_HARDWARE_FAILURE,
1,
ERRLOG_SELFTEST_FAILED);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -