xref: /reactos/drivers/network/dd/dc21x4/dc21x4.h (revision 59d8a77d)
1 /*
2  * PROJECT:     ReactOS DC21x4 Driver
3  * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE:     Main header file
5  * COPYRIGHT:   Copyright 2023 Dmitry Borisov <di.sean@protonmail.com>
6  */
7 
8 #pragma once
9 
10 #if !DBG
11 #define NO_KERNEL_LIST_ENTRY_CHECKS
12 #endif
13 #include <ndis.h>
14 #include <section_attribs.h>
15 
16 #include "dc21x4hw.h"
17 #include "eeprom.h"
18 #include "media.h"
19 #include "util.h"
20 
21 #define DC21X4_TAG   '4x12'
22 
23 #define DC_TRANSMIT_DESCRIPTORS    64
24 #define DC_TRANSMIT_BLOCKS         48
25 #define DC_TRANSMIT_BUFFERS        4
26 #define DC_LOOPBACK_FRAMES         4
27 
28 #define DC_RECEIVE_BUFFERS_DEFAULT     64
29 #define DC_RECEIVE_BUFFERS_MIN         8
30 #define DC_RECEIVE_BUFFERS_EXTRA       16
31 
32 #define DC_RECEIVE_ARRAY_SIZE      16
33 
34 #define DC_MULTICAST_LIST_SIZE     36
35 
36 #define DC_MAXIMUM_FRAME_SIZE      1514
37 #define DC_TRANSMIT_BLOCK_SIZE     1536
38 #define DC_RECEIVE_BLOCK_SIZE      1536
39 #define DC_ETHERNET_HEADER_SIZE    14
40 
41 #define DC_TX_UNDERRUN_LIMIT    5
42 #define DC_INTERRUPT_PROCESSING_LIMIT    8
43 
44 #define DC_FRAGMENTATION_THRESHOLD    32
45 
46 #define DC_PACKET_FILTERS ( \
47     NDIS_PACKET_TYPE_DIRECTED | \
48     NDIS_PACKET_TYPE_MULTICAST | \
49     NDIS_PACKET_TYPE_BROADCAST | \
50     NDIS_PACKET_TYPE_PROMISCUOUS | \
51     NDIS_PACKET_TYPE_ALL_MULTICAST)
52 
53 #define DC_LOOPBACK_FRAME_SIZE    64
54 
55 /* Transmit descriptors reserved for internal use */
56 #define DC_TBD_RESERVE     (2 + DC_LOOPBACK_FRAMES) /* (+2 for setup frame) */
57 #define DC_TCB_RESERVE     (1 + DC_LOOPBACK_FRAMES) /* (+1 for setup frame) */
58 
59 #define DC_EVENT_SETUP_FRAME_COMPLETED    0x00000001
60 
61 typedef struct _DC21X4_ADAPTER       DC21X4_ADAPTER, *PDC21X4_ADAPTER;
62 typedef struct _DC_TCB               DC_TCB, *PDC_TCB;
63 typedef struct _DC_RCB               DC_RCB, *PDC_RCB;
64 typedef struct _DC_COALESCE_BUFFER   DC_COALESCE_BUFFER, *PDC_COALESCE_BUFFER;
65 
66 typedef VOID
67 (MEDIA_HANDLE_LINK_STATE_CHANGE)(
68     _In_ PDC21X4_ADAPTER Adapter,
69     _In_ ULONG InterruptStatus);
70 typedef MEDIA_HANDLE_LINK_STATE_CHANGE *PMEDIA_HANDLE_LINK_STATE_CHANGE;
71 
72 typedef struct _DC_TX_BUFFER_DATA
73 {
74     PVOID VirtualAddress;
75     NDIS_PHYSICAL_ADDRESS PhysicalAddress;
76 } DC_TX_BUFFER_DATA, *PDC_TX_BUFFER_DATA;
77 
78 typedef struct _DC_STATISTICS
79 {
80     ULONG64 TransmitOk;
81     ULONG64 TransmitDeferred;
82     ULONG64 TransmitHeartbeatErrors;
83     ULONG64 TransmitOneRetry;
84     ULONG64 TransmitMoreCollisions;
85     ULONG64 TransmitErrors;
86     ULONG64 TransmitExcessiveCollisions;
87     ULONG64 TransmitUnderrunErrors;
88     ULONG64 TransmitLostCarrierSense;
89     ULONG64 TransmitLateCollisions;
90     ULONG64 ReceiveOk;
91     ULONG64 ReceiveBroadcast;
92     ULONG64 ReceiveMulticast;
93     ULONG64 ReceiveUnicast;
94     ULONG64 ReceiveErrors;
95     ULONG64 ReceiveOverrunErrors;
96     ULONG64 ReceiveNoBuffers;
97     ULONG64 ReceiveCrcErrors;
98     ULONG64 ReceiveAlignmentErrors;
99 } DC_STATISTICS, *PDC_STATISTICS;
100 
101 typedef struct _DC21X4_ADAPTER
102 {
103     PUCHAR IoBase;
104     ULONG InterruptMask;
105     ULONG CurrentInterruptMask;
106 
107     ULONG Features;
108 #define DC_NEED_RX_OVERFLOW_WORKAROUND              0x80000000
109 #define DC_SIA_GPIO                                 0x00000001
110 #define DC_SIA_ANALOG_CONTROL                       0x00000002
111 #define DC_HAS_POWER_MANAGEMENT                     0x00000004
112 #define DC_HAS_POWER_SAVING                         0x00000008
113 #define DC_HAS_MII                                  0x00000010
114 #define DC_PERFECT_FILTERING_ONLY                   0x00000020
115 #define DC_ENABLE_PCI_COMMANDS                      0x00000040
116 #define DC_MII_AUTOSENSE                            0x00000080
117 #define DC_HAS_TIMER                                0x00000100
118 
119     ULONG Flags;
120 #define DC_ACTIVE                                   0x80000000
121 #define DC_IO_MAPPED                                0x00000001
122 #define DC_IRQ_SHARED                               0x00000002
123 #define DC_FIRST_SETUP                              0x00000004
124 #define DC_AUTOSENSE                                0x00000008
125 
126     ULONG InterruptStatus;
127     PMEDIA_HANDLE_LINK_STATE_CHANGE HandleLinkStateChange;
128 
129     DECLSPEC_CACHEALIGN NDIS_SPIN_LOCK SendLock;
130     PDC_TCB TailTcb;
131     PDC_TCB LastTcb;
132     PDC_TCB CurrentTcb;
133     PDC_TBD CurrentTbd;
134     PDC_TBD HeadTbd;
135     PDC_TBD TailTbd;
136     LIST_ENTRY SendQueueList;
137     ULONG TcbSlots;
138     ULONG TbdSlots;
139     ULONG TcbCompleted;
140     ULONG LastTcbCompleted;
141     PDC_TCB HeadTcb;
142     SINGLE_LIST_ENTRY SendBufferList;
143     SCATTER_GATHER_LIST LocalSgList;
144 
145     DECLSPEC_CACHEALIGN NDIS_SPIN_LOCK ReceiveLock;
146     PDC_RCB* RcbArray;
147     PDC_RBD CurrentRbd;
148     PDC_RBD HeadRbd;
149     PDC_RBD TailRbd;
150     SINGLE_LIST_ENTRY FreeRcbList;
151     ULONG RcbFree;
152 
153     ULONG TransmitUnderruns;
154     ULONG PacketFilter;
155 
156     DC_STATISTICS Statistics;
157 
158     NDIS_HANDLE AdapterHandle;
159     NDIS_HANDLE WrapperConfigurationHandle;
160 
161     DECLSPEC_CACHEALIGN NDIS_SPIN_LOCK ModeLock;
162     ULONG ModeFlags;
163 #define DC_MODE_AUTONEG_MASK                 0x0000000F
164 #define DC_MODE_PORT_AUTOSENSE               0x00000010
165 #define DC_MODE_TEST_PACKET                  0x00000020
166 #define DC_MODE_AUI_FAILED                   0x00000040
167 #define DC_MODE_BNC_FAILED                   0x00000080
168 
169 #define DC_MODE_AUTONEG_NONE                 0x00000000
170 #define DC_MODE_AUTONEG_WAIT_INTERRUPT       0x00000001
171 #define DC_MODE_AUTONEG_LINK_STATUS_CHECK    0x00000002
172 
173     ULONG OpMode;
174     ULONG MediaNumber;
175     ULONG MediaBitmap;
176     BOOLEAN LinkUp;
177     ULONG PhyAddress;
178     ULONG SiaSetting;
179     ULONG LastReceiveActivity;
180     volatile LONG MediaTestStatus;
181     NDIS_MINIPORT_TIMER MediaMonitorTimer;
182     DC_MII_MEDIA MiiMedia;
183     DC_MEDIA Media[MEDIA_LIST_MAX];
184 
185     ULONG AnalogControl;
186     ULONG SymAdvertising;
187     ULONG MiiAdvertising;
188     ULONG MiiControl;
189     DC_CHIP_TYPE ChipType;
190     ULONG LinkStateChangeMask;
191 
192     ULONG WakeUpFlags;
193     NDIS_DEVICE_POWER_STATE PowerState;
194     NDIS_DEVICE_POWER_STATE PrevPowerState;
195 
196     ULONG HpnaInitBitmap;
197     UCHAR HpnaRegister[32];
198 
199     UCHAR PermanentMacAddress[ETH_LENGTH_OF_ADDRESS];
200     UCHAR CurrentMacAddress[ETH_LENGTH_OF_ADDRESS];
201 
202     ULONG MulticastMaxEntries;
203     _Field_range_(0, MulticastMaxEntries)
204     ULONG MulticastCount;
205     struct
206     {
207         UCHAR MacAddress[ETH_LENGTH_OF_ADDRESS];
208     } MulticastList[DC_MULTICAST_LIST_SIZE];
209 
210     ULONG LinkSpeedMbps;
211     ULONG BusMode;
212     ULONG DefaultMedia;
213     ULONG RcbCount;
214     BOOLEAN OidPending;
215     BOOLEAN ProgramHashPerfectFilter;
216     PULONG SetupFrame;
217     PULONG SetupFrameSaved;
218     ULONG SetupFramePhys;
219     ULONG LoopbackFrameSlots;
220     ULONG LoopbackFrameNumber;
221     ULONG LoopbackFramePhys[DC_LOOPBACK_FRAMES];
222     ULONG BusNumber;
223     UCHAR DeviceNumber;
224     UCHAR RevisionId;
225     UCHAR ControllerIndex;
226     UCHAR ResetStreamLength;
227     USHORT ResetStream[SROM_MAX_STREAM_REGS];
228     USHORT DeviceId;
229     SINGLE_LIST_ENTRY AllocRcbList;
230     SINGLE_LIST_ENTRY UsedRcbList;
231     NDIS_MINIPORT_INTERRUPT Interrupt;
232     ULONG InterruptVector;
233     ULONG InterruptLevel;
234     ULONG InterruptFlags;
235     ULONG AdapterSize;
236     NDIS_WORK_ITEM PowerWorkItem;
237     NDIS_WORK_ITEM ResetWorkItem;
238     NDIS_WORK_ITEM TxRecoveryWorkItem;
239     _Interlocked_ volatile LONG ResetLock;
240     NDIS_PHYSICAL_ADDRESS IoBaseAddress;
241     PDC_SROM_ENTRY SRomEntry;
242     PVOID AdapterOriginal;
243     PVOID TbdOriginal;
244     PVOID RbdOriginal;
245     ULONG TbdPhys;
246     ULONG RbdPhys;
247     NDIS_HANDLE BufferPool;
248     NDIS_HANDLE PacketPool;
249     NDIS_PHYSICAL_ADDRESS TbdPhysOriginal;
250     NDIS_PHYSICAL_ADDRESS RbdPhysOriginal;
251     PVOID LoopbackFrame[DC_LOOPBACK_FRAMES];
252     PDC_COALESCE_BUFFER CoalesceBuffer;
253     DC_TX_BUFFER_DATA SendBufferData[DC_TRANSMIT_BUFFERS];
254 } DC21X4_ADAPTER, *PDC21X4_ADAPTER;
255 
256 #include "sendrcv.h"
257 
258 extern LIST_ENTRY SRompAdapterList;
259 
260 FORCEINLINE
261 ULONG
DC_READ(_In_ PDC21X4_ADAPTER Adapter,_In_ DC_CSR Register)262 DC_READ(
263     _In_ PDC21X4_ADAPTER Adapter,
264     _In_ DC_CSR Register)
265 {
266     ULONG Value;
267 
268     NdisRawReadPortUlong((PULONG)(Adapter->IoBase + Register), &Value);
269     return Value;
270 }
271 
272 #define DC_WRITE(Adapter, Register, Value)  \
273     NdisRawWritePortUlong((PULONG)((Adapter)->IoBase + (Register)), (Value));
274 
275 CODE_SEG("INIT")
276 DRIVER_INITIALIZE DriverEntry;
277 
278 CODE_SEG("PAGE")
279 NDIS_STATUS
280 NTAPI
281 DcInitialize(
282     _Out_ PNDIS_STATUS OpenErrorStatus,
283     _Out_ PUINT SelectedMediumIndex,
284     _In_ PNDIS_MEDIUM MediumArray,
285     _In_ UINT MediumArraySize,
286     _In_ NDIS_HANDLE MiniportAdapterHandle,
287     _In_ NDIS_HANDLE WrapperConfigurationContext);
288 
289 VOID
290 NTAPI
291 DcSendPackets(
292     _In_ NDIS_HANDLE MiniportAdapterContext,
293     _In_ PPNDIS_PACKET PacketArray,
294     _In_ UINT NumberOfPackets);
295 
296 VOID
297 NTAPI
298 DcCancelSendPackets(
299     _In_ NDIS_HANDLE MiniportAdapterContext,
300     _In_ PVOID CancelId);
301 
302 VOID
303 DcProcessPendingPackets(
304     _In_ PDC21X4_ADAPTER Adapter);
305 
306 VOID
307 NTAPI
308 DcReturnPacket(
309     _In_ NDIS_HANDLE MiniportAdapterContext,
310     _In_ PNDIS_PACKET Packet);
311 
312 NDIS_STATUS
313 NTAPI
314 DcQueryInformation(
315     _In_ NDIS_HANDLE MiniportAdapterContext,
316     _In_ NDIS_OID Oid,
317     _In_ PVOID InformationBuffer,
318     _In_ ULONG InformationBufferLength,
319     _Out_ PULONG BytesWritten,
320     _Out_ PULONG BytesNeeded);
321 
322 NDIS_STATUS
323 NTAPI
324 DcSetInformation(
325     _In_ NDIS_HANDLE MiniportAdapterContext,
326     _In_ NDIS_OID Oid,
327     _In_ PVOID InformationBuffer,
328     _In_ ULONG InformationBufferLength,
329     _Out_ PULONG BytesRead,
330     _Out_ PULONG BytesNeeded);
331 
332 VOID
333 NTAPI
334 DcIsr(
335     _Out_ PBOOLEAN InterruptRecognized,
336     _Out_ PBOOLEAN QueueMiniportHandleInterrupt,
337     _In_ NDIS_HANDLE MiniportAdapterContext);
338 
339 VOID
340 NTAPI
341 DcHandleInterrupt(
342     _In_ NDIS_HANDLE MiniportAdapterContext);
343 
344 CODE_SEG("PAGE")
345 VOID
346 NTAPI
347 DcPowerWorker(
348     _In_ PNDIS_WORK_ITEM WorkItem,
349     _In_opt_ PVOID Context);
350 
351 NDIS_STATUS
352 DcSetPower(
353     _In_ PDC21X4_ADAPTER Adapter,
354     _In_ NDIS_DEVICE_POWER_STATE PowerState);
355 
356 NDIS_STATUS
357 DcAddWakeUpPattern(
358     _In_ PDC21X4_ADAPTER Adapter,
359     _In_ PNDIS_PM_PACKET_PATTERN PmPattern);
360 
361 NDIS_STATUS
362 DcRemoveWakeUpPattern(
363     _In_ PDC21X4_ADAPTER Adapter,
364     _In_ PNDIS_PM_PACKET_PATTERN PmPattern);
365 
366 CODE_SEG("PAGE")
367 VOID
368 DcFreeAdapter(
369     _In_ __drv_freesMem(Mem) PDC21X4_ADAPTER Adapter);
370 
371 CODE_SEG("PAGE")
372 VOID
373 NTAPI
374 DcResetWorker(
375     _In_ PNDIS_WORK_ITEM WorkItem,
376     _In_opt_ PVOID Context);
377 
378 DECLSPEC_NOINLINE
379 VOID
380 DcStopAdapter(
381     _In_ PDC21X4_ADAPTER Adapter,
382     _In_ BOOLEAN WaitForPackets);
383 
384 CODE_SEG("PAGE")
385 VOID
386 DcStartAdapter(
387     _In_ PDC21X4_ADAPTER Adapter);
388 
389 CODE_SEG("PAGE")
390 NDIS_STATUS
391 DcSetupAdapter(
392     _In_ PDC21X4_ADAPTER Adapter);
393 
394 CODE_SEG("PAGE")
395 NDIS_STATUS
396 DcReadEeprom(
397     _In_ PDC21X4_ADAPTER Adapter);
398 
399 CODE_SEG("PAGE")
400 VOID
401 DcFreeEeprom(
402     _In_ PDC21X4_ADAPTER Adapter);
403 
404 CODE_SEG("PAGE")
405 VOID
406 DcInitTxRing(
407     _In_ PDC21X4_ADAPTER Adapter);
408 
409 CODE_SEG("PAGE")
410 VOID
411 DcInitRxRing(
412     _In_ PDC21X4_ADAPTER Adapter);
413 
414 ULONG
415 DcEthernetCrc(
416     _In_reads_bytes_(Size) const VOID* Buffer,
417     _In_ ULONG Size);
418 
419 VOID
420 DcDisableHw(
421     _In_ PDC21X4_ADAPTER Adapter);
422 
423 VOID
424 DcStopTxRxProcess(
425     _In_ PDC21X4_ADAPTER Adapter);
426 
427 VOID
428 DcWriteGpio(
429     _In_ PDC21X4_ADAPTER Adapter,
430     _In_ ULONG Value);
431 
432 VOID
433 DcWriteSia(
434     _In_ PDC21X4_ADAPTER Adapter,
435     _In_ ULONG Csr13,
436     _In_ ULONG Csr14,
437     _In_ ULONG Csr15);
438 
439 VOID
440 DcTestPacket(
441     _In_ PDC21X4_ADAPTER Adapter);
442 
443 CODE_SEG("PAGE")
444 VOID
445 DcSetupFrameInitialize(
446     _In_ PDC21X4_ADAPTER Adapter);
447 
448 BOOLEAN
449 DcSetupFrameDownload(
450     _In_ PDC21X4_ADAPTER Adapter,
451     _In_ BOOLEAN WaitForCompletion);
452 
453 NDIS_STATUS
454 DcApplyPacketFilter(
455     _In_ PDC21X4_ADAPTER Adapter,
456     _In_ ULONG PacketFilter);
457 
458 NDIS_STATUS
459 DcUpdateMulticastList(
460     _In_ PDC21X4_ADAPTER Adapter);
461 
462 VOID
463 DcPowerSave(
464     _In_ PDC21X4_ADAPTER Adapter,
465     _In_ BOOLEAN Enable);
466 
467 CODE_SEG("PAGE")
468 BOOLEAN
469 DcFindMiiPhy(
470     _In_ PDC21X4_ADAPTER Adapter);
471 
472 BOOLEAN
473 MiiWrite(
474     _In_ PDC21X4_ADAPTER Adapter,
475     _In_ ULONG PhyAddress,
476     _In_ ULONG RegAddress,
477     _In_ ULONG Data);
478 
479 BOOLEAN
480 MiiRead(
481     _In_ PDC21X4_ADAPTER Adapter,
482     _In_ ULONG PhyAddress,
483     _In_ ULONG RegAddress,
484     _Out_ PULONG Data);
485 
486 CODE_SEG("PAGE")
487 VOID
488 HpnaPhyInit(
489     _In_ PDC21X4_ADAPTER Adapter);
490 
491 VOID
492 NTAPI
493 DcTransmitTimeoutRecoveryWorker(
494     _In_ PNDIS_WORK_ITEM WorkItem,
495     _In_opt_ PVOID Context);
496 
497 NDIS_TIMER_FUNCTION MediaMonitor21040Dpc;
498 NDIS_TIMER_FUNCTION MediaMonitor21041Dpc;
499 NDIS_TIMER_FUNCTION MediaMonitor21140Dpc;
500 NDIS_TIMER_FUNCTION MediaMonitor21143Dpc;
501 
502 MEDIA_HANDLE_LINK_STATE_CHANGE MediaLinkStateChange21040;
503 MEDIA_HANDLE_LINK_STATE_CHANGE MediaLinkStateChange21041;
504 MEDIA_HANDLE_LINK_STATE_CHANGE MediaLinkStateChange21143;
505 
506 CODE_SEG("PAGE")
507 VOID
508 MediaInitMediaList(
509     _In_ PDC21X4_ADAPTER Adapter);
510 
511 CODE_SEG("PAGE")
512 VOID
513 MediaInitDefaultMedia(
514     _In_ PDC21X4_ADAPTER Adapter,
515     _In_ ULONG MediaNumber);
516 
517 VOID
518 MediaIndicateConnect(
519     _In_ PDC21X4_ADAPTER Adapter,
520     _In_ BOOLEAN LinkUp);
521 
522 VOID
523 MediaSelectMiiPort(
524     _In_ PDC21X4_ADAPTER Adapter,
525     _In_ BOOLEAN ResetPhy);
526 
527 VOID
528 MediaMiiSelect(
529     _In_ PDC21X4_ADAPTER Adapter);
530 
531 BOOLEAN
532 MediaMiiCheckLink(
533     _In_ PDC21X4_ADAPTER Adapter);
534 
535 VOID
536 MediaSiaSelect(
537     _In_ PDC21X4_ADAPTER Adapter);
538 
539 VOID
540 MediaGprSelect(
541     _In_ PDC21X4_ADAPTER Adapter);
542