📄 nic_req.c
字号:
{
NTSTATUS status = STATUS_SUCCESS;
UCHAR NewParameterField;
UINT i;
BOOLEAN bResult;
DebugPrint(TRACE, DBG_IOCTLS, "--> NICSetPacketFilter, PacketFilter=%08x\n", PacketFilter);
//
// Need to enable or disable broadcast and promiscuous support depending
// on the new filter
//
NewParameterField = CB_557_CFIG_DEFAULT_PARM15;
if (PacketFilter & NDIS_PACKET_TYPE_BROADCAST)
{
NewParameterField &= ~CB_CFIG_BROADCAST_DIS;
}
else
{
NewParameterField |= CB_CFIG_BROADCAST_DIS;
}
if (PacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS)
{
NewParameterField |= CB_CFIG_PROMISCUOUS;
}
else
{
NewParameterField &= ~CB_CFIG_PROMISCUOUS;
}
do
{
if ((FdoData->OldParameterField == NewParameterField ) &&
!(PacketFilter & NDIS_PACKET_TYPE_ALL_MULTICAST))
{
break;
}
//
// Only need to do something to the HW if the filter bits have changed.
//
FdoData->OldParameterField = NewParameterField;
((PCB_HEADER_STRUC)FdoData->NonTxCmdBlock)->CbCommand = CB_CONFIGURE;
((PCB_HEADER_STRUC)FdoData->NonTxCmdBlock)->CbStatus = 0;
((PCB_HEADER_STRUC)FdoData->NonTxCmdBlock)->CbLinkPointer = DRIVER_NULL;
//
// 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;
//
// Set the Tx underrun retries
//
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[7] =
(UCHAR) (CB_557_CFIG_DEFAULT_PARM7 | (FdoData->AiUnderrunRetry << 1));
//
// Set the Tx and Rx Fifo limits
//
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[1] =
(UCHAR) ((FdoData->AiTxFifo << 4) | FdoData->AiRxFifo);
//
// set the MWI enable bit if needed
//
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;
}
//
// 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] =
(UCHAR) (NewParameterField | 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] =
(UCHAR) (NewParameterField & (~CB_CFIG_CRS_OR_CDT));
}
//
// 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
{
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[19] =
CB_557_CFIG_DEFAULT_PARM19;
}
//
// if multicast all is being turned on, set the bit
//
if (PacketFilter & NDIS_PACKET_TYPE_ALL_MULTICAST)
{
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[21] =
(CB_557_CFIG_DEFAULT_PARM21 | CB_CFIG_MULTICAST_ALL);
}
else
{
FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[21] =
CB_557_CFIG_DEFAULT_PARM21;
}
//
// Wait for the SCB to clear before we check the CU status.
//
if (!WaitScb(FdoData))
{
status = STATUS_DEVICE_DATA_ERROR;
break;
}
//
// If we have issued any transmits, then the CU will either be active,
// or in the suspended state. If the CU is active, then we wait for
// it to be suspended.
//
if (FdoData->TransmitIdle == FALSE)
{
//
// Wait for suspended state
//
MP_STALL_AND_WAIT((FdoData->CSRAddress->ScbStatus & SCB_CUS_MASK) != SCB_CUS_ACTIVE, 5000, bResult);
if (!bResult)
{
MP_SET_HARDWARE_ERROR(FdoData);
status = STATUS_DEVICE_DATA_ERROR;
break;
}
//
// Check the current status of the receive unit
//
if ((FdoData->CSRAddress->ScbStatus & SCB_RUS_MASK) != SCB_RUS_IDLE)
{
// Issue an RU abort. Since an interrupt will be issued, the
// RU will be started by the DPC.
status = D100IssueScbCommand(FdoData, SCB_RUC_ABORT, TRUE);
if (status != STATUS_SUCCESS)
{
break;
}
}
if (!WaitScb(FdoData))
{
status = STATUS_DEVICE_DATA_ERROR;
break;
}
//
// Restore the transmit software flags. After the multicast
// command is issued, the command unit will be idle, because the
// EL bit will be set in the multicast commmand block.
//
FdoData->TransmitIdle = TRUE;
FdoData->ResumeWait = TRUE;
}
//
// Display config info
//
DebugPrint(TRACE, DBG_IOCTLS, "Re-Issuing Configure command for filter change\n");
DebugPrint(TRACE, DBG_IOCTLS, "Config Block at virt addr %p, phys address %x\n",
&((PCB_HEADER_STRUC)FdoData->NonTxCmdBlock)->CbStatus, FdoData->NonTxCmdBlockPhys);
for (i = 0; i < CB_CFIG_BYTE_COUNT; i++)
DebugPrint(LOUD, DBG_IOCTLS, " Config byte %x = %.2x\n", i, FdoData->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[i]);
//
// Submit the configure command to the chip, and wait for it to complete.
//
FdoData->CSRAddress->ScbGeneralPointer = FdoData->NonTxCmdBlockPhys;
status = D100SubmitCommandBlockAndWait(FdoData);
if (status != STATUS_SUCCESS)
{
status = STATUS_DEVICE_NOT_READY;
}
} while (FALSE);
DebugPrint(TRACE, DBG_IOCTLS, "<-- NICSetPacketFilter, Status=%x\n", status);
return(status);
}
NTSTATUS
NICSetMulticastList(
IN PFDO_DATA FdoData
)
/*++
Routine Description:
This routine will set up the FdoData for a specified multicast address list
Arguments:
FdoData Pointer to our FdoData
Return Value:
--*/
{
NTSTATUS status;
PUCHAR McAddress;
UINT i, j;
BOOLEAN bResult;
DebugPrint(TRACE, DBG_IOCTLS, "--> NICSetMulticastList\n");
//
// Setup the command block for the multicast command.
//
for (i = 0; i < FdoData->MCAddressCount; i++)
{
DebugPrint(TRACE, DBG_IOCTLS, "MC(%d) = %02x-%02x-%02x-%02x-%02x-%02x\n",
i,
FdoData->MCList[i][0],
FdoData->MCList[i][1],
FdoData->MCList[i][2],
FdoData->MCList[i][3],
FdoData->MCList[i][4],
FdoData->MCList[i][5]);
McAddress = &FdoData->NonTxCmdBlock->NonTxCb.Multicast.McAddress[i*ETHERNET_ADDRESS_LENGTH];
for (j = 0; j < ETH_LENGTH_OF_ADDRESS; j++)
*(McAddress++) = FdoData->MCList[i][j];
}
FdoData->NonTxCmdBlock->NonTxCb.Multicast.McCount =
(USHORT)(FdoData->MCAddressCount * ETH_LENGTH_OF_ADDRESS);
((PCB_HEADER_STRUC)FdoData->NonTxCmdBlock)->CbStatus = 0;
((PCB_HEADER_STRUC)FdoData->NonTxCmdBlock)->CbCommand = CB_MULTICAST;
//
// Wait for the SCB to clear before we check the CU status.
//
if (!WaitScb(FdoData))
{
status = STATUS_DEVICE_DATA_ERROR;
MP_EXIT;
}
//
// If we have issued any transmits, then the CU will either be active, or
// in the suspended state. If the CU is active, then we wait for it to be
// suspended.
//
if (FdoData->TransmitIdle == FALSE)
{
//
// Wait for suspended state
//
MP_STALL_AND_WAIT((FdoData->CSRAddress->ScbStatus & SCB_CUS_MASK) != SCB_CUS_ACTIVE, 5000, bResult);
if (!bResult)
{
MP_SET_HARDWARE_ERROR(FdoData);
status = STATUS_DEVICE_DATA_ERROR;
}
//
// Restore the transmit software flags. After the multicast command is
// issued, the command unit will be idle, because the EL bit will be
// set in the multicast commmand block.
//
FdoData->TransmitIdle = TRUE;
FdoData->ResumeWait = TRUE;
}
//
// Update the command list pointer.
//
FdoData->CSRAddress->ScbGeneralPointer = FdoData->NonTxCmdBlockPhys;
//
// Submit the multicast command to the FdoData and wait for it to complete.
//
status = D100SubmitCommandBlockAndWait(FdoData);
if (status != STATUS_SUCCESS)
{
status = STATUS_DEVICE_NOT_READY;
}
exit:
DebugPrint(TRACE, DBG_IOCTLS, "<-- NICSetMulticastList, status=%x\n", status);
return(status);
}
VOID
NICFillPoMgmtCaps (
IN PFDO_DATA FdoData,
IN OUT PNDIS_PNP_CAPABILITIES pPower_Management_Capabilities,
IN OUT PNDIS_STATUS pStatus,
IN OUT PULONG pulInfoLen
)
/*++
Routine Description:
Fills in the Power Managment structure depending the capabilities of
the software driver and the card.
Currently this is only supported on 82559 Version of the driver
Arguments:
FdoData Pointer to the FdoData structure
pPower_Management_Capabilities - Power management struct as defined in the DDK,
pStatus Status to be returned by the request,
pulInfoLen Length of the pPowerManagmentCapabilites
Return Value:
Success or failure depending on the type of card
--*/
{
BOOLEAN bIsPoMgmtSupported;
bIsPoMgmtSupported = IsPoMgmtSupported(FdoData);
if (bIsPoMgmtSupported == TRUE)
{
pPower_Management_Capabilities->Flags = NDIS_DEVICE_WAKE_UP_ENABLE;
pPower_Management_Capabilities->WakeUpCapabilities.MinMagicPacketWakeUp = NdisDeviceStateUnspecified;
pPower_Management_Capabilities->WakeUpCapabilities.MinPatternWakeUp = NdisDeviceStateD3;
pPower_Management_Capabilities->WakeUpCapabilities.MinLinkChangeWakeUp = NdisDeviceStateUnspecified;
*pulInfoLen = sizeof (*pPower_Management_Capabilities);
*pStatus = STATUS_SUCCESS;
}
else
{
RtlZeroMemory (pPower_Management_Capabilities, sizeof(*pPower_Management_Capabilities));
*pStatus = STATUS_NOT_SUPPORTED;
*pulInfoLen = 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -