📄 init.c
字号:
INITSTR(("NdisMAllocateMapRegister Failed - %x\n", Status));
Adapter->NumMapRegisters = 0;
return Status;
}
// Allocate cached memory for the SW receive frame descriptors. (RFD)
Adapter->RecvCachedSize = (Adapter->NumRfd * sizeof(D100SwRfd));
Status = D100_ALLOC_MEM(&Adapter->RecvCached, Adapter->RecvCachedSize);
if (Status != NDIS_STATUS_SUCCESS)
{
D100LogError(Adapter, EVENT_12, NDIS_ERROR_CODE_OUT_OF_RESOURCES, 0);
Adapter->RecvCached = (PUCHAR) 0;
INITSTR(("Could not allocate %d bytes for RecvCached mem\n", Adapter->RecvCachedSize));
return Status;
}
INITSTR(("Allocated %08x %8d bytes for RecvCached mem\n", Adapter->RecvCached, Adapter->RecvCachedSize));
NdisZeroMemory((PVOID) Adapter->RecvCached, Adapter->RecvCachedSize);
// Allocate memory for the shared receive resources with enough
// extra to paragraph align everything.
Adapter->RecvUnCachedSize = 16 + (Adapter->NumRfd * sizeof(RFD_STRUC));
// Allocate the shared memory for the receive data structures.
NdisMAllocateSharedMemory(
Adapter->D100AdapterHandle,
Adapter->RecvUnCachedSize,
FALSE,
(PVOID) &Adapter->RecvUnCached,
&Adapter->RecvUnCachedPhys
);
if (!Adapter->RecvUnCached)
{
D100LogError(Adapter, EVENT_13, NDIS_ERROR_CODE_OUT_OF_RESOURCES, 0);
INITSTR(("Could not allocate %d bytes for RecvUnCached mem\n", Adapter->RecvUnCachedSize));
return NDIS_STATUS_FAILURE;
}
INITSTR(("Allocated %08x %8d bytes for RecvUnCached mem\n", Adapter->RecvUnCached, Adapter->RecvUnCachedSize));
NdisZeroMemory((PVOID) Adapter->RecvUnCached, Adapter->RecvUnCachedSize);
// Allocate cached memory for the SW transmit structures.
Adapter->XmitCachedSize = (Adapter->NumTcb * sizeof(D100SwTcb)) +
(Adapter->NumCoalesce * sizeof(COALESCE));
Status = D100_ALLOC_MEM( &Adapter->XmitCached, Adapter->XmitCachedSize);
if (Status != NDIS_STATUS_SUCCESS)
{
D100LogError(Adapter, EVENT_14, NDIS_ERROR_CODE_OUT_OF_RESOURCES, 0);
Adapter->XmitCached = (PUCHAR) 0;
INITSTR(("Could not allocate %d bytes for XmitCached mem\n", Adapter->XmitCachedSize));
return Status;
}
INITSTR(("Allocated %08x %8d bytes for XmitCached mem\n", Adapter->XmitCached, Adapter->XmitCachedSize));
// initialize this recently allocated area to zeros
NdisZeroMemory((PVOID) Adapter->XmitCached, Adapter->XmitCachedSize);
// Allocate memory for the shared transmit resources with enough extra mem
// to paragraph align everything
Adapter->CbUnCachedSize =
sizeof(SELF_TEST_STRUC) + 16 +
sizeof(DUMP_AREA_STRUC) + 16 +
sizeof(NON_TRANSMIT_CB) + 16 +
sizeof(ERR_COUNT_STRUC) + 16 +
MINIMUM_ETHERNET_PACKET_SIZE +
(Adapter->NumTcb * sizeof(TXCB_STRUC)) + 0x100 +
(Adapter->NumTbd * sizeof(TBD_STRUC)) + 16 +
((Adapter->NumCoalesce + 1) * COALESCE_BUFFER_SIZE);
// Allocate the shared memory for the command block data structures.
NdisMAllocateSharedMemory(
Adapter->D100AdapterHandle,
Adapter->CbUnCachedSize,
FALSE,
(PVOID) &Adapter->CbUnCached,
&Adapter->CbUnCachedPhys);
if (!Adapter->CbUnCached)
{
D100LogError(Adapter, EVENT_15, NDIS_ERROR_CODE_OUT_OF_RESOURCES, 0);
INITSTR(("Could not allocate %d bytes for XmitUnCached mem\n", Adapter->CbUnCachedSize));
return NDIS_STATUS_FAILURE;
}
INITSTR(("Allocated %08x %8d bytes for XmitUnCached mem\n", Adapter->CbUnCached, Adapter->CbUnCachedSize));
// initialize this recently allocated area to zeros
NdisZeroMemory((PVOID) Adapter->CbUnCached, Adapter->CbUnCachedSize);
// Initialize the 82557 Control Structures pointers
CbPhys = NdisGetPhysicalAddressLow(Adapter->CbUnCachedPhys);
// Physical addresses for certain structures must be aligned on
// paragraph boundaries or other greater boundaries
#define ALIGN_CBandP \
CbPhys += 0x0000000F; \
CbPhys &= (~0x0000000F); \
MemP = (Adapter->CbUnCached + \
(CbPhys - NdisGetPhysicalAddressLow(Adapter->CbUnCachedPhys)));
#define ALIGN_TCB \
CbPhys += 0x000000FF; \
CbPhys &= (~0x000000FF); \
MemP = (Adapter->CbUnCached + \
(CbPhys - NdisGetPhysicalAddressLow(Adapter->CbUnCachedPhys)));
// Setup SelfTest Command Block Pointers
ALIGN_CBandP
Adapter->SelfTest = (PSELF_TEST_STRUC) MemP;
Adapter->SelfTestPhys = CbPhys;
CbPhys += sizeof(SELF_TEST_STRUC);
// Setup non-Transmit Command Block Pointers
ALIGN_CBandP
Adapter->NonTxCmdBlock = (PNON_TRANSMIT_CB) MemP;
Adapter->NonTxCmdBlockHdr = (PCB_HEADER_STRUC) MemP;
Adapter->NonTxCmdBlockPhys = CbPhys;
CbPhys += sizeof(NON_TRANSMIT_CB);
// Setup dump buffer area
ALIGN_CBandP
Adapter->DumpSpace = (PDUMP_AREA_STRUC) MemP;
Adapter->DumpSpacePhys = CbPhys;
CbPhys += sizeof(DUMP_AREA_STRUC);
// Setup stats counters area
ALIGN_CBandP
Adapter->StatsCounters = (PERR_COUNT_STRUC) MemP;
Adapter->StatsCounterPhys = CbPhys;
CbPhys += sizeof(ERR_COUNT_STRUC);
// Save Transmit Memory Structures Starting Addresses
ALIGN_TCB
Adapter->XmitUnCached = MemP;
Adapter->XmitUnCachedPhys = Adapter->CbUnCachedPhys;
NdisSetPhysicalAddressLow(Adapter->XmitUnCachedPhys, CbPhys);
INITSTR(("SelfTest area ptr=%x\n", Adapter->SelfTest));
INITSTR(("NonTxCmd Block ptr=%x\n", Adapter->NonTxCmdBlock));
INITSTR(("Dump buffer ptr=%x\n", Adapter->DumpSpace));
INITSTR(("Stats counts dump area ptr=%x\n", Adapter->StatsCounters));
INITSTR(("First Transmit Block ptr=%x\n", Adapter->XmitUnCached));
return NDIS_STATUS_SUCCESS;
}
//-----------------------------------------------------------------------------
// Procedure: SelfTestHardware
//
// Description: This routine will issue PORT Self-test command to test the
// D100. The self-test will fail if the adapter's master-enable
// bit is not set in the PCI Command Register, of if the adapter
// is not seated in a PCI master-enabled slot.
//
// Arguments:
// Adapter - ptr to Adapter object instance
//
// Returns:
// NDIS_STATUS_SUCCESS - If the adapter passes the self-test
// NDIS_STATUS_FAILURE- If the adapter fails the self-test
//-----------------------------------------------------------------------------
NDIS_STATUS
SelfTestHardware(
IN PD100_ADAPTER Adapter
)
{
ULONG SelfTestCommandCode;
DEBUGFUNC("SelfTestHardware");
INITSTR(("\n"));
// Issue a software reset to the adapter
(void) SoftwareReset(Adapter);
// Execute The PORT Self Test Command On The 82557/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;
// Wait 5 milliseconds for the self-test to complete
D100StallExecution(5);
// 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))
{
D100LogError(Adapter, EVENT_3, NDIS_ERROR_CODE_ADAPTER_DISABLED, 0);
INITSTR(("Self-Test failed. Sig =%x, Results = %x\n",
Adapter->SelfTest->StSignature, Adapter->SelfTest->StResults));
return NDIS_STATUS_FAILURE;
}
return NDIS_STATUS_SUCCESS;
}
//-----------------------------------------------------------------------------
// Procedure: SetupTransmitQueues
//
// Description: Setup TCBs, TBDs and coalesce buffers at INIT time. This
// routine may also be called at RESET time.
//
// Arguments:
// Adapter - ptr to Adapter object instance
// DebugPrint - A boolean value that will be TRUE if this routine is to
// write all of transmit queue debug info to the debug terminal.
//
// Returns: (none)
//-----------------------------------------------------------------------------
VOID
SetupTransmitQueues(
IN PD100_ADAPTER Adapter,
IN BOOLEAN DebugPrint
)
{
// TCB local variables
PD100SwTcb SwTcbPtr; // cached TCB list logical pointers
PTXCB_STRUC HwTcbPtr; // uncached TCB list logical pointers
ULONG HwTcbPhys; // uncached TCB list physical pointer
UINT TcbCount;
// TBD local variables
PTBD_STRUC HwTbdPtr; // uncached TBD list pointers
ULONG HwTbdPhys; // uncached TBD list physical pointer
UINT CoalesceCount;
PCOALESCE Coalesce;
PUCHAR CoalesceBufVirtPtr;
ULONG CoalesceBufPhysPtr;
DEBUGFUNC("SetupTransmitQueues");
INITSTR(("\n"));
DEBUGCHAR(Adapter,'F');
// init the lists
QueueInitList(&Adapter->TxCBList);
QueueInitList(&Adapter->ActiveChainList);
QueueInitList(&Adapter->CompletedChainList);
QueueInitList(&Adapter->CoalesceBufferList);
// init the command unit flags
Adapter->TransmitIdle = TRUE;
Adapter->ResumeWait = TRUE;
INITSTRTX(DebugPrint, ("Free TCB list %x\n", &Adapter->TxCBList));
INITSTRTX(DebugPrint, ("Active TCB List %x\n", &Adapter->ActiveChainList));
// print some basic sizing debug info
INITSTRTX(DebugPrint, ("sizeof(SwTcb)=%x\n", sizeof(D100SwTcb)));
INITSTRTX(DebugPrint, ("sizeof(HwTcb)=%x\n", sizeof(TXCB_STRUC)));
INITSTRTX(DebugPrint, ("Adapter->NumTcb=%d\n", Adapter->NumTcb));
INITSTRTX(DebugPrint, ("sizeof(HwTbd)=%x\n", sizeof(TBD_STRUC)));
INITSTRTX(DebugPrint, ("Adapter->NumTbdPerTcb=%d\n", Adapter->NumTbdPerTcb));
INITSTRTX(DebugPrint, ("Adapter->NumTbd=%d\n", Adapter->NumTbd));
// Setup the initial pointers to the HW and SW TCB data space
SwTcbPtr = (PD100SwTcb) Adapter->XmitCached;
HwTcbPtr = (PTXCB_STRUC) Adapter->XmitUnCached;
HwTcbPhys = NdisGetPhysicalAddressLow(Adapter->XmitUnCachedPhys);
// Setup the initial pointers to the TBD data space.
// TBDs are located immediately following the TCBs
HwTbdPtr = (PTBD_STRUC) (Adapter->XmitUnCached +
(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++, SwTcbPtr++, HwTcbPtr++, HwTcbPhys += sizeof(TXCB_STRUC),
HwTbdPtr = (PTBD_STRUC) (((ULONG_PTR) HwTbdPtr) +
((ULONG) (sizeof(TBD_STRUC) * Adapter->NumTbdPerTcb))),
HwTbdPhys += (sizeof(TBD_STRUC) * Adapter->NumTbdPerTcb))
{
#if DBG
SwTcbPtr->TcbNum = TcbCount;
#endif
INITSTRTX(DebugPrint, (" TcbCount=%d\n", TcbCount));
INITSTRTX(DebugPrint, (" SwTcbPtr=%lx\n", SwTcbPtr));
INITSTRTX(DebugPrint, (" HwTcbPtr=%lx\n", HwTcbPtr));
INITSTRTX(DebugPrint, (" HwTcbPhys=%lx\n", HwTcbPhys));
INITSTRTX(DebugPrint, (" FirstTbdPtr=%lx\n", HwTbdPtr));
INITSTRTX(DebugPrint, (" FirstTbdPhys=%lx\n", HwTbdPhys));
// point the cached TCB to the logical address of the uncached one
SwTcbPtr->Tcb = HwTcbPtr;
// save the uncached TCB physical address in the cached TCB
SwTcbPtr->TcbPhys = (ULONG)HwTcbPhys;
// store virtual and physical pointers to the TBD array
SwTcbPtr->FirstTbd = HwTbdPtr;
SwTcbPtr->FirstTbdPhys = HwTbdPhys;
// initialize the uncached TCB contents -- status is zeroed
HwTcbPtr->TxCbHeader.CbStatus = 0;
// This is the last in CBL
HwTcbPtr->TxCbHeader.CbCommand = CB_EL_BIT | CB_TX_SF_BIT | CB_TRANSMIT;
// Set the link pointer so that this TCB points to the next TCB in the
// chain. If this is the last TCB in the chain, then it should point
// back to the first TCB.
if (TcbCount == (Adapter->NumTcb -1))
HwTcbPtr->TxCbHeader.CbLinkPointer = NdisGetPhysicalAddressLow(Adapter->XmitUnCachedPhys);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -