Windows NT 4.0 source code leak
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.

1624 lines
33 KiB

4 years ago
  1. /*++
  2. Copyright (c) 1990-1995 Microsoft Corporation
  3. Module Name:
  4. Ndiswan.c
  5. Abstract:
  6. This is the initialization file for the NdisWan driver. This driver
  7. is a shim between the protocols, where it conforms to the NDIS 3.1
  8. Miniport interface spec, and the WAN Miniport drivers, where it exports
  9. the WAN Extensions for Miniports (it looks like a protocol to the WAN
  10. Miniport drivers).
  11. Author:
  12. Tony Bell (TonyBe) June 06, 1995
  13. Environment:
  14. Kernel Mode
  15. Revision History:
  16. TonyBe 06/06/95 Created
  17. --*/
  18. #include "wan.h"
  19. #include "tcpip.h"
  20. #include "vjslip.h"
  21. //
  22. // Local function prototypes
  23. //
  24. NDIS_STATUS
  25. NdisWanCreateLinkCB(
  26. OUT PLINKCB *LinkCB
  27. );
  28. VOID
  29. NdisWanInitLinkCB(
  30. IN PLINKCB *LinkCB,
  31. IN PWAN_ADAPTERCB WanAdapterCB,
  32. IN ULONG SendWindow
  33. );
  34. VOID
  35. NdisWanDestroyLinkCB(
  36. IN PLINKCB LinkCB
  37. );
  38. NDIS_STATUS
  39. NdisWanCreateBundleCB(
  40. OUT PBUNDLECB *BundleCB
  41. );
  42. VOID
  43. NdisWanInitBundleCB(
  44. IN PBUNDLECB BundleCB
  45. );
  46. VOID
  47. NdisWanDestroyBundleCB(
  48. IN PBUNDLECB BundleCB
  49. );
  50. NDIS_STATUS
  51. NdisWanCreateProtocolCB(
  52. OUT PPROTOCOLCB *ProtocolCB,
  53. IN USHORT usProtocolType,
  54. IN USHORT usBindingNameLength,
  55. IN PWSTR BindingName,
  56. IN ULONG ulBufferLength,
  57. IN PUCHAR Buffer
  58. );
  59. //VOID
  60. //NdisWanInitProtocolCB(
  61. // IN PPROTOCOLCB ProtocolCB,
  62. // IN ULONG ulBufferLength,
  63. // IN PUCHAR Buffer,
  64. // IN USHORT usProtocolType
  65. // );
  66. VOID
  67. NdisWanDestroyProtocolCB(
  68. IN PPROTOCOLCB ProtocolCB
  69. );
  70. NDIS_STATUS
  71. NdisWanAllocateSendResources(
  72. IN PLINKCB LinkCB,
  73. IN ULONG SendWindow
  74. );
  75. VOID
  76. NdisWanFreeSendResources(
  77. IN PLINKCB LinkCB
  78. );
  79. //
  80. // End local function prototypes
  81. //
  82. NDIS_STATUS
  83. NdisWanCreateAdapterCB(
  84. OUT PADAPTERCB *pAdapterCB,
  85. IN PNDIS_STRING AdapterName
  86. )
  87. /*++
  88. Routine Name:
  89. NdisWanCreateAdapterCB
  90. Routine Description:
  91. This routine creates and initializes an AdapterCB
  92. Arguments:
  93. pAdapterCB - Pointer to a pointer to the AdapterCB that was created
  94. Return Values:
  95. NDIS_STATUS_SUCCESS
  96. NDIS_STATUS_RESOURCES
  97. --*/
  98. {
  99. PADAPTERCB LocalAdapterCB;
  100. ULONG ulAllocationSize, i;
  101. PDEFERRED_DESC FreeDesc;
  102. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanCreateAdapterCB: Enter"));
  103. //
  104. // Allocate and zero out the memory block
  105. //
  106. ulAllocationSize = sizeof(ADAPTERCB) + 20*sizeof(DEFERRED_DESC);
  107. NdisWanAllocateMemory(&LocalAdapterCB, ulAllocationSize);
  108. if (LocalAdapterCB == NULL) {
  109. return (NDIS_STATUS_RESOURCES);
  110. }
  111. //
  112. // setup the new control block
  113. //
  114. LocalAdapterCB->ulAllocationSize = ulAllocationSize;
  115. NdisAllocateSpinLock(&LocalAdapterCB->Lock);
  116. #ifdef MINIPORT_NAME
  117. // NdisWanStringToNdisString(&LocalAdapterCB->AdapterName, AdapterName->Buffer);
  118. NdisWanAllocateAdapterName(&LocalAdapterCB->AdapterName, AdapterName);
  119. #endif
  120. //
  121. // Setup free deferred desc list
  122. //
  123. FreeDesc = (PDEFERRED_DESC)((PUCHAR)LocalAdapterCB + sizeof(ADAPTERCB));
  124. for (i = 0; i < 20; i++) {
  125. InsertHeadDeferredQueue(&LocalAdapterCB->FreeDeferredQueue, FreeDesc);
  126. (PUCHAR)FreeDesc += sizeof(DEFERRED_DESC);
  127. }
  128. #if DBG
  129. InitializeListHead(&LocalAdapterCB->DbgNdisPacketList);
  130. #endif
  131. //
  132. // Add to global list
  133. //
  134. InsertTailGlobalList(AdapterCBList, &(LocalAdapterCB->Linkage));
  135. *pAdapterCB = LocalAdapterCB;
  136. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("%ls AdapterCB: 0x%x, Number: %d",
  137. LocalAdapterCB->AdapterName.Buffer, *pAdapterCB, AdapterCBList.ulCount));
  138. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanCreateAdapterCB: Exit"));
  139. return (NDIS_STATUS_SUCCESS);
  140. }
  141. VOID
  142. NdisWanDestroyAdapterCB(
  143. IN PADAPTERCB pAdapterCB
  144. )
  145. /*++
  146. Routine Name:
  147. NdisWanDestroyAdapterCB
  148. Routine Description:
  149. This destroys an AdapterCB
  150. Arguments:
  151. pAdapterCB - Pointer to to the AdapterCB that is being destroyed
  152. Return Values:
  153. None
  154. --*/
  155. {
  156. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanDestroyAdapterCB: Enter"));
  157. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("AdapterCB: 0x%x", pAdapterCB));
  158. #ifdef MINIPORT_NAME
  159. NdisWanFreeNdisString(&pAdapterCB->AdapterName);
  160. #endif
  161. NdisFreeSpinLock(&pAdapterCB->Lock);
  162. NdisWanFreeMemory(pAdapterCB);
  163. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanDestroyAdapterCB: Exit"));
  164. }
  165. NDIS_STATUS
  166. NdisWanCreateWanAdapterCB(
  167. IN PWSTR BindName
  168. )
  169. /*++
  170. Routine Name:
  171. NdisWanCreateWanAdapterCB
  172. Routine Description:
  173. This routine creates and initializes a WanAdapterCB
  174. Arguments:
  175. BindName - Pointer to an NDIS_STRING that has the name of the WAN Miniport
  176. that will be used in the NdisOpenAdapter call when we bind to
  177. the WAN Miniport.
  178. Return Values:
  179. NDIS_STATUS_SUCCESS
  180. NDIS_STATUS_RESOURCES
  181. --*/
  182. {
  183. PWAN_ADAPTERCB pWanAdapterCB;
  184. ULONG ulAllocationSize;
  185. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanCreateWanAdapterCB: Enter"));
  186. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("BindName: %ls", BindName));
  187. //
  188. // Allocate memory for WanAdapterCB
  189. //
  190. ulAllocationSize = sizeof(WAN_ADAPTERCB);
  191. NdisWanAllocateMemory(&pWanAdapterCB, ulAllocationSize);
  192. if (pWanAdapterCB == NULL) {
  193. return (NDIS_STATUS_RESOURCES);
  194. }
  195. //
  196. // Init WanAdapterCB
  197. //
  198. //
  199. // Setup new control block
  200. //
  201. pWanAdapterCB->ulAllocationSize = ulAllocationSize;
  202. NdisWanStringToNdisString(&(pWanAdapterCB->MiniportName), BindName);
  203. NdisAllocateSpinLock(&pWanAdapterCB->Lock);
  204. InitializeListHead(&pWanAdapterCB->FreeLinkCBList);
  205. #if DBG
  206. InitializeListHead(&pWanAdapterCB->DbgWanPacketList);
  207. #endif
  208. //
  209. // Put WanAdapterCB on global list
  210. //
  211. InsertTailGlobalList(WanAdapterCBList, &(pWanAdapterCB->Linkage));
  212. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("WanMiniport %ls WanAdapterCB: 0x%x",
  213. pWanAdapterCB->MiniportName.Buffer, pWanAdapterCB));
  214. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanCreateWanAdapterCB: Exit"));
  215. return(NDIS_STATUS_SUCCESS);
  216. }
  217. VOID
  218. NdisWanDestroyWanAdapterCB(
  219. IN PWAN_ADAPTERCB pWanAdapterCB
  220. )
  221. /*++
  222. Routine Name:
  223. NdisWanDestroyWanAdapterCB
  224. Routine Description:
  225. This routine destroys a WanAdapterCB
  226. Arguments:
  227. pWanAdapterCB - Pointer to the WanAdapterCB that is being destroyed
  228. Return Values:
  229. None
  230. --*/
  231. {
  232. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanDestroyWanAdapterCB: Enter - WanAdapterCB: 0x%4.4x", pWanAdapterCB));
  233. //
  234. // Free the memory allocated for the NDIS_STRING
  235. //
  236. NdisWanFreeNdisString(&pWanAdapterCB->MiniportName);
  237. NdisFreeSpinLock(&pWanAdapter->Lock);
  238. //
  239. // Free the memory allocated for the control block
  240. //
  241. NdisWanFreeMemory(pWanAdapterCB);
  242. NdisWanDbgOut(DBG_TRACE, DBG_MEMORY, ("NdisWanDestroyWanAdapterCB: Exit"));
  243. }
  244. VOID
  245. NdisWanGetProtocolCB(
  246. OUT PPROTOCOLCB *ProtocolCB,
  247. IN USHORT usProtocolType,
  248. IN USHORT usBindingNameLength,
  249. IN PWSTR BindingName,
  250. IN ULONG ulBufferLength,
  251. IN PUCHAR Buffer
  252. )
  253. /*++
  254. Routine Name:
  255. Routine Description:
  256. Arguments:
  257. Return Values:
  258. --*/
  259. {
  260. *ProtocolCB = NULL;
  261. // NdisAcquireSpinLock(&(FreeProtocolCBList.Lock));
  262. //
  263. // See if there are any ProtocolCB's available on the free list.
  264. // If there are not we will need to allocate one.
  265. //
  266. // if (FreeProtocolCBList.ulCount == 0) {
  267. //
  268. // Create ProtocolCB
  269. //
  270. NdisWanCreateProtocolCB(ProtocolCB,
  271. usProtocolType,
  272. usBindingNameLength,
  273. BindingName,
  274. ulBufferLength,
  275. Buffer);
  276. // } else {
  277. //
  278. // Get the ProtocolCB from the free list
  279. //
  280. // *ProtocolCB = (PPROTOCOLCB)RemoveHeadList(&(FreeProtocolCBList.List));
  281. // FreeProtocolCBList.ulCount--;
  282. // }
  283. // NdisReleaseSpinLock(&(FreeProtocolCBList.Lock));
  284. // if (*ProtocolCB != NULL) {
  285. // NdisWanInitProtocolCB(*ProtocolCB,
  286. // ulBufferLength,
  287. // Buffer,
  288. // usProtocolType);
  289. // }
  290. }
  291. NDIS_STATUS
  292. NdisWanCreateProtocolCB(
  293. OUT PPROTOCOLCB *ProtocolCB,
  294. IN USHORT usProtocolType,
  295. IN USHORT usBindingNameLength,
  296. IN PWSTR BindingName,
  297. IN ULONG ulBufferLength,
  298. IN PUCHAR Buffer
  299. )
  300. /*++
  301. Routine Name:
  302. Routine Description:
  303. Arguments:
  304. Return Values:
  305. NDIS_STATUS_SUCCESS - ProtocolCB was allocated and initialized
  306. NDIS_STATUS_RESOURCES - Error allocating memory for ProtocolCB
  307. --*/
  308. {
  309. PPROTOCOLCB LocalProtocolCB = NULL;
  310. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  311. ULONG ulAllocationSize = sizeof(PROTOCOLCB) + ulBufferLength;
  312. PUCHAR AllocatedMemory;
  313. ULONG i;
  314. NdisWanAllocateMemory(&AllocatedMemory, ulAllocationSize);
  315. if (AllocatedMemory != NULL) {
  316. LocalProtocolCB = (PPROTOCOLCB)AllocatedMemory;
  317. LocalProtocolCB->ulAllocationSize = ulAllocationSize;
  318. AllocatedMemory += sizeof(PROTOCOLCB);
  319. LocalProtocolCB->LineUpInfo = AllocatedMemory;
  320. #ifdef BANDWIDTH_ON_DEMAND
  321. //
  322. // Initialize the sample table
  323. //
  324. LocalProtocolCB->SampleTable.ulSampleArraySize = SAMPLE_ARRAY_SIZE;
  325. NdisWanInitWanTime(&LocalProtocolCB->SampleTable.SampleRate, ONE_HUNDRED_MILS);
  326. NdisWanInitWanTime(&LocalProtocolCB->SampleTable.SamplePeriod, ONE_SECOND);
  327. #endif
  328. //
  329. // Copy the bindingname
  330. //
  331. NdisWanStringToNdisString(&LocalProtocolCB->BindingName, BindingName);
  332. //
  333. // Copy over the protocol info
  334. //
  335. LocalProtocolCB->ulLineUpInfoLength = ulBufferLength;
  336. NdisMoveMemory(LocalProtocolCB->LineUpInfo,
  337. Buffer,
  338. ulBufferLength);
  339. //
  340. // Setup the protocol type
  341. //
  342. LocalProtocolCB->usProtocolType = usProtocolType;
  343. //
  344. // Get the PPP protocol value for this protocol type
  345. //
  346. LocalProtocolCB->usPPPProtocolID = GetPPP_ProtocolID(usProtocolType, PROTOCOL_TYPE);
  347. switch (usProtocolType) {
  348. case PROTOCOL_IP:
  349. LocalProtocolCB->NonIdleDetectFunc = IpIsDataFrame;
  350. break;
  351. case PROTOCOL_IPX:
  352. LocalProtocolCB->NonIdleDetectFunc = IpxIsDataFrame;
  353. break;
  354. case PROTOCOL_NBF:
  355. LocalProtocolCB->NonIdleDetectFunc = NbfIsDataFrame;
  356. break;
  357. default:
  358. LocalProtocolCB->NonIdleDetectFunc = NULL;
  359. break;
  360. }
  361. NdisWanGetSystemTime(&LocalProtocolCB->LastRecvNonIdleData);
  362. #ifdef BANDWIDTH_ON_DEMAND
  363. LocalProtocolCB->SampleTable.ulFirstIndex =
  364. LocalProtocolCB->SampleTable.ulCurrentIndex = 0;
  365. NdisZeroMemory(&LocalProtocolCB->SampleTable.SampleArray[0],
  366. sizeof(SEND_SAMPLE) * SAMPLE_ARRAY_SIZE);
  367. #endif // end BANDWIDTH_ON_DEMAND
  368. } else {
  369. Status = NDIS_STATUS_RESOURCES;
  370. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_MEMORY, ("Error allocating memory for ProtocolCB, ulAllocationSize: %d",
  371. ulAllocationSize));
  372. }
  373. *ProtocolCB = LocalProtocolCB;
  374. return (Status);
  375. }
  376. //VOID
  377. //NdisWanInitProtocolCB(
  378. // IN PPROTOCOLCB ProtocolCB,
  379. // IN ULONG ulBufferLength,
  380. // IN PUCHAR Buffer,
  381. // IN USHORT usProtocolType
  382. // )
  383. ///*++
  384. //
  385. //Routine Name:
  386. //
  387. //Routine Description:
  388. //
  389. //Arguments:
  390. //
  391. //Return Values:
  392. //
  393. //--*/
  394. //{
  395. // //
  396. // // Copy over the protocol info
  397. // //
  398. // ProtocolCB->ulLineUpInfoLength = ulBufferLength;
  399. // NdisMoveMemory(ProtocolCB->LineUpInfo,
  400. // Buffer,
  401. // ulBufferLength);
  402. //
  403. // //
  404. // // Setup the protocol type
  405. // //
  406. // ProtocolCB->usProtocolType = usProtocolType;
  407. //
  408. // //
  409. // // Get the PPP protocol value for this protocol type
  410. // //
  411. // ProtocolCB->usPPPProtocolID = GetPPP_ProtocolID(usProtocolType, PROTOCOL_TYPE);
  412. //
  413. // ProtocolCB->SampleTable.ulFirstIndex =
  414. // ProtocolCB->SampleTable.ulCurrentIndex = 0;
  415. // NdisZeroMemory(&ProtocolCB->SampleTable.SampleArray[0],
  416. // sizeof(SEND_SAMPLE) * SAMPLE_ARRAY_SIZE);
  417. //
  418. //}
  419. VOID
  420. NdisWanReturnProtocolCB(
  421. IN PPROTOCOLCB ProtocolCB
  422. )
  423. /*++
  424. Routine Name:
  425. Routine Description:
  426. Arguments:
  427. Return Values:
  428. --*/
  429. {
  430. // NdisAcquireSpinLock(&(FreeProtocolCBList.Lock));
  431. //
  432. // if (FreeProtocolCBList.ulCount > FreeProtocolCBList.ulMaxCount) {
  433. NdisWanDestroyProtocolCB(ProtocolCB);
  434. // } else {
  435. //
  436. // InsertTailGlobalList(FreeProtocolCBList, &(ProtocolCB->Linkage));
  437. //
  438. // FreeProtocolCBList.ulCount++;
  439. //
  440. // }
  441. //
  442. // NdisReleaseSpinLock(&(FreeProtocolCBList.Lock));
  443. }
  444. VOID
  445. NdisWanDestroyProtocolCB(
  446. IN PPROTOCOLCB ProtocolCB
  447. )
  448. /*++
  449. Routine Name:
  450. Routine Description:
  451. Arguments:
  452. Return Values:
  453. --*/
  454. {
  455. ASSERT(ProtocolCB->HeadNdisPacketQueue == NULL);
  456. ASSERT(ProtocolCB->TailNdisPacketQueue == NULL);
  457. if (ProtocolCB->DeviceName.Length != 0) {
  458. NdisWanFreeNdisString(&ProtocolCB->DeviceName);
  459. }
  460. if (ProtocolCB->BindingName.Length != 0) {
  461. NdisWanFreeNdisString(&ProtocolCB->BindingName);
  462. }
  463. NdisWanFreeMemory(ProtocolCB);
  464. }
  465. VOID
  466. NdisWanGetLinkCB(
  467. OUT PLINKCB *LinkCB,
  468. IN PWAN_ADAPTERCB WanAdapterCB,
  469. IN ULONG SendWindow
  470. )
  471. /*++
  472. Routine Name:
  473. NdisWanGetLinkCB
  474. Routine Description:
  475. This function returns a pointer to a LinkCB. The LinkCB is either retrieved
  476. from the WanAdapters free list or, if this list is empty, it is allocated.
  477. Arguments:
  478. *LinkCB - Pointer to the location to store the pointer to the LinkCB
  479. WanAdapterCB - Pointer to the WanAdapter control block that this Link is
  480. associated with
  481. Return Values:
  482. None
  483. --*/
  484. {
  485. //
  486. // See if we have any free LinkCB's hanging around
  487. // if not we will allocate one
  488. //
  489. NdisAcquireSpinLock(&(WanAdapterCB->Lock));
  490. if (IsListEmpty(&(WanAdapterCB->FreeLinkCBList))) {
  491. //
  492. // Create LinkCB
  493. //
  494. NdisWanCreateLinkCB(LinkCB);
  495. } else {
  496. //
  497. // Get the LinkCB from the free list
  498. //
  499. *LinkCB = (PLINKCB)RemoveHeadList(&(WanAdapterCB->FreeLinkCBList));
  500. }
  501. NdisReleaseSpinLock(&(WanAdapterCB->Lock));
  502. //
  503. // Set the new link state
  504. //
  505. NdisWanInitLinkCB(LinkCB, WanAdapterCB, SendWindow);
  506. }
  507. NDIS_STATUS
  508. NdisWanCreateLinkCB(
  509. OUT PLINKCB *LinkCB
  510. )
  511. /*++
  512. Routine Name:
  513. Routine Description:
  514. Arguments:
  515. Return Values:
  516. --*/
  517. {
  518. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  519. PLINKCB LocalLinkCB = NULL;
  520. ULONG ulAllocationSize, n;
  521. PUCHAR AllocatedMemory = NULL;
  522. //
  523. // Figure out how much we need to allocate
  524. //
  525. ulAllocationSize = sizeof(LINKCB);
  526. //
  527. // Allocate the memory for the LinkCB and it's WAN PACKETS
  528. //
  529. NdisWanAllocateMemory(&AllocatedMemory, ulAllocationSize);
  530. if (AllocatedMemory != NULL) {
  531. //
  532. // Initialize the control block
  533. //
  534. LocalLinkCB = (PLINKCB)AllocatedMemory;
  535. LocalLinkCB->ulAllocationSize = ulAllocationSize;
  536. InitializeListHead(&LocalLinkCB->WanPacketPool);
  537. NdisWanInitializeSyncEvent(&LocalLinkCB->OutstandingFramesEvent);
  538. } else {
  539. Status = NDIS_STATUS_RESOURCES;
  540. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_MEMORY, ("Error allocating memory for LinkCB, AllocationSize: %d",
  541. ulAllocationSize));
  542. }
  543. *LinkCB = LocalLinkCB;
  544. return (Status);
  545. }
  546. VOID
  547. NdisWanInitLinkCB(
  548. IN PLINKCB *LinkCB,
  549. IN PWAN_ADAPTERCB WanAdapterCB,
  550. IN ULONG SendWindow
  551. )
  552. /*++
  553. Routine Name:
  554. Routine Description:
  555. Arguments:
  556. Return Values:
  557. --*/
  558. {
  559. PLINKCB LocalLinkCB = *LinkCB;
  560. if (LocalLinkCB == NULL) {
  561. return;
  562. }
  563. LocalLinkCB->hLinkContext = NULL;
  564. LocalLinkCB->ulReferenceCount = 0;
  565. LocalLinkCB->State = LINK_UP;
  566. LocalLinkCB->WanAdapterCB = WanAdapterCB;
  567. LocalLinkCB->OutstandingFrames = 0;
  568. LocalLinkCB->LastRecvSeqNumber = 0;
  569. LocalLinkCB->ulBandwidth = 100;
  570. LocalLinkCB->PacketMemory = NULL;
  571. LocalLinkCB->PacketMemorySize = 0;
  572. LocalLinkCB->RecvFragmentsLost = 0;
  573. NdisZeroMemory(&LocalLinkCB->LinkInfo, sizeof(WAN_LINK_INFO));
  574. LocalLinkCB->LinkInfo.HeaderPadding = WanAdapterCB->WanInfo.HeaderPadding;
  575. LocalLinkCB->LinkInfo.TailPadding = WanAdapterCB->WanInfo.TailPadding;
  576. LocalLinkCB->LinkInfo.SendACCM =
  577. LocalLinkCB->LinkInfo.RecvACCM = WanAdapterCB->WanInfo.DesiredACCM;
  578. NdisZeroMemory(&LocalLinkCB->LinkStats, sizeof(WAN_STATS));
  579. if (NdisWanAllocateSendResources(LocalLinkCB, SendWindow) != NDIS_STATUS_SUCCESS) {
  580. //
  581. // return the linkcb
  582. //
  583. NdisWanReturnLinkCB(LocalLinkCB);
  584. *LinkCB = NULL;
  585. }
  586. }
  587. VOID
  588. NdisWanReturnLinkCB(
  589. PLINKCB LinkCB
  590. )
  591. /*++
  592. Routine Name:
  593. Routine Description:
  594. Arguments:
  595. Return Values:
  596. --*/
  597. {
  598. PWAN_ADAPTERCB WanAdapterCB = LinkCB->WanAdapterCB;
  599. NdisAcquireSpinLock(&(WanAdapterCB->Lock));
  600. //
  601. // Free the wanpacket pool
  602. //
  603. NdisWanFreeSendResources(LinkCB);
  604. InsertTailList(&WanAdapterCB->FreeLinkCBList, &LinkCB->Linkage);
  605. NdisReleaseSpinLock(&(WanAdapterCB->Lock));
  606. }
  607. VOID
  608. NdisWanDestroyLinkCB(
  609. IN PLINKCB LinkCB
  610. )
  611. /*++
  612. Routine Name:
  613. Routine Description:
  614. Arguments:
  615. Return Values:
  616. --*/
  617. {
  618. PWAN_ADAPTERCB WanAdapterCB = LinkCB->WanAdapterCB;
  619. //
  620. // Free the memory allocated for the control block
  621. //
  622. NdisWanFreeMemory(LinkCB);
  623. }
  624. NDIS_STATUS
  625. NdisWanAllocateSendResources(
  626. IN PLINKCB LinkCB,
  627. IN ULONG SendWindow
  628. )
  629. /*++
  630. Routine Name:
  631. NdisWanAllocateSendResources
  632. Routine Description:
  633. Allocates all resources (SendDescriptors, WanPackets, ...)
  634. required for sending data. Should be called at line up time.
  635. Arguments:
  636. LinkCB - Pointer to the linkcb that the send resources will be attached to.
  637. SendWindow - Maximum number of sends that this link can handle
  638. Return Values:
  639. NDIS_STATUS_SUCCESS
  640. NDIS_STATUS_RESOURCES
  641. --*/
  642. {
  643. PWAN_ADAPTERCB WanAdapterCB = LinkCB->WanAdapterCB;
  644. ULONG BufferSize, PacketMemorySize, NumberOfPackets, n;
  645. PUCHAR PacketMemory = NULL;
  646. PNDIS_WAN_PACKET WanPacket;
  647. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  648. SendWindow = (SendWindow == 0) ?
  649. WanAdapterCB->WanInfo.MaxTransmit : SendWindow;
  650. SendWindow = (SendWindow == 0) ? 1 : SendWindow;
  651. //
  652. // The number of packets that we will create is the send
  653. // window of this WAN Miniport + 1
  654. //
  655. NumberOfPackets = SendWindow + 1;
  656. //
  657. // The size of the buffer that we create is
  658. //
  659. BufferSize = WanAdapterCB->WanInfo.MaxFrameSize +
  660. WanAdapterCB->WanInfo.HeaderPadding +
  661. WanAdapterCB->WanInfo.TailPadding +
  662. 40 + sizeof(PVOID);
  663. //
  664. // We assume compression is always on so we pad out 12%
  665. // incase the compressor expands. I don't know where the
  666. // 12% figure comes from.
  667. //
  668. BufferSize += (WanAdapterCB->WanInfo.MaxFrameSize + 7) / 8;
  669. //
  670. // Make sure that the buffer is dword aligned.
  671. //
  672. BufferSize &= ~(sizeof(PVOID) - 1);
  673. PacketMemorySize = (BufferSize + sizeof(NDIS_WAN_PACKET)) * NumberOfPackets;
  674. //
  675. // Allocate the memory for the wan packet buffer pool
  676. //
  677. NdisAllocateMemory(&PacketMemory,
  678. PacketMemorySize,
  679. WanAdapterCB->WanInfo.MemoryFlags,
  680. WanAdapterCB->WanInfo.HighestAcceptableAddress);
  681. if (PacketMemory != NULL) {
  682. LinkCB->PacketMemory = PacketMemory;
  683. LinkCB->PacketMemorySize = PacketMemorySize;
  684. LinkCB->BufferSize = BufferSize;
  685. for (n = 0; n < NumberOfPackets; n++) {
  686. WanPacket = (PNDIS_WAN_PACKET)PacketMemory;
  687. PacketMemory += sizeof(NDIS_WAN_PACKET);
  688. InsertTailList(&LinkCB->WanPacketPool, &WanPacket->WanPacketQueue);
  689. LinkCB->ulWanPacketCount++;
  690. }
  691. //
  692. // Walk the list of newly created packets and fix up startbuffer and
  693. // endbuffer pointers.
  694. //
  695. for (WanPacket = (PNDIS_WAN_PACKET)LinkCB->WanPacketPool.Flink;
  696. (PVOID)WanPacket != (PVOID)&LinkCB->WanPacketPool;
  697. WanPacket = (PNDIS_WAN_PACKET)WanPacket->WanPacketQueue.Flink) {
  698. //
  699. // Point to the begining of the data.
  700. //
  701. WanPacket->StartBuffer = PacketMemory;
  702. PacketMemory += BufferSize;
  703. //
  704. // The 5 bytes give us a short buffer at the end and will
  705. // keep a WAN Miniport from alignment checking if it uses
  706. // this pointer to 'back copy'
  707. //
  708. WanPacket->EndBuffer = PacketMemory - 5;
  709. }
  710. } else {
  711. Status = NDIS_STATUS_RESOURCES;
  712. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_MEMORY, ("Error allocating memory for BufferPool, AllocationSize: %d",
  713. PacketMemorySize));
  714. }
  715. return (Status);
  716. }
  717. VOID
  718. NdisWanFreeSendResources(
  719. IN PLINKCB LinkCB
  720. )
  721. /*++
  722. Routine Name:
  723. NdisWanFreeSendResources
  724. Routine Description:
  725. This routine removes the WanPackets from this linkcb's send list
  726. and free's the memory allocated for these packets. Should be called
  727. at linedown time after all outstanding sends have been accounted for.
  728. Arguments:
  729. LinkCB - Pointer to the linkcb that the resources are being freed from.
  730. Return Values:
  731. None
  732. --*/
  733. {
  734. PNDIS_WAN_PACKET WanPacket;
  735. PUCHAR PacketMemory;
  736. ULONG PacketMemorySize, Flags;
  737. PacketMemory = LinkCB->PacketMemory;
  738. PacketMemorySize = LinkCB->PacketMemorySize;
  739. Flags = LinkCB->WanAdapterCB->WanInfo.MemoryFlags;
  740. //
  741. // Remove the packets from the wan packet pool
  742. //
  743. while (!IsListEmpty(&LinkCB->WanPacketPool)) {
  744. RemoveHeadList(&LinkCB->WanPacketPool);
  745. LinkCB->ulWanPacketCount--;
  746. }
  747. //
  748. // Free the block of memory allocated for this send
  749. //
  750. if (PacketMemory != NULL) {
  751. NdisFreeMemory(PacketMemory, PacketMemorySize, Flags);
  752. }
  753. }
  754. VOID
  755. NdisWanGetBundleCB(
  756. OUT PBUNDLECB *BundleCB
  757. )
  758. /*++
  759. Routine Name:
  760. Routine Description:
  761. Arguments:
  762. Return Values:
  763. --*/
  764. {
  765. NdisAcquireSpinLock(&(FreeBundleCBList.Lock));
  766. //
  767. // See if there are any BundleCB's available on the free list.
  768. // If there are not we will need to allocate one.
  769. //
  770. if (FreeBundleCBList.ulCount == 0) {
  771. //
  772. // Create BundleCB
  773. //
  774. NdisWanCreateBundleCB(BundleCB);
  775. } else {
  776. //
  777. // Get the BundleCB from the free list
  778. //
  779. *BundleCB = (PBUNDLECB)RemoveHeadList(&(FreeBundleCBList.List));
  780. FreeBundleCBList.ulCount--;
  781. }
  782. NdisReleaseSpinLock(&(FreeBundleCBList.Lock));
  783. if (*BundleCB != NULL) {
  784. NdisWanInitBundleCB(*BundleCB);
  785. }
  786. }
  787. NDIS_STATUS
  788. NdisWanCreateBundleCB(
  789. OUT PBUNDLECB *BundleCB
  790. )
  791. /*++
  792. Routine Name:
  793. Routine Description:
  794. Arguments:
  795. Return Values:
  796. --*/
  797. {
  798. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  799. PBUNDLECB LocalBundleCB = NULL;
  800. ULONG ulAllocationSize;
  801. PUCHAR AllocatedMemory = NULL;
  802. //
  803. // Allocation size is the size of the control block plus the size
  804. // of a table of pointers to protocolcb's that might be routed to
  805. // this bundle.
  806. //
  807. ulAllocationSize = sizeof(BUNDLECB) +
  808. sizeof(PROTOCOLCB) +
  809. (sizeof(PPROTOCOLCB) * MAX_PROTOCOLS);
  810. NdisWanAllocateMemory(&AllocatedMemory, ulAllocationSize);
  811. if (AllocatedMemory != NULL) {
  812. PWSTR IOName = L"I/O ProtocolCB";
  813. PPROTOCOLCB ProtocolCB;
  814. //
  815. // This is the bundlecb
  816. //
  817. LocalBundleCB = (PBUNDLECB)AllocatedMemory;
  818. LocalBundleCB->ulAllocationSize = ulAllocationSize;
  819. AllocatedMemory += sizeof(BUNDLECB);
  820. //
  821. // This is the memory used for the I/O protocolcb
  822. //
  823. ProtocolCB = (PPROTOCOLCB)AllocatedMemory;
  824. AllocatedMemory += sizeof(PROTOCOLCB);
  825. //
  826. // This is the protocolcb table
  827. //
  828. (PUCHAR)LocalBundleCB->ProtocolCBTable = (PUCHAR)AllocatedMemory;
  829. //
  830. // Initialize the BundleCB
  831. //
  832. NdisAllocateSpinLock(&LocalBundleCB->Lock);
  833. InitializeListHead(&LocalBundleCB->LinkCBList);
  834. InitializeListHead(&LocalBundleCB->SendPacketQueue);
  835. InitializeListHead(&LocalBundleCB->RecvDescPool);
  836. InitializeListHead(&LocalBundleCB->RecvDescAssemblyList);
  837. InitializeListHead(&LocalBundleCB->ProtocolCBList);
  838. NdisWanInitializeSyncEvent(&LocalBundleCB->OutstandingFramesEvent);
  839. NdisWanInitializeSyncEvent(&LocalBundleCB->IndicationEvent);
  840. #ifdef BANDWIDTH_ON_DEMAND
  841. LocalBundleCB->UpperBonDInfo.SampleTable.ulSampleArraySize = SAMPLE_ARRAY_SIZE;
  842. LocalBundleCB->LowerBonDInfo.SampleTable.ulSampleArraySize = SAMPLE_ARRAY_SIZE;
  843. #endif // end of BANDWIDTH_ON_DEMAND
  844. //
  845. // Add the protocolcb to the bundle's table and list
  846. //
  847. ProtocolCB->hProtocolHandle = 0;
  848. ProtocolCB->BundleCB = LocalBundleCB;
  849. ProtocolCB->HeadNdisPacketQueue =
  850. ProtocolCB->TailNdisPacketQueue = NULL;
  851. NdisWanStringToNdisString(&ProtocolCB->DeviceName, IOName);
  852. #ifdef BANDWIDTH_ON_DEMAND
  853. ProtocolCB->SampleTable.ulSampleArraySize = SAMPLE_ARRAY_SIZE;
  854. NdisWanInitWanTime(&ProtocolCB->SampleTable.SampleRate, ONE_HUNDRED_MILS);
  855. NdisWanInitWanTime(&ProtocolCB->SampleTable.SamplePeriod, ONE_SECOND);
  856. #endif
  857. LocalBundleCB->ProtocolCBTable[0] = ProtocolCB;
  858. InsertHeadList(&LocalBundleCB->ProtocolCBList, &ProtocolCB->Linkage);
  859. LocalBundleCB->ulNumberOfRoutes = 1;
  860. } else {
  861. Status = NDIS_STATUS_RESOURCES;
  862. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_MEMORY, ("Error allocating memory for BundleCB, AllocationSize: %d",
  863. ulAllocationSize));
  864. }
  865. *BundleCB = LocalBundleCB;
  866. return (Status);
  867. }
  868. VOID
  869. NdisWanInitBundleCB(
  870. PBUNDLECB BundleCB
  871. )
  872. /*++
  873. Routine Name:
  874. Routine Description:
  875. Arguments:
  876. Return Values:
  877. --*/
  878. {
  879. PPROTOCOLCB ProtocolCB = BundleCB->ProtocolCBTable[0];
  880. PRECV_DESC RecvDescHole;
  881. #ifdef BANDWIDTH_ON_DEMAND
  882. PSAMPLE_TABLE SampleTable;
  883. PBOND_INFO BonDInfo;
  884. #endif // end of BANDWIDTH_ON_DEMAND
  885. BundleCB->State = BUNDLE_UP;
  886. NdisZeroMemory(&BundleCB->FramingInfo, sizeof(BUNDLE_FRAME_INFO));
  887. BundleCB->NextLinkToXmit = NULL;
  888. BundleCB->SendingLinks = 0;
  889. BundleCB->SendSeqNumber = 0;
  890. BundleCB->SendSeqMask = 0;
  891. BundleCB->SendSeqTest = 0;
  892. BundleCB->Flags = 0;
  893. NdisZeroMemory(&BundleCB->LineUpInfo, sizeof(BUNDLE_LINE_UP));
  894. BundleCB->LineUpInfo.ulMaximumTotalSize = MAX_TOTAL_SIZE;
  895. //
  896. // Init the recv hole desc
  897. //
  898. BundleCB->RecvSeqMask = 0;
  899. BundleCB->RecvSeqTest = 0;
  900. BundleCB->RecvFragmentsLost = 0;
  901. BundleCB->MinReceivedSeqNumber = 0;
  902. ASSERT(BundleCB->RecvDescAssemblyList.Flink == BundleCB->RecvDescAssemblyList.Blink);
  903. NdisWanGetRecvDesc(BundleCB, &RecvDescHole);
  904. RecvDescHole->SequenceNumber = 0;
  905. RecvDescHole->Flags = 1;
  906. BundleCB->RecvDescHole = RecvDescHole;
  907. InsertHeadList(&BundleCB->RecvDescAssemblyList, &RecvDescHole->Linkage);
  908. NdisWanGetSystemTime(&BundleCB->LastRecvNonIdleData);
  909. ProtocolCB->SendMaskBit = IO_SEND_MASK_BIT;
  910. NdisZeroMemory(&BundleCB->SendVJInfo, sizeof(VJ_INFO));
  911. NdisZeroMemory(&BundleCB->RecvVJInfo, sizeof(VJ_INFO));
  912. NdisZeroMemory(&BundleCB->SendCompInfo, sizeof(COMPRESS_INFO));
  913. NdisZeroMemory(&BundleCB->RecvCompInfo, sizeof(COMPRESS_INFO));
  914. NdisZeroMemory(&BundleCB->SendEncryptInfo,sizeof(ENCRYPTION_INFO));
  915. NdisZeroMemory(&BundleCB->RecvEncryptInfo,sizeof(ENCRYPTION_INFO));
  916. /*
  917. #ifdef ENCRYPT_128BIT
  918. BundleCB->SendEncryptInfo.SessionKeyLength =
  919. BundleCB->RecvEncryptInfo.SessionKeyLength = 16;
  920. BundleCB->SendCompInfo.MSCompType =
  921. BundleCB->RecvCompInfo.MSCompType = NDISWAN_ENCRYPTION |
  922. NDISWAN_40_ENCRYPTION |
  923. NDISWAN_128_ENCRYPTION |
  924. NDISWAN_COMPRESSION;
  925. #else
  926. BundleCB->SendEncryptInfo.SessionKeyLength =
  927. BundleCB->RecvEncryptInfo.SessionKeyLength = 8;
  928. BundleCB->SendCompInfo.MSCompType =
  929. BundleCB->RecvCompInfo.MSCompType = NDISWAN_ENCRYPTION |
  930. NDISWAN_40_ENCRYPTION |
  931. NDISWAN_COMPRESSION;
  932. #endif
  933. */
  934. BundleCB->SendCompInfo.CompType =
  935. BundleCB->RecvCompInfo.CompType = COMPTYPE_NONE;
  936. ProtocolCB->usProtocolType = PROTOCOL_PRIVATE_IO;
  937. ProtocolCB->usPPPProtocolID = PPP_PROTOCOL_PRIVATE_IO;
  938. BundleCB->SendMask = IO_SEND_MASK_BIT;
  939. #ifdef BANDWIDTH_ON_DEMAND
  940. ProtocolCB->usPriority = 100;
  941. ProtocolCB->ulByteQuota = 0xFFFFFFFF;
  942. ProtocolCB->SampleTable.ulFirstIndex =
  943. ProtocolCB->SampleTable.ulCurrentIndex = 0;
  944. NdisZeroMemory(&ProtocolCB->SampleTable.SampleArray[0],
  945. sizeof(SEND_SAMPLE) * SAMPLE_ARRAY_SIZE);
  946. BonDInfo = &BundleCB->UpperBonDInfo;
  947. BonDInfo->ulBytesThreshold = 0;
  948. BonDInfo->State = BonDIdle;
  949. BonDInfo->usPercentBandwidth = 0xFFFF;
  950. BonDInfo->ulSecondsInSamplePeriod = 0;
  951. NdisWanInitWanTime(&BonDInfo->StartTime, 0);
  952. SampleTable = &BonDInfo->SampleTable;
  953. NdisWanInitWanTime(&SampleTable->SampleRate, 0);
  954. NdisWanInitWanTime(&SampleTable->SamplePeriod, 0);
  955. SampleTable->ulFirstIndex =
  956. SampleTable->ulCurrentIndex =
  957. SampleTable->ulCurrentSampleByteCount = 0;
  958. NdisZeroMemory(&SampleTable->SampleArray[0],
  959. sizeof(SEND_SAMPLE) * SAMPLE_ARRAY_SIZE);
  960. BonDInfo = &BundleCB->LowerBonDInfo;
  961. BonDInfo->ulBytesThreshold = 0;
  962. BonDInfo->State = BonDIdle;
  963. BonDInfo->usPercentBandwidth = 0xFFFF;
  964. BonDInfo->ulSecondsInSamplePeriod = 0;
  965. NdisWanInitWanTime(&BonDInfo->StartTime, 0);
  966. SampleTable = &BonDInfo->SampleTable;
  967. NdisWanInitWanTime(&SampleTable->SampleRate, 0);
  968. NdisWanInitWanTime(&SampleTable->SamplePeriod, 0);
  969. SampleTable->ulFirstIndex =
  970. SampleTable->ulCurrentIndex =
  971. SampleTable->ulCurrentSampleByteCount = 0;
  972. NdisZeroMemory(&SampleTable->SampleArray[0],
  973. sizeof(SEND_SAMPLE) * SAMPLE_ARRAY_SIZE);
  974. #endif // end of BANDWIDTH_ON_DEMAND
  975. BundleCB->ulNameLength = 0;
  976. NdisZeroMemory(&BundleCB->Name, MAX_NAME_LENGTH);
  977. NdisZeroMemory(&BundleCB->BundleStats, sizeof(WAN_STATS));
  978. }
  979. VOID
  980. NdisWanReturnBundleCB(
  981. IN PBUNDLECB BundleCB
  982. )
  983. /*++
  984. Routine Name:
  985. Routine Description:
  986. Arguments:
  987. Return Values:
  988. --*/
  989. {
  990. sl_compress_terminate(&BundleCB->VJCompress);
  991. WanDeallocateCCP(BundleCB);
  992. FlushRecvDescAssemblyList(BundleCB);
  993. FreeRecvDescFreeList(BundleCB);
  994. NdisAcquireSpinLock(&(FreeBundleCBList.Lock));
  995. if (FreeBundleCBList.ulCount >= FreeBundleCBList.ulMaxCount) {
  996. NdisWanDestroyBundleCB(BundleCB);
  997. } else {
  998. InsertTailList(&FreeBundleCBList.List, &(BundleCB->Linkage));
  999. FreeBundleCBList.ulCount++;
  1000. }
  1001. NdisReleaseSpinLock(&(FreeBundleCBList.Lock));
  1002. }
  1003. VOID
  1004. NdisWanDestroyBundleCB(
  1005. IN PBUNDLECB BundleCB
  1006. )
  1007. /*++
  1008. Routine Name:
  1009. Routine Description:
  1010. Arguments:
  1011. Return Values:
  1012. --*/
  1013. {
  1014. PPROTOCOLCB ProtocolCB = BundleCB->ProtocolCBTable[0];
  1015. NdisFreeSpinLock(&BundleCB->Lock);
  1016. NdisWanFreeNdisString(&ProtocolCB->DeviceName);
  1017. NdisWanFreeMemory(BundleCB);
  1018. }
  1019. NDIS_STATUS
  1020. NdisWanCreatePPPProtocolTable(
  1021. VOID
  1022. )
  1023. /*++
  1024. Routine Name:
  1025. Routine Description:
  1026. Arguments:
  1027. Return Values:
  1028. --*/
  1029. {
  1030. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  1031. ULONG ulAllocationSize = 0;
  1032. PUCHAR AllocatedMemory;
  1033. //
  1034. // Allocate ProtocolLookupTable. This table is used to match protocol values
  1035. // with their corresponding PPP Protocol values. The table size is set to
  1036. // MAX_PROTOCOLS.
  1037. //
  1038. ulAllocationSize = sizeof(PPP_PROTOCOL_TABLE) +
  1039. (sizeof(USHORT) * MAX_PROTOCOLS) +
  1040. (sizeof(USHORT) * MAX_PROTOCOLS);
  1041. NdisWanAllocateMemory(&AllocatedMemory, ulAllocationSize);
  1042. if (AllocatedMemory == NULL) {
  1043. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_MEMORY,
  1044. ("Failed allocating memory for ProtocolLookupTable! TableSize: %d",
  1045. ulAllocationSize));
  1046. return (NDIS_STATUS_RESOURCES);
  1047. }
  1048. PPP_ProtocolTable = (PPPP_PROTOCOL_TABLE)AllocatedMemory;
  1049. //
  1050. // Save the allocation size
  1051. //
  1052. PPP_ProtocolTable->ulAllocationSize = ulAllocationSize;
  1053. //
  1054. // Store the array size. This should be read from the registry
  1055. //
  1056. PPP_ProtocolTable->ulArraySize = MAX_PROTOCOLS;
  1057. NdisAllocateSpinLock(&PPP_ProtocolTable->Lock);
  1058. //
  1059. // Setup the pointer to the ProtocolValue array
  1060. //
  1061. AllocatedMemory += sizeof(PPP_PROTOCOL_TABLE);
  1062. PPP_ProtocolTable->ProtocolID = (PUSHORT)(AllocatedMemory);
  1063. //
  1064. // Setup the pointer to the PPPProtocolValue array
  1065. //
  1066. AllocatedMemory += (sizeof(USHORT) * MAX_PROTOCOLS);
  1067. PPP_ProtocolTable->PPPProtocolID = (PUSHORT)(AllocatedMemory);
  1068. //
  1069. // Insert default values for Netbuei, IP, IPX
  1070. //
  1071. InsertPPP_ProtocolID(PROTOCOL_PRIVATE_IO, PROTOCOL_TYPE);
  1072. InsertPPP_ProtocolID(PPP_PROTOCOL_PRIVATE_IO, PPP_TYPE);
  1073. InsertPPP_ProtocolID(PROTOCOL_IP, PROTOCOL_TYPE);
  1074. InsertPPP_ProtocolID(PPP_PROTOCOL_IP, PPP_TYPE);
  1075. InsertPPP_ProtocolID(PROTOCOL_IPX, PROTOCOL_TYPE);
  1076. InsertPPP_ProtocolID(PPP_PROTOCOL_IPX, PPP_TYPE);
  1077. InsertPPP_ProtocolID(PROTOCOL_NBF, PROTOCOL_TYPE);
  1078. InsertPPP_ProtocolID(PPP_PROTOCOL_NBF, PPP_TYPE);
  1079. return (Status);
  1080. }
  1081. VOID
  1082. NdisWanDestroyPPPProtocolTable(
  1083. VOID
  1084. )
  1085. /*++
  1086. Routine Name:
  1087. Routine Description:
  1088. Arguments:
  1089. Return Values:
  1090. --*/
  1091. {
  1092. NdisFreeSpinLock(&PPP_ProtocolTable->Lock);
  1093. NdisWanFreeMemory(PPP_ProtocolTable);
  1094. }
  1095. NDIS_STATUS
  1096. NdisWanCreateConnectionTable(
  1097. ULONG TableSize
  1098. )
  1099. /*++
  1100. Routine Name:
  1101. Routine Description:
  1102. Arguments:
  1103. Return Values:
  1104. --*/
  1105. {
  1106. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  1107. ULONG ulAllocationSize = 0;
  1108. PUCHAR AllocatedMemory;
  1109. PCONNECTION_TABLE NewTable;
  1110. //
  1111. // Since we skip the first place in the tables we increase the
  1112. // size by one.
  1113. //
  1114. TableSize += 1;
  1115. //
  1116. // Allocate the Bundle and Link Arrays based on the number of possible connections
  1117. // that we have in the system. This should be grown if we get called
  1118. // to reinitialize and gain new ports.
  1119. //
  1120. ulAllocationSize = sizeof(CONNECTION_TABLE) +
  1121. (sizeof(PBUNDLECB) * TableSize) +
  1122. (sizeof(PLINKCB) * TableSize);
  1123. NdisWanAllocateMemory(&AllocatedMemory, ulAllocationSize);
  1124. if (AllocatedMemory == NULL) {
  1125. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_MEMORY,
  1126. ("Failed allocating memory for ConnectionTable! Size: %d, Links: %d",
  1127. ulAllocationSize, TableSize));
  1128. return (NDIS_STATUS_RESOURCES);
  1129. }
  1130. NewTable = (PCONNECTION_TABLE)AllocatedMemory;
  1131. NdisAllocateSpinLock(&NewTable->Lock);
  1132. //
  1133. // This is the amount of memory we allocated
  1134. //
  1135. NewTable->ulAllocationSize = ulAllocationSize;
  1136. NewTable->ulArraySize = TableSize;
  1137. InitializeListHead(&NewTable->BundleList);
  1138. //
  1139. // Setup pointer to the linkcb array
  1140. //
  1141. AllocatedMemory += sizeof(CONNECTION_TABLE);
  1142. NewTable->LinkArray = (PLINKCB*)(AllocatedMemory);
  1143. //
  1144. // Setup the pointer to the bundlecb array
  1145. //
  1146. AllocatedMemory += (sizeof(PLINKCB) * TableSize);
  1147. NewTable->BundleArray = (PBUNDLECB*)(AllocatedMemory);
  1148. if (ConnectionTable != NULL) {
  1149. //
  1150. // We must be growing the table
  1151. //
  1152. NewTable->ulNumActiveLinks = ConnectionTable->ulNumActiveLinks;
  1153. NewTable->ulNumActiveBundles = ConnectionTable->ulNumActiveBundles;
  1154. NdisMoveMemory((PUCHAR)NewTable->LinkArray,
  1155. (PUCHAR)ConnectionTable->LinkArray,
  1156. ConnectionTable->ulArraySize * sizeof(PLINKCB));
  1157. NdisMoveMemory((PUCHAR)NewTable->BundleArray,
  1158. (PUCHAR)ConnectionTable->BundleArray,
  1159. ConnectionTable->ulArraySize * sizeof(PBUNDLECB));
  1160. while (!IsListEmpty(&ConnectionTable->BundleList)) {
  1161. PBUNDLECB BundleCB;
  1162. BundleCB = (PBUNDLECB)RemoveHeadList(&ConnectionTable->BundleList);
  1163. InsertTailList(&NewTable->BundleList, &BundleCB->Linkage);
  1164. }
  1165. NdisWanDestroyConnectionTable();
  1166. }
  1167. ConnectionTable = NewTable;
  1168. return (Status);
  1169. }
  1170. VOID
  1171. NdisWanDestroyConnectionTable(
  1172. VOID
  1173. )
  1174. /*++
  1175. Routine Name:
  1176. Routine Description:
  1177. Arguments:
  1178. Return Values:
  1179. --*/
  1180. {
  1181. NdisFreeSpinLock(&ConnectionTable->Lock);
  1182. NdisWanFreeMemory(ConnectionTable);
  1183. }
  1184. VOID
  1185. NdisWanGetDeferredDesc(
  1186. PADAPTERCB AdapterCB,
  1187. PDEFERRED_DESC *RetDesc
  1188. )
  1189. {
  1190. ULONG i;
  1191. if (IsDeferredQueueEmpty(&AdapterCB->FreeDeferredQueue)) {
  1192. PDEFERRED_DESC DeferredDesc;
  1193. NdisWanAllocateMemory(&DeferredDesc, sizeof(DEFERRED_DESC) * 20);
  1194. if (DeferredDesc != NULL) {
  1195. for (i = 0; i < 20; i++) {
  1196. InsertHeadDeferredQueue(&AdapterCB->FreeDeferredQueue, DeferredDesc);
  1197. (PUCHAR)DeferredDesc += sizeof(DEFERRED_DESC);
  1198. }
  1199. }
  1200. }
  1201. *RetDesc = RemoveHeadDeferredQueue(&AdapterCB->FreeDeferredQueue);
  1202. ASSERT(*RetDesc != NULL);
  1203. }