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.

1530 lines
40 KiB

  1. /*++
  2. Copyright (c) 1996-1999 Microsoft Corporation
  3. Module Name:
  4. wansup.c
  5. Abstract:
  6. support for ndiswan
  7. Author:
  8. Yoram Bernet (yoramb) 29-Oct-1997
  9. Rajesh Sundaram (rajeshsu) 01-Aug-1998
  10. Environment:
  11. Kernel Mode
  12. Revision History:
  13. --*/
  14. #include "psched.h"
  15. #pragma hdrstop
  16. /* External */
  17. /* Static */
  18. //
  19. // Should be defined in ndis.h. Put it here for now.
  20. //
  21. #define UNKNOWN_PROTOCOL_TYPE (USHORT) -1
  22. NDIS_STATUS
  23. CleanWanLink(PADAPTER Adapter,
  24. PPS_WAN_LINK WanLink);
  25. NDIS_STATUS
  26. WanHandleISSLOW(
  27. IN PGPC_CLIENT_VC Vc,
  28. IN PCO_CALL_PARAMETERS CallParameters);
  29. VOID
  30. PsWanMungeAddress(PUSHORT id, USHORT Index)
  31. {
  32. *id = Index;
  33. }
  34. NDIS_STATUS
  35. DeleteInterfaceForNdisWan(
  36. IN PADAPTER Adapter,
  37. IN PVOID StatusBuffer,
  38. IN UINT StatusBufferSize
  39. )
  40. {
  41. PNDIS_WAN_LINE_DOWN LineDownBuff;
  42. PLIST_ENTRY NextWanLink;
  43. PPS_WAN_LINK WanLink;
  44. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  45. LineDownBuff = (PNDIS_WAN_LINE_DOWN)StatusBuffer;
  46. PsDbgOut(DBG_TRACE, DBG_WAN,
  47. ("[DeleteInterfaceForNdisWan]: Linedown for remote address %02X:%02X:%02X:%02X:%02X:%02X \n",
  48. LineDownBuff->RemoteAddress[0],
  49. LineDownBuff->RemoteAddress[1],
  50. LineDownBuff->RemoteAddress[2],
  51. LineDownBuff->RemoteAddress[3],
  52. LineDownBuff->RemoteAddress[4],
  53. LineDownBuff->RemoteAddress[5]));
  54. //
  55. // Walk the List & remove the WanLink
  56. //
  57. PS_LOCK(&Adapter->Lock);
  58. NextWanLink = Adapter->WanLinkList.Flink;
  59. while(NextWanLink != &Adapter->WanLinkList) {
  60. WanLink = CONTAINING_RECORD(NextWanLink, PS_WAN_LINK, Linkage);
  61. //
  62. // We cannot compare the LocalAddress, because NDISWAN initially
  63. // passes us 0 for the LocalAddress in the LINE_UP
  64. // The LocalAddress is for Wanarp to store its context which it
  65. // sends down to NDISWAN. NDISWAN then sends this context back
  66. // to us as LocalAddress in LINE_DOWN. So, we have to ignore
  67. // the LocalAddress in the LINE_DOWN.
  68. //
  69. if(NdisEqualMemory(WanLink->OriginalRemoteMacAddress,
  70. LineDownBuff->RemoteAddress,
  71. sizeof(LineDownBuff->RemoteAddress)))
  72. {
  73. //
  74. // Get rid of the wanlink from the list.
  75. //
  76. g_WanLinkTable[WanLink->UniqueIndex] = 0;
  77. PS_UNLOCK(&Adapter->Lock);
  78. //
  79. // Munge the s-mac and r-mac so that wanarp can clean correctly.
  80. //
  81. PsWanMungeAddress((PUSHORT)&LineDownBuff->RemoteAddress[0],
  82. WanLink->UniqueIndex);
  83. PsWanMungeAddress((PUSHORT)&LineDownBuff->LocalAddress[0],
  84. (USHORT)(*(PUSHORT)&WanLink->OriginalLocalMacAddress[0]));
  85. Status = CleanWanLink(Adapter, WanLink);
  86. NdisMIndicateStatus(Adapter->PsNdisHandle,
  87. NDIS_STATUS_WAN_LINE_DOWN,
  88. StatusBuffer,
  89. StatusBufferSize);
  90. return NDIS_STATUS_SUCCESS;
  91. }
  92. NextWanLink = NextWanLink->Flink;
  93. }
  94. PS_UNLOCK(&Adapter->Lock);
  95. PsDbgOut(DBG_CRITICAL_ERROR, DBG_WAN,
  96. ("[DeleteInterfaceForNdisWan]: Could not find wanlink for Remote Mac: (%02X:%02X:%02X:%02X:%02X:%02X) \n",
  97. LineDownBuff->RemoteAddress[0],
  98. LineDownBuff->RemoteAddress[1],
  99. LineDownBuff->RemoteAddress[2],
  100. LineDownBuff->RemoteAddress[3],
  101. LineDownBuff->RemoteAddress[4],
  102. LineDownBuff->RemoteAddress[5]));
  103. return Status;
  104. }
  105. NDIS_STATUS
  106. PsWanGenerateUniqueIndex(
  107. PPS_WAN_LINK WanLink
  108. )
  109. {
  110. PADAPTER Adapter = WanLink->Adapter;
  111. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  112. USHORT size, Index, i, j;
  113. PULONG_PTR NewTable;
  114. PS_LOCK(&Adapter->Lock);
  115. for(i=0, Index = g_NextWanIndex;
  116. i < g_WanTableSize;
  117. i++)
  118. {
  119. if(g_WanLinkTable[Index] == 0)
  120. {
  121. //
  122. // We got a free slot.
  123. //
  124. g_WanLinkTable[Index] = (ULONG_PTR)WanLink;
  125. WanLink->UniqueIndex = Index;
  126. //
  127. // Assume that the next one is free.
  128. //
  129. g_NextWanIndex ++;
  130. g_NextWanIndex = g_NextWanIndex % g_WanTableSize;
  131. PS_UNLOCK(&Adapter->Lock);
  132. return NDIS_STATUS_SUCCESS;
  133. }
  134. Index ++;
  135. Index = Index % g_WanTableSize;
  136. }
  137. //
  138. // We could not find a slot to insert the wanlink. Grow the table
  139. // and copy the existing table.
  140. //
  141. size = (g_WanTableSize + WAN_TABLE_INCREMENT) * sizeof(ULONG_PTR);
  142. PsAllocatePool(NewTable, size, WanTableTag);
  143. if(!NewTable)
  144. {
  145. PS_UNLOCK(&Adapter->Lock);
  146. return NDIS_STATUS_FAILURE;
  147. }
  148. NdisZeroMemory(NewTable, size);
  149. NdisMoveMemory(NewTable, g_WanLinkTable, g_WanTableSize * sizeof(ULONG_PTR));
  150. PsFreePool(g_WanLinkTable);
  151. g_WanLinkTable = NewTable;
  152. //
  153. //
  154. //
  155. g_WanLinkTable[g_WanTableSize] = (ULONG_PTR)WanLink;
  156. WanLink->UniqueIndex = g_WanTableSize;
  157. g_NextWanIndex = g_WanTableSize + 1;
  158. g_WanTableSize += WAN_TABLE_INCREMENT;
  159. PS_UNLOCK(&Adapter->Lock);
  160. return NDIS_STATUS_SUCCESS;
  161. }
  162. VOID
  163. DeleteWanLink(
  164. PVOID Instance,
  165. BOOLEAN AdapterLocked)
  166. {
  167. PPS_WAN_LINK WanLink = (PPS_WAN_LINK)Instance;
  168. if(WanLink->pDiffServMapping)
  169. {
  170. PsFreePool(WanLink->pDiffServMapping);
  171. }
  172. if(WanLink->ShutdownMask & SHUTDOWN_DELETE_PIPE)
  173. {
  174. (*WanLink->PsComponent->DeletePipe)(WanLink->PsPipeContext);
  175. }
  176. if(WanLink->ShutdownMask & SHUTDOWN_FREE_PS_CONTEXT)
  177. {
  178. PsFreePool(WanLink->PsPipeContext);
  179. }
  180. if(WanLink->InstanceName.Buffer) {
  181. PsFreePool(WanLink->InstanceName.Buffer);
  182. }
  183. if(WanLink->MpDeviceName.Buffer){
  184. PsFreePool(WanLink->MpDeviceName.Buffer);
  185. }
  186. if(AdapterLocked)
  187. {
  188. RemoveEntryList(&WanLink->Linkage);
  189. }
  190. else
  191. {
  192. PS_LOCK(&WanLink->Adapter->Lock);
  193. RemoveEntryList(&WanLink->Linkage);
  194. PS_UNLOCK(&WanLink->Adapter->Lock);
  195. }
  196. NdisFreeSpinLock(&WanLink->Lock);
  197. PsFreePool(WanLink);
  198. }
  199. NDIS_STATUS
  200. CreateInterfaceForNdisWan(
  201. IN PADAPTER Adapter,
  202. IN PVOID StatusBuffer,
  203. IN UINT StatusBufferSize
  204. )
  205. /*++
  206. Routine Description:
  207. Creates a TC interface to represent an underlying WAN link.
  208. Arguments:
  209. Adapter - the adapter on which the link is being created.
  210. StatusBuffer - the buffer from NDISWAN.
  211. StatusBufferSize - the length of the buffer.
  212. Return Values:
  213. None
  214. --*/
  215. {
  216. PNDIS_WAN_LINE_UP LineUpBuff;
  217. PPS_WAN_LINK WanLink;
  218. PLIST_ENTRY NextWanLink;
  219. NDIS_STATUS Status;
  220. PIP_WAN_LINKUP_INFO RouterInfo;
  221. NTSTATUS NtStatus;
  222. LARGE_INTEGER Increment = {0, 1};
  223. LARGE_INTEGER Index;
  224. PGPC_CLIENT_VC Vc;
  225. UCHAR ZeroAddress[] = {0, 0, 0, 0, 0, 0};
  226. NDIS_HANDLE LineUpHandle;
  227. int i,j;
  228. LineUpBuff = (PNDIS_WAN_LINE_UP)StatusBuffer;
  229. //
  230. // Check for MultiLink:
  231. //
  232. // The first link up will have a ZeroLocal Address, in this case, we create a new QoS interface.
  233. // All subsequent lineups will have a non-zero LocalAddress. If the link is being updated, we
  234. // only need to update the linkspeed on the existing interface.
  235. //
  236. if(!(NdisEqualMemory(LineUpBuff->LocalAddress, ZeroAddress, 6)))
  237. {
  238. //
  239. // Get the exisiting WanLink
  240. //
  241. PS_LOCK(&Adapter->Lock);
  242. NextWanLink = Adapter->WanLinkList.Flink;
  243. while(NextWanLink != &Adapter->WanLinkList) {
  244. WanLink = CONTAINING_RECORD(NextWanLink, PS_WAN_LINK, Linkage);
  245. if(NdisEqualMemory(WanLink->OriginalRemoteMacAddress,
  246. LineUpBuff->RemoteAddress,
  247. sizeof(LineUpBuff->RemoteAddress)))
  248. {
  249. REFADD(&Adapter->RefCount, 'WANU');
  250. PS_UNLOCK(&Adapter->Lock);
  251. PsDbgOut(DBG_TRACE, DBG_WAN,
  252. ("[CreateInterfaceForNdisWan]: Link speed of WanLink 0x%x has changed "
  253. "from %d to %d \n", WanLink, WanLink->LinkSpeed, LineUpBuff->LinkSpeed));
  254. WanLink->LinkSpeed = LineUpBuff->LinkSpeed;
  255. UpdateWanLinkBandwidthParameters(WanLink);
  256. TcIndicateInterfaceChange(Adapter, WanLink, NDIS_STATUS_INTERFACE_CHANGE);
  257. //
  258. // Munge s-mac and d-mac and send to wanarp.
  259. //
  260. PsWanMungeAddress((PUSHORT)&LineUpBuff->RemoteAddress[0],
  261. WanLink->UniqueIndex);
  262. PsWanMungeAddress((PUSHORT)&LineUpBuff->LocalAddress[0],
  263. (USHORT)(*(PUSHORT)&WanLink->OriginalLocalMacAddress[0]));
  264. NdisMIndicateStatus(Adapter->PsNdisHandle,
  265. NDIS_STATUS_WAN_LINE_UP,
  266. StatusBuffer,
  267. StatusBufferSize);
  268. REFDEL(&Adapter->RefCount, FALSE, 'WANU');
  269. return NDIS_STATUS_SUCCESS;
  270. }
  271. NextWanLink = NextWanLink->Flink;
  272. }
  273. PS_UNLOCK(&Adapter->Lock);
  274. PsDbgOut(DBG_FAILURE, DBG_WAN,
  275. ("[CreateInterfaceForNdisWan]: Got a change notification, but could not find wanlink "
  276. "Remote Mac: (%02X:%02X:%02X:%02X:%02X:%02X) \n",
  277. LineUpBuff->RemoteAddress[0],
  278. LineUpBuff->RemoteAddress[1],
  279. LineUpBuff->RemoteAddress[2],
  280. LineUpBuff->RemoteAddress[3],
  281. LineUpBuff->RemoteAddress[4],
  282. LineUpBuff->RemoteAddress[5]));
  283. return NDIS_STATUS_FAILURE;
  284. }
  285. //
  286. // Create an internal representation of the link.
  287. //
  288. PsAllocatePool(WanLink,
  289. sizeof(PS_WAN_LINK),
  290. WanLinkTag);
  291. if(WanLink == NULL)
  292. {
  293. PsDbgOut(DBG_FAILURE,
  294. DBG_WAN,
  295. ("[CreateInterfaceForNdisWan]: Adapter %08X, couldn't create WanLink\n",
  296. Adapter));
  297. return NDIS_STATUS_RESOURCES;
  298. }
  299. //
  300. // Initialize the wanlink.
  301. //
  302. NdisZeroMemory(WanLink, sizeof(PS_WAN_LINK));
  303. WanLink->Adapter = Adapter;
  304. REFINIT(&WanLink->RefCount, WanLink, DeleteWanLink);
  305. REFADD(&WanLink->RefCount, 'WANU');
  306. PS_INIT_SPIN_LOCK(&WanLink->Lock);
  307. //
  308. // Link the SausageLink on the link list.
  309. //
  310. NdisInterlockedIncrement(&Adapter->WanLinkCount);
  311. NdisInterlockedInsertHeadList(&Adapter->WanLinkList,
  312. &WanLink->Linkage,
  313. &Adapter->Lock.Lock);
  314. //
  315. // Update the LinkSpeed and create a pipe off the wanlink.
  316. //
  317. WanLink->RawLinkSpeed = LineUpBuff->LinkSpeed;
  318. WanLink->LinkSpeed = ( WanLink->RawLinkSpeed / 8 ) * 100;
  319. Status = UpdateWanLinkBandwidthParameters(WanLink);
  320. if(!NT_SUCCESS(Status))
  321. {
  322. PsDbgOut(DBG_FAILURE,
  323. DBG_WAN,
  324. ("[CreateInterfaceForNdisWan]: Adapter %08X, UpdateWanLinkBandwidthParameters failed with %08X",
  325. Adapter, Status));
  326. REFDEL(&WanLink->RefCount, FALSE, 'WANU');
  327. return Status;
  328. }
  329. //
  330. // Extract the network addresses from the protocol part
  331. // of the status buffer. Update the network layer address list
  332. // which is held on the adapter.
  333. //
  334. switch(LineUpBuff->ProtocolType)
  335. {
  336. case PROTOCOL_IP:
  337. RouterInfo = (PIP_WAN_LINKUP_INFO) LineUpBuff->ProtocolBuffer;
  338. WanLink->DialUsage = RouterInfo->duUsage;
  339. WanLink->ProtocolType = LineUpBuff->ProtocolType;
  340. WanLink->LocalIpAddress = RouterInfo->dwLocalAddr;
  341. WanLink->RemoteIpAddress = RouterInfo->dwRemoteAddr;
  342. WanLink->LocalIpxAddress = 0;
  343. WanLink->RemoteIpxAddress = 0;
  344. break;
  345. default:
  346. //
  347. // Unknown address type. We'll create a manageable
  348. // entity, but - we don't know how to represent its
  349. // addresses. Therefore, we also don't know how to
  350. // format traffic control filters for it. So - it
  351. // probably won't be particualrly useful. At least it
  352. // lets the user see that there is an interface.
  353. //
  354. WanLink->ProtocolType = UNKNOWN_PROTOCOL_TYPE;
  355. WanLink->LocalIpAddress = 0;
  356. WanLink->RemoteIpAddress = 0;
  357. WanLink->LocalIpxAddress = 0;
  358. WanLink->RemoteIpxAddress = 0;
  359. }
  360. PsAllocatePool(WanLink->InstanceName.Buffer,
  361. Adapter->WMIInstanceName.Length + WanPrefix.Length + INSTANCE_ID_SIZE,
  362. PsMiscTag);
  363. if(!WanLink->InstanceName.Buffer)
  364. {
  365. PsDbgOut(DBG_FAILURE,
  366. DBG_WAN,
  367. ("[CreateInterfaceForNdisWan]: Adapter %08X, could not allocate memory for instance name \n",
  368. Adapter));
  369. REFDEL(&WanLink->RefCount, FALSE, 'WANU');
  370. return NDIS_STATUS_RESOURCES;
  371. }
  372. if((Status = PsWanGenerateUniqueIndex(WanLink)) != NDIS_STATUS_SUCCESS)
  373. {
  374. PsDbgOut(DBG_FAILURE,
  375. DBG_WAN,
  376. ("[CreateInterfaceForNdisWan]: Adapter %08X, PsWanGenerateUniqueIndex failed with Status %08X \n",
  377. Adapter, Status));
  378. REFDEL(&WanLink->RefCount, FALSE, 'WANU');
  379. return Status;
  380. }
  381. Index.QuadPart = WanLink->UniqueIndex;
  382. NtStatus = GenerateInstanceName(&WanPrefix,
  383. Adapter,
  384. &Index,
  385. &WanLink->InstanceName);
  386. //
  387. // Copy the DeviceName
  388. //
  389. WanLink->MpDeviceName.MaximumLength = LineUpBuff->DeviceName.MaximumLength;
  390. PsAllocatePool(WanLink->MpDeviceName.Buffer,
  391. WanLink->MpDeviceName.MaximumLength,
  392. PsMiscTag);
  393. if(!WanLink->MpDeviceName.Buffer)
  394. {
  395. PsDbgOut(DBG_FAILURE,
  396. DBG_WAN,
  397. ("[CreateInterfaceForNdisWan]: Adapter %08X, could not allocate memory for device name \n",
  398. Adapter));
  399. PS_LOCK(&Adapter->Lock);
  400. g_WanLinkTable[WanLink->UniqueIndex] = 0;
  401. REFDEL(&WanLink->RefCount, TRUE, 'WANU');
  402. PS_UNLOCK(&Adapter->Lock);
  403. return NDIS_STATUS_RESOURCES;
  404. }
  405. NdisZeroMemory(WanLink->MpDeviceName.Buffer, WanLink->MpDeviceName.MaximumLength);
  406. Status = CreateBestEffortVc(Adapter,
  407. &WanLink->BestEffortVc,
  408. WanLink);
  409. if(Status != NDIS_STATUS_SUCCESS)
  410. {
  411. PsDbgOut(DBG_FAILURE,
  412. DBG_WAN,
  413. ("[CreateInterfaceForNdisWan]: Adapter %08X, could not create BestEffort Vc, status %08X",
  414. Adapter, Status));
  415. PS_LOCK(&Adapter->Lock);
  416. g_WanLinkTable[WanLink->UniqueIndex] = 0;
  417. REFDEL(&WanLink->RefCount, TRUE, 'WANU');
  418. PS_UNLOCK(&Adapter->Lock);
  419. return Status;
  420. }
  421. //
  422. // Create 2 BEVCS and make the NextVc as the first one.
  423. WanLink->NextVc = 0;
  424. for( i = 0; i < BEVC_LIST_LEN; i++)
  425. {
  426. Status = CreateBestEffortVc(Adapter,
  427. &WanLink->BeVcList[i],
  428. WanLink);
  429. if(Status != NDIS_STATUS_SUCCESS)
  430. {
  431. PsDbgOut(DBG_FAILURE,
  432. DBG_WAN,
  433. ("[CreateInterfaceForNdisWan]: Adapter %08X, could not create BestEffort Vc, status %08X",
  434. Adapter, Status));
  435. PS_LOCK(&Adapter->Lock);
  436. g_WanLinkTable[WanLink->UniqueIndex] = 0;
  437. for( j = 0; j < i; j++ )
  438. {
  439. PS_LOCK_DPC(&WanLink->BeVcList[j].Lock);
  440. InternalCloseCall(&WanLink->BeVcList[j]);
  441. PS_LOCK(&Adapter->Lock);
  442. }
  443. PS_LOCK_DPC(&WanLink->BestEffortVc.Lock);
  444. InternalCloseCall(&WanLink->BestEffortVc);
  445. REFDEL(&WanLink->RefCount, TRUE, 'WANU');
  446. return Status;
  447. }
  448. }
  449. //
  450. // Copy the original Remote Addresses and munge it.
  451. //
  452. NdisMoveMemory(&WanLink->OriginalRemoteMacAddress,
  453. &LineUpBuff->RemoteAddress,
  454. 6);
  455. PsWanMungeAddress((PUSHORT) &LineUpBuff->RemoteAddress[0], WanLink->UniqueIndex);
  456. NdisMIndicateStatus(Adapter->PsNdisHandle,
  457. NDIS_STATUS_WAN_LINE_UP,
  458. StatusBuffer,
  459. StatusBufferSize);
  460. //
  461. // Fail if wanarp has failed the line up
  462. //
  463. *((ULONG UNALIGNED *)(&LineUpHandle)) =
  464. *((ULONG UNALIGNED *)(&LineUpBuff->LocalAddress[2]));
  465. if (LineUpHandle == NULL)
  466. {
  467. PsDbgOut(DBG_FAILURE, DBG_WAN,
  468. ("[ClStatusIndication]: wanarp has failed the lineup. "
  469. "Remote Address (%02X:%02X:%02X:%02X:%02X:%02X) \n",
  470. LineUpBuff->RemoteAddress[0],
  471. LineUpBuff->RemoteAddress[1],
  472. LineUpBuff->RemoteAddress[2],
  473. LineUpBuff->RemoteAddress[3],
  474. LineUpBuff->RemoteAddress[4],
  475. LineUpBuff->RemoteAddress[5]));
  476. PS_LOCK(&Adapter->Lock);
  477. g_WanLinkTable[WanLink->UniqueIndex] = 0;
  478. for( j = 0; j < BEVC_LIST_LEN; j++ )
  479. {
  480. PS_LOCK_DPC(&WanLink->BeVcList[j].Lock);
  481. InternalCloseCall(&WanLink->BeVcList[j]);
  482. PS_LOCK(&Adapter->Lock);
  483. }
  484. PS_LOCK_DPC(&WanLink->BestEffortVc.Lock);
  485. InternalCloseCall(&WanLink->BestEffortVc);
  486. REFDEL(&WanLink->RefCount, FALSE, 'WANU');
  487. return NDIS_STATUS_FAILURE;
  488. }
  489. else
  490. {
  491. //
  492. // If wanarp has succeeded the lineup, we cannot get a zero local mac address.
  493. //
  494. PsAssert(!(NdisEqualMemory(LineUpBuff->LocalAddress, ZeroAddress, 6)));
  495. }
  496. //
  497. // Copy the device name that wanarp has filled in.
  498. //
  499. WanLink->MpDeviceName.Length = LineUpBuff->DeviceName.Length;
  500. NdisMoveMemory(WanLink->MpDeviceName.Buffer,
  501. LineUpBuff->DeviceName.Buffer,
  502. LineUpBuff->DeviceName.Length);
  503. //
  504. // Munge the smac address. Remember the original one that wanarp gave us.
  505. //
  506. NdisMoveMemory(&WanLink->OriginalLocalMacAddress,
  507. &LineUpBuff->LocalAddress,
  508. 6);
  509. PsWanMungeAddress((PUSHORT)&LineUpBuff->LocalAddress[0], WanLink->UniqueIndex);
  510. //
  511. // Create the headers that have to be slapped on the send/recv path.
  512. //
  513. NdisMoveMemory(&WanLink->SendHeader.DestAddr[0],
  514. WanLink->OriginalRemoteMacAddress,
  515. ARP_802_ADDR_LENGTH);
  516. NdisMoveMemory(&WanLink->SendHeader.SrcAddr[0] ,
  517. LineUpBuff->LocalAddress,
  518. ARP_802_ADDR_LENGTH);
  519. NdisMoveMemory(&WanLink->RecvHeader.DestAddr[0],
  520. WanLink->OriginalLocalMacAddress,
  521. ARP_802_ADDR_LENGTH);
  522. NdisMoveMemory(&WanLink->RecvHeader.SrcAddr[0],
  523. LineUpBuff->RemoteAddress,
  524. ARP_802_ADDR_LENGTH);
  525. //
  526. // Unmunge the remote address in the lineup buff now.
  527. //
  528. PsWanMungeAddress((PUSHORT)&LineUpBuff->RemoteAddress[0],
  529. (USHORT)(*(PUSHORT)WanLink->OriginalRemoteMacAddress));
  530. //
  531. // We are ready to recv and send packets.
  532. //
  533. PS_LOCK(&WanLink->Lock);
  534. WanLink->State = WanStateOpen;
  535. PS_UNLOCK(&WanLink->Lock);
  536. PsScheduleInterfaceIdWorkItem(Adapter, WanLink);
  537. //
  538. // Indicate the new interface up to the TCI. We indicate both the
  539. // addition of a new interface and the addresses available on it.
  540. // The address descriptors indicated for WAN interfaces differ from
  541. // those indicated for LAN interfaces. WAN interfaces include a
  542. // destination network layer address, as well as a source address.
  543. //
  544. TcIndicateInterfaceChange(Adapter, WanLink, NDIS_STATUS_INTERFACE_UP);
  545. PsDbgOut(DBG_TRACE, DBG_WAN,
  546. ("[CreateInterfaceForNdisWan]: Created WanLink 0x%x, Remote Address (%02X:%02X:%02X:%02X:%02X:%02X) \n",
  547. WanLink,
  548. LineUpBuff->RemoteAddress[0],
  549. LineUpBuff->RemoteAddress[1],
  550. LineUpBuff->RemoteAddress[2],
  551. LineUpBuff->RemoteAddress[3],
  552. LineUpBuff->RemoteAddress[4],
  553. LineUpBuff->RemoteAddress[5]));
  554. return(NDIS_STATUS_SUCCESS);
  555. }
  556. NDIS_STATUS
  557. OpenWanAddressFamily(
  558. IN PADAPTER Adapter,
  559. IN PCO_ADDRESS_FAMILY WanAddressFamily
  560. )
  561. /*++
  562. Routine Description:
  563. Establish the binding between the PS miniport, NDISWAN and the
  564. NDISWAN call manager.
  565. Arguments:
  566. Adapter - pointer to adapter
  567. Return Value:
  568. None
  569. --*/
  570. {
  571. NDIS_CLIENT_CHARACTERISTICS WanClCharacteristics;
  572. NDIS_STATUS Status;
  573. WanClCharacteristics.MajorVersion = 5;
  574. WanClCharacteristics.MinorVersion = 0;
  575. WanClCharacteristics.Reserved = 0;
  576. WanClCharacteristics.ClCreateVcHandler = WanCreateVc;
  577. WanClCharacteristics.ClDeleteVcHandler = WanDeleteVc;
  578. WanClCharacteristics.ClOpenAfCompleteHandler = WanOpenAddressFamilyComplete;
  579. WanClCharacteristics.ClCloseAfCompleteHandler = WanCloseAddressFamilyComplete;
  580. WanClCharacteristics.ClRegisterSapCompleteHandler = WanRegisterSapComplete;
  581. WanClCharacteristics.ClDeregisterSapCompleteHandler = WanDeregisterSapComplete;
  582. WanClCharacteristics.ClMakeCallCompleteHandler = WanMakeCallComplete;
  583. WanClCharacteristics.ClModifyCallQoSCompleteHandler = WanModifyCallComplete;
  584. WanClCharacteristics.ClCloseCallCompleteHandler = WanCloseCallComplete;
  585. WanClCharacteristics.ClAddPartyCompleteHandler = WanAddPartyComplete;
  586. WanClCharacteristics.ClDropPartyCompleteHandler = WanDropPartyComplete;
  587. WanClCharacteristics.ClIncomingCallHandler = WanIncomingCall;
  588. WanClCharacteristics.ClIncomingCallQoSChangeHandler = WanIncomingCallQoSChange;
  589. WanClCharacteristics.ClIncomingCloseCallHandler = WanIncomingCloseCall;
  590. WanClCharacteristics.ClIncomingDropPartyHandler = WanIncomingDropParty;
  591. WanClCharacteristics.ClCallConnectedHandler = WanCallConnected;
  592. WanClCharacteristics.ClRequestHandler = WanCoRequest;
  593. WanClCharacteristics.ClRequestCompleteHandler = WanCoRequestComplete;
  594. PsDbgOut(DBG_TRACE,
  595. DBG_WAN | DBG_INIT,
  596. ("[OpenWanAddressFamily]: Adapter %08X \n", Adapter));
  597. Status = NdisClOpenAddressFamily(Adapter->LowerMpHandle,
  598. WanAddressFamily,
  599. Adapter,
  600. &WanClCharacteristics,
  601. sizeof(WanClCharacteristics),
  602. &Adapter->WanCmHandle);
  603. if(Status != NDIS_STATUS_PENDING)
  604. {
  605. WanOpenAddressFamilyComplete(Status,
  606. Adapter,
  607. Adapter->WanCmHandle);
  608. }
  609. return Status;
  610. } // OpenWanAddressFamily
  611. VOID
  612. WanOpenAddressFamilyComplete(
  613. IN NDIS_STATUS Status,
  614. IN NDIS_HANDLE ProtocolAfContext,
  615. IN NDIS_HANDLE NdisAfHandle
  616. )
  617. /*++
  618. Routine Description:
  619. Complete a call to NdisClOpenAddressFamily.
  620. Arguments:
  621. see the DDK
  622. Return Value:
  623. None
  624. --*/
  625. {
  626. PADAPTER Adapter = (PADAPTER)ProtocolAfContext;
  627. if(Status != NDIS_STATUS_SUCCESS){
  628. PsDbgOut(DBG_CRITICAL_ERROR,
  629. DBG_WAN,
  630. ("[WanOpenAddressFamilyComplete]: Adapter %08X, open failed %08X\n",
  631. Adapter, Status));
  632. PsAdapterWriteEventLog(
  633. EVENT_PS_REGISTER_ADDRESS_FAMILY_FAILED,
  634. 0,
  635. &Adapter->MpDeviceName,
  636. sizeof(Status),
  637. &Status);
  638. return;
  639. }
  640. else{
  641. PS_LOCK(&Adapter->Lock);
  642. Adapter->WanBindingState |= WAN_ADDR_FAMILY_OPEN;
  643. Adapter->ShutdownMask |= SHUTDOWN_CLOSE_WAN_ADDR_FAMILY;
  644. Adapter->WanCmHandle = NdisAfHandle;
  645. Adapter->FinalStatus = Status;
  646. PS_UNLOCK(&Adapter->Lock);
  647. PsDbgOut(DBG_TRACE,
  648. DBG_WAN | DBG_INIT,
  649. ("[WanOpenAddressFamilyComplete]: Adapter %08X, Status = %x\n",
  650. Adapter,
  651. Status));
  652. }
  653. } // WanOpenAddressFamilyComplete
  654. VOID
  655. WanMakeCallComplete(
  656. IN NDIS_STATUS Status,
  657. IN NDIS_HANDLE ProtocolVcContext,
  658. IN NDIS_HANDLE NdisPartyHandle,
  659. IN OUT PCO_CALL_PARAMETERS CallParameters
  660. )
  661. {
  662. PGPC_CLIENT_VC Vc = (PGPC_CLIENT_VC) ProtocolVcContext;
  663. PADAPTER Adapter = Vc->Adapter;
  664. PsStructAssert(Adapter);
  665. //
  666. // Common code to complete both synchronous and asynchronous
  667. // returns from WanMakeCall. Note that, unless there is a WAN
  668. // adapter, CmMakeCall will always complete synchronously.
  669. //
  670. if(Status != NDIS_STATUS_SUCCESS){
  671. //
  672. // We probably at least succeeeded in creating a VC in NDISWAN.
  673. // If we did, we should delete it here. We may have failed however,
  674. // because we could not create the VC, in which case, we have
  675. // nothing to delete.
  676. //
  677. if(Vc->NdisWanVcHandle){
  678. NdisCoDeleteVc(Vc->NdisWanVcHandle);
  679. Vc->NdisWanVcHandle = NULL;
  680. }
  681. }
  682. CompleteMakeCall(Vc,
  683. CallParameters,
  684. Status);
  685. }
  686. VOID
  687. WanModifyCallComplete(
  688. IN NDIS_STATUS Status,
  689. IN NDIS_HANDLE ProtocolVcContext,
  690. IN OUT PCO_CALL_PARAMETERS CallParameters
  691. )
  692. {
  693. PGPC_CLIENT_VC Vc = (PGPC_CLIENT_VC)ProtocolVcContext;
  694. PADAPTER Adapter = Vc->Adapter;
  695. PsStructAssert(Adapter);
  696. //
  697. // Common code to complete both synchronous and asynchronous
  698. // returns from WanModifyCall.
  699. //
  700. if(Status != NDIS_STATUS_SUCCESS) {
  701. //
  702. // We changed some of the ISSLOW stuff - Time to revert back
  703. //
  704. WanHandleISSLOW(Vc, Vc->CallParameters);
  705. }
  706. ModifyCallComplete(Vc, CallParameters, Status);
  707. }
  708. VOID
  709. WanCloseAddressFamilyComplete(
  710. IN NDIS_STATUS Status,
  711. IN NDIS_HANDLE ProtocolBindingContext
  712. )
  713. {
  714. PADAPTER Adapter = (PADAPTER)ProtocolBindingContext;
  715. PS_LOCK(&Adapter->Lock);
  716. Adapter->WanBindingState &= ~WAN_ADDR_FAMILY_OPEN;
  717. PS_UNLOCK(&Adapter->Lock);
  718. }
  719. NDIS_STATUS
  720. WanCreateVc(
  721. IN NDIS_HANDLE ProtocolAfContext,
  722. IN NDIS_HANDLE NdisVcHandle,
  723. OUT PNDIS_HANDLE ProtocolVcContext
  724. )
  725. {
  726. DEBUGCHK;
  727. return NDIS_STATUS_FAILURE;
  728. }
  729. NDIS_STATUS
  730. WanDeleteVc(
  731. IN NDIS_HANDLE ProtocolVcContext
  732. )
  733. {
  734. DEBUGCHK;
  735. return NDIS_STATUS_FAILURE;
  736. }
  737. VOID
  738. WanRegisterSapComplete(
  739. IN NDIS_STATUS Status,
  740. IN NDIS_HANDLE ProtocolSapContext,
  741. IN PCO_SAP Sap,
  742. IN NDIS_HANDLE NdisSapHandle
  743. )
  744. {
  745. DEBUGCHK;
  746. }
  747. VOID
  748. WanDeregisterSapComplete(
  749. IN NDIS_STATUS Status,
  750. IN NDIS_HANDLE ProtocolSapContext
  751. )
  752. {
  753. DEBUGCHK;
  754. }
  755. NDIS_STATUS
  756. WanIncomingCall(
  757. IN NDIS_HANDLE ProtocolSapContext,
  758. IN NDIS_HANDLE ProtocolVcContext,
  759. IN OUT PCO_CALL_PARAMETERS CallParameters
  760. )
  761. {
  762. DEBUGCHK;
  763. return NDIS_STATUS_FAILURE;
  764. }
  765. VOID
  766. WanAddPartyComplete(
  767. IN NDIS_STATUS Status,
  768. IN NDIS_HANDLE ProtocolPartyContext,
  769. IN NDIS_HANDLE NdisPartyHandle,
  770. IN PCO_CALL_PARAMETERS CallParameters
  771. )
  772. {
  773. DEBUGCHK;
  774. }
  775. VOID
  776. WanDropPartyComplete(
  777. IN NDIS_STATUS Status,
  778. IN NDIS_HANDLE ProtocolPartyContext
  779. )
  780. {
  781. DEBUGCHK;
  782. }
  783. NDIS_STATUS
  784. WanHandleISSLOW(
  785. IN PGPC_CLIENT_VC Vc,
  786. IN PCO_CALL_PARAMETERS CallParameters
  787. )
  788. {
  789. LONG ParamsLength;
  790. LPQOS_OBJECT_HDR QoSObject;
  791. PADAPTER Adapter = Vc->Adapter;
  792. PCO_MEDIA_PARAMETERS CallMgrParams = CallParameters->MediaParameters;
  793. ULONGLONG i,j,k;
  794. //
  795. // See if this is an ISSLOW flow.
  796. //
  797. ParamsLength = (LONG)CallMgrParams->MediaSpecific.Length;
  798. QoSObject = (LPQOS_OBJECT_HDR)CallMgrParams->MediaSpecific.Parameters;
  799. //
  800. // By default, this is not an ISSLOW flow.
  801. //
  802. Vc->Flags &= ~GPC_ISSLOW_FLOW;
  803. while(ParamsLength > 0){
  804. if(QoSObject->ObjectType == QOS_OBJECT_WAN_MEDIA)
  805. {
  806. LPQOS_WAN_MEDIA WanMedia = (LPQOS_WAN_MEDIA)QoSObject;
  807. WanMedia->ISSLOW = FALSE;
  808. //
  809. // See if the flow is an ISSLOW flow. If the TokenRate of the flow
  810. // is under ISSLOW TokenRate and the PacketSize is under MaxPacketSize
  811. // Then we qualify this as ISSLOW flows.
  812. //
  813. // If a wanlink's linkspeed is greater than a certain amount, we don't run issow over it.
  814. //
  815. if((Vc->WanLink->LinkSpeed <= Adapter->ISSLOWLinkSpeed) &&
  816. (CallParameters->CallMgrParameters->Transmit.ServiceType != SERVICETYPE_BESTEFFORT))
  817. {
  818. i = (ULONG) Adapter->ISSLOWTokenRate * (ULONG) CallParameters->CallMgrParameters->Transmit.MaxSduSize;
  819. j = (ULONG) Adapter->ISSLOWPacketSize * (ULONG) CallParameters->CallMgrParameters->Transmit.TokenRate;
  820. k = (ULONG) Adapter->ISSLOWTokenRate * (ULONG)Adapter->ISSLOWPacketSize;
  821. if((i+j)<k)
  822. {
  823. WanMedia->ISSLOW = TRUE;
  824. PsDbgOut(DBG_TRACE, DBG_WAN,
  825. ("[WanHandleISSLOW]: Vc %08X is an ISSLOW VC (TokenRate = %d, PacketSize = %d \n",
  826. Vc, CallParameters->CallMgrParameters->Transmit.TokenRate,
  827. CallParameters->CallMgrParameters->Transmit.MaxSduSize));
  828. //
  829. // The MaxSDUSize is normally a measure of the latency requirements of -that- flow
  830. // For audio codes, MaxSDUSize = f(Latency requirements, unit size);
  831. //
  832. // But, we don't want to chop these into very small fragments. Therefore, we have
  833. // an upper bound and pick the maximum.
  834. //
  835. if(CallParameters->CallMgrParameters->Transmit.MaxSduSize > Adapter->ISSLOWFragmentSize)
  836. {
  837. Vc->ISSLOWFragmentSize = CallParameters->CallMgrParameters->Transmit.MaxSduSize;
  838. }
  839. else
  840. {
  841. Vc->ISSLOWFragmentSize = Adapter->ISSLOWFragmentSize;
  842. }
  843. Vc->Flags |= GPC_ISSLOW_FLOW;
  844. PsDbgOut(DBG_TRACE, DBG_WAN,
  845. ("[WanHandleISSLOW]: Adapter %08X, ISSLOW Vc %08X, FragmentSize = %d bytes \n",
  846. Adapter, Vc, Vc->ISSLOWFragmentSize));
  847. }
  848. else
  849. {
  850. PsDbgOut(DBG_TRACE, DBG_WAN,
  851. ("[WanHandleISSLOW]: Non ISSLOW Vc %08X. ISSLOW TokenRate %d, "
  852. "ISSLOW Packet Size %d, VC TokenRate %d, VC Packet Size %d \n",
  853. Vc, Adapter->ISSLOWTokenRate,
  854. Adapter->ISSLOWPacketSize,
  855. CallParameters->CallMgrParameters->Transmit.TokenRate,
  856. CallParameters->CallMgrParameters->Transmit.MaxSduSize));
  857. }
  858. }
  859. else
  860. {
  861. PsDbgOut(DBG_TRACE, DBG_WAN,
  862. ("[WanHandleISSLOW]: Non ISSLOW Vc %08X. (servicetype == B/E "
  863. " or WAN LinkSpeed %d < ISSLOW LinkSpeed %d \n",
  864. Vc, Vc->WanLink->LinkSpeed, Adapter->ISSLOWLinkSpeed));
  865. }
  866. return NDIS_STATUS_SUCCESS;
  867. }
  868. else {
  869. if(
  870. ((LONG)QoSObject->ObjectLength <= 0) ||
  871. ((LONG)QoSObject->ObjectLength > ParamsLength)
  872. ){
  873. return(QOS_STATUS_TC_OBJECT_LENGTH_INVALID);
  874. }
  875. ParamsLength -= QoSObject->ObjectLength;
  876. QoSObject = (LPQOS_OBJECT_HDR)((UINT_PTR)QoSObject +
  877. QoSObject->ObjectLength);
  878. }
  879. }
  880. return NDIS_STATUS_FAILURE;
  881. }
  882. NDIS_STATUS
  883. WanMakeCall(
  884. IN PGPC_CLIENT_VC Vc,
  885. IN OUT PCO_CALL_PARAMETERS CallParameters
  886. )
  887. {
  888. NDIS_STATUS Status;
  889. PADAPTER Adapter;
  890. Adapter = Vc->Adapter;
  891. PsStructAssert(Adapter);
  892. //
  893. // Handle ISSLOW
  894. //
  895. WanHandleISSLOW(Vc, CallParameters);
  896. //
  897. // Create a VC in the Wan adapter.
  898. //
  899. Vc->NdisWanVcHandle = NULL;
  900. Status = NdisCoCreateVc(Adapter->LowerMpHandle,
  901. Adapter->WanCmHandle,
  902. Vc,
  903. &Vc->NdisWanVcHandle);
  904. PsAssert(Status != NDIS_STATUS_PENDING);
  905. if(Status != NDIS_STATUS_SUCCESS)
  906. {
  907. Vc->NdisWanVcHandle = 0;
  908. PsDbgOut(DBG_FAILURE, DBG_WAN,
  909. ("[WanMakeCall]: cannot create VC. Status = %d\n", Status));
  910. WanMakeCallComplete(Status, Vc, NULL, CallParameters);
  911. }
  912. else
  913. {
  914. Status = NdisClMakeCall(Vc->NdisWanVcHandle, CallParameters, NULL, NULL);
  915. if(Status != NDIS_STATUS_PENDING){
  916. WanMakeCallComplete(Status, Vc, NULL, CallParameters);
  917. }
  918. }
  919. return (NDIS_STATUS_PENDING);
  920. }
  921. VOID
  922. WanCloseCall(
  923. IN PGPC_CLIENT_VC Vc
  924. )
  925. {
  926. NDIS_STATUS Status;
  927. //
  928. // Issue a CloseCall to the WAN call manager.
  929. //
  930. PsAssert(Vc->NdisWanVcHandle);
  931. Status = NdisClCloseCall(Vc->NdisWanVcHandle,
  932. NULL,
  933. NULL,
  934. 0);
  935. if(Status != NDIS_STATUS_PENDING)
  936. {
  937. WanCloseCallComplete(Status,
  938. Vc,
  939. Vc->CallParameters);
  940. }
  941. }
  942. VOID
  943. WanCloseCallComplete(
  944. NDIS_STATUS Status,
  945. NDIS_HANDLE ProtocolVcContext,
  946. PCO_CALL_PARAMETERS CallParameters
  947. )
  948. {
  949. PGPC_CLIENT_VC Vc = (PGPC_CLIENT_VC) ProtocolVcContext;
  950. Status = NdisCoDeleteVc(Vc->NdisWanVcHandle);
  951. PsAssert(Status != NDIS_STATUS_PENDING);
  952. Vc->NdisWanVcHandle = 0;
  953. CmDeleteVc(Vc);
  954. }
  955. NDIS_STATUS
  956. WanModifyCall(
  957. IN PGPC_CLIENT_VC Vc,
  958. IN OUT PCO_CALL_PARAMETERS CallParameters
  959. )
  960. {
  961. NDIS_STATUS Status;
  962. WanHandleISSLOW(Vc, CallParameters);
  963. PsAssert(Vc->NdisWanVcHandle);
  964. Status = NdisClModifyCallQoS(Vc->NdisWanVcHandle, CallParameters);
  965. if(Status != NDIS_STATUS_PENDING)
  966. {
  967. WanModifyCallComplete(Status, Vc, CallParameters);
  968. }
  969. return NDIS_STATUS_PENDING;
  970. }
  971. VOID
  972. AskWanLinksToClose(PADAPTER Adapter)
  973. {
  974. PLIST_ENTRY NextWanLink;
  975. PPS_WAN_LINK WanLink;
  976. PsDbgOut(DBG_TRACE, DBG_WAN,
  977. ("[AskWanLinksToClose]: Adapter %08X - All wanlinks are closing \n", Adapter));
  978. //
  979. // Walk the List & remove the WanLink
  980. //
  981. PS_LOCK(&Adapter->Lock);
  982. while(!IsListEmpty(&Adapter->WanLinkList)) {
  983. NextWanLink = RemoveHeadList(&Adapter->WanLinkList);
  984. WanLink = CONTAINING_RECORD(NextWanLink, PS_WAN_LINK, Linkage);
  985. //
  986. // Get rid of the wanlink from the list.
  987. //
  988. g_WanLinkTable[WanLink->UniqueIndex] = 0;
  989. PS_UNLOCK(&Adapter->Lock);
  990. CleanWanLink(Adapter, WanLink);
  991. PS_LOCK(&Adapter->Lock);
  992. }
  993. PS_UNLOCK(&Adapter->Lock);
  994. return;
  995. }
  996. NDIS_STATUS
  997. CleanWanLink(PADAPTER Adapter,
  998. PPS_WAN_LINK WanLink)
  999. {
  1000. PLIST_ENTRY NextVc;
  1001. PGPC_CLIENT_VC Vc;
  1002. PUSHORT id;
  1003. int j;
  1004. PsDbgOut(DBG_TRACE, DBG_WAN, ("[CleanWanLink]: WanLink 0x%x is going down \n", WanLink));
  1005. TcIndicateInterfaceChange(Adapter, WanLink, NDIS_STATUS_INTERFACE_DOWN);
  1006. PS_LOCK(&WanLink->Lock);
  1007. WanLink->State = WanStateClosing;
  1008. PS_UNLOCK(&WanLink->Lock);
  1009. PS_LOCK(&Adapter->Lock);
  1010. //
  1011. // Make sure to delete Be Vc1 also..
  1012. for( j = 0; j < BEVC_LIST_LEN; j++ )
  1013. {
  1014. PS_LOCK_DPC(&WanLink->BeVcList[j].Lock);
  1015. InternalCloseCall(&WanLink->BeVcList[j]);
  1016. PS_LOCK(&Adapter->Lock);
  1017. }
  1018. PS_LOCK_DPC(&WanLink->BestEffortVc.Lock);
  1019. InternalCloseCall(&WanLink->BestEffortVc);
  1020. NdisInterlockedDecrement(&Adapter->WanLinkCount);
  1021. PS_LOCK(&Adapter->Lock);
  1022. //
  1023. // Clean up all the GPC VCs on the WanLink;
  1024. //
  1025. NextVc = Adapter->GpcClientVcList.Flink;
  1026. while(NextVc != &Adapter->GpcClientVcList)
  1027. {
  1028. Vc = CONTAINING_RECORD(NextVc, GPC_CLIENT_VC, Linkage);
  1029. NextVc = NextVc->Flink;
  1030. PsAssert(Vc);
  1031. if(Vc->WanLink == WanLink)
  1032. {
  1033. PS_LOCK_DPC(&Vc->Lock);
  1034. if(Vc->ClVcState == CL_INTERNAL_CLOSE_PENDING || Vc->Flags & INTERNAL_CLOSE_REQUESTED)
  1035. {
  1036. // We have already closed this Vc. Let's move on.
  1037. PS_UNLOCK_DPC(&Vc->Lock);
  1038. }
  1039. else
  1040. {
  1041. InternalCloseCall(Vc);
  1042. PS_LOCK(&Adapter->Lock);
  1043. //
  1044. // Sigh. We can't really get hold to the NextVc in a reliable manner. When we call
  1045. // InternalCloseCall on the Vc, it releases the Adapter Lock (since it might have to
  1046. // make calls into NDIS). Now, in this window, the next Vc could go away, and we
  1047. // could point to a stale Vc. So, we start at the head of the list.
  1048. // Note that this can never lead to a infinite loop, since we don't process the
  1049. // internal close'd VCs repeatedly.
  1050. //
  1051. NextVc = Adapter->GpcClientVcList.Flink;
  1052. }
  1053. }
  1054. }
  1055. PS_UNLOCK(&Adapter->Lock);
  1056. REFDEL(&WanLink->RefCount, FALSE, 'WANU');
  1057. return NDIS_STATUS_SUCCESS;
  1058. }
  1059. VOID
  1060. WanIncomingCallQoSChange(
  1061. IN NDIS_HANDLE ProtocolVcContext,
  1062. IN PCO_CALL_PARAMETERS CallParameters
  1063. )
  1064. {
  1065. DEBUGCHK;
  1066. }
  1067. VOID
  1068. WanIncomingCloseCall(
  1069. IN NDIS_STATUS CloseStatus,
  1070. IN NDIS_HANDLE ProtocolVcContext,
  1071. IN PVOID CloseData OPTIONAL,
  1072. IN UINT Size OPTIONAL
  1073. )
  1074. {
  1075. PGPC_CLIENT_VC Vc = (PGPC_CLIENT_VC) ProtocolVcContext;
  1076. PsAssert(Vc);
  1077. CheckLLTag(Vc, GpcClientVc);
  1078. PS_LOCK(&Vc->Adapter->Lock);
  1079. PS_LOCK_DPC(&Vc->Lock);
  1080. InternalCloseCall(Vc);
  1081. return;
  1082. }
  1083. VOID
  1084. WanIncomingDropParty(
  1085. IN NDIS_STATUS DropStatus,
  1086. IN NDIS_HANDLE ProtocolPartyContext,
  1087. IN PVOID CloseData OPTIONAL,
  1088. IN UINT Size OPTIONAL
  1089. )
  1090. {
  1091. DEBUGCHK;
  1092. }
  1093. VOID
  1094. WanCallConnected(
  1095. IN NDIS_HANDLE ProtocolPartyContext
  1096. )
  1097. {
  1098. DEBUGCHK;
  1099. }
  1100. NDIS_STATUS
  1101. WanCoRequest(
  1102. IN NDIS_HANDLE ProtocolAfContext,
  1103. IN NDIS_HANDLE ProtocolVcContext OPTIONAL,
  1104. IN NDIS_HANDLE ProtocolPartyContext OPTIONAL,
  1105. IN OUT PNDIS_REQUEST NdisRequest
  1106. )
  1107. {
  1108. DEBUGCHK;
  1109. return NDIS_STATUS_INVALID_OID;
  1110. }
  1111. VOID
  1112. WanCoRequestComplete(
  1113. IN NDIS_STATUS Status,
  1114. IN NDIS_HANDLE ProtocolAfContext,
  1115. IN NDIS_HANDLE ProtocolVcContext OPTIONAL,
  1116. IN NDIS_HANDLE ProtocolPartyContext OPTIONAL,
  1117. IN PNDIS_REQUEST NdisRequest
  1118. )
  1119. {
  1120. ClRequestComplete(ProtocolAfContext,
  1121. NdisRequest,
  1122. Status);
  1123. }
  1124. NDIS_STATUS
  1125. UpdateWanLinkBandwidthParameters(PPS_WAN_LINK WanLink)
  1126. {
  1127. //
  1128. // Called any time the link speed is updated. This
  1129. // function generates the adapter link speed and the
  1130. // and non-best-effort rate limits, both in bytes per second.
  1131. //
  1132. PsUpdateLinkSpeed(WanLink->Adapter,
  1133. WanLink->RawLinkSpeed,
  1134. &WanLink->RemainingBandWidth,
  1135. &WanLink->LinkSpeed,
  1136. &WanLink->NonBestEffortLimit,
  1137. &WanLink->Lock);
  1138. return UpdateWanSchedulingPipe(WanLink);
  1139. }