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.

4972 lines
100 KiB

  1. /*++
  2. Copyright (c) 1997 FORE Systems, Inc.
  3. Copyright (c) 1997 Microsoft Corporation
  4. Module Name:
  5. elanpkt.c
  6. Abstract:
  7. Revision History:
  8. Notes:
  9. --*/
  10. #include <precomp.h>
  11. #pragma hdrstop
  12. VOID
  13. AtmLaneSendConfigureRequest(
  14. IN PATMLANE_ELAN pElan
  15. )
  16. /*++
  17. Routine Description:
  18. Send an LE_CONFIGURE_REQUEST for the given ELAN to the LECS.
  19. It is assumed that caller holds a lock on the ELAN structure
  20. and it will be released here.
  21. Arguments:
  22. pElan - Pointer to ATMLANE elan structure
  23. Return Value:
  24. None
  25. --*/
  26. {
  27. PATMLANE_ATM_ENTRY pAtmEntry;
  28. PATMLANE_VC pVc;
  29. PNDIS_PACKET pNdisPacket;
  30. PNDIS_BUFFER pNdisBuffer;
  31. PUCHAR pPkt;
  32. LANE_CONTROL_FRAME UNALIGNED * pCf;
  33. ULONG ulTemp;
  34. NDIS_STATUS Status;
  35. ULONG rc;
  36. DBGP((3, "SendConfigureRequest: Elan %x\n", pElan));
  37. //
  38. // Initialize
  39. //
  40. pNdisPacket = (PNDIS_PACKET)NULL;
  41. pNdisBuffer = (PNDIS_BUFFER)NULL;
  42. Status = NDIS_STATUS_SUCCESS;
  43. pVc = NULL_PATMLANE_VC;
  44. do
  45. {
  46. ACQUIRE_ELAN_ATM_LIST_LOCK(pElan);
  47. pAtmEntry = pElan->pLecsAtmEntry;
  48. if (pAtmEntry == NULL_PATMLANE_ATM_ENTRY)
  49. {
  50. RELEASE_ELAN_ATM_LIST_LOCK(pElan);
  51. Status = NDIS_STATUS_FAILURE;
  52. break;
  53. }
  54. ACQUIRE_ATM_ENTRY_LOCK_DPC(pAtmEntry);
  55. pVc = pAtmEntry->pVcList;
  56. if (pVc == NULL_PATMLANE_VC)
  57. {
  58. RELEASE_ATM_ENTRY_LOCK_DPC(pAtmEntry);
  59. RELEASE_ELAN_ATM_LIST_LOCK(pElan);
  60. break;
  61. }
  62. //
  63. // Reference the VC to keep it around
  64. //
  65. ACQUIRE_VC_LOCK_DPC(pVc);
  66. AtmLaneReferenceVc(pVc, "temp");
  67. RELEASE_VC_LOCK_DPC(pVc);
  68. RELEASE_ATM_ENTRY_LOCK_DPC(pAtmEntry);
  69. RELEASE_ELAN_ATM_LIST_LOCK(pElan);
  70. //
  71. // Allocate the Ndis packet header.
  72. //
  73. pNdisPacket = AtmLaneAllocProtoPacket(pElan);
  74. if ((PNDIS_PACKET)NULL == pNdisPacket)
  75. {
  76. DBGP((0, "SendConfigureRequest: allocate packet failed\n"));
  77. Status = NDIS_STATUS_RESOURCES;
  78. break;
  79. }
  80. //
  81. // Allocate the protocol buffer
  82. //
  83. pNdisBuffer = AtmLaneAllocateProtoBuffer(
  84. pElan,
  85. pElan->ProtocolBufSize,
  86. &(pPkt)
  87. );
  88. if ((PNDIS_BUFFER)NULL == pNdisBuffer)
  89. {
  90. DBGP((0, "SendConfigureRequest: allocate proto buffer failed\n"));
  91. Status = NDIS_STATUS_RESOURCES;
  92. break;
  93. }
  94. //
  95. // Fill in the packet with LE_CONFIGURE_REQUEST
  96. //
  97. NdisZeroMemory(pPkt, pElan->ProtocolBufSize);
  98. pCf = (PLANE_CONTROL_FRAME)pPkt;
  99. pCf->Marker = LANE_CONTROL_MARKER;
  100. pCf->Protocol = LANE_PROTOCOL;
  101. pCf->Version = LANE_VERSION;
  102. pCf->OpCode = LANE_CONFIGURE_REQUEST;
  103. ulTemp = NdisInterlockedIncrement(&pElan->TransactionId);
  104. pCf->Tid = SWAPULONG(ulTemp);
  105. pCf->SourceMacAddress.Type = LANE_MACADDRTYPE_MACADDR;
  106. if (pElan->LanType == LANE_LANTYPE_TR)
  107. {
  108. NdisMoveMemory(
  109. &pCf->SourceMacAddress.Byte,
  110. &pElan->MacAddressTr,
  111. sizeof(MAC_ADDRESS)
  112. );
  113. }
  114. else
  115. {
  116. NdisMoveMemory(
  117. &pCf->SourceMacAddress.Byte,
  118. &pElan->MacAddressEth,
  119. sizeof(MAC_ADDRESS)
  120. );
  121. }
  122. NdisMoveMemory(
  123. &pCf->SourceAtmAddr,
  124. &pElan->AtmAddress.Address,
  125. ATM_ADDRESS_LENGTH
  126. );
  127. DBGP((4, "%d: sending Config Req, Elan %x has LanType %d, CfgLanType %d\n",
  128. pElan->ElanNumber,
  129. pElan,
  130. pElan->LanType,
  131. pElan->CfgLanType));
  132. pCf->LanType = LANE_LANTYPE_UNSPEC;
  133. pCf->MaxFrameSize = (UCHAR) pElan->CfgMaxFrameSizeCode;
  134. pCf->ElanNameSize = pElan->ElanNameSize;
  135. NdisMoveMemory(
  136. &pCf->ElanName,
  137. pElan->ElanName,
  138. LANE_ELANNAME_SIZE_MAX
  139. );
  140. //
  141. // Link the ndis buffer to the ndis packet
  142. //
  143. NdisChainBufferAtFront(pNdisPacket, pNdisBuffer);
  144. //
  145. // Reacquire VC lock and if VC still connected send packet
  146. //
  147. ACQUIRE_VC_LOCK(pVc);
  148. if (IS_FLAG_SET(
  149. pVc->Flags,
  150. VC_CALL_STATE_MASK,
  151. VC_CALL_STATE_ACTIVE))
  152. {
  153. AtmLaneSendPacketOnVc(pVc, pNdisPacket, FALSE);
  154. //
  155. // VC lock released in above
  156. //
  157. }
  158. else
  159. {
  160. Status = NDIS_STATUS_FAILURE;
  161. RELEASE_VC_LOCK(pVc);
  162. }
  163. }
  164. while (FALSE);
  165. //
  166. // Remove temp VC reference
  167. //
  168. if (pVc != NULL_PATMLANE_VC)
  169. {
  170. ACQUIRE_VC_LOCK(pVc);
  171. rc = AtmLaneDereferenceVc(pVc, "temp");
  172. if (rc > 0)
  173. {
  174. RELEASE_VC_LOCK(pVc);
  175. }
  176. //
  177. // else VC is gone
  178. //
  179. }
  180. //
  181. // Cleanup if failure
  182. //
  183. if (Status != NDIS_STATUS_SUCCESS)
  184. {
  185. if (pNdisPacket != (PNDIS_PACKET)NULL)
  186. {
  187. AtmLaneFreeProtoPacket(pElan, pNdisPacket);
  188. }
  189. if (pNdisBuffer != (PNDIS_BUFFER)NULL)
  190. {
  191. AtmLaneFreeProtoBuffer(pElan, pNdisBuffer);
  192. }
  193. }
  194. TRACEOUT(SendConfigureRequest);
  195. return;
  196. }
  197. VOID
  198. AtmLaneSendJoinRequest(
  199. IN PATMLANE_ELAN pElan
  200. )
  201. /*++
  202. Routine Description:
  203. Send an LE_JOIN_REQUEST for the given ELAN to the LES.
  204. It is assumed that caller holds a lock on the ELAN structure
  205. and it will be released here.
  206. Arguments:
  207. pElan - Pointer to ATMLANE elan structure
  208. Return Value:
  209. None
  210. --*/
  211. {
  212. PATMLANE_ATM_ENTRY pAtmEntry;
  213. PATMLANE_VC pVc;
  214. PNDIS_PACKET pNdisPacket;
  215. PNDIS_BUFFER pNdisBuffer;
  216. PUCHAR pPkt;
  217. LANE_CONTROL_FRAME UNALIGNED * pCf;
  218. ULONG ulTemp;
  219. NDIS_STATUS Status;
  220. ULONG rc;
  221. TRACEIN(SendJoinRequest);
  222. DBGP((3, "SendJoinRequest: Elan %x\n", pElan));
  223. //
  224. // Initialize
  225. //
  226. pNdisPacket = (PNDIS_PACKET)NULL;
  227. pNdisBuffer = (PNDIS_BUFFER)NULL;
  228. Status = NDIS_STATUS_SUCCESS;
  229. pVc = NULL_PATMLANE_VC;
  230. do
  231. {
  232. ACQUIRE_ELAN_ATM_LIST_LOCK(pElan);
  233. pAtmEntry = pElan->pLesAtmEntry;
  234. if (pAtmEntry == NULL_PATMLANE_ATM_ENTRY)
  235. {
  236. RELEASE_ELAN_ATM_LIST_LOCK(pElan);
  237. Status = NDIS_STATUS_FAILURE;
  238. break;
  239. }
  240. ACQUIRE_ATM_ENTRY_LOCK_DPC(pAtmEntry);
  241. pVc = pAtmEntry->pVcList;
  242. if (pVc == NULL_PATMLANE_VC)
  243. {
  244. RELEASE_ATM_ENTRY_LOCK_DPC(pAtmEntry);
  245. RELEASE_ELAN_ATM_LIST_LOCK(pElan);
  246. break;
  247. }
  248. //
  249. // Reference the VC to keep it around
  250. //
  251. ACQUIRE_VC_LOCK_DPC(pVc);
  252. AtmLaneReferenceVc(pVc, "temp");
  253. RELEASE_VC_LOCK_DPC(pVc);
  254. RELEASE_ATM_ENTRY_LOCK_DPC(pAtmEntry);
  255. RELEASE_ELAN_ATM_LIST_LOCK(pElan);
  256. //
  257. // Allocate the Ndis packet header.
  258. //
  259. pNdisPacket = AtmLaneAllocProtoPacket(pElan);
  260. if ((PNDIS_PACKET)NULL == pNdisPacket)
  261. {
  262. DBGP((0, "SendJoinRequest: allocate packet failed\n"));
  263. Status = NDIS_STATUS_RESOURCES;
  264. break;
  265. }
  266. //
  267. // Allocate the protocol buffer
  268. //
  269. pNdisBuffer = AtmLaneAllocateProtoBuffer(
  270. pElan,
  271. pElan->ProtocolBufSize,
  272. &(pPkt)
  273. );
  274. if ((PNDIS_BUFFER)NULL == pNdisBuffer)
  275. {
  276. DBGP((0, "SendJoinRequest: allocate proto buffer failed\n"));
  277. Status = NDIS_STATUS_RESOURCES;
  278. break;
  279. }
  280. //
  281. // Fill in the packet with LE_JOIN_REQUEST
  282. //
  283. NdisZeroMemory(pPkt, pElan->ProtocolBufSize);
  284. pCf = (PLANE_CONTROL_FRAME)pPkt;
  285. pCf->Marker = LANE_CONTROL_MARKER;
  286. pCf->Protocol = LANE_PROTOCOL;
  287. pCf->Version = LANE_VERSION;
  288. pCf->OpCode = LANE_JOIN_REQUEST;
  289. ulTemp = NdisInterlockedIncrement(&pElan->TransactionId);
  290. pCf->Tid = SWAPULONG(ulTemp);
  291. pCf->SourceMacAddress.Type = LANE_MACADDRTYPE_MACADDR;
  292. if (pElan->LanType == LANE_LANTYPE_TR)
  293. {
  294. NdisMoveMemory(
  295. &pCf->SourceMacAddress.Byte,
  296. &pElan->MacAddressTr,
  297. sizeof(MAC_ADDRESS)
  298. );
  299. }
  300. else
  301. {
  302. DBGP((0, "%d Send Join with MAC addr: %s\n",
  303. pElan->ElanNumber,
  304. MacAddrToString(&pElan->MacAddressEth)));
  305. NdisMoveMemory(
  306. &pCf->SourceMacAddress.Byte,
  307. &pElan->MacAddressEth,
  308. sizeof(MAC_ADDRESS)
  309. );
  310. }
  311. NdisMoveMemory(
  312. &pCf->SourceAtmAddr,
  313. &pElan->AtmAddress.Address,
  314. ATM_ADDRESS_LENGTH
  315. );
  316. pCf->LanType = pElan->LanType;
  317. pCf->MaxFrameSize = pElan->MaxFrameSizeCode;
  318. pCf->ElanNameSize = pElan->ElanNameSize;
  319. NdisMoveMemory(
  320. &pCf->ElanName,
  321. pElan->ElanName,
  322. LANE_ELANNAME_SIZE_MAX
  323. );
  324. //
  325. // Link the ndis buffer to the ndis packet
  326. //
  327. NdisChainBufferAtFront(pNdisPacket, pNdisBuffer);
  328. //
  329. // Reacquire VC lock and if VC still connected send packet
  330. //
  331. ACQUIRE_VC_LOCK(pVc);
  332. if (IS_FLAG_SET(
  333. pVc->Flags,
  334. VC_CALL_STATE_MASK,
  335. VC_CALL_STATE_ACTIVE))
  336. {
  337. AtmLaneSendPacketOnVc(pVc, pNdisPacket, FALSE);
  338. //
  339. // VC lock released in above
  340. //
  341. }
  342. else
  343. {
  344. Status = NDIS_STATUS_FAILURE;
  345. RELEASE_VC_LOCK(pVc);
  346. }
  347. }
  348. while (FALSE);
  349. //
  350. // Remove temp VC reference
  351. //
  352. if (pVc != NULL_PATMLANE_VC)
  353. {
  354. ACQUIRE_VC_LOCK(pVc);
  355. rc = AtmLaneDereferenceVc(pVc, "temp");
  356. if (rc > 0)
  357. {
  358. RELEASE_VC_LOCK(pVc);
  359. }
  360. //
  361. // else VC is gone
  362. //
  363. }
  364. //
  365. // Cleanup if failure
  366. //
  367. if (Status != NDIS_STATUS_SUCCESS)
  368. {
  369. if (pNdisPacket != (PNDIS_PACKET)NULL)
  370. {
  371. AtmLaneFreeProtoPacket(pElan, pNdisPacket);
  372. }
  373. if (pNdisBuffer != (PNDIS_BUFFER)NULL)
  374. {
  375. AtmLaneFreeProtoBuffer(pElan, pNdisBuffer);
  376. }
  377. }
  378. TRACEOUT(SendJoinRequest);
  379. return;
  380. }
  381. VOID
  382. AtmLaneSendArpRequest(
  383. IN PATMLANE_ELAN pElan,
  384. IN PATMLANE_MAC_ENTRY pMacEntry LOCKIN NOLOCKOUT
  385. )
  386. /*++
  387. Routine Description:
  388. Send an LE_ARP_REQUEST for a particular Mac Entry to the LES.
  389. Arguments:
  390. pElan - Pointer to ATMLANE elan structure
  391. pMacEntry - Pointer to ATMLANE Mac Entry for which
  392. to send the LE_ARP_REQUEST.
  393. Return Value:
  394. None
  395. --*/
  396. {
  397. PATMLANE_ATM_ENTRY pAtmEntry;
  398. PATMLANE_VC pVc;
  399. PNDIS_PACKET pNdisPacket;
  400. PNDIS_BUFFER pNdisBuffer;
  401. PUCHAR pPkt;
  402. LANE_CONTROL_FRAME UNALIGNED * pCf;
  403. ULONG ulTemp;
  404. NDIS_STATUS Status;
  405. ULONG rc;
  406. BOOLEAN MacEntryLockReleased;
  407. TRACEIN(SendArpRequest);
  408. DBGP((3, "SendArpRequest: Elan %x MacEntry %x\n",
  409. pElan, pMacEntry));
  410. //
  411. // Initialize
  412. //
  413. pNdisPacket = (PNDIS_PACKET)NULL;
  414. pNdisBuffer = (PNDIS_BUFFER)NULL;
  415. Status = NDIS_STATUS_SUCCESS;
  416. pVc = NULL_PATMLANE_VC;
  417. MacEntryLockReleased = FALSE;
  418. do
  419. {
  420. ACQUIRE_ELAN_ATM_LIST_LOCK(pElan);
  421. pAtmEntry = pElan->pLesAtmEntry;
  422. if (pAtmEntry == NULL_PATMLANE_ATM_ENTRY)
  423. {
  424. RELEASE_ELAN_ATM_LIST_LOCK(pElan);
  425. Status = NDIS_STATUS_FAILURE;
  426. break;
  427. }
  428. ACQUIRE_ATM_ENTRY_LOCK_DPC(pAtmEntry);
  429. pVc = pAtmEntry->pVcList;
  430. if (pVc == NULL_PATMLANE_VC)
  431. {
  432. RELEASE_ATM_ENTRY_LOCK_DPC(pAtmEntry);
  433. RELEASE_ELAN_ATM_LIST_LOCK(pElan);
  434. break;
  435. }
  436. //
  437. // Reference the VC to keep it around
  438. //
  439. ACQUIRE_VC_LOCK_DPC(pVc);
  440. AtmLaneReferenceVc(pVc, "temp");
  441. RELEASE_VC_LOCK_DPC(pVc);
  442. RELEASE_ATM_ENTRY_LOCK_DPC(pAtmEntry);
  443. RELEASE_ELAN_ATM_LIST_LOCK(pElan);
  444. //
  445. // Allocate the Ndis packet header.
  446. //
  447. pNdisPacket = AtmLaneAllocProtoPacket(pElan);
  448. if ((PNDIS_PACKET)NULL == pNdisPacket)
  449. {
  450. DBGP((0, "SendArpRequest: allocate packet failed\n"));
  451. Status = NDIS_STATUS_RESOURCES;
  452. break;
  453. }
  454. //
  455. // Allocate the protocol buffer
  456. //
  457. pNdisBuffer = AtmLaneAllocateProtoBuffer(
  458. pElan,
  459. pElan->ProtocolBufSize,
  460. &(pPkt)
  461. );
  462. if ((PNDIS_BUFFER)NULL == pNdisBuffer)
  463. {
  464. DBGP((0, "SendArpRequest: allocate proto buffer failed\n"));
  465. Status = NDIS_STATUS_RESOURCES;
  466. break;
  467. }
  468. //
  469. // Fill in the packet with LE_ARP_REQUEST
  470. //
  471. NdisZeroMemory(pPkt, pElan->ProtocolBufSize);
  472. pCf = (PLANE_CONTROL_FRAME)pPkt;
  473. pCf->Marker = LANE_CONTROL_MARKER;
  474. pCf->Protocol = LANE_PROTOCOL;
  475. pCf->Version = LANE_VERSION;
  476. pCf->OpCode = LANE_ARP_REQUEST;
  477. ulTemp = NdisInterlockedIncrement(&pElan->TransactionId);
  478. pCf->Tid = SWAPULONG(ulTemp);
  479. pCf->LecId = pElan->LecId; // already swapped
  480. //
  481. // Leave SourceMacAddress zero (not present).
  482. // TargetMacAddress is what we are looking for!
  483. //
  484. pCf->TargetMacAddress.Type = (USHORT) pMacEntry->MacAddrType;
  485. NdisMoveMemory(
  486. &pCf->TargetMacAddress.Byte,
  487. &pMacEntry->MacAddress,
  488. sizeof(MAC_ADDRESS)
  489. );
  490. //
  491. // SourceAtmAddr is the Elan's
  492. //
  493. NdisMoveMemory(
  494. &pCf->SourceAtmAddr,
  495. &pElan->AtmAddress.Address,
  496. ATM_ADDRESS_LENGTH
  497. );
  498. //
  499. // Store swapped Tid in MacEntry for later matching!
  500. //
  501. pMacEntry->ArpTid = SWAPULONG(ulTemp);
  502. RELEASE_MAC_ENTRY_LOCK(pMacEntry);
  503. MacEntryLockReleased = TRUE;
  504. //
  505. // Link the ndis buffer to the ndis packet
  506. //
  507. NdisChainBufferAtFront(pNdisPacket, pNdisBuffer);
  508. //
  509. // Reacquire VC lock and if VC still connected send packet
  510. //
  511. ACQUIRE_VC_LOCK(pVc);
  512. if (IS_FLAG_SET(
  513. pVc->Flags,
  514. VC_CALL_STATE_MASK,
  515. VC_CALL_STATE_ACTIVE))
  516. {
  517. DBGP((2, "SendArpRequest: %s Sending ARP Request: Atm Entry %x pVc %x\n",
  518. MacAddrToString(&pMacEntry->MacAddress), pAtmEntry, pVc));
  519. AtmLaneSendPacketOnVc(pVc, pNdisPacket, FALSE);
  520. //
  521. // VC lock released in above
  522. //
  523. }
  524. else
  525. {
  526. Status = NDIS_STATUS_FAILURE;
  527. RELEASE_VC_LOCK(pVc);
  528. }
  529. }
  530. while (FALSE);
  531. if (!MacEntryLockReleased)
  532. {
  533. RELEASE_MAC_ENTRY_LOCK(pMacEntry);
  534. }
  535. //
  536. // Remove temp VC reference
  537. //
  538. if (pVc != NULL_PATMLANE_VC)
  539. {
  540. ACQUIRE_VC_LOCK(pVc);
  541. rc = AtmLaneDereferenceVc(pVc, "temp");
  542. if (rc > 0)
  543. {
  544. RELEASE_VC_LOCK(pVc);
  545. }
  546. //
  547. // else VC is gone
  548. //
  549. }
  550. //
  551. // Cleanup if failure
  552. //
  553. if (Status != NDIS_STATUS_SUCCESS)
  554. {
  555. if (pNdisPacket != (PNDIS_PACKET)NULL)
  556. {
  557. AtmLaneFreeProtoPacket(pElan, pNdisPacket);
  558. }
  559. if (pNdisBuffer != (PNDIS_BUFFER)NULL)
  560. {
  561. AtmLaneFreeProtoBuffer(pElan, pNdisBuffer);
  562. }
  563. }
  564. TRACEOUT(SendArpRequest);
  565. return;
  566. }
  567. VOID
  568. AtmLaneSendReadyQuery(
  569. IN PATMLANE_ELAN pElan,
  570. IN PATMLANE_VC pVc LOCKIN NOLOCKOUT
  571. )
  572. /*++
  573. Routine Description:
  574. Sends a READY_QUERY frame on the VC.
  575. It is assumed that caller holds a lock on the VC structure
  576. and it will be released here.
  577. Arguments:
  578. pElan - Pointer to ATMLANE elan structure
  579. pVc - Pointer to the ATMLANE VC structure
  580. on which to send the frame.
  581. Return Value:
  582. None
  583. --*/
  584. {
  585. PNDIS_PACKET pNdisPacket;
  586. PNDIS_BUFFER pNdisBuffer;
  587. ULONG TotalLength;
  588. ULONG BufferLength;
  589. PLANE_READY_FRAME pQueryRf;
  590. NDIS_STATUS Status;
  591. TRACEIN(SendReadyQuery);
  592. //
  593. // Initialize
  594. //
  595. pNdisPacket = (PNDIS_PACKET)NULL;
  596. pNdisBuffer = (PNDIS_BUFFER)NULL;
  597. Status = NDIS_STATUS_SUCCESS;
  598. do
  599. {
  600. //
  601. // Allocate the Ndis packet header.
  602. //
  603. pNdisPacket = AtmLaneAllocProtoPacket(pElan);
  604. if ((PNDIS_PACKET)NULL == pNdisPacket)
  605. {
  606. DBGP((0, "SendReadyQuery: allocate packet failed\n"));
  607. Status = NDIS_STATUS_RESOURCES;
  608. break;
  609. }
  610. //
  611. // Allocate the protocol buffer
  612. //
  613. pNdisBuffer = AtmLaneAllocateProtoBuffer(
  614. pElan,
  615. sizeof(LANE_READY_FRAME),
  616. &((PUCHAR)(pQueryRf))
  617. );
  618. if ((PNDIS_BUFFER)NULL == pNdisBuffer)
  619. {
  620. DBGP((0, "SendReadyQuery: allocate proto buffer failed\n"));
  621. Status = NDIS_STATUS_RESOURCES;
  622. break;
  623. }
  624. //
  625. // Fill in Indication
  626. //
  627. pQueryRf->Marker = LANE_CONTROL_MARKER;
  628. pQueryRf->Protocol = LANE_PROTOCOL;
  629. pQueryRf->Version = LANE_VERSION;
  630. pQueryRf->OpCode = LANE_READY_QUERY;
  631. //
  632. // Link the ndis buffer to the ndis packet
  633. //
  634. NdisChainBufferAtFront(pNdisPacket, pNdisBuffer);
  635. //
  636. // Send it
  637. //
  638. DBGP((2, "SendReadyQuery: pVc %x sending READY QUERY\n", pVc));
  639. AtmLaneSendPacketOnVc(pVc, pNdisPacket, FALSE);
  640. //
  641. // VC lock released in above
  642. //
  643. break;
  644. }
  645. while (FALSE);
  646. //
  647. // Cleanup if failure
  648. //
  649. if (Status != NDIS_STATUS_SUCCESS)
  650. {
  651. RELEASE_VC_LOCK(pVc);
  652. if (pNdisPacket != (PNDIS_PACKET)NULL)
  653. {
  654. AtmLaneFreeProtoPacket(pElan, pNdisPacket);
  655. }
  656. if (pNdisBuffer != (PNDIS_BUFFER)NULL)
  657. {
  658. AtmLaneFreeProtoBuffer(pElan, pNdisBuffer);
  659. }
  660. }
  661. TRACEOUT(SendReadyQuery);
  662. return;
  663. }
  664. VOID
  665. AtmLaneSendReadyIndication(
  666. IN PATMLANE_ELAN pElan,
  667. IN PATMLANE_VC pVc LOCKIN NOLOCKOUT
  668. )
  669. /*++
  670. Routine Description:
  671. Sends a ready indication frame on the VC.
  672. It is assumed that caller holds a lock on the VC structure
  673. and it will be released here.
  674. Arguments:
  675. pElan - Pointer to ATMLANE elan structure
  676. pVc - Pointer to the ATMLANE VC structure
  677. on which to send the frame.
  678. Return Value:
  679. None
  680. --*/
  681. {
  682. ULONG TotalLength;
  683. ULONG BufferLength;
  684. PLANE_READY_FRAME pIndRf;
  685. PNDIS_PACKET pNdisPacket;
  686. PNDIS_BUFFER pNdisBuffer;
  687. NDIS_STATUS Status;
  688. TRACEIN(SendReadyIndication);
  689. //
  690. // Initialize
  691. //
  692. pNdisPacket = (PNDIS_PACKET)NULL;
  693. pNdisBuffer = (PNDIS_BUFFER)NULL;
  694. Status = NDIS_STATUS_SUCCESS;
  695. do
  696. {
  697. //
  698. // Allocate the Ndis packet header.
  699. //
  700. pNdisPacket = AtmLaneAllocProtoPacket(pElan);
  701. if ((PNDIS_PACKET)NULL == pNdisPacket)
  702. {
  703. DBGP((0, "SendReadyIndication: allocate packet failed\n"));
  704. Status = NDIS_STATUS_RESOURCES;
  705. break;
  706. }
  707. //
  708. // Allocate the protocol buffer
  709. //
  710. pNdisBuffer = AtmLaneAllocateProtoBuffer(
  711. pElan,
  712. sizeof(LANE_READY_FRAME),
  713. &((PUCHAR)(pIndRf))
  714. );
  715. if ((PNDIS_BUFFER)NULL == pNdisBuffer)
  716. {
  717. DBGP((0, "SendReadyIndication: allocate proto buffer failed\n"));
  718. Status = NDIS_STATUS_RESOURCES;
  719. break;
  720. }
  721. //
  722. // Fill in Indication
  723. //
  724. pIndRf->Marker = LANE_CONTROL_MARKER;
  725. pIndRf->Protocol = LANE_PROTOCOL;
  726. pIndRf->Version = LANE_VERSION;
  727. pIndRf->OpCode = LANE_READY_IND;
  728. //
  729. // Link the ndis buffer to the ndis packet
  730. //
  731. NdisChainBufferAtFront(pNdisPacket, pNdisBuffer);
  732. //
  733. // Send it
  734. //
  735. DBGP((2, "SendReadyIndication: pVc %x sending READY INDICATION\n", pVc));
  736. AtmLaneSendPacketOnVc(pVc, pNdisPacket, FALSE);
  737. //
  738. // VC lock released in above
  739. //
  740. break;
  741. }
  742. while (FALSE);
  743. //
  744. // Cleanup if failure
  745. //
  746. if (Status != NDIS_STATUS_SUCCESS)
  747. {
  748. RELEASE_VC_LOCK(pVc);
  749. if (pNdisPacket != (PNDIS_PACKET)NULL)
  750. {
  751. AtmLaneFreeProtoPacket(pElan, pNdisPacket);
  752. }
  753. if (pNdisBuffer != (PNDIS_BUFFER)NULL)
  754. {
  755. AtmLaneFreeProtoBuffer(pElan, pNdisBuffer);
  756. }
  757. }
  758. TRACEOUT(SendReadyIndication);
  759. return;
  760. }
  761. VOID
  762. AtmLaneSendFlushRequest(
  763. IN PATMLANE_ELAN pElan,
  764. IN PATMLANE_MAC_ENTRY pMacEntry LOCKIN NOLOCKOUT,
  765. IN PATMLANE_ATM_ENTRY pAtmEntry
  766. )
  767. /*++
  768. Routine Description:
  769. Sends a flush request to the BUS for a particular MAC Entry
  770. using the destination ATM address in the specified ATM Entry.
  771. Arguments:
  772. pElan - Pointer to ATMLANE Elan structure
  773. pMacEntry - Pointer to ATMLANE Mac entry structure
  774. pAtmEntry - Pointer to ATMLANE Atm entry structure
  775. Return Value:
  776. None
  777. --*/
  778. {
  779. PATMLANE_ATM_ENTRY pBusAtmEntry;
  780. PATMLANE_VC pVc;
  781. ULONG TotalLength;
  782. ULONG BufferLength;
  783. ULONG ulTemp;
  784. PLANE_CONTROL_FRAME pCf;
  785. PNDIS_PACKET pNdisPacket;
  786. PNDIS_BUFFER pNdisBuffer;
  787. NDIS_STATUS Status;
  788. ULONG rc;
  789. BOOLEAN MacEntryLockReleased;
  790. TRACEIN(SendFlushRequest);
  791. //
  792. // Initialize
  793. //
  794. pNdisPacket = (PNDIS_PACKET)NULL;
  795. pNdisBuffer = (PNDIS_BUFFER)NULL;
  796. Status = NDIS_STATUS_SUCCESS;
  797. pVc = NULL_PATMLANE_VC;
  798. MacEntryLockReleased = FALSE;
  799. do
  800. {
  801. ACQUIRE_ELAN_ATM_LIST_LOCK(pElan);
  802. pBusAtmEntry = pElan->pBusAtmEntry;
  803. if (pBusAtmEntry == NULL_PATMLANE_ATM_ENTRY)
  804. {
  805. RELEASE_ELAN_ATM_LIST_LOCK(pElan);
  806. Status = NDIS_STATUS_FAILURE;
  807. break;
  808. }
  809. ACQUIRE_ATM_ENTRY_LOCK_DPC(pBusAtmEntry);
  810. pVc = pBusAtmEntry->pVcList;
  811. if (pVc == NULL_PATMLANE_VC)
  812. {
  813. RELEASE_ATM_ENTRY_LOCK_DPC(pBusAtmEntry);
  814. RELEASE_ELAN_ATM_LIST_LOCK(pElan);
  815. break;
  816. }
  817. //
  818. // Reference the VC to keep it around
  819. //
  820. ACQUIRE_VC_LOCK_DPC(pVc);
  821. AtmLaneReferenceVc(pVc, "temp");
  822. RELEASE_VC_LOCK_DPC(pVc);
  823. RELEASE_ATM_ENTRY_LOCK_DPC(pBusAtmEntry);
  824. RELEASE_ELAN_ATM_LIST_LOCK(pElan);
  825. //
  826. // Allocate the Ndis packet header.
  827. //
  828. pNdisPacket = AtmLaneAllocProtoPacket(pElan);
  829. if ((PNDIS_PACKET)NULL == pNdisPacket)
  830. {
  831. DBGP((0, "SendFlushRequest: allocate packet failed\n"));
  832. Status = NDIS_STATUS_RESOURCES;
  833. break;
  834. }
  835. //
  836. // Allocate the protocol buffer
  837. //
  838. pNdisBuffer = AtmLaneAllocateProtoBuffer(
  839. pElan,
  840. sizeof(LANE_CONTROL_FRAME),
  841. &((PUCHAR)(pCf))
  842. );
  843. if ((PNDIS_BUFFER)NULL == pNdisBuffer)
  844. {
  845. DBGP((0, "SendFlushRequest: allocate proto buffer failed\n"));
  846. Status = NDIS_STATUS_RESOURCES;
  847. break;
  848. }
  849. //
  850. // Fill in Flush Request
  851. //
  852. NdisZeroMemory((PUCHAR)pCf, sizeof(LANE_CONTROL_FRAME));
  853. pCf->Marker = LANE_CONTROL_MARKER;
  854. pCf->Protocol = LANE_PROTOCOL;
  855. pCf->Version = LANE_VERSION;
  856. pCf->OpCode = LANE_FLUSH_REQUEST;
  857. ulTemp = NdisInterlockedIncrement(&pElan->TransactionId);
  858. pCf->Tid = SWAPULONG(ulTemp);
  859. pCf->LecId = pElan->LecId; // already swapped
  860. NdisMoveMemory(
  861. &pCf->SourceAtmAddr,
  862. &pElan->AtmAddress.Address,
  863. ATM_ADDRESS_LENGTH
  864. );
  865. NdisMoveMemory(
  866. &pCf->TargetAtmAddr,
  867. &pAtmEntry->AtmAddress.Address,
  868. ATM_ADDRESS_LENGTH
  869. );
  870. //
  871. // Store swapped Tid in MacEntry for later matching!
  872. //
  873. pMacEntry->FlushTid = SWAPULONG(ulTemp);
  874. RELEASE_MAC_ENTRY_LOCK(pMacEntry);
  875. MacEntryLockReleased = TRUE;
  876. //
  877. // Link the ndis buffer to the ndis packet
  878. //
  879. NdisChainBufferAtFront(pNdisPacket, pNdisBuffer);
  880. //
  881. // Reacquire VC lock and if VC still connected send packet
  882. //
  883. ACQUIRE_VC_LOCK(pVc);
  884. if (IS_FLAG_SET(
  885. pVc->Flags,
  886. VC_CALL_STATE_MASK,
  887. VC_CALL_STATE_ACTIVE))
  888. {
  889. DBGP((2, "SendFlushRequest: sending FLUSH REQUEST for MacEntry %x\n", pMacEntry));
  890. AtmLaneSendPacketOnVc(pVc, pNdisPacket, FALSE);
  891. //
  892. // VC lock released in above
  893. //
  894. }
  895. else
  896. {
  897. Status = NDIS_STATUS_FAILURE;
  898. RELEASE_VC_LOCK(pVc);
  899. }
  900. break;
  901. }
  902. while (FALSE);
  903. if (!MacEntryLockReleased)
  904. {
  905. RELEASE_MAC_ENTRY_LOCK(pMacEntry);
  906. }
  907. //
  908. // Remove temp VC reference
  909. //
  910. if (pVc != NULL_PATMLANE_VC)
  911. {
  912. ACQUIRE_VC_LOCK(pVc);
  913. rc = AtmLaneDereferenceVc(pVc, "temp");
  914. if (rc > 0)
  915. {
  916. RELEASE_VC_LOCK(pVc);
  917. }
  918. //
  919. // else VC is gone
  920. //
  921. }
  922. //
  923. // Cleanup if failure
  924. //
  925. if (Status != NDIS_STATUS_SUCCESS)
  926. {
  927. if (pNdisPacket != (PNDIS_PACKET)NULL)
  928. {
  929. AtmLaneFreeProtoPacket(pElan, pNdisPacket);
  930. }
  931. if (pNdisBuffer != (PNDIS_BUFFER)NULL)
  932. {
  933. AtmLaneFreeProtoBuffer(pElan, pNdisBuffer);
  934. }
  935. }
  936. TRACEOUT(SendFlushRequest);
  937. return;
  938. }
  939. VOID
  940. AtmLaneConfigureResponseHandler(
  941. IN PATMLANE_ELAN pElan,
  942. IN PATMLANE_VC pVc,
  943. IN PNDIS_PACKET pNdisPacket
  944. )
  945. /*++
  946. Routine Description:
  947. Handles incoming packets from the Configuration Direct VC.
  948. Arguments:
  949. pElan - Pointer to ATMLANE Elan structure
  950. pVc - Pointer to ATMLANE Vc structure
  951. pNdisPacket - Pointer to the Ndis Packet
  952. Return Value:
  953. None
  954. --*/
  955. {
  956. PNDIS_BUFFER pNdisBuffer;
  957. ULONG TotalLength;
  958. ULONG BufferLength;
  959. PLANE_CONTROL_FRAME pCf;
  960. ULONG NumTlvs;
  961. ULONG UNALIGNED * pType;
  962. PUCHAR pLength;
  963. USHORT UNALIGNED * pUShort;
  964. ULONG UNALIGNED * pULong;
  965. NDIS_STATUS EventCode;
  966. USHORT NumStrings;
  967. PWCHAR StringList[2];
  968. BOOLEAN FreeString[2];
  969. TRACEIN(ConfigureResponseHandler);
  970. do
  971. {
  972. //
  973. // Get initial buffer and total length of packet
  974. //
  975. NdisGetFirstBufferFromPacket(
  976. pNdisPacket,
  977. &pNdisBuffer,
  978. (PVOID *)&pCf,
  979. &BufferLength,
  980. &TotalLength);
  981. //
  982. // Packet must be at least the size of a control frame.
  983. // Could be larger with optional TLVs.
  984. //
  985. if (TotalLength < sizeof(LANE_CONTROL_FRAME))
  986. {
  987. DBGP((0,
  988. "ConfigureResponseHandler: Received runt control frame (%d)\n",
  989. TotalLength));
  990. break;
  991. }
  992. //
  993. // If buffer is not at least the size of a control frame
  994. // we currently will not deal with it.
  995. //
  996. if (BufferLength < sizeof(LANE_CONTROL_FRAME))
  997. {
  998. DBGP((0, "ConfigureResponseHandler: Control frame is fragmented\n"));
  999. break;
  1000. }
  1001. //
  1002. // Verify that this is really a configure reponse
  1003. //
  1004. if (pCf->Marker != LANE_CONTROL_MARKER ||
  1005. pCf->Protocol != LANE_PROTOCOL ||
  1006. pCf->Version != LANE_VERSION ||
  1007. pCf->OpCode != LANE_CONFIGURE_RESPONSE)
  1008. {
  1009. DBGP((0, "ConfigureResponseHandler: Not a configure response\n"));
  1010. //DbgPrintHexDump(0, (PUCHAR)pCf, BufferLength);
  1011. break;
  1012. }
  1013. //
  1014. // Check for successful configure status
  1015. //
  1016. if (pCf->Status != LANE_STATUS_SUCCESS)
  1017. {
  1018. //
  1019. // Failure
  1020. //
  1021. DBGP((0,
  1022. "ConfigureResponseHandler: Unsuccessful Status 0x%x (%d)\n",
  1023. SWAPUSHORT(pCf->Status), SWAPUSHORT(pCf->Status)));
  1024. //
  1025. // Setup to log event
  1026. //
  1027. StringList[0] = NULL;
  1028. FreeString[0] = FALSE;
  1029. StringList[1] = NULL;
  1030. FreeString[1] = FALSE;
  1031. switch (pCf->Status)
  1032. {
  1033. case LANE_STATUS_VERSNOSUPP:
  1034. EventCode = EVENT_ATMLANE_CFGREQ_FAIL_VERSNOSUPP;
  1035. StringList[0] = pElan->CfgElanName.Buffer;
  1036. NumStrings = 1;
  1037. break;
  1038. case LANE_STATUS_REQPARMINVAL:
  1039. EventCode = EVENT_ATMLANE_CFGREQ_FAIL_REQPARMINVAL;
  1040. StringList[0] = pElan->CfgElanName.Buffer;
  1041. NumStrings = 1;
  1042. break;
  1043. case LANE_STATUS_INSUFFRES:
  1044. EventCode = EVENT_ATMLANE_CFGREQ_FAIL_INSUFFRES;
  1045. StringList[0] = pElan->CfgElanName.Buffer;
  1046. NumStrings = 1;
  1047. break;
  1048. case LANE_STATUS_NOACCESS:
  1049. EventCode = EVENT_ATMLANE_CFGREQ_FAIL_NOACCESS;
  1050. StringList[0] = pElan->CfgElanName.Buffer;
  1051. NumStrings = 1;
  1052. break;
  1053. case LANE_STATUS_REQIDINVAL:
  1054. EventCode = EVENT_ATMLANE_CFGREQ_FAIL_REQIDINVAL;
  1055. StringList[0] = pElan->CfgElanName.Buffer;
  1056. NumStrings = 1;
  1057. break;
  1058. case LANE_STATUS_LANDESTINVAL:
  1059. EventCode = EVENT_ATMLANE_CFGREQ_FAIL_LANDESTINVAL;
  1060. StringList[0] = pElan->CfgElanName.Buffer;
  1061. if (pElan->LanType == LANE_LANTYPE_ETH)
  1062. {
  1063. StringList[1] = AtmLaneMacAddrToString(&pElan->MacAddressEth);
  1064. FreeString[1] = TRUE;
  1065. }
  1066. else
  1067. {
  1068. StringList[1] = AtmLaneMacAddrToString(&pElan->MacAddressTr);
  1069. FreeString[1] = TRUE;
  1070. }
  1071. NumStrings = 2;
  1072. break;
  1073. case LANE_STATUS_ATMADDRINVAL:
  1074. EventCode = EVENT_ATMLANE_CFGREQ_FAIL_ATMADDRINVAL;
  1075. StringList[0] = pElan->CfgElanName.Buffer;
  1076. StringList[1] = AtmLaneAtmAddrToString(&pElan->AtmAddress);
  1077. FreeString[1] = TRUE;
  1078. NumStrings = 2;
  1079. break;
  1080. case LANE_STATUS_NOCONF:
  1081. EventCode = EVENT_ATMLANE_CFGREQ_FAIL_NOCONF;
  1082. StringList[0] = pElan->CfgElanName.Buffer;
  1083. NumStrings = 1;
  1084. break;
  1085. case LANE_STATUS_CONFERROR:
  1086. EventCode = EVENT_ATMLANE_CFGREQ_FAIL_CONFERROR;
  1087. StringList[0] = pElan->CfgElanName.Buffer;
  1088. NumStrings = 1;
  1089. break;
  1090. case LANE_STATUS_INSUFFINFO:
  1091. default:
  1092. EventCode = EVENT_ATMLANE_CFGREQ_FAIL_INSUFFINFO;
  1093. StringList[0] = pElan->CfgElanName.Buffer;
  1094. NumStrings = 1;
  1095. break;
  1096. }
  1097. //
  1098. // If not repeated event on this ELAN write the event to log
  1099. //
  1100. if (pElan->LastEventCode != EventCode)
  1101. {
  1102. pElan->LastEventCode = EventCode;
  1103. (VOID) NdisWriteEventLogEntry(
  1104. pAtmLaneGlobalInfo->pDriverObject,
  1105. EventCode, 0, NumStrings, StringList, 0, NULL);
  1106. }
  1107. //
  1108. // Free any strings allocated
  1109. //
  1110. if (FreeString[0] && StringList[0] != NULL)
  1111. {
  1112. FREE_MEM(StringList[0]);
  1113. }
  1114. if (FreeString[1] && StringList[1] != NULL)
  1115. {
  1116. FREE_MEM(StringList[1]);
  1117. }
  1118. //
  1119. // Notify event handler of failure
  1120. //
  1121. ACQUIRE_ELAN_LOCK(pElan);
  1122. AtmLaneQueueElanEvent(pElan, ELAN_EVENT_CONFIGURE_RESPONSE, NDIS_STATUS_FAILURE);
  1123. RELEASE_ELAN_LOCK(pElan);
  1124. break;
  1125. }
  1126. //
  1127. // Successful Configure Response
  1128. //
  1129. //
  1130. // Extract the required Elan parameters
  1131. //
  1132. ACQUIRE_ELAN_LOCK(pElan);
  1133. pElan->LanType = pCf->LanType;
  1134. DBGP((1, "%d LanType = %x\n", pElan->ElanNumber, pElan->LanType));
  1135. if (pElan->LanType == LANE_LANTYPE_UNSPEC)
  1136. {
  1137. DBGP((1, "Defaulting to LanType 1 (Ethernet/802.3)\n"));
  1138. pElan->LanType = LANE_LANTYPE_ETH;
  1139. }
  1140. pElan->MaxFrameSizeCode = pCf->MaxFrameSize;
  1141. DBGP((1, "%d MaxFrameSizeCode = %x\n", pElan->ElanNumber, pElan->MaxFrameSizeCode));
  1142. if (pElan->MaxFrameSizeCode == LANE_MAXFRAMESIZE_CODE_UNSPEC)
  1143. {
  1144. DBGP((1, "Defaulting to MaxFrameSizeCode 1 (1516)\n"));
  1145. pElan->MaxFrameSizeCode = LANE_MAXFRAMESIZE_CODE_1516;
  1146. }
  1147. switch (pElan->MaxFrameSizeCode)
  1148. {
  1149. case LANE_MAXFRAMESIZE_CODE_18190:
  1150. pElan->MaxFrameSize = 18190;
  1151. break;
  1152. case LANE_MAXFRAMESIZE_CODE_9234:
  1153. pElan->MaxFrameSize = 9234;
  1154. break;
  1155. case LANE_MAXFRAMESIZE_CODE_4544:
  1156. pElan->MaxFrameSize = 4544;
  1157. break;
  1158. case LANE_MAXFRAMESIZE_CODE_1516:
  1159. case LANE_MAXFRAMESIZE_CODE_UNSPEC:
  1160. default:
  1161. pElan->MaxFrameSize = 1516;
  1162. break;
  1163. }
  1164. if (pElan->LanType == LANE_LANTYPE_ETH)
  1165. {
  1166. pElan->MinFrameSize = LANE_MIN_ETHPACKET;
  1167. }
  1168. else
  1169. {
  1170. pElan->MinFrameSize = LANE_MIN_TRPACKET;
  1171. }
  1172. NdisZeroMemory(
  1173. pElan->ElanName,
  1174. LANE_ELANNAME_SIZE_MAX);
  1175. NdisMoveMemory(
  1176. pElan->ElanName,
  1177. pCf->ElanName,
  1178. pCf->ElanNameSize);
  1179. pElan->ElanNameSize = pCf->ElanNameSize;
  1180. pElan->LesAddress.AddressType = ATM_NSAP;
  1181. pElan->LesAddress.NumberOfDigits = ATM_ADDRESS_LENGTH;
  1182. NdisMoveMemory(
  1183. pElan->LesAddress.Address,
  1184. &pCf->TargetAtmAddr,
  1185. ATM_ADDRESS_LENGTH);
  1186. DBGP((1, "%d LES ATMAddr: %s\n",
  1187. pElan->ElanNumber,
  1188. AtmAddrToString(pElan->LesAddress.Address)));
  1189. //
  1190. // Check for TLVs
  1191. //
  1192. if (pCf->NumTlvs > 0)
  1193. {
  1194. DBGP((2, "ConfigureReponseHandler: NumTlvs is %d\n", pCf->NumTlvs));
  1195. NumTlvs = pCf->NumTlvs;
  1196. pType = (ULONG UNALIGNED *)
  1197. (((PUCHAR)pCf) + sizeof(LANE_CONTROL_FRAME));
  1198. while (NumTlvs--)
  1199. {
  1200. pLength = (PUCHAR)pType + sizeof(*pType);
  1201. pUShort = (USHORT UNALIGNED *)
  1202. (((PUCHAR)pLength) + sizeof(*pLength));
  1203. pULong = (ULONG UNALIGNED *)
  1204. (((PUCHAR)pLength) + sizeof(*pLength));
  1205. switch (*pType)
  1206. {
  1207. case LANE_CFG_CONTROL_TIMEOUT: // C7
  1208. pElan->ControlTimeout = SWAPUSHORT(*pUShort);
  1209. if (pElan->ControlTimeout < LANE_C7_MIN ||
  1210. pElan->ControlTimeout > LANE_C7_MAX)
  1211. pElan->ControlTimeout = LANE_C7_DEF;
  1212. DBGP((1, "%d Control Time-out %d\n",
  1213. pElan->ElanNumber,
  1214. pElan->ControlTimeout));
  1215. break;
  1216. case LANE_CFG_UNK_FRAME_COUNT: // C10
  1217. pElan->MaxUnkFrameCount = SWAPUSHORT(*pUShort);
  1218. if (pElan->MaxUnkFrameCount < LANE_C10_MIN ||
  1219. pElan->MaxUnkFrameCount > LANE_C10_MAX)
  1220. pElan->MaxUnkFrameCount = LANE_C10_DEF;
  1221. DBGP((1, "%d Maximum Unknown Frame Count %d\n",
  1222. pElan->ElanNumber,
  1223. pElan->MaxUnkFrameCount));
  1224. break;
  1225. case LANE_CFG_UNK_FRAME_TIME: // C11
  1226. pElan->MaxUnkFrameTime = SWAPUSHORT(*pUShort);
  1227. if (pElan->MaxUnkFrameTime < LANE_C11_MIN ||
  1228. pElan->MaxUnkFrameTime > LANE_C11_MAX)
  1229. pElan->MaxUnkFrameTime = LANE_C11_DEF;
  1230. DBGP((1, "%d Maximum Unknown Frame Time %d\n",
  1231. pElan->ElanNumber,
  1232. pElan->MaxUnkFrameTime));
  1233. break;
  1234. case LANE_CFG_VCC_TIMEOUT: // C12
  1235. pElan->VccTimeout = SWAPULONG(*pULong);
  1236. if (pElan->VccTimeout < LANE_C12_MIN)
  1237. pElan->VccTimeout = LANE_C12_DEF;
  1238. DBGP((1, "%d VCC Timeout Period %d\n",
  1239. pElan->ElanNumber,
  1240. pElan->VccTimeout));
  1241. break;
  1242. case LANE_CFG_MAX_RETRY_COUNT: // C13
  1243. pElan->MaxRetryCount = SWAPUSHORT(*pUShort);
  1244. if (/* pElan->MaxRetryCount < LANE_C13_MIN || */
  1245. pElan->MaxRetryCount > LANE_C13_MAX)
  1246. pElan->MaxRetryCount = LANE_C13_DEF;
  1247. DBGP((1, "%d Maximum Retry Count %d\n",
  1248. pElan->ElanNumber,
  1249. pElan->MaxRetryCount));
  1250. break;
  1251. case LANE_CFG_AGING_TIME: // C17
  1252. pElan->AgingTime = SWAPULONG(*pULong);
  1253. if (pElan->AgingTime < LANE_C17_MIN ||
  1254. pElan->AgingTime > LANE_C17_MAX)
  1255. pElan->AgingTime = LANE_C17_DEF;
  1256. DBGP((1, "%d Aging Time %d\n",
  1257. pElan->ElanNumber,
  1258. pElan->AgingTime));
  1259. break;
  1260. case LANE_CFG_FWD_DELAY_TIME: // C18
  1261. pElan->ForwardDelayTime = SWAPUSHORT(*pUShort);
  1262. if (pElan->ForwardDelayTime < LANE_C18_MIN ||
  1263. pElan->ForwardDelayTime > LANE_C18_MAX)
  1264. pElan->ForwardDelayTime = LANE_C18_DEF;
  1265. DBGP((1, "%d Forward Delay Time %d\n",
  1266. pElan->ElanNumber,
  1267. pElan->ForwardDelayTime));
  1268. break;
  1269. case LANE_CFG_ARP_RESP_TIME: // C20
  1270. pElan->ArpResponseTime = SWAPUSHORT(*pUShort);
  1271. if (pElan->ArpResponseTime < LANE_C20_MIN ||
  1272. pElan->ArpResponseTime > LANE_C20_MAX)
  1273. pElan->ArpResponseTime = LANE_C20_DEF;
  1274. DBGP((1, "%d Arp Response Time %d\n",
  1275. pElan->ElanNumber,
  1276. pElan->ArpResponseTime));
  1277. break;
  1278. case LANE_CFG_FLUSH_TIMEOUT: // C21
  1279. pElan->FlushTimeout = SWAPUSHORT(*pUShort);
  1280. if (pElan->FlushTimeout < LANE_C21_MIN ||
  1281. pElan->FlushTimeout > LANE_C21_MAX)
  1282. pElan->FlushTimeout = LANE_C21_DEF;
  1283. DBGP((1, "%d Flush Time-out %d\n",
  1284. pElan->ElanNumber,
  1285. pElan->FlushTimeout));
  1286. break;
  1287. case LANE_CFG_PATH_SWITCH_DELAY: // C22
  1288. pElan->PathSwitchingDelay = SWAPUSHORT(*pUShort);
  1289. if (pElan->PathSwitchingDelay < LANE_C22_MIN ||
  1290. pElan->PathSwitchingDelay > LANE_C22_MAX)
  1291. pElan->PathSwitchingDelay = LANE_C22_DEF;
  1292. DBGP((1, "%d Path Switching Delay %d\n",
  1293. pElan->ElanNumber,
  1294. pElan->PathSwitchingDelay));
  1295. break;
  1296. case LANE_CFG_LOCAL_SEGMENT_ID: // C23
  1297. pElan->LocalSegmentId = SWAPUSHORT(*pUShort);
  1298. DBGP((1, "%d Local Segment ID %d\n",
  1299. pElan->ElanNumber,
  1300. pElan->LocalSegmentId));
  1301. break;
  1302. case LANE_CFG_MCAST_VCC_TYPE: // C24
  1303. pElan->McastSendVcType = SWAPUSHORT(*pUShort);
  1304. DBGP((1, "%d Mcast Send VCC Type %d\n",
  1305. pElan->ElanNumber,
  1306. pElan->McastSendVcType));
  1307. break;
  1308. case LANE_CFG_MCAST_VCC_AVG: // C25
  1309. pElan->McastSendVcAvgRate = SWAPULONG(*pULong);
  1310. DBGP((1, "%d Mcast Send VCC AvgRate %d\n",
  1311. pElan->ElanNumber,
  1312. pElan->McastSendVcAvgRate));
  1313. break;
  1314. case LANE_CFG_MCAST_VCC_PEAK: // C26
  1315. pElan->McastSendVcPeakRate = SWAPULONG(*pULong);
  1316. DBGP((1, "%d Mcast Send VCC PeakRate %d\n",
  1317. pElan->ElanNumber,
  1318. pElan->McastSendVcPeakRate));
  1319. break;
  1320. case LANE_CFG_CONN_COMPL_TIMER: // C28
  1321. pElan->ConnComplTimer = SWAPUSHORT(*pUShort);
  1322. if (pElan->ConnComplTimer < LANE_C28_MIN ||
  1323. pElan->ConnComplTimer > LANE_C28_MAX)
  1324. pElan->ConnComplTimer = LANE_C28_DEF;
  1325. DBGP((1, "%d Connection Completion Timer %d\n",
  1326. pElan->ElanNumber,
  1327. pElan->ConnComplTimer));
  1328. break;
  1329. }
  1330. pType = (ULONG UNALIGNED *)
  1331. (((PUCHAR)pType) + sizeof(pType) +
  1332. sizeof(*pLength) + *pLength);
  1333. } // while (NumTlvs--)
  1334. //
  1335. // Recalc the bus rate limiter parameters
  1336. //
  1337. pElan->LimitTime = pElan->MaxUnkFrameTime * 1000;
  1338. pElan->IncrTime = pElan->LimitTime / pElan->MaxUnkFrameCount;
  1339. }
  1340. //
  1341. // Notify event handler of success
  1342. //
  1343. AtmLaneQueueElanEvent(pElan, ELAN_EVENT_CONFIGURE_RESPONSE, NDIS_STATUS_SUCCESS);
  1344. RELEASE_ELAN_LOCK(pElan);
  1345. }
  1346. while (FALSE);
  1347. TRACEOUT(ConfigureResponsehandler);
  1348. return;
  1349. }
  1350. VOID
  1351. AtmLaneControlPacketHandler(
  1352. IN PATMLANE_ELAN pElan,
  1353. IN PATMLANE_VC pVc,
  1354. IN PNDIS_PACKET pNdisPacket
  1355. )
  1356. /*++
  1357. Routine Description:
  1358. Handles incoming packets from the control VC(s) to/from the LES.
  1359. Arguments:
  1360. pElan - Pointer to ATMLANE Elan structure
  1361. pVc - Pointer to ATMLANE Vc structure
  1362. pNdisPacket - Pointer to the Ndis Packet
  1363. Return Value:
  1364. None
  1365. --*/
  1366. {
  1367. PNDIS_BUFFER pNdisBuffer;
  1368. ULONG TotalLength;
  1369. ULONG BufferLength;
  1370. PLANE_CONTROL_FRAME pCf;
  1371. NDIS_STATUS Status;
  1372. TRACEIN(ControlPacketHandler);
  1373. do
  1374. {
  1375. //
  1376. // Get initial buffer and total length of packet
  1377. //
  1378. NdisGetFirstBufferFromPacket(
  1379. pNdisPacket,
  1380. &pNdisBuffer,
  1381. (PVOID *)&pCf,
  1382. &BufferLength,
  1383. &TotalLength);
  1384. //
  1385. // Packet must be at least the size of a control frame.
  1386. //
  1387. if (TotalLength < sizeof(LANE_CONTROL_FRAME))
  1388. {
  1389. DBGP((0,
  1390. "ConPacketHandler: Received runt control frame (%d)\n",
  1391. TotalLength));
  1392. break;
  1393. }
  1394. //
  1395. // If buffer is not at least the size of a control frame
  1396. // we currently will not deal with it.
  1397. //
  1398. if (BufferLength < sizeof(LANE_CONTROL_FRAME))
  1399. {
  1400. DBGP((0, "ConfigureResponseHandler: Control frame is fragmented\n"));
  1401. break;
  1402. }
  1403. //
  1404. // Verify that this is really a control packet
  1405. //
  1406. if (pCf->Marker != LANE_CONTROL_MARKER ||
  1407. pCf->Protocol != LANE_PROTOCOL ||
  1408. pCf->Version != LANE_VERSION)
  1409. {
  1410. DBGP((0, "ControlPacketHandler: Not a control packet!\n"));
  1411. //DbgPrintHexDump(0, (PUCHAR)pCf, BufferLength);
  1412. break;
  1413. }
  1414. //
  1415. // Now handle by type of control packet
  1416. //
  1417. switch (pCf->OpCode)
  1418. {
  1419. case LANE_JOIN_RESPONSE:
  1420. DBGP((2, "ControlPacketHandler: Join Response\n"));
  1421. AtmLaneJoinResponseHandler(pElan, pCf);
  1422. break;
  1423. case LANE_ARP_RESPONSE:
  1424. DBGP((2, "ControlPacketHandler: ARP Response\n"));
  1425. AtmLaneArpResponseHandler(pElan, pCf);
  1426. break;
  1427. case LANE_ARP_REQUEST:
  1428. DBGP((1, "ControlPacketHandler: ARP Request\n"));
  1429. AtmLaneArpRequestHandler(pElan, pCf);
  1430. break;
  1431. case LANE_TOPOLOGY_REQUEST:
  1432. DBGP((1, "ControlPacketHandler: TOPOLOGY Request\n"));
  1433. AtmLaneTopologyRequestHandler(pElan, pCf);
  1434. break;
  1435. case LANE_NARP_REQUEST:
  1436. DBGP((2, "ControlPacketHandler: NARP Request\n"));
  1437. // ignore these
  1438. break;
  1439. case LANE_FLUSH_RESPONSE:
  1440. DBGP((2, "ControlPacketHandler: FLUSH Response\n"));
  1441. AtmLaneFlushResponseHandler(pElan, pCf);
  1442. break;
  1443. default:
  1444. DBGP((0, "ControlPacketHandler: Unexpected OpCode %x!\n",
  1445. pCf->OpCode));
  1446. //DbgPrintHexDump(0, (PUCHAR)pCf, BufferLength);
  1447. break;
  1448. } // switch (pCf->OpCode)
  1449. break;
  1450. }
  1451. while (FALSE);
  1452. TRACEOUT(ControlPackethandler);
  1453. return;
  1454. }
  1455. VOID
  1456. AtmLaneJoinResponseHandler(
  1457. IN PATMLANE_ELAN pElan,
  1458. IN PLANE_CONTROL_FRAME pCf
  1459. )
  1460. /*++
  1461. Routine Description:
  1462. Handles incoming Join Response packets from the LES.
  1463. Arguments:
  1464. pElan - Pointer to ATMLANE Elan structure
  1465. pCf - Pointer to LANE Control Frame
  1466. Return Value:
  1467. None
  1468. --*/
  1469. {
  1470. PWCHAR StringList[2];
  1471. BOOLEAN FreeString[2];
  1472. NDIS_STATUS EventCode;
  1473. USHORT NumStrings;
  1474. TRACEIN(JoinResponseHandler);
  1475. ACQUIRE_ELAN_LOCK(pElan);
  1476. if (ELAN_STATE_JOIN == pElan->State)
  1477. {
  1478. //
  1479. // Only handle join response in JOIN state!
  1480. //
  1481. if (LANE_STATUS_SUCCESS == pCf->Status)
  1482. {
  1483. //
  1484. // Success.
  1485. //
  1486. // Extract the info we need
  1487. //
  1488. pElan->LecId = pCf->LecId; // leave in network byte order
  1489. DBGP((2,
  1490. "ControlPacketHandler: LECID %x\n",
  1491. SWAPUSHORT(pElan->LecId)));
  1492. AtmLaneQueueElanEvent(pElan, ELAN_EVENT_JOIN_RESPONSE, NDIS_STATUS_SUCCESS);
  1493. }
  1494. else
  1495. {
  1496. //
  1497. // Failure
  1498. //
  1499. DBGP((0,
  1500. "ControlPacketHandler: Unsuccessful Status (%d)\n",
  1501. pCf->Status));
  1502. //
  1503. // Setup to write error to event log
  1504. //
  1505. StringList[0] = NULL;
  1506. FreeString[0] = FALSE;
  1507. StringList[1] = NULL;
  1508. FreeString[1] = FALSE;
  1509. switch (pCf->Status)
  1510. {
  1511. case LANE_STATUS_VERSNOSUPP:
  1512. EventCode = EVENT_ATMLANE_JOINREQ_FAIL_VERSNOSUPP;
  1513. StringList[0] = pElan->CfgElanName.Buffer;
  1514. NumStrings = 1;
  1515. break;
  1516. case LANE_STATUS_DUPLANDEST:
  1517. EventCode = EVENT_ATMLANE_JOINREQ_FAIL_DUPLANDEST;
  1518. StringList[0] = pElan->CfgElanName.Buffer;
  1519. if (pElan->LanType == LANE_LANTYPE_ETH)
  1520. {
  1521. StringList[1] = AtmLaneMacAddrToString(&pElan->MacAddressEth);
  1522. FreeString[1] = TRUE;
  1523. }
  1524. else
  1525. {
  1526. StringList[1] = AtmLaneMacAddrToString(&pElan->MacAddressTr);
  1527. FreeString[1] = TRUE;
  1528. }
  1529. NumStrings = 2;
  1530. break;
  1531. case LANE_STATUS_DUPATMADDR:
  1532. EventCode = EVENT_ATMLANE_JOINREQ_FAIL_DUPATMADDR;
  1533. StringList[0] = pElan->CfgElanName.Buffer;
  1534. StringList[1] = AtmLaneAtmAddrToString(&pElan->AtmAddress);
  1535. FreeString[1] = TRUE;
  1536. NumStrings = 2;
  1537. break;
  1538. case LANE_STATUS_INSUFFRES:
  1539. EventCode = EVENT_ATMLANE_JOINREQ_FAIL_INSUFFRES;
  1540. StringList[0] = pElan->CfgElanName.Buffer;
  1541. NumStrings = 1;
  1542. break;
  1543. case LANE_STATUS_NOACCESS:
  1544. EventCode = EVENT_ATMLANE_JOINREQ_FAIL_NOACCESS;
  1545. StringList[0] = pElan->CfgElanName.Buffer;
  1546. NumStrings = 1;
  1547. break;
  1548. case LANE_STATUS_REQIDINVAL:
  1549. EventCode = EVENT_ATMLANE_JOINREQ_FAIL_REQIDINVAL;
  1550. StringList[0] = pElan->CfgElanName.Buffer;
  1551. NumStrings = 1;
  1552. break;
  1553. case LANE_STATUS_LANDESTINVAL:
  1554. EventCode = EVENT_ATMLANE_JOINREQ_FAIL_LANDESTINVAL;
  1555. StringList[0] = pElan->CfgElanName.Buffer;
  1556. if (pElan->LanType == LANE_LANTYPE_ETH)
  1557. {
  1558. StringList[1] = AtmLaneMacAddrToString(&pElan->MacAddressEth);
  1559. FreeString[1] = TRUE;
  1560. }
  1561. else
  1562. {
  1563. StringList[1] = AtmLaneMacAddrToString(&pElan->MacAddressTr);
  1564. FreeString[1] = TRUE;
  1565. }
  1566. NumStrings = 2;
  1567. break;
  1568. case LANE_STATUS_ATMADDRINVAL:
  1569. EventCode = EVENT_ATMLANE_JOINREQ_FAIL_ATMADDRINVAL;
  1570. StringList[0] = pElan->CfgElanName.Buffer;
  1571. StringList[1] = AtmLaneAtmAddrToString(&pElan->AtmAddress);
  1572. FreeString[1] = TRUE;
  1573. NumStrings = 2;
  1574. break;
  1575. case LANE_STATUS_REQPARMINVAL:
  1576. default:
  1577. EventCode = EVENT_ATMLANE_JOINREQ_FAIL_REQPARMINVAL;
  1578. StringList[0] = pElan->CfgElanName.Buffer;
  1579. NumStrings = 1;
  1580. break;
  1581. }
  1582. //
  1583. // If not repeated event on this ELAN write the event to log
  1584. //
  1585. if (pElan->LastEventCode != EventCode)
  1586. {
  1587. pElan->LastEventCode = EventCode;
  1588. (VOID) NdisWriteEventLogEntry(
  1589. pAtmLaneGlobalInfo->pDriverObject,
  1590. EventCode, 0, NumStrings, StringList, 0, NULL);
  1591. }
  1592. //
  1593. // Free any strings allocated
  1594. //
  1595. if (FreeString[0] && StringList[0] != NULL)
  1596. {
  1597. FREE_MEM(StringList[0]);
  1598. }
  1599. if (FreeString[1] && StringList[1] != NULL)
  1600. {
  1601. FREE_MEM(StringList[1]);
  1602. }
  1603. AtmLaneQueueElanEvent(pElan, ELAN_EVENT_JOIN_RESPONSE, NDIS_STATUS_FAILURE);
  1604. }
  1605. }
  1606. else
  1607. {
  1608. //
  1609. // else bad elan state - ignore packet
  1610. //
  1611. DBGP((0,
  1612. "ControlPacketHandler: Elan state wrong - Ignoring packet\n",
  1613. pCf->Status));
  1614. }
  1615. RELEASE_ELAN_LOCK(pElan);
  1616. TRACEOUT(JoinResponseHandler);
  1617. return;
  1618. }
  1619. VOID
  1620. AtmLaneReadyQueryHandler(
  1621. IN PATMLANE_ELAN pElan,
  1622. IN PATMLANE_VC pVc,
  1623. IN PNDIS_PACKET pQueryNdisPacket
  1624. )
  1625. /*++
  1626. Routine Description:
  1627. Handles incoming READY_QUERY packets from peers.
  1628. Arguments:
  1629. pElan - Pointer to ATMLANE Elan structure
  1630. pVc - Pointer to ATMLANE VC for this packet
  1631. pQueryNdisPacket - Pointer to the Ndis Packet
  1632. Return Value:
  1633. None
  1634. --*/
  1635. {
  1636. PNDIS_BUFFER pNdisBuffer;
  1637. ULONG TotalLength;
  1638. ULONG BufferLength;
  1639. PLANE_READY_FRAME pQueryRf;
  1640. PLANE_READY_FRAME pIndRf;
  1641. PNDIS_PACKET pIndNdisPacket;
  1642. TRACEIN(ReadyQueryHandler);
  1643. do
  1644. {
  1645. //
  1646. // Get initial buffer and total length of packet
  1647. //
  1648. NdisGetFirstBufferFromPacket(
  1649. pQueryNdisPacket,
  1650. &pNdisBuffer,
  1651. &pQueryRf,
  1652. &BufferLength,
  1653. &TotalLength);
  1654. //
  1655. // Packet must be at least the size of a READY frame.
  1656. //
  1657. if (TotalLength < sizeof(LANE_READY_FRAME))
  1658. {
  1659. DBGP((0,
  1660. "ReadyQueryHandler: Received runt ready frame (%d)\n",
  1661. TotalLength));
  1662. break;
  1663. }
  1664. //
  1665. // If buffer is not at least the size of a ready frame
  1666. // we currently will not deal with it.
  1667. //
  1668. if (BufferLength < sizeof(LANE_READY_FRAME))
  1669. {
  1670. DBGP((0, "ReadyQueryHandler: Control frame is fragmented\n"));
  1671. break;
  1672. }
  1673. //
  1674. // Verify that this is really a ready query
  1675. //
  1676. if (pQueryRf->Marker != LANE_CONTROL_MARKER ||
  1677. pQueryRf->Protocol != LANE_PROTOCOL ||
  1678. pQueryRf->Version != LANE_VERSION ||
  1679. pQueryRf->OpCode != LANE_READY_QUERY)
  1680. {
  1681. DBGP((0, "ReadyQueryHandler: Not a ready query\n"));
  1682. //DbgPrintHexDump(0, (PUCHAR)pQueryRf, BufferLength);
  1683. break;
  1684. }
  1685. //
  1686. // Send Ready Indication back on VC
  1687. //
  1688. ACQUIRE_VC_LOCK(pVc);
  1689. AtmLaneSendReadyIndication(pElan, pVc);
  1690. //
  1691. // VC lock released in above
  1692. //
  1693. break;
  1694. }
  1695. while (FALSE);
  1696. TRACEOUT(ReadyQueryHandler);
  1697. return;
  1698. }
  1699. VOID
  1700. AtmLaneFlushRequestHandler(
  1701. IN PATMLANE_ELAN pElan,
  1702. IN PNDIS_PACKET pRequestNdisPacket
  1703. )
  1704. /*++
  1705. Routine Description:
  1706. Handles incoming FLUSH_REQUEST packets from peers.
  1707. Arguments:
  1708. pElan - Pointer to ATMLANE Elan structure
  1709. pRequestNdisPacket - Pointer to the Ndis Packet
  1710. Return Value:
  1711. None
  1712. --*/
  1713. {
  1714. PATMLANE_ATM_ENTRY pAtmEntry;
  1715. PATMLANE_VC pVc;
  1716. PNDIS_BUFFER pRequestNdisBuffer;
  1717. PNDIS_PACKET pResponseNdisPacket;
  1718. PNDIS_BUFFER pResponseNdisBuffer;
  1719. ULONG TotalLength;
  1720. ULONG BufferLength;
  1721. PLANE_CONTROL_FRAME pRequestCf;
  1722. PLANE_CONTROL_FRAME pResponseCf;
  1723. NDIS_STATUS Status;
  1724. ULONG rc;
  1725. TRACEIN(FlushRequestHandler);
  1726. //
  1727. // Initialize
  1728. //
  1729. pResponseNdisPacket = (PNDIS_PACKET)NULL;
  1730. pResponseNdisBuffer = (PNDIS_BUFFER)NULL;
  1731. Status = NDIS_STATUS_SUCCESS;
  1732. pVc = NULL_PATMLANE_VC;
  1733. do
  1734. {
  1735. ACQUIRE_ELAN_ATM_LIST_LOCK(pElan);
  1736. pAtmEntry = pElan->pLesAtmEntry;
  1737. if (pAtmEntry == NULL_PATMLANE_ATM_ENTRY)
  1738. {
  1739. RELEASE_ELAN_ATM_LIST_LOCK(pElan);
  1740. Status = NDIS_STATUS_FAILURE;
  1741. break;
  1742. }
  1743. ACQUIRE_ATM_ENTRY_LOCK_DPC(pAtmEntry);
  1744. pVc = pAtmEntry->pVcList;
  1745. if (pVc == NULL_PATMLANE_VC)
  1746. {
  1747. RELEASE_ATM_ENTRY_LOCK_DPC(pAtmEntry);
  1748. RELEASE_ELAN_ATM_LIST_LOCK(pElan);
  1749. break;
  1750. }
  1751. //
  1752. // Reference the VC to keep it around
  1753. //
  1754. ACQUIRE_VC_LOCK_DPC(pVc);
  1755. AtmLaneReferenceVc(pVc, "temp");
  1756. RELEASE_VC_LOCK_DPC(pVc);
  1757. RELEASE_ATM_ENTRY_LOCK_DPC(pAtmEntry);
  1758. RELEASE_ELAN_ATM_LIST_LOCK(pElan);
  1759. //
  1760. // Get initial buffer and total length of packet
  1761. //
  1762. NdisGetFirstBufferFromPacket(
  1763. pRequestNdisPacket,
  1764. &pRequestNdisBuffer,
  1765. (PVOID *)&pRequestCf,
  1766. &BufferLength,
  1767. &TotalLength);
  1768. //
  1769. // Packet must be at least the size of a control frame.
  1770. //
  1771. if (TotalLength < sizeof(LANE_CONTROL_FRAME))
  1772. {
  1773. DBGP((0,
  1774. "FlushRequestHandler: Received runt control frame (%d)\n",
  1775. TotalLength));
  1776. Status = NDIS_STATUS_FAILURE;
  1777. break;
  1778. }
  1779. //
  1780. // If buffer is not at least the size of a control frame
  1781. // we currently will not deal with it.
  1782. //
  1783. if (BufferLength < sizeof(LANE_CONTROL_FRAME))
  1784. {
  1785. DBGP((0, "FlushRequestHandler: Control frame is fragmented\n"));
  1786. Status = NDIS_STATUS_FAILURE;
  1787. break;
  1788. }
  1789. //
  1790. // Verify that this is really a flush request
  1791. //
  1792. if (pRequestCf->Marker != LANE_CONTROL_MARKER ||
  1793. pRequestCf->Protocol != LANE_PROTOCOL ||
  1794. pRequestCf->Version != LANE_VERSION ||
  1795. pRequestCf->OpCode != LANE_FLUSH_REQUEST)
  1796. {
  1797. DBGP((0, "FlushRequestHandler: Not a flush request\n"));
  1798. //DbgPrintHexDump(0, (PUCHAR)pRequestCf, BufferLength);
  1799. Status = NDIS_STATUS_FAILURE;
  1800. break;
  1801. }
  1802. //
  1803. // See if it is really destined for us
  1804. //
  1805. if (!ATM_ADDR_EQUAL(pRequestCf->TargetAtmAddr, pElan->AtmAddress.Address))
  1806. {
  1807. DBGP((1, "FlushRequestHandler: bad target addr, discarding, Vc %x\n", pVc));
  1808. Status = NDIS_STATUS_FAILURE;
  1809. break;
  1810. }
  1811. //
  1812. // Turn packet around and send it to the LES
  1813. //
  1814. do
  1815. {
  1816. //
  1817. // Allocate the Ndis packet header.
  1818. //
  1819. pResponseNdisPacket = AtmLaneAllocProtoPacket(pElan);
  1820. if ((PNDIS_PACKET)NULL == pResponseNdisPacket)
  1821. {
  1822. DBGP((0, "FlushRequestHandler: allocate packet failed\n"));
  1823. Status = NDIS_STATUS_RESOURCES;
  1824. break;
  1825. }
  1826. //
  1827. // Allocate the protocol buffer
  1828. //
  1829. pResponseNdisBuffer = AtmLaneAllocateProtoBuffer(
  1830. pElan,
  1831. pElan->ProtocolBufSize,
  1832. &((PUCHAR)(pResponseCf))
  1833. );
  1834. if ((PNDIS_BUFFER)NULL == pResponseNdisBuffer)
  1835. {
  1836. DBGP((0, "FlushRequestHandler: allocate proto buffer failed\n"));
  1837. Status = NDIS_STATUS_RESOURCES;
  1838. break;
  1839. }
  1840. //
  1841. // Copy in the request packet
  1842. //
  1843. NdisMoveMemory(
  1844. pResponseCf,
  1845. pRequestCf,
  1846. sizeof(LANE_CONTROL_FRAME)
  1847. );
  1848. //
  1849. // Change to a response opcode
  1850. //
  1851. pResponseCf->OpCode = LANE_FLUSH_RESPONSE;
  1852. //
  1853. // Link the ndis buffer to the ndis packet
  1854. //
  1855. NdisChainBufferAtFront(pResponseNdisPacket, pResponseNdisBuffer);
  1856. //
  1857. // Reacquire VC lock and if VC still connected send packet
  1858. //
  1859. ACQUIRE_VC_LOCK(pVc);
  1860. if (IS_FLAG_SET(
  1861. pVc->Flags,
  1862. VC_CALL_STATE_MASK,
  1863. VC_CALL_STATE_ACTIVE))
  1864. {
  1865. DBGP((2, "FlushRequestHandler: Sent FLUSH RESPONSE\n"));
  1866. AtmLaneSendPacketOnVc(pVc, pResponseNdisPacket, FALSE);
  1867. //
  1868. // VC lock released in above
  1869. //
  1870. }
  1871. else
  1872. {
  1873. Status = NDIS_STATUS_FAILURE;
  1874. RELEASE_VC_LOCK(pVc);
  1875. }
  1876. break;
  1877. }
  1878. while (FALSE);
  1879. break;
  1880. }
  1881. while (FALSE);
  1882. //
  1883. // Remove temp VC reference
  1884. //
  1885. if (pVc != NULL_PATMLANE_VC)
  1886. {
  1887. ACQUIRE_VC_LOCK(pVc);
  1888. rc = AtmLaneDereferenceVc(pVc, "temp");
  1889. if (rc > 0)
  1890. {
  1891. RELEASE_VC_LOCK(pVc);
  1892. }
  1893. //
  1894. // else VC is gone
  1895. //
  1896. }
  1897. //
  1898. // Cleanup if failure
  1899. //
  1900. if (Status != NDIS_STATUS_SUCCESS)
  1901. {
  1902. if (pResponseNdisPacket != (PNDIS_PACKET)NULL)
  1903. {
  1904. AtmLaneFreeProtoPacket(pElan, pResponseNdisPacket);
  1905. }
  1906. if (pResponseNdisBuffer != (PNDIS_BUFFER)NULL)
  1907. {
  1908. AtmLaneFreeProtoBuffer(pElan, pResponseNdisBuffer);
  1909. }
  1910. }
  1911. TRACEOUT(FlushRequestHandler);
  1912. return;
  1913. }
  1914. VOID
  1915. AtmLaneArpRequestHandler(
  1916. IN PATMLANE_ELAN pElan,
  1917. IN PLANE_CONTROL_FRAME pRequestCf
  1918. )
  1919. /*++
  1920. Routine Description:
  1921. Handles incoming Arp Request packets from the LES.
  1922. Arguments:
  1923. pRequestCf - Pointer to ARP Request Frame
  1924. Return Value:
  1925. None
  1926. --*/
  1927. {
  1928. PATMLANE_ATM_ENTRY pAtmEntry;
  1929. PATMLANE_VC pVc;
  1930. PNDIS_PACKET pResponseNdisPacket;
  1931. PNDIS_BUFFER pResponseNdisBuffer;
  1932. ULONG TotalLength;
  1933. ULONG BufferLength;
  1934. PLANE_CONTROL_FRAME pResponseCf;
  1935. NDIS_STATUS Status;
  1936. ULONG rc;
  1937. PMAC_ADDRESS pMacAddress;
  1938. TRACEIN(ArpRequestHandler);
  1939. //
  1940. // Initialize
  1941. //
  1942. pResponseNdisPacket = (PNDIS_PACKET)NULL;
  1943. pResponseNdisBuffer = (PNDIS_BUFFER)NULL;
  1944. Status = NDIS_STATUS_SUCCESS;
  1945. pVc = NULL_PATMLANE_VC;
  1946. pMacAddress = (PMAC_ADDRESS)pRequestCf->TargetMacAddress.Byte;
  1947. do
  1948. {
  1949. DBGP((2, "%d Arp Request for MAC %s\n",
  1950. pElan->ElanNumber, MacAddrToString(pMacAddress)));
  1951. //
  1952. // If not looking for our MAC address then done.
  1953. //
  1954. if (pElan->LanType == LANE_LANTYPE_TR)
  1955. {
  1956. if (!MAC_ADDR_EQUAL(pMacAddress, &pElan->MacAddressTr))
  1957. {
  1958. break;
  1959. }
  1960. }
  1961. else
  1962. {
  1963. if (!MAC_ADDR_EQUAL(pMacAddress, &pElan->MacAddressEth))
  1964. {
  1965. break;
  1966. }
  1967. }
  1968. DBGP((1, "%d ARP REQUEST\n", pElan->ElanNumber));
  1969. //
  1970. // Get the LES Vc
  1971. //
  1972. ACQUIRE_ELAN_ATM_LIST_LOCK(pElan);
  1973. pAtmEntry = pElan->pLesAtmEntry;
  1974. if (pAtmEntry == NULL_PATMLANE_ATM_ENTRY)
  1975. {
  1976. RELEASE_ELAN_ATM_LIST_LOCK(pElan);
  1977. DBGP((0, "%d ARP REQUEST before we have an LES entry\n", pElan->ElanNumber));
  1978. Status = NDIS_STATUS_FAILURE;
  1979. break;
  1980. }
  1981. ACQUIRE_ATM_ENTRY_LOCK_DPC(pAtmEntry);
  1982. pVc = pAtmEntry->pVcList;
  1983. if (pVc == NULL_PATMLANE_VC)
  1984. {
  1985. RELEASE_ATM_ENTRY_LOCK_DPC(pAtmEntry);
  1986. RELEASE_ELAN_ATM_LIST_LOCK(pElan);
  1987. DBGP((0, "%d ARP REQUEST with no VC to LES\n", pElan->ElanNumber));
  1988. break;
  1989. }
  1990. //
  1991. // Reference the VC to keep it around
  1992. //
  1993. ACQUIRE_VC_LOCK_DPC(pVc);
  1994. AtmLaneReferenceVc(pVc, "temp");
  1995. RELEASE_VC_LOCK_DPC(pVc);
  1996. RELEASE_ATM_ENTRY_LOCK_DPC(pAtmEntry);
  1997. RELEASE_ELAN_ATM_LIST_LOCK(pElan);
  1998. //
  1999. // Send Arp Response to the LES
  2000. //
  2001. do
  2002. {
  2003. //
  2004. // Allocate the Ndis packet header.
  2005. //
  2006. pResponseNdisPacket = AtmLaneAllocProtoPacket(pElan);
  2007. if ((PNDIS_PACKET)NULL == pResponseNdisPacket)
  2008. {
  2009. DBGP((0, "ArpRequestHandler: allocate packet failed\n"));
  2010. Status = NDIS_STATUS_RESOURCES;
  2011. break;
  2012. }
  2013. //
  2014. // Allocate the protocol buffer
  2015. //
  2016. pResponseNdisBuffer = AtmLaneAllocateProtoBuffer(
  2017. pElan,
  2018. pElan->ProtocolBufSize,
  2019. &((PUCHAR)(pResponseCf))
  2020. );
  2021. if ((PNDIS_BUFFER)NULL == pResponseNdisBuffer)
  2022. {
  2023. DBGP((0, "ArpRequestHandler: allocate proto buffer failed\n"));
  2024. Status = NDIS_STATUS_RESOURCES;
  2025. break;
  2026. }
  2027. //
  2028. // Copy in the request packet
  2029. //
  2030. NdisMoveMemory(
  2031. pResponseCf,
  2032. pRequestCf,
  2033. sizeof(LANE_CONTROL_FRAME)
  2034. );
  2035. //
  2036. // Change to a response opcode
  2037. //
  2038. pResponseCf->OpCode = LANE_ARP_RESPONSE;
  2039. //
  2040. // Fill in our ATM Address
  2041. //
  2042. NdisMoveMemory(
  2043. &pResponseCf->TargetAtmAddr,
  2044. &pElan->AtmAddress.Address,
  2045. ATM_ADDRESS_LENGTH
  2046. );
  2047. //
  2048. // Link the ndis buffer to the ndis packet
  2049. //
  2050. NdisChainBufferAtFront(pResponseNdisPacket, pResponseNdisBuffer);
  2051. //
  2052. // Reacquire VC lock and if VC still connected send packet
  2053. //
  2054. ACQUIRE_VC_LOCK(pVc);
  2055. if (IS_FLAG_SET(
  2056. pVc->Flags,
  2057. VC_CALL_STATE_MASK,
  2058. VC_CALL_STATE_ACTIVE))
  2059. {
  2060. DBGP((2, "ArpRequestHandler: Sent ARP RESPONSE\n"));
  2061. AtmLaneSendPacketOnVc(pVc, pResponseNdisPacket, FALSE);
  2062. //
  2063. // VC lock released in above
  2064. //
  2065. }
  2066. else
  2067. {
  2068. Status = NDIS_STATUS_FAILURE;
  2069. RELEASE_VC_LOCK(pVc);
  2070. }
  2071. break;
  2072. }
  2073. while (FALSE);
  2074. break;
  2075. }
  2076. while (FALSE);
  2077. //
  2078. // Remove temp VC reference
  2079. //
  2080. if (pVc != NULL_PATMLANE_VC)
  2081. {
  2082. ACQUIRE_VC_LOCK(pVc);
  2083. rc = AtmLaneDereferenceVc(pVc, "temp");
  2084. if (rc > 0)
  2085. {
  2086. RELEASE_VC_LOCK(pVc);
  2087. }
  2088. //
  2089. // else VC is gone
  2090. //
  2091. }
  2092. //
  2093. // Cleanup if failure
  2094. //
  2095. if (Status != NDIS_STATUS_SUCCESS)
  2096. {
  2097. if (pResponseNdisPacket != (PNDIS_PACKET)NULL)
  2098. {
  2099. AtmLaneFreeProtoPacket(pElan, pResponseNdisPacket);
  2100. }
  2101. if (pResponseNdisBuffer != (PNDIS_BUFFER)NULL)
  2102. {
  2103. AtmLaneFreeProtoBuffer(pElan, pResponseNdisBuffer);
  2104. }
  2105. }
  2106. TRACEOUT(ArpRequestHandler);
  2107. return;
  2108. }
  2109. VOID
  2110. AtmLaneArpResponseHandler(
  2111. IN PATMLANE_ELAN pElan,
  2112. IN PLANE_CONTROL_FRAME pCf
  2113. )
  2114. /*++
  2115. Routine Description:
  2116. Handle an LE_ARP Response frame.
  2117. The MAC Entry should already exist and the Tid in the
  2118. ARP frame should match the one in the MAC Entry.
  2119. If either is not true then the information is ignored.
  2120. An ATM Entry is created or and existing one is found.
  2121. The MAC Entry is linked to it and appropriate actions
  2122. are taken based on the MAC Entry state.
  2123. Arguments:
  2124. pElan - Pointer to ATMLANE Elan
  2125. pMacAddress - MAC Address
  2126. pAtmAddress - ATM Address
  2127. Return Value:
  2128. None.
  2129. --*/
  2130. {
  2131. PATMLANE_MAC_ENTRY pMacEntry;
  2132. PATMLANE_ATM_ENTRY pAtmEntry;
  2133. PMAC_ADDRESS pMacAddress;
  2134. PUCHAR pAtmAddress;
  2135. BOOLEAN WasRunning;
  2136. BOOLEAN bFound;
  2137. ULONG MacAddrType;
  2138. ULONG rc;
  2139. TRACEIN(ArpResponseHandler);
  2140. //
  2141. // Initialize
  2142. //
  2143. pMacEntry = NULL_PATMLANE_MAC_ENTRY;
  2144. pAtmEntry = NULL_PATMLANE_ATM_ENTRY;
  2145. MacAddrType = pCf->TargetMacAddress.Type;
  2146. pMacAddress = (PMAC_ADDRESS)pCf->TargetMacAddress.Byte;
  2147. pAtmAddress = pCf->TargetAtmAddr;
  2148. do
  2149. {
  2150. //
  2151. // Check Status
  2152. //
  2153. if (pCf->Status != LANE_STATUS_SUCCESS)
  2154. {
  2155. DBGP((0,
  2156. "ArpResponseHandler: Unsuccessful Status (%d) for %s\n",
  2157. pCf->Status,
  2158. MacAddrToString(pMacAddress)));
  2159. break;
  2160. }
  2161. //
  2162. // Get an existing MAC Entry
  2163. //
  2164. ACQUIRE_ELAN_MAC_TABLE_LOCK(pElan);
  2165. pMacEntry = AtmLaneSearchForMacAddress(
  2166. pElan,
  2167. MacAddrType,
  2168. pMacAddress,
  2169. FALSE
  2170. );
  2171. RELEASE_ELAN_MAC_TABLE_LOCK(pElan);
  2172. if (pMacEntry == NULL_PATMLANE_MAC_ENTRY)
  2173. {
  2174. DBGP((0, "ArpResponseHandler: non-existing MAC %s\n",
  2175. MacAddrToString(pMacAddress)));
  2176. break;
  2177. }
  2178. ACQUIRE_MAC_ENTRY_LOCK(pMacEntry);
  2179. //
  2180. // Verify that Tid matches
  2181. //
  2182. if (pMacEntry->ArpTid != pCf->Tid)
  2183. {
  2184. DBGP((0, "ArpResponseHandler: invalid Tid for MAC %s\n",
  2185. MacAddrToString(pMacAddress)));
  2186. RELEASE_MAC_ENTRY_LOCK(pMacEntry);
  2187. break;
  2188. }
  2189. DBGP((1, "%d Resolved %s to %s\n",
  2190. pElan->ElanNumber,
  2191. MacAddrToString(pMacAddress),
  2192. AtmAddrToString(pAtmAddress)));
  2193. //
  2194. // Get an existing or create new ATM Entry
  2195. //
  2196. pAtmEntry = AtmLaneSearchForAtmAddress(
  2197. pElan,
  2198. pAtmAddress,
  2199. (((pMacEntry->Flags & MAC_ENTRY_BROADCAST) != 0)
  2200. ? ATM_ENTRY_TYPE_BUS
  2201. : ATM_ENTRY_TYPE_PEER),
  2202. TRUE
  2203. );
  2204. if (pAtmEntry == NULL_PATMLANE_ATM_ENTRY)
  2205. {
  2206. //
  2207. // resource problem - ARP timeout will clean up MAC Entry
  2208. //
  2209. RELEASE_MAC_ENTRY_LOCK(pMacEntry);
  2210. break;
  2211. }
  2212. //
  2213. // Got both entries.
  2214. //
  2215. // If the MAC Entry is linked to a different
  2216. // ATM Entry, unlink it from the old entry.
  2217. //
  2218. if ((pMacEntry->pAtmEntry != NULL_PATMLANE_ATM_ENTRY) &&
  2219. (pMacEntry->pAtmEntry != pAtmEntry))
  2220. {
  2221. DBGP((0,
  2222. "LearnMacToAtm: MacEntry %x moving from ATM Entry %x to ATM Entry %x\n",
  2223. pMacEntry, pMacEntry->pAtmEntry, pAtmEntry));
  2224. SET_FLAG(
  2225. pMacEntry->Flags,
  2226. MAC_ENTRY_STATE_MASK,
  2227. MAC_ENTRY_NEW);
  2228. bFound = AtmLaneUnlinkMacEntryFromAtmEntry(pMacEntry);
  2229. pMacEntry->pAtmEntry = NULL_PATMLANE_ATM_ENTRY;
  2230. if (bFound)
  2231. {
  2232. rc = AtmLaneDereferenceMacEntry(pMacEntry, "atm");
  2233. if (rc == 0)
  2234. {
  2235. //
  2236. // The MAC entry is gone. Let the next outgoing packet
  2237. // cause a new entry to be created.
  2238. //
  2239. break;
  2240. }
  2241. }
  2242. }
  2243. if (IS_FLAG_SET(
  2244. pMacEntry->Flags,
  2245. MAC_ENTRY_STATE_MASK,
  2246. MAC_ENTRY_ARPING))
  2247. {
  2248. //
  2249. // MAC Entry is in ARPING state
  2250. //
  2251. ASSERT(pMacEntry->pAtmEntry == NULL_PATMLANE_ATM_ENTRY);
  2252. //
  2253. // Link MAC Entry and ATM Entry together
  2254. //
  2255. ACQUIRE_ATM_ENTRY_LOCK_DPC(pAtmEntry);
  2256. #if DBG1
  2257. {
  2258. PATMLANE_MAC_ENTRY pTmpMacEntry;
  2259. ULONG Count = 0;
  2260. for (pTmpMacEntry = pAtmEntry->pMacEntryList;
  2261. pTmpMacEntry != NULL;
  2262. pTmpMacEntry = pTmpMacEntry->pNextToAtm)
  2263. {
  2264. if (pTmpMacEntry == pMacEntry)
  2265. {
  2266. DBGP((0, "LearnMacToAtm: pMacEntry %x already in list for pAtmEntry %x\n",
  2267. pTmpMacEntry, pAtmEntry));
  2268. DbgBreakPoint();
  2269. }
  2270. Count++;
  2271. if (Count > 5000)
  2272. {
  2273. DBGP((0, "Loop in list on pAtmEntry %x\n", pAtmEntry));
  2274. DbgBreakPoint();
  2275. break;
  2276. }
  2277. }
  2278. }
  2279. #endif // DBG
  2280. pMacEntry->pAtmEntry = pAtmEntry;
  2281. AtmLaneReferenceAtmEntry(pAtmEntry, "mac");
  2282. pMacEntry->pNextToAtm = pAtmEntry->pMacEntryList;
  2283. pAtmEntry->pMacEntryList = pMacEntry;
  2284. RELEASE_ATM_ENTRY_LOCK_DPC(pAtmEntry);
  2285. AtmLaneReferenceMacEntry(pMacEntry, "atm");
  2286. DBGP((1, "%d Linked1 MAC %x to ATM %x\n",
  2287. pAtmEntry->pElan->ElanNumber,
  2288. pMacEntry,
  2289. pAtmEntry));
  2290. //
  2291. // Cancel ARP timer
  2292. //
  2293. WasRunning = AtmLaneStopTimer(&(pMacEntry->Timer), pElan);
  2294. if (WasRunning)
  2295. {
  2296. rc = AtmLaneDereferenceMacEntry(pMacEntry, "timer");
  2297. ASSERT(rc > 0);
  2298. }
  2299. //
  2300. // Transition to RESOLVED state
  2301. //
  2302. SET_FLAG(
  2303. pMacEntry->Flags,
  2304. MAC_ENTRY_STATE_MASK,
  2305. MAC_ENTRY_RESOLVED);
  2306. //
  2307. // Handle special case for broadcast address.
  2308. //
  2309. if ((pMacEntry->Flags & MAC_ENTRY_BROADCAST) != 0)
  2310. {
  2311. RELEASE_MAC_ENTRY_LOCK(pMacEntry);
  2312. //
  2313. // Cache the AtmEntry in the Elan
  2314. //
  2315. ACQUIRE_ELAN_ATM_LIST_LOCK(pElan);
  2316. pElan->pBusAtmEntry = pAtmEntry;
  2317. RELEASE_ELAN_ATM_LIST_LOCK(pElan);
  2318. //
  2319. // Copy the Atm Address into the AtmEntry
  2320. //
  2321. pAtmEntry->AtmAddress.AddressType = ATM_NSAP;
  2322. pAtmEntry->AtmAddress.NumberOfDigits = ATM_ADDRESS_LENGTH;
  2323. NdisMoveMemory(
  2324. pAtmEntry->AtmAddress.Address,
  2325. pAtmAddress,
  2326. ATM_ADDRESS_LENGTH
  2327. );
  2328. //
  2329. // Signal the event to the state machine
  2330. //
  2331. AtmLaneQueueElanEvent(pElan, ELAN_EVENT_ARP_RESPONSE, NDIS_STATUS_SUCCESS);
  2332. //
  2333. // Event handler will initiate the call to the bus
  2334. //
  2335. break; // done
  2336. }
  2337. //
  2338. // Not broadcast address.
  2339. //
  2340. // Start the Aging timer.
  2341. // Use Elan AgingTime if TopologyChange is inactive.
  2342. // Use Elan ForwardDelayTime if TopologyChange is active.
  2343. //
  2344. AtmLaneReferenceMacEntry(pMacEntry, "timer");
  2345. AtmLaneStartTimer(
  2346. pElan,
  2347. &pMacEntry->Timer,
  2348. AtmLaneMacEntryAgingTimeout,
  2349. pElan->TopologyChange?pElan->ForwardDelayTime:pElan->AgingTime,
  2350. (PVOID)pMacEntry
  2351. );
  2352. //
  2353. // If ATM Entry not connected and a call not in progress
  2354. // then start a call
  2355. //
  2356. ACQUIRE_ATM_ENTRY_LOCK(pAtmEntry);
  2357. if (!IS_FLAG_SET(
  2358. pAtmEntry->Flags,
  2359. ATM_ENTRY_STATE_MASK,
  2360. ATM_ENTRY_CONNECTED))
  2361. {
  2362. if ((pAtmEntry->Flags & ATM_ENTRY_CALLINPROGRESS) == 0)
  2363. {
  2364. //
  2365. // Mark ATM entry with call in progress
  2366. //
  2367. pAtmEntry->Flags |= ATM_ENTRY_CALLINPROGRESS;
  2368. //
  2369. // Release the MAC lock and reacquire ATM lock
  2370. //
  2371. RELEASE_ATM_ENTRY_LOCK(pAtmEntry);
  2372. RELEASE_MAC_ENTRY_LOCK(pMacEntry);
  2373. ACQUIRE_ATM_ENTRY_LOCK(pAtmEntry);
  2374. AtmLaneMakeCall(pElan, pAtmEntry, FALSE);
  2375. //
  2376. // ATM Entry released in above
  2377. //
  2378. }
  2379. else
  2380. {
  2381. //
  2382. // Call already in progress
  2383. //
  2384. RELEASE_ATM_ENTRY_LOCK(pAtmEntry);
  2385. RELEASE_MAC_ENTRY_LOCK(pMacEntry);
  2386. }
  2387. break; // done
  2388. }
  2389. //
  2390. // ATM Entry is connected
  2391. //
  2392. RELEASE_ATM_ENTRY_LOCK(pAtmEntry);
  2393. //
  2394. // Transition to FLUSHING state
  2395. //
  2396. SET_FLAG(
  2397. pMacEntry->Flags,
  2398. MAC_ENTRY_STATE_MASK,
  2399. MAC_ENTRY_FLUSHING);
  2400. //
  2401. // Start flushing
  2402. //
  2403. pMacEntry->RetriesLeft = 0;
  2404. AtmLaneReferenceMacEntry(pMacEntry, "timer");
  2405. AtmLaneStartTimer(
  2406. pElan,
  2407. &pMacEntry->FlushTimer,
  2408. AtmLaneFlushTimeout,
  2409. pElan->FlushTimeout,
  2410. (PVOID)pMacEntry
  2411. );
  2412. AtmLaneSendFlushRequest(pElan, pMacEntry, pAtmEntry);
  2413. //
  2414. // MAC Entry released in above
  2415. //
  2416. break; // done
  2417. }
  2418. if (IS_FLAG_SET(
  2419. pMacEntry->Flags,
  2420. MAC_ENTRY_STATE_MASK,
  2421. MAC_ENTRY_AGED))
  2422. {
  2423. //
  2424. // MAC Entry is being revalidated
  2425. //
  2426. //
  2427. // Cancel ARP timer
  2428. //
  2429. WasRunning = AtmLaneStopTimer(&(pMacEntry->Timer), pElan);
  2430. if (WasRunning)
  2431. {
  2432. rc = AtmLaneDereferenceMacEntry(pMacEntry, "timer");
  2433. ASSERT(rc > 0);
  2434. }
  2435. //
  2436. // Start the Aging timer up again
  2437. //
  2438. AtmLaneReferenceMacEntry(pMacEntry, "timer");
  2439. AtmLaneStartTimer(
  2440. pElan,
  2441. &pMacEntry->Timer,
  2442. AtmLaneMacEntryAgingTimeout,
  2443. pElan->TopologyChange?pElan->ForwardDelayTime:pElan->AgingTime,
  2444. (PVOID)pMacEntry
  2445. );
  2446. //
  2447. // Check if MAC Entry is switching to new ATM Entry
  2448. if (pMacEntry->pAtmEntry == NULL_PATMLANE_ATM_ENTRY)
  2449. {
  2450. //
  2451. // Link MAC Entry and new ATM Entry together
  2452. //
  2453. ACQUIRE_ATM_ENTRY_LOCK_DPC(pAtmEntry);
  2454. #if DBG1
  2455. {
  2456. PATMLANE_MAC_ENTRY pTmpMacEntry;
  2457. ULONG Count = 0;
  2458. for (pTmpMacEntry = pAtmEntry->pMacEntryList;
  2459. pTmpMacEntry != NULL;
  2460. pTmpMacEntry = pTmpMacEntry->pNextToAtm)
  2461. {
  2462. if (pTmpMacEntry == pMacEntry)
  2463. {
  2464. DBGP((0, "RespHandler: pMacEntry %x already in list for pAtmEntry %x\n",
  2465. pTmpMacEntry, pAtmEntry));
  2466. DbgBreakPoint();
  2467. }
  2468. Count++;
  2469. if (Count > 5000)
  2470. {
  2471. DBGP((0, "RespHandler: Loop in list on pAtmEntry %x\n", pAtmEntry));
  2472. DbgBreakPoint();
  2473. break;
  2474. }
  2475. }
  2476. }
  2477. #endif // DBG
  2478. pMacEntry->pAtmEntry = pAtmEntry;
  2479. AtmLaneReferenceAtmEntry(pAtmEntry, "mac");
  2480. pMacEntry->pNextToAtm = pAtmEntry->pMacEntryList;
  2481. pAtmEntry->pMacEntryList = pMacEntry;
  2482. RELEASE_ATM_ENTRY_LOCK_DPC(pAtmEntry);
  2483. AtmLaneReferenceMacEntry(pMacEntry, "atm");
  2484. DBGP((1, "%d Linked2 MAC %x to ATM %x\n",
  2485. pAtmEntry->pElan->ElanNumber,
  2486. pMacEntry,
  2487. pAtmEntry));
  2488. //
  2489. // Transition back to resolved state
  2490. //
  2491. SET_FLAG(
  2492. pMacEntry->Flags,
  2493. MAC_ENTRY_STATE_MASK,
  2494. MAC_ENTRY_RESOLVED);
  2495. }
  2496. //
  2497. // If ATM Entry not connected and a call not in progress
  2498. // then start a call
  2499. //
  2500. ACQUIRE_ATM_ENTRY_LOCK(pAtmEntry);
  2501. if (!IS_FLAG_SET(
  2502. pAtmEntry->Flags,
  2503. ATM_ENTRY_STATE_MASK,
  2504. ATM_ENTRY_CONNECTED))
  2505. {
  2506. if ((pAtmEntry->Flags & ATM_ENTRY_CALLINPROGRESS) == 0)
  2507. {
  2508. //
  2509. // Mark ATM entry with call in progress
  2510. //
  2511. pAtmEntry->Flags |= ATM_ENTRY_CALLINPROGRESS;
  2512. //
  2513. // Release the MAC lock and reacquire ATM lock
  2514. //
  2515. RELEASE_ATM_ENTRY_LOCK(pAtmEntry);
  2516. RELEASE_MAC_ENTRY_LOCK(pMacEntry);
  2517. ACQUIRE_ATM_ENTRY_LOCK(pAtmEntry);
  2518. AtmLaneMakeCall(pElan, pAtmEntry, FALSE);
  2519. //
  2520. // ATM Entry released in above
  2521. //
  2522. }
  2523. else
  2524. {
  2525. //
  2526. // Call already in progress
  2527. //
  2528. RELEASE_ATM_ENTRY_LOCK(pAtmEntry);
  2529. RELEASE_MAC_ENTRY_LOCK(pMacEntry);
  2530. }
  2531. break; // done
  2532. }
  2533. RELEASE_ATM_ENTRY_LOCK(pAtmEntry);
  2534. //
  2535. // MAC Entry is now either still AGED or
  2536. // transitioned to RESOLVED state.
  2537. //
  2538. ASSERT((pMacEntry->Flags & (MAC_ENTRY_AGED | MAC_ENTRY_RESOLVED)) != 0);
  2539. if (IS_FLAG_SET(
  2540. pMacEntry->Flags,
  2541. MAC_ENTRY_STATE_MASK,
  2542. MAC_ENTRY_RESOLVED))
  2543. {
  2544. //
  2545. // MAC entry must have moved to new, connected ATM Entry
  2546. // Do the flush
  2547. //
  2548. SET_FLAG(
  2549. pMacEntry->Flags,
  2550. MAC_ENTRY_STATE_MASK,
  2551. MAC_ENTRY_FLUSHING);
  2552. pMacEntry->RetriesLeft = 0;
  2553. AtmLaneReferenceMacEntry(pMacEntry, "timer");
  2554. AtmLaneStartTimer(
  2555. pElan,
  2556. &pMacEntry->FlushTimer,
  2557. AtmLaneFlushTimeout,
  2558. pElan->FlushTimeout,
  2559. (PVOID)pMacEntry
  2560. );
  2561. AtmLaneSendFlushRequest(pElan, pMacEntry, pAtmEntry);
  2562. //
  2563. // MAC Entry released in above
  2564. //
  2565. break; // done
  2566. }
  2567. //
  2568. // MAC Entry can just transition back to ACTIVE
  2569. //
  2570. SET_FLAG(
  2571. pMacEntry->Flags,
  2572. MAC_ENTRY_STATE_MASK,
  2573. MAC_ENTRY_ACTIVE);
  2574. RELEASE_MAC_ENTRY_LOCK(pMacEntry);
  2575. break;
  2576. }
  2577. //
  2578. // Shouldn't get here
  2579. //
  2580. RELEASE_MAC_ENTRY_LOCK(pMacEntry);
  2581. DBGP((0, "LearnMacToAtm: MacEntry in wrong state!\n"));
  2582. break;
  2583. }
  2584. while (FALSE);
  2585. if (NULL_PATMLANE_ATM_ENTRY != pAtmEntry)
  2586. {
  2587. //
  2588. // Remove the temp ref added by SearchFor...
  2589. //
  2590. ACQUIRE_ATM_ENTRY_LOCK(pAtmEntry);
  2591. rc = AtmLaneDereferenceAtmEntry(pAtmEntry, "search");
  2592. if (rc != 0)
  2593. {
  2594. RELEASE_ATM_ENTRY_LOCK(pAtmEntry);
  2595. }
  2596. }
  2597. TRACEOUT(ArpResponseHandler);
  2598. return;
  2599. }
  2600. VOID
  2601. AtmLaneFlushResponseHandler(
  2602. IN PATMLANE_ELAN pElan,
  2603. IN PLANE_CONTROL_FRAME pCf
  2604. )
  2605. /*++
  2606. Routine Description:
  2607. Handles incoming Flush Response packets from peers.
  2608. Arguments:
  2609. pCf - Pointer to LANE Control Frame
  2610. Return Value:
  2611. None
  2612. --*/
  2613. {
  2614. PATMLANE_ATM_ENTRY pAtmEntry;
  2615. PATMLANE_MAC_ENTRY pMacEntry;
  2616. PNDIS_PACKET pNdisPacket;
  2617. PNDIS_PACKET pNextPacket;
  2618. PATMLANE_VC pVc;
  2619. BOOLEAN WasRunning;
  2620. ULONG rc;
  2621. TRACEIN(FlushResponseHandler);
  2622. pAtmEntry = NULL_PATMLANE_ATM_ENTRY;
  2623. do
  2624. {
  2625. //
  2626. // Check that we originated the request
  2627. //
  2628. if (!ATM_ADDR_EQUAL(pCf->SourceAtmAddr, &pElan->AtmAddress.Address))
  2629. {
  2630. DBGP((0, "FlushResponseHandler: Response not addressed to us!\n"));
  2631. break;
  2632. }
  2633. //
  2634. // Find the Atm Entry for the target address
  2635. //
  2636. pAtmEntry = AtmLaneSearchForAtmAddress(
  2637. pElan,
  2638. pCf->TargetAtmAddr,
  2639. ATM_ENTRY_TYPE_PEER,
  2640. FALSE); // don't create a new one
  2641. if (pAtmEntry == NULL_PATMLANE_ATM_ENTRY)
  2642. {
  2643. DBGP((0, "FlushResponseHandler: No matching ATM entry\n"));
  2644. break;
  2645. }
  2646. //
  2647. // Grab and Reference the VC for this ATM Entry
  2648. //
  2649. ACQUIRE_ATM_ENTRY_LOCK(pAtmEntry);
  2650. pVc = pAtmEntry->pVcList;
  2651. if (pVc == NULL_PATMLANE_VC)
  2652. {
  2653. DBGP((0, "FlushResponseHandler: No VC on ATM Entry\n"));
  2654. RELEASE_ATM_ENTRY_LOCK(pAtmEntry);
  2655. break;
  2656. }
  2657. ACQUIRE_VC_LOCK_DPC(pVc);
  2658. AtmLaneReferenceVc(pVc, "temp");
  2659. RELEASE_VC_LOCK_DPC(pVc);
  2660. //
  2661. // Find the Mac Entry on this Atm Entry that matches the Tid
  2662. //
  2663. pMacEntry = pAtmEntry->pMacEntryList;
  2664. while(pMacEntry != NULL_PATMLANE_MAC_ENTRY)
  2665. {
  2666. if (pMacEntry->FlushTid == pCf->Tid)
  2667. break;
  2668. pMacEntry = pMacEntry->pNextToAtm;
  2669. }
  2670. if (pMacEntry == NULL_PATMLANE_MAC_ENTRY)
  2671. {
  2672. //
  2673. // No MAC Entry still exists that originated this flush
  2674. //
  2675. DBGP((0, "FlushResponseHandler: No MAC entry with matching TID\n"));
  2676. ACQUIRE_VC_LOCK(pVc);
  2677. rc = AtmLaneDereferenceVc(pVc, "temp");
  2678. if (rc > 0)
  2679. {
  2680. RELEASE_VC_LOCK(pVc);
  2681. }
  2682. RELEASE_ATM_ENTRY_LOCK(pAtmEntry);
  2683. break;
  2684. }
  2685. else
  2686. {
  2687. //
  2688. // Found it
  2689. //
  2690. RELEASE_ATM_ENTRY_LOCK(pAtmEntry);
  2691. }
  2692. //
  2693. // Mark MAC Entry ACTIVE
  2694. //
  2695. ACQUIRE_MAC_ENTRY_LOCK(pMacEntry);
  2696. AtmLaneReferenceMacEntry(pMacEntry, "temp");
  2697. SET_FLAG(
  2698. pMacEntry->Flags,
  2699. MAC_ENTRY_STATE_MASK,
  2700. MAC_ENTRY_ACTIVE);
  2701. //
  2702. // Cancel the flush timer
  2703. //
  2704. WasRunning = AtmLaneStopTimer(&pMacEntry->FlushTimer, pElan);
  2705. if (WasRunning)
  2706. {
  2707. rc = AtmLaneDereferenceMacEntry(pMacEntry, "flush timer");
  2708. ASSERT(rc > 0);
  2709. }
  2710. //
  2711. // Send any queued packets
  2712. //
  2713. while ((pNdisPacket = AtmLaneDequeuePacketFromHead(pMacEntry)) !=
  2714. (PNDIS_PACKET)NULL)
  2715. {
  2716. //
  2717. // Send it
  2718. //
  2719. RELEASE_MAC_ENTRY_LOCK(pMacEntry);
  2720. ACQUIRE_VC_LOCK(pVc);
  2721. AtmLaneSendPacketOnVc(pVc, pNdisPacket, TRUE);
  2722. ACQUIRE_MAC_ENTRY_LOCK(pMacEntry);
  2723. }
  2724. //
  2725. // Dereference the MAC Entry
  2726. //
  2727. rc = AtmLaneDereferenceMacEntry(pMacEntry, "temp");
  2728. if (rc > 0)
  2729. {
  2730. RELEASE_MAC_ENTRY_LOCK(pMacEntry);
  2731. }
  2732. //
  2733. // Dereference the VC
  2734. //
  2735. ACQUIRE_VC_LOCK(pVc);
  2736. rc = AtmLaneDereferenceVc(pVc, "temp");
  2737. if (rc > 0)
  2738. {
  2739. RELEASE_VC_LOCK(pVc);
  2740. }
  2741. break;
  2742. }
  2743. while (FALSE);
  2744. if (NULL_PATMLANE_ATM_ENTRY != pAtmEntry)
  2745. {
  2746. //
  2747. // Remove the temp ref added by SearchFor...
  2748. //
  2749. ACQUIRE_ATM_ENTRY_LOCK(pAtmEntry);
  2750. rc = AtmLaneDereferenceAtmEntry(pAtmEntry, "search");
  2751. if (rc != 0)
  2752. {
  2753. RELEASE_ATM_ENTRY_LOCK(pAtmEntry);
  2754. }
  2755. }
  2756. TRACEOUT(FlushResponseHandler);
  2757. return;
  2758. }
  2759. VOID
  2760. AtmLaneReadyIndicationHandler(
  2761. IN PATMLANE_ELAN pElan,
  2762. IN PATMLANE_VC pVc,
  2763. IN PNDIS_PACKET pIndNdisPacket
  2764. )
  2765. /*++
  2766. Routine Description:
  2767. Handles incoming READY_INDICATION packets from peers.
  2768. Arguments:
  2769. pElan - Pointer to ATMLANE Elan structure
  2770. pVc - Pointer to ATMLANE VC for this packet
  2771. pIndNdisPacket - Pointer to the Ndis Packet
  2772. Return Value:
  2773. None
  2774. --*/
  2775. {
  2776. BOOLEAN WasRunning;
  2777. ULONG rc;
  2778. TRACEIN(ReadyIndicationHandler);
  2779. ACQUIRE_VC_LOCK(pVc);
  2780. //
  2781. // Cancel the ready timer on VC
  2782. //
  2783. WasRunning = AtmLaneStopTimer(&pVc->ReadyTimer, pElan);
  2784. if (WasRunning)
  2785. {
  2786. rc = AtmLaneDereferenceVc(pVc, "ready timer");
  2787. }
  2788. else
  2789. {
  2790. rc = pVc->RefCount;
  2791. }
  2792. //
  2793. // If VC still around update state
  2794. //
  2795. if (rc > 0)
  2796. {
  2797. DBGP((2, "ReadyIndicationHandler: pVc %x State to INDICATED\n", pVc));
  2798. SET_FLAG(
  2799. pVc->Flags,
  2800. VC_READY_STATE_MASK,
  2801. VC_READY_INDICATED
  2802. );
  2803. RELEASE_VC_LOCK(pVc);
  2804. }
  2805. //
  2806. // else VC is gone
  2807. //
  2808. TRACEOUT(ReadyIndicationHandler);
  2809. return;
  2810. }
  2811. VOID
  2812. AtmLaneTopologyRequestHandler(
  2813. IN PATMLANE_ELAN pElan,
  2814. IN PLANE_CONTROL_FRAME pCf
  2815. )
  2816. /*++
  2817. Routine Description:
  2818. Handles incoming Topology Request packets from the LES.
  2819. Arguments:
  2820. pRequestCf - Pointer to ARP Request Frame
  2821. Return Value:
  2822. None
  2823. --*/
  2824. {
  2825. ULONG i;
  2826. PATMLANE_MAC_ENTRY pMacEntry;
  2827. TRACEIN(TopologyRequestHandler);
  2828. if ((pCf->Flags & LANE_CONTROL_FLAGS_TOPOLOGY_CHANGE) == 0)
  2829. {
  2830. //
  2831. // Topology change state OFF
  2832. //
  2833. DBGP((1, "%d TOPOLOGY CHANGE OFF\n", pElan->ElanNumber));
  2834. pElan->TopologyChange = 0;
  2835. }
  2836. else
  2837. {
  2838. //
  2839. // Topology change state ON
  2840. //
  2841. DBGP((1, "%d TOPOLOGY CHANGE ON\n", pElan->ElanNumber));
  2842. pElan->TopologyChange = 1;
  2843. //
  2844. // Abort all MAC table entries.
  2845. //
  2846. for (i = 0; i < ATMLANE_MAC_TABLE_SIZE; i++)
  2847. {
  2848. ACQUIRE_ELAN_MAC_TABLE_LOCK(pElan);
  2849. while (pElan->pMacTable[i] != NULL_PATMLANE_MAC_ENTRY)
  2850. {
  2851. pMacEntry = pElan->pMacTable[i];
  2852. RELEASE_ELAN_MAC_TABLE_LOCK(pElan);
  2853. ACQUIRE_MAC_ENTRY_LOCK(pMacEntry);
  2854. AtmLaneAbortMacEntry(pMacEntry);
  2855. //
  2856. // MAC Entry Lock is released within the above.
  2857. //
  2858. ACQUIRE_ELAN_MAC_TABLE_LOCK(pElan);
  2859. }
  2860. RELEASE_ELAN_MAC_TABLE_LOCK(pElan);
  2861. }
  2862. }
  2863. TRACEOUT(TopologyRequestHandler);
  2864. return;
  2865. }
  2866. BOOLEAN
  2867. AtmLaneDataPacketHandler(
  2868. IN PATMLANE_ELAN pElan,
  2869. IN PATMLANE_VC pVc,
  2870. IN PNDIS_PACKET pNdisPacket
  2871. )
  2872. /*++
  2873. Routine Description:
  2874. Handles incoming packets from the data VCs from peers and
  2875. unknown and multicast packets from the BUS.
  2876. Arguments:
  2877. pElan - Pointer to ATMLANE Elan structure
  2878. pVc - Pointer to ATMLANE Vc structure
  2879. pNdisPacket - Pointer to the Ndis Packet
  2880. Return Value:
  2881. TRUE - if packet will be retained (i.e. sent
  2882. up to protocols)
  2883. FALSE - if packet was a flush request packet and
  2884. can be reliquished back to adapter
  2885. immediately.
  2886. --*/
  2887. {
  2888. ULONG TotalLength;
  2889. ULONG TempLength;
  2890. PUCHAR pBuffer;
  2891. BOOLEAN RetainIt;
  2892. PLANE_CONTROL_FRAME pCf;
  2893. PNDIS_PACKET pNewNdisPacket;
  2894. PNDIS_BUFFER pFirstNdisBuffer;
  2895. PNDIS_BUFFER pTempNdisBuffer;
  2896. PNDIS_BUFFER pNewNdisBuffer;
  2897. PUCHAR pTempBuffer;
  2898. NDIS_STATUS Status;
  2899. ULONG MacHdrSize;
  2900. ULONG DestAddrType;
  2901. MAC_ADDRESS DestAddr;
  2902. BOOLEAN DestIsMulticast;
  2903. NDIS_HANDLE MiniportAdapterHandle;
  2904. TRACEIN(DataPacketHandler);
  2905. // Initialize
  2906. RetainIt = FALSE; // default is not to keep packet
  2907. pNewNdisPacket = NULL;
  2908. do
  2909. {
  2910. //
  2911. // Get initial buffer and total length of packet
  2912. //
  2913. NdisGetFirstBufferFromPacket(
  2914. pNdisPacket,
  2915. &pFirstNdisBuffer,
  2916. &pBuffer,
  2917. &TempLength,
  2918. &TotalLength);
  2919. DBGP((3, "DataPacketHandler: Pkt %x Length %d\n",
  2920. pNdisPacket, TotalLength));
  2921. //DbgPrintNdisPacket(pNdisPacket);
  2922. //
  2923. // Filter out flush request and ready query frames
  2924. //
  2925. if (TempLength < 6)
  2926. {
  2927. DBGP((0, "DataPacketHandler: pVc %x First fragment"
  2928. " < 6, discarding\n", pVc));
  2929. break;
  2930. }
  2931. pCf = (PLANE_CONTROL_FRAME)pBuffer;
  2932. if (pCf->Marker == LANE_CONTROL_MARKER &&
  2933. pCf->Protocol == LANE_PROTOCOL &&
  2934. pCf->Version == LANE_VERSION)
  2935. {
  2936. switch (pCf->OpCode)
  2937. {
  2938. case LANE_FLUSH_REQUEST:
  2939. DBGP((2, "DataPacketHandler: pVc %x FLUSH REQUEST\n", pVc));
  2940. AtmLaneFlushRequestHandler(pElan, pNdisPacket);
  2941. break;
  2942. case LANE_READY_QUERY:
  2943. DBGP((2, "DataPacketHandler: pVc %x READY QUERY\n", pVc));
  2944. AtmLaneReadyQueryHandler(pElan, pVc, pNdisPacket);
  2945. break;
  2946. case LANE_READY_IND:
  2947. DBGP((2, "DataPacketHandler: pVc %x READY INDICATION\n", pVc));
  2948. AtmLaneReadyIndicationHandler(pElan, pVc, pNdisPacket);
  2949. break;
  2950. default:
  2951. DBGP((2,
  2952. "DataPacketHandler: pVc %x Unexpected control"
  2953. " packet, opcode %x\n",
  2954. pVc, pCf->OpCode));
  2955. break;
  2956. }
  2957. break;
  2958. }
  2959. //
  2960. // If miniport is not operational - discard
  2961. //
  2962. if ((pElan->Flags & ELAN_MINIPORT_OPERATIONAL) == 0)
  2963. {
  2964. DBGP((2, "%d Dropping pkt %x, cuz Elan %x Flags are %x\n",
  2965. pElan->ElanNumber, pNdisPacket, pElan, pElan->Flags));
  2966. break;
  2967. }
  2968. //
  2969. // If no filters are set, discard.
  2970. //
  2971. if (pElan->CurPacketFilter == 0)
  2972. {
  2973. DBGP((2, "%d Dropping pkt %x, cuz Elan %x Filter is zero\n",
  2974. pElan->ElanNumber, pNdisPacket, pElan));
  2975. break;
  2976. }
  2977. MiniportAdapterHandle = pElan->MiniportAdapterHandle;
  2978. if (NULL == MiniportAdapterHandle)
  2979. {
  2980. DBGP((0, "%d Dropping pkt %x cuz ELAN %x has Null handle!\n",
  2981. pElan->ElanNumber, pNdisPacket, pElan));
  2982. break;
  2983. }
  2984. //
  2985. // Mark VC with fact that it has had data packet receive activity
  2986. //
  2987. // To avoid slowing down the receive path, MP issues with
  2988. // setting this flag are ignored. This flag is a VC aging
  2989. // optimization and not critical.
  2990. //
  2991. pVc->ReceiveActivity = 1;
  2992. //
  2993. // Repackage it and learn some stuff about it.
  2994. //
  2995. pNewNdisPacket = AtmLaneWrapRecvPacket(
  2996. pElan,
  2997. pNdisPacket,
  2998. &MacHdrSize,
  2999. &DestAddrType,
  3000. &DestAddr,
  3001. &DestIsMulticast);
  3002. //
  3003. // If wrap failed just discard packet
  3004. //
  3005. if (pNewNdisPacket == (PNDIS_PACKET)NULL)
  3006. {
  3007. DBGP((2, "%d Dropping pkt %x, len %d, VC %x, wrap failed\n",
  3008. pElan->ElanNumber, pNdisPacket, TotalLength, pVc));
  3009. break;
  3010. }
  3011. //
  3012. // Branch on Ethernet v.s. Token Ring
  3013. //
  3014. if (pElan->LanType == LANE_LANTYPE_ETH)
  3015. {
  3016. //
  3017. // Filter out BUS reflections that we originated.
  3018. //
  3019. if (pCf->Marker == pElan->LecId)
  3020. {
  3021. DBGP((2, "%d Dropping pkt %x, len %d, VC %x, BUS reflection\n",
  3022. pElan->ElanNumber, pNdisPacket, TotalLength, pVc));
  3023. break;
  3024. }
  3025. //
  3026. // Filter out Unicasts not addressed to us
  3027. //
  3028. if ((!DestIsMulticast) &&
  3029. (!MAC_ADDR_EQUAL(&DestAddr, &pElan->MacAddressEth)))
  3030. {
  3031. DBGP((2, "%d Dropping pkt %x, len %d, VC %x, unicast not for us\n",
  3032. pElan->ElanNumber, pNdisPacket, TotalLength, pVc));
  3033. break;
  3034. }
  3035. }
  3036. else
  3037. {
  3038. ASSERT(pElan->LanType == LANE_LANTYPE_TR);
  3039. //
  3040. // Filter out Non-Multicast BUS reflections that we originated
  3041. //
  3042. if ((pCf->Marker == pElan->LecId) && (!DestIsMulticast))
  3043. {
  3044. DBGP((2, "%d Dropping pkt %x, len %d, VC %x, TR Bus refln\n",
  3045. pElan->ElanNumber, pNdisPacket, TotalLength, pVc));
  3046. break;
  3047. }
  3048. //
  3049. // Filter out Unicasts not addressed to us
  3050. //
  3051. if ((!DestIsMulticast) &&
  3052. (!MAC_ADDR_EQUAL(&DestAddr, &pElan->MacAddressTr)))
  3053. {
  3054. DBGP((2, "%d Dropping pkt %x, len %d, VC %x, TR unicast not for us\n",
  3055. pElan->ElanNumber, pNdisPacket, TotalLength, pVc));
  3056. break;
  3057. }
  3058. }
  3059. //
  3060. // Filter out multicast/broadcast if we don't have these enabled.
  3061. //
  3062. if (DestIsMulticast)
  3063. {
  3064. if ((pElan->CurPacketFilter &
  3065. (NDIS_PACKET_TYPE_MULTICAST|
  3066. NDIS_PACKET_TYPE_BROADCAST|
  3067. NDIS_PACKET_TYPE_ALL_MULTICAST)) == 0)
  3068. {
  3069. DBGP((2, "%d Dropping multicast pkt %x, cuz CurPacketFilter is %x\n",
  3070. pElan->ElanNumber, pNdisPacket, pElan->CurPacketFilter));
  3071. break;
  3072. }
  3073. if (((pElan->CurPacketFilter & NDIS_PACKET_TYPE_BROADCAST) == 0) &&
  3074. MAC_ADDR_EQUAL(&DestAddr, &gMacBroadcastAddress))
  3075. {
  3076. DBGP((2, "%d Dropping broadcast pkt %x, cuz CurPacketFilter is %x\n",
  3077. pElan->ElanNumber, pNdisPacket, pElan->CurPacketFilter));
  3078. break;
  3079. }
  3080. }
  3081. //
  3082. // Count it
  3083. //
  3084. NdisInterlockedIncrement(&pElan->FramesRecvGood);
  3085. //
  3086. // Indicate it up to protocols and other interested parties
  3087. //
  3088. NDIS_SET_PACKET_HEADER_SIZE(pNewNdisPacket, MacHdrSize);
  3089. TRACELOGWRITE((&TraceLog,
  3090. TL_MINDPACKET,
  3091. pNewNdisPacket));
  3092. //
  3093. // Set the packet status according to what we received from the miniport.
  3094. //
  3095. Status = NDIS_GET_PACKET_STATUS(pNdisPacket);
  3096. NDIS_SET_PACKET_STATUS(pNewNdisPacket, Status);
  3097. NdisMIndicateReceivePacket(
  3098. MiniportAdapterHandle,
  3099. &pNewNdisPacket,
  3100. 1
  3101. );
  3102. if (Status != NDIS_STATUS_RESOURCES)
  3103. {
  3104. RetainIt = TRUE;
  3105. DBGP((2, "DataPacketHandler: Packet Retained!\n"));
  3106. }
  3107. //
  3108. // else our ReturnPackets handler is guaranteed to be called.
  3109. //
  3110. }
  3111. while (FALSE);
  3112. //
  3113. // Unwrap the packet if it was wrapped and we don't have to keep it.
  3114. //
  3115. if (pNewNdisPacket && !RetainIt)
  3116. {
  3117. (VOID)AtmLaneUnwrapRecvPacket(pElan, pNewNdisPacket);
  3118. }
  3119. TRACEOUT(DataPacketHandler);
  3120. return (RetainIt);
  3121. }
  3122. VOID
  3123. AtmLaneSendPacketOnVc(
  3124. IN PATMLANE_VC pVc LOCKIN NOLOCKOUT,
  3125. IN PNDIS_PACKET pNdisPacket,
  3126. IN BOOLEAN Refresh
  3127. )
  3128. /*++
  3129. Routine Description:
  3130. Send a packet on the specified VC.
  3131. Assumes caller has lock on VC structure.
  3132. Assumes caller has checked VC state for validity.
  3133. If requested, refresh the aging timer.
  3134. Sends the packet.
  3135. Returns the send status
  3136. Arguments:
  3137. pVc - Pointer to ATMLANE VC
  3138. pNdisPacket - Pointer to packet to be sent.
  3139. Refresh - If TRUE refresh the Aging Timer.
  3140. Return Value:
  3141. NDIS_STATUS value set on the packet by the miniport.
  3142. --*/
  3143. {
  3144. NDIS_HANDLE NdisVcHandle;
  3145. PATMLANE_ELAN pElan;
  3146. TRACEIN(SendPacketOnVc);
  3147. pElan = pVc->pElan;
  3148. STRUCT_ASSERT(pElan, atmlane_elan);
  3149. //
  3150. // If requested, refresh the aging timer
  3151. //
  3152. if (Refresh)
  3153. {
  3154. AtmLaneRefreshTimer(&pVc->AgingTimer);
  3155. }
  3156. #if SENDLIST
  3157. //
  3158. // Check list for duplicate send
  3159. //
  3160. NdisAcquireSpinLock(&pElan->SendListLock);
  3161. {
  3162. PNDIS_PACKET pDbgPkt;
  3163. pDbgPkt = pElan->pSendList;
  3164. while (pDbgPkt != (PNDIS_PACKET)NULL)
  3165. {
  3166. if (pNdisPacket == pDbgPkt)
  3167. {
  3168. DBGP((0, "SendPacketOnVc: Duplicate Send!\n"));
  3169. // DbgBreakPoint();
  3170. }
  3171. pDbgPkt = PSEND_RSVD(pDbgPkt)->pNextInSendList;
  3172. }
  3173. }
  3174. //
  3175. // Queue packet on list of outstanding sends
  3176. //
  3177. PSEND_RSVD(pNdisPacket)->pNextInSendList = pElan->pSendList;
  3178. pElan->pSendList = pNdisPacket;
  3179. NdisReleaseSpinLock(&pElan->SendListLock);
  3180. #endif // SENDLIST
  3181. //
  3182. // Reference the VC with the outstanding send
  3183. //
  3184. AtmLaneReferenceVc(pVc, "sendpkt");
  3185. //
  3186. // Note this outstanding send.
  3187. //
  3188. pVc->OutstandingSends++;
  3189. //
  3190. // Get the Ndis handle
  3191. //
  3192. NdisVcHandle = pVc->NdisVcHandle;
  3193. //
  3194. // Send it
  3195. //
  3196. DBGP((3, "SendPacketOnVc: pVc %x, Pkt %x, VcHandle %x\n",
  3197. pVc, pNdisPacket, NdisVcHandle));
  3198. TRACELOGWRITE((&TraceLog, TL_COSENDPACKET, pNdisPacket));
  3199. TRACELOGWRITEPKT((&TraceLog, pNdisPacket));
  3200. RELEASE_VC_LOCK(pVc);
  3201. NdisCoSendPackets(NdisVcHandle, &pNdisPacket, 1);
  3202. #if PROTECT_PACKETS
  3203. //
  3204. // Lock the packet
  3205. //
  3206. ACQUIRE_SENDPACKET_LOCK(pNdisPacket);
  3207. //
  3208. // Mark it with NdisCoSendPackets having returned
  3209. //
  3210. ASSERT((PSEND_RSVD(pNdisPacket)->Flags & PACKET_RESERVED_COSENDRETURNED) == 0);
  3211. PSEND_RSVD(pNdisPacket)->Flags |= PACKET_RESERVED_COSENDRETURNED;
  3212. //
  3213. // Complete the packet only if it is marked as having been completed
  3214. // by miniport.
  3215. //
  3216. if ((PSEND_RSVD(pNdisPacket)->Flags & PACKET_RESERVED_COMPLETED) != 0)
  3217. {
  3218. AtmLaneCompleteSendPacket(pElan, pNdisPacket,
  3219. PSEND_RSVD(pNdisPacket)->CompletionStatus);
  3220. //
  3221. // packet lock released in above
  3222. //
  3223. }
  3224. else
  3225. {
  3226. RELEASE_SENDPACKET_LOCK(pNdisPacket);
  3227. }
  3228. #endif // PROTECT_PACKETS
  3229. TRACEOUT(SendPacketOnVc);
  3230. return;
  3231. }
  3232. VOID
  3233. AtmLaneQueuePacketOnHead(
  3234. IN PATMLANE_MAC_ENTRY pMacEntry,
  3235. IN PNDIS_PACKET pNdisPacket
  3236. )
  3237. /*++
  3238. Routine Description:
  3239. Queue a packet at the head of the MAC Entry
  3240. packet queue for later transmit.
  3241. Assumes caller has lock on MAC Entry.
  3242. Arguments:
  3243. pMacEntry - Pointer to ATMLANE MAC Entry.
  3244. pNdisPacket - The packet to be queued.
  3245. Return Value:
  3246. None
  3247. --*/
  3248. {
  3249. PNDIS_PACKET pPrevPacket;
  3250. TRACEIN(QueuePacketOnHead);
  3251. SET_NEXT_PACKET(pNdisPacket, pMacEntry->PacketList);
  3252. pMacEntry->PacketList = pNdisPacket;
  3253. pMacEntry->PacketListCount++;
  3254. DBGP((2, "%d QueueHead Count %d on %s\n",
  3255. pMacEntry->pElan->ElanNumber,
  3256. pMacEntry->PacketListCount,
  3257. MacAddrToString(&pMacEntry->MacAddress)));
  3258. TRACEOUT(QueuePacketOnHead);
  3259. return;
  3260. }
  3261. VOID
  3262. AtmLaneQueuePacketOnTail(
  3263. IN PATMLANE_MAC_ENTRY pMacEntry,
  3264. IN PNDIS_PACKET pNdisPacket
  3265. )
  3266. /*++
  3267. Routine Description:
  3268. Queue a packet at the tail of the MAC Entry
  3269. packet queue for later transmit.
  3270. Assumes caller has lock on MAC Entry.
  3271. Arguments:
  3272. pMacEntry - Pointer to ATMLANE MAC Entry.
  3273. pNdisPacket - The packet to be queued.
  3274. Return Value:
  3275. None
  3276. --*/
  3277. {
  3278. PNDIS_PACKET pPrevPacket;
  3279. TRACEIN(QueuePacketOnTail);
  3280. if (pMacEntry->PacketList == (PNDIS_PACKET)NULL)
  3281. {
  3282. //
  3283. // Currently empty.
  3284. //
  3285. pMacEntry->PacketList = pNdisPacket;
  3286. }
  3287. else
  3288. {
  3289. //
  3290. // Go to the end of the packet list.
  3291. //
  3292. pPrevPacket = pMacEntry->PacketList;
  3293. while (GET_NEXT_PACKET(pPrevPacket) != (PNDIS_PACKET)NULL)
  3294. {
  3295. pPrevPacket = GET_NEXT_PACKET(pPrevPacket);
  3296. }
  3297. //
  3298. // Found the last packet in the list. Chain this packet
  3299. // to it.
  3300. //
  3301. SET_NEXT_PACKET(pPrevPacket, pNdisPacket);
  3302. }
  3303. //
  3304. // Set tail's next pointer to NULL.
  3305. //
  3306. SET_NEXT_PACKET(pNdisPacket, NULL);
  3307. pMacEntry->PacketListCount++;
  3308. DBGP((2, "%d QueueTail Count %d on %s\n",
  3309. pMacEntry->pElan->ElanNumber,
  3310. pMacEntry->PacketListCount,
  3311. MacAddrToString(&pMacEntry->MacAddress)));
  3312. TRACEOUT(QueuePacketOnTail);
  3313. return;
  3314. }
  3315. PNDIS_PACKET
  3316. AtmLaneDequeuePacketFromHead(
  3317. IN PATMLANE_MAC_ENTRY pMacEntry
  3318. )
  3319. /*++
  3320. Routine Description:
  3321. Dequeue a packet from the head of the MAC Entry packet queue.
  3322. Assumes caller has lock on MAC Entry.
  3323. Arguments:
  3324. pMacEntry - Pointer to ATMLANE MAC Entry.
  3325. Return Value:
  3326. First packet on the MAC Entry queue or NULL if queue is empty.
  3327. --*/
  3328. {
  3329. PNDIS_PACKET pNdisPacket;
  3330. TRACEIN(DequeuePacketFromHead);
  3331. do
  3332. {
  3333. //
  3334. // If queue is empty, setup to return NULL
  3335. //
  3336. if (pMacEntry->PacketList == (PNDIS_PACKET)NULL)
  3337. {
  3338. ASSERT(pMacEntry->PacketListCount == 0);
  3339. pNdisPacket = (PNDIS_PACKET)NULL;
  3340. break;
  3341. }
  3342. //
  3343. // Queue is not empty - remove head
  3344. //
  3345. ASSERT(pMacEntry->PacketListCount > 0);
  3346. pNdisPacket = pMacEntry->PacketList;
  3347. pMacEntry->PacketList = GET_NEXT_PACKET(pNdisPacket);
  3348. SET_NEXT_PACKET(pNdisPacket, NULL);
  3349. pMacEntry->PacketListCount--;
  3350. DBGP((2, "%d DequeueHead Count %d on %s\n",
  3351. pMacEntry->pElan->ElanNumber,
  3352. pMacEntry->PacketListCount,
  3353. MacAddrToString(&pMacEntry->MacAddress)));
  3354. break;
  3355. }
  3356. while (FALSE);
  3357. TRACEOUT(DequeuePacketFromHead);
  3358. return pNdisPacket;
  3359. }
  3360. NDIS_STATUS
  3361. AtmLaneSendUnicastPacket(
  3362. IN PATMLANE_ELAN pElan,
  3363. IN ULONG DestAddrType,
  3364. IN PMAC_ADDRESS pDestAddress,
  3365. IN PNDIS_PACKET pNdisPacket
  3366. )
  3367. /*++
  3368. Routine Description:
  3369. Send a unicast packet.
  3370. Arguments:
  3371. pElan - Pointer to ATMLANE elan structure
  3372. DestAddrType - Either LANE_MACADDRTYPE_MACADDR or
  3373. LANE_MACADDRTYPE_ROUTEDESCR.
  3374. pDestAddress - Pointer to Destination MAC Address
  3375. pNdisPacket - Pointer to packet to be sent.
  3376. Return Value:
  3377. NDIS_STATUS_PENDING - if packet queued or sent
  3378. NDIS_STATUS_FAILURE - if some error
  3379. --*/
  3380. {
  3381. PATMLANE_MAC_ENTRY pMacEntry;
  3382. PATMLANE_ATM_ENTRY pAtmEntry;
  3383. PATMLANE_VC pVc;
  3384. NDIS_STATUS Status;
  3385. ULONG rc;
  3386. TRACEIN(SendUnicastPacket);
  3387. //
  3388. // Initialize
  3389. //
  3390. pMacEntry = NULL_PATMLANE_MAC_ENTRY;
  3391. Status = NDIS_STATUS_PENDING;
  3392. do
  3393. {
  3394. //
  3395. // Find a MAC entry for this destination address
  3396. //
  3397. ACQUIRE_ELAN_MAC_TABLE_LOCK(pElan);
  3398. pMacEntry = AtmLaneSearchForMacAddress(
  3399. pElan,
  3400. DestAddrType,
  3401. pDestAddress,
  3402. TRUE // Create new entry if not found
  3403. );
  3404. if (pMacEntry == NULL_PATMLANE_MAC_ENTRY)
  3405. {
  3406. Status = NDIS_STATUS_RESOURCES;
  3407. RELEASE_ELAN_MAC_TABLE_LOCK(pElan);
  3408. break;
  3409. }
  3410. //
  3411. // Add a temp ref so that this won't go away when we release
  3412. // the MAC table lock (#303602).
  3413. //
  3414. ACQUIRE_MAC_ENTRY_LOCK_DPC(pMacEntry);
  3415. AtmLaneReferenceMacEntry(pMacEntry, "tempunicast");
  3416. RELEASE_MAC_ENTRY_LOCK_DPC(pMacEntry);
  3417. RELEASE_ELAN_MAC_TABLE_LOCK(pElan);
  3418. //
  3419. // Lock the MAC Entry
  3420. //
  3421. ACQUIRE_MAC_ENTRY_LOCK(pMacEntry);
  3422. //
  3423. // Check if it has been deref'ed away.
  3424. //
  3425. rc = AtmLaneDereferenceMacEntry(pMacEntry, "tempunicast");
  3426. if (rc == 0)
  3427. {
  3428. //
  3429. // The MAC entry is gone! Fail this send.
  3430. //
  3431. Status = NDIS_STATUS_FAILURE;
  3432. break;
  3433. }
  3434. //
  3435. // MAC Entry State - NEW
  3436. //
  3437. if (IS_FLAG_SET(
  3438. pMacEntry->Flags,
  3439. MAC_ENTRY_STATE_MASK,
  3440. MAC_ENTRY_NEW))
  3441. {
  3442. DBGP((2, "SendUnicastPacket: NEW Mac Entry %x for %s\n",
  3443. pMacEntry, MacAddrToString(pDestAddress)));
  3444. //
  3445. // Queue packet on MAC Entry
  3446. //
  3447. AtmLaneQueuePacketOnHead(pMacEntry, pNdisPacket);
  3448. //
  3449. // Transition to ARPING State
  3450. //
  3451. SET_FLAG(
  3452. pMacEntry->Flags,
  3453. MAC_ENTRY_STATE_MASK,
  3454. MAC_ENTRY_ARPING);
  3455. ASSERT(pMacEntry->pAtmEntry == NULL_PATMLANE_ATM_ENTRY);
  3456. //
  3457. // Start the BUS sends.
  3458. //
  3459. AtmLaneStartBusSends(pMacEntry);
  3460. //
  3461. // Lock released in above
  3462. //
  3463. //
  3464. // Reacquire the lock
  3465. //
  3466. ACQUIRE_MAC_ENTRY_LOCK(pMacEntry);
  3467. //
  3468. // Start the ARP protocol
  3469. //
  3470. pMacEntry->RetriesLeft = pElan->MaxRetryCount;
  3471. AtmLaneReferenceMacEntry(pMacEntry, "timer");
  3472. AtmLaneStartTimer(
  3473. pElan,
  3474. &pMacEntry->Timer,
  3475. AtmLaneArpTimeout,
  3476. pElan->ArpResponseTime,
  3477. (PVOID)pMacEntry
  3478. );
  3479. AtmLaneSendArpRequest(pElan, pMacEntry);
  3480. //
  3481. // MAC Entry lock released in above
  3482. //
  3483. break;
  3484. }
  3485. //
  3486. // MAC Entry State - ARPING
  3487. //
  3488. if (IS_FLAG_SET(
  3489. pMacEntry->Flags,
  3490. MAC_ENTRY_STATE_MASK,
  3491. MAC_ENTRY_ARPING))
  3492. {
  3493. DBGP((2, "SendUnicastPacket: ARPING Mac Entry %x for %s\n",
  3494. pMacEntry, MacAddrToString(pDestAddress)));
  3495. //
  3496. // Queue packet on MAC Entry
  3497. //
  3498. AtmLaneQueuePacketOnHead(pMacEntry, pNdisPacket);
  3499. //
  3500. // Start the BUS sends
  3501. //
  3502. AtmLaneStartBusSends(pMacEntry);
  3503. //
  3504. // Lock released in above
  3505. //
  3506. break;
  3507. }
  3508. //
  3509. // MAC Entry State - RESOLVED
  3510. //
  3511. if (IS_FLAG_SET(
  3512. pMacEntry->Flags,
  3513. MAC_ENTRY_STATE_MASK,
  3514. MAC_ENTRY_RESOLVED))
  3515. {
  3516. DBGP((2, "SendUnicastPacket: RESOLVED Mac Entry %x for %s\n",
  3517. pMacEntry, MacAddrToString(pDestAddress)));
  3518. //
  3519. // Queue packet on MAC Entry
  3520. //
  3521. AtmLaneQueuePacketOnHead(pMacEntry, pNdisPacket);
  3522. //
  3523. // Start the BUS sends
  3524. //
  3525. AtmLaneStartBusSends(pMacEntry);
  3526. //
  3527. // Lock released in above
  3528. //
  3529. break;
  3530. }
  3531. //
  3532. // MAC Entry State - FLUSHING
  3533. //
  3534. if (IS_FLAG_SET(
  3535. pMacEntry->Flags,
  3536. MAC_ENTRY_STATE_MASK,
  3537. MAC_ENTRY_FLUSHING))
  3538. {
  3539. DBGP((2, "SendUnicastPacket: FLUSHING Mac Entry %x for %s\n",
  3540. pMacEntry, MacAddrToString(pDestAddress)));
  3541. //
  3542. // Queue packet on MAC Entry
  3543. //
  3544. AtmLaneQueuePacketOnHead(pMacEntry, pNdisPacket);
  3545. RELEASE_MAC_ENTRY_LOCK(pMacEntry);
  3546. break;
  3547. }
  3548. //
  3549. // MAC Entry State - ACTIVE
  3550. //
  3551. //
  3552. if (IS_FLAG_SET(
  3553. pMacEntry->Flags,
  3554. MAC_ENTRY_STATE_MASK,
  3555. MAC_ENTRY_ACTIVE))
  3556. {
  3557. DBGP((2, "SendUnicastPacket: ACTIVE Mac Entry %x for %s\n",
  3558. pMacEntry, MacAddrToString(pDestAddress)));
  3559. //
  3560. // Mark MAC Entry as having been used to send a packet.
  3561. // Will cause revalidation at aging time instead of deletion.
  3562. //
  3563. pMacEntry->Flags |= MAC_ENTRY_USED_FOR_SEND;
  3564. ASSERT(pMacEntry->pAtmEntry != NULL_PATMLANE_ATM_ENTRY);
  3565. pVc = pMacEntry->pAtmEntry->pVcList;
  3566. if (pVc == NULL_PATMLANE_VC)
  3567. {
  3568. RELEASE_MAC_ENTRY_LOCK(pMacEntry);
  3569. Status = NDIS_STATUS_FAILURE;
  3570. break;
  3571. }
  3572. ACQUIRE_VC_LOCK(pVc);
  3573. AtmLaneReferenceVc(pVc, "unicast");
  3574. RELEASE_VC_LOCK(pVc);
  3575. RELEASE_MAC_ENTRY_LOCK(pMacEntry);
  3576. ACQUIRE_VC_LOCK(pVc);
  3577. rc = AtmLaneDereferenceVc(pVc, "unicast");
  3578. if (rc == 0)
  3579. {
  3580. Status = NDIS_STATUS_FAILURE;
  3581. break;
  3582. }
  3583. AtmLaneSendPacketOnVc(pVc, pNdisPacket, TRUE);
  3584. //
  3585. // Vc lock released in above
  3586. //
  3587. NdisInterlockedIncrement(&pElan->FramesXmitGood); // count packet
  3588. break;
  3589. }
  3590. //
  3591. // MAC Entry State - AGED
  3592. //
  3593. //
  3594. if (IS_FLAG_SET(
  3595. pMacEntry->Flags,
  3596. MAC_ENTRY_STATE_MASK,
  3597. MAC_ENTRY_AGED))
  3598. {
  3599. DBGP((2, "SendUnicastPacket: AGED Mac Entry %x for %s\n",
  3600. pMacEntry, MacAddrToString(pDestAddress)));
  3601. ASSERT(pMacEntry->pAtmEntry != NULL_PATMLANE_ATM_ENTRY);
  3602. ASSERT(pMacEntry->pAtmEntry->pVcList != NULL_PATMLANE_VC);
  3603. pVc = pMacEntry->pAtmEntry->pVcList;
  3604. ACQUIRE_VC_LOCK(pVc);
  3605. AtmLaneReferenceVc(pVc, "unicast");
  3606. RELEASE_VC_LOCK(pVc);
  3607. RELEASE_MAC_ENTRY_LOCK(pMacEntry);
  3608. ACQUIRE_VC_LOCK(pVc);
  3609. rc = AtmLaneDereferenceVc(pVc, "unicast");
  3610. if (rc == 0)
  3611. {
  3612. Status = NDIS_STATUS_FAILURE;
  3613. break;
  3614. }
  3615. AtmLaneSendPacketOnVc(pVc, pNdisPacket, TRUE);
  3616. //
  3617. // Vc lock released in above
  3618. //
  3619. NdisInterlockedIncrement(&pElan->FramesXmitGood); // count packet
  3620. break;
  3621. }
  3622. //
  3623. // MAC Entry State - ABORTING
  3624. //
  3625. //
  3626. if (IS_FLAG_SET(
  3627. pMacEntry->Flags,
  3628. MAC_ENTRY_STATE_MASK,
  3629. MAC_ENTRY_ABORTING))
  3630. {
  3631. DBGP((2, "SendUnicastPacket: ABORTING Mac Entry %x for %s\n",
  3632. pMacEntry, MacAddrToString(pDestAddress)));
  3633. Status = NDIS_STATUS_FAILURE;
  3634. RELEASE_MAC_ENTRY_LOCK(pMacEntry);
  3635. break;
  3636. }
  3637. }
  3638. while (FALSE);
  3639. TRACEOUT(SendUnicastPacket);
  3640. return Status;
  3641. }
  3642. VOID
  3643. AtmLaneStartBusSends(
  3644. IN PATMLANE_MAC_ENTRY pMacEntry LOCKIN NOLOCKOUT
  3645. )
  3646. /*++
  3647. Routine Description:
  3648. Starts up the bus send process.
  3649. Arguments:
  3650. pMacEntry - A pointer to an ATMLANE MAC Entry structure
  3651. Return Value:
  3652. None
  3653. --*/
  3654. {
  3655. TRACEIN(StartBusSends);
  3656. do
  3657. {
  3658. //
  3659. // If timer set, just wait for it to go off
  3660. //
  3661. if (pMacEntry->Flags & MAC_ENTRY_BUS_TIMER)
  3662. {
  3663. RELEASE_MAC_ENTRY_LOCK(pMacEntry);
  3664. break;
  3665. }
  3666. //
  3667. // Otherwise do the sends
  3668. //
  3669. AtmLaneDoBusSends(pMacEntry);
  3670. //
  3671. // lock released in above
  3672. //
  3673. }
  3674. while (FALSE);
  3675. TRACEOUT(StartBusSends);
  3676. return;
  3677. }
  3678. VOID
  3679. AtmLaneDoBusSends(
  3680. IN PATMLANE_MAC_ENTRY pMacEntry LOCKIN NOLOCKOUT
  3681. )
  3682. /*++
  3683. Routine Description:
  3684. Attempt to send the packets on the MAC Entry's queue.
  3685. Schedule a timer to send later if we exceed the BUS send limits.
  3686. The caller is assumed to have acquired the MAC entry lock,
  3687. which will be released here.
  3688. Arguments:
  3689. pMacEntry - A pointer to an ATMLANE MAC Entry structure
  3690. Return Value:
  3691. None
  3692. --*/
  3693. {
  3694. PATMLANE_ATM_ENTRY pAtmEntry;
  3695. PATMLANE_VC pVc;
  3696. PATMLANE_ELAN pElan;
  3697. PNDIS_PACKET pNdisPacket;
  3698. ULONG rc;
  3699. TRACEIN(DoBusSends);
  3700. pElan = pMacEntry->pElan;
  3701. //
  3702. // Initialize
  3703. //
  3704. pVc = NULL_PATMLANE_VC;
  3705. //
  3706. // Place a temp ref on this MAC entry so that it won't go away.
  3707. //
  3708. AtmLaneReferenceMacEntry(pMacEntry, "DoBusSends");
  3709. do
  3710. {
  3711. //
  3712. // If Elan state not operational then done
  3713. //
  3714. if (ELAN_STATE_OPERATIONAL != pElan->AdminState ||
  3715. ELAN_STATE_OPERATIONAL != pElan->State)
  3716. {
  3717. break;
  3718. }
  3719. ACQUIRE_ELAN_ATM_LIST_LOCK(pElan);
  3720. pAtmEntry = pElan->pBusAtmEntry;
  3721. if (pAtmEntry == NULL_PATMLANE_ATM_ENTRY)
  3722. {
  3723. RELEASE_ELAN_ATM_LIST_LOCK(pElan);
  3724. break;
  3725. }
  3726. ACQUIRE_ATM_ENTRY_LOCK_DPC(pAtmEntry);
  3727. pVc = pAtmEntry->pVcList;
  3728. if (pVc == NULL_PATMLANE_VC)
  3729. {
  3730. RELEASE_ATM_ENTRY_LOCK_DPC(pAtmEntry);
  3731. RELEASE_ELAN_ATM_LIST_LOCK(pElan);
  3732. break;
  3733. }
  3734. //
  3735. // Reference the VC to keep it around
  3736. //
  3737. ACQUIRE_VC_LOCK_DPC(pVc);
  3738. AtmLaneReferenceVc(pVc, "temp");
  3739. RELEASE_VC_LOCK_DPC(pVc);
  3740. RELEASE_ATM_ENTRY_LOCK_DPC(pAtmEntry);
  3741. RELEASE_ELAN_ATM_LIST_LOCK(pElan);
  3742. //
  3743. // loop until no more packets or send limit reached
  3744. //
  3745. do
  3746. {
  3747. //
  3748. // If no more packets to send then done
  3749. //
  3750. if (pMacEntry->PacketList == (PNDIS_PACKET)NULL)
  3751. {
  3752. break;
  3753. }
  3754. //
  3755. // Check if ok to send a packet now
  3756. //
  3757. if (!AtmLaneOKToBusSend(pMacEntry))
  3758. {
  3759. //
  3760. // Not OK to send now, try later
  3761. //
  3762. // Reference the MAC Entry
  3763. //
  3764. AtmLaneReferenceMacEntry(pMacEntry, "bus timer");
  3765. //
  3766. // Reschedule the timer routine
  3767. //
  3768. pMacEntry->Flags |= MAC_ENTRY_BUS_TIMER;
  3769. NdisSetTimer(&pMacEntry->BusTimer, pMacEntry->IncrTime);
  3770. break;
  3771. }
  3772. //
  3773. // Dequeue a packet
  3774. //
  3775. pNdisPacket = AtmLaneDequeuePacketFromHead(pMacEntry);
  3776. RELEASE_MAC_ENTRY_LOCK(pMacEntry);
  3777. ASSERT(pNdisPacket != (PNDIS_PACKET)NULL);
  3778. //
  3779. // Reacquire VC lock and if VC still connected send packet
  3780. //
  3781. ACQUIRE_VC_LOCK(pVc);
  3782. if (IS_FLAG_SET(
  3783. pVc->Flags,
  3784. VC_CALL_STATE_MASK,
  3785. VC_CALL_STATE_ACTIVE))
  3786. {
  3787. DBGP((2, "DoBusSends: pVc %x Pkt %x Sending to BUS\n",
  3788. pVc, pNdisPacket));
  3789. AtmLaneSendPacketOnVc(pVc, pNdisPacket, FALSE);
  3790. //
  3791. // VC lock released in above
  3792. //
  3793. NdisInterlockedIncrement(&pElan->FramesXmitGood); // count it
  3794. ACQUIRE_MAC_ENTRY_LOCK(pMacEntry);
  3795. }
  3796. else
  3797. {
  3798. //
  3799. // Not sent, release lock, requeue packet, abort
  3800. //
  3801. DBGP((2, "DoBusSend: pVc %x, Flags %x not good, pkt %x\n",
  3802. pVc, pVc->Flags, pNdisPacket));
  3803. RELEASE_VC_LOCK(pVc);
  3804. ACQUIRE_MAC_ENTRY_LOCK(pMacEntry);
  3805. AtmLaneQueuePacketOnHead(pMacEntry, pNdisPacket);
  3806. break;
  3807. }
  3808. }
  3809. while (FALSE);
  3810. //
  3811. // Remove temp VC reference
  3812. //
  3813. if (pVc == NULL_PATMLANE_VC)
  3814. {
  3815. ACQUIRE_VC_LOCK(pVc);
  3816. rc = AtmLaneDereferenceVc(pVc, "temp");
  3817. if (rc > 0)
  3818. {
  3819. RELEASE_VC_LOCK(pVc);
  3820. }
  3821. //
  3822. // else VC is gone
  3823. //
  3824. }
  3825. }
  3826. while (FALSE);
  3827. //
  3828. // Remove the temp ref we had added to the MAC entry on entering
  3829. // this function.
  3830. //
  3831. rc = AtmLaneDereferenceMacEntry(pMacEntry, "DoBusSends");
  3832. if (rc != 0)
  3833. {
  3834. RELEASE_MAC_ENTRY_LOCK(pMacEntry);
  3835. }
  3836. //
  3837. // else the MAC entry is gone.
  3838. //
  3839. TRACEOUT(DoBusSends);
  3840. return;
  3841. }
  3842. VOID
  3843. AtmLaneBusSendTimer(
  3844. IN PVOID SystemSpecific1,
  3845. IN PVOID pContext,
  3846. IN PVOID SystemSpecific2,
  3847. IN PVOID SystemSpecific3
  3848. )
  3849. {
  3850. PATMLANE_MAC_ENTRY pMacEntry;
  3851. ULONG rc;
  3852. TRACEIN(BusSendTimer);
  3853. pMacEntry = (PATMLANE_MAC_ENTRY)pContext;
  3854. STRUCT_ASSERT(pMacEntry, atmlane_mac);
  3855. do
  3856. {
  3857. //
  3858. // Grab the Mac Entry's lock
  3859. //
  3860. ACQUIRE_MAC_ENTRY_LOCK(pMacEntry);
  3861. //
  3862. // Clear the bus timer flag
  3863. //
  3864. pMacEntry->Flags &= ~ MAC_ENTRY_BUS_TIMER;
  3865. //
  3866. // Dereference the Mac Entry
  3867. //
  3868. rc = AtmLaneDereferenceMacEntry(pMacEntry, "bus timer");
  3869. if (rc == 0)
  3870. {
  3871. break;
  3872. }
  3873. //
  3874. // Mac Entry still here, try to send more
  3875. //
  3876. AtmLaneDoBusSends(pMacEntry);
  3877. //
  3878. // lock released in above
  3879. //
  3880. break;
  3881. }
  3882. while (FALSE);
  3883. TRACEOUT(BusSendTimer);
  3884. return;
  3885. }
  3886. BOOLEAN
  3887. AtmLaneOKToBusSend(
  3888. IN PATMLANE_MAC_ENTRY pMacEntry
  3889. )
  3890. /*++
  3891. Routine Description:
  3892. Determines if, at the current time, it is OK to send
  3893. a packet to the BUS. Additionally, if it is OK to send
  3894. a packet, it updates the state variables in the MAC Entry
  3895. in preparation for another attempt to send a packet to
  3896. the Bus.
  3897. The LANE spec requires a LANE client to restrict the
  3898. sending of packets over the BUS to a specific LAN
  3899. destination address by using two parameters:
  3900. Maximum Unknown Packet Count
  3901. Maximum Unknown Packet Time
  3902. A LANE client can only send "Maximum Unknown Packet Count"
  3903. packets within the period of time "Maximum Unknown Packet
  3904. Time".
  3905. This function expects the MAC Entry to contain three
  3906. variables:
  3907. BusyTime
  3908. LimitTime
  3909. IncrTime
  3910. Arguments:
  3911. pMacEntry - Pointer to an ATMLANE MAC Entry.
  3912. Return Value:
  3913. TRUE - if ok to send packet on BUS
  3914. FALSE - if exceeded traffic to the BUS
  3915. --*/
  3916. {
  3917. ULONG Now;
  3918. ULONG BusyTime;
  3919. LONG TimeUntilIdle;
  3920. Now = AtmLaneSystemTimeMs();
  3921. BusyTime = pMacEntry->BusyTime;
  3922. TimeUntilIdle = BusyTime - Now;
  3923. //
  3924. // bring busy until time up to current; also handles
  3925. // wrapping. Under normal circumstances, TimeUntilIdle
  3926. // is either < 0 or no more than limitTime + incrtime.
  3927. // The value of limitTime * 8 is a little more conservative and
  3928. // cheaper to compute.
  3929. //
  3930. if (TimeUntilIdle < 0 ||
  3931. TimeUntilIdle > (LONG)(pMacEntry->LimitTime << 3))
  3932. {
  3933. BusyTime = Now;
  3934. }
  3935. else
  3936. {
  3937. if (TimeUntilIdle > (LONG)pMacEntry->LimitTime)
  3938. {
  3939. //
  3940. // channel is already estimated to be busy until past
  3941. // the burst time, so we can't overload it by sending
  3942. // more now.
  3943. //
  3944. return FALSE;
  3945. }
  3946. }
  3947. //
  3948. // mark channel as busy for another inter-packet arrival
  3949. // time, and return OK to send the new packet.
  3950. //
  3951. pMacEntry->BusyTime = BusyTime + pMacEntry->IncrTime;
  3952. return TRUE;
  3953. }
  3954. VOID
  3955. AtmLaneFreePacketQueue(
  3956. IN PATMLANE_MAC_ENTRY pMacEntry,
  3957. IN NDIS_STATUS Status
  3958. )
  3959. /*++
  3960. Routine Description:
  3961. Frees the list of packets queued on a MAC Entry.
  3962. Assumes caller holds lock on MAC Entry.
  3963. Arguments:
  3964. pMacEntry - Pointer to MAC Entry.
  3965. Status - The status to use if the packet is
  3966. protocol packet.
  3967. Return Value:
  3968. None
  3969. --*/
  3970. {
  3971. PNDIS_PACKET pNdisPacket;
  3972. TRACEIN(FreePacketQueue);
  3973. while ((pNdisPacket = AtmLaneDequeuePacketFromHead(pMacEntry)) != (PNDIS_PACKET)NULL)
  3974. {
  3975. RELEASE_MAC_ENTRY_LOCK(pMacEntry);
  3976. #if PROTECT_PACKETS
  3977. ACQUIRE_SENDPACKET_LOCK(pNdisPacket);
  3978. PSEND_RSVD(pNdisPacket)->Flags |= PACKET_RESERVED_COSENDRETURNED;
  3979. PSEND_RSVD(pNdisPacket)->Flags |= PACKET_RESERVED_COMPLETED;
  3980. #endif // PROTECT_PACKETS
  3981. AtmLaneCompleteSendPacket(pMacEntry->pElan, pNdisPacket, Status);
  3982. //
  3983. // packet lock released in above
  3984. //
  3985. ACQUIRE_MAC_ENTRY_LOCK(pMacEntry);
  3986. }
  3987. TRACEOUT(FreePacketQueue);
  3988. return;
  3989. }
  3990. VOID
  3991. AtmLaneCompleteSendPacket(
  3992. IN PATMLANE_ELAN pElan,
  3993. IN PNDIS_PACKET pNdisPacket LOCKIN NOLOCKOUT,
  3994. IN NDIS_STATUS Status
  3995. )
  3996. /*++
  3997. Routine Description:
  3998. Complete a send packet. The packet is one of the following types:
  3999. (a) Belonging to a protocol (b) Belonging to the ATMLANE module.
  4000. In the case of a protocol packet we unwrap it and complete it.
  4001. In the case of an ATMLANE packet we just free it.
  4002. Arguments:
  4003. pElan - Pointer to ATMLANE Elan.
  4004. pNdisPacket - Pointer to the packet
  4005. Status - The status to use if the packet is
  4006. protocol packet.
  4007. Return Value:
  4008. None
  4009. --*/
  4010. {
  4011. PNDIS_BUFFER pNdisBuffer;
  4012. PNDIS_PACKET pProtNdisPacket;
  4013. TRACEIN(CompleteSendPacket);
  4014. #if PROTECT_PACKETS
  4015. //
  4016. // Assert that we can release and/or complete all resources for this packet
  4017. //
  4018. ASSERT((PSEND_RSVD(pNdisPacket)->Flags &
  4019. (PACKET_RESERVED_COMPLETED | PACKET_RESERVED_COSENDRETURNED))
  4020. == (PACKET_RESERVED_COMPLETED | PACKET_RESERVED_COSENDRETURNED));
  4021. #endif // PROTECT_PACKETS
  4022. //
  4023. // Determine originator of packet
  4024. //
  4025. if (IS_FLAG_SET(
  4026. PSEND_RSVD(pNdisPacket)->Flags,
  4027. PACKET_RESERVED_OWNER_MASK,
  4028. PACKET_RESERVED_OWNER_ATMLANE
  4029. ))
  4030. {
  4031. //
  4032. // Packet originated by ATMLANE. Free the buffer.
  4033. //
  4034. NdisUnchainBufferAtFront(pNdisPacket, &pNdisBuffer);
  4035. ASSERT(NULL != pNdisBuffer);
  4036. AtmLaneFreeProtoBuffer(pElan, pNdisBuffer);
  4037. //
  4038. // Free the packet header.
  4039. //
  4040. DBGP((3, "CompleteSendPkt: Freeing AtmLane owned pkt %x\n", pNdisPacket));
  4041. #if PROTECT_PACKETS
  4042. RELEASE_SENDPACKET_LOCK(pNdisPacket);
  4043. FREE_SENDPACKET_LOCK(pNdisPacket);
  4044. #endif // PROTECT_PACKETS
  4045. NdisFreePacket(pNdisPacket);
  4046. #if PKT_HDR_COUNTS
  4047. InterlockedIncrement(&pElan->ProtPktCount);
  4048. if ((pElan->ProtPktCount % 20) == 0 &&
  4049. pElan->ProtPktCount != pElan->MaxProtocolBufs)
  4050. {
  4051. DBGP((1, "ProtPktCount %d\n", pElan->ProtPktCount));
  4052. }
  4053. #endif
  4054. }
  4055. else
  4056. {
  4057. //
  4058. // Packet orignated by a protocol.
  4059. // Unwrap it.
  4060. // Complete it to the protocol.
  4061. //
  4062. pProtNdisPacket = AtmLaneUnwrapSendPacket(pElan, pNdisPacket);
  4063. //
  4064. // packet lock released in above
  4065. //
  4066. TRACELOGWRITE((&TraceLog, TL_MSENDCOMPL, pProtNdisPacket, Status));
  4067. TRACELOGWRITEPKT((&TraceLog, pProtNdisPacket));
  4068. // DBGP((0, "NdisMSendComplete: Pkt %x Stat %x\n", pProtNdisPacket, Status));
  4069. NdisMSendComplete(
  4070. pElan->MiniportAdapterHandle,
  4071. pProtNdisPacket,
  4072. Status);
  4073. }
  4074. TRACEOUT(CompleteSendPacket);
  4075. return;
  4076. }
  4077. PWSTR
  4078. AtmLaneMacAddrToString(
  4079. IN VOID * pIn
  4080. )
  4081. {
  4082. static PWSTR WHexChars = L"0123456789abcdef";
  4083. PWSTR StrBuf;
  4084. ULONG Index;
  4085. PWSTR pWStr;
  4086. PUCHAR pMacAddr;
  4087. PWSTR punicodeMacAddrBuffer = ((PWSTR)0);
  4088. UNICODE_STRING unicodeString;
  4089. ANSI_STRING ansiString;
  4090. TRACEIN(MacAddrToString);
  4091. // alloc space for output unicode string
  4092. ALLOC_MEM(&punicodeMacAddrBuffer, (((sizeof(MAC_ADDRESS) * 2) + 1) * sizeof(WCHAR)));
  4093. if (((PWSTR)0) != punicodeMacAddrBuffer)
  4094. {
  4095. for (Index = 0, pWStr = punicodeMacAddrBuffer, pMacAddr = pIn;
  4096. Index < sizeof(MAC_ADDRESS);
  4097. Index++, pMacAddr++)
  4098. {
  4099. *pWStr++ = WHexChars[(*pMacAddr)>>4];
  4100. *pWStr++ = WHexChars[(*pMacAddr)&0xf];
  4101. }
  4102. *pWStr = L'\0';
  4103. }
  4104. TRACEOUT(MacAddrToString);
  4105. return punicodeMacAddrBuffer;
  4106. }
  4107. PWSTR
  4108. AtmLaneAtmAddrToString(
  4109. IN PATM_ADDRESS pIn
  4110. )
  4111. {
  4112. static PWSTR WHexChars = L"0123456789abcdef";
  4113. PWSTR StrBuf;
  4114. ULONG Index;
  4115. PWSTR pWStr;
  4116. PUCHAR pAtmAddr;
  4117. PWSTR punicodeAtmAddrBuffer = ((PWSTR)0);
  4118. UNICODE_STRING unicodeString;
  4119. ANSI_STRING ansiString;
  4120. TRACEIN(AtmAddrToString);
  4121. // alloc space for output unicode string
  4122. ALLOC_MEM(&punicodeAtmAddrBuffer, (((ATM_ADDRESS_LENGTH * 2) + 1) * sizeof(WCHAR)));
  4123. if (((PWSTR)0) != punicodeAtmAddrBuffer)
  4124. {
  4125. // format ATM addr into Unicode string buffer
  4126. for (Index = 0, pWStr = punicodeAtmAddrBuffer, pAtmAddr = pIn->Address;
  4127. Index < pIn->NumberOfDigits;
  4128. Index++, pAtmAddr++)
  4129. {
  4130. *pWStr++ = WHexChars[(*pAtmAddr)>>4];
  4131. *pWStr++ = WHexChars[(*pAtmAddr)&0xf];
  4132. }
  4133. *pWStr = L'\0';
  4134. }
  4135. TRACEOUT(AtmAddrToString);
  4136. return punicodeAtmAddrBuffer;
  4137. }