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.

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