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.

6892 lines
178 KiB

  1. //
  2. // Copyright (c) 1998-1999, Microsoft Corporation, all rights reserved
  3. //
  4. // mp.c
  5. //
  6. // IEEE1394 mini-port/call-manager driver
  7. //
  8. // Mini-port routines
  9. //
  10. // 12/28/1998 JosephJ Created,
  11. //
  12. #include <precomp.h>
  13. #include "mp.h"
  14. #pragma hdrstop
  15. //-----------------------------------------------------------------------------
  16. // Data used in processing requests
  17. //-----------------------------------------------------------------------------
  18. NDIS_OID SupportedOids[] =
  19. {
  20. OID_GEN_CO_SUPPORTED_LIST,
  21. OID_GEN_CO_HARDWARE_STATUS,
  22. OID_GEN_CO_MEDIA_SUPPORTED,
  23. OID_GEN_CO_MEDIA_IN_USE,
  24. OID_GEN_CO_LINK_SPEED,
  25. OID_GEN_CO_VENDOR_ID,
  26. OID_GEN_CO_VENDOR_DESCRIPTION,
  27. OID_GEN_CO_DRIVER_VERSION,
  28. OID_GEN_CO_PROTOCOL_OPTIONS,
  29. OID_GEN_CO_MEDIA_CONNECT_STATUS,
  30. OID_GEN_CO_MAC_OPTIONS,
  31. OID_GEN_CO_VENDOR_DRIVER_VERSION,
  32. OID_GEN_CO_MINIMUM_LINK_SPEED,
  33. OID_GEN_CO_XMIT_PDUS_OK,
  34. OID_GEN_CO_RCV_PDUS_OK,
  35. OID_GEN_CO_XMIT_PDUS_ERROR,
  36. OID_GEN_CO_RCV_PDUS_ERROR,
  37. OID_GEN_CO_RCV_PDUS_NO_BUFFER,
  38. OID_1394_LOCAL_NODE_INFO,
  39. OID_1394_VC_INFO,
  40. OID_1394_NICINFO,
  41. OID_1394_IP1394_CONNECT_STATUS,
  42. OID_1394_ENTER_BRIDGE_MODE,
  43. OID_1394_EXIT_BRIDGE_MODE,
  44. OID_1394_ISSUE_BUS_RESET,
  45. OID_802_3_CURRENT_ADDRESS,
  46. #ifdef _ETHERNET_
  47. OID_GEN_MAXIMUM_LOOKAHEAD,
  48. OID_GEN_MAXIMUM_FRAME_SIZE,
  49. OID_GEN_MAXIMUM_TOTAL_SIZE,
  50. OID_GEN_LINK_SPEED,
  51. OID_GEN_TRANSMIT_BUFFER_SPACE,
  52. OID_GEN_RECEIVE_BUFFER_SPACE,
  53. OID_GEN_TRANSMIT_BLOCK_SIZE,
  54. OID_GEN_RECEIVE_BLOCK_SIZE,
  55. OID_GEN_MAXIMUM_SEND_PACKETS,
  56. OID_GEN_CURRENT_PACKET_FILTER,
  57. OID_GEN_CURRENT_LOOKAHEAD,
  58. OID_802_3_PERMANENT_ADDRESS,
  59. OID_802_3_MULTICAST_LIST,
  60. OID_802_3_MAXIMUM_LIST_SIZE,
  61. OID_802_3_RCV_ERROR_ALIGNMENT,
  62. OID_802_3_XMIT_ONE_COLLISION,
  63. OID_802_3_XMIT_MORE_COLLISIONS,
  64. OID_GEN_PROTOCOL_OPTIONS,
  65. OID_GEN_CURRENT_PACKET_FILTER,
  66. OID_GEN_CURRENT_LOOKAHEAD,
  67. OID_GEN_PHYSICAL_MEDIUM,
  68. #endif
  69. OID_PNP_QUERY_POWER,
  70. OID_PNP_SET_POWER,
  71. OID_IP1394_QUERY_UID,
  72. OID_IP1394_QUERY_STATS,
  73. OID_IP1394_QUERY_REMOTE_UID,
  74. OID_1394_QUERY_EUID_NODE_MAP
  75. };
  76. //-----------------------------------------------------------------------------
  77. // Locally used function prototypes
  78. //-----------------------------------------------------------------------------
  79. NDIS_STATUS
  80. nicAllocateLoopbackPacketPool (
  81. IN PADAPTERCB pAdapter
  82. );
  83. VOID
  84. nicFreeLoopbackPacketPool (
  85. IN PADAPTERCB pAdapter
  86. );
  87. VOID
  88. nicLoopbackPacket(
  89. IN VCCB* pVc,
  90. IN PNDIS_PACKET pPacket
  91. );
  92. VOID
  93. nicQueryEuidNodeMacMap (
  94. IN PADAPTERCB pAdapter,
  95. IN PNDIS_REQUEST pRequest
  96. );
  97. VOID
  98. nicRemoveRemoteNodeFromNodeTable(
  99. IN PNODE_TABLE pNodeTable,
  100. IN PREMOTE_NODE pRemoteNode
  101. );
  102. NDIS_STATUS
  103. MPSetPower (
  104. IN PADAPTERCB pAdapter,
  105. IN NET_DEVICE_POWER_STATE DeviceState
  106. );
  107. //-----------------------------------------------------------------------------
  108. // Mini-port handlers
  109. //-----------------------------------------------------------------------------
  110. NDIS_STATUS
  111. NicMpInitialize(
  112. OUT PNDIS_STATUS OpenErrorStatus,
  113. OUT PUINT SelectedMediumIndex,
  114. IN PNDIS_MEDIUM MediumArray,
  115. IN UINT MediumArraySize,
  116. IN NDIS_HANDLE MiniportAdapterHandle,
  117. IN NDIS_HANDLE WrapperConfigurationContext
  118. )
  119. // Standard 'MiniportInitialize' routine called by NDIS to initialize a
  120. // new WAN adapter. See DDK doc. The driver will receive no requests
  121. // until this initialization has completed.
  122. //
  123. // After a resume from suspend, multiple miniports will be initialized in a
  124. // non -serialized manner. Be prepared.
  125. //
  126. {
  127. NDIS_STATUS NdisStatus;
  128. NTSTATUS NtStatus;
  129. PADAPTERCB pAdapter= NULL;
  130. PDEVICE_OBJECT pNdisDeviceObject = NULL;
  131. PDEVICE_OBJECT p1394DeviceObject = NULL;
  132. LARGE_INTEGER LocalHostUniqueId;
  133. REMOTE_NODE *p1394RemoteNodePdoCb = NULL;
  134. UINT64 u64LocalHostUniqueId =0;
  135. BOOLEAN FreeAdapter = FALSE;
  136. BOOLEAN DequeueAdapter = FALSE;
  137. ULONG Generation;
  138. ULONG InitStatus;
  139. //
  140. // This is the order with which the initialize routine is done.
  141. //
  142. enum
  143. {
  144. NoState,
  145. AllocatedAdapter,
  146. AdapterQueued,
  147. InitializedEvents,
  148. InitializedBcr,
  149. RegisteredResetCallback,
  150. AddedConfigRom,
  151. RegisteredEnumerator,
  152. InitializedLookasideList,
  153. InitializedPktLog,
  154. InitializedRcvThread,
  155. InitializedSendThread,
  156. InitializedReassembly,
  157. InitializedLoopbackPool
  158. };
  159. STORE_CURRENT_IRQL
  160. TIMESTAMP_ENTRY("==>IntializeHandler");
  161. TIMESTAMP_INITIALIZE();
  162. TRACE( TL_T, TM_Init, ( "==>NicMpInitialize" ) );
  163. InitStatus = NoState;
  164. NdisStatus = *OpenErrorStatus = NDIS_STATUS_SUCCESS;
  165. // Find the medium index in the array of media, looking for the only one
  166. // we support, 'NdisMedium1394'.
  167. //
  168. {
  169. UINT i;
  170. for (i = 0; i < MediumArraySize; ++i)
  171. {
  172. if (MediumArray[ i ] == g_ulMedium )
  173. {
  174. break;
  175. }
  176. }
  177. if (i >= MediumArraySize)
  178. {
  179. TRACE( TL_A, TM_Init, ( "medium?" ) );
  180. return NDIS_STATUS_FAILURE;
  181. }
  182. *SelectedMediumIndex = i;
  183. }
  184. // Allocate and zero a control block for the new adapter.
  185. //
  186. pAdapter = ALLOC_NONPAGED( sizeof(ADAPTERCB), MTAG_ADAPTERCB );
  187. TRACE( TL_N, TM_Init, ( "Acb=$%p", pAdapter ) );
  188. if (!pAdapter)
  189. {
  190. return NDIS_STATUS_RESOURCES;
  191. }
  192. FreeAdapter = TRUE;
  193. InitStatus = AllocatedAdapter;
  194. NdisZeroMemory (pAdapter, sizeof(*pAdapter) );
  195. // Add a reference that will eventually be removed by an NDIS call to
  196. // the nicFreeAdapter handler.
  197. //
  198. nicReferenceAdapter (pAdapter, "MpInitialize" );
  199. // Set a marker for easier memory dump browsing and future assertions.
  200. //
  201. pAdapter->ulTag = MTAG_ADAPTERCB;
  202. // Save the NDIS handle associated with this adapter for use in future
  203. // NdisXxx calls.
  204. //
  205. pAdapter->MiniportAdapterHandle = MiniportAdapterHandle;
  206. // Initialize the adapter-wide lock.
  207. //
  208. NdisAllocateSpinLock( &pAdapter->lock );
  209. // Initialize the various lists of top-level resources.
  210. //
  211. pAdapter->HardwareStatus = NdisHardwareStatusInitializing;
  212. //
  213. // The enumerator and bus1394 have asked us to load, therefore media
  214. // should be connected
  215. //
  216. pAdapter->MediaConnectStatus = NdisMediaStateDisconnected;
  217. InitializeListHead( &pAdapter->AFList );
  218. InitializeListHead( &pAdapter->PDOList );
  219. InitializeListHead( &pAdapter->BroadcastChannel.VcList );
  220. //
  221. // Default initialization values
  222. //
  223. pAdapter->Speed = SPEED_FLAGS_400;
  224. pAdapter->SpeedMbps = 4 * 1000000;
  225. pAdapter->SCode = SCODE_400_RATE;
  226. do
  227. {
  228. // Read this adapter's registry settings.
  229. //
  230. NdisStatus = nicGetRegistrySettings(
  231. WrapperConfigurationContext,
  232. pAdapter
  233. );
  234. if (NdisStatus != NDIS_STATUS_SUCCESS)
  235. {
  236. break;
  237. }
  238. // Inform NDIS of the attributes of our adapter. Set the
  239. // 'MiniportAdapterContext' returned to us by NDIS when it calls our
  240. // handlers to the address of our adapter control block. Turn off
  241. // hardware oriented timeouts.
  242. //
  243. NdisMSetAttributesEx(
  244. MiniportAdapterHandle,
  245. (NDIS_HANDLE)pAdapter,
  246. (UINT)0,
  247. NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT | NDIS_ATTRIBUTE_IGNORE_TOKEN_RING_ERRORS |
  248. NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND | NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT |
  249. NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK,
  250. NdisInterfaceInternal );
  251. NdisStatus = nicMCmRegisterAddressFamily (pAdapter);
  252. if (NdisStatus != NDIS_STATUS_SUCCESS)
  253. {
  254. //
  255. // If we fail, Let the next entrant try the same thing
  256. //
  257. break;
  258. }
  259. ADAPTER_SET_FLAG (pAdapter,fADAPTER_RegisteredAF);
  260. //
  261. // Insert into global list of adapters. So we will be ready to receive notifications
  262. // from the enumerator
  263. //
  264. NdisAcquireSpinLock ( &g_DriverLock);
  265. InsertHeadList (&g_AdapterList, &pAdapter->linkAdapter);
  266. DequeueAdapter = TRUE;
  267. InitStatus = AdapterQueued;
  268. NdisReleaseSpinLock (&g_DriverLock);
  269. pAdapter->HardwareStatus = NdisHardwareStatusReady;
  270. //
  271. // Set up linkages. Get the PDO for the device from Ndis
  272. //
  273. NdisMGetDeviceProperty( MiniportAdapterHandle,
  274. &pNdisDeviceObject,
  275. NULL,
  276. NULL,
  277. NULL,
  278. NULL );
  279. ASSERT (pNdisDeviceObject != NULL);
  280. pAdapter->Generation = 0;
  281. //
  282. // Update data structure with the local hosts VDO
  283. //
  284. pAdapter->pNdisDeviceObject = pNdisDeviceObject;
  285. TRACE( TL_I, TM_Mp, ( " LocalHost VDO %x", pNdisDeviceObject) );
  286. nicInitializeAllEvents (pAdapter);
  287. InitStatus = InitializedEvents;
  288. //
  289. // Initialize the BCM so it is ready to handle Resets
  290. //
  291. NdisStatus = nicInitializeBroadcastChannelRegister (pAdapter);
  292. if (NdisStatus != NDIS_STATUS_SUCCESS)
  293. {
  294. BREAK( TM_Init, ( "nicMpInitialize - nicInitializeBroadcastChannelRegister ") );
  295. }
  296. InitStatus = InitializedBcr;
  297. //
  298. // Initialize the generation count , reset callback and config rom
  299. //
  300. NdisStatus = nicGetGenerationCount (pAdapter, &Generation);
  301. if (NdisStatus != NDIS_STATUS_SUCCESS)
  302. {
  303. BREAK (TM_Init, ("Initialize Handler - nicGetGeneration Failed" ) );
  304. }
  305. pAdapter->Generation = Generation;
  306. //
  307. // request notification of bus resets
  308. //
  309. NdisStatus = nicBusResetNotification (pAdapter,
  310. REGISTER_NOTIFICATION_ROUTINE,
  311. nicResetNotificationCallback,
  312. pAdapter);
  313. if (NdisStatus != NDIS_STATUS_SUCCESS)
  314. {
  315. BREAK (TM_Init, ("Initialize Handler - nicBusResetNotification Failed" ) );
  316. }
  317. InitStatus = RegisteredResetCallback;
  318. //
  319. // add ip/1394 to the config rom
  320. //
  321. NdisStatus = nicAddIP1394ToConfigRom (pAdapter);
  322. if (NdisStatus != NDIS_STATUS_SUCCESS)
  323. {
  324. BREAK (TM_Init, ("Initialize Handler - nicAddIP1394ToConfigRom Failed" ) );
  325. }
  326. InitStatus = AddedConfigRom;
  327. //
  328. // Lets find out our MaxRec
  329. //
  330. NdisStatus = nicGetReadWriteCapLocalHost(pAdapter, &pAdapter->ReadWriteCaps);
  331. pAdapter->MaxRec = nicGetMaxRecFromBytes(pAdapter->ReadWriteCaps.MaxAsyncWriteRequest);
  332. TRACE (TL_V, TM_Mp, (" MaxRec %x\n", pAdapter->MaxRec ) );
  333. nicUpdateLocalHostSpeed (pAdapter);
  334. TRACE (TL_V, TM_Mp, (" SCode %x", pAdapter->SCode) );
  335. //
  336. // Bus Reset - used to kick off the BCM algorithm
  337. //
  338. nicIssueBusReset (pAdapter,BUS_RESET_FLAGS_FORCE_ROOT );
  339. #if QUEUED_PACKETS
  340. nicInitSerializedStatusStruct (pAdapter); // cannot fail
  341. #endif
  342. //
  343. // Register this adapter with the enumerator.
  344. //
  345. if (NdisEnum1394DeregisterAdapter != NULL)
  346. {
  347. NtStatus = NdisEnum1394RegisterAdapter((PVOID)pAdapter,
  348. pNdisDeviceObject,
  349. &pAdapter->EnumAdapterHandle,
  350. &LocalHostUniqueId);
  351. if (NtStatus != STATUS_SUCCESS)
  352. {
  353. ADAPTER_SET_FLAG(pAdapter, fADAPTER_FailedRegisteration);
  354. //
  355. // Don;t Bail Out
  356. //
  357. //NdisStatus = NDIS_STATUS_FAILURE;
  358. BREAK( TM_Init, ( "nicMpInitialize - NdisEnum1394RegisterAdapter FAILED ") );
  359. }
  360. else
  361. {
  362. ADAPTER_SET_FLAG(pAdapter, fADAPTER_RegisteredWithEnumerator);
  363. InitStatus = RegisteredEnumerator;
  364. }
  365. }
  366. else
  367. {
  368. GET_LOCAL_HOST_INFO1 Uid;
  369. //
  370. // Enum is not loaded get the Unique Id
  371. //
  372. NdisStatus = nicGetLocalHostUniqueId (pAdapter,
  373. &Uid );
  374. if (NdisStatus != NDIS_STATUS_SUCCESS)
  375. {
  376. BREAK( TM_Init, ( " nicMpInitialize - nicGetLocalHostUniqueId FAILED ") );
  377. }
  378. else
  379. {
  380. LocalHostUniqueId = Uid.UniqueId;
  381. }
  382. }
  383. //
  384. // Validate the Local Adapter's Unique Id
  385. //
  386. if (LocalHostUniqueId.QuadPart == (UINT64)(0) )
  387. {
  388. nicWriteErrorLog (pAdapter,NDIS_ERROR_CODE_HARDWARE_FAILURE, NIC_ERROR_CODE_INVALID_UNIQUE_ID_0);
  389. NdisStatus = NDIS_STATUS_FAILURE;
  390. break;
  391. }
  392. if (LocalHostUniqueId.QuadPart == (UINT64)(-1) )
  393. {
  394. nicWriteErrorLog (pAdapter,NDIS_ERROR_CODE_HARDWARE_FAILURE,NIC_ERROR_CODE_INVALID_UNIQUE_ID_FF);
  395. NdisStatus = NDIS_STATUS_FAILURE;
  396. break;
  397. }
  398. #ifdef PKT_LOG
  399. nic1394AllocPktLog (pAdapter);
  400. if (pAdapter->pPktLog == NULL)
  401. {
  402. NdisStatus = NDIS_STATUS_FAILURE;
  403. BREAK (TM_Init, ("nicMpInitialize - Could not allocate packetlog" ) );
  404. }
  405. nic1394InitPktLog(pAdapter->pPktLog);
  406. InitStatus = InitializedPktLog;
  407. #endif
  408. #if QUEUED_PACKETS
  409. NdisStatus = nicInitSerializedReceiveStruct(pAdapter);
  410. if (NdisStatus != NDIS_STATUS_SUCCESS)
  411. {
  412. BREAK (TM_Init, ("nicMpInitialize - nicInitSerializedReceiveStruct FAILED" ) );
  413. }
  414. InitStatus = InitializedRcvThread;
  415. NdisStatus = nicInitSerializedSendStruct(pAdapter);
  416. if (NdisStatus != NDIS_STATUS_SUCCESS)
  417. {
  418. BREAK (TM_Init, ("nicMpInitialize - nicInitSerializedSendStruct FAILED" ) );
  419. }
  420. InitStatus = InitializedSendThread;
  421. //
  422. // Init Stats
  423. //
  424. nicInitQueueStats();
  425. nicInitTrackFailure();
  426. pAdapter->AdaptStats.ulResetTime = nicGetSystemTime() ;
  427. #endif
  428. //
  429. // Initialize the reassembly timers
  430. //
  431. nicInitSerializedReassemblyStruct(pAdapter); // cannot fail
  432. InitStatus = InitializedReassembly;
  433. //
  434. // This swap is done so that the byte reported by the bus driver matches that
  435. // which is used in the notification of add nodes, remove nodes and make call
  436. //
  437. LocalHostUniqueId.LowPart = SWAPBYTES_ULONG (LocalHostUniqueId.LowPart );
  438. LocalHostUniqueId.HighPart = SWAPBYTES_ULONG (LocalHostUniqueId.HighPart );
  439. u64LocalHostUniqueId = LocalHostUniqueId.QuadPart;
  440. pAdapter->UniqueId = u64LocalHostUniqueId;
  441. pAdapter->HardwareStatus = NdisHardwareStatusReady;
  442. //
  443. // Get Our local Fake Mac address
  444. //
  445. nicGetFakeMacAddress (&u64LocalHostUniqueId, &pAdapter->MacAddressEth);
  446. TRACE( TL_I, TM_Init, ( "NdisDeviceObject %.8x, p1394DeviceObject %.8x", pNdisDeviceObject, p1394DeviceObject) );
  447. //
  448. // Initialize the lookaside lists
  449. //
  450. nicInitializeAdapterLookasideLists (pAdapter);
  451. InitStatus = InitializedLookasideList;
  452. //
  453. // Initialize the remote node table
  454. //
  455. nicUpdateRemoteNodeTable (pAdapter);
  456. //
  457. // initialize the gasp header
  458. //
  459. nicMakeGaspHeader (pAdapter, &pAdapter->GaspHeader);
  460. //
  461. // Assign a MAC address to this Adapter
  462. //
  463. #ifdef _ETHERNET_
  464. {
  465. AdapterNum++;
  466. //
  467. // generate a locally
  468. // administered address by manipulating the first two bytes.
  469. //
  470. }
  471. #endif
  472. //
  473. // Allocate the loopback pools
  474. //
  475. NdisStatus= nicAllocateLoopbackPacketPool (pAdapter);
  476. if (NdisStatus != NDIS_STATUS_SUCCESS)
  477. {
  478. BREAK (TM_Init, ("nicMpInitialize - nicAllocateLoopbackPacketPool FAILED" ) );
  479. }
  480. InitStatus = InitializedLoopbackPool;
  481. ADAPTER_SET_FLAG (pAdapter, fADAPTER_DoStatusIndications);
  482. pAdapter->PowerState = NetDeviceStateD0;
  483. } while (FALSE);
  484. if (NdisStatus != NDIS_STATUS_SUCCESS)
  485. {
  486. ULONG FailureStatus = NDIS_STATUS_FAILURE;
  487. // Failed, so undo whatever portion succeeded.
  488. //
  489. TRACE( TL_I, TM_Init, ( "NicMpInitialize FAILING InitStatus %x", InitStatus) );
  490. ADAPTER_SET_FLAG (pAdapter, fADAPTER_FailedInit);
  491. ADAPTER_CLEAR_FLAG (pAdapter, fADAPTER_DoStatusIndications);
  492. //
  493. // This is in reverse order of the init and there are no breaks here.
  494. // The implicit assumption is that if the code failed at a certain point
  495. // it will have to undo whatever was previously allocated
  496. //
  497. switch (InitStatus)
  498. {
  499. case InitializedLoopbackPool:
  500. {
  501. nicFreeLoopbackPacketPool(pAdapter);
  502. FALL_THROUGH;
  503. }
  504. case InitializedLookasideList:
  505. {
  506. nicDeleteAdapterLookasideLists(pAdapter);
  507. FALL_THROUGH;
  508. }
  509. case InitializedReassembly:
  510. {
  511. nicDeInitSerializedReassmblyStruct(pAdapter);
  512. FALL_THROUGH;
  513. }
  514. case InitializedSendThread:
  515. {
  516. #if QUEUED_PACKETS
  517. nicDeInitSerializedSendStruct(pAdapter);
  518. #endif
  519. FALL_THROUGH;
  520. }
  521. case InitializedRcvThread:
  522. {
  523. #if QUEUED_PACKETS
  524. nicDeInitSerializedReceiveStruct(pAdapter);
  525. nicDeInitSerializedStatusStruct (pAdapter);
  526. #endif
  527. FALL_THROUGH;
  528. }
  529. case InitializedPktLog:
  530. {
  531. #ifdef PKT_LOG
  532. nic1394DeallocPktLog(pAdapter);
  533. #endif
  534. FALL_THROUGH
  535. }
  536. case RegisteredEnumerator:
  537. {
  538. //
  539. // If we registered with the enumerator , then deregister
  540. //
  541. if ((NdisEnum1394DeregisterAdapter != NULL) &&
  542. ADAPTER_TEST_FLAG(pAdapter, fADAPTER_RegisteredWithEnumerator))
  543. {
  544. //
  545. // deregister this adapter with enumerator
  546. //
  547. TRACE( TL_V, TM_Init, ( " Deregistering with the Enum %x", pAdapter->EnumAdapterHandle) );
  548. NdisEnum1394DeregisterAdapter(pAdapter->EnumAdapterHandle);
  549. ADAPTER_CLEAR_FLAG(pAdapter, fADAPTER_RegisteredWithEnumerator | fADAPTER_FailedRegisteration);
  550. }
  551. FALL_THROUGH
  552. }
  553. case AddedConfigRom:
  554. {
  555. TRACE( TL_V, TM_Init, ( " removing config rom handle %x", pAdapter->hCromData ) );
  556. FailureStatus = nicSetLocalHostPropertiesCRom(pAdapter,
  557. (PUCHAR)&Net1394ConfigRom,
  558. sizeof(Net1394ConfigRom),
  559. SLHP_FLAG_REMOVE_CROM_DATA,
  560. &pAdapter->hCromData,
  561. &pAdapter->pConfigRomMdl);
  562. FALL_THROUGH
  563. }
  564. case RegisteredResetCallback:
  565. {
  566. TRACE( TL_V, TM_Init, ( " Deregistering reset callback ") );
  567. //
  568. // Deregeister the reset callback
  569. //
  570. FailureStatus = nicBusResetNotification (pAdapter,
  571. DEREGISTER_NOTIFICATION_ROUTINE,
  572. nicResetNotificationCallback,
  573. pAdapter) ;
  574. FALL_THROUGH
  575. }
  576. case InitializedBcr:
  577. {
  578. TRACE( TL_V, TM_Init, ( " Freeing BCR ") );
  579. nicFreeBroadcastChannelRegister(pAdapter);
  580. TRACE (TL_V, TM_Mp, ("About to Wait for Free AddressRange" ) );
  581. NdisWaitEvent (&pAdapter->BCRData.BCRFreeAddressRange.NdisEvent, WAIT_INFINITE);
  582. TRACE (TL_V, TM_Mp, ("Wait Completed for Free AddressRange\n" ) );
  583. FALL_THROUGH
  584. }
  585. case InitializedEvents:
  586. {
  587. //
  588. // Do nothing
  589. //
  590. FALL_THROUGH
  591. }
  592. case AdapterQueued:
  593. {
  594. NdisAcquireSpinLock ( &g_DriverLock);
  595. nicRemoveEntryList (&pAdapter->linkAdapter);
  596. NdisReleaseSpinLock (&g_DriverLock);
  597. FALL_THROUGH
  598. }
  599. case AllocatedAdapter:
  600. {
  601. nicDereferenceAdapter(pAdapter, "NicMpInitialize");
  602. break;
  603. }
  604. default :
  605. {
  606. ASSERT (0);
  607. }
  608. }
  609. }
  610. TRACE( TL_T, TM_Init, ( "<==NicMpInitialize=$%08x", NdisStatus ) );
  611. MATCH_IRQL;
  612. TRACE( TL_I, TM_Init, ( "NicMpInitialize Status %x, pAdapter %p", NdisStatus,pAdapter ) );
  613. TIMESTAMP_EXIT("<==IntializeHandler");
  614. return NdisStatus;
  615. }
  616. VOID
  617. NicMpHalt(
  618. IN NDIS_HANDLE MiniportAdapterContext
  619. )
  620. // Standard 'MiniportHalt' routine called by NDIS to deallocate all
  621. // resources attached to the adapter. NDIS does not make any other calls
  622. // for this mini-port adapter during or after this call. NDIS will not
  623. // call this routine when packets indicated as received have not been
  624. // returned, or when any VC is created and known to NDIS. Runs at PASSIVE
  625. // IRQL.
  626. //
  627. {
  628. PADAPTERCB pAdapter = (PADAPTERCB) MiniportAdapterContext;
  629. BOOLEAN TimerCancelled = FALSE;
  630. STORE_CURRENT_IRQL
  631. TIMESTAMP_ENTRY("==>Haltandler");
  632. TRACE( TL_T, TM_Mp, ( "==>NicMpHalt" ) );
  633. TRACE( TL_I, TM_Mp, ( " Adapter %x Halted", pAdapter ) );
  634. if (pAdapter->ulTag != MTAG_ADAPTERCB)
  635. {
  636. ASSERT( !"Atag?" );
  637. return;
  638. }
  639. ADAPTER_CLEAR_FLAG (pAdapter, fADAPTER_DoStatusIndications);
  640. //
  641. // Unload the Arp module if necessary
  642. //
  643. if (pAdapter->fIsArpStarted == TRUE)
  644. {
  645. nicQueueRequestToArp(pAdapter, UnloadArpNoRequest, NULL);
  646. }
  647. ADAPTER_SET_FLAG (pAdapter, fADAPTER_Halting);
  648. #if QUEUED_PACKETS
  649. nicDeInitSerializedStatusStruct(pAdapter);
  650. nicDeInitSerializedSendStruct(pAdapter);
  651. nicDeInitSerializedReceiveStruct(pAdapter);
  652. #endif
  653. //
  654. // Stop the reassembly timer
  655. //
  656. nicDeInitSerializedReassmblyStruct(pAdapter);
  657. //
  658. // Deallocating the packet log
  659. //
  660. #ifdef PKT_LOG
  661. nic1394DeallocPktLog(pAdapter);
  662. #endif
  663. //
  664. // remove the config rom
  665. //
  666. nicSetLocalHostPropertiesCRom(pAdapter,
  667. (PUCHAR)&Net1394ConfigRom,
  668. sizeof(Net1394ConfigRom),
  669. SLHP_FLAG_REMOVE_CROM_DATA,
  670. &pAdapter->hCromData,
  671. &pAdapter->pConfigRomMdl);
  672. pAdapter->hCromData = NULL;
  673. //
  674. // free the apapter packet pool
  675. nicFreeLoopbackPacketPool(pAdapter);
  676. //
  677. // Free the BCR
  678. //
  679. nicFreeBroadcastChannelRegister(pAdapter);
  680. TRACE (TL_V, TM_Mp, ("About to Wait for Free AddressRange\n" ) );
  681. NdisWaitEvent (&pAdapter->BCRData.BCRFreeAddressRange.NdisEvent, WAIT_INFINITE);
  682. TRACE (TL_V, TM_Mp, ("Wait Completed for Free AddressRange\n" ) );
  683. nicBusResetNotification (pAdapter,
  684. DEREGISTER_NOTIFICATION_ROUTINE,
  685. nicResetNotificationCallback,
  686. pAdapter);
  687. //
  688. // deregister this adapter with enumerator
  689. //
  690. if ((NdisEnum1394DeregisterAdapter != NULL) &&
  691. ADAPTER_TEST_FLAG(pAdapter, fADAPTER_RegisteredWithEnumerator))
  692. {
  693. //
  694. // deregister this adapter with enumerator
  695. //
  696. NdisEnum1394DeregisterAdapter(pAdapter->EnumAdapterHandle);
  697. ADAPTER_CLEAR_FLAG(pAdapter, fADAPTER_RegisteredWithEnumerator | fADAPTER_FailedRegisteration);
  698. }
  699. //
  700. // No more Irps on this adapter's VDO
  701. //
  702. ADAPTER_SET_FLAG (pAdapter, fADAPTER_VDOInactive);
  703. //
  704. // Cancel Outstanding Timer
  705. //
  706. ADAPTER_SET_FLAG (pAdapter, fADAPTER_FreedTimers);
  707. //
  708. // Cancel Outstanding WorItems
  709. //
  710. while (pAdapter->OutstandingWorkItems != 0)
  711. {
  712. NdisMSleep (10000);
  713. }
  714. ADAPTER_SET_FLAG (pAdapter, fADAPTER_DeletedWorkItems);
  715. // Remove this adapter from the global list of adapters.
  716. //
  717. NdisAcquireSpinLock(&g_DriverLock);
  718. nicRemoveEntryList(&pAdapter->linkAdapter);
  719. NdisReleaseSpinLock(&g_DriverLock);
  720. ADAPTER_ACQUIRE_LOCK (pAdapter);
  721. // do Adapter Specific Work here
  722. pAdapter->HardwareStatus = NdisHardwareStatusClosing;
  723. //
  724. // Free all lookaside lists
  725. //
  726. nicDeleteAdapterLookasideLists (pAdapter);
  727. ADAPTER_SET_FLAG (pAdapter, fADAPTER_DeletedLookasideLists);
  728. //
  729. // Free the Adapter's BCRData. TopologyMap as that is locally allocated
  730. //
  731. if (pAdapter->BCRData.pTopologyMap)
  732. {
  733. FREE_NONPAGED (pAdapter->BCRData.pTopologyMap);
  734. }
  735. ADAPTER_RELEASE_LOCK (pAdapter);
  736. NdisFreeSpinLock (&pAdapter->lock);
  737. while (pAdapter->lRef != 1)
  738. {
  739. //
  740. // sleep for 1 second waiting for outstanding operations to complete
  741. //
  742. NdisMSleep (1000);
  743. }
  744. nicDereferenceAdapter( pAdapter, "nicMpHalt" );
  745. //ASSERT (g_AdapterFreed == TRUE);
  746. TRACE( TL_T, TM_Mp, ( "<==NicMpHalt " ) );
  747. TIMESTAMP_EXIT("<==Haltandler");
  748. TIMESTAMP_HALT();
  749. TRACE( TL_I, TM_Init, ( "Nic1394 Halted %p ", pAdapter ) );
  750. MATCH_IRQL
  751. }
  752. NDIS_STATUS
  753. NicMpReset(
  754. OUT PBOOLEAN AddressingReset,
  755. IN NDIS_HANDLE MiniportAdapterContext
  756. )
  757. // Standard 'MiniportReset' routine called by NDIS to reset the driver's
  758. // software state.
  759. //
  760. {
  761. TRACE( TL_T, TM_Mp, ( "NicMpReset" ) );
  762. return NDIS_STATUS_SUCCESS;
  763. }
  764. NDIS_STATUS
  765. NicMpCoActivateVc(
  766. IN NDIS_HANDLE MiniportVcContext,
  767. IN OUT PCO_CALL_PARAMETERS CallParameters
  768. )
  769. // Standard 'MiniportCoActivateVc' routine called by NDIS in response to a
  770. // protocol's request to activate a virtual circuit.
  771. //
  772. // The only "protocol" to call us is our call manager half, which knows
  773. // exactly what it's doing and so we don't have to do anything here.
  774. // It does expect us to return success synchronously.
  775. //
  776. {
  777. return NDIS_STATUS_SUCCESS;
  778. }
  779. NDIS_STATUS
  780. NicMpCoDeactivateVc(
  781. IN NDIS_HANDLE MiniportVcContext
  782. )
  783. // Standard 'MiniportCoDeactivateVc' routine called by NDIS in response to
  784. // a protocol's request to de-activate a virtual circuit.
  785. //
  786. // The only "protocol" to call us is our call manager half, which knows
  787. // exactly what it's doing and so we don't have to do anything here.
  788. // It does expect us to return success synchronously.
  789. //
  790. {
  791. return NDIS_STATUS_SUCCESS;
  792. }
  793. VOID
  794. NicMpCoSendPackets(
  795. IN NDIS_HANDLE MiniportVcContext,
  796. IN PPNDIS_PACKET PacketArray,
  797. IN UINT NumberOfPackets
  798. )
  799. // 'MiniportCoSendPackets' routine called by NDIS in response to
  800. // a protocol's request to send packets on a virtual circuit.
  801. //
  802. {
  803. UINT i;
  804. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  805. NDIS_PACKET** ppPacket;
  806. VCCB* pVc;
  807. extern UINT NicSends;
  808. TRACE( TL_V, TM_Send, ( "==>NicMpCoSendPackets(%d), Vc %.8x", NumberOfPackets, MiniportVcContext ) );
  809. pVc = (VCCB* )MiniportVcContext;
  810. ASSERT( pVc->Hdr.ulTag == MTAG_VCCB );
  811. for (i = 0, ppPacket = PacketArray;
  812. i < NumberOfPackets;
  813. ++i, ++ppPacket)
  814. {
  815. NDIS_PACKET* pPacket = *ppPacket;
  816. // SendPacket sends the packet and eventually calls
  817. // NdisMCoSendComplete to notify caller of the result.
  818. //
  819. NDIS_SET_PACKET_STATUS( pPacket, NDIS_STATUS_PENDING );
  820. nicIncrementSends (pVc);
  821. nicDumpPkt (pPacket , "Sending ");
  822. //
  823. // Loopback the packet it is a broadcast packet
  824. //
  825. if (pVc->Hdr.VcType == NIC1394_SendRecvChannel ||
  826. pVc->Hdr.VcType == NIC1394_MultiChannel ||
  827. pVc->Hdr.VcType == NIC1394_SendChannel)
  828. {
  829. nicLoopbackPacket(pVc, pPacket);
  830. }
  831. #if QUEUED_PACKETS
  832. NdisStatus = nicQueueSendPacket(pPacket, pVc);
  833. #else
  834. nicUpdatePacketState (pPacket, NIC1394_TAG_IN_SEND);
  835. NdisStatus = pVc->Hdr.VcHandlers.SendPackets (pVc, pPacket);
  836. #endif
  837. if (NT_SUCCESS (NdisStatus) == FALSE)
  838. {
  839. TRACE( TL_N, TM_Send, ( "SendHandler failed Status %.8x", NdisStatus ) );
  840. break;
  841. }
  842. }
  843. // If the call to the VC's Send handler was not successful
  844. // Indicate failure for that packet and all packets following it
  845. //
  846. if (NT_SUCCESS(NdisStatus) == FALSE) // can pend also
  847. {
  848. // Start from the packet which caused the break and indicate
  849. // Failure (call the completion handler for each packet
  850. //
  851. for ( ; i < NumberOfPackets;++i,++ppPacket)
  852. {
  853. TRACE( TL_V, TM_Send, ( "Calling NdisCoSendComplete, status %x, VcHandle %x, pPkt %x",
  854. NDIS_STATUS_FAILURE , pVc->Hdr.NdisVcHandle, *ppPacket ) );
  855. nicMpCoSendComplete (NDIS_STATUS_FAILURE, pVc,*ppPacket);
  856. }
  857. }
  858. TRACE( TL_T, TM_Send, ( "<==NicMpCoSendPackets " ) );
  859. }
  860. NDIS_STATUS
  861. NicMpCoRequest(
  862. IN NDIS_HANDLE MiniportAdapterContext,
  863. IN NDIS_HANDLE MiniportVcContext,
  864. IN OUT PNDIS_REQUEST NdisRequest
  865. )
  866. // Standard 'MiniportCoRequestHandler' routine called by NDIS in response
  867. // to a protocol's request information from the mini-port. Unlike the
  868. // Query/SetInformation handlers that this routine obsoletes, requests are
  869. // not serialized.
  870. //
  871. {
  872. ADAPTERCB* pAdapter;
  873. VCCB* pVc;
  874. NDIS_STATUS status;
  875. TRACE( TL_T, TM_Mp, ( "NicMpCoReq, Request %.8x", NdisRequest ) );
  876. pAdapter = (ADAPTERCB* )MiniportAdapterContext;
  877. if (pAdapter->ulTag != MTAG_ADAPTERCB)
  878. {
  879. ASSERT( !"Atag?" );
  880. return NDIS_STATUS_INVALID_DATA;
  881. }
  882. pVc = (VCCB* )MiniportVcContext;
  883. if (pVc && pVc->Hdr.ulTag != MTAG_VCCB)
  884. {
  885. ASSERT( !"Vtag?" );
  886. return NDIS_STATUS_INVALID_DATA;
  887. }
  888. switch (NdisRequest->RequestType)
  889. {
  890. case NdisRequestQueryStatistics:
  891. case NdisRequestQueryInformation:
  892. {
  893. status = nicQueryInformation(
  894. pAdapter,
  895. pVc,
  896. NdisRequest
  897. );
  898. break;
  899. }
  900. case NdisRequestSetInformation:
  901. {
  902. status = nicSetInformation(
  903. pAdapter,
  904. pVc,
  905. NdisRequest
  906. );
  907. break;
  908. }
  909. default:
  910. {
  911. status = NDIS_STATUS_NOT_SUPPORTED;
  912. TRACE( TL_V, TM_Mp, ( "type=%d?", NdisRequest->RequestType ) );
  913. break;
  914. }
  915. }
  916. TRACE( TL_T, TM_Mp, ( "NicMpCoReq, Status=$%x", status ) );
  917. return status;
  918. }
  919. //-----------------------------------------------------------------------------
  920. // Mini-port utility routines (alphabetically)
  921. // Some are used externally
  922. //-----------------------------------------------------------------------------
  923. VOID
  924. nicDereferenceAdapter(
  925. IN PADAPTERCB pAdapter,
  926. IN PCHAR pDebugPrint
  927. )
  928. // Removes a reference from the adapter control block 'pAdapter', and when
  929. // frees the adapter resources when the last reference is removed.
  930. //
  931. {
  932. LONG lRef;
  933. lRef = NdisInterlockedDecrement( &pAdapter->lRef );
  934. TRACE( TL_V, TM_Ref, ( "**nicDereferenceAdapter pAdapter %x, to %d, %s ", pAdapter, pAdapter->lRef, pDebugPrint ) );
  935. ASSERT( lRef >= 0 );
  936. if (lRef == 0)
  937. {
  938. nicFreeAdapter( pAdapter );
  939. }
  940. }
  941. VOID
  942. nicFreeAdapter(
  943. IN ADAPTERCB* pAdapter
  944. )
  945. // Frees all resources allocated for adapter 'pAdapter', including
  946. // 'pAdapter' itself.
  947. //
  948. {
  949. pAdapter->ulTag = MTAG_FREED;
  950. ASSERT (pAdapter->lRef == 0);
  951. FREE_NONPAGED( pAdapter );
  952. g_AdapterFreed = TRUE;
  953. }
  954. NDIS_STATUS
  955. nicGetRegistrySettings(
  956. IN NDIS_HANDLE WrapperConfigurationContext,
  957. IN ADAPTERCB * pAdapter
  958. )
  959. // Read this mini-port's registry settings into caller's output variables.
  960. // 'WrapperConfigurationContext' is the handle to passed to
  961. // MiniportInitialize.
  962. //
  963. {
  964. NDIS_STATUS status;
  965. NDIS_HANDLE hCfg;
  966. NDIS_CONFIGURATION_PARAMETER* pncp;
  967. PNDIS_CONFIGURATION_PARAMETER pNameConfig;
  968. NDIS_STRING strMiniportName = NDIS_STRING_CONST("MiniportName");
  969. ULONG AdapterNameSizeInBytes = 0;
  970. NdisOpenConfiguration( &status, &hCfg, WrapperConfigurationContext );
  971. if (status != NDIS_STATUS_SUCCESS)
  972. return status;
  973. do
  974. {
  975. //
  976. // Read the Miniport Name. First setup the buffer
  977. //
  978. NdisReadConfiguration(&status,
  979. &pNameConfig,
  980. hCfg,
  981. &strMiniportName,
  982. NdisParameterString);
  983. if (status != NDIS_STATUS_SUCCESS)
  984. {
  985. break;
  986. }
  987. AdapterNameSizeInBytes = pNameConfig->ParameterData.StringData.Length;
  988. //
  989. // Only Copy the Adapter name if the size of the string from the registry
  990. // is smaller than the size we have allocated in the adapter structure.
  991. // There should also be room for the trailing L'\0' character.
  992. //
  993. if ((ADAPTER_NAME_SIZE*sizeof(WCHAR)) > (AdapterNameSizeInBytes+2))
  994. {
  995. PUCHAR pAdapterName = (PUCHAR)&pAdapter->AdapterName[0];
  996. pAdapter->AdapterNameSize = AdapterNameSizeInBytes;
  997. NdisMoveMemory (pAdapterName, // Destination
  998. pNameConfig->ParameterData.StringData.Buffer, // Source
  999. AdapterNameSizeInBytes ); // number of characters
  1000. //
  1001. // NULL - terminate the string by adding the L'\0' Unicode character
  1002. //
  1003. pAdapterName[AdapterNameSizeInBytes]= 0;
  1004. pAdapterName[AdapterNameSizeInBytes+1]= 0;
  1005. }
  1006. }
  1007. while (FALSE);
  1008. NdisCloseConfiguration( hCfg );
  1009. TRACE( TL_N, TM_Init,
  1010. ( "Reg: Name %s", &pAdapter->AdapterName));
  1011. return status;
  1012. }
  1013. NDIS_STATUS
  1014. nicQueryInformation(
  1015. IN ADAPTERCB* pAdapter,
  1016. IN VCCB* pVc,
  1017. IN OUT PNDIS_REQUEST NdisRequest
  1018. )
  1019. /*++
  1020. Routine Description:
  1021. NOTE: this function can be called in at least two contexts:
  1022. 1: in the context of an NdisRequest
  1023. 2: in the context of our own work item, if the request needs to be completed
  1024. at passive.
  1025. Arguments:
  1026. Return Value:
  1027. --*/
  1028. {
  1029. NDIS_STATUS status;
  1030. ULONG ulInfo;
  1031. VOID* pInfo;
  1032. ULONG ulInfoLen;
  1033. USHORT usInfo;
  1034. NDIS_OID Oid;
  1035. PVOID InformationBuffer;
  1036. ULONG InformationBufferLength;
  1037. PULONG BytesWritten;
  1038. PULONG BytesNeeded;
  1039. NDIS_CO_LINK_SPEED CoLinkSpeed;
  1040. NIC1394_LOCAL_NODE_INFO LocalNodeInfo;
  1041. NIC1394_VC_INFO VcInfo;
  1042. REMOTE_UID RemoteUid;
  1043. NDIS_PNP_CAPABILITIES PnpCaps;
  1044. NIC1394_NICINFO NicInfo;
  1045. Oid = NdisRequest->DATA.QUERY_INFORMATION.Oid;
  1046. InformationBuffer = NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer;
  1047. InformationBufferLength =
  1048. NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength;
  1049. BytesWritten = &NdisRequest->DATA.QUERY_INFORMATION.BytesWritten;
  1050. BytesNeeded = &NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded;
  1051. // The next variables are used to setup the data structures that are
  1052. // used to respond to the OIDs they correspond to
  1053. //
  1054. TRACE( TL_T, TM_Init, ( "==>nicQueryInformation, Adapter %.8x, Vc %.8x, Oid %.8x",pAdapter, pVc, Oid ));
  1055. // The cases in this switch statement find or create a buffer containing
  1056. // the requested information and point 'pInfo' at it, noting it's length
  1057. // in 'ulInfoLen'. Since many of the OIDs return a ULONG, a 'ulInfo'
  1058. // buffer is set up as the default.
  1059. //
  1060. ulInfo = 0;
  1061. pInfo = &ulInfo;
  1062. ulInfoLen = sizeof(ulInfo);
  1063. status = NDIS_STATUS_SUCCESS;
  1064. switch (Oid)
  1065. {
  1066. case OID_GEN_CO_SUPPORTED_LIST:
  1067. {
  1068. pInfo = &SupportedOids[0];
  1069. ulInfoLen = sizeof(SupportedOids);
  1070. break;
  1071. }
  1072. case OID_GEN_CO_HARDWARE_STATUS:
  1073. {
  1074. //
  1075. // Copy the hardware status into the users buffer.
  1076. //
  1077. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_CO_HARDWARE_STATUS)" ) );
  1078. NdisAcquireSpinLock (&pAdapter->lock);
  1079. pInfo = (PUCHAR) &pAdapter->HardwareStatus;
  1080. NdisReleaseSpinLock (&pAdapter->lock);
  1081. ulInfoLen = sizeof(pAdapter->HardwareStatus);
  1082. break;
  1083. }
  1084. case OID_GEN_MAXIMUM_LOOKAHEAD:
  1085. {
  1086. #if TODO
  1087. // Verify the following...
  1088. #endif
  1089. // Report the maximum number of bytes we can always provide as
  1090. // lookahead data on receive indications. We always indicate full
  1091. // packets so this is the same as the receive block size. And
  1092. // since we always allocate enough for a full packet, the receive
  1093. // block size is the same as the frame size.
  1094. //
  1095. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_MAXIMUM_LOOKAHEAD)" ) );
  1096. ulInfo = Nic1394_MaxFrameSize;
  1097. break;
  1098. }
  1099. case OID_GEN_CO_MAC_OPTIONS:
  1100. {
  1101. #if TODO
  1102. // Verify the following...
  1103. #endif
  1104. // Report a bitmask defining optional properties of the driver.
  1105. //
  1106. // NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA promises that our receive
  1107. // buffer is not on a device-specific card.
  1108. //
  1109. // NDIS_MAC_OPTION_TRANSFERS_NOT_PEND promises we won't return
  1110. // NDIS_STATUS_PENDING from our TransferData handler which is true
  1111. // since we don't have one.
  1112. //
  1113. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_CO_MAC_OPTIONS)" ) );
  1114. ulInfo = 0;
  1115. break;
  1116. }
  1117. case OID_GEN_CO_MEDIA_SUPPORTED:
  1118. case OID_GEN_CO_MEDIA_IN_USE:
  1119. {
  1120. //
  1121. // We support 1394.
  1122. //
  1123. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_CO_MEDIA_SUPPORTED or OID_GEN_CO_MEDIA_IN_USE)" ) );
  1124. ulInfo = g_ulMedium;
  1125. break;
  1126. }
  1127. #ifndef _ETHERNET_
  1128. //
  1129. // There are different return values for CO_LINK_SPEED and LINK_SPEED
  1130. //
  1131. case OID_GEN_CO_LINK_SPEED:
  1132. #endif
  1133. case OID_GEN_CO_MINIMUM_LINK_SPEED:
  1134. {
  1135. //
  1136. // Link speed depends upon the type of adapter. We will need to
  1137. // add support for different speeds and so forth
  1138. //
  1139. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_CO_MINIMUM_LINK_SPEED or OID_GEN_CO_LINK_SPEED)" ) );
  1140. CoLinkSpeed.Inbound = CoLinkSpeed.Outbound = pAdapter->SpeedMbps; //10 Mbps ????
  1141. pInfo = (PUCHAR)&CoLinkSpeed;
  1142. ulInfoLen = sizeof(CoLinkSpeed);
  1143. TRACE( TL_V, TM_Mp, ( "Link Speed %x" ,CoLinkSpeed.Outbound ) );
  1144. break;
  1145. }
  1146. case OID_GEN_CO_VENDOR_ID:
  1147. {
  1148. //
  1149. // We need to add the appropriate vendor id for the nic1394
  1150. //
  1151. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_CO_VENDOR_ID)" ) );
  1152. ulInfo = 0xFFFFFFFF;
  1153. break;
  1154. }
  1155. case OID_GEN_CO_VENDOR_DESCRIPTION:
  1156. {
  1157. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_CO_VENDOR_DESCRIPTION)" ) );
  1158. pInfo = (PUCHAR)pnic1394DriverDescription;
  1159. ulInfoLen = strlen(pnic1394DriverDescription);
  1160. break;
  1161. }
  1162. case OID_GEN_VENDOR_DRIVER_VERSION:
  1163. {
  1164. pInfo =(PVOID) &nic1394DriverGeneration;
  1165. ulInfoLen = sizeof(nic1394DriverGeneration);
  1166. break;
  1167. }
  1168. case OID_GEN_CO_DRIVER_VERSION:
  1169. {
  1170. //
  1171. // Return the version of NDIS that we expect.
  1172. //
  1173. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_CO_DRIVER_VERSION)" ) );
  1174. usInfo = ((NDIS_MajorVersion << 8) | NDIS_MinorVersion);
  1175. pInfo = (PUCHAR)&usInfo;
  1176. ulInfoLen = sizeof(USHORT);
  1177. break;
  1178. }
  1179. case OID_GEN_CO_PROTOCOL_OPTIONS:
  1180. {
  1181. //
  1182. // We don't support protocol options.
  1183. //
  1184. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_CO_PROTOCOL_OPTIONS)" ) );
  1185. ulInfo = 0;
  1186. break;
  1187. }
  1188. case OID_GEN_CO_MEDIA_CONNECT_STATUS:
  1189. {
  1190. //
  1191. // Return our true state only if we have ever received a
  1192. // remote node in this boot.
  1193. //
  1194. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_CO_MEDIA_CONNECT_STATUS)" ) );
  1195. if (ADAPTER_TEST_FLAG(pAdapter, fADAPTER_RemoteNodeInThisBoot) == FALSE)
  1196. {
  1197. ulInfo = NdisMediaStateConnected;
  1198. }
  1199. else
  1200. {
  1201. ulInfo = pAdapter->MediaConnectStatus;
  1202. }
  1203. break;
  1204. }
  1205. case OID_1394_IP1394_CONNECT_STATUS:
  1206. {
  1207. //
  1208. // Return whether or not we have a link. This is used by the Arp
  1209. // module to set connectivity
  1210. //
  1211. TRACE( TL_V, TM_Mp, ( "QInfo(OID_1394_IP1394_CONNECT_STATUS)" ) );
  1212. ulInfo = pAdapter->MediaConnectStatus;
  1213. break;
  1214. }
  1215. case OID_GEN_CO_SUPPORTED_GUIDS:
  1216. {
  1217. //
  1218. // Point to the list of supported guids.
  1219. // We do not support any guids at the current time
  1220. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_CO_SUPPORTED_GUIDS)" ) );
  1221. pInfo = (PUCHAR) &GuidList;
  1222. ulInfoLen = sizeof(GuidList);
  1223. break;
  1224. break;
  1225. }
  1226. case OID_1394_LOCAL_NODE_INFO:
  1227. {
  1228. // This Oid return information about the local node
  1229. // on the machine
  1230. // Need to change this with real values that will be present
  1231. // in the header structures
  1232. //
  1233. TRACE( TL_V, TM_Mp, ( "QInfo(OID_1394_LOCAL_NODE_INFO)" ) );
  1234. ADAPTER_ACQUIRE_LOCK (pAdapter);
  1235. LocalNodeInfo.UniqueID = pAdapter->UniqueId;
  1236. LocalNodeInfo.BusGeneration = pAdapter->Generation;
  1237. LocalNodeInfo.NodeAddress = pAdapter->NodeAddress;
  1238. LocalNodeInfo.MaxRecvBlockSize = pAdapter->MaxRec;
  1239. LocalNodeInfo.MaxRecvSpeed = pAdapter->SCode;
  1240. ADAPTER_RELEASE_LOCK (pAdapter);
  1241. pInfo = &LocalNodeInfo;
  1242. ulInfoLen = sizeof(LocalNodeInfo);
  1243. break;
  1244. }
  1245. case OID_1394_VC_INFO:
  1246. {
  1247. // Returns information about the VC that is being queried
  1248. //
  1249. TRACE( TL_V, TM_Mp, ("QInfo(OID_1394_VC_INFO)") );
  1250. if (pVc != NULL)
  1251. {
  1252. VcInfo.Destination = pVc->Hdr.Nic1394MediaParams.Destination;
  1253. pInfo = &VcInfo;
  1254. ulInfoLen = sizeof(VcInfo);
  1255. }
  1256. else
  1257. {
  1258. status = NDIS_STATUS_FAILURE;
  1259. }
  1260. break;
  1261. }
  1262. case OID_1394_NICINFO:
  1263. {
  1264. if (InformationBufferLength >= sizeof(NicInfo))
  1265. {
  1266. //
  1267. // We need to call nicFillNicInfo at passive, so we switch
  1268. // to a work item context.
  1269. //
  1270. if (KeGetCurrentIrql() > PASSIVE_LEVEL)
  1271. {
  1272. PNIC_WORK_ITEM pNicWorkItem;
  1273. pNicWorkItem = ALLOC_NONPAGED (sizeof(NIC_WORK_ITEM), MTAG_WORKITEM);
  1274. if (pNicWorkItem != NULL)
  1275. {
  1276. NdisZeroMemory(pNicWorkItem, sizeof(*pNicWorkItem));
  1277. pNicWorkItem->RequestInfo.pNdisRequest = NdisRequest;
  1278. pNicWorkItem->RequestInfo.pVc = NULL;
  1279. NdisInitializeWorkItem ( &pNicWorkItem->NdisWorkItem,
  1280. (NDIS_PROC) nicQueryInformationWorkItem,
  1281. (PVOID) pAdapter);
  1282. TRACE( TL_V, TM_Cm, ( "Scheduling QueryInformation WorkItem" ) );
  1283. nicReferenceAdapter (pAdapter, "nicFillBusInfo ");
  1284. NdisInterlockedIncrement(&pAdapter->OutstandingWorkItems);
  1285. NdisScheduleWorkItem (&pNicWorkItem->NdisWorkItem);
  1286. status = NDIS_STATUS_PENDING;
  1287. }
  1288. else
  1289. {
  1290. status = NDIS_STATUS_RESOURCES;
  1291. }
  1292. }
  1293. else
  1294. {
  1295. status = nicFillNicInfo (
  1296. pAdapter,
  1297. (PNIC1394_NICINFO) InformationBuffer, // Input
  1298. &NicInfo // Output
  1299. );
  1300. ASSERT(status != NDIS_STATUS_PENDING);
  1301. }
  1302. }
  1303. pInfo = &NicInfo;
  1304. ulInfoLen = sizeof(NicInfo);
  1305. break;
  1306. }
  1307. case OID_1394_QUERY_EUID_NODE_MAP:
  1308. {
  1309. if (sizeof (EUID_TOPOLOGY) <= InformationBufferLength )
  1310. {
  1311. nicQueryEuidNodeMacMap (pAdapter, NdisRequest);
  1312. status = NDIS_STATUS_PENDING;
  1313. }
  1314. else
  1315. {
  1316. //
  1317. // This will cause NDIS_STATUS_INVALID_LENGTH to be returned
  1318. //
  1319. ulInfoLen = sizeof (EUID_TOPOLOGY);
  1320. }
  1321. break;
  1322. }
  1323. case OID_GEN_CO_XMIT_PDUS_OK:
  1324. {
  1325. ulInfo = pAdapter->AdaptStats.ulXmitOk;
  1326. break;
  1327. }
  1328. case OID_GEN_CO_RCV_PDUS_OK:
  1329. {
  1330. ulInfo = pAdapter->AdaptStats.ulRcvOk;
  1331. break;
  1332. }
  1333. case OID_GEN_CO_XMIT_PDUS_ERROR:
  1334. {
  1335. ulInfo = pAdapter->AdaptStats.ulXmitError;
  1336. break;
  1337. }
  1338. case OID_GEN_CO_RCV_PDUS_ERROR:
  1339. {
  1340. ulInfo = pAdapter->AdaptStats.ulRcvError;
  1341. break;
  1342. }
  1343. case OID_GEN_CO_RCV_PDUS_NO_BUFFER:
  1344. {
  1345. ulInfo = 0;
  1346. break;
  1347. }
  1348. case OID_GEN_PHYSICAL_MEDIUM:
  1349. {
  1350. TRACE( TL_V, TM_Mp, ( " OID_GEN_PHYSICAL_MEDIUM" ) );
  1351. ulInfo = NdisPhysicalMedium1394;
  1352. break;
  1353. }
  1354. case OID_1394_ISSUE_BUS_RESET:
  1355. {
  1356. TRACE( TL_V, TM_Mp, ( " OID_1394_ISSUE_BUS_RESET" ) );
  1357. //
  1358. // The ndistester is currently the only user of this oid and does not set the flag
  1359. //
  1360. if (InformationBufferLength == sizeof(ULONG))
  1361. {
  1362. nicIssueBusReset (pAdapter, BUS_RESET_FLAGS_FORCE_ROOT );
  1363. }
  1364. break;
  1365. }
  1366. //
  1367. // Wmi below
  1368. //
  1369. case OID_IP1394_QUERY_UID:
  1370. {
  1371. TRACE( TL_V, TM_Mp, ( " OID_IP1394_QUERY_UID" ) );
  1372. pInfo = &pAdapter->UniqueId;
  1373. ulInfoLen = sizeof (UINT64);
  1374. break;
  1375. }
  1376. case OID_IP1394_QUERY_STATS:
  1377. {
  1378. TRACE( TL_V, TM_Mp, ( " OID_IP1394_QUERY_STATS" ) );
  1379. pInfo = &pAdapter->AdaptStats;
  1380. ulInfoLen = sizeof (ADAPT_STATS);
  1381. break;
  1382. }
  1383. case OID_IP1394_QUERY_REMOTE_UID:
  1384. {
  1385. TRACE( TL_V, TM_Mp, ( "OID_IP1394_QUERY_REMOTE_UID " ) );
  1386. NdisZeroMemory (&RemoteUid, sizeof (RemoteUid) );
  1387. ADAPTER_ACQUIRE_LOCK (pAdapter);
  1388. {
  1389. ULONG j = 0;
  1390. // Populate all 5 remote node entries
  1391. while (j < (2*MAX_NUM_REMOTE_NODES))
  1392. {
  1393. if (pAdapter->NodeTable.RemoteNode[j/2] != NULL)
  1394. {
  1395. PULARGE_INTEGER pUniqueId = (PULARGE_INTEGER)&pAdapter->NodeTable.RemoteNode[j/2]->UniqueId;
  1396. RemoteUid.Uid[j] = pUniqueId->LowPart ;
  1397. j++;
  1398. RemoteUid.Uid[j] = pUniqueId->HighPart;
  1399. }
  1400. else
  1401. {
  1402. j++;
  1403. }
  1404. j++;
  1405. }
  1406. }
  1407. ADAPTER_RELEASE_LOCK (pAdapter);
  1408. pInfo = &RemoteUid;
  1409. ulInfoLen = sizeof (RemoteUid);
  1410. break;
  1411. }
  1412. case OID_PNP_CAPABILITIES:
  1413. {
  1414. TRACE( TL_V, TM_Mp, ("QInfo(OID_PNP_CAPABILITIES)") );
  1415. PnpCaps.Flags = 0;
  1416. PnpCaps.WakeUpCapabilities.MinMagicPacketWakeUp = NdisDeviceStateUnspecified;
  1417. PnpCaps.WakeUpCapabilities.MinPatternWakeUp = NdisDeviceStateUnspecified;
  1418. PnpCaps.WakeUpCapabilities.MinLinkChangeWakeUp = NdisDeviceStateUnspecified;
  1419. pInfo = &PnpCaps;
  1420. ulInfoLen = sizeof (PnpCaps);
  1421. break;
  1422. }
  1423. case OID_PNP_QUERY_POWER:
  1424. {
  1425. //
  1426. // The miniport is always ready to go into low power state.
  1427. //
  1428. *BytesWritten = sizeof (NDIS_DEVICE_POWER_STATE );
  1429. *BytesNeeded = sizeof (NDIS_DEVICE_POWER_STATE );
  1430. status = NDIS_STATUS_SUCCESS;
  1431. break;
  1432. }
  1433. #ifdef _ETHERNET_
  1434. case OID_GEN_CURRENT_LOOKAHEAD:
  1435. case OID_GEN_MAXIMUM_FRAME_SIZE:
  1436. case OID_GEN_MAXIMUM_TOTAL_SIZE:
  1437. case OID_GEN_TRANSMIT_BLOCK_SIZE:
  1438. case OID_GEN_RECEIVE_BLOCK_SIZE:
  1439. case OID_GEN_MAXIMUM_SEND_PACKETS:
  1440. case OID_GEN_TRANSMIT_BUFFER_SPACE:
  1441. case OID_GEN_RECEIVE_BUFFER_SPACE:
  1442. case OID_802_3_PERMANENT_ADDRESS:
  1443. case OID_802_3_CURRENT_ADDRESS:
  1444. case OID_802_3_MULTICAST_LIST:
  1445. case OID_802_3_MAXIMUM_LIST_SIZE:
  1446. case OID_802_3_RCV_ERROR_ALIGNMENT:
  1447. case OID_802_3_XMIT_ONE_COLLISION:
  1448. case OID_802_3_XMIT_MORE_COLLISIONS:
  1449. case OID_GEN_LINK_SPEED:
  1450. case OID_GEN_CURRENT_PACKET_FILTER:
  1451. {
  1452. status = NicEthQueryInformation((NDIS_HANDLE)pAdapter,
  1453. Oid,
  1454. InformationBuffer,
  1455. InformationBufferLength,
  1456. BytesWritten,
  1457. BytesNeeded
  1458. );
  1459. if (status == NDIS_STATUS_SUCCESS)
  1460. {
  1461. pInfo = InformationBuffer;
  1462. ulInfoLen = *BytesWritten;
  1463. }
  1464. else
  1465. {
  1466. if (status == NDIS_STATUS_INVALID_LENGTH)
  1467. {
  1468. ulInfoLen = *BytesNeeded;
  1469. }
  1470. else
  1471. {
  1472. status = NDIS_STATUS_NOT_SUPPORTED;
  1473. TRACE( TL_V, TM_Mp, ( "Q-OID=$%08x?", Oid ) );
  1474. }
  1475. }
  1476. break;
  1477. }
  1478. #endif
  1479. default:
  1480. {
  1481. TRACE( TL_V, TM_Mp, ( "Q-OID=$%08x?", Oid ) );
  1482. status = NDIS_STATUS_NOT_SUPPORTED;
  1483. ulInfoLen = 0;
  1484. break;
  1485. }
  1486. }
  1487. if (ulInfoLen > InformationBufferLength)
  1488. {
  1489. // Caller's buffer is too small. Tell him what he needs.
  1490. //
  1491. *BytesNeeded = ulInfoLen;
  1492. *BytesWritten = 0;
  1493. status = NDIS_STATUS_INVALID_LENGTH;
  1494. }
  1495. else
  1496. {
  1497. //
  1498. // If the request has not been pended then, fill
  1499. // out the retuen values
  1500. //
  1501. if (status == NDIS_STATUS_SUCCESS )
  1502. {
  1503. // Copy the found result to caller's buffer.
  1504. //
  1505. if (ulInfoLen > 0)
  1506. {
  1507. NdisMoveMemory( InformationBuffer, pInfo, ulInfoLen );
  1508. DUMPDW( TL_V, TM_Mp, pInfo, ulInfoLen );
  1509. }
  1510. *BytesNeeded = *BytesWritten = ulInfoLen;
  1511. }
  1512. }
  1513. TRACE( TL_N, TM_Mp, ( " Q-OID=$%08x, Status %x, Bytes Written %x", Oid, status, *BytesWritten ) );
  1514. TRACE( TL_T, TM_Init, ( "<==nicQueryInformation, Status %.8x", status ));
  1515. return status;
  1516. }
  1517. VOID
  1518. nicReferenceAdapter(
  1519. IN ADAPTERCB* pAdapter ,
  1520. IN PCHAR pDebugPrint
  1521. )
  1522. // Adds areference to the adapter block, 'pAdapter'.
  1523. //
  1524. {
  1525. LONG lRef;
  1526. lRef = NdisInterlockedIncrement( &pAdapter->lRef );
  1527. TRACE( TL_V, TM_Ref, ( "**nicReferenceAdapter pAdapter %x, to %d, %s ", pAdapter, pAdapter->lRef, pDebugPrint ) );
  1528. }
  1529. NDIS_STATUS
  1530. nicSetInformation(
  1531. IN ADAPTERCB* pAdapter,
  1532. IN VCCB* pVc,
  1533. IN OUT PNDIS_REQUEST NdisRequest
  1534. )
  1535. // Handle SetInformation requests. Arguments are as for the standard NDIS
  1536. // 'MiniportQueryInformation' handler except this routine does not count
  1537. // on being serialized with respect to other requests.
  1538. //
  1539. {
  1540. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  1541. ULONG ulInfo = 0;
  1542. VOID* pInfo= NULL;
  1543. ULONG ulInfoLen= 0;
  1544. USHORT usInfo = 0;
  1545. NDIS_OID Oid;
  1546. PVOID InformationBuffer;
  1547. ULONG InformationBufferLength;
  1548. PULONG BytesRead;
  1549. PULONG BytesNeeded;
  1550. //
  1551. // Initialize the REquest Variables
  1552. //
  1553. Oid = NdisRequest->DATA.SET_INFORMATION.Oid;
  1554. InformationBuffer = NdisRequest->DATA.SET_INFORMATION.InformationBuffer;
  1555. InformationBufferLength =
  1556. NdisRequest->DATA.SET_INFORMATION.InformationBufferLength;
  1557. BytesRead = &NdisRequest->DATA.SET_INFORMATION.BytesRead;
  1558. BytesNeeded = &NdisRequest->DATA.SET_INFORMATION.BytesNeeded;
  1559. TRACE( TL_T, TM_Init, ( "==>nicSetInformation , Adapter %.8x, Vc %.8x, Oid %.8x",pAdapter, pVc, Oid ));
  1560. Status = NDIS_STATUS_SUCCESS;
  1561. switch (Oid)
  1562. {
  1563. #if 0
  1564. // These OIDs are mandatory according to current doc, but since
  1565. // NDISWAN never requests them they are omitted.
  1566. //
  1567. case OID_GEN_CURRENT_PACKET_FILTER:
  1568. case OID_GEN_CURRENT_LOOKAHEAD:
  1569. case OID_GEN_PROTOCOL_OPTIONS:
  1570. case OID_WAN_PROTOCOL_TYPE:
  1571. case OID_WAN_HEADER_FORMAT:
  1572. #endif
  1573. case OID_GEN_CURRENT_PACKET_FILTER:
  1574. {
  1575. ULONG Filter;
  1576. if (InformationBufferLength < sizeof (ULONG))
  1577. {
  1578. Status = NDIS_STATUS_INVALID_LENGTH;
  1579. break;
  1580. }
  1581. else
  1582. {
  1583. *BytesNeeded = sizeof (ULONG);
  1584. }
  1585. //
  1586. // Store the new value.
  1587. //
  1588. NdisMoveMemory(&Filter, InformationBuffer, sizeof(ULONG));
  1589. //
  1590. // Don't allow promisc mode, because we can't support that.
  1591. //
  1592. if (Filter & NDIS_PACKET_TYPE_PROMISCUOUS)
  1593. {
  1594. Status = NDIS_STATUS_FAILURE;
  1595. break;
  1596. }
  1597. Filter = *((PULONG)InformationBuffer);
  1598. pAdapter->CurPacketFilter = Filter;
  1599. Status = NDIS_STATUS_SUCCESS;
  1600. ulInfoLen = sizeof (ULONG);
  1601. break;
  1602. }
  1603. case OID_1394_ENTER_BRIDGE_MODE:
  1604. {
  1605. *BytesNeeded = 0;
  1606. nicInitializeLoadArpStruct(pAdapter);
  1607. Status = nicQueueRequestToArp (pAdapter,
  1608. LoadArp, // Load Arp Module
  1609. NdisRequest);
  1610. if (Status == NDIS_STATUS_SUCCESS)
  1611. {
  1612. //
  1613. // we have successfully queued a Workitem
  1614. // so this request needs to be pended
  1615. //
  1616. Status = NDIS_STATUS_PENDING;
  1617. }
  1618. ulInfoLen = sizeof (ULONG);
  1619. break;
  1620. }
  1621. case OID_1394_EXIT_BRIDGE_MODE:
  1622. {
  1623. *BytesNeeded = 0;
  1624. if (ADAPTER_TEST_FLAG(pAdapter, fADAPTER_BridgeMode) == TRUE)
  1625. {
  1626. Status = nicQueueRequestToArp (pAdapter,
  1627. UnloadArp, //Unload Arp Module
  1628. NdisRequest);
  1629. if (Status == NDIS_STATUS_SUCCESS)
  1630. {
  1631. //
  1632. // we have successfully queued a Workitem
  1633. // so this request needs to be pended
  1634. //
  1635. Status = NDIS_STATUS_PENDING;
  1636. }
  1637. }
  1638. else
  1639. {
  1640. //
  1641. // We are not in bridge mode, tcpip must not have triggered the bridge to send us
  1642. // ENTER_BRIDGE_MODE Oid. Succeed the request
  1643. //
  1644. Status = NDIS_STATUS_SUCCESS;
  1645. }
  1646. ulInfoLen = sizeof (ULONG);
  1647. break;
  1648. }
  1649. case OID_802_3_MULTICAST_LIST:
  1650. case OID_GEN_CURRENT_LOOKAHEAD:
  1651. case OID_GEN_NETWORK_LAYER_ADDRESSES:
  1652. {
  1653. Status = NicEthSetInformation(pAdapter,
  1654. Oid,
  1655. InformationBuffer,
  1656. InformationBufferLength,
  1657. BytesRead ,
  1658. BytesNeeded
  1659. );
  1660. if (Status != NDIS_STATUS_SUCCESS && Status != NDIS_STATUS_INVALID_LENGTH)
  1661. {
  1662. Status = NDIS_STATUS_NOT_SUPPORTED;
  1663. }
  1664. break;
  1665. }
  1666. case OID_1394_ISSUE_BUS_RESET:
  1667. {
  1668. TRACE( TL_V, TM_Mp, ( " OID_1394_ISSUE_BUS_RESET" ) );
  1669. //
  1670. // The ndistester is currently the only user of this oid and does not set the flag
  1671. //
  1672. if (InformationBufferLength == sizeof(ULONG))
  1673. {
  1674. nicIssueBusReset (pAdapter, BUS_RESET_FLAGS_FORCE_ROOT );
  1675. }
  1676. break;
  1677. }
  1678. case OID_PNP_SET_POWER:
  1679. TRACE( TL_V, TM_Mp, ( "QInfo OID_PNP_SET_POWER %x", Oid ) );
  1680. *BytesRead = sizeof (NDIS_DEVICE_POWER_STATE );
  1681. *BytesNeeded = sizeof (NDIS_DEVICE_POWER_STATE );
  1682. if (InformationBufferLength >= sizeof (NDIS_DEVICE_POWER_STATE))
  1683. {
  1684. NDIS_DEVICE_POWER_STATE PoState;
  1685. NdisMoveMemory (&PoState, InformationBuffer, sizeof(PoState));
  1686. Status = MPSetPower(pAdapter,PoState);
  1687. }
  1688. break;
  1689. default:
  1690. {
  1691. TRACE( TL_A, TM_Mp, ( "S-OID=$%08x?", Oid ) );
  1692. Status = NDIS_STATUS_NOT_SUPPORTED;
  1693. *BytesRead = *BytesNeeded = 0;
  1694. break;
  1695. }
  1696. }
  1697. if (*BytesNeeded > InformationBufferLength)
  1698. {
  1699. // Caller's buffer is too small. Tell him what he needs.
  1700. //
  1701. *BytesRead = 0;
  1702. Status = NDIS_STATUS_INVALID_LENGTH;
  1703. }
  1704. else
  1705. {
  1706. *BytesNeeded = *BytesRead = ulInfoLen;
  1707. }
  1708. TRACE( TL_A, TM_Mp, ( " S-OID=$%08x, Status %x, Bytes Read %x", Oid, Status, *BytesRead ) );
  1709. TRACE( TL_T, TM_Init, ( "<==nicSetInformation, Status %.8x", Status ));
  1710. return Status;
  1711. }
  1712. //------------------------------------------------------------------------------
  1713. // C O N N E C T I O N L E S S F U N T I O N S S T A R T H E R E
  1714. //
  1715. NDIS_STATUS
  1716. NicEthSetInformation(
  1717. IN NDIS_HANDLE MiniportAdapterContext,
  1718. NDIS_OID Oid,
  1719. PVOID InformationBuffer,
  1720. ULONG InformationBufferLength,
  1721. PULONG BytesRead,
  1722. PULONG BytesNeeded
  1723. )
  1724. /*++
  1725. Routine Description:
  1726. This is the Set information that will be used by the CL edge
  1727. Arguments:
  1728. Return Value:
  1729. --*/
  1730. {
  1731. NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
  1732. UINT BytesLeft = InformationBufferLength;
  1733. PUCHAR InfoBuffer = (PUCHAR)(InformationBuffer);
  1734. UINT OidLength;
  1735. ULONG LookAhead;
  1736. ULONG Filter;
  1737. PADAPTERCB pAdapter;
  1738. BOOLEAN IsShuttingDown;
  1739. STORE_CURRENT_IRQL;
  1740. pAdapter = (PADAPTERCB)MiniportAdapterContext;
  1741. TRACE( TL_T, TM_Init, ( "==>nicEthSetInformation , Adapter %.8x, Oid %.8x",pAdapter, Oid ));
  1742. //
  1743. // IS the adapter shutting down
  1744. //
  1745. ADAPTER_ACQUIRE_LOCK (pAdapter);
  1746. IsShuttingDown = (! ADAPTER_ACTIVE(pAdapter)) ;
  1747. ADAPTER_RELEASE_LOCK (pAdapter);
  1748. if (IsShuttingDown)
  1749. {
  1750. TRACE( TL_T, TM_Init, ( " nicSetInformation Shutting Down , Adapter %.8x, Oid %.8x",pAdapter, Oid ));
  1751. *BytesRead = 0;
  1752. *BytesNeeded = 0;
  1753. NdisStatus = NDIS_STATUS_SUCCESS;
  1754. return (NdisStatus);
  1755. }
  1756. //
  1757. // Get Oid and Length of request
  1758. //
  1759. OidLength = BytesLeft;
  1760. switch (Oid)
  1761. {
  1762. case OID_802_3_MULTICAST_LIST:
  1763. if (OidLength % sizeof(MAC_ADDRESS))
  1764. {
  1765. NdisStatus = NDIS_STATUS_INVALID_LENGTH;
  1766. *BytesRead = 0;
  1767. *BytesNeeded = 0;
  1768. break;
  1769. }
  1770. if (OidLength > (MCAST_LIST_SIZE * sizeof(MAC_ADDRESS)))
  1771. {
  1772. NdisStatus= NDIS_STATUS_MULTICAST_FULL;
  1773. *BytesRead = 0;
  1774. *BytesNeeded = 0;
  1775. break;
  1776. }
  1777. NdisZeroMemory(
  1778. &pAdapter->McastAddrs[0],
  1779. MCAST_LIST_SIZE * sizeof(MAC_ADDRESS)
  1780. );
  1781. NdisMoveMemory(
  1782. &pAdapter->McastAddrs[0],
  1783. InfoBuffer,
  1784. OidLength
  1785. );
  1786. pAdapter->McastAddrCount = OidLength / sizeof(MAC_ADDRESS);
  1787. break;
  1788. case OID_GEN_CURRENT_PACKET_FILTER:
  1789. //
  1790. // Verify length
  1791. //
  1792. if (OidLength != sizeof(ULONG))
  1793. {
  1794. NdisStatus = NDIS_STATUS_INVALID_LENGTH;
  1795. *BytesRead = 0;
  1796. *BytesNeeded = sizeof(ULONG);
  1797. break;
  1798. }
  1799. //
  1800. // Store the new value.
  1801. //
  1802. NdisMoveMemory(&Filter, InfoBuffer, sizeof(ULONG));
  1803. //
  1804. // Don't allow promisc mode, because we can't support that.
  1805. //
  1806. if (Filter & NDIS_PACKET_TYPE_PROMISCUOUS)
  1807. {
  1808. NdisStatus = NDIS_STATUS_FAILURE;
  1809. break;
  1810. }
  1811. ADAPTER_ACQUIRE_LOCK (pAdapter);
  1812. pAdapter->CurPacketFilter = Filter;
  1813. ADAPTER_RELEASE_LOCK (pAdapter);
  1814. break;
  1815. case OID_802_5_CURRENT_FUNCTIONAL:
  1816. case OID_802_5_CURRENT_GROUP:
  1817. // XXX just accept whatever for now ???
  1818. break;
  1819. case OID_GEN_CURRENT_LOOKAHEAD:
  1820. //
  1821. // Verify length
  1822. //
  1823. if (OidLength != 4)
  1824. {
  1825. NdisStatus = NDIS_STATUS_INVALID_LENGTH;
  1826. *BytesRead = 0;
  1827. *BytesNeeded = 0;
  1828. break;
  1829. }
  1830. //
  1831. // Store the new value.
  1832. //
  1833. NdisMoveMemory(&LookAhead, InfoBuffer, 4);
  1834. pAdapter->CurLookAhead = LookAhead;
  1835. break;
  1836. case OID_GEN_NETWORK_LAYER_ADDRESSES:
  1837. NdisStatus = NDIS_STATUS_SUCCESS;
  1838. *BytesRead = InformationBufferLength;
  1839. *BytesNeeded = InformationBufferLength;
  1840. break;
  1841. case OID_PNP_SET_POWER:
  1842. TRACE( TL_V, TM_Mp, ( "QInfo OID_PNP_SET_POWER %x", Oid ) );
  1843. *BytesRead = sizeof (NDIS_DEVICE_POWER_STATE );
  1844. *BytesNeeded = sizeof (NDIS_DEVICE_POWER_STATE );
  1845. if (InformationBufferLength >= sizeof (NDIS_DEVICE_POWER_STATE))
  1846. {
  1847. NDIS_DEVICE_POWER_STATE PoState;
  1848. NdisMoveMemory (&PoState, InformationBuffer, sizeof(PoState));
  1849. NdisStatus = MPSetPower(pAdapter,PoState);
  1850. }
  1851. break;
  1852. case OID_1394_ISSUE_BUS_RESET:
  1853. {
  1854. TRACE( TL_V, TM_Mp, ( " OID_1394_ISSUE_BUS_RESET" ) );
  1855. if (InformationBufferLength == sizeof(ULONG))
  1856. {
  1857. nicIssueBusReset (pAdapter, (*(PULONG)InformationBuffer));
  1858. }
  1859. else
  1860. {
  1861. nicIssueBusReset (pAdapter, BUS_RESET_FLAGS_FORCE_ROOT );
  1862. }
  1863. break;
  1864. }
  1865. default:
  1866. NdisStatus = NDIS_STATUS_INVALID_OID;
  1867. *BytesRead = 0;
  1868. *BytesNeeded = 0;
  1869. break;
  1870. }
  1871. if (NdisStatus == NDIS_STATUS_SUCCESS)
  1872. {
  1873. DUMPDW( TL_V, TM_Mp, InformationBuffer, InformationBufferLength );
  1874. *BytesRead = BytesLeft;
  1875. *BytesNeeded = 0;
  1876. }
  1877. TRACE( TL_T, TM_Init, ( "<==NicEthSetInformation , Adapter %.8x, Oid %.8x, NdisStatus %x",pAdapter, Oid, NdisStatus ));
  1878. MATCH_IRQL;
  1879. return NdisStatus;
  1880. }
  1881. NDIS_STATUS
  1882. NicEthQueryInformation(
  1883. IN NDIS_HANDLE MiniportAdapterContext,
  1884. IN NDIS_OID Oid,
  1885. IN PVOID InformationBuffer,
  1886. IN ULONG InformationBufferLength,
  1887. OUT PULONG BytesWritten,
  1888. OUT PULONG BytesNeeded
  1889. )
  1890. /*++
  1891. Routine Description:
  1892. This is the Query information that will be used by the CL edge
  1893. Arguments:
  1894. Return Value:
  1895. --*/
  1896. {
  1897. UINT BytesLeft = InformationBufferLength;
  1898. PUCHAR InfoBuffer = (PUCHAR)(InformationBuffer);
  1899. NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
  1900. NDIS_HARDWARE_STATUS HardwareStatus = NdisHardwareStatusReady;
  1901. NDIS_MEDIA_STATE MediaState;
  1902. NDIS_MEDIUM Medium;
  1903. PADAPTERCB pAdapter;
  1904. ULONG GenericULong;
  1905. USHORT GenericUShort;
  1906. UCHAR GenericArray[6];
  1907. UINT MoveBytes = sizeof(GenericULong);
  1908. PVOID MoveSource = (PVOID)(&GenericULong);
  1909. ULONG i;
  1910. // PATMLANE_MAC_ENTRY pMacEntry;
  1911. // PATMLANE_ATM_ENTRY pAtmEntry;
  1912. STORE_CURRENT_IRQL;
  1913. pAdapter = (PADAPTERCB)MiniportAdapterContext;
  1914. TRACE( TL_T, TM_Init, ( "==>NicEthQueryInformation , Adapter %.8x, Oid %.8x",pAdapter, Oid ));
  1915. //
  1916. // Switch on request type
  1917. //
  1918. switch (Oid)
  1919. {
  1920. case OID_GEN_MAC_OPTIONS:
  1921. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_MAC_OPTIONS)" ) );
  1922. GenericULong = NDIS_MAC_OPTION_NO_LOOPBACK;
  1923. break;
  1924. case OID_GEN_SUPPORTED_LIST:
  1925. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_SUPPORTED_LIST)" ) );
  1926. MoveSource = (PVOID)(SupportedOids);
  1927. MoveBytes = sizeof(SupportedOids);
  1928. break;
  1929. case OID_GEN_HARDWARE_STATUS:
  1930. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_HARDWARE_STATUS)" ) );
  1931. HardwareStatus = NdisHardwareStatusReady;
  1932. MoveSource = (PVOID)(&HardwareStatus);
  1933. MoveBytes = sizeof(NDIS_HARDWARE_STATUS);
  1934. break;
  1935. case OID_GEN_MEDIA_CONNECT_STATUS:
  1936. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_MEDIA_CONNECT_STATUS)" ) );
  1937. if (ADAPTER_TEST_FLAG(pAdapter, fADAPTER_RemoteNodeInThisBoot) == FALSE)
  1938. {
  1939. MediaState = NdisMediaStateConnected;
  1940. }
  1941. else
  1942. {
  1943. MediaState = pAdapter->MediaConnectStatus;
  1944. }
  1945. MoveSource = (PVOID)(&MediaState);
  1946. MoveBytes = sizeof(NDIS_MEDIA_STATE);
  1947. break;
  1948. case OID_GEN_MEDIA_SUPPORTED:
  1949. case OID_GEN_MEDIA_IN_USE:
  1950. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_MEDIA_SUPPORTED)" ) );
  1951. Medium = g_ulMedium;
  1952. MoveSource = (PVOID) (&Medium);
  1953. MoveBytes = sizeof(NDIS_MEDIUM);
  1954. break;
  1955. case OID_GEN_MAXIMUM_LOOKAHEAD:
  1956. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_MAXIMUM_LOOKAHEAD)" ) );
  1957. GenericULong = pAdapter->MaxRecvBufferSize;
  1958. break;
  1959. case OID_GEN_CURRENT_LOOKAHEAD:
  1960. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_CURRENT_LOOKAHEAD)" ) );
  1961. GenericULong = pAdapter->MaxRecvBufferSize;
  1962. break;
  1963. case OID_GEN_MAXIMUM_FRAME_SIZE:
  1964. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_MAXIMUM_FRAME_SIZE)" ) );
  1965. GenericULong = 1512; //pAdapter->MaxRecvBufferSize;
  1966. break;
  1967. case OID_GEN_MAXIMUM_TOTAL_SIZE:
  1968. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_MAXIMUM_TOTAL_SIZE)" ) );
  1969. GenericULong = 1512; //pAdapter->MaxRecvBufferSize;
  1970. break;
  1971. case OID_GEN_TRANSMIT_BLOCK_SIZE:
  1972. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_TRANSMIT_BLOCK_SIZE)" ) );
  1973. GenericULong = pAdapter->MaxRecvBufferSize - sizeof (NDIS1394_UNFRAGMENTED_HEADER);
  1974. break;
  1975. case OID_GEN_RECEIVE_BLOCK_SIZE:
  1976. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_RECEIVE_BLOCK_SIZE)" ) );
  1977. GenericULong = pAdapter->MaxRecvBufferSize - sizeof (NDIS1394_UNFRAGMENTED_HEADER);
  1978. break;
  1979. case OID_GEN_MAXIMUM_SEND_PACKETS:
  1980. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_MAXIMUM_SEND_PACKETS)" ) );
  1981. GenericULong = 32; // XXX What is our limit? From adapter?
  1982. break;
  1983. case OID_GEN_LINK_SPEED:
  1984. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_LINK_SPEED)" ) );
  1985. GenericULong = pAdapter->SpeedMbps;
  1986. break;
  1987. case OID_GEN_TRANSMIT_BUFFER_SPACE:
  1988. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_TRANSMIT_BUFFER_SPACE)" ) );
  1989. GenericULong = pAdapter->MaxSendBufferSize;;
  1990. break;
  1991. case OID_GEN_RECEIVE_BUFFER_SPACE:
  1992. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_RECEIVE_BUFFER_SPACE)" ) );
  1993. GenericULong = pAdapter->MaxRecvBufferSize;
  1994. break;
  1995. case OID_GEN_VENDOR_ID:
  1996. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_VENDOR_ID)" ) );
  1997. GenericULong = 0xFFFFFFFF;
  1998. break;
  1999. case OID_GEN_VENDOR_DESCRIPTION:
  2000. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_VENDOR_DESCRIPTION)" ) );
  2001. MoveSource = (PVOID)"Microsoft IP/1394 Miniport";
  2002. MoveBytes = 27;
  2003. break;
  2004. case OID_GEN_DRIVER_VERSION:
  2005. case OID_GEN_VENDOR_DRIVER_VERSION:
  2006. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_DRIVER_VERSION)" ) );
  2007. GenericULong = 2;
  2008. break;
  2009. case OID_802_3_PERMANENT_ADDRESS:
  2010. case OID_802_3_CURRENT_ADDRESS:
  2011. TRACE( TL_V, TM_Mp, ( "QInfo(OID_802_3_CURRENT_ADDRESS)" ) );
  2012. NdisMoveMemory((PCHAR)GenericArray,
  2013. &pAdapter->MacAddressEth,
  2014. sizeof(MAC_ADDRESS));
  2015. MoveSource = (PVOID)(GenericArray);
  2016. MoveBytes = sizeof(MAC_ADDRESS);
  2017. break;
  2018. case OID_802_3_MULTICAST_LIST:
  2019. TRACE( TL_V, TM_Mp, ( "QInfo(OID_802_3_MULTICAST_LIST)" ) );
  2020. MoveSource = (PVOID) &pAdapter->McastAddrs[0];
  2021. MoveBytes = pAdapter->McastAddrCount * sizeof(MAC_ADDRESS);
  2022. break;
  2023. case OID_802_3_MAXIMUM_LIST_SIZE:
  2024. TRACE( TL_V, TM_Mp, ( "QInfo(OID_802_3_MAXIMUM_LIST_SIZE)" ) );
  2025. GenericULong = MCAST_LIST_SIZE;
  2026. break;
  2027. case OID_GEN_XMIT_OK:
  2028. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_XMIT_OK)" ) );
  2029. GenericULong = pAdapter->AdaptStats.ulXmitOk;;
  2030. break;
  2031. case OID_GEN_RCV_OK:
  2032. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_RCV_OK)" ) );
  2033. GenericULong = pAdapter->AdaptStats.ulRcvOk ;
  2034. break;
  2035. case OID_GEN_CURRENT_PACKET_FILTER:
  2036. TRACE( TL_V, TM_Mp, ( "QInfo(OID_GEN_CURRENT_PACKET_FILTER)" ) );
  2037. GenericULong = pAdapter->CurPacketFilter ;
  2038. break;
  2039. case OID_GEN_XMIT_ERROR:
  2040. case OID_GEN_RCV_ERROR:
  2041. case OID_GEN_RCV_NO_BUFFER:
  2042. case OID_802_3_RCV_ERROR_ALIGNMENT:
  2043. case OID_802_3_XMIT_ONE_COLLISION:
  2044. case OID_802_3_XMIT_MORE_COLLISIONS:
  2045. GenericULong = 0;
  2046. TRACE( TL_V, TM_Mp, ( "QInfo oid %x", Oid ) );
  2047. break;
  2048. case OID_PNP_QUERY_POWER:
  2049. TRACE( TL_V, TM_Mp, ( "QInfo OID_PNP_QUERY_POWER %x", Oid ) );
  2050. *BytesWritten = sizeof (NDIS_DEVICE_POWER_STATE );
  2051. *BytesNeeded = sizeof (NDIS_DEVICE_POWER_STATE );
  2052. NdisStatus = NDIS_STATUS_SUCCESS;
  2053. break;
  2054. case OID_1394_ISSUE_BUS_RESET:
  2055. {
  2056. TRACE( TL_V, TM_Mp, ( " OID_1394_ISSUE_BUS_RESET" ) );
  2057. GenericULong = 0;
  2058. if (InformationBufferLength == sizeof(ULONG))
  2059. {
  2060. nicIssueBusReset (pAdapter, (*(PULONG)InformationBuffer));
  2061. }
  2062. else
  2063. {
  2064. nicIssueBusReset (pAdapter, BUS_RESET_FLAGS_FORCE_ROOT );
  2065. }
  2066. break;
  2067. }
  2068. default:
  2069. NdisStatus = NDIS_STATUS_INVALID_OID;
  2070. break;
  2071. }
  2072. if (NdisStatus == NDIS_STATUS_SUCCESS)
  2073. {
  2074. if (MoveBytes > BytesLeft)
  2075. {
  2076. //
  2077. // Not enough room in InformationBuffer. Punt
  2078. //
  2079. *BytesNeeded = MoveBytes;
  2080. NdisStatus = NDIS_STATUS_INVALID_LENGTH;
  2081. }
  2082. else
  2083. {
  2084. //
  2085. // Store result.
  2086. //
  2087. NdisMoveMemory(InfoBuffer, MoveSource, MoveBytes);
  2088. //(*BytesWritten) += MoveBytes;
  2089. *BytesWritten = MoveBytes;
  2090. DUMPDW( TL_V, TM_Mp, InfoBuffer, *BytesWritten);
  2091. }
  2092. }
  2093. TRACE( TL_T, TM_Init, ( "<==NicEthQueryInformation , Adapter %.8x, Oid %.8x, Status %x Bytes Written %x ",pAdapter, Oid, NdisStatus, *BytesWritten ));
  2094. //MATCH_IRQL;
  2095. return NdisStatus;
  2096. }
  2097. VOID
  2098. NicMpSendPackets(
  2099. IN NDIS_HANDLE MiniportAdapterContext,
  2100. IN PPNDIS_PACKET PacketArray,
  2101. IN UINT NumberOfPackets
  2102. )
  2103. {
  2104. PADAPTERCB pAdapter = (PADAPTERCB)MiniportAdapterContext;
  2105. PETHERNET_VCCB pEthernetVc = NULL;
  2106. BOOLEAN fVcActive = FALSE;
  2107. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  2108. NDIS_STATUS IndicatedStatus = NDIS_STATUS_FAILURE;
  2109. ULONG i;
  2110. TRACE( TL_T, TM_Init, ( "==> NicMpSendPackets , Adapter %.8x, ppPacket %x, Num %x",pAdapter, PacketArray, NumberOfPackets ));
  2111. do
  2112. {
  2113. if (pAdapter->pEthernetVc == NULL)
  2114. {
  2115. break;
  2116. }
  2117. ADAPTER_ACQUIRE_LOCK (pAdapter);
  2118. pEthernetVc = pAdapter->pEthernetVc;
  2119. fVcActive = VC_ACTIVE(pEthernetVc);
  2120. if (fVcActive == TRUE)
  2121. {
  2122. for (i =0 ; i < NumberOfPackets; i++)
  2123. {
  2124. //
  2125. // Reference the Vc for each packet
  2126. //
  2127. nicReferenceCall((PVCCB)pEthernetVc, "NicMpSendPackets");
  2128. }
  2129. }
  2130. ADAPTER_RELEASE_LOCK (pAdapter);
  2131. if (fVcActive)
  2132. {
  2133. //
  2134. //Set resource and indicate the packet array up to ndis
  2135. //
  2136. for (i =0 ; i < NumberOfPackets; i++)
  2137. {
  2138. PNDIS_PACKET pMyPacket = NULL, pPacket = NULL;
  2139. PPKT_CONTEXT pPktContext = NULL;
  2140. pPacket = PacketArray[i];
  2141. //
  2142. // Now allocate a new packet
  2143. //
  2144. nicAllocatePacket (&NdisStatus,
  2145. &pMyPacket,
  2146. &pEthernetVc->PacketPool);
  2147. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2148. {
  2149. pMyPacket = NULL;
  2150. break;
  2151. }
  2152. //
  2153. // Set the original packet as the packet context
  2154. //
  2155. pPktContext = (PPKT_CONTEXT)&pMyPacket->MiniportReservedEx;
  2156. pPktContext->EthernetSend.pOrigPacket = pPacket;
  2157. IndicatedStatus = NDIS_STATUS_RESOURCES;
  2158. NDIS_SET_PACKET_STATUS (pMyPacket, IndicatedStatus);
  2159. //
  2160. // Chain the NdisBuffers
  2161. //
  2162. pMyPacket->Private.Head = pPacket->Private.Head;
  2163. pMyPacket->Private.Tail = pPacket->Private.Tail;
  2164. //
  2165. // Dump the packet
  2166. //
  2167. {
  2168. nicDumpPkt (pMyPacket, "Conn Less Send ");
  2169. nicCheckForEthArps (pMyPacket);
  2170. }
  2171. //
  2172. // We are in Ndis' context so we do not need a timer
  2173. //
  2174. NdisMCoIndicateReceivePacket(pEthernetVc->Hdr.NdisVcHandle, &pMyPacket,NumberOfPackets );
  2175. if (IndicatedStatus == NDIS_STATUS_RESOURCES)
  2176. {
  2177. //
  2178. // Return Packets work
  2179. //
  2180. pPktContext = (PPKT_CONTEXT)&pMyPacket->MiniportReservedEx;
  2181. ASSERT ( pPacket == pPktContext->EthernetSend.pOrigPacket );
  2182. //
  2183. // Free the locally allocated packet
  2184. //
  2185. nicFreePacket(pMyPacket, &pEthernetVc->PacketPool);
  2186. }
  2187. }
  2188. NdisMCoReceiveComplete(pAdapter->MiniportAdapterHandle);
  2189. }
  2190. }while (FALSE);
  2191. //
  2192. // Regardless of success, we need to complete the sends
  2193. //
  2194. for ( i = 0 ; i < NumberOfPackets; i++)
  2195. {
  2196. if (fVcActive == TRUE)
  2197. {
  2198. nicDereferenceCall ((PVCCB)pEthernetVc, "NicMpSendPackets" );
  2199. }
  2200. NdisMSendComplete ( pAdapter->MiniportAdapterHandle,
  2201. PacketArray[i],
  2202. NDIS_STATUS_SUCCESS);
  2203. }
  2204. TRACE( TL_T, TM_Init, ( "<== NicMpSendPackets "));
  2205. }
  2206. //----------------------------------------------------------------------------
  2207. // R E M O T E N O D E F U N C T I O N S S T A R T H E R E
  2208. //
  2209. NTSTATUS
  2210. nicAddRemoteNode(
  2211. IN PVOID Nic1394AdapterContext, // Nic1394 handle for the local host adapter
  2212. IN PVOID Enum1394NodeHandle, // Enum1394 handle for the remote node
  2213. IN PDEVICE_OBJECT RemoteNodePhysicalDeviceObject, // physical device object for the remote node
  2214. IN ULONG UniqueId0, // unique ID Low for the remote node
  2215. IN ULONG UniqueId1, // unique ID High for the remote node
  2216. OUT PVOID * pNic1394NodeContext // Nic1394 context for the remote node
  2217. )
  2218. // Function Description:
  2219. // This function does updates all the required nic1394 data structures to signal the arrival
  2220. // of a new remote node. Inserts itself into the correct list and allocates an address range
  2221. // for itself.
  2222. //
  2223. // Arguments
  2224. // pAdapter - Adapter structure
  2225. // UINT64 Unique Id associated with the remote node
  2226. //
  2227. // Return Value:
  2228. // Out is the pointer to the Pdo Control block that will be sent as a context for the Remove routine
  2229. {
  2230. NTSTATUS Status = STATUS_SUCCESS;
  2231. REMOTE_NODE *pRemoteNode = NULL;
  2232. PADAPTERCB pAdapter = (PADAPTERCB)Nic1394AdapterContext;
  2233. UINT64 RemoteNodeUniqueId;
  2234. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  2235. BOOLEAN fNeedToRequestResetNotification = FALSE;
  2236. ULONG Generation = 0;
  2237. BOOLEAN fIsOnlyNode = FALSE;
  2238. STORE_CURRENT_IRQL;
  2239. RemoteNodeUniqueId = 0;
  2240. RemoteNodeUniqueId = UniqueId0;
  2241. RemoteNodeUniqueId = RemoteNodeUniqueId<<32;
  2242. RemoteNodeUniqueId = RemoteNodeUniqueId | UniqueId1 ;
  2243. TRACE( TL_N, TM_Mp, ( "** nicAddRemoteNode Remote %.8x, UniqueId %I64x", RemoteNodePhysicalDeviceObject, RemoteNodeUniqueId) );
  2244. // Initialize a PdoCb with the 1394 Pdo and insert it into the Pdo list
  2245. //
  2246. do
  2247. {
  2248. NdisStatus = NicInitializeRemoteNode(&pRemoteNode,
  2249. RemoteNodePhysicalDeviceObject,
  2250. RemoteNodeUniqueId);
  2251. *pNic1394NodeContext = pRemoteNode;
  2252. if (NdisStatus!=NDIS_STATUS_SUCCESS)
  2253. {
  2254. TRACE( TL_A, TM_Mp, ( "NicMpInitializePdoCb FAILED %.8x", RemoteNodePhysicalDeviceObject) );
  2255. break;
  2256. }
  2257. pRemoteNode->pAdapter = pAdapter;
  2258. pRemoteNode->Enum1394NodeHandle = Enum1394NodeHandle;
  2259. pAdapter->MediaConnectStatus = NdisMediaStateConnected;
  2260. //
  2261. // We need to go through the RecvFiFo List and get allocate any address ranges on this pdo as well
  2262. //
  2263. ADAPTER_ACQUIRE_LOCK (pAdapter);
  2264. //
  2265. // Increment the Refcount. This signifies that the pRemoteNode has been created and will
  2266. // be derefed only when the nic gets a notification of removal.
  2267. //
  2268. pRemoteNode->pAdapter = pAdapter;
  2269. //
  2270. // Add a reference to the adapter as the Pdo Block, now has a pointer to it
  2271. // Will be derefed in the RemoveRemoteNode
  2272. //
  2273. nicReferenceAdapter (pAdapter, "nicAddRemoteNode");
  2274. //
  2275. // Figure out if there are no remote node in the Adapter's list. that will make this node the only remote node
  2276. // and we will have to kickstart the BCM algorithm
  2277. //
  2278. fIsOnlyNode = IsListEmpty (&pAdapter->PDOList);
  2279. TRACE( TL_V, TM_Mp, ( " nicAddRemoteNode: fIsOnlyNode %x", fIsOnlyNode ) );
  2280. //
  2281. // Insert the PDO into the adapter's RemoteNode List
  2282. //
  2283. InsertTailList (&pAdapter->PDOList, &pRemoteNode->linkPdo);
  2284. NdisInterlockedIncrement (&pAdapter->AdaptStats.ulNumRemoteNodes);
  2285. //
  2286. // Increment the ref on the Pdo block as the adapter, now has a pointer to it
  2287. // Will be derefed whereve the remote node is popped of the list
  2288. //
  2289. nicReferenceRemoteNode (pRemoteNode, "nicAddRemoteNode");
  2290. //
  2291. // Now set the flag that the Pdo Block is activated, and that
  2292. // it is ready to receive Irps
  2293. //
  2294. REMOTE_NODE_SET_FLAG (pRemoteNode, PDO_Activated);
  2295. ADAPTER_RELEASE_LOCK (pAdapter);
  2296. {
  2297. NODE_ADDRESS RemoteNodeAddress;
  2298. NdisStatus = nicGet1394AddressOfRemoteNode( pRemoteNode,
  2299. &RemoteNodeAddress,
  2300. 0 );
  2301. if (NdisStatus == NDIS_STATUS_SUCCESS)
  2302. {
  2303. TRACE( TL_V, TM_Mp, ( " RemoteNode %x , NodeAddress %",
  2304. pRemoteNode, RemoteNodeAddress.NA_Node_Number) );
  2305. ADAPTER_ACQUIRE_LOCK (pAdapter);
  2306. pAdapter->NodeTable.RemoteNode[RemoteNodeAddress.NA_Node_Number] = pRemoteNode;
  2307. pRemoteNode->RemoteAddress = RemoteNodeAddress;
  2308. ADAPTER_RELEASE_LOCK (pAdapter);
  2309. }
  2310. else
  2311. {
  2312. ASSERT (!" Unable to get Address from remote node");
  2313. //
  2314. // Do not fail the Add Node
  2315. //
  2316. REMOTE_NODE_SET_FLAG (pRemoteNode, PDO_NotInsertedInTable);
  2317. NdisStatus = NDIS_STATUS_SUCCESS;
  2318. }
  2319. }
  2320. //
  2321. // Update the local host's speed values
  2322. //
  2323. nicUpdateLocalHostSpeed (pAdapter);
  2324. //
  2325. // Update the remote node's cached caps.
  2326. //
  2327. {
  2328. UINT SpeedTo;
  2329. UINT EffectiveMaxBufferSize;
  2330. UINT MaxRec;
  2331. // Specifying FALSE (!from cache) below causes pRemoteNode's cached caps
  2332. // to be refreshed. Ignore return value.
  2333. //
  2334. (VOID) nicQueryRemoteNodeCaps (pAdapter,
  2335. pRemoteNode,
  2336. &SpeedTo,
  2337. &EffectiveMaxBufferSize,
  2338. &MaxRec
  2339. );
  2340. }
  2341. //
  2342. // We have received a remote node in this boot.
  2343. // Set the flag. No need to hold the lock
  2344. //
  2345. ADAPTER_SET_FLAG(pAdapter, fADAPTER_RemoteNodeInThisBoot);
  2346. //
  2347. // Kick start the BCM algorithm if this is the only node in the Adapter's list. also need to initialize the BCR
  2348. // if necessary. All done in this BCMAddRemoteNode function
  2349. //
  2350. nicBCMAddRemoteNode (pAdapter,
  2351. fIsOnlyNode );
  2352. //
  2353. // Inform the protocols of this new node, so that
  2354. // it can query us for a new Euid Map
  2355. //
  2356. nicInformProtocolsOfReset(pAdapter);
  2357. }while (FALSE);
  2358. TRACE( TL_T, TM_Mp, ("<==nicAddRemoteNode Remote %.8x, Status %.8x", RemoteNodePhysicalDeviceObject, Status));
  2359. MATCH_IRQL;
  2360. return NdisStatus;
  2361. }
  2362. VOID
  2363. nicAddRemoteNodeChannelVc (
  2364. IN PADAPTERCB pAdapter,
  2365. IN PREMOTE_NODE pRemoteNode
  2366. )
  2367. // Function Description:
  2368. // Do Nothing for now
  2369. //
  2370. // Called with the lock held
  2371. // Arguments
  2372. // pADapter - Local host
  2373. // pRemoteNode - Remote Node being added
  2374. //
  2375. // Return Value:
  2376. // None;
  2377. //
  2378. //
  2379. {
  2380. PLIST_ENTRY pVcListEntry = NULL;
  2381. PLIST_ENTRY pAfListEntry = NULL;
  2382. PVCCB pVc = NULL;
  2383. PCHANNEL_VCCB pChannelVc = NULL;
  2384. PAFCB pAf = NULL;
  2385. TRACE( TL_T, TM_Mp, ("==>nicAddRemoteNodeChannelVc pAdapter %x, pRemoteNode %x", pAdapter, pRemoteNode ) );
  2386. TRACE( TL_T, TM_Mp, ("<==nicAddRemoteNodeChannelVc pAdapter %x, pRemoteNode %x", pAdapter, pRemoteNode ) );
  2387. }
  2388. VOID
  2389. nicDeleteLookasideList (
  2390. IN OUT PNIC_NPAGED_LOOKASIDE_LIST pLookasideList
  2391. )
  2392. {
  2393. TRACE( TL_T, TM_Cm, ( "==> nicDeleteLookasideList pLookaside List %x", pLookasideList ) );
  2394. if (pLookasideList)
  2395. {
  2396. ASSERT (pLookasideList->OutstandingPackets == 0);
  2397. NdisDeleteNPagedLookasideList (&pLookasideList->List);
  2398. }
  2399. TRACE( TL_T, TM_Cm, ( "<== nicDeleteLookasideList pLookaside List %x", pLookasideList) );
  2400. }
  2401. NDIS_STATUS
  2402. nicFreeRemoteNode(
  2403. IN REMOTE_NODE *pRemoteNode
  2404. )
  2405. // Function:
  2406. // Frees the memory cocupied by a PdoCb
  2407. // Argument:
  2408. // PdoControl Block
  2409. // Return Value, Always Success
  2410. {
  2411. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  2412. TRACE( TL_T, TM_Mp, ( "==>nicFreeRemoteNodepRemoteNode %.8x", pRemoteNode ) );
  2413. ASSERT (pRemoteNode->Ref.ReferenceCount == 0);
  2414. nicFreeNicSpinLock (&pRemoteNode->ReassemblyLock);
  2415. nicSetFlags (&pRemoteNode->ulFlags, PDO_Removed);
  2416. nicClearFlags (&pRemoteNode->ulFlags, PDO_BeingRemoved);
  2417. pRemoteNode->pPdo = NULL;
  2418. pRemoteNode->ulTag = MTAG_FREED;
  2419. FREE_NONPAGED (pRemoteNode);
  2420. TRACE( TL_T, TM_Mp, ( "<==nicFreeRemoteNode" ) );
  2421. return NdisStatus;
  2422. }
  2423. VOID
  2424. nicInitializeLookasideList(
  2425. IN OUT PNIC_NPAGED_LOOKASIDE_LIST pLookasideList,
  2426. ULONG Size,
  2427. ULONG Tag,
  2428. USHORT Depth
  2429. )
  2430. /*++
  2431. Routine Description:
  2432. Allocates and initializes a nic Lookaside list
  2433. Arguments:
  2434. Return Value:
  2435. --*/
  2436. {
  2437. TRACE( TL_T, TM_Cm, ( "==> nicInitializeLookasideList pLookaside List %x, size %x, Tag %x, Depth %x, ",
  2438. pLookasideList, Size, Tag, Depth) );
  2439. NdisInitializeNPagedLookasideList( &pLookasideList->List,
  2440. NULL, //Allocate
  2441. NULL, // Free
  2442. 0, // Flags
  2443. Size,
  2444. MTAG_CBUF,
  2445. Depth ); // Depth
  2446. pLookasideList->Size = Size;
  2447. TRACE( TL_T, TM_Cm, ( "<== nicInitializeLookasideList " ) );
  2448. }
  2449. NDIS_STATUS
  2450. NicInitializeRemoteNode(
  2451. OUT REMOTE_NODE **ppRemoteNode,
  2452. IN PDEVICE_OBJECT p1394DeviceObject,
  2453. IN UINT64 UniqueId
  2454. )
  2455. /*++
  2456. Routine Description:
  2457. This function allocates and initializes a control block for the Device Object
  2458. that is being passed . Also sets the initalize flag and, intialized the Vc List
  2459. Copies the unique id, Initializes the reassembly structures ( lock and list)
  2460. Arguments:
  2461. pRemoteNode - Pointer to remote node that was allocated
  2462. pDevice Object for the remote node
  2463. Unique Id - UID of the remote node
  2464. Return Value:
  2465. Resources - if the Allocation failed
  2466. Success - otherwise
  2467. --*/
  2468. {
  2469. NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
  2470. PREMOTE_NODE pRemoteNode = NULL;
  2471. TRACE( TL_T, TM_Mp, ( "==>NicInitializeRemoteNode PDO %.8x UniqueId %I64x", p1394DeviceObject, UniqueId) );
  2472. do
  2473. {
  2474. pRemoteNode = ALLOC_NONPAGED( sizeof(REMOTE_NODE), MTAG_REMOTE_NODE);
  2475. if (pRemoteNode == NULL)
  2476. {
  2477. TRACE( TL_A, TM_Mp, ( "Memory Allocation for Pdo Block FAILED" ) );
  2478. *ppRemoteNode = NULL;
  2479. NdisStatus = NDIS_STATUS_RESOURCES;
  2480. break;
  2481. }
  2482. //
  2483. // Zero out the strcuture
  2484. //
  2485. NdisZeroMemory ( pRemoteNode , sizeof(REMOTE_NODE) );
  2486. //
  2487. // Set up the tag
  2488. //
  2489. pRemoteNode ->ulTag = MTAG_REMOTE_NODE;
  2490. //
  2491. // Set up the remote device's PDO
  2492. //
  2493. pRemoteNode ->pPdo = p1394DeviceObject;
  2494. //
  2495. // Set up the Unique ID
  2496. //
  2497. pRemoteNode ->UniqueId = UniqueId;
  2498. //
  2499. // Set up a Fake Mac Address for the Unique ID
  2500. //
  2501. nicGetMacAddressFromEuid(&UniqueId, &pRemoteNode->ENetAddress) ;
  2502. //
  2503. // Initialize the VC that are open on this Remote Node
  2504. //
  2505. InitializeListHead ( &(pRemoteNode->VcList));
  2506. //
  2507. // Initialize the ref count
  2508. //
  2509. nicInitializeRef (&pRemoteNode->Ref);
  2510. //
  2511. // allocate the spin lock to control reassembly
  2512. //
  2513. nicInitializeNicSpinLock (&(pRemoteNode ->ReassemblyLock));
  2514. //
  2515. // list for all reassemblies happenning on the remote node
  2516. //
  2517. InitializeListHead (&pRemoteNode->ReassemblyList);
  2518. *ppRemoteNode = pRemoteNode ;
  2519. } while (FALSE);
  2520. TRACE( TL_T, TM_Mp, ( "<==NicInitializeRemoteNode, Status %.8x, pRemoteNode %.8x", NdisStatus, *ppRemoteNode) );
  2521. return NdisStatus;
  2522. }
  2523. VOID
  2524. nicNoRemoteNodesLeft (
  2525. IN PADAPTERCB pAdapter
  2526. )
  2527. // Function Description:
  2528. // Called from the RemoveRemote Node codepath
  2529. // This means that the last node has gone away.
  2530. // We need to clean out all the BroadcastChannel's register
  2531. // so that the next incoming node does not read incorrect values.
  2532. // Check to see if a BCM algorithm is not in progress
  2533. // Arguments
  2534. // pADpater - Local host
  2535. //
  2536. // Return Value:
  2537. //
  2538. {
  2539. BOOLEAN fBCMInProgress;
  2540. ADDRESS_RANGE_CONTEXT BCRAddressRange;
  2541. TRACE( TL_T, TM_Bcm, ( "==>nicNoRemoteNodesLeft pAdapter %x ",pAdapter ) );
  2542. pAdapter->MediaConnectStatus = NdisMediaStateDisconnected;
  2543. if (ADAPTER_TEST_FLAG( pAdapter, fADAPTER_Halting) == FALSE)
  2544. {
  2545. nicMIndicateStatus ( pAdapter,NDIS_STATUS_MEDIA_DISCONNECT, NULL,0);
  2546. }
  2547. TRACE( TL_T, TM_Bcm, ( "<==nicNoRemoteNodesLeft pAdapter %x ",pAdapter ) );
  2548. }
  2549. VOID
  2550. nicReallocateChannels (
  2551. IN PNDIS_WORK_ITEM pWorkItem,
  2552. IN PVOID Context
  2553. )
  2554. // Function Description:
  2555. // Walk through all the channel VCs and reallocate all their respective channels
  2556. // Except the BCM channel . the BCM will reallocate this
  2557. //
  2558. // Tell the protocol that the 1394 bus has been reset. after all the channels have
  2559. // been allocated
  2560. //
  2561. // Arguments
  2562. // Context= pRemoteNode - that is still around
  2563. //
  2564. // Return Value:
  2565. // None
  2566. {
  2567. ULONGLONG ChannelsAllocatedByLocalHost = 0;
  2568. ULONG Channel = 0;
  2569. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  2570. PADAPTERCB pAdapter = (PADAPTERCB) Context;
  2571. ULONGLONG One = 1;
  2572. TRACE( TL_T, TM_Mp, ( "==>nicReallocateChannels pAdpater %x", pAdapter) );
  2573. TRACE( TL_V, TM_Mp, (" nicReallocateChannels ChannelsAllocatedByLocalHost %I64x ", ChannelsAllocatedByLocalHost) );
  2574. Channel =0;
  2575. while (Channel < 64)
  2576. {
  2577. //
  2578. // Does the channel 'i' need to be allocated
  2579. //
  2580. ADAPTER_ACQUIRE_LOCK (pAdapter);
  2581. ChannelsAllocatedByLocalHost = pAdapter->ChannelsAllocatedByLocalHost ;
  2582. ADAPTER_RELEASE_LOCK (pAdapter);
  2583. if ( (( g_ullOne<<Channel ) & ChannelsAllocatedByLocalHost) == TRUE)
  2584. {
  2585. if (Channel == BROADCAST_CHANNEL)
  2586. {
  2587. //
  2588. // The broadcast channel will be allocated by the BCM. skip it.
  2589. //
  2590. continue;
  2591. }
  2592. NdisStatus = nicAllocateChannel (pAdapter,
  2593. Channel,
  2594. NULL);
  2595. //
  2596. // If allocation fails ... Have not implemented recovery yet.
  2597. //
  2598. if (NdisStatus != NDIS_STATUS_SUCCESS)
  2599. {
  2600. ASSERT (NdisStatus == NDIS_STATUS_SUCCESS)
  2601. }
  2602. }
  2603. Channel ++;
  2604. }
  2605. #if 0 // We don't need this currently
  2606. //
  2607. // Pick up the remote node info for all remote nodes.
  2608. //
  2609. nicUpdateRemoteNodeCaps(pAdapter);
  2610. #endif // 0
  2611. //
  2612. // Now that the channels are reallocated, inform the protocols of the reset
  2613. //
  2614. nicInformProtocolsOfReset(pAdapter);
  2615. //
  2616. // Dereference the ref that was added prior to scheduling this workitem
  2617. //
  2618. NdisInterlockedDecrement(&pAdapter->OutstandingWorkItems);
  2619. nicDereferenceAdapter(pAdapter, "nicResetReallocateChannels ");
  2620. FREE_NONPAGED(pWorkItem);
  2621. TRACE( TL_T, TM_Mp, ( "<==nicReallocateChannels " ) );
  2622. }
  2623. NDIS_STATUS
  2624. nicRemoteNodeRemoveVcCleanUp(
  2625. IN REMOTE_NODE *pRemoteNode
  2626. )
  2627. // Function Description:
  2628. //
  2629. // This function walks through the Pdo's Vc list annd closes
  2630. // the calls on each of them. These are SendFIFO VCs
  2631. // Channel VC's will not be closed when the remote node is removed.
  2632. // This is typically called from a remove remote node function
  2633. //
  2634. // Arguments
  2635. // PdoCb Pdo Control block that is getting removed
  2636. //
  2637. // Return Value:
  2638. // Always Success
  2639. //
  2640. // Called with the lock held
  2641. //
  2642. {
  2643. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  2644. PVCCB pVc = NULL;
  2645. PLIST_ENTRY pVcList = NULL;
  2646. STORE_CURRENT_IRQL;
  2647. TRACE( TL_T, TM_Mp, ( "==>nicRemoteNodeRemoveVcCleanUp pRemoteNode %.8x", pRemoteNode ) );
  2648. pVcList = ListNext (&pRemoteNode->VcList);
  2649. while (pVcList != &pRemoteNode->VcList)
  2650. {
  2651. pVc = (VCCB*) CONTAINING_RECORD (pVcList, VCHDR, SinglePdoVcLink);
  2652. //
  2653. // move to the next Vc in the list
  2654. //
  2655. pVcList = ListNext (pVcList);
  2656. TRACE( TL_V, TM_Mp, ( " nicRemoteNodeRemoveVcCleanUp VcType %x",pVc->Hdr.VcType ) );
  2657. switch(pVc->Hdr.VcType)
  2658. {
  2659. case NIC1394_SendRecvChannel:
  2660. case NIC1394_RecvChannel:
  2661. case NIC1394_SendChannel:
  2662. {
  2663. PCHANNEL_VCCB pChannelVc = (PCHANNEL_VCCB)pVc;
  2664. PREMOTE_NODE pNewChannelNode = NULL;
  2665. //
  2666. // Nothing to do here now
  2667. //
  2668. break;
  2669. }
  2670. case NIC1394_SendFIFO:
  2671. {
  2672. //
  2673. // We know that it is a Send FIFO and the call needs to be closed
  2674. //
  2675. VC_SET_FLAG (pVc, VCBF_VcDispatchedCloseCall);
  2676. //
  2677. // This is to guarantee that we have the Vc Structure around at the end of the call
  2678. //
  2679. nicReferenceVc (pVc);
  2680. REMOTE_NODE_RELEASE_LOCK (pRemoteNode);
  2681. TRACE( TL_V, TM_Mp, ( "Dispatching a close call for Vc%.8x ",pVc ) );
  2682. NdisMCmDispatchIncomingCloseCall (NDIS_STATUS_SUCCESS,
  2683. pVc->Hdr.NdisVcHandle,
  2684. NULL,
  2685. 0 );
  2686. REMOTE_NODE_ACQUIRE_LOCK (pRemoteNode);
  2687. //
  2688. // Deref the ref made above.
  2689. //
  2690. nicDereferenceVc (pVc);
  2691. break;
  2692. }
  2693. default:
  2694. {
  2695. //
  2696. // There should be no other VC types here
  2697. //
  2698. TRACE( TL_A, TM_Mp, ( " Invalid VC %x Type nicRemoteNodeRemoveVcCleanUp ", pVc ) );
  2699. ASSERT (0);
  2700. }
  2701. }
  2702. }
  2703. MATCH_IRQL;
  2704. TRACE( TL_T, TM_Mp, ( "<==nicRemoteNodeRemoveVcCleanUp " ) );
  2705. return NDIS_STATUS_SUCCESS;
  2706. }
  2707. NTSTATUS
  2708. nicRemoveRemoteNode(
  2709. IN PVOID Nic1394NodeContext // Nic1394 context for the remote node
  2710. )
  2711. // Function Description:
  2712. // This function does all the hard work when the nic gets notification
  2713. // of a remote node going away.
  2714. // Closes all calls on the Pdo ,
  2715. // Removes the Remote Node from the adapter's listPdo
  2716. // frees all the reassemblies on this node
  2717. // and then waits for the refcount to go to zero
  2718. //
  2719. // Arguments
  2720. // Nic1394NodeContext : The Remote Node that is going away
  2721. //
  2722. // Return Value:
  2723. // Success: if all calls succeed
  2724. //
  2725. //
  2726. //
  2727. {
  2728. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  2729. NTSTATUS Status = STATUS_SUCCESS;
  2730. PREMOTE_NODE pRemoteNode = (REMOTE_NODE *)Nic1394NodeContext;
  2731. PADAPTERCB pAdapter = pRemoteNode->pAdapter;
  2732. BOOLEAN bWaitEventSignalled = FALSE;
  2733. PLIST_ENTRY pVcListEntry = NULL;
  2734. PVCCB pVc = NULL;
  2735. BOOLEAN FreeAddressRange = TRUE;
  2736. BOOLEAN fIsPdoListEmpty = FALSE;
  2737. LIST_ENTRY ReassemblyList;
  2738. STORE_CURRENT_IRQL;
  2739. TRACE( TL_T, TM_Mp, ( " ** nicRemoveRemoteNode Node Context %x , Pdo %x",Nic1394NodeContext, pRemoteNode->pPdo ) );
  2740. do
  2741. {
  2742. pAdapter->pLastRemoteNode = pRemoteNode;
  2743. REMOTE_NODE_ACQUIRE_LOCK (pRemoteNode);
  2744. //
  2745. // We should tell everyone that the Pdo is being removed. However keep the node active
  2746. // because there are Vc's which might need to submit Irps
  2747. //
  2748. REMOTE_NODE_SET_FLAG (pRemoteNode, PDO_BeingRemoved);
  2749. //
  2750. // Dispatch Close call requests for active calls on this Pdo.
  2751. // However, keep the VCs in the pdocb's list
  2752. // The NicCmCloseCall is the only function that removes Pdo's from the list
  2753. // Will need to free the address range for any recv Vcs seperately
  2754. //
  2755. NdisStatus = nicRemoteNodeRemoveVcCleanUp (pRemoteNode);
  2756. //
  2757. // Remove the remote node from the RemoteNode Table
  2758. //
  2759. //
  2760. nicRemoveRemoteNodeFromNodeTable(&pAdapter->NodeTable,pRemoteNode);
  2761. //
  2762. // Free All reassembly operations on this remopte node
  2763. //
  2764. nicFreeReassembliesOnRemoteNode (pRemoteNode, &ReassemblyList);
  2765. //
  2766. // Dereference the ref that was added when the Pdo block was inserted in the Adapter's list
  2767. // The actual removal will take place later. We still have close calls to be completed and they
  2768. // will need the PdoCb. So it remains in the adapter's queue
  2769. //
  2770. nicDereferenceRemoteNode (pRemoteNode, "nicRemoveRemoteNode");
  2771. //
  2772. // Need to Deref the Reference made in NicInitializeRemoteNode function
  2773. //
  2774. nicDereferenceRemoteNode (pRemoteNode, "nicRemoveRemoteNode");
  2775. //
  2776. // Dequeue the remote node here
  2777. //
  2778. nicRemoveEntryList (&pRemoteNode->linkPdo);
  2779. NdisInterlockedDecrement (&pAdapter->AdaptStats.ulNumRemoteNodes);
  2780. //
  2781. // If this was the last remote node, then some special cleaning will be done
  2782. //
  2783. fIsPdoListEmpty = IsListEmpty (&pAdapter->PDOList);
  2784. TRACE( TL_T, TM_Mp, ( " nicRemoveRemoteNode fIsOnlyNode %x ",fIsPdoListEmpty ) );
  2785. REMOTE_NODE_RELEASE_LOCK (pRemoteNode);
  2786. //
  2787. // Now, we wait forever for all the reference to go away
  2788. //
  2789. TRACE( TL_V, TM_Mp, ( "About ot Wait RemoteNode Ref's to go to zero" ) );
  2790. bWaitEventSignalled = NdisWaitEvent (&pRemoteNode->Ref.RefZeroEvent, ONE_MINUTE);
  2791. if (bWaitEventSignalled == FALSE)
  2792. {
  2793. //
  2794. // Our WaitEvent timed out. Will need to fail gracefully. For now assert(0)
  2795. //
  2796. TRACE( TL_A, TM_Mp, ( "Wait Timed Out pRemoteNode %.8x, RefCount %.8x ",
  2797. pRemoteNode, pRemoteNode->Ref.ReferenceCount) );
  2798. ASSERT (bWaitEventSignalled == TRUE);
  2799. }
  2800. TRACE( TL_V, TM_Mp, ( "Wait Succeeded Ref == 0, pRemoteNode %.8x, RefCount %.8x ",
  2801. pRemoteNode, pRemoteNode->Ref.ReferenceCount) );
  2802. //
  2803. // If this was the last node, and the remote node list is empty, we need to clean up the BCR
  2804. //
  2805. if (fIsPdoListEmpty == TRUE)
  2806. {
  2807. nicNoRemoteNodesLeft (pAdapter);
  2808. }
  2809. //
  2810. // Delete the reassemblies that belong to this remote node and free them
  2811. //
  2812. if (IsListEmpty (&ReassemblyList) == FALSE)
  2813. {
  2814. nicAbortReassemblyList (&ReassemblyList);
  2815. }
  2816. nicFreeRemoteNode(pRemoteNode);
  2817. //
  2818. // Now update the speed on the adapter
  2819. //
  2820. nicUpdateLocalHostSpeed(pAdapter);
  2821. //
  2822. // Inform the protocols of the node removal, so that
  2823. // it can query us for a new Euid Map
  2824. //
  2825. nicInformProtocolsOfReset(pAdapter);
  2826. //
  2827. // Careful this could cause the adapter refcounts to go to zero
  2828. //
  2829. nicDereferenceAdapter(pAdapter, "nicRemoveRemoteNode ");
  2830. } while (FALSE);
  2831. TRACE( TL_T, TM_Mp, ( "<== nicRemoveRemoteNode Status %.8x ",
  2832. NdisStatus ) );
  2833. MATCH_IRQL;
  2834. return NDIS_STATUS_SUCCESS;
  2835. }
  2836. VOID
  2837. nicResetNotificationCallback (
  2838. IN PVOID pContext
  2839. )
  2840. // Function Description:
  2841. // This routine will be called whenever the bus is reset.
  2842. // It will be called at DISPATCH Level
  2843. //
  2844. // Arguments
  2845. // Context : a Remote Node
  2846. //
  2847. //
  2848. // Return Value:
  2849. // None
  2850. {
  2851. PADAPTERCB pAdapter = (PADAPTERCB) pContext;
  2852. BOOLEAN fNeedToQueueBCMWorkItem = FALSE;
  2853. TRACE( TL_T, TM_Mp, ( "==>nicResetNotificationCallback Context %.8x ", pContext ) );
  2854. NdisInterlockedIncrement (&pAdapter->AdaptStats.ulNumResetCallbacks);
  2855. pAdapter->AdaptStats.ulResetTime = nicGetSystemTime();
  2856. //NdisInterlockedIncrement (&pAdapter->Generation);
  2857. TRACE( TL_I, TM_Mp, ( " BUS RESET Callback Context %x, Old Gen %x ", pContext , pAdapter->Generation) );
  2858. //
  2859. // Restart the BCM
  2860. //
  2861. nicResetRestartBCM (pAdapter);
  2862. //
  2863. // reallocate all channels that were opened by this node
  2864. //
  2865. nicResetReallocateChannels( pAdapter);
  2866. //
  2867. // Invalidate all pending reassemblies
  2868. //
  2869. nicFreeAllPendingReassemblyStructures(pAdapter);
  2870. TRACE( TL_T, TM_Mp, ( "<==nicResetNotificationCallback " ) );
  2871. }
  2872. VOID
  2873. nicResetReallocateChannels (
  2874. IN PADAPTERCB pAdapter
  2875. )
  2876. // Function Description:
  2877. // Fires off a workitem to reallocate channels. ONLY To be called from a reset.
  2878. // because it causes an indication to the protocols, once all the channels have
  2879. // been re-allocated
  2880. //
  2881. // Arguments
  2882. // Adapter: Local Adapter
  2883. //
  2884. //
  2885. // Return Value:
  2886. // None
  2887. {
  2888. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  2889. PNDIS_WORK_ITEM pResetChannelWorkItem;
  2890. TRACE( TL_T, TM_Mp, ( "==>nicResetReallocateChannels " ) );
  2891. //
  2892. // reference the adapter as it is going to passed to a workiter.
  2893. // decremented in the workitem
  2894. //
  2895. nicReferenceAdapter(pAdapter, "nicResetReallocateChannels");
  2896. do
  2897. {
  2898. pResetChannelWorkItem = ALLOC_NONPAGED (sizeof(NDIS_WORK_ITEM), MTAG_WORKITEM);
  2899. if (pResetChannelWorkItem== NULL)
  2900. {
  2901. TRACE( TL_A, TM_Cm, ( "nicResetReallocateChannels : Local Alloc failed for WorkItem" ) );
  2902. NdisStatus = NDIS_STATUS_RESOURCES;
  2903. break;
  2904. }
  2905. else
  2906. {
  2907. //
  2908. // From here on, this function cannot fail.
  2909. //
  2910. NdisStatus = NDIS_STATUS_SUCCESS;
  2911. }
  2912. NdisInitializeWorkItem ( pResetChannelWorkItem,
  2913. (NDIS_PROC) nicReallocateChannels ,
  2914. (PVOID) pAdapter);
  2915. TRACE( TL_V, TM_Cm, ( "Scheduling Channels WorkItem" ) );
  2916. NdisInterlockedIncrement(&pAdapter->OutstandingWorkItems);
  2917. NdisScheduleWorkItem (pResetChannelWorkItem);
  2918. } while (FALSE);
  2919. TRACE( TL_T, TM_Mp, ( "<==nicResetReallocateChannels %x ", NdisStatus ) );
  2920. }
  2921. VOID
  2922. nicResetRestartBCM (
  2923. IN PADAPTERCB pAdapter
  2924. )
  2925. // Function Description:
  2926. // Clean up the adapter's data structure and restart the BCM algorithm
  2927. //
  2928. // Arguments
  2929. // Adapter: Local Adapter
  2930. //
  2931. //
  2932. // Return Value:
  2933. // None
  2934. {
  2935. TRACE( TL_T, TM_Mp, ( "==>nicResetRestartBCM pAdpater %x", pAdapter ) );
  2936. //
  2937. // We might have a thread waiting in FindIrmAmongRemoteNodes. .. Let it go and make it
  2938. // abort the BCM
  2939. //
  2940. pAdapter->BCRData.BCRWaitForNewRemoteNode.EventCode = nic1394EventCode_BusReset;
  2941. NdisSetEvent (&pAdapter->BCRData.BCRWaitForNewRemoteNode.NdisEvent);
  2942. //
  2943. // Now set up the data structures so we can restart the BCM for this generation
  2944. //
  2945. ADAPTER_ACQUIRE_LOCK(pAdapter);
  2946. pAdapter->BCRData.LocalHostBCRBigEndian = BCR_IMPLEMENTED_BIG_ENDIAN;
  2947. pAdapter->BCRData.IRM_BCR.NC_One = 1;
  2948. pAdapter->BCRData.IRM_BCR.NC_Valid = 0;
  2949. pAdapter->BCRData.IRM_BCR.NC_Channel = 0x3f;
  2950. //
  2951. // Clear the flags that are only valid through a single run of the BCM algorithm
  2952. //
  2953. BCR_CLEAR_FLAG (pAdapter, BCR_BCMFailed | BCR_LocalHostBCRUpdated | BCR_ChannelAllocated | BCR_LocalHostIsIRM);
  2954. //
  2955. // This will inform any BCM algorithm that a new reset happened
  2956. //
  2957. ADAPTER_SET_FLAG (pAdapter, fADAPTER_InvalidGenerationCount);
  2958. ADAPTER_RELEASE_LOCK(pAdapter);
  2959. //
  2960. // Now reschedule a work item to do the BCM algorithm
  2961. //
  2962. TRACE( TL_A, TM_Bcm , ("Reset - scheduling the BCM" ) );
  2963. nicScheduleBCMWorkItem(pAdapter);
  2964. TRACE( TL_T, TM_Mp, ( "<==nicResetRestartBCM " ) );
  2965. }
  2966. VOID
  2967. nicBusResetWorkItem(
  2968. NDIS_WORK_ITEM* pResetWorkItem,
  2969. IN PVOID Context
  2970. )
  2971. {
  2972. PADAPTERCB pAdapter= (PADAPTERCB) Context;
  2973. TRACE( TL_T, TM_Mp, ( "==>nicBusResetWorkItem " ) );
  2974. nicBusReset (pAdapter,
  2975. BUS_RESET_FLAGS_FORCE_ROOT );
  2976. NdisInterlockedDecrement(&pAdapter->OutstandingWorkItems);
  2977. nicDereferenceAdapter(pAdapter, "nicBusResetWorkItem");
  2978. TRACE( TL_T, TM_Mp, ( "<==nicBusResetWorkItem" ) );
  2979. FREE_NONPAGED (pResetWorkItem);
  2980. }
  2981. VOID
  2982. nicIssueBusReset (
  2983. PADAPTERCB pAdapter,
  2984. ULONG Flags
  2985. )
  2986. // Function Description:
  2987. // Picks up a PDO and issues a bus reset on that PDO
  2988. // As this can come down through an NdisRequest, it can be at IRQL <=DISPATCH_LEVEL
  2989. // Arguments
  2990. // pAdapter - Local Host in question
  2991. //
  2992. // Return Value:
  2993. // Success - If Irp succeeded. Appropriate Error code otherwise
  2994. //
  2995. //
  2996. {
  2997. PREMOTE_NODE pRemoteNode = NULL;
  2998. TRACE( TL_T, TM_Mp, ( "==> nicIssueBusReset %x ",Flags ) );
  2999. if (PASSIVE_LEVEL == KeGetCurrentIrql () )
  3000. {
  3001. nicBusReset (pAdapter, Flags);
  3002. }
  3003. else
  3004. {
  3005. //
  3006. // Dereferenced in the workitem
  3007. //
  3008. nicReferenceAdapter (pAdapter, "nicIssueBusReset ");
  3009. do
  3010. {
  3011. PNDIS_WORK_ITEM pReset;
  3012. pReset = ALLOC_NONPAGED (sizeof(NDIS_WORK_ITEM), MTAG_WORKITEM);
  3013. if (pReset == NULL)
  3014. {
  3015. TRACE( TL_A, TM_Cm, ( "Local Alloc failed for WorkItem" ) );
  3016. break;
  3017. }
  3018. NdisInitializeWorkItem ( pReset,
  3019. (NDIS_PROC)nicBusResetWorkItem,
  3020. (PVOID)pAdapter);
  3021. TRACE( TL_A, TM_Cm, ( "Setting WorkItem" ) );
  3022. NdisInterlockedIncrement(&pAdapter->OutstandingWorkItems);
  3023. NdisScheduleWorkItem (pReset);
  3024. }while (FALSE);
  3025. }
  3026. TRACE( TL_T, TM_Mp, ( "<== nicIssueBusReset " ) );
  3027. }
  3028. VOID
  3029. nicUpdateLocalHostSpeed (
  3030. IN PADAPTERCB pAdapter
  3031. )
  3032. /*++
  3033. Routine Description:
  3034. Updates the speed for the local host and updates the payload for
  3035. all ChannelVCs
  3036. This also updates the SCode that goes to the ARP module..
  3037. The SCode will never be updated unless this function is called
  3038. via the BCM algorithm
  3039. Arguments:
  3040. Return Value:
  3041. --*/
  3042. {
  3043. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  3044. PREMOTE_NODE pRemoteNode = NULL;
  3045. PDEVICE_OBJECT Node[64];
  3046. ULONG Num = 0;
  3047. PREMOTE_NODE pTempNode;
  3048. PLIST_ENTRY pListEntry = ListNext(&pAdapter->PDOList);
  3049. ULONG SpeedMbps = 10000000;
  3050. ULONG PrevSpeed = pAdapter->Speed;
  3051. ULONG Speed =0;
  3052. ULONG MaxRecvBufferSize = 0;
  3053. ULONG MaxSendBufferSize = 0;
  3054. ULONG SCode = 0;
  3055. TRACE( TL_T, TM_Bcm, ( "==> nicUpdateLocalHostSpeed " ) );
  3056. do
  3057. {
  3058. NdisZeroMemory (&Node[0], 64*sizeof(PVOID) );
  3059. while (pListEntry != &pAdapter->PDOList)
  3060. {
  3061. pTempNode = CONTAINING_RECORD (pListEntry,
  3062. REMOTE_NODE,
  3063. linkPdo);
  3064. if (REMOTE_NODE_ACTIVE (pTempNode) == TRUE)
  3065. {
  3066. //
  3067. // Add this node to our array as it is valid
  3068. //
  3069. Num++;
  3070. Node[Num-1] = pTempNode->pPdo;
  3071. }
  3072. pListEntry = ListNext (pListEntry);
  3073. } // End of while loop
  3074. if (Num >63 || Num == 0)
  3075. {
  3076. TRACE (TL_I, TM_Mp, ("Invalid Num OfRemoteNodes %x", Num) );
  3077. Speed = 0;
  3078. break;
  3079. }
  3080. NdisStatus = nicGetMaxSpeedBetweenDevices( pAdapter,
  3081. Num,
  3082. Node,
  3083. &Speed);
  3084. if (NdisStatus != NDIS_STATUS_SUCCESS)
  3085. {
  3086. Speed = 0;
  3087. BREAK (TM_Mp, ("nicUpdateLocalHostSpeed : nicGetMaxSpeedBetweenDevices FAILED") );
  3088. }
  3089. //
  3090. // By looking at the speed constants 1 -> 100Mbps
  3091. //
  3092. SpeedMbps = Speed*1000000;
  3093. //
  3094. // update the scode -- default 400.
  3095. // As 400+ hardware is prototype from WinXP, we default to 400 for now
  3096. //
  3097. SCode = SCODE_400_RATE;
  3098. if (Speed > SPEED_FLAGS_400)
  3099. {
  3100. Speed = SPEED_FLAGS_400;
  3101. }
  3102. switch (Speed)
  3103. {
  3104. case SPEED_FLAGS_400 :
  3105. {
  3106. SCode = SCODE_400_RATE ;
  3107. MaxRecvBufferSize = ISOCH_PAYLOAD_400_RATE;
  3108. MaxSendBufferSize = ASYNC_PAYLOAD_400_RATE;
  3109. break;
  3110. }
  3111. case SPEED_FLAGS_100 :
  3112. {
  3113. SCode = SCODE_100_RATE;
  3114. MaxRecvBufferSize = ISOCH_PAYLOAD_100_RATE;
  3115. MaxSendBufferSize = ASYNC_PAYLOAD_100_RATE;
  3116. break;
  3117. }
  3118. case SPEED_FLAGS_200 :
  3119. {
  3120. SCode = SCODE_200_RATE;
  3121. MaxRecvBufferSize = ISOCH_PAYLOAD_200_RATE;
  3122. MaxSendBufferSize = ASYNC_PAYLOAD_200_RATE;
  3123. break;
  3124. }
  3125. default:
  3126. {
  3127. SCode = SCODE_400_RATE ;
  3128. MaxRecvBufferSize = ISOCH_PAYLOAD_400_RATE;
  3129. MaxSendBufferSize = ASYNC_PAYLOAD_400_RATE;
  3130. break;
  3131. }
  3132. }
  3133. ADAPTER_ACQUIRE_LOCK(pAdapter);
  3134. pAdapter->Speed = Speed;
  3135. pAdapter->SpeedMbps = SpeedMbps;
  3136. pAdapter->SCode = SCode;
  3137. pAdapter->MaxRecvBufferSize = MaxRecvBufferSize;
  3138. pAdapter->MaxSendBufferSize = MaxSendBufferSize;
  3139. ADAPTER_RELEASE_LOCK (pAdapter);
  3140. TRACE( TL_V, TM_Mp, ( " nicUpdateLocalHostSpeed Speed returned %d",SpeedMbps ) );
  3141. //
  3142. // Now update the speed value in all the channel VC's as they are dependent on this parameter
  3143. //
  3144. if (Speed == PrevSpeed ||
  3145. Speed > SPEED_FLAGS_1600 )
  3146. {
  3147. //
  3148. // either the speed has not changed or it has invalid value, break out
  3149. //
  3150. TRACE (TL_V, TM_Init, ("Will not update - Speed %x, Prev Speed %x", Speed, PrevSpeed) );
  3151. break;
  3152. }
  3153. //
  3154. // The speed and the payload have changed. Update all the channel Vc's
  3155. // and Recv FIFOVc's payload
  3156. //
  3157. nicUpdateSpeedInAllVCs (pAdapter,
  3158. Speed
  3159. );
  3160. } while (FALSE);
  3161. TRACE( TL_T, TM_Mp, ( "<== nicUpdateLocalHostSpeed SpeedCode %x, Num %x" , pAdapter->Speed, Num) );
  3162. }
  3163. VOID
  3164. nicUpdateSpeedInAllVCs (
  3165. PADAPTERCB pAdapter,
  3166. ULONG Speed
  3167. )
  3168. /*++
  3169. Routine Description:
  3170. This routine updates the speed flag in all Channel Vcs
  3171. It assumes that the new speed is different from the old speed
  3172. Arguments:
  3173. pAdapter- Local Adapter intance
  3174. Speed - new speed
  3175. Return Value:
  3176. --*/
  3177. {
  3178. PAFCB pAfcb = NULL;
  3179. PVCCB pVc = NULL;
  3180. PLIST_ENTRY pAfEntry = NULL;
  3181. PLIST_ENTRY pVcEntry = NULL;
  3182. ULONG MaxPayload = 0;
  3183. ULONG SCode = 0;
  3184. TRACE( TL_T, TM_Mp, ( "==> nicUpdateSpeedInAllVCs ") );
  3185. switch (Speed)
  3186. {
  3187. case SPEED_FLAGS_100 :
  3188. {
  3189. SCode = SCODE_100_RATE;
  3190. MaxPayload = ISOCH_PAYLOAD_100_RATE;
  3191. break;
  3192. }
  3193. case SPEED_FLAGS_200 :
  3194. {
  3195. SCode = SCODE_200_RATE;
  3196. MaxPayload = ISOCH_PAYLOAD_200_RATE ;
  3197. break;
  3198. }
  3199. case SPEED_FLAGS_400 :
  3200. {
  3201. SCode = SCODE_400_RATE;
  3202. MaxPayload = ISOCH_PAYLOAD_400_RATE;
  3203. break;
  3204. }
  3205. case SPEED_FLAGS_800 :
  3206. {
  3207. SCode = SCODE_800_RATE;
  3208. MaxPayload = ISOCH_PAYLOAD_400_RATE;
  3209. break;
  3210. }
  3211. case SPEED_FLAGS_1600 :
  3212. {
  3213. SCode = SCODE_1600_RATE;
  3214. MaxPayload = ISOCH_PAYLOAD_400_RATE;
  3215. break;
  3216. }
  3217. case SPEED_FLAGS_3200 :
  3218. {
  3219. SCode = SCODE_1600_RATE;
  3220. MaxPayload = ISOCH_PAYLOAD_400_RATE;
  3221. break;
  3222. }
  3223. default :
  3224. {
  3225. ASSERT (Speed <= SPEED_FLAGS_3200 && Speed != 0 );
  3226. break;
  3227. }
  3228. }
  3229. ADAPTER_ACQUIRE_LOCK (pAdapter);
  3230. pAfEntry = ListNext (&pAdapter->AFList);
  3231. //
  3232. // Walk through all the Vc and set the value on the channelVcs
  3233. //
  3234. while (pAfEntry != &pAdapter->AFList)
  3235. {
  3236. pAfcb = CONTAINING_RECORD (pAfEntry, AFCB, linkAFCB);
  3237. pAfEntry = ListNext (pAfEntry);
  3238. pVcEntry = ListNext (&pAfcb->AFVCList);
  3239. //
  3240. // Now walk through the VCs on the Af
  3241. //
  3242. while (pVcEntry != &pAfcb->AFVCList)
  3243. {
  3244. pVc = (PVCCB) CONTAINING_RECORD (pVcEntry, VCHDR, linkAFVcs );
  3245. pVcEntry = ListNext ( pVcEntry );
  3246. //
  3247. // If it is a channel Send Vc update the Speed and Payload
  3248. //
  3249. if (pVc->Hdr.VcType == NIC1394_SendRecvChannel || pVc->Hdr.VcType == NIC1394_SendChannel)
  3250. {
  3251. PCHANNEL_VCCB pChannelVc = (PCHANNEL_VCCB)pVc;
  3252. pChannelVc->Speed = Speed;
  3253. pVc->Hdr.MaxPayload = MaxPayload;
  3254. }
  3255. } //while (pVcEntry != &pAfcb->AFVCList)
  3256. } //while (pAfEntry != &pAdapter->AFList)
  3257. pAdapter->SCode = SCode;
  3258. ADAPTER_RELEASE_LOCK (pAdapter);
  3259. TRACE( TL_T, TM_Mp, ( "<== nicUpdateSpeedInAllVCs ") );
  3260. }
  3261. VOID
  3262. nicInitializeAllEvents (
  3263. IN PADAPTERCB pAdapter
  3264. )
  3265. // Function Description:
  3266. // Initialize all the events in the adapter block
  3267. //
  3268. // Arguments
  3269. // pAdapter - The local host in question.
  3270. //
  3271. // Return Value:
  3272. // None
  3273. {
  3274. TRACE( TL_T, TM_Mp, ( "==> nicInitializeAllEvents " ) );
  3275. NdisInitializeEvent (&pAdapter->RecvFIFOEvent);
  3276. NdisInitializeEvent (&pAdapter->WaitForRemoteNode.NdisEvent);
  3277. pAdapter->WaitForRemoteNode.EventCode = Nic1394EventCode_InvalidEventCode;
  3278. NdisInitializeEvent (&pAdapter->BCRData.MakeCallWaitEvent.NdisEvent);
  3279. pAdapter->BCRData.MakeCallWaitEvent.EventCode = Nic1394EventCode_InvalidEventCode;
  3280. NdisInitializeEvent (&pAdapter->BCRData.BCRWaitForNewRemoteNode.NdisEvent);
  3281. pAdapter->BCRData.BCRWaitForNewRemoteNode.EventCode = Nic1394EventCode_InvalidEventCode;
  3282. NdisInitializeEvent (&pAdapter->BCRData.BCRFreeAddressRange.NdisEvent);
  3283. pAdapter->BCRData.BCRFreeAddressRange.EventCode = Nic1394EventCode_InvalidEventCode;
  3284. TRACE( TL_T, TM_Mp, ( "<== nicInitializeAllEvents " ) );
  3285. }
  3286. VOID
  3287. nicInitializeAdapterLookasideLists (
  3288. IN PADAPTERCB pAdapter
  3289. )
  3290. // Function Description:
  3291. // Initialize all the lookaside lists in the adapter block
  3292. //
  3293. // Arguments
  3294. // pAdapter - The local host in question.
  3295. //
  3296. // Return Value:
  3297. // None
  3298. {
  3299. USHORT DefaultDepth = 15;
  3300. TRACE( TL_T, TM_Mp, ( "==> nicInitializeAdapterLookasideLists pAdpater %x ", pAdapter ) );
  3301. nicInitializeLookasideList ( &pAdapter->SendLookasideList100,
  3302. sizeof (PAYLOAD_100_LOOKASIDE_BUFFER),
  3303. MTAG_CBUF,
  3304. DefaultDepth );
  3305. pAdapter->SendLookasideList100.MaxSendSize = PAYLOAD_100;
  3306. TRACE( TL_V, TM_Mp, ( " SendLookasideList100 Payload %x", PAYLOAD_100) );
  3307. nicInitializeLookasideList ( &pAdapter->SendLookasideList2K,
  3308. sizeof (PAYLOAD_2K_LOOKASIDE_BUFFER),
  3309. MTAG_CBUF,
  3310. DefaultDepth );
  3311. pAdapter->SendLookasideList2K.MaxSendSize = PAYLOAD_2K;
  3312. TRACE( TL_V, TM_Mp, ( " SendLookasideList2K Payload %x", PAYLOAD_2K) );
  3313. nicInitializeLookasideList ( &pAdapter->SendLookasideList8K,
  3314. sizeof (PAYLOAD_8K_LOOKASIDE_BUFFER),
  3315. MTAG_CBUF,
  3316. 0 );
  3317. pAdapter->SendLookasideList8K.MaxSendSize = PAYLOAD_8K;
  3318. TRACE( TL_V, TM_Mp, ( " SendLookasideList8K Payload %x", PAYLOAD_8K) );
  3319. TRACE( TL_T, TM_Mp, ( "<== nicInitializeAdapterLookasideLists " ) );
  3320. }
  3321. VOID
  3322. nicDeleteAdapterLookasideLists (
  3323. IN PADAPTERCB pAdapter
  3324. )
  3325. // Function Description:
  3326. // Delete all the lookaside lists in the adapter block
  3327. //
  3328. // Arguments
  3329. // pAdapter - The local host in question.
  3330. //
  3331. // Return Value:
  3332. // None
  3333. {
  3334. TRACE( TL_T, TM_Mp, ( "==> nicDeleteAdapterLookasideLists pAdapter %x ", pAdapter ) );
  3335. TRACE( TL_T, TM_Mp, ( " Delete NonFragmentationLookasideList %x ", &pAdapter->SendLookasideList2K) );
  3336. nicDeleteLookasideList (&pAdapter->SendLookasideList2K);
  3337. TRACE( TL_T, TM_Mp, ( " Delete FragmentationLookasideList %x ", &pAdapter->SendLookasideList100) );
  3338. nicDeleteLookasideList (&pAdapter->SendLookasideList100);
  3339. TRACE( TL_T, TM_Mp, ( " Delete SmallPacketLookasideList %x ", &pAdapter->SendLookasideList8K) );
  3340. nicDeleteLookasideList (&pAdapter->SendLookasideList8K);
  3341. TRACE( TL_T, TM_Mp, ( "<== nicDeleteAdapterLookasideLists " ) );
  3342. }
  3343. VOID
  3344. ReassemblyTimerFunction (
  3345. IN PVOID SystemSpecific1,
  3346. IN PVOID FunctionContext,
  3347. IN PVOID SystemSpecific2,
  3348. IN PVOID SystemSpecific3
  3349. )
  3350. // Function Description:
  3351. // Walk through all the pending reassembly operations and
  3352. // take out the ones that need to be freed (Have been untouched
  3353. // since the timer last fired)
  3354. //
  3355. // Append the ToBeFreed reassemblies into a seperate linked list
  3356. // and free them after releasing the spin locks
  3357. //
  3358. // If the there are any pending reassemblies then the timer requeues
  3359. // itself
  3360. //
  3361. // Arguments
  3362. // padapter - Adapter (local host in question)
  3363. //
  3364. //
  3365. // Return Value:
  3366. // None
  3367. //
  3368. {
  3369. PREMOTE_NODE pRemoteNode = NULL;
  3370. PLIST_ENTRY pRemoteNodeList = NULL;
  3371. PLIST_ENTRY pReassemblyList = NULL;
  3372. LIST_ENTRY ToBeFreedList;
  3373. PNDIS1394_REASSEMBLY_STRUCTURE pReassembly = NULL;
  3374. PADAPTERCB pAdapter = (PADAPTERCB) FunctionContext;
  3375. ULONG RefValue = 0;
  3376. STORE_CURRENT_IRQL;
  3377. ( TL_T, TM_Mp, ( "==> ReassemblyTimerFunction pAdapter %x", pAdapter ) );
  3378. InitializeListHead(&ToBeFreedList);
  3379. ADAPTER_ACQUIRE_LOCK (pAdapter);
  3380. pRemoteNodeList = ListNext (&pAdapter->PDOList);
  3381. pAdapter->Reassembly.PktsInQueue =0;
  3382. //
  3383. // Walking through the remote nodes
  3384. //
  3385. while (pRemoteNodeList != &pAdapter->PDOList)
  3386. {
  3387. pRemoteNode = CONTAINING_RECORD(pRemoteNodeList, REMOTE_NODE, linkPdo);
  3388. pRemoteNodeList = ListNext (pRemoteNodeList);
  3389. RefValue = pRemoteNode->Ref.ReferenceCount; ;
  3390. //
  3391. // Reference the remote node, so we can guarantee its presence
  3392. //
  3393. if (REMOTE_NODE_ACTIVE (pRemoteNode) == FALSE)
  3394. {
  3395. //
  3396. // The remote node is going away. Skip this remote node
  3397. //
  3398. continue;
  3399. }
  3400. if (nicReferenceRemoteNode (pRemoteNode, "ReassemblyTimerFunction" )== FALSE )
  3401. {
  3402. //
  3403. // The remote node is going away. Skip this remote node
  3404. //
  3405. continue;
  3406. }
  3407. REMOTE_NODE_REASSEMBLY_ACQUIRE_LOCK (pRemoteNode);
  3408. //
  3409. // Now walking through all the reassembly structures on that remote node
  3410. //
  3411. pReassemblyList = ListNext(&pRemoteNode->ReassemblyList);
  3412. while (pReassemblyList != &pRemoteNode->ReassemblyList)
  3413. {
  3414. pReassembly = CONTAINING_RECORD (pReassemblyList,
  3415. NDIS1394_REASSEMBLY_STRUCTURE,
  3416. ReassemblyListEntry);
  3417. pReassemblyList = ListNext(pReassemblyList);
  3418. //
  3419. // If the reassembly has not been touched since the last timer it needs to be freed.
  3420. // Other threads can ask us to free the reassembly by setting the aborted flag
  3421. //
  3422. if (REASSEMBLY_TEST_FLAG (pReassembly, REASSEMBLY_FREED) == TRUE)
  3423. {
  3424. continue;
  3425. }
  3426. if (REASSEMBLY_TEST_FLAG (pReassembly, (REASSEMBLY_NOT_TOUCHED| REASSEMBLY_ABORTED)) == TRUE)
  3427. {
  3428. REASSEMBLY_SET_FLAG (pReassembly, REASSEMBLY_FREED);
  3429. //
  3430. // We have the lock, so we can remove this reassembly structure from the remote node
  3431. //
  3432. TRACE( TL_V, TM_Reas, ( "Removing Reassembly %x", pReassembly) );
  3433. RemoveEntryList(&pReassembly->ReassemblyListEntry);
  3434. //
  3435. // dereference the remote node . ref was made when the reassembly was added
  3436. // to the remote node
  3437. //
  3438. nicDereferenceRemoteNode (pRemoteNode, "ReassemblyTimerFunction - Removing reassembly" );
  3439. nicDereferenceReassembly (pReassembly, "ReassemblyTimerFunction - Removing reassembly");
  3440. //
  3441. // add this reassembly to the to be freed list.
  3442. //
  3443. InsertTailList(&ToBeFreedList,&pReassembly->ReassemblyListEntry);
  3444. }
  3445. else
  3446. {
  3447. //
  3448. // Mark the Reassembly as Not Touched. If a fragment is received, it will clear the flag
  3449. //
  3450. REASSEMBLY_SET_FLAG (pReassembly, REASSEMBLY_NOT_TOUCHED);
  3451. pAdapter->Reassembly.PktsInQueue ++;
  3452. }
  3453. }// while (pReassemblyList != &pRemoteNode->ReassemblyList)
  3454. REMOTE_NODE_REASSEMBLY_RELEASE_LOCK(pRemoteNode);
  3455. nicDereferenceRemoteNode(pRemoteNode , "ReassemblyTimerFunction " );
  3456. } //while (pRemoteNodeList != &pAdapter->PDOList)
  3457. //
  3458. // Clear the timer set flag , so that any new reassenblies will restart the timer
  3459. //
  3460. pAdapter->Reassembly.bTimerAlreadySet = FALSE;
  3461. pAdapter->Reassembly.CompleteEvent.EventCode = nic1394EventCode_ReassemblyTimerComplete;
  3462. NdisSetEvent (&pAdapter->Reassembly.CompleteEvent.NdisEvent);
  3463. ADAPTER_RELEASE_LOCK (pAdapter);
  3464. //
  3465. // Now we walk the ToBeFreedList and free each of the reasembly structures
  3466. //
  3467. if (IsListEmpty (&ToBeFreedList) == FALSE)
  3468. {
  3469. nicAbortReassemblyList (&ToBeFreedList);
  3470. }
  3471. if (pAdapter->Reassembly.PktsInQueue > 0)
  3472. {
  3473. //
  3474. // Requeue the timer, as there are still fragments remaining in the list.
  3475. //
  3476. nicQueueReassemblyTimer(pAdapter, FALSE);
  3477. }
  3478. TRACE( TL_T, TM_Mp, ( "<== ReassemblyTimerFunction " ) );
  3479. MATCH_IRQL;
  3480. }
  3481. NDIS_STATUS
  3482. nicAddIP1394ToConfigRom (
  3483. IN PADAPTERCB pAdapter
  3484. )
  3485. {
  3486. HANDLE hCromData = NULL;
  3487. NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
  3488. PMDL pConfigRomMdl = NULL;
  3489. TRACE( TL_T, TM_Mp, ( "==> nicAddIP1394ToConfigRom pAdapter %x", pAdapter ) );
  3490. NdisStatus = nicSetLocalHostPropertiesCRom(pAdapter,
  3491. (PUCHAR)&Net1394ConfigRom,
  3492. sizeof(Net1394ConfigRom),
  3493. SLHP_FLAG_ADD_CROM_DATA,
  3494. &hCromData,
  3495. &pConfigRomMdl);
  3496. ASSERT (NdisStatus == NDIS_STATUS_SUCCESS);
  3497. if (NdisStatus == NDIS_STATUS_SUCCESS)
  3498. {
  3499. pAdapter->hCromData = hCromData;
  3500. pAdapter->pConfigRomMdl = pConfigRomMdl;
  3501. }
  3502. TRACE( TL_T, TM_Mp, ( "<== nicAddIP1394ToConfigRom pAdapter %x", pAdapter ) );
  3503. return NdisStatus;
  3504. }
  3505. NDIS_STATUS
  3506. nicMCmRegisterAddressFamily (
  3507. IN PADAPTERCB pAdapter
  3508. )
  3509. // Function Description:
  3510. // This function will only be called once per local host
  3511. // This will cause the ARP module to send Create Vc's etc
  3512. //
  3513. // Arguments
  3514. // pAdapter -local host
  3515. //
  3516. //
  3517. // Return Value:
  3518. // None
  3519. //
  3520. {
  3521. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  3522. BOOLEAN fDoRegister = TRUE;
  3523. TRACE( TL_T, TM_Mp, ( "==> nicCmRegisterAddressFamily pAdapter %x", pAdapter ) );
  3524. do
  3525. {
  3526. // Register the address family of our call manager with NDIS for the
  3527. // newly bound adapter. We use the mini-port form of
  3528. // RegisterAddressFamily instead of the protocol form because
  3529. // we are a miniport/callmanager combo. The mini-port form
  3530. // causes the call manager VC context to
  3531. // automatically map to the mini-port VC context, which is exactly
  3532. // what we want.
  3533. //
  3534. // NDIS notifies all call manager clients of the new family we
  3535. // register.
  3536. //
  3537. {
  3538. NDIS_CALL_MANAGER_CHARACTERISTICS ncmc;
  3539. CO_ADDRESS_FAMILY family;
  3540. NdisZeroMemory( &family, sizeof(family) );
  3541. family.MajorVersion = NDIS_MajorVersion;
  3542. family.MinorVersion = NDIS_MinorVersion;
  3543. family.AddressFamily = CO_ADDRESS_FAMILY_1394;
  3544. NdisZeroMemory( &ncmc, sizeof(ncmc) );
  3545. ncmc.MajorVersion = NDIS_MajorVersion;
  3546. ncmc.MinorVersion = NDIS_MinorVersion;
  3547. ncmc.CmCreateVcHandler = NicCmCreateVc;
  3548. ncmc.CmDeleteVcHandler = NicCmDeleteVc;
  3549. ncmc.CmOpenAfHandler = NicCmOpenAf;
  3550. ncmc.CmCloseAfHandler = NicCmCloseAf;
  3551. ncmc.CmRegisterSapHandler = nicRegisterSapHandler;
  3552. ncmc.CmDeregisterSapHandler = nicDeregisterSapHandler;
  3553. ncmc.CmMakeCallHandler = NicCmMakeCall;
  3554. ncmc.CmCloseCallHandler = NicCmCloseCall;
  3555. // NEW for 1394 no ncmc.CmIncomingCallCompleteHandler
  3556. ncmc.CmAddPartyHandler = nicCmAddPartyHandler;
  3557. ncmc.CmDropPartyHandler = nicCmDropPartyHandler;
  3558. // no CmDropPartyHandler
  3559. // NEW for 1394 no ncmc.CmActivateVcCompleteHandler
  3560. // NEW for 1394 no ncmc.CmDeactivateVcCompleteHandler
  3561. ncmc.CmModifyCallQoSHandler = NicCmModifyCallQoS;
  3562. ncmc.CmRequestHandler = NicCmRequest;
  3563. // no CmRequestCompleteHandler
  3564. TRACE( TL_I, TM_Cm, ( "NdisMCmRegAf" ) );
  3565. NdisStatus = NdisMCmRegisterAddressFamily (pAdapter->MiniportAdapterHandle,
  3566. &family,
  3567. &ncmc,
  3568. sizeof(ncmc) );
  3569. TRACE( TL_I, TM_Cm, ( "NdisMCmRegAf=$%x", NdisStatus ) );
  3570. }
  3571. } while (FALSE);
  3572. TRACE( TL_T, TM_Mp, ( "<== nicCmRegisterAddressFamily NdisStatus %x", NdisStatus ) );
  3573. return NdisStatus;
  3574. }
  3575. VOID
  3576. nicFreeReassembliesOnRemoteNode (
  3577. IN PREMOTE_NODE pRemoteNode,
  3578. PLIST_ENTRY pToBeFreedList
  3579. )
  3580. /*++
  3581. Routine Description:
  3582. Free All reassemblies that are on this remote node.
  3583. Acquires the reassembly Lock , pops the reassemblies off the list and then aborts them
  3584. This functions is an exception to our reassembly garbage collection. algorithm as the context of this function
  3585. requires immediate freeing of the reassembly structures
  3586. Expects the remote node lock to be held
  3587. Arguments:
  3588. pRemote Node - Remote Node that is being pulled out
  3589. Return Value:
  3590. --*/
  3591. {
  3592. ULONG NumFreed=0;
  3593. PLIST_ENTRY pReassemblyList = NULL;
  3594. PNDIS1394_REASSEMBLY_STRUCTURE pReassembly = NULL;
  3595. STORE_CURRENT_IRQL;
  3596. TRACE( TL_T, TM_Mp, ( "==> nicFreeReassembliesOnRemoteNode pRemoteNode %x", pRemoteNode) );
  3597. InitializeListHead(pToBeFreedList);
  3598. //
  3599. // Now walking through all the reassembly structures on that remote node
  3600. //
  3601. //
  3602. // If the remtoe node is in the list, it is fair game for us to extract it
  3603. //
  3604. REMOTE_NODE_REASSEMBLY_ACQUIRE_LOCK (pRemoteNode);
  3605. pReassemblyList = ListNext(&pRemoteNode->ReassemblyList);
  3606. while (pReassemblyList != &pRemoteNode->ReassemblyList)
  3607. {
  3608. pReassembly = CONTAINING_RECORD (pReassemblyList,
  3609. NDIS1394_REASSEMBLY_STRUCTURE,
  3610. ReassemblyListEntry);
  3611. pReassemblyList = ListNext(pReassemblyList);
  3612. //
  3613. // Once the reassembly has been marked as free, it should no longer be in the remote
  3614. // node's list .
  3615. //
  3616. ASSERT (REASSEMBLY_TEST_FLAG (pReassembly, REASSEMBLY_FREED) == FALSE);
  3617. REASSEMBLY_SET_FLAG (pReassembly, REASSEMBLY_FREED);
  3618. //
  3619. // We have the lock, so we can remove this reassembly structure from the remote node
  3620. //
  3621. TRACE( TL_V, TM_Mp, ( "Removing Reassembly %x", pReassembly) );
  3622. RemoveEntryList(&pReassembly->ReassemblyListEntry);
  3623. //
  3624. // dereference the remote node . ref was made when the reassembly was added
  3625. // to the remote node
  3626. //
  3627. nicDereferenceRemoteNode (pRemoteNode, "nicFreeReassembliesOnRemoteNode " );
  3628. nicDereferenceReassembly(pReassembly, "nicFreeReassembliesOnRemoteNode " );
  3629. //
  3630. // add this reassembly to the to be freed list.
  3631. //
  3632. InsertTailList(pToBeFreedList,&pReassembly->ReassemblyListEntry);
  3633. }// while (pReassemblyList != &pRemoteNode->ReassemblyList)
  3634. REMOTE_NODE_REASSEMBLY_RELEASE_LOCK(pRemoteNode);
  3635. TRACE( TL_T, TM_Mp, ( "<== nicFreeReassembliesOnRemoteNode NumFreed %x",NumFreed ) );
  3636. MATCH_IRQL;
  3637. }
  3638. UCHAR
  3639. nicGetMaxRecFromBytes(
  3640. IN ULONG ByteSize
  3641. )
  3642. /*++
  3643. Routine Description:
  3644. Converts Size in bytes to MaxRec
  3645. 512 - 8
  3646. 1024 - 9
  3647. Arguments:
  3648. ULONG Bytes Size
  3649. Return Value:
  3650. --*/
  3651. {
  3652. TRACE( TL_T ,TM_Mp, ( "==>nicGetMaxRecFromBytes ByteSize %x",ByteSize) );
  3653. if (ByteSize == ASYNC_PAYLOAD_100_RATE) return MAX_REC_100_RATE;
  3654. if (ByteSize == ASYNC_PAYLOAD_200_RATE) return MAX_REC_200_RATE;
  3655. if (ByteSize == ASYNC_PAYLOAD_400_RATE) return MAX_REC_400_RATE;
  3656. if (ByteSize == ASYNC_PAYLOAD_800_RATE_LOCAL) return MAX_REC_800_RATE_LOCAL;
  3657. if (ByteSize == ASYNC_PAYLOAD_1600_RATE_LOCAL) return MAX_REC_1600_RATE_LOCAL;
  3658. if (ByteSize == ASYNC_PAYLOAD_3200_RATE_LOCAL) return MAX_REC_3200_RATE_LOCAL;
  3659. //
  3660. // Default to 400 for all greater values
  3661. //
  3662. return MAX_REC_400_RATE;
  3663. }
  3664. UCHAR
  3665. nicGetMaxRecFromSpeed(
  3666. IN ULONG Scode
  3667. )
  3668. /*++
  3669. Routine Description:
  3670. Converts Size in bytes to MaxRec
  3671. 512 - 8
  3672. 1024 - 9
  3673. Arguments:
  3674. ULONG Bytes Size
  3675. Return Value:
  3676. --*/
  3677. {
  3678. TRACE( TL_T ,TM_Mp, ( "==>nicGetMaxRecFromSpeed Scode %x",Scode) );
  3679. if (Scode == SPEED_FLAGS_100) return MAX_REC_100_RATE;
  3680. if (Scode == SPEED_FLAGS_200 ) return MAX_REC_200_RATE;
  3681. if (Scode == SPEED_FLAGS_400 ) return MAX_REC_400_RATE;
  3682. if (Scode == SPEED_FLAGS_800 ) return MAX_REC_800_RATE_LOCAL ;
  3683. if (Scode == SPEED_FLAGS_1600 ) return MAX_REC_1600_RATE_LOCAL ;
  3684. if (Scode == SPEED_FLAGS_3200 ) return MAX_REC_3200_RATE_LOCAL ;
  3685. //
  3686. // default
  3687. //
  3688. return MAX_REC_400_RATE;
  3689. }
  3690. PREMOTE_NODE
  3691. nicGetRemoteNodeFromTable (
  3692. ULONG NodeNumber,
  3693. PADAPTERCB pAdapter
  3694. )
  3695. /*++
  3696. Routine Description:
  3697. Looks up the remote node in a locked table , references the remote node and returns
  3698. Arguments:
  3699. ULONG NodeNumber
  3700. Return Value:
  3701. pRemoteNode
  3702. --*/
  3703. {
  3704. PREMOTE_NODE pRemoteNode = NULL;
  3705. ADAPTER_ACQUIRE_LOCK (pAdapter);
  3706. pRemoteNode = pAdapter->NodeTable.RemoteNode[NodeNumber];
  3707. if (pRemoteNode != NULL)
  3708. {
  3709. nicReferenceRemoteNode (pRemoteNode, "nicGetRemoteNodeFromTable");
  3710. }
  3711. ADAPTER_RELEASE_LOCK (pAdapter);
  3712. return pRemoteNode;
  3713. }
  3714. NDIS_STATUS
  3715. nicFillNicInfo (
  3716. IN PADAPTERCB pAdapter,
  3717. PNIC1394_NICINFO pInNicInfo,
  3718. PNIC1394_NICINFO pOutNicInfo
  3719. )
  3720. /*++
  3721. Routine Description:
  3722. Arguments:
  3723. pAdapter- fills in the required data
  3724. pBus Info - Assumes the buffer is valid
  3725. Return Value:
  3726. --*/
  3727. {
  3728. NDIS_STATUS Status = NDIS_STATUS_INVALID_DATA;
  3729. do
  3730. {
  3731. //
  3732. // First check internal version
  3733. //
  3734. if (pInNicInfo->Hdr.Version != NIC1394_NICINFO_VERSION)
  3735. {
  3736. TRACE( TL_A, TM_Mp, ( " NICINFO.Version mismatch. Want %lu got %lu\n",
  3737. NIC1394_NICINFO_VERSION,
  3738. pInNicInfo->Hdr.Version
  3739. ));
  3740. break;
  3741. }
  3742. //
  3743. // Struct-copy the old to the new. It's wasteful, but we don't want
  3744. // to dig into how much of the in buffer contains valid data.
  3745. //
  3746. *pOutNicInfo = *pInNicInfo;
  3747. //
  3748. // Rest is op-specific
  3749. //
  3750. switch(pOutNicInfo->Hdr.Op)
  3751. {
  3752. case NIC1394_NICINFO_OP_BUSINFO:
  3753. Status = nicFillBusInfo(pAdapter, &pOutNicInfo->BusInfo);
  3754. break;
  3755. case NIC1394_NICINFO_OP_REMOTENODEINFO:
  3756. Status = nicFillRemoteNodeInfo(pAdapter, &pOutNicInfo->RemoteNodeInfo);
  3757. break;
  3758. case NIC1394_NICINFO_OP_CHANNELINFO:
  3759. Status = nicFillChannelInfo(pAdapter, &pOutNicInfo->ChannelInfo);
  3760. break;
  3761. case NIC1394_NICINFO_OP_RESETSTATS:
  3762. Status = nicResetStats (pAdapter, &pOutNicInfo->ResetStats);
  3763. default:
  3764. TRACE( TL_A, TM_Mp, ( " NICINFO.Op (%lu) is unknown.\n",
  3765. pInNicInfo->Hdr.Op
  3766. ));
  3767. break;
  3768. }
  3769. } while (FALSE);
  3770. return Status;
  3771. }
  3772. NDIS_STATUS
  3773. nicResetStats (
  3774. IN PADAPTERCB pAdapter,
  3775. PNIC1394_RESETSTATS pResetStats
  3776. )
  3777. {
  3778. NdisZeroMemory (&pAdapter->AdaptStats.TempStats, sizeof (pAdapter->AdaptStats.TempStats) );
  3779. return NDIS_STATUS_SUCCESS;
  3780. }
  3781. NDIS_STATUS
  3782. nicFillBusInfo(
  3783. IN PADAPTERCB pAdapter,
  3784. IN OUT PNIC1394_BUSINFO pBi
  3785. )
  3786. {
  3787. ULARGE_INTEGER BusMap, ActiveMap;
  3788. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  3789. NIC_SEND_RECV_STATS* pNicStats = NULL;
  3790. PADAPT_STATS pAdaptStats = &pAdapter->AdaptStats;
  3791. //
  3792. // Fill with Dummy data
  3793. //
  3794. pBi->NumBusResets = pAdaptStats->ulNumResetCallbacks;
  3795. pBi->SecondsSinceBusReset = nicGetSystemTime() - pAdaptStats->ulResetTime;
  3796. pBi->Flags = (BCR_TEST_FLAG( pAdapter, BCR_LocalHostIsIRM) == TRUE ) ? NIC1394_BUSINFO_LOCAL_IS_IRM : 0;
  3797. //
  3798. // CHANNEL RELATED INFORMATION
  3799. //
  3800. NdisStatus = nicQueryChannelMap( pAdapter, &BusMap);
  3801. if (NdisStatus == NDIS_STATUS_SUCCESS)
  3802. {
  3803. pBi->Channel.BusMap = BusMap.QuadPart;
  3804. }
  3805. //
  3806. // For now
  3807. //
  3808. ActiveMap.QuadPart = pAdapter->ChannelsAllocatedByLocalHost;
  3809. //
  3810. // First zero out some info
  3811. //
  3812. NdisZeroMemory( &pBi->Channel.SendPktStats, sizeof (pBi->Channel.SendPktStats ));
  3813. NdisZeroMemory( &pBi->Fifo.SendPktStats, sizeof (pBi->Fifo.SendPktStats) ) ;
  3814. //
  3815. // Now go through each Vc and extract the relevant information
  3816. //
  3817. ADAPTER_ACQUIRE_LOCK (pAdapter);
  3818. #define GARBAGE 9999
  3819. pBi->Channel.Bcr = *((PULONG) &pAdapter->BCRData.IRM_BCR);
  3820. pBi->LocalNodeInfo.UniqueID = pAdapter->UniqueId; // This node's 64-bit Unique ID.
  3821. pBi->LocalNodeInfo.BusGeneration = pAdapter->Generation; // 1394 Bus generation ID.
  3822. pBi->LocalNodeInfo.NodeAddress = pAdapter->NodeAddress;
  3823. pBi->LocalNodeInfo.MaxRecvBlockSize = pAdapter->MaxRec;
  3824. pBi->LocalNodeInfo.MaxRecvSpeed = pAdapter->SCode;
  3825. //
  3826. // Fill up Recv Vc Stats
  3827. //
  3828. if (pAdapter->pRecvFIFOVc != NULL)
  3829. {
  3830. PRECVFIFO_VCCB pRecvVc = pAdapter->pRecvFIFOVc;
  3831. pBi->Fifo.Recv_Off_Low = pRecvVc->VcAddressRange.AR_Off_Low;
  3832. pBi->Fifo.Recv_Off_High = pRecvVc ->VcAddressRange.AR_Off_High;
  3833. nicCopyPacketStats(&pBi->Fifo.RecvPktStats
  3834. ,pAdapter->AdaptStats.TempStats.Fifo.ulRecv,
  3835. GARBAGE ,
  3836. GARBAGE ,
  3837. GARBAGE);
  3838. pBi->Fifo.NumFreeRecvBuffers = pRecvVc->NumAllocatedFifos - pRecvVc->NumIndicatedFifos;
  3839. pBi->Fifo.MinFreeRecvBuffers = GARBAGE ; // todo
  3840. }
  3841. //
  3842. // Fifo Send Stats
  3843. //
  3844. pNicStats = &pAdaptStats->TempStats.Fifo;
  3845. nicCopyPacketStats ( &pBi->Fifo.SendPktStats,
  3846. pNicStats->ulSendNicSucess,
  3847. pNicStats->ulSendNicFail,
  3848. pNicStats->ulSendBusSuccess,
  3849. pNicStats->ulSendBusFail );
  3850. nicCopyPacketStats ( &pBi->Fifo.RecvPktStats,
  3851. pNicStats->ulRecv,
  3852. 0,
  3853. 0,
  3854. 0);
  3855. //
  3856. // Channel Send Stats
  3857. //
  3858. pNicStats = &pAdapter->AdaptStats.TempStats.Channel;
  3859. nicCopyPacketStats ( &pBi->Channel.SendPktStats,
  3860. pNicStats->ulSendNicSucess,
  3861. pNicStats->ulSendNicFail,
  3862. pNicStats->ulSendBusSuccess,
  3863. pNicStats->ulSendBusFail );
  3864. //
  3865. // Broadcast channel data - same as channel
  3866. //
  3867. nicCopyPacketStats ( &pBi->Channel.BcSendPktStats,
  3868. pNicStats->ulSendNicSucess,
  3869. pNicStats->ulSendNicFail,
  3870. pNicStats->ulSendBusSuccess,
  3871. pNicStats->ulSendBusFail );
  3872. //
  3873. // Recv Channels
  3874. //
  3875. nicCopyPacketStats ( &pBi->Channel.BcRecvPktStats ,
  3876. pNicStats->ulRecv,
  3877. 0,
  3878. 0,
  3879. 0);
  3880. ADAPTER_RELEASE_LOCK (pAdapter);
  3881. pBi->Channel.ActiveChannelMap= ActiveMap.QuadPart;
  3882. pBi->Fifo.NumOutstandingReassemblies = pAdaptStats->TempStats.ulNumOutstandingReassemblies;
  3883. pBi->Fifo.MaxOutstandingReassemblies =pAdaptStats->TempStats.ulMaxOutstandingReassemblies;
  3884. //pBi->Fifo.NumAbortedReassemblies = ReassemblyCompleted;
  3885. //
  3886. // Information about remote nodes. More information about each of these nodes
  3887. // may be queried using *OP_REMOTE_NODEINFO
  3888. //
  3889. pBi->NumRemoteNodes = pAdaptStats->ulNumRemoteNodes;
  3890. ADAPTER_ACQUIRE_LOCK (pAdapter);
  3891. {
  3892. UINT i = 0;
  3893. PLIST_ENTRY pRemoteEntry = ListNext(&pAdapter->PDOList);
  3894. while (pRemoteEntry != &pAdapter->PDOList)
  3895. {
  3896. PREMOTE_NODE pRemote = CONTAINING_RECORD (pRemoteEntry,
  3897. REMOTE_NODE,
  3898. linkPdo);
  3899. pRemoteEntry = ListNext(pRemoteEntry);
  3900. pBi->RemoteNodeUniqueIDS[i] = pRemote->UniqueId;
  3901. i++;
  3902. }
  3903. }
  3904. ADAPTER_RELEASE_LOCK (pAdapter);
  3905. return NDIS_STATUS_SUCCESS;
  3906. }
  3907. NDIS_STATUS
  3908. nicFillChannelInfo(
  3909. IN PADAPTERCB pAdapter,
  3910. IN OUT PNIC1394_CHANNELINFO pCi
  3911. )
  3912. {
  3913. return NDIS_STATUS_SUCCESS;
  3914. }
  3915. NDIS_STATUS
  3916. nicFillRemoteNodeInfo(
  3917. IN PADAPTERCB pAdapter,
  3918. IN OUT PNIC1394_REMOTENODEINFO pRni
  3919. )
  3920. {
  3921. NDIS_STATUS NdisStatus;
  3922. REMOTE_NODE *pRemoteNode = NULL;
  3923. do
  3924. {
  3925. //
  3926. // First let's find the remote node, based on the unique ID.
  3927. // nicFindRemoteNodeFromAdapter refs pRemoteNode on success.
  3928. //
  3929. NdisStatus = nicFindRemoteNodeFromAdapter(pAdapter,
  3930. NULL, // pPDO OPTIONAL
  3931. pRni->UniqueID,
  3932. &pRemoteNode);
  3933. if (NdisStatus != NDIS_STATUS_SUCCESS)
  3934. {
  3935. pRemoteNode = NULL;
  3936. break;
  3937. }
  3938. NdisStatus = nicQueryRemoteNodeCaps (pAdapter,
  3939. pRemoteNode,
  3940. &pRni->MaxSpeedBetweenNodes,
  3941. &pRni->EffectiveMaxBlockSize,
  3942. &pRni->MaxRec
  3943. );
  3944. REMOTE_NODE_ACQUIRE_LOCK (pRemoteNode);
  3945. pRni->NodeAddress = *(PUSHORT) &pRemoteNode->RemoteAddress;
  3946. if (REMOTE_NODE_ACTIVE (pRemoteNode))
  3947. {
  3948. pRni->Flags = NIC1394_REMOTEINFO_ACTIVE;
  3949. }
  3950. else
  3951. {
  3952. pRni->Flags = NIC1394_REMOTEINFO_UNLOADING; // we assume it's unloading.
  3953. }
  3954. REMOTE_NODE_RELEASE_LOCK (pRemoteNode);
  3955. //
  3956. // Don't support the following yet.
  3957. //
  3958. NdisZeroMemory (&pRni->SendFifoPktStats, sizeof (pRni->SendFifoPktStats) );
  3959. NdisZeroMemory (&pRni->SendFifoPktStats, sizeof (pRni->SendFifoPktStats));
  3960. NdisZeroMemory (&pRni->RecvFifoPktStats, sizeof (pRni->SendFifoPktStats));
  3961. NdisZeroMemory (&pRni->RecvChannelPktStats , sizeof (pRni->SendFifoPktStats));
  3962. } while (FALSE);
  3963. if (pRemoteNode != NULL)
  3964. {
  3965. nicDereferenceRemoteNode(pRemoteNode, "nicFillRemoteNodeInfo");
  3966. }
  3967. return NdisStatus;
  3968. }
  3969. VOID
  3970. nicCopyPacketStats (
  3971. NIC1394_PACKET_STATS* pStats,
  3972. UINT TotNdisPackets, // Total number of NDIS packets sent/indicated
  3973. UINT NdisPacketsFailures,// Number of NDIS packets failed/discarded
  3974. UINT TotBusPackets, // Total number of BUS-level reads/writes
  3975. UINT BusPacketFailures // Number of BUS-level failures(sends)/discards(recv)
  3976. )
  3977. {
  3978. pStats->TotNdisPackets= TotNdisPackets; // Total number of NDIS packets sent/indicated
  3979. pStats->NdisPacketsFailures= NdisPacketsFailures;// Number of NDIS packets failed/discarded
  3980. pStats->TotBusPackets = TotBusPackets; // Total number of BUS-level reads/writes
  3981. pStats->TotBusPackets = BusPacketFailures; // Number of BUS-level failures(sends)/discards(recv)
  3982. }
  3983. VOID
  3984. nicAddPacketStats(
  3985. NIC1394_PACKET_STATS* pStats,
  3986. UINT TotNdisPackets, // Total number of NDIS packets sent/indicated
  3987. UINT NdisPacketsFailures,// Number of NDIS packets failed/discarded
  3988. UINT TotBusPackets, // Total number of BUS-level reads/writes
  3989. UINT BusPacketFailures // Number of BUS-level failures(sends)/discards(recv)
  3990. )
  3991. {
  3992. pStats->TotNdisPackets+= TotNdisPackets; // Total number of NDIS packets sent/indicated
  3993. pStats->NdisPacketsFailures+= NdisPacketsFailures;// Number of NDIS packets failed/discarded
  3994. pStats->TotBusPackets += TotBusPackets; // Total number of BUS-level reads/writes
  3995. pStats->TotBusPackets += BusPacketFailures; // Number of BUS-level failures(sends)/discards(recv)
  3996. }
  3997. VOID
  3998. nicInformProtocolsOfReset(
  3999. IN PADAPTERCB pAdapter
  4000. )
  4001. /*++
  4002. Routine Description:
  4003. Informs protocols of reset. Does an NdisMCoIndicateStatus with a locally allocated structure
  4004. which includes the new Local Node Address and Generation
  4005. Arguments:
  4006. Return Value:
  4007. --*/
  4008. {
  4009. NIC1394_STATUS_BUFFER StatusBuffer;
  4010. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  4011. TRACE( TL_T, TM_Mp, ( "==> nicInformProtocolsOfReset ") );
  4012. do
  4013. {
  4014. NdisZeroMemory (&StatusBuffer, sizeof (StatusBuffer) );
  4015. StatusBuffer.Signature = NIC1394_MEDIA_SPECIFIC;
  4016. StatusBuffer.Event = NIC1394_EVENT_BUS_RESET;
  4017. NdisMCoIndicateStatus(pAdapter->MiniportAdapterHandle,
  4018. NULL,
  4019. NDIS_STATUS_MEDIA_SPECIFIC_INDICATION,
  4020. &StatusBuffer,
  4021. sizeof(StatusBuffer));
  4022. } while (FALSE);
  4023. TRACE( TL_T, TM_Mp, ( "<== nicInformProtocolsOfReset ") );
  4024. }
  4025. VOID
  4026. nicUpdateRemoteNodeCaps(
  4027. PADAPTERCB pAdapter
  4028. )
  4029. /*++
  4030. Update the caps (maxrec, maxspeed-to, max effective buffer size) for all
  4031. nodes that we have connections to.
  4032. --*/
  4033. {
  4034. ULONG i = 0;
  4035. ULONG NumNodes = 0;
  4036. PREMOTE_NODE pRemoteNode = NULL;
  4037. NODE_ADDRESS NodeAddress;
  4038. NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
  4039. for (i=0; i<MAX_NUMBER_NODES; i++)
  4040. {
  4041. UINT SpeedTo;
  4042. UINT EffectiveMaxBufferSize;
  4043. UINT MaxRec;
  4044. if (pAdapter->NodeTable.RemoteNode[i] == NULL)
  4045. {
  4046. continue; // ******************* CONTINUE ****************
  4047. }
  4048. ADAPTER_ACQUIRE_LOCK (pAdapter);
  4049. pRemoteNode = pAdapter->NodeTable.RemoteNode[i];
  4050. // We check again, with the lock held.
  4051. //
  4052. if (pRemoteNode == NULL || !REMOTE_NODE_ACTIVE (pRemoteNode))
  4053. {
  4054. ADAPTER_RELEASE_LOCK (pAdapter);
  4055. continue; // ******************* CONTINUE ****************
  4056. }
  4057. nicReferenceRemoteNode (pRemoteNode, "nicUpdateRemoteNodeCaps ");
  4058. ADAPTER_RELEASE_LOCK (pAdapter);
  4059. // Specifying FALSE (!from cache) below causes pRemoteNode's cached caps
  4060. // to be refreshed.
  4061. //
  4062. NdisStatus = nicQueryRemoteNodeCaps (pAdapter,
  4063. pRemoteNode,
  4064. &SpeedTo,
  4065. &EffectiveMaxBufferSize,
  4066. &MaxRec
  4067. );
  4068. if (NdisStatus != NDIS_STATUS_SUCCESS)
  4069. {
  4070. TRACE( TL_A, TM_Mp, ( "nicUpdateRemoteNodeCaps couldn't update caps fo node %x", pRemoteNode));
  4071. }
  4072. nicDereferenceRemoteNode (pRemoteNode, "nicUpdateRemoteNodeCaps ");
  4073. }
  4074. }
  4075. VOID
  4076. nicQueryInformationWorkItem(
  4077. IN PNDIS_WORK_ITEM pWorkItem,
  4078. IN PVOID Context
  4079. )
  4080. {
  4081. PADAPTERCB pAdapter= (PADAPTERCB) Context;
  4082. PNIC_WORK_ITEM pNicWorkItem = (PNIC_WORK_ITEM) pWorkItem;
  4083. NDIS_STATUS Status;
  4084. Status = nicQueryInformation(
  4085. pAdapter,
  4086. pNicWorkItem->RequestInfo.pVc,
  4087. pNicWorkItem->RequestInfo.pNdisRequest
  4088. );
  4089. //
  4090. // We call at passive, so we should never be pending here.
  4091. //
  4092. ASSERT(Status != NDIS_STATUS_PENDING);
  4093. //
  4094. // Asynchronously complete the work item.
  4095. //
  4096. NdisMCoRequestComplete(
  4097. Status,
  4098. pAdapter->MiniportAdapterHandle,
  4099. pNicWorkItem->RequestInfo.pNdisRequest
  4100. );
  4101. //
  4102. // Deref the work item adapter reference.
  4103. //
  4104. FREE_NONPAGED (pWorkItem);
  4105. NdisInterlockedDecrement(&pAdapter->OutstandingWorkItems);
  4106. nicDereferenceAdapter(pAdapter, "nicQueryInfoWorkItem");
  4107. }
  4108. NDIS_STATUS
  4109. nicInitSerializedStatusStruct(
  4110. PADAPTERCB pAdapter
  4111. )
  4112. /*++
  4113. Routine Description:
  4114. Used to initialize the Send Serialization Struct
  4115. Arguments:
  4116. Return Value:
  4117. --*/
  4118. {
  4119. NdisZeroMemory (&pAdapter->Status, sizeof(pAdapter->Status));
  4120. InitializeListHead(&pAdapter->Status.Queue);
  4121. NdisMInitializeTimer (&pAdapter->Status.Timer,
  4122. pAdapter->MiniportAdapterHandle,
  4123. nicIndicateStatusTimer,
  4124. pAdapter);
  4125. return NDIS_STATUS_SUCCESS;
  4126. }
  4127. VOID
  4128. nicDeInitSerializedStatusStruct(
  4129. PADAPTERCB pAdapter
  4130. )
  4131. /*++
  4132. Routine Description:
  4133. Deinits the Status Init routine
  4134. Arguments:
  4135. Return Value:
  4136. --*/
  4137. {
  4138. }
  4139. VOID
  4140. nicMIndicateStatus(
  4141. IN PADAPTERCB pAdapter ,
  4142. IN NDIS_STATUS GeneralStatus,
  4143. IN PVOID StatusBuffer,
  4144. IN UINT StatusBufferSize
  4145. )
  4146. /*++
  4147. Routine Description:
  4148. This function inserts a packet into the send queue. If there is no timer servicing the queue
  4149. then it queues a timer to dequeue the packet in Global Event's context
  4150. Arguments:
  4151. Self explanatory
  4152. Return Value:
  4153. Success - if inserted into the the queue
  4154. --*/
  4155. {
  4156. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  4157. BOOLEAN fSetTimer = FALSE;
  4158. BOOLEAN fNeedToFreeContext = FALSE;
  4159. PNDIS_STATUS_CONTEXT pContext = NULL;
  4160. if (ADAPTER_TEST_FLAG (pAdapter, fADAPTER_DoStatusIndications) == FALSE)
  4161. {
  4162. return;
  4163. }
  4164. #if QUEUED_PACKETS
  4165. do
  4166. {
  4167. pContext = ALLOC_NONPAGED (sizeof(NDIS_STATUS_CONTEXT ), MTAG_TIMERQ);
  4168. if (pContext == NULL)
  4169. {
  4170. break;
  4171. }
  4172. //
  4173. // Store the pvc in the Miniport Reserved
  4174. //
  4175. pContext->GeneralStatus = GeneralStatus;
  4176. pContext->StatusBuffer = StatusBuffer;
  4177. pContext->StatusBufferSize = StatusBufferSize;
  4178. ADAPTER_ACQUIRE_LOCK (pAdapter);
  4179. //
  4180. // Find out if this thread needs to fire the timer
  4181. //
  4182. if (ADAPTER_TEST_FLAG (pAdapter, fADAPTER_Halting) ||
  4183. ADAPTER_TEST_FLAG (pAdapter, fADAPTER_VDOInactive))
  4184. {
  4185. ADAPTER_RELEASE_LOCK (pAdapter);
  4186. fNeedToFreeContext = TRUE;
  4187. break;
  4188. }
  4189. if (pAdapter->Status.bTimerAlreadySet == FALSE)
  4190. {
  4191. fSetTimer = TRUE;
  4192. pAdapter->Status.bTimerAlreadySet = TRUE;
  4193. }
  4194. InsertTailList(
  4195. &pAdapter->Status.Queue,
  4196. &pContext->Link
  4197. );
  4198. pAdapter->Status.PktsInQueue++;
  4199. nicReferenceAdapter (pAdapter, "nicMIndicateStatus ");
  4200. ADAPTER_RELEASE_LOCK (pAdapter);
  4201. //
  4202. // Now queue the timer
  4203. //
  4204. if (fSetTimer == TRUE)
  4205. {
  4206. PNDIS_MINIPORT_TIMER pTimer;
  4207. //
  4208. // Initialize the timer
  4209. //
  4210. pTimer = &pAdapter->Status.Timer;
  4211. NdisMSetTimer ( pTimer, 0);
  4212. }
  4213. Status = NDIS_STATUS_SUCCESS;
  4214. } while (FALSE);
  4215. #else
  4216. NdisMCoIndicateStatus (pAdapter->MiniportAdapterHandle ,
  4217. NULL,
  4218. GeneralStatus,
  4219. StatusBuffer,
  4220. StatusBufferSize
  4221. );
  4222. #endif
  4223. if (fNeedToFreeContext == TRUE)
  4224. {
  4225. FREE_NONPAGED (pContext);
  4226. }
  4227. }
  4228. VOID
  4229. nicIndicateStatusTimer(
  4230. IN PVOID SystemSpecific1,
  4231. IN PVOID FunctionContext,
  4232. IN PVOID SystemSpecific2,
  4233. IN PVOID SystemSpecific3
  4234. )
  4235. /*++
  4236. Routine Description:
  4237. This function dequeues a packet and invokes the appropriate send handler
  4238. to fire this packet off to the 1394 bus driver
  4239. Arguments:
  4240. Function context - Adapter structure, which has the Packet queue.
  4241. Each packet has the VC embedded in it.
  4242. Return Value:
  4243. --*/
  4244. {
  4245. PADAPTERCB pAdapter = (PADAPTERCB) FunctionContext;
  4246. BOOLEAN fVcCorrupted = FALSE;
  4247. TRACE( TL_T, TM_Recv, ( "==>nicIndicateStatusTimer Context %x", FunctionContext));
  4248. ADAPTER_ACQUIRE_LOCK (pAdapter);
  4249. //
  4250. // Empty the Queue indicating as many packets as possible
  4251. //
  4252. while (IsListEmpty(&pAdapter->Status.Queue)==FALSE)
  4253. {
  4254. PNDIS_STATUS_CONTEXT pStatus;
  4255. PLIST_ENTRY pLink;
  4256. NDIS_STATUS NdisStatus;
  4257. pAdapter->Status.PktsInQueue--;
  4258. pLink = RemoveHeadList(&pAdapter->Status.Queue);
  4259. ADAPTER_RELEASE_LOCK (pAdapter);
  4260. //
  4261. // Extract the send context
  4262. //
  4263. pStatus = CONTAINING_RECORD(
  4264. pLink,
  4265. NDIS_STATUS_CONTEXT,
  4266. Link);
  4267. NdisMCoIndicateStatus (pAdapter->MiniportAdapterHandle,
  4268. NULL,
  4269. pStatus->GeneralStatus,
  4270. pStatus->StatusBuffer,
  4271. pStatus->StatusBufferSize
  4272. ) ;
  4273. FREE_NONPAGED (pStatus);
  4274. ADAPTER_ACQUIRE_LOCK (pAdapter);
  4275. nicDereferenceAdapter(pAdapter, "nicIndicateStatusTimer");
  4276. }
  4277. //
  4278. // clear the flag
  4279. //
  4280. ASSERT (pAdapter->Status.PktsInQueue==0);
  4281. ASSERT (IsListEmpty(&pAdapter->Status.Queue));
  4282. pAdapter->Status.bTimerAlreadySet = FALSE;
  4283. ADAPTER_RELEASE_LOCK (pAdapter);
  4284. TRACE( TL_T, TM_Recv, ( "<==nicIndicateStatusTimer"));
  4285. }
  4286. NDIS_STATUS
  4287. nicAllocateLoopbackPacketPool (
  4288. IN PADAPTERCB pAdapter
  4289. )
  4290. /*++
  4291. Routine Description:
  4292. allocate a packet and buffer pool for loopback packet
  4293. Arguments:
  4294. Return Value:
  4295. --*/
  4296. {
  4297. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  4298. do
  4299. {
  4300. //
  4301. // Allocate a packet pool to indicate loopback receives from.
  4302. //
  4303. NdisAllocatePacketPoolEx(
  4304. &NdisStatus,
  4305. &pAdapter->LoopbackPool.Handle,
  4306. 32,
  4307. 32,
  4308. sizeof(LOOPBACK_RSVD)
  4309. );
  4310. if (NdisStatus != NDIS_STATUS_SUCCESS)
  4311. {
  4312. break;
  4313. }
  4314. pAdapter->LoopbackPool.AllocatedPackets = 0;
  4315. KeInitializeSpinLock (&pAdapter->LoopbackPool.Lock);
  4316. NdisAllocateBufferPool(
  4317. &NdisStatus,
  4318. &pAdapter->LoopbackBufferPool,
  4319. 64
  4320. );
  4321. if (NdisStatus != NDIS_STATUS_SUCCESS)
  4322. {
  4323. break;
  4324. }
  4325. } while (FALSE);
  4326. return NdisStatus;
  4327. }
  4328. VOID
  4329. nicFreeLoopbackPacketPool (
  4330. IN PADAPTERCB pAdapter
  4331. )
  4332. /*++
  4333. Routine Description:
  4334. free the packet and buffer pool for loopback packet
  4335. Arguments:
  4336. Return Value:
  4337. --*/
  4338. {
  4339. if (pAdapter->LoopbackPool.Handle != NULL)
  4340. {
  4341. nicFreePacketPool (&pAdapter->LoopbackPool);
  4342. }
  4343. if (pAdapter->LoopbackBufferPool != NULL)
  4344. {
  4345. NdisFreeBufferPool(pAdapter->LoopbackBufferPool);
  4346. pAdapter->LoopbackBufferPool = NULL;
  4347. }
  4348. }
  4349. VOID
  4350. nicLoopbackPacket(
  4351. IN VCCB* pVc,
  4352. IN PNDIS_PACKET pPacket
  4353. )
  4354. /*++
  4355. Routine Description:
  4356. Allocate a packet and indicate it up on the vc
  4357. Arguments:
  4358. Return Value:
  4359. --*/
  4360. {
  4361. NDIS_STATUS Status;
  4362. PNDIS_BUFFER pFirstBuffer;
  4363. ULONG TotalLength;
  4364. PNDIS_PACKET pLoopbackPacket;
  4365. PUCHAR pCopyBuf;
  4366. PNDIS_BUFFER pLoopbackBuffer;
  4367. ULONG BytesCopied;
  4368. ADAPTERCB* pAdapter;
  4369. PLOOPBACK_RSVD pLoopbackRsvd;
  4370. pAdapter = pVc->Hdr.pAF->pAdapter;
  4371. TRACE( TL_T, TM_Recv, ("NIC1394: loopback pkt %p on VC %p, type %d\n",
  4372. pPacket, pVc, pVc->Hdr.VcType));
  4373. pLoopbackPacket = NULL;
  4374. pLoopbackBuffer = NULL;
  4375. pCopyBuf = NULL;
  4376. do
  4377. {
  4378. nicAllocatePacket(&Status, &pLoopbackPacket, &pAdapter->LoopbackPool);
  4379. if (Status != NDIS_STATUS_SUCCESS)
  4380. {
  4381. break;
  4382. }
  4383. NdisQueryPacket(
  4384. pPacket,
  4385. NULL,
  4386. NULL,
  4387. &pFirstBuffer,
  4388. &TotalLength
  4389. );
  4390. pCopyBuf = ALLOC_NONPAGED (TotalLength, MTAG_RBUF);
  4391. if (pCopyBuf == NULL)
  4392. {
  4393. Status = NDIS_STATUS_RESOURCES;
  4394. break;
  4395. }
  4396. NdisAllocateBuffer(
  4397. &Status,
  4398. &pLoopbackBuffer,
  4399. pAdapter->LoopbackBufferPool,
  4400. pCopyBuf,
  4401. TotalLength
  4402. );
  4403. if (Status != NDIS_STATUS_SUCCESS)
  4404. {
  4405. break;
  4406. }
  4407. pLoopbackBuffer->Next = NULL;
  4408. NdisChainBufferAtFront(pLoopbackPacket, pLoopbackBuffer);
  4409. NdisCopyFromPacketToPacket(
  4410. pLoopbackPacket,
  4411. 0,
  4412. TotalLength,
  4413. pPacket,
  4414. 0,
  4415. &BytesCopied
  4416. );
  4417. //
  4418. // Make sure we can reclaim the packet after the receive indicate
  4419. // returns.
  4420. //
  4421. // If the status is made async, then the loopback Tag will
  4422. // break in the return packet handler
  4423. //
  4424. NDIS_SET_PACKET_STATUS(pLoopbackPacket, NDIS_STATUS_RESOURCES);
  4425. // Set the Loopback Tag.
  4426. pLoopbackRsvd = (PLOOPBACK_RSVD) pLoopbackPacket->ProtocolReserved;
  4427. pLoopbackRsvd->LoopbackTag = NIC_LOOPBACK_TAG;
  4428. NdisMCoIndicateReceivePacket(
  4429. pVc->Hdr.NdisVcHandle,
  4430. &pLoopbackPacket,
  4431. 1);
  4432. NdisFreeBuffer(pLoopbackBuffer);
  4433. nicFreePacket(pLoopbackPacket, &pAdapter->LoopbackPool);
  4434. FREE_NONPAGED(pCopyBuf);
  4435. }
  4436. while (FALSE);
  4437. if (Status != NDIS_STATUS_SUCCESS)
  4438. {
  4439. if (pCopyBuf)
  4440. {
  4441. FREE_NONPAGED(pCopyBuf);
  4442. }
  4443. if (pLoopbackBuffer)
  4444. {
  4445. NdisFreeBuffer(pLoopbackBuffer);
  4446. }
  4447. if (pLoopbackPacket)
  4448. {
  4449. nicFreePacket(pLoopbackPacket, &pAdapter->LoopbackPool);
  4450. }
  4451. }
  4452. }
  4453. VOID
  4454. nicWriteErrorLog (
  4455. IN PADAPTERCB pAdapter,
  4456. IN NDIS_ERROR_CODE ErrorCode,
  4457. IN ULONG ErrorValue
  4458. )
  4459. {
  4460. NdisWriteErrorLogEntry( pAdapter->MiniportAdapterHandle,
  4461. ErrorCode,
  4462. 1,
  4463. ErrorValue
  4464. );
  4465. }
  4466. VOID
  4467. nicUpdateRemoteNodeTable (
  4468. IN PADAPTERCB pAdapter
  4469. )
  4470. // Function Description:
  4471. //
  4472. // Go through all the remote nodes in the system and query its Node Address
  4473. // Make two tables, one contains all the remote nodes that have been refed. The
  4474. // other contains the Nodes according to their Node Addresses(TempNodeTable).
  4475. //
  4476. // Simple algorithm:
  4477. // Take a snapshot of the current RemoteNodes List into RefNodeTable
  4478. // Ref all the remote nodes in a local structure.
  4479. // Get their new remote node addresses (TempNodeTable)
  4480. // Copy the TempNodeTable into the Adapter Structure - it is now official
  4481. // Update the address in the remote node themselves
  4482. // Dereference the Ref made above
  4483. //
  4484. // Arguments
  4485. //
  4486. //
  4487. //
  4488. // Return Value:
  4489. //
  4490. //
  4491. {
  4492. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  4493. PNODE_TABLE pNodeTable = &pAdapter->NodeTable;
  4494. PLIST_ENTRY pRemoteNodeList;
  4495. NODE_ADDRESS RemoteNodeAddress;
  4496. NODE_TABLE RefNodeTable;
  4497. NODE_TABLE TempNodeTable;
  4498. ULONG NumRemoteNodes = 0;
  4499. ULONG MaxNumRefNodeTable = 0;
  4500. STORE_CURRENT_IRQL;
  4501. TRACE( TL_T, TM_Mp, ( " ==>nicUpdateRemoteNodeTable pAdapter %x, TempNodeTable%x", pAdapter , &TempNodeTable) );
  4502. NdisZeroMemory (&TempNodeTable, sizeof (NODE_TABLE) );
  4503. NdisZeroMemory (&RefNodeTable, sizeof(RefNodeTable));
  4504. NumRemoteNodes = 0;
  4505. ADAPTER_ACQUIRE_LOCK (pAdapter);
  4506. pRemoteNodeList = ListNext (&pAdapter->PDOList);
  4507. //
  4508. // Walk through the entire list and make a copy of the current list.
  4509. // Reference each remote node on the list.
  4510. // The lock will ensure that the list is valid
  4511. //
  4512. while (pRemoteNodeList != &pAdapter->PDOList)
  4513. {
  4514. PREMOTE_NODE pRemoteNode;
  4515. pRemoteNode = CONTAINING_RECORD (pRemoteNodeList, REMOTE_NODE, linkPdo);
  4516. //
  4517. // Reference the remote node. This guarantees that the remote node will
  4518. // remain valid and in the list until it is dereferenced (deref happens below)
  4519. //
  4520. nicReferenceRemoteNode (pRemoteNode, "nicUpdateRemoteNodeTable ");
  4521. RefNodeTable.RemoteNode[MaxNumRefNodeTable] = pRemoteNode;
  4522. //
  4523. // Increment the Cursors and go to the next RemoteNode
  4524. //
  4525. pRemoteNodeList = ListNext (pRemoteNodeList);
  4526. MaxNumRefNodeTable++;
  4527. } //while (pRemoteNodeList != &pAdapter->PDOList)
  4528. ADAPTER_RELEASE_LOCK (pAdapter);
  4529. //
  4530. // Without the lock, call into the Bus Driver to get the remote address
  4531. // of each remote node
  4532. //
  4533. {
  4534. USHORT RefIndex;
  4535. PREMOTE_NODE pCurrRemoteNode;
  4536. //
  4537. // Initialize the structures
  4538. //
  4539. pCurrRemoteNode = RefNodeTable.RemoteNode[0];
  4540. RefIndex =0;
  4541. while (pCurrRemoteNode != NULL)
  4542. {
  4543. // Get the Node Address of the current Remote Node
  4544. //
  4545. NdisStatus = nicGet1394AddressOfRemoteNode (pCurrRemoteNode,
  4546. &RemoteNodeAddress,
  4547. 0);
  4548. if (NdisStatus == NDIS_STATUS_SUCCESS)
  4549. {
  4550. //
  4551. // Fill in the Temp Remote Node Table
  4552. //
  4553. PREMOTE_NODE *ppRemoteNode;
  4554. ppRemoteNode = &TempNodeTable.RemoteNode[RemoteNodeAddress.NA_Node_Number];
  4555. if (*ppRemoteNode == NULL)
  4556. {
  4557. //
  4558. // Update the value in the table
  4559. //
  4560. *ppRemoteNode = pCurrRemoteNode;
  4561. NumRemoteNodes ++;
  4562. }
  4563. }
  4564. // Move to the next node in our local RefNodeTable
  4565. //
  4566. RefIndex++;
  4567. pCurrRemoteNode = RefNodeTable.RemoteNode[RefIndex];
  4568. }
  4569. }
  4570. ADAPTER_ACQUIRE_LOCK(pAdapter)
  4571. //
  4572. // Use the results of our queries to update our internal structures
  4573. // Regardless of success or failure, copy the temp node table over
  4574. // into the adapter
  4575. //
  4576. NdisMoveMemory (&pAdapter->NodeTable, &TempNodeTable, sizeof (NODE_TABLE) );
  4577. pAdapter->NumRemoteNodes = NumRemoteNodes;
  4578. //
  4579. // Update the node address within each of these remote nodes
  4580. //
  4581. {
  4582. ULONG NumUpdated = 0;
  4583. USHORT i=0;
  4584. //
  4585. // Update the Remote Node structures with their new Node Addresses
  4586. //
  4587. while (NumUpdated != NumRemoteNodes)
  4588. {
  4589. if (i >= (sizeof(TempNodeTable.RemoteNode)/sizeof(TempNodeTable.RemoteNode[0])))
  4590. {
  4591. // We've gone past the end of the array. Should never do that.
  4592. //
  4593. ASSERT(!"Walked off the end of the NodeTable");
  4594. break;
  4595. }
  4596. if (TempNodeTable.RemoteNode[i] != NULL)
  4597. {
  4598. TempNodeTable.RemoteNode[i]->RemoteAddress.NA_Node_Number = i;
  4599. NumUpdated ++;
  4600. }
  4601. i++; // Use i to check if we have walked off the end of the table
  4602. TRACE( TL_V, TM_Mp, ( " UpdatingRemoteNodeAddresses NumUpdated %x, i %x, NumRemoteNodes %x",
  4603. NumUpdated, i, NumRemoteNodes) );
  4604. } // while (TRUE)
  4605. }
  4606. //
  4607. // We're done, Now Dereference the Remote Node References Made above
  4608. //
  4609. {
  4610. USHORT RefIndex=0;
  4611. PREMOTE_NODE pCurrRemoteNode;
  4612. //
  4613. // Initialize the structures
  4614. //
  4615. pCurrRemoteNode = RefNodeTable.RemoteNode[0];
  4616. RefIndex =0;
  4617. while (pCurrRemoteNode != NULL)
  4618. {
  4619. nicDereferenceRemoteNode(pCurrRemoteNode, "nicUpdateRemoteNodeTable");
  4620. RefIndex++;
  4621. pCurrRemoteNode = RefNodeTable.RemoteNode[RefIndex];
  4622. }
  4623. }
  4624. ADAPTER_RELEASE_LOCK (pAdapter);
  4625. TRACE( TL_T, TM_Mp, ( "<== nicUpdateRemoteNodeTable pAdapter %x, NumRemoteNodes %x", pAdapter, NumRemoteNodes ) );
  4626. MATCH_IRQL;
  4627. }
  4628. VOID
  4629. nicRemoveRemoteNodeFromNodeTable(
  4630. IN PNODE_TABLE pNodeTable,
  4631. IN PREMOTE_NODE pRemoteNode
  4632. )
  4633. {
  4634. //
  4635. // This function assumes that the adapter lock is held.
  4636. //
  4637. PPREMOTE_NODE ppRemoteNode = NULL;
  4638. //
  4639. // find the remote node and delete it from the node table.
  4640. //
  4641. //
  4642. // The RemoteNode is probably already in the correct place in the Node Table. We'll look there first
  4643. //
  4644. ppRemoteNode = &pNodeTable->RemoteNode[pRemoteNode->RemoteAddress.NA_Node_Number] ;
  4645. if (*ppRemoteNode != pRemoteNode)
  4646. {
  4647. //
  4648. //We did not find the remote node, now we need to go through all the entries and see
  4649. // if the remote node is there
  4650. //
  4651. UINT i =0;
  4652. while (i<MAX_NUMBER_NODES)
  4653. {
  4654. ppRemoteNode = &pNodeTable->RemoteNode[i];
  4655. if (*ppRemoteNode == pRemoteNode)
  4656. {
  4657. //
  4658. // we have found the remote node in the node table-- remove it
  4659. //
  4660. break;
  4661. }
  4662. i++; // try the next node
  4663. } // while ()
  4664. }
  4665. //
  4666. // if we were able to find the remote node either by the node number or through our iterative search
  4667. // then remove it from the Node Table
  4668. //
  4669. if (*ppRemoteNode == pRemoteNode)
  4670. {
  4671. *ppRemoteNode = NULL;
  4672. }
  4673. }
  4674. VOID
  4675. nicVerifyEuidTopology(
  4676. IN PADAPTERCB pAdapter,
  4677. IN PEUID_TOPOLOGY pEuidMap
  4678. )
  4679. /*++
  4680. Routine Description:
  4681. Update THe node address of each remote node and then fills up the euid Map structre
  4682. Arguments:
  4683. Return Value:
  4684. --*/
  4685. {
  4686. EUID_TOPOLOGY EuidTopology;
  4687. PLIST_ENTRY pRemoteNodeList;
  4688. PREMOTE_NODE pRemoteNode = NULL;
  4689. //
  4690. // Requery each remote node for its latest HW address
  4691. //
  4692. nicUpdateRemoteNodeTable (pAdapter);
  4693. //
  4694. // Recreate the list and verify that the topology has not changed from under us.
  4695. //
  4696. NdisZeroMemory (pEuidMap, sizeof(*pEuidMap));
  4697. ADAPTER_ACQUIRE_LOCK(pAdapter);
  4698. pRemoteNodeList = ListNext (&pAdapter->PDOList);
  4699. //
  4700. // Walk through the entire list and fire of a request for each RemoteNode
  4701. // The lock will ensure that the list is valid
  4702. //
  4703. while (pRemoteNodeList != &pAdapter->PDOList)
  4704. {
  4705. USHORT NodeNumber;
  4706. pEuidMap->NumberOfRemoteNodes++;
  4707. pRemoteNode = CONTAINING_RECORD (pRemoteNodeList, REMOTE_NODE, linkPdo);
  4708. pRemoteNodeList = ListNext (pRemoteNodeList);
  4709. NodeNumber = pRemoteNode->RemoteAddress.NA_Node_Number;
  4710. pEuidMap->Node[NodeNumber].Euid = pRemoteNode->UniqueId;
  4711. pEuidMap->Node[NodeNumber].ENetAddress = pRemoteNode->ENetAddress;
  4712. } //while (pRemoteNodeList != &pAdapter->PDOList)
  4713. ADAPTER_RELEASE_LOCK (pAdapter);
  4714. }
  4715. nicVerifyEuidMapWorkItem (
  4716. NDIS_WORK_ITEM* pWorkItem,
  4717. IN PVOID Context
  4718. )
  4719. /*++
  4720. Routine Description:
  4721. This routine is a workitem routine.
  4722. It is called whenever we are asked to report back our Mapping and is always
  4723. called in the context of the miniport getting a request from arp1394.sys.
  4724. Arguments:
  4725. pAdapter Local host
  4726. Return Value:
  4727. --*/
  4728. {
  4729. PNIC_WORK_ITEM pNicWorkItem = (PNIC_WORK_ITEM )pWorkItem;
  4730. PNDIS_REQUEST pRequest = pNicWorkItem->RequestInfo.pNdisRequest;
  4731. PADAPTERCB pAdapter = (PADAPTERCB)Context;
  4732. PEUID_TOPOLOGY pEuidMap = (PEUID_TOPOLOGY) pRequest->DATA.QUERY_INFORMATION.InformationBuffer;
  4733. //
  4734. // Verify the contents of the Euid Map
  4735. //
  4736. nicVerifyEuidTopology(pAdapter,pEuidMap);
  4737. //
  4738. // As we atleast have the old data (before verification),
  4739. // we should always succeed the request
  4740. //
  4741. NdisMCoRequestComplete(NDIS_STATUS_SUCCESS,
  4742. pAdapter->MiniportAdapterHandle,
  4743. pRequest);
  4744. FREE_NONPAGED (pNicWorkItem);
  4745. NdisInterlockedDecrement(&pAdapter->OutstandingWorkItems);
  4746. }
  4747. VOID
  4748. nicQueryEuidNodeMacMap (
  4749. IN PADAPTERCB pAdapter,
  4750. IN PNDIS_REQUEST pRequest
  4751. )
  4752. /*++
  4753. Routine Description:
  4754. Goes through all the remote nodes and extracts their Euid, Node Number and Mac
  4755. address.
  4756. This function first tries to query each remote node to get
  4757. its latest address either via by directly asking the remote node or thorough a work item.
  4758. If that fails, then it takes the last known good values and reports it to the Arp module.
  4759. Arguments:
  4760. Return Value:
  4761. --*/
  4762. {
  4763. PLIST_ENTRY pRemoteNodeList;
  4764. PREMOTE_NODE pRemoteNode;
  4765. NDIS_STATUS Status = NDIS_STATUS_FAILURE;
  4766. PEUID_TOPOLOGY pEuidMap = (PEUID_TOPOLOGY) pRequest->DATA.QUERY_INFORMATION.InformationBuffer;
  4767. PNIC_WORK_ITEM pUpdateTableWorkItem = NULL;
  4768. NdisZeroMemory (pEuidMap, sizeof (*pEuidMap));
  4769. Status = NDIS_STATUS_SUCCESS;
  4770. do
  4771. {
  4772. if (KeGetCurrentIrql() == PASSIVE_LEVEL)
  4773. {
  4774. //
  4775. // This thread queries and completes the request
  4776. //
  4777. nicVerifyEuidTopology(pAdapter, pEuidMap);
  4778. break;
  4779. }
  4780. //
  4781. // We need to update the generation count
  4782. //
  4783. pUpdateTableWorkItem = ALLOC_NONPAGED (sizeof(NIC_WORK_ITEM), MTAG_WORKITEM);
  4784. if (pUpdateTableWorkItem !=NULL)
  4785. {
  4786. //
  4787. // Set the Workitem
  4788. //
  4789. NdisInitializeWorkItem ( &pUpdateTableWorkItem->NdisWorkItem,
  4790. (NDIS_PROC)nicVerifyEuidMapWorkItem,
  4791. (PVOID)pAdapter );
  4792. pUpdateTableWorkItem->RequestInfo.pNdisRequest = pRequest;
  4793. NdisInterlockedIncrement(&pAdapter->OutstandingWorkItems);
  4794. NdisScheduleWorkItem (&pUpdateTableWorkItem->NdisWorkItem);
  4795. //
  4796. // Only code path that pends the request -because of the workitem
  4797. //
  4798. Status = NDIS_STATUS_PENDING;
  4799. }
  4800. else
  4801. {
  4802. //
  4803. // Allocation failure - We report the results without verifying them.
  4804. //
  4805. ADAPTER_ACQUIRE_LOCK(pAdapter);
  4806. pRemoteNodeList = ListNext (&pAdapter->PDOList);
  4807. //
  4808. // Walk through the entire list and fire of a request for each RemoteNode
  4809. // The lock will ensure that the list is valid
  4810. //
  4811. while (pRemoteNodeList != &pAdapter->PDOList)
  4812. {
  4813. USHORT NodeNumber;
  4814. pEuidMap->NumberOfRemoteNodes++;
  4815. pRemoteNode = CONTAINING_RECORD (pRemoteNodeList, REMOTE_NODE, linkPdo);
  4816. pRemoteNodeList = ListNext (pRemoteNodeList);
  4817. NodeNumber = pRemoteNode->RemoteAddress.NA_Node_Number;
  4818. pEuidMap->Node[NodeNumber].Euid = pRemoteNode->UniqueId;
  4819. pEuidMap->Node[NodeNumber].ENetAddress = pRemoteNode->ENetAddress;
  4820. } //while (pRemoteNodeList != &pAdapter->PDOList)
  4821. ADAPTER_RELEASE_LOCK (pAdapter);
  4822. //
  4823. // This thread completes the request with possibly stale data.
  4824. //
  4825. break;
  4826. }
  4827. }while (FALSE);
  4828. if (NDIS_STATUS_PENDING != Status)
  4829. {
  4830. NdisMCoRequestComplete(Status,
  4831. pAdapter->MiniportAdapterHandle,
  4832. pRequest);
  4833. }
  4834. }
  4835. NDIS_STATUS
  4836. MPSetPower (
  4837. IN PADAPTERCB pAdapter,
  4838. IN NET_DEVICE_POWER_STATE DeviceState
  4839. )
  4840. /*++
  4841. Routine Description:
  4842. if PowerState is LowPower, then we
  4843. 1) there are no outstanding VCs or AFs open in the miniport
  4844. 2) free the Broadcast Channel Register,
  4845. If the PowerState is On, then
  4846. 1) we reallocate the BroadcastChannel Register
  4847. 2) if we are in bridge mode, Start the Arp module
  4848. Arguments:
  4849. Return Value:
  4850. --*/
  4851. {
  4852. NDIS_STATUS NdisStatus = NDIS_STATUS_FAILURE;
  4853. switch (DeviceState)
  4854. {
  4855. case NetDeviceStateD0:
  4856. {
  4857. //
  4858. // Initialize the BCM so it is ready to handle Resets
  4859. //
  4860. ADAPTER_CLEAR_FLAG(pAdapter, fADAPTER_LowPowerState);
  4861. NdisStatus = nicInitializeBroadcastChannelRegister (pAdapter);
  4862. if (NdisStatus != NDIS_STATUS_SUCCESS)
  4863. {
  4864. nicFreeBroadcastChannelRegister(pAdapter);
  4865. break;
  4866. }
  4867. ASSERT (NdisStatus == NDIS_STATUS_SUCCESS);
  4868. nicScheduleBCMWorkItem (pAdapter);
  4869. //
  4870. // If we are in bridge mode, then start the arp module
  4871. //
  4872. if (ADAPTER_TEST_FLAG (pAdapter, fADAPTER_BridgeMode) == TRUE)
  4873. {
  4874. nicQueueRequestToArp(pAdapter, BindArp, NULL);
  4875. }
  4876. //
  4877. // Re-initialize the Reassembly Timer
  4878. //
  4879. nicInitSerializedReassemblyStruct(pAdapter); // cannot fail
  4880. NdisStatus = NDIS_STATUS_SUCCESS;
  4881. }
  4882. break;
  4883. case NetDeviceStateD1:
  4884. case NetDeviceStateD2:
  4885. case NetDeviceStateD3:
  4886. {
  4887. //
  4888. // Free the Broadcast Channel Register
  4889. //
  4890. nicFreeBroadcastChannelRegister(pAdapter);
  4891. //
  4892. // Wait for the Free to complete.
  4893. //
  4894. NdisWaitEvent (&pAdapter->BCRData.BCRFreeAddressRange.NdisEvent,0);
  4895. NdisResetEvent (&pAdapter->BCRData.BCRFreeAddressRange.NdisEvent);
  4896. ADAPTER_SET_FLAG(pAdapter, fADAPTER_LowPowerState);
  4897. //
  4898. // ReStart any pending broadcast channel make calls
  4899. //
  4900. pAdapter->BCRData.MakeCallWaitEvent.EventCode = nic1394EventCode_FreedAddressRange;
  4901. NdisSetEvent (&pAdapter->BCRData.MakeCallWaitEvent.NdisEvent);
  4902. //
  4903. // Wait for Outstanding WorItems and timers
  4904. //
  4905. nicDeInitSerializedReassmblyStruct(pAdapter);
  4906. while (pAdapter->OutstandingWorkItems != 0)
  4907. {
  4908. NdisMSleep (10000);
  4909. }
  4910. NdisStatus = NDIS_STATUS_SUCCESS;
  4911. }
  4912. break;
  4913. default:
  4914. {
  4915. ASSERT (0);
  4916. break;
  4917. }
  4918. }
  4919. ASSERT (NDIS_STATUS_SUCCESS == NdisStatus);
  4920. pAdapter->PowerState = DeviceState;
  4921. return NdisStatus;
  4922. }