|
|
1.1 ! root 1: /*++ ! 2: ! 3: Copyright (c) 1990-1992 Microsoft Corporation ! 4: ! 5: Module Name: ! 6: ! 7: sonic.c ! 8: ! 9: Abstract: ! 10: ! 11: This is the main file for the National Semiconductor SONIC ! 12: Ethernet controller. This driver conforms to the NDIS 3.0 interface. ! 13: ! 14: The overall structure and much of the code is taken from ! 15: the Lance NDIS driver by Tony Ercolano. ! 16: ! 17: Author: ! 18: ! 19: Anthony V. Ercolano (Tonye) 20-Jul-1990 ! 20: Adam Barr (adamba) 14-Nov-1990 ! 21: ! 22: Environment: ! 23: ! 24: Kernel Mode - Or whatever is the equivalent. ! 25: ! 26: Revision History: ! 27: ! 28: ! 29: --*/ ! 30: ! 31: #include <ndis.h> ! 32: ! 33: ! 34: #include <efilter.h> ! 35: #include <sonichrd.h> ! 36: #include <sonicsft.h> ! 37: ! 38: ! 39: ! 40: // ! 41: // This variable is used to control debug output. ! 42: // ! 43: ! 44: #if DBG ! 45: INT SonicDbg = 0; ! 46: #endif ! 47: ! 48: ! 49: STATIC ! 50: VOID ! 51: SonicShutdown( ! 52: IN PVOID ShutdownContext ! 53: ); ! 54: ! 55: STATIC ! 56: NDIS_STATUS ! 57: SonicOpenAdapter( ! 58: OUT PNDIS_STATUS OpenErrorStatus, ! 59: OUT NDIS_HANDLE *MacBindingHandle, ! 60: OUT PUINT SelectedMediumIndex, ! 61: IN PNDIS_MEDIUM MediumArray, ! 62: IN UINT MediumArraySize, ! 63: IN NDIS_HANDLE NdisBindingContext, ! 64: IN NDIS_HANDLE MacAdapterContext, ! 65: IN UINT OpenOptions, ! 66: IN PSTRING AddressingInformation OPTIONAL ! 67: ); ! 68: ! 69: STATIC ! 70: NDIS_STATUS ! 71: SonicCloseAdapter( ! 72: IN NDIS_HANDLE MacBindingHandle ! 73: ); ! 74: ! 75: ! 76: STATIC ! 77: VOID ! 78: SonicUnload( ! 79: IN NDIS_HANDLE MacMacContext ! 80: ); ! 81: ! 82: STATIC ! 83: NDIS_STATUS ! 84: SonicAddAdapter( ! 85: IN NDIS_HANDLE MacMacContext, ! 86: IN NDIS_HANDLE ConfigurationHandle, ! 87: IN PNDIS_STRING AdapterName ! 88: ); ! 89: ! 90: STATIC ! 91: VOID ! 92: SonicRemoveAdapter( ! 93: IN NDIS_HANDLE MacAdapterContext ! 94: ); ! 95: ! 96: STATIC ! 97: NDIS_STATUS ! 98: SonicReset( ! 99: IN NDIS_HANDLE MacBindingHandle ! 100: ); ! 101: ! 102: #if 0 ! 103: STATIC ! 104: UINT ! 105: CalculateCRC( ! 106: IN UINT NumberOfBytes, ! 107: IN PCHAR Input ! 108: ); ! 109: #endif ! 110: ! 111: STATIC ! 112: BOOLEAN ! 113: SonicSynchClearIsr( ! 114: IN PVOID Context ! 115: ); ! 116: ! 117: STATIC ! 118: VOID ! 119: SonicStopChip( ! 120: IN PSONIC_ADAPTER Adapter ! 121: ); ! 122: ! 123: STATIC ! 124: BOOLEAN ! 125: SetupRegistersAndInit( ! 126: IN PSONIC_ADAPTER Adapter ! 127: ); ! 128: ! 129: STATIC ! 130: BOOLEAN ! 131: SonicInitialInit( ! 132: IN PSONIC_ADAPTER Adapter ! 133: ); ! 134: ! 135: #ifdef NDIS_NT ! 136: ! 137: NTSTATUS ! 138: DriverEntry( ! 139: IN PDRIVER_OBJECT DriverObject, ! 140: IN PUNICODE_STRING RegistryPath ! 141: ); ! 142: ! 143: #else ! 144: ! 145: NDIS_STATUS ! 146: DriverEntry( ! 147: VOID ! 148: ); ! 149: ! 150: #endif ! 151: ! 152: STATIC ! 153: NDIS_STATUS ! 154: SonicRegisterAdapter( ! 155: IN NDIS_HANDLE NdisMacHandle, ! 156: IN NDIS_HANDLE ConfigurationHandle, ! 157: IN PNDIS_STRING DeviceName, ! 158: IN PUCHAR NetworkAddress, ! 159: IN UCHAR AdapterType, ! 160: IN UINT SlotNumber, ! 161: IN UINT Controller, ! 162: IN UINT MultifunctionAdapter, ! 163: IN UINT SonicInterruptVector, ! 164: IN UINT SonicInterruptLevel, ! 165: IN NDIS_INTERRUPT_MODE SonicInterruptMode, ! 166: IN UINT MaximumOpenAdapters ! 167: ); ! 168: ! 169: typedef enum { ! 170: SonicHardwareOk, ! 171: SonicHardwareChecksum, ! 172: SonicHardwareConfig ! 173: } SONIC_HARDWARE_STATUS; ! 174: ! 175: STATIC ! 176: SONIC_HARDWARE_STATUS ! 177: SonicHardwareGetDetails( ! 178: IN PSONIC_ADAPTER Adapter, ! 179: IN UINT SlotNumber, ! 180: IN UINT Controller, ! 181: IN UINT MultifunctionAdapter, ! 182: OUT PULONG InitialPort, ! 183: OUT PULONG NumberOfPorts, ! 184: IN OUT PUINT InterruptVector, ! 185: IN OUT PUINT InterruptLevel, ! 186: OUT ULONG ErrorLogData[3] ! 187: ); ! 188: ! 189: STATIC ! 190: BOOLEAN ! 191: SonicHardwareGetAddress( ! 192: IN PSONIC_ADAPTER Adapter, ! 193: OUT ULONG ErrorLogData[3] ! 194: ); ! 195: ! 196: #ifdef SONIC_INTERNAL ! 197: ! 198: // ! 199: // These routines are support reading the address for the ! 200: // sonic internal implementation on the R4000 motherboards. ! 201: // ! 202: ! 203: STATIC ! 204: NTSTATUS ! 205: SonicHardwareSaveInformation( ! 206: IN PWSTR ValueName, ! 207: IN ULONG ValueType, ! 208: IN PVOID ValueData, ! 209: IN ULONG ValueLength, ! 210: IN PVOID Context, ! 211: IN PVOID EntryContext ! 212: ); ! 213: ! 214: STATIC ! 215: BOOLEAN ! 216: SonicHardwareVerifyChecksum( ! 217: IN PSONIC_ADAPTER Adapter, ! 218: IN PUCHAR EthernetAddress, ! 219: OUT ULONG ErrorLogData[3] ! 220: ); ! 221: ! 222: #endif ! 223: ! 224: ! 225: // ! 226: // Use the alloc_text pragma to specify the driver initialization routines ! 227: // (they can be paged out). ! 228: // ! 229: ! 230: #ifdef ALLOC_PRAGMA ! 231: #pragma alloc_text(init,DriverEntry) ! 232: #pragma alloc_text(init,SonicRegisterAdapter) ! 233: #pragma alloc_text(init,SonicInitialInit) ! 234: #pragma alloc_text(init,SonicAddAdapter) ! 235: #pragma alloc_text(init,SonicHardwareGetDetails) ! 236: #pragma alloc_text(init,SonicHardwareGetAddress) ! 237: #ifdef SONIC_INTERNAL ! 238: #pragma alloc_text(init,SonicHardwareSaveInformation) ! 239: #pragma alloc_text(init,SonicHardwareVerifyChecksum) ! 240: #endif ! 241: #endif ! 242: ! 243: ! 244: ! 245: NTSTATUS ! 246: DriverEntry( ! 247: IN PDRIVER_OBJECT DriverObject, ! 248: IN PUNICODE_STRING RegistryPath ! 249: ) ! 250: ! 251: /*++ ! 252: ! 253: Routine Description: ! 254: ! 255: This is the primary initialization routine for the sonic driver. ! 256: It is simply responsible for the intializing the wrapper and registering ! 257: the MAC. It then calls a system and architecture specific routine that ! 258: will initialize and register each adapter. ! 259: ! 260: Arguments: ! 261: ! 262: DriverObject - Pointer to driver object created by the system. ! 263: ! 264: Return Value: ! 265: ! 266: The status of the operation. ! 267: ! 268: --*/ ! 269: ! 270: { ! 271: ! 272: // ! 273: // Receives the status of the NdisRegisterMac operation. ! 274: // ! 275: NDIS_STATUS Status; ! 276: ! 277: PSONIC_MAC SonicMac; ! 278: ! 279: NDIS_HANDLE SonicWrapperHandle; ! 280: ! 281: static const NDIS_STRING MacName = NDIS_STRING_CONST("SONIC"); ! 282: NDIS_MAC_CHARACTERISTICS SonicChar; ! 283: ! 284: ! 285: // ! 286: // Initialize the wrapper. ! 287: // ! 288: ! 289: NdisInitializeWrapper( ! 290: &SonicWrapperHandle, ! 291: DriverObject, ! 292: RegistryPath, ! 293: NULL ! 294: ); ! 295: ! 296: // ! 297: // Now allocate memory for our global structure. ! 298: // ! 299: ! 300: SONIC_ALLOC_MEMORY(&Status, &SonicMac, sizeof(SONIC_MAC)); ! 301: ! 302: if (Status != NDIS_STATUS_SUCCESS) { ! 303: ! 304: return NDIS_STATUS_RESOURCES; ! 305: ! 306: } ! 307: ! 308: SonicMac->WrapperHandle = SonicWrapperHandle; ! 309: ! 310: // ! 311: // Initialize the MAC characteristics for the call to ! 312: // NdisRegisterMac. ! 313: // ! 314: ! 315: SonicChar.MajorNdisVersion = SONIC_NDIS_MAJOR_VERSION; ! 316: SonicChar.MinorNdisVersion = SONIC_NDIS_MINOR_VERSION; ! 317: SonicChar.OpenAdapterHandler = SonicOpenAdapter; ! 318: SonicChar.CloseAdapterHandler = SonicCloseAdapter; ! 319: SonicChar.SendHandler = SonicSend; ! 320: SonicChar.TransferDataHandler = SonicTransferData; ! 321: SonicChar.ResetHandler = SonicReset; ! 322: SonicChar.RequestHandler = SonicRequest; ! 323: SonicChar.QueryGlobalStatisticsHandler = SonicQueryGlobalStatistics; ! 324: SonicChar.UnloadMacHandler = SonicUnload; ! 325: SonicChar.AddAdapterHandler = SonicAddAdapter; ! 326: SonicChar.RemoveAdapterHandler = SonicRemoveAdapter; ! 327: SonicChar.Name = MacName; ! 328: ! 329: ! 330: NdisRegisterMac( ! 331: &Status, ! 332: &SonicMac->MacHandle, ! 333: SonicWrapperHandle, ! 334: (NDIS_HANDLE)SonicMac, // MacMacContext ! 335: &SonicChar, ! 336: sizeof(SonicChar) ! 337: ); ! 338: ! 339: if (Status == NDIS_STATUS_SUCCESS) { ! 340: ! 341: return NDIS_STATUS_SUCCESS; ! 342: ! 343: } ! 344: ! 345: ! 346: // ! 347: // We can only get here if something went wrong with registering ! 348: // the mac or *all* of the adapters. ! 349: // ! 350: ! 351: NdisTerminateWrapper(SonicWrapperHandle, NULL); ! 352: ! 353: return NDIS_STATUS_FAILURE; ! 354: ! 355: } ! 356: ! 357: #if DBG ! 358: // ! 359: // Save this to retrieve it in the debugger. ! 360: // ! 361: ! 362: PVOID SonicAdapterAddress; ! 363: #endif ! 364: ! 365: ! 366: STATIC ! 367: NDIS_STATUS ! 368: SonicRegisterAdapter( ! 369: IN NDIS_HANDLE NdisMacHandle, ! 370: IN NDIS_HANDLE ConfigurationHandle, ! 371: IN PNDIS_STRING DeviceName, ! 372: IN PUCHAR NetworkAddress, ! 373: IN UCHAR AdapterType, ! 374: IN UINT SlotNumber, ! 375: IN UINT Controller, ! 376: IN UINT MultifunctionAdapter, ! 377: IN UINT SonicInterruptVector, ! 378: IN UINT SonicInterruptLevel, ! 379: IN NDIS_INTERRUPT_MODE SonicInterruptMode, ! 380: IN UINT MaximumOpenAdapters ! 381: ) ! 382: ! 383: /*++ ! 384: ! 385: Routine Description: ! 386: ! 387: This routine (and its interface) are not portable. They are ! 388: defined by the OS, the architecture, and the particular SONIC ! 389: implementation. ! 390: ! 391: This routine is responsible for the allocation of the datastructures ! 392: for the driver as well as any hardware specific details necessary ! 393: to talk with the device. ! 394: ! 395: Arguments: ! 396: ! 397: NdisMacHandle - The handle given back to the mac from ndis when ! 398: the mac registered itself. ! 399: ! 400: ConfigurationHandle - Config handle passed to MacAddAdapter. ! 401: ! 402: DeviceName - The string containing the name to give to the ! 403: device adapter. ! 404: ! 405: NetworkAddress - The network address, or NULL if the default ! 406: should be used. ! 407: ! 408: AdapterType - The type of the adapter; currently SONIC_ADAPTER_TYPE_EISA ! 409: and SONIC_ADAPTER_TYPE_INTERNAL are supported, ! 410: ! 411: SlotNumber - The slot number for the EISA card. ! 412: ! 413: Controller - The controller number for INTERNAL chips. ! 414: ! 415: MultifunctionAdapter - The INTERNAL bus number for INTERNAL chips. ! 416: ! 417: SonicInterruptVector - The interrupt vector to use for the adapter. ! 418: ! 419: SonicInterruptLevel - The interrupt request level to use for this ! 420: adapter. ! 421: ! 422: SonicInterruptMode - The interrupt mode to be use for this adapter. ! 423: ! 424: MaximumOpenAdapters - The maximum number of opens at any one time. ! 425: ! 426: Return Value: ! 427: ! 428: Returns a failure status if anything occurred that prevents the ! 429: initialization of the adapter. ! 430: ! 431: --*/ ! 432: ! 433: { ! 434: ! 435: // ! 436: // Pointer for the adapter root. ! 437: // ! 438: PSONIC_ADAPTER Adapter; ! 439: ! 440: // ! 441: // Status of various NDIS calls. ! 442: // ! 443: NDIS_STATUS Status; ! 444: ! 445: // ! 446: // Holds information needed when registering the adapter. ! 447: // ! 448: NDIS_ADAPTER_INFORMATION AdapterInformation; ! 449: ! 450: // ! 451: // Number of ports needed ! 452: // ! 453: ULONG InitialPort; ! 454: ULONG NumberOfPorts; ! 455: ! 456: // ! 457: // Returned from SonicHardwareGetDetails; if it failed, ! 458: // we log an error and exit. ! 459: // ! 460: SONIC_HARDWARE_STATUS HardwareDetailsStatus; ! 461: ! 462: // ! 463: // Used to store error log data from SonicHardwareGetDetails. ! 464: // ! 465: ULONG ErrorLogData[3]; ! 466: ! 467: // ! 468: // We put in this assertion to make sure that ushort are 2 bytes. ! 469: // if they aren't then the initialization block definition needs ! 470: // to be changed. ! 471: // ! 472: // Also all of the logic that deals with status registers assumes ! 473: // that control registers are only 2 bytes. ! 474: // ! 475: ! 476: ASSERT(sizeof(USHORT) == 2); ! 477: ! 478: // ! 479: // The Sonic uses four bytes four physical addresses, so we ! 480: // must ensure that this is the case (SONIC_PHYSICAL_ADDRESS) ! 481: // is defined as a ULONG). ! 482: // ! 483: ! 484: ASSERT(sizeof(SONIC_PHYSICAL_ADDRESS) == 4); ! 485: ! 486: // ! 487: // Allocate the Adapter block. ! 488: // ! 489: ! 490: SONIC_ALLOC_MEMORY(&Status, &Adapter, sizeof(SONIC_ADAPTER)); ! 491: ! 492: if (Status == NDIS_STATUS_SUCCESS) { ! 493: #if DBG ! 494: SonicAdapterAddress = Adapter; ! 495: #endif ! 496: ! 497: SONIC_ZERO_MEMORY( ! 498: Adapter, ! 499: sizeof(SONIC_ADAPTER) ! 500: ); ! 501: ! 502: ! 503: Adapter->AdapterType = AdapterType; ! 504: if (SonicInterruptMode == NdisInterruptLatched) { ! 505: Adapter->InterruptLatched = TRUE; ! 506: } ! 507: Adapter->PermanentAddressValid = FALSE; ! 508: ! 509: // ! 510: // Set up the AdapterInformation structure; zero it out ! 511: // first using sizeof (in case any fields are added). ! 512: // ! 513: ! 514: SONIC_ZERO_MEMORY (&AdapterInformation, sizeof(NDIS_ADAPTER_INFORMATION)); ! 515: AdapterInformation.DmaChannel = 0; ! 516: AdapterInformation.Master = TRUE; ! 517: AdapterInformation.PhysicalMapRegistersNeeded = ! 518: SONIC_MAX_FRAGMENTS * SONIC_NUMBER_OF_TRANSMIT_DESCRIPTORS; ! 519: AdapterInformation.MaximumPhysicalMapping = ! 520: SONIC_LARGE_BUFFER_SIZE; ! 521: ! 522: // ! 523: // This returns the I/O ports used by the Sonic and may ! 524: // modify SonicInterruptVector and SonicInterruptLevel, ! 525: // as well as modiying some fields in Adapter. ! 526: // ! 527: ! 528: if ((HardwareDetailsStatus = ! 529: SonicHardwareGetDetails( ! 530: Adapter, ! 531: SlotNumber, ! 532: Controller, ! 533: MultifunctionAdapter, ! 534: &InitialPort, ! 535: &NumberOfPorts, ! 536: &SonicInterruptVector, ! 537: &SonicInterruptLevel, ! 538: ErrorLogData)) != SonicHardwareOk) { ! 539: ! 540: // ! 541: // If it fails, we call NdisRegisterAdapter anyway ! 542: // (so we can log an error using the NdisAdapterHandle), ! 543: // then return failure. ! 544: // ! 545: ! 546: AdapterInformation.NumberOfPortDescriptors = 0; ! 547: ! 548: } else { ! 549: ! 550: AdapterInformation.NumberOfPortDescriptors = 1; ! 551: AdapterInformation.PortDescriptors[0].InitialPort = InitialPort; ! 552: AdapterInformation.PortDescriptors[0].NumberOfPorts = NumberOfPorts; ! 553: AdapterInformation.PortDescriptors[0].PortOffset = (PVOID *)(&(Adapter->SonicPortAddress)); ! 554: ! 555: } ! 556: ! 557: if (AdapterType == SONIC_ADAPTER_TYPE_EISA) { ! 558: AdapterInformation.AdapterType = NdisInterfaceEisa; ! 559: } else { ! 560: AdapterInformation.AdapterType = NdisInterfaceInternal; ! 561: } ! 562: ! 563: // ! 564: // Register the adapter with NDIS. ! 565: // ! 566: ! 567: if ((Status = NdisRegisterAdapter( ! 568: &Adapter->NdisAdapterHandle, ! 569: NdisMacHandle, ! 570: Adapter, ! 571: ConfigurationHandle, ! 572: DeviceName, ! 573: &AdapterInformation ! 574: )) == NDIS_STATUS_SUCCESS) { ! 575: ! 576: if (HardwareDetailsStatus != SonicHardwareOk) { ! 577: ! 578: // ! 579: // Log an error and exit. ! 580: // ! 581: ! 582: if (HardwareDetailsStatus == SonicHardwareChecksum) { ! 583: ! 584: NdisWriteErrorLogEntry( ! 585: Adapter->NdisAdapterHandle, ! 586: NDIS_ERROR_CODE_NETWORK_ADDRESS, ! 587: 6, ! 588: hardwareDetails, ! 589: SONIC_ERRMSG_HARDWARE_ADDRESS, ! 590: NDIS_STATUS_FAILURE, ! 591: ErrorLogData[0], ! 592: ErrorLogData[1], ! 593: ErrorLogData[2] ! 594: ); ! 595: ! 596: } else { ! 597: ! 598: NdisWriteErrorLogEntry( ! 599: Adapter->NdisAdapterHandle, ! 600: NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER, ! 601: 0 ! 602: ); ! 603: ! 604: } ! 605: ! 606: NdisDeregisterAdapter(Adapter->NdisAdapterHandle); ! 607: SONIC_FREE_MEMORY(Adapter, sizeof(SONIC_ADAPTER)); ! 608: return NDIS_STATUS_FAILURE; ! 609: ! 610: } ! 611: ! 612: ! 613: // ! 614: // Allocate memory for all of the adapter structures. ! 615: // ! 616: ! 617: Adapter->NumberOfTransmitDescriptors = ! 618: SONIC_NUMBER_OF_TRANSMIT_DESCRIPTORS; ! 619: Adapter->NumberOfReceiveBuffers = ! 620: SONIC_NUMBER_OF_RECEIVE_BUFFERS; ! 621: Adapter->NumberOfReceiveDescriptors = ! 622: SONIC_NUMBER_OF_RECEIVE_DESCRIPTORS; ! 623: ! 624: ! 625: if (AllocateAdapterMemory(Adapter)) { ! 626: ! 627: // ! 628: // Get the network address. This writes ! 629: // an error log entry if it fails. This routine ! 630: // may do nothing on some systems, if ! 631: // SonicHardwareGetDetails has already determined ! 632: // the network address. ! 633: // ! 634: ! 635: if (!SonicHardwareGetAddress(Adapter, ErrorLogData)) { ! 636: ! 637: NdisWriteErrorLogEntry( ! 638: Adapter->NdisAdapterHandle, ! 639: NDIS_ERROR_CODE_NETWORK_ADDRESS, ! 640: 6, ! 641: hardwareDetails, ! 642: SONIC_ERRMSG_HARDWARE_ADDRESS, ! 643: NDIS_STATUS_FAILURE, ! 644: ErrorLogData[0], ! 645: ErrorLogData[1], ! 646: ErrorLogData[2] ! 647: ); ! 648: ! 649: DeleteAdapterMemory(Adapter); ! 650: NdisDeregisterAdapter(Adapter->NdisAdapterHandle); ! 651: SONIC_FREE_MEMORY(Adapter, sizeof(SONIC_ADAPTER)); ! 652: return NDIS_STATUS_FAILURE; ! 653: ! 654: } ! 655: ! 656: // ! 657: // Initialize the current hardware address. ! 658: // ! 659: ! 660: SONIC_MOVE_MEMORY( ! 661: Adapter->CurrentNetworkAddress, ! 662: (NetworkAddress != NULL) ? ! 663: NetworkAddress : ! 664: Adapter->PermanentNetworkAddress, ! 665: ETH_LENGTH_OF_ADDRESS); ! 666: ! 667: ! 668: InitializeListHead(&Adapter->OpenBindings); ! 669: Adapter->OpenCount = 0; ! 670: Adapter->Removed = FALSE; ! 671: InitializeListHead(&Adapter->CloseList); ! 672: NdisAllocateSpinLock(&Adapter->Lock); ! 673: ! 674: ! 675: Adapter->LastTransmitDescriptor = ! 676: Adapter->TransmitDescriptorArea + ! 677: (Adapter->NumberOfTransmitDescriptors-1); ! 678: Adapter->NumberOfAvailableDescriptors = ! 679: Adapter->NumberOfTransmitDescriptors; ! 680: Adapter->AllocateableDescriptor = ! 681: Adapter->TransmitDescriptorArea; ! 682: Adapter->TransmittingDescriptor = ! 683: Adapter->TransmitDescriptorArea; ! 684: Adapter->FirstUncommittedDescriptor = ! 685: Adapter->TransmitDescriptorArea; ! 686: Adapter->PacketsSinceLastInterrupt = 0; ! 687: ! 688: Adapter->CurrentReceiveBufferIndex = 0; ! 689: Adapter->CurrentReceiveDescriptorIndex = 0; ! 690: Adapter->LastReceiveDescriptor = ! 691: &Adapter->ReceiveDescriptorArea[ ! 692: Adapter->NumberOfReceiveDescriptors-1]; ! 693: ! 694: Adapter->InterruptMaskRegister = SONIC_INT_DEFAULT_VALUE; ! 695: Adapter->ReceiveDescriptorsExhausted = FALSE; ! 696: Adapter->ReceiveBuffersExhausted = FALSE; ! 697: Adapter->ReceiveControlRegister = SONIC_RCR_DEFAULT_VALUE; ! 698: ! 699: Adapter->ProcessingReceiveInterrupt = FALSE; ! 700: Adapter->ProcessingGeneralInterrupt = FALSE; ! 701: Adapter->ProcessingDeferredOperations = FALSE; ! 702: Adapter->FirstLoopBack = NULL; ! 703: Adapter->LastLoopBack = NULL; ! 704: Adapter->FirstFinishTransmit = NULL; ! 705: Adapter->LastFinishTransmit = NULL; ! 706: Adapter->SendStageOpen = TRUE; ! 707: Adapter->AlreadyProcessingSendStage = FALSE; ! 708: Adapter->FirstSendStagePacket = NULL; ! 709: Adapter->LastSendStagePacket = NULL; ! 710: ! 711: Adapter->References = 1; ! 712: ! 713: Adapter->ResetInProgress = FALSE; ! 714: Adapter->IndicatingResetStart = FALSE; ! 715: Adapter->IndicatingResetEnd = FALSE; ! 716: Adapter->ResettingOpen = NULL; ! 717: Adapter->FirstInitialization = TRUE; ! 718: ! 719: SONIC_ZERO_MEMORY (&Adapter->GeneralMandatory, GM_ARRAY_SIZE * sizeof(ULONG)); ! 720: SONIC_ZERO_MEMORY (&Adapter->GeneralOptionalByteCount, GO_COUNT_ARRAY_SIZE * sizeof(SONIC_LARGE_INTEGER)); ! 721: SONIC_ZERO_MEMORY (&Adapter->GeneralOptionalFrameCount, GO_COUNT_ARRAY_SIZE * sizeof(ULONG)); ! 722: SONIC_ZERO_MEMORY (&Adapter->GeneralOptional, (GO_ARRAY_SIZE - GO_ARRAY_START) * sizeof(ULONG)); ! 723: SONIC_ZERO_MEMORY (&Adapter->MediaMandatory, MM_ARRAY_SIZE * sizeof(ULONG)); ! 724: SONIC_ZERO_MEMORY (&Adapter->MediaOptional, MO_ARRAY_SIZE * sizeof(ULONG)); ! 725: ! 726: // ! 727: // Initialize the CAM and associated things. ! 728: // At the beginning nothing is enabled since ! 729: // our filter is 0, although we do store ! 730: // our network address in the first slot. ! 731: // ! 732: ! 733: Adapter->MulticastCamEnableBits = 0x0000; ! 734: Adapter->CurrentPacketFilter = 0; ! 735: Adapter->CamDescriptorArea->CamEnable = 0x0000; ! 736: Adapter->CamDescriptorsUsed = 0x0001; ! 737: Adapter->CamDescriptorAreaSize = 1; ! 738: ! 739: NdisInitializeTimer( ! 740: &Adapter->DeferredTimer, ! 741: SonicTimerProcess, ! 742: (PVOID)Adapter); ! 743: ! 744: SONIC_LOAD_CAM_FRAGMENT( ! 745: &Adapter->CamDescriptorArea->CamFragments[0], ! 746: 0, ! 747: Adapter->CurrentNetworkAddress ! 748: ); ! 749: ! 750: ! 751: if (!EthCreateFilter( ! 752: SONIC_CAM_ENTRIES-1, // maximum MC addresses ! 753: SonicChangeAddresses, ! 754: SonicChangeClass, ! 755: SonicCloseAction, ! 756: Adapter->CurrentNetworkAddress, ! 757: &Adapter->Lock, ! 758: &Adapter->FilterDB ! 759: )) { ! 760: ! 761: NdisWriteErrorLogEntry( ! 762: Adapter->NdisAdapterHandle, ! 763: NDIS_ERROR_CODE_OUT_OF_RESOURCES, ! 764: 2, ! 765: registerAdapter, ! 766: SONIC_ERRMSG_CREATE_FILTER ! 767: ); ! 768: ! 769: DeleteAdapterMemory(Adapter); ! 770: NdisDeregisterAdapter(Adapter->NdisAdapterHandle); ! 771: NdisFreeSpinLock(&Adapter->Lock); ! 772: SONIC_FREE_MEMORY(Adapter, sizeof(SONIC_ADAPTER)); ! 773: return NDIS_STATUS_RESOURCES; ! 774: ! 775: } else { ! 776: ! 777: // ! 778: // Initialize the interrupt. ! 779: // ! 780: ! 781: NdisInitializeInterrupt( ! 782: &Status, ! 783: &Adapter->Interrupt, ! 784: Adapter->NdisAdapterHandle, ! 785: SonicInterruptService, ! 786: Adapter, ! 787: SonicDeferredProcessing, ! 788: SonicInterruptVector, ! 789: SonicInterruptLevel, ! 790: TRUE, ! 791: SonicInterruptMode ! 792: ); ! 793: ! 794: ! 795: if (Status != NDIS_STATUS_SUCCESS) { ! 796: ! 797: NdisWriteErrorLogEntry( ! 798: Adapter->NdisAdapterHandle, ! 799: NDIS_ERROR_CODE_INTERRUPT_CONNECT, ! 800: 2, ! 801: registerAdapter, ! 802: SONIC_ERRMSG_INIT_INTERRUPT ! 803: ); ! 804: ! 805: EthDeleteFilter(Adapter->FilterDB); ! 806: DeleteAdapterMemory(Adapter); ! 807: NdisDeregisterAdapter(Adapter->NdisAdapterHandle); ! 808: NdisFreeSpinLock(&Adapter->Lock); ! 809: SONIC_FREE_MEMORY(Adapter, sizeof(SONIC_ADAPTER)); ! 810: return Status; ! 811: ! 812: } ! 813: ! 814: // ! 815: // Start the card up. This writes an error ! 816: // log entry if it fails. ! 817: // ! 818: ! 819: if (!SonicInitialInit(Adapter)) { ! 820: ! 821: NdisRemoveInterrupt(&Adapter->Interrupt); ! 822: EthDeleteFilter(Adapter->FilterDB); ! 823: DeleteAdapterMemory(Adapter); ! 824: NdisDeregisterAdapter(Adapter->NdisAdapterHandle); ! 825: NdisFreeSpinLock(&Adapter->Lock); ! 826: SONIC_FREE_MEMORY(Adapter, sizeof(SONIC_ADAPTER)); ! 827: return NDIS_STATUS_FAILURE; ! 828: ! 829: } else { ! 830: ! 831: // ! 832: // Initialize the wake up timer to catch interrupts that ! 833: // don't complete. It fires continuously ! 834: // every 5 seconds, and we check if there are any ! 835: // uncompleted operations from the previous 5 second ! 836: // period. ! 837: // ! 838: ! 839: Adapter->WakeUpDpc = (PVOID)SonicWakeUpDpc; ! 840: ! 841: NdisInitializeTimer(&Adapter->WakeUpTimer, ! 842: (PVOID)(Adapter->WakeUpDpc), ! 843: Adapter ); ! 844: ! 845: NdisSetTimer( ! 846: &Adapter->WakeUpTimer, ! 847: 5000 ! 848: ); ! 849: ! 850: NdisRegisterAdapterShutdownHandler( ! 851: Adapter->NdisAdapterHandle, ! 852: (PVOID)Adapter, ! 853: SonicShutdown ! 854: ); ! 855: ! 856: return NDIS_STATUS_SUCCESS; ! 857: ! 858: } ! 859: ! 860: } ! 861: ! 862: ! 863: } else { ! 864: ! 865: // ! 866: // Call to AllocateAdapterMemory failed. ! 867: // ! 868: ! 869: NdisWriteErrorLogEntry( ! 870: Adapter->NdisAdapterHandle, ! 871: NDIS_ERROR_CODE_OUT_OF_RESOURCES, ! 872: 2, ! 873: registerAdapter, ! 874: SONIC_ERRMSG_ALLOC_MEMORY ! 875: ); ! 876: ! 877: DeleteAdapterMemory(Adapter); ! 878: NdisDeregisterAdapter(Adapter->NdisAdapterHandle); ! 879: SONIC_FREE_MEMORY(Adapter, sizeof(SONIC_ADAPTER)); ! 880: return NDIS_STATUS_RESOURCES; ! 881: ! 882: } ! 883: ! 884: } else { ! 885: ! 886: // ! 887: // Call to NdisRegisterAdapter failed. ! 888: // ! 889: ! 890: SONIC_FREE_MEMORY(Adapter, sizeof(SONIC_ADAPTER)); ! 891: return Status; ! 892: ! 893: } ! 894: ! 895: } else { ! 896: ! 897: // ! 898: // Couldn't allocate adapter object. ! 899: // ! 900: ! 901: return Status; ! 902: ! 903: } ! 904: ! 905: } ! 906: ! 907: extern ! 908: BOOLEAN ! 909: SonicInitialInit( ! 910: IN PSONIC_ADAPTER Adapter ! 911: ) ! 912: ! 913: /*++ ! 914: ! 915: Routine Description: ! 916: ! 917: This routine sets up the initial init of the driver. ! 918: ! 919: Arguments: ! 920: ! 921: Adapter - The adapter for the hardware. ! 922: ! 923: Return Value: ! 924: ! 925: None. ! 926: ! 927: --*/ ! 928: ! 929: { ! 930: ! 931: UINT Time = 50; ! 932: ! 933: // ! 934: // First we make sure that the device is stopped. ! 935: // ! 936: ! 937: SonicStopChip(Adapter); ! 938: ! 939: // ! 940: // Set up the registers. ! 941: // ! 942: ! 943: if (!SetupRegistersAndInit(Adapter)) { ! 944: ! 945: NdisWriteErrorLogEntry( ! 946: Adapter->NdisAdapterHandle, ! 947: NDIS_ERROR_CODE_ADAPTER_NOT_FOUND, ! 948: 3, ! 949: registerAdapter, ! 950: SONIC_ERRMSG_INITIAL_INIT ! 951: ); ! 952: ! 953: return FALSE; ! 954: ! 955: } ! 956: ! 957: ! 958: // ! 959: // Delay execution for 1/2 second to give the sonic ! 960: // time to initialize. ! 961: // ! 962: ! 963: while (Time > 0) { ! 964: ! 965: if (!Adapter->FirstInitialization) { ! 966: break; ! 967: } ! 968: ! 969: NdisStallExecution(10000); ! 970: Time--; ! 971: ! 972: } ! 973: ! 974: ! 975: // ! 976: // The only way that first initialization could have ! 977: // been turned off is if we actually initialized. ! 978: // ! 979: ! 980: if (!Adapter->FirstInitialization) { ! 981: ! 982: // ! 983: // We actually did get the initialization. ! 984: // ! 985: // We can start the chip. We may not ! 986: // have any bindings to indicate to but this ! 987: // is unimportant. ! 988: // ! 989: ! 990: SonicStartChip(Adapter); ! 991: ! 992: return TRUE; ! 993: ! 994: ! 995: } else { ! 996: ! 997: NdisWriteErrorLogEntry( ! 998: Adapter->NdisAdapterHandle, ! 999: NDIS_ERROR_CODE_TIMEOUT, ! 1000: 2, ! 1001: registerAdapter, ! 1002: SONIC_ERRMSG_INITIAL_INIT ! 1003: ); ! 1004: ! 1005: return FALSE; ! 1006: ! 1007: } ! 1008: ! 1009: } ! 1010: ! 1011: STATIC ! 1012: BOOLEAN ! 1013: SonicSynchClearIsr( ! 1014: IN PVOID Context ! 1015: ) ! 1016: ! 1017: /*++ ! 1018: ! 1019: Routine Description: ! 1020: ! 1021: This routine is used during a reset. It ensures that no ! 1022: interrupts will come through, and that any DPRs that run ! 1023: will find no interrupts to process. ! 1024: ! 1025: Arguments: ! 1026: ! 1027: Context - A pointer to a SONIC_ADAPTER structure. ! 1028: ! 1029: Return Value: ! 1030: ! 1031: Always returns true. ! 1032: ! 1033: --*/ ! 1034: ! 1035: { ! 1036: ! 1037: PSONIC_ADAPTER Adapter = (PSONIC_ADAPTER)Context; ! 1038: ! 1039: SONIC_WRITE_PORT(Adapter, SONIC_INTERRUPT_STATUS, 0xffff); ! 1040: Adapter->IsrValue = 0; ! 1041: ! 1042: return TRUE; ! 1043: ! 1044: } ! 1045: ! 1046: extern ! 1047: VOID ! 1048: SonicStartChip( ! 1049: IN PSONIC_ADAPTER Adapter ! 1050: ) ! 1051: ! 1052: /*++ ! 1053: ! 1054: Routine Description: ! 1055: ! 1056: This routine is used to start an already initialized sonic. ! 1057: ! 1058: Arguments: ! 1059: ! 1060: Adapter - The adapter for the SONIC to start. ! 1061: ! 1062: Return Value: ! 1063: ! 1064: None. ! 1065: ! 1066: --*/ ! 1067: ! 1068: { ! 1069: ! 1070: // ! 1071: // Take us out of reset mode if we are in it. ! 1072: // ! 1073: ! 1074: SONIC_WRITE_PORT(Adapter, SONIC_COMMAND, ! 1075: 0x0000 ! 1076: ); ! 1077: ! 1078: SONIC_WRITE_PORT(Adapter, SONIC_COMMAND, ! 1079: SONIC_CR_RECEIVER_ENABLE ! 1080: ); ! 1081: ! 1082: } ! 1083: ! 1084: STATIC ! 1085: VOID ! 1086: SonicStopChip( ! 1087: IN PSONIC_ADAPTER Adapter ! 1088: ) ! 1089: ! 1090: /*++ ! 1091: ! 1092: Routine Description: ! 1093: ! 1094: This routine is used to stop a sonic. ! 1095: ! 1096: This routine is *not* portable. It is specific to the 386 ! 1097: implementation of the sonic. On the bus master card the ACON bit ! 1098: must be set in csr3, whereas on the decstation, csr3 remains clear. ! 1099: ! 1100: Arguments: ! 1101: ! 1102: Adapter - The adapter for the SONIC to stop. ! 1103: ! 1104: Return Value: ! 1105: ! 1106: None. ! 1107: ! 1108: --*/ ! 1109: ! 1110: { ! 1111: ! 1112: SONIC_WRITE_PORT(Adapter, SONIC_COMMAND, ! 1113: SONIC_CR_RECEIVER_DISABLE | ! 1114: SONIC_CR_SOFTWARE_RESET ! 1115: ); ! 1116: ! 1117: } ! 1118: ! 1119: extern ! 1120: VOID ! 1121: SonicStartCamReload( ! 1122: IN PSONIC_ADAPTER Adapter ! 1123: ) ! 1124: ! 1125: /*++ ! 1126: ! 1127: Routine Description: ! 1128: ! 1129: This routine starts a CAM reload, which will cause an ! 1130: interrupt when it is done. ! 1131: ! 1132: Arguments: ! 1133: ! 1134: Adapter - The adapter for the SONIC to reload. ! 1135: ! 1136: Return Value: ! 1137: ! 1138: None. ! 1139: ! 1140: --*/ ! 1141: ! 1142: { ! 1143: ! 1144: // ! 1145: // Move CAM Enable into the appropriate spot. ! 1146: // ! 1147: ! 1148: SONIC_LOAD_CAM_ENABLE( ! 1149: &Adapter->CamDescriptorArea->CamFragments[ ! 1150: Adapter->CamDescriptorAreaSize], ! 1151: Adapter->CamDescriptorArea->CamEnable ! 1152: ); ! 1153: ! 1154: ! 1155: // ! 1156: // Flush the CAM before we start the reload. ! 1157: // ! 1158: ! 1159: SONIC_FLUSH_WRITE_BUFFER(Adapter->CamDescriptorAreaFlushBuffer); ! 1160: ! 1161: ! 1162: SONIC_WRITE_PORT(Adapter, SONIC_CAM_DESCRIPTOR, ! 1163: SONIC_GET_LOW_PART_ADDRESS(Adapter->CamDescriptorAreaPhysical) ! 1164: ); ! 1165: ! 1166: SONIC_WRITE_PORT(Adapter, SONIC_CAM_DESCRIPTOR_COUNT, ! 1167: (USHORT)Adapter->CamDescriptorAreaSize ! 1168: ); ! 1169: ! 1170: ! 1171: // ! 1172: // Start the Load CAM, which will cause an interrupt ! 1173: // when it is done. ! 1174: // ! 1175: ! 1176: SONIC_WRITE_PORT(Adapter, SONIC_COMMAND, ! 1177: SONIC_CR_LOAD_CAM ! 1178: ); ! 1179: ! 1180: } ! 1181: ! 1182: STATIC ! 1183: NDIS_STATUS ! 1184: SonicOpenAdapter( ! 1185: OUT PNDIS_STATUS OpenErrorStatus, ! 1186: OUT NDIS_HANDLE *MacBindingHandle, ! 1187: OUT PUINT SelectedMediumIndex, ! 1188: IN PNDIS_MEDIUM MediumArray, ! 1189: IN UINT MediumArraySize, ! 1190: IN NDIS_HANDLE NdisBindingContext, ! 1191: IN NDIS_HANDLE MacAdapterContext, ! 1192: IN UINT OpenOptions, ! 1193: IN PSTRING AddressingInformation OPTIONAL ! 1194: ) ! 1195: ! 1196: /*++ ! 1197: ! 1198: Routine Description: ! 1199: ! 1200: This routine is used to create an open instance of an adapter, in effect ! 1201: creating a binding between an upper-level module and the MAC module over ! 1202: the adapter. ! 1203: ! 1204: Arguments: ! 1205: ! 1206: OpenErrorStatus - Returns more information in some cases. ! 1207: ! 1208: MacBindingHandle - A pointer to a location in which the MAC stores ! 1209: a context value that it uses to represent this binding. ! 1210: ! 1211: SelectedMediumIndex - A pointer to a location in which the MAC stores ! 1212: the medium selected out of MediumArray. ! 1213: ! 1214: MediumArray - An array of media that the protocol can support. ! 1215: ! 1216: MediumArraySize - The number of elements in MediumArray. ! 1217: ! 1218: NdisBindingContext - A value to be recorded by the MAC and passed as ! 1219: context whenever an indication is delivered by the MAC for this binding. ! 1220: ! 1221: MacAdapterContext - The value associated with the adapter that is being ! 1222: opened when the MAC registered the adapter with NdisRegisterAdapter. ! 1223: ! 1224: OpenOptions - A bit mask containing flags with information about this ! 1225: binding. ! 1226: ! 1227: AddressingInformation - An optional pointer to a variable length string ! 1228: containing hardware-specific information that can be used to program the ! 1229: device. (This is not used by this MAC.) ! 1230: ! 1231: Return Value: ! 1232: ! 1233: The function value is the status of the operation. If the MAC does not ! 1234: complete this request synchronously, the value would be ! 1235: NDIS_STATUS_PENDING. ! 1236: ! 1237: ! 1238: --*/ ! 1239: ! 1240: { ! 1241: ! 1242: // ! 1243: // The SONIC_ADAPTER that this open binding should belong too. ! 1244: // ! 1245: PSONIC_ADAPTER Adapter; ! 1246: ! 1247: // ! 1248: // Holds the status that should be returned to the caller. ! 1249: // ! 1250: NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS; ! 1251: ! 1252: // ! 1253: // Simple iteration variable, for scanning the medium array. ! 1254: // ! 1255: UINT i; ! 1256: ! 1257: // ! 1258: // Pointer to the space allocated for the binding. ! 1259: // ! 1260: PSONIC_OPEN NewOpen; ! 1261: ! 1262: // ! 1263: // Points to the MacReserved section of NewOpen->OpenCloseRequest. ! 1264: // ! 1265: PSONIC_REQUEST_RESERVED Reserved; ! 1266: ! 1267: ! 1268: // ! 1269: // If we are being removed, don't allow new opens. ! 1270: // ! 1271: ! 1272: Adapter = PSONIC_ADAPTER_FROM_CONTEXT_HANDLE(MacAdapterContext); ! 1273: ! 1274: if (Adapter->Removed) { ! 1275: return NDIS_STATUS_FAILURE; ! 1276: } ! 1277: ! 1278: ! 1279: // ! 1280: // Search for the 802.3 media type ! 1281: // ! 1282: ! 1283: for (i=0; i<MediumArraySize; i++) { ! 1284: ! 1285: if (MediumArray[i] == NdisMedium802_3) { ! 1286: break; ! 1287: } ! 1288: ! 1289: } ! 1290: ! 1291: if (i == MediumArraySize) { ! 1292: ! 1293: return NDIS_STATUS_UNSUPPORTED_MEDIA; ! 1294: ! 1295: } ! 1296: ! 1297: *SelectedMediumIndex = i; ! 1298: ! 1299: ! 1300: NdisAcquireSpinLock(&Adapter->Lock); ! 1301: Adapter->References++; ! 1302: ! 1303: NdisReleaseSpinLock(&Adapter->Lock); ! 1304: ! 1305: // ! 1306: // Allocate the space for the open binding. Fill in the fields. ! 1307: // ! 1308: ! 1309: SONIC_ALLOC_MEMORY(&StatusToReturn, &NewOpen, sizeof(SONIC_OPEN)); ! 1310: ! 1311: if (StatusToReturn == NDIS_STATUS_SUCCESS) { ! 1312: ! 1313: *MacBindingHandle = BINDING_HANDLE_FROM_PSONIC_OPEN(NewOpen); ! 1314: InitializeListHead(&NewOpen->OpenList); ! 1315: NewOpen->NdisBindingContext = NdisBindingContext; ! 1316: NewOpen->References = 1; ! 1317: NewOpen->BindingShuttingDown = FALSE; ! 1318: NewOpen->OwningSonic = Adapter; ! 1319: ! 1320: NewOpen->OpenCloseRequest.RequestType = NdisRequestOpen; ! 1321: Reserved = PSONIC_RESERVED_FROM_REQUEST(&NewOpen->OpenCloseRequest); ! 1322: Reserved->OpenBlock = NewOpen; ! 1323: Reserved->Next = (PNDIS_REQUEST)NULL; ! 1324: ! 1325: NdisAcquireSpinLock(&Adapter->Lock); ! 1326: ! 1327: SonicQueueRequest(Adapter, &NewOpen->OpenCloseRequest); ! 1328: ! 1329: StatusToReturn = NDIS_STATUS_PENDING; ! 1330: ! 1331: } else { ! 1332: ! 1333: NdisWriteErrorLogEntry( ! 1334: Adapter->NdisAdapterHandle, ! 1335: NDIS_ERROR_CODE_OUT_OF_RESOURCES, ! 1336: 2, ! 1337: openAdapter, ! 1338: SONIC_ERRMSG_ALLOC_OPEN ! 1339: ); ! 1340: ! 1341: ! 1342: NdisAcquireSpinLock(&Adapter->Lock); ! 1343: ! 1344: } ! 1345: ! 1346: ! 1347: // ! 1348: // This macro assumes it is called with the lock held, ! 1349: // and releases it. ! 1350: // ! 1351: ! 1352: SONIC_DO_DEFERRED(Adapter); ! 1353: return StatusToReturn; ! 1354: } ! 1355: ! 1356: STATIC ! 1357: NDIS_STATUS ! 1358: SonicCloseAdapter( ! 1359: IN NDIS_HANDLE MacBindingHandle ! 1360: ) ! 1361: ! 1362: /*++ ! 1363: ! 1364: Routine Description: ! 1365: ! 1366: This routine causes the MAC to close an open handle (binding). ! 1367: ! 1368: Arguments: ! 1369: ! 1370: MacBindingHandle - The context value returned by the MAC when the ! 1371: adapter was opened. In reality it is a PSONIC_OPEN. ! 1372: ! 1373: Return Value: ! 1374: ! 1375: The function value is the status of the operation. ! 1376: ! 1377: ! 1378: --*/ ! 1379: ! 1380: { ! 1381: ! 1382: // ! 1383: // The SONIC_ADAPTER that this open binding should belong too. ! 1384: // ! 1385: PSONIC_ADAPTER Adapter; ! 1386: ! 1387: // ! 1388: // Holds the status that should be returned to the caller. ! 1389: // ! 1390: NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS; ! 1391: ! 1392: // ! 1393: // Pointer to the space allocated for the binding. ! 1394: // ! 1395: PSONIC_OPEN Open; ! 1396: ! 1397: ! 1398: Adapter = PSONIC_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle); ! 1399: ! 1400: // ! 1401: // Hold the lock while we update the reference counts for the ! 1402: // adapter and the open. ! 1403: // ! 1404: ! 1405: NdisAcquireSpinLock(&Adapter->Lock); ! 1406: Adapter->References++; ! 1407: ! 1408: Open = PSONIC_OPEN_FROM_BINDING_HANDLE(MacBindingHandle); ! 1409: ! 1410: // ! 1411: // Don't do anything if this binding is already closing. ! 1412: // ! 1413: ! 1414: if (!Open->BindingShuttingDown) { ! 1415: ! 1416: PSONIC_REQUEST_RESERVED Reserved = PSONIC_RESERVED_FROM_REQUEST(&Open->OpenCloseRequest); ! 1417: ! 1418: Open->OpenCloseRequest.RequestType = NdisRequestClose; ! 1419: Reserved->OpenBlock = Open; ! 1420: Reserved->Next = (PNDIS_REQUEST)NULL; ! 1421: ! 1422: ++Open->References; ! 1423: ! 1424: SonicQueueRequest(Adapter, &Open->OpenCloseRequest); ! 1425: ! 1426: // ! 1427: // Remove the creation reference. ! 1428: // ! 1429: ! 1430: --Open->References; ! 1431: ! 1432: StatusToReturn = NDIS_STATUS_PENDING; ! 1433: ! 1434: } else { ! 1435: ! 1436: StatusToReturn = NDIS_STATUS_CLOSING; ! 1437: ! 1438: } ! 1439: ! 1440: // ! 1441: // This macro assumes it is called with the lock held, ! 1442: // and releases it. ! 1443: // ! 1444: ! 1445: SONIC_DO_DEFERRED(Adapter); ! 1446: return StatusToReturn; ! 1447: ! 1448: } ! 1449: ! 1450: STATIC ! 1451: VOID ! 1452: SonicUnload( ! 1453: IN NDIS_HANDLE MacMacContext ! 1454: ) ! 1455: ! 1456: /*++ ! 1457: ! 1458: Routine Description: ! 1459: ! 1460: SonicUnload is called when the MAC is to unload itself. ! 1461: ! 1462: Arguments: ! 1463: ! 1464: None. ! 1465: ! 1466: Return Value: ! 1467: ! 1468: None. ! 1469: ! 1470: --*/ ! 1471: ! 1472: { ! 1473: ! 1474: NDIS_STATUS Status; ! 1475: ! 1476: PSONIC_MAC SonicMac = (PSONIC_MAC)MacMacContext; ! 1477: ! 1478: ! 1479: NdisDeregisterMac( ! 1480: &Status, ! 1481: SonicMac->MacHandle ! 1482: ); ! 1483: ! 1484: NdisTerminateWrapper( ! 1485: SonicMac->WrapperHandle, ! 1486: NULL ! 1487: ); ! 1488: ! 1489: return; ! 1490: ! 1491: } ! 1492: ! 1493: ! 1494: STATIC ! 1495: NDIS_STATUS ! 1496: SonicAddAdapter( ! 1497: IN NDIS_HANDLE MacMacContext, ! 1498: IN NDIS_HANDLE ConfigurationHandle, ! 1499: IN PNDIS_STRING AdapterName ! 1500: ) ! 1501: ! 1502: /*++ ! 1503: ! 1504: Routine Description: ! 1505: ! 1506: SonicAddAdapter adds an adapter to the list supported ! 1507: by this MAC. ! 1508: ! 1509: Arguments: ! 1510: ! 1511: MacMacContext - The context passed to NdisRegisterMac (will be NULL). ! 1512: ! 1513: ConfigurationHandle - A handle to pass to NdisOpenConfiguration. ! 1514: ! 1515: AdapterName - The name to register with via NdisRegisterAdapter. ! 1516: ! 1517: Return Value: ! 1518: ! 1519: NDIS_STATUS_SUCCESS ! 1520: NDIS_STATUS_PENDING ! 1521: ! 1522: --*/ ! 1523: ! 1524: { ! 1525: ! 1526: NDIS_STATUS Status = NDIS_STATUS_SUCCESS; ! 1527: PSONIC_MAC SonicMac = (PSONIC_MAC)MacMacContext; ! 1528: NDIS_HANDLE ConfigHandle; ! 1529: NDIS_STRING AdapterTypeString = NDIS_STRING_CONST("AdapterType"); ! 1530: #ifdef SONIC_INTERNAL ! 1531: NDIS_STRING MultifunctionAdapterString = NDIS_STRING_CONST("MultifunctionAdapter"); ! 1532: NDIS_STRING NetworkControllerString = NDIS_STRING_CONST("NetworkController"); ! 1533: #endif ! 1534: PNDIS_CONFIGURATION_PARAMETER ReturnedValue; ! 1535: PUCHAR NetworkAddress; ! 1536: UINT NetworkAddressLength; ! 1537: UCHAR AdapterType; ! 1538: UINT InterruptVector; ! 1539: UINT InterruptLevel; ! 1540: NDIS_INTERRUPT_MODE InterruptMode; ! 1541: UINT SlotNumber; ! 1542: UINT Controller = 0; ! 1543: UINT MultifunctionAdapter = 0; ! 1544: ! 1545: // ! 1546: // Open the configuration info. ! 1547: // ! 1548: ! 1549: NdisOpenConfiguration( ! 1550: &Status, ! 1551: &ConfigHandle, ! 1552: ConfigurationHandle ! 1553: ); ! 1554: ! 1555: if (Status != NDIS_STATUS_SUCCESS) { ! 1556: return Status; ! 1557: } ! 1558: ! 1559: ! 1560: // ! 1561: // Check that adapter type is supported. ! 1562: // The default depends on the processor type. ! 1563: // ! 1564: ! 1565: AdapterType = SONIC_ADAPTER_TYPE_DEFAULT; ! 1566: ! 1567: NdisReadConfiguration( ! 1568: &Status, ! 1569: &ReturnedValue, ! 1570: ConfigHandle, ! 1571: &AdapterTypeString, ! 1572: NdisParameterInteger ! 1573: ); ! 1574: ! 1575: if (Status == NDIS_STATUS_SUCCESS) { ! 1576: ! 1577: // ! 1578: // See if the adapter type is valid. We skip to AdapterTypeRecognized ! 1579: // if the AdapterType is known to this driver. ! 1580: // ! 1581: ! 1582: #ifdef SONIC_EISA ! 1583: if (ReturnedValue->ParameterData.IntegerData == SONIC_ADAPTER_TYPE_EISA) { ! 1584: goto AdapterTypeRecognized; ! 1585: } ! 1586: #endif ! 1587: ! 1588: #ifdef SONIC_INTERNAL ! 1589: if (ReturnedValue->ParameterData.IntegerData == SONIC_ADAPTER_TYPE_INTERNAL) { ! 1590: goto AdapterTypeRecognized; ! 1591: } ! 1592: #endif ! 1593: ! 1594: // ! 1595: // Card type not supported by this driver ! 1596: // ! 1597: ! 1598: #if DBG ! 1599: DbgPrint("SONIC: Error in adapter type: %lx\n", ReturnedValue->ParameterData.IntegerData); ! 1600: #endif ! 1601: NdisCloseConfiguration(ConfigHandle); ! 1602: return NDIS_STATUS_FAILURE; ! 1603: ! 1604: ! 1605: AdapterTypeRecognized: ! 1606: ! 1607: AdapterType = (UCHAR)ReturnedValue->ParameterData.IntegerData; ! 1608: } ! 1609: ! 1610: switch (AdapterType) { ! 1611: ! 1612: #ifdef SONIC_EISA ! 1613: ! 1614: case SONIC_ADAPTER_TYPE_EISA: ! 1615: { ! 1616: ! 1617: NDIS_EISA_FUNCTION_INFORMATION EisaData; ! 1618: USHORT Portzc88; ! 1619: UCHAR zc88Value; ! 1620: UCHAR Mask; ! 1621: UCHAR InitType; ! 1622: UCHAR PortValue; ! 1623: USHORT PortAddress; ! 1624: PUCHAR CurrentChar; ! 1625: BOOLEAN LastEntry; ! 1626: ! 1627: NdisReadEisaSlotInformation( ! 1628: &Status, ! 1629: ConfigurationHandle, ! 1630: &SlotNumber, ! 1631: &EisaData ! 1632: ); ! 1633: ! 1634: if (Status != NDIS_STATUS_SUCCESS) { ! 1635: ! 1636: #if DBG ! 1637: DbgPrint("SONIC: Could not read EISA data\n"); ! 1638: #endif ! 1639: NdisCloseConfiguration(ConfigHandle); ! 1640: return NDIS_STATUS_FAILURE; ! 1641: ! 1642: } ! 1643: ! 1644: CurrentChar = EisaData.InitializationData; ! 1645: ! 1646: Portzc88 = (SlotNumber << 12) + 0xc88; ! 1647: ! 1648: LastEntry = FALSE; ! 1649: while (!LastEntry) { ! 1650: InitType = *(CurrentChar++); ! 1651: PortAddress = *((USHORT UNALIGNED *)CurrentChar); ! 1652: CurrentChar += sizeof(USHORT); ! 1653: ! 1654: if ((InitType & 0x80) == 0) { ! 1655: LastEntry = TRUE; ! 1656: } ! 1657: ! 1658: PortValue = *(CurrentChar++); ! 1659: ! 1660: if (InitType & 0x40) { ! 1661: Mask = *(CurrentChar++); ! 1662: } else { ! 1663: Mask = 0; ! 1664: } ! 1665: ! 1666: // ! 1667: // The only port we care about is zc88 (z is the ! 1668: // slot number) since it has the interrupt in it. ! 1669: // ! 1670: ! 1671: if (PortAddress != Portzc88) { ! 1672: continue; ! 1673: } ! 1674: ! 1675: zc88Value &= Mask; ! 1676: zc88Value |= PortValue; ! 1677: ! 1678: } ! 1679: ! 1680: switch ((zc88Value & 0x06) >> 1) { ! 1681: case 0: ! 1682: InterruptVector = 5; break; ! 1683: case 1: ! 1684: InterruptVector = 9; break; ! 1685: case 2: ! 1686: InterruptVector = 10; break; ! 1687: case 3: ! 1688: InterruptVector = 11; break; ! 1689: } ! 1690: ! 1691: InterruptLevel = InterruptVector; ! 1692: ! 1693: if ((zc88Value & 0x01) != 0) { ! 1694: InterruptMode = NdisInterruptLatched; ! 1695: } else { ! 1696: InterruptMode = NdisInterruptLevelSensitive; ! 1697: } ! 1698: ! 1699: break; ! 1700: ! 1701: } ! 1702: ! 1703: #endif // SONIC_EISA ! 1704: ! 1705: #ifdef SONIC_INTERNAL ! 1706: ! 1707: case SONIC_ADAPTER_TYPE_INTERNAL: ! 1708: { ! 1709: ! 1710: // ! 1711: // For the internal adapter, we read the MultifunctionAdapter number ! 1712: // and NetworkController number, which are both optional. For ! 1713: // passing to SonicRegisterAdapter. ! 1714: // ! 1715: ! 1716: NdisReadConfiguration( ! 1717: &Status, ! 1718: &ReturnedValue, ! 1719: ConfigHandle, ! 1720: &MultifunctionAdapterString, ! 1721: NdisParameterInteger ! 1722: ); ! 1723: ! 1724: if (Status == NDIS_STATUS_SUCCESS) { ! 1725: ! 1726: MultifunctionAdapter = ReturnedValue->ParameterData.IntegerData; ! 1727: ! 1728: } ! 1729: ! 1730: NdisReadConfiguration( ! 1731: &Status, ! 1732: &ReturnedValue, ! 1733: ConfigHandle, ! 1734: &NetworkControllerString, ! 1735: NdisParameterInteger ! 1736: ); ! 1737: ! 1738: if (Status == NDIS_STATUS_SUCCESS) { ! 1739: ! 1740: Controller = ReturnedValue->ParameterData.IntegerData; ! 1741: ! 1742: } ! 1743: ! 1744: // ! 1745: // These are filled in by SonicHardwareGetDetails. ! 1746: // ! 1747: ! 1748: InterruptVector = 0; ! 1749: InterruptLevel = 0; ! 1750: ! 1751: // ! 1752: // The internal adapter is level-sensitive. ! 1753: // ! 1754: ! 1755: InterruptMode = NdisInterruptLevelSensitive; ! 1756: ! 1757: break; ! 1758: ! 1759: } ! 1760: ! 1761: #endif // SONIC_INTERNAL ! 1762: ! 1763: default: ! 1764: ! 1765: ASSERT(FALSE); ! 1766: break; ! 1767: ! 1768: } ! 1769: ! 1770: ! 1771: // ! 1772: // Read network address ! 1773: // ! 1774: ! 1775: NdisReadNetworkAddress( ! 1776: &Status, ! 1777: (PVOID *)&NetworkAddress, ! 1778: &NetworkAddressLength, ! 1779: ConfigHandle); ! 1780: ! 1781: ! 1782: // ! 1783: // Make sure that the address is the right length asnd ! 1784: // at least one of the bytes is non-zero. ! 1785: // ! 1786: ! 1787: if ((Status == NDIS_STATUS_SUCCESS) && ! 1788: (NetworkAddressLength == ETH_LENGTH_OF_ADDRESS) && ! 1789: ((NetworkAddress[0] | ! 1790: NetworkAddress[1] | ! 1791: NetworkAddress[2] | ! 1792: NetworkAddress[3] | ! 1793: NetworkAddress[4] | ! 1794: NetworkAddress[5]) != 0)) { ! 1795: ! 1796: #if DBG ! 1797: if (SonicDbg) { ! 1798: DbgPrint("SONIC: New Address = %.2x-%.2x-%.2x-%.2x-%.2x-%.2x\n", ! 1799: NetworkAddress[0], ! 1800: NetworkAddress[1], ! 1801: NetworkAddress[2], ! 1802: NetworkAddress[3], ! 1803: NetworkAddress[4], ! 1804: NetworkAddress[5]); ! 1805: } ! 1806: #endif ! 1807: ! 1808: } else { ! 1809: ! 1810: // ! 1811: // Tells SonicRegisterAdapter to use the ! 1812: // burned-in address. ! 1813: // ! 1814: ! 1815: NetworkAddress = NULL; ! 1816: ! 1817: } ! 1818: ! 1819: // ! 1820: // Used passed-in adapter name to register. ! 1821: // ! 1822: ! 1823: Status = SonicRegisterAdapter( ! 1824: SonicMac->MacHandle, ! 1825: ConfigurationHandle, ! 1826: AdapterName, ! 1827: NetworkAddress, ! 1828: AdapterType, ! 1829: SlotNumber, ! 1830: Controller, ! 1831: MultifunctionAdapter, ! 1832: InterruptVector, ! 1833: InterruptLevel, ! 1834: InterruptMode, ! 1835: 32); ! 1836: ! 1837: ! 1838: NdisCloseConfiguration(ConfigHandle); ! 1839: ! 1840: ! 1841: return Status; // should be NDIS_STATUS_SUCCESS ! 1842: ! 1843: } ! 1844: ! 1845: STATIC ! 1846: VOID ! 1847: SonicRemoveAdapter( ! 1848: IN NDIS_HANDLE MacAdapterContext ! 1849: ) ! 1850: ! 1851: /*++ ! 1852: ! 1853: Routine Description: ! 1854: ! 1855: SonicRemoveAdapter removes an adapter previously registered ! 1856: with NdisRegisterAdapter. ! 1857: ! 1858: Arguments: ! 1859: ! 1860: MacAdapterContext - The context value that the MAC passed ! 1861: to NdisRegisterAdapter; actually as pointer to a ! 1862: SONIC_ADAPTER. ! 1863: ! 1864: Return Value: ! 1865: ! 1866: None. ! 1867: ! 1868: --*/ ! 1869: ! 1870: { ! 1871: PSONIC_ADAPTER Adapter; ! 1872: BOOLEAN Canceled; ! 1873: ! 1874: Adapter = PSONIC_ADAPTER_FROM_CONTEXT_HANDLE(MacAdapterContext); ! 1875: ! 1876: Adapter->Removed = TRUE; ! 1877: ! 1878: // ! 1879: // Stop the chip. ! 1880: // ! 1881: ! 1882: SonicStopChip (Adapter); ! 1883: ! 1884: NdisDeregisterAdapterShutdownHandler(Adapter->NdisAdapterHandle); ! 1885: ! 1886: ASSERT (Adapter->OpenCount == 0); ! 1887: ! 1888: // ! 1889: // There are no opens left, so remove ourselves. ! 1890: // ! 1891: ! 1892: // ! 1893: // Stop the deadman timer ! 1894: // ! 1895: ! 1896: NdisCancelTimer(&Adapter->WakeUpTimer, &Canceled); ! 1897: ! 1898: if ( !Canceled ) { ! 1899: NdisStallExecution(500000); ! 1900: } ! 1901: ! 1902: NdisRemoveInterrupt(&Adapter->Interrupt); ! 1903: ! 1904: EthDeleteFilter(Adapter->FilterDB); ! 1905: ! 1906: DeleteAdapterMemory(Adapter); ! 1907: NdisDeregisterAdapter(Adapter->NdisAdapterHandle); ! 1908: ! 1909: NdisFreeSpinLock(&Adapter->Lock); ! 1910: SONIC_FREE_MEMORY(Adapter, sizeof(SONIC_ADAPTER)); ! 1911: ! 1912: } ! 1913: ! 1914: STATIC ! 1915: NDIS_STATUS ! 1916: SonicReset( ! 1917: IN NDIS_HANDLE MacBindingHandle ! 1918: ) ! 1919: ! 1920: /*++ ! 1921: ! 1922: Routine Description: ! 1923: ! 1924: The SonicReset request instructs the MAC to issue a hardware reset ! 1925: to the network adapter. The MAC also resets its software state. See ! 1926: the description of NdisReset for a detailed description of this request. ! 1927: ! 1928: Arguments: ! 1929: ! 1930: MacBindingHandle - The context value returned by the MAC when the ! 1931: adapter was opened. In reality, it is a pointer to SONIC_OPEN. ! 1932: ! 1933: Return Value: ! 1934: ! 1935: The function value is the status of the operation. ! 1936: ! 1937: ! 1938: --*/ ! 1939: ! 1940: { ! 1941: ! 1942: // ! 1943: // Holds the status that should be returned to the caller. ! 1944: // ! 1945: NDIS_STATUS StatusToReturn = NDIS_STATUS_PENDING; ! 1946: ! 1947: PSONIC_ADAPTER Adapter = ! 1948: PSONIC_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle); ! 1949: ! 1950: // ! 1951: // Hold the locks while we update the reference counts on the ! 1952: // adapter and the open. ! 1953: // ! 1954: ! 1955: if (Adapter->Removed) { ! 1956: ! 1957: return(NDIS_STATUS_FAILURE); ! 1958: ! 1959: } ! 1960: ! 1961: NdisAcquireSpinLock(&Adapter->Lock); ! 1962: ! 1963: Adapter->References++; ! 1964: ! 1965: if (!Adapter->ResetInProgress && !Adapter->IndicatingResetStart) { ! 1966: ! 1967: PSONIC_OPEN Open; ! 1968: ! 1969: Open = PSONIC_OPEN_FROM_BINDING_HANDLE(MacBindingHandle); ! 1970: ! 1971: if (!Open->BindingShuttingDown) { ! 1972: ! 1973: Adapter->IndicatingResetStart = TRUE; ! 1974: ! 1975: if (!Adapter->IndicatingResetEnd) { ! 1976: ! 1977: // ! 1978: // Loop through, indicating RESET_START; we ! 1979: // don't bother with the StatusComplete ! 1980: // indication until RESET_END is indicated. ! 1981: // ! 1982: ! 1983: PSONIC_OPEN Open; ! 1984: PLIST_ENTRY CurrentLink; ! 1985: ! 1986: CurrentLink = Adapter->OpenBindings.Flink; ! 1987: ! 1988: while (CurrentLink != &Adapter->OpenBindings) { ! 1989: ! 1990: Open = CONTAINING_RECORD( ! 1991: CurrentLink, ! 1992: SONIC_OPEN, ! 1993: OpenList ! 1994: ); ! 1995: ! 1996: Open->References++; ! 1997: NdisReleaseSpinLock(&Adapter->Lock); ! 1998: ! 1999: NdisIndicateStatus( ! 2000: Open->NdisBindingContext, ! 2001: NDIS_STATUS_RESET_START, ! 2002: NULL, ! 2003: 0 ! 2004: ); ! 2005: ! 2006: NdisAcquireSpinLock(&Adapter->Lock); ! 2007: Open->References--; ! 2008: ! 2009: CurrentLink = CurrentLink->Flink; ! 2010: ! 2011: } ! 2012: ! 2013: ! 2014: Adapter->IndicatingResetStart = FALSE; ! 2015: ! 2016: SetupForReset( ! 2017: Adapter, ! 2018: PSONIC_OPEN_FROM_BINDING_HANDLE(MacBindingHandle) ! 2019: ); ! 2020: } ! 2021: ! 2022: Open->References++; ! 2023: Adapter->ResettingOpen = Open; ! 2024: ! 2025: StatusToReturn = NDIS_STATUS_PENDING; ! 2026: ! 2027: } else { ! 2028: ! 2029: StatusToReturn = NDIS_STATUS_CLOSING; ! 2030: ! 2031: } ! 2032: ! 2033: } else { ! 2034: ! 2035: StatusToReturn = NDIS_STATUS_RESET_IN_PROGRESS; ! 2036: ! 2037: } ! 2038: ! 2039: ! 2040: // ! 2041: // This macro assumes it is called with the lock held, ! 2042: // and releases it. ! 2043: // ! 2044: ! 2045: SONIC_DO_DEFERRED(Adapter); ! 2046: return StatusToReturn; ! 2047: ! 2048: } ! 2049: ! 2050: #if 0 ! 2051: STATIC ! 2052: UINT ! 2053: CalculateCRC( ! 2054: IN UINT NumberOfBytes, ! 2055: IN PCHAR Input ! 2056: ) ! 2057: ! 2058: /*++ ! 2059: ! 2060: Routine Description: ! 2061: ! 2062: Calculates a 32 bit crc value over the input number of bytes. ! 2063: ! 2064: NOTE: This routine assumes UINTs are 32 bits. ! 2065: ! 2066: Arguments: ! 2067: ! 2068: NumberOfBytes - The number of bytes in the input. ! 2069: ! 2070: Input - An input "string" to calculate a CRC over. ! 2071: ! 2072: Return Value: ! 2073: ! 2074: A 32 bit crc value. ! 2075: ! 2076: ! 2077: --*/ ! 2078: ! 2079: { ! 2080: ! 2081: const UINT POLY = 0x04c11db6; ! 2082: UINT CRCValue = 0xffffffff; ! 2083: ! 2084: ASSERT(sizeof(UINT) == 4); ! 2085: ! 2086: for ( ! 2087: ; ! 2088: NumberOfBytes; ! 2089: NumberOfBytes-- ! 2090: ) { ! 2091: ! 2092: UINT CurrentBit; ! 2093: UCHAR CurrentByte = *Input; ! 2094: Input++; ! 2095: ! 2096: for ( ! 2097: CurrentBit = 8; ! 2098: CurrentBit; ! 2099: CurrentBit-- ! 2100: ) { ! 2101: ! 2102: UINT CurrentCRCHigh = CRCValue >> 31; ! 2103: ! 2104: CRCValue <<= 1; ! 2105: ! 2106: if (CurrentCRCHigh ^ (CurrentByte & 0x01)) { ! 2107: ! 2108: CRCValue ^= POLY; ! 2109: CRCValue |= 0x00000001; ! 2110: ! 2111: } ! 2112: ! 2113: CurrentByte >>= 1; ! 2114: ! 2115: } ! 2116: ! 2117: } ! 2118: ! 2119: return CRCValue; ! 2120: ! 2121: } ! 2122: #endif ! 2123: ! 2124: extern ! 2125: VOID ! 2126: StartAdapterReset( ! 2127: IN PSONIC_ADAPTER Adapter ! 2128: ) ! 2129: ! 2130: /*++ ! 2131: ! 2132: Routine Description: ! 2133: ! 2134: This is the first phase of resetting the adapter hardware. ! 2135: ! 2136: It makes the following assumptions: ! 2137: ! 2138: 1) That the hardware has been stopped. ! 2139: ! 2140: 2) That it can not be preempted. ! 2141: ! 2142: 3) That no other adapter activity can occur. ! 2143: ! 2144: When this routine is finished all of the adapter information ! 2145: will be as if the driver was just initialized. ! 2146: ! 2147: Arguments: ! 2148: ! 2149: Adapter - The adapter whose hardware is to be reset. ! 2150: ! 2151: Return Value: ! 2152: ! 2153: None. ! 2154: ! 2155: --*/ ! 2156: { ! 2157: ! 2158: // ! 2159: // These are used for cleaning the rings. ! 2160: // ! 2161: ! 2162: PSONIC_RECEIVE_DESCRIPTOR CurrentReceiveDescriptor; ! 2163: PSONIC_TRANSMIT_DESCRIPTOR CurrentTransmitDescriptor; ! 2164: UINT i; ! 2165: SONIC_PHYSICAL_ADDRESS SonicPhysicalAdr; ! 2166: ! 2167: ! 2168: // ! 2169: // Shut down the chip. We won't be doing any more work until ! 2170: // the reset is complete. ! 2171: // ! 2172: ! 2173: SonicStopChip(Adapter); ! 2174: ! 2175: // ! 2176: // Once the chip is stopped we can't get any more interrupts. ! 2177: // Any interrupts that are "queued" for processing could ! 2178: // only possibly service this reset. It is therefore safe for ! 2179: // us to clear the adapter global csr value. ! 2180: // ! 2181: Adapter->IsrValue = 0; ! 2182: ! 2183: ! 2184: Adapter->LastTransmitDescriptor = ! 2185: Adapter->TransmitDescriptorArea + ! 2186: (Adapter->NumberOfTransmitDescriptors-1); ! 2187: Adapter->NumberOfAvailableDescriptors = ! 2188: Adapter->NumberOfTransmitDescriptors; ! 2189: Adapter->AllocateableDescriptor = ! 2190: Adapter->TransmitDescriptorArea; ! 2191: Adapter->TransmittingDescriptor = ! 2192: Adapter->TransmitDescriptorArea; ! 2193: Adapter->FirstUncommittedDescriptor = ! 2194: Adapter->TransmitDescriptorArea; ! 2195: Adapter->PacketsSinceLastInterrupt = 0; ! 2196: ! 2197: Adapter->CurrentReceiveBufferIndex = 0; ! 2198: Adapter->CurrentReceiveDescriptorIndex = 0; ! 2199: Adapter->LastReceiveDescriptor = ! 2200: &Adapter->ReceiveDescriptorArea[ ! 2201: Adapter->NumberOfReceiveDescriptors-1]; ! 2202: ! 2203: Adapter->InterruptMaskRegister = SONIC_INT_DEFAULT_VALUE; ! 2204: Adapter->ReceiveDescriptorsExhausted = FALSE; ! 2205: Adapter->ReceiveBuffersExhausted = FALSE; ! 2206: Adapter->ReceiveControlRegister = SONIC_RCR_DEFAULT_VALUE; ! 2207: ! 2208: Adapter->SendStageOpen = TRUE; ! 2209: ! 2210: Adapter->AlreadyProcessingSendStage = FALSE; ! 2211: ! 2212: // ! 2213: // Clean the receive descriptors and initialize the link ! 2214: // fields. ! 2215: // ! 2216: ! 2217: SONIC_ZERO_MEMORY( ! 2218: Adapter->ReceiveDescriptorArea, ! 2219: (sizeof(SONIC_RECEIVE_DESCRIPTOR)*Adapter->NumberOfReceiveDescriptors) ! 2220: ); ! 2221: ! 2222: for ( ! 2223: i = 0, CurrentReceiveDescriptor = Adapter->ReceiveDescriptorArea; ! 2224: i < Adapter->NumberOfReceiveDescriptors; ! 2225: i++,CurrentReceiveDescriptor++ ! 2226: ) { ! 2227: ! 2228: CurrentReceiveDescriptor->InUse = SONIC_OWNED_BY_SONIC; ! 2229: ! 2230: SonicPhysicalAdr = NdisGetPhysicalAddressLow(Adapter->ReceiveDescriptorAreaPhysical) + ! 2231: (i * sizeof(SONIC_RECEIVE_DESCRIPTOR)); ! 2232: ! 2233: if (i == 0) { ! 2234: ! 2235: Adapter->ReceiveDescriptorArea[ ! 2236: Adapter->NumberOfReceiveDescriptors-1].Link = ! 2237: SonicPhysicalAdr | SONIC_END_OF_LIST; ! 2238: ! 2239: } else { ! 2240: ! 2241: Adapter->ReceiveDescriptorArea[i-1].Link = SonicPhysicalAdr; ! 2242: ! 2243: } ! 2244: ! 2245: } ! 2246: ! 2247: ! 2248: // ! 2249: // Clean the transmit descriptors and initialize the link ! 2250: // fields. ! 2251: // ! 2252: ! 2253: SONIC_ZERO_MEMORY( ! 2254: Adapter->TransmitDescriptorArea, ! 2255: (sizeof(SONIC_TRANSMIT_DESCRIPTOR)*Adapter->NumberOfTransmitDescriptors) ! 2256: ); ! 2257: ! 2258: for ( ! 2259: i = 0, CurrentTransmitDescriptor = Adapter->TransmitDescriptorArea; ! 2260: i < Adapter->NumberOfTransmitDescriptors; ! 2261: i++,CurrentTransmitDescriptor++ ! 2262: ) { ! 2263: ! 2264: SonicPhysicalAdr = NdisGetPhysicalAddressLow(Adapter->TransmitDescriptorAreaPhysical) + ! 2265: (i * sizeof(SONIC_TRANSMIT_DESCRIPTOR)); ! 2266: ! 2267: if (i == 0) { ! 2268: ! 2269: Adapter->TransmitDescriptorArea[Adapter->NumberOfTransmitDescriptors-1].Link = SonicPhysicalAdr; ! 2270: ! 2271: } else { ! 2272: ! 2273: (CurrentTransmitDescriptor-1)->Link = SonicPhysicalAdr; ! 2274: ! 2275: } ! 2276: ! 2277: } ! 2278: ! 2279: ! 2280: // ! 2281: // Recover all of the adapter buffers. ! 2282: // ! 2283: ! 2284: { ! 2285: ! 2286: UINT i; ! 2287: ! 2288: for ( ! 2289: i = 0; ! 2290: i < (SONIC_NUMBER_OF_SMALL_BUFFERS + ! 2291: SONIC_NUMBER_OF_MEDIUM_BUFFERS + ! 2292: SONIC_NUMBER_OF_LARGE_BUFFERS); ! 2293: i++ ! 2294: ) { ! 2295: ! 2296: Adapter->SonicBuffers[i].Next = i+1; ! 2297: ! 2298: } ! 2299: ! 2300: Adapter->SonicBufferListHeads[0] = -1; ! 2301: Adapter->SonicBufferListHeads[1] = 0; ! 2302: Adapter->SonicBuffers[SONIC_NUMBER_OF_SMALL_BUFFERS-1].Next = -1; ! 2303: Adapter->SonicBufferListHeads[2] = SONIC_NUMBER_OF_SMALL_BUFFERS; ! 2304: Adapter->SonicBuffers[(SONIC_NUMBER_OF_SMALL_BUFFERS+ ! 2305: SONIC_NUMBER_OF_MEDIUM_BUFFERS)-1].Next = -1; ! 2306: Adapter->SonicBufferListHeads[3] = SONIC_NUMBER_OF_SMALL_BUFFERS + ! 2307: SONIC_NUMBER_OF_MEDIUM_BUFFERS; ! 2308: Adapter->SonicBuffers[(SONIC_NUMBER_OF_SMALL_BUFFERS+ ! 2309: SONIC_NUMBER_OF_MEDIUM_BUFFERS+ ! 2310: SONIC_NUMBER_OF_LARGE_BUFFERS)-1].Next = -1; ! 2311: ! 2312: } ! 2313: ! 2314: // ! 2315: // Go through the various transmit lists and abort every packet. ! 2316: // ! 2317: ! 2318: { ! 2319: ! 2320: UINT i; ! 2321: PNDIS_PACKET Packet; ! 2322: PSONIC_PACKET_RESERVED Reserved; ! 2323: PSONIC_OPEN Open; ! 2324: PNDIS_PACKET Next; ! 2325: ! 2326: for ( ! 2327: i = 0; ! 2328: i < 3; ! 2329: i++ ! 2330: ) { ! 2331: ! 2332: switch (i) { ! 2333: ! 2334: case 0: ! 2335: Next = Adapter->FirstLoopBack; ! 2336: break; ! 2337: case 1: ! 2338: Next = Adapter->FirstFinishTransmit; ! 2339: break; ! 2340: case 2: ! 2341: Next = Adapter->FirstSendStagePacket; ! 2342: break; ! 2343: ! 2344: } ! 2345: ! 2346: ! 2347: while (Next) { ! 2348: ! 2349: Packet = Next; ! 2350: Reserved = PSONIC_RESERVED_FROM_PACKET(Packet); ! 2351: Next = Reserved->Next; ! 2352: Open = ! 2353: PSONIC_OPEN_FROM_BINDING_HANDLE(Reserved->MacBindingHandle); ! 2354: ! 2355: // ! 2356: // The completion of the packet is one less reason ! 2357: // to keep the open around. ! 2358: // ! 2359: ! 2360: ASSERT(Open->References); ! 2361: ! 2362: NdisCompleteSend( ! 2363: Open->NdisBindingContext, ! 2364: Packet, ! 2365: NDIS_STATUS_REQUEST_ABORTED ! 2366: ); ! 2367: ! 2368: Open->References--; ! 2369: ! 2370: } ! 2371: ! 2372: } ! 2373: ! 2374: Adapter->FirstLoopBack = NULL; ! 2375: Adapter->LastLoopBack = NULL; ! 2376: Adapter->FirstFinishTransmit = NULL; ! 2377: Adapter->LastFinishTransmit = NULL; ! 2378: Adapter->FirstSendStagePacket = NULL; ! 2379: Adapter->LastSendStagePacket = NULL; ! 2380: Adapter->GeneralOptional[GO_TRANSMIT_QUEUE_LENGTH - GO_ARRAY_START] = 0; ! 2381: ! 2382: } ! 2383: ! 2384: (VOID)SetupRegistersAndInit(Adapter); ! 2385: ! 2386: } ! 2387: ! 2388: STATIC ! 2389: BOOLEAN ! 2390: SetupRegistersAndInit( ! 2391: IN PSONIC_ADAPTER Adapter ! 2392: ) ! 2393: ! 2394: /*++ ! 2395: ! 2396: Routine Description: ! 2397: ! 2398: It is this routines responsibility to make sure that the ! 2399: initialization block is filled and the chip is initialized ! 2400: *but not* started. ! 2401: ! 2402: NOTE: This routine assumes that it is called with the lock ! 2403: acquired OR that only a single thread of execution is working ! 2404: with this particular adapter. ! 2405: ! 2406: Arguments: ! 2407: ! 2408: Adapter - The adapter whose hardware is to be initialized. ! 2409: ! 2410: Return Value: ! 2411: ! 2412: TRUE if the registers are initialized successfully. ! 2413: ! 2414: --*/ ! 2415: { ! 2416: ! 2417: USHORT CommandRegister; ! 2418: UINT Time; ! 2419: ! 2420: ! 2421: SONIC_WRITE_PORT(Adapter, SONIC_DATA_CONFIGURATION, ! 2422: Adapter->DataConfigurationRegister ! 2423: ); ! 2424: ! 2425: SONIC_WRITE_PORT(Adapter, SONIC_RECEIVE_CONTROL, ! 2426: Adapter->ReceiveControlRegister ! 2427: ); ! 2428: ! 2429: SONIC_WRITE_PORT(Adapter, SONIC_INTERRUPT_MASK, ! 2430: Adapter->InterruptMaskRegister ! 2431: ); ! 2432: ! 2433: SONIC_WRITE_PORT(Adapter, SONIC_INTERRUPT_STATUS, ! 2434: (USHORT)0xffff ! 2435: ); ! 2436: ! 2437: ! 2438: ! 2439: SONIC_WRITE_PORT(Adapter, SONIC_UPPER_TRANSMIT_DESCRIPTOR, ! 2440: SONIC_GET_HIGH_PART_ADDRESS( ! 2441: NdisGetPhysicalAddressLow(Adapter->TransmitDescriptorAreaPhysical)) ! 2442: ); ! 2443: ! 2444: SONIC_WRITE_PORT(Adapter, SONIC_CURR_TRANSMIT_DESCRIPTOR, ! 2445: SONIC_GET_LOW_PART_ADDRESS( ! 2446: NdisGetPhysicalAddressLow(Adapter->TransmitDescriptorAreaPhysical)) ! 2447: ); ! 2448: ! 2449: ! 2450: SONIC_WRITE_PORT(Adapter, SONIC_UPPER_RECEIVE_DESCRIPTOR, ! 2451: SONIC_GET_HIGH_PART_ADDRESS( ! 2452: NdisGetPhysicalAddressLow(Adapter->ReceiveDescriptorAreaPhysical)) ! 2453: ); ! 2454: ! 2455: SONIC_WRITE_PORT(Adapter, SONIC_CURR_RECEIVE_DESCRIPTOR, ! 2456: SONIC_GET_LOW_PART_ADDRESS( ! 2457: NdisGetPhysicalAddressLow(Adapter->ReceiveDescriptorAreaPhysical)) ! 2458: ); ! 2459: ! 2460: ! 2461: // ! 2462: // The EOBC value cannot be odd (since the card register ! 2463: // wants it in words); in addition it appears that the ! 2464: // value in the register must be even, so this number ! 2465: // has to be a multiple of 4. ! 2466: // ! 2467: ASSERT((SONIC_END_OF_BUFFER_COUNT & 0x3) == 0); ! 2468: ! 2469: switch (Adapter->AdapterType) { ! 2470: ! 2471: #ifdef SONIC_EISA ! 2472: ! 2473: case SONIC_ADAPTER_TYPE_EISA: ! 2474: ! 2475: // ! 2476: // For the EISA card, set EOBC to 2 words more than real ! 2477: // size. ! 2478: // ! 2479: ! 2480: SONIC_WRITE_PORT(Adapter, SONIC_END_OF_BUFFER_WORD_COUNT, ! 2481: (SONIC_END_OF_BUFFER_COUNT / 2) + 2 ! 2482: ); ! 2483: break; ! 2484: ! 2485: #endif // SONIC_EISA ! 2486: ! 2487: #ifdef SONIC_INTERNAL ! 2488: ! 2489: case SONIC_ADAPTER_TYPE_INTERNAL: ! 2490: ! 2491: SONIC_WRITE_PORT(Adapter, SONIC_END_OF_BUFFER_WORD_COUNT, ! 2492: SONIC_END_OF_BUFFER_COUNT / 2 ! 2493: ); ! 2494: break; ! 2495: ! 2496: #endif // SONIC_INTERNAL ! 2497: ! 2498: default: ! 2499: ! 2500: ASSERT(FALSE); ! 2501: break; ! 2502: ! 2503: } ! 2504: ! 2505: ! 2506: SONIC_WRITE_PORT(Adapter, SONIC_UPPER_RECEIVE_RESOURCE, ! 2507: SONIC_GET_HIGH_PART_ADDRESS( ! 2508: NdisGetPhysicalAddressLow(Adapter->ReceiveResourceAreaPhysical)) ! 2509: ); ! 2510: ! 2511: SONIC_WRITE_PORT(Adapter, SONIC_RESOURCE_START, ! 2512: SONIC_GET_LOW_PART_ADDRESS( ! 2513: NdisGetPhysicalAddressLow(Adapter->ReceiveResourceAreaPhysical)) ! 2514: ); ! 2515: ! 2516: SONIC_WRITE_PORT(Adapter, SONIC_RESOURCE_END, ! 2517: (USHORT)(SONIC_GET_LOW_PART_ADDRESS( ! 2518: NdisGetPhysicalAddressLow(Adapter->ReceiveResourceAreaPhysical)) + ! 2519: sizeof(SONIC_RECEIVE_RESOURCE) * ! 2520: Adapter->NumberOfReceiveBuffers) ! 2521: ); ! 2522: ! 2523: SONIC_WRITE_PORT(Adapter, SONIC_RESOURCE_READ, ! 2524: SONIC_GET_LOW_PART_ADDRESS( ! 2525: NdisGetPhysicalAddressLow(Adapter->ReceiveResourceAreaPhysical)) ! 2526: ); ! 2527: ! 2528: SONIC_WRITE_PORT(Adapter, SONIC_RESOURCE_WRITE, ! 2529: SONIC_GET_LOW_PART_ADDRESS( ! 2530: NdisGetPhysicalAddressLow(Adapter->ReceiveResourceAreaPhysical)) ! 2531: ); ! 2532: ! 2533: ! 2534: // ! 2535: // Now take us out of reset mode... ! 2536: // ! 2537: ! 2538: SONIC_WRITE_PORT(Adapter, SONIC_COMMAND, ! 2539: 0x0000 ! 2540: ); ! 2541: ! 2542: // ! 2543: // ...and issue the Read RRA command. ! 2544: // ! 2545: ! 2546: SONIC_WRITE_PORT(Adapter, SONIC_COMMAND, ! 2547: SONIC_CR_READ_RRA ! 2548: ); ! 2549: ! 2550: ! 2551: ! 2552: // ! 2553: // Wait for 1/5 second for Read RRA to finish. ! 2554: // ! 2555: ! 2556: Time = 20; ! 2557: ! 2558: while (Time > 0) { ! 2559: ! 2560: NdisStallExecution(10000); ! 2561: ! 2562: SONIC_READ_PORT(Adapter, SONIC_COMMAND, &CommandRegister); ! 2563: if ((CommandRegister & SONIC_CR_READ_RRA) == 0) { ! 2564: break; ! 2565: } ! 2566: ! 2567: Time--; ! 2568: ! 2569: } ! 2570: ! 2571: if (Time == 0) { ! 2572: ! 2573: #if DBG ! 2574: DbgPrint("SONIC: Could not read RRA\n"); ! 2575: #endif ! 2576: return FALSE; ! 2577: ! 2578: } ! 2579: ! 2580: ! 2581: // ! 2582: // This will cause a LOAD_CAM interrupt when it is done. ! 2583: // ! 2584: ! 2585: SonicStartCamReload(Adapter); ! 2586: ! 2587: return TRUE; ! 2588: ! 2589: } ! 2590: ! 2591: extern ! 2592: VOID ! 2593: SetupForReset( ! 2594: IN PSONIC_ADAPTER Adapter, ! 2595: IN PSONIC_OPEN Open ! 2596: ) ! 2597: ! 2598: /*++ ! 2599: ! 2600: Routine Description: ! 2601: ! 2602: This routine is used to fill in the who and why a reset is ! 2603: being set up as well as setting the appropriate fields in the ! 2604: adapter. ! 2605: ! 2606: NOTE: This routine must be called with the lock acquired. ! 2607: ! 2608: Arguments: ! 2609: ! 2610: Adapter - The adapter whose hardware is to be initialized. ! 2611: ! 2612: Open - A pointer to an sonic open structure. ! 2613: ! 2614: Return Value: ! 2615: ! 2616: None. ! 2617: ! 2618: --*/ ! 2619: { ! 2620: ! 2621: PNDIS_REQUEST CurrentRequest; ! 2622: PNDIS_REQUEST * CurrentNextLocation; ! 2623: PSONIC_OPEN TmpOpen; ! 2624: ! 2625: PSONIC_REQUEST_RESERVED Reserved; ! 2626: ! 2627: // ! 2628: // Shut down the chip. We won't be doing any more work until ! 2629: // the reset is complete. We take it out of reset mode, however. ! 2630: // ! 2631: ! 2632: SonicStopChip(Adapter); ! 2633: ! 2634: ! 2635: // ! 2636: // Once the chip is stopped we can't get any more interrupts. ! 2637: // This call ensures that any ISR which is just about to run ! 2638: // will find no bits in the ISR, and any DPR which fires will ! 2639: // find nothing queued to do. ! 2640: // ! 2641: ! 2642: NdisSynchronizeWithInterrupt( ! 2643: &Adapter->Interrupt, ! 2644: SonicSynchClearIsr, ! 2645: (PVOID)Adapter); ! 2646: ! 2647: ! 2648: Adapter->ResetInProgress = TRUE; ! 2649: ! 2650: // ! 2651: // Shut down all of the transmit queues so that the ! 2652: // transmit portion of the chip will eventually calm down. ! 2653: // ! 2654: ! 2655: Adapter->SendStageOpen = FALSE; ! 2656: ! 2657: // ! 2658: // If there is a close at the top of the queue, then ! 2659: // it may be in two states: ! 2660: // ! 2661: // 1- Has interrupted, and the InterruptDpc got the ! 2662: // interrupt out of Adapter->IsrValue before we zeroed it. ! 2663: // ! 2664: // 2- Has interrupted, but we zeroed Adapter->IsrValue ! 2665: // before it read it, OR has not yet interrupted. ! 2666: // ! 2667: // In case 1, the interrupt will be processed and the ! 2668: // close will complete without our intervention. In ! 2669: // case 2, the open will not complete. In that case ! 2670: // the CAM will have been updated for that open, so ! 2671: // all that remains is for us to dereference the open ! 2672: // as would have been done in the interrupt handler. ! 2673: // ! 2674: // Closes that are not at the top of the queue we ! 2675: // leave in place; when we restart the queue after ! 2676: // the reset, they will get processed. ! 2677: // ! 2678: ! 2679: CurrentRequest = Adapter->FirstRequest; ! 2680: ! 2681: if (CurrentRequest) { ! 2682: ! 2683: Reserved = PSONIC_RESERVED_FROM_REQUEST(CurrentRequest); ! 2684: ! 2685: // ! 2686: // If the first request is a close, take it off the ! 2687: // queue, and "complete" it. ! 2688: // ! 2689: ! 2690: if (CurrentRequest->RequestType == NdisRequestClose) { ! 2691: Adapter->FirstRequest = Reserved->Next; ! 2692: --(Reserved->OpenBlock)->References; ! 2693: CurrentRequest = Adapter->FirstRequest; ! 2694: } ! 2695: ! 2696: CurrentNextLocation = &(Adapter->FirstRequest); ! 2697: ! 2698: while (CurrentRequest) { ! 2699: ! 2700: Reserved = PSONIC_RESERVED_FROM_REQUEST(CurrentRequest); ! 2701: ! 2702: if ((CurrentRequest->RequestType == NdisRequestClose) || ! 2703: (CurrentRequest->RequestType == NdisRequestOpen)) { ! 2704: ! 2705: // ! 2706: // Opens are inoffensive, we just leave them ! 2707: // on the list. Closes that were not at the ! 2708: // head of the list were not processing and ! 2709: // can be left on also. ! 2710: // ! 2711: ! 2712: CurrentNextLocation = &(Reserved->Next); ! 2713: ! 2714: } else { ! 2715: ! 2716: // ! 2717: // Not a close, remove it from the list and ! 2718: // fail it. ! 2719: // ! 2720: ! 2721: *CurrentNextLocation = Reserved->Next; ! 2722: TmpOpen = Reserved->OpenBlock; ! 2723: ! 2724: NdisReleaseSpinLock(&Adapter->Lock); ! 2725: ! 2726: NdisCompleteRequest( ! 2727: TmpOpen->NdisBindingContext, ! 2728: CurrentRequest, ! 2729: NDIS_STATUS_RESET_IN_PROGRESS ! 2730: ); ! 2731: ! 2732: NdisAcquireSpinLock(&Adapter->Lock); ! 2733: ! 2734: --TmpOpen->References; ! 2735: ! 2736: } ! 2737: ! 2738: CurrentRequest = *CurrentNextLocation; ! 2739: ! 2740: } ! 2741: ! 2742: Adapter->RequestInProgress = FALSE; ! 2743: ! 2744: } ! 2745: ! 2746: } ! 2747: ! 2748: #ifdef SONIC_INTERNAL ! 2749: ! 2750: // ! 2751: // The next routines are to support reading the registry to ! 2752: // obtain information about the internal sonic on the ! 2753: // MIPS R4000 motherboards. ! 2754: // ! 2755: ! 2756: // ! 2757: // This structure is used as the Context in the callbacks ! 2758: // to SonicHardwareSaveInformation. ! 2759: // ! 2760: ! 2761: typedef struct _SONIC_HARDWARE_INFO { ! 2762: ! 2763: // ! 2764: // These are read out of the "Configuration Data" ! 2765: // data. ! 2766: // ! 2767: ! 2768: CCHAR InterruptVector; ! 2769: KIRQL InterruptLevel; ! 2770: USHORT DataConfigurationRegister; ! 2771: LARGE_INTEGER PortAddress; ! 2772: BOOLEAN DataValid; ! 2773: UCHAR EthernetAddress[8]; ! 2774: BOOLEAN AddressValid; ! 2775: ! 2776: // ! 2777: // This is set to TRUE if "Identifier" is equal to ! 2778: // "SONIC". ! 2779: // ! 2780: ! 2781: BOOLEAN SonicIdentifier; ! 2782: ! 2783: } SONIC_HARDWARE_INFO, *PSONIC_HARDWARE_INFO; ! 2784: ! 2785: ! 2786: STATIC ! 2787: NTSTATUS ! 2788: SonicHardwareSaveInformation( ! 2789: IN PWSTR ValueName, ! 2790: IN ULONG ValueType, ! 2791: IN PVOID ValueData, ! 2792: IN ULONG ValueLength, ! 2793: IN PVOID Context, ! 2794: IN PVOID EntryContext ! 2795: ) ! 2796: ! 2797: /*++ ! 2798: ! 2799: Routine Description: ! 2800: ! 2801: This routine is a callback routine for RtlQueryRegistryValues. ! 2802: It is called back with the data for the "Identifier" value ! 2803: and verifies that it is "SONIC", then is called back with ! 2804: the resource list and records the ports, interrupt number, ! 2805: and DCR value. ! 2806: ! 2807: Arguments: ! 2808: ! 2809: ValueName - The name of the value ("Identifier" or "Configuration ! 2810: Data"). ! 2811: ! 2812: ValueType - The type of the value (REG_SZ or REG_BINARY). ! 2813: ! 2814: ValueData - The null-terminated data for the value. ! 2815: ! 2816: ValueLength - The length of ValueData (ignored). ! 2817: ! 2818: Context - A pointer to the SONIC_HARDWARE_INFO structure. ! 2819: ! 2820: EntryContext - FALSE for "Identifier", TRUE for "Configuration Data". ! 2821: ! 2822: Return Value: ! 2823: ! 2824: STATUS_SUCCESS ! 2825: ! 2826: --*/ ! 2827: ! 2828: { ! 2829: PSONIC_HARDWARE_INFO HardwareInfo = (PSONIC_HARDWARE_INFO)Context; ! 2830: ! 2831: if ((BOOLEAN)EntryContext) { ! 2832: ! 2833: // ! 2834: // This is the "Configuration Data" callback. ! 2835: // ! 2836: ! 2837: if ((ValueType == REG_BINARY || ValueType == REG_FULL_RESOURCE_DESCRIPTOR) && ! 2838: (ValueLength >= sizeof(CM_FULL_RESOURCE_DESCRIPTOR))) { ! 2839: ! 2840: BOOLEAN InterruptRead = FALSE; ! 2841: BOOLEAN PortAddressRead = FALSE; ! 2842: BOOLEAN DeviceSpecificRead = FALSE; ! 2843: UINT i; ! 2844: ! 2845: PCM_PARTIAL_RESOURCE_LIST ResourceList; ! 2846: PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor; ! 2847: PCM_SONIC_DEVICE_DATA SonicDeviceData; ! 2848: ! 2849: ResourceList = ! 2850: &((PCM_FULL_RESOURCE_DESCRIPTOR)ValueData)->PartialResourceList; ! 2851: ! 2852: for (i = 0; i < ResourceList->Count; i++) { ! 2853: ! 2854: ResourceDescriptor = &(ResourceList->PartialDescriptors[i]); ! 2855: ! 2856: switch (ResourceDescriptor->Type) { ! 2857: ! 2858: case CmResourceTypePort: ! 2859: ! 2860: HardwareInfo->PortAddress = ResourceDescriptor->u.Port.Start; ! 2861: PortAddressRead = TRUE; ! 2862: break; ! 2863: ! 2864: case CmResourceTypeInterrupt: ! 2865: ! 2866: HardwareInfo->InterruptVector = (CCHAR)ResourceDescriptor->u.Interrupt.Vector; ! 2867: HardwareInfo->InterruptLevel = (KIRQL)ResourceDescriptor->u.Interrupt.Level; ! 2868: InterruptRead = TRUE; ! 2869: break; ! 2870: ! 2871: case CmResourceTypeDeviceSpecific: ! 2872: ! 2873: if (i == ResourceList->Count-1) { ! 2874: ! 2875: SonicDeviceData = (PCM_SONIC_DEVICE_DATA) ! 2876: &(ResourceList->PartialDescriptors[ResourceList->Count]); ! 2877: ! 2878: // ! 2879: // Make sure we have enough room for each element we read. ! 2880: // ! 2881: ! 2882: if (ResourceDescriptor->u.DeviceSpecificData.DataSize >= ! 2883: (ULONG)(FIELD_OFFSET (CM_SONIC_DEVICE_DATA, EthernetAddress[0]))) { ! 2884: ! 2885: HardwareInfo->DataConfigurationRegister = ! 2886: SonicDeviceData->DataConfigurationRegister; ! 2887: DeviceSpecificRead = TRUE; ! 2888: ! 2889: // ! 2890: // Version.Revision later than 0.0 means that ! 2891: // the ethernet address is there too. ! 2892: // ! 2893: ! 2894: if ((SonicDeviceData->Version != 0) || ! 2895: (SonicDeviceData->Revision != 0)) { ! 2896: ! 2897: if (ResourceDescriptor->u.DeviceSpecificData.DataSize >= ! 2898: (ULONG)(FIELD_OFFSET (CM_SONIC_DEVICE_DATA, EthernetAddress[0]) + 8)) { ! 2899: ! 2900: SONIC_MOVE_MEMORY( ! 2901: HardwareInfo->EthernetAddress, ! 2902: SonicDeviceData->EthernetAddress, ! 2903: 8); ! 2904: ! 2905: HardwareInfo->AddressValid = TRUE; ! 2906: ! 2907: } ! 2908: ! 2909: } ! 2910: ! 2911: } ! 2912: ! 2913: } ! 2914: ! 2915: break; ! 2916: ! 2917: } ! 2918: ! 2919: } ! 2920: ! 2921: // ! 2922: // Make sure we got all we wanted. ! 2923: // ! 2924: ! 2925: if (PortAddressRead && InterruptRead && DeviceSpecificRead) { ! 2926: HardwareInfo->DataValid = TRUE; ! 2927: } ! 2928: ! 2929: } ! 2930: ! 2931: } else { ! 2932: ! 2933: static const WCHAR SonicString[] = L"SONIC"; ! 2934: ! 2935: // ! 2936: // This is the "Identifier" callback. ! 2937: // ! 2938: ! 2939: if ((ValueType == REG_SZ) && ! 2940: (ValueLength >= sizeof(SonicString)) && ! 2941: (RtlCompareMemory (ValueData, (PVOID)&SonicString, sizeof(SonicString)) == sizeof(SonicString))) { ! 2942: ! 2943: HardwareInfo->SonicIdentifier = TRUE; ! 2944: ! 2945: } ! 2946: ! 2947: } ! 2948: ! 2949: return STATUS_SUCCESS; ! 2950: ! 2951: } ! 2952: ! 2953: ! 2954: STATIC ! 2955: BOOLEAN ! 2956: SonicHardwareVerifyChecksum( ! 2957: IN PSONIC_ADAPTER Adapter, ! 2958: IN PUCHAR EthernetAddress, ! 2959: OUT ULONG ErrorLogData[3] ! 2960: ) ! 2961: ! 2962: /*++ ! 2963: ! 2964: Routine Description: ! 2965: ! 2966: This routine verifies that the checksum on the address ! 2967: for an internal sonic on a MIPS R4000 system is correct. ! 2968: ! 2969: Arguments: ! 2970: ! 2971: Adapter - The adapter which is being verified. ! 2972: ! 2973: EthernetAddress - A pointer to the address, with the checksum ! 2974: following it. ! 2975: ! 2976: ErrorLogData - If the checksum is bad, returns the address ! 2977: and the checksum we expected. ! 2978: ! 2979: Return Value: ! 2980: ! 2981: TRUE if the checksum is correct. ! 2982: ! 2983: --*/ ! 2984: ! 2985: { ! 2986: ! 2987: // ! 2988: // Iteration variable. ! 2989: // ! 2990: UINT i; ! 2991: ! 2992: // ! 2993: // Holds the checksum value. ! 2994: // ! 2995: USHORT CheckSum = 0; ! 2996: ! 2997: ! 2998: // ! 2999: // The network address is stored in the first 6 bytes of ! 3000: // EthernetAddress. Following that is a zero byte followed ! 3001: // by a value such that the sum of a checksum on the six ! 3002: // bytes and this value is 0xff. The checksum is computed ! 3003: // by adding together the six bytes, with the carry being ! 3004: // wrapped back to the first byte. ! 3005: // ! 3006: ! 3007: for (i=0; i<6; i++) { ! 3008: ! 3009: CheckSum += EthernetAddress[i]; ! 3010: if (CheckSum > 0xff) { ! 3011: CheckSum -= 0xff; ! 3012: } ! 3013: ! 3014: } ! 3015: ! 3016: ! 3017: if ((EthernetAddress[6] != 0x00) || ! 3018: ((EthernetAddress[7] + CheckSum) != 0xff)) { ! 3019: ! 3020: ErrorLogData[0] = ((ULONG)(EthernetAddress[3]) << 24) + ! 3021: ((ULONG)(EthernetAddress[2]) << 16) + ! 3022: ((ULONG)(EthernetAddress[1]) << 8) + ! 3023: ((ULONG)(EthernetAddress[0])); ! 3024: ErrorLogData[1] = ((ULONG)(EthernetAddress[7]) << 24) + ! 3025: ((ULONG)(EthernetAddress[6]) << 16) + ! 3026: ((ULONG)(EthernetAddress[5]) << 8) + ! 3027: ((ULONG)(EthernetAddress[4])); ! 3028: ErrorLogData[2] = 0xff - CheckSum; ! 3029: ! 3030: return FALSE; ! 3031: ! 3032: } ! 3033: ! 3034: return TRUE; ! 3035: ! 3036: } ! 3037: ! 3038: #endif // SONIC_INTERNAL ! 3039: ! 3040: ! 3041: STATIC ! 3042: SONIC_HARDWARE_STATUS ! 3043: SonicHardwareGetDetails( ! 3044: IN PSONIC_ADAPTER Adapter, ! 3045: IN UINT SlotNumber, ! 3046: IN UINT Controller, ! 3047: IN UINT MultifunctionAdapter, ! 3048: OUT PULONG InitialPort, ! 3049: OUT PULONG NumberOfPorts, ! 3050: IN OUT PUINT InterruptVector, ! 3051: IN OUT PUINT InterruptLevel, ! 3052: OUT ULONG ErrorLogData[3] ! 3053: ) ! 3054: ! 3055: /*++ ! 3056: ! 3057: Routine Description: ! 3058: ! 3059: This routine gets the initial port and number of ports for ! 3060: the Sonic. It also sets Adapter->PortShift. The ports are ! 3061: numbered 0, 1, 2, etc. but may appear as 16- or 32-bit ! 3062: ports, so PortShift will be 1 or 2 depending on how wide ! 3063: the ports are. ! 3064: ! 3065: It also sets the value of Adapter->DataConfigurationRegister, ! 3066: and may modify InterruptVector, InterruptLevel, and ! 3067: Adapter->PermanentNetworkAddress. ! 3068: ! 3069: Arguments: ! 3070: ! 3071: Adapter - The adapter in question. ! 3072: ! 3073: SlotNumber - For the EISA card this is the slot number that the ! 3074: card is in. ! 3075: ! 3076: Controller - For the internal version, it is the ! 3077: NetworkController number. ! 3078: ! 3079: MultifunctionAdapter - For the internal version, it is the adapter number. ! 3080: ! 3081: InitialPort - The base of the Sonic ports. ! 3082: ! 3083: NumberOfPorts - The number of bytes of ports to map. ! 3084: ! 3085: InterruptVector - A pointer to the interrupt vector. Depending ! 3086: on the card type, this may be passed in or returned by ! 3087: this function. ! 3088: ! 3089: InterruptLevel - A pointer to the interrupt level. Depending ! 3090: on the card type, this may be passed in or returned by ! 3091: this function. ! 3092: ! 3093: ErrorLogData - If the return status is SonicHardwareChecksum, ! 3094: this returns 3 longwords to be included in the error log. ! 3095: ! 3096: Return Value: ! 3097: ! 3098: SonicHardwareOk if successful, SonicHardwareChecksum if the ! 3099: checksum is bad, SonicHardwareConfig for other problems. ! 3100: ! 3101: --*/ ! 3102: ! 3103: { ! 3104: ! 3105: switch (Adapter->AdapterType) { ! 3106: ! 3107: #ifdef SONIC_EISA ! 3108: ! 3109: case SONIC_ADAPTER_TYPE_EISA: ! 3110: ! 3111: *InitialPort = (SlotNumber << 12); ! 3112: *NumberOfPorts = 0xD00; ! 3113: Adapter->PortShift = 1; ! 3114: Adapter->DataConfigurationRegister = ! 3115: SONIC_DCR_PROGRAMMABLE_OUTPUT_1 | ! 3116: SONIC_DCR_USER_DEFINABLE_1 | ! 3117: SONIC_DCR_3_WAIT_STATE | ! 3118: SONIC_DCR_BLOCK_MODE_DMA | ! 3119: SONIC_DCR_32_BIT_DATA_WIDTH | ! 3120: SONIC_DCR_8_WORD_RECEIVE_FIFO | ! 3121: SONIC_DCR_8_WORD_TRANSMIT_FIFO; ! 3122: ! 3123: return SonicHardwareOk; ! 3124: break; ! 3125: ! 3126: #endif // SONIC_EISA ! 3127: ! 3128: #ifdef SONIC_INTERNAL ! 3129: ! 3130: case SONIC_ADAPTER_TYPE_INTERNAL: ! 3131: { ! 3132: ! 3133: // ! 3134: // For MIPS R4000 systems, we have to query the registry to obtain ! 3135: // information about ports, interrupts, and the value to be ! 3136: // stored in the DCR register. ! 3137: // ! 3138: ! 3139: // ! 3140: // NOTE: The following code is NT-specific, since that is ! 3141: // currently the only system that runs on the MIPS R4000 hardware. ! 3142: // ! 3143: // We initialize an RTL_QUERY_TABLE to retrieve the Identifer ! 3144: // and ConfigurationData strings from the registry. ! 3145: // ! 3146: ! 3147: PWSTR ConfigDataPath = L"\\Registry\\Machine\\Hardware\\Description\\System\\MultifunctionAdapter\\#\\NetworkController\\#"; ! 3148: PWSTR IdentifierString = L"Identifier"; ! 3149: PWSTR ConfigDataString = L"Configuration Data"; ! 3150: RTL_QUERY_REGISTRY_TABLE QueryTable[4]; ! 3151: SONIC_HARDWARE_INFO SonicHardwareInfo; ! 3152: NTSTATUS Status; ! 3153: ! 3154: ! 3155: // ! 3156: // Set up QueryTable to do the following: ! 3157: // ! 3158: ! 3159: // ! 3160: // 1) Call SonicSaveHardwareInformation for the "Identifier" ! 3161: // value. ! 3162: // ! 3163: ! 3164: QueryTable[0].QueryRoutine = SonicHardwareSaveInformation; ! 3165: QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED; ! 3166: QueryTable[0].Name = IdentifierString; ! 3167: QueryTable[0].EntryContext = (PVOID)FALSE; ! 3168: QueryTable[0].DefaultType = REG_NONE; ! 3169: ! 3170: // ! 3171: // 2) Call SonicSaveHardwareInformation for the "Configuration Data" ! 3172: // value. ! 3173: // ! 3174: ! 3175: QueryTable[1].QueryRoutine = SonicHardwareSaveInformation; ! 3176: QueryTable[1].Flags = RTL_QUERY_REGISTRY_REQUIRED; ! 3177: QueryTable[1].Name = ConfigDataString; ! 3178: QueryTable[1].EntryContext = (PVOID)TRUE; ! 3179: QueryTable[1].DefaultType = REG_NONE; ! 3180: ! 3181: // ! 3182: // 3) Stop ! 3183: // ! 3184: ! 3185: QueryTable[2].QueryRoutine = NULL; ! 3186: QueryTable[2].Flags = 0; ! 3187: QueryTable[2].Name = NULL; ! 3188: ! 3189: ! 3190: // ! 3191: // Modify ConfigDataPath to replace the two # symbols with ! 3192: // the MultifunctionAdapter number and NetworkController number. ! 3193: // ! 3194: ! 3195: ConfigDataPath[67] = (WCHAR)('0' + MultifunctionAdapter); ! 3196: ConfigDataPath[87] = (WCHAR)('0' + Controller); ! 3197: ! 3198: SonicHardwareInfo.DataValid = FALSE; ! 3199: SonicHardwareInfo.AddressValid = FALSE; ! 3200: SonicHardwareInfo.SonicIdentifier = FALSE; ! 3201: ! 3202: Status = RtlQueryRegistryValues( ! 3203: RTL_REGISTRY_ABSOLUTE, ! 3204: ConfigDataPath, ! 3205: QueryTable, ! 3206: (PVOID)&SonicHardwareInfo, ! 3207: NULL); ! 3208: ! 3209: if (!NT_SUCCESS(Status)) { ! 3210: #if DBG ! 3211: DbgPrint ("SONIC: Could not read hardware information\n"); ! 3212: #endif ! 3213: return SonicHardwareConfig; ! 3214: } ! 3215: ! 3216: if (SonicHardwareInfo.DataValid && SonicHardwareInfo.SonicIdentifier) { ! 3217: ! 3218: *InterruptVector = (UINT)SonicHardwareInfo.InterruptVector; ! 3219: *InterruptLevel = (UINT)SonicHardwareInfo.InterruptLevel; ! 3220: *InitialPort = SonicHardwareInfo.PortAddress.LowPart; ! 3221: *NumberOfPorts = 192; ! 3222: Adapter->PortShift = 2; ! 3223: Adapter->DataConfigurationRegister = ! 3224: SonicHardwareInfo.DataConfigurationRegister; ! 3225: ! 3226: if (SonicHardwareInfo.AddressValid) { ! 3227: ! 3228: if (!SonicHardwareVerifyChecksum(Adapter, SonicHardwareInfo.EthernetAddress, ErrorLogData)) { ! 3229: #if DBG ! 3230: DbgPrint("SONIC: Invalid registry network address checksum!!\n"); ! 3231: #endif ! 3232: return SonicHardwareChecksum; ! 3233: } ! 3234: ! 3235: SONIC_MOVE_MEMORY( ! 3236: Adapter->PermanentNetworkAddress, ! 3237: SonicHardwareInfo.EthernetAddress, ! 3238: 8); ! 3239: Adapter->PermanentAddressValid = TRUE; ! 3240: ! 3241: } ! 3242: ! 3243: return SonicHardwareOk; ! 3244: ! 3245: } else { ! 3246: ! 3247: #if DBG ! 3248: DbgPrint ("SONIC: Incorrect registry hardware information\n"); ! 3249: #endif ! 3250: return SonicHardwareConfig; ! 3251: ! 3252: } ! 3253: ! 3254: break; ! 3255: ! 3256: } ! 3257: ! 3258: #endif // SONIC_INTERNAL ! 3259: ! 3260: default: ! 3261: ! 3262: ASSERT(FALSE); ! 3263: break; ! 3264: ! 3265: } ! 3266: ! 3267: return SonicHardwareConfig; ! 3268: ! 3269: } ! 3270: ! 3271: ! 3272: STATIC ! 3273: BOOLEAN ! 3274: SonicHardwareGetAddress( ! 3275: IN PSONIC_ADAPTER Adapter, ! 3276: IN ULONG ErrorLogData[3] ! 3277: ) ! 3278: ! 3279: /*++ ! 3280: ! 3281: Routine Description: ! 3282: ! 3283: This routine gets the network address from the hardware. ! 3284: ! 3285: Arguments: ! 3286: ! 3287: Adapter - Where to store the network address. ! 3288: ! 3289: ErrorLogData - If the checksum is bad, returns the address ! 3290: and the checksum we expected. ! 3291: ! 3292: Return Value: ! 3293: ! 3294: TRUE if successful. ! 3295: ! 3296: --*/ ! 3297: ! 3298: { ! 3299: #define NVRAM_READ_ONLY_BASE 0x8000b000 ! 3300: ! 3301: // ! 3302: // Iteration variable. ! 3303: // ! 3304: UINT i; ! 3305: ! 3306: ! 3307: switch (Adapter->AdapterType) { ! 3308: ! 3309: #ifdef SONIC_EISA ! 3310: ! 3311: case SONIC_ADAPTER_TYPE_EISA: ! 3312: ! 3313: // ! 3314: // The EISA card has the address stored at ports xC90 to xC95, ! 3315: // where x is the slot number. ! 3316: // ! 3317: ! 3318: for (i = 0; i < 6; i++) { ! 3319: ! 3320: NdisRawReadPortUchar( ! 3321: Adapter->SonicPortAddress + 0xc90 + i, ! 3322: &Adapter->PermanentNetworkAddress[i]); ! 3323: ! 3324: } ! 3325: ! 3326: break; ! 3327: ! 3328: #endif // SONIC_EISA ! 3329: ! 3330: #ifdef SONIC_INTERNAL ! 3331: ! 3332: case SONIC_ADAPTER_TYPE_INTERNAL: ! 3333: { ! 3334: ! 3335: NDIS_STATUS Status; ! 3336: USHORT SiliconRevision; ! 3337: ! 3338: if (!Adapter->PermanentAddressValid) { ! 3339: ! 3340: // ! 3341: // Physical addresses for call to NdisMapIoSpace. ! 3342: // ! 3343: ! 3344: NDIS_PHYSICAL_ADDRESS NvRamPhysical = ! 3345: NDIS_PHYSICAL_ADDRESS_CONST(NVRAM_READ_ONLY_BASE, 0); ! 3346: ! 3347: // ! 3348: // Temporarily maps the NVRAM into our address space. ! 3349: // ! 3350: PVOID NvRamMapping; ! 3351: ! 3352: ! 3353: ! 3354: // ! 3355: // If PermanentAddressValid is still FALSE then the address ! 3356: // was not read by SonicHardwareGetDetails, so we must do it ! 3357: // here. ! 3358: // ! 3359: ! 3360: NdisMapIoSpace ( ! 3361: &Status, ! 3362: &NvRamMapping, ! 3363: Adapter->NdisAdapterHandle, ! 3364: NvRamPhysical, ! 3365: 8 ! 3366: ); ! 3367: ! 3368: if (Status != NDIS_STATUS_SUCCESS) { ! 3369: ! 3370: NdisWriteErrorLogEntry( ! 3371: Adapter->NdisAdapterHandle, ! 3372: NDIS_ERROR_CODE_RESOURCE_CONFLICT, ! 3373: 0 ! 3374: ); ! 3375: ! 3376: return(FALSE); ! 3377: ! 3378: } ! 3379: ! 3380: // ! 3381: // Verify that the checksum matches. ! 3382: // ! 3383: ! 3384: if (!SonicHardwareVerifyChecksum(Adapter, (PUCHAR)NvRamMapping, ErrorLogData)) { ! 3385: ! 3386: #if DBG ! 3387: DbgPrint("SONIC: Invalid NVRAM network address checksum!!\n"); ! 3388: #endif ! 3389: NdisUnmapIoSpace(Adapter->NdisAdapterHandle, NvRamMapping, 8); ! 3390: return FALSE; ! 3391: ! 3392: } ! 3393: ! 3394: // ! 3395: // Checksum is OK, save the address. ! 3396: // ! 3397: ! 3398: for (i=0; i<6; i++) { ! 3399: Adapter->PermanentNetworkAddress[i] = *((PUCHAR)NvRamMapping+i); ! 3400: } ! 3401: Adapter->PermanentAddressValid = TRUE; ! 3402: ! 3403: NdisUnmapIoSpace(Adapter->NdisAdapterHandle, NvRamMapping, 8); ! 3404: ! 3405: } ! 3406: ! 3407: // ! 3408: // The Data Configuration Register is already set up, but we ! 3409: // change the FIFO initialization for old revisions. ! 3410: // ! 3411: ! 3412: SONIC_READ_PORT(Adapter, SONIC_SILICON_REVISION, &SiliconRevision); ! 3413: ! 3414: if (SiliconRevision < 4) { ! 3415: ! 3416: Adapter->DataConfigurationRegister = ! 3417: (Adapter->DataConfigurationRegister & SONIC_DCR_FIFO_MASK) | ! 3418: SONIC_DCR_8_WORD_RECEIVE_FIFO | ! 3419: SONIC_DCR_8_WORD_TRANSMIT_FIFO; ! 3420: ! 3421: } ! 3422: ! 3423: break; ! 3424: ! 3425: } ! 3426: ! 3427: #endif // SONIC_INTERNAL ! 3428: ! 3429: default: ! 3430: ! 3431: ASSERT(FALSE); ! 3432: break; ! 3433: ! 3434: } ! 3435: ! 3436: ! 3437: #if DBG ! 3438: if (SonicDbg) { ! 3439: DbgPrint("SONIC: "); ! 3440: DbgPrint("[ %x-%x-%x-%x-%x-%x ]\n", ! 3441: (UCHAR)Adapter->PermanentNetworkAddress[0], ! 3442: (UCHAR)Adapter->PermanentNetworkAddress[1], ! 3443: (UCHAR)Adapter->PermanentNetworkAddress[2], ! 3444: (UCHAR)Adapter->PermanentNetworkAddress[3], ! 3445: (UCHAR)Adapter->PermanentNetworkAddress[4], ! 3446: (UCHAR)Adapter->PermanentNetworkAddress[5]); ! 3447: DbgPrint("\n"); ! 3448: } ! 3449: #endif ! 3450: ! 3451: return TRUE; ! 3452: ! 3453: } ! 3454: ! 3455: ! 3456: VOID ! 3457: SonicShutdown( ! 3458: IN PVOID ShutdownContext ! 3459: ) ! 3460: ! 3461: /*++ ! 3462: ! 3463: Routine Description: ! 3464: ! 3465: Turns off the card during a powerdown of the system. ! 3466: ! 3467: Arguments: ! 3468: ! 3469: ShutdownContext - Really a pointer to the adapter structure. ! 3470: ! 3471: Return Value: ! 3472: ! 3473: None. ! 3474: ! 3475: --*/ ! 3476: ! 3477: { ! 3478: PSONIC_ADAPTER Adapter = (PSONIC_ADAPTER)(ShutdownContext); ! 3479: ! 3480: NdisAcquireSpinLock(&Adapter->Lock); ! 3481: ! 3482: // ! 3483: // Set the flag ! 3484: // ! 3485: ! 3486: Adapter->Removed = TRUE; ! 3487: ! 3488: // ! 3489: // Shut down the chip. We won't be doing any more work until ! 3490: // the reset is complete. ! 3491: // ! 3492: ! 3493: SonicStopChip(Adapter); ! 3494: ! 3495: NdisStallExecution(250000); ! 3496: ! 3497: NdisReleaseSpinLock(&Adapter->Lock); ! 3498: ! 3499: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.