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 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