📄 request.c
字号:
/****************************************************************************
** COPYRIGHT (C) 1994-1997 INTEL CORPORATION **
** DEVELOPED FOR MICROSOFT BY INTEL CORP., HILLSBORO, OREGON **
** HTTP://WWW.INTEL.COM/ **
** THIS FILE IS PART OF THE INTEL ETHEREXPRESS PRO/100B(TM) AND **
** ETHEREXPRESS PRO/100+(TM) NDIS 5.0 MINIPORT SAMPLE DRIVER **
****************************************************************************/
/****************************************************************************
Module Name:
request.c
This driver runs on the following hardware:
- 82557/82558 based PCI 10/100Mb ethernet adapters
(aka Intel EtherExpress(TM) PRO Adapters)
Environment:
Kernel Mode - Or whatever is the equivalent on WinNT
Revision History
- JCB 8/14/97 Example Driver Created
*****************************************************************************/
#include "precomp.h"
#include "d100.rc"
#pragma hdrstop
#pragma warning (disable: 4514)
//-----------------------------------------------------------------------------
// Procedure: D100SetPacketFilter
//
// Description: This routine will set up the adapter so that it accepts packets
// that match the specified packet filter. The only filter bits
// that can truly be toggled are for broadcast and promiscuous
//
// Arguments:
// Adapter - ptr to Adapter object instance
// NewPacketFilter - A bit-mask which contains the new packet filter.
//
// Returns:
// NDIS_STATUS_SUCCESS
// NDIS_STATUS_NOT_ACCEPTED
// NDIS_STATUS_NOT_SUPPORTED
//-----------------------------------------------------------------------------
NDIS_STATUS
D100SetPacketFilter(
IN PD100_ADAPTER Adapter,
IN ULONG NewPacketFilter
)
{
UCHAR NewParameterField;
UINT i;
NDIS_STATUS Status;
DEBUGFUNC("D100SetPacketFilter");
// the filtering changes need to result in the hardware being
// reset.
if (!((NewPacketFilter ^ Adapter->PacketFilter) &
(NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_MULTICAST |
NDIS_PACKET_TYPE_BROADCAST | NDIS_PACKET_TYPE_PROMISCUOUS |
NDIS_PACKET_TYPE_ALL_MULTICAST)))
{
REQUEST(Adapter, ("Filter Type %08x didn't change significantly, so return\n", NewPacketFilter));
// save the new packet filter in our adapter object
Adapter->PacketFilter = NewPacketFilter;
return (NDIS_STATUS_SUCCESS);
}
// save the new packet filter in our adapter object
Adapter->PacketFilter = NewPacketFilter;
// Need to enable or disable broadcast and promiscuous support depending
// on the new filter
NewParameterField = CB_557_CFIG_DEFAULT_PARM15;
if (NewPacketFilter & NDIS_PACKET_TYPE_BROADCAST)
NewParameterField &= ~CB_CFIG_BROADCAST_DIS;
else
NewParameterField |= CB_CFIG_BROADCAST_DIS;
if (NewPacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS)
NewParameterField |= CB_CFIG_PROMISCUOUS;
else
NewParameterField &= ~CB_CFIG_PROMISCUOUS;
// Only need to do something to the HW if the filter bits have changed.
if ((Adapter->OldParameterField != NewParameterField ) ||
(NewPacketFilter & NDIS_PACKET_TYPE_ALL_MULTICAST))
{
REQUEST(Adapter, ("Filter Type %08x changed -- doing re-config\n", NewPacketFilter));
Adapter->OldParameterField = NewParameterField;
Adapter->NonTxCmdBlockHdr->CbCommand = CB_CONFIGURE;
Adapter->NonTxCmdBlockHdr->CbStatus = 0;
Adapter->NonTxCmdBlockHdr->CbLinkPointer = DRIVER_NULL;
// First fill in the static (end user can't change) config bytes
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[0] = CB_557_CFIG_DEFAULT_PARM0;
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[2] = CB_557_CFIG_DEFAULT_PARM2;
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[3] = CB_557_CFIG_DEFAULT_PARM3;
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[9] = CB_557_CFIG_DEFAULT_PARM9;
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[10] = CB_557_CFIG_DEFAULT_PARM10;
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[11] = CB_557_CFIG_DEFAULT_PARM11;
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[12] = CB_557_CFIG_DEFAULT_PARM12;
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[13] = CB_557_CFIG_DEFAULT_PARM13;
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[14] = CB_557_CFIG_DEFAULT_PARM14;
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[15] = CB_557_CFIG_DEFAULT_PARM15;
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[16] = CB_557_CFIG_DEFAULT_PARM16;
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[17] = CB_557_CFIG_DEFAULT_PARM17;
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[18] = CB_557_CFIG_DEFAULT_PARM18;
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[20] = CB_557_CFIG_DEFAULT_PARM20;
// next toggle in or out of promiscuous mode
if (NewPacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS)
{
// turn on save bad frames
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[6] =
(CB_557_CFIG_DEFAULT_PARM6 | CB_CFIG_SAVE_BAD_FRAMES);
// turn on save short frames
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[7] =
(UCHAR) ((CB_557_CFIG_DEFAULT_PARM7 &
(~(CB_CFIG_URUN_RETRY | CB_CFIG_DISC_SHORT_FRAMES))) |
(Adapter->AiUnderrunRetry << 1)
);
}
else
{
// turn off save bad frames
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[6] =
CB_557_CFIG_DEFAULT_PARM6;
// turn off save short frames
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[7] =
(UCHAR) ((CB_557_CFIG_DEFAULT_PARM7 &
(~CB_CFIG_URUN_RETRY)) |
(Adapter->AiUnderrunRetry << 1)
);
}
// Set the Tx and Rx Fifo limits
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[1] =
(UCHAR) ((Adapter->AiTxFifo << 4) | Adapter->AiRxFifo);
// set the MWI enable bit if needed
if (Adapter->MWIEnable)
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[3] |= CB_CFIG_B3_MWI_ENABLE;
// Set the Tx and Rx DMA maximum byte count fields.
if ((Adapter->AiRxDmaCount) || (Adapter->AiTxDmaCount))
{
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[4] =
Adapter->AiRxDmaCount;
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[5] =
(UCHAR) (Adapter->AiTxDmaCount | CB_CFIG_DMBC_EN);
}
else
{
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[4] =
CB_557_CFIG_DEFAULT_PARM4;
Adapter->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 (Adapter->PhyAddress == 32)
{
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[8] =
(CB_557_CFIG_DEFAULT_PARM8 & (~CB_CFIG_503_MII));
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[15] =
(UCHAR) (NewParameterField | CB_CFIG_CRS_OR_CDT);
}
else
{
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[8] =
(CB_557_CFIG_DEFAULT_PARM8 | CB_CFIG_503_MII);
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[15] =
(UCHAR) (NewParameterField & (~CB_CFIG_CRS_OR_CDT));
}
// Setup Full duplex stuff
// If forced to half duplex
if (Adapter->AiForceDpx == 1)
Adapter->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 (Adapter->AiForceDpx == 2)
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[19] =
(CB_557_CFIG_DEFAULT_PARM19 | CB_CFIG_FORCE_FDX);
// If auto-duplex
else
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[19] =
CB_557_CFIG_DEFAULT_PARM19;
// if multicast all is being turned on, set the bit
if (NewPacketFilter & NDIS_PACKET_TYPE_ALL_MULTICAST)
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[21] =
(CB_557_CFIG_DEFAULT_PARM21 | CB_CFIG_MULTICAST_ALL);
else
Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[21] =
CB_557_CFIG_DEFAULT_PARM21;
// Wait for the SCB to clear before we check the CU status.
WaitScb(Adapter);
// 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 (Adapter->TransmitIdle == FALSE)
{
// Wait for suspended state
for (i = 200000; i != 0; i--)
{
if ((Adapter->CSRAddress->ScbStatus & SCB_CUS_MASK) != SCB_CUS_ACTIVE)
break;
NdisStallExecution(20);
}
if (!i)
{
HARDWARE_NOT_RESPONDING (Adapter);
Status = (NDIS_STATUS_FAILURE);
}
// 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.
Adapter->TransmitIdle = TRUE;
Adapter->ResumeWait = TRUE;
}
// display the config info to the debugger
REQUEST(Adapter, ("Re-Issuing Configure command for filter change\n"));
REQUEST(Adapter, ("Config Block at virt addr %x, phys address %x\n",
&Adapter->NonTxCmdBlockHdr->CbStatus, Adapter->NonTxCmdBlockPhys));
for (i=0; i < CB_CFIG_BYTE_COUNT; i++)
REQUEST(Adapter, (" Config byte %x = %.2x\n", i, Adapter->NonTxCmdBlock->NonTxCb.Config.ConfigBytes[i]));
Adapter->CSRAddress->ScbGeneralPointer = Adapter->NonTxCmdBlockPhys;
// Submit the configure command to the chip, and wait for it to complete.
if (!D100SubmitCommandBlockAndWait(Adapter))
Status = NDIS_STATUS_NOT_ACCEPTED;
else
Status = NDIS_STATUS_SUCCESS;
// Release the spinlock
return(Status);
}
REQUEST(Adapter, ("Filter Type %08x did not change config\n", NewPacketFilter));
return (NDIS_STATUS_SUCCESS);
}
//-----------------------------------------------------------------------------
// Procedure: D100ChangeMCAddresses
//
// Description: This routine will set up the adapter for a specified multicast
// address list.
//
// Arguments:
// Adapter - ptr to Adapter object instance
// AddressCount - The new number of Multicast addresses.
//
// Returns:
// NDIS_STATUS_SUCCESS
// NDIS_STATUS_NOT_ACCEPTED
//-----------------------------------------------------------------------------
NDIS_STATUS
D100ChangeMCAddresses(
IN PD100_ADAPTER Adapter,
IN UINT AddressCount
)
{
// Holds the change that should be returned to the filtering package.
PUCHAR McAddress;
UINT i, j;
NDIS_STATUS Status;
DEBUGFUNC("D100ChangeMCAddresses");
TRACE1(Adapter,("\n"));
TRACE1(Adapter,("Configuring for %x mc addresses\n", AddressCount));
DEBUGCHAR(Adapter,'M');
// Setup the command block for the multicast command.
for (i = 0;(i < AddressCount) && (i < MAX_MULTICAST_ADDRESSES);i++)
{
TRACE1(Adapter,(" mc %d =%.2x %.2x %.2x %.2x %.2x %.2x\n", i,
Adapter->PrivateMulticastBuffer[i][0],
Adapter->PrivateMulticastBuffer[i][1],
Adapter->PrivateMulticastBuffer[i][2],
Adapter->PrivateMulticastBuffer[i][3],
Adapter->PrivateMulticastBuffer[i][4],
Adapter->PrivateMulticastBuffer[i][5]));
McAddress = &Adapter->NonTxCmdBlock->NonTxCb.Multicast.McAddress[i*ETHERNET_ADDRESS_LENGTH];
for (j = 0; j < ETH_LENGTH_OF_ADDRESS; j++)
*(McAddress++) = Adapter->PrivateMulticastBuffer[i][j];
}
Adapter -> NonTxCmdBlock -> NonTxCb.Multicast.McCount =
(USHORT) (AddressCount * ETH_LENGTH_OF_ADDRESS);
Adapter->NonTxCmdBlockHdr->CbStatus = 0;
Adapter->NonTxCmdBlockHdr->CbCommand = CB_MULTICAST;
// Wait for the SCB to clear before we check the CU status.
WaitScb(Adapter);
// 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 (Adapter->TransmitIdle == FALSE)
{
// Wait for suspended state
for (i = 200000; i != 0; i--)
{
if ((Adapter->CSRAddress->ScbStatus & SCB_CUS_MASK) != SCB_CUS_ACTIVE)
break;
NdisStallExecution(20);
}
if (!i)
{
HARDWARE_NOT_RESPONDING (Adapter);
Status = (NDIS_STATUS_FAILURE);
}
// 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.
Adapter->TransmitIdle = TRUE;
Adapter->ResumeWait = TRUE;
}
// Update the command list pointer.
Adapter->CSRAddress->ScbGeneralPointer = Adapter->NonTxCmdBlockPhys;
// Submit the multicast command to the adapter and wait for it to complete.
if (!D100SubmitCommandBlockAndWait(Adapter))
Status = (NDIS_STATUS_NOT_ACCEPTED);
else
Status = (NDIS_STATUS_SUCCESS);
DEBUGCHAR(Adapter,'m');
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -