Source code of Windows XP (NT5)
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

  1. /*
  2. (C) Copyright 1998
  3. All rights reserved.
  4. Portions of this software are:
  5. (C) Copyright 1995, 1999 TriplePoint, Inc. -- http://www.TriplePoint.com
  6. License to use this software is granted under the terms outlined in
  7. the TriplePoint Software Services Agreement.
  8. (C) Copyright 1992 Microsoft Corp. -- http://www.Microsoft.com
  9. License to use this software is granted under the terms outlined in
  10. the Microsoft Windows Device Driver Development Kit.
  11. @doc INTERNAL Link Link_c
  12. @module Link.c |
  13. This module implements the NDIS_MAC_LINE_UP, NDIS_MAC_LINE_DOWN, and
  14. NDIS_MAC_FRAGMENT interfaces between the NDIS WAN Miniport and the
  15. NDIS WAN Wrapper.
  16. @head3 Contents |
  17. @index class,mfunc,func,msg,mdata,struct,enum | Link_c
  18. @end
  19. */
  20. #define __FILEID__ LINK_OBJECT_TYPE
  21. // Unique file ID for error logging
  22. #include "Miniport.h" // Defines all the miniport objects
  23. #if defined(NDIS_LCODE)
  24. # pragma NDIS_LCODE // Windows 95 wants this code locked down!
  25. # pragma NDIS_LDATA
  26. #endif
  27. /* @doc INTERNAL Link Link_c NDIS_MAC_LINE_UP
  28. @struct NDIS_MAC_LINE_UP |
  29. This structure is passed to <f NdisMIndicateStatus> with the
  30. <t NDIS_STATUS_WAN_LINE_UP> status message when <f LinkLineUp> is
  31. called by the Miniport.
  32. @field IN ULONG | LinkSpeed |
  33. The speed of the link, in 100 bps units (bits per second).
  34. @field IN NDIS_WAN_QUALITY | Quality |
  35. The quality of service indicator for this link.
  36. @field IN USHORT | SendWindow |
  37. The recommended send window, i.e., the number of packets that should
  38. be given to the adapter before pausing to wait for an acknowledgement.
  39. Some devices achieve higher throughput if they have several packets
  40. to send at once; others are especially unreliable. A value of zero
  41. indicates no recommendation.
  42. @field IN NDIS_HANDLE | ConnectionWrapperID |
  43. The Miniport supplied handle by which this line will be known to the
  44. Connection Wrapper clients. This must be a unique handle across all
  45. drivers using the Connection Wrapper, so typically <f htCall> should
  46. be used to gaurantee it is unique. This must be the same value
  47. returned from the OID_TAPI_GETID request for the <p "ndis">
  48. DeviceClass (See <f TspiGetID>). Refer to the Connection Wrapper
  49. Interface Specification for further details. If not using the
  50. Connection Wrapper, this value must be zero.
  51. @field IN NDIS_HANDLE | MiniportLinkContext |
  52. The Miniport supplied handle passed down in future Miniport calls
  53. (such as <f MiniportWanSend> for this link. Typically, the Miniport
  54. will provide a pointer to its control block for that link. The value
  55. must be unique, for the first LINE_UP indication on a particular
  56. link. Subsequent LINE_UP indications may be called if line
  57. characteristics change. When subsequent LINE_UP indication calls are
  58. made, the <p MiniportLinkContext> must be filled with the value
  59. returned on the first LINE_UP indication call.
  60. @field IN NDIS_HANDLE | NdisLinkContext |
  61. The WAN wrapper supplied handle to be used in future Miniport calls
  62. (such as <f NdisMWanIndicateReceive>) to the WAN Wrapper. The WAN
  63. Wrapper will provide a unique handle for every LINE_UP indication.
  64. The <p NdisLinkContext> must be zero if this is the first LINE_UP
  65. indication. It must contain the value returned on the first LINE_UP
  66. indication for subsequent LINE_UP indication calls.
  67. */
  68. /* @doc INTERNAL Link Link_c LinkLineUp
  69. @func
  70. <f LinkLineUp> marks a link as connected and sends a LINE_UP indication
  71. to the WAN wrapper.
  72. A line up indication is generated when a new link becomes active. Prior
  73. to this the MAC will accept frames and may let them succeed or fail, but
  74. it is unlikely that they will actually be received by any remote. During
  75. this state protocols are encouraged to reduce their timers and retry
  76. counts so as to quickly fail any outgoing connection attempts.
  77. <f Note>: This indication must be sent to the WAN wrapper prior to returning
  78. from the OID_TAPI_ANSWER request, and prior to indicating the
  79. LINECALLSTATE_CONNECTED to the Connection Wrapper. Otherwise, the
  80. Connection Wrapper client might attempt to send data to the WAN wrapper
  81. before it is aware of the line.
  82. @comm
  83. The status code for the line up indication is <t NDIS_STATUS_WAN_LINE_UP>
  84. and is passed to <f NdisMIndicateStatus>. The format of the StatusBuffer
  85. for this code is defined by <t NDIS_MAC_LINE_UP>.
  86. */
  87. VOID LinkLineUp(
  88. IN PBCHANNEL_OBJECT pBChannel // @parm
  89. // A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
  90. )
  91. {
  92. DBG_FUNC("LinkLineUp")
  93. NDIS_MAC_LINE_UP LineUpInfo;
  94. // Line up structure passed to NdisMIndicateStatus.
  95. PMINIPORT_ADAPTER_OBJECT pAdapter;
  96. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  97. ASSERT(pBChannel && pBChannel->ObjectType == BCHANNEL_OBJECT_TYPE);
  98. pAdapter = GET_ADAPTER_FROM_BCHANNEL(pBChannel);
  99. /*
  100. // We can't bring up a NULL link.
  101. */
  102. if (pBChannel->IsOpen && pBChannel->NdisLinkContext == NULL)
  103. {
  104. DBG_ENTER(pAdapter);
  105. ASSERT(pBChannel->htCall);
  106. /*
  107. // Initialize the LINE_UP event packet.
  108. */
  109. LineUpInfo.LinkSpeed = pBChannel->LinkSpeed / 100;
  110. LineUpInfo.Quality = NdisWanErrorControl;
  111. LineUpInfo.SendWindow = (USHORT)pAdapter->WanInfo.MaxTransmit;
  112. LineUpInfo.ConnectionWrapperID = (NDIS_HANDLE) pBChannel->htCall;
  113. LineUpInfo.MiniportLinkContext = pBChannel;
  114. LineUpInfo.NdisLinkContext = pBChannel->NdisLinkContext;
  115. /*
  116. // Indicate the event to the WAN wrapper.
  117. */
  118. NdisMIndicateStatus(pAdapter->MiniportAdapterHandle,
  119. NDIS_STATUS_WAN_LINE_UP,
  120. &LineUpInfo,
  121. sizeof(LineUpInfo)
  122. );
  123. pAdapter->NeedStatusCompleteIndication = TRUE;
  124. /*
  125. // Save the WAN wrapper link context for use when indicating received
  126. // packets and errors.
  127. */
  128. pBChannel->NdisLinkContext = LineUpInfo.NdisLinkContext;
  129. DBG_FILTER(pAdapter,DBG_TAPICALL_ON,
  130. ("#%d Call=0x%X CallState=0x%X NdisLinkContext=0x%X MiniportLinkContext=0x%X\n",
  131. pBChannel->BChannelIndex,
  132. pBChannel->htCall, pBChannel->CallState,
  133. pBChannel->NdisLinkContext,
  134. pBChannel
  135. ));
  136. DBG_LEAVE(pAdapter);
  137. }
  138. }
  139. /* @doc INTERNAL Link Link_c NDIS_MAC_LINE_DOWN
  140. @struct NDIS_MAC_LINE_DOWN |
  141. This structure is passed to <f NdisMIndicateStatus> with the
  142. <t NDIS_STATUS_WAN_LINE_DOWN> status message when <f LinkLineDown>
  143. is called by the Miniport.
  144. @field IN NDIS_HANDLE | NdisLinkContext |
  145. The value returned in the <t NDIS_MAC_LINE_UP> structure during a
  146. previous call to <f LinkLineUp>.
  147. */
  148. /* @doc INTERNAL Link Link_c LinkLineDown
  149. @func
  150. <f LinkLineDown> marks a link as disconnected and sends a LINE_DOWN
  151. indication to the WAN wrapper.
  152. A line down indication is generated when a link goes down. Protocols
  153. should again reduce their timers and retry counts until the next line
  154. up indication.
  155. @comm
  156. The status code for the line down indication is <t NDIS_STATUS_WAN_LINE_DOWN>
  157. and is passed to <f NdisMIndicateStatus>. The format of the StatusBuffer
  158. for this code is defined by <t NDIS_MAC_LINE_DOWN>.
  159. */
  160. VOID LinkLineDown(
  161. IN PBCHANNEL_OBJECT pBChannel // @parm
  162. // A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
  163. )
  164. {
  165. DBG_FUNC("LinkLineDown")
  166. NDIS_MAC_LINE_DOWN LineDownInfo;
  167. // Line down structure passed to NdisMIndicateStatus.
  168. PMINIPORT_ADAPTER_OBJECT pAdapter;
  169. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  170. ASSERT(pBChannel && pBChannel->ObjectType == BCHANNEL_OBJECT_TYPE);
  171. pAdapter = GET_ADAPTER_FROM_BCHANNEL(pBChannel);
  172. /*
  173. // We can't allow indications to NULL...
  174. */
  175. if (pBChannel->NdisLinkContext)
  176. {
  177. DBG_ENTER(pAdapter);
  178. DBG_FILTER(pAdapter,DBG_TAPICALL_ON,
  179. ("#%d Call=0x%X CallState=0x%X NdisLinkContext=0x%X MiniportLinkContext=0x%X\n",
  180. pBChannel->BChannelIndex,
  181. pBChannel->htCall, pBChannel->CallState,
  182. pBChannel->NdisLinkContext,
  183. pBChannel
  184. ));
  185. /*
  186. // Setup the LINE_DOWN event packet and indicate the event to the
  187. // WAN wrapper.
  188. */
  189. LineDownInfo.NdisLinkContext = pBChannel->NdisLinkContext;
  190. NdisMIndicateStatus(pAdapter->MiniportAdapterHandle,
  191. NDIS_STATUS_WAN_LINE_DOWN,
  192. &LineDownInfo,
  193. sizeof(LineDownInfo)
  194. );
  195. pAdapter->NeedStatusCompleteIndication = TRUE;
  196. /*
  197. // The line is down, so there's no more context for receives.
  198. */
  199. pBChannel->NdisLinkContext = NULL;
  200. pBChannel->CallClosing = FALSE;
  201. DBG_LEAVE(pAdapter);
  202. }
  203. }
  204. /* @doc INTERNAL Link Link_c NDIS_MAC_FRAGMENT
  205. @struct NDIS_MAC_FRAGMENT |
  206. This structure is passed to <f NdisMIndicateStatus> with the
  207. <t NDIS_STATUS_WAN_FRAGMENT> status message when <f LinkLineError>
  208. is called by the Miniport.
  209. @field IN NDIS_HANDLE | NdisLinkContext |
  210. The value returned in the <t NDIS_MAC_LINE_UP> structure during a
  211. previous call to <f LinkLineUp>.
  212. @field IN ULONG | Errors |
  213. Is a bit OR'd mask of the following values:
  214. WAN_ERROR_CRC,
  215. WAN_ERROR_FRAMING,
  216. WAN_ERROR_HARDWAREOVERRUN,
  217. WAN_ERROR_BUFFEROVERRUN,
  218. WAN_ERROR_TIMEOUT,
  219. WAN_ERROR_ALIGNMENT
  220. */
  221. /* @doc INTERNAL Link Link_c LinkLineError
  222. @func
  223. <f LinkLineError> is used to indicate to the WAN wrapper that a partial
  224. packet was received from the remote end. The <t NDIS_STATUS_WAN_FRAGMENT>
  225. indication is used to notify WAN wrapper.
  226. A fragment indication indicates that a partial packet was received from
  227. the remote. The protocol is encouraged to send frames to the remote that
  228. will notify it of this situation, rather than waiting for a timeout to
  229. occur.
  230. <f Note>: The WAN wrapper keeps track of dropped packets by counting the
  231. number of fragment indications on the link.
  232. @comm
  233. The status code for the fragment indication is <t NDIS_STATUS_WAN_FRAGMENT>
  234. and is passed to <f NdisMIndicateStatus>. The format of the StatusBuffer
  235. for this code is defined by <t NDIS_MAC_LINE_DOWN>.
  236. */
  237. void LinkLineError(
  238. IN PBCHANNEL_OBJECT pBChannel, // @parm
  239. // A pointer to the <t BCHANNEL_OBJECT> returned by <f BChannelCreate>.
  240. IN ULONG Errors // @parm
  241. // A bit field set to one or more bits indicating the reason the fragment
  242. // was received. If no direct mapping from the WAN medium error to one
  243. // of the six errors listed below exists, choose the most apropriate
  244. // error.
  245. )
  246. {
  247. DBG_FUNC("LinkLineError")
  248. NDIS_MAC_FRAGMENT FragmentInfo;
  249. // Error information structure passed to NdisMIndicateStatus.
  250. PMINIPORT_ADAPTER_OBJECT pAdapter;
  251. // A pointer to the <t MINIPORT_ADAPTER_OBJECT>.
  252. ASSERT(pBChannel && pBChannel->ObjectType == BCHANNEL_OBJECT_TYPE);
  253. pAdapter = GET_ADAPTER_FROM_BCHANNEL(pBChannel);
  254. /*
  255. // NOTE - Don't report any errors until we receive at least one
  256. // good packet. Connecting to a Digi NT system, we get a burst
  257. // of bad packets while Digi tries some odd framing. After a
  258. // couple seconds, Digi syncs up and things work okay.
  259. */
  260. if (pBChannel->TotalRxPackets == 0)
  261. {
  262. return;
  263. }
  264. /*
  265. // We can't allow indications to NULL...
  266. */
  267. if (pBChannel->NdisLinkContext)
  268. {
  269. DBG_ENTER(pAdapter);
  270. DBG_WARNING(pAdapter,
  271. ("#%d Call=0x%X CallState=0x%X NdisLinkContext=0x%X Errors=0x%X NumRxPkts=%d\n",
  272. pBChannel->BChannelIndex,
  273. pBChannel->htCall, pBChannel->CallState,
  274. pBChannel->NdisLinkContext,
  275. Errors, pBChannel->TotalRxPackets
  276. ));
  277. /*
  278. // Setup the FRAGMENT event packet and indicate it to the WAN wrapper.
  279. */
  280. FragmentInfo.NdisLinkContext = pBChannel->NdisLinkContext;
  281. FragmentInfo.Errors = Errors;
  282. NdisMIndicateStatus(pAdapter->MiniportAdapterHandle,
  283. NDIS_STATUS_WAN_FRAGMENT,
  284. &FragmentInfo,
  285. sizeof(FragmentInfo)
  286. );
  287. pAdapter->NeedStatusCompleteIndication = TRUE;
  288. DBG_LEAVE(pAdapter);
  289. }
  290. }