|
|
1.1 ! root 1: /*++ ! 2: ! 3: Copyright (c) 1990 Microsoft Corporation ! 4: ! 5: Module Name: ! 6: ! 7: lance.c ! 8: ! 9: Abstract: ! 10: ! 11: This is the main file for the Advanced Micro Devices LANCE (Am 7990) ! 12: Ethernet controller. This driver conforms to the NDIS 3.0 interface. ! 13: ! 14: The idea for handling loopback and sends simultaneously is largely ! 15: adapted from the EtherLink II NDIS driver by Adam Barr. ! 16: ! 17: Author: ! 18: ! 19: Anthony V. Ercolano (Tonye) 20-Jul-1990 ! 20: ! 21: Environment: ! 22: ! 23: Kernel Mode - Or whatever is the equivalent on OS/2 and DOS. ! 24: ! 25: Revision History: ! 26: ! 27: 31-Jul-1992 R.D. Lanser: ! 28: ! 29: Changed DECST card type to DECTC for the DEC TurboChannel option ! 30: PMAD-AA (Lance ethernet). This option will be available for all ! 31: TurboChannel systems regardless of CPU type or system. ! 32: ! 33: Removed UsedLanceBuffer conditional (always true). ! 34: ! 35: Added InterruptRequestLevel to the _LANCE_ADAPTER structure because ! 36: 'lance.c' was passing the InterruptVector as the IRQL to the interrupt ! 37: connect routine which is not correct. This works on JAZZ because the ! 38: JAZZ HalGetInterruptVector is hardcoded to return a fixed IRQL for ! 39: EISA devices. ! 40: ! 41: Remove hardcoded configuration information and added gets from the ! 42: registry for the base address, interrupt vector, and interrupt ! 43: request level. ! 44: ! 45: ! 46: --*/ ! 47: ! 48: #include <ndis.h> ! 49: #include <efilter.h> ! 50: #include "lancehrd.h" ! 51: #include "lancesft.h" ! 52: #include "dectc.h" ! 53: ! 54: #if DBG ! 55: #define STATIC ! 56: #else ! 57: #define STATIC static ! 58: #endif ! 59: ! 60: ! 61: #if DBG ! 62: ! 63: UCHAR LanceSendFails[256]; ! 64: UCHAR LanceSendFailPlace = 0; ! 65: ! 66: #endif ! 67: ! 68: ! 69: NDIS_HANDLE LanceNdisWrapperHandle; ! 70: NDIS_HANDLE LanceMacHandle; ! 71: PDRIVER_OBJECT LanceDriverObject; ! 72: ! 73: // ! 74: // This constant is used for places where NdisAllocateMemory ! 75: // needs to be called and the HighestAcceptableAddress does ! 76: // not matter. ! 77: // ! 78: ! 79: NDIS_PHYSICAL_ADDRESS HighestAcceptableMax = ! 80: NDIS_PHYSICAL_ADDRESS_CONST(-1,-1); ! 81: ! 82: ! 83: #if LANCELOG ! 84: ! 85: NDIS_TIMER LogTimer; ! 86: BOOLEAN LogTimerRunning = FALSE; ! 87: ! 88: UCHAR Log[LOG_SIZE]; ! 89: ! 90: UCHAR LogPlace = 0; ! 91: UCHAR LogWrapped = 0; ! 92: ! 93: UCHAR LancePrintLog = 0; ! 94: ! 95: void ! 96: LogDpc( ! 97: IN PVOID SystemSpecific1, ! 98: PVOID Context, ! 99: IN PVOID SystemSpecific2, ! 100: IN PVOID SystemSpecific3 ! 101: ) ! 102: { ! 103: ! 104: UNREFERENCED_PARAMETER(Context); ! 105: UNREFERENCED_PARAMETER(SystemSpecific1); ! 106: UNREFERENCED_PARAMETER(SystemSpecific2); ! 107: UNREFERENCED_PARAMETER(SystemSpecific3); ! 108: ! 109: LOG(TIMER); ! 110: ! 111: NdisSetTimer(&LogTimer, 1000); ! 112: ! 113: } ! 114: ! 115: ! 116: #endif ! 117: ! 118: ! 119: ! 120: ! 121: #define MAX_MULTICAST_ADDRESS ((UINT)32) ! 122: ! 123: // ! 124: // Used for accessing the filter package multicast address list. ! 125: // ! 126: ! 127: static CHAR MulticastAddresses[MAX_MULTICAST_ADDRESS][ETH_LENGTH_OF_ADDRESS]; ! 128: ! 129: ! 130: ! 131: // ! 132: // If you add to this, make sure to add the ! 133: // a case in LanceFillInGlobalData() and in ! 134: // LanceQueryGlobalStatistics() if global ! 135: // information only or ! 136: // LanceQueryProtocolStatistics() if it is ! 137: // protocol queriable information. ! 138: // ! 139: UINT LanceGlobalSupportedOids[] = { ! 140: OID_GEN_SUPPORTED_LIST, ! 141: OID_GEN_HARDWARE_STATUS, ! 142: OID_GEN_MEDIA_SUPPORTED, ! 143: OID_GEN_MEDIA_IN_USE, ! 144: OID_GEN_MAXIMUM_LOOKAHEAD, ! 145: OID_GEN_MAXIMUM_FRAME_SIZE, ! 146: OID_GEN_MAXIMUM_TOTAL_SIZE, ! 147: OID_GEN_MAC_OPTIONS, ! 148: OID_GEN_PROTOCOL_OPTIONS, ! 149: OID_GEN_LINK_SPEED, ! 150: OID_GEN_TRANSMIT_BUFFER_SPACE, ! 151: OID_GEN_RECEIVE_BUFFER_SPACE, ! 152: OID_GEN_TRANSMIT_BLOCK_SIZE, ! 153: OID_GEN_RECEIVE_BLOCK_SIZE, ! 154: OID_GEN_VENDOR_ID, ! 155: OID_GEN_VENDOR_DESCRIPTION, ! 156: OID_GEN_DRIVER_VERSION, ! 157: OID_GEN_CURRENT_PACKET_FILTER, ! 158: OID_GEN_CURRENT_LOOKAHEAD, ! 159: OID_GEN_XMIT_OK, ! 160: OID_GEN_RCV_OK, ! 161: OID_GEN_XMIT_ERROR, ! 162: OID_GEN_RCV_ERROR, ! 163: OID_GEN_RCV_NO_BUFFER, ! 164: OID_802_3_PERMANENT_ADDRESS, ! 165: OID_802_3_CURRENT_ADDRESS, ! 166: OID_802_3_MULTICAST_LIST, ! 167: OID_802_3_MAXIMUM_LIST_SIZE, ! 168: OID_802_3_RCV_ERROR_ALIGNMENT, ! 169: OID_802_3_XMIT_ONE_COLLISION, ! 170: OID_802_3_XMIT_MORE_COLLISIONS ! 171: }; ! 172: ! 173: // ! 174: // If you add to this, make sure to add the ! 175: // a case in LanceQueryGlobalStatistics() and in ! 176: // LanceQueryProtocolInformation() ! 177: // ! 178: UINT LanceProtocolSupportedOids[] = { ! 179: OID_GEN_SUPPORTED_LIST, ! 180: OID_GEN_HARDWARE_STATUS, ! 181: OID_GEN_MEDIA_SUPPORTED, ! 182: OID_GEN_MEDIA_IN_USE, ! 183: OID_GEN_MAXIMUM_LOOKAHEAD, ! 184: OID_GEN_MAXIMUM_FRAME_SIZE, ! 185: OID_GEN_MAXIMUM_TOTAL_SIZE, ! 186: OID_GEN_MAC_OPTIONS, ! 187: OID_GEN_PROTOCOL_OPTIONS, ! 188: OID_GEN_LINK_SPEED, ! 189: OID_GEN_TRANSMIT_BUFFER_SPACE, ! 190: OID_GEN_RECEIVE_BUFFER_SPACE, ! 191: OID_GEN_TRANSMIT_BLOCK_SIZE, ! 192: OID_GEN_RECEIVE_BLOCK_SIZE, ! 193: OID_GEN_VENDOR_ID, ! 194: OID_GEN_VENDOR_DESCRIPTION, ! 195: OID_GEN_DRIVER_VERSION, ! 196: OID_GEN_CURRENT_PACKET_FILTER, ! 197: OID_GEN_CURRENT_LOOKAHEAD, ! 198: OID_802_3_PERMANENT_ADDRESS, ! 199: OID_802_3_CURRENT_ADDRESS, ! 200: OID_802_3_MULTICAST_LIST, ! 201: OID_802_3_MAXIMUM_LIST_SIZE ! 202: }; ! 203: ! 204: ! 205: ! 206: // ! 207: // This macro is to synchronize execution with interrupts. It ! 208: // gets the stored value of the CSR 0 and clears the old value. ! 209: // ! 210: #define GET_CSR0_SINCE_LAST_PROCESSED(A,V) \ ! 211: { \ ! 212: PLANCE_ADAPTER _A = A; \ ! 213: LANCE_SYNCH_CONTEXT _C; \ ! 214: _C.Adapter = _A; \ ! 215: _C.LocalRead = (V); \ ! 216: NdisSynchronizeWithInterrupt( \ ! 217: &(_A)->Interrupt, \ ! 218: LanceInterruptSynch, \ ! 219: &_C \ ! 220: ); \ ! 221: } ! 222: ! 223: // ! 224: // We define a constant csr0 value that is useful for initializing ! 225: // an already stopped LANCE. ! 226: // ! 227: // This also enables the chip for interrupts. ! 228: // ! 229: #define LANCE_CSR0_INIT_CHIP ((USHORT)0x41) ! 230: ! 231: // ! 232: // We define a constant csr0 value that is useful for clearing all of ! 233: // the interesting bits that *could* be set on an interrupt. ! 234: // ! 235: #define LANCE_CSR0_CLEAR_INTERRUPT_BITS ((USHORT)0x7f00) ! 236: ! 237: STATIC ! 238: NDIS_STATUS ! 239: LanceOpenAdapter( ! 240: OUT PNDIS_STATUS OpenErrorStatus, ! 241: OUT NDIS_HANDLE *MacBindingHandle, ! 242: OUT PUINT SelectedMediumIndex, ! 243: IN PNDIS_MEDIUM MediumArray, ! 244: IN UINT MediumArraySize, ! 245: IN NDIS_HANDLE NdisBindingContext, ! 246: IN NDIS_HANDLE MacAdapterContext, ! 247: IN UINT OpenOptions, ! 248: IN PSTRING AddressingInformation OPTIONAL ! 249: ); ! 250: ! 251: ! 252: VOID ! 253: LanceUnload( ! 254: IN NDIS_HANDLE MacMacContext ! 255: ); ! 256: ! 257: STATIC ! 258: NDIS_STATUS ! 259: LanceCloseAdapter( ! 260: IN NDIS_HANDLE MacBindingHandle ! 261: ); ! 262: ! 263: ! 264: STATIC ! 265: NDIS_STATUS ! 266: LanceRequest( ! 267: IN NDIS_HANDLE MacBindingHandle, ! 268: IN PNDIS_REQUEST NdisRequest ! 269: ); ! 270: ! 271: NDIS_STATUS ! 272: LanceQueryProtocolInformation( ! 273: IN PLANCE_ADAPTER Adapter, ! 274: IN PLANCE_OPEN Open, ! 275: IN NDIS_OID Oid, ! 276: IN BOOLEAN GlobalMode, ! 277: IN PVOID InfoBuffer, ! 278: IN UINT BytesLeft, ! 279: OUT PUINT BytesNeeded, ! 280: OUT PUINT BytesWritten ! 281: ); ! 282: ! 283: NDIS_STATUS ! 284: LanceQueryInformation( ! 285: IN PLANCE_ADAPTER Adapter, ! 286: IN PLANCE_OPEN Open, ! 287: IN PNDIS_REQUEST NdisRequest ! 288: ); ! 289: ! 290: NDIS_STATUS ! 291: LanceSetInformation( ! 292: IN PLANCE_ADAPTER Adapter, ! 293: IN PLANCE_OPEN Open, ! 294: IN PNDIS_REQUEST NdisRequest ! 295: ); ! 296: ! 297: STATIC ! 298: NDIS_STATUS ! 299: LanceReset( ! 300: IN NDIS_HANDLE MacBindingHandle ! 301: ); ! 302: ! 303: ! 304: STATIC ! 305: NDIS_STATUS ! 306: LanceSetPacketFilter( ! 307: IN PLANCE_ADAPTER Adapter, ! 308: IN PLANCE_OPEN Open, ! 309: IN PNDIS_REQUEST NdisRequest, ! 310: IN UINT PacketFilter ! 311: ); ! 312: ! 313: ! 314: NDIS_STATUS ! 315: LanceFillInGlobalData( ! 316: IN PLANCE_ADAPTER Adapter, ! 317: IN PNDIS_REQUEST NdisRequest ! 318: ); ! 319: ! 320: ! 321: STATIC ! 322: NDIS_STATUS ! 323: LanceQueryGlobalStatistics( ! 324: IN NDIS_HANDLE MacAdapterContext, ! 325: IN PNDIS_REQUEST NdisRequest ! 326: ); ! 327: ! 328: NDIS_STATUS ! 329: LanceChangeMulticastAddresses( ! 330: IN UINT OldFilterCount, ! 331: IN CHAR OldAddresses[][ETH_LENGTH_OF_ADDRESS], ! 332: IN UINT NewFilterCount, ! 333: IN CHAR NewAddresses[][ETH_LENGTH_OF_ADDRESS], ! 334: IN NDIS_HANDLE MacBindingHandle, ! 335: IN PNDIS_REQUEST NdisRequest, ! 336: IN BOOLEAN Set ! 337: ); ! 338: ! 339: STATIC ! 340: NDIS_STATUS ! 341: LanceChangeFilterClasses( ! 342: IN UINT OldFilterClasses, ! 343: IN UINT NewFilterClasses, ! 344: IN NDIS_HANDLE MacBindingHandle, ! 345: IN PNDIS_REQUEST NdisRequest, ! 346: IN BOOLEAN Set ! 347: ); ! 348: ! 349: STATIC ! 350: VOID ! 351: LanceCloseAction( ! 352: IN NDIS_HANDLE MacBindingHandle ! 353: ); ! 354: ! 355: STATIC ! 356: BOOLEAN ! 357: AllocateAdapterMemory( ! 358: IN PLANCE_ADAPTER Adapter ! 359: ); ! 360: ! 361: STATIC ! 362: VOID ! 363: DeleteAdapterMemory( ! 364: IN PLANCE_ADAPTER Adapter ! 365: ); ! 366: ! 367: STATIC ! 368: VOID ! 369: ReturnAdapterResources( ! 370: IN PLANCE_ADAPTER Adapter, ! 371: IN UINT BufferIndex ! 372: ); ! 373: ! 374: STATIC ! 375: VOID ! 376: RelinquishReceivePacket( ! 377: IN PLANCE_ADAPTER Adapter, ! 378: IN UINT StartingIndex, ! 379: IN UINT NumberOfBuffers ! 380: ); ! 381: ! 382: STATIC ! 383: BOOLEAN ! 384: ProcessReceiveInterrupts( ! 385: IN PLANCE_ADAPTER Adapter ! 386: ); ! 387: ! 388: STATIC ! 389: BOOLEAN ! 390: ProcessTransmitInterrupts( ! 391: IN PLANCE_ADAPTER Adapter ! 392: ); ! 393: ! 394: STATIC ! 395: VOID ! 396: LanceStandardInterruptDPC( ! 397: IN PVOID SystemSpecific, ! 398: IN PVOID Context, ! 399: IN PVOID SystemArgument1, ! 400: IN PVOID SystemArgument2 ! 401: ); ! 402: ! 403: ! 404: extern ! 405: BOOLEAN ! 406: LanceISR( ! 407: IN PVOID Context ! 408: ); ! 409: ! 410: STATIC ! 411: BOOLEAN ! 412: LanceInterruptSynch( ! 413: IN PVOID Context ! 414: ); ! 415: ! 416: STATIC ! 417: UINT ! 418: CalculateCRC( ! 419: IN UINT NumberOfBytes, ! 420: IN PCHAR Input ! 421: ); ! 422: ! 423: STATIC ! 424: VOID ! 425: ProcessInterrupt( ! 426: IN PLANCE_ADAPTER Adapter ! 427: ); ! 428: ! 429: STATIC ! 430: VOID ! 431: LanceStartChip( ! 432: IN PLANCE_ADAPTER Adapter ! 433: ); ! 434: ! 435: STATIC ! 436: VOID ! 437: LanceSetInitializationBlock( ! 438: IN PLANCE_ADAPTER Adapter ! 439: ); ! 440: ! 441: STATIC ! 442: VOID ! 443: SetInitBlockAndInit( ! 444: IN PLANCE_ADAPTER Adapter ! 445: ); ! 446: ! 447: STATIC ! 448: VOID ! 449: StartAdapterReset( ! 450: IN PLANCE_ADAPTER Adapter ! 451: ); ! 452: ! 453: STATIC ! 454: VOID ! 455: SetupForReset( ! 456: IN PLANCE_ADAPTER Adapter, ! 457: IN PLANCE_OPEN Open, ! 458: IN PNDIS_REQUEST NdisRequest, ! 459: IN NDIS_REQUEST_TYPE RequestType ! 460: ); ! 461: ! 462: STATIC ! 463: NDIS_STATUS ! 464: LanceInitialInit( ! 465: IN PLANCE_ADAPTER Adapter ! 466: ); ! 467: ! 468: ! 469: STATIC ! 470: VOID ! 471: FinishPendOp( ! 472: IN PLANCE_ADAPTER Adapter, ! 473: IN BOOLEAN Successful ! 474: ); ! 475: ! 476: ! 477: // ! 478: // Non portable interface. ! 479: // ! 480: ! 481: NTSTATUS ! 482: DriverEntry( ! 483: IN PDRIVER_OBJECT DriverObject, ! 484: IN PUNICODE_STRING RegistryPath ! 485: ) ! 486: ! 487: /*++ ! 488: ! 489: Routine Description: ! 490: ! 491: This is the primary initialization routine for the lance driver. ! 492: It is simply responsible for the intializing the wrapper and registering ! 493: the MAC. It then calls a system and architecture specific routine that ! 494: will initialize and register each adapter. ! 495: ! 496: Arguments: ! 497: ! 498: DriverObject - Pointer to driver object created by the system. ! 499: ! 500: Return Value: ! 501: ! 502: The status of the operation. ! 503: ! 504: --*/ ! 505: ! 506: { ! 507: ! 508: ! 509: // ! 510: // Receives the status of the NdisRegisterMac operation. ! 511: // ! 512: NDIS_STATUS InitStatus; ! 513: ! 514: NDIS_HANDLE NdisMacHandle; ! 515: ! 516: NDIS_HANDLE NdisWrapperHandle; ! 517: ! 518: char Tmp[sizeof(NDIS_MAC_CHARACTERISTICS)]; ! 519: PNDIS_MAC_CHARACTERISTICS LanceChar = (PNDIS_MAC_CHARACTERISTICS)Tmp; ! 520: ! 521: NDIS_STRING MacName = NDIS_STRING_CONST("Lance"); ! 522: ! 523: // ! 524: // Initialize the wrapper. ! 525: // ! 526: ! 527: NdisInitializeWrapper(&NdisWrapperHandle, ! 528: DriverObject, ! 529: RegistryPath, ! 530: NULL ! 531: ); ! 532: ! 533: // ! 534: // Initialize the MAC characteristics for the call to ! 535: // NdisRegisterMac. ! 536: // ! 537: ! 538: LanceChar->MajorNdisVersion = LANCE_NDIS_MAJOR_VERSION; ! 539: LanceChar->MinorNdisVersion = LANCE_NDIS_MINOR_VERSION; ! 540: LanceChar->OpenAdapterHandler = LanceOpenAdapter; ! 541: LanceChar->CloseAdapterHandler = LanceCloseAdapter; ! 542: LanceChar->SendHandler = LanceSend; ! 543: LanceChar->TransferDataHandler = LanceTransferData; ! 544: LanceChar->ResetHandler = LanceReset; ! 545: LanceChar->RequestHandler = LanceRequest; ! 546: LanceChar->AddAdapterHandler = LanceAddAdapter; ! 547: LanceChar->UnloadMacHandler = LanceUnload; ! 548: LanceChar->RemoveAdapterHandler = LanceRemoveAdapter; ! 549: LanceChar->QueryGlobalStatisticsHandler = LanceQueryGlobalStatistics; ! 550: ! 551: LanceChar->Name = MacName; ! 552: ! 553: LanceDriverObject = DriverObject; ! 554: LanceNdisWrapperHandle = NdisWrapperHandle; ! 555: ! 556: NdisRegisterMac( ! 557: &InitStatus, ! 558: &NdisMacHandle, ! 559: NdisWrapperHandle, ! 560: &NdisMacHandle, ! 561: LanceChar, ! 562: sizeof(*LanceChar) ! 563: ); ! 564: ! 565: LanceMacHandle = NdisMacHandle; ! 566: ! 567: if (InitStatus == NDIS_STATUS_SUCCESS) { ! 568: ! 569: return NDIS_STATUS_SUCCESS; ! 570: ! 571: } ! 572: ! 573: NdisTerminateWrapper(NdisWrapperHandle, NULL); ! 574: ! 575: return NDIS_STATUS_FAILURE; ! 576: ! 577: } ! 578: ! 579: NDIS_STATUS ! 580: LanceAddAdapter( ! 581: IN NDIS_HANDLE MacMacContext, ! 582: IN NDIS_HANDLE ConfigurationHandle, ! 583: IN PNDIS_STRING AdapterName ! 584: ) ! 585: /*++ ! 586: Routine Description: ! 587: ! 588: This is the Wd MacAddAdapter routine. The system calls this routine ! 589: to add support for a particular WD adapter. This routine extracts ! 590: configuration information from the configuration data base and registers ! 591: the adapter with NDIS. ! 592: ! 593: Arguments: ! 594: ! 595: see NDIS 3.0 spec... ! 596: ! 597: Return Value: ! 598: ! 599: NDIS_STATUS_SUCCESS - Adapter was successfully added. ! 600: NDIS_STATUS_FAILURE - Adapter was not added, also MAC deregistered. ! 601: ! 602: --*/ ! 603: { ! 604: // ! 605: // Pointer for the adapter root. ! 606: // ! 607: PLANCE_ADAPTER Adapter; ! 608: ! 609: ! 610: NDIS_HANDLE ConfigHandle; ! 611: PNDIS_CONFIGURATION_PARAMETER ReturnedValue; ! 612: NDIS_STRING IoAddressStr = NDIS_STRING_CONST("IoBaseAddress"); ! 613: NDIS_STRING MaxMulticastListStr = NDIS_STRING_CONST("MaximumMulticastList"); ! 614: NDIS_STRING NetworkAddressStr = NDIS_STRING_CONST("NetworkAddress"); ! 615: NDIS_STRING InterruptStr = NDIS_STRING_CONST("InterruptNumber"); ! 616: NDIS_STRING CardStr = NDIS_STRING_CONST("CardType"); ! 617: NDIS_STRING MemoryBaseAddrStr = NDIS_STRING_CONST("MemoryMappedBaseAddress"); ! 618: ! 619: NDIS_HANDLE NdisMacHandle = (NDIS_HANDLE)(*((PNDIS_HANDLE)MacMacContext)); ! 620: ! 621: NDIS_STATUS Status; ! 622: ! 623: NDIS_ADAPTER_INFORMATION AdapterInformation; // needed to register adapter ! 624: NDIS_EISA_FUNCTION_INFORMATION EisaData; ! 625: USHORT ConfigValue = 0; ! 626: UCHAR HiBaseValue = 0; ! 627: ! 628: UINT MaxMulticastList = 32; ! 629: PVOID NetAddress; ! 630: UINT Length; ! 631: ! 632: USHORT RegUshort; ! 633: UCHAR RegUchar; ! 634: UINT LanceSlot = 1; ! 635: ! 636: BOOLEAN ConfigError = FALSE; ! 637: NDIS_STATUS ConfigErrorCode; ! 638: ! 639: ! 640: // ! 641: // Allocate the Adapter block. ! 642: // ! 643: ! 644: LANCE_ALLOC_PHYS(&Adapter, sizeof(LANCE_ADAPTER)); ! 645: ! 646: if (Adapter == NULL){ ! 647: ! 648: return NDIS_STATUS_RESOURCES; ! 649: ! 650: } ! 651: ! 652: LANCE_ZERO_MEMORY( ! 653: Adapter, ! 654: sizeof(LANCE_ADAPTER) ! 655: ); ! 656: ! 657: Adapter->NdisMacHandle = NdisMacHandle; ! 658: ! 659: ! 660: // ! 661: // Start with the default card ! 662: // ! 663: ! 664: Adapter->LanceCard = LANCE_DE201; ! 665: ! 666: Adapter->RAP = LANCE_DE201_PRI_RAP_ADDRESS; ! 667: Adapter->RDP = LANCE_DE201_PRI_RDP_ADDRESS; ! 668: Adapter->Nicsr = LANCE_DE201_PRI_NICSR_ADDRESS; ! 669: Adapter->NicsrDefaultValue = 0; ! 670: Adapter->NetworkHardwareAddress = LANCE_DE201_PRI_NETWORK_ADDRESS; ! 671: Adapter->HardwareBaseAddr = LANCE_DE201_BASE; ! 672: Adapter->AmountOfHardwareMemory = LANCE_DE201_HARDWARE_MEMORY; ! 673: Adapter->InterruptNumber = LANCE_DE201_INTERRUPT_VECTOR; ! 674: Adapter->InterruptRequestLevel = LANCE_DE201_INTERRUPT_VECTOR; ! 675: ! 676: NdisOpenConfiguration( ! 677: &Status, ! 678: &ConfigHandle, ! 679: ConfigurationHandle ! 680: ); ! 681: ! 682: if (Status != NDIS_STATUS_SUCCESS) { ! 683: ! 684: return NDIS_STATUS_FAILURE; ! 685: ! 686: } ! 687: ! 688: // ! 689: // Read Card Type ! 690: // ! 691: ! 692: NdisReadConfiguration( ! 693: &Status, ! 694: &ReturnedValue, ! 695: ConfigHandle, ! 696: &CardStr, ! 697: NdisParameterInteger ! 698: ); ! 699: ! 700: if (Status == NDIS_STATUS_SUCCESS) { ! 701: ! 702: if (ReturnedValue->ParameterData.IntegerData == 2) { ! 703: ! 704: Adapter->LanceCard = LANCE_DE201; ! 705: ! 706: } else if (ReturnedValue->ParameterData.IntegerData == 1) { ! 707: ! 708: Adapter->LanceCard = LANCE_DE100; ! 709: ! 710: } else if (ReturnedValue->ParameterData.IntegerData == 3) { ! 711: ! 712: Adapter->LanceCard = LANCE_DEPCA; ! 713: ! 714: #ifndef i386 ! 715: } else if (ReturnedValue->ParameterData.IntegerData == 4) { ! 716: ! 717: Adapter->LanceCard = LANCE_DECTC; ! 718: ! 719: ConfigErrorCode = LanceDecTcGetConfiguration(ConfigHandle, Adapter); ! 720: ! 721: if ( ConfigErrorCode != NDIS_STATUS_SUCCESS ) { ! 722: ConfigError = TRUE; ! 723: } ! 724: #endif // i386 ! 725: ! 726: } else if (ReturnedValue->ParameterData.IntegerData == 5) { ! 727: ! 728: Adapter->LanceCard = LANCE_DE422; ! 729: ! 730: } else if (ReturnedValue->ParameterData.IntegerData == 6) { ! 731: ! 732: // ! 733: // This is the De200, but it operates exactly like the 201. ! 734: // ! 735: ! 736: Adapter->LanceCard = LANCE_DE201; ! 737: ! 738: } else if (ReturnedValue->ParameterData.IntegerData == 7) { ! 739: ! 740: // ! 741: // This is the De101, but it operates exactly like the 100. ! 742: // ! 743: ! 744: Adapter->LanceCard = LANCE_DE100; ! 745: ! 746: } else { ! 747: ! 748: ConfigError = TRUE; ! 749: ConfigErrorCode = NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION; ! 750: ! 751: goto RegisterAdapter; ! 752: } ! 753: ! 754: } ! 755: ! 756: // ! 757: // Read MaxMulticastList ! 758: // ! 759: ! 760: NdisReadConfiguration( ! 761: &Status, ! 762: &ReturnedValue, ! 763: ConfigHandle, ! 764: &MaxMulticastListStr, ! 765: NdisParameterInteger ! 766: ); ! 767: ! 768: if (Status == NDIS_STATUS_SUCCESS) { ! 769: ! 770: MaxMulticastList = ReturnedValue->ParameterData.IntegerData; ! 771: ! 772: } ! 773: ! 774: // ! 775: // Read net address ! 776: // ! 777: ! 778: NdisReadNetworkAddress( ! 779: &Status, ! 780: &NetAddress, ! 781: &Length, ! 782: ConfigHandle ! 783: ); ! 784: ! 785: if ((Length == ETH_LENGTH_OF_ADDRESS) && (Status == NDIS_STATUS_SUCCESS)) { ! 786: ! 787: ETH_COPY_NETWORK_ADDRESS( ! 788: Adapter->CurrentNetworkAddress, ! 789: NetAddress ! 790: ); ! 791: ! 792: } ! 793: ! 794: if (Adapter->LanceCard & (LANCE_DE201 | LANCE_DE100)) { ! 795: ! 796: // ! 797: // Read IoAddress ! 798: // ! 799: ! 800: NdisReadConfiguration( ! 801: &Status, ! 802: &ReturnedValue, ! 803: ConfigHandle, ! 804: &IoAddressStr, ! 805: NdisParameterInteger ! 806: ); ! 807: ! 808: if (Status == NDIS_STATUS_SUCCESS) { ! 809: ! 810: if (ReturnedValue->ParameterData.IntegerData == 1) { ! 811: ! 812: Adapter->RAP = LANCE_DE201_PRI_RAP_ADDRESS; ! 813: ! 814: Adapter->RDP = LANCE_DE201_PRI_RDP_ADDRESS; ! 815: ! 816: Adapter->Nicsr = LANCE_DE201_PRI_NICSR_ADDRESS; ! 817: ! 818: Adapter->NetworkHardwareAddress = LANCE_DE201_PRI_NETWORK_ADDRESS; ! 819: ! 820: } else if (ReturnedValue->ParameterData.IntegerData == 2) { ! 821: ! 822: Adapter->RAP = LANCE_DE201_SEC_RAP_ADDRESS; ! 823: ! 824: Adapter->RDP = LANCE_DE201_SEC_RDP_ADDRESS; ! 825: ! 826: Adapter->Nicsr = LANCE_DE201_SEC_NICSR_ADDRESS; ! 827: ! 828: Adapter->NetworkHardwareAddress = LANCE_DE201_SEC_NETWORK_ADDRESS; ! 829: ! 830: } else { ! 831: ! 832: ConfigError = TRUE; ! 833: ConfigErrorCode = NDIS_ERROR_CODE_BAD_IO_BASE_ADDRESS; ! 834: ! 835: goto RegisterAdapter; ! 836: } ! 837: ! 838: } ! 839: ! 840: ! 841: ! 842: ! 843: // ! 844: // Read Interrupt ! 845: // ! 846: ! 847: NdisReadConfiguration( ! 848: &Status, ! 849: &ReturnedValue, ! 850: ConfigHandle, ! 851: &InterruptStr, ! 852: NdisParameterInteger ! 853: ); ! 854: ! 855: if (Status == NDIS_STATUS_SUCCESS) { ! 856: ! 857: Adapter->InterruptNumber = (CCHAR)(ReturnedValue->ParameterData.IntegerData); ! 858: Adapter->InterruptRequestLevel = Adapter->InterruptNumber; ! 859: ! 860: if (Adapter->LanceCard == LANCE_DE201) { ! 861: ! 862: if (!((Adapter->InterruptNumber == 5) || ! 863: (Adapter->InterruptNumber == 9) || ! 864: (Adapter->InterruptNumber == 10) || ! 865: (Adapter->InterruptNumber == 11) || ! 866: (Adapter->InterruptNumber == 15))) { ! 867: ! 868: ConfigError = TRUE; ! 869: ConfigErrorCode = NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION; ! 870: ! 871: goto RegisterAdapter; ! 872: ! 873: } ! 874: ! 875: } else { ! 876: ! 877: if (!((Adapter->InterruptNumber == 2) || ! 878: (Adapter->InterruptNumber == 3) || ! 879: (Adapter->InterruptNumber == 4) || ! 880: (Adapter->InterruptNumber == 5) || ! 881: (Adapter->InterruptNumber == 7))) { ! 882: ! 883: ConfigError = TRUE; ! 884: ConfigErrorCode = NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION; ! 885: ! 886: goto RegisterAdapter; ! 887: ! 888: } ! 889: ! 890: } ! 891: ! 892: } ! 893: ! 894: ! 895: ! 896: // ! 897: // Read MemoryBaseAddress ! 898: // ! 899: ! 900: ! 901: NdisReadConfiguration( ! 902: &Status, ! 903: &ReturnedValue, ! 904: ConfigHandle, ! 905: &MemoryBaseAddrStr, ! 906: NdisParameterHexInteger ! 907: ); ! 908: ! 909: if (Status == NDIS_STATUS_SUCCESS) { ! 910: ! 911: Adapter->HardwareBaseAddr = (PVOID)(ReturnedValue->ParameterData.IntegerData); ! 912: ! 913: if (!((Adapter->HardwareBaseAddr == (PVOID)0xC0000) || ! 914: (Adapter->HardwareBaseAddr == (PVOID)0xC8000) || ! 915: (Adapter->HardwareBaseAddr == (PVOID)0xD0000) || ! 916: (Adapter->HardwareBaseAddr == (PVOID)0xD8000) || ! 917: (Adapter->HardwareBaseAddr == (PVOID)0xE0000) || ! 918: (Adapter->HardwareBaseAddr == (PVOID)0xE8000))) { ! 919: ! 920: ConfigError = TRUE; ! 921: ConfigErrorCode = NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION; ! 922: ! 923: goto RegisterAdapter; ! 924: ! 925: } ! 926: ! 927: } ! 928: ! 929: ! 930: if (((ULONG)Adapter->HardwareBaseAddr) & 0x8000) { ! 931: ! 932: Adapter->AmountOfHardwareMemory = 0x8000; ! 933: Adapter->HardwareBaseOffset = 0x8000; ! 934: ! 935: } else { ! 936: ! 937: Adapter->AmountOfHardwareMemory = 0x10000; ! 938: Adapter->HardwareBaseOffset = 0x0; ! 939: ! 940: } ! 941: ! 942: } else if (Adapter->LanceCard == LANCE_DEPCA) { ! 943: ! 944: Adapter->NetworkHardwareAddress = LANCE_DEPCA_EPROM_ADDRESS; ! 945: Adapter->InterruptNumber = LANCE_DEPCA_INTERRUPT_VECTOR; ! 946: Adapter->InterruptRequestLevel = LANCE_DEPCA_INTERRUPT_VECTOR; ! 947: Adapter->RAP = LANCE_DEPCA_RAP_ADDRESS; ! 948: Adapter->RDP = LANCE_DEPCA_RDP_ADDRESS; ! 949: Adapter->AmountOfHardwareMemory = LANCE_DEPCA_HARDWARE_MEMORY; ! 950: Adapter->HardwareBaseAddr = LANCE_DEPCA_BASE; ! 951: Adapter->Nicsr = LANCE_DEPCA_NICSR_ADDRESS; ! 952: Adapter->LanceCard = LANCE_DE100; ! 953: ! 954: } else if (Adapter->LanceCard == LANCE_DE422) { ! 955: ! 956: PUCHAR CurrentChar; ! 957: BOOLEAN LastEntry; ! 958: UCHAR InitType; ! 959: USHORT PortAddress, PortValue, Mask; ! 960: ! 961: NdisReadEisaSlotInformation( ! 962: &Status, ! 963: ConfigurationHandle, ! 964: &Adapter->SlotNumber, ! 965: &EisaData ! 966: ); ! 967: ! 968: if (Status != NDIS_STATUS_SUCCESS) { ! 969: ! 970: ConfigError = TRUE; ! 971: ConfigErrorCode = NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION; ! 972: ! 973: goto RegisterAdapter; ! 974: ! 975: } ! 976: ! 977: // ! 978: // Setup Ports ! 979: // ! 980: ! 981: Adapter->RAP = (((ULONG)Adapter->SlotNumber) << 12) + ! 982: LANCE_DE422_RAP_ADDRESS; ! 983: ! 984: Adapter->RDP = (((ULONG)Adapter->SlotNumber) << 12) + ! 985: LANCE_DE422_RDP_ADDRESS; ! 986: ! 987: Adapter->Nicsr = (((ULONG)Adapter->SlotNumber) << 12) + ! 988: LANCE_DE422_NICSR_ADDRESS; ! 989: ! 990: Adapter->NetworkHardwareAddress = (((ULONG)Adapter->SlotNumber) << 12) + ! 991: LANCE_DE422_NETWORK_ADDRESS; ! 992: ! 993: CurrentChar = (PUCHAR) (EisaData.InitializationData); ! 994: LastEntry = FALSE; ! 995: ! 996: while (!LastEntry) { ! 997: ! 998: InitType = *(CurrentChar++); ! 999: PortAddress = *((USHORT UNALIGNED *) CurrentChar++); ! 1000: ! 1001: CurrentChar++; ! 1002: ! 1003: if ((InitType & 0x80) == 0) { ! 1004: LastEntry = TRUE; ! 1005: } ! 1006: ! 1007: ! 1008: ! 1009: if (PortAddress == (USHORT)(Adapter->NetworkHardwareAddress)) { ! 1010: ! 1011: PortValue = *((USHORT UNALIGNED *) CurrentChar++); ! 1012: ! 1013: } else if (PortAddress == ((Adapter->SlotNumber << 12) + ! 1014: LANCE_DE422_EXTENDED_MEMORY_BASE_ADDRESS)) { ! 1015: ! 1016: PortValue = (USHORT)(*(CurrentChar++)); ! 1017: ! 1018: } else { ! 1019: ! 1020: continue; ! 1021: ! 1022: } ! 1023: ! 1024: ! 1025: ! 1026: if (InitType & 0x40) { ! 1027: ! 1028: if (PortAddress == Adapter->NetworkHardwareAddress) { ! 1029: ! 1030: Mask = *((USHORT UNALIGNED *) CurrentChar++); ! 1031: ! 1032: } else { ! 1033: ! 1034: Mask = (USHORT)(*(CurrentChar++)); ! 1035: ! 1036: } ! 1037: ! 1038: } else { ! 1039: ! 1040: Mask = 0; ! 1041: ! 1042: } ! 1043: ! 1044: if (PortAddress == Adapter->NetworkHardwareAddress) { ! 1045: ! 1046: ConfigValue &= Mask; ! 1047: ConfigValue |= PortValue; ! 1048: ! 1049: } else { ! 1050: ! 1051: HiBaseValue &= (UCHAR)Mask; ! 1052: HiBaseValue |= (UCHAR)PortValue; ! 1053: ! 1054: } ! 1055: ! 1056: } ! 1057: ! 1058: // ! 1059: // Interpret values ! 1060: // ! 1061: ! 1062: switch (ConfigValue & 0x78) { ! 1063: ! 1064: case 0x40: ! 1065: ! 1066: Adapter->InterruptNumber = 11; ! 1067: break; ! 1068: ! 1069: case 0x20: ! 1070: ! 1071: Adapter->InterruptNumber = 10; ! 1072: break; ! 1073: ! 1074: case 0x10: ! 1075: ! 1076: Adapter->InterruptNumber = 9; ! 1077: break; ! 1078: ! 1079: case 0x08: ! 1080: ! 1081: Adapter->InterruptNumber = 5; ! 1082: break; ! 1083: ! 1084: default: ! 1085: ! 1086: ConfigError = TRUE; ! 1087: ConfigErrorCode = NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION; ! 1088: ! 1089: goto RegisterAdapter; ! 1090: ! 1091: } ! 1092: ! 1093: Adapter->InterruptRequestLevel = Adapter->InterruptNumber; ! 1094: // ! 1095: // We postpone the rest of the processing since we have to read from ! 1096: // the NICSR to get the amount of hardware memory and cannot do that ! 1097: // until after we have called NdisRegisterAdater. ! 1098: // ! 1099: ! 1100: } ! 1101: ! 1102: RegisterAdapter: ! 1103: ! 1104: NdisCloseConfiguration(ConfigHandle); ! 1105: ! 1106: // ! 1107: // The adapter is initialized, register it with NDIS. ! 1108: // This must occur before interrupts are enabled since the ! 1109: // InitializeInterrupt routine requires the NdisAdapterHandle ! 1110: // ! 1111: ! 1112: // ! 1113: // Set up the AdapterInformation structure; zero it ! 1114: // first in case it is extended later. ! 1115: // ! 1116: ! 1117: LANCE_ZERO_MEMORY(&AdapterInformation, sizeof(NDIS_ADAPTER_INFORMATION)); ! 1118: ! 1119: if (Adapter->LanceCard & (LANCE_DE100 | LANCE_DE201)) { ! 1120: ! 1121: AdapterInformation.AdapterType = NdisInterfaceIsa; ! 1122: ! 1123: } else if (Adapter->LanceCard == LANCE_DE422) { ! 1124: ! 1125: AdapterInformation.AdapterType = NdisInterfaceEisa; ! 1126: ! 1127: } ! 1128: ! 1129: AdapterInformation.NumberOfPortDescriptors = 1; ! 1130: ! 1131: #ifndef i386 ! 1132: ! 1133: if (Adapter->LanceCard == LANCE_DECTC) { ! 1134: ! 1135: Status = LanceDecTcGetInformation(Adapter, &AdapterInformation); ! 1136: if (Status != NDIS_STATUS_SUCCESS) { ! 1137: return Status; ! 1138: } ! 1139: ! 1140: } else ! 1141: ! 1142: #endif ! 1143: ! 1144: if (Adapter->LanceCard & (LANCE_DE100 | LANCE_DE201)) { ! 1145: ! 1146: AdapterInformation.PortDescriptors[0].InitialPort = (ULONG)Adapter->Nicsr; ! 1147: AdapterInformation.PortDescriptors[0].NumberOfPorts = 0x10; ! 1148: ! 1149: } else if (Adapter->LanceCard == LANCE_DE422) { ! 1150: ! 1151: AdapterInformation.PortDescriptors[0].InitialPort = (ULONG)(Adapter->Nicsr); ! 1152: AdapterInformation.PortDescriptors[0].NumberOfPorts = 0x90; ! 1153: ! 1154: } ! 1155: ! 1156: if ((Status = NdisRegisterAdapter( ! 1157: &Adapter->NdisAdapterHandle, ! 1158: Adapter->NdisMacHandle, ! 1159: Adapter, ! 1160: ConfigurationHandle, ! 1161: AdapterName, ! 1162: &AdapterInformation ! 1163: )) != NDIS_STATUS_SUCCESS) { ! 1164: ! 1165: LANCE_FREE_PHYS(Adapter, sizeof(LANCE_ADAPTER)); ! 1166: ! 1167: return Status; ! 1168: ! 1169: } ! 1170: ! 1171: ! 1172: if (ConfigError) { ! 1173: ! 1174: NdisWriteErrorLogEntry( ! 1175: Adapter->NdisAdapterHandle, ! 1176: ConfigErrorCode, ! 1177: 0 ! 1178: ); ! 1179: ! 1180: NdisDeregisterAdapter(Adapter->NdisAdapterHandle); ! 1181: ! 1182: LANCE_FREE_PHYS(Adapter, sizeof(LANCE_ADAPTER)); ! 1183: ! 1184: return NDIS_STATUS_FAILURE; ! 1185: ! 1186: } ! 1187: ! 1188: // ! 1189: // Now we get the rest of the information necessary for the DE422. ! 1190: // ! 1191: ! 1192: if (Adapter->LanceCard == LANCE_DE422) { ! 1193: ! 1194: // ! 1195: // Verify card is a DE422 ! 1196: // ! 1197: ! 1198: NdisReadPortUshort(Adapter->NdisAdapterHandle, ! 1199: (((ULONG)(Adapter->SlotNumber)) << 12) + ! 1200: LANCE_DE422_EISA_IDENTIFICATION, ! 1201: &RegUshort ! 1202: ); ! 1203: ! 1204: if (RegUshort != 0xA310) { ! 1205: ! 1206: // ! 1207: // Not a DE422 card ! 1208: // ! 1209: ! 1210: NdisWriteErrorLogEntry( ! 1211: Adapter->NdisAdapterHandle, ! 1212: NDIS_ERROR_CODE_ADAPTER_NOT_FOUND, ! 1213: 0 ! 1214: ); ! 1215: ! 1216: NdisDeregisterAdapter(Adapter->NdisAdapterHandle); ! 1217: ! 1218: LANCE_FREE_PHYS(Adapter, sizeof(LANCE_ADAPTER)); ! 1219: ! 1220: return NDIS_STATUS_FAILURE; ! 1221: ! 1222: } ! 1223: ! 1224: NdisReadPortUshort(Adapter->NdisAdapterHandle, ! 1225: (((ULONG)(Adapter->SlotNumber)) << 12) + ! 1226: LANCE_DE422_EISA_IDENTIFICATION + 2, ! 1227: &RegUshort ! 1228: ); ! 1229: ! 1230: if (RegUshort != 0x2042) { ! 1231: ! 1232: // ! 1233: // Not a DE422 card ! 1234: // ! 1235: ! 1236: NdisWriteErrorLogEntry( ! 1237: Adapter->NdisAdapterHandle, ! 1238: NDIS_ERROR_CODE_ADAPTER_NOT_FOUND, ! 1239: 0 ! 1240: ); ! 1241: ! 1242: NdisDeregisterAdapter(Adapter->NdisAdapterHandle); ! 1243: ! 1244: LANCE_FREE_PHYS(Adapter, sizeof(LANCE_ADAPTER)); ! 1245: ! 1246: return NDIS_STATUS_FAILURE; ! 1247: ! 1248: } ! 1249: ! 1250: // ! 1251: // Check that the card is enabled. ! 1252: // ! 1253: ! 1254: NdisReadPortUchar(Adapter->NdisAdapterHandle, ! 1255: (((ULONG)(Adapter->SlotNumber)) << 12) + ! 1256: LANCE_DE422_EISA_CONTROL, ! 1257: &RegUchar ! 1258: ); ! 1259: ! 1260: if (!(RegUchar & 0x1)) { ! 1261: ! 1262: NdisWriteErrorLogEntry( ! 1263: Adapter->NdisAdapterHandle, ! 1264: NDIS_ERROR_CODE_ADAPTER_DISABLED, ! 1265: 0 ! 1266: ); ! 1267: ! 1268: NdisDeregisterAdapter(Adapter->NdisAdapterHandle); ! 1269: ! 1270: LANCE_FREE_PHYS(Adapter, sizeof(LANCE_ADAPTER)); ! 1271: ! 1272: return NDIS_STATUS_FAILURE; ! 1273: ! 1274: } ! 1275: ! 1276: // ! 1277: // Get Memory size ! 1278: // ! 1279: ! 1280: NdisReadPortUshort(Adapter->NdisAdapterHandle, ! 1281: Adapter->Nicsr, ! 1282: &RegUshort ! 1283: ); ! 1284: ! 1285: if (RegUshort & LANCE_NICSR_BUFFER_SIZE) { ! 1286: ! 1287: Adapter->AmountOfHardwareMemory = 0x8000; ! 1288: ! 1289: } else if (RegUshort & LANCE_NICSR_128K) { ! 1290: ! 1291: Adapter->AmountOfHardwareMemory = 0x20000; ! 1292: Adapter->NicsrDefaultValue = LANCE_NICSR_128K; ! 1293: ! 1294: } else { ! 1295: ! 1296: Adapter->AmountOfHardwareMemory = 0x10000; ! 1297: ! 1298: } ! 1299: ! 1300: // ! 1301: // Get Base memory address ! 1302: // ! 1303: ! 1304: switch (Adapter->AmountOfHardwareMemory) { ! 1305: ! 1306: case 0x8000: ! 1307: ! 1308: switch (ConfigValue & 0x07) { ! 1309: ! 1310: case 0x04: ! 1311: ! 1312: Adapter->HardwareBaseAddr = (PVOID)((HiBaseValue << 24) + 0xC8000); ! 1313: Adapter->HardwareBaseOffset = 0x8000; ! 1314: break; ! 1315: ! 1316: case 0x05: ! 1317: ! 1318: Adapter->HardwareBaseAddr = (PVOID)((HiBaseValue << 24) + 0xE8000); ! 1319: Adapter->HardwareBaseOffset = 0x8000; ! 1320: break; ! 1321: ! 1322: case 0x06: ! 1323: ! 1324: Adapter->HardwareBaseAddr = (PVOID)((HiBaseValue << 24) + 0xD8000); ! 1325: Adapter->HardwareBaseOffset = 0x8000; ! 1326: break; ! 1327: ! 1328: case 0x07: ! 1329: ! 1330: Adapter->HardwareBaseAddr = (PVOID)((HiBaseValue << 24) + 0xF8000); ! 1331: Adapter->HardwareBaseOffset = 0x8000; ! 1332: break; ! 1333: ! 1334: default: ! 1335: ! 1336: NdisWriteErrorLogEntry( ! 1337: Adapter->NdisAdapterHandle, ! 1338: NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION, ! 1339: 0 ! 1340: ); ! 1341: ! 1342: NdisDeregisterAdapter(Adapter->NdisAdapterHandle); ! 1343: ! 1344: LANCE_FREE_PHYS(Adapter, sizeof(LANCE_ADAPTER)); ! 1345: ! 1346: return NDIS_STATUS_FAILURE; ! 1347: ! 1348: } ! 1349: break; ! 1350: ! 1351: case 0x10000: ! 1352: ! 1353: switch (ConfigValue & 0x07) { ! 1354: ! 1355: case 0x00: ! 1356: ! 1357: Adapter->HardwareBaseAddr = (PVOID)((HiBaseValue << 24) + 0xC0000); ! 1358: Adapter->HardwareBaseOffset = 0x0000; ! 1359: break; ! 1360: ! 1361: case 0x01: ! 1362: ! 1363: Adapter->HardwareBaseAddr = (PVOID)((HiBaseValue << 24) + 0xE0000); ! 1364: Adapter->HardwareBaseOffset = 0x0000; ! 1365: break; ! 1366: ! 1367: case 0x02: ! 1368: ! 1369: Adapter->HardwareBaseAddr = (PVOID)((HiBaseValue << 24) + 0xD0000); ! 1370: Adapter->HardwareBaseOffset = 0x0000; ! 1371: break; ! 1372: ! 1373: case 0x03: ! 1374: ! 1375: Adapter->HardwareBaseAddr = (PVOID)((HiBaseValue << 24) + 0xF0000); ! 1376: Adapter->HardwareBaseOffset = 0x0000; ! 1377: break; ! 1378: ! 1379: default: ! 1380: ! 1381: NdisWriteErrorLogEntry( ! 1382: Adapter->NdisAdapterHandle, ! 1383: NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION, ! 1384: 0 ! 1385: ); ! 1386: ! 1387: NdisDeregisterAdapter(Adapter->NdisAdapterHandle); ! 1388: ! 1389: LANCE_FREE_PHYS(Adapter, sizeof(LANCE_ADAPTER)); ! 1390: ! 1391: return NDIS_STATUS_FAILURE; ! 1392: ! 1393: } ! 1394: break; ! 1395: ! 1396: case 0x20000: ! 1397: ! 1398: switch (ConfigValue & 0x07) { ! 1399: ! 1400: case 0x00: ! 1401: ! 1402: Adapter->HardwareBaseAddr = (PVOID)((HiBaseValue << 24) + 0xC0000); ! 1403: Adapter->HardwareBaseOffset = 0x0000; ! 1404: break; ! 1405: ! 1406: case 0x01: ! 1407: ! 1408: Adapter->HardwareBaseAddr = (PVOID)((HiBaseValue << 24) + 0xD0000); ! 1409: Adapter->HardwareBaseOffset = 0x0000; ! 1410: break; ! 1411: ! 1412: default: ! 1413: ! 1414: NdisWriteErrorLogEntry( ! 1415: Adapter->NdisAdapterHandle, ! 1416: NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION, ! 1417: 0 ! 1418: ); ! 1419: ! 1420: NdisDeregisterAdapter(Adapter->NdisAdapterHandle); ! 1421: ! 1422: LANCE_FREE_PHYS(Adapter, sizeof(LANCE_ADAPTER)); ! 1423: ! 1424: return NDIS_STATUS_FAILURE; ! 1425: ! 1426: } ! 1427: ! 1428: break; ! 1429: ! 1430: } ! 1431: ! 1432: } ! 1433: ! 1434: // ! 1435: // Set the port addresses and the network address. ! 1436: // ! 1437: ! 1438: Adapter->InterruptsStopped = FALSE; ! 1439: Adapter->MaxMulticastList = MaxMulticastList; ! 1440: ! 1441: Status = LanceRegisterAdapter( ! 1442: Adapter ! 1443: ); ! 1444: ! 1445: if (Status != NDIS_STATUS_SUCCESS) { ! 1446: ! 1447: ! 1448: ! 1449: // ! 1450: // LanceRegisterAdapter failed. ! 1451: // ! 1452: ! 1453: NdisDeregisterAdapter(Adapter->NdisAdapterHandle); ! 1454: ! 1455: LANCE_FREE_PHYS(Adapter, sizeof(LANCE_ADAPTER)); ! 1456: ! 1457: return NDIS_STATUS_FAILURE; ! 1458: ! 1459: } ! 1460: ! 1461: return NDIS_STATUS_SUCCESS; ! 1462: } ! 1463: ! 1464: ! 1465: VOID ! 1466: LanceRemoveAdapter( ! 1467: IN PVOID MacAdapterContext ! 1468: ) ! 1469: /*++ ! 1470: ! 1471: Routine Description: ! 1472: ! 1473: LanceRemoveAdapter removes an adapter previously registered ! 1474: with NdisRegisterAdapter. ! 1475: ! 1476: Arguments: ! 1477: ! 1478: MacAdapterContext - The context value that the MAC passed ! 1479: to NdisRegisterAdapter; actually as pointer to an ! 1480: LANCE_ADAPTER. ! 1481: ! 1482: Return Value: ! 1483: ! 1484: None. ! 1485: ! 1486: --*/ ! 1487: { ! 1488: ! 1489: PLANCE_ADAPTER Adapter; ! 1490: BOOLEAN Canceled; ! 1491: ! 1492: Adapter = PLANCE_ADAPTER_FROM_CONTEXT_HANDLE(MacAdapterContext); ! 1493: ! 1494: // ! 1495: // There are no opens left, so remove ourselves. ! 1496: // ! 1497: ! 1498: #if LANCELOG ! 1499: if (LogTimerRunning) { ! 1500: NdisCancelTimer(&LogTimer, &Canceled); ! 1501: LogTimerRunning = FALSE; ! 1502: } ! 1503: #endif ! 1504: ! 1505: NdisCancelTimer(&Adapter->WakeUpTimer, &Canceled); ! 1506: ! 1507: if ( !Canceled ) { ! 1508: ! 1509: NdisStallExecution(500000); ! 1510: } ! 1511: ! 1512: NdisRemoveInterrupt(&(Adapter->Interrupt)); ! 1513: ! 1514: NdisUnmapIoSpace( ! 1515: Adapter->NdisAdapterHandle, ! 1516: Adapter->MmMappedBaseAddr, ! 1517: Adapter->AmountOfHardwareMemory ! 1518: ); ! 1519: ! 1520: EthDeleteFilter(Adapter->FilterDB); ! 1521: ! 1522: NdisDeregisterAdapter(Adapter->NdisAdapterHandle); ! 1523: ! 1524: NdisFreeSpinLock(&Adapter->Lock); ! 1525: ! 1526: NdisFreeMemory(Adapter, sizeof(LANCE_ADAPTER), 0); ! 1527: ! 1528: return; ! 1529: } ! 1530: ! 1531: VOID ! 1532: LanceUnload( ! 1533: IN NDIS_HANDLE MacMacContext ! 1534: ) ! 1535: ! 1536: /*++ ! 1537: ! 1538: Routine Description: ! 1539: ! 1540: LanceUnload is called when the MAC is to unload itself. ! 1541: ! 1542: Arguments: ! 1543: ! 1544: MacMacContext - not used. ! 1545: ! 1546: Return Value: ! 1547: ! 1548: None. ! 1549: ! 1550: --*/ ! 1551: ! 1552: { ! 1553: NDIS_STATUS InitStatus; ! 1554: ! 1555: UNREFERENCED_PARAMETER(MacMacContext); ! 1556: ! 1557: NdisDeregisterMac( ! 1558: &InitStatus, ! 1559: LanceMacHandle ! 1560: ); ! 1561: ! 1562: NdisTerminateWrapper( ! 1563: LanceNdisWrapperHandle, ! 1564: NULL ! 1565: ); ! 1566: ! 1567: return; ! 1568: } ! 1569: ! 1570: LanceRegisterAdapter( ! 1571: IN PLANCE_ADAPTER Adapter ! 1572: ) ! 1573: ! 1574: /*++ ! 1575: ! 1576: Routine Description: ! 1577: ! 1578: This routine (and its interface) are not portable. They are ! 1579: defined by the OS, the architecture, and the particular LANCE ! 1580: implementation. ! 1581: ! 1582: This routine is responsible for the allocation of the datastructures ! 1583: for the driver as well as any hardware specific details necessary ! 1584: to talk with the device. ! 1585: ! 1586: Arguments: ! 1587: ! 1588: Adapter - Pointer to the adapter block. ! 1589: ! 1590: Return Value: ! 1591: ! 1592: Returns false if anything occurred that prevents the initialization ! 1593: of the adapter. ! 1594: ! 1595: --*/ ! 1596: { ! 1597: ! 1598: // ! 1599: // Result of Ndis Calls. ! 1600: // ! 1601: NDIS_STATUS Status; ! 1602: ! 1603: ! 1604: // ! 1605: // We put in this assertion to make sure that ushort are 2 bytes. ! 1606: // if they aren't then the initialization block definition needs ! 1607: // to be changed. ! 1608: // ! 1609: // Also all of the logic that deals with status registers assumes ! 1610: // that control registers are only 2 bytes. ! 1611: // ! 1612: ! 1613: ASSERT(sizeof(USHORT) == 2); ! 1614: ! 1615: // ! 1616: // This assertion checks that the network address in the initialization ! 1617: // block does start on the third byte of the initalization block. ! 1618: // ! 1619: // If this is true then other fields in the initialization block ! 1620: // and the send and receive descriptors should be at their correct ! 1621: // locations. ! 1622: // ! 1623: ! 1624: ASSERT(FIELD_OFFSET(LANCE_INITIALIZATION_BLOCK,PhysicalAddress[0]) == 2); ! 1625: ! 1626: ! 1627: // ! 1628: // Allocate memory for all of the adapter structures. ! 1629: // ! 1630: ! 1631: Adapter->NumberOfTransmitRings = LANCE_NUMBER_OF_TRANSMIT_RINGS; ! 1632: Adapter->LogNumberTransmitRings = LANCE_LOG_TRANSMIT_RINGS; ! 1633: ! 1634: #ifndef i386 ! 1635: ! 1636: if (Adapter->LanceCard == LANCE_DECTC) { ! 1637: ! 1638: Status = LanceDecTcSoftwareDetails(Adapter); ! 1639: if (Status != NDIS_STATUS_SUCCESS) { ! 1640: return Status; ! 1641: } ! 1642: ! 1643: } else ! 1644: ! 1645: ! 1646: #endif ! 1647: ! 1648: { ! 1649: ! 1650: if (Adapter->AmountOfHardwareMemory == 0x20000) { ! 1651: ! 1652: ASSERT(Adapter->LanceCard == LANCE_DE422); ! 1653: ! 1654: Adapter->SizeOfReceiveBuffer = LANCE_128K_SIZE_OF_RECEIVE_BUFFERS; ! 1655: Adapter->NumberOfSmallBuffers = LANCE_128K_NUMBER_OF_SMALL_BUFFERS; ! 1656: Adapter->NumberOfMediumBuffers= LANCE_128K_NUMBER_OF_MEDIUM_BUFFERS; ! 1657: Adapter->NumberOfLargeBuffers = LANCE_128K_NUMBER_OF_LARGE_BUFFERS; ! 1658: ! 1659: Adapter->NumberOfReceiveRings = LANCE_128K_NUMBER_OF_RECEIVE_RINGS; ! 1660: Adapter->LogNumberReceiveRings = LANCE_128K_LOG_RECEIVE_RINGS; ! 1661: ! 1662: } else if (Adapter->AmountOfHardwareMemory == 0x10000) { ! 1663: ! 1664: Adapter->NumberOfReceiveRings = LANCE_64K_NUMBER_OF_RECEIVE_RINGS; ! 1665: Adapter->LogNumberReceiveRings = LANCE_64K_LOG_RECEIVE_RINGS; ! 1666: ! 1667: Adapter->SizeOfReceiveBuffer = LANCE_64K_SIZE_OF_RECEIVE_BUFFERS; ! 1668: Adapter->NumberOfSmallBuffers = LANCE_64K_NUMBER_OF_SMALL_BUFFERS; ! 1669: Adapter->NumberOfMediumBuffers= LANCE_64K_NUMBER_OF_MEDIUM_BUFFERS; ! 1670: Adapter->NumberOfLargeBuffers = LANCE_64K_NUMBER_OF_LARGE_BUFFERS; ! 1671: ! 1672: } else { ! 1673: ! 1674: Adapter->NumberOfReceiveRings = LANCE_32K_NUMBER_OF_RECEIVE_RINGS; ! 1675: Adapter->LogNumberReceiveRings = LANCE_32K_LOG_RECEIVE_RINGS; ! 1676: ! 1677: Adapter->SizeOfReceiveBuffer = LANCE_32K_SIZE_OF_RECEIVE_BUFFERS; ! 1678: Adapter->NumberOfSmallBuffers = LANCE_32K_NUMBER_OF_SMALL_BUFFERS; ! 1679: Adapter->NumberOfMediumBuffers= LANCE_32K_NUMBER_OF_MEDIUM_BUFFERS; ! 1680: Adapter->NumberOfLargeBuffers = LANCE_32K_NUMBER_OF_LARGE_BUFFERS; ! 1681: ! 1682: } ! 1683: ! 1684: } ! 1685: ! 1686: #ifndef i386 ! 1687: ! 1688: if (((Adapter->LanceCard == LANCE_DECTC) && ! 1689: (LanceDecTcHardwareDetails(Adapter) == NDIS_STATUS_SUCCESS)) || ! 1690: LanceHardwareDetails(Adapter)) { ! 1691: ! 1692: #else ! 1693: ! 1694: if (LanceHardwareDetails(Adapter)) { ! 1695: ! 1696: #endif ! 1697: ! 1698: NDIS_PHYSICAL_ADDRESS PhysicalAddress; ! 1699: ! 1700: // ! 1701: // Get hold of the RAP and RDP address as well ! 1702: // as filling in the hardware assigned network ! 1703: // address. ! 1704: // ! 1705: ! 1706: if ((Adapter->CurrentNetworkAddress[0] == 0x00) && ! 1707: (Adapter->CurrentNetworkAddress[1] == 0x00) && ! 1708: (Adapter->CurrentNetworkAddress[2] == 0x00) && ! 1709: (Adapter->CurrentNetworkAddress[3] == 0x00) && ! 1710: (Adapter->CurrentNetworkAddress[4] == 0x00) && ! 1711: (Adapter->CurrentNetworkAddress[5] == 0x00)) { ! 1712: ! 1713: Adapter->CurrentNetworkAddress[0] = Adapter->NetworkAddress[0]; ! 1714: Adapter->CurrentNetworkAddress[1] = Adapter->NetworkAddress[1]; ! 1715: Adapter->CurrentNetworkAddress[2] = Adapter->NetworkAddress[2]; ! 1716: Adapter->CurrentNetworkAddress[3] = Adapter->NetworkAddress[3]; ! 1717: Adapter->CurrentNetworkAddress[4] = Adapter->NetworkAddress[4]; ! 1718: Adapter->CurrentNetworkAddress[5] = Adapter->NetworkAddress[5]; ! 1719: ! 1720: } ! 1721: ! 1722: NdisSetPhysicalAddressHigh(PhysicalAddress, 0); ! 1723: NdisSetPhysicalAddressLow(PhysicalAddress, (ULONG)(Adapter->HardwareBaseAddr)); ! 1724: ! 1725: NdisMapIoSpace( ! 1726: &Status, ! 1727: &(Adapter->MmMappedBaseAddr), ! 1728: Adapter->NdisAdapterHandle, ! 1729: PhysicalAddress, ! 1730: Adapter->AmountOfHardwareMemory ! 1731: ); ! 1732: ! 1733: if (Status != NDIS_STATUS_SUCCESS) { ! 1734: ! 1735: NdisWriteErrorLogEntry( ! 1736: Adapter->NdisAdapterHandle, ! 1737: NDIS_ERROR_CODE_RESOURCE_CONFLICT, ! 1738: 0 ! 1739: ); ! 1740: ! 1741: return(Status); ! 1742: ! 1743: } ! 1744: ! 1745: Adapter->CurrentMemoryFirstFree = Adapter->MmMappedBaseAddr; ! 1746: ! 1747: ! 1748: Adapter->MemoryFirstUnavailable = ! 1749: (PUCHAR)(Adapter->CurrentMemoryFirstFree) + ! 1750: Adapter->AmountOfHardwareMemory; ! 1751: ! 1752: if (!AllocateAdapterMemory(Adapter)) { ! 1753: ! 1754: NdisWriteErrorLogEntry( ! 1755: Adapter->NdisAdapterHandle, ! 1756: NDIS_ERROR_CODE_OUT_OF_RESOURCES, ! 1757: 0 ! 1758: ); ! 1759: ! 1760: return( NDIS_STATUS_ADAPTER_NOT_FOUND ); ! 1761: ! 1762: } ! 1763: ! 1764: InitializeListHead(&Adapter->OpenBindings); ! 1765: InitializeListHead(&Adapter->CloseList); ! 1766: ! 1767: NdisAllocateSpinLock(&Adapter->Lock); ! 1768: ! 1769: Adapter->InterruptDPC = (PVOID)LanceStandardInterruptDPC; ! 1770: Adapter->LoopbackDPC = (PVOID)LanceStandardInterruptDPC; ! 1771: ! 1772: ! 1773: Adapter->AllocateableRing = Adapter->TransmitRing; ! 1774: Adapter->TransmittingRing = Adapter->TransmitRing; ! 1775: Adapter->FirstUncommittedRing = Adapter->TransmitRing; ! 1776: Adapter->NumberOfAvailableRings = Adapter->NumberOfTransmitRings; ! 1777: Adapter->LastTransmitRingEntry = Adapter->TransmitRing + ! 1778: (Adapter->NumberOfTransmitRings-1); ! 1779: ! 1780: Adapter->FirstLoopBack = NULL; ! 1781: Adapter->LastLoopBack = NULL; ! 1782: Adapter->FirstFinishTransmit = NULL; ! 1783: Adapter->LastFinishTransmit = NULL; ! 1784: Adapter->StageOpen = TRUE; ! 1785: Adapter->AlreadyProcessingStage = FALSE; ! 1786: Adapter->FirstStage1Packet = NULL; ! 1787: Adapter->LastStage1Packet = NULL; ! 1788: Adapter->CurrentReceiveIndex = 0; ! 1789: Adapter->OutOfReceiveBuffers = 0; ! 1790: Adapter->CRCError = 0; ! 1791: Adapter->FramingError = 0; ! 1792: Adapter->RetryFailure = 0; ! 1793: Adapter->LostCarrier = 0; ! 1794: Adapter->LateCollision = 0; ! 1795: Adapter->UnderFlow = 0; ! 1796: Adapter->Deferred = 0; ! 1797: Adapter->OneRetry = 0; ! 1798: Adapter->MoreThanOneRetry = 0; ! 1799: Adapter->ResetInProgress = FALSE; ! 1800: Adapter->ResetInitStarted = FALSE; ! 1801: Adapter->ResettingOpen = NULL; ! 1802: Adapter->FirstInitialization = TRUE; ! 1803: Adapter->HardwareFailure = FALSE; ! 1804: Adapter->PendQueue = NULL; ! 1805: Adapter->PendQueueTail = NULL; ! 1806: ! 1807: // ! 1808: // First we make sure that the device is stopped. We call ! 1809: // directly since we don't have an Interrupt object yet. ! 1810: // ! 1811: ! 1812: LanceSyncStopChip(Adapter); ! 1813: ! 1814: ! 1815: // ! 1816: // Initialize the interrupt. ! 1817: // ! 1818: ! 1819: NdisInitializeInterrupt( ! 1820: &Status, ! 1821: &Adapter->Interrupt, ! 1822: Adapter->NdisAdapterHandle, ! 1823: (PNDIS_INTERRUPT_SERVICE)LanceISR, ! 1824: Adapter, ! 1825: (PNDIS_DEFERRED_PROCESSING)Adapter->InterruptDPC, ! 1826: Adapter->InterruptNumber, ! 1827: Adapter->InterruptRequestLevel, ! 1828: FALSE, ! 1829: NdisInterruptLatched ! 1830: ); ! 1831: ! 1832: if (Status != NDIS_STATUS_SUCCESS){ ! 1833: ! 1834: NdisWriteErrorLogEntry( ! 1835: Adapter->NdisAdapterHandle, ! 1836: NDIS_ERROR_CODE_INTERRUPT_CONNECT, ! 1837: 0 ! 1838: ); ! 1839: ! 1840: NdisUnmapIoSpace( ! 1841: Adapter->NdisAdapterHandle, ! 1842: Adapter->MmMappedBaseAddr, ! 1843: Adapter->AmountOfHardwareMemory); ! 1844: ! 1845: DeleteAdapterMemory(Adapter); ! 1846: ! 1847: return Status; ! 1848: } ! 1849: ! 1850: ! 1851: if (!EthCreateFilter( ! 1852: Adapter->MaxMulticastList, ! 1853: LanceChangeMulticastAddresses, ! 1854: LanceChangeFilterClasses, ! 1855: LanceCloseAction, ! 1856: Adapter->CurrentNetworkAddress, ! 1857: &Adapter->Lock, ! 1858: &Adapter->FilterDB ! 1859: )) { ! 1860: ! 1861: NdisWriteErrorLogEntry( ! 1862: Adapter->NdisAdapterHandle, ! 1863: NDIS_ERROR_CODE_OUT_OF_RESOURCES, ! 1864: 0 ! 1865: ); ! 1866: ! 1867: NdisUnmapIoSpace( ! 1868: Adapter->NdisAdapterHandle, ! 1869: Adapter->MmMappedBaseAddr, ! 1870: Adapter->AmountOfHardwareMemory); ! 1871: ! 1872: DeleteAdapterMemory(Adapter); ! 1873: ! 1874: NdisRemoveInterrupt(&Adapter->Interrupt); ! 1875: ! 1876: return NDIS_STATUS_RESOURCES; ! 1877: ! 1878: } ! 1879: ! 1880: if ((Status = LanceInitialInit(Adapter)) != NDIS_STATUS_SUCCESS) { ! 1881: ! 1882: ! 1883: NdisWriteErrorLogEntry( ! 1884: Adapter->NdisAdapterHandle, ! 1885: NDIS_ERROR_CODE_HARDWARE_FAILURE, ! 1886: 0 ! 1887: ); ! 1888: ! 1889: EthDeleteFilter(Adapter->FilterDB); ! 1890: ! 1891: NdisUnmapIoSpace( ! 1892: Adapter->NdisAdapterHandle, ! 1893: Adapter->MmMappedBaseAddr, ! 1894: Adapter->AmountOfHardwareMemory); ! 1895: ! 1896: DeleteAdapterMemory(Adapter); ! 1897: ! 1898: NdisRemoveInterrupt(&Adapter->Interrupt); ! 1899: ! 1900: return Status; ! 1901: ! 1902: } ! 1903: ! 1904: // ! 1905: // Initialize the wake up timer to catch interrupts that ! 1906: // don't complete. It fires continuously ! 1907: // every 5 seconds, and we check if there are any ! 1908: // uncompleted operations from the previous two-second ! 1909: // period. ! 1910: // ! 1911: ! 1912: Adapter->WakeUpDpc = (PVOID)LanceWakeUpDpc; ! 1913: ! 1914: NdisInitializeTimer(&Adapter->WakeUpTimer, ! 1915: (PVOID)(Adapter->WakeUpDpc), ! 1916: Adapter ); ! 1917: ! 1918: NdisSetTimer( ! 1919: &Adapter->WakeUpTimer, ! 1920: 5000 ! 1921: ); ! 1922: ! 1923: return Status; ! 1924: ! 1925: } else { ! 1926: ! 1927: NdisWriteErrorLogEntry( ! 1928: Adapter->NdisAdapterHandle, ! 1929: NDIS_ERROR_CODE_ADAPTER_NOT_FOUND, ! 1930: 0 ! 1931: ); ! 1932: ! 1933: return NDIS_STATUS_FAILURE; ! 1934: ! 1935: } ! 1936: ! 1937: } ! 1938: ! 1939: extern ! 1940: NDIS_STATUS ! 1941: LanceInitialInit( ! 1942: IN PLANCE_ADAPTER Adapter ! 1943: ) ! 1944: ! 1945: /*++ ! 1946: ! 1947: Routine Description: ! 1948: ! 1949: This routine sets up the initial init of the driver. ! 1950: ! 1951: Arguments: ! 1952: ! 1953: Adapter - The adapter for the hardware. ! 1954: ! 1955: Return Value: ! 1956: ! 1957: None. ! 1958: ! 1959: --*/ ! 1960: ! 1961: { ! 1962: ! 1963: if (Adapter->LanceCard & (LANCE_DE201 | LANCE_DE100 | LANCE_DE422)) { ! 1964: ! 1965: // ! 1966: // Allow interrupts ! 1967: // ! 1968: ! 1969: Adapter->InterruptsStopped = FALSE; ! 1970: ! 1971: LOG(UNPEND); ! 1972: ! 1973: LANCE_WRITE_NICSR(Adapter, LANCE_NICSR_INT_ON); ! 1974: ! 1975: } ! 1976: ! 1977: SetInitBlockAndInit(Adapter); ! 1978: ! 1979: // ! 1980: // Delay execution for 1/2 second to give the lance ! 1981: // time to initialize. ! 1982: // ! 1983: ! 1984: ! 1985: NdisStallExecution( 500000 ); ! 1986: ! 1987: NdisAcquireSpinLock(&Adapter->Lock); ! 1988: ! 1989: // ! 1990: // The only way that first initialization could have ! 1991: // been turned off is if we actually initialized. ! 1992: // ! 1993: ! 1994: if (!Adapter->FirstInitialization) { ! 1995: ! 1996: // ! 1997: // Initialize the Deferred processing timer. ! 1998: // ! 1999: ! 2000: NdisInitializeTimer(&Adapter->DeferredTimer, ! 2001: Adapter->LoopbackDPC, ! 2002: Adapter); ! 2003: ! 2004: #if LANCELOG ! 2005: ! 2006: if (!LogTimerRunning) { ! 2007: ! 2008: NdisInitializeTimer(&LogTimer, ! 2009: (PVOID)LogDpc, ! 2010: (PVOID)(&LogTimer) ! 2011: ); ! 2012: ! 2013: NdisSetTimer(&LogTimer,1000); ! 2014: ! 2015: LogTimerRunning = TRUE; ! 2016: ! 2017: } ! 2018: ! 2019: #endif ! 2020: ! 2021: // ! 2022: // We actually did get the initialization. ! 2023: // ! 2024: ! 2025: NdisReleaseSpinLock(&Adapter->Lock); ! 2026: ! 2027: // ! 2028: // We can start the chip. We may not ! 2029: // have any bindings to indicateto but this ! 2030: // is unimportant. ! 2031: // ! 2032: ! 2033: LanceStartChip(Adapter); ! 2034: ! 2035: ! 2036: return NDIS_STATUS_SUCCESS; ! 2037: ! 2038: ! 2039: } else { ! 2040: ! 2041: NdisReleaseSpinLock(&Adapter->Lock); ! 2042: ! 2043: return NDIS_STATUS_FAILURE; ! 2044: ! 2045: } ! 2046: ! 2047: } ! 2048: ! 2049: STATIC ! 2050: VOID ! 2051: LanceStartChip( ! 2052: IN PLANCE_ADAPTER Adapter ! 2053: ) ! 2054: ! 2055: /*++ ! 2056: ! 2057: Routine Description: ! 2058: ! 2059: This routine is used to start an already initialized lance. ! 2060: ! 2061: Arguments: ! 2062: ! 2063: Adapter - The adapter for the LANCE to start. ! 2064: ! 2065: Return Value: ! 2066: ! 2067: None. ! 2068: ! 2069: --*/ ! 2070: ! 2071: { ! 2072: ! 2073: if (Adapter->ResetInProgress) { ! 2074: ! 2075: return; ! 2076: ! 2077: } ! 2078: ! 2079: // ! 2080: // Set the RAP to csr0. ! 2081: // ! 2082: ! 2083: LANCE_WRITE_RAP( ! 2084: Adapter, ! 2085: LANCE_SELECT_CSR0 ! 2086: ); ! 2087: ! 2088: // ! 2089: // Set the RDP to a start chip. ! 2090: // ! 2091: ! 2092: LANCE_WRITE_RDP( ! 2093: Adapter, ! 2094: LANCE_CSR0_START | LANCE_CSR0_INTERRUPT_ENABLE ! 2095: ); ! 2096: ! 2097: } ! 2098: ! 2099: STATIC ! 2100: BOOLEAN ! 2101: LanceInterruptSynch( ! 2102: IN PVOID Context ! 2103: ) ! 2104: ! 2105: /*++ ! 2106: ! 2107: Routine Description: ! 2108: ! 2109: This routine is used by the normal interrupt processing routine ! 2110: to synchronize with interrupts from the card. It will or ! 2111: the value of the stored csr 0 into the other passed address ! 2112: in the context and clear the stored csr 0 value. ! 2113: block and clear the stored csr0. ! 2114: ! 2115: Arguments: ! 2116: ! 2117: Context - This is really a pointer to a record type peculiar ! 2118: to this routine. The record contains a pointer to the adapter ! 2119: and a pointer to an address in which to place the contents ! 2120: of csr 0. ! 2121: ! 2122: Return Value: ! 2123: ! 2124: Always returns true. ! 2125: ! 2126: --*/ ! 2127: ! 2128: { ! 2129: ! 2130: PLANCE_SYNCH_CONTEXT C = Context; ! 2131: ! 2132: *(C->LocalRead) = *(C->LocalRead) | C->Adapter->CSR0Value; ! 2133: ! 2134: C->Adapter->CSR0Value = 0; ! 2135: ! 2136: return TRUE; ! 2137: ! 2138: } ! 2139: ! 2140: extern ! 2141: BOOLEAN ! 2142: LanceISR( ! 2143: IN PVOID Context ! 2144: ) ! 2145: ! 2146: /*++ ! 2147: ! 2148: Routine Description: ! 2149: ! 2150: Interrupt service routine for the lance. It's main job is ! 2151: to get the value of CSR0 and record the changes in the ! 2152: adapters own list of interrupt reasons. ! 2153: ! 2154: Arguments: ! 2155: ! 2156: Context - Really a pointer to the adapter. ! 2157: ! 2158: Return Value: ! 2159: ! 2160: Returns true if the INTR bit of CSR0 of the lance is enabled. ! 2161: ! 2162: --*/ ! 2163: ! 2164: { ! 2165: ! 2166: // ! 2167: // Will hold the value from the csr. ! 2168: // ! 2169: USHORT LocalCSR0Value; ! 2170: ! 2171: // ! 2172: // Holds the pointer to the adapter. ! 2173: // ! 2174: PLANCE_ADAPTER Adapter = Context; ! 2175: ! 2176: BOOLEAN StoppedInterrupts=FALSE; ! 2177: ! 2178: LOG(IN_ISR); ! 2179: ! 2180: if (Adapter->LanceCard & (LANCE_DE201 | LANCE_DE100 | LANCE_DE422)) { ! 2181: ! 2182: // ! 2183: // If not currently pended, pend interrupts... ! 2184: // ! 2185: ! 2186: if (!(Adapter->InterruptsStopped)){ ! 2187: ! 2188: // ! 2189: // Pend interrupts ! 2190: // ! 2191: ! 2192: StoppedInterrupts = TRUE; ! 2193: ! 2194: Adapter->InterruptsStopped = TRUE; ! 2195: ! 2196: LOG(PEND); ! 2197: ! 2198: LANCE_ISR_WRITE_NICSR(Adapter, ! 2199: LANCE_NICSR_IMASK | LANCE_NICSR_LED_ON | LANCE_NICSR_INT_ON); ! 2200: ! 2201: } ! 2202: ! 2203: } ! 2204: ! 2205: // ! 2206: // We don't need to select csr0, as the only way we could get ! 2207: // an interrupt is to have already selected 0. ! 2208: // ! 2209: ! 2210: LANCE_ISR_READ_RDP(Adapter, &LocalCSR0Value); ! 2211: ! 2212: if (LocalCSR0Value & LANCE_CSR0_INTERRUPT_FLAG) { ! 2213: ! 2214: // ! 2215: // It's our interrupt. Clear only those bits that we got ! 2216: // in this read of csr0. We do it this way incase any new ! 2217: // reasons for interrupts occur between the time that we ! 2218: // read csr0 and the time that we clear the bits. ! 2219: // ! 2220: ! 2221: LANCE_ISR_WRITE_RDP( ! 2222: Adapter, ! 2223: (USHORT)((LANCE_CSR0_CLEAR_INTERRUPT_BITS & LocalCSR0Value) | ! 2224: LANCE_CSR0_INTERRUPT_ENABLE) ! 2225: ); ! 2226: ! 2227: ! 2228: if (Adapter->FirstInitialization && ! 2229: (LocalCSR0Value & LANCE_CSR0_INITIALIZATION_DONE)) { ! 2230: ! 2231: Adapter->FirstInitialization = FALSE; ! 2232: ! 2233: if ((Adapter->LanceCard & (LANCE_DE201 | LANCE_DE100 | LANCE_DE422)) && ! 2234: StoppedInterrupts) { ! 2235: ! 2236: // ! 2237: // Allow interrupts ! 2238: // ! 2239: ! 2240: Adapter->InterruptsStopped = FALSE; ! 2241: ! 2242: LOG(UNPEND); ! 2243: ! 2244: LANCE_ISR_WRITE_NICSR(Adapter, LANCE_NICSR_INT_ON); ! 2245: ! 2246: } ! 2247: ! 2248: LOG(OUT_ISR); ! 2249: ! 2250: return FALSE; ! 2251: ! 2252: } else { ! 2253: ! 2254: // ! 2255: // Or the csr value into the adapter version of csr 0. ! 2256: // ! 2257: ! 2258: Adapter->CSR0Value |= LocalCSR0Value; ! 2259: ! 2260: LOG(OUT_ISR); ! 2261: ! 2262: return TRUE; ! 2263: ! 2264: } ! 2265: ! 2266: } else { ! 2267: ! 2268: if ((Adapter->LanceCard & (LANCE_DE201 | LANCE_DE100 | LANCE_DE422)) && ! 2269: StoppedInterrupts) { ! 2270: ! 2271: // ! 2272: // Allow interrupts ! 2273: // ! 2274: ! 2275: Adapter->InterruptsStopped = FALSE; ! 2276: ! 2277: LOG(UNPEND); ! 2278: ! 2279: LANCE_ISR_WRITE_NICSR(Adapter, LANCE_NICSR_INT_ON); ! 2280: ! 2281: } ! 2282: ! 2283: LOG(OUT_ISR); ! 2284: ! 2285: return FALSE; ! 2286: ! 2287: } ! 2288: ! 2289: } ! 2290: ! 2291: STATIC ! 2292: VOID ! 2293: LanceStandardInterruptDPC( ! 2294: IN PVOID SystemSpecific, ! 2295: IN PVOID Context, ! 2296: IN PVOID SystemArgument1, ! 2297: IN PVOID SystemArgument2 ! 2298: ) ! 2299: ! 2300: /*++ ! 2301: ! 2302: Routine Description: ! 2303: ! 2304: This DPC routine is queued by the interrupt service routine ! 2305: and other routines within the driver that notice that ! 2306: some deferred processing needs to be done. It's main ! 2307: job is to call the interrupt processing code. ! 2308: ! 2309: Arguments: ! 2310: ! 2311: SystemSpecific - not used. ! 2312: ! 2313: Context - Really a pointer to the adapter. ! 2314: ! 2315: ! 2316: SystemArgument1 - Flag if we should turn interrupts on when done ! 2317: processing. ! 2318: ! 2319: SystemArgument2 - Not used. ! 2320: ! 2321: Return Value: ! 2322: ! 2323: None. ! 2324: ! 2325: --*/ ! 2326: ! 2327: { ! 2328: // ! 2329: // Holds the pointer to the adapter. ! 2330: // ! 2331: PLANCE_ADAPTER Adapter = Context; ! 2332: ! 2333: USHORT InterruptsStopped; ! 2334: ! 2335: UNREFERENCED_PARAMETER(SystemSpecific); ! 2336: UNREFERENCED_PARAMETER(SystemArgument1); ! 2337: UNREFERENCED_PARAMETER(SystemArgument2); ! 2338: ! 2339: LOG(IN_DPC); ! 2340: ! 2341: NdisDprAcquireSpinLock(&Adapter->Lock); ! 2342: ! 2343: if (Adapter->ProcessInterruptRunning) { ! 2344: ! 2345: LOG(OUT_DPC); ! 2346: ! 2347: NdisDprReleaseSpinLock(&Adapter->Lock); ! 2348: ! 2349: return; ! 2350: ! 2351: } ! 2352: ! 2353: Adapter->ProcessInterruptRunning = TRUE; ! 2354: ! 2355: ProcessInterrupt(Adapter); ! 2356: ! 2357: InterruptsStopped = Adapter->InterruptsStopped; ! 2358: ! 2359: if ((Adapter->LanceCard & (LANCE_DE201 | LANCE_DE100 | LANCE_DE422)) && ! 2360: InterruptsStopped) { ! 2361: ! 2362: // ! 2363: // Allow interrupts ! 2364: // ! 2365: ! 2366: LOG(UNPEND); ! 2367: ! 2368: LOG(OUT_DPC); ! 2369: ! 2370: ! 2371: // ! 2372: // Safe to write here since the ISR will not fire with interrupts stopped. ! 2373: // ! 2374: ! 2375: Adapter->InterruptsStopped = FALSE; ! 2376: ! 2377: LANCE_WRITE_NICSR(Adapter, LANCE_NICSR_INT_ON); ! 2378: ! 2379: } else { ! 2380: ! 2381: LOG(OUT_DPC); ! 2382: ! 2383: } ! 2384: ! 2385: NdisDprReleaseSpinLock(&Adapter->Lock); ! 2386: ! 2387: } ! 2388: ! 2389: STATIC ! 2390: BOOLEAN ! 2391: AllocateAdapterMemory( ! 2392: IN PLANCE_ADAPTER Adapter ! 2393: ) ! 2394: ! 2395: /*++ ! 2396: ! 2397: Routine Description: ! 2398: ! 2399: This routine allocates memory for: ! 2400: ! 2401: - Transmit ring entries ! 2402: ! 2403: - Receive ring entries ! 2404: ! 2405: - Receive buffers ! 2406: ! 2407: - Adapter buffers for use if user transmit buffers don't meet hardware ! 2408: contraints ! 2409: ! 2410: - Structures to map transmit ring entries back to the packets. ! 2411: ! 2412: Arguments: ! 2413: ! 2414: Adapter - The adapter to allocate memory for. ! 2415: ! 2416: Return Value: ! 2417: ! 2418: Returns FALSE if some memory needed for the adapter could not ! 2419: be allocated. ! 2420: ! 2421: --*/ ! 2422: ! 2423: { ! 2424: ! 2425: // ! 2426: // Pointer to a transmit ring entry. Used while initializing ! 2427: // the ring. ! 2428: // ! 2429: PLANCE_TRANSMIT_ENTRY CurrentTransmitEntry; ! 2430: ! 2431: // ! 2432: // Pointer to a receive ring entry. Used while initializing ! 2433: // the ring. ! 2434: // ! 2435: PLANCE_RECEIVE_ENTRY CurrentReceiveEntry; ! 2436: ! 2437: // ! 2438: // Simple iteration variable. ! 2439: // ! 2440: UINT i; ! 2441: ! 2442: // ! 2443: // These variables exist to reduce the amount of checking below. ! 2444: // ! 2445: ! 2446: ULONG NumberOfSmallBuffers; ! 2447: ULONG NumberOfMediumBuffers; ! 2448: ULONG NumberOfLargeBuffers; ! 2449: ! 2450: ! 2451: NumberOfSmallBuffers = Adapter->NumberOfSmallBuffers; ! 2452: NumberOfMediumBuffers = Adapter->NumberOfMediumBuffers; ! 2453: NumberOfLargeBuffers = Adapter->NumberOfLargeBuffers; ! 2454: ! 2455: ! 2456: ! 2457: // ! 2458: // Allocate memory for the initialization block. Note that ! 2459: // this memory can not cross a page boundary. ! 2460: // ! 2461: ! 2462: LANCE_ALLOCATE_MEMORY_FOR_HARDWARE( ! 2463: Adapter, ! 2464: sizeof(LANCE_INITIALIZATION_BLOCK), ! 2465: &Adapter->InitBlock ! 2466: ); ! 2467: ! 2468: if (Adapter->InitBlock == NULL) { ! 2469: DeleteAdapterMemory(Adapter); ! 2470: return FALSE; ! 2471: } ! 2472: ! 2473: // ! 2474: // Allocate the transmit ring descriptors. ! 2475: // ! 2476: ! 2477: LANCE_ALLOCATE_MEMORY_FOR_HARDWARE( ! 2478: Adapter, ! 2479: sizeof(LANCE_TRANSMIT_ENTRY)*Adapter->NumberOfTransmitRings, ! 2480: &Adapter->TransmitRing ! 2481: ) ! 2482: ! 2483: if (Adapter->TransmitRing == NULL) { ! 2484: DeleteAdapterMemory(Adapter); ! 2485: return FALSE; ! 2486: } ! 2487: ! 2488: // ! 2489: // We have the transmit ring descriptors. Make sure each is ! 2490: // in a clean state. ! 2491: // ! 2492: ! 2493: for ( ! 2494: i = 0, CurrentTransmitEntry = Adapter->TransmitRing; ! 2495: i < Adapter->NumberOfTransmitRings; ! 2496: i++,CurrentTransmitEntry++ ! 2497: ) { ! 2498: ! 2499: LANCE_ZERO_MEMORY_FOR_HARDWARE( ! 2500: CurrentTransmitEntry, ! 2501: sizeof(LANCE_TRANSMIT_ENTRY) ! 2502: ); ! 2503: ! 2504: } ! 2505: ! 2506: ! 2507: // ! 2508: // Allocate all of the receive ring entries ! 2509: // ! 2510: ! 2511: LANCE_ALLOCATE_MEMORY_FOR_HARDWARE( ! 2512: Adapter, ! 2513: sizeof(LANCE_RECEIVE_ENTRY)*Adapter->NumberOfReceiveRings, ! 2514: &Adapter->ReceiveRing ! 2515: ) ! 2516: ! 2517: if (Adapter->ReceiveRing == NULL) { ! 2518: DeleteAdapterMemory(Adapter); ! 2519: return FALSE; ! 2520: } ! 2521: ! 2522: // ! 2523: // We have the receive ring descriptors. Allocate an ! 2524: // array to hold the virtual addresses of each receive ! 2525: // buffer. ! 2526: // ! 2527: ! 2528: LANCE_ALLOC_PHYS( ! 2529: &(Adapter->ReceiveVAs), ! 2530: sizeof(PVOID) * Adapter->NumberOfReceiveRings ! 2531: ); ! 2532: ! 2533: if (Adapter->ReceiveVAs == NULL) { ! 2534: DeleteAdapterMemory(Adapter); ! 2535: return FALSE; ! 2536: } ! 2537: ! 2538: // ! 2539: // Clean the above memory ! 2540: // ! 2541: ! 2542: LANCE_ZERO_MEMORY( ! 2543: Adapter->ReceiveVAs, ! 2544: (sizeof(PVOID)*Adapter->NumberOfReceiveRings) ! 2545: ); ! 2546: ! 2547: ! 2548: // ! 2549: // We have the receive ring descriptors. Allocate a buffer ! 2550: // for each descriptor and make sure descriptor is in a clean state. ! 2551: // ! 2552: // While we're at it, relinquish ownership of the ring discriptors to ! 2553: // the lance. ! 2554: // ! 2555: ! 2556: for ( ! 2557: i = 0, CurrentReceiveEntry = Adapter->ReceiveRing; ! 2558: i < Adapter->NumberOfReceiveRings; ! 2559: i++,CurrentReceiveEntry++ ! 2560: ) { ! 2561: ! 2562: LANCE_ALLOCATE_MEMORY_FOR_HARDWARE( ! 2563: Adapter, ! 2564: Adapter->SizeOfReceiveBuffer, ! 2565: &Adapter->ReceiveVAs[i] ! 2566: ); ! 2567: ! 2568: if (Adapter->ReceiveVAs[i] == NULL) { ! 2569: DeleteAdapterMemory(Adapter); ! 2570: return FALSE; ! 2571: } ! 2572: ! 2573: ! 2574: LANCE_SET_RECEIVE_BUFFER_ADDRESS( ! 2575: Adapter, ! 2576: CurrentReceiveEntry, ! 2577: Adapter->ReceiveVAs[i] ! 2578: ); ! 2579: ! 2580: ! 2581: LANCE_SET_RECEIVE_BUFFER_LENGTH( ! 2582: CurrentReceiveEntry, ! 2583: Adapter->SizeOfReceiveBuffer ! 2584: ); ! 2585: ! 2586: LANCE_WRITE_HARDWARE_MEMORY_UCHAR( ! 2587: CurrentReceiveEntry->ReceiveSummaryBits, ! 2588: LANCE_RECEIVE_OWNED_BY_CHIP ! 2589: ); ! 2590: ! 2591: ! 2592: } ! 2593: ! 2594: // ! 2595: // Allocate the ring to packet structure. ! 2596: // ! 2597: ! 2598: LANCE_ALLOC_PHYS( ! 2599: &(Adapter->RingToPacket), ! 2600: sizeof(LANCE_RING_TO_PACKET) * Adapter->NumberOfTransmitRings ! 2601: ); ! 2602: ! 2603: if (Adapter->RingToPacket == NULL) { ! 2604: DeleteAdapterMemory(Adapter); ! 2605: return FALSE; ! 2606: } ! 2607: ! 2608: LANCE_ZERO_MEMORY( ! 2609: Adapter->RingToPacket, ! 2610: sizeof(LANCE_RING_TO_PACKET) * Adapter->NumberOfTransmitRings ! 2611: ); ! 2612: ! 2613: // ! 2614: // Allocate the array of buffer descriptors. ! 2615: // ! 2616: ! 2617: LANCE_ALLOC_PHYS( ! 2618: &(Adapter->LanceBuffers), ! 2619: sizeof(LANCE_BUFFER_DESCRIPTOR) * ! 2620: (NumberOfSmallBuffers + ! 2621: NumberOfMediumBuffers + ! 2622: NumberOfLargeBuffers) ! 2623: ); ! 2624: ! 2625: if (Adapter->LanceBuffers == NULL) { ! 2626: DeleteAdapterMemory(Adapter); ! 2627: return FALSE; ! 2628: } ! 2629: ! 2630: // ! 2631: // Zero the memory of all the descriptors so that we can ! 2632: // know which buffers wern't allocated incase we can't allocate ! 2633: // them all. ! 2634: // ! 2635: LANCE_ZERO_MEMORY( ! 2636: Adapter->LanceBuffers, ! 2637: sizeof(LANCE_BUFFER_DESCRIPTOR)* ! 2638: (NumberOfSmallBuffers + ! 2639: NumberOfMediumBuffers + ! 2640: NumberOfLargeBuffers) ! 2641: ); ! 2642: ! 2643: // ! 2644: // Allocate each of the small lance buffers and fill in the ! 2645: // buffer descriptor. ! 2646: // ! 2647: ! 2648: Adapter->LanceBufferListHeads[0] = -1; ! 2649: Adapter->LanceBufferListHeads[1] = 0; ! 2650: ! 2651: for ( ! 2652: i = 0; ! 2653: i < NumberOfSmallBuffers; ! 2654: i++ ! 2655: ) { ! 2656: ! 2657: LANCE_ALLOCATE_MEMORY_FOR_HARDWARE( ! 2658: Adapter, ! 2659: LANCE_SMALL_BUFFER_SIZE, ! 2660: &Adapter->LanceBuffers[i].VirtualLanceBuffer ! 2661: ); ! 2662: ! 2663: if (Adapter->LanceBuffers[i].VirtualLanceBuffer == NULL) { ! 2664: DeleteAdapterMemory(Adapter); ! 2665: return FALSE; ! 2666: } ! 2667: ! 2668: Adapter->LanceBuffers[i].Next = i+1; ! 2669: Adapter->LanceBuffers[i].BufferSize = LANCE_SMALL_BUFFER_SIZE; ! 2670: ! 2671: } ! 2672: ! 2673: // ! 2674: // Make sure that the last buffer correctly terminates the free list. ! 2675: // ! 2676: ! 2677: Adapter->LanceBuffers[i-1].Next = -1; ! 2678: ! 2679: // ! 2680: // Do the medium buffers now. ! 2681: // ! 2682: ! 2683: Adapter->LanceBufferListHeads[2] = i; ! 2684: ! 2685: for ( ! 2686: ; ! 2687: i < NumberOfSmallBuffers + NumberOfMediumBuffers; ! 2688: i++ ! 2689: ) { ! 2690: ! 2691: LANCE_ALLOCATE_MEMORY_FOR_HARDWARE( ! 2692: Adapter, ! 2693: LANCE_MEDIUM_BUFFER_SIZE, ! 2694: &Adapter->LanceBuffers[i].VirtualLanceBuffer ! 2695: ); ! 2696: ! 2697: if (Adapter->LanceBuffers[i].VirtualLanceBuffer == NULL) { ! 2698: DeleteAdapterMemory(Adapter); ! 2699: return FALSE; ! 2700: } ! 2701: ! 2702: ! 2703: Adapter->LanceBuffers[i].Next = i+1; ! 2704: Adapter->LanceBuffers[i].BufferSize = LANCE_MEDIUM_BUFFER_SIZE; ! 2705: ! 2706: } ! 2707: ! 2708: // ! 2709: // Make sure that the last buffer correctly terminates the free list. ! 2710: // ! 2711: ! 2712: Adapter->LanceBuffers[i-1].Next = -1; ! 2713: ! 2714: ! 2715: Adapter->LanceBufferListHeads[3] = i; ! 2716: ! 2717: for ( ! 2718: ; ! 2719: i < NumberOfSmallBuffers + NumberOfMediumBuffers + NumberOfLargeBuffers; ! 2720: i++ ! 2721: ) { ! 2722: ! 2723: ! 2724: LANCE_ALLOCATE_MEMORY_FOR_HARDWARE( ! 2725: Adapter, ! 2726: LANCE_LARGE_BUFFER_SIZE, ! 2727: &Adapter->LanceBuffers[i].VirtualLanceBuffer ! 2728: ); ! 2729: ! 2730: if (Adapter->LanceBuffers[i].VirtualLanceBuffer == NULL) { ! 2731: DeleteAdapterMemory(Adapter); ! 2732: return FALSE; ! 2733: } ! 2734: ! 2735: ! 2736: Adapter->LanceBuffers[i].Next = i+1; ! 2737: Adapter->LanceBuffers[i].BufferSize = LANCE_LARGE_BUFFER_SIZE; ! 2738: ! 2739: } ! 2740: ! 2741: // ! 2742: // Make sure that the last buffer correctly terminates the free list. ! 2743: // ! 2744: ! 2745: Adapter->LanceBuffers[i-1].Next = -1; ! 2746: ! 2747: return TRUE; ! 2748: ! 2749: } ! 2750: ! 2751: STATIC ! 2752: VOID ! 2753: DeleteAdapterMemory( ! 2754: IN PLANCE_ADAPTER Adapter ! 2755: ) ! 2756: ! 2757: /*++ ! 2758: ! 2759: Routine Description: ! 2760: ! 2761: This routine deallocates memory for: ! 2762: ! 2763: - Transmit ring entries ! 2764: ! 2765: - Receive ring entries ! 2766: ! 2767: - Receive buffers ! 2768: ! 2769: - Adapter buffers for use if user transmit buffers don't meet hardware ! 2770: contraints ! 2771: ! 2772: - Structures to map transmit ring entries back to the packets. ! 2773: ! 2774: Arguments: ! 2775: ! 2776: Adapter - The adapter to deallocate memory for. ! 2777: ! 2778: Return Value: ! 2779: ! 2780: None. ! 2781: ! 2782: --*/ ! 2783: ! 2784: { ! 2785: ! 2786: // ! 2787: // These variables exist to reduce the amount of checking below. ! 2788: // ! 2789: ! 2790: ULONG NumberOfSmallBuffers; ! 2791: ULONG NumberOfMediumBuffers; ! 2792: ULONG NumberOfLargeBuffers; ! 2793: ! 2794: NumberOfSmallBuffers = Adapter->NumberOfSmallBuffers; ! 2795: NumberOfMediumBuffers = Adapter->NumberOfMediumBuffers; ! 2796: NumberOfLargeBuffers = Adapter->NumberOfLargeBuffers; ! 2797: ! 2798: ! 2799: if (Adapter->InitBlock) { ! 2800: ! 2801: LANCE_DEALLOCATE_MEMORY_FOR_HARDWARE( ! 2802: Adapter, ! 2803: Adapter->InitBlock ! 2804: ); ! 2805: ! 2806: } ! 2807: ! 2808: if (Adapter->TransmitRing) { ! 2809: ! 2810: LANCE_DEALLOCATE_MEMORY_FOR_HARDWARE( ! 2811: Adapter, ! 2812: Adapter->TransmitRing ! 2813: ); ! 2814: ! 2815: } ! 2816: ! 2817: if (Adapter->ReceiveRing) { ! 2818: ! 2819: LANCE_DEALLOCATE_MEMORY_FOR_HARDWARE( ! 2820: Adapter, ! 2821: Adapter->ReceiveRing ! 2822: ); ! 2823: ! 2824: } ! 2825: ! 2826: if (Adapter->ReceiveVAs) { ! 2827: ! 2828: UINT i; ! 2829: ! 2830: for ( ! 2831: i = 0; ! 2832: i < Adapter->NumberOfReceiveRings; ! 2833: i++ ! 2834: ) { ! 2835: ! 2836: if (Adapter->ReceiveVAs[i]) { ! 2837: ! 2838: LANCE_DEALLOCATE_MEMORY_FOR_HARDWARE( ! 2839: Adapter, ! 2840: Adapter->ReceiveVAs[i] ! 2841: ); ! 2842: ! 2843: } else { ! 2844: ! 2845: break; ! 2846: ! 2847: } ! 2848: ! 2849: } ! 2850: ! 2851: LANCE_FREE_PHYS( ! 2852: Adapter->ReceiveVAs, ! 2853: sizeof(PVOID) * Adapter->NumberOfReceiveRings ! 2854: ); ! 2855: ! 2856: } ! 2857: ! 2858: if (Adapter->RingToPacket) { ! 2859: ! 2860: LANCE_FREE_PHYS( ! 2861: Adapter->RingToPacket, ! 2862: sizeof(LANCE_RING_TO_PACKET) * Adapter->NumberOfTransmitRings ! 2863: ); ! 2864: ! 2865: } ! 2866: ! 2867: if (Adapter->LanceBuffers) { ! 2868: ! 2869: UINT i; ! 2870: ! 2871: for ( ! 2872: i = 0; ! 2873: i < NumberOfSmallBuffers + NumberOfMediumBuffers + NumberOfLargeBuffers; ! 2874: i++) { ! 2875: ! 2876: if (Adapter->LanceBuffers[i].VirtualLanceBuffer) { ! 2877: ! 2878: LANCE_DEALLOCATE_MEMORY_FOR_HARDWARE( ! 2879: Adapter, ! 2880: Adapter->LanceBuffers[i].VirtualLanceBuffer ! 2881: ); ! 2882: ! 2883: } else { ! 2884: ! 2885: break; ! 2886: ! 2887: } ! 2888: ! 2889: } ! 2890: ! 2891: LANCE_FREE_PHYS( ! 2892: Adapter->LanceBuffers, ! 2893: sizeof(LANCE_BUFFER_DESCRIPTOR) * ! 2894: (NumberOfSmallBuffers + ! 2895: NumberOfMediumBuffers + ! 2896: NumberOfLargeBuffers) ! 2897: ); ! 2898: ! 2899: } ! 2900: ! 2901: } ! 2902: ! 2903: STATIC ! 2904: NDIS_STATUS ! 2905: LanceOpenAdapter( ! 2906: OUT PNDIS_STATUS OpenErrorStatus, ! 2907: OUT NDIS_HANDLE *MacBindingHandle, ! 2908: OUT PUINT SelectedMediumIndex, ! 2909: IN PNDIS_MEDIUM MediumArray, ! 2910: IN UINT MediumArraySize, ! 2911: IN NDIS_HANDLE NdisBindingContext, ! 2912: IN NDIS_HANDLE MacAdapterContext, ! 2913: IN UINT OpenOptions, ! 2914: IN PSTRING AddressingInformation OPTIONAL ! 2915: ) ! 2916: ! 2917: /*++ ! 2918: ! 2919: Routine Description: ! 2920: ! 2921: This routine is used to create an open instance of an adapter, in effect ! 2922: creating a binding between an upper-level module and the MAC module over ! 2923: the adapter. ! 2924: ! 2925: Arguments: ! 2926: ! 2927: MacBindingHandle - A pointer to a location in which the MAC stores ! 2928: a context value that it uses to represent this binding. ! 2929: ! 2930: SelectedMediumIndex - Index of MediumArray which this adapter supports. ! 2931: ! 2932: MediumArray - Array of Medium types which the protocol is requesting. ! 2933: ! 2934: MediumArraySize - Number of entries in MediumArray. ! 2935: ! 2936: NdisBindingContext - A value to be recorded by the MAC and passed as ! 2937: context whenever an indication is delivered by the MAC for this binding. ! 2938: ! 2939: MacAdapterContext - The value associated with the adapter that is being ! 2940: opened when the MAC registered the adapter with NdisRegisterAdapter. ! 2941: ! 2942: OpenOptions - A bit mask of flags. Not used. ! 2943: ! 2944: AddressingInformation - An optional pointer to a variable length string ! 2945: containing hardware-specific information that can be used to program the ! 2946: device. (This is not used by this MAC.) ! 2947: ! 2948: Return Value: ! 2949: ! 2950: The function value is the status of the operation. If the MAC does not ! 2951: complete this request synchronously, the value would be ! 2952: NDIS_STATUS_PENDING. ! 2953: ! 2954: ! 2955: --*/ ! 2956: ! 2957: { ! 2958: ! 2959: // ! 2960: // The LANCE_ADAPTER that this open binding should belong too. ! 2961: // ! 2962: PLANCE_ADAPTER Adapter; ! 2963: ! 2964: // ! 2965: // Holds the status that should be returned to the caller. ! 2966: // ! 2967: NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS; ! 2968: ! 2969: PLANCE_OPEN NewOpen; ! 2970: ! 2971: ! 2972: UNREFERENCED_PARAMETER(OpenOptions); ! 2973: UNREFERENCED_PARAMETER(OpenErrorStatus); ! 2974: UNREFERENCED_PARAMETER(AddressingInformation); ! 2975: ! 2976: ! 2977: // ! 2978: // Search for correct medium. ! 2979: // ! 2980: ! 2981: for (; MediumArraySize > 0; MediumArraySize--){ ! 2982: ! 2983: if (MediumArray[MediumArraySize - 1] == NdisMedium802_3){ ! 2984: ! 2985: MediumArraySize--; ! 2986: ! 2987: break; ! 2988: ! 2989: } ! 2990: ! 2991: } ! 2992: ! 2993: if (MediumArray[MediumArraySize] != NdisMedium802_3){ ! 2994: ! 2995: return(NDIS_STATUS_UNSUPPORTED_MEDIA); ! 2996: ! 2997: } ! 2998: ! 2999: *SelectedMediumIndex = MediumArraySize; ! 3000: ! 3001: ! 3002: Adapter = PLANCE_ADAPTER_FROM_CONTEXT_HANDLE(MacAdapterContext); ! 3003: ! 3004: NdisInterlockedAddUlong(&Adapter->References, 1, &Adapter->Lock); ! 3005: ! 3006: // ! 3007: // Allocate the space for the open binding. Fill in the fields. ! 3008: // ! 3009: ! 3010: LANCE_ALLOC_PHYS(&NewOpen,sizeof(LANCE_OPEN)); ! 3011: ! 3012: if (NewOpen != NULL){ ! 3013: ! 3014: *MacBindingHandle = BINDING_HANDLE_FROM_PLANCE_OPEN(NewOpen); ! 3015: ! 3016: InitializeListHead(&NewOpen->OpenList); ! 3017: ! 3018: NewOpen->NdisBindingContext = NdisBindingContext; ! 3019: NewOpen->References = 0; ! 3020: NewOpen->BindingShuttingDown = FALSE; ! 3021: NewOpen->OwningLance = Adapter; ! 3022: ! 3023: NewOpen->LookAhead = LANCE_MAX_LOOKAHEAD; ! 3024: ! 3025: NdisAcquireSpinLock(&Adapter->Lock); ! 3026: ! 3027: Adapter->MaxLookAhead = LANCE_MAX_LOOKAHEAD; ! 3028: ! 3029: if (!EthNoteFilterOpenAdapter( ! 3030: NewOpen->OwningLance->FilterDB, ! 3031: NewOpen, ! 3032: NdisBindingContext, ! 3033: &NewOpen->NdisFilterHandle ! 3034: )) { ! 3035: ! 3036: NdisReleaseSpinLock(&Adapter->Lock); ! 3037: ! 3038: LANCE_FREE_PHYS(NewOpen, sizeof(LANCE_OPEN)); ! 3039: ! 3040: StatusToReturn = NDIS_STATUS_FAILURE; ! 3041: ! 3042: NdisAcquireSpinLock(&Adapter->Lock); ! 3043: ! 3044: } else { ! 3045: ! 3046: // ! 3047: // Everything has been filled in. Synchronize access to the ! 3048: // adapter block and link the new open adapter in and increment ! 3049: // the opens reference count to account for the fact that the ! 3050: // filter routines have a "reference" to the open. ! 3051: // ! 3052: ! 3053: InsertTailList(&Adapter->OpenBindings,&NewOpen->OpenList); ! 3054: NewOpen->References++; ! 3055: ! 3056: } ! 3057: ! 3058: } else { ! 3059: ! 3060: NdisWriteErrorLogEntry( ! 3061: Adapter->NdisAdapterHandle, ! 3062: NDIS_ERROR_CODE_OUT_OF_RESOURCES, ! 3063: 1, ! 3064: (ULONG)openAdapter ! 3065: ); ! 3066: ! 3067: ! 3068: StatusToReturn = NDIS_STATUS_RESOURCES; ! 3069: ! 3070: NdisAcquireSpinLock(&Adapter->Lock); ! 3071: ! 3072: } ! 3073: ! 3074: LANCE_DO_DEFERRED(Adapter); ! 3075: ! 3076: return StatusToReturn; ! 3077: } ! 3078: ! 3079: VOID ! 3080: LanceAdjustMaxLookAhead( ! 3081: IN PLANCE_ADAPTER Adapter ! 3082: ) ! 3083: /*++ ! 3084: ! 3085: Routine Description: ! 3086: ! 3087: This routine finds the open with the maximum lookahead value and ! 3088: stores that in the adapter block. ! 3089: ! 3090: Arguments: ! 3091: ! 3092: Adapter - A pointer to the adapter block. ! 3093: ! 3094: Returns: ! 3095: ! 3096: None. ! 3097: ! 3098: --*/ ! 3099: { ! 3100: ULONG CurrentMax = 0; ! 3101: PLIST_ENTRY Link = &(Adapter->OpenBindings); ! 3102: ! 3103: while (Link->Flink != &(Adapter->OpenBindings)) { ! 3104: ! 3105: if (((PLANCE_OPEN)(Link->Flink))->LookAhead > CurrentMax) { ! 3106: ! 3107: CurrentMax = ((PLANCE_OPEN)(Link->Flink))->LookAhead; ! 3108: ! 3109: } ! 3110: ! 3111: Link = Link->Flink; ! 3112: ! 3113: } ! 3114: ! 3115: if (CurrentMax == 0) { ! 3116: ! 3117: CurrentMax = LANCE_MAX_LOOKAHEAD; ! 3118: ! 3119: } ! 3120: ! 3121: Adapter->MaxLookAhead = CurrentMax; ! 3122: ! 3123: } ! 3124: ! 3125: ! 3126: STATIC ! 3127: NDIS_STATUS ! 3128: LanceCloseAdapter( ! 3129: IN NDIS_HANDLE MacBindingHandle ! 3130: ) ! 3131: ! 3132: /*++ ! 3133: ! 3134: Routine Description: ! 3135: ! 3136: This routine causes the MAC to close an open handle (binding). ! 3137: ! 3138: Arguments: ! 3139: ! 3140: MacBindingHandle - The context value returned by the MAC when the ! 3141: adapter was opened. In reality it is a PLANCE_OPEN. ! 3142: ! 3143: Return Value: ! 3144: ! 3145: The function value is the status of the operation. ! 3146: ! 3147: ! 3148: --*/ ! 3149: ! 3150: { ! 3151: ! 3152: PLANCE_ADAPTER Adapter; ! 3153: ! 3154: NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS; ! 3155: ! 3156: PLANCE_OPEN Open; ! 3157: ! 3158: Adapter = PLANCE_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle); ! 3159: ! 3160: // ! 3161: // Hold the lock while we update the reference counts for the ! 3162: // adapter and the open. ! 3163: // ! 3164: ! 3165: Open = PLANCE_OPEN_FROM_BINDING_HANDLE(MacBindingHandle); ! 3166: ! 3167: NdisAcquireSpinLock(&Adapter->Lock); ! 3168: ! 3169: Adapter->References++; ! 3170: ! 3171: if (!Open->BindingShuttingDown) { ! 3172: ! 3173: Open->References++; ! 3174: ! 3175: StatusToReturn = EthDeleteFilterOpenAdapter( ! 3176: Adapter->FilterDB, ! 3177: Open->NdisFilterHandle, ! 3178: NULL ! 3179: ); ! 3180: ! 3181: // ! 3182: // If the status is successful that merely implies that ! 3183: // we were able to delete the reference to the open binding ! 3184: // from the filtering code. If we have a successful status ! 3185: // at this point we still need to check whether the reference ! 3186: // count to determine whether we can close. ! 3187: // ! 3188: // ! 3189: // The delete filter routine can return a "special" status ! 3190: // that indicates that there is a current NdisIndicateReceive ! 3191: // on this binding. See below. ! 3192: // ! 3193: ! 3194: if (StatusToReturn == NDIS_STATUS_SUCCESS) { ! 3195: ! 3196: // ! 3197: // Check whether the reference count is two. If ! 3198: // it is then we can get rid of the memory for ! 3199: // this open. ! 3200: // ! 3201: // A count of two indicates one for this routine ! 3202: // and one for the filter which we *know* we can ! 3203: // get rid of. ! 3204: // ! 3205: ! 3206: if (Open->References == 2) { ! 3207: ! 3208: // ! 3209: // We are the only reference to the open. Remove ! 3210: // it from the open list and delete the memory. ! 3211: // ! 3212: ! 3213: RemoveEntryList(&Open->OpenList); ! 3214: ! 3215: if (Adapter->MaxLookAhead == Open->LookAhead) { ! 3216: ! 3217: LanceAdjustMaxLookAhead(Adapter); ! 3218: ! 3219: } ! 3220: ! 3221: LANCE_FREE_PHYS(Open, sizeof(LANCE_OPEN)); ! 3222: ! 3223: } else { ! 3224: ! 3225: Open->BindingShuttingDown = TRUE; ! 3226: ! 3227: // ! 3228: // Remove the open from the open list and put it on ! 3229: // the closing list. ! 3230: // ! 3231: ! 3232: RemoveEntryList(&Open->OpenList); ! 3233: InsertTailList(&Adapter->CloseList,&Open->OpenList); ! 3234: ! 3235: // ! 3236: // Account for this routines reference to the open ! 3237: // as well as reference because of the filtering. ! 3238: // ! 3239: ! 3240: Open->References -= 2; ! 3241: ! 3242: // ! 3243: // Change the status to indicate that we will ! 3244: // be closing this later. ! 3245: // ! 3246: ! 3247: StatusToReturn = NDIS_STATUS_PENDING; ! 3248: ! 3249: } ! 3250: ! 3251: } else if (StatusToReturn == NDIS_STATUS_PENDING) { ! 3252: ! 3253: Open->BindingShuttingDown = TRUE; ! 3254: ! 3255: // ! 3256: // Remove the open from the open list and put it on ! 3257: // the closing list. ! 3258: // ! 3259: ! 3260: RemoveEntryList(&Open->OpenList); ! 3261: InsertTailList(&Adapter->CloseList,&Open->OpenList); ! 3262: ! 3263: // ! 3264: // Account for this routines reference to the open ! 3265: // as well as original open reference. ! 3266: // ! 3267: ! 3268: Open->References -= 2; ! 3269: ! 3270: } else if (StatusToReturn == NDIS_STATUS_CLOSING_INDICATING) { ! 3271: ! 3272: // ! 3273: // When we have this status it indicates that the filtering ! 3274: // code was currently doing an NdisIndicateReceive. It ! 3275: // would not be wise to delete the memory for the open at ! 3276: // this point. The filtering code will call our close action ! 3277: // routine upon return from NdisIndicateReceive and that ! 3278: // action routine will decrement the reference count for ! 3279: // the open. ! 3280: // ! 3281: ! 3282: Open->BindingShuttingDown = TRUE; ! 3283: ! 3284: // ! 3285: // This status is private to the filtering routine. Just ! 3286: // tell the caller the the close is pending. ! 3287: // ! 3288: ! 3289: StatusToReturn = NDIS_STATUS_PENDING; ! 3290: ! 3291: // ! 3292: // Remove the open from the open list and put it on ! 3293: // the closing list. ! 3294: // ! 3295: ! 3296: RemoveEntryList(&Open->OpenList); ! 3297: InsertTailList(&Adapter->CloseList,&Open->OpenList); ! 3298: ! 3299: // ! 3300: // Account for this routines reference to the open. CloseAction ! 3301: // will remove the second reference. ! 3302: // ! 3303: ! 3304: Open->References--; ! 3305: ! 3306: } else { ! 3307: ! 3308: // ! 3309: // Account for this routines reference to the open. ! 3310: // ! 3311: ! 3312: Open->References--; ! 3313: ! 3314: } ! 3315: ! 3316: } else { ! 3317: ! 3318: StatusToReturn = NDIS_STATUS_CLOSING; ! 3319: ! 3320: } ! 3321: ! 3322: ! 3323: LANCE_DO_DEFERRED(Adapter); ! 3324: ! 3325: return StatusToReturn; ! 3326: ! 3327: } ! 3328: ! 3329: NDIS_STATUS ! 3330: LanceRequest( ! 3331: IN NDIS_HANDLE MacBindingHandle, ! 3332: IN PNDIS_REQUEST NdisRequest ! 3333: ) ! 3334: ! 3335: /*++ ! 3336: ! 3337: Routine Description: ! 3338: ! 3339: This routine allows a protocol to query and set information ! 3340: about the MAC. ! 3341: ! 3342: Arguments: ! 3343: ! 3344: MacBindingHandle - The context value returned by the MAC when the ! 3345: adapter was opened. In reality, it is a pointer to PLANCE_OPEN. ! 3346: ! 3347: NdisRequest - A structure which contains the request type (Set or ! 3348: Query), an array of operations to perform, and an array for holding ! 3349: the results of the operations. ! 3350: ! 3351: Return Value: ! 3352: ! 3353: The function value is the status of the operation. ! 3354: ! 3355: --*/ ! 3356: ! 3357: { ! 3358: NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS; ! 3359: ! 3360: PLANCE_OPEN Open = (PLANCE_OPEN)(MacBindingHandle); ! 3361: PLANCE_ADAPTER Adapter = (Open->OwningLance); ! 3362: ! 3363: if (Adapter->HardwareFailure) { ! 3364: ! 3365: return(NDIS_STATUS_FAILURE); ! 3366: ! 3367: } ! 3368: ! 3369: ! 3370: // ! 3371: // Ensure that the open does not close while in this function. ! 3372: // ! 3373: ! 3374: NdisAcquireSpinLock(&Adapter->Lock); ! 3375: ! 3376: Adapter->References++; ! 3377: ! 3378: #if LANCE_TRACE ! 3379: DbgPrint("In LanceRequest\n"); ! 3380: #endif ! 3381: ! 3382: // ! 3383: // Process request ! 3384: // ! 3385: ! 3386: if (NdisRequest->RequestType == NdisRequestQueryInformation) { ! 3387: ! 3388: StatusToReturn = LanceQueryInformation(Adapter, Open, NdisRequest); ! 3389: ! 3390: } else { ! 3391: ! 3392: if (NdisRequest->RequestType == NdisRequestSetInformation) { ! 3393: ! 3394: StatusToReturn = LanceSetInformation(Adapter,Open,NdisRequest); ! 3395: ! 3396: } else { ! 3397: ! 3398: StatusToReturn = NDIS_STATUS_NOT_RECOGNIZED; ! 3399: ! 3400: } ! 3401: ! 3402: } ! 3403: ! 3404: LANCE_DO_DEFERRED(Adapter); ! 3405: ! 3406: #if LANCE_TRACE ! 3407: DbgPrint("Out LanceRequest %x\n",StatusToReturn); ! 3408: #endif ! 3409: ! 3410: return(StatusToReturn); ! 3411: ! 3412: } ! 3413: ! 3414: NDIS_STATUS ! 3415: LanceQueryProtocolInformation( ! 3416: IN PLANCE_ADAPTER Adapter, ! 3417: IN PLANCE_OPEN Open, ! 3418: IN NDIS_OID Oid, ! 3419: IN BOOLEAN GlobalMode, ! 3420: IN PVOID InfoBuffer, ! 3421: IN UINT BytesLeft, ! 3422: OUT PUINT BytesNeeded, ! 3423: OUT PUINT BytesWritten ! 3424: ) ! 3425: ! 3426: /*++ ! 3427: ! 3428: Routine Description: ! 3429: ! 3430: The LanceQueryProtocolInformation process a Query request for ! 3431: NDIS_OIDs that are specific to a binding about the MAC. Note that ! 3432: some of the OIDs that are specific to bindings are also queryable ! 3433: on a global basis. Rather than recreate this code to handle the ! 3434: global queries, I use a flag to indicate if this is a query for the ! 3435: global data or the binding specific data. ! 3436: ! 3437: Arguments: ! 3438: ! 3439: Adapter - a pointer to the adapter. ! 3440: ! 3441: Open - a pointer to the open instance. ! 3442: ! 3443: Oid - the NDIS_OID to process. ! 3444: ! 3445: GlobalMode - Some of the binding specific information is also used ! 3446: when querying global statistics. This is a flag to specify whether ! 3447: to return the global value, or the binding specific value. ! 3448: ! 3449: PlaceInInfoBuffer - a pointer into the NdisRequest->InformationBuffer ! 3450: into which store the result of the query. ! 3451: ! 3452: BytesLeft - the number of bytes left in the InformationBuffer. ! 3453: ! 3454: BytesNeeded - If there is not enough room in the information buffer ! 3455: then this will contain the number of bytes needed to complete the ! 3456: request. ! 3457: ! 3458: BytesWritten - a pointer to the number of bytes written into the ! 3459: InformationBuffer. ! 3460: ! 3461: Return Value: ! 3462: ! 3463: The function value is the status of the operation. ! 3464: ! 3465: --*/ ! 3466: ! 3467: { ! 3468: NDIS_MEDIUM Medium = NdisMedium802_3; ! 3469: ULONG GenericULong; ! 3470: USHORT GenericUShort; ! 3471: UCHAR GenericArray[6]; ! 3472: ! 3473: NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS; ! 3474: ! 3475: // ! 3476: // Common variables for pointing to result of query ! 3477: // ! 3478: ! 3479: PVOID MoveSource; ! 3480: ULONG MoveBytes; ! 3481: ! 3482: NDIS_HARDWARE_STATUS HardwareStatus = NdisHardwareStatusReady; ! 3483: ! 3484: // ! 3485: // General Algorithm: ! 3486: // ! 3487: // Switch(Request) ! 3488: // Get requested information ! 3489: // Store results in a common variable. ! 3490: // Copy result in common variable to result buffer. ! 3491: // ! 3492: ! 3493: // ! 3494: // Make sure that ulong is 4 bytes. Else GenericULong must change ! 3495: // to something of size 4. ! 3496: // ! 3497: ASSERT(sizeof(ULONG) == 4); ! 3498: ! 3499: ! 3500: #if LANCE_TRACE ! 3501: DbgPrint("In LanceQueryProtocolInfo\n"); ! 3502: #endif ! 3503: ! 3504: // ! 3505: // Set default values ! 3506: // ! 3507: ! 3508: MoveSource = (PVOID)(&GenericULong); ! 3509: MoveBytes = sizeof(GenericULong); ! 3510: ! 3511: // ! 3512: // Switch on request type ! 3513: // ! 3514: ! 3515: switch (Oid) { ! 3516: ! 3517: case OID_GEN_MAC_OPTIONS: ! 3518: ! 3519: GenericULong = (ULONG)(NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | ! 3520: NDIS_MAC_OPTION_RECEIVE_SERIALIZED ! 3521: ); ! 3522: ! 3523: break; ! 3524: ! 3525: case OID_GEN_SUPPORTED_LIST: ! 3526: ! 3527: if (!GlobalMode){ ! 3528: ! 3529: MoveSource = (PVOID)(LanceProtocolSupportedOids); ! 3530: MoveBytes = sizeof(LanceProtocolSupportedOids); ! 3531: ! 3532: } else { ! 3533: ! 3534: MoveSource = (PVOID)(LanceGlobalSupportedOids); ! 3535: MoveBytes = sizeof(LanceGlobalSupportedOids); ! 3536: ! 3537: } ! 3538: break; ! 3539: ! 3540: case OID_GEN_HARDWARE_STATUS: ! 3541: ! 3542: ! 3543: if (Adapter->ResetInProgress){ ! 3544: ! 3545: HardwareStatus = NdisHardwareStatusReset; ! 3546: ! 3547: } else { ! 3548: ! 3549: HardwareStatus = NdisHardwareStatusReady; ! 3550: ! 3551: } ! 3552: ! 3553: ! 3554: MoveSource = (PVOID)(&HardwareStatus); ! 3555: MoveBytes = sizeof(NDIS_HARDWARE_STATUS); ! 3556: ! 3557: break; ! 3558: ! 3559: case OID_GEN_MEDIA_SUPPORTED: ! 3560: case OID_GEN_MEDIA_IN_USE: ! 3561: ! 3562: MoveSource = (PVOID) (&Medium); ! 3563: MoveBytes = sizeof(NDIS_MEDIUM); ! 3564: break; ! 3565: ! 3566: case OID_GEN_MAXIMUM_LOOKAHEAD: ! 3567: ! 3568: GenericULong = LANCE_MAX_LOOKAHEAD; ! 3569: ! 3570: break; ! 3571: ! 3572: ! 3573: case OID_GEN_MAXIMUM_FRAME_SIZE: ! 3574: ! 3575: GenericULong = (ULONG)(LANCE_LARGE_BUFFER_SIZE - LANCE_HEADER_SIZE); ! 3576: ! 3577: break; ! 3578: ! 3579: ! 3580: case OID_GEN_MAXIMUM_TOTAL_SIZE: ! 3581: ! 3582: GenericULong = (ULONG)(LANCE_LARGE_BUFFER_SIZE); ! 3583: ! 3584: break; ! 3585: ! 3586: ! 3587: case OID_GEN_LINK_SPEED: ! 3588: ! 3589: GenericULong = (ULONG)(100000); ! 3590: ! 3591: break; ! 3592: ! 3593: ! 3594: case OID_GEN_TRANSMIT_BUFFER_SPACE: ! 3595: ! 3596: GenericULong = (ULONG)((LANCE_SMALL_BUFFER_SIZE * Adapter->NumberOfSmallBuffers) + ! 3597: (LANCE_MEDIUM_BUFFER_SIZE * Adapter->NumberOfMediumBuffers) + ! 3598: (LANCE_LARGE_BUFFER_SIZE * Adapter->NumberOfLargeBuffers)); ! 3599: ! 3600: ! 3601: break; ! 3602: ! 3603: case OID_GEN_RECEIVE_BUFFER_SPACE: ! 3604: ! 3605: GenericULong = (ULONG)(Adapter->NumberOfReceiveRings * ! 3606: Adapter->SizeOfReceiveBuffer); ! 3607: ! 3608: break; ! 3609: ! 3610: case OID_GEN_TRANSMIT_BLOCK_SIZE: ! 3611: ! 3612: GenericULong = (ULONG)(LANCE_SMALL_BUFFER_SIZE); ! 3613: ! 3614: break; ! 3615: ! 3616: case OID_GEN_RECEIVE_BLOCK_SIZE: ! 3617: ! 3618: GenericULong = (ULONG)(Adapter->SizeOfReceiveBuffer); ! 3619: ! 3620: break; ! 3621: ! 3622: case OID_GEN_VENDOR_ID: ! 3623: ! 3624: NdisMoveMemory( ! 3625: (PVOID)&GenericULong, ! 3626: Adapter->NetworkAddress, ! 3627: 3 ! 3628: ); ! 3629: ! 3630: GenericULong &= 0xFFFFFF00; ! 3631: ! 3632: if (Adapter->LanceCard == LANCE_DE201) { ! 3633: ! 3634: GenericULong |= 0x01; ! 3635: ! 3636: } else if (Adapter->LanceCard == LANCE_DE100) { ! 3637: ! 3638: GenericULong |= 0x02; ! 3639: ! 3640: } else if (Adapter->LanceCard == LANCE_DE422) { ! 3641: ! 3642: GenericULong |= 0x03; ! 3643: ! 3644: } else { ! 3645: ! 3646: GenericULong |= 0x04; ! 3647: ! 3648: } ! 3649: ! 3650: MoveSource = (PVOID)(&GenericULong); ! 3651: MoveBytes = sizeof(GenericULong); ! 3652: break; ! 3653: ! 3654: case OID_GEN_VENDOR_DESCRIPTION: ! 3655: ! 3656: if (Adapter->LanceCard == LANCE_DE201) { ! 3657: ! 3658: MoveSource = (PVOID)"DEC Etherworks Turbo Adapter"; ! 3659: MoveBytes = 29; ! 3660: ! 3661: } else if (Adapter->LanceCard == LANCE_DE100) { ! 3662: ! 3663: MoveSource = (PVOID)"DEC Etherworks Adapter"; ! 3664: MoveBytes = 23; ! 3665: ! 3666: } else if (Adapter->LanceCard == LANCE_DE422) { ! 3667: ! 3668: MoveSource = (PVOID)"DEC Etherworks Turbo EISA Adapter"; ! 3669: MoveBytes = 34; ! 3670: ! 3671: } else { ! 3672: ! 3673: MoveSource = (PVOID)"Lance Adapter"; ! 3674: MoveBytes = 15; ! 3675: ! 3676: } ! 3677: ! 3678: break; ! 3679: ! 3680: case OID_GEN_DRIVER_VERSION: ! 3681: ! 3682: GenericUShort = (USHORT)0x0301; ! 3683: ! 3684: MoveSource = (PVOID)(&GenericUShort); ! 3685: MoveBytes = sizeof(GenericUShort); ! 3686: break; ! 3687: ! 3688: ! 3689: case OID_GEN_CURRENT_PACKET_FILTER: ! 3690: ! 3691: if (GlobalMode ) { ! 3692: ! 3693: GenericULong = ETH_QUERY_FILTER_CLASSES( ! 3694: Adapter->FilterDB ! 3695: ); ! 3696: ! 3697: } else { ! 3698: ! 3699: GenericULong = ETH_QUERY_PACKET_FILTER( ! 3700: Adapter->FilterDB, ! 3701: Open->NdisFilterHandle ! 3702: ); ! 3703: ! 3704: } ! 3705: ! 3706: break; ! 3707: ! 3708: case OID_GEN_CURRENT_LOOKAHEAD: ! 3709: ! 3710: if ( GlobalMode ) { ! 3711: ! 3712: GenericULong = Adapter->MaxLookAhead; ! 3713: ! 3714: } else { ! 3715: ! 3716: GenericULong = Open->LookAhead; ! 3717: ! 3718: } ! 3719: ! 3720: break; ! 3721: ! 3722: case OID_802_3_PERMANENT_ADDRESS: ! 3723: ! 3724: LANCE_MOVE_MEMORY((PCHAR)GenericArray, ! 3725: Adapter->NetworkAddress, ! 3726: ETH_LENGTH_OF_ADDRESS ! 3727: ); ! 3728: ! 3729: MoveSource = (PVOID)(GenericArray); ! 3730: MoveBytes = sizeof(Adapter->NetworkAddress); ! 3731: break; ! 3732: ! 3733: case OID_802_3_CURRENT_ADDRESS: ! 3734: ! 3735: ! 3736: LANCE_MOVE_MEMORY((PCHAR)GenericArray, ! 3737: Adapter->CurrentNetworkAddress, ! 3738: ETH_LENGTH_OF_ADDRESS ! 3739: ); ! 3740: ! 3741: MoveSource = (PVOID)(GenericArray); ! 3742: MoveBytes = sizeof(Adapter->CurrentNetworkAddress); ! 3743: break; ! 3744: ! 3745: case OID_802_3_MULTICAST_LIST: ! 3746: ! 3747: ! 3748: { ! 3749: UINT NumAddresses; ! 3750: ! 3751: if (GlobalMode) { ! 3752: ! 3753: NumAddresses = ETH_NUMBER_OF_GLOBAL_FILTER_ADDRESSES(Adapter->FilterDB); ! 3754: ! 3755: if ((NumAddresses * ETH_LENGTH_OF_ADDRESS) > BytesLeft) { ! 3756: ! 3757: *BytesNeeded = (NumAddresses * ETH_LENGTH_OF_ADDRESS); ! 3758: ! 3759: StatusToReturn = NDIS_STATUS_INVALID_LENGTH; ! 3760: ! 3761: break; ! 3762: ! 3763: } ! 3764: ! 3765: EthQueryGlobalFilterAddresses( ! 3766: &StatusToReturn, ! 3767: Adapter->FilterDB, ! 3768: BytesLeft, ! 3769: &NumAddresses, ! 3770: InfoBuffer ! 3771: ); ! 3772: ! 3773: *BytesWritten = NumAddresses * ETH_LENGTH_OF_ADDRESS; ! 3774: ! 3775: // ! 3776: // Should not be an error since we held the spinlock ! 3777: // nothing should have changed. ! 3778: // ! 3779: ! 3780: ASSERT(StatusToReturn == NDIS_STATUS_SUCCESS); ! 3781: ! 3782: } else { ! 3783: ! 3784: NumAddresses = EthNumberOfOpenFilterAddresses( ! 3785: Adapter->FilterDB, ! 3786: Open->NdisFilterHandle ! 3787: ); ! 3788: ! 3789: if ((NumAddresses * ETH_LENGTH_OF_ADDRESS) > BytesLeft) { ! 3790: ! 3791: *BytesNeeded = (NumAddresses * ETH_LENGTH_OF_ADDRESS); ! 3792: ! 3793: StatusToReturn = NDIS_STATUS_INVALID_LENGTH; ! 3794: ! 3795: break; ! 3796: ! 3797: } ! 3798: ! 3799: EthQueryOpenFilterAddresses( ! 3800: &StatusToReturn, ! 3801: Adapter->FilterDB, ! 3802: Open->NdisFilterHandle, ! 3803: BytesLeft, ! 3804: &NumAddresses, ! 3805: InfoBuffer ! 3806: ); ! 3807: ! 3808: // ! 3809: // Should not be an error since we held the spinlock ! 3810: // nothing should have changed. ! 3811: // ! 3812: ! 3813: ASSERT(StatusToReturn == NDIS_STATUS_SUCCESS); ! 3814: ! 3815: *BytesWritten = NumAddresses * ETH_LENGTH_OF_ADDRESS; ! 3816: ! 3817: } ! 3818: ! 3819: } ! 3820: ! 3821: MoveSource = (PVOID)NULL; ! 3822: MoveBytes = 0; ! 3823: ! 3824: break; ! 3825: ! 3826: case OID_802_3_MAXIMUM_LIST_SIZE: ! 3827: ! 3828: GenericULong = Adapter->MaxMulticastList; ! 3829: ! 3830: break; ! 3831: ! 3832: ! 3833: ! 3834: default: ! 3835: ! 3836: StatusToReturn = NDIS_STATUS_NOT_SUPPORTED; ! 3837: break; ! 3838: } ! 3839: ! 3840: if (StatusToReturn == NDIS_STATUS_SUCCESS){ ! 3841: ! 3842: if (MoveBytes > BytesLeft){ ! 3843: ! 3844: // ! 3845: // Not enough room in InformationBuffer. Punt ! 3846: // ! 3847: ! 3848: *BytesNeeded = MoveBytes; ! 3849: ! 3850: StatusToReturn = NDIS_STATUS_INVALID_LENGTH; ! 3851: ! 3852: } else { ! 3853: ! 3854: // ! 3855: // Store result. ! 3856: // ! 3857: ! 3858: LANCE_MOVE_MEMORY(InfoBuffer, MoveSource, MoveBytes); ! 3859: ! 3860: (*BytesWritten) += MoveBytes; ! 3861: ! 3862: } ! 3863: } ! 3864: ! 3865: #if LANCE_TRACE ! 3866: DbgPrint("Out LanceQueryProtocolInfo\n"); ! 3867: #endif ! 3868: ! 3869: return(StatusToReturn); ! 3870: } ! 3871: ! 3872: NDIS_STATUS ! 3873: LanceQueryInformation( ! 3874: IN PLANCE_ADAPTER Adapter, ! 3875: IN PLANCE_OPEN Open, ! 3876: IN PNDIS_REQUEST NdisRequest ! 3877: ) ! 3878: /*++ ! 3879: ! 3880: Routine Description: ! 3881: ! 3882: The LanceQueryInformation is used by LanceRequest to query information ! 3883: about the MAC. ! 3884: ! 3885: Arguments: ! 3886: ! 3887: Adapter - A pointer to the adapter. ! 3888: ! 3889: Open - A pointer to a particular open instance. ! 3890: ! 3891: NdisRequest - A structure which contains the request type (Query), ! 3892: an array of operations to perform, and an array for holding ! 3893: the results of the operations. ! 3894: ! 3895: Return Value: ! 3896: ! 3897: The function value is the status of the operation. ! 3898: ! 3899: --*/ ! 3900: ! 3901: { ! 3902: ! 3903: UINT BytesWritten = 0; ! 3904: UINT BytesNeeded = 0; ! 3905: UINT BytesLeft = NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength; ! 3906: PUCHAR InfoBuffer = (PUCHAR)(NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer); ! 3907: ! 3908: NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS; ! 3909: ! 3910: ! 3911: #if LANCE_TRACE ! 3912: DbgPrint("In LanceQueryInfo\n"); ! 3913: #endif ! 3914: ! 3915: ! 3916: StatusToReturn = LanceQueryProtocolInformation( ! 3917: Adapter, ! 3918: Open, ! 3919: NdisRequest->DATA.QUERY_INFORMATION.Oid, ! 3920: FALSE, ! 3921: InfoBuffer, ! 3922: BytesLeft, ! 3923: &BytesNeeded, ! 3924: &BytesWritten ! 3925: ); ! 3926: ! 3927: ! 3928: NdisRequest->DATA.QUERY_INFORMATION.BytesWritten = BytesWritten; ! 3929: ! 3930: NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded = BytesNeeded; ! 3931: ! 3932: #if LANCE_TRACE ! 3933: DbgPrint("Out LanceQueryInfo\n"); ! 3934: #endif ! 3935: ! 3936: return(StatusToReturn); ! 3937: } ! 3938: ! 3939: NDIS_STATUS ! 3940: LanceSetInformation( ! 3941: IN PLANCE_ADAPTER Adapter, ! 3942: IN PLANCE_OPEN Open, ! 3943: IN PNDIS_REQUEST NdisRequest ! 3944: ) ! 3945: /*++ ! 3946: ! 3947: Routine Description: ! 3948: ! 3949: The LanceSetInformation is used by LanceRequest to set information ! 3950: about the MAC. ! 3951: ! 3952: Note: Assumes it is called with the lock held. ! 3953: ! 3954: Arguments: ! 3955: ! 3956: Adapter - A pointer to the adapter. ! 3957: ! 3958: Open - A pointer to an open instance. ! 3959: ! 3960: NdisRequest - A structure which contains the request type (Set), ! 3961: an array of operations to perform, and an array for holding ! 3962: the results of the operations. ! 3963: ! 3964: Return Value: ! 3965: ! 3966: The function value is the status of the operation. ! 3967: ! 3968: --*/ ! 3969: ! 3970: { ! 3971: ! 3972: // ! 3973: // General Algorithm: ! 3974: // ! 3975: // For each request ! 3976: // Verify length ! 3977: // Switch(Request) ! 3978: // Process Request ! 3979: // ! 3980: ! 3981: UINT BytesRead = 0; ! 3982: UINT BytesNeeded = 0; ! 3983: UINT BytesLeft = NdisRequest->DATA.SET_INFORMATION.InformationBufferLength; ! 3984: PUCHAR InfoBuffer = (PUCHAR)(NdisRequest->DATA.SET_INFORMATION.InformationBuffer); ! 3985: ! 3986: // ! 3987: // Variables for a particular request ! 3988: // ! 3989: ! 3990: NDIS_OID Oid; ! 3991: UINT OidLength; ! 3992: ! 3993: // ! 3994: // Variables for holding the new values to be used. ! 3995: // ! 3996: ! 3997: ULONG LookAhead; ! 3998: ULONG Filter; ! 3999: ! 4000: NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS; ! 4001: ! 4002: ! 4003: #if LANCE_TRACE ! 4004: DbgPrint("In LanceSetInfo\n"); ! 4005: #endif ! 4006: ! 4007: ! 4008: // ! 4009: // Get Oid and Length of next request ! 4010: // ! 4011: ! 4012: Oid = NdisRequest->DATA.SET_INFORMATION.Oid; ! 4013: ! 4014: OidLength = BytesLeft; ! 4015: ! 4016: switch (Oid) { ! 4017: ! 4018: ! 4019: case OID_802_3_MULTICAST_LIST: ! 4020: ! 4021: // ! 4022: // Verify length ! 4023: // ! 4024: ! 4025: if ((OidLength % ETH_LENGTH_OF_ADDRESS) != 0){ ! 4026: ! 4027: StatusToReturn = NDIS_STATUS_INVALID_LENGTH; ! 4028: ! 4029: NdisRequest->DATA.SET_INFORMATION.BytesRead = 0; ! 4030: NdisRequest->DATA.SET_INFORMATION.BytesNeeded = 0; ! 4031: ! 4032: return(StatusToReturn); ! 4033: ! 4034: } ! 4035: ! 4036: // ! 4037: // Call into filter package. ! 4038: // ! 4039: ! 4040: if (!Open->BindingShuttingDown) { ! 4041: ! 4042: // ! 4043: // Increment the open while it is going through the filtering ! 4044: // routines. ! 4045: // ! 4046: ! 4047: Open->References++; ! 4048: ! 4049: StatusToReturn = EthChangeFilterAddresses( ! 4050: Adapter->FilterDB, ! 4051: Open->NdisFilterHandle, ! 4052: NdisRequest, ! 4053: OidLength / ETH_LENGTH_OF_ADDRESS, ! 4054: (CHAR **)InfoBuffer, ! 4055: TRUE ! 4056: ); ! 4057: ! 4058: Open->References--; ! 4059: ! 4060: } else { ! 4061: ! 4062: StatusToReturn = NDIS_STATUS_CLOSING; ! 4063: ! 4064: } ! 4065: ! 4066: break; ! 4067: ! 4068: ! 4069: case OID_GEN_CURRENT_PACKET_FILTER: ! 4070: ! 4071: // ! 4072: // Verify length ! 4073: // ! 4074: ! 4075: if (OidLength != 4) { ! 4076: ! 4077: StatusToReturn = NDIS_STATUS_INVALID_LENGTH; ! 4078: ! 4079: NdisRequest->DATA.SET_INFORMATION.BytesRead = 0; ! 4080: NdisRequest->DATA.SET_INFORMATION.BytesNeeded = 0; ! 4081: ! 4082: break; ! 4083: ! 4084: } ! 4085: ! 4086: ! 4087: LANCE_MOVE_MEMORY(&Filter, InfoBuffer, 4); ! 4088: ! 4089: // ! 4090: // Verify bits ! 4091: // ! 4092: ! 4093: if (Filter & (NDIS_PACKET_TYPE_SOURCE_ROUTING | ! 4094: NDIS_PACKET_TYPE_SMT | ! 4095: NDIS_PACKET_TYPE_MAC_FRAME | ! 4096: NDIS_PACKET_TYPE_FUNCTIONAL | ! 4097: NDIS_PACKET_TYPE_ALL_FUNCTIONAL | ! 4098: NDIS_PACKET_TYPE_GROUP ! 4099: )) { ! 4100: ! 4101: StatusToReturn = NDIS_STATUS_NOT_SUPPORTED; ! 4102: ! 4103: NdisRequest->DATA.SET_INFORMATION.BytesRead = 4; ! 4104: NdisRequest->DATA.SET_INFORMATION.BytesNeeded = 0; ! 4105: ! 4106: break; ! 4107: ! 4108: } ! 4109: ! 4110: StatusToReturn = LanceSetPacketFilter(Adapter, ! 4111: Open, ! 4112: NdisRequest, ! 4113: Filter); ! 4114: ! 4115: break; ! 4116: ! 4117: case OID_GEN_CURRENT_LOOKAHEAD: ! 4118: ! 4119: // ! 4120: // Verify length ! 4121: // ! 4122: ! 4123: if (OidLength != 4) { ! 4124: ! 4125: StatusToReturn = NDIS_STATUS_INVALID_LENGTH; ! 4126: ! 4127: NdisRequest->DATA.SET_INFORMATION.BytesRead = 0; ! 4128: NdisRequest->DATA.SET_INFORMATION.BytesNeeded = 0; ! 4129: ! 4130: break; ! 4131: ! 4132: } ! 4133: ! 4134: LANCE_MOVE_MEMORY(&LookAhead, InfoBuffer, 4); ! 4135: ! 4136: if (LookAhead <= (LANCE_MAX_LOOKAHEAD)) { ! 4137: ! 4138: if (Open->LookAhead > Adapter->MaxLookAhead) { ! 4139: ! 4140: Open->LookAhead = LookAhead; ! 4141: ! 4142: Adapter->MaxLookAhead = LookAhead; ! 4143: ! 4144: } else { ! 4145: ! 4146: if ((Open->LookAhead == Adapter->MaxLookAhead) && ! 4147: (LookAhead < Adapter->MaxLookAhead)) { ! 4148: ! 4149: Open->LookAhead = LookAhead; ! 4150: ! 4151: LanceAdjustMaxLookAhead(Adapter); ! 4152: ! 4153: } else { ! 4154: ! 4155: Open->LookAhead = LookAhead; ! 4156: ! 4157: } ! 4158: ! 4159: } ! 4160: ! 4161: } else { ! 4162: ! 4163: StatusToReturn = NDIS_STATUS_INVALID_LENGTH; ! 4164: ! 4165: } ! 4166: ! 4167: break; ! 4168: ! 4169: case OID_GEN_PROTOCOL_OPTIONS: ! 4170: ! 4171: StatusToReturn = NDIS_STATUS_SUCCESS; ! 4172: break; ! 4173: ! 4174: default: ! 4175: ! 4176: StatusToReturn = NDIS_STATUS_INVALID_OID; ! 4177: ! 4178: NdisRequest->DATA.SET_INFORMATION.BytesRead = 0; ! 4179: NdisRequest->DATA.SET_INFORMATION.BytesNeeded = 0; ! 4180: ! 4181: break; ! 4182: } ! 4183: ! 4184: if (StatusToReturn == NDIS_STATUS_SUCCESS){ ! 4185: ! 4186: NdisRequest->DATA.SET_INFORMATION.BytesRead = OidLength; ! 4187: NdisRequest->DATA.SET_INFORMATION.BytesNeeded = 0; ! 4188: ! 4189: } ! 4190: ! 4191: #if LANCE_TRACE ! 4192: DbgPrint("Out LanceSetInfo\n"); ! 4193: #endif ! 4194: ! 4195: return(StatusToReturn); ! 4196: } ! 4197: ! 4198: STATIC ! 4199: NDIS_STATUS ! 4200: LanceSetPacketFilter( ! 4201: IN PLANCE_ADAPTER Adapter, ! 4202: IN PLANCE_OPEN Open, ! 4203: IN PNDIS_REQUEST NdisRequest, ! 4204: IN UINT PacketFilter ! 4205: ) ! 4206: ! 4207: /*++ ! 4208: ! 4209: Routine Description: ! 4210: ! 4211: The LanceSetPacketFilter request allows a protocol to control the types ! 4212: of packets that it receives from the MAC. ! 4213: ! 4214: Note : Assumes that the lock is currently held. ! 4215: ! 4216: Arguments: ! 4217: ! 4218: Adapter - Pointer to the LANCE_ADAPTER. ! 4219: ! 4220: Open - Pointer to the instance of LANCE_OPEN for Ndis. ! 4221: ! 4222: NdisRequest - Pointer to the NDIS_REQUEST which submitted the set ! 4223: packet filter command. ! 4224: ! 4225: PacketFilter - A bit mask that contains flags that correspond to specific ! 4226: classes of received packets. If a particular bit is set in the mask, ! 4227: then packet reception for that class of packet is enabled. If the ! 4228: bit is clear, then packets that fall into that class are not received ! 4229: by the client. A single exception to this rule is that if the promiscuous ! 4230: bit is set, then the client receives all packets on the network, regardless ! 4231: of the state of the other flags. ! 4232: ! 4233: Return Value: ! 4234: ! 4235: The function value is the status of the operation. ! 4236: ! 4237: --*/ ! 4238: ! 4239: { ! 4240: ! 4241: // ! 4242: // Keeps track of the *MAC's* status. The status will only be ! 4243: // reset if the filter change action routine is called. ! 4244: // ! 4245: NDIS_STATUS StatusOfFilterChange = NDIS_STATUS_SUCCESS; ! 4246: ! 4247: ! 4248: #if LANCE_TRACE ! 4249: DbgPrint("In LanceSetPacketFilter\n"); ! 4250: #endif ! 4251: ! 4252: Adapter->References++; ! 4253: ! 4254: if (!Open->BindingShuttingDown) { ! 4255: ! 4256: // ! 4257: // Increment the open while it is going through the filtering ! 4258: // routines. ! 4259: // ! 4260: ! 4261: Open->References++; ! 4262: ! 4263: StatusOfFilterChange = EthFilterAdjust( ! 4264: Adapter->FilterDB, ! 4265: Open->NdisFilterHandle, ! 4266: NdisRequest, ! 4267: PacketFilter, ! 4268: TRUE ! 4269: ); ! 4270: ! 4271: Open->References--; ! 4272: ! 4273: } else { ! 4274: ! 4275: StatusOfFilterChange = NDIS_STATUS_CLOSING; ! 4276: ! 4277: } ! 4278: ! 4279: Adapter->References--; ! 4280: ! 4281: #if LANCE_TRACE ! 4282: DbgPrint("Out LanceSetPacketFilter\n"); ! 4283: #endif ! 4284: ! 4285: return StatusOfFilterChange; ! 4286: } ! 4287: ! 4288: ! 4289: NDIS_STATUS ! 4290: LanceFillInGlobalData( ! 4291: IN PLANCE_ADAPTER Adapter, ! 4292: IN PNDIS_REQUEST NdisRequest ! 4293: ) ! 4294: ! 4295: /*++ ! 4296: ! 4297: Routine Description: ! 4298: ! 4299: This routine completes a GlobalStatistics request. It is critical that ! 4300: if information is needed from the Adapter->* fields, they have been ! 4301: updated before this routine is called. ! 4302: ! 4303: Arguments: ! 4304: ! 4305: Adapter - A pointer to the Adapter. ! 4306: ! 4307: NdisRequest - A structure which contains the request type (Global ! 4308: Query), an array of operations to perform, and an array for holding ! 4309: the results of the operations. ! 4310: ! 4311: Return Value: ! 4312: ! 4313: The function value is the status of the operation. ! 4314: ! 4315: --*/ ! 4316: { ! 4317: // ! 4318: // General Algorithm: ! 4319: // ! 4320: // Switch(Request) ! 4321: // Get requested information ! 4322: // Store results in a common variable. ! 4323: // default: ! 4324: // Try protocol query information ! 4325: // If that fails, fail query. ! 4326: // ! 4327: // Copy result in common variable to result buffer. ! 4328: // Finish processing ! 4329: ! 4330: UINT BytesWritten = 0; ! 4331: UINT BytesNeeded = 0; ! 4332: UINT BytesLeft = NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength; ! 4333: PUCHAR InfoBuffer = (PUCHAR)(NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer); ! 4334: ! 4335: NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS; ! 4336: ! 4337: // ! 4338: // This variable holds result of query ! 4339: // ! 4340: ! 4341: ULONG GenericULong; ! 4342: ULONG MoveBytes = sizeof(ULONG) * 2 + sizeof(NDIS_OID); ! 4343: ! 4344: // ! 4345: // Make sure that int is 4 bytes. Else GenericULong must change ! 4346: // to something of size 4. ! 4347: // ! 4348: ASSERT(sizeof(ULONG) == 4); ! 4349: ! 4350: ! 4351: StatusToReturn = LanceQueryProtocolInformation( ! 4352: Adapter, ! 4353: NULL, ! 4354: NdisRequest->DATA.QUERY_INFORMATION.Oid, ! 4355: TRUE, ! 4356: InfoBuffer, ! 4357: BytesLeft, ! 4358: &BytesNeeded, ! 4359: &BytesWritten ! 4360: ); ! 4361: ! 4362: ! 4363: if (StatusToReturn == NDIS_STATUS_NOT_SUPPORTED){ ! 4364: ! 4365: StatusToReturn = NDIS_STATUS_SUCCESS; ! 4366: ! 4367: NdisAcquireSpinLock(&Adapter->Lock); ! 4368: ! 4369: // ! 4370: // Switch on request type ! 4371: // ! 4372: ! 4373: switch (NdisRequest->DATA.QUERY_INFORMATION.Oid) { ! 4374: ! 4375: case OID_GEN_XMIT_OK: ! 4376: ! 4377: GenericULong = (ULONG)(Adapter->Transmit + ! 4378: Adapter->LateCollision); ! 4379: ! 4380: break; ! 4381: ! 4382: case OID_GEN_RCV_OK: ! 4383: ! 4384: GenericULong = (ULONG)(Adapter->Receive); ! 4385: ! 4386: break; ! 4387: ! 4388: case OID_GEN_XMIT_ERROR: ! 4389: ! 4390: GenericULong = (ULONG)(Adapter->LostCarrier); ! 4391: ! 4392: break; ! 4393: ! 4394: case OID_GEN_RCV_ERROR: ! 4395: ! 4396: GenericULong = (ULONG)(Adapter->CRCError); ! 4397: ! 4398: break; ! 4399: ! 4400: case OID_GEN_RCV_NO_BUFFER: ! 4401: ! 4402: GenericULong = (ULONG)(Adapter->OutOfReceiveBuffers); ! 4403: ! 4404: break; ! 4405: ! 4406: case OID_802_3_RCV_ERROR_ALIGNMENT: ! 4407: ! 4408: GenericULong = (ULONG)(Adapter->FramingError); ! 4409: ! 4410: break; ! 4411: ! 4412: case OID_802_3_XMIT_ONE_COLLISION: ! 4413: ! 4414: GenericULong = (ULONG)(Adapter->OneRetry); ! 4415: ! 4416: break; ! 4417: ! 4418: case OID_802_3_XMIT_MORE_COLLISIONS: ! 4419: ! 4420: GenericULong = (ULONG)(Adapter->MoreThanOneRetry); ! 4421: ! 4422: break; ! 4423: ! 4424: ! 4425: default: ! 4426: ! 4427: StatusToReturn = NDIS_STATUS_INVALID_OID; ! 4428: ! 4429: break; ! 4430: ! 4431: } ! 4432: ! 4433: NdisReleaseSpinLock(&Adapter->Lock); ! 4434: ! 4435: if (StatusToReturn == NDIS_STATUS_SUCCESS){ ! 4436: ! 4437: // ! 4438: // Check to make sure there is enough room in the ! 4439: // buffer to store the result. ! 4440: // ! 4441: ! 4442: if (BytesLeft >= sizeof(ULONG)){ ! 4443: ! 4444: // ! 4445: // Store the result. ! 4446: // ! 4447: ! 4448: LANCE_MOVE_MEMORY( ! 4449: (PVOID)InfoBuffer, ! 4450: (PVOID)(&GenericULong), ! 4451: sizeof(UINT) ! 4452: ); ! 4453: ! 4454: BytesWritten += sizeof(ULONG); ! 4455: ! 4456: } else { ! 4457: ! 4458: StatusToReturn = NDIS_STATUS_INVALID_LENGTH; ! 4459: ! 4460: } ! 4461: ! 4462: } ! 4463: ! 4464: } ! 4465: ! 4466: NdisRequest->DATA.QUERY_INFORMATION.BytesWritten = BytesWritten; ! 4467: ! 4468: NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded = BytesNeeded; ! 4469: ! 4470: return(StatusToReturn); ! 4471: } ! 4472: ! 4473: NDIS_STATUS ! 4474: LanceQueryGlobalStatistics( ! 4475: IN NDIS_HANDLE MacAdapterContext, ! 4476: IN PNDIS_REQUEST NdisRequest ! 4477: ) ! 4478: ! 4479: /*++ ! 4480: ! 4481: Routine Description: ! 4482: ! 4483: The LanceQueryGlobalStatistics is used by the protocol to query ! 4484: global information about the MAC. ! 4485: ! 4486: Arguments: ! 4487: ! 4488: MacAdapterContext - The value associated with the adapter that is being ! 4489: opened when the MAC registered the adapter with NdisRegisterAdapter. ! 4490: ! 4491: NdisRequest - A structure which contains the request type (Query), ! 4492: an array of operations to perform, and an array for holding ! 4493: the results of the operations. ! 4494: ! 4495: Return Value: ! 4496: ! 4497: The function value is the status of the operation. ! 4498: ! 4499: --*/ ! 4500: ! 4501: { ! 4502: ! 4503: // ! 4504: // General Algorithm: ! 4505: // ! 4506: // ! 4507: // Check if a request is going to pend... ! 4508: // If so, pend the entire operation. ! 4509: // ! 4510: // Else ! 4511: // Fill in the request block. ! 4512: // ! 4513: // ! 4514: ! 4515: PLANCE_ADAPTER Adapter = (PLANCE_ADAPTER)(MacAdapterContext); ! 4516: ! 4517: NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS; ! 4518: ! 4519: // ! 4520: // Check if a request is valid and going to pend... ! 4521: // If so, pend the entire operation. ! 4522: // ! 4523: ! 4524: ! 4525: // ! 4526: // Switch on request type ! 4527: // ! 4528: ! 4529: switch (NdisRequest->DATA.QUERY_INFORMATION.Oid) { ! 4530: case OID_GEN_SUPPORTED_LIST: ! 4531: case OID_GEN_HARDWARE_STATUS: ! 4532: case OID_GEN_MEDIA_SUPPORTED: ! 4533: case OID_GEN_MEDIA_IN_USE: ! 4534: case OID_GEN_MAXIMUM_LOOKAHEAD: ! 4535: case OID_GEN_MAXIMUM_FRAME_SIZE: ! 4536: case OID_GEN_MAXIMUM_TOTAL_SIZE: ! 4537: case OID_GEN_MAC_OPTIONS: ! 4538: case OID_GEN_LINK_SPEED: ! 4539: case OID_GEN_TRANSMIT_BUFFER_SPACE: ! 4540: case OID_GEN_RECEIVE_BUFFER_SPACE: ! 4541: case OID_GEN_TRANSMIT_BLOCK_SIZE: ! 4542: case OID_GEN_RECEIVE_BLOCK_SIZE: ! 4543: case OID_GEN_VENDOR_ID: ! 4544: case OID_GEN_VENDOR_DESCRIPTION: ! 4545: case OID_GEN_DRIVER_VERSION: ! 4546: case OID_GEN_CURRENT_PACKET_FILTER: ! 4547: case OID_GEN_CURRENT_LOOKAHEAD: ! 4548: case OID_802_3_PERMANENT_ADDRESS: ! 4549: case OID_802_3_CURRENT_ADDRESS: ! 4550: case OID_802_5_CURRENT_FUNCTIONAL: ! 4551: case OID_GEN_XMIT_OK: ! 4552: case OID_GEN_RCV_OK: ! 4553: case OID_GEN_XMIT_ERROR: ! 4554: case OID_GEN_RCV_ERROR: ! 4555: case OID_GEN_RCV_NO_BUFFER: ! 4556: case OID_802_3_MULTICAST_LIST: ! 4557: case OID_802_3_MAXIMUM_LIST_SIZE: ! 4558: case OID_802_3_RCV_ERROR_ALIGNMENT: ! 4559: case OID_802_3_XMIT_ONE_COLLISION: ! 4560: case OID_802_3_XMIT_MORE_COLLISIONS: ! 4561: ! 4562: break; ! 4563: ! 4564: default: ! 4565: ! 4566: StatusToReturn = NDIS_STATUS_INVALID_OID; ! 4567: ! 4568: break; ! 4569: ! 4570: } ! 4571: ! 4572: if (StatusToReturn == NDIS_STATUS_SUCCESS){ ! 4573: ! 4574: StatusToReturn = LanceFillInGlobalData(Adapter, NdisRequest); ! 4575: ! 4576: } ! 4577: ! 4578: return(StatusToReturn); ! 4579: } ! 4580: ! 4581: ! 4582: ! 4583: STATIC ! 4584: NDIS_STATUS ! 4585: LanceReset( ! 4586: IN NDIS_HANDLE MacBindingHandle ! 4587: ) ! 4588: ! 4589: /*++ ! 4590: ! 4591: Routine Description: ! 4592: ! 4593: The LanceReset request instructs the MAC to issue a hardware reset ! 4594: to the network adapter. The MAC also resets its software state. See ! 4595: the description of NdisReset for a detailed description of this request. ! 4596: ! 4597: Arguments: ! 4598: ! 4599: MacBindingHandle - The context value returned by the MAC when the ! 4600: adapter was opened. In reality, it is a pointer to LANCE_OPEN. ! 4601: ! 4602: Return Value: ! 4603: ! 4604: The function value is the status of the operation. ! 4605: ! 4606: ! 4607: --*/ ! 4608: ! 4609: { ! 4610: ! 4611: // ! 4612: // Holds the status that should be returned to the caller. ! 4613: // ! 4614: NDIS_STATUS StatusToReturn = NDIS_STATUS_PENDING; ! 4615: ! 4616: PLANCE_ADAPTER Adapter = ! 4617: PLANCE_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle); ! 4618: ! 4619: // ! 4620: // Hold the locks while we update the reference counts on the ! 4621: // adapter and the open. ! 4622: // ! 4623: ! 4624: NdisAcquireSpinLock(&Adapter->Lock); ! 4625: ! 4626: Adapter->References++; ! 4627: ! 4628: if (!Adapter->ResetInProgress) { ! 4629: ! 4630: PLANCE_OPEN Open; ! 4631: ! 4632: Open = PLANCE_OPEN_FROM_BINDING_HANDLE(MacBindingHandle); ! 4633: ! 4634: if (!Open->BindingShuttingDown) { ! 4635: ! 4636: // ! 4637: // Is was a reset request ! 4638: // ! 4639: ! 4640: PLIST_ENTRY CurrentLink; ! 4641: ! 4642: Open->References++; ! 4643: ! 4644: CurrentLink = Adapter->OpenBindings.Flink; ! 4645: ! 4646: while (CurrentLink != &Adapter->OpenBindings) { ! 4647: ! 4648: Open = CONTAINING_RECORD( ! 4649: CurrentLink, ! 4650: LANCE_OPEN, ! 4651: OpenList ! 4652: ); ! 4653: ! 4654: Open->References++; ! 4655: ! 4656: NdisReleaseSpinLock(&Adapter->Lock); ! 4657: ! 4658: NdisIndicateStatus( ! 4659: Open->NdisBindingContext, ! 4660: NDIS_STATUS_RESET_START, ! 4661: NULL, ! 4662: 0 ! 4663: ); ! 4664: ! 4665: NdisAcquireSpinLock(&Adapter->Lock); ! 4666: ! 4667: Open->References--; ! 4668: ! 4669: CurrentLink = CurrentLink->Flink; ! 4670: ! 4671: } ! 4672: ! 4673: Open = PLANCE_OPEN_FROM_BINDING_HANDLE(MacBindingHandle); ! 4674: ! 4675: #if LANCE_TRACE ! 4676: DbgPrint("Starting reset for 0x%x\n", Open); ! 4677: #endif ! 4678: ! 4679: SetupForReset( ! 4680: Adapter, ! 4681: Open, ! 4682: NULL, ! 4683: NdisRequestGeneric1 // Means Reset ! 4684: ); ! 4685: ! 4686: Open->References--; ! 4687: ! 4688: } else { ! 4689: ! 4690: StatusToReturn = NDIS_STATUS_CLOSING; ! 4691: ! 4692: } ! 4693: ! 4694: } else { ! 4695: ! 4696: StatusToReturn = NDIS_STATUS_SUCCESS; ! 4697: ! 4698: } ! 4699: ! 4700: LANCE_DO_DEFERRED(Adapter); ! 4701: ! 4702: return StatusToReturn; ! 4703: ! 4704: } ! 4705: ! 4706: STATIC ! 4707: VOID ! 4708: LanceSetInitializationBlock( ! 4709: IN PLANCE_ADAPTER Adapter ! 4710: ) ! 4711: ! 4712: /*++ ! 4713: ! 4714: Routine Description: ! 4715: ! 4716: This routine simply fills the initialization block ! 4717: with the information necessary for initialization. ! 4718: ! 4719: NOTE: This routine assumes that it is called with the lock ! 4720: acquired OR that only a single thread of execution is accessing ! 4721: the particular adapter. ! 4722: ! 4723: Arguments: ! 4724: ! 4725: Adapter - The adapter which holds the initialization block ! 4726: to initialize. ! 4727: ! 4728: Return Value: ! 4729: ! 4730: None. ! 4731: ! 4732: ! 4733: --*/ ! 4734: ! 4735: { ! 4736: ! 4737: PHYSICAL_ADDRESS PhysAdr; ! 4738: ! 4739: UINT PacketFilters; ! 4740: ! 4741: PLANCE_RECEIVE_ENTRY CurrentEntry = Adapter->ReceiveRing; ! 4742: USHORT Mode; ! 4743: UCHAR RingNumber; ! 4744: UCHAR i; ! 4745: ! 4746: #if LANCE_TRACE ! 4747: DbgPrint("in SetInitBlock\n"); ! 4748: #endif ! 4749: ! 4750: LANCE_ZERO_MEMORY_FOR_HARDWARE( ! 4751: Adapter->InitBlock, ! 4752: sizeof(LANCE_INITIALIZATION_BLOCK) ! 4753: ); ! 4754: ! 4755: for (i=0; i < ETH_LENGTH_OF_ADDRESS; i++) { ! 4756: ! 4757: LANCE_WRITE_HARDWARE_MEMORY_UCHAR( ! 4758: Adapter->InitBlock->PhysicalAddress[i], ! 4759: Adapter->CurrentNetworkAddress[i] ! 4760: ); ! 4761: ! 4762: } ! 4763: ! 4764: PhysAdr = LANCE_GET_HARDWARE_PHYSICAL_ADDRESS(Adapter, Adapter->TransmitRing); ! 4765: ! 4766: ! 4767: LANCE_WRITE_HARDWARE_LOW_PART_ADDRESS( ! 4768: Adapter->InitBlock->LowTransmitRingAddress, ! 4769: LANCE_GET_LOW_PART_ADDRESS(PhysAdr.LowPart) ! 4770: ); ! 4771: LANCE_WRITE_HARDWARE_HIGH_PART_ADDRESS( ! 4772: Adapter->InitBlock->HighTransmitRingAddress, ! 4773: LANCE_GET_HIGH_PART_ADDRESS(PhysAdr.LowPart) ! 4774: ); ! 4775: ! 4776: PhysAdr = LANCE_GET_HARDWARE_PHYSICAL_ADDRESS(Adapter, Adapter->ReceiveRing); ! 4777: ! 4778: // ! 4779: // Set that the chip owns each entry in the ring ! 4780: // ! 4781: ! 4782: for (CurrentEntry = Adapter->ReceiveRing, RingNumber = 0; ! 4783: RingNumber < Adapter->NumberOfReceiveRings ; ! 4784: RingNumber++, CurrentEntry++) { ! 4785: ! 4786: LANCE_WRITE_HARDWARE_MEMORY_UCHAR( ! 4787: CurrentEntry->ReceiveSummaryBits, ! 4788: LANCE_RECEIVE_OWNED_BY_CHIP ! 4789: ); ! 4790: ! 4791: } ! 4792: ! 4793: ! 4794: LANCE_WRITE_HARDWARE_LOW_PART_ADDRESS( ! 4795: Adapter->InitBlock->LowReceiveRingAddress, ! 4796: LANCE_GET_LOW_PART_ADDRESS(PhysAdr.LowPart) ! 4797: ); ! 4798: LANCE_WRITE_HARDWARE_HIGH_PART_ADDRESS( ! 4799: Adapter->InitBlock->HighReceiveRingAddress, ! 4800: LANCE_GET_HIGH_PART_ADDRESS(PhysAdr.LowPart) ! 4801: ); ! 4802: ! 4803: LANCE_WRITE_HARDWARE_MEMORY_UCHAR( ! 4804: Adapter->InitBlock->TransmitLengthLow5BitsReserved, ! 4805: (UCHAR)(Adapter->LogNumberTransmitRings << 5) ! 4806: ); ! 4807: ! 4808: LANCE_WRITE_HARDWARE_MEMORY_UCHAR( ! 4809: Adapter->InitBlock->ReceiveLengthLow5BitsReserved, ! 4810: (UCHAR)(Adapter->LogNumberReceiveRings << 5) ! 4811: ); ! 4812: ! 4813: // ! 4814: // Set up the address filtering. ! 4815: // ! 4816: // First get hold of the combined packet filter. ! 4817: // ! 4818: ! 4819: PacketFilters = ETH_QUERY_FILTER_CLASSES(Adapter->FilterDB); ! 4820: ! 4821: #if LANCE_TRACE ! 4822: DbgPrint("Filters 0x%x\n", PacketFilters); ! 4823: #endif ! 4824: ! 4825: if (PacketFilters & NDIS_PACKET_TYPE_PROMISCUOUS) { ! 4826: ! 4827: // ! 4828: // If one binding is promiscuous there is no point in ! 4829: // setting up any other filtering. Every packet is ! 4830: // going to be accepted by the hardware. ! 4831: // ! 4832: ! 4833: LANCE_READ_HARDWARE_MEMORY_USHORT( ! 4834: Adapter->InitBlock->ModeRegister, ! 4835: &Mode ! 4836: ); ! 4837: ! 4838: LANCE_WRITE_HARDWARE_MEMORY_USHORT( ! 4839: Adapter->InitBlock->ModeRegister, ! 4840: Mode | LANCE_MODE_PROMISCUOUS ! 4841: ); ! 4842: ! 4843: } else if (PacketFilters & NDIS_PACKET_TYPE_ALL_MULTICAST) { ! 4844: ! 4845: // ! 4846: // We turn on all the bits in the filter since one binding ! 4847: // wants every multicast address. ! 4848: // ! 4849: ! 4850: LANCE_WRITE_HARDWARE_MEMORY_UCHAR( ! 4851: Adapter->InitBlock->LogicalAddressFilter[0], ! 4852: 0xff ! 4853: ); ! 4854: LANCE_WRITE_HARDWARE_MEMORY_UCHAR( ! 4855: Adapter->InitBlock->LogicalAddressFilter[1], ! 4856: 0xff ! 4857: ); ! 4858: LANCE_WRITE_HARDWARE_MEMORY_UCHAR( ! 4859: Adapter->InitBlock->LogicalAddressFilter[2], ! 4860: 0xff ! 4861: ); ! 4862: LANCE_WRITE_HARDWARE_MEMORY_UCHAR( ! 4863: Adapter->InitBlock->LogicalAddressFilter[3], ! 4864: 0xff ! 4865: ); ! 4866: LANCE_WRITE_HARDWARE_MEMORY_UCHAR( ! 4867: Adapter->InitBlock->LogicalAddressFilter[4], ! 4868: 0xff ! 4869: ); ! 4870: LANCE_WRITE_HARDWARE_MEMORY_UCHAR( ! 4871: Adapter->InitBlock->LogicalAddressFilter[5], ! 4872: 0xff ! 4873: ); ! 4874: LANCE_WRITE_HARDWARE_MEMORY_UCHAR( ! 4875: Adapter->InitBlock->LogicalAddressFilter[6], ! 4876: 0xff ! 4877: ); ! 4878: LANCE_WRITE_HARDWARE_MEMORY_UCHAR( ! 4879: Adapter->InitBlock->LogicalAddressFilter[7], ! 4880: 0xff ! 4881: ); ! 4882: ! 4883: } else if (PacketFilters & NDIS_PACKET_TYPE_MULTICAST) { ! 4884: ! 4885: // ! 4886: // At least one open binding wants multicast addresses. ! 4887: // ! 4888: // We get the multicast addresses from the filter and ! 4889: // put each one through a CRC. We then take the high ! 4890: // order 6 bits from the 32 bit CRC and set that bit ! 4891: // in the logical address filter. ! 4892: // ! 4893: ! 4894: UINT NumberOfAddresses; ! 4895: ! 4896: NDIS_STATUS Status; ! 4897: ! 4898: EthQueryGlobalFilterAddresses( ! 4899: &Status, ! 4900: Adapter->FilterDB, ! 4901: MAX_MULTICAST_ADDRESS * ETH_LENGTH_OF_ADDRESS, ! 4902: &NumberOfAddresses, ! 4903: MulticastAddresses ! 4904: ); ! 4905: ! 4906: ! 4907: ASSERT(Status == NDIS_STATUS_SUCCESS); ! 4908: ! 4909: ASSERT(sizeof(ULONG) == 4); ! 4910: ! 4911: for ( ! 4912: ; ! 4913: NumberOfAddresses; ! 4914: NumberOfAddresses-- ! 4915: ) { ! 4916: ! 4917: UINT CRCValue; ! 4918: ! 4919: UINT HashValue = 0; ! 4920: ! 4921: CRCValue = CalculateCRC( ! 4922: 6, ! 4923: MulticastAddresses[NumberOfAddresses-1] ! 4924: ); ! 4925: ! 4926: HashValue |= ((CRCValue & 0x00000001)?(0x00000020):(0x00000000)); ! 4927: HashValue |= ((CRCValue & 0x00000002)?(0x00000010):(0x00000000)); ! 4928: HashValue |= ((CRCValue & 0x00000004)?(0x00000008):(0x00000000)); ! 4929: HashValue |= ((CRCValue & 0x00000008)?(0x00000004):(0x00000000)); ! 4930: HashValue |= ((CRCValue & 0x00000010)?(0x00000002):(0x00000000)); ! 4931: HashValue |= ((CRCValue & 0x00000020)?(0x00000001):(0x00000000)); ! 4932: ! 4933: LANCE_READ_HARDWARE_MEMORY_UCHAR( ! 4934: Adapter->InitBlock->LogicalAddressFilter[HashValue >> 3], ! 4935: &RingNumber ! 4936: ); ! 4937: ! 4938: LANCE_WRITE_HARDWARE_MEMORY_UCHAR( ! 4939: Adapter->InitBlock->LogicalAddressFilter[HashValue >> 3], ! 4940: RingNumber | (1 << (HashValue & 0x00000007)) ! 4941: ); ! 4942: ! 4943: } ! 4944: ! 4945: } ! 4946: ! 4947: #if LANCE_TRACE ! 4948: DbgPrint("out SetInitBlock\n"); ! 4949: #endif ! 4950: } ! 4951: ! 4952: STATIC ! 4953: UINT ! 4954: CalculateCRC( ! 4955: IN UINT NumberOfBytes, ! 4956: IN PCHAR Input ! 4957: ) ! 4958: ! 4959: /*++ ! 4960: ! 4961: Routine Description: ! 4962: ! 4963: Calculates a 32 bit crc value over the input number of bytes. ! 4964: ! 4965: Arguments: ! 4966: ! 4967: NumberOfBytes - The number of bytes in the input. ! 4968: ! 4969: Input - An input "string" to calculate a CRC over. ! 4970: ! 4971: Return Value: ! 4972: ! 4973: A 32 bit crc value. ! 4974: ! 4975: ! 4976: --*/ ! 4977: ! 4978: { ! 4979: ! 4980: const UINT POLY = 0x04c11db6; ! 4981: UINT CRCValue = 0xffffffff; ! 4982: ! 4983: ASSERT(sizeof(UINT) == 4); ! 4984: ! 4985: for ( ! 4986: ; ! 4987: NumberOfBytes; ! 4988: NumberOfBytes-- ! 4989: ) { ! 4990: ! 4991: UINT CurrentBit; ! 4992: UCHAR CurrentByte = *Input; ! 4993: Input++; ! 4994: ! 4995: for ( ! 4996: CurrentBit = 8; ! 4997: CurrentBit; ! 4998: CurrentBit-- ! 4999: ) { ! 5000: ! 5001: UINT CurrentCRCHigh = CRCValue >> 31; ! 5002: ! 5003: CRCValue <<= 1; ! 5004: ! 5005: if (CurrentCRCHigh ^ (CurrentByte & 0x01)) { ! 5006: ! 5007: CRCValue ^= POLY; ! 5008: CRCValue |= 0x00000001; ! 5009: ! 5010: } ! 5011: ! 5012: CurrentByte >>= 1; ! 5013: ! 5014: } ! 5015: ! 5016: } ! 5017: ! 5018: return CRCValue; ! 5019: ! 5020: } ! 5021: ! 5022: STATIC ! 5023: NDIS_STATUS ! 5024: LanceChangeMulticastAddresses( ! 5025: IN UINT OldFilterCount, ! 5026: IN CHAR OldAddresses[][ETH_LENGTH_OF_ADDRESS], ! 5027: IN UINT NewFilterCount, ! 5028: IN CHAR NewAddresses[][ETH_LENGTH_OF_ADDRESS], ! 5029: IN NDIS_HANDLE MacBindingHandle, ! 5030: IN PNDIS_REQUEST NdisRequest, ! 5031: IN BOOLEAN Set ! 5032: ) ! 5033: ! 5034: /*++ ! 5035: ! 5036: Routine Description: ! 5037: ! 5038: Action routine that will get called when a particular filter ! 5039: class is first used or last cleared. ! 5040: ! 5041: NOTE: This routine assumes that it is called with the lock ! 5042: acquired. ! 5043: ! 5044: Arguments: ! 5045: ! 5046: ! 5047: OldFilterCount - Number of Addresses in the old list of multicast ! 5048: addresses. ! 5049: ! 5050: OldAddresses - An array of all the multicast addresses that used ! 5051: to be on the adapter. ! 5052: ! 5053: NewFilterCount - Number of Addresses that should be put on the adapter. ! 5054: ! 5055: NewAddresses - An array of all the multicast addresses that should ! 5056: now be used. ! 5057: ! 5058: MacBindingHandle - The context value returned by the MAC when the ! 5059: adapter was opened. In reality, it is a pointer to LANCE_OPEN. ! 5060: ! 5061: NdisRequest - The request which submitted the filter change. ! 5062: Must use when completing this request with the NdisCompleteRequest ! 5063: service, if the MAC completes this request asynchronously. ! 5064: ! 5065: Set - If true the change resulted from a set, otherwise the ! 5066: change resulted from a open closing. ! 5067: ! 5068: Return Value: ! 5069: ! 5070: None. ! 5071: ! 5072: ! 5073: --*/ ! 5074: ! 5075: { ! 5076: ! 5077: ! 5078: PLANCE_ADAPTER Adapter = PLANCE_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle); ! 5079: ! 5080: UNREFERENCED_PARAMETER(OldFilterCount); ! 5081: UNREFERENCED_PARAMETER(OldAddresses); ! 5082: UNREFERENCED_PARAMETER(NewFilterCount); ! 5083: UNREFERENCED_PARAMETER(NewAddresses); ! 5084: ! 5085: #if LANCE_TRACE ! 5086: DbgPrint("In LanceChangeMultiAdresses\n"); ! 5087: #endif ! 5088: ! 5089: if (Adapter->HardwareFailure) { ! 5090: ! 5091: return(NDIS_STATUS_SUCCESS); ! 5092: ! 5093: } ! 5094: ! 5095: if (NdisRequest == NULL) { ! 5096: ! 5097: // ! 5098: // It's a close request. ! 5099: // ! 5100: ! 5101: NdisRequest = (PNDIS_REQUEST) ! 5102: &(PLANCE_OPEN_FROM_BINDING_HANDLE(MacBindingHandle)->CloseMulticastRequest); ! 5103: ! 5104: } ! 5105: ! 5106: // ! 5107: // Check to see if the device is already resetting. If it is ! 5108: // then pend this add. ! 5109: // ! 5110: ! 5111: if (Adapter->ResetInProgress) { ! 5112: ! 5113: if (Adapter->PendQueue == NULL) { ! 5114: ! 5115: Adapter->PendQueue = Adapter->PendQueueTail = NdisRequest; ! 5116: ! 5117: } else { ! 5118: ! 5119: PLANCE_PEND_DATA_FROM_PNDIS_REQUEST(Adapter->PendQueueTail)->Next = ! 5120: NdisRequest; ! 5121: ! 5122: } ! 5123: ! 5124: PLANCE_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest)->Next = NULL; ! 5125: ! 5126: PLANCE_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest)->Open = ! 5127: PLANCE_OPEN_FROM_BINDING_HANDLE(MacBindingHandle); ! 5128: ! 5129: PLANCE_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest)->RequestType = ! 5130: Set ? NdisRequestGeneric2 : NdisRequestClose; ! 5131: ! 5132: return(NDIS_STATUS_PENDING); ! 5133: ! 5134: } else { ! 5135: ! 5136: // ! 5137: // We need to add this to the hardware multicast filtering. ! 5138: // ! 5139: ! 5140: SetupForReset( ! 5141: Adapter, ! 5142: PLANCE_OPEN_FROM_BINDING_HANDLE(MacBindingHandle), ! 5143: NdisRequest, ! 5144: Set ? NdisRequestGeneric2 : // Means SetMulticastAddress ! 5145: NdisRequestClose ! 5146: ); ! 5147: ! 5148: } ! 5149: ! 5150: #if LANCE_TRACE ! 5151: DbgPrint("Out LanceChangeMultiAdresses\n"); ! 5152: #endif ! 5153: ! 5154: return NDIS_STATUS_PENDING; ! 5155: ! 5156: } ! 5157: ! 5158: STATIC ! 5159: NDIS_STATUS ! 5160: LanceChangeFilterClasses( ! 5161: IN UINT OldFilterClasses, ! 5162: IN UINT NewFilterClasses, ! 5163: IN NDIS_HANDLE MacBindingHandle, ! 5164: IN PNDIS_REQUEST NdisRequest, ! 5165: IN BOOLEAN Set ! 5166: ) ! 5167: ! 5168: /*++ ! 5169: ! 5170: Routine Description: ! 5171: ! 5172: Action routine that will get called when an address is added to ! 5173: the filter that wasn't referenced by any other open binding. ! 5174: ! 5175: NOTE: This routine assumes that it is called with the lock ! 5176: acquired. ! 5177: ! 5178: Arguments: ! 5179: ! 5180: OldFilterClasses - The filter mask that used to be on the adapter. ! 5181: ! 5182: NewFilterClasses - The new filter mask to be put on the adapter. ! 5183: ! 5184: MacBindingHandle - The context value returned by the MAC when the ! 5185: adapter was opened. In reality, it is a pointer to LANCE_OPEN. ! 5186: ! 5187: NdisRequest - The request which submitted the filter change. ! 5188: Must use when completing this request with the NdisCompleteRequest ! 5189: service, if the MAC completes this request asynchronously. ! 5190: ! 5191: Set - If true the change resulted from a set, otherwise the ! 5192: change resulted from a open closing. ! 5193: ! 5194: --*/ ! 5195: ! 5196: { ! 5197: ! 5198: PLANCE_ADAPTER Adapter = PLANCE_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle); ! 5199: ! 5200: UNREFERENCED_PARAMETER(OldFilterClasses); ! 5201: UNREFERENCED_PARAMETER(NewFilterClasses); ! 5202: ! 5203: #if LANCE_TRACE ! 5204: DbgPrint("In LanceChangeFilterClasses\n"); ! 5205: #endif ! 5206: ! 5207: ! 5208: if (Adapter->HardwareFailure) { ! 5209: ! 5210: return(NDIS_STATUS_SUCCESS); ! 5211: ! 5212: } ! 5213: ! 5214: ! 5215: if (NdisRequest == NULL) { ! 5216: ! 5217: // ! 5218: // It's a close request. ! 5219: // ! 5220: ! 5221: NdisRequest = (PNDIS_REQUEST) ! 5222: &(PLANCE_OPEN_FROM_BINDING_HANDLE(MacBindingHandle)->CloseFilterRequest); ! 5223: ! 5224: } ! 5225: ! 5226: // ! 5227: // Check to see if the device is already resetting. If it is ! 5228: // then pend this add. ! 5229: // ! 5230: ! 5231: ! 5232: if (Adapter->ResetInProgress) { ! 5233: ! 5234: if (Adapter->PendQueue == NULL) { ! 5235: ! 5236: Adapter->PendQueue = Adapter->PendQueueTail = NdisRequest; ! 5237: ! 5238: } else { ! 5239: ! 5240: PLANCE_PEND_DATA_FROM_PNDIS_REQUEST(Adapter->PendQueueTail)->Next = ! 5241: NdisRequest; ! 5242: ! 5243: } ! 5244: ! 5245: PLANCE_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest)->Next = NULL; ! 5246: ! 5247: PLANCE_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest)->Open = ! 5248: PLANCE_OPEN_FROM_BINDING_HANDLE(MacBindingHandle); ! 5249: ! 5250: PLANCE_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest)->RequestType = ! 5251: Set ? NdisRequestGeneric2 : NdisRequestClose; ! 5252: ! 5253: return(NDIS_STATUS_PENDING); ! 5254: ! 5255: } else { ! 5256: ! 5257: // ! 5258: // We need to add this to the hardware multicast filtering. ! 5259: // ! 5260: ! 5261: SetupForReset( ! 5262: Adapter, ! 5263: PLANCE_OPEN_FROM_BINDING_HANDLE(MacBindingHandle), ! 5264: NdisRequest, ! 5265: Set ? NdisRequestGeneric3 : // Means SetPacketFilter ! 5266: NdisRequestClose ! 5267: ); ! 5268: ! 5269: } ! 5270: ! 5271: #if LANCE_TRACE ! 5272: DbgPrint("Out LanceChangeFilterClasses\n"); ! 5273: #endif ! 5274: ! 5275: return NDIS_STATUS_PENDING; ! 5276: ! 5277: } ! 5278: ! 5279: STATIC ! 5280: VOID ! 5281: LanceCloseAction( ! 5282: IN NDIS_HANDLE MacBindingHandle ! 5283: ) ! 5284: ! 5285: /*++ ! 5286: ! 5287: Routine Description: ! 5288: ! 5289: Action routine that will get called when a particular binding ! 5290: was closed while it was indicating through NdisIndicateReceive ! 5291: ! 5292: All this routine needs to do is to decrement the reference count ! 5293: of the binding. ! 5294: ! 5295: NOTE: This routine assumes that it is called with the lock acquired. ! 5296: ! 5297: Arguments: ! 5298: ! 5299: MacBindingHandle - The context value returned by the MAC when the ! 5300: adapter was opened. In reality, it is a pointer to LANCE_OPEN. ! 5301: ! 5302: Return Value: ! 5303: ! 5304: None. ! 5305: ! 5306: ! 5307: --*/ ! 5308: ! 5309: { ! 5310: ! 5311: PLANCE_OPEN_FROM_BINDING_HANDLE(MacBindingHandle)->References--; ! 5312: ! 5313: } ! 5314: ! 5315: STATIC ! 5316: VOID ! 5317: ProcessInterrupt( ! 5318: IN PLANCE_ADAPTER Adapter ! 5319: ) ! 5320: ! 5321: /*++ ! 5322: ! 5323: Routine Description: ! 5324: ! 5325: Main routine for processing interrupts. ! 5326: ! 5327: NOTE: MUST BE CALLED WITH LOCK HELD! ! 5328: ! 5329: Arguments: ! 5330: ! 5331: Adapter - The Adapter to process interrupts for. ! 5332: ! 5333: Return Value: ! 5334: ! 5335: None. ! 5336: ! 5337: --*/ ! 5338: ! 5339: { ! 5340: ! 5341: // ! 5342: // Holds a value of csr0. ! 5343: // ! 5344: USHORT Csr = 0; ! 5345: ! 5346: // ! 5347: // Loop until there are no more processing sources. ! 5348: // ! 5349: ! 5350: while (TRUE) { ! 5351: ! 5352: Adapter->WakeUpTimeout = FALSE; ! 5353: ! 5354: GET_CSR0_SINCE_LAST_PROCESSED( ! 5355: Adapter, ! 5356: &Csr ! 5357: ); ! 5358: ! 5359: // ! 5360: // Check the interrupt source and other reasons ! 5361: // for processing. If there are no reasons to ! 5362: // process then exit this loop. ! 5363: // ! 5364: // Note that when we check the for processing sources ! 5365: // that we "carefully" check to see if we are already ! 5366: // processing one of the stage queues. We do this ! 5367: // by checking the "AlreadyProcessingStageX" variables ! 5368: // in the adapter. If any of these are true then ! 5369: // we let whoever set that boolean take care of pushing ! 5370: // the packet through the stage queues. ! 5371: // ! 5372: // By checking the "AlreadyProcessingStageX" variables ! 5373: // we can prevent a possible priority inversion where ! 5374: // we get "stuck" behind something that is processing ! 5375: // at a lower priority level. ! 5376: // ! 5377: ! 5378: if (((!Adapter->ResetInitStarted) && ! 5379: ((Csr & (LANCE_CSR0_MEMORY_ERROR | ! 5380: LANCE_CSR0_MISSED_PACKET | ! 5381: LANCE_CSR0_BABBLE | ! 5382: LANCE_CSR0_RECEIVER_INTERRUPT | ! 5383: LANCE_CSR0_TRANSMITTER_INTERRUPT)) || ! 5384: (Adapter->FirstLoopBack) || ! 5385: (Adapter->ResetInProgress && (!Adapter->References)) || ! 5386: ((!Adapter->AlreadyProcessingStage) && ! 5387: (Adapter->StageOpen && Adapter->FirstStage1Packet)))) || ! 5388: (Csr & LANCE_CSR0_INITIALIZATION_DONE)) { ! 5389: ! 5390: Adapter->References++; ! 5391: ! 5392: } else { ! 5393: ! 5394: break; ! 5395: ! 5396: } ! 5397: ! 5398: // ! 5399: // Check for initialization. ! 5400: // ! 5401: // Note that we come out of the synchronization above holding ! 5402: // the spinlock. ! 5403: // ! 5404: ! 5405: if (Csr & LANCE_CSR0_INITIALIZATION_DONE) { ! 5406: ! 5407: // ! 5408: // This will point (possibly null) to the open that ! 5409: // initiated the reset. ! 5410: // ! 5411: PLANCE_OPEN ResettingOpen; ! 5412: ! 5413: // ! 5414: // Possibly undefined reason why the reset was requested. ! 5415: // ! 5416: // It is undefined if the adapter initiated the reset ! 5417: // request on its own. It could do that if there ! 5418: // were some sort of error not associated with any particular ! 5419: // open. ! 5420: // ! 5421: NDIS_REQUEST_TYPE ResetRequestType; ! 5422: ! 5423: // ! 5424: // Possibly undefined request for the reset request. ! 5425: // ! 5426: PNDIS_REQUEST ResetNdisRequest; ! 5427: ! 5428: LOG(RESET_STEP_3); ! 5429: ! 5430: ASSERT(!Adapter->FirstInitialization); ! 5431: ! 5432: Csr &= ~LANCE_CSR0_INITIALIZATION_DONE; ! 5433: ! 5434: Adapter->ResetInProgress = FALSE; ! 5435: Adapter->ResetInitStarted = FALSE; ! 5436: ! 5437: // ! 5438: // We save off the open that caused this reset incase ! 5439: // we get *another* reset while we're indicating the ! 5440: // last reset is done. ! 5441: // ! 5442: ! 5443: ResettingOpen = Adapter->ResettingOpen; ! 5444: ResetRequestType = Adapter->ResetRequestType; ! 5445: ResetNdisRequest = Adapter->ResetNdisRequest; ! 5446: ! 5447: // ! 5448: // We need to signal every open binding that the ! 5449: // reset is complete. We increment the reference ! 5450: // count on the open binding while we're doing indications ! 5451: // so that the open can't be deleted out from under ! 5452: // us while we're indicating (recall that we can't own ! 5453: // the lock during the indication). ! 5454: // ! 5455: ! 5456: { ! 5457: ! 5458: PLANCE_OPEN Open; ! 5459: ! 5460: // ! 5461: // Look to see which open initiated the reset. ! 5462: // ! 5463: // If the reset was initiated by an open because it ! 5464: // was closing we will let the closing binding loop ! 5465: // further on in this routine indicate that the ! 5466: // request was complete. ! 5467: // ! 5468: // If the reset was initiated for some obscure hardware ! 5469: // reason that can't be associated with a particular ! 5470: // open (e.g. memory error on receiving a packet) then ! 5471: // we won't have an initiating request so we can't ! 5472: // indicate. (The ResettingOpen pointer will be ! 5473: // NULL in this case.) ! 5474: // ! 5475: ! 5476: #if LANCE_TRACE ! 5477: DbgPrint("0x%x 0x%x 0x%x %d %d\n", ! 5478: Adapter, ! 5479: ResettingOpen, ! 5480: ResetNdisRequest, ! 5481: ResetRequestType, ! 5482: NdisRequestClose ! 5483: ); ! 5484: #endif ! 5485: ! 5486: if ((ResettingOpen != NULL) && ! 5487: (ResetRequestType != NdisRequestClose)) { ! 5488: ! 5489: if (ResetNdisRequest != NULL) { ! 5490: ! 5491: // ! 5492: // It was a request submitted by a protocol. ! 5493: // ! 5494: ! 5495: FinishPendOp(Adapter, TRUE); ! 5496: ! 5497: } else { ! 5498: ! 5499: // ! 5500: // It was a request submitted by the MAC or ! 5501: // a reset command. ! 5502: // ! 5503: ! 5504: if (ResetRequestType == NdisRequestGeneric1) { ! 5505: ! 5506: // ! 5507: // Is was a reset request ! 5508: // ! 5509: ! 5510: PLIST_ENTRY CurrentLink; ! 5511: ! 5512: CurrentLink = Adapter->OpenBindings.Flink; ! 5513: ! 5514: while (CurrentLink != &Adapter->OpenBindings) { ! 5515: ! 5516: Open = CONTAINING_RECORD( ! 5517: CurrentLink, ! 5518: LANCE_OPEN, ! 5519: OpenList ! 5520: ); ! 5521: ! 5522: Open->References++; ! 5523: NdisDprReleaseSpinLock(&Adapter->Lock); ! 5524: ! 5525: NdisIndicateStatus( ! 5526: Open->NdisBindingContext, ! 5527: NDIS_STATUS_RESET_END, ! 5528: NULL, ! 5529: 0 ! 5530: ); ! 5531: ! 5532: NdisIndicateStatusComplete( ! 5533: Open->NdisBindingContext ! 5534: ); ! 5535: ! 5536: NdisDprAcquireSpinLock(&Adapter->Lock); ! 5537: ! 5538: Open->References--; ! 5539: ! 5540: CurrentLink = CurrentLink->Flink; ! 5541: ! 5542: } ! 5543: ! 5544: #if DBG ! 5545: Adapter->ResettingOpen = NULL; ! 5546: Adapter->ResetNdisRequest = NULL; ! 5547: Adapter->ResetRequestType = (NDIS_REQUEST_TYPE)0; ! 5548: #endif ! 5549: ! 5550: #if LANCE_TRACE ! 5551: DbgPrint("Completing reset\n"); ! 5552: #endif ! 5553: ! 5554: NdisDprReleaseSpinLock(&Adapter->Lock); ! 5555: ! 5556: NdisCompleteReset( ! 5557: ResettingOpen->NdisBindingContext, ! 5558: NDIS_STATUS_SUCCESS ! 5559: ); ! 5560: ! 5561: ! 5562: NdisDprAcquireSpinLock(&Adapter->Lock); ! 5563: ! 5564: ResettingOpen->References--; ! 5565: ! 5566: } ! 5567: ! 5568: ! 5569: } ! 5570: ! 5571: // ! 5572: // Restart the chip. ! 5573: // ! 5574: ! 5575: LanceStartChip(Adapter); ! 5576: ! 5577: } else { ! 5578: ! 5579: // ! 5580: // It was a close that pended (if there is ! 5581: // a ResettingOpen). Subtract 2, one for the ! 5582: // reset and one for the pended operation. ! 5583: // ! 5584: ! 5585: if (ResettingOpen) { ! 5586: ! 5587: ResettingOpen->References--; ! 5588: ! 5589: #if DBG ! 5590: Adapter->ResettingOpen = NULL; ! 5591: Adapter->ResetNdisRequest = NULL; ! 5592: Adapter->ResetRequestType = (NDIS_REQUEST_TYPE)0; ! 5593: #endif ! 5594: ! 5595: } ! 5596: ! 5597: if (!Adapter->ResetInProgress) { ! 5598: ! 5599: LanceStartChip(Adapter); ! 5600: ! 5601: } ! 5602: ! 5603: } ! 5604: ! 5605: } ! 5606: ! 5607: // ! 5608: // Fire off any pending operations... ! 5609: // ! 5610: ! 5611: if (Adapter->PendQueue != NULL) { ! 5612: ! 5613: PNDIS_REQUEST NdisRequest; ! 5614: ! 5615: NdisRequest = Adapter->PendQueue; ! 5616: ! 5617: Adapter->PendQueue = ! 5618: PLANCE_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest)->Next; ! 5619: ! 5620: if (NdisRequest == Adapter->PendQueueTail) { ! 5621: ! 5622: Adapter->PendQueueTail = NULL; ! 5623: ! 5624: } ! 5625: ! 5626: if (PLANCE_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest)->RequestType == ! 5627: NdisRequestClose) { ! 5628: ! 5629: SetupForReset( ! 5630: Adapter, ! 5631: PLANCE_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest)->Open, ! 5632: NULL, ! 5633: NdisRequestClose ! 5634: ); ! 5635: ! 5636: } else { ! 5637: ! 5638: SetupForReset( ! 5639: Adapter, ! 5640: PLANCE_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest)->Open, ! 5641: NdisRequest, ! 5642: PLANCE_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest)->RequestType ! 5643: ); ! 5644: ! 5645: } ! 5646: ! 5647: } ! 5648: ! 5649: goto LoopBottom; ! 5650: ! 5651: } ! 5652: ! 5653: // ! 5654: // Note that the following code depends on the fact that ! 5655: // code above left the spinlock held. ! 5656: // ! 5657: ! 5658: // ! 5659: // If we have a reset in progress and the adapters reference ! 5660: // count is 1 (meaning no routine is in the interface and ! 5661: // we are the only "active" interrupt processing routine) then ! 5662: // it is safe to start the reset. ! 5663: // ! 5664: ! 5665: if (Adapter->ResetInProgress && ! 5666: !Adapter->ResetInitStarted && ! 5667: (Adapter->References == 1)) { ! 5668: ! 5669: #if LANCE_TRACE ! 5670: DbgPrint("Starting Initialization.\n"); ! 5671: #endif ! 5672: ! 5673: StartAdapterReset(Adapter); ! 5674: ! 5675: Adapter->ResetInitStarted = TRUE; ! 5676: goto LoopBottom; ! 5677: ! 5678: } ! 5679: ! 5680: // ! 5681: // Check for non-packet related errors. ! 5682: // ! 5683: ! 5684: if (Csr & (LANCE_CSR0_MEMORY_ERROR | ! 5685: LANCE_CSR0_MISSED_PACKET | ! 5686: LANCE_CSR0_BABBLE)) { ! 5687: ! 5688: if (Csr & LANCE_CSR0_MISSED_PACKET) { ! 5689: ! 5690: Adapter->MissedPacket++; ! 5691: ! 5692: } else if (Csr & LANCE_CSR0_BABBLE) { ! 5693: ! 5694: // ! 5695: // A babble error implies that we've sent a ! 5696: // packet that is greater than the ethernet length. ! 5697: // This implies that the driver is broken. ! 5698: // ! 5699: ! 5700: Adapter->Babble++; ! 5701: ! 5702: NdisWriteErrorLogEntry( ! 5703: Adapter->NdisAdapterHandle, ! 5704: NDIS_ERROR_CODE_DRIVER_FAILURE, ! 5705: 2, ! 5706: (ULONG)processInterrupt, ! 5707: (ULONG)0x1 ! 5708: ); ! 5709: ! 5710: ! 5711: } else { ! 5712: ! 5713: // ! 5714: // Could only be a memory error. This shuts down ! 5715: // the receiver and the transmitter. We have to ! 5716: // reset to get the device started again. ! 5717: // ! 5718: ! 5719: Adapter->MemoryError++; ! 5720: ! 5721: SetupForReset( ! 5722: Adapter, ! 5723: NULL, ! 5724: NULL, ! 5725: NdisRequestGeneric4 // Means MAC issued ! 5726: ); ! 5727: ! 5728: } ! 5729: ! 5730: Csr &= ~LANCE_CSR0_ERROR_BITS; ! 5731: ! 5732: } ! 5733: ! 5734: // ! 5735: // Check the interrupt vector and see if there are any ! 5736: // more receives to process. After we process any ! 5737: // other interrupt source we always come back to the top ! 5738: // of the loop to check if any more receive packets have ! 5739: // come in. This is to lessen the probability that we ! 5740: // drop a receive. ! 5741: // ! 5742: ! 5743: ! 5744: if (Csr & LANCE_CSR0_RECEIVER_INTERRUPT) { ! 5745: ! 5746: if (ProcessReceiveInterrupts(Adapter)) { ! 5747: ! 5748: Csr &= ~LANCE_CSR0_RECEIVER_INTERRUPT; ! 5749: ! 5750: } ! 5751: ! 5752: } ! 5753: ! 5754: // ! 5755: // Process the transmit interrupts if there are any. ! 5756: // ! 5757: ! 5758: if (Csr & LANCE_CSR0_TRANSMITTER_INTERRUPT) { ! 5759: ! 5760: // ! 5761: // We need to check if the transmitter has ! 5762: // stopped as a result of an error. If it ! 5763: // has then we really need to reset the adapter. ! 5764: // ! 5765: ! 5766: if (!(Csr & LANCE_CSR0_TRANSMITTER_ON)) { ! 5767: ! 5768: // ! 5769: // Might as well turn off the transmitter interrupt ! 5770: // source since we won't ever be processing them ! 5771: // and we don't want to come back here again. ! 5772: // ! 5773: ! 5774: Csr &= ~LANCE_CSR0_TRANSMITTER_INTERRUPT; ! 5775: ! 5776: // ! 5777: // Before we setup for the reset make sure that ! 5778: // we aren't already resetting. ! 5779: // ! 5780: ! 5781: if (!Adapter->ResetInProgress) { ! 5782: ! 5783: SetupForReset( ! 5784: Adapter, ! 5785: NULL, ! 5786: 0, ! 5787: NdisRequestGeneric4 // means MAC issued ! 5788: ); ! 5789: ! 5790: } ! 5791: ! 5792: goto LoopBottom; ! 5793: ! 5794: } else { ! 5795: ! 5796: if (!ProcessTransmitInterrupts(Adapter)) { ! 5797: ! 5798: // ! 5799: // Process interrupts returns false if it ! 5800: // finds no more work to do. If this so we ! 5801: // turn off the transmitter interrupt source. ! 5802: // ! 5803: ! 5804: Csr &= ~LANCE_CSR0_TRANSMITTER_INTERRUPT; ! 5805: ! 5806: } ! 5807: ! 5808: } ! 5809: ! 5810: } ! 5811: ! 5812: ! 5813: // ! 5814: // Only try to push a packet through the stage queues ! 5815: // if somebody else isn't already doing it and ! 5816: // there is some hope of moving some packets ! 5817: // ahead. ! 5818: // ! 5819: ! 5820: if ((!Adapter->AlreadyProcessingStage) && ! 5821: (Adapter->StageOpen && Adapter->FirstStage1Packet)) { ! 5822: ! 5823: LanceStagedAllocation(Adapter); ! 5824: ! 5825: } ! 5826: ! 5827: // ! 5828: // Process the loopback queue. ! 5829: // ! 5830: // ! 5831: ! 5832: if (Adapter->FirstLoopBack != NULL) { ! 5833: ! 5834: LanceProcessLoopback(Adapter); ! 5835: ! 5836: } ! 5837: ! 5838: // ! 5839: // If there are any opens on the closing list and their ! 5840: // reference counts are zero then complete the close and ! 5841: // delete them from the list. ! 5842: // ! 5843: // ! 5844: ! 5845: LoopBottom:; ! 5846: ! 5847: // ! 5848: // NOTE: This code assumes that the above code left ! 5849: // the spinlock acquired. ! 5850: // ! 5851: // Bottom of the interrupt processing loop. Another dpc ! 5852: // could be coming in at this point to process interrupts. ! 5853: // We clear the flag that says we're processing interrupts ! 5854: // so that some invocation of the DPC can grab it and process ! 5855: // any further interrupts. ! 5856: // ! 5857: ! 5858: if (!IsListEmpty(&Adapter->CloseList)) { ! 5859: ! 5860: PLANCE_OPEN Open; ! 5861: PLIST_ENTRY Link = &(Adapter->CloseList); ! 5862: ! 5863: ! 5864: while (Link->Flink != &(Adapter->CloseList)) { ! 5865: ! 5866: Open = CONTAINING_RECORD( ! 5867: Link->Flink, ! 5868: LANCE_OPEN, ! 5869: OpenList ! 5870: ); ! 5871: ! 5872: ! 5873: if (!Open->References) { ! 5874: ! 5875: NdisDprReleaseSpinLock(&Adapter->Lock); ! 5876: ! 5877: NdisCompleteCloseAdapter( ! 5878: Open->NdisBindingContext, ! 5879: NDIS_STATUS_SUCCESS ! 5880: ); ! 5881: ! 5882: NdisDprAcquireSpinLock(&Adapter->Lock); ! 5883: ! 5884: RemoveEntryList(&Open->OpenList); ! 5885: ! 5886: if (Adapter->MaxLookAhead == Open->LookAhead) { ! 5887: ! 5888: LanceAdjustMaxLookAhead(Adapter); ! 5889: ! 5890: } ! 5891: ! 5892: LANCE_FREE_PHYS(Open, sizeof(LANCE_OPEN)); ! 5893: ! 5894: } ! 5895: ! 5896: Link = Link->Flink; ! 5897: ! 5898: } ! 5899: ! 5900: ! 5901: } ! 5902: ! 5903: Adapter->References--; ! 5904: ! 5905: } ! 5906: ! 5907: Adapter->ProcessInterruptRunning = FALSE; ! 5908: ! 5909: // ! 5910: // Check if we indicated any packets. ! 5911: // ! 5912: // Note: The only way to get out of the loop (via the break above) is ! 5913: // while we're still holding the spin lock. ! 5914: // ! 5915: ! 5916: if (Adapter->IndicatedAPacket) { ! 5917: ! 5918: Adapter->IndicatedAPacket = FALSE; ! 5919: ! 5920: NdisDprReleaseSpinLock(&Adapter->Lock); ! 5921: ! 5922: EthFilterIndicateReceiveComplete(Adapter->FilterDB); ! 5923: ! 5924: NdisDprAcquireSpinLock(&Adapter->Lock); ! 5925: ! 5926: } ! 5927: ! 5928: } ! 5929: ! 5930: STATIC ! 5931: BOOLEAN ! 5932: ProcessReceiveInterrupts( ! 5933: IN PLANCE_ADAPTER Adapter ! 5934: ) ! 5935: ! 5936: /*++ ! 5937: ! 5938: Routine Description: ! 5939: ! 5940: Process the packets that have finished receiving. ! 5941: ! 5942: NOTE: This routine assumes that no other thread of execution ! 5943: is processing receives! THE LOCK MUST BE HELD ! 5944: ! 5945: Arguments: ! 5946: ! 5947: Adapter - The adapter to indicate to. ! 5948: ! 5949: Return Value: ! 5950: ! 5951: Whether to clear the interrupt or not. ! 5952: ! 5953: --*/ ! 5954: ! 5955: { ! 5956: ! 5957: ! 5958: // ! 5959: // We don't get here unless there was a receive. Loop through ! 5960: // the receive descriptors starting at the last known descriptor ! 5961: // owned by the hardware that begins a packet. ! 5962: // ! 5963: // Examine each receive ring descriptor for errors. ! 5964: // ! 5965: // We keep an array whose elements are indexed by the ring ! 5966: // index of the receive descriptors. The arrays elements are ! 5967: // the virtual addresses of the buffers pointed to by ! 5968: // each ring descriptor. ! 5969: // ! 5970: // When we have the entire packet (and error processing doesn't ! 5971: // prevent us from indicating it), we give the routine that ! 5972: // processes the packet through the filter, the buffers virtual ! 5973: // address (which is always the lookahead size) and as the ! 5974: // MAC context the index to the first and last ring descriptors ! 5975: // comprising the packet. ! 5976: // ! 5977: ! 5978: // ! 5979: // Index of the ring descriptor in the ring. ! 5980: // ! 5981: UINT CurrentIndex = Adapter->CurrentReceiveIndex; ! 5982: ! 5983: // ! 5984: // Pointer to the ring descriptor being examined. ! 5985: // ! 5986: PLANCE_RECEIVE_ENTRY CurrentEntry = Adapter->ReceiveRing + CurrentIndex; ! 5987: ! 5988: // ! 5989: // Hold in a local the top receive ring index so that we don't ! 5990: // need to get it from the adapter all the time. ! 5991: // ! 5992: const UINT TopReceiveIndex = Adapter->NumberOfReceiveRings - 1; ! 5993: ! 5994: // ! 5995: // Boolean to record the fact that we've finished processing ! 5996: // one packet and we're about to start a new one. ! 5997: // ! 5998: BOOLEAN NewPacket = FALSE; ! 5999: ! 6000: // ! 6001: // Count of the number of buffers in the current packet. ! 6002: // ! 6003: UINT NumberOfBuffers = 1; ! 6004: ! 6005: // ! 6006: // Pointer to host addressable space for the lookahead buffer ! 6007: // ! 6008: PUCHAR LookaheadBuffer; ! 6009: ! 6010: ULONG ReceivePacketCount = 0; ! 6011: ! 6012: while (TRUE) { ! 6013: ! 6014: UCHAR ReceiveSummaryBits; ! 6015: ! 6016: ! 6017: // ! 6018: // Check to see whether we own the packet. If ! 6019: // we don't then simply return to the caller. ! 6020: // ! 6021: ! 6022: LANCE_READ_HARDWARE_MEMORY_UCHAR( ! 6023: CurrentEntry->ReceiveSummaryBits, ! 6024: &ReceiveSummaryBits ! 6025: ); ! 6026: ! 6027: if (ReceiveSummaryBits & LANCE_RECEIVE_OWNED_BY_CHIP) { ! 6028: ! 6029: LOG(RECEIVE); ! 6030: ! 6031: return TRUE; ! 6032: ! 6033: } else if (ReceivePacketCount > 10) { ! 6034: ! 6035: LOG(RECEIVE) ! 6036: ! 6037: return FALSE; ! 6038: ! 6039: } else if (ReceiveSummaryBits & LANCE_RECEIVE_ERROR_SUMMARY) { ! 6040: ! 6041: ! 6042: // ! 6043: // We have an error in the packet. Record ! 6044: // the details of the error. ! 6045: // ! 6046: ! 6047: // ! 6048: // Synch with the set/query information routines. ! 6049: // ! 6050: ! 6051: if (ReceiveSummaryBits & LANCE_RECEIVE_BUFFER_ERROR) { ! 6052: ! 6053: // ! 6054: // Probably ran out of descriptors. ! 6055: // ! 6056: ! 6057: Adapter->OutOfReceiveBuffers++; ! 6058: ! 6059: } else if (ReceiveSummaryBits & LANCE_RECEIVE_CRC_ERROR) { ! 6060: ! 6061: Adapter->CRCError++; ! 6062: ! 6063: } else if (ReceiveSummaryBits & LANCE_RECEIVE_OVERFLOW_ERROR) { ! 6064: ! 6065: Adapter->OutOfReceiveBuffers++; ! 6066: ! 6067: } else if (ReceiveSummaryBits & LANCE_RECEIVE_FRAMING_ERROR) { ! 6068: ! 6069: Adapter->FramingError++; ! 6070: ! 6071: } ! 6072: ! 6073: ReceivePacketCount++; ! 6074: ! 6075: // ! 6076: // Give the packet back to the hardware. ! 6077: // ! 6078: ! 6079: RelinquishReceivePacket( ! 6080: Adapter, ! 6081: Adapter->CurrentReceiveIndex, ! 6082: NumberOfBuffers ! 6083: ); ! 6084: ! 6085: NewPacket = TRUE; ! 6086: ! 6087: } else if (ReceiveSummaryBits & LANCE_RECEIVE_END_OF_PACKET) { ! 6088: ! 6089: // ! 6090: // We've reached the end of the packet. Prepare ! 6091: // the parameters for indication, then indicate. ! 6092: // ! 6093: ! 6094: UINT PacketSize; ! 6095: UINT LookAheadSize; ! 6096: ! 6097: LANCE_RECEIVE_CONTEXT Context; ! 6098: ! 6099: ASSERT(sizeof(LANCE_RECEIVE_CONTEXT) == sizeof(NDIS_HANDLE)); ! 6100: ! 6101: // ! 6102: // Check just before we do indications that we aren't ! 6103: // resetting. ! 6104: // ! 6105: ! 6106: if (Adapter->ResetInProgress) { ! 6107: ! 6108: return TRUE; ! 6109: } ! 6110: ! 6111: Context.INFO.IsContext = TRUE; ! 6112: Context.INFO.FirstBuffer = Adapter->CurrentReceiveIndex; ! 6113: Context.INFO.LastBuffer = CurrentIndex; ! 6114: ! 6115: LANCE_GET_MESSAGE_SIZE(CurrentEntry, PacketSize); ! 6116: ! 6117: LookAheadSize = PacketSize; ! 6118: ! 6119: // ! 6120: // Find amount to indicate. ! 6121: // ! 6122: ! 6123: LookAheadSize = ((LookAheadSize < Adapter->SizeOfReceiveBuffer) ? ! 6124: LookAheadSize : ! 6125: Adapter->SizeOfReceiveBuffer); ! 6126: ! 6127: LookAheadSize -= LANCE_HEADER_SIZE; ! 6128: ! 6129: // ! 6130: // Increment the number of packets succesfully received. ! 6131: // ! 6132: ! 6133: Adapter->Receive++; ! 6134: ! 6135: LOG(INDICATE); ! 6136: ! 6137: Adapter->IndicatingMacReceiveContext = Context; ! 6138: ! 6139: Adapter->IndicatedAPacket = TRUE; ! 6140: ! 6141: NdisDprReleaseSpinLock(&Adapter->Lock); ! 6142: ! 6143: NdisCreateLookaheadBufferFromSharedMemory( ! 6144: (PVOID)(Adapter->ReceiveVAs[Adapter->CurrentReceiveIndex]), ! 6145: LookAheadSize + LANCE_HEADER_SIZE, ! 6146: &LookaheadBuffer ! 6147: ); ! 6148: ! 6149: if (LookaheadBuffer != NULL) { ! 6150: ! 6151: if (PacketSize < LANCE_HEADER_SIZE) { ! 6152: ! 6153: if (PacketSize >= ETH_LENGTH_OF_ADDRESS) { ! 6154: ! 6155: // ! 6156: // Runt packet ! 6157: // ! 6158: ! 6159: EthFilterIndicateReceive( ! 6160: Adapter->FilterDB, ! 6161: (NDIS_HANDLE)Context.WholeThing, ! 6162: LookaheadBuffer, ! 6163: LookaheadBuffer, ! 6164: PacketSize, ! 6165: NULL, ! 6166: 0, ! 6167: 0 ! 6168: ); ! 6169: ! 6170: } ! 6171: ! 6172: } else { ! 6173: ! 6174: EthFilterIndicateReceive( ! 6175: Adapter->FilterDB, ! 6176: (NDIS_HANDLE)Context.WholeThing, ! 6177: LookaheadBuffer, ! 6178: LookaheadBuffer, ! 6179: LANCE_HEADER_SIZE, ! 6180: LookaheadBuffer + LANCE_HEADER_SIZE, ! 6181: LookAheadSize, ! 6182: PacketSize - LANCE_HEADER_SIZE ! 6183: ); ! 6184: ! 6185: } ! 6186: ! 6187: NdisDestroyLookaheadBufferFromSharedMemory( ! 6188: LookaheadBuffer ! 6189: ); ! 6190: ! 6191: } ! 6192: ! 6193: NdisDprAcquireSpinLock(&Adapter->Lock); ! 6194: ! 6195: ReceivePacketCount++; ! 6196: ! 6197: // ! 6198: // Give the packet back to the hardware. ! 6199: // ! 6200: ! 6201: RelinquishReceivePacket( ! 6202: Adapter, ! 6203: Adapter->CurrentReceiveIndex, ! 6204: NumberOfBuffers ! 6205: ); ! 6206: ! 6207: NewPacket = TRUE; ! 6208: ! 6209: } ! 6210: ! 6211: // ! 6212: // We're at some indermediate packet. Advance to ! 6213: // the next one. ! 6214: // ! 6215: ! 6216: if (CurrentIndex == TopReceiveIndex) { ! 6217: ! 6218: CurrentIndex = 0; ! 6219: CurrentEntry = Adapter->ReceiveRing; ! 6220: ! 6221: } else { ! 6222: ! 6223: CurrentIndex++; ! 6224: CurrentEntry++; ! 6225: ! 6226: } ! 6227: ! 6228: if (NewPacket) { ! 6229: ! 6230: Adapter->CurrentReceiveIndex = CurrentIndex; ! 6231: NewPacket = FALSE; ! 6232: NumberOfBuffers = 0; ! 6233: ! 6234: } ! 6235: ! 6236: NumberOfBuffers++; ! 6237: ! 6238: if (NumberOfBuffers > (TopReceiveIndex + 1)) { ! 6239: ! 6240: // ! 6241: // Error! For some reason we wrapped without ever seeing ! 6242: // the end of packet. The card is hosed. Stop the ! 6243: // whole process. ! 6244: // ! 6245: ! 6246: // ! 6247: // There are opens to notify ! 6248: // ! 6249: ! 6250: PLIST_ENTRY CurrentLink; ! 6251: PLANCE_OPEN Open; ! 6252: BOOLEAN Cancel; ! 6253: ! 6254: Adapter->HardwareFailure = TRUE; ! 6255: ! 6256: CurrentLink = Adapter->OpenBindings.Flink; ! 6257: ! 6258: while (CurrentLink != &Adapter->OpenBindings) { ! 6259: ! 6260: Open = CONTAINING_RECORD( ! 6261: CurrentLink, ! 6262: LANCE_OPEN, ! 6263: OpenList ! 6264: ); ! 6265: ! 6266: Open->References++; ! 6267: ! 6268: NdisDprReleaseSpinLock(&Adapter->Lock); ! 6269: ! 6270: NdisIndicateStatus( ! 6271: Open->NdisBindingContext, ! 6272: NDIS_STATUS_CLOSING, ! 6273: NULL, ! 6274: 0 ! 6275: ); ! 6276: ! 6277: NdisIndicateStatusComplete( ! 6278: Open->NdisBindingContext ! 6279: ); ! 6280: ! 6281: NdisDprAcquireSpinLock(&Adapter->Lock); ! 6282: ! 6283: Open->References--; ! 6284: ! 6285: CurrentLink = CurrentLink->Flink; ! 6286: ! 6287: } ! 6288: ! 6289: #if LANCELOG ! 6290: ! 6291: if (LogTimerRunning) { ! 6292: ! 6293: NdisCancelTimer(&LogTimer, &Cancel); ! 6294: NdisStallExecution(500000); ! 6295: LogTimerRunning = FALSE; ! 6296: ! 6297: } ! 6298: ! 6299: #endif ! 6300: ! 6301: ! 6302: NdisRemoveInterrupt(&(Adapter->Interrupt)); ! 6303: ! 6304: NdisWriteErrorLogEntry( ! 6305: Adapter->NdisAdapterHandle, ! 6306: NDIS_ERROR_CODE_HARDWARE_FAILURE, ! 6307: 0 ! 6308: ); ! 6309: ! 6310: NdisDeregisterAdapter(Adapter->NdisAdapterHandle); ! 6311: ! 6312: return TRUE; ! 6313: ! 6314: } ! 6315: ! 6316: } ! 6317: ! 6318: } ! 6319: ! 6320: STATIC ! 6321: VOID ! 6322: RelinquishReceivePacket( ! 6323: IN PLANCE_ADAPTER Adapter, ! 6324: IN UINT StartingIndex, ! 6325: IN UINT NumberOfBuffers ! 6326: ) ! 6327: ! 6328: /*++ ! 6329: ! 6330: Routine Description: ! 6331: ! 6332: Gives a range of receive descriptors back to the hardware. ! 6333: ! 6334: NOTE: MUST BE CALLED WITH THE LOCK HELD!! ! 6335: ! 6336: Arguments: ! 6337: ! 6338: Adapter - The adapter that the ring works with. ! 6339: ! 6340: StartingIndex - The first ring to return. Note that since ! 6341: we are dealing with a ring, this value could be greater than ! 6342: the EndingIndex. ! 6343: ! 6344: NumberOfBuffers - The number of buffers (or ring descriptors) in ! 6345: the current packet. ! 6346: ! 6347: Return Value: ! 6348: ! 6349: None. ! 6350: ! 6351: --*/ ! 6352: ! 6353: { ! 6354: ! 6355: // ! 6356: // Index of the ring descriptor in the ring. ! 6357: // ! 6358: UINT CurrentIndex = StartingIndex; ! 6359: ! 6360: // ! 6361: // Pointer to the ring descriptor being returned. ! 6362: // ! 6363: PLANCE_RECEIVE_ENTRY CurrentEntry = Adapter->ReceiveRing + CurrentIndex; ! 6364: ! 6365: // ! 6366: // Hold in a local so that we don't need to access via the adapter. ! 6367: // ! 6368: const UINT TopReceiveIndex = Adapter->NumberOfReceiveRings - 1; ! 6369: ! 6370: UCHAR Tmp; ! 6371: ! 6372: LANCE_READ_HARDWARE_MEMORY_UCHAR( ! 6373: CurrentEntry->ReceiveSummaryBits, ! 6374: &Tmp ! 6375: ); ! 6376: ! 6377: ASSERT(!(Tmp & LANCE_RECEIVE_OWNED_BY_CHIP)); ! 6378: ASSERT(Tmp & LANCE_RECEIVE_START_OF_PACKET); ! 6379: ! 6380: for ( ! 6381: ; ! 6382: NumberOfBuffers; ! 6383: NumberOfBuffers-- ! 6384: ) { ! 6385: ! 6386: LANCE_WRITE_HARDWARE_MEMORY_UCHAR( ! 6387: CurrentEntry->ReceiveSummaryBits, ! 6388: LANCE_RECEIVE_OWNED_BY_CHIP ! 6389: ); ! 6390: ! 6391: if (CurrentIndex == TopReceiveIndex) { ! 6392: ! 6393: CurrentEntry = Adapter->ReceiveRing; ! 6394: CurrentIndex = 0; ! 6395: ! 6396: } else { ! 6397: ! 6398: CurrentEntry++; ! 6399: CurrentIndex++; ! 6400: ! 6401: } ! 6402: ! 6403: } ! 6404: ! 6405: } ! 6406: ! 6407: STATIC ! 6408: BOOLEAN ! 6409: ProcessTransmitInterrupts( ! 6410: IN PLANCE_ADAPTER Adapter ! 6411: ) ! 6412: ! 6413: /*++ ! 6414: ! 6415: Routine Description: ! 6416: ! 6417: Process the packets that have finished transmitting. ! 6418: ! 6419: NOTE: This routine assumes that it is being executed in a ! 6420: single thread of execution. CALLED WITH LOCK HELD!!! ! 6421: ! 6422: Arguments: ! 6423: ! 6424: Adapter - The adapter that was sent from. ! 6425: ! 6426: Return Value: ! 6427: ! 6428: This function will return TRUE if it finished up the ! 6429: send on a packet. It will return FALSE if for some ! 6430: reason there was no packet to process. ! 6431: ! 6432: --*/ ! 6433: ! 6434: { ! 6435: // ! 6436: // Index into the ring to packet structure. This index points ! 6437: // to the first ring entry for the first buffer used for transmitting ! 6438: // the packet. ! 6439: // ! 6440: UINT FirstIndex; ! 6441: ! 6442: // ! 6443: // Pointer to the last ring entry for the packet to be transmitted. ! 6444: // This pointer might actually point to a ring entry before the first ! 6445: // ring entry for the packet since the ring structure is, simply, a ring. ! 6446: // ! 6447: PLANCE_TRANSMIT_ENTRY LastRingEntry; ! 6448: ! 6449: // ! 6450: // Pointer to the packet that started this transmission. ! 6451: // ! 6452: PNDIS_PACKET OwningPacket; ! 6453: ! 6454: // ! 6455: // First Buffer ! 6456: // ! 6457: PNDIS_BUFFER FirstBuffer; ! 6458: ! 6459: // ! 6460: // Virtual address of first buffer ! 6461: // ! 6462: PVOID BufferVA; ! 6463: ! 6464: // ! 6465: // Length of the first buffer ! 6466: // ! 6467: UINT Length; ! 6468: ! 6469: // ! 6470: // Points to the reserved part of the OwningPacket. ! 6471: // ! 6472: PLANCE_RESERVED Reserved; ! 6473: ! 6474: UCHAR TransmitSummaryBits; ! 6475: USHORT ErrorSummaryInfo; ! 6476: ! 6477: // ! 6478: // Used to hold the ring to packet mapping information so that ! 6479: // we can release the ring entries as quickly as possible. ! 6480: // ! 6481: LANCE_RING_TO_PACKET SavedRingMapping; ! 6482: ! 6483: ! 6484: // ! 6485: // Get hold of the first transmitted packet. ! 6486: // ! 6487: ! 6488: // ! 6489: // First we check that this is a packet that was transmitted ! 6490: // but not already processed. Recall that this routine ! 6491: // will be called repeatedly until this tests false, Or we ! 6492: // hit a packet that we don't completely own. ! 6493: // ! 6494: ! 6495: // ! 6496: // NOTE: I found a problem where FirstUncommitedRing wraps around ! 6497: // and becomes equal to TransmittingRing. This only happens when ! 6498: // NumberOfAvailableRings is 0 (JohnsonA) ! 6499: // ! 6500: ! 6501: if ((Adapter->TransmittingRing == Adapter->FirstUncommittedRing) && ! 6502: (Adapter->NumberOfAvailableRings > 0)) { ! 6503: ! 6504: return FALSE; ! 6505: ! 6506: } else { ! 6507: ! 6508: FirstIndex = Adapter->TransmittingRing - Adapter->TransmitRing; ! 6509: ! 6510: } ! 6511: ! 6512: ! 6513: // ! 6514: // We put the mapping into a local variable so that we ! 6515: // can return the mapping as soon as possible. ! 6516: // ! 6517: ! 6518: SavedRingMapping = Adapter->RingToPacket[FirstIndex]; ! 6519: ! 6520: // ! 6521: // Get a pointer to the last ring entry for this packet. ! 6522: // ! 6523: ! 6524: LastRingEntry = Adapter->TransmitRing + ! 6525: SavedRingMapping.RingIndex; ! 6526: ! 6527: // ! 6528: // Get a pointer to the owning packet and the reserved part of ! 6529: // the packet. ! 6530: // ! 6531: ! 6532: OwningPacket = SavedRingMapping.OwningPacket; ! 6533: ! 6534: SavedRingMapping.OwningPacket = NULL; ! 6535: ! 6536: if (OwningPacket == NULL) { ! 6537: ! 6538: // ! 6539: // We seem to be in a messed up state. Ignore this interrupt and ! 6540: // the wake up dpc will reset the card if necessary. ! 6541: // ! 6542: ! 6543: ASSERT(OwningPacket != NULL); ! 6544: return(FALSE); ! 6545: ! 6546: } ! 6547: ! 6548: if (Adapter->FirstFinishTransmit == NULL) { ! 6549: ! 6550: // ! 6551: // We seem to be in a messed up state. Ignore this interrupt and ! 6552: // the wake up dpc will reset the card if necessary. ! 6553: // ! 6554: ! 6555: ASSERT(Adapter->FirstFinishTransmit != NULL); ! 6556: return(FALSE); ! 6557: ! 6558: } ! 6559: ! 6560: Reserved = PLANCE_RESERVED_FROM_PACKET(OwningPacket); ! 6561: ! 6562: // ! 6563: // Check that the host does indeed own this entire packet. ! 6564: // ! 6565: ! 6566: LANCE_READ_HARDWARE_MEMORY_UCHAR( ! 6567: LastRingEntry->TransmitSummaryBits, ! 6568: &TransmitSummaryBits ! 6569: ); ! 6570: ! 6571: if (TransmitSummaryBits & LANCE_TRANSMIT_OWNED_BY_CHIP) { ! 6572: ! 6573: // ! 6574: // We don't own this last packet. We return FALSE to indicate ! 6575: // that we don't have any more packets to work on. ! 6576: // ! 6577: ! 6578: return FALSE; ! 6579: ! 6580: } else { ! 6581: ! 6582: // ! 6583: // Pointer to the current ring descriptor being examine for errors ! 6584: // and the statistics accumulated during its transmission. ! 6585: // ! 6586: PLANCE_TRANSMIT_ENTRY CurrentRingEntry; ! 6587: ! 6588: // ! 6589: // The binding that is submitting this packet. ! 6590: // ! 6591: PLANCE_OPEN Open; ! 6592: ! 6593: // ! 6594: // Holds whether the packet successfully transmitted or not. ! 6595: // ! 6596: BOOLEAN Successful = TRUE; ! 6597: ! 6598: LOG(TRANSMIT_COMPLETE); ! 6599: ! 6600: CurrentRingEntry = Adapter->TransmitRing + FirstIndex; ! 6601: ! 6602: // ! 6603: // now return these buffers to the adapter. ! 6604: // ! 6605: ! 6606: ReturnAdapterResources( ! 6607: Adapter, ! 6608: SavedRingMapping.LanceBuffersIndex ! 6609: ); ! 6610: ! 6611: // ! 6612: // Since the host owns the entire packet check the ring ! 6613: // entries from first to last for any errors in transmission. ! 6614: // Any errors found or multiple tries should be recorded in ! 6615: // the information structure for the adapter. ! 6616: // ! 6617: // We treat Late Collisions as success since the packet was ! 6618: // fully transmitted and may have been received. ! 6619: // ! 6620: ! 6621: while (TRUE) { ! 6622: ! 6623: LANCE_READ_HARDWARE_MEMORY_UCHAR( ! 6624: CurrentRingEntry->TransmitSummaryBits, ! 6625: &TransmitSummaryBits ! 6626: ); ! 6627: ! 6628: LANCE_READ_HARDWARE_MEMORY_USHORT( ! 6629: CurrentRingEntry->ErrorSummaryInfo, ! 6630: &ErrorSummaryInfo ! 6631: ); ! 6632: ! 6633: if ((TransmitSummaryBits & LANCE_TRANSMIT_ANY_ERRORS) && ! 6634: !(ErrorSummaryInfo & LANCE_TRANSMIT_LATE_COLLISION)) { ! 6635: ! 6636: if (ErrorSummaryInfo & LANCE_TRANSMIT_RETRY) { ! 6637: ! 6638: Adapter->RetryFailure++; ! 6639: ! 6640: } else if (ErrorSummaryInfo & LANCE_TRANSMIT_LOST_CARRIER) { ! 6641: ! 6642: Adapter->LostCarrier++; ! 6643: ! 6644: } else if (ErrorSummaryInfo & LANCE_TRANSMIT_UNDERFLOW) { ! 6645: ! 6646: Adapter->UnderFlow++; ! 6647: ! 6648: } ! 6649: ! 6650: #if DBG ! 6651: LanceSendFails[LanceSendFailPlace] = ! 6652: (UCHAR)(ErrorSummaryInfo); ! 6653: LanceSendFailPlace++; ! 6654: ! 6655: ! 6656: #endif ! 6657: ! 6658: #if LANCE_TRACE ! 6659: DbgPrint("Unsuccessful Transmit 0x%x\n", ! 6660: ErrorSummaryInfo); ! 6661: #endif ! 6662: ! 6663: Successful = FALSE; ! 6664: ! 6665: // ! 6666: // Move the pointer to transmitting but unprocessed ! 6667: // ring entries to after this packet, and recover ! 6668: // the remaining now available ring entries. ! 6669: // ! 6670: ! 6671: Adapter->NumberOfAvailableRings += ! 6672: (CurrentRingEntry <= LastRingEntry)? ! 6673: ((LastRingEntry - CurrentRingEntry)+1): ! 6674: ((Adapter->LastTransmitRingEntry - CurrentRingEntry) + ! 6675: (LastRingEntry-Adapter->TransmitRing) + 2); ! 6676: ! 6677: if (LastRingEntry == Adapter->LastTransmitRingEntry) { ! 6678: ! 6679: Adapter->TransmittingRing = Adapter->TransmitRing; ! 6680: ! 6681: } else { ! 6682: ! 6683: Adapter->TransmittingRing = LastRingEntry + 1; ! 6684: ! 6685: } ! 6686: ! 6687: break; ! 6688: ! 6689: } else { ! 6690: ! 6691: // ! 6692: // Logical variable that records whether this ! 6693: // is the last packet. ! 6694: // ! 6695: BOOLEAN DoneWithPacket = ! 6696: TransmitSummaryBits & ! 6697: LANCE_TRANSMIT_END_OF_PACKET; ! 6698: ! 6699: if (ErrorSummaryInfo & ! 6700: LANCE_TRANSMIT_LATE_COLLISION) { ! 6701: ! 6702: Adapter->LateCollision++; ! 6703: ! 6704: } ! 6705: ! 6706: if (TransmitSummaryBits & ! 6707: LANCE_TRANSMIT_START_OF_PACKET) { ! 6708: ! 6709: // ! 6710: // Collect some statistics on how many tries were needed. ! 6711: // ! 6712: ! 6713: if (TransmitSummaryBits & LANCE_TRANSMIT_DEFERRED) { ! 6714: ! 6715: Adapter->Deferred++; ! 6716: ! 6717: } else if (TransmitSummaryBits & LANCE_TRANSMIT_ONE_RETRY) { ! 6718: ! 6719: Adapter->OneRetry++; ! 6720: ! 6721: } else if (TransmitSummaryBits & LANCE_TRANSMIT_MORE_THAN_ONE_RETRY) { ! 6722: ! 6723: Adapter->MoreThanOneRetry++; ! 6724: ! 6725: ! 6726: } ! 6727: ! 6728: } ! 6729: ! 6730: if (CurrentRingEntry == Adapter->LastTransmitRingEntry) { ! 6731: ! 6732: CurrentRingEntry = Adapter->TransmitRing; ! 6733: ! 6734: } else { ! 6735: ! 6736: CurrentRingEntry++; ! 6737: ! 6738: } ! 6739: ! 6740: Adapter->TransmittingRing = CurrentRingEntry; ! 6741: Adapter->NumberOfAvailableRings++; ! 6742: ! 6743: if (DoneWithPacket) { ! 6744: ! 6745: break; ! 6746: ! 6747: } ! 6748: ! 6749: } ! 6750: ! 6751: } ! 6752: ! 6753: // ! 6754: // Store result ! 6755: // ! 6756: ! 6757: if (Successful) { ! 6758: ! 6759: // ! 6760: // Increment number of packets successfully sent. ! 6761: // ! 6762: ! 6763: Adapter->Transmit++; ! 6764: ! 6765: } ! 6766: ! 6767: // ! 6768: // Remove packet from sending queue ! 6769: // ! 6770: ! 6771: Adapter->FirstFinishTransmit = Reserved->Next; ! 6772: ! 6773: if (Adapter->FirstFinishTransmit == NULL) { ! 6774: ! 6775: Adapter->LastFinishTransmit = NULL; ! 6776: ! 6777: } ! 6778: ! 6779: // ! 6780: // Do a quick check to see if the packet has a high likelyhood ! 6781: // of needing to loopback. (NOTE: This means that if the packet ! 6782: // must be loopbacked then this function will return true. If ! 6783: // the packet doesn't need to be loopbacked then the function ! 6784: // will probably return false.) ! 6785: // ! 6786: ! 6787: // ! 6788: // Get first buffer ! 6789: // ! 6790: ! 6791: NdisQueryPacket( ! 6792: OwningPacket, ! 6793: NULL, ! 6794: NULL, ! 6795: &FirstBuffer, ! 6796: NULL ! 6797: ); ! 6798: ! 6799: // ! 6800: // Get VA of first buffer ! 6801: // ! 6802: ! 6803: NdisQueryBuffer( ! 6804: FirstBuffer, ! 6805: &BufferVA, ! 6806: &Length ! 6807: ); ! 6808: ! 6809: if (EthShouldAddressLoopBack( ! 6810: Adapter->FilterDB, ! 6811: BufferVA ! 6812: )) { ! 6813: ! 6814: Reserved->SuccessfulTransmit = Successful; ! 6815: ! 6816: if (!Adapter->FirstLoopBack) { ! 6817: ! 6818: Adapter->FirstLoopBack = OwningPacket; ! 6819: ! 6820: } else { ! 6821: ! 6822: PLANCE_RESERVED_FROM_PACKET(Adapter->LastLoopBack)->Next = OwningPacket; ! 6823: ! 6824: } ! 6825: ! 6826: Reserved->Next = NULL; ! 6827: Adapter->LastLoopBack = OwningPacket; ! 6828: ! 6829: } else { ! 6830: ! 6831: ! 6832: Open = PLANCE_OPEN_FROM_BINDING_HANDLE(Reserved->MacBindingHandle); ! 6833: ! 6834: // ! 6835: // Along with at least one reference because of the coming ! 6836: // indication there should be a reference because of the ! 6837: // packet to indicate. ! 6838: // ! 6839: ! 6840: ASSERT(Open->References > 0); ! 6841: ! 6842: NdisDprReleaseSpinLock(&Adapter->Lock); ! 6843: ! 6844: NdisCompleteSend( ! 6845: Open->NdisBindingContext, ! 6846: OwningPacket, ! 6847: ((Successful)?(NDIS_STATUS_SUCCESS):(NDIS_STATUS_FAILURE)) ! 6848: ); ! 6849: ! 6850: NdisDprAcquireSpinLock(&Adapter->Lock); ! 6851: ! 6852: // ! 6853: // Remove reference for packet ! 6854: // ! 6855: ! 6856: Open->References--; ! 6857: ! 6858: } ! 6859: ! 6860: // ! 6861: // Since we've given back some ring entries we should ! 6862: // open of the stage if it was closed and we are not resetting. ! 6863: // ! 6864: ! 6865: if ((!Adapter->StageOpen) && (!Adapter->ResetInProgress)) { ! 6866: ! 6867: Adapter->StageOpen = TRUE; ! 6868: ! 6869: } ! 6870: ! 6871: return TRUE; ! 6872: } ! 6873: ! 6874: } ! 6875: ! 6876: STATIC ! 6877: VOID ! 6878: ReturnAdapterResources( ! 6879: IN PLANCE_ADAPTER Adapter, ! 6880: IN UINT BufferIndex ! 6881: ) ! 6882: ! 6883: /*++ ! 6884: ! 6885: Routine Description: ! 6886: ! 6887: Given that a packet has used adapter resources (which the routine ! 6888: asserts), return those resources to the adapter. ! 6889: ! 6890: NOTE: CALLED WITH LOCK HELD!!! ! 6891: ! 6892: Arguments: ! 6893: ! 6894: Adapter - The adapter that the packet came through. ! 6895: ! 6896: BufferIndex - The adapter buffer descriptor index to put back on the ! 6897: free list. ! 6898: ! 6899: ! 6900: Return Value: ! 6901: ! 6902: None. ! 6903: ! 6904: --*/ ! 6905: { ! 6906: ! 6907: // ! 6908: // The adapter buffer descriptor that was allocated to this packet. ! 6909: // ! 6910: PLANCE_BUFFER_DESCRIPTOR BufferDescriptor = Adapter->LanceBuffers + ! 6911: BufferIndex; ! 6912: ! 6913: // ! 6914: // Index of the listhead that heads the list that the adapter ! 6915: // buffer descriptor belongs too. ! 6916: // ! 6917: INT ListHeadIndex = BufferDescriptor->Next; ! 6918: ! 6919: // ! 6920: // Put the adapter buffer back on the free list. ! 6921: // ! 6922: ! 6923: BufferDescriptor->Next = Adapter->LanceBufferListHeads[ListHeadIndex]; ! 6924: Adapter->LanceBufferListHeads[ListHeadIndex] = BufferIndex; ! 6925: ! 6926: // ! 6927: // If the stage was closed and we aren't resetting then open ! 6928: // it back up. ! 6929: // ! 6930: ! 6931: if ((!Adapter->StageOpen) && (!Adapter->ResetInProgress)) { ! 6932: ! 6933: Adapter->StageOpen = TRUE; ! 6934: ! 6935: } ! 6936: ! 6937: } ! 6938: ! 6939: STATIC ! 6940: VOID ! 6941: StartAdapterReset( ! 6942: IN PLANCE_ADAPTER Adapter ! 6943: ) ! 6944: ! 6945: /*++ ! 6946: ! 6947: Routine Description: ! 6948: ! 6949: This is the first phase of resetting the adapter hardware. ! 6950: ! 6951: It makes the following assumptions: ! 6952: ! 6953: 1) That the hardware has been stopped. ! 6954: ! 6955: 2) That it can not be preempted. ! 6956: ! 6957: 3) That no other adapter activity can occur. ! 6958: ! 6959: When this routine is finished all of the adapter information ! 6960: will be as if the driver was just initialized. ! 6961: ! 6962: Arguments: ! 6963: ! 6964: Adapter - The adapter whose hardware is to be reset. ! 6965: ! 6966: Return Value: ! 6967: ! 6968: None. ! 6969: ! 6970: --*/ ! 6971: ! 6972: { ! 6973: UINT i; ! 6974: PNDIS_PACKET Packet; ! 6975: PLANCE_RESERVED Reserved; ! 6976: PLANCE_OPEN Open; ! 6977: PNDIS_PACKET Next; ! 6978: ! 6979: ! 6980: #if LANCE_TRACE ! 6981: DbgPrint("In StartAdapterReset\n"); ! 6982: #endif ! 6983: ! 6984: LOG(RESET_STEP_2); ! 6985: ! 6986: // ! 6987: // Go through the various transmit lists and.... ! 6988: // ! 6989: ! 6990: ! 6991: for ( ! 6992: i = 3; ! 6993: i > 0; ! 6994: i-- ! 6995: ) { ! 6996: ! 6997: switch (i) { ! 6998: ! 6999: case 1: ! 7000: Next = Adapter->FirstFinishTransmit; ! 7001: break; ! 7002: case 2: ! 7003: Next = Adapter->FirstStage1Packet; ! 7004: break; ! 7005: case 3: ! 7006: Next = Adapter->FirstLoopBack; ! 7007: break; ! 7008: ! 7009: } ! 7010: ! 7011: ! 7012: while (Next) { ! 7013: ! 7014: Packet = Next; ! 7015: Reserved = PLANCE_RESERVED_FROM_PACKET(Packet); ! 7016: Next = Reserved->Next; ! 7017: Open = ! 7018: PLANCE_OPEN_FROM_BINDING_HANDLE(Reserved->MacBindingHandle); ! 7019: ! 7020: ! 7021: if (Adapter->ResetRequestType == NdisRequestGeneric1) { ! 7022: ! 7023: // ! 7024: // Abort the packet ! 7025: // ! 7026: // The completion of the packet is one less reason ! 7027: // to keep the open around. ! 7028: // ! 7029: ! 7030: ASSERT(Open->References); ! 7031: ! 7032: Open->References--; ! 7033: ! 7034: NdisReleaseSpinLock(&Adapter->Lock); ! 7035: ! 7036: NdisCompleteSend( ! 7037: Open->NdisBindingContext, ! 7038: Packet, ! 7039: NDIS_STATUS_REQUEST_ABORTED ! 7040: ); ! 7041: ! 7042: NdisAcquireSpinLock(&Adapter->Lock); ! 7043: ! 7044: } else if ((i == 1) || (i ==3)) { ! 7045: ! 7046: // ! 7047: // Complete these sends ! 7048: // ! 7049: // The completion of the packet is one less reason ! 7050: // to keep the open around. ! 7051: // ! 7052: ! 7053: ASSERT(Open->References); ! 7054: ! 7055: Adapter->Transmit++; ! 7056: ! 7057: LOG(RESET_COMPLETE_PACKET); ! 7058: ! 7059: NdisReleaseSpinLock(&Adapter->Lock); ! 7060: ! 7061: NdisCompleteSend( ! 7062: Open->NdisBindingContext, ! 7063: Packet, ! 7064: NDIS_STATUS_SUCCESS ! 7065: ); ! 7066: ! 7067: NdisAcquireSpinLock(&Adapter->Lock); ! 7068: ! 7069: Open->References--; ! 7070: ! 7071: } ! 7072: ! 7073: } ! 7074: ! 7075: } ! 7076: ! 7077: ! 7078: ! 7079: Adapter->CSR0Value = 0; ! 7080: Adapter->NumberOfAvailableRings = Adapter->NumberOfTransmitRings; ! 7081: Adapter->AllocateableRing = Adapter->TransmitRing; ! 7082: Adapter->TransmittingRing = Adapter->TransmitRing; ! 7083: Adapter->FirstUncommittedRing = Adapter->TransmitRing; ! 7084: ! 7085: ! 7086: Adapter->StageOpen = TRUE; ! 7087: ! 7088: Adapter->AlreadyProcessingStage = FALSE; ! 7089: ! 7090: Adapter->CurrentReceiveIndex = 0; ! 7091: ! 7092: // ! 7093: // Clean all of the receive ring entries. ! 7094: // ! 7095: ! 7096: { ! 7097: ! 7098: PLANCE_RECEIVE_ENTRY CurrentReceive = Adapter->ReceiveRing; ! 7099: const PLANCE_RECEIVE_ENTRY After = Adapter->ReceiveRing+ ! 7100: Adapter->NumberOfReceiveRings; ! 7101: ! 7102: do { ! 7103: ! 7104: LANCE_WRITE_HARDWARE_MEMORY_UCHAR( ! 7105: CurrentReceive->ReceiveSummaryBits, ! 7106: LANCE_RECEIVE_OWNED_BY_CHIP ! 7107: ); ! 7108: CurrentReceive++; ! 7109: ! 7110: ! 7111: } while (CurrentReceive != After); ! 7112: ! 7113: } ! 7114: ! 7115: ! 7116: // ! 7117: // Clean all of the transmit ring entries. ! 7118: // ! 7119: ! 7120: { ! 7121: ! 7122: PLANCE_TRANSMIT_ENTRY CurrentTransmit = Adapter->TransmitRing; ! 7123: const PLANCE_TRANSMIT_ENTRY After = Adapter->TransmitRing+ ! 7124: Adapter->NumberOfTransmitRings; ! 7125: ! 7126: do { ! 7127: ! 7128: LANCE_WRITE_HARDWARE_MEMORY_UCHAR( ! 7129: CurrentTransmit->TransmitSummaryBits, ! 7130: 0x00 ! 7131: ); ! 7132: CurrentTransmit++; ! 7133: ! 7134: ! 7135: } while (CurrentTransmit != After); ! 7136: ! 7137: } ! 7138: ! 7139: // ! 7140: // Recover all of the adapter buffers. ! 7141: // ! 7142: ! 7143: for ( ! 7144: i = 0; ! 7145: i < (Adapter->NumberOfSmallBuffers + ! 7146: Adapter->NumberOfMediumBuffers + ! 7147: Adapter->NumberOfLargeBuffers); ! 7148: i++ ! 7149: ) { ! 7150: ! 7151: Adapter->LanceBuffers[i].Next = i+1; ! 7152: ! 7153: } ! 7154: ! 7155: Adapter->LanceBufferListHeads[0] = -1; ! 7156: Adapter->LanceBufferListHeads[1] = 0; ! 7157: Adapter->LanceBuffers[(Adapter->NumberOfSmallBuffers)-1].Next = -1; ! 7158: Adapter->LanceBufferListHeads[2] = Adapter->NumberOfSmallBuffers; ! 7159: Adapter->LanceBuffers[(Adapter->NumberOfSmallBuffers + ! 7160: Adapter->NumberOfMediumBuffers)-1].Next = -1; ! 7161: Adapter->LanceBufferListHeads[3] = Adapter->NumberOfSmallBuffers + ! 7162: Adapter->NumberOfMediumBuffers; ! 7163: Adapter->LanceBuffers[(Adapter->NumberOfSmallBuffers+ ! 7164: Adapter->NumberOfMediumBuffers+ ! 7165: Adapter->NumberOfLargeBuffers)-1].Next = -1; ! 7166: ! 7167: // ! 7168: // If it was a Reset from LanceReset(), clear out all queues. ! 7169: // ! 7170: ! 7171: if (Adapter->ResetRequestType == NdisRequestGeneric1) { ! 7172: ! 7173: Adapter->FirstLoopBack = NULL; ! 7174: Adapter->LastLoopBack = NULL; ! 7175: Adapter->FirstFinishTransmit = NULL; ! 7176: Adapter->LastFinishTransmit = NULL; ! 7177: Adapter->FirstStage1Packet = NULL; ! 7178: Adapter->LastStage1Packet = NULL; ! 7179: ! 7180: } else { ! 7181: ! 7182: // ! 7183: // It was a reset from a SetInfo, ! 7184: // Clear out only the intermediate queues - the ! 7185: // packets were moved out and back to stage1. (sigh) ! 7186: // ! 7187: ! 7188: Adapter->FirstFinishTransmit = NULL; ! 7189: Adapter->LastFinishTransmit = NULL; ! 7190: ! 7191: // ! 7192: // Re-allocate all the stage 1 packets. ! 7193: // ! 7194: ! 7195: Next = Adapter->FirstStage1Packet; ! 7196: ! 7197: Adapter->FirstStage1Packet = NULL; ! 7198: Adapter->LastStage1Packet = NULL; ! 7199: ! 7200: while (Next != NULL) { ! 7201: ! 7202: LOG(RESET_RECOVER_PACKET); ! 7203: ! 7204: Packet = Next, ! 7205: Reserved = PLANCE_RESERVED_FROM_PACKET(Packet); ! 7206: Next = Reserved->Next; ! 7207: ! 7208: SetupAllocate(Adapter, Reserved->MacBindingHandle, Packet); ! 7209: ! 7210: } ! 7211: ! 7212: } ! 7213: ! 7214: ! 7215: SetInitBlockAndInit(Adapter); ! 7216: ! 7217: #if LANCE_TRACE ! 7218: DbgPrint("Out StartAdapterReset\n"); ! 7219: #endif ! 7220: ! 7221: } ! 7222: ! 7223: STATIC ! 7224: VOID ! 7225: SetInitBlockAndInit( ! 7226: IN PLANCE_ADAPTER Adapter ! 7227: ) ! 7228: ! 7229: /*++ ! 7230: ! 7231: Routine Description: ! 7232: ! 7233: It is this routines responsibility to make sure that the ! 7234: initialization block is filled and the chip is initialized ! 7235: *but not* started. ! 7236: ! 7237: NOTE: This routine assumes that it is called with the lock ! 7238: acquired OR that only a single thread of execution is working ! 7239: with this particular adapter. ! 7240: ! 7241: Arguments: ! 7242: ! 7243: Adapter - The adapter whose hardware is to be initialized. ! 7244: ! 7245: Return Value: ! 7246: ! 7247: None. ! 7248: ! 7249: --*/ ! 7250: { ! 7251: ! 7252: PHYSICAL_ADDRESS PhysAdr; ! 7253: ! 7254: // ! 7255: // Fill in the adapters initialization block. ! 7256: // ! 7257: ! 7258: LanceSetInitializationBlock(Adapter); ! 7259: ! 7260: PhysAdr = LANCE_GET_HARDWARE_PHYSICAL_ADDRESS(Adapter,Adapter->InitBlock); ! 7261: ! 7262: // ! 7263: // Make sure that it does have even byte alignment. ! 7264: // ! 7265: ! 7266: ASSERT(!(PhysAdr.LowPart & 0x01)); ! 7267: ! 7268: // ! 7269: // Write the address of the initialization block to csr1 and csr2. ! 7270: // ! 7271: ! 7272: LANCE_WRITE_RAP( ! 7273: Adapter, ! 7274: LANCE_SELECT_CSR1 ! 7275: ); ! 7276: ! 7277: LANCE_WRITE_RDP( ! 7278: Adapter, ! 7279: LANCE_GET_LOW_PART_ADDRESS(PhysAdr.LowPart) ! 7280: ); ! 7281: ! 7282: LANCE_WRITE_RAP( ! 7283: Adapter, ! 7284: LANCE_SELECT_CSR2 ! 7285: ); ! 7286: ! 7287: LANCE_WRITE_RDP( ! 7288: Adapter, ! 7289: LANCE_GET_HIGH_PART_ADDRESS(PhysAdr.LowPart) ! 7290: ); ! 7291: ! 7292: // ! 7293: // Write to csr0 to initialize the chip. ! 7294: // ! 7295: ! 7296: LANCE_WRITE_RAP( ! 7297: Adapter, ! 7298: LANCE_SELECT_CSR0 ! 7299: ); ! 7300: ! 7301: LANCE_WRITE_RDP( ! 7302: Adapter, ! 7303: LANCE_CSR0_INIT_CHIP ! 7304: ); ! 7305: ! 7306: } ! 7307: ! 7308: STATIC ! 7309: VOID ! 7310: SetupForReset( ! 7311: IN PLANCE_ADAPTER Adapter, ! 7312: IN PLANCE_OPEN Open, ! 7313: IN PNDIS_REQUEST NdisRequest, ! 7314: IN NDIS_REQUEST_TYPE RequestType ! 7315: ) ! 7316: ! 7317: /*++ ! 7318: ! 7319: Routine Description: ! 7320: ! 7321: This routine is used to fill in the who and why a reset is ! 7322: being set up as well as setting the appropriate fields in the ! 7323: adapter. ! 7324: ! 7325: NOTE: This routine must be called with the lock acquired. ! 7326: ! 7327: Arguments: ! 7328: ! 7329: Adapter - The adapter whose hardware is to be initialized. ! 7330: ! 7331: Open - A (possibly NULL) pointer to an lance open structure. ! 7332: The reason it could be null is if the adapter is initiating the ! 7333: reset on its own. ! 7334: ! 7335: NdisRequest - A pointer to the NDIS_REQUEST which requested the reset. ! 7336: ! 7337: RequestType - If the open is not null then the request type that ! 7338: is causing the reset. ! 7339: ! 7340: Return Value: ! 7341: ! 7342: None. ! 7343: ! 7344: --*/ ! 7345: { ! 7346: ! 7347: #if LANCE_TRACE ! 7348: DbgPrint("In SetupForReset\n"); ! 7349: #endif ! 7350: ! 7351: LOG(RESET_STEP_1); ! 7352: ! 7353: // ! 7354: // Shut down the chip. We won't be doing any more work until ! 7355: // the reset is complete. ! 7356: // ! 7357: ! 7358: NdisSynchronizeWithInterrupt( ! 7359: &Adapter->Interrupt, ! 7360: LanceSyncStopChip, ! 7361: (PVOID)Adapter ! 7362: ); ! 7363: ! 7364: // ! 7365: // Once the chip is stopped we can't get any more interrupts. ! 7366: // Any interrupts that are "queued" for processing could ! 7367: // only possibly service this reset. It is therefore safe for ! 7368: // us to clear the adapter global csr value. ! 7369: // ! 7370: ! 7371: Adapter->CSR0Value = 0; ! 7372: ! 7373: Adapter->ResetInProgress = TRUE; ! 7374: Adapter->ResetInitStarted = FALSE; ! 7375: ! 7376: // ! 7377: // Shut down all of the transmit queues so that the ! 7378: // transmit portion of the chip will eventually calm down. ! 7379: // ! 7380: ! 7381: Adapter->StageOpen = FALSE; ! 7382: ! 7383: Adapter->ResetNdisRequest = NdisRequest; ! 7384: Adapter->ResettingOpen = Open; ! 7385: Adapter->ResetRequestType = RequestType; ! 7386: ! 7387: // ! 7388: // If there is a valid open we should up the reference count ! 7389: // so that the open can't be deleted before we indicate that ! 7390: // their request is finished. ! 7391: // ! 7392: ! 7393: if (Open) { ! 7394: ! 7395: Open->References++; ! 7396: ! 7397: } ! 7398: ! 7399: #if LANCE_TRACE ! 7400: DbgPrint("Out SetupForReset\n"); ! 7401: #endif ! 7402: ! 7403: } ! 7404: ! 7405: ! 7406: STATIC ! 7407: VOID ! 7408: FinishPendOp( ! 7409: IN PLANCE_ADAPTER Adapter, ! 7410: IN BOOLEAN Successful ! 7411: ) ! 7412: ! 7413: /*++ ! 7414: ! 7415: Routine Description: ! 7416: ! 7417: This routine is called when a pended operation completes. ! 7418: It calles CompleteRequest if needed and does any other ! 7419: cleanup required. ! 7420: ! 7421: NOTE: This routine is called with the lock held and ! 7422: returns with it held. ! 7423: ! 7424: NOTE: This routine assumes that the pended operation to ! 7425: be completed was specifically requested by the protocol. ! 7426: ! 7427: ! 7428: Arguments: ! 7429: ! 7430: Adapter - The adapter. ! 7431: ! 7432: Successful - Was the pended operation completed successfully. ! 7433: ! 7434: Return Value: ! 7435: ! 7436: None. ! 7437: ! 7438: --*/ ! 7439: ! 7440: { ! 7441: ASSERT(Adapter->ResetNdisRequest != NULL); ! 7442: ! 7443: ! 7444: // ! 7445: // It was a request for filter change or multicastlist change. ! 7446: // ! 7447: ! 7448: if (Successful) { ! 7449: ! 7450: // ! 7451: // complete the operation. ! 7452: // ! 7453: ! 7454: ! 7455: NdisReleaseSpinLock(&(Adapter->Lock)); ! 7456: ! 7457: NdisCompleteRequest( ! 7458: Adapter->ResettingOpen->NdisBindingContext, ! 7459: Adapter->ResetNdisRequest, ! 7460: NDIS_STATUS_SUCCESS ! 7461: ); ! 7462: ! 7463: NdisAcquireSpinLock(&(Adapter->Lock)); ! 7464: ! 7465: Adapter->ResetNdisRequest = NULL; ! 7466: ! 7467: Adapter->ResettingOpen->References--; ! 7468: ! 7469: } else { ! 7470: ! 7471: ! 7472: // ! 7473: // complete the operation. ! 7474: // ! 7475: ! 7476: ! 7477: NdisReleaseSpinLock(&(Adapter->Lock)); ! 7478: ! 7479: NdisCompleteRequest( ! 7480: Adapter->ResettingOpen->NdisBindingContext, ! 7481: Adapter->ResetNdisRequest, ! 7482: NDIS_STATUS_FAILURE ! 7483: ); ! 7484: ! 7485: NdisAcquireSpinLock(&(Adapter->Lock)); ! 7486: ! 7487: Adapter->ResetNdisRequest = NULL; ! 7488: ! 7489: Adapter->ResettingOpen->References--; ! 7490: ! 7491: } ! 7492: ! 7493: return; ! 7494: ! 7495: } ! 7496: ! 7497: ! 7498: ! 7499: STATIC ! 7500: BOOLEAN ! 7501: LanceSyncWriteRAP( ! 7502: IN PVOID Context ! 7503: ) ! 7504: /*++ ! 7505: ! 7506: Routine Description: ! 7507: ! 7508: This routine is used by the normal interrupt processing routine ! 7509: to synchronize with interrupts from the card. It will write ! 7510: to the RAP ! 7511: ! 7512: ! 7513: Arguments: ! 7514: ! 7515: Context - This is really a pointer to a record type peculiar ! 7516: to this routine. The record contains a pointer to the adapter ! 7517: and a pointer to the value to write. ! 7518: ! 7519: ! 7520: Return Value: ! 7521: ! 7522: Always returns true. ! 7523: ! 7524: --*/ ! 7525: ! 7526: { ! 7527: ! 7528: ! 7529: PLANCE_SYNCH_CONTEXT C = Context; ! 7530: ! 7531: LANCE_ISR_WRITE_RAP(C->Adapter, C->LocalWrite); ! 7532: ! 7533: return FALSE; ! 7534: ! 7535: } ! 7536: ! 7537: BOOLEAN ! 7538: LanceSyncWriteRDP( ! 7539: IN PVOID Context ! 7540: ) ! 7541: /*++ ! 7542: ! 7543: Routine Description: ! 7544: ! 7545: This routine is used by the normal interrupt processing routine ! 7546: to synchronize with interrupts from the card. It will write ! 7547: into the RDP register ! 7548: ! 7549: ! 7550: Arguments: ! 7551: ! 7552: Context - This is really a pointer to a record type peculiar ! 7553: to this routine. The record contains a pointer to the adapter ! 7554: and a pointer to the value to write. ! 7555: ! 7556: Return Value: ! 7557: ! 7558: Always returns true. ! 7559: ! 7560: --*/ ! 7561: ! 7562: { ! 7563: ! 7564: ! 7565: PLANCE_SYNCH_CONTEXT C = Context; ! 7566: ! 7567: LANCE_ISR_WRITE_RDP(C->Adapter, C->LocalWrite); ! 7568: ! 7569: return FALSE; ! 7570: ! 7571: ! 7572: } ! 7573: ! 7574: STATIC ! 7575: BOOLEAN ! 7576: LanceSyncReadRDP( ! 7577: IN PVOID Context ! 7578: ) ! 7579: /*++ ! 7580: ! 7581: Routine Description: ! 7582: ! 7583: This routine is used by the normal interrupt processing routine ! 7584: to synchronize with interrupts from the card. It will read ! 7585: from the RDP. ! 7586: ! 7587: Arguments: ! 7588: ! 7589: Context - This is really a pointer to a record type peculiar ! 7590: to this routine. The record contains a pointer to the adapter ! 7591: and a pointer to a USHORT to store the value into. ! 7592: ! 7593: Return Value: ! 7594: ! 7595: Always returns true. ! 7596: ! 7597: --*/ ! 7598: ! 7599: { ! 7600: ! 7601: ! 7602: PLANCE_SYNCH_CONTEXT C = Context; ! 7603: ! 7604: LANCE_ISR_READ_RDP(C->Adapter, C->LocalRead); ! 7605: ! 7606: return FALSE; ! 7607: ! 7608: } ! 7609: ! 7610: STATIC ! 7611: BOOLEAN ! 7612: LanceSyncWriteNicsr( ! 7613: IN PVOID Context ! 7614: ) ! 7615: /*++ ! 7616: ! 7617: Routine Description: ! 7618: ! 7619: This routine is used by the normal interrupt processing routine ! 7620: to synchronize with interrupts from the card. It will ! 7621: Write to the NIC Status Register. ! 7622: ! 7623: Arguments: ! 7624: ! 7625: Context - This is really a pointer to a record type peculiar ! 7626: to this routine. The record contains a pointer to the adapter ! 7627: and a pointer to an address which holds the value to write. ! 7628: ! 7629: Return Value: ! 7630: ! 7631: Always returns false. ! 7632: ! 7633: --*/ ! 7634: ! 7635: { ! 7636: ! 7637: PLANCE_SYNCH_CONTEXT C = Context; ! 7638: ! 7639: LANCE_ISR_WRITE_NICSR(C->Adapter, C->LocalWrite); ! 7640: ! 7641: return FALSE; ! 7642: ! 7643: } ! 7644: ! 7645: STATIC ! 7646: BOOLEAN ! 7647: LanceSyncStopChip( ! 7648: IN PVOID Context ! 7649: ) ! 7650: ! 7651: /*++ ! 7652: ! 7653: Routine Description: ! 7654: ! 7655: This routine is used to stop a lance. ! 7656: ! 7657: ! 7658: ! 7659: Arguments: ! 7660: ! 7661: Adapter - The adapter for the LANCE to stop. ! 7662: ! 7663: Return Value: ! 7664: ! 7665: FALSE ! 7666: ! 7667: --*/ ! 7668: ! 7669: { ! 7670: ! 7671: PLANCE_ADAPTER Adapter = (PLANCE_ADAPTER)Context; ! 7672: ! 7673: // ! 7674: // Set the RAP to csr0. ! 7675: // ! 7676: ! 7677: LANCE_ISR_WRITE_RAP( ! 7678: Adapter, ! 7679: LANCE_SELECT_CSR0 ! 7680: ); ! 7681: ! 7682: // ! 7683: // Set the RDP to stop chip. ! 7684: // ! 7685: ! 7686: LANCE_ISR_WRITE_RDP( ! 7687: Adapter, ! 7688: LANCE_CSR0_STOP ! 7689: ); ! 7690: ! 7691: if (Adapter->LanceCard & (LANCE_DE201 | LANCE_DE100 | LANCE_DE422)) { ! 7692: ! 7693: // ! 7694: // Always reset the ACON bit after a stop. ! 7695: // ! 7696: ! 7697: LANCE_ISR_WRITE_RAP( ! 7698: Adapter, ! 7699: LANCE_SELECT_CSR3 ! 7700: ); ! 7701: ! 7702: LANCE_ISR_WRITE_RDP( ! 7703: Adapter, ! 7704: LANCE_CSR3_ACON ! 7705: ); ! 7706: ! 7707: } ! 7708: ! 7709: // ! 7710: // Select CSR0 again. ! 7711: // ! 7712: ! 7713: LANCE_ISR_WRITE_RAP( ! 7714: Adapter, ! 7715: LANCE_SELECT_CSR0 ! 7716: ); ! 7717: ! 7718: return(FALSE); ! 7719: } ! 7720: ! 7721: ! 7722: VOID ! 7723: LanceWakeUpDpc( ! 7724: IN PVOID SystemSpecific1, ! 7725: IN PVOID Context, ! 7726: IN PVOID SystemSpecific2, ! 7727: IN PVOID SystemSpecific3 ! 7728: ) ! 7729: ! 7730: /*++ ! 7731: ! 7732: Routine Description: ! 7733: ! 7734: This DPC routine is queued every 5 seconds to check on the ! 7735: queues. If an interrupt was not received ! 7736: in the last 5 seconds and there should have been one, ! 7737: then we abort all operations. ! 7738: ! 7739: Arguments: ! 7740: ! 7741: Context - Really a pointer to the adapter. ! 7742: ! 7743: Return Value: ! 7744: ! 7745: None. ! 7746: ! 7747: --*/ ! 7748: { ! 7749: PLANCE_ADAPTER Adapter = (PLANCE_ADAPTER)Context; ! 7750: PLANCE_OPEN TmpOpen; ! 7751: PNDIS_PACKET TransmitPacket; ! 7752: PLANCE_PEND_DATA PendOp; ! 7753: PNDIS_REQUEST Request; ! 7754: PLANCE_RESERVED Reserved; ! 7755: ! 7756: UNREFERENCED_PARAMETER(SystemSpecific1); ! 7757: UNREFERENCED_PARAMETER(SystemSpecific2); ! 7758: UNREFERENCED_PARAMETER(SystemSpecific3); ! 7759: ! 7760: NdisDprAcquireSpinLock(&Adapter->Lock); ! 7761: ! 7762: if ((Adapter->WakeUpTimeout) && ! 7763: ((Adapter->FirstFinishTransmit != NULL) || ! 7764: (Adapter->FirstStage1Packet != NULL) || ! 7765: (Adapter->PendQueue != NULL) || ! 7766: (Adapter->ResetNdisRequest != NULL))) { ! 7767: ! 7768: // ! 7769: // We had a pending operation the last time we ran, ! 7770: // and it has not been completed...we need to complete ! 7771: // it now. ! 7772: ! 7773: Adapter->WakeUpTimeout = FALSE; ! 7774: ! 7775: Adapter->TimeoutCount++; ! 7776: ! 7777: if (Adapter->TimeoutCount < 10) { ! 7778: ! 7779: // ! 7780: // Limit the number of error log entries ! 7781: // ! 7782: ! 7783: NdisWriteErrorLogEntry( ! 7784: Adapter->NdisAdapterHandle, ! 7785: NDIS_ERROR_CODE_HARDWARE_FAILURE, ! 7786: 0 ! 7787: ); ! 7788: ! 7789: ! 7790: } ! 7791: ! 7792: if ((Adapter->ResettingOpen != NULL) && ! 7793: (Adapter->ResetRequestType != NdisRequestClose)) { ! 7794: ! 7795: if (Adapter->ResetNdisRequest != NULL) { ! 7796: ! 7797: // ! 7798: // It was a request submitted by a protocol. ! 7799: // ! 7800: ! 7801: TmpOpen = Adapter->ResettingOpen; ! 7802: ! 7803: NdisDprReleaseSpinLock(&(Adapter->Lock)); ! 7804: ! 7805: NdisCompleteRequest( ! 7806: Adapter->ResettingOpen->NdisBindingContext, ! 7807: Adapter->ResetNdisRequest, ! 7808: NDIS_STATUS_SUCCESS ! 7809: ); ! 7810: ! 7811: NdisDprAcquireSpinLock(&(Adapter->Lock)); ! 7812: ! 7813: TmpOpen->References--; ! 7814: ! 7815: } ! 7816: ! 7817: } ! 7818: ! 7819: while (Adapter->PendQueue) { ! 7820: ! 7821: Request = Adapter->PendQueue; ! 7822: PendOp = PLANCE_PEND_DATA_FROM_PNDIS_REQUEST(Request); ! 7823: ! 7824: Adapter->PendQueue = PendOp->Next; ! 7825: ! 7826: if (Adapter->PendQueue == NULL){ ! 7827: ! 7828: // ! 7829: // We have just emptied the list. ! 7830: // ! 7831: ! 7832: Adapter->PendQueueTail = NULL; ! 7833: ! 7834: } ! 7835: ! 7836: ! 7837: if ((PendOp->Open != NULL) && ! 7838: (PendOp->RequestType != NdisRequestClose)) { ! 7839: ! 7840: // ! 7841: // It was a request submitted by a protocol. ! 7842: // ! 7843: ! 7844: TmpOpen = PendOp->Open; ! 7845: ! 7846: NdisDprReleaseSpinLock(&(Adapter->Lock)); ! 7847: ! 7848: NdisCompleteRequest( ! 7849: PendOp->Open->NdisBindingContext, ! 7850: Request, ! 7851: NDIS_STATUS_SUCCESS ! 7852: ); ! 7853: ! 7854: NdisDprAcquireSpinLock(&(Adapter->Lock)); ! 7855: ! 7856: TmpOpen->References--; ! 7857: ! 7858: } ! 7859: ! 7860: } ! 7861: ! 7862: while (Adapter->FirstFinishTransmit != NULL) { ! 7863: ! 7864: TransmitPacket = Adapter->FirstFinishTransmit; ! 7865: ! 7866: Reserved = PLANCE_RESERVED_FROM_PACKET(TransmitPacket); ! 7867: ! 7868: Adapter->FirstFinishTransmit = Reserved->Next; ! 7869: ! 7870: if (Adapter->FirstFinishTransmit == NULL) { ! 7871: ! 7872: Adapter->LastFinishTransmit = NULL; ! 7873: ! 7874: } ! 7875: ! 7876: TmpOpen = PLANCE_OPEN_FROM_BINDING_HANDLE(Reserved->MacBindingHandle); ! 7877: ! 7878: NdisDprReleaseSpinLock(&Adapter->Lock); ! 7879: ! 7880: NdisCompleteSend( ! 7881: TmpOpen->NdisBindingContext, ! 7882: TransmitPacket, ! 7883: NDIS_STATUS_SUCCESS ! 7884: ); ! 7885: ! 7886: NdisDprAcquireSpinLock(&Adapter->Lock); ! 7887: ! 7888: TmpOpen->References--; ! 7889: ! 7890: } ! 7891: ! 7892: while (Adapter->FirstStage1Packet != NULL) { ! 7893: ! 7894: TransmitPacket = Adapter->FirstStage1Packet; ! 7895: ! 7896: Reserved = PLANCE_RESERVED_FROM_PACKET(TransmitPacket); ! 7897: ! 7898: // ! 7899: // Remove the packet from the queue. ! 7900: // ! 7901: ! 7902: Adapter->FirstStage1Packet = Reserved->Next; ! 7903: ! 7904: if (Adapter->FirstStage1Packet == NULL) { ! 7905: ! 7906: Adapter->LastStage1Packet = NULL; ! 7907: ! 7908: } ! 7909: ! 7910: TmpOpen = PLANCE_OPEN_FROM_BINDING_HANDLE(Reserved->MacBindingHandle); ! 7911: ! 7912: NdisDprReleaseSpinLock(&Adapter->Lock); ! 7913: ! 7914: NdisCompleteSend( ! 7915: TmpOpen->NdisBindingContext, ! 7916: TransmitPacket, ! 7917: NDIS_STATUS_SUCCESS ! 7918: ); ! 7919: ! 7920: NdisDprAcquireSpinLock(&Adapter->Lock); ! 7921: ! 7922: TmpOpen->References--; ! 7923: ! 7924: } ! 7925: ! 7926: Adapter->WakeUpTimeout = FALSE; ! 7927: ! 7928: SetupForReset( ! 7929: Adapter, ! 7930: NULL, ! 7931: NULL, ! 7932: NdisRequestGeneric4 // Means MAC issued ! 7933: ); ! 7934: ! 7935: NdisSetTimer(&Adapter->DeferredTimer, 0); ! 7936: ! 7937: NdisDprReleaseSpinLock(&Adapter->Lock); ! 7938: ! 7939: } else { ! 7940: ! 7941: if ((Adapter->FirstFinishTransmit != NULL) || ! 7942: (Adapter->FirstStage1Packet != NULL) || ! 7943: (Adapter->PendQueue != NULL) || ! 7944: (Adapter->ResetNdisRequest != NULL)) { ! 7945: ! 7946: Adapter->WakeUpTimeout = TRUE; ! 7947: ! 7948: } ! 7949: ! 7950: NdisDprReleaseSpinLock(&Adapter->Lock); ! 7951: ! 7952: ! 7953: } ! 7954: ! 7955: // ! 7956: // Fire off another Dpc to execute after 5 seconds ! 7957: // ! 7958: ! 7959: NdisSetTimer( ! 7960: &Adapter->WakeUpTimer, ! 7961: 5000 ! 7962: ); ! 7963: ! 7964: } ! 7965: ! 7966: ! 7967:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.