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.

2718 lines
61 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. adapter.c - Adapter Interface routines.
  5. Abstract:
  6. Handlers for adapter events are here. The only exception is the
  7. CoReceivePacket handler, which is in arppkt.c.
  8. Revision History:
  9. Who When What
  10. -------- -------- ----------------------------------------------
  11. arvindm 08-12-96 Created
  12. Notes:
  13. --*/
  14. #include <precomp.h>
  15. #define _FILENUMBER 'PADA'
  16. ULONG MCastSendOk = 0;
  17. ULONG MCastSendFail = 0;
  18. ULONG MCastRcv = 0;
  19. INT
  20. AtmArpBindAdapterHandler(
  21. OUT PNDIS_STATUS pStatus,
  22. IN NDIS_HANDLE BindContext,
  23. IN PNDIS_STRING pDeviceName,
  24. IN PVOID SystemSpecific1,
  25. IN PVOID SystemSpecific2
  26. )
  27. /*++
  28. Routine Description:
  29. This is called by NDIS when it has an adapter for which there is a
  30. binding to the ATMARP client.
  31. We first allocate an Adapter structure. Then we open our configuration
  32. section for this adapter and save the handle in the Adapter structure.
  33. Finally, we open the adapter.
  34. We don't do anything more for this adapter until NDIS notifies us of
  35. the presence of a Call manager (via our AfRegisterNotify handler).
  36. Arguments:
  37. pStatus - Place to return status of this call
  38. BindContext - Not used, because we don't pend this call
  39. pDeviceName - The name of the adapter we are requested to bind to
  40. SystemSpecific1 - Opaque to us; to be used to access configuration info
  41. SystemSpecific2 - Opaque to us; not used.
  42. Return Value:
  43. Always TRUE. We set *pStatus to an error code if something goes wrong before we
  44. call NdisOpenAdapter, otherwise NDIS_STATUS_PENDING.
  45. --*/
  46. {
  47. PATMARP_ADAPTER pAdapter; // Pointer to new adapter structure
  48. PATMARP_ADAPTER * ppAdapter; // Used in case we need to delink
  49. NDIS_STATUS Status;
  50. NDIS_STATUS OpenStatus;
  51. UINT MediumIndex;
  52. ULONG Length;
  53. PNDIS_STRING pAdapterConfigString;
  54. #ifdef ATMARP_WIN98
  55. PANSI_STRING pAnsiConfigString;
  56. NDIS_STRING UnicodeConfigString;
  57. #endif
  58. AADEBUGP(AAD_LOUD,
  59. ("BindAdapter: Context 0x%x, pDevName 0x%x, SS1 0x%x, SS2 0x%x\n",
  60. BindContext, pDeviceName, SystemSpecific1, SystemSpecific2));
  61. #if DBG
  62. if (AaSkipAll)
  63. {
  64. AADEBUGP(AAD_ERROR, ("BindAdapter: aborting\n"));
  65. *pStatus = NDIS_STATUS_NOT_RECOGNIZED;
  66. return ((INT)TRUE);
  67. }
  68. #endif // DBG
  69. //
  70. // Initialize.
  71. //
  72. pAdapter = NULL_PATMARP_ADAPTER;
  73. Status = NDIS_STATUS_SUCCESS;
  74. #ifdef ATMARP_WIN98
  75. UnicodeConfigString.Buffer = NULL;
  76. #endif
  77. do
  78. {
  79. #ifndef ATMARP_WIN98
  80. pAdapterConfigString = (PNDIS_STRING)SystemSpecific1;
  81. #else
  82. //
  83. // SS1 is a pointer to an ANSI string. Convert it to Unicode.
  84. //
  85. pAnsiConfigString = (PANSI_STRING)SystemSpecific1;
  86. AA_ALLOC_MEM(UnicodeConfigString.Buffer, WCHAR, sizeof(WCHAR)*(pAnsiConfigString->MaximumLength));
  87. if (UnicodeConfigString.Buffer == NULL)
  88. {
  89. Status = NDIS_STATUS_RESOURCES;
  90. break;
  91. }
  92. UnicodeConfigString.MaximumLength = sizeof(WCHAR) * (pAnsiConfigString->MaximumLength);
  93. UnicodeConfigString.Length = 0;
  94. NdisAnsiStringToUnicodeString(&UnicodeConfigString, pAnsiConfigString);
  95. pAdapterConfigString = &UnicodeConfigString;
  96. #endif
  97. //
  98. // Check if this is a device we have already bound to.
  99. //
  100. if (AtmArpIsDeviceAlreadyBound(pDeviceName))
  101. {
  102. Status = NDIS_STATUS_NOT_ACCEPTED;
  103. AADEBUGP(AAD_WARNING, ("BindAdapter: already bound to %Z\n", pDeviceName));
  104. break;
  105. }
  106. //
  107. // Allocate an Adapter structure
  108. //
  109. Length = sizeof(ATMARP_ADAPTER) + pDeviceName->MaximumLength + sizeof(WCHAR) + pAdapterConfigString->MaximumLength;
  110. AA_ALLOC_MEM(pAdapter, ATMARP_ADAPTER, Length);
  111. if (pAdapter == NULL_PATMARP_ADAPTER)
  112. {
  113. Status = NDIS_STATUS_RESOURCES;
  114. break;
  115. }
  116. //
  117. // Initialize the Adapter structure
  118. //
  119. AA_SET_MEM(pAdapter, 0, Length);
  120. #if DBG
  121. pAdapter->aaa_sig = aaa_signature;
  122. #endif // DBG
  123. AA_INIT_BLOCK_STRUCT(&(pAdapter->Block));
  124. pAdapter->SystemSpecific1 = SystemSpecific1;
  125. pAdapter->SystemSpecific2 = SystemSpecific2;
  126. pAdapter->BindContext = BindContext;
  127. pAdapter->DeviceName.MaximumLength = pDeviceName->MaximumLength;
  128. pAdapter->DeviceName.Length = pDeviceName->Length;
  129. pAdapter->DeviceName.Buffer = (PWCHAR)((PUCHAR)pAdapter + sizeof(ATMARP_ADAPTER));
  130. AA_COPY_MEM(pAdapter->DeviceName.Buffer,
  131. pDeviceName->Buffer,
  132. pDeviceName->Length);
  133. //
  134. // Copy in the string to be used when we want to open our
  135. // configuration key for this adapter.
  136. //
  137. pAdapter->ConfigString.MaximumLength = pAdapterConfigString->MaximumLength;
  138. pAdapter->ConfigString.Length = pAdapterConfigString->Length;
  139. pAdapter->ConfigString.Buffer = (PWCHAR)((PUCHAR)pAdapter + sizeof(ATMARP_ADAPTER)+ pDeviceName->MaximumLength) + sizeof(WCHAR);
  140. AA_COPY_MEM(pAdapter->ConfigString.Buffer,
  141. pAdapterConfigString->Buffer,
  142. pAdapterConfigString->Length);
  143. AA_INIT_BLOCK_STRUCT(&pAdapter->UnbindBlock);
  144. AA_ACQUIRE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  145. //
  146. // Link this Adapter structure to the global list of adapters.
  147. //
  148. pAtmArpGlobalInfo->AdapterCount++;
  149. pAdapter->pNextAdapter = pAtmArpGlobalInfo->pAdapterList;
  150. pAtmArpGlobalInfo->pAdapterList = pAdapter;
  151. AA_RELEASE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  152. //
  153. // Open the adapter
  154. //
  155. pAdapter->Medium = NdisMediumAtm;
  156. NdisOpenAdapter(
  157. &Status,
  158. &OpenStatus,
  159. &(pAdapter->NdisAdapterHandle),
  160. &(MediumIndex), // place to return selected medium index
  161. &pAdapter->Medium, // Array of medium types
  162. 1, // Size of Media list
  163. pAtmArpGlobalInfo->ProtocolHandle,
  164. (NDIS_HANDLE)pAdapter, // our context for the adapter binding
  165. pDeviceName,
  166. 0, // Open options
  167. (PSTRING)NULL // Addressing Info...
  168. );
  169. if (Status != NDIS_STATUS_PENDING)
  170. {
  171. AtmArpOpenAdapterCompleteHandler(
  172. (NDIS_HANDLE)pAdapter,
  173. Status,
  174. OpenStatus
  175. );
  176. }
  177. Status = NDIS_STATUS_PENDING;
  178. break;
  179. }
  180. while (FALSE);
  181. if (Status != NDIS_STATUS_PENDING)
  182. {
  183. //
  184. // We didn't make it upto NdisOpenAdapter. Clean up.
  185. //
  186. AADEBUGP(AAD_WARNING, ("BindAdapter: failed with Status 0x%x\n", Status));
  187. if (pAdapter != NULL_PATMARP_ADAPTER)
  188. {
  189. //
  190. // Free it. We know we haven't linked it to the global
  191. // list of adapters.
  192. //
  193. AA_FREE_MEM(pAdapter);
  194. }
  195. }
  196. #ifdef ATMARP_WIN98
  197. if (UnicodeConfigString.Buffer != NULL)
  198. {
  199. AA_FREE_MEM(UnicodeConfigString.Buffer);
  200. }
  201. #endif // ATMARP_WIN98
  202. *pStatus = Status;
  203. AADEBUGP(AAD_INFO, ("BindAdapterHandler: returning Status 0x%x\n", Status));
  204. return ((INT)TRUE);
  205. }
  206. VOID
  207. AtmArpUnbindAdapterHandler(
  208. OUT PNDIS_STATUS pStatus,
  209. IN NDIS_HANDLE ProtocolBindingContext,
  210. IN NDIS_HANDLE UnbindContext
  211. )
  212. /*++
  213. Routine Description:
  214. This routine is called by NDIS when it wants us to unbind
  215. from an adapter. Or, this may be called from within our Unload
  216. handler. We undo the sequence of operations we performed
  217. in our BindAdapter handler.
  218. Arguments:
  219. pStatus - Place to return status of this operation
  220. ProtocolBindingContext - Our context for this adapter binding, which
  221. is a pointer to an ATMARP Adapter structure.
  222. UnbindContext - This is NULL if this routine is called from
  223. within our Unload handler. Otherwise (i.e.
  224. NDIS called us), we retain this for later use
  225. when calling NdisCompleteUnbindAdapter.
  226. Return Value:
  227. None. We set *pStatus to NDIS_STATUS_PENDING always.
  228. --*/
  229. {
  230. PATMARP_ADAPTER pAdapter;
  231. PATMARP_INTERFACE pInterface;
  232. PATMARP_INTERFACE pNextInterface;
  233. NDIS_STATUS Status;
  234. #if DBG
  235. AA_IRQL EntryIrq, ExitIrq;
  236. #endif
  237. AA_GET_ENTRY_IRQL(EntryIrq);
  238. pAdapter = (PATMARP_ADAPTER)ProtocolBindingContext;
  239. AA_STRUCT_ASSERT(pAdapter, aaa);
  240. AADEBUGP(AAD_INFO, ("UnbindAdapterHandler: pAdapter 0x%x, UnbindContext 0x%x\n",
  241. pAdapter, UnbindContext));
  242. *pStatus = NDIS_STATUS_PENDING;
  243. AA_ACQUIRE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  244. //
  245. // Save the unbind context for a possible later call to
  246. // NdisCompleteUnbindAdapter.
  247. //
  248. pAdapter->UnbindContext = UnbindContext;
  249. pAdapter->Flags |= AA_ADAPTER_FLAGS_UNBINDING;
  250. //
  251. // Wait for any AF register processing to finish.
  252. //
  253. while (pAdapter->Flags & AA_ADAPTER_FLAGS_PROCESSING_AF)
  254. {
  255. AA_RELEASE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  256. AADEBUGP(AAD_FATAL, ("UnbindAdapter: pAdapter %x, Afregister going on!!!\n", pAdapter));
  257. Status = AA_WAIT_ON_BLOCK_STRUCT(&(pAdapter->UnbindBlock));
  258. AA_ACQUIRE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  259. }
  260. AA_RELEASE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  261. //
  262. // If there are no Interfaces on this adapter, we are done.
  263. //
  264. if (pAdapter->pInterfaceList == NULL_PATMARP_INTERFACE)
  265. {
  266. AtmArpCompleteUnbindAdapter(pAdapter);
  267. AA_CHECK_EXIT_IRQL(EntryIrq, ExitIrq);
  268. return;
  269. }
  270. //
  271. // Mark all interfaces on this adapter.
  272. //
  273. for (pInterface = pAdapter->pInterfaceList;
  274. pInterface != NULL_PATMARP_INTERFACE;
  275. pInterface = pNextInterface)
  276. {
  277. pNextInterface = pInterface->pNextInterface;
  278. AA_ACQUIRE_IF_LOCK(pInterface);
  279. pInterface->AdminState = pInterface->State = IF_STATUS_DOWN;
  280. pInterface->LastChangeTime = GetTimeTicks();
  281. AA_RELEASE_IF_LOCK(pInterface);
  282. }
  283. //
  284. // Now, bring down each of these interfaces. For each interface,
  285. // we tear down the ARP table, and shut down the Call Manager
  286. // interface. When this is complete, we will call IP's DelInterface
  287. // entry point.
  288. //
  289. for (pInterface = pAdapter->pInterfaceList;
  290. pInterface != NULL_PATMARP_INTERFACE;
  291. pInterface = pNextInterface)
  292. {
  293. pNextInterface = pInterface->pNextInterface;
  294. AtmArpShutdownInterface(pInterface);
  295. }
  296. AA_CHECK_EXIT_IRQL(EntryIrq, ExitIrq);
  297. return;
  298. }
  299. VOID
  300. AtmArpCompleteUnbindAdapter(
  301. IN PATMARP_ADAPTER pAdapter
  302. )
  303. /*++
  304. Routine Description:
  305. Complete the process of adapter unbinding. All Interfaces on this
  306. adapter are assumed to have been removed.
  307. If we are unbinding from the adapter as a result of NDIS' call to
  308. our UnbindAdapter handler, we complete that here.
  309. Arguments:
  310. pAdapter - Pointer to the adapter being unbound.
  311. Return Value:
  312. None
  313. --*/
  314. {
  315. NDIS_HANDLE UnbindContext;
  316. PATMARP_ADAPTER * ppAdapter;
  317. NDIS_STATUS Status;
  318. UnbindContext = pAdapter->UnbindContext;
  319. AADEBUGP(AAD_INFO, ("CompleteUnbindAdapter: pAdapter 0x%x, UnbindContext 0x%x\n",
  320. pAdapter, UnbindContext));
  321. AA_ACQUIRE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  322. if (pAdapter->Flags & AA_ADAPTER_FLAGS_CLOSING)
  323. {
  324. AA_RELEASE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  325. return;
  326. }
  327. pAdapter->Flags |= AA_ADAPTER_FLAGS_CLOSING;
  328. AA_RELEASE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  329. #if ATMOFFLOAD
  330. //
  331. // Disable offload if enabled...
  332. //
  333. AtmArpDisableOffload(pAdapter);
  334. #endif // ATMOFFLOAD
  335. NdisCloseAdapter(
  336. &Status,
  337. pAdapter->NdisAdapterHandle
  338. );
  339. if (Status != NDIS_STATUS_PENDING)
  340. {
  341. AtmArpCloseAdapterCompleteHandler(
  342. (NDIS_HANDLE) pAdapter,
  343. Status
  344. );
  345. }
  346. }
  347. VOID
  348. AtmArpOpenAdapterCompleteHandler(
  349. IN NDIS_HANDLE ProtocolBindingContext,
  350. IN NDIS_STATUS Status,
  351. IN NDIS_STATUS OpenErrorStatus
  352. )
  353. /*++
  354. Routine Description:
  355. This is called by NDIS when a previous call to NdisOpenAdapter
  356. that had pended has completed. We now complete the BindAdapter
  357. that lead to this.
  358. Arguments:
  359. ProtocolBindingContext - Our context for this adapter binding, which
  360. is a pointer to an ATMARP Adapter structure.
  361. Status - Status of OpenAdapter
  362. OpenErrorStatus - Error code in case of failure.
  363. Return Value:
  364. None
  365. --*/
  366. {
  367. PATMARP_ADAPTER pAdapter;
  368. PATMARP_ADAPTER * ppAdapter;
  369. NDIS_HANDLE BindAdapterContext;
  370. pAdapter = (PATMARP_ADAPTER)ProtocolBindingContext;
  371. AA_STRUCT_ASSERT(pAdapter, aaa);
  372. BindAdapterContext = pAdapter->BindContext;
  373. if (Status != NDIS_STATUS_SUCCESS)
  374. {
  375. //
  376. // Remove the adapter from the global list.
  377. //
  378. AA_ACQUIRE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  379. ppAdapter = &(pAtmArpGlobalInfo->pAdapterList);
  380. while (*ppAdapter != pAdapter)
  381. {
  382. ppAdapter = &((*ppAdapter)->pNextAdapter);
  383. }
  384. *ppAdapter = pAdapter->pNextAdapter;
  385. pAtmArpGlobalInfo->AdapterCount--;
  386. AA_RELEASE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  387. AA_FREE_MEM(pAdapter);
  388. }
  389. #if ATMOFFLOAD
  390. else
  391. {
  392. //
  393. // Query and enable offloading
  394. //
  395. Status = AtmArpQueryAndEnableOffload(pAdapter);
  396. if (Status != NDIS_STATUS_SUCCESS)
  397. {
  398. //
  399. // AtmArpQueryAndEnableOffload is not supposed to return unless
  400. // there's a fatal error -- we don't expect this.
  401. //
  402. AA_ASSERT(FALSE);
  403. }
  404. }
  405. #endif //ATMOFFLOAD
  406. AADEBUGP(AAD_INFO, ("OpenAdapterComplete: pAdapter 0x%x, Status 0x%x\n",
  407. pAdapter, Status));
  408. (*(pAtmArpGlobalInfo->pIPBindCompleteRtn))(
  409. Status,
  410. BindAdapterContext
  411. );
  412. return;
  413. }
  414. VOID
  415. AtmArpCloseAdapterCompleteHandler(
  416. IN NDIS_HANDLE ProtocolBindingContext,
  417. IN NDIS_STATUS Status
  418. )
  419. /*++
  420. Routine Description:
  421. This is called by NDIS when a previous call to NdisCloseAdapter
  422. that had pended has completed. The thread that called NdisCloseAdapter
  423. would have blocked itself, so we simply wake it up now.
  424. Arguments:
  425. ProtocolBindingContext - Our context for this adapter binding, which
  426. is a pointer to an ATMARP Adapter structure.
  427. Status - Status of CloseAdapter
  428. Return Value:
  429. None
  430. --*/
  431. {
  432. PATMARP_ADAPTER pAdapter;
  433. NDIS_HANDLE UnbindContext;
  434. PATMARP_ADAPTER * ppAdapter;
  435. pAdapter = (PATMARP_ADAPTER)ProtocolBindingContext;
  436. AA_STRUCT_ASSERT(pAdapter, aaa);
  437. UnbindContext = pAdapter->UnbindContext;
  438. AADEBUGP(AAD_INFO, ("CloseAdapterCompleteHandler: pAdapter 0x%x, UnbindContext 0x%x\n",
  439. pAdapter, UnbindContext));
  440. pAdapter->NdisAdapterHandle = NULL;
  441. //
  442. // Remove the adapter from the global list.
  443. //
  444. AA_ACQUIRE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  445. ppAdapter = &(pAtmArpGlobalInfo->pAdapterList);
  446. while (*ppAdapter != pAdapter)
  447. {
  448. ppAdapter = &((*ppAdapter)->pNextAdapter);
  449. }
  450. *ppAdapter = pAdapter->pNextAdapter;
  451. pAtmArpGlobalInfo->AdapterCount--;
  452. AA_RELEASE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  453. //
  454. // Free any structures attached to the adapter structure.
  455. //
  456. if (pAdapter->pDescrString != (PUCHAR)NULL)
  457. {
  458. AA_FREE_MEM(pAdapter->pDescrString);
  459. }
  460. if (pAdapter->IPConfigString.Buffer != NULL)
  461. {
  462. AA_FREE_MEM(pAdapter->IPConfigString.Buffer);
  463. }
  464. //
  465. // Release the adapter structure.
  466. //
  467. AA_FREE_MEM(pAdapter);
  468. //
  469. // If NDIS had requested us to Unbind, complete the
  470. // request now.
  471. //
  472. if (UnbindContext != (NDIS_HANDLE)NULL)
  473. {
  474. NdisCompleteUnbindAdapter(
  475. UnbindContext,
  476. NDIS_STATUS_SUCCESS
  477. );
  478. }
  479. else
  480. {
  481. //
  482. // We initiated the unbind from our Unload handler,
  483. // which would have been waiting for us to complete.
  484. // Wake up that thread now.
  485. //
  486. AA_SIGNAL_BLOCK_STRUCT(&(pAtmArpGlobalInfo->Block), NDIS_STATUS_SUCCESS);
  487. }
  488. }
  489. VOID
  490. AtmArpSendCompleteHandler(
  491. IN NDIS_HANDLE ProtocolBindingContext,
  492. IN PNDIS_PACKET pNdisPacket,
  493. IN NDIS_STATUS Status
  494. )
  495. /*++
  496. Routine Description:
  497. This is the Connection-less Send Complete handler, which signals
  498. completion of such a Send. Since we don't ever use this feature,
  499. we don't expect this routine to be called.
  500. Arguments:
  501. <Ignored>
  502. Return Value:
  503. None
  504. --*/
  505. {
  506. AADEBUGP(AAD_ERROR, ("SendCompleteHandler unexpected\n"));
  507. AA_ASSERT(FALSE);
  508. }
  509. VOID
  510. AtmArpTransferDataCompleteHandler(
  511. IN NDIS_HANDLE ProtocolBindingContext,
  512. IN PNDIS_PACKET pNdisPacket,
  513. IN NDIS_STATUS Status,
  514. IN UINT BytesTransferred
  515. )
  516. /*++
  517. Routine Description:
  518. This is the Connection-less Transfer Data Complete handler, which
  519. signals completion of a call to NdisTransferData. Since we never
  520. call NdisTransferData, this routine should never get called.
  521. Arguments:
  522. <Ignored>
  523. Return Value:
  524. None
  525. --*/
  526. {
  527. AADEBUGP(AAD_ERROR, ("TransferDataComplete Handler unexpected!\n"));
  528. AA_ASSERT(FALSE);
  529. }
  530. VOID
  531. AtmArpResetCompleteHandler(
  532. IN NDIS_HANDLE ProtocolBindingContext,
  533. IN NDIS_STATUS Status
  534. )
  535. /*++
  536. Routine Description:
  537. This routine is called when the miniport indicates that a Reset
  538. operation has just completed. We ignore this event.
  539. Arguments:
  540. ProtocolBindingContext - Our context for this adapter binding, which
  541. is a pointer to an ATMARP Adapter structure.
  542. Status - Status of the reset operation.
  543. Return Value:
  544. None
  545. --*/
  546. {
  547. PATMARP_ADAPTER pAdapter;
  548. pAdapter = (PATMARP_ADAPTER)ProtocolBindingContext;
  549. AA_STRUCT_ASSERT(pAdapter, aaa);
  550. AADEBUGP(AAD_INFO, ("Reset Complete on Adapter 0x%x\n", pAdapter));
  551. }
  552. VOID
  553. AtmArpRequestCompleteHandler(
  554. IN NDIS_HANDLE ProtocolBindingContext,
  555. IN PNDIS_REQUEST pNdisRequest,
  556. IN NDIS_STATUS Status
  557. )
  558. /*++
  559. Routine Description:
  560. This is called by NDIS when a previous call we made to NdisRequest() has
  561. completed. We would be blocked on our adapter structure, waiting for this
  562. to happen -- wake up the blocked thread.
  563. Arguments:
  564. ProtocolBindingContext - Pointer to our Adapter structure
  565. pNdisRequest - The request that completed
  566. Status - Status of the request.
  567. Return Value:
  568. None
  569. --*/
  570. {
  571. PATMARP_ADAPTER pAdapter;
  572. pAdapter = (PATMARP_ADAPTER)ProtocolBindingContext;
  573. AA_STRUCT_ASSERT(pAdapter, aaa);
  574. AA_SIGNAL_BLOCK_STRUCT(&(pAdapter->Block), Status);
  575. return;
  576. }
  577. NDIS_STATUS
  578. AtmArpReceiveHandler(
  579. IN NDIS_HANDLE ProtocolBindingContext,
  580. IN NDIS_HANDLE MacReceiveContext,
  581. IN PVOID pHeaderBuffer,
  582. IN UINT HeaderBufferSize,
  583. IN PVOID pLookAheadBuffer,
  584. IN UINT LookaheadBufferSize,
  585. IN UINT PacketSize
  586. )
  587. /*++
  588. Routine Description:
  589. This is our Connection-less receive handler. Since we only use
  590. Connection oriented services, this routine should never get called.
  591. Arguments:
  592. <Ignored>
  593. Return Value:
  594. None
  595. --*/
  596. {
  597. AADEBUGP(AAD_ERROR, ("Connectionless ReceiveHandler unexpected\n"));
  598. AA_ASSERT(FALSE);
  599. return(NDIS_STATUS_NOT_RECOGNIZED);
  600. }
  601. VOID
  602. AtmArpReceiveCompleteHandler(
  603. IN NDIS_HANDLE ProtocolBindingContext
  604. )
  605. /*++
  606. Routine Description:
  607. This is called by NDIS when the miniport is done with receiving
  608. a bunch of packets, meaning that it is now time to start processing
  609. them. We simply pass this on to IP (on all IF's configured on this
  610. adapter).
  611. Arguments:
  612. ProtocolBindingContext - Our context for this adapter binding, which
  613. is a pointer to an ATMARP Adapter structure.
  614. Return Value:
  615. None
  616. --*/
  617. {
  618. PATMARP_ADAPTER pAdapter;
  619. PATMARP_INTERFACE pInterface;
  620. pAdapter = (PATMARP_ADAPTER)ProtocolBindingContext;
  621. AA_STRUCT_ASSERT(pAdapter, aaa);
  622. for (pInterface = pAdapter->pInterfaceList;
  623. pInterface != NULL_PATMARP_INTERFACE;
  624. pInterface = pInterface->pNextInterface)
  625. {
  626. (*(pInterface->IPRcvCmpltHandler))();
  627. }
  628. }
  629. INT
  630. AtmArpReceivePacketHandler(
  631. IN NDIS_HANDLE ProtocolBindingContext,
  632. IN PNDIS_PACKET pNdisPacket
  633. )
  634. /*++
  635. Routine Description:
  636. This is the Connectionless receive handler, which should never be
  637. called, since we only use Connection Oriented miniport services.
  638. Arguments:
  639. <Ignored>
  640. Return Value:
  641. Reference count on the received packet. We always return 0.
  642. --*/
  643. {
  644. AADEBUGP(AAD_ERROR, ("ReceivePacket Handler unexpected!\n"));
  645. AA_ASSERT(FALSE);
  646. return(0);
  647. }
  648. VOID
  649. AtmArpStatusHandler(
  650. IN NDIS_HANDLE ProtocolBindingContext,
  651. IN NDIS_STATUS GeneralStatus,
  652. IN PVOID pStatusBuffer,
  653. IN UINT StatusBufferSize
  654. )
  655. /*++
  656. Routine Description:
  657. This routine is called when the miniport indicates an adapter-wide
  658. status change. We ignore this.
  659. Arguments:
  660. <Ignored>
  661. Return Value:
  662. None
  663. --*/
  664. {
  665. AADEBUGP(AAD_INFO, ("Status Handler: Bind Ctx 0x%x, Status 0x%x\n",
  666. ProtocolBindingContext,
  667. GeneralStatus));
  668. }
  669. VOID
  670. AtmArpStatusCompleteHandler(
  671. IN NDIS_HANDLE ProtocolBindingContext
  672. )
  673. /*++
  674. Routine Description:
  675. This routine is called when the miniport wants to tell us about
  676. completion of a status change (?). Ignore this.
  677. Arguments:
  678. <Ignored>
  679. Return Value:
  680. None
  681. --*/
  682. {
  683. AADEBUGP(AAD_INFO, ("Status Complete Handler: Bind Ctx 0x%x\n",
  684. ProtocolBindingContext));
  685. }
  686. VOID
  687. AtmArpCoSendCompleteHandler(
  688. IN NDIS_STATUS Status,
  689. IN NDIS_HANDLE ProtocolVcContext,
  690. IN PNDIS_PACKET pNdisPacket
  691. )
  692. /*++
  693. Routine Description:
  694. This routine is called by NDIS when the ATM miniport is finished
  695. with a packet we had previously sent via NdisCoSendPackets. We first
  696. check if this packet was generated by us (e.g. ATMARP protocol packet):
  697. if so, we free this here. Otherwise (packet sent by the IP layer), we
  698. first remove any header buffer that we had attached to the packet and
  699. free it, before calling IP's entry point for Transmit Complete.
  700. Arguments:
  701. Status - Status of the NdisCoSendPackets.
  702. ProtocolVcContext - Our context for the VC on which the packet was sent
  703. (i.e. pointer to ATMARP VC).
  704. pNdisPacket - The packet whose "send" is being completed.
  705. Return Value:
  706. None
  707. --*/
  708. {
  709. PATMARP_VC pVc;
  710. PATMARP_INTERFACE pInterface;
  711. PacketContext *PC; // IP/ARP Info about this packet
  712. PNDIS_BUFFER pNdisBuffer; // First Buffer in this packet
  713. UINT TotalLength;
  714. AA_HEADER_TYPE HdrType;
  715. ATMARP_VC_ENCAPSULATION_TYPE Encapsulation;
  716. ULONG rc;
  717. pVc = (PATMARP_VC)ProtocolVcContext;
  718. AA_STRUCT_ASSERT(pVc, avc);
  719. #ifdef VC_REFS_ON_SENDS
  720. AA_ACQUIRE_VC_LOCK(pVc);
  721. pInterface = pVc->pInterface;
  722. Encapsulation = pVc->FlowSpec.Encapsulation;
  723. rc = AtmArpDereferenceVc(pVc); // SendComplete
  724. if (rc != 0)
  725. {
  726. pVc->OutstandingSends--;
  727. if (AA_IS_FLAG_SET(
  728. pVc->Flags,
  729. AA_VC_CLOSE_STATE_MASK,
  730. AA_VC_CLOSE_STATE_CLOSING) &&
  731. (pVc->OutstandingSends == 0))
  732. {
  733. AtmArpCloseCall(pVc);
  734. //
  735. // VC lock is released above.
  736. //
  737. }
  738. else
  739. {
  740. AA_RELEASE_VC_LOCK(pVc);
  741. }
  742. }
  743. #else
  744. pInterface = pVc->pInterface;
  745. Encapsulation = pVc->FlowSpec.Encapsulation;
  746. #endif // VC_REFS_ON_SENDS
  747. AA_ASSERT(pNdisPacket->Private.Head != NULL);
  748. #if DBG
  749. #if DBG_CO_SEND
  750. {
  751. PULONG pContext;
  752. extern ULONG OutstandingSends;
  753. pContext = (PULONG)&(pNdisPacket->WrapperReserved[0]);;
  754. // Check for duplicate completion:
  755. AA_ASSERT(*pContext != 'BbBb');
  756. *pContext = 'BbBb';
  757. NdisInterlockedDecrement(&OutstandingSends);
  758. }
  759. #endif // DBG_CO_SEND
  760. #endif // DBG
  761. NdisQueryPacket(
  762. pNdisPacket,
  763. NULL, // we don't need PhysicalBufferCount
  764. NULL, // we don't need BufferCount
  765. NULL, // we don't need FirstBuffer (yet)
  766. &TotalLength
  767. );
  768. if (Status == NDIS_STATUS_SUCCESS)
  769. {
  770. AA_IF_STAT_ADD(pInterface, OutOctets, TotalLength);
  771. }
  772. else if (Status == NDIS_STATUS_RESOURCES)
  773. {
  774. AA_IF_STAT_INCR(pInterface, OutDiscards);
  775. }
  776. else if (Status != NDIS_STATUS_SUCCESS)
  777. {
  778. AA_IF_STAT_INCR(pInterface, OutErrors);
  779. }
  780. PC = (PacketContext *)pNdisPacket->ProtocolReserved;
  781. AADEBUGP(AAD_EXTRA_LOUD,
  782. ("CoSend complete[%s]: VC 0x%x, Pkt 0x%x, Status 0x%x:\n",
  783. ((PC->pc_common.pc_owner != PACKET_OWNER_LINK)? "IP": "ARP"),
  784. pVc, pNdisPacket, Status));
  785. //
  786. // Check who generated this packet.
  787. //
  788. if (PC->pc_common.pc_owner != PACKET_OWNER_LINK)
  789. {
  790. //
  791. // Belongs to IP. Check if we had prepended an LLC/SNAP header.
  792. //
  793. if (Encapsulation == ENCAPSULATION_TYPE_LLCSNAP)
  794. {
  795. PUCHAR pPacket;
  796. UINT Length;
  797. #ifdef BACK_FILL
  798. NdisQueryPacket(pNdisPacket, NULL, NULL, &pNdisBuffer, NULL);
  799. AA_ASSERT(pNdisBuffer != NULL);
  800. NdisQueryBuffer(pNdisBuffer, &pPacket, &Length);
  801. //
  802. // Commmon part first: find the header type, and update
  803. // statistics.
  804. //
  805. if (pPacket[5] == LLC_SNAP_OUI2)
  806. {
  807. HdrType = AA_HEADER_TYPE_UNICAST;
  808. if (Status == NDIS_STATUS_SUCCESS)
  809. {
  810. AA_IF_STAT_INCR(pInterface, OutUnicastPkts);
  811. }
  812. }
  813. else
  814. {
  815. HdrType = AA_HEADER_TYPE_NUNICAST;
  816. if (Status == NDIS_STATUS_SUCCESS)
  817. {
  818. AA_IF_STAT_INCR(pInterface, OutNonUnicastPkts);
  819. INCR_STAT(MCastSendOk);
  820. }
  821. else
  822. {
  823. INCR_STAT(MCastSendFail);
  824. }
  825. }
  826. //
  827. // Now check if we had attached a header buffer or not.
  828. //
  829. if (AtmArpDoBackFill && AA_BACK_FILL_POSSIBLE(pNdisBuffer))
  830. {
  831. ULONG HeaderLength;
  832. //
  833. // We would have back-filled IP's buffer with the LLC/SNAP
  834. // header. Remove the back-fill.
  835. //
  836. HeaderLength = ((HdrType == AA_HEADER_TYPE_UNICAST)?
  837. sizeof(AtmArpLlcSnapHeader) :
  838. #ifdef IPMCAST
  839. sizeof(AtmArpMcType1ShortHeader));
  840. #else
  841. 0);
  842. #endif // IPMCAST
  843. (PUCHAR)pNdisBuffer->MappedSystemVa += HeaderLength;
  844. pNdisBuffer->ByteOffset += HeaderLength;
  845. pNdisBuffer->ByteCount -= HeaderLength;
  846. }
  847. else
  848. {
  849. //
  850. // The first buffer would be our header buffer. Remove
  851. // it from the packet and return to our pool.
  852. //
  853. NdisUnchainBufferAtFront(pNdisPacket, &pNdisBuffer);
  854. AtmArpFreeHeader(pInterface, pNdisBuffer, HdrType);
  855. }
  856. #else
  857. //
  858. // Free the LLC/SNAP header buffer.
  859. //
  860. NdisUnchainBufferAtFront(pNdisPacket, &pNdisBuffer);
  861. AA_ASSERT(pNdisBuffer != NULL);
  862. NdisQueryBuffer(pNdisBuffer, &pPacket, &Length);
  863. if (pPacket[5] == LLC_SNAP_OUI2)
  864. {
  865. HdrType = AA_HEADER_TYPE_UNICAST;
  866. if (Status == NDIS_STATUS_SUCCESS)
  867. {
  868. AA_IF_STAT_INCR(pInterface, OutUnicastPkts);
  869. }
  870. }
  871. else
  872. {
  873. HdrType = AA_HEADER_TYPE_NUNICAST;
  874. if (Status == NDIS_STATUS_SUCCESS)
  875. {
  876. AA_IF_STAT_INCR(pInterface, OutNonUnicastPkts);
  877. INCR_STAT(MCastSendOk);
  878. }
  879. else
  880. {
  881. INCR_STAT(MCastSendFail);
  882. }
  883. }
  884. AtmArpFreeHeader(pInterface, pNdisBuffer, HdrType);
  885. #endif // BACK_FILL
  886. }
  887. #ifdef PERF
  888. AadLogSendComplete(pNdisPacket);
  889. #endif // PERF
  890. //
  891. // Inform IP of send completion.
  892. //
  893. (*(pInterface->IPTxCmpltHandler))(
  894. pInterface->IPContext,
  895. pNdisPacket,
  896. Status
  897. );
  898. }
  899. else
  900. {
  901. //
  902. // Packet generated by the ATMARP module. This would be an
  903. // ATMARP protocol packet, so free the NDIS buffer now.
  904. //
  905. NdisUnchainBufferAtFront(pNdisPacket, &pNdisBuffer);
  906. AA_ASSERT(pNdisBuffer != NULL);
  907. #if DBG
  908. {
  909. ULONG ArpPktLength;
  910. PUCHAR ArpPktStart;
  911. NdisQueryBuffer(pNdisBuffer, (PVOID)&ArpPktStart, &ArpPktLength);
  912. AADEBUGPDUMP(AAD_EXTRA_LOUD+100, ArpPktStart, ArpPktLength);
  913. }
  914. #endif // DBG
  915. AtmArpFreeProtoBuffer(pInterface, pNdisBuffer);
  916. AtmArpFreePacket(pInterface, pNdisPacket);
  917. }
  918. return;
  919. }
  920. VOID
  921. AtmArpCoStatusHandler(
  922. IN NDIS_HANDLE ProtocolBindingContext,
  923. IN NDIS_HANDLE ProtocolVcContext OPTIONAL,
  924. IN NDIS_STATUS GeneralStatus,
  925. IN PVOID pStatusBuffer,
  926. IN UINT StatusBufferSize
  927. )
  928. /*++
  929. Routine Description:
  930. This routine is called when the miniport indicates a status
  931. change, possibly on a VC. Ignore this.
  932. Arguments:
  933. <Ignored>
  934. Return Value:
  935. None
  936. --*/
  937. {
  938. AADEBUGP(AAD_INFO, ("CoStatus Handler: Bind Ctx 0x%x, VC Ctx 0x%x, Status 0x%x\n",
  939. ProtocolBindingContext,
  940. ProtocolVcContext,
  941. GeneralStatus));
  942. }
  943. /*++
  944. AtmArpCoReceivePacketHandler -- is in arppkt.c
  945. --*/
  946. #ifdef _PNP_POWER_
  947. NDIS_STATUS
  948. AtmArpPnPReconfigHandler(
  949. IN PATMARP_ADAPTER pAdapter OPTIONAL,
  950. IN PNET_PNP_EVENT pNetPnPEvent
  951. )
  952. /*++
  953. Routine Description:
  954. Handle a reconfig message on the specified adapter. If no adapter
  955. is specified, it is a global parameter that has changed.
  956. Arguments:
  957. pAdapter - Pointer to our adapter structure
  958. pNetPnPEvent - Pointer to reconfig event
  959. Return Value:
  960. NDIS_STATUS_SUCCESS always, for now.
  961. --*/
  962. {
  963. ATMARPC_PNP_RECONFIG_REQUEST UNALIGNED * pArpReconfigReq;
  964. PIP_PNP_RECONFIG_REQUEST pIpReconfigReq;
  965. NDIS_STATUS Status;
  966. pIpReconfigReq = (PIP_PNP_RECONFIG_REQUEST)pNetPnPEvent->Buffer;
  967. AA_ASSERT(pIpReconfigReq->arpConfigOffset != 0);
  968. pArpReconfigReq = (ATMARPC_PNP_RECONFIG_REQUEST UNALIGNED *)
  969. ((PUCHAR)pIpReconfigReq + pIpReconfigReq->arpConfigOffset);
  970. AADEBUGP(AAD_WARNING, ("AtmArpPnPReconfig: pIpReconfig 0x%x, arpConfigOffset 0x%x\n",
  971. pIpReconfigReq, pIpReconfigReq->arpConfigOffset));
  972. do
  973. {
  974. PATMARP_INTERFACE pInterface;
  975. PATMARP_INTERFACE pNextInterface;
  976. NDIS_STRING IPReconfigString;
  977. //
  978. // Locate the IP interface string passed in...
  979. //
  980. ULONG uOffset = pArpReconfigReq->IfKeyOffset;
  981. if (uOffset == 0)
  982. {
  983. Status = NDIS_STATUS_FAILURE;
  984. break;
  985. }
  986. else
  987. {
  988. //
  989. // ((PUCHAR)pArpReconfigReq + uOffset) points to a
  990. // "counted unicode string", which means that it's an array
  991. // of words, with the 1st word being the length in characters of
  992. // the string (there is no terminating null) and the following
  993. // <length> words being the string itself.
  994. // We need to create an NDIS_STRING based on this buffer in order
  995. // to compare it with each interface's config string.
  996. //
  997. PWCH pwc = (PWCH) ((PUCHAR)pArpReconfigReq + uOffset);
  998. IPReconfigString.Length = sizeof(WCHAR)*pwc[0];
  999. IPReconfigString.MaximumLength = IPReconfigString.Length;
  1000. IPReconfigString.Buffer = pwc+1;
  1001. }
  1002. //
  1003. // Do we have a binding context?
  1004. //
  1005. if (pAdapter == NULL_PATMARP_ADAPTER)
  1006. {
  1007. Status = NDIS_STATUS_FAILURE;
  1008. break;
  1009. }
  1010. //
  1011. // We wrap the search in a try-except clause because the passed-in
  1012. // structure could be bogus. Note that we will only test at most
  1013. // as many characters of the passed-in string as the lengths of
  1014. // our internal set of interface config strings.
  1015. //
  1016. try
  1017. {
  1018. //
  1019. // Find the interface associated with this request.
  1020. //
  1021. AA_ACQUIRE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  1022. for (pInterface = pAdapter->pInterfaceList;
  1023. pInterface != NULL_PATMARP_INTERFACE;
  1024. pInterface = pNextInterface)
  1025. {
  1026. BOOLEAN IsEqual = FALSE;
  1027. pNextInterface = pInterface->pNextInterface;
  1028. AA_RELEASE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  1029. //
  1030. // Compare the IPReconfigString
  1031. // JJ TODO: NdisEqualUnicodeString must be called in PASSIVE level
  1032. // we know that the reconfig call is done at passive level,
  1033. // but how to assert that fact here?
  1034. // AA_ASSERT(EntryIrq == PASSIVE_LEVEL);
  1035. //
  1036. IsEqual = NdisEqualUnicodeString(
  1037. &IPReconfigString,
  1038. &(pInterface->IPConfigString),
  1039. TRUE // case insensitive
  1040. );
  1041. AA_ACQUIRE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  1042. if (IsEqual)
  1043. {
  1044. break; // found it!
  1045. }
  1046. }
  1047. AA_RELEASE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  1048. }
  1049. except (EXCEPTION_EXECUTE_HANDLER)
  1050. {
  1051. Status = NDIS_STATUS_FAILURE;
  1052. break;
  1053. }
  1054. //
  1055. // JJ We should find the interface if this adapter has any interfaces
  1056. // at all -- else it means that we're being sent bogus reconfig
  1057. // information.
  1058. //
  1059. AA_ASSERT(pInterface!= NULL || pAdapter->pInterfaceList==NULL);
  1060. if (pInterface != NULL_PATMARP_INTERFACE)
  1061. {
  1062. AA_ACQUIRE_IF_LOCK(pInterface);
  1063. //
  1064. // Set it's state to indicate that a reconfig is pending.
  1065. // and save away pNetPnPEvent for completion later.
  1066. //
  1067. if ( pInterface->ReconfigState != RECONFIG_NOT_IN_PROGRESS
  1068. || pInterface->pReconfigEvent != NULL)
  1069. {
  1070. AA_RELEASE_IF_LOCK(pInterface);
  1071. //
  1072. // We should not get here because this means that
  1073. // we were asked to reconfigure when there was a
  1074. // pending reconfiguration, which is not supposed to happen.
  1075. //
  1076. Status = NDIS_STATUS_FAILURE;
  1077. AA_ASSERT(FALSE);
  1078. }
  1079. else
  1080. {
  1081. pInterface->ReconfigState = RECONFIG_SHUTDOWN_PENDING;
  1082. pInterface->pReconfigEvent = pNetPnPEvent;
  1083. pInterface->AdminState = IF_STATUS_DOWN;
  1084. AtmArpReferenceInterface(pInterface); // Reconfig
  1085. AA_RELEASE_IF_LOCK(pInterface);
  1086. //
  1087. // Initiate shutdown in preparation of a restart.
  1088. // AtmArpShutdown is responsible for
  1089. // completing the ndis reconfig request asynchronously.
  1090. //
  1091. AtmArpShutdownInterface(pInterface);
  1092. Status = NDIS_STATUS_PENDING;
  1093. }
  1094. }
  1095. else
  1096. {
  1097. //
  1098. // We didn't find the interface, fail the request...
  1099. //
  1100. Status = NDIS_STATUS_FAILURE;
  1101. }
  1102. } while (FALSE);
  1103. return (Status);
  1104. }
  1105. NDIS_STATUS
  1106. AtmArpPnPEventHandler(
  1107. IN NDIS_HANDLE ProtocolBindingContext,
  1108. IN PNET_PNP_EVENT pNetPnPEvent
  1109. )
  1110. /*++
  1111. Routine Description:
  1112. This is the NDIS entry point called when NDIS wants to inform
  1113. us about a PNP/PM event happening on an adapter. If the event
  1114. is for us, we consume it. Otherwise, we pass this event along
  1115. to IP along the first Interface on this adapter.
  1116. When IP is done with it, it will call our IfPnPEventComplete
  1117. routine.
  1118. Arguments:
  1119. ProtocolBindingContext - Our context for this adapter binding, which
  1120. is a pointer to an ATMARP Adapter structure.
  1121. pNetPnPEvent - Pointer to the event.
  1122. Return Value:
  1123. None
  1124. --*/
  1125. {
  1126. PATMARP_ADAPTER pAdapter;
  1127. PATMARP_INTERFACE pInterface;
  1128. NDIS_STATUS Status;
  1129. PIP_PNP_RECONFIG_REQUEST pIpReconfigReq;
  1130. ULONG Length;
  1131. pAdapter = (PATMARP_ADAPTER)ProtocolBindingContext;
  1132. #ifdef NT
  1133. do
  1134. {
  1135. pIpReconfigReq = (PIP_PNP_RECONFIG_REQUEST)pNetPnPEvent->Buffer;
  1136. Length = pNetPnPEvent->BufferLength;
  1137. //
  1138. // Is this directed to us?
  1139. //
  1140. if (pNetPnPEvent->NetEvent == NetEventReconfigure)
  1141. {
  1142. if (Length < sizeof(IP_PNP_RECONFIG_REQUEST))
  1143. {
  1144. Status = NDIS_STATUS_RESOURCES;
  1145. break;
  1146. }
  1147. if (pIpReconfigReq->arpConfigOffset != 0)
  1148. {
  1149. Status = AtmArpPnPReconfigHandler(pAdapter, pNetPnPEvent);
  1150. break;
  1151. }
  1152. }
  1153. //
  1154. // This belongs to IP. Do we have a binding context?
  1155. //
  1156. if (pAdapter == NULL_PATMARP_ADAPTER)
  1157. {
  1158. Status = NDIS_STATUS_FAILURE;
  1159. break;
  1160. }
  1161. AA_STRUCT_ASSERT(pAdapter, aaa);
  1162. pInterface = pAdapter->pInterfaceList;
  1163. if ((pInterface != NULL_PATMARP_INTERFACE) &&
  1164. (pInterface->IPContext != NULL))
  1165. {
  1166. AA_ASSERT(pInterface->IPPnPEventHandler != NULL);
  1167. Status = (*pInterface->IPPnPEventHandler)(
  1168. pInterface->IPContext,
  1169. pNetPnPEvent
  1170. );
  1171. }
  1172. else
  1173. {
  1174. Status = NDIS_STATUS_SUCCESS;
  1175. }
  1176. break;
  1177. }
  1178. while (FALSE);
  1179. #else
  1180. Status = NDIS_STATUS_SUCCESS;
  1181. #endif // NT
  1182. AADEBUGP(AAD_INFO,
  1183. ("PnPEventHandler: pIF 0x%x, pEvent 0x%x, Evt 0x%x, Status 0x%x\n",
  1184. pInterface, pNetPnPEvent, pNetPnPEvent->NetEvent, Status));
  1185. return (Status);
  1186. }
  1187. #endif // _PNP_POWER_
  1188. NDIS_STATUS
  1189. AtmArpSendAdapterNdisRequest(
  1190. IN PATMARP_ADAPTER pAdapter,
  1191. IN PNDIS_REQUEST pNdisRequest,
  1192. IN NDIS_REQUEST_TYPE RequestType,
  1193. IN NDIS_OID Oid,
  1194. IN PVOID pBuffer,
  1195. IN ULONG BufferLength
  1196. )
  1197. /*++
  1198. Routine Description:
  1199. Send an NDIS Request to query an adapter for information.
  1200. If the request pends, block on the ATMARP Adapter structure
  1201. till it completes.
  1202. Arguments:
  1203. pAdapter - Points to ATMARP Adapter structure
  1204. pNdisRequest - Pointer to NDIS request structure
  1205. RequestType - Set/Query information
  1206. Oid - OID to be passed in the request
  1207. pBuffer - place for value(s)
  1208. BufferLength - length of above
  1209. Return Value:
  1210. The NDIS status of the request.
  1211. --*/
  1212. {
  1213. NDIS_STATUS Status;
  1214. //
  1215. // Fill in the NDIS Request structure
  1216. //
  1217. pNdisRequest->RequestType = RequestType;
  1218. if (RequestType == NdisRequestQueryInformation)
  1219. {
  1220. pNdisRequest->DATA.QUERY_INFORMATION.Oid = Oid;
  1221. pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer = pBuffer;
  1222. pNdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength = BufferLength;
  1223. pNdisRequest->DATA.QUERY_INFORMATION.BytesWritten = 0;
  1224. pNdisRequest->DATA.QUERY_INFORMATION.BytesNeeded = BufferLength;
  1225. }
  1226. else
  1227. {
  1228. pNdisRequest->DATA.SET_INFORMATION.Oid = Oid;
  1229. pNdisRequest->DATA.SET_INFORMATION.InformationBuffer = pBuffer;
  1230. pNdisRequest->DATA.SET_INFORMATION.InformationBufferLength = BufferLength;
  1231. pNdisRequest->DATA.SET_INFORMATION.BytesRead = 0;
  1232. pNdisRequest->DATA.SET_INFORMATION.BytesNeeded = 0;
  1233. }
  1234. AA_INIT_BLOCK_STRUCT(&(pAdapter->Block));
  1235. NdisRequest(
  1236. &Status,
  1237. pAdapter->NdisAdapterHandle,
  1238. pNdisRequest
  1239. );
  1240. if (Status == NDIS_STATUS_PENDING)
  1241. {
  1242. Status = AA_WAIT_ON_BLOCK_STRUCT(&(pAdapter->Block));
  1243. }
  1244. return (Status);
  1245. }
  1246. NDIS_STATUS
  1247. AtmArpGetAdapterInfo(
  1248. IN PATMARP_ADAPTER pAdapter
  1249. )
  1250. /*++
  1251. Routine Description:
  1252. Query an adapter for hardware-specific information that we need:
  1253. - burnt in hardware address (ESI part)
  1254. - Max packet size
  1255. - line rate
  1256. Arguments:
  1257. pAdapter - Pointer to ATMARP adapter structure
  1258. Return Value:
  1259. NDIS_STATUS_SUCCESS on success.
  1260. Failure code on some non-ignorable failure (such as
  1261. device doesn't support MTU >= 8196).
  1262. --*/
  1263. {
  1264. NDIS_STATUS Status;
  1265. NDIS_REQUEST NdisRequest;
  1266. ULONG Value;
  1267. //
  1268. // Initialize.
  1269. //
  1270. AA_SET_MEM(pAdapter->MacAddress, 0, AA_ATM_ESI_LEN);
  1271. do
  1272. {
  1273. //
  1274. // Description string: we first query this with a 0 length buffer
  1275. // length, so that we get the actual # of bytes needed. Then we
  1276. // allocate a buffer for the descriptor string, and use that to
  1277. // get the actual string.
  1278. //
  1279. Status = AtmArpSendAdapterNdisRequest(
  1280. pAdapter,
  1281. &NdisRequest,
  1282. NdisRequestQueryInformation,
  1283. OID_GEN_CO_VENDOR_DESCRIPTION,
  1284. (PVOID)(pAdapter->pDescrString),
  1285. 0
  1286. );
  1287. if ((Status == NDIS_STATUS_INVALID_LENGTH) ||
  1288. (Status == NDIS_STATUS_BUFFER_TOO_SHORT))
  1289. {
  1290. //
  1291. // Now allocate a buffer of the right length.
  1292. //
  1293. pAdapter->DescrLength = NdisRequest.DATA.QUERY_INFORMATION.BytesNeeded;
  1294. AA_ALLOC_MEM(pAdapter->pDescrString, UCHAR, pAdapter->DescrLength);
  1295. if (pAdapter->pDescrString != (PUCHAR)NULL)
  1296. {
  1297. Status = AtmArpSendAdapterNdisRequest(
  1298. pAdapter,
  1299. &NdisRequest,
  1300. NdisRequestQueryInformation,
  1301. OID_GEN_CO_VENDOR_DESCRIPTION,
  1302. (PVOID)(pAdapter->pDescrString),
  1303. pAdapter->DescrLength
  1304. );
  1305. }
  1306. else
  1307. {
  1308. pAdapter->DescrLength = 0;
  1309. }
  1310. AADEBUGP(AAD_LOUD, ("GetAdapterInfo: Query VENDOR Descr2 ret 0x%x, DescrLen %d\n",
  1311. Status, pAdapter->DescrLength));
  1312. }
  1313. else
  1314. {
  1315. AADEBUGP(AAD_LOUD, ("GetAdapterInfo: Query VENDOR Descr1 ret 0x%x\n", Status));
  1316. }
  1317. //
  1318. // MAC Address:
  1319. //
  1320. Status = AtmArpSendAdapterNdisRequest(
  1321. pAdapter,
  1322. &NdisRequest,
  1323. NdisRequestQueryInformation,
  1324. OID_ATM_HW_CURRENT_ADDRESS,
  1325. (PVOID)(pAdapter->MacAddress),
  1326. AA_ATM_ESI_LEN
  1327. );
  1328. //
  1329. // Max Frame Size:
  1330. //
  1331. Status = AtmArpSendAdapterNdisRequest(
  1332. pAdapter,
  1333. &NdisRequest,
  1334. NdisRequestQueryInformation,
  1335. OID_ATM_MAX_AAL5_PACKET_SIZE,
  1336. (PVOID)(&(pAdapter->MaxPacketSize)),
  1337. sizeof(ULONG)
  1338. );
  1339. if (Status != NDIS_STATUS_SUCCESS)
  1340. {
  1341. //
  1342. // Use the default.
  1343. //
  1344. pAdapter->MaxPacketSize = AA_DEF_ATM_MAX_PACKET_SIZE;
  1345. }
  1346. if (pAdapter->MaxPacketSize > AA_MAX_ATM_MAX_PACKET_SIZE)
  1347. {
  1348. pAdapter->MaxPacketSize = AA_MAX_ATM_MAX_PACKET_SIZE;
  1349. }
  1350. //
  1351. // Check that the adapter support the minimum.
  1352. //
  1353. if (pAdapter->MaxPacketSize < AA_MIN_ATM_MAX_PACKET_SIZE)
  1354. {
  1355. AADEBUGP(AAD_FATAL,
  1356. ("GetAdapterInfo: (FATAL) MaxPacketSize of (%lu) is too small.\n",
  1357. pAdapter->MaxPacketSize));
  1358. Status = NDIS_STATUS_RESOURCES;
  1359. break;
  1360. }
  1361. //
  1362. // Link speed:
  1363. //
  1364. Status = AtmArpSendAdapterNdisRequest(
  1365. pAdapter,
  1366. &NdisRequest,
  1367. NdisRequestQueryInformation,
  1368. OID_GEN_CO_LINK_SPEED,
  1369. (PVOID)(&(pAdapter->LineRate)),
  1370. sizeof(pAdapter->LineRate)
  1371. );
  1372. if ((Status != NDIS_STATUS_SUCCESS) ||
  1373. (pAdapter->LineRate.Inbound == 0) ||
  1374. (pAdapter->LineRate.Outbound == 0))
  1375. {
  1376. //
  1377. // Use the default.
  1378. //
  1379. pAdapter->LineRate.Outbound = pAdapter->LineRate.Inbound = AA_DEF_ATM_LINE_RATE;
  1380. AADEBUGP(AAD_LOUD, ("Using default line rate %d bytes/sec\n",
  1381. AA_DEF_ATM_LINE_RATE));
  1382. }
  1383. else
  1384. {
  1385. //
  1386. // Convert from 100 bits/sec to bytes/sec
  1387. //
  1388. pAdapter->LineRate.Outbound = (pAdapter->LineRate.Outbound * 100)/8;
  1389. pAdapter->LineRate.Inbound = (pAdapter->LineRate.Inbound * 100)/8;
  1390. AADEBUGP(AAD_LOUD, ("Got line rates from miniport: In %d, Out %d bytes/sec\n",
  1391. pAdapter->LineRate.Outbound,
  1392. pAdapter->LineRate.Inbound));
  1393. }
  1394. Status = NDIS_STATUS_SUCCESS;
  1395. } while(FALSE);
  1396. return Status;
  1397. }
  1398. NDIS_STATUS
  1399. AtmArpSendNdisRequest(
  1400. IN PATMARP_ADAPTER pAdapter,
  1401. IN PNDIS_REQUEST pNdisRequest,
  1402. IN NDIS_REQUEST_TYPE RequestType,
  1403. IN NDIS_OID Oid,
  1404. IN PVOID pBuffer,
  1405. IN ULONG BufferLength
  1406. )
  1407. /*++
  1408. Routine Description:
  1409. Send an NDIS (non-Connection Oriented) request to the Miniport. We
  1410. allocate an NDIS_REQUEST structure, link the supplied buffer to it,
  1411. and send the request. If the request does not pend, we call our
  1412. completion routine from here.
  1413. Arguments:
  1414. pAdapter - Pointer to our Adapter structure representing
  1415. the adapter to which the request is to be sent
  1416. pNdisRequest - Pointer to NDIS request structure
  1417. RequestType - Set/Query information
  1418. Oid - OID to be passed in the request
  1419. pBuffer - place for value(s)
  1420. BufferLength - length of above
  1421. Return Value:
  1422. Status of the NdisRequest.
  1423. --*/
  1424. {
  1425. NDIS_STATUS Status;
  1426. //
  1427. // Fill in the NDIS Request structure
  1428. //
  1429. pNdisRequest->RequestType = RequestType;
  1430. if (RequestType == NdisRequestQueryInformation)
  1431. {
  1432. pNdisRequest->DATA.QUERY_INFORMATION.Oid = Oid;
  1433. pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer = pBuffer;
  1434. pNdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength = BufferLength;
  1435. pNdisRequest->DATA.QUERY_INFORMATION.BytesWritten = 0;
  1436. pNdisRequest->DATA.QUERY_INFORMATION.BytesNeeded = BufferLength;
  1437. }
  1438. else
  1439. {
  1440. pNdisRequest->DATA.SET_INFORMATION.Oid = Oid;
  1441. pNdisRequest->DATA.SET_INFORMATION.InformationBuffer = pBuffer;
  1442. pNdisRequest->DATA.SET_INFORMATION.InformationBufferLength = BufferLength;
  1443. pNdisRequest->DATA.SET_INFORMATION.BytesRead = 0;
  1444. pNdisRequest->DATA.SET_INFORMATION.BytesNeeded = 0;
  1445. }
  1446. NdisRequest(
  1447. &Status,
  1448. pAdapter->NdisAdapterHandle,
  1449. pNdisRequest);
  1450. return (Status);
  1451. }
  1452. VOID
  1453. AtmArpShutdownInterface(
  1454. IN PATMARP_INTERFACE pInterface
  1455. )
  1456. /*++
  1457. Routine Description:
  1458. Bring down the specified ARP interface.
  1459. We tear down the ARP table, and shut down the Call Manager
  1460. interface. When this is complete, we will call IP's DelInterface
  1461. entry point.
  1462. Arguments:
  1463. pInterface - Points to the Interface to be shut down.
  1464. Return Value:
  1465. None
  1466. --*/
  1467. {
  1468. IP_STATUS Status;
  1469. INT i;
  1470. ULONG rc;
  1471. PATMARP_IP_ENTRY pIpEntry;
  1472. PATMARP_ATM_ENTRY pAtmEntry;
  1473. PATMARP_ATM_ENTRY pNextAtmEntry;
  1474. PATMARP_VC pVc;
  1475. PATMARP_VC pNextVc;
  1476. PATMARP_ADAPTER pAdapter;
  1477. BOOLEAN WasRunning;
  1478. #if DBG
  1479. AA_IRQL EntryIrq, ExitIrq;
  1480. #endif
  1481. AA_GET_ENTRY_IRQL(EntryIrq);
  1482. AA_ACQUIRE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  1483. pAdapter = pInterface->pAdapter;
  1484. //
  1485. // Wait for any AF register processing to finish.
  1486. //
  1487. while (pAdapter->Flags & AA_ADAPTER_FLAGS_PROCESSING_AF)
  1488. {
  1489. AA_RELEASE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  1490. AADEBUGP(AAD_FATAL, ("ShutdownIf: IF %p, pAdapter %x, Afregister going on!!!\n",
  1491. pInterface, pAdapter));
  1492. Status = AA_WAIT_ON_BLOCK_STRUCT(&(pAdapter->UnbindBlock));
  1493. AA_ACQUIRE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  1494. }
  1495. AA_RELEASE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  1496. //
  1497. // Stop any timer running on this interface
  1498. //
  1499. AA_ACQUIRE_IF_LOCK(pInterface);
  1500. if (AtmArpStopTimer(&(pInterface->Timer), pInterface))
  1501. {
  1502. rc = AtmArpDereferenceInterface(pInterface); // Timer ref
  1503. AA_ASSERT(rc != 0);
  1504. }
  1505. #ifdef IPMCAST
  1506. //
  1507. // Stop any Multicast timer running on this interface
  1508. //
  1509. if (AtmArpStopTimer(&(pInterface->McTimer), pInterface))
  1510. {
  1511. rc = AtmArpDereferenceInterface(pInterface); // Timer ref
  1512. AA_ASSERT(rc != 0);
  1513. }
  1514. #endif
  1515. AA_RELEASE_IF_LOCK(pInterface);
  1516. //
  1517. // Deregister all SAPs so that we don't get any more
  1518. // incoming calls.
  1519. //
  1520. AtmArpDeregisterSaps(pInterface);
  1521. AA_CHECK_EXIT_IRQL(EntryIrq, ExitIrq);
  1522. //
  1523. // We set the ARP Table state to "down" -- this will ensure that it
  1524. // will not grow while we are shutting down.
  1525. //
  1526. AA_ACQUIRE_IF_TABLE_LOCK(pInterface);
  1527. pInterface->ArpTableUp = FALSE;
  1528. //
  1529. // Go through the ARP Table and abort all IP entries
  1530. //
  1531. for (i = 0; i < ATMARP_TABLE_SIZE; i++)
  1532. {
  1533. while (pInterface->pArpTable[i] != NULL_PATMARP_IP_ENTRY)
  1534. {
  1535. pIpEntry = pInterface->pArpTable[i];
  1536. AA_ACQUIRE_IE_LOCK_DPC(pIpEntry);
  1537. AA_REF_IE(pIpEntry, IE_REFTYPE_TMP); // Shutdown Interface
  1538. AA_RELEASE_IE_LOCK_DPC(pIpEntry);
  1539. AA_RELEASE_IF_TABLE_LOCK(pInterface);
  1540. AA_ACQUIRE_IE_LOCK(pIpEntry);
  1541. if (AA_DEREF_IE(pIpEntry, IE_REFTYPE_TMP)) // Shutdown Interface
  1542. {
  1543. AtmArpAbortIPEntry(pIpEntry);
  1544. //
  1545. // IE Lock is released within the above.
  1546. //
  1547. }
  1548. AA_ACQUIRE_IF_TABLE_LOCK(pInterface);
  1549. }
  1550. }
  1551. AA_RELEASE_IF_TABLE_LOCK(pInterface);
  1552. AA_CHECK_EXIT_IRQL(EntryIrq, ExitIrq);
  1553. #ifdef IPMCAST
  1554. //
  1555. // Delete all Join Entries
  1556. //
  1557. AA_ACQUIRE_IF_LOCK(pInterface);
  1558. {
  1559. PATMARP_IPMC_JOIN_ENTRY pJoinEntry;
  1560. PATMARP_IPMC_JOIN_ENTRY pNextJoinEntry;
  1561. for (pJoinEntry = pInterface->pJoinList;
  1562. pJoinEntry != NULL_PATMARP_IPMC_JOIN_ENTRY;
  1563. pJoinEntry = pNextJoinEntry)
  1564. {
  1565. WasRunning = AtmArpStopTimer(&(pJoinEntry->Timer), pInterface);
  1566. pNextJoinEntry = pJoinEntry->pNextJoinEntry;
  1567. if (WasRunning)
  1568. {
  1569. rc = AA_DEREF_JE(pJoinEntry); // ShutdownIF: timer stopped
  1570. }
  1571. else
  1572. {
  1573. rc = pJoinEntry->RefCount;
  1574. }
  1575. if (rc != 0)
  1576. {
  1577. (VOID)AA_DEREF_JE(pJoinEntry); // ShutdownIF: kill Join Entry
  1578. }
  1579. }
  1580. pInterface->pJoinList = NULL_PATMARP_IPMC_JOIN_ENTRY;
  1581. }
  1582. AA_RELEASE_IF_LOCK(pInterface);
  1583. #endif
  1584. //
  1585. // We set the AtmEntry list state to "down" (this will ensure that it
  1586. // will not grow while we are shutting down), then
  1587. // go through the list of ATM Entries on this interface, and
  1588. // abort all of them.
  1589. //
  1590. AA_ACQUIRE_IF_ATM_LIST_LOCK(pInterface);
  1591. pInterface->AtmEntryListUp = FALSE;
  1592. pNextAtmEntry = pInterface->pAtmEntryList;
  1593. if (pNextAtmEntry != NULL_PATMARP_ATM_ENTRY)
  1594. {
  1595. AA_ACQUIRE_AE_LOCK_DPC(pNextAtmEntry);
  1596. AA_REF_AE(pNextAtmEntry, AE_REFTYPE_TMP); // ShutdownInterface
  1597. AA_RELEASE_AE_LOCK_DPC(pNextAtmEntry);
  1598. }
  1599. while (pNextAtmEntry != NULL_PATMARP_ATM_ENTRY)
  1600. {
  1601. pAtmEntry = pNextAtmEntry;
  1602. pNextAtmEntry = pAtmEntry->pNext;
  1603. //
  1604. // Note that we still have the lock to pInterface when
  1605. // we aquire the lock to pAtmEntry below. This order of aquiring
  1606. // locks must be strictly followed everywhere in order to prevent
  1607. // a deadlock.
  1608. //
  1609. // We can't release the LIST_LOCK without first addrefing pAtmEntry,
  1610. // otherwise while both locks are free someone else can delref and
  1611. // possibly deallocate pAtmEntry.
  1612. //
  1613. if (pNextAtmEntry != NULL_PATMARP_ATM_ENTRY)
  1614. {
  1615. AA_ACQUIRE_AE_LOCK_DPC(pNextAtmEntry);
  1616. AA_REF_AE(pNextAtmEntry, AE_REFTYPE_TMP); // ShutdownInterface
  1617. AA_RELEASE_AE_LOCK_DPC(pNextAtmEntry);
  1618. }
  1619. AA_RELEASE_IF_ATM_LIST_LOCK(pInterface);
  1620. AA_CHECK_EXIT_IRQL(EntryIrq, ExitIrq);
  1621. AA_ACQUIRE_AE_LOCK(pAtmEntry);
  1622. if (AA_DEREF_AE(pAtmEntry, AE_REFTYPE_TMP) != 0) // ShutdownInterface
  1623. {
  1624. AtmArpInvalidateAtmEntry(
  1625. pAtmEntry,
  1626. TRUE // we ARE shutting down
  1627. );
  1628. //
  1629. // The ATM Entry lock is released within the above.
  1630. //
  1631. }
  1632. AA_CHECK_EXIT_IRQL(EntryIrq, ExitIrq);
  1633. AA_ACQUIRE_IF_ATM_LIST_LOCK(pInterface);
  1634. }
  1635. AA_RELEASE_IF_ATM_LIST_LOCK(pInterface);
  1636. AA_CHECK_EXIT_IRQL(EntryIrq, ExitIrq);
  1637. //
  1638. // Go through the list of unresolved VCs on this interface,
  1639. // and close all of them.
  1640. //
  1641. AA_ACQUIRE_IF_LOCK(pInterface);
  1642. pVc = pInterface->pUnresolvedVcs;
  1643. pInterface->pUnresolvedVcs = NULL_PATMARP_VC;
  1644. while (pVc != NULL_PATMARP_VC)
  1645. {
  1646. pNextVc = pVc->pNextVc;
  1647. AA_RELEASE_IF_LOCK(pInterface);
  1648. AA_ACQUIRE_VC_LOCK(pVc);
  1649. if (AtmArpDereferenceVc(pVc) != 0) // Unresolved VC list entry
  1650. {
  1651. AtmArpCloseCall(pVc);
  1652. //
  1653. // the VC lock is released within the above.
  1654. //
  1655. }
  1656. pVc = pNextVc;
  1657. AA_ACQUIRE_IF_LOCK(pInterface);
  1658. }
  1659. AA_RELEASE_IF_LOCK(pInterface);
  1660. AA_CHECK_EXIT_IRQL(EntryIrq, ExitIrq);
  1661. //
  1662. // Close the Call Manager interface.
  1663. //
  1664. AtmArpCloseCallMgr(pInterface);
  1665. }
  1666. BOOLEAN
  1667. AtmArpIsDeviceAlreadyBound(
  1668. IN PNDIS_STRING pDeviceName
  1669. )
  1670. /*++
  1671. Routine Description:
  1672. Check if we have already bound to a device (adapter).
  1673. Arguments:
  1674. pDeviceName - Points to device name to be checked.
  1675. Return Value:
  1676. TRUE iff we already have an Adapter structure representing
  1677. this device.
  1678. --*/
  1679. {
  1680. PATMARP_ADAPTER pAdapter;
  1681. BOOLEAN bFound = FALSE;
  1682. AA_ACQUIRE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  1683. for (pAdapter = pAtmArpGlobalInfo->pAdapterList;
  1684. pAdapter != NULL_PATMARP_ADAPTER;
  1685. pAdapter = pAdapter->pNextAdapter)
  1686. {
  1687. if ((pDeviceName->Length == pAdapter->DeviceName.Length) &&
  1688. (AA_MEM_CMP(pDeviceName->Buffer,
  1689. pAdapter->DeviceName.Buffer,
  1690. pDeviceName->Length) == 0))
  1691. {
  1692. bFound = TRUE;
  1693. break;
  1694. }
  1695. }
  1696. AA_RELEASE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  1697. return (bFound);
  1698. }
  1699. #if ATMOFFLOAD
  1700. NDIS_STATUS
  1701. AtmArpQueryAndEnableOffload(
  1702. IN PATMARP_ADAPTER pAdapter
  1703. )
  1704. /*++
  1705. Routine Description:
  1706. Query the capabilities of the adapter and set all recognized offload capabilities.
  1707. Set pMaxOffLoadSize and pMinSegmentCount to the corresponding values, and
  1708. also set pInterface->OffloadFlags to the set of enabled tasks.
  1709. Arguments:
  1710. pAdapter - The adapter on which to enable offloading.
  1711. Return Value:
  1712. TRUE iff the operation was either succesful or no tasks were enabled. False
  1713. if there was a fatal error.
  1714. --*/
  1715. {
  1716. NDIS_STATUS Status = STATUS_BUFFER_OVERFLOW;
  1717. PNDIS_TASK_OFFLOAD_HEADER pHeader = NULL;
  1718. AA_ACQUIRE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  1719. pAdapter->Offload.Flags = 0;
  1720. pAdapter->Offload.MaxOffLoadSize = 0;
  1721. pAdapter->Offload.MinSegmentCount = 0;
  1722. AA_RELEASE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  1723. do
  1724. {
  1725. PNDIS_TASK_OFFLOAD pTask;
  1726. ULONG Flags = 0;
  1727. UINT MaxOffLoadSize = 0;
  1728. UINT MinSegmentCount = 0;
  1729. NDIS_TASK_IPSEC ipsecCaps;
  1730. UINT BufferSize = 0;
  1731. NDIS_REQUEST NdisRequest;
  1732. //
  1733. // Query capabilities
  1734. //
  1735. {
  1736. NDIS_TASK_OFFLOAD_HEADER Header;
  1737. AA_SET_MEM(&Header, 0, sizeof(Header));
  1738. Header.EncapsulationFormat.Flags.FixedHeaderSize = 1;
  1739. Header.EncapsulationFormat.EncapsulationHeaderSize =
  1740. AA_PKT_LLC_SNAP_HEADER_LENGTH;
  1741. Header.EncapsulationFormat.Encapsulation =
  1742. LLC_SNAP_ROUTED_Encapsulation;
  1743. Header.Version = NDIS_TASK_OFFLOAD_VERSION;
  1744. Header.Size = sizeof(Header);
  1745. AADEBUGP(AAD_INFO, ("Querying for Task offload\n"));
  1746. Status = AtmArpSendAdapterNdisRequest(
  1747. pAdapter,
  1748. &NdisRequest,
  1749. NdisRequestQueryInformation,
  1750. OID_TCP_TASK_OFFLOAD,
  1751. &Header,
  1752. sizeof(Header)
  1753. );
  1754. if ((Status == NDIS_STATUS_INVALID_LENGTH) ||
  1755. (Status == NDIS_STATUS_BUFFER_TOO_SHORT)) {
  1756. //
  1757. // Alloc the proper-sized buffer and query a 2nd time...
  1758. //
  1759. BufferSize = NdisRequest.DATA.QUERY_INFORMATION.BytesNeeded;
  1760. AA_ALLOC_MEM(pHeader, NDIS_TASK_OFFLOAD_HEADER, BufferSize);
  1761. if (pHeader != NULL)
  1762. {
  1763. *pHeader = Header; // struct copy.
  1764. Status = AtmArpSendAdapterNdisRequest(
  1765. pAdapter,
  1766. &NdisRequest,
  1767. NdisRequestQueryInformation,
  1768. OID_TCP_TASK_OFFLOAD,
  1769. pHeader,
  1770. BufferSize
  1771. );
  1772. }
  1773. }
  1774. }
  1775. if (Status != NDIS_STATUS_SUCCESS)
  1776. {
  1777. AADEBUGP(AAD_INFO, ("Query Offload failed. Status=%x\n", Status));
  1778. break;
  1779. }
  1780. if ( pHeader == NULL
  1781. || pHeader->OffsetFirstTask == 0)
  1782. {
  1783. AADEBUGP(AAD_INFO, ("No tasks to offload\n"));
  1784. break;
  1785. }
  1786. AA_ASSERT(pHeader->OffsetFirstTask == sizeof(NDIS_TASK_OFFLOAD_HEADER));
  1787. AADEBUGP(AAD_WARNING,
  1788. ("Something to Offload. Offload buffer size %x\n", BufferSize));
  1789. //
  1790. // Parse the buffer for Checksum and tcplargesend offload capabilities
  1791. //
  1792. for (
  1793. pTask = (NDIS_TASK_OFFLOAD *) ((UCHAR *)pHeader
  1794. + pHeader->OffsetFirstTask);
  1795. 1; // we break when done
  1796. pTask = (PNDIS_TASK_OFFLOAD) ((PUCHAR)pTask + pTask->OffsetNextTask))
  1797. {
  1798. if (pTask->Task == TcpIpChecksumNdisTask)
  1799. {
  1800. //
  1801. //this adapter supports checksum offload
  1802. //check if tcp and/or ip chksums bits are present
  1803. //
  1804. PNDIS_TASK_TCP_IP_CHECKSUM ChecksumInfo
  1805. = (PNDIS_TASK_TCP_IP_CHECKSUM) pTask->TaskBuffer;
  1806. // if (ChecksumInfo->V4Transmit.V4Checksum) (commented out in arpc.c)
  1807. {
  1808. AADEBUGP(AAD_INFO, ("V4 Checksum offload\n"));
  1809. if (ChecksumInfo->V4Transmit.TcpChecksum) {
  1810. Flags |= TCP_XMT_CHECKSUM_OFFLOAD;
  1811. AADEBUGP(AAD_INFO, (" Tcp Checksum offload\n"));
  1812. }
  1813. if (ChecksumInfo->V4Transmit.IpChecksum) {
  1814. Flags |= IP_XMT_CHECKSUM_OFFLOAD;
  1815. AADEBUGP(AAD_INFO, (" IP xmt Checksum offload\n"));
  1816. }
  1817. if (ChecksumInfo->V4Receive.TcpChecksum) {
  1818. Flags |= TCP_RCV_CHECKSUM_OFFLOAD;
  1819. AADEBUGP(AAD_INFO, (" Tcp Rcv Checksum offload\n"));
  1820. }
  1821. if (ChecksumInfo->V4Receive.IpChecksum) {
  1822. Flags |= IP_RCV_CHECKSUM_OFFLOAD;
  1823. AADEBUGP(AAD_INFO, (" IP rcv Checksum offload\n"));
  1824. }
  1825. }
  1826. }
  1827. else if (pTask->Task == TcpLargeSendNdisTask)
  1828. {
  1829. PNDIS_TASK_TCP_LARGE_SEND TcpLargeSend, in_LargeSend =
  1830. (PNDIS_TASK_TCP_LARGE_SEND)pTask->TaskBuffer;
  1831. Flags |= TCP_LARGE_SEND_OFFLOAD;
  1832. MaxOffLoadSize = in_LargeSend->MaxOffLoadSize;
  1833. MinSegmentCount = in_LargeSend->MinSegmentCount;
  1834. AADEBUGP(AAD_INFO, (" Tcp large send!! \n"));
  1835. }
  1836. else if (pTask->Task == IpSecNdisTask)
  1837. {
  1838. PNDIS_TASK_IPSEC pIPSecCaps =
  1839. (PNDIS_TASK_IPSEC) pTask->TaskBuffer;
  1840. //
  1841. // Save off the capabilities for setting them later.
  1842. //
  1843. ipsecCaps = *pIPSecCaps;
  1844. //
  1845. // CryptoOnly is assumed if we have IpSecNdisTask
  1846. //
  1847. Flags |= IPSEC_OFFLOAD_CRYPTO_ONLY;
  1848. //
  1849. // Do Support first
  1850. //
  1851. if (pIPSecCaps->Supported.AH_ESP_COMBINED) {
  1852. Flags |= IPSEC_OFFLOAD_AH_ESP;
  1853. AADEBUGP(AAD_INFO, ("AH_ESP\n"));
  1854. }
  1855. if (pIPSecCaps->Supported.TRANSPORT_TUNNEL_COMBINED) {
  1856. Flags |= IPSEC_OFFLOAD_TPT_TUNNEL;
  1857. AADEBUGP(AAD_INFO, ("TPT_TUNNEL\n"));
  1858. }
  1859. if (pIPSecCaps->Supported.V4_OPTIONS) {
  1860. Flags |= IPSEC_OFFLOAD_V4_OPTIONS;
  1861. AADEBUGP(AAD_INFO, ("V4_OPTIONS\n"));
  1862. }
  1863. if (pIPSecCaps->Supported.RESERVED) {
  1864. pIPSecCaps->Supported.RESERVED = 0;
  1865. //Flags |= IPSEC_OFFLOAD_QUERY_SPI;
  1866. AADEBUGP(AAD_INFO, ("QUERY_SPI\n"));
  1867. }
  1868. //
  1869. // Do V4AH next
  1870. //
  1871. if (pIPSecCaps->V4AH.MD5) {
  1872. Flags |= IPSEC_OFFLOAD_AH_MD5;
  1873. AADEBUGP(AAD_INFO, ("MD5\n"));
  1874. }
  1875. if (pIPSecCaps->V4AH.SHA_1) {
  1876. Flags |= IPSEC_OFFLOAD_AH_SHA_1;
  1877. AADEBUGP(AAD_INFO, ("SHA\n"));
  1878. }
  1879. if (pIPSecCaps->V4AH.Transport) {
  1880. Flags |= IPSEC_OFFLOAD_AH_TPT;
  1881. AADEBUGP(AAD_INFO, ("AH_TRANSPORT\n"));
  1882. }
  1883. if (pIPSecCaps->V4AH.Tunnel) {
  1884. Flags |= IPSEC_OFFLOAD_AH_TUNNEL;
  1885. AADEBUGP(AAD_INFO, ("AH_TUNNEL\n"));
  1886. }
  1887. if (pIPSecCaps->V4AH.Send) {
  1888. Flags |= IPSEC_OFFLOAD_AH_XMT;
  1889. AADEBUGP(AAD_INFO, ("AH_XMT\n"));
  1890. }
  1891. if (pIPSecCaps->V4AH.Receive) {
  1892. Flags |= IPSEC_OFFLOAD_AH_RCV;
  1893. AADEBUGP(AAD_INFO, ("AH_RCV\n"));
  1894. }
  1895. //
  1896. // Do V4ESP next
  1897. //
  1898. if (pIPSecCaps->V4ESP.DES) {
  1899. Flags |= IPSEC_OFFLOAD_ESP_DES;
  1900. AADEBUGP(AAD_INFO, ("ESP_DES\n"));
  1901. }
  1902. if (pIPSecCaps->V4ESP.RESERVED) {
  1903. pIPSecCaps->V4ESP.RESERVED = 0;
  1904. //Flags |= IPSEC_OFFLOAD_ESP_DES_40;
  1905. AADEBUGP(AAD_INFO, ("ESP_DES_40\n"));
  1906. }
  1907. if (pIPSecCaps->V4ESP.TRIPLE_DES) {
  1908. Flags |= IPSEC_OFFLOAD_ESP_3_DES;
  1909. AADEBUGP(AAD_INFO, ("ESP_3_DES\n"));
  1910. }
  1911. if (pIPSecCaps->V4ESP.NULL_ESP) {
  1912. Flags |= IPSEC_OFFLOAD_ESP_NONE;
  1913. AADEBUGP(AAD_INFO, ("ESP_NONE\n"));
  1914. }
  1915. if (pIPSecCaps->V4ESP.Transport) {
  1916. Flags |= IPSEC_OFFLOAD_ESP_TPT;
  1917. AADEBUGP(AAD_INFO, ("ESP_TRANSPORT\n"));
  1918. }
  1919. if (pIPSecCaps->V4ESP.Tunnel) {
  1920. Flags |= IPSEC_OFFLOAD_ESP_TUNNEL;
  1921. AADEBUGP(AAD_INFO, ("ESP_TUNNEL\n"));
  1922. }
  1923. if (pIPSecCaps->V4ESP.Send) {
  1924. Flags |= IPSEC_OFFLOAD_ESP_XMT;
  1925. AADEBUGP(AAD_INFO, ("ESP_XMT\n"));
  1926. }
  1927. if (pIPSecCaps->V4ESP.Receive) {
  1928. Flags |= IPSEC_OFFLOAD_ESP_RCV;
  1929. AADEBUGP(AAD_INFO, ("ESP_RCV\n"));
  1930. }
  1931. }
  1932. if (pTask->OffsetNextTask == 0)
  1933. {
  1934. break; // No more tasks.
  1935. }
  1936. } // for
  1937. //
  1938. // Done parsing supported tasks.
  1939. // Now construct the set of tasks we actually want to enable.
  1940. //
  1941. if (Flags)
  1942. {
  1943. UINT *pPrevOffset = &pHeader->OffsetFirstTask;
  1944. AADEBUGP(AAD_WARNING, ("Enabling H/W capabilities: %lx\n", Flags));
  1945. //
  1946. // Zero out the buffer beyond the task offload header structure
  1947. //
  1948. AA_SET_MEM(pTask, 0, BufferSize-sizeof(*pHeader));
  1949. pHeader->OffsetFirstTask = 0;
  1950. pTask = (NDIS_TASK_OFFLOAD *) (pHeader+1);
  1951. if ((Flags & TCP_XMT_CHECKSUM_OFFLOAD) ||
  1952. (Flags & IP_XMT_CHECKSUM_OFFLOAD) ||
  1953. (Flags & TCP_RCV_CHECKSUM_OFFLOAD) ||
  1954. (Flags & IP_RCV_CHECKSUM_OFFLOAD))
  1955. {
  1956. PNDIS_TASK_TCP_IP_CHECKSUM ChksumBuf =
  1957. (PNDIS_TASK_TCP_IP_CHECKSUM)pTask->TaskBuffer;
  1958. *pPrevOffset = (UINT) ((PUCHAR)pTask - (PUCHAR)pHeader);
  1959. pPrevOffset = &pTask->OffsetNextTask;
  1960. pTask->Task = TcpIpChecksumNdisTask;
  1961. pTask->TaskBufferLength = sizeof(NDIS_TASK_TCP_IP_CHECKSUM);
  1962. if (Flags & TCP_XMT_CHECKSUM_OFFLOAD)
  1963. {
  1964. ChksumBuf->V4Transmit.TcpChecksum = 1;
  1965. //ChksumBuf->V4Transmit.V4Checksum = 1;
  1966. }
  1967. if (Flags & IP_XMT_CHECKSUM_OFFLOAD)
  1968. {
  1969. ChksumBuf->V4Transmit.IpChecksum = 1;
  1970. //ChksumBuf->V4Transmit.V4Checksum = 1;
  1971. }
  1972. if (Flags & TCP_RCV_CHECKSUM_OFFLOAD)
  1973. {
  1974. ChksumBuf->V4Receive.TcpChecksum = 1;
  1975. //ChksumBuf->V4Receive.V4Checksum = 1;
  1976. }
  1977. if (Flags & IP_RCV_CHECKSUM_OFFLOAD)
  1978. {
  1979. ChksumBuf->V4Receive.IpChecksum = 1;
  1980. //ChksumBuf->V4Receive.V4Checksum = 1;
  1981. }
  1982. //
  1983. // Point to place where next task goes...
  1984. //
  1985. pTask = (PNDIS_TASK_OFFLOAD) (ChksumBuf+1);
  1986. }
  1987. if (Flags & TCP_LARGE_SEND_OFFLOAD)
  1988. {
  1989. PNDIS_TASK_TCP_LARGE_SEND out_LargeSend =
  1990. (PNDIS_TASK_TCP_LARGE_SEND)pTask->TaskBuffer;
  1991. *pPrevOffset = (UINT) ((PUCHAR)pTask - (PUCHAR)pHeader);
  1992. pPrevOffset = &pTask->OffsetNextTask;
  1993. pTask->Task = TcpLargeSendNdisTask;
  1994. pTask->TaskBufferLength = sizeof(NDIS_TASK_TCP_LARGE_SEND);
  1995. out_LargeSend->MaxOffLoadSize = MaxOffLoadSize;
  1996. out_LargeSend->MinSegmentCount = MinSegmentCount;
  1997. //
  1998. // Point to place where next task goes...
  1999. //
  2000. pTask = (PNDIS_TASK_OFFLOAD) (out_LargeSend+1);
  2001. }
  2002. if ((Flags & (IPSEC_OFFLOAD_AH_XMT |
  2003. IPSEC_OFFLOAD_AH_RCV |
  2004. IPSEC_OFFLOAD_ESP_XMT |
  2005. IPSEC_OFFLOAD_ESP_RCV)))
  2006. {
  2007. PNDIS_TASK_IPSEC pIPSecCaps =
  2008. (PNDIS_TASK_IPSEC)pTask->TaskBuffer;
  2009. *pPrevOffset = (UINT) ((PUCHAR)pTask - (PUCHAR)pHeader);
  2010. pPrevOffset = &pTask->OffsetNextTask;
  2011. //
  2012. // plunk down the advertised capabilities
  2013. //
  2014. pTask->Task = IpSecNdisTask;
  2015. pTask->TaskBufferLength = sizeof(NDIS_TASK_IPSEC);
  2016. //
  2017. // Point to place where next task goes...
  2018. //
  2019. pTask = (PNDIS_TASK_OFFLOAD) (pIPSecCaps+1);
  2020. }
  2021. }
  2022. //
  2023. // Having constructed the set of tasks to enable, we actually attempt
  2024. // to enable them...
  2025. //
  2026. if (pHeader->OffsetFirstTask)
  2027. {
  2028. //
  2029. // At least one task to enable, let's enable ...
  2030. //
  2031. UINT SetBufferSize = (UINT) ((PUCHAR)pTask - (PUCHAR)pHeader);
  2032. AA_ASSERT(SetBufferSize <= BufferSize);
  2033. AADEBUGP(AAD_WARNING,
  2034. ("Setting offload tasks: %x bytes. Miniport returned %x bytes\n",
  2035. SetBufferSize, BufferSize));
  2036. Status = AtmArpSendAdapterNdisRequest(
  2037. pAdapter,
  2038. &NdisRequest,
  2039. NdisRequestSetInformation,
  2040. OID_TCP_TASK_OFFLOAD,
  2041. pHeader,
  2042. SetBufferSize
  2043. );
  2044. if (Status != NDIS_STATUS_SUCCESS)
  2045. {
  2046. AADEBUGP(AAD_WARNING,
  2047. ("ARP: Failed to set offload tasks: %lx, status: %lx\n",
  2048. Flags, Status));
  2049. }
  2050. else
  2051. {
  2052. AADEBUGP(AAD_WARNING,
  2053. ("ARP: Succeeded setting offload tasks: %lx:\n", Flags));
  2054. AA_ACQUIRE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  2055. pAdapter->Offload.Flags = Flags;
  2056. pAdapter->Offload.MaxOffLoadSize = MaxOffLoadSize;
  2057. pAdapter->Offload.MinSegmentCount = MinSegmentCount;
  2058. AA_RELEASE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  2059. }
  2060. }
  2061. } while (FALSE);
  2062. if (pHeader != NULL)
  2063. {
  2064. AA_FREE_MEM(pHeader);
  2065. }
  2066. //
  2067. // We return success unless there was a fatal error and there was none...
  2068. //
  2069. return NDIS_STATUS_SUCCESS;
  2070. }
  2071. VOID
  2072. AtmArpDisableOffload(
  2073. IN PATMARP_ADAPTER pAdapter
  2074. )
  2075. /*++
  2076. Routine Description:
  2077. Disable offload capabilities, if enabled for this interface.
  2078. Arguments:
  2079. pAdapter - The adapter on which to disable offloading.
  2080. Return Value:
  2081. TRUE iff the operation was either succesful or no tasks were enabled. False
  2082. if there was a fatal error.
  2083. --*/
  2084. {
  2085. ULONG Flags;
  2086. AA_ACQUIRE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  2087. Flags = pAdapter->Offload.Flags;
  2088. pAdapter->Offload.Flags = 0;
  2089. pAdapter->Offload.MaxOffLoadSize = 0;
  2090. pAdapter->Offload.MinSegmentCount = 0;
  2091. AA_RELEASE_GLOBAL_LOCK(pAtmArpGlobalInfo);
  2092. if (Flags)
  2093. {
  2094. NDIS_REQUEST NdisRequest;
  2095. NDIS_TASK_OFFLOAD_HEADER Header;
  2096. AA_SET_MEM(&Header, 0, sizeof(Header));
  2097. Header.EncapsulationFormat.Flags.FixedHeaderSize = 1;
  2098. Header.EncapsulationFormat.EncapsulationHeaderSize = 2;
  2099. Header.EncapsulationFormat.Encapsulation =
  2100. LLC_SNAP_ROUTED_Encapsulation;
  2101. Header.Version = NDIS_TASK_OFFLOAD_VERSION;
  2102. Header.Size = sizeof(Header);
  2103. //
  2104. // Header.OffsetFirstTask == 0 tells the miniport to disable all tasks.
  2105. //
  2106. AADEBUGP(AAD_WARNING, ("Disabling all offloaded tasks for this adapter\n"));
  2107. AtmArpSendAdapterNdisRequest(
  2108. pAdapter,
  2109. &NdisRequest,
  2110. NdisRequestSetInformation,
  2111. OID_TCP_TASK_OFFLOAD,
  2112. &Header,
  2113. sizeof(Header)
  2114. );
  2115. }
  2116. }
  2117. #endif // ATMOFFLOAD