📄 nic_init.c
字号:
return;
}
NTSTATUS
NICSelfTest(
IN PFDO_DATA FdoData
)
/*++
Routine Description:
Perform a NIC self-test
Arguments:
FdoData Pointer to our adapter
Return Value:
NT status code
--*/
{
NTSTATUS status = STATUS_SUCCESS;
ULONG SelfTestCommandCode;
DebugPrint(TRACE, DBG_INIT, "--> NICSelfTest\n");
DebugPrint(LOUD, DBG_INIT, "SelfTest=%p, SelfTestPhys=%x\n",
FdoData->SelfTest, FdoData->SelfTestPhys);
//
// Issue a software reset to the adapter
//
HwSoftwareReset(FdoData);
//
// Execute The PORT Self Test Command On The 82558.
//
ASSERT(FdoData->SelfTestPhys != 0);
SelfTestCommandCode = FdoData->SelfTestPhys;
//
// Setup SELF TEST Command Code in D3 - D0
//
SelfTestCommandCode |= PORT_SELFTEST;
//
// Initialize the self-test signature and results DWORDS
//
FdoData->SelfTest->StSignature = 0;
FdoData->SelfTest->StResults = 0xffffffff;
//
// Do the port command
//
FdoData->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 ((FdoData->SelfTest->StSignature == 0) || (FdoData->SelfTest->StResults != 0))
{
DebugPrint(ERROR, DBG_INIT, "StSignature=%x, StResults=%x\n",
FdoData->SelfTest->StSignature, FdoData->SelfTest->StResults);
status = STATUS_DEVICE_CONFIGURATION_ERROR;
}
DebugPrint(TRACE, DBG_INIT, "<-- NICSelfTest, status=%x\n", status);
return status;
}
NTSTATUS
NICInitializeAdapter(
IN PFDO_DATA FdoData
)
/*++
Routine Description:
Initialize the adapter and set up everything
Arguments:
FdoData Pointer to our adapter
Return Value:
NT Status Code
--*/
{
NTSTATUS status;
DebugPrint(TRACE, DBG_INIT, "--> NICInitializeAdapter\n");
do
{
// set up our link indication variable
// it doesn't matter what this is right now because it will be
// set correctly if link fails
FdoData->MediaState = Connected;
// Issue a software reset to the D100
HwSoftwareReset(FdoData);
// Load the CU BASE (set to 0, because we use linear mode)
FdoData->CSRAddress->ScbGeneralPointer = 0;
status = D100IssueScbCommand(FdoData, SCB_CUC_LOAD_BASE, FALSE);
if (status != STATUS_SUCCESS)
{
break;
}
// Wait for the SCB command word to clear before we set the general pointer
if (!WaitScb(FdoData))
{
status = STATUS_DEVICE_DATA_ERROR;
break;
}
// Load the RU BASE (set to 0, because we use linear mode)
FdoData->CSRAddress->ScbGeneralPointer = 0;
status = D100IssueScbCommand(FdoData, SCB_RUC_LOAD_BASE, FALSE);
if (status != STATUS_SUCCESS)
{
break;
}
// Configure the adapter
status = HwConfigure(FdoData);
if (status != STATUS_SUCCESS)
{
break;
}
status = HwSetupIAAddress(FdoData);
if (status != STATUS_SUCCESS)
{
break;
}
// Clear the internal counters
HwClearAllCounters(FdoData);
} while (FALSE);
if (status != STATUS_SUCCESS)
{
// TODO: Log an entry into the eventlog
}
DebugPrint(TRACE, DBG_INIT, "<-- NICInitializeAdapter, status=%x\n", status);
return status;
}
VOID
NICShutdown(
IN PFDO_DATA FdoData)
/*++
Routine Description:
Shutdown the device
Arguments:
FdoData - Pointer to our adapter
Return Value:
None
--*/
{
DebugPrint(INFO, DBG_INIT, "---> NICShutdown\n");
if(FdoData->CSRAddress) {
//
// Disable interrupt and issue a full reset
//
NICDisableInterrupt(FdoData);
NICIssueFullReset(FdoData);
//
// Reset the PHY chip. We do this so that after a warm boot, the PHY will
// be in a known state, with auto-negotiation enabled.
//
ResetPhy(FdoData);
}
DebugPrint(INFO, DBG_INIT, "<--- NICShutdown\n");
}
VOID
HwSoftwareReset(
IN PFDO_DATA FdoData
)
/*++
Routine Description:
Issue a software reset to the hardware
Arguments:
FdoData Pointer to our adapter
Return Value:
None
--*/
{
DebugPrint(TRACE, DBG_HW_ACCESS, "--> HwSoftwareReset\n");
// Issue a PORT command with a data word of 0
FdoData->CSRAddress->Port = PORT_SOFTWARE_RESET;
// wait after the port reset command
KeStallExecutionProcessor(NIC_DELAY_POST_RESET);
// Mask off our interrupt line -- its unmasked after reset
NICDisableInterrupt(FdoData);
DebugPrint(TRACE, DBG_HW_ACCESS, "<-- HwSoftwareReset\n");
}
NTSTATUS
HwConfigure(
IN PFDO_DATA FdoData
)
/*++
Routine Description:
Configure the hardware
Arguments:
FdoData Pointer to our adapter
Return Value:
NT Status
--*/
{
NTSTATUS status;
PCB_HEADER_STRUC NonTxCmdBlockHdr =
(PCB_HEADER_STRUC)FdoData->NonTxCmdBlock;
UINT i;
DebugPrint(TRACE, DBG_HW_ACCESS, "--> HwConfigure\n");
//
// Init the packet filter to nothing.
//
FdoData->OldPacketFilter = FdoData->PacketFilter;
FdoData->PacketFilter = 0;
//
// Store the current setting for BROADCAST/PROMISCUOS modes
FdoData->OldParameterField = CB_557_CFIG_DEFAULT_PARM15;
// Setup the non-transmit command block header for the configure command.
NonTxCmdBlockHdr->CbStatus = 0;
NonTxCmdBlockHdr->CbCommand = CB_CONFIGURE;
NonTxCmdBlockHdr->CbLinkPointer = DRIVER_NULL;
// Fill in the configure command data.
// First fill in the static (end user can't change) config bytes
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[0] = CB_557_CFIG_DEFAULT_PARM0;
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[2] = CB_557_CFIG_DEFAULT_PARM2;
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[3] = CB_557_CFIG_DEFAULT_PARM3;
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[6] = CB_557_CFIG_DEFAULT_PARM6;
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[9] = CB_557_CFIG_DEFAULT_PARM9;
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[10] = CB_557_CFIG_DEFAULT_PARM10;
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[11] = CB_557_CFIG_DEFAULT_PARM11;
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[12] = CB_557_CFIG_DEFAULT_PARM12;
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[13] = CB_557_CFIG_DEFAULT_PARM13;
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[14] = CB_557_CFIG_DEFAULT_PARM14;
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[16] = CB_557_CFIG_DEFAULT_PARM16;
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[17] = CB_557_CFIG_DEFAULT_PARM17;
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[18] = CB_557_CFIG_DEFAULT_PARM18;
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[20] = CB_557_CFIG_DEFAULT_PARM20;
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[21] = CB_557_CFIG_DEFAULT_PARM21;
// Now fill in the rest of the configuration bytes (the bytes that contain
// user configurable parameters).
// Set the Tx and Rx Fifo limits
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[1] =
(UCHAR) ((FdoData->AiTxFifo << 4) | FdoData->AiRxFifo);
if (FdoData->MWIEnable)
{
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[3] |= CB_CFIG_B3_MWI_ENABLE;
}
// Set the Tx and Rx DMA maximum byte count fields.
if ((FdoData->AiRxDmaCount) || (FdoData->AiTxDmaCount))
{
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[4] =
FdoData->AiRxDmaCount;
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[5] =
(UCHAR) (FdoData->AiTxDmaCount | CB_CFIG_DMBC_EN);
}
else
{
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[4] =
CB_557_CFIG_DEFAULT_PARM4;
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[5] =
CB_557_CFIG_DEFAULT_PARM5;
}
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[7] =
(UCHAR) ((CB_557_CFIG_DEFAULT_PARM7 & (~CB_CFIG_URUN_RETRY)) |
(FdoData->AiUnderrunRetry << 1)
);
// Setup for MII or 503 operation. The CRS+CDT bit should only be set
// when operating in 503 mode.
if (FdoData->PhyAddress == 32)
{
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[8] =
(CB_557_CFIG_DEFAULT_PARM8 & (~CB_CFIG_503_MII));
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[15] =
(CB_557_CFIG_DEFAULT_PARM15 | CB_CFIG_CRS_OR_CDT);
}
else
{
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[8] =
(CB_557_CFIG_DEFAULT_PARM8 | CB_CFIG_503_MII);
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[15] =
((CB_557_CFIG_DEFAULT_PARM15 & (~CB_CFIG_CRS_OR_CDT)) | CB_CFIG_BROADCAST_DIS);
}
// Setup Full duplex stuff
// If forced to half duplex
if (FdoData->AiForceDpx == 1)
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[19] =
(CB_557_CFIG_DEFAULT_PARM19 &
(~(CB_CFIG_FORCE_FDX| CB_CFIG_FDX_ENABLE)));
// If forced to full duplex
else if (FdoData->AiForceDpx == 2)
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[19] =
(CB_557_CFIG_DEFAULT_PARM19 | CB_CFIG_FORCE_FDX);
// If auto-duplex
else
{
// We must force full duplex on if we are using PHY 0, and we are
// supposed to run in FDX mode. We do this because the D100 has only
// one FDX# input pin, and that pin will be connected to PHY 1.
if ((FdoData->PhyAddress == 0) && (FdoData->usDuplexMode == 2))
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[19] =
(CB_557_CFIG_DEFAULT_PARM19 | CB_CFIG_FORCE_FDX);
else
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[19] =
CB_557_CFIG_DEFAULT_PARM19;
}
// display the config info to the debugger
DebugPrint(LOUD, DBG_HW_ACCESS, " Issuing Configure command\n");
DebugPrint(LOUD, DBG_HW_ACCESS, " Config Block at virt addr %p phys address %x\n",
&NonTxCmdBlockHdr->CbStatus, FdoData->NonTxCmdBlockPhys);
for (i=0; i < CB_CFIG_BYTE_COUNT; i++)
DebugPrint(LOUD, DBG_HW_ACCESS, " Config byte %x = %.2x\n",
i, FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[i]);
// Wait for the SCB command word to clear before we set the general pointer
if (!WaitScb(FdoData))
{
status = STATUS_DEVICE_DATA_ERROR;
}
else
{
ASSERT(FdoData->CSRAddress->ScbCommandLow == 0);
FdoData->CSRAddress->ScbGeneralPointer = FdoData->NonTxCmdBlockPhys;
// Submit the configure command to the chip, and wait for it to complete.
status = D100SubmitCommandBlockAndWait(FdoData);
}
DebugPrint(TRACE, DBG_HW_ACCESS,
"<-- HwConfigure, status=%x\n", status);
return status;
}
NTSTATUS
HwSetupIAAddress(
IN PFDO_DATA FdoData
)
/*++
Routine Description:
Set up the individual MAC address
Arguments:
FdoData Pointer to our adapter
Return Value:
NT Status code
--*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -