eth8xxc.c
来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 1,543 行 · 第 1/4 页
C
1,543 行
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG BytesRead,
OUT PULONG BytesNeeded)
/*++
Description:
ETH8XXSetInformation handles a set operation for a single OID.
For OID_GEN_CURRENT_PACKET_FILTER, the following list of packet
type filters are currently supported:
NDIS_PACKET_TYPE_DIRECTED - specific individual address
NDIS_PACKET_MULTICAST - list of group/individual addresses
NDIS_PACKET_TYPE_ALL_MULTICAST - all group addresses
NDIS_PACKET_TYPE_BROADCAST - broadcast address FF-FF-FF-FF-FF-FF
NDIS_PACKET_TYPE_PROMISCUOUS - receive all regardless of address
Arguments:
MiniportAdapterContext - the context value that the miniport
returned from eth8xxInitialize
(actually a pointer to an ETH8XX_ADAPTER)
Oid - the OID to be set
InformationBuffer - holds the data to be set
InformationBufferLength - the length of InformationBuffer
BytesRead - if the call is successful, returns the
number of bytes read from InformationBuffer
BytesNeeded - if InformationBuffer does not contain
enough data to satisfy the OID, returns the
amount of data expected
Return Value:
NDIS_STATUS_SUCCESS - if the OID was successfully set
NDIS_STATUS_PENDING - operation will be completed asynchronously
NDIS_STATUS_INVALID_LENGTH - incorrect information buffer length
NDIS_STATUS_INVALID_OID - invalid/unsupported OID
--*/
{
/* Pointer to the adapter structure. */
PETH8XX_ADAPTER Adapter =
PETH8XX_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
UINT BytesLeft = InformationBufferLength;
PUCHAR InfoBuffer = (PUCHAR)(InformationBuffer);
UINT OidLength;
NDIS_STATUS Rc = NDIS_STATUS_SUCCESS;
ULONG Filter; /* Temporary holding place. */
ULONG LookAhead;
DEBUGMSG(ZONE_INIT | ZONE_FUNCTION,
(TEXT("+ETH8XX: eth8xxSetInformation\r\n")));
/* Get OID and Length of the request. */
OidLength = BytesLeft;
switch (Oid)
{
case OID_802_3_MULTICAST_LIST:
DEBUGMSG(ZONE_INIT | ZONE_FUNCTION,
(TEXT(" ETH8XX: OID_802_3_MULTICAST_LIST\r\n")));
/* Verify the length. */
if ((OidLength % ETH_LENGTH_OF_ADDRESS) != 0)
{
Rc = NDIS_STATUS_INVALID_LENGTH;
*BytesRead = 0;
*BytesNeeded = 0;
break;
}
/* Set the new list on the adapter. */
NdisMoveMemory(Adapter->Addresses, InfoBuffer, OidLength);
/* If we are currently receiving all multicast or
* we are promsicuous then we DO NOT call this, or
* it will reset those settings.
*/
if (!(Adapter->PacketFilter & (NDIS_PACKET_TYPE_ALL_MULTICAST
| NDIS_PACKET_TYPE_PROMISCUOUS)))
{
Adapter->NbrMulticasts = OidLength / ETH_LENGTH_OF_ADDRESS;
Rc = eth8xxSetMulticastAddressList(Adapter);
} else {
/* List of multicast addresses kept in Adapter->Addresses. */
Rc = NDIS_STATUS_SUCCESS;
}
break;
case OID_GEN_CURRENT_PACKET_FILTER:
DEBUGMSG(ZONE_INIT | ZONE_FUNCTION,
(TEXT(" ETH8XX: OID_GEN_CURRENT_PACKET_FILTER\r\n")));
if (OidLength != 4 )
{
Rc = NDIS_STATUS_INVALID_LENGTH;
*BytesRead = 0;
*BytesNeeded = 0;
} else {
NdisMoveMemory(&Filter, InfoBuffer, 4);
DEBUGMSG(ZONE_INIT,
(TEXT(" ETH8XX: Previous Filter: %d\r\n"),
Adapter->PrevFilter));
DEBUGMSG(ZONE_INIT,
(TEXT(" ETH8XX: Current Filter : %d\r\n"),
Adapter->PacketFilter));
DEBUGMSG(ZONE_INIT,
(TEXT(" ETH8XX: New Filter : %d\r\n"), Filter));
/* Verify that the requested filter is supported. */
if (Filter & ~(NDIS_PACKET_TYPE_DIRECTED
| NDIS_PACKET_TYPE_MULTICAST
| NDIS_PACKET_TYPE_ALL_MULTICAST
| NDIS_PACKET_TYPE_PROMISCUOUS
| NDIS_PACKET_TYPE_BROADCAST
))
{
DEBUGMSG(ZONE_ERROR,
(TEXT(" ETH8XX: returning NDIS_STATUS_NOT_SUPPORTED\r\n")));
Rc = NDIS_STATUS_NOT_SUPPORTED;
*BytesRead = 4;
*BytesNeeded = 0;
} else {
/* Set the new value on the adapter. */
Adapter->PrevFilter = Adapter->PacketFilter;
Adapter->PacketFilter = Filter;
Rc = eth8xxSetPacketFilter(Adapter);
}
}
break;
case OID_GEN_CURRENT_LOOKAHEAD:
DEBUGMSG(ZONE_INIT | ZONE_FUNCTION,
(TEXT(" ETH8XX: OID_CUR_LOOKAHEAD\r\n")));
/* Verify the length. */
if (OidLength != 4)
{
Rc = NDIS_STATUS_INVALID_LENGTH;
*BytesRead = 0;
*BytesNeeded = 0;
break;
}
/* Store the new value. */
NdisMoveMemory(&LookAhead, InfoBuffer, 4);
if (LookAhead <= (ULONG)ETH8XX_MAX_LOOKAHEAD)
{
Adapter->MaxLookAhead = LookAhead;
} else {
Rc = NDIS_STATUS_INVALID_LENGTH;
}
break;
default:
DEBUGMSG(ZONE_INIT | ZONE_FUNCTION,
(TEXT(" ETH8XX: OID_INVALID\r\n")));
*BytesRead = 0;
*BytesNeeded = 0;
Rc = NDIS_STATUS_INVALID_OID;
}
if (Rc == NDIS_STATUS_SUCCESS)
{
*BytesRead = BytesLeft;
*BytesNeeded = 0;
}
DEBUGMSG(ZONE_INIT | ZONE_FUNCTION,
(TEXT("-ETH8XX: eth8xxSetInformation\r\n")));
return(Rc);
}
/*----------------------------------------------------------------------*/
NDIS_STATUS eth8xxSetPacketFilter(IN PETH8XX_ADAPTER Adapter)
/*++
Description:
Configures the incoming frame address filter for the Ethernet
interface. The "if...else" blocks are there to avoid unnecessary
hardware accesses which in some cases can be time consuming
(specifically if the Ethernet interface has to be stopped and
then restarted).
Arguments:
Adapter - pointer to the NDIS miniport adapter block
Return Value:
NDIS_STATUS_SUCCESS - successfully updated address filter
NDIS_STATUS_FAILURE - failed to update address filter
Notes:
Note that to receive all multicast packets the multicast
registers on the Ethernet interface must be filled with 1's.
To be promiscuous that must be done as well as setting the
promiscuous physical flag in the PSMR. This must be done
as long as ANY protocol bound to this adapter has their
filter set accordingly.
--*/
{
NDIS_STATUS rc = NDIS_STATUS_SUCCESS;
DEBUGMSG(ZONE_FUNCTION | ZONE_INIT,
(TEXT("+ETH8XX: eth8xxSetPacketFilter\r\n")));
/* Handle setting/clearing ALL MULTICAST mode filter. */
if (Adapter->PacketFilter & NDIS_PACKET_TYPE_ALL_MULTICAST)
{
if (!(Adapter->PrevFilter & NDIS_PACKET_TYPE_ALL_MULTICAST))
{
/* Enable reception of "all multicast" frames. */
rc = HW_Set_All_Multicast(Adapter, TRUE);
}
} else if ((Adapter->PacketFilter & NDIS_PACKET_TYPE_MULTICAST)
&& (Adapter->NbrMulticasts > 0)) {
/* No need for ALL MULTICAST, use specific multicast addresses. */
rc = eth8xxSetMulticastAddressList(Adapter);
} else if (Adapter->PrevFilter & NDIS_PACKET_TYPE_ALL_MULTICAST) {
/* Turn off "all multicast" mode. */
rc = HW_Set_All_Multicast(Adapter, FALSE);
}
/* Handle setting/clearing PROMISCUOUS mode filter. */
if (Adapter->PacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS)
{
if (!(Adapter->PrevFilter & NDIS_PACKET_TYPE_PROMISCUOUS))
{
/* Enable reception of all frames. */
HW_Set_Promiscuous(Adapter, TRUE);
}
} else if (Adapter->PrevFilter & NDIS_PACKET_TYPE_PROMISCUOUS) {
/* Disable promiscuous mode. */
HW_Set_Promiscuous(Adapter, FALSE);
}
/* Handle setting/clearing BROADCAST reception mode filter. */
if (Adapter->PacketFilter & NDIS_PACKET_TYPE_BROADCAST)
{
if (!(Adapter->PrevFilter & NDIS_PACKET_TYPE_BROADCAST))
{
/* Turn on receiving all broadcast frames. */
HW_Set_Broadcast(Adapter, TRUE);
}
} else if (Adapter->PrevFilter & NDIS_PACKET_TYPE_BROADCAST) {
/* Discard all broadcast frames. */
HW_Set_Broadcast(Adapter, FALSE);
}
DEBUGMSG(ZONE_FUNCTION | ZONE_INIT,
(TEXT("-ETH8XX: eth8xxSetPacketFilter\r\n")));
return(NDIS_STATUS_SUCCESS);
}
/*----------------------------------------------------------------------*/
NDIS_STATUS eth8xxSetMulticastAddressList(IN PETH8XX_ADAPTER Adapter)
/*++
Description:
Sets the Ethernet multicast address list for this adapter.
Arguments:
Adapter - pointer to the NDIS miniport adapter block
Return Value:
NDIS_STATUS_SUCCESS - successfully set multicast list
NDIS_STATUS_FAILURE - failed to update multicast list
Notes:
When invoked, we must ensure that the multicast list in the filter
package becomes the multicast list for the adapter. To do this, we
determine the required contents of the CPM multicast registers and
update them. The MPC821 User's Guide also states that the adapter
does not need to be stopped prior to executing the SET GROUP ADDRESS
command.
--*/
{
NDIS_STATUS rc = NDIS_STATUS_FAILURE;
DEBUGMSG(ZONE_INIT|ZONE_FUNCTION,
(TEXT("+ETH8XX: eth8xxSetMulticastAddress\r\n")));
/* Update the Individual and Group multicast registers. */
if (HW_Fill_Multicast_Regs(Adapter))
{
rc = NDIS_STATUS_SUCCESS;
}
DEBUGMSG(ZONE_INIT|ZONE_FUNCTION,
(TEXT("-ETH8XX: eth8xxSetMulticastAddress\r\n")));
return(rc);
}
/*----------------------------------------------------------------------*/
NDIS_STATUS eth8xxSend(IN NDIS_HANDLE MiniportAdapterContext,
IN PNDIS_PACKET Packet,
IN UINT Flags)
/*++
Description:
The eth8xxSend request instructs the driver to transmit a packet
through the Ethernet interface onto the medium.
Arguments:
MiniportAdapterContext - Context registered with the wrapper, really
a pointer to the adapter.
Packet - A pointer to a descriptor for the packet that
is to be transmitted.
SendFlags - Optional send flags.
Notes:
This miniport driver will accept multiple send requests (until
the transmit queue is filled up). This will keep the CPM as busy
as possible, i.e. when a transmit interrupt has been handled the
next transmission can be immediately initiated.
--*/
{
PETH8XX_ADAPTER Adapter =
PETH8XX_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
NDIS_STATUS sendStatus;
DEBUGMSG(ZONE_FUNCTION | ZONE_XMIT,
(TEXT("+ETH8XX: eth8xxSend\r\n")));
EnterCriticalSection(&v_UpdateTxBufList);
/* Put the packet on the send queue. */
if (Adapter->FirstPacket == NULL)
{
Adapter->FirstPacket = Packet;
} else {
RESERVED(Adapter->LastPacket)->Next = Packet;
}
RESERVED(Packet)->Next = NULL;
Adapter->LastPacket = Packet;
LeaveCriticalSection(&v_UpdateTxBufList);
/* Process the send queue. */
sendStatus = eth8xxDoNextSend(Adapter, FALSE);
DEBUGMSG(ZONE_FUNCTION | ZONE_XMIT,
(TEXT("-ETH8XX: eth8xxSend\r\n")));
return(sendStatus);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?