Leaked source code of windows server 2003
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.

1027 lines
30 KiB

  1. /*++
  2. Copyright (c) 1992-2001 Microsoft Corporation
  3. Module Name:
  4. mux.h
  5. Abstract:
  6. Data structures, defines and function prototypes for the MUX driver.
  7. Environment:
  8. Kernel mode only.
  9. Revision History:
  10. --*/
  11. #ifdef NDIS51_MINIPORT
  12. #define MUX_MAJOR_NDIS_VERSION 5
  13. #define MUX_MINOR_NDIS_VERSION 1
  14. #else
  15. #define MUX_MAJOR_NDIS_VERSION 4
  16. #define MUX_MINOR_NDIS_VERSION 0
  17. #endif
  18. #ifdef NDIS51
  19. #define MUX_PROT_MAJOR_NDIS_VERSION 5
  20. #define MUX_PROT_MINOR_NDIS_VERSION 0
  21. #else
  22. #define MUX_PROT_MAJOR_NDIS_VERSION 4
  23. #define MUX_PROT_MINOR_NDIS_VERSION 0
  24. #endif
  25. #define TAG 'SxuM'
  26. #define WAIT_INFINITE 0
  27. #if DBG
  28. //
  29. // Debug levels: lower values indicate higher urgency
  30. //
  31. #define MUX_EXTRA_LOUD 20
  32. #define MUX_VERY_LOUD 10
  33. #define MUX_LOUD 8
  34. #define MUX_INFO 6
  35. #define MUX_WARN 4
  36. #define MUX_ERROR 2
  37. #define MUX_FATAL 0
  38. extern INT muxDebugLevel;
  39. #define DBGPRINT(lev, Fmt) \
  40. { \
  41. if ((lev) <= muxDebugLevel) \
  42. { \
  43. DbgPrint("MUX-IM: "); \
  44. DbgPrint Fmt; \
  45. } \
  46. }
  47. #else
  48. #define DBGPRINT(lev, Fmt)
  49. #endif //DBG
  50. #define ETH_IS_LOCALLY_ADMINISTERED(Address) \
  51. (BOOLEAN)(((PUCHAR)(Address))[0] & ((UCHAR)0x02))
  52. // forward declarations
  53. typedef struct _ADAPT ADAPT, *PADAPT;
  54. typedef struct _VELAN VELAN, *PVELAN;
  55. typedef struct _MUX_NDIS_REQUEST MUX_NDIS_REQUEST, *PMUX_NDIS_REQUEST;
  56. typedef
  57. VOID
  58. (*PMUX_REQ_COMPLETE_HANDLER) (
  59. IN PADAPT pAdapt,
  60. IN struct _MUX_NDIS_REQUEST * pMuxRequest,
  61. IN NDIS_STATUS Status
  62. );
  63. // This OID specifies the NDIS version in use by the
  64. // virtual miniport driver. The high byte is the major version.
  65. // The low byte is the minor version.
  66. #define VELAN_DRIVER_VERSION ((MUX_MAJOR_NDIS_VERSION << 8) + \
  67. (MUX_MINOR_NDIS_VERSION))
  68. // media type, we use ethernet, change if necessary
  69. #define VELAN_MEDIA_TYPE NdisMedium802_3
  70. // change to your company name instead of using Microsoft
  71. #define VELAN_VENDOR_DESC "Microsoft"
  72. // Highest byte is the NIC byte plus three vendor bytes, they are normally
  73. // obtained from the NIC
  74. #define VELAN_VENDOR_ID 0x00FFFFFF
  75. #define VELAN_MAX_MCAST_LIST 32
  76. #define VELAN_MAX_SEND_PKTS 5
  77. #define ETH_MAX_PACKET_SIZE 1514
  78. #define ETH_MIN_PACKET_SIZE 60
  79. #define ETH_HEADER_SIZE 14
  80. #define VELAN_SUPPORTED_FILTERS ( \
  81. NDIS_PACKET_TYPE_DIRECTED | \
  82. NDIS_PACKET_TYPE_MULTICAST | \
  83. NDIS_PACKET_TYPE_BROADCAST | \
  84. NDIS_PACKET_TYPE_PROMISCUOUS | \
  85. NDIS_PACKET_TYPE_ALL_MULTICAST)
  86. #define MUX_ADAPTER_PACKET_FILTER \
  87. NDIS_PACKET_TYPE_PROMISCUOUS
  88. //
  89. // Define flag bits we set on send packets to prevent
  90. // loopback from occurring on the lower binding.
  91. //
  92. #ifdef NDIS51
  93. #define MUX_SEND_PACKET_FLAGS NDIS_FLAGS_DONT_LOOPBACK
  94. #else
  95. #define NDIS_FLAGS_SKIP_LOOPBACK_WIN2K 0x400
  96. #define MUX_SEND_PACKET_FLAGS (NDIS_FLAGS_DONT_LOOPBACK | \
  97. NDIS_FLAGS_SKIP_LOOPBACK_WIN2K)
  98. #endif
  99. #define MIN_PACKET_POOL_SIZE 255
  100. #define MAX_PACKET_POOL_SIZE 4096
  101. typedef UCHAR MUX_MAC_ADDRESS[6];
  102. //
  103. // Our context stored in packets sent down to the
  104. // lower binding. Note that this sample driver only forwards
  105. // sends down; it does not originate sends itself.
  106. // These packets are allocated from the SendPacketPool.
  107. //
  108. typedef struct _MUX_SEND_RSVD
  109. {
  110. PVELAN pVElan; // originating ELAN
  111. PNDIS_PACKET pOriginalPacket; // original packet
  112. } MUX_SEND_RSVD, *PMUX_SEND_RSVD;
  113. #define MUX_RSVD_FROM_SEND_PACKET(_pPkt) \
  114. ((PMUX_SEND_RSVD)(_pPkt)->ProtocolReserved)
  115. //
  116. // Our context stored in each packet forwarded up to an
  117. // ELAN from a lower binding. The original packet refers to
  118. // a packet indicated up to us that should be returned via
  119. // NdisReturnPackets when our packet is returned to us. This
  120. // is set to NULL there isn't such a packet.
  121. // These packets are allocated from the RecvPacketPool.
  122. //
  123. typedef struct _MUX_RECV_RSVD
  124. {
  125. PNDIS_PACKET pOriginalPacket;
  126. } MUX_RECV_RSVD, *PMUX_RECV_RSVD;
  127. #define MUX_RSVD_FROM_RECV_PACKET(_pPkt) \
  128. ((PMUX_RECV_RSVD)(_pPkt)->MiniportReserved)
  129. //
  130. // Make sure we don't attempt to use more than the allowed
  131. // room in MiniportReserved on received packets.
  132. //
  133. C_ASSERT(sizeof(MUX_RECV_RSVD) <= sizeof(((PNDIS_PACKET)0)->MiniportReserved));
  134. //
  135. // Out context stored in each packet that we use to forward
  136. // a TransferData request to the lower binding.
  137. // These packets are allocated from the RecvPacketPool.
  138. //
  139. typedef struct _MUX_TD_RSVD
  140. {
  141. PVELAN pVElan;
  142. PNDIS_PACKET pOriginalPacket;
  143. } MUX_TD_RSVD, *PMUX_TD_RSVD;
  144. #define MUX_RSVD_FROM_TD_PACKET(_pPkt) \
  145. ((PMUX_TD_RSVD)(_pPkt)->ProtocolReserved)
  146. //
  147. // Default values:
  148. //
  149. #define MUX_DEFAULT_LINK_SPEED 100000 // in 100s of bits/sec
  150. #define MUX_DEFAULT_LOOKAHEAD_SIZE 512
  151. NTSTATUS
  152. DriverEntry(
  153. IN PDRIVER_OBJECT DriverObject,
  154. IN PUNICODE_STRING RegistryPath
  155. );
  156. NTSTATUS
  157. PtDispatch(
  158. IN PDEVICE_OBJECT DeviceObject,
  159. IN PIRP Irp
  160. );
  161. NDIS_STATUS
  162. PtRegisterDevice(
  163. VOID
  164. );
  165. NDIS_STATUS
  166. PtDeregisterDevice(
  167. VOID
  168. );
  169. //
  170. // Protocol proto-types
  171. //
  172. VOID
  173. PtOpenAdapterComplete(
  174. IN NDIS_HANDLE ProtocolBindingContext,
  175. IN NDIS_STATUS Status,
  176. IN NDIS_STATUS OpenErrorStatus
  177. );
  178. VOID
  179. PtQueryAdapterInfo(
  180. IN PADAPT pAdapt
  181. );
  182. VOID
  183. PtQueryAdapterSync(
  184. IN PADAPT pAdapt,
  185. IN NDIS_OID Oid,
  186. IN PVOID InformationBuffer,
  187. IN ULONG InformationBufferLength
  188. );
  189. VOID
  190. PtRequestAdapterAsync(
  191. IN PADAPT pAdapt,
  192. IN NDIS_REQUEST_TYPE RequestType,
  193. IN NDIS_OID Oid,
  194. IN PVOID InformationBuffer,
  195. IN ULONG InformationBufferLength,
  196. IN PMUX_REQ_COMPLETE_HANDLER pCallback
  197. );
  198. VOID
  199. PtCloseAdapterComplete(
  200. IN NDIS_HANDLE ProtocolBindingContext,
  201. IN NDIS_STATUS Status
  202. );
  203. VOID
  204. PtResetComplete(
  205. IN NDIS_HANDLE ProtocolBindingContext,
  206. IN NDIS_STATUS Status
  207. );
  208. VOID
  209. PtRequestComplete(
  210. IN NDIS_HANDLE ProtocolBindingContext,
  211. IN PNDIS_REQUEST NdisRequest,
  212. IN NDIS_STATUS Status
  213. );
  214. VOID
  215. PtCompleteForwardedRequest(
  216. IN PADAPT pAdapt,
  217. IN PMUX_NDIS_REQUEST pMuxNdisRequest,
  218. IN NDIS_STATUS Status
  219. );
  220. VOID
  221. PtPostProcessPnPCapabilities(
  222. IN PVELAN pVElan,
  223. IN PVOID InformationBuffer,
  224. IN ULONG InformationBufferLength
  225. );
  226. VOID
  227. PtCompleteBlockingRequest(
  228. IN PADAPT pAdapt,
  229. IN PMUX_NDIS_REQUEST pMuxNdisRequest,
  230. IN NDIS_STATUS Status
  231. );
  232. VOID
  233. PtDiscardCompletedRequest(
  234. IN PADAPT pAdapt,
  235. IN PMUX_NDIS_REQUEST pMuxNdisRequest,
  236. IN NDIS_STATUS Status
  237. );
  238. VOID
  239. PtStatus(
  240. IN NDIS_HANDLE ProtocolBindingContext,
  241. IN NDIS_STATUS GeneralStatus,
  242. IN PVOID StatusBuffer,
  243. IN UINT StatusBufferSize
  244. );
  245. VOID
  246. PtStatusComplete(
  247. IN NDIS_HANDLE ProtocolBindingContext
  248. );
  249. VOID
  250. PtSendComplete(
  251. IN NDIS_HANDLE ProtocolBindingContext,
  252. IN PNDIS_PACKET Packet,
  253. IN NDIS_STATUS Status
  254. );
  255. VOID
  256. PtTransferDataComplete(
  257. IN NDIS_HANDLE ProtocolBindingContext,
  258. IN PNDIS_PACKET Packet,
  259. IN NDIS_STATUS Status,
  260. IN UINT BytesTransferred
  261. );
  262. NDIS_STATUS
  263. PtReceive(
  264. IN NDIS_HANDLE ProtocolBindingContext,
  265. IN NDIS_HANDLE MacReceiveContext,
  266. IN PVOID HeaderBuffer,
  267. IN UINT HeaderBufferSize,
  268. IN PVOID LookAheadBuffer,
  269. IN UINT LookaheadBufferSize,
  270. IN UINT PacketSize
  271. );
  272. VOID
  273. PtReceiveComplete(
  274. IN NDIS_HANDLE ProtocolBindingContext
  275. );
  276. INT
  277. PtReceivePacket(
  278. IN NDIS_HANDLE ProtocolBindingContext,
  279. IN PNDIS_PACKET Packet
  280. );
  281. VOID
  282. PtBindAdapter(
  283. OUT PNDIS_STATUS Status,
  284. IN NDIS_HANDLE BindContext,
  285. IN PNDIS_STRING DeviceName,
  286. IN PVOID SystemSpecific1,
  287. IN PVOID SystemSpecific2
  288. );
  289. VOID
  290. PtUnbindAdapter(
  291. OUT PNDIS_STATUS Status,
  292. IN NDIS_HANDLE ProtocolBindingContext,
  293. IN NDIS_HANDLE UnbindContext
  294. );
  295. NDIS_STATUS
  296. PtPNPHandler(
  297. IN NDIS_HANDLE ProtocolBindingContext,
  298. IN PNET_PNP_EVENT pNetPnPEvent
  299. );
  300. NDIS_STATUS
  301. PtCreateAndStartVElan(
  302. IN PADAPT pAdapt,
  303. IN PNDIS_STRING pVElanKey
  304. );
  305. PVELAN
  306. PtAllocateAndInitializeVElan(
  307. IN PADAPT pAdapt,
  308. IN PNDIS_STRING pVElanKey
  309. );
  310. VOID
  311. PtDeallocateVElan(
  312. IN PVELAN pVElan
  313. );
  314. VOID
  315. PtStopVElan(
  316. IN PVELAN pVElan
  317. );
  318. VOID
  319. PtUnlinkVElanFromAdapter(
  320. IN PVELAN pVElan
  321. );
  322. PVELAN
  323. PtFindVElan(
  324. IN PADAPT pAdapt,
  325. IN PNDIS_STRING pElanKey
  326. );
  327. NDIS_STATUS
  328. PtBootStrapVElans(
  329. IN PADAPT pAdapt
  330. );
  331. VOID
  332. PtReferenceVElan(
  333. IN PVELAN pVElan,
  334. IN PUCHAR String
  335. );
  336. ULONG
  337. PtDereferenceVElan(
  338. IN PVELAN pVElan,
  339. IN PUCHAR String
  340. );
  341. BOOLEAN
  342. PtReferenceAdapter(
  343. IN PADAPT pAdapt,
  344. IN PUCHAR String
  345. );
  346. ULONG
  347. PtDereferenceAdapter(
  348. IN PADAPT pAdapt,
  349. IN PUCHAR String
  350. );
  351. //
  352. // Miniport proto-types
  353. //
  354. NDIS_STATUS
  355. MPInitialize(
  356. OUT PNDIS_STATUS OpenErrorStatus,
  357. OUT PUINT SelectedMediumIndex,
  358. IN PNDIS_MEDIUM MediumArray,
  359. IN UINT MediumArraySize,
  360. IN NDIS_HANDLE MiniportAdapterHandle,
  361. IN NDIS_HANDLE WrapperConfigurationContext
  362. );
  363. VOID
  364. MPSendPackets(
  365. IN NDIS_HANDLE MiniportAdapterContext,
  366. IN PPNDIS_PACKET PacketArray,
  367. IN UINT NumberOfPackets
  368. );
  369. NDIS_STATUS
  370. MPQueryInformation(
  371. IN NDIS_HANDLE MiniportAdapterContext,
  372. IN NDIS_OID Oid,
  373. IN PVOID InformationBuffer,
  374. IN ULONG InformationBufferLength,
  375. OUT PULONG BytesWritten,
  376. OUT PULONG BytesNeeded
  377. );
  378. NDIS_STATUS
  379. MPSetInformation(
  380. IN NDIS_HANDLE MiniportAdapterContext,
  381. IN NDIS_OID Oid,
  382. IN PVOID InformationBuffer,
  383. IN ULONG InformationBufferLength,
  384. OUT PULONG BytesRead,
  385. OUT PULONG BytesNeeded
  386. );
  387. VOID
  388. MPReturnPacket(
  389. IN NDIS_HANDLE MiniportAdapterContext,
  390. IN PNDIS_PACKET Packet
  391. );
  392. NDIS_STATUS
  393. MPTransferData(
  394. OUT PNDIS_PACKET Packet,
  395. OUT PUINT BytesTransferred,
  396. IN NDIS_HANDLE MiniportAdapterContext,
  397. IN NDIS_HANDLE MiniportReceiveContext,
  398. IN UINT ByteOffset,
  399. IN UINT BytesToTransfer
  400. );
  401. VOID
  402. MPHalt(
  403. IN NDIS_HANDLE MiniportAdapterContext
  404. );
  405. NDIS_STATUS
  406. MPSetPacketFilter(
  407. IN PVELAN pVElan,
  408. IN ULONG PacketFilter
  409. );
  410. NDIS_STATUS
  411. MPSetMulticastList(
  412. IN PVELAN pVElan,
  413. IN PVOID InformationBuffer,
  414. IN ULONG InformationBufferLength,
  415. OUT PULONG pBytesRead,
  416. OUT PULONG pBytesNeeded
  417. );
  418. PUCHAR
  419. MacAddrToString(PVOID In
  420. );
  421. VOID
  422. MPGenerateMacAddr(
  423. PVELAN pVElan
  424. );
  425. #ifdef NDIS51_MINIPORT
  426. VOID
  427. MPCancelSendPackets(
  428. IN NDIS_HANDLE MiniportAdapterContext,
  429. IN PVOID CancelId
  430. );
  431. VOID
  432. MPDevicePnPEvent(
  433. IN NDIS_HANDLE MiniportAdapterContext,
  434. IN NDIS_DEVICE_PNP_EVENT DevicePnPEvent,
  435. IN PVOID InformationBuffer,
  436. IN ULONG InformationBufferLength
  437. );
  438. VOID
  439. MPAdapterShutdown(
  440. IN NDIS_HANDLE MiniportAdapterContext
  441. );
  442. #endif //NDIS51_MINIPORT
  443. VOID
  444. MPUnload(
  445. IN PDRIVER_OBJECT DriverObject
  446. );
  447. NDIS_STATUS
  448. MPForwardRequest(
  449. IN PVELAN pVElan,
  450. IN NDIS_REQUEST_TYPE RequestType,
  451. IN NDIS_OID Oid,
  452. IN PVOID InformationBuffer,
  453. IN ULONG InformationBufferLength,
  454. OUT PULONG BytesReadOrWritten,
  455. OUT PULONG BytesNeeded
  456. );
  457. //
  458. // Super-structure for NDIS_REQUEST, to allow us to keep context
  459. // about requests sent down to a lower binding.
  460. //
  461. typedef struct _MUX_NDIS_REQUEST
  462. {
  463. PVELAN pVElan; // Set iff this is a forwarded
  464. // request from a VELAN.
  465. NDIS_STATUS Status; // Completion status
  466. NDIS_EVENT Event; // Used to block for completion.
  467. PMUX_REQ_COMPLETE_HANDLER pCallback; // Called on completion of request
  468. NDIS_REQUEST Request;
  469. } MUX_NDIS_REQUEST, *PMUX_NDIS_REQUEST;
  470. //
  471. // The ADAPT object represents a binding to a lower adapter by
  472. // the protocol edge of this driver. Based on the configured
  473. // Upper bindings, zero or more virtual miniport devices (VELANs)
  474. // are created above this binding.
  475. //
  476. typedef struct _ADAPT
  477. {
  478. // Chain adapters. Access to this is protected by the global lock.
  479. LIST_ENTRY Link;
  480. // References to this adapter.
  481. ULONG RefCount;
  482. // Handle to the lower adapter, used in NDIS calls referring
  483. // to this adapter.
  484. NDIS_HANDLE BindingHandle;
  485. // List of all the virtual ELANs created on this lower binding
  486. LIST_ENTRY VElanList;
  487. // Length of above list.
  488. ULONG VElanCount;
  489. // String used to access configuration for this binding.
  490. NDIS_STRING ConfigString;
  491. // Open Status. Used by bind/halt for Open/Close Adapter status.
  492. NDIS_STATUS Status;
  493. NDIS_EVENT Event;
  494. //
  495. // Packet filter set to the underlying adapter. This is
  496. // a combination (union) of filter bits set on all
  497. // attached VELAN miniports.
  498. //
  499. ULONG PacketFilter;
  500. // Medium of the underlying Adapter.
  501. NDIS_MEDIUM Medium;
  502. // Link speed of the underlying adapter.
  503. ULONG LinkSpeed;
  504. // Max lookahead size for the underlying adapter.
  505. ULONG MaxLookAhead;
  506. // Power state of the underlying adapter
  507. NDIS_DEVICE_POWER_STATE PtDevicePowerState;
  508. // Ethernet address of the underlying adapter.
  509. UCHAR CurrentAddress[ETH_LENGTH_OF_ADDRESS];
  510. #ifndef WIN9X
  511. //
  512. // Read/Write lock: allows multiple readers but only a single
  513. // writer. Used to protect the VELAN list and fields (e.g. packet
  514. // filter) shared on an ADAPT by multiple VELANs. Code that
  515. // needs to traverse the VELAN list safely acquires a READ lock.
  516. // Code that needs to safely modify the VELAN list or shared
  517. // fields acquires a WRITE lock (which also excludes READers).
  518. //
  519. // See macros MUX_ACQUIRE_ADAPT_xxx/MUX_RELEASE_ADAPT_xxx below.
  520. //
  521. // TBD - if we want to support this on Win9X, reimplement this!
  522. //
  523. NDIS_RW_LOCK ReadWriteLock;
  524. #endif // WIN9X
  525. } ADAPT, *PADAPT;
  526. //
  527. // VELAN object represents a virtual ELAN instance and its
  528. // corresponding virtual miniport adapter.
  529. //
  530. typedef struct _VELAN
  531. {
  532. // Link into parent adapter's VELAN list.
  533. LIST_ENTRY Link;
  534. // References to this VELAN.
  535. ULONG RefCount;
  536. // Parent ADAPT.
  537. PADAPT pAdapt;
  538. // Copy of BindingHandle from ADAPT.
  539. NDIS_HANDLE BindingHandle;
  540. // Adapter handle for NDIS up-calls related to this virtual miniport.
  541. NDIS_HANDLE MiniportAdapterHandle;
  542. // Virtual miniport's power state.
  543. NDIS_DEVICE_POWER_STATE MPDevicePowerState;
  544. // Has our Halt entry point been called?
  545. BOOLEAN MiniportHalting;
  546. // Do we need to indicate receive complete?
  547. BOOLEAN IndicateRcvComplete;
  548. // Do we need to indicate status complete?
  549. BOOLEAN IndicateStatusComplete;
  550. // Synchronization fields
  551. BOOLEAN MiniportInitPending;
  552. NDIS_EVENT MiniportInitEvent;
  553. // Uncompleted Sends/Requests to the adapter below.
  554. ULONG OutstandingSends;
  555. // Count outstanding indications, including received
  556. // packets, passed up to protocols on this VELAN.
  557. ULONG OutstandingReceives;
  558. // Packet pool for send packets
  559. NDIS_HANDLE SendPacketPoolHandle;
  560. // Packet pool for receive packets
  561. NDIS_HANDLE RecvPacketPoolHandle;
  562. // A request block that is used to forward a request presented
  563. // to the virtual miniport, to the lower binding. Since NDIS
  564. // serializes requests to a miniport, we only need one of these
  565. // per VELAN.
  566. //
  567. MUX_NDIS_REQUEST Request;
  568. PULONG BytesNeeded;
  569. PULONG BytesReadOrWritten;
  570. // Have we queued a request because the lower binding is
  571. // at a low power state?
  572. BOOLEAN QueuedRequest;
  573. // Have we started to deinitialize this VELAN?
  574. BOOLEAN DeInitializing;
  575. // configuration
  576. UCHAR PermanentAddress[ETH_LENGTH_OF_ADDRESS];
  577. UCHAR CurrentAddress[ETH_LENGTH_OF_ADDRESS];
  578. NDIS_STRING CfgDeviceName; // used as the unique
  579. // ID for the VELAN
  580. ULONG VElanNumber; // logical Elan number
  581. //
  582. // ----- Buffer Management: Header buffers and Protocol buffers ----
  583. //
  584. // Some standard miniport parameters (OID values).
  585. ULONG PacketFilter;
  586. ULONG LookAhead;
  587. ULONG LinkSpeed;
  588. ULONG MaxBusySends;
  589. ULONG MaxBusyRecvs;
  590. // Packet counts
  591. ULONG64 GoodTransmits;
  592. ULONG64 GoodReceives;
  593. ULONG NumTxSinceLastAdjust;
  594. // Count of transmit errors
  595. ULONG TxAbortExcessCollisions;
  596. ULONG TxLateCollisions;
  597. ULONG TxDmaUnderrun;
  598. ULONG TxLostCRS;
  599. ULONG TxOKButDeferred;
  600. ULONG OneRetry;
  601. ULONG MoreThanOneRetry;
  602. ULONG TotalRetries;
  603. ULONG TransmitFailuresOther;
  604. // Count of receive errors
  605. ULONG RcvCrcErrors;
  606. ULONG RcvAlignmentErrors;
  607. ULONG RcvResourceErrors;
  608. ULONG RcvDmaOverrunErrors;
  609. ULONG RcvCdtFrames;
  610. ULONG RcvRuntErrors;
  611. #if IEEE_VLAN_SUPPORT
  612. ULONG RcvFormatErrors;
  613. ULONG RcvVlanIdErrors;
  614. #endif
  615. ULONG RegNumTcb;
  616. // Multicast list
  617. MUX_MAC_ADDRESS McastAddrs[VELAN_MAX_MCAST_LIST];
  618. ULONG McastAddrCount;
  619. #if IEEE_VLAN_SUPPORT
  620. ULONG VlanId;
  621. NDIS_HANDLE BufferPoolHandle;
  622. NPAGED_LOOKASIDE_LIST TagLookaside;
  623. #endif
  624. NDIS_STATUS LastIndicatedStatus;
  625. NDIS_STATUS LatestUnIndicateStatus;
  626. NDIS_SPIN_LOCK Lock;
  627. } VELAN, *PVELAN;
  628. #if IEEE_VLAN_SUPPORT
  629. #define TPID 0x0081
  630. //
  631. // Define tag_header structure
  632. //
  633. typedef struct _VLAN_TAG_HEADER
  634. {
  635. UCHAR TagInfo[2];
  636. } VLAN_TAG_HEADER, *PVLAN_TAG_HEADER;
  637. //
  638. // Define context struct that used when the lower driver
  639. // uses non-packet indication. It contains the original
  640. // context, the tagging information and the tag-header
  641. // length
  642. //
  643. typedef struct _MUX_RCV_CONTEXT
  644. {
  645. ULONG TagHeaderLen;
  646. NDIS_PACKET_8021Q_INFO NdisPacket8021QInfo;
  647. PVOID MacRcvContext;
  648. }MUX_RCV_CONTEXT, *PMUX_RCV_CONTEXT;
  649. //
  650. // Macro definitions for VLAN support
  651. //
  652. #define VLAN_TAG_HEADER_SIZE 4
  653. #define VLANID_DEFAULT 0
  654. #define VLAN_ID_MAX 0xfff
  655. #define VLAN_ID_MIN 0x0
  656. #define USER_PRIORITY_MASK 0xe0
  657. #define CANONICAL_FORMAT_ID_MASK 0x10
  658. #define HIGH_VLAN_ID_MASK 0x0F
  659. //
  660. // Get information for tag headre
  661. //
  662. #define GET_CANONICAL_FORMAT_ID_FROM_TAG(_pTagHeader) \
  663. ( _pTagHeader->TagInfo[0] & CANONICAL_FORMAT_ID_MASK)
  664. #define GET_USER_PRIORITY_FROM_TAG(_pTagHeader) \
  665. ( _pTagHeader->TagInfo[0] & USER_PRIORITY_MASK)
  666. #define GET_VLAN_ID_FROM_TAG(_pTagHeader) \
  667. (ULONG)(((USHORT)(_pTagHeader->TagInfo[0] & HIGH_VLAN_ID_MASK) << 8) | (USHORT)(_pTagHeader->TagInfo[1]))
  668. //
  669. // Clear the tag header struct
  670. //
  671. #define INITIALIZE_TAG_HEADER_TO_ZERO(_pTagHeader) \
  672. { \
  673. _pTagHeader->TagInfo[0] = 0; \
  674. _pTagHeader->TagInfo[1] = 0; \
  675. }
  676. //
  677. // Set VLAN information to tag header
  678. // Before we called all the set macro, first we need to initialize pTagHeader to be 0
  679. //
  680. #define SET_CANONICAL_FORMAT_ID_TO_TAG(_pTagHeader, CanonicalFormatId) \
  681. _pTagHeader->TagInfo[0] |= ((UCHAR)CanonicalFormatId << 4)
  682. #define SET_USER_PRIORITY_TO_TAG(_pTagHeader, UserPriority) \
  683. _pTagHeader->TagInfo[0] |= ((UCHAR)UserPriority << 5)
  684. #define SET_VLAN_ID_TO_TAG(_pTagHeader, VlanId) \
  685. { \
  686. _pTagHeader->TagInfo[0] |= (((UCHAR)VlanId >> 8) & 0x0f); \
  687. _pTagHeader->TagInfo[1] |= (UCHAR)VlanId;\
  688. }
  689. //
  690. // Copy tagging information in the indicated frame to per packet info
  691. //
  692. #define COPY_TAG_INFO_FROM_HEADER_TO_PACKET_INFO(_Ieee8021qInfo, _pTagHeader) \
  693. { \
  694. (_Ieee8021qInfo).TagHeader.UserPriority = ((_pTagHeader->TagInfo[0] & USER_PRIORITY_MASK) >> 5); \
  695. (_Ieee8021qInfo).TagHeader.CanonicalFormatId = ((_pTagHeader->TagInfo[0] & CANONICAL_FORMAT_ID_MASK) >> 4); \
  696. (_Ieee8021qInfo).TagHeader.VlanId = (((USHORT)(_pTagHeader->TagInfo[0] & HIGH_VLAN_ID_MASK) << 8)| (USHORT)(_pTagHeader->TagInfo[1])); \
  697. }
  698. //
  699. // Function to handle tagging on sending side
  700. //
  701. NDIS_STATUS
  702. MPHandleSendTagging(
  703. IN PVELAN pVElan,
  704. IN PNDIS_PACKET Packet,
  705. IN OUT PNDIS_PACKET MyPacket
  706. );
  707. //
  708. // Functions to handle tagging on receiving side with packet indication
  709. //
  710. NDIS_STATUS
  711. PtHandleRcvTagging(
  712. IN PVELAN pVElan,
  713. IN PNDIS_PACKET Packet,
  714. IN OUT PNDIS_PACKET MyPacket
  715. );
  716. #endif //IEEE_VLAN_SUPPORT
  717. //
  718. // Macro definitions for others.
  719. //
  720. //
  721. // Is a given power state a low-power state?
  722. //
  723. #define MUX_IS_LOW_POWER_STATE(_PwrState) \
  724. ((_PwrState) > NdisDeviceStateD0)
  725. #define MUX_INIT_ADAPT_RW_LOCK(_pAdapt) \
  726. NdisInitializeReadWriteLock(&(_pAdapt)->ReadWriteLock)
  727. #define MUX_ACQUIRE_ADAPT_READ_LOCK(_pAdapt, _pLockState) \
  728. NdisAcquireReadWriteLock(&(_pAdapt)->ReadWriteLock, \
  729. FALSE, \
  730. _pLockState)
  731. #define MUX_RELEASE_ADAPT_READ_LOCK(_pAdapt, _pLockState) \
  732. NdisReleaseReadWriteLock(&(_pAdapt)->ReadWriteLock, \
  733. _pLockState)
  734. #define MUX_ACQUIRE_ADAPT_WRITE_LOCK(_pAdapt, _pLockState) \
  735. NdisAcquireReadWriteLock(&(_pAdapt)->ReadWriteLock, \
  736. TRUE, \
  737. _pLockState)
  738. #define MUX_RELEASE_ADAPT_WRITE_LOCK(_pAdapt, _pLockState) \
  739. NdisReleaseReadWriteLock(&(_pAdapt)->ReadWriteLock, \
  740. _pLockState)
  741. #define MUX_INCR_PENDING_RECEIVES(_pVElan) \
  742. NdisInterlockedIncrement((PLONG)&pVElan->OutstandingReceives)
  743. #define MUX_DECR_PENDING_RECEIVES(_pVElan) \
  744. NdisInterlockedDecrement((PLONG)&pVElan->OutstandingReceives)
  745. #define MUX_INCR_PENDING_SENDS(_pVElan) \
  746. NdisInterlockedIncrement((PLONG)&pVElan->OutstandingSends)
  747. #define MUX_DECR_PENDING_SENDS(_pVElan) \
  748. NdisInterlockedDecrement((PLONG)&pVElan->OutstandingSends)
  749. #define MUX_INCR_STATISTICS(_pUlongVal) \
  750. NdisInterlockedIncrement((PLONG)_pUlongVal)
  751. #define MUX_INCR_STATISTICS64(_pUlong64Val) \
  752. { \
  753. PLARGE_INTEGER _pLargeInt = (PLARGE_INTEGER)_pUlong64Val;\
  754. if (NdisInterlockedIncrement((PLONG)&_pLargeInt->LowPart) == 0) \
  755. { \
  756. NdisInterlockedIncrement(&_pLargeInt->HighPart); \
  757. } \
  758. }
  759. #define ASSERT_AT_PASSIVE() \
  760. ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL)
  761. //
  762. // Simple Mutual Exclusion constructs used in preference to
  763. // using KeXXX calls since we don't have Mutex calls in NDIS.
  764. // These can only be called at passive IRQL.
  765. //
  766. typedef struct _MUX_MUTEX
  767. {
  768. ULONG Counter;
  769. ULONG ModuleAndLine; // useful for debugging
  770. } MUX_MUTEX, *PMUX_MUTEX;
  771. #define MUX_INIT_MUTEX(_pMutex) \
  772. { \
  773. (_pMutex)->Counter = 0; \
  774. (_pMutex)->ModuleAndLine = 0; \
  775. }
  776. #define MUX_ACQUIRE_MUTEX(_pMutex) \
  777. { \
  778. while (NdisInterlockedIncrement((PLONG)&((_pMutex)->Counter)) != 1)\
  779. { \
  780. NdisInterlockedDecrement((PLONG)&((_pMutex)->Counter)); \
  781. NdisMSleep(10000); \
  782. } \
  783. (_pMutex)->ModuleAndLine = (MODULE_NUMBER << 16) | __LINE__;\
  784. }
  785. #define MUX_RELEASE_MUTEX(_pMutex) \
  786. { \
  787. (_pMutex)->ModuleAndLine = 0; \
  788. NdisInterlockedDecrement((PLONG)&(_pMutex)->Counter); \
  789. }
  790. //
  791. // Global variables
  792. //
  793. extern NDIS_HANDLE ProtHandle, DriverHandle;
  794. extern NDIS_MEDIUM MediumArray[1];
  795. extern NDIS_SPIN_LOCK GlobalLock;
  796. extern MUX_MUTEX GlobalMutex;
  797. extern LIST_ENTRY AdapterList;
  798. extern ULONG NextVElanNumber;
  799. //
  800. // Module numbers for debugging
  801. //
  802. #define MODULE_MUX 'X'
  803. #define MODULE_PROT 'P'
  804. #define MODULE_MINI 'M'