Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

389 lines
14 KiB

/*
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
(C) Copyright 1998
All rights reserved.
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
Portions of this software are:
(C) Copyright 1995, 1999 TriplePoint, Inc. -- http://www.TriplePoint.com
License to use this software is granted under the terms outlined in
the TriplePoint Software Services Agreement.
(C) Copyright 1992 Microsoft Corp. -- http://www.Microsoft.com
License to use this software is granted under the terms outlined in
the Microsoft Windows Device Driver Development Kit.
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
@doc INTERNAL Link Link_c
@module Link.c |
This module implements the NDIS_MAC_LINE_UP, NDIS_MAC_LINE_DOWN, and
NDIS_MAC_FRAGMENT interfaces between the NDIS WAN Miniport and the
NDIS WAN Wrapper.
@head3 Contents |
@index class,mfunc,func,msg,mdata,struct,enum | Link_c
@end
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
*/
#define __FILEID__ LINK_OBJECT_TYPE
// Unique file ID for error logging
#include "Miniport.h" // Defines all the miniport objects
#if defined(NDIS_LCODE)
# pragma NDIS_LCODE // Windows 95 wants this code locked down!
# pragma NDIS_LDATA
#endif
/* @doc INTERNAL Link Link_c NDIS_MAC_LINE_UP
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
@struct NDIS_MAC_LINE_UP |
This structure is passed to <f NdisMIndicateStatus> with the
<t NDIS_STATUS_WAN_LINE_UP> status message when <f LinkLineUp> is
called by the Miniport.
@field IN ULONG | LinkSpeed |
The speed of the link, in 100 bps units (bits per second).
@field IN NDIS_WAN_QUALITY | Quality |
The quality of service indicator for this link.
@field IN USHORT | SendWindow |
The recommended send window, i.e., the number of packets that should
be given to the adapter before pausing to wait for an acknowledgement.
Some devices achieve higher throughput if they have several packets
to send at once; others are especially unreliable. A value of zero
indicates no recommendation.
@field IN NDIS_HANDLE | ConnectionWrapperID |
The Miniport supplied handle by which this line will be known to the
Connection Wrapper clients. This must be a unique handle across all
drivers using the Connection Wrapper, so typically <f htCall> should
be used to gaurantee it is unique. This must be the same value
returned from the OID_TAPI_GETID request for the <p "ndis">
DeviceClass (See <f TspiGetID>). Refer to the Connection Wrapper
Interface Specification for further details. If not using the
Connection Wrapper, this value must be zero.
@field IN NDIS_HANDLE | MiniportLinkContext |
The Miniport supplied handle passed down in future Miniport calls
(such as <f MiniportWanSend> for this link. Typically, the Miniport
will provide a pointer to its control block for that link. The value
must be unique, for the first LINE_UP indication on a particular
link. Subsequent LINE_UP indications may be called if line
characteristics change. When subsequent LINE_UP indication calls are
made, the <p MiniportLinkContext> must be filled with the value
returned on the first LINE_UP indication call.
@field IN NDIS_HANDLE | NdisLinkContext |
The WAN wrapper supplied handle to be used in future Miniport calls
(such as <f NdisMWanIndicateReceive>) to the WAN Wrapper. The WAN
Wrapper will provide a unique handle for every LINE_UP indication.
The <p NdisLinkContext> must be zero if this is the first LINE_UP
indication. It must contain the value returned on the first LINE_UP
indication for subsequent LINE_UP indication calls.
*/
/* @doc INTERNAL Link Link_c LinkLineUp
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
@func
<f LinkLineUp> marks a link as connected and sends a LINE_UP indication
to the WAN wrapper.
A line up indication is generated when a new link becomes active. Prior
to this the MAC will accept frames and may let them succeed or fail, but
it is unlikely that they will actually be received by any remote. During
this state protocols are encouraged to reduce their timers and retry
counts so as to quickly fail any outgoing connection attempts.
<f Note>: This indication must be sent to the WAN wrapper prior to returning
from the OID_TAPI_ANSWER request, and prior to indicating the
LINECALLSTATE_CONNECTED to the Connection Wrapper. Otherwise, the
Connection Wrapper client might attempt to send data to the WAN wrapper
before it is aware of the line.
@comm
The status code for the line up indication is <t NDIS_STATUS_WAN_LINE_UP>
and is passed to <f NdisMIndicateStatus>. The format of the StatusBuffer
for this code is defined by <t NDIS_MAC_LINE_UP>.
*/
VOID LinkLineUp(
IN PBCHANNEL_OBJECT pBChannel // @parm
// A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
)
{
DBG_FUNC("LinkLineUp")
NDIS_MAC_LINE_UP LineUpInfo;
// Line up structure passed to NdisMIndicateStatus.
PMINIPORT_ADAPTER_OBJECT pAdapter;
// A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
ASSERT(pBChannel && pBChannel->ObjectType == BCHANNEL_OBJECT_TYPE);
pAdapter = GET_ADAPTER_FROM_BCHANNEL(pBChannel);
/*
// We can't bring up a NULL link.
*/
if (pBChannel->IsOpen && pBChannel->NdisLinkContext == NULL)
{
DBG_ENTER(pAdapter);
ASSERT(pBChannel->htCall);
/*
// Initialize the LINE_UP event packet.
*/
LineUpInfo.LinkSpeed = pBChannel->LinkSpeed / 100;
LineUpInfo.Quality = NdisWanErrorControl;
LineUpInfo.SendWindow = (USHORT)pAdapter->WanInfo.MaxTransmit;
LineUpInfo.ConnectionWrapperID = (NDIS_HANDLE) pBChannel->htCall;
LineUpInfo.MiniportLinkContext = pBChannel;
LineUpInfo.NdisLinkContext = pBChannel->NdisLinkContext;
/*
// Indicate the event to the WAN wrapper.
*/
NdisMIndicateStatus(pAdapter->MiniportAdapterHandle,
NDIS_STATUS_WAN_LINE_UP,
&LineUpInfo,
sizeof(LineUpInfo)
);
pAdapter->NeedStatusCompleteIndication = TRUE;
/*
// Save the WAN wrapper link context for use when indicating received
// packets and errors.
*/
pBChannel->NdisLinkContext = LineUpInfo.NdisLinkContext;
DBG_FILTER(pAdapter,DBG_TAPICALL_ON,
("#%d Call=0x%X CallState=0x%X NdisLinkContext=0x%X MiniportLinkContext=0x%X\n",
pBChannel->BChannelIndex,
pBChannel->htCall, pBChannel->CallState,
pBChannel->NdisLinkContext,
pBChannel
));
DBG_LEAVE(pAdapter);
}
}
/* @doc INTERNAL Link Link_c NDIS_MAC_LINE_DOWN
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
@struct NDIS_MAC_LINE_DOWN |
This structure is passed to <f NdisMIndicateStatus> with the
<t NDIS_STATUS_WAN_LINE_DOWN> status message when <f LinkLineDown>
is called by the Miniport.
@field IN NDIS_HANDLE | NdisLinkContext |
The value returned in the <t NDIS_MAC_LINE_UP> structure during a
previous call to <f LinkLineUp>.
*/
/* @doc INTERNAL Link Link_c LinkLineDown
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
@func
<f LinkLineDown> marks a link as disconnected and sends a LINE_DOWN
indication to the WAN wrapper.
A line down indication is generated when a link goes down. Protocols
should again reduce their timers and retry counts until the next line
up indication.
@comm
The status code for the line down indication is <t NDIS_STATUS_WAN_LINE_DOWN>
and is passed to <f NdisMIndicateStatus>. The format of the StatusBuffer
for this code is defined by <t NDIS_MAC_LINE_DOWN>.
*/
VOID LinkLineDown(
IN PBCHANNEL_OBJECT pBChannel // @parm
// A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
)
{
DBG_FUNC("LinkLineDown")
NDIS_MAC_LINE_DOWN LineDownInfo;
// Line down structure passed to NdisMIndicateStatus.
PMINIPORT_ADAPTER_OBJECT pAdapter;
// A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
ASSERT(pBChannel && pBChannel->ObjectType == BCHANNEL_OBJECT_TYPE);
pAdapter = GET_ADAPTER_FROM_BCHANNEL(pBChannel);
/*
// We can't allow indications to NULL...
*/
if (pBChannel->NdisLinkContext)
{
DBG_ENTER(pAdapter);
DBG_FILTER(pAdapter,DBG_TAPICALL_ON,
("#%d Call=0x%X CallState=0x%X NdisLinkContext=0x%X MiniportLinkContext=0x%X\n",
pBChannel->BChannelIndex,
pBChannel->htCall, pBChannel->CallState,
pBChannel->NdisLinkContext,
pBChannel
));
/*
// Setup the LINE_DOWN event packet and indicate the event to the
// WAN wrapper.
*/
LineDownInfo.NdisLinkContext = pBChannel->NdisLinkContext;
NdisMIndicateStatus(pAdapter->MiniportAdapterHandle,
NDIS_STATUS_WAN_LINE_DOWN,
&LineDownInfo,
sizeof(LineDownInfo)
);
pAdapter->NeedStatusCompleteIndication = TRUE;
/*
// The line is down, so there's no more context for receives.
*/
pBChannel->NdisLinkContext = NULL;
pBChannel->CallClosing = FALSE;
DBG_LEAVE(pAdapter);
}
}
/* @doc INTERNAL Link Link_c NDIS_MAC_FRAGMENT
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
@struct NDIS_MAC_FRAGMENT |
This structure is passed to <f NdisMIndicateStatus> with the
<t NDIS_STATUS_WAN_FRAGMENT> status message when <f LinkLineError>
is called by the Miniport.
@field IN NDIS_HANDLE | NdisLinkContext |
The value returned in the <t NDIS_MAC_LINE_UP> structure during a
previous call to <f LinkLineUp>.
@field IN ULONG | Errors |
Is a bit OR'd mask of the following values:
WAN_ERROR_CRC,
WAN_ERROR_FRAMING,
WAN_ERROR_HARDWAREOVERRUN,
WAN_ERROR_BUFFEROVERRUN,
WAN_ERROR_TIMEOUT,
WAN_ERROR_ALIGNMENT
*/
/* @doc INTERNAL Link Link_c LinkLineError
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
@func
<f LinkLineError> is used to indicate to the WAN wrapper that a partial
packet was received from the remote end. The <t NDIS_STATUS_WAN_FRAGMENT>
indication is used to notify WAN wrapper.
A fragment indication indicates that a partial packet was received from
the remote. The protocol is encouraged to send frames to the remote that
will notify it of this situation, rather than waiting for a timeout to
occur.
<f Note>: The WAN wrapper keeps track of dropped packets by counting the
number of fragment indications on the link.
@comm
The status code for the fragment indication is <t NDIS_STATUS_WAN_FRAGMENT>
and is passed to <f NdisMIndicateStatus>. The format of the StatusBuffer
for this code is defined by <t NDIS_MAC_LINE_DOWN>.
*/
void LinkLineError(
IN PBCHANNEL_OBJECT pBChannel, // @parm
// A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
IN ULONG Errors // @parm
// A bit field set to one or more bits indicating the reason the fragment
// was received. If no direct mapping from the WAN medium error to one
// of the six errors listed below exists, choose the most apropriate
// error.
)
{
DBG_FUNC("LinkLineError")
NDIS_MAC_FRAGMENT FragmentInfo;
// Error information structure passed to NdisMIndicateStatus.
PMINIPORT_ADAPTER_OBJECT pAdapter;
// A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
ASSERT(pBChannel && pBChannel->ObjectType == BCHANNEL_OBJECT_TYPE);
pAdapter = GET_ADAPTER_FROM_BCHANNEL(pBChannel);
/*
// NOTE - Don't report any errors until we receive at least one
// good packet. Connecting to a Digi NT system, we get a burst
// of bad packets while Digi tries some odd framing. After a
// couple seconds, Digi syncs up and things work okay.
*/
if (pBChannel->TotalRxPackets == 0)
{
return;
}
/*
// We can't allow indications to NULL...
*/
if (pBChannel->NdisLinkContext)
{
DBG_ENTER(pAdapter);
DBG_WARNING(pAdapter,
("#%d Call=0x%X CallState=0x%X NdisLinkContext=0x%X Errors=0x%X NumRxPkts=%d\n",
pBChannel->BChannelIndex,
pBChannel->htCall, pBChannel->CallState,
pBChannel->NdisLinkContext,
Errors, pBChannel->TotalRxPackets
));
/*
// Setup the FRAGMENT event packet and indicate it to the WAN wrapper.
*/
FragmentInfo.NdisLinkContext = pBChannel->NdisLinkContext;
FragmentInfo.Errors = Errors;
NdisMIndicateStatus(pAdapter->MiniportAdapterHandle,
NDIS_STATUS_WAN_FRAGMENT,
&FragmentInfo,
sizeof(FragmentInfo)
);
pAdapter->NeedStatusCompleteIndication = TRUE;
DBG_LEAVE(pAdapter);
}
}