|
|
1.1 ! root 1: /*++ ! 2: ! 3: Copyright (c) 1990 Microsoft Corporation ! 4: ! 5: Module Name: ! 6: ! 7: ibmtok.c ! 8: ! 9: Abstract: ! 10: ! 11: This is the main file for the IBM Token-Ring 16/4 Adapter. ! 12: This driver conforms to the NDIS 3.0 interface. ! 13: ! 14: The overall structure and much of the code is taken from ! 15: the Lance NDIS driver by Tony Ercolano. ! 16: ! 17: Author: ! 18: ! 19: Anthony V. Ercolano (Tonye) 20-Jul-1990 ! 20: Adam Barr (adamba) 15-Feb-1990 ! 21: ! 22: Environment: ! 23: ! 24: Kernel Mode - Or whatever is the equivalent. ! 25: ! 26: Revision History: ! 27: ! 28: Sean Selitrennikoff -- 9/15/91: ! 29: Added code to handle Microchannel with PC I/O bus handling. ! 30: Fixed bugs. ! 31: Sean Selitrennikoff -- 10/15/91: ! 32: Converted to Ndis 3.0 spec. ! 33: George Joy -- 12/1/91 ! 34: Changed for compilation under DOS as well as NT ! 35: Sean Selitrennikoff -- 1/8/92: ! 36: Added error logging ! 37: ! 38: --*/ ! 39: ! 40: #pragma optimize("",off) ! 41: ! 42: #include <ndis.h> ! 43: ! 44: ! 45: #include <tfilter.h> ! 46: #include <tokhrd.h> ! 47: #include <toksft.h> ! 48: ! 49: ! 50: #if LOG ! 51: ! 52: // ! 53: // Place in the circular buffer. ! 54: // ! 55: extern UCHAR IbmtokLogPlace; ! 56: ! 57: // ! 58: // Circular buffer for storing log information. ! 59: // ! 60: extern UCHAR IbmtokLog[]; ! 61: ! 62: #define IF_LOG(A) {IbmtokLog[IbmtokLogPlace++] = (A); IbmtokLog[IbmtokLogPlace+2] = '.';} ! 63: ! 64: #else ! 65: ! 66: #define IF_LOG(A) ! 67: ! 68: #endif ! 69: ! 70: // ! 71: // This constant is used for places where NdisAllocateMemory ! 72: // needs to be called and the HighestAcceptableAddress does ! 73: // not matter. ! 74: // ! 75: ! 76: const NDIS_PHYSICAL_ADDRESS HighestAcceptableMax = ! 77: NDIS_PHYSICAL_ADDRESS_CONST(-1,-1); ! 78: ! 79: ! 80: // ! 81: // If you add to this, make sure to add the ! 82: // a case in IbmtokFillInGlobalData() and in ! 83: // IbmtokQueryGlobalStatistics() ! 84: // ! 85: static const UINT IbmtokGlobalSupportedOids[] = { ! 86: OID_GEN_SUPPORTED_LIST, ! 87: OID_GEN_HARDWARE_STATUS, ! 88: OID_GEN_MEDIA_SUPPORTED, ! 89: OID_GEN_MEDIA_IN_USE, ! 90: OID_GEN_MAXIMUM_LOOKAHEAD, ! 91: OID_GEN_MAXIMUM_FRAME_SIZE, ! 92: OID_GEN_MAXIMUM_TOTAL_SIZE, ! 93: OID_GEN_MAC_OPTIONS, ! 94: OID_GEN_PROTOCOL_OPTIONS, ! 95: OID_GEN_LINK_SPEED, ! 96: OID_GEN_TRANSMIT_BUFFER_SPACE, ! 97: OID_GEN_RECEIVE_BUFFER_SPACE, ! 98: OID_GEN_TRANSMIT_BLOCK_SIZE, ! 99: OID_GEN_RECEIVE_BLOCK_SIZE, ! 100: OID_GEN_VENDOR_ID, ! 101: OID_GEN_VENDOR_DESCRIPTION, ! 102: OID_GEN_DRIVER_VERSION, ! 103: OID_GEN_CURRENT_PACKET_FILTER, ! 104: OID_GEN_CURRENT_LOOKAHEAD, ! 105: OID_GEN_XMIT_OK, ! 106: OID_GEN_RCV_OK, ! 107: OID_GEN_XMIT_ERROR, ! 108: OID_GEN_RCV_ERROR, ! 109: OID_GEN_RCV_NO_BUFFER, ! 110: OID_802_5_PERMANENT_ADDRESS, ! 111: OID_802_5_CURRENT_ADDRESS, ! 112: OID_802_5_CURRENT_FUNCTIONAL, ! 113: OID_802_5_CURRENT_GROUP, ! 114: OID_802_5_LAST_OPEN_STATUS, ! 115: OID_802_5_CURRENT_RING_STATUS, ! 116: OID_802_5_CURRENT_RING_STATE, ! 117: OID_802_5_LINE_ERRORS, ! 118: OID_802_5_LOST_FRAMES ! 119: }; ! 120: ! 121: // ! 122: // If you add to this, make sure to add the ! 123: // a case in IbmtokQueryGlobalStatistics() and in ! 124: // IbmtokQueryProtocolInformation() ! 125: // ! 126: static const UINT IbmtokProtocolSupportedOids[] = { ! 127: OID_GEN_SUPPORTED_LIST, ! 128: OID_GEN_HARDWARE_STATUS, ! 129: OID_GEN_MEDIA_SUPPORTED, ! 130: OID_GEN_MEDIA_IN_USE, ! 131: OID_GEN_MAXIMUM_LOOKAHEAD, ! 132: OID_GEN_MAXIMUM_FRAME_SIZE, ! 133: OID_GEN_MAXIMUM_TOTAL_SIZE, ! 134: OID_GEN_MAC_OPTIONS, ! 135: OID_GEN_PROTOCOL_OPTIONS, ! 136: OID_GEN_LINK_SPEED, ! 137: OID_GEN_TRANSMIT_BUFFER_SPACE, ! 138: OID_GEN_RECEIVE_BUFFER_SPACE, ! 139: OID_GEN_TRANSMIT_BLOCK_SIZE, ! 140: OID_GEN_RECEIVE_BLOCK_SIZE, ! 141: OID_GEN_VENDOR_ID, ! 142: OID_GEN_VENDOR_DESCRIPTION, ! 143: OID_GEN_DRIVER_VERSION, ! 144: OID_GEN_CURRENT_PACKET_FILTER, ! 145: OID_GEN_CURRENT_LOOKAHEAD, ! 146: OID_802_5_PERMANENT_ADDRESS, ! 147: OID_802_5_CURRENT_ADDRESS, ! 148: OID_802_5_CURRENT_FUNCTIONAL, ! 149: OID_802_5_CURRENT_GROUP ! 150: }; ! 151: ! 152: ! 153: // ! 154: // On a development build, don't define functions as static ! 155: // so we can set breakpoints on them. ! 156: // ! 157: ! 158: #if DEVL ! 159: #define STATIC ! 160: #else ! 161: #define STATIC static ! 162: #endif ! 163: ! 164: #if DBG ! 165: INT IbmtokDbg = 0; ! 166: #define LOG 1 ! 167: #else ! 168: #define LOG 0 ! 169: #endif ! 170: ! 171: ! 172: // ! 173: // Get from configuration file. ! 174: // ! 175: ! 176: #define MAX_MULTICAST_ADDRESS ((UINT)16) ! 177: #define MAX_ADAPTERS ((UINT)4) ! 178: ! 179: ! 180: // ! 181: // This macro determines if the directed address ! 182: // filtering in the CAM is actually necessary given ! 183: // the current filter. ! 184: // ! 185: #define CAM_DIRECTED_SIGNIFICANT(_Filter) \ ! 186: ((((_Filter) & NDIS_PACKET_TYPE_DIRECTED) && \ ! 187: (!((_Filter) & NDIS_PACKET_TYPE_PROMISCUOUS))) ? 1 : 0) ! 188: ! 189: ! 190: // ! 191: // This macro determines if the multicast filtering in ! 192: // the CAM are actually necessary given the current filter. ! 193: // ! 194: #define CAM_MULTICAST_SIGNIFICANT(_Filter) \ ! 195: ((((_Filter) & NDIS_PACKET_TYPE_MULTICAST) && \ ! 196: (!((_Filter) & (NDIS_PACKET_TYPE_ALL_MULTICAST | \ ! 197: NDIS_PACKET_TYPE_PROMISCUOUS)))) ? 1 : 0) ! 198: ! 199: ! 200: STATIC ! 201: NDIS_STATUS ! 202: IbmtokOpenAdapter( ! 203: OUT PNDIS_STATUS OpenErrorStatus, ! 204: OUT NDIS_HANDLE *MacBindingHandle, ! 205: OUT PUINT SelectedMediumIndex, ! 206: IN PNDIS_MEDIUM MediumArray, ! 207: IN UINT MediumArraySize, ! 208: IN NDIS_HANDLE NdisBindingContext, ! 209: IN NDIS_HANDLE MacAdapterContext, ! 210: IN UINT OpenOptions, ! 211: IN PSTRING AddressingInformation OPTIONAL ! 212: ); ! 213: ! 214: STATIC ! 215: NDIS_STATUS ! 216: IbmtokCloseAdapter( ! 217: IN NDIS_HANDLE MacBindingHandle ! 218: ); ! 219: ! 220: ! 221: STATIC ! 222: NDIS_STATUS ! 223: IbmtokRequest( ! 224: IN NDIS_HANDLE MacBindingHandle, ! 225: IN PNDIS_REQUEST NdisRequest ! 226: ); ! 227: ! 228: STATIC ! 229: NDIS_STATUS ! 230: IbmtokQueryInformation( ! 231: IN PIBMTOK_ADAPTER Adapter, ! 232: IN PIBMTOK_OPEN Open, ! 233: IN PNDIS_REQUEST NdisRequest ! 234: ); ! 235: ! 236: ! 237: STATIC ! 238: NDIS_STATUS ! 239: IbmtokSetInformation( ! 240: IN PIBMTOK_ADAPTER Adapter, ! 241: IN PIBMTOK_OPEN Open, ! 242: IN PNDIS_REQUEST NdisRequest ! 243: ); ! 244: ! 245: STATIC ! 246: NDIS_STATUS ! 247: IbmtokQueryGlobalStatistics( ! 248: IN NDIS_HANDLE MacAdapterContext, ! 249: IN PNDIS_REQUEST NdisRequest ! 250: ); ! 251: ! 252: NDIS_STATUS ! 253: IbmtokAddAdapter( ! 254: IN NDIS_HANDLE MacMacContext, ! 255: IN NDIS_HANDLE ConfigurationHandle, ! 256: IN PNDIS_STRING AdaptName ! 257: ); ! 258: ! 259: VOID ! 260: IbmtokRemoveAdapter( ! 261: IN PVOID MacAdapterContext ! 262: ); ! 263: ! 264: STATIC ! 265: NDIS_STATUS ! 266: IbmtokSetPacketFilter( ! 267: IN PIBMTOK_ADAPTER Adapter, ! 268: IN PIBMTOK_OPEN Open, ! 269: IN PNDIS_REQUEST NdisRequest, ! 270: IN UINT PacketFilter ! 271: ); ! 272: ! 273: STATIC ! 274: NDIS_STATUS ! 275: IbmtokSetGroupAddress( ! 276: IN PIBMTOK_ADAPTER Adapter, ! 277: IN PIBMTOK_OPEN Open, ! 278: IN PNDIS_REQUEST NdisRequest, ! 279: IN PUCHAR Address ! 280: ); ! 281: ! 282: STATIC ! 283: NDIS_STATUS ! 284: IbmtokChangeFunctionalAddress( ! 285: IN PIBMTOK_ADAPTER Adapter, ! 286: IN PIBMTOK_OPEN Open, ! 287: IN PNDIS_REQUEST NdisRequest, ! 288: IN PUCHAR Address ! 289: ); ! 290: ! 291: STATIC ! 292: NDIS_STATUS ! 293: IbmtokReset( ! 294: IN NDIS_HANDLE MacBindingHandle ! 295: ); ! 296: ! 297: STATIC ! 298: NDIS_STATUS ! 299: IbmtokTest( ! 300: IN NDIS_HANDLE MacBindingHandle ! 301: ); ! 302: ! 303: STATIC ! 304: NDIS_STATUS ! 305: IbmtokChangeFilter( ! 306: IN UINT OldFilterClasses, ! 307: IN UINT NewFilterClasses, ! 308: IN NDIS_HANDLE MacBindingHandle, ! 309: IN PNDIS_REQUEST NdisRequest, ! 310: IN BOOLEAN Set ! 311: ); ! 312: ! 313: STATIC ! 314: NDIS_STATUS ! 315: IbmtokChangeAddress( ! 316: IN TR_FUNCTIONAL_ADDRESS OldFunctionalAddress, ! 317: IN TR_FUNCTIONAL_ADDRESS NewFunctionalAddress, ! 318: IN NDIS_HANDLE MacBindingHandle, ! 319: IN PNDIS_REQUEST NdisRequest, ! 320: IN BOOLEAN Set ! 321: ); ! 322: ! 323: STATIC ! 324: NDIS_STATUS ! 325: IbmtokChangeGroupAddress( ! 326: IN TR_FUNCTIONAL_ADDRESS OldGroupAddress, ! 327: IN TR_FUNCTIONAL_ADDRESS NewGroupAddress, ! 328: IN NDIS_HANDLE MacBindingHandle, ! 329: IN PNDIS_REQUEST NdisRequest, ! 330: IN BOOLEAN Set ! 331: ); ! 332: ! 333: STATIC ! 334: BOOLEAN ! 335: IbmtokHardwareDetails( ! 336: IN PIBMTOK_ADAPTER Adapter ! 337: ); ! 338: ! 339: STATIC ! 340: NDIS_STATUS ! 341: IbmtokRegisterAdapter( ! 342: IN PIBMTOK_ADAPTER Adapter, ! 343: IN NDIS_HANDLE ConfigurationHandle, ! 344: IN PNDIS_STRING DeviceName, ! 345: IN BOOLEAN McaCard, ! 346: IN BOOLEAN ConfigError ! 347: ); ! 348: ! 349: STATIC ! 350: VOID ! 351: SetInitializeVariables( ! 352: IN PIBMTOK_ADAPTER Adapter ! 353: ); ! 354: ! 355: VOID ! 356: SetResetVariables( ! 357: IN PIBMTOK_ADAPTER Adapter ! 358: ); ! 359: ! 360: extern ! 361: VOID ! 362: IbmtokStartAdapterReset( ! 363: IN PIBMTOK_ADAPTER Adapter ! 364: ); ! 365: ! 366: STATIC ! 367: VOID ! 368: IbmtokCloseAction( ! 369: IN NDIS_HANDLE MacBindingHandle ! 370: ); ! 371: ! 372: STATIC ! 373: VOID ! 374: IbmtokSetupRegistersAndInit( ! 375: IN PIBMTOK_ADAPTER Adapter ! 376: ); ! 377: ! 378: STATIC ! 379: NDIS_STATUS ! 380: IbmtokInitialInit( ! 381: IN PIBMTOK_ADAPTER Adapter ! 382: ); ! 383: ! 384: VOID ! 385: IbmtokUnload( ! 386: IN NDIS_HANDLE MacMacContext ! 387: ); ! 388: ! 389: ! 390: NTSTATUS ! 391: DriverEntry( ! 392: IN PDRIVER_OBJECT DriverObject, ! 393: IN PUNICODE_STRING RegistryPath ! 394: ) ! 395: /*++ ! 396: ! 397: Routine Description: ! 398: ! 399: This is the primary initialization routine for the ibmtok driver. ! 400: It is simply responsible for the intializing the wrapper and registering ! 401: the MAC. It then calls a system and architecture specific routine that ! 402: will initialize and register each adapter. ! 403: ! 404: Arguments: ! 405: ! 406: DriverObject - Pointer to driver object created by the system. ! 407: ! 408: Return Value: ! 409: ! 410: The status of the operation. ! 411: ! 412: --*/ ! 413: ! 414: { ! 415: ! 416: ! 417: // ! 418: // Receives the status of the NdisRegisterMac operation. ! 419: // ! 420: NDIS_STATUS InitStatus; ! 421: PIBMTOK_MAC IbmtokMac; ! 422: NDIS_HANDLE NdisWrapperHandle; ! 423: char Tmp[sizeof(NDIS_MAC_CHARACTERISTICS)]; ! 424: PNDIS_MAC_CHARACTERISTICS IbmtokChar = (PNDIS_MAC_CHARACTERISTICS)(PVOID)Tmp; ! 425: NDIS_STRING MacName = NDIS_STRING_CONST("IbmTok"); ! 426: ! 427: // ! 428: // Initialize the wrapper. ! 429: // ! 430: ! 431: NdisInitializeWrapper( ! 432: &NdisWrapperHandle, ! 433: DriverObject, ! 434: RegistryPath, ! 435: NULL ! 436: ); ! 437: ! 438: // ! 439: // Now allocate memory for our global structure. ! 440: // ! 441: ! 442: InitStatus = IBMTOK_ALLOC_PHYS(&IbmtokMac, sizeof(IBMTOK_MAC)); ! 443: ! 444: if (InitStatus != NDIS_STATUS_SUCCESS) { ! 445: ! 446: return NDIS_STATUS_RESOURCES; ! 447: ! 448: } ! 449: ! 450: IbmtokMac->NdisWrapperHandle = NdisWrapperHandle; ! 451: ! 452: // ! 453: // Initialize the MAC characteristics for the call to ! 454: // NdisRegisterMac. ! 455: // ! 456: ! 457: ! 458: IbmtokChar->MajorNdisVersion = IBMTOK_NDIS_MAJOR_VERSION; ! 459: IbmtokChar->MinorNdisVersion = IBMTOK_NDIS_MINOR_VERSION; ! 460: IbmtokChar->OpenAdapterHandler = (OPEN_ADAPTER_HANDLER) IbmtokOpenAdapter; ! 461: IbmtokChar->CloseAdapterHandler = (CLOSE_ADAPTER_HANDLER) IbmtokCloseAdapter; ! 462: IbmtokChar->RequestHandler = IbmtokRequest; ! 463: IbmtokChar->SendHandler = IbmtokSend; ! 464: IbmtokChar->TransferDataHandler = IbmtokTransferData; ! 465: IbmtokChar->ResetHandler = IbmtokReset; ! 466: IbmtokChar->UnloadMacHandler = IbmtokUnload; ! 467: IbmtokChar->QueryGlobalStatisticsHandler = IbmtokQueryGlobalStatistics; ! 468: IbmtokChar->AddAdapterHandler = IbmtokAddAdapter; ! 469: IbmtokChar->RemoveAdapterHandler = IbmtokRemoveAdapter; ! 470: ! 471: IbmtokChar->Name = MacName; ! 472: ! 473: NdisRegisterMac( ! 474: &InitStatus, ! 475: &IbmtokMac->NdisMacHandle, ! 476: NdisWrapperHandle, ! 477: (PVOID)IbmtokMac, ! 478: IbmtokChar, ! 479: sizeof(*IbmtokChar) ! 480: ); ! 481: ! 482: if (InitStatus != NDIS_STATUS_SUCCESS) { ! 483: ! 484: NdisTerminateWrapper(NdisWrapperHandle, NULL); ! 485: ! 486: return NDIS_STATUS_FAILURE; ! 487: ! 488: } ! 489: ! 490: return NDIS_STATUS_SUCCESS; ! 491: ! 492: } ! 493: ! 494: ! 495: STATIC ! 496: NDIS_STATUS ! 497: IbmtokRegisterAdapter( ! 498: IN PIBMTOK_ADAPTER Adapter, ! 499: IN NDIS_HANDLE ConfigurationHandle, ! 500: IN PNDIS_STRING DeviceName, ! 501: IN BOOLEAN McaCard, ! 502: IN BOOLEAN ConfigError ! 503: ) ! 504: ! 505: /*++ ! 506: ! 507: Routine Description: ! 508: ! 509: This routine (and its interface) are not portable. They are ! 510: defined by the OS, the architecture, and the particular IBMTOK ! 511: implementation. ! 512: ! 513: This routine is responsible for the allocation of the datastructures ! 514: for the driver as well as any hardware specific details necessary ! 515: to talk with the device. ! 516: ! 517: Arguments: ! 518: ! 519: Adapter - Pointer to the adapter block. ! 520: ! 521: ConfigurationHandle - Handle passed to MacAddAdapter, to be passed to ! 522: NdisRegisterAdapter. ! 523: ! 524: DeviceName - Name of this adapter. ! 525: ! 526: McaCard - This is an MCA bus. ! 527: ! 528: ConfigError - TRUE if a configuration error was found earlier. ! 529: ! 530: Return Value: ! 531: ! 532: Returns NDIS_STATUS_SUCCESS if everything goes ok, else ! 533: if anything occurred that prevents the initialization ! 534: of the adapter it returns an appropriate NDIS error. ! 535: ! 536: --*/ ! 537: ! 538: { ! 539: ! 540: NDIS_STATUS Status; ! 541: ! 542: // ! 543: // Holds information needed when registering the adapter. ! 544: // ! 545: ! 546: NDIS_ADAPTER_INFORMATION AdapterInformation; ! 547: ! 548: // We put in this assertion to make sure that ushort are 2 bytes. ! 549: // if they aren't then the initialization block definition needs ! 550: // to be changed. ! 551: // ! 552: // Also all of the logic that deals with status registers assumes ! 553: // that control registers are only 2 bytes. ! 554: // ! 555: ! 556: ASSERT(sizeof(USHORT) == 2); ! 557: ! 558: // ! 559: // Get the interrupt number and MMIO address. ! 560: // ! 561: ! 562: // ! 563: // Set the adapter state. ! 564: // ! 565: ! 566: SetInitializeVariables(Adapter); ! 567: ! 568: SetResetVariables(Adapter); ! 569: ! 570: // ! 571: // Set up the AdapterInformation structure; zero it ! 572: // first in case it is extended later. ! 573: // ! 574: ! 575: IBMTOK_ZERO_MEMORY (&AdapterInformation, sizeof(NDIS_ADAPTER_INFORMATION)); ! 576: AdapterInformation.AdapterType = (McaCard ? NdisInterfaceMca : NdisInterfaceIsa); ! 577: AdapterInformation.NumberOfPortDescriptors = 1; ! 578: AdapterInformation.PortDescriptors[0].InitialPort = Adapter->IbmtokPortAddress; ! 579: AdapterInformation.PortDescriptors[0].NumberOfPorts = 4; ! 580: ! 581: // ! 582: // Register the adapter with Ndis. ! 583: // ! 584: ! 585: Status = NdisRegisterAdapter( ! 586: &Adapter->NdisAdapterHandle, ! 587: Adapter->NdisMacHandle, ! 588: Adapter, ! 589: ConfigurationHandle, ! 590: DeviceName, ! 591: &AdapterInformation ! 592: ); ! 593: ! 594: if (Status != NDIS_STATUS_SUCCESS) { ! 595: ! 596: return(Status); ! 597: ! 598: } ! 599: ! 600: if (ConfigError) { ! 601: ! 602: // ! 603: // Error and quit ! 604: // ! 605: ! 606: NdisWriteErrorLogEntry( ! 607: Adapter->NdisAdapterHandle, ! 608: NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION, ! 609: 0 ! 610: ); ! 611: ! 612: NdisDeregisterAdapter(Adapter->NdisAdapterHandle); ! 613: ! 614: return(NDIS_STATUS_FAILURE); ! 615: ! 616: } ! 617: ! 618: ! 619: ! 620: if (!IbmtokHardwareDetails(Adapter)) { ! 621: ! 622: NdisDeregisterAdapter(Adapter->NdisAdapterHandle); ! 623: return NDIS_STATUS_ADAPTER_NOT_FOUND; ! 624: ! 625: } ! 626: ! 627: ! 628: // ! 629: // Reset the card to put it in a valid state. ! 630: // ! 631: ! 632: if (Adapter->SharedRamPaging) { ! 633: ! 634: WRITE_ADAPTER_REGISTER(Adapter, SRPR_LOW, 0xc0); ! 635: ! 636: } ! 637: ! 638: // ! 639: // OK, do the reset as detailed in the Tech Ref... ! 640: // ! 641: ! 642: WRITE_ADAPTER_PORT(Adapter, RESET_LATCH, 0); ! 643: ! 644: NdisStallExecution(50000); ! 645: ! 646: WRITE_ADAPTER_PORT(Adapter, RESET_RELEASE, 0); ! 647: ! 648: // ! 649: // Initialize the interrupt. ! 650: // ! 651: ! 652: NdisAllocateSpinLock(&Adapter->InterruptLock); ! 653: ! 654: NdisInitializeInterrupt( ! 655: &Status, ! 656: &Adapter->Interrupt, ! 657: Adapter->NdisAdapterHandle, ! 658: IbmtokISR, ! 659: Adapter, ! 660: IbmtokDPC, ! 661: Adapter->InterruptLevel, ! 662: Adapter->InterruptLevel, ! 663: FALSE, ! 664: (Adapter->UsingPcIoBus)?NdisInterruptLatched: ! 665: NdisInterruptLevelSensitive ! 666: ); ! 667: ! 668: if (Status == NDIS_STATUS_SUCCESS){ ! 669: ! 670: // ! 671: // Set up the Adapter variables. (We have to do the ! 672: // initial init to get the network address before we ! 673: // create the filter DB.) ! 674: // ! 675: if (IbmtokInitialInit(Adapter) != NDIS_STATUS_SUCCESS) { ! 676: ! 677: NdisWriteErrorLogEntry( ! 678: Adapter->NdisAdapterHandle, ! 679: NDIS_ERROR_CODE_ADAPTER_NOT_FOUND, ! 680: 2, ! 681: registerAdapter, ! 682: IBMTOK_ERRMSG_NOT_FOUND ! 683: ); ! 684: ! 685: NdisRemoveInterrupt(&Adapter->Interrupt); ! 686: ! 687: NdisDeregisterAdapter(Adapter->NdisAdapterHandle); ! 688: NdisFreeSpinLock(&(Adapter->Lock)); ! 689: return NDIS_STATUS_ADAPTER_NOT_FOUND; ! 690: ! 691: } else { ! 692: ! 693: if (!TrCreateFilter( ! 694: IbmtokChangeAddress, ! 695: IbmtokChangeGroupAddress, ! 696: IbmtokChangeFilter, ! 697: IbmtokCloseAction, ! 698: Adapter->NetworkAddress, ! 699: &Adapter->Lock, ! 700: &Adapter->FilterDB ! 701: )) { ! 702: ! 703: NdisWriteErrorLogEntry( ! 704: Adapter->NdisAdapterHandle, ! 705: NDIS_ERROR_CODE_OUT_OF_RESOURCES, ! 706: 2, ! 707: registerAdapter, ! 708: IBMTOK_ERRMSG_CREATE_DB ! 709: ); ! 710: ! 711: NdisRemoveInterrupt(&Adapter->Interrupt); ! 712: NdisDeregisterAdapter(Adapter->NdisAdapterHandle); ! 713: NdisFreeSpinLock(&(Adapter->Lock)); ! 714: return NDIS_STATUS_RESOURCES; ! 715: ! 716: } else { ! 717: ! 718: // ! 719: // Initialize the wake up timer to catch interrupts that ! 720: // don't complete. It fires continuously ! 721: // every thirty seconds, and we check if there are any ! 722: // uncompleted operations from the previous two-second ! 723: // period. ! 724: // ! 725: ! 726: Adapter->WakeUpDpc = (PVOID)IbmtokWakeUpDpc; ! 727: ! 728: NdisInitializeTimer(&Adapter->WakeUpTimer, ! 729: (PVOID)(Adapter->WakeUpDpc), ! 730: Adapter ); ! 731: ! 732: NdisSetTimer( ! 733: &Adapter->WakeUpTimer, ! 734: 30000 ! 735: ); ! 736: ! 737: return(NDIS_STATUS_SUCCESS); ! 738: ! 739: } ! 740: ! 741: } ! 742: ! 743: } else { ! 744: ! 745: NdisWriteErrorLogEntry( ! 746: Adapter->NdisAdapterHandle, ! 747: NDIS_ERROR_CODE_INTERRUPT_CONNECT, ! 748: 2, ! 749: registerAdapter, ! 750: IBMTOK_ERRMSG_INIT_INTERRUPT ! 751: ); ! 752: ! 753: NdisDeregisterAdapter(Adapter->NdisAdapterHandle); ! 754: NdisFreeSpinLock(&(Adapter->Lock)); ! 755: return(Status); ! 756: } ! 757: ! 758: } ! 759: ! 760: STATIC ! 761: VOID ! 762: SetInitializeVariables( ! 763: IN PIBMTOK_ADAPTER Adapter ! 764: ) ! 765: ! 766: /*++ ! 767: ! 768: Routine Description: ! 769: ! 770: This routine initializes all the variables in the Adapter ! 771: structure that should only be set during adapter initialization ! 772: (i.e. not during a reset). ! 773: ! 774: Arguments: ! 775: ! 776: Adapter - The adapter for the hardware. ! 777: ! 778: Return Value: ! 779: ! 780: None. ! 781: ! 782: --*/ ! 783: ! 784: { ! 785: InitializeListHead(&Adapter->OpenBindings); ! 786: InitializeListHead(&Adapter->CloseList); ! 787: InitializeListHead(&Adapter->CloseDuringResetList); ! 788: ! 789: NdisAllocateSpinLock(&Adapter->Lock); ! 790: ! 791: // ! 792: // If this is not true, then uncomment below ! 793: // ! 794: ! 795: ASSERT(FALSE == (BOOLEAN)0); ! 796: ! 797: // Adapter->HandleSrbRunning = FALSE; ! 798: // Adapter->HandleArbRunning = FALSE; ! 799: ! 800: // Adapter->OpenInProgress = FALSE; ! 801: ! 802: Adapter->AdapterNotOpen = TRUE; ! 803: Adapter->NotAcceptingRequests = TRUE; ! 804: ! 805: // Adapter->ResetInProgress = FALSE; ! 806: // Adapter->ResettingOpen = NULL; ! 807: // Adapter->ResetInterruptAllowed = FALSE; ! 808: // Adapter->ResetInterruptHasArrived = FALSE; ! 809: ! 810: // Adapter->BringUp = FALSE; ! 811: ! 812: // ! 813: // Note: These assume that the SAP info will not ! 814: // take up more than 218 bytes. This is ok, for now, since ! 815: // we open the card with 0 SAPs allowed. ! 816: // ! 817: ! 818: Adapter->ReceiveBufferLength = 256; ! 819: Adapter->NumberOfTransmitBuffers = 1; ! 820: ! 821: // ! 822: // Note: The following fields are set in the interrupt handler after ! 823: // the card tells us if the ring is 16 or 4 Mbps. ! 824: // ! 825: // ! 826: // TransmitBufferLength ! 827: // NumberOfReceiveBuffers ! 828: // MaximumTransmittablePacket ! 829: // ! 830: ! 831: // Adapter->IsrpDeferredBits = 0; ! 832: ! 833: Adapter->FirstInitialization = TRUE; ! 834: ! 835: // Adapter->OutstandingAsbFreeRequest = FALSE; ! 836: } ! 837: ! 838: VOID ! 839: SetResetVariables( ! 840: IN PIBMTOK_ADAPTER Adapter ! 841: ) ! 842: ! 843: /*++ ! 844: ! 845: Routine Description: ! 846: ! 847: This routine initializes all the variables in the Adapter ! 848: structure that are set both during an initialization and ! 849: after a reset. ! 850: ! 851: Arguments: ! 852: ! 853: Adapter - The adapter for the hardware. ! 854: ! 855: Return Value: ! 856: ! 857: None. ! 858: ! 859: --*/ ! 860: ! 861: { ! 862: Adapter->FirstTransmit = NULL; ! 863: Adapter->LastTransmit = NULL; ! 864: Adapter->FirstWaitingForAsb = NULL; ! 865: Adapter->LastWaitingForAsb = NULL; ! 866: Adapter->TransmittingPacket = NULL; ! 867: ! 868: IBMTOK_ZERO_MEMORY(Adapter->CorrelatorArray, ! 869: sizeof(PNDIS_PACKET) * MAX_COMMAND_CORRELATOR); ! 870: ! 871: Adapter->PendQueue = NULL; ! 872: Adapter->EndOfPendQueue = NULL; ! 873: ! 874: Adapter->SrbAvailable = TRUE; ! 875: Adapter->AsbAvailable = TRUE; ! 876: ! 877: Adapter->IsrpBits = 0; ! 878: Adapter->IsrpLowBits = 0; ! 879: ! 880: Adapter->NextCorrelatorToComplete = 0; ! 881: Adapter->ReceiveWaitingForAsbList = (USHORT)-1; ! 882: Adapter->ReceiveWaitingForAsbEnd = (USHORT)-1; ! 883: Adapter->UseNextAsbForReceive = TRUE; ! 884: } ! 885: ! 886: extern ! 887: NDIS_STATUS ! 888: IbmtokInitialInit( ! 889: IN PIBMTOK_ADAPTER Adapter ! 890: ) ! 891: ! 892: /*++ ! 893: ! 894: Routine Description: ! 895: ! 896: This routine sets up the initial init of the driver. ! 897: ! 898: Arguments: ! 899: ! 900: Adapter - The adapter for the hardware. ! 901: ! 902: Return Value: ! 903: ! 904: None. ! 905: ! 906: --*/ ! 907: ! 908: { ! 909: USHORT RegValue; ! 910: UINT Time = 50; // Number of 100 milliseconds to delay while waiting ! 911: // for the card to initialize. ! 912: ! 913: IbmtokSetupRegistersAndInit(Adapter); ! 914: ! 915: // ! 916: // Delay execution for 5 seconds to give the ring ! 917: // time to initialize. ! 918: // ! 919: ! 920: while((!Adapter->BringUp) && (Time != 0)){ ! 921: ! 922: NdisStallExecution(100000); ! 923: ! 924: Time--; ! 925: ! 926: } ! 927: ! 928: if (!Adapter->BringUp){ ! 929: ! 930: return(NDIS_STATUS_ADAPTER_NOT_FOUND); ! 931: ! 932: } else { ! 933: ! 934: // ! 935: // Do remaining initialization. ! 936: // ! 937: ! 938: USHORT WrbOffset; ! 939: PSRB_BRING_UP_RESULT BringUpSrb; ! 940: PUCHAR EncodedAddress; ! 941: UCHAR Value1, Value2; ! 942: ! 943: READ_ADAPTER_REGISTER(Adapter, WRBR_LOW, &Value1); ! 944: READ_ADAPTER_REGISTER(Adapter, WRBR_HIGH, &Value2); ! 945: ! 946: WrbOffset = (((USHORT)Value1) << 8) + (USHORT)Value2; ! 947: ! 948: Adapter->InitialWrbOffset = WrbOffset; ! 949: ! 950: #if DBG ! 951: if (IbmtokDbg) { ! 952: ! 953: DbgPrint("IBMTOK: Initial Offset = 0x%x\n", WrbOffset); ! 954: ! 955: } ! 956: #endif ! 957: ! 958: BringUpSrb = (PSRB_BRING_UP_RESULT) ! 959: (Adapter->SharedRam + WrbOffset); ! 960: ! 961: NdisReadRegisterUshort(&(BringUpSrb->ReturnCode), &RegValue); ! 962: ! 963: if (RegValue != 0x0000) { ! 964: ! 965: if (RegValue == 0x30){ ! 966: ! 967: NdisWriteErrorLogEntry( ! 968: Adapter->NdisAdapterHandle, ! 969: NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION, ! 970: 0x32, ! 971: handleSrbSsb, ! 972: IBMTOK_ERRMSG_BRINGUP_FAILURE ! 973: ); ! 974: ! 975: ! 976: return(NDIS_STATUS_ADAPTER_NOT_FOUND); ! 977: ! 978: } else { ! 979: ! 980: NdisWriteErrorLogEntry( ! 981: Adapter->NdisAdapterHandle, ! 982: NDIS_ERROR_CODE_HARDWARE_FAILURE, ! 983: 3, ! 984: handleSrbSsb, ! 985: IBMTOK_ERRMSG_BRINGUP_FAILURE, ! 986: (ULONG)RegValue ! 987: ); ! 988: ! 989: return(NDIS_STATUS_ADAPTER_NOT_FOUND); ! 990: ! 991: ! 992: } ! 993: ! 994: } else { ! 995: ! 996: Adapter->FirstInitialization = FALSE; ! 997: Adapter->BringUp = TRUE; ! 998: ! 999: } ! 1000: ! 1001: NdisReadRegisterUchar(&(BringUpSrb->InitStatus), &RegValue); ! 1002: ! 1003: if (RegValue & 0x01) { ! 1004: ! 1005: #if DBG ! 1006: if (IbmtokDbg) DbgPrint("IBMTOK: 16 Mbps\n"); ! 1007: #endif ! 1008: ! 1009: Adapter->Running16Mbps = TRUE; ! 1010: ! 1011: } else { ! 1012: ! 1013: Adapter->Running16Mbps = FALSE; ! 1014: ! 1015: } ! 1016: ! 1017: // ! 1018: // ZZZ: This code assumes that there is no shared ram paging and ! 1019: // that the MappedSharedRam is all that is available. ! 1020: // ! 1021: ! 1022: ! 1023: #if DBG ! 1024: if (IbmtokDbg) DbgPrint( "IBMTOK: shared RAM size is %x (%d)\n", Adapter->MappedSharedRam, Adapter->MappedSharedRam ); ! 1025: #endif ! 1026: if (Adapter->MappedSharedRam > 0x2000){ ! 1027: ! 1028: ULONG RamAvailable; ! 1029: UCHAR NumTransmitBuffers = (UCHAR)Adapter->NumberOfTransmitBuffers; ! 1030: ! 1031: // ! 1032: // 2096 is the amount of shared ram that is current sucked ! 1033: // up by the areas found on page 7-27 of the Tech. Ref. ! 1034: // ! 1035: // ! 1036: ! 1037: RamAvailable = Adapter->MappedSharedRam; ! 1038: ! 1039: if (Adapter->MappedSharedRam == 0x10000){ ! 1040: ! 1041: // ! 1042: // Subtract an extra 8K to account for when we map ! 1043: // MMIO space to the top 8K of RAM. ! 1044: // ! 1045: ! 1046: RamAvailable = RamAvailable - 2096 - 0x2000; ! 1047: ! 1048: } else { ! 1049: ! 1050: RamAvailable = RamAvailable - 1584; ! 1051: ! 1052: } ! 1053: #if DBG ! 1054: if (IbmtokDbg) DbgPrint( "IBMTOK: RAM available is %x (%d)\n", RamAvailable, RamAvailable ); ! 1055: #endif ! 1056: ! 1057: // ! 1058: // The card has more than 8K of ram, so adjust ! 1059: // transmit buffer size to abuse this. ! 1060: // ! 1061: ! 1062: if (Adapter->Running16Mbps) { ! 1063: ! 1064: // ! 1065: // Use the maximum allowed ! 1066: // ! 1067: ! 1068: Adapter->TransmitBufferLength = Adapter->Max16MbpsDhb; ! 1069: #if DBG ! 1070: if (IbmtokDbg) DbgPrint( "IBMTOK: 16 MB ring. Transmit buffer length is %x (%d)\n", Adapter->TransmitBufferLength, Adapter->TransmitBufferLength ); ! 1071: #endif ! 1072: ! 1073: } else { ! 1074: ! 1075: // ! 1076: // Use the maximum allowed ! 1077: // ! 1078: Adapter->TransmitBufferLength = Adapter->Max4MbpsDhb; ! 1079: #if DBG ! 1080: if (IbmtokDbg) DbgPrint( "IBMTOK: 4 MB ring. Transmit buffer length is %x (%d)\n", Adapter->TransmitBufferLength, Adapter->TransmitBufferLength ); ! 1081: #endif ! 1082: ! 1083: } ! 1084: ! 1085: // ! 1086: // First we subtract off buffer space for receiving the ! 1087: // maximum sized packet that can be on the wire. This is ! 1088: // the *minimum* number of receive buffers and may be ! 1089: // modified below if the transmit space does not take up ! 1090: // the rest. ! 1091: // ! 1092: ! 1093: #if DBG ! 1094: if (IbmtokDbg) DbgPrint( "IBMTOK: Receive buffer length is %x (%d)\n", Adapter->ReceiveBufferLength, Adapter->ReceiveBufferLength ); ! 1095: #endif ! 1096: if (RamAvailable < Adapter->TransmitBufferLength) { ! 1097: ! 1098: // ! 1099: // There is not enough buffer space for even a single maximum ! 1100: // sized frame. So, just divide the buffer space into two ! 1101: // equally sized areas -- receive and transmit. ! 1102: // ! 1103: ! 1104: Adapter->NumberOfReceiveBuffers = (USHORT)((RamAvailable / 2) / ! 1105: Adapter->ReceiveBufferLength) ! 1106: + 1; ! 1107: #if DBG ! 1108: if (IbmtokDbg) DbgPrint( "IBMTOK: RAM too small. # receive buffers is %x (%d)\n", Adapter->NumberOfReceiveBuffers, Adapter->NumberOfReceiveBuffers ); ! 1109: #endif ! 1110: ! 1111: } else { ! 1112: ! 1113: Adapter->NumberOfReceiveBuffers = (USHORT)(Adapter->TransmitBufferLength / ! 1114: Adapter->ReceiveBufferLength) + 1; ! 1115: #if DBG ! 1116: if (IbmtokDbg) DbgPrint( "IBMTOK: RAM large enough. # receive buffers is %x (%d)\n", Adapter->NumberOfReceiveBuffers, Adapter->NumberOfReceiveBuffers ); ! 1117: #endif ! 1118: ! 1119: } ! 1120: ! 1121: RamAvailable = RamAvailable - ! 1122: (Adapter->NumberOfReceiveBuffers * Adapter->ReceiveBufferLength); ! 1123: #if DBG ! 1124: if (IbmtokDbg) { ! 1125: DbgPrint( "IBMTOK: RAM available for transmit is %x (%d)\n", RamAvailable, RamAvailable ); ! 1126: DbgPrint( "IBMTOK: # transmit buffers is %x (%d)\n", NumTransmitBuffers, NumTransmitBuffers ); ! 1127: } ! 1128: #endif ! 1129: ! 1130: if (Adapter->TransmitBufferLength > (RamAvailable / NumTransmitBuffers)) { ! 1131: ! 1132: if ((RamAvailable / NumTransmitBuffers) < 0x1000) { ! 1133: ! 1134: Adapter->TransmitBufferLength = 0x800; ! 1135: ! 1136: } else if ((RamAvailable / NumTransmitBuffers) < 0x2000) { ! 1137: ! 1138: Adapter->TransmitBufferLength = 0x1000; ! 1139: ! 1140: } else if ((RamAvailable / NumTransmitBuffers) < 0x4000) { ! 1141: ! 1142: Adapter->TransmitBufferLength = 0x2000; ! 1143: ! 1144: } else { ! 1145: ! 1146: Adapter->TransmitBufferLength = 0x4000; ! 1147: ! 1148: } ! 1149: ! 1150: #if DBG ! 1151: if (IbmtokDbg) DbgPrint( "IBMTOK: RAM too small. Transmit buffer length is %x (%d)\n", Adapter->TransmitBufferLength, Adapter->TransmitBufferLength ); ! 1152: #endif ! 1153: } ! 1154: ! 1155: ! 1156: // ! 1157: // If computed value is greater than the value that the ! 1158: // registry allows, then use the registry value. ! 1159: // ! 1160: ! 1161: #if DBG ! 1162: if (IbmtokDbg) DbgPrint( "IBMTOK: Original max transmit length is %x (%d)\n", Adapter->MaxTransmittablePacket, Adapter->MaxTransmittablePacket ); ! 1163: #endif ! 1164: if (Adapter->TransmitBufferLength > Adapter->MaxTransmittablePacket) { ! 1165: ! 1166: Adapter->TransmitBufferLength = Adapter->MaxTransmittablePacket; ! 1167: #if DBG ! 1168: if (IbmtokDbg) DbgPrint( "IBMTOK: Max too small. Transmit buffer length is %x (%d)\n", Adapter->TransmitBufferLength, Adapter->TransmitBufferLength ); ! 1169: #endif ! 1170: ! 1171: } ! 1172: ! 1173: Adapter->MaxTransmittablePacket = Adapter->TransmitBufferLength - 6; ! 1174: #if DBG ! 1175: if (IbmtokDbg) DbgPrint( "IBMTOK: New max transmit length is %x (%d)\n", Adapter->MaxTransmittablePacket, Adapter->MaxTransmittablePacket ); ! 1176: #endif ! 1177: ! 1178: // ! 1179: // Remove space taken up by transmit buffers. ! 1180: // ! 1181: ! 1182: RamAvailable = RamAvailable - ((ULONG)NumTransmitBuffers * ! 1183: (ULONG)Adapter->TransmitBufferLength); ! 1184: ! 1185: // ! 1186: // Add in any left over space for receive buffers. ! 1187: // ! 1188: ! 1189: Adapter->NumberOfReceiveBuffers += (USHORT)(RamAvailable / ! 1190: Adapter->ReceiveBufferLength); ! 1191: #if DBG ! 1192: if (IbmtokDbg) DbgPrint( "IBMTOK: New # receive buffers is %x (%d)\n", Adapter->NumberOfReceiveBuffers, Adapter->NumberOfReceiveBuffers ); ! 1193: #endif ! 1194: ! 1195: } else { ! 1196: ! 1197: Adapter->TransmitBufferLength = 0x800; ! 1198: Adapter->NumberOfTransmitBuffers = 1; ! 1199: #if DBG ! 1200: if (IbmtokDbg) { ! 1201: DbgPrint( "IBMTOK: Only 8K shared RAM. Transmit buffer length is %x (%d)\n", Adapter->TransmitBufferLength, Adapter->TransmitBufferLength ); ! 1202: DbgPrint( "IBMTOK: Transmit buffer length is %x (%d)\n", Adapter->TransmitBufferLength, Adapter->TransmitBufferLength ); ! 1203: } ! 1204: #endif ! 1205: ! 1206: // ! 1207: // There is only 8K of buffer space, which is not enough space for ! 1208: // receiving and transmitting packets on even a 4Mbit ring. So, ! 1209: // use some reasonable values for transmit and receive space. ! 1210: // ! 1211: ! 1212: // If computed value is greater than the value that the ! 1213: // registry allows, then use the registry value. ! 1214: // ! 1215: ! 1216: #if DBG ! 1217: if (IbmtokDbg) DbgPrint( "IBMTOK: Original max transmit length is %x (%d)\n", Adapter->MaxTransmittablePacket, Adapter->MaxTransmittablePacket ); ! 1218: #endif ! 1219: if (Adapter->TransmitBufferLength > Adapter->MaxTransmittablePacket) { ! 1220: ! 1221: Adapter->TransmitBufferLength = Adapter->MaxTransmittablePacket; ! 1222: #if DBG ! 1223: if (IbmtokDbg) DbgPrint( "IBMTOK: Max too small. Transmit buffer length is %x (%d)\n", Adapter->TransmitBufferLength, Adapter->TransmitBufferLength ); ! 1224: #endif ! 1225: ! 1226: } ! 1227: ! 1228: Adapter->MaxTransmittablePacket = Adapter->TransmitBufferLength - 6; ! 1229: ! 1230: Adapter->NumberOfReceiveBuffers = 15; ! 1231: #if DBG ! 1232: if (IbmtokDbg) { ! 1233: DbgPrint( "IBMTOK: New max transmit length is %x (%d)\n", Adapter->MaxTransmittablePacket, Adapter->MaxTransmittablePacket ); ! 1234: DbgPrint( "IBMTOK: # receive buffers is %x (%d)\n", Adapter->NumberOfReceiveBuffers, Adapter->NumberOfReceiveBuffers ); ! 1235: } ! 1236: #endif ! 1237: ! 1238: } ! 1239: ! 1240: #if DBG ! 1241: if (IbmtokDbg) { ! 1242: DbgPrint("IBMTOK: Space: 0x%x, # Rcv: 0x%x, TransmitSize: 0x%x\n", ! 1243: Adapter->RrrLowValue, ! 1244: Adapter->NumberOfReceiveBuffers, ! 1245: Adapter->MaxTransmittablePacket ! 1246: ); ! 1247: } ! 1248: #endif ! 1249: ! 1250: NdisReadRegisterUshort(&(BringUpSrb->EncodedAddressPointer), &RegValue); ! 1251: ! 1252: EncodedAddress = (PUCHAR) ! 1253: SRAM_PTR_TO_PVOID(Adapter,RegValue); ! 1254: ! 1255: IBMTOK_MOVE_FROM_MAPPED_MEMORY(Adapter->PermanentNetworkAddress, EncodedAddress, ! 1256: TR_LENGTH_OF_ADDRESS); ! 1257: ! 1258: ! 1259: if ((Adapter->NetworkAddress[0] == 0x00) && ! 1260: (Adapter->NetworkAddress[1] == 0x00) && ! 1261: (Adapter->NetworkAddress[2] == 0x00) && ! 1262: (Adapter->NetworkAddress[3] == 0x00) && ! 1263: (Adapter->NetworkAddress[4] == 0x00) && ! 1264: (Adapter->NetworkAddress[5] == 0x00)) { ! 1265: ! 1266: ! 1267: IBMTOK_MOVE_FROM_MAPPED_MEMORY(Adapter->NetworkAddress, EncodedAddress, ! 1268: TR_LENGTH_OF_ADDRESS); ! 1269: } ! 1270: ! 1271: // ! 1272: // If required, we have to zero the upper section ! 1273: // of the Shared RAM now. ! 1274: // ! 1275: // ! 1276: // THIS DOESN'T WORK! It hangs the system while ! 1277: // zeroing the first address. (One gets an infinite number of ! 1278: // hardware interrupts w/o any reason) ! 1279: // ! 1280: ! 1281: #if 0 ! 1282: if (Adapter->UpperSharedRamZero) { ! 1283: ! 1284: PUCHAR ZeroPointer; ! 1285: UINT i; ! 1286: PUCHAR OldSharedRam; ! 1287: NDIS_PHYSICAL_ADDRESS PhysicalAddress; ! 1288: ! 1289: #if DBG ! 1290: if (IbmtokDbg) DbgPrint("IBMTOK: Zeroing Memory\n"); ! 1291: #endif ! 1292: ! 1293: ! 1294: if (Adapter->MappedSharedRam < 0x10000) { ! 1295: ! 1296: // ! 1297: // This portion of memory is not currently mapped, so do it. ! 1298: // ! 1299: ! 1300: OldSharedRam = Adapter->SharedRam; ! 1301: ! 1302: NdisSetPhysicalAddressHigh(PhysicalAddress, 0); ! 1303: NdisSetPhysicalAddressLow(PhysicalAddress, (Adapter->RrrLowValue << 12) + (0x10000 - 512)); ! 1304: ! 1305: NdisMapIoSpace( ! 1306: &Status, ! 1307: &(Adapter->SharedRam), ! 1308: Adapter->NdisAdapterHandle, ! 1309: PhysicalAddress, ! 1310: 512); ! 1311: ! 1312: if (Status != NDIS_STATUS_SUCCESS) { ! 1313: ! 1314: NdisWriteErrorLogEntry( ! 1315: Adapter->NdisAdapterHandle, ! 1316: NDIS_ERROR_CODE_RESOURCE_CONFLICT, ! 1317: 0 ! 1318: ); ! 1319: ! 1320: return(Status); ! 1321: ! 1322: } ! 1323: ! 1324: } ! 1325: ! 1326: if (Adapter->SharedRamPaging){ ! 1327: ! 1328: SETUP_SRPR(Adapter, SHARED_RAM_ZERO_OFFSET); ! 1329: ! 1330: #if DBG ! 1331: if (IbmtokDbg) DbgPrint("IBMTOK: Shared RAM paging enabled\n"); ! 1332: #endif ! 1333: ! 1334: ZeroPointer = ! 1335: SHARED_RAM_ADDRESS(Adapter, ! 1336: SHARED_RAM_LOW_BITS(SHARED_RAM_ZERO_OFFSET)); ! 1337: ! 1338: } else { ! 1339: ! 1340: if (Adapter->MappedSharedRam < 0x10000) { ! 1341: ! 1342: // ! 1343: // No offset for this portion, since we just mapped it. ! 1344: // ! 1345: // ! 1346: ! 1347: ZeroPointer = SHARED_RAM_ADDRESS(Adapter, 0); ! 1348: ! 1349: } else { ! 1350: ! 1351: ZeroPointer = ! 1352: SHARED_RAM_ADDRESS(Adapter, SHARED_RAM_ZERO_OFFSET); ! 1353: ! 1354: } ! 1355: ! 1356: } ! 1357: ! 1358: for (i=0; i<SHARED_RAM_ZERO_LENGTH; i++) { ! 1359: ! 1360: NdisWriteRegisterUchar(&(ZeroPointer[i]), 0x00); ! 1361: ! 1362: } ! 1363: ! 1364: if (Adapter->MappedSharedRam < 0x10000) { ! 1365: ! 1366: // ! 1367: // Unmap it ! 1368: // ! 1369: ! 1370: NdisUnmapIoSpace(Adapter->NdisAdapterHandle, ! 1371: Adapter->SharedRam, ! 1372: 512); ! 1373: ! 1374: Adapter->SharedRam = OldSharedRam; ! 1375: ! 1376: } ! 1377: ! 1378: } ! 1379: #endif ! 1380: ! 1381: ! 1382: // ! 1383: // Now set the timer to the maximum...we still need it ! 1384: // as a card heartbeat. ! 1385: // ! 1386: ! 1387: WRITE_ADAPTER_REGISTER(Adapter, TVR_HIGH, 0xff); ! 1388: ! 1389: return NDIS_STATUS_SUCCESS; ! 1390: ! 1391: } ! 1392: ! 1393: } ! 1394: ! 1395: STATIC ! 1396: NDIS_STATUS ! 1397: IbmtokOpenAdapter( ! 1398: OUT PNDIS_STATUS OpenErrorStatus, ! 1399: OUT NDIS_HANDLE *MacBindingHandle, ! 1400: OUT PUINT SelectedMediumIndex, ! 1401: IN PNDIS_MEDIUM MediumArray, ! 1402: IN UINT MediumArraySize, ! 1403: IN NDIS_HANDLE NdisBindingContext, ! 1404: IN NDIS_HANDLE MacAdapterContext, ! 1405: IN UINT OpenOptions, ! 1406: IN PSTRING AddressingInformation OPTIONAL ! 1407: ) ! 1408: ! 1409: /*++ ! 1410: ! 1411: Routine Description: ! 1412: ! 1413: OpenErrorStatus - Returns more information about the error status. In ! 1414: this card it is not used, since this code returns either success or ! 1415: pending, no failure is possible. ! 1416: ! 1417: This routine is used to create an open instance of an adapter, in effect ! 1418: creating a binding between an upper-level module and the MAC module over ! 1419: the adapter. ! 1420: ! 1421: Arguments: ! 1422: ! 1423: OpenErrorStatus - Returns more information about the error status. In ! 1424: this card it is not used, since this code returns either success or ! 1425: pending, no failure is possible. ! 1426: ! 1427: MacBindingHandle - A pointer to a location in which the MAC stores ! 1428: a context value that it uses to represent this binding. ! 1429: ! 1430: ! 1431: SelectedMediumIndex - An index into the MediumArray of the medium ! 1432: typedef that the MAC wishes to viewed as. ! 1433: ! 1434: MediumArray - An array of medium types which the protocol supports. ! 1435: ! 1436: MediumArraySize - The number of elements in MediumArray. ! 1437: ! 1438: NdisBindingContext - A value to be recorded by the MAC and passed as ! 1439: context whenever an indication is delivered by the MAC for this binding. ! 1440: ! 1441: MacAdapterContext - The value associated with the adapter that is being ! 1442: opened when the MAC registered the adapter with NdisRegisterAdapter. ! 1443: ! 1444: IN UINT OpenOptions, ! 1445: ! 1446: AddressingInformation - An optional pointer to a variable length string ! 1447: containing hardware-specific information that can be used to program the ! 1448: device. (This is not used by this MAC.) ! 1449: ! 1450: Return Value: ! 1451: ! 1452: The function value is the status of the operation. If the MAC does not ! 1453: complete this request synchronously, the value would be ! 1454: NDIS_STATUS_PENDING. ! 1455: ! 1456: ! 1457: --*/ ! 1458: ! 1459: { ! 1460: ! 1461: // ! 1462: // The IBMTOK_ADAPTER that this open binding should belong too. ! 1463: // ! 1464: PIBMTOK_ADAPTER Adapter; ! 1465: ! 1466: // ! 1467: // Holds the status that should be returned to the caller. ! 1468: // ! 1469: NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS; ! 1470: ! 1471: // ! 1472: // Pointer to the space allocated for the binding. ! 1473: // ! 1474: PIBMTOK_OPEN NewOpen; ! 1475: ! 1476: // ! 1477: // Generic loop variable ! 1478: // ! 1479: UINT i; ! 1480: ! 1481: ! 1482: UNREFERENCED_PARAMETER(AddressingInformation); ! 1483: ! 1484: *OpenErrorStatus = (NDIS_STATUS)0; ! 1485: ! 1486: // ! 1487: // Search for the medium type (token ring) ! 1488: // ! 1489: ! 1490: for(i=0; i < MediumArraySize; i++){ ! 1491: ! 1492: if (MediumArray[i] == NdisMedium802_5){ ! 1493: ! 1494: break; ! 1495: ! 1496: } ! 1497: ! 1498: } ! 1499: ! 1500: if (i == MediumArraySize){ ! 1501: ! 1502: return(NDIS_STATUS_UNSUPPORTED_MEDIA); ! 1503: ! 1504: } ! 1505: ! 1506: *SelectedMediumIndex = i; ! 1507: ! 1508: Adapter = PIBMTOK_ADAPTER_FROM_CONTEXT_HANDLE(MacAdapterContext); ! 1509: ! 1510: NdisInterlockedAddUlong((PULONG)&Adapter->References, 1, &Adapter->Lock); ! 1511: ! 1512: // ! 1513: // Allocate the space for the open binding. Fill in the fields. ! 1514: // ! 1515: ! 1516: if (IBMTOK_ALLOC_PHYS(&NewOpen, sizeof(IBMTOK_OPEN)) == ! 1517: NDIS_STATUS_SUCCESS){ ! 1518: ! 1519: *MacBindingHandle = BINDING_HANDLE_FROM_PIBMTOK_OPEN(NewOpen); ! 1520: InitializeListHead(&NewOpen->OpenList); ! 1521: NewOpen->NdisBindingContext = NdisBindingContext; ! 1522: NewOpen->References = 0; ! 1523: NewOpen->BindingShuttingDown = FALSE; ! 1524: NewOpen->OwningIbmtok = Adapter; ! 1525: NewOpen->OpenPending = FALSE; ! 1526: ! 1527: NdisAcquireSpinLock(&Adapter->Lock); ! 1528: if (!TrNoteFilterOpenAdapter( ! 1529: NewOpen->OwningIbmtok->FilterDB, ! 1530: NewOpen, ! 1531: NdisBindingContext, ! 1532: &NewOpen->NdisFilterHandle ! 1533: )) { ! 1534: ! 1535: NdisReleaseSpinLock(&Adapter->Lock); ! 1536: ! 1537: NdisWriteErrorLogEntry( ! 1538: Adapter->NdisAdapterHandle, ! 1539: NDIS_ERROR_CODE_OUT_OF_RESOURCES, ! 1540: 2, ! 1541: openAdapter, ! 1542: IBMTOK_ERRMSG_OPEN_DB ! 1543: ); ! 1544: ! 1545: IBMTOK_FREE_PHYS(NewOpen, sizeof(IBMTOK_OPEN)); ! 1546: ! 1547: StatusToReturn = NDIS_STATUS_FAILURE; ! 1548: NdisAcquireSpinLock(&Adapter->Lock); ! 1549: ! 1550: } else { ! 1551: ! 1552: // ! 1553: // Everything has been filled in. Synchronize access to the ! 1554: // adapter block and link the new open adapter in and increment ! 1555: // the opens reference count to account for the fact that the ! 1556: // filter routines have a "reference" to the open. ! 1557: // ! 1558: ! 1559: NewOpen->LookAhead = IBMTOK_MAX_LOOKAHEAD; ! 1560: ! 1561: Adapter->LookAhead = IBMTOK_MAX_LOOKAHEAD; ! 1562: ! 1563: InsertTailList(&Adapter->OpenBindings,&NewOpen->OpenList); ! 1564: NewOpen->References++; ! 1565: ! 1566: // ! 1567: // Now see if the adapter is currently open. ! 1568: // ! 1569: ! 1570: if (Adapter->AdapterNotOpen) { ! 1571: ! 1572: // ! 1573: // The adapter is not open, so this has to pend. ! 1574: // ! 1575: NewOpen->OpenPending = TRUE; ! 1576: ! 1577: StatusToReturn = NDIS_STATUS_PENDING; ! 1578: ! 1579: if (!Adapter->OpenInProgress) { ! 1580: ! 1581: // ! 1582: // Fill in the SRB for the open if this is the first ! 1583: // one for the card. ! 1584: // ! 1585: ! 1586: PSRB_OPEN_ADAPTER OpenSrb; ! 1587: ! 1588: IF_LOG('o'); ! 1589: ! 1590: Adapter->OpenInProgress = TRUE; ! 1591: Adapter->CurrentRingState = NdisRingStateOpening; ! 1592: ! 1593: NdisReleaseSpinLock(&Adapter->Lock); ! 1594: ! 1595: OpenSrb = (PSRB_OPEN_ADAPTER) ! 1596: (Adapter->SharedRam + Adapter->InitialWrbOffset); ! 1597: ! 1598: IBMTOK_ZERO_MAPPED_MEMORY(OpenSrb, sizeof(SRB_OPEN_ADAPTER)); ! 1599: ! 1600: NdisWriteRegisterUchar( ! 1601: (PUCHAR)&OpenSrb->Command, ! 1602: SRB_CMD_OPEN_ADAPTER); ! 1603: NdisWriteRegisterUshort( ! 1604: (PUSHORT)&OpenSrb->OpenOptions, ! 1605: OPEN_CONTENDER); ! 1606: ! 1607: for (i=0; i < TR_LENGTH_OF_ADDRESS; i++) { ! 1608: NdisWriteRegisterUchar((PCHAR)&OpenSrb->NodeAddress[i], ! 1609: Adapter->NetworkAddress[i] ! 1610: ); ! 1611: } ! 1612: ! 1613: WRITE_IBMSHORT(OpenSrb->ReceiveBufferNum, ! 1614: Adapter->NumberOfReceiveBuffers); ! 1615: WRITE_IBMSHORT(OpenSrb->ReceiveBufferLen, ! 1616: Adapter->ReceiveBufferLength); ! 1617: ! 1618: WRITE_IBMSHORT(OpenSrb->TransmitBufferLen, ! 1619: Adapter->TransmitBufferLength); ! 1620: NdisWriteRegisterUchar( ! 1621: (PUCHAR)&OpenSrb->TransmitBufferNum, ! 1622: (UCHAR)Adapter->NumberOfTransmitBuffers); ! 1623: ! 1624: WRITE_ADAPTER_REGISTER(Adapter, ISRA_HIGH_SET, ! 1625: ISRA_HIGH_COMMAND_IN_SRB); ! 1626: ! 1627: NdisAcquireSpinLock(&Adapter->Lock); ! 1628: ! 1629: } ! 1630: ! 1631: } ! 1632: ! 1633: } ! 1634: ! 1635: } else { ! 1636: ! 1637: NdisWriteErrorLogEntry( ! 1638: Adapter->NdisAdapterHandle, ! 1639: NDIS_ERROR_CODE_OUT_OF_RESOURCES, ! 1640: 2, ! 1641: openAdapter, ! 1642: IBMTOK_ERRMSG_ALLOC_MEM ! 1643: ); ! 1644: ! 1645: return(NDIS_STATUS_RESOURCES); ! 1646: ! 1647: } ! 1648: ! 1649: ! 1650: ! 1651: ! 1652: // ! 1653: // This macro assumes it is called with the lock held, ! 1654: // and releases it. ! 1655: // ! 1656: ! 1657: IBMTOK_DO_DEFERRED(Adapter); ! 1658: return StatusToReturn; ! 1659: } ! 1660: ! 1661: VOID ! 1662: IbmtokAdjustMaxLookAhead( ! 1663: IN PIBMTOK_ADAPTER Adapter ! 1664: ) ! 1665: /*++ ! 1666: ! 1667: Routine Description: ! 1668: ! 1669: This routine finds the open with the maximum lookahead value and ! 1670: stores that in the adapter block. ! 1671: ! 1672: Arguments: ! 1673: ! 1674: Adapter - A pointer to the adapter block. ! 1675: ! 1676: Returns: ! 1677: ! 1678: None. ! 1679: ! 1680: --*/ ! 1681: { ! 1682: ULONG CurrentMax = 0; ! 1683: PLIST_ENTRY CurrentLink; ! 1684: PIBMTOK_OPEN TempOpen; ! 1685: ! 1686: CurrentLink = Adapter->OpenBindings.Flink; ! 1687: ! 1688: while (CurrentLink != &(Adapter->OpenBindings)){ ! 1689: ! 1690: TempOpen = CONTAINING_RECORD( ! 1691: CurrentLink, ! 1692: IBMTOK_OPEN, ! 1693: OpenList ! 1694: ); ! 1695: ! 1696: if (TempOpen->LookAhead > CurrentMax) { ! 1697: ! 1698: CurrentMax = TempOpen->LookAhead; ! 1699: ! 1700: } ! 1701: ! 1702: CurrentLink = CurrentLink->Flink; ! 1703: ! 1704: } ! 1705: ! 1706: if (CurrentMax == 0) { ! 1707: ! 1708: CurrentMax = IBMTOK_MAX_LOOKAHEAD; ! 1709: ! 1710: } ! 1711: ! 1712: Adapter->LookAhead = CurrentMax; ! 1713: ! 1714: } ! 1715: ! 1716: STATIC ! 1717: NDIS_STATUS ! 1718: IbmtokCloseAdapter( ! 1719: IN NDIS_HANDLE MacBindingHandle ! 1720: ) ! 1721: ! 1722: /*++ ! 1723: ! 1724: Routine Description: ! 1725: ! 1726: This routine causes the MAC to close an open handle (binding). ! 1727: ! 1728: Arguments: ! 1729: ! 1730: MacBindingHandle - The context value returned by the MAC when the ! 1731: adapter was opened. In reality it is a PIBMTOK_OPEN. ! 1732: ! 1733: Return Value: ! 1734: ! 1735: The function value is the status of the operation. ! 1736: ! 1737: ! 1738: --*/ ! 1739: ! 1740: { ! 1741: ! 1742: PIBMTOK_ADAPTER Adapter; ! 1743: PIBMTOK_OPEN Open; ! 1744: ! 1745: NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS; ! 1746: ! 1747: Adapter = PIBMTOK_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle); ! 1748: Open = PIBMTOK_OPEN_FROM_BINDING_HANDLE(MacBindingHandle); ! 1749: ! 1750: // ! 1751: // Hold the lock while we update the reference counts for the ! 1752: // adapter and the open. ! 1753: // ! 1754: ! 1755: NdisAcquireSpinLock(&Adapter->Lock); ! 1756: Adapter->References++; ! 1757: ! 1758: if (!Open->BindingShuttingDown) { ! 1759: ! 1760: Open->References++; ! 1761: ! 1762: StatusToReturn = TrDeleteFilterOpenAdapter( ! 1763: Adapter->FilterDB, ! 1764: Open->NdisFilterHandle, ! 1765: NULL ! 1766: ); ! 1767: ! 1768: // ! 1769: // If the status is successful that merely implies that ! 1770: // we were able to delete the reference to the open binding ! 1771: // from the filtering code. If we have a successful status ! 1772: // at this point we still need to check whether the reference ! 1773: // count to determine whether we can close. ! 1774: // ! 1775: // ! 1776: // The delete filter routine can return a "special" status ! 1777: // that indicates that there is a current NdisIndicateReceive ! 1778: // on this binding. ! 1779: // ! 1780: ! 1781: ! 1782: if (StatusToReturn == NDIS_STATUS_SUCCESS) { ! 1783: ! 1784: // ! 1785: // Check whether the reference count is two. If ! 1786: // it is then we can get rid of the memory for ! 1787: // this open. ! 1788: // ! 1789: // A count of two indicates one for this routine ! 1790: // and one for the filter which we *know* we can ! 1791: // get rid of. ! 1792: // ! 1793: ! 1794: if (Open->References == 2) { ! 1795: ! 1796: RemoveEntryList(&Open->OpenList); ! 1797: ! 1798: // ! 1799: // We are the only reference to the open. Remove ! 1800: // it from the open list and delete the memory. ! 1801: // ! 1802: ! 1803: RemoveEntryList(&Open->OpenList); ! 1804: ! 1805: if (Open->LookAhead == Adapter->LookAhead) { ! 1806: ! 1807: IbmtokAdjustMaxLookAhead(Adapter); ! 1808: ! 1809: } ! 1810: ! 1811: IBMTOK_FREE_PHYS(Open,sizeof(IBMTOK_OPEN)); ! 1812: ! 1813: } else { ! 1814: ! 1815: Open->BindingShuttingDown = TRUE; ! 1816: ! 1817: // ! 1818: // Remove the open from the open list and put it on ! 1819: // the closing list. ! 1820: // ! 1821: ! 1822: RemoveEntryList(&Open->OpenList); ! 1823: InsertTailList(&Adapter->CloseList,&Open->OpenList); ! 1824: ! 1825: // ! 1826: // Account for this routines reference to the open ! 1827: // as well as reference because of the filtering. ! 1828: // ! 1829: ! 1830: Open->References -= 2; ! 1831: ! 1832: // ! 1833: // Change the status to indicate that we will ! 1834: // be closing this later. ! 1835: // ! 1836: ! 1837: StatusToReturn = NDIS_STATUS_PENDING; ! 1838: ! 1839: } ! 1840: ! 1841: } else if (StatusToReturn == NDIS_STATUS_PENDING) { ! 1842: ! 1843: ! 1844: // ! 1845: // If it pended, there may be ! 1846: // operations queued. ! 1847: // ! 1848: ! 1849: IbmtokProcessSrbRequests(Adapter); ! 1850: ! 1851: // ! 1852: // Now start closing down this open. ! 1853: // ! 1854: ! 1855: Open->BindingShuttingDown = TRUE; ! 1856: ! 1857: // ! 1858: // Remove the open from the open list and put it on ! 1859: // the closing list. ! 1860: // ! 1861: ! 1862: RemoveEntryList(&Open->OpenList); ! 1863: InsertTailList(&Adapter->CloseList,&Open->OpenList); ! 1864: ! 1865: // ! 1866: // Account for this routines reference to the open ! 1867: // as well as reference because of the filtering. ! 1868: // ! 1869: ! 1870: Open->References -= 2; ! 1871: ! 1872: } else if (StatusToReturn == NDIS_STATUS_CLOSING_INDICATING) { ! 1873: ! 1874: // ! 1875: // When we have this status it indicates that the filtering ! 1876: // code was currently doing an NdisIndicateReceive. It ! 1877: // would not be wise to delete the memory for the open at ! 1878: // this point. The filtering code will call our close action ! 1879: // routine upon return from NdisIndicateReceive and that ! 1880: // action routine will decrement the reference count for ! 1881: // the open. ! 1882: // ! 1883: ! 1884: Open->BindingShuttingDown = TRUE; ! 1885: ! 1886: // ! 1887: // This status is private to the filtering routine. Just ! 1888: // tell the caller the the close is pending. ! 1889: // ! 1890: ! 1891: StatusToReturn = NDIS_STATUS_PENDING; ! 1892: ! 1893: // ! 1894: // Remove the open from the open list and put it on ! 1895: // the closing list. ! 1896: // ! 1897: ! 1898: RemoveEntryList(&Open->OpenList); ! 1899: InsertTailList(&Adapter->CloseList,&Open->OpenList); ! 1900: ! 1901: // ! 1902: // Account for this routines reference to the open. ! 1903: // ! 1904: ! 1905: Open->References--; ! 1906: ! 1907: } else if (StatusToReturn == NDIS_STATUS_RESET_IN_PROGRESS) { ! 1908: ! 1909: Open->BindingShuttingDown = TRUE; ! 1910: ! 1911: // ! 1912: // Remove the open from the open list and put it on ! 1913: // the closing list. ! 1914: // ! 1915: ! 1916: RemoveEntryList(&Open->OpenList); ! 1917: InsertTailList(&Adapter->CloseDuringResetList,&Open->OpenList); ! 1918: ! 1919: ! 1920: // ! 1921: // Account for this routines reference to the open. ! 1922: // ! 1923: ! 1924: Open->References--; ! 1925: ! 1926: StatusToReturn = NDIS_STATUS_PENDING; ! 1927: ! 1928: } else { ! 1929: ! 1930: NdisWriteErrorLogEntry( ! 1931: Adapter->NdisAdapterHandle, ! 1932: NDIS_ERROR_CODE_DRIVER_FAILURE, ! 1933: 2, ! 1934: IBMTOK_ERRMSG_INVALID_STATUS, ! 1935: 1 ! 1936: ); ! 1937: ! 1938: } ! 1939: ! 1940: } else { ! 1941: ! 1942: StatusToReturn = NDIS_STATUS_CLOSING; ! 1943: ! 1944: } ! 1945: ! 1946: ! 1947: // ! 1948: // This macro assumes it is called with the lock held, ! 1949: // and releases it. ! 1950: // ! 1951: ! 1952: IBMTOK_DO_DEFERRED(Adapter); ! 1953: return StatusToReturn; ! 1954: ! 1955: } ! 1956: ! 1957: STATIC ! 1958: NDIS_STATUS ! 1959: IbmtokRequest( ! 1960: IN NDIS_HANDLE MacBindingHandle, ! 1961: IN PNDIS_REQUEST NdisRequest ! 1962: ) ! 1963: ! 1964: /*++ ! 1965: ! 1966: Routine Description: ! 1967: ! 1968: The IbmtokRequest allows a protocol to query and set information ! 1969: about the MAC. ! 1970: ! 1971: Arguments: ! 1972: ! 1973: MacBindingHandle - The context value returned by the MAC when the ! 1974: adapter was opened. In reality, it is a pointer to IBMTOK_OPEN. ! 1975: ! 1976: NdisRequest - A structure which contains the request type (Set or ! 1977: Query), an array of operations to perform, and an array for holding ! 1978: the results of the operations. ! 1979: ! 1980: Return Value: ! 1981: ! 1982: The function value is the status of the operation. ! 1983: ! 1984: --*/ ! 1985: ! 1986: { ! 1987: NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS; ! 1988: ! 1989: PIBMTOK_ADAPTER Adapter = PIBMTOK_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle); ! 1990: PIBMTOK_OPEN Open = PIBMTOK_OPEN_FROM_BINDING_HANDLE(MacBindingHandle); ! 1991: ! 1992: NdisAcquireSpinLock(&(Adapter->Lock)); ! 1993: ! 1994: Adapter->References++; ! 1995: ! 1996: // ! 1997: // Process request ! 1998: // ! 1999: ! 2000: if (NdisRequest->RequestType == NdisRequestQueryInformation) { ! 2001: ! 2002: StatusToReturn = IbmtokQueryInformation(Adapter, Open, NdisRequest); ! 2003: ! 2004: } else if (NdisRequest->RequestType == NdisRequestSetInformation) { ! 2005: ! 2006: ! 2007: // ! 2008: // Make sure Adapter is in a valid state. ! 2009: // ! 2010: ! 2011: if (Adapter->Unplugged) { ! 2012: ! 2013: StatusToReturn = NDIS_STATUS_DEVICE_FAILED; ! 2014: ! 2015: } else if (!Adapter->NotAcceptingRequests) { ! 2016: ! 2017: // ! 2018: // Make sure the open instance is valid ! 2019: // ! 2020: ! 2021: if (!Open->BindingShuttingDown) { ! 2022: ! 2023: StatusToReturn = IbmtokSetInformation(Adapter,Open,NdisRequest); ! 2024: ! 2025: } else { ! 2026: ! 2027: StatusToReturn = NDIS_STATUS_CLOSING; ! 2028: ! 2029: } ! 2030: ! 2031: } else { ! 2032: ! 2033: if (Adapter->ResetInProgress) { ! 2034: ! 2035: StatusToReturn = NDIS_STATUS_RESET_IN_PROGRESS; ! 2036: ! 2037: } else if (Adapter->AdapterNotOpen) { ! 2038: ! 2039: StatusToReturn = NDIS_STATUS_FAILURE; ! 2040: ! 2041: } else { ! 2042: ! 2043: NdisWriteErrorLogEntry( ! 2044: Adapter->NdisAdapterHandle, ! 2045: NDIS_ERROR_CODE_DRIVER_FAILURE, ! 2046: 2, ! 2047: IBMTOK_ERRMSG_INVALID_STATE, ! 2048: 3 ! 2049: ); ! 2050: ! 2051: } ! 2052: } ! 2053: } else { ! 2054: ! 2055: StatusToReturn = NDIS_STATUS_NOT_RECOGNIZED; ! 2056: ! 2057: } ! 2058: ! 2059: IBMTOK_DO_DEFERRED(Adapter); ! 2060: ! 2061: return(StatusToReturn); ! 2062: ! 2063: } ! 2064: ! 2065: STATIC ! 2066: NDIS_STATUS ! 2067: IbmtokQueryProtocolInformation( ! 2068: IN PIBMTOK_ADAPTER Adapter, ! 2069: IN PIBMTOK_OPEN Open, ! 2070: IN NDIS_OID Oid, ! 2071: IN BOOLEAN GlobalMode, ! 2072: IN PVOID InfoBuffer, ! 2073: IN UINT BytesLeft, ! 2074: OUT PUINT BytesNeeded, ! 2075: OUT PUINT BytesWritten ! 2076: ) ! 2077: ! 2078: /*++ ! 2079: ! 2080: Routine Description: ! 2081: ! 2082: The IbmtokQueryProtocolInformation process a Query request for ! 2083: NDIS_OIDs that are specific to a binding about the MAC. Note that ! 2084: some of the OIDs that are specific to bindings are also queryable ! 2085: on a global basis. Rather than recreate this code to handle the ! 2086: global queries, I use a flag to indicate if this is a query for the ! 2087: global data or the binding specific data. ! 2088: ! 2089: Arguments: ! 2090: ! 2091: Adapter - a pointer to the adapter. ! 2092: ! 2093: Open - a pointer to the open instance. ! 2094: ! 2095: Oid - the NDIS_OID to process. ! 2096: ! 2097: GlobalMode - Some of the binding specific information is also used ! 2098: when querying global statistics. This is a flag to specify whether ! 2099: to return the global value, or the binding specific value. ! 2100: ! 2101: InfoBuffer - a pointer into the NdisRequest->InformationBuffer ! 2102: into which store the result of the query. ! 2103: ! 2104: BytesLeft - the number of bytes left in the InformationBuffer. ! 2105: ! 2106: BytesNeeded - If there is not enough room in the information buffer ! 2107: then this will contain the number of bytes needed to complete the ! 2108: request. ! 2109: ! 2110: BytesWritten - a pointer to the number of bytes written into the ! 2111: InformationBuffer. ! 2112: ! 2113: Return Value: ! 2114: ! 2115: The function value is the status of the operation. ! 2116: ! 2117: --*/ ! 2118: ! 2119: { ! 2120: NDIS_MEDIUM Medium = NdisMedium802_5; ! 2121: ULONG GenericULong; ! 2122: USHORT GenericUShort; ! 2123: UCHAR GenericArray[6]; ! 2124: ! 2125: NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS; ! 2126: ! 2127: // ! 2128: // Common variables for pointing to result of query ! 2129: // ! 2130: ! 2131: PVOID MoveSource = (PVOID)(&GenericULong); ! 2132: ULONG MoveBytes = sizeof(GenericULong); ! 2133: ! 2134: NDIS_HARDWARE_STATUS HardwareStatus = NdisHardwareStatusReady; ! 2135: ! 2136: // ! 2137: // General Algorithm: ! 2138: // ! 2139: // Switch(Request) ! 2140: // Get requested information ! 2141: // Store results in a common variable. ! 2142: // Copy result in common variable to result buffer. ! 2143: // ! 2144: ! 2145: // ! 2146: // Switch on request type ! 2147: // ! 2148: ! 2149: switch (Oid) { ! 2150: ! 2151: case OID_GEN_MAC_OPTIONS: ! 2152: ! 2153: GenericULong = (ULONG)(NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | ! 2154: NDIS_MAC_OPTION_RECEIVE_SERIALIZED ! 2155: ); ! 2156: ! 2157: break; ! 2158: ! 2159: case OID_GEN_SUPPORTED_LIST: ! 2160: ! 2161: if (!GlobalMode){ ! 2162: MoveSource = (PVOID)(IbmtokProtocolSupportedOids); ! 2163: MoveBytes = sizeof(IbmtokProtocolSupportedOids); ! 2164: } else { ! 2165: MoveSource = (PVOID)(IbmtokGlobalSupportedOids); ! 2166: MoveBytes = sizeof(IbmtokGlobalSupportedOids); ! 2167: } ! 2168: break; ! 2169: ! 2170: case OID_GEN_HARDWARE_STATUS: ! 2171: ! 2172: ! 2173: if (Adapter->ResetInProgress){ ! 2174: ! 2175: HardwareStatus = NdisHardwareStatusReset; ! 2176: ! 2177: } else if ((Adapter->FirstInitialization) || ! 2178: (Adapter->OpenInProgress)){ ! 2179: ! 2180: HardwareStatus = NdisHardwareStatusInitializing; ! 2181: ! 2182: } else if (Adapter->NotAcceptingRequests){ ! 2183: ! 2184: HardwareStatus = NdisHardwareStatusNotReady; ! 2185: ! 2186: } else ! 2187: HardwareStatus = NdisHardwareStatusReady; ! 2188: ! 2189: ! 2190: MoveSource = (PVOID)(&HardwareStatus); ! 2191: MoveBytes = sizeof(NDIS_HARDWARE_STATUS); ! 2192: ! 2193: break; ! 2194: ! 2195: case OID_GEN_MEDIA_SUPPORTED: ! 2196: case OID_GEN_MEDIA_IN_USE: ! 2197: ! 2198: MoveSource = (PVOID) (&Medium); ! 2199: MoveBytes = sizeof(NDIS_MEDIUM); ! 2200: break; ! 2201: ! 2202: case OID_GEN_MAXIMUM_LOOKAHEAD: ! 2203: ! 2204: GenericULong = IBMTOK_MAX_LOOKAHEAD; ! 2205: ! 2206: break; ! 2207: ! 2208: ! 2209: case OID_GEN_MAXIMUM_FRAME_SIZE: ! 2210: case OID_GEN_MAXIMUM_TOTAL_SIZE: ! 2211: ! 2212: GenericULong = (ULONG)(Adapter->MaxTransmittablePacket); ! 2213: ! 2214: if (Oid == OID_GEN_MAXIMUM_FRAME_SIZE) { ! 2215: ! 2216: // ! 2217: // For the receive frame size, we subtract the minimum ! 2218: // header size from the number. ! 2219: // ! 2220: ! 2221: GenericULong -= 14; ! 2222: } ! 2223: ! 2224: break; ! 2225: ! 2226: ! 2227: case OID_GEN_LINK_SPEED: ! 2228: ! 2229: GenericULong = (ULONG)(Adapter->Running16Mbps? 160000 : 40000); ! 2230: ! 2231: break; ! 2232: ! 2233: ! 2234: case OID_GEN_TRANSMIT_BUFFER_SPACE: ! 2235: ! 2236: GenericULong = (ULONG)(Adapter->NumberOfTransmitBuffers * ! 2237: Adapter->TransmitBufferLength); ! 2238: ! 2239: break; ! 2240: ! 2241: case OID_GEN_RECEIVE_BUFFER_SPACE: ! 2242: ! 2243: GenericULong = (ULONG)(Adapter->NumberOfReceiveBuffers * ! 2244: Adapter->ReceiveBufferLength); ! 2245: ! 2246: break; ! 2247: ! 2248: case OID_GEN_TRANSMIT_BLOCK_SIZE: ! 2249: ! 2250: GenericULong = (ULONG)(Adapter->TransmitBufferLength); ! 2251: ! 2252: break; ! 2253: ! 2254: case OID_GEN_RECEIVE_BLOCK_SIZE: ! 2255: ! 2256: GenericULong = (ULONG)(Adapter->ReceiveBufferLength); ! 2257: ! 2258: break; ! 2259: ! 2260: case OID_GEN_VENDOR_ID: ! 2261: ! 2262: NdisMoveMemory( ! 2263: (PVOID)&GenericULong, ! 2264: Adapter->PermanentNetworkAddress, ! 2265: 3 ! 2266: ); ! 2267: GenericULong &= 0xFFFFFF00; ! 2268: ! 2269: if (Adapter->UsingPcIoBus) { ! 2270: ! 2271: GenericULong |= 0x01; ! 2272: ! 2273: } ! 2274: ! 2275: MoveSource = (PVOID)(&GenericULong); ! 2276: MoveBytes = sizeof(GenericULong); ! 2277: break; ! 2278: ! 2279: case OID_GEN_VENDOR_DESCRIPTION: ! 2280: ! 2281: if (Adapter->UsingPcIoBus){ ! 2282: MoveSource = (PVOID)"Ibm Token Ring Network Card for PC I/O bus."; ! 2283: MoveBytes = 44; ! 2284: } else { ! 2285: MoveSource = (PVOID)"Ibm Token Ring Network Card for MCA bus."; ! 2286: MoveBytes = 41; ! 2287: } ! 2288: break; ! 2289: ! 2290: case OID_GEN_DRIVER_VERSION: ! 2291: ! 2292: GenericUShort = (USHORT)((IBMTOK_NDIS_MAJOR_VERSION << 8) | IBMTOK_NDIS_MINOR_VERSION); ! 2293: ! 2294: MoveSource = (PVOID)(&GenericUShort); ! 2295: MoveBytes = sizeof(GenericUShort); ! 2296: break; ! 2297: ! 2298: ! 2299: case OID_GEN_CURRENT_PACKET_FILTER: ! 2300: ! 2301: if (GlobalMode) { ! 2302: ! 2303: GenericULong = (ULONG)(Adapter->CurrentPacketFilter); ! 2304: ! 2305: } else { ! 2306: ! 2307: GenericULong = (ULONG)(TR_QUERY_PACKET_FILTER( ! 2308: Adapter->FilterDB, ! 2309: Open->NdisFilterHandle)); ! 2310: ! 2311: } ! 2312: ! 2313: break; ! 2314: ! 2315: case OID_GEN_CURRENT_LOOKAHEAD: ! 2316: ! 2317: if (!GlobalMode){ ! 2318: ! 2319: GenericULong = Open->LookAhead; ! 2320: ! 2321: } else { ! 2322: ! 2323: PLIST_ENTRY CurrentLink; ! 2324: PIBMTOK_OPEN TempOpen; ! 2325: ! 2326: CurrentLink = Adapter->OpenBindings.Flink; ! 2327: ! 2328: GenericULong = 0; ! 2329: ! 2330: while (CurrentLink != &(Adapter->OpenBindings)){ ! 2331: ! 2332: TempOpen = CONTAINING_RECORD( ! 2333: CurrentLink, ! 2334: IBMTOK_OPEN, ! 2335: OpenList ! 2336: ); ! 2337: ! 2338: if (TempOpen->LookAhead > GenericULong) { ! 2339: ! 2340: GenericULong = TempOpen->LookAhead; ! 2341: ! 2342: if (GenericULong == IBMTOK_MAX_LOOKAHEAD) { ! 2343: ! 2344: break; ! 2345: ! 2346: } ! 2347: } ! 2348: ! 2349: CurrentLink = CurrentLink->Flink; ! 2350: ! 2351: } ! 2352: ! 2353: } ! 2354: ! 2355: break; ! 2356: ! 2357: case OID_802_5_PERMANENT_ADDRESS: ! 2358: ! 2359: TR_COPY_NETWORK_ADDRESS((PCHAR)GenericArray, ! 2360: Adapter->PermanentNetworkAddress); ! 2361: ! 2362: MoveSource = (PVOID)(GenericArray); ! 2363: MoveBytes = sizeof(Adapter->PermanentNetworkAddress); ! 2364: ! 2365: break; ! 2366: ! 2367: case OID_802_5_CURRENT_ADDRESS: ! 2368: ! 2369: TR_COPY_NETWORK_ADDRESS((PCHAR)GenericArray, ! 2370: Adapter->NetworkAddress); ! 2371: ! 2372: MoveSource = (PVOID)(GenericArray); ! 2373: MoveBytes = sizeof(Adapter->NetworkAddress); ! 2374: ! 2375: break; ! 2376: ! 2377: case OID_802_5_CURRENT_FUNCTIONAL: ! 2378: ! 2379: if (!GlobalMode){ ! 2380: ! 2381: GenericULong = TR_QUERY_FILTER_BINDING_ADDRESS( ! 2382: Adapter->FilterDB, ! 2383: Open->NdisFilterHandle); ! 2384: ! 2385: } else { ! 2386: ! 2387: GenericULong = Adapter->CurrentCardFunctional & 0xffffffff; ! 2388: ! 2389: } ! 2390: ! 2391: // ! 2392: // Now we need to reverse the crazy thing. ! 2393: // ! 2394: ! 2395: GenericULong = (ULONG)( ! 2396: ((GenericULong >> 24) & 0xFF) | ! 2397: ((GenericULong >> 8) & 0xFF00) | ! 2398: ((GenericULong << 8) & 0xFF0000) | ! 2399: ((GenericULong << 24) & 0xFF000000) ! 2400: ); ! 2401: ! 2402: break; ! 2403: ! 2404: case OID_802_5_CURRENT_GROUP: ! 2405: ! 2406: GenericULong = Adapter->CurrentCardGroup & 0xffffffff; ! 2407: ! 2408: // ! 2409: // Now we need to reverse the crazy thing. ! 2410: // ! 2411: ! 2412: GenericULong = (ULONG)( ! 2413: ((GenericULong >> 24) & 0xFF) | ! 2414: ((GenericULong >> 8) & 0xFF00) | ! 2415: ((GenericULong << 8) & 0xFF0000) | ! 2416: ((GenericULong << 24) & 0xFF000000) ! 2417: ); ! 2418: ! 2419: break; ! 2420: ! 2421: default: ! 2422: ! 2423: StatusToReturn = NDIS_STATUS_NOT_SUPPORTED; ! 2424: break; ! 2425: } ! 2426: ! 2427: if (StatusToReturn == NDIS_STATUS_SUCCESS){ ! 2428: ! 2429: if (MoveBytes > BytesLeft){ ! 2430: ! 2431: // ! 2432: // Not enough room in InformationBuffer. Punt ! 2433: // ! 2434: ! 2435: *BytesNeeded = MoveBytes; ! 2436: ! 2437: StatusToReturn = NDIS_STATUS_INVALID_LENGTH; ! 2438: ! 2439: } else { ! 2440: ! 2441: // ! 2442: // Store result. ! 2443: // ! 2444: ! 2445: IBMTOK_MOVE_MEMORY(InfoBuffer, MoveSource, MoveBytes); ! 2446: ! 2447: (*BytesWritten) += MoveBytes; ! 2448: ! 2449: } ! 2450: } ! 2451: ! 2452: return(StatusToReturn); ! 2453: } ! 2454: ! 2455: STATIC ! 2456: NDIS_STATUS ! 2457: IbmtokQueryInformation( ! 2458: IN PIBMTOK_ADAPTER Adapter, ! 2459: IN PIBMTOK_OPEN Open, ! 2460: IN PNDIS_REQUEST NdisRequest ! 2461: ) ! 2462: /*++ ! 2463: ! 2464: Routine Description: ! 2465: ! 2466: The IbmtokQueryInformation is used by IbmtokRequest to query information ! 2467: about the MAC. ! 2468: ! 2469: Arguments: ! 2470: ! 2471: Adapter - A pointer to the adapter. ! 2472: ! 2473: Open - A pointer to a particular open instance. ! 2474: ! 2475: NdisRequest - A structure which contains the request type (Query), ! 2476: an array of operations to perform, and an array for holding ! 2477: the results of the operations. ! 2478: ! 2479: Return Value: ! 2480: ! 2481: The function value is the status of the operation. ! 2482: ! 2483: --*/ ! 2484: ! 2485: { ! 2486: ! 2487: UINT BytesWritten = 0; ! 2488: UINT BytesNeeded = 0; ! 2489: UINT BytesLeft = NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength; ! 2490: PUCHAR InfoBuffer = (PUCHAR)(NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer); ! 2491: ! 2492: NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS; ! 2493: ! 2494: ! 2495: StatusToReturn = IbmtokQueryProtocolInformation( ! 2496: Adapter, ! 2497: Open, ! 2498: NdisRequest->DATA.QUERY_INFORMATION.Oid, ! 2499: FALSE, ! 2500: InfoBuffer, ! 2501: BytesLeft, ! 2502: &BytesNeeded, ! 2503: &BytesWritten ! 2504: ); ! 2505: ! 2506: NdisRequest->DATA.QUERY_INFORMATION.BytesWritten = BytesWritten; ! 2507: ! 2508: NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded = BytesNeeded; ! 2509: ! 2510: return(StatusToReturn); ! 2511: } ! 2512: ! 2513: STATIC ! 2514: NDIS_STATUS ! 2515: IbmtokSetInformation( ! 2516: IN PIBMTOK_ADAPTER Adapter, ! 2517: IN PIBMTOK_OPEN Open, ! 2518: IN PNDIS_REQUEST NdisRequest ! 2519: ) ! 2520: /*++ ! 2521: ! 2522: Routine Description: ! 2523: ! 2524: The IbmtokSetInformation is used by IbmtokRequest to set information ! 2525: about the MAC. ! 2526: ! 2527: Arguments: ! 2528: ! 2529: Adapter - A pointer to the adapter. ! 2530: ! 2531: Open - A pointer to an open instance. ! 2532: ! 2533: NdisRequest - A structure which contains the request type (Set), ! 2534: an array of operations to perform, and an array for holding ! 2535: the results of the operations. ! 2536: ! 2537: Return Value: ! 2538: ! 2539: The function value is the status of the operation. ! 2540: ! 2541: --*/ ! 2542: ! 2543: { ! 2544: ! 2545: // ! 2546: // General Algorithm: ! 2547: // ! 2548: // Verify length ! 2549: // Switch(Request) ! 2550: // Process Request ! 2551: // ! 2552: ! 2553: UINT BytesNeeded = 0; ! 2554: UINT BytesLeft = NdisRequest->DATA.SET_INFORMATION.InformationBufferLength; ! 2555: PUCHAR InfoBuffer = (PUCHAR)(NdisRequest->DATA.SET_INFORMATION.InformationBuffer); ! 2556: ! 2557: // ! 2558: // Variables for the request ! 2559: // ! 2560: ! 2561: NDIS_OID Oid; ! 2562: UINT OidLength; ! 2563: ! 2564: // ! 2565: // Variables for holding the new values to be used. ! 2566: // ! 2567: ! 2568: ULONG LookAhead; ! 2569: ULONG Filter; ! 2570: ! 2571: NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS; ! 2572: ! 2573: ! 2574: // ! 2575: // Get Oid and Length of request ! 2576: // ! 2577: ! 2578: Oid = NdisRequest->DATA.SET_INFORMATION.Oid; ! 2579: ! 2580: OidLength = BytesLeft; ! 2581: ! 2582: // ! 2583: // Verify length ! 2584: // ! 2585: ! 2586: if (OidLength != 4){ ! 2587: ! 2588: StatusToReturn = NDIS_STATUS_INVALID_LENGTH; ! 2589: ! 2590: NdisRequest->DATA.SET_INFORMATION.BytesRead = 0; ! 2591: NdisRequest->DATA.SET_INFORMATION.BytesNeeded = 0; ! 2592: ! 2593: return(StatusToReturn); ! 2594: } ! 2595: ! 2596: switch (Oid) { ! 2597: ! 2598: case OID_802_5_CURRENT_FUNCTIONAL: ! 2599: ! 2600: StatusToReturn = IbmtokChangeFunctionalAddress( ! 2601: Adapter, ! 2602: Open, ! 2603: NdisRequest, ! 2604: InfoBuffer ! 2605: ); ! 2606: ! 2607: break; ! 2608: ! 2609: case OID_GEN_CURRENT_PACKET_FILTER: ! 2610: ! 2611: IBMTOK_MOVE_MEMORY(&Filter, InfoBuffer, 4); ! 2612: ! 2613: StatusToReturn = IbmtokSetPacketFilter(Adapter, ! 2614: Open, ! 2615: NdisRequest, ! 2616: Filter); ! 2617: ! 2618: break; ! 2619: ! 2620: case OID_802_5_CURRENT_GROUP: ! 2621: ! 2622: StatusToReturn = IbmtokSetGroupAddress( ! 2623: Adapter, ! 2624: Open, ! 2625: NdisRequest, ! 2626: InfoBuffer ! 2627: ); ! 2628: ! 2629: break; ! 2630: ! 2631: ! 2632: case OID_GEN_PROTOCOL_OPTIONS: ! 2633: ! 2634: StatusToReturn = NDIS_STATUS_SUCCESS; ! 2635: ! 2636: break; ! 2637: ! 2638: case OID_GEN_CURRENT_LOOKAHEAD: ! 2639: ! 2640: IBMTOK_MOVE_MEMORY(&LookAhead, InfoBuffer, 4); ! 2641: ! 2642: if (LookAhead > IBMTOK_MAX_LOOKAHEAD) { ! 2643: ! 2644: StatusToReturn = NDIS_STATUS_INVALID_LENGTH; ! 2645: ! 2646: } else { ! 2647: ! 2648: if (LookAhead > Adapter->LookAhead) { ! 2649: ! 2650: Open->LookAhead = LookAhead; ! 2651: ! 2652: Adapter->LookAhead = LookAhead; ! 2653: ! 2654: } else { ! 2655: ! 2656: if ((Open->LookAhead == Adapter->LookAhead) && ! 2657: (LookAhead < Open->LookAhead)) { ! 2658: ! 2659: Open->LookAhead = LookAhead; ! 2660: ! 2661: IbmtokAdjustMaxLookAhead(Adapter); ! 2662: ! 2663: } else { ! 2664: ! 2665: Open->LookAhead = LookAhead; ! 2666: ! 2667: } ! 2668: ! 2669: } ! 2670: ! 2671: } ! 2672: ! 2673: break; ! 2674: ! 2675: default: ! 2676: ! 2677: StatusToReturn = NDIS_STATUS_INVALID_OID; ! 2678: ! 2679: NdisRequest->DATA.SET_INFORMATION.BytesRead = 0; ! 2680: NdisRequest->DATA.SET_INFORMATION.BytesNeeded = 0; ! 2681: ! 2682: break; ! 2683: } ! 2684: ! 2685: if (StatusToReturn == NDIS_STATUS_SUCCESS){ ! 2686: ! 2687: NdisRequest->DATA.SET_INFORMATION.BytesRead = OidLength; ! 2688: NdisRequest->DATA.SET_INFORMATION.BytesNeeded = 0; ! 2689: ! 2690: } ! 2691: ! 2692: ! 2693: ! 2694: return(StatusToReturn); ! 2695: } ! 2696: ! 2697: STATIC ! 2698: NDIS_STATUS ! 2699: IbmtokSetPacketFilter( ! 2700: IN PIBMTOK_ADAPTER Adapter, ! 2701: IN PIBMTOK_OPEN Open, ! 2702: IN PNDIS_REQUEST NdisRequest, ! 2703: IN UINT PacketFilter ! 2704: ) ! 2705: ! 2706: /*++ ! 2707: ! 2708: Routine Description: ! 2709: ! 2710: This routine processes the stages necessary to implement changing ! 2711: the packets that a protocol receives from the MAC. ! 2712: ! 2713: Arguments: ! 2714: ! 2715: Adapter - A pointer to the Adapter. ! 2716: ! 2717: Open - A pointer to the open instance. ! 2718: ! 2719: NdisRequest - A pointer to the request submitting the set command. ! 2720: ! 2721: PacketFilter - A bit mask that contains flags that correspond to specific ! 2722: classes of received packets. If a particular bit is set in the mask, ! 2723: then packet reception for that class of packet is enabled. If the ! 2724: bit is clear, then packets that fall into that class are not received ! 2725: by the client. A single exception to this rule is that if the promiscuous ! 2726: bit is set, then the client receives all packets on the network, regardless ! 2727: of the state of the other flags. ! 2728: ! 2729: Return Value: ! 2730: ! 2731: The function value is the status of the operation. ! 2732: ! 2733: --*/ ! 2734: ! 2735: { ! 2736: ! 2737: // ! 2738: // Keeps track of the *MAC's* status. The status will only be ! 2739: // reset if the filter change action routine is called. ! 2740: // ! 2741: NDIS_STATUS StatusOfFilterChange = NDIS_STATUS_SUCCESS; ! 2742: ! 2743: // ! 2744: // Verify bits ! 2745: // ! 2746: ! 2747: if (PacketFilter & (NDIS_PACKET_TYPE_SOURCE_ROUTING | ! 2748: NDIS_PACKET_TYPE_MULTICAST | ! 2749: NDIS_PACKET_TYPE_PROMISCUOUS | ! 2750: NDIS_PACKET_TYPE_ALL_MULTICAST | ! 2751: NDIS_PACKET_TYPE_SMT | ! 2752: NDIS_PACKET_TYPE_MAC_FRAME ! 2753: )) { ! 2754: ! 2755: return(NDIS_STATUS_NOT_SUPPORTED); ! 2756: ! 2757: } ! 2758: ! 2759: // ! 2760: // Increment the open while it is going through the filtering ! 2761: // routines. ! 2762: // ! 2763: ! 2764: Open->References++; ! 2765: ! 2766: StatusOfFilterChange = TrFilterAdjust( ! 2767: Adapter->FilterDB, ! 2768: Open->NdisFilterHandle, ! 2769: NdisRequest, ! 2770: PacketFilter, ! 2771: TRUE ! 2772: ); ! 2773: Open->References--; ! 2774: ! 2775: if (StatusOfFilterChange == NDIS_STATUS_PENDING) { ! 2776: ! 2777: // ! 2778: // If it pended, it will be in the pend ! 2779: // queue so we should start that up. ! 2780: // ! 2781: ! 2782: IbmtokProcessSrbRequests(Adapter); ! 2783: ! 2784: } ! 2785: ! 2786: return StatusOfFilterChange; ! 2787: } ! 2788: ! 2789: STATIC ! 2790: NDIS_STATUS ! 2791: IbmtokChangeFunctionalAddress( ! 2792: IN PIBMTOK_ADAPTER Adapter, ! 2793: IN PIBMTOK_OPEN Open, ! 2794: IN PNDIS_REQUEST NdisRequest, ! 2795: IN PUCHAR Address ! 2796: ) ! 2797: ! 2798: /*++ ! 2799: ! 2800: Routine Description: ! 2801: ! 2802: This routine processes the stages necessary to implement changing ! 2803: the packets that a protocol receives from the MAC. ! 2804: ! 2805: ! 2806: Note: The spin lock must be held before entering this routine. ! 2807: ! 2808: Arguments: ! 2809: ! 2810: Adapter - A pointer to the Adapter. ! 2811: ! 2812: Open - A pointer to the open instance. ! 2813: ! 2814: NdisRequest - A pointer to the request submitting the set command. ! 2815: ! 2816: Address - The new functional address. ! 2817: ! 2818: Return Value: ! 2819: ! 2820: The function value is the status of the operation. ! 2821: ! 2822: --*/ ! 2823: ! 2824: { ! 2825: ! 2826: // ! 2827: // Keeps track of the *MAC's* status. The status will only be ! 2828: // reset if the address change action routine is called. ! 2829: // ! 2830: NDIS_STATUS StatusOfChange = NDIS_STATUS_SUCCESS; ! 2831: ! 2832: // ! 2833: // Increment the open while it is going through the filtering ! 2834: // routines. ! 2835: // ! 2836: ! 2837: Open->References++; ! 2838: ! 2839: StatusOfChange = TrChangeFunctionalAddress( ! 2840: Open->OwningIbmtok->FilterDB, ! 2841: Open->NdisFilterHandle, ! 2842: NdisRequest, ! 2843: Address, ! 2844: TRUE ! 2845: ); ! 2846: ! 2847: Open->References--; ! 2848: ! 2849: if (StatusOfChange == NDIS_STATUS_PENDING) { ! 2850: ! 2851: // ! 2852: // If it pended, it will be in the pend ! 2853: // queue so we should start that up. ! 2854: // ! 2855: ! 2856: IbmtokProcessSrbRequests(Adapter); ! 2857: ! 2858: } ! 2859: ! 2860: return StatusOfChange; ! 2861: } ! 2862: ! 2863: STATIC ! 2864: NDIS_STATUS ! 2865: IbmtokSetGroupAddress( ! 2866: IN PIBMTOK_ADAPTER Adapter, ! 2867: IN PIBMTOK_OPEN Open, ! 2868: IN PNDIS_REQUEST NdisRequest, ! 2869: IN PUCHAR Address ! 2870: ) ! 2871: ! 2872: /*++ ! 2873: ! 2874: Routine Description: ! 2875: ! 2876: This routine processes the stages necessary to implement changing ! 2877: the packets that a protocol receives from the MAC. ! 2878: ! 2879: ! 2880: Note: The spin lock must be held before entering this routine. ! 2881: ! 2882: Arguments: ! 2883: ! 2884: Adapter - A pointer to the Adapter. ! 2885: ! 2886: Open - A pointer to the open instance. ! 2887: ! 2888: NdisRequest - A pointer to the request submitting the set command. ! 2889: ! 2890: Address - The new group address. ! 2891: ! 2892: Return Value: ! 2893: ! 2894: The function value is the status of the operation. ! 2895: ! 2896: --*/ ! 2897: ! 2898: { ! 2899: ! 2900: // ! 2901: // Keeps track of the *MAC's* status. The status will only be ! 2902: // reset if the address change action routine is called. ! 2903: // ! 2904: NDIS_STATUS StatusOfChange = NDIS_STATUS_SUCCESS; ! 2905: ! 2906: // ! 2907: // Increment the open while it is going through the filtering ! 2908: // routines. ! 2909: // ! 2910: ! 2911: Open->References++; ! 2912: ! 2913: StatusOfChange = TrChangeGroupAddress( ! 2914: Open->OwningIbmtok->FilterDB, ! 2915: Open->NdisFilterHandle, ! 2916: NdisRequest, ! 2917: Address, ! 2918: TRUE ! 2919: ); ! 2920: ! 2921: Open->References--; ! 2922: ! 2923: if (StatusOfChange == NDIS_STATUS_PENDING) { ! 2924: ! 2925: // ! 2926: // If it pended, it will be in the pend ! 2927: // queue so we should start that up. ! 2928: // ! 2929: ! 2930: IbmtokProcessSrbRequests(Adapter); ! 2931: ! 2932: } ! 2933: ! 2934: return StatusOfChange; ! 2935: } ! 2936: ! 2937: NDIS_STATUS ! 2938: IbmtokFillInGlobalData( ! 2939: IN PIBMTOK_ADAPTER Adapter, ! 2940: IN PNDIS_REQUEST NdisRequest ! 2941: ) ! 2942: ! 2943: /*++ ! 2944: ! 2945: Routine Description: ! 2946: ! 2947: This routine completes a GlobalStatistics request. It is critical that ! 2948: if information is needed from the Adapter->* fields, they have been ! 2949: updated before this routine is called. ! 2950: ! 2951: Arguments: ! 2952: ! 2953: Adapter - A pointer to the Adapter. ! 2954: ! 2955: NdisRequest - A structure which contains the request type (Global ! 2956: Query), an array of operations to perform, and an array for holding ! 2957: the results of the operations. ! 2958: ! 2959: Return Value: ! 2960: ! 2961: The function value is the status of the operation. ! 2962: ! 2963: --*/ ! 2964: { ! 2965: // ! 2966: // General Algorithm: ! 2967: // ! 2968: // Switch(Request) ! 2969: // Get requested information ! 2970: // Store results in a common variable. ! 2971: // default: ! 2972: // Try protocol query information ! 2973: // If that fails, fail query. ! 2974: // ! 2975: // Copy result in common variable to result buffer. ! 2976: // Finish processing ! 2977: ! 2978: UINT BytesWritten = 0; ! 2979: UINT BytesNeeded = 0; ! 2980: UINT BytesLeft = NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength; ! 2981: PUCHAR InfoBuffer = (PUCHAR)(NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer); ! 2982: ! 2983: NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS; ! 2984: ! 2985: // ! 2986: // This variable holds result of query ! 2987: // ! 2988: ! 2989: ULONG GenericULong; ! 2990: ULONG MoveBytes = sizeof(ULONG) * 2 + sizeof(NDIS_OID); ! 2991: ! 2992: ! 2993: StatusToReturn = IbmtokQueryProtocolInformation( ! 2994: Adapter, ! 2995: NULL, ! 2996: NdisRequest->DATA.QUERY_INFORMATION.Oid, ! 2997: TRUE, ! 2998: InfoBuffer, ! 2999: BytesLeft, ! 3000: &BytesNeeded, ! 3001: &BytesWritten ! 3002: ); ! 3003: ! 3004: ! 3005: if (StatusToReturn == NDIS_STATUS_NOT_SUPPORTED){ ! 3006: ! 3007: StatusToReturn = NDIS_STATUS_SUCCESS; ! 3008: ! 3009: // ! 3010: // Switch on request type ! 3011: // ! 3012: ! 3013: switch (NdisRequest->DATA.QUERY_INFORMATION.Oid) { ! 3014: ! 3015: case OID_GEN_XMIT_OK: ! 3016: ! 3017: GenericULong = (ULONG)(Adapter->FramesTransmitted); ! 3018: ! 3019: break; ! 3020: ! 3021: case OID_GEN_RCV_OK: ! 3022: ! 3023: GenericULong = (ULONG)(Adapter->FramesReceived); ! 3024: ! 3025: break; ! 3026: ! 3027: case OID_GEN_XMIT_ERROR: ! 3028: ! 3029: GenericULong = (ULONG)(Adapter->FrameTransmitErrors); ! 3030: ! 3031: break; ! 3032: ! 3033: case OID_GEN_RCV_ERROR: ! 3034: ! 3035: GenericULong = (ULONG)(Adapter->FrameReceiveErrors); ! 3036: ! 3037: break; ! 3038: ! 3039: case OID_GEN_RCV_NO_BUFFER: ! 3040: ! 3041: GenericULong = (ULONG)(Adapter->ReceiveCongestionCount); ! 3042: ! 3043: break; ! 3044: ! 3045: case OID_802_5_LINE_ERRORS: ! 3046: ! 3047: GenericULong = (ULONG)(Adapter->LineErrors); ! 3048: ! 3049: break; ! 3050: ! 3051: case OID_802_5_LOST_FRAMES: ! 3052: ! 3053: GenericULong = (ULONG)(Adapter->LostFrames); ! 3054: ! 3055: break; ! 3056: ! 3057: case OID_802_5_LAST_OPEN_STATUS: ! 3058: ! 3059: GenericULong = (ULONG)(NDIS_STATUS_TOKEN_RING_OPEN_ERROR | ! 3060: (NDIS_STATUS)(Adapter->OpenErrorCode)); ! 3061: ! 3062: break; ! 3063: ! 3064: case OID_802_5_CURRENT_RING_STATUS: ! 3065: ! 3066: GenericULong = (ULONG)(Adapter->LastNotifyStatus); ! 3067: ! 3068: break; ! 3069: ! 3070: case OID_802_5_CURRENT_RING_STATE: ! 3071: ! 3072: GenericULong = (ULONG)(Adapter->CurrentRingState); ! 3073: ! 3074: break; ! 3075: ! 3076: default: ! 3077: ! 3078: StatusToReturn = NDIS_STATUS_INVALID_OID; ! 3079: ! 3080: break; ! 3081: ! 3082: } ! 3083: ! 3084: if (StatusToReturn == NDIS_STATUS_SUCCESS){ ! 3085: ! 3086: // ! 3087: // Check to make sure there is enough room in the ! 3088: // buffer to store the result. ! 3089: // ! 3090: ! 3091: if (BytesLeft >= sizeof(ULONG)) { ! 3092: ! 3093: // ! 3094: // Store the result. ! 3095: // ! 3096: ! 3097: IBMTOK_MOVE_MEMORY( ! 3098: (PVOID)InfoBuffer, ! 3099: (PVOID)(&GenericULong), ! 3100: sizeof(ULONG) ! 3101: ); ! 3102: ! 3103: BytesWritten += sizeof(ULONG); ! 3104: ! 3105: } else { ! 3106: ! 3107: BytesNeeded = sizeof(ULONG) - BytesLeft; ! 3108: ! 3109: StatusToReturn = NDIS_STATUS_INVALID_LENGTH; ! 3110: ! 3111: } ! 3112: ! 3113: } ! 3114: ! 3115: } ! 3116: ! 3117: NdisRequest->DATA.QUERY_INFORMATION.BytesWritten = BytesWritten; ! 3118: ! 3119: NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded = BytesNeeded; ! 3120: ! 3121: return(StatusToReturn); ! 3122: } ! 3123: ! 3124: STATIC ! 3125: NDIS_STATUS ! 3126: IbmtokQueryGlobalStatistics( ! 3127: IN NDIS_HANDLE MacAdapterContext, ! 3128: IN PNDIS_REQUEST NdisRequest ! 3129: ) ! 3130: ! 3131: /*++ ! 3132: ! 3133: Routine Description: ! 3134: ! 3135: The IbmtokQueryGlobalStatistics is used by the protocol to query ! 3136: global information about the MAC. ! 3137: ! 3138: Arguments: ! 3139: ! 3140: MacAdapterContext - The value associated with the adapter that is being ! 3141: opened when the MAC registered the adapter with NdisRegisterAdapter. ! 3142: ! 3143: NdisRequest - A structure which contains the request type (Query), ! 3144: an array of operations to perform, and an array for holding ! 3145: the results of the operations. ! 3146: ! 3147: Return Value: ! 3148: ! 3149: The function value is the status of the operation. ! 3150: ! 3151: --*/ ! 3152: ! 3153: { ! 3154: ! 3155: // ! 3156: // General Algorithm: ! 3157: // ! 3158: // ! 3159: // Check if a request is going to pend... ! 3160: // If so, pend the entire operation. ! 3161: // ! 3162: // Else ! 3163: // Fill in the request block. ! 3164: // ! 3165: // ! 3166: ! 3167: PIBMTOK_ADAPTER Adapter = PIBMTOK_ADAPTER_FROM_CONTEXT_HANDLE(MacAdapterContext); ! 3168: ! 3169: NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS; ! 3170: ! 3171: // ! 3172: // Check if a request is valid and going to pend... ! 3173: // If so, pend the entire operation. ! 3174: // ! 3175: ! 3176: NdisInterlockedAddUlong((PULONG)&Adapter->References, 1 ,&(Adapter->Lock)); ! 3177: ! 3178: // ! 3179: // Switch on request type ! 3180: // ! 3181: ! 3182: switch (NdisRequest->DATA.QUERY_INFORMATION.Oid) { ! 3183: case OID_GEN_SUPPORTED_LIST: ! 3184: case OID_GEN_HARDWARE_STATUS: ! 3185: case OID_GEN_MEDIA_SUPPORTED: ! 3186: case OID_GEN_MEDIA_IN_USE: ! 3187: case OID_GEN_MAXIMUM_LOOKAHEAD: ! 3188: case OID_GEN_MAXIMUM_FRAME_SIZE: ! 3189: case OID_GEN_MAXIMUM_TOTAL_SIZE: ! 3190: case OID_GEN_MAC_OPTIONS: ! 3191: case OID_GEN_LINK_SPEED: ! 3192: case OID_GEN_TRANSMIT_BUFFER_SPACE: ! 3193: case OID_GEN_RECEIVE_BUFFER_SPACE: ! 3194: case OID_GEN_TRANSMIT_BLOCK_SIZE: ! 3195: case OID_GEN_RECEIVE_BLOCK_SIZE: ! 3196: case OID_GEN_VENDOR_ID: ! 3197: case OID_GEN_DRIVER_VERSION: ! 3198: case OID_GEN_CURRENT_PACKET_FILTER: ! 3199: case OID_GEN_CURRENT_LOOKAHEAD: ! 3200: case OID_802_5_CURRENT_GROUP: ! 3201: case OID_802_5_LAST_OPEN_STATUS: ! 3202: case OID_802_5_CURRENT_RING_STATUS: ! 3203: case OID_802_5_CURRENT_RING_STATE: ! 3204: case OID_802_5_PERMANENT_ADDRESS: ! 3205: case OID_802_5_CURRENT_ADDRESS: ! 3206: case OID_802_5_CURRENT_FUNCTIONAL: ! 3207: break; ! 3208: ! 3209: case OID_GEN_XMIT_OK: ! 3210: case OID_GEN_RCV_OK: ! 3211: case OID_GEN_XMIT_ERROR: ! 3212: case OID_GEN_RCV_ERROR: ! 3213: case OID_GEN_RCV_NO_BUFFER: ! 3214: case OID_802_5_LINE_ERRORS: ! 3215: case OID_802_5_LOST_FRAMES: ! 3216: ! 3217: StatusToReturn = NDIS_STATUS_PENDING; ! 3218: ! 3219: break; ! 3220: ! 3221: default: ! 3222: ! 3223: StatusToReturn = NDIS_STATUS_INVALID_OID; ! 3224: ! 3225: break; ! 3226: } ! 3227: ! 3228: if (StatusToReturn == NDIS_STATUS_PENDING) { ! 3229: ! 3230: // ! 3231: // Build a pending operation ! 3232: // ! 3233: ! 3234: PIBMTOK_PEND_DATA PendOp = PIBMTOK_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest); ! 3235: ! 3236: PendOp->Next = NULL; ! 3237: PendOp->COMMAND.NDIS.STATISTICS.ReadLogPending = FALSE; ! 3238: ! 3239: NdisAcquireSpinLock(&Adapter->Lock); ! 3240: ! 3241: if (Adapter->PendQueue == NULL){ ! 3242: ! 3243: Adapter->PendQueue = Adapter->EndOfPendQueue = PendOp; ! 3244: ! 3245: } else { ! 3246: ! 3247: Adapter->EndOfPendQueue->Next = PendOp; ! 3248: ! 3249: } ! 3250: ! 3251: ! 3252: // ! 3253: // It is now in the pend ! 3254: // queue so we should start that up. ! 3255: // ! 3256: ! 3257: IbmtokProcessSrbRequests(Adapter); ! 3258: ! 3259: NdisReleaseSpinLock(&Adapter->Lock); ! 3260: ! 3261: // ! 3262: // Defer subtracting from Adapter->Reference until the ! 3263: // request completes (see IbmtokFinishPendQueueOp()). ! 3264: // ! 3265: ! 3266: return(StatusToReturn); ! 3267: ! 3268: } ! 3269: ! 3270: if (StatusToReturn == NDIS_STATUS_SUCCESS){ ! 3271: ! 3272: StatusToReturn = IbmtokFillInGlobalData(Adapter, NdisRequest); ! 3273: ! 3274: } ! 3275: ! 3276: NdisAcquireSpinLock(&Adapter->Lock); ! 3277: ! 3278: IBMTOK_DO_DEFERRED(Adapter); ! 3279: ! 3280: return(StatusToReturn); ! 3281: } ! 3282: ! 3283: STATIC ! 3284: NDIS_STATUS ! 3285: IbmtokReset( ! 3286: IN NDIS_HANDLE MacBindingHandle ! 3287: ) ! 3288: ! 3289: /*++ ! 3290: ! 3291: Routine Description: ! 3292: ! 3293: The IbmtokReset request instructs the MAC to issue a hardware reset ! 3294: to the network adapter. The MAC also resets its software state. See ! 3295: the description of NdisReset for a detailed description of this request. ! 3296: ! 3297: Arguments: ! 3298: ! 3299: MacBindingHandle - The context value returned by the MAC when the ! 3300: adapter was opened. In reality, it is a pointer to IBMTOK_OPEN. ! 3301: ! 3302: Return Value: ! 3303: ! 3304: The function value is the status of the operation. ! 3305: ! 3306: ! 3307: --*/ ! 3308: ! 3309: { ! 3310: ! 3311: // ! 3312: // Holds the status that should be returned to the caller. ! 3313: // ! 3314: NDIS_STATUS StatusToReturn = NDIS_STATUS_PENDING; ! 3315: ! 3316: PIBMTOK_ADAPTER Adapter = ! 3317: PIBMTOK_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle); ! 3318: ! 3319: PIBMTOK_OPEN Open; ! 3320: ! 3321: // ! 3322: // Hold the locks while we update the reference counts on the ! 3323: // adapter and the open. ! 3324: // ! 3325: ! 3326: NdisAcquireSpinLock(&Adapter->Lock); ! 3327: Open = PIBMTOK_OPEN_FROM_BINDING_HANDLE(MacBindingHandle); ! 3328: ! 3329: Adapter->References++; ! 3330: ! 3331: if (Adapter->ResetInProgress) { ! 3332: ! 3333: StatusToReturn = NDIS_STATUS_RESET_IN_PROGRESS; ! 3334: ! 3335: } else if (Adapter->AdapterNotOpen) { ! 3336: ! 3337: StatusToReturn = NDIS_STATUS_FAILURE; ! 3338: ! 3339: } else { ! 3340: ! 3341: if (!Open->BindingShuttingDown) { ! 3342: ! 3343: Open->References++; ! 3344: IbmtokSetupForReset( ! 3345: Adapter, ! 3346: PIBMTOK_OPEN_FROM_BINDING_HANDLE(MacBindingHandle) ! 3347: ); ! 3348: Open->References--; ! 3349: ! 3350: } else { ! 3351: ! 3352: StatusToReturn = NDIS_STATUS_CLOSING; ! 3353: ! 3354: } ! 3355: ! 3356: } ! 3357: ! 3358: // ! 3359: // This macro assumes it is called with the lock held, ! 3360: // and releases it. ! 3361: // ! 3362: ! 3363: IBMTOK_DO_DEFERRED(Adapter); ! 3364: return StatusToReturn; ! 3365: ! 3366: } ! 3367: ! 3368: STATIC ! 3369: NDIS_STATUS ! 3370: IbmtokChangeFilter( ! 3371: IN UINT OldFilterClasses, ! 3372: IN UINT NewFilterClasses, ! 3373: IN NDIS_HANDLE MacBindingHandle, ! 3374: IN PNDIS_REQUEST NdisRequest, ! 3375: IN BOOLEAN Set ! 3376: ) ! 3377: ! 3378: /*++ ! 3379: ! 3380: Routine Description: ! 3381: ! 3382: Action routine that will get called when a particular filter ! 3383: class is first used or last cleared. ! 3384: ! 3385: NOTE: This routine assumes that it is called with the lock ! 3386: acquired. ! 3387: ! 3388: Arguments: ! 3389: ! 3390: OldFilterClasses - The values of the class filter before it ! 3391: was changed. ! 3392: ! 3393: NewFilterClasses - The current value of the class filter ! 3394: ! 3395: MacBindingHandle - The context value returned by the MAC when the ! 3396: adapter was opened. In reality, it is a pointer to IBMTOK_OPEN. ! 3397: ! 3398: Set - If true the change resulted from a set, otherwise the ! 3399: change resulted from a open closing. ! 3400: ! 3401: Return Value: ! 3402: ! 3403: None. ! 3404: ! 3405: --*/ ! 3406: ! 3407: { ! 3408: ! 3409: ! 3410: PIBMTOK_ADAPTER Adapter = PIBMTOK_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle); ! 3411: ! 3412: // ! 3413: // The open that made this request. ! 3414: // ! 3415: PIBMTOK_OPEN Open = PIBMTOK_OPEN_FROM_BINDING_HANDLE(MacBindingHandle); ! 3416: ! 3417: // ! 3418: // Holds the change that should be returned to the filtering package. ! 3419: // ! 3420: NDIS_STATUS StatusOfChange; ! 3421: ! 3422: if (NdisRequest == NULL) { ! 3423: ! 3424: NdisRequest = &(Open->CloseRequestChangeFilter); ! 3425: ! 3426: NdisRequest->RequestType = NdisRequestClose; ! 3427: ! 3428: ! 3429: } ! 3430: ! 3431: ! 3432: if (Adapter->ResetInProgress) { ! 3433: ! 3434: StatusOfChange = NDIS_STATUS_RESET_IN_PROGRESS; ! 3435: ! 3436: } else { ! 3437: ! 3438: // ! 3439: // The whole purpose of this routine is to determine whether ! 3440: // the filtering changes need to result in the hardware being ! 3441: // reset. ! 3442: // ! 3443: ! 3444: ASSERT(OldFilterClasses != NewFilterClasses); ! 3445: ! 3446: #if DBG ! 3447: if (IbmtokDbg) DbgPrint("IBMTOK: Change filter\n"); ! 3448: #endif ! 3449: ! 3450: if (NewFilterClasses & ! 3451: (NDIS_PACKET_TYPE_PROMISCUOUS | NDIS_PACKET_TYPE_SOURCE_ROUTING)) { ! 3452: ! 3453: // ! 3454: // The adapter cannot support promiscuous mode, or ! 3455: // source routing which implies promiscuous. ! 3456: // ! 3457: ! 3458: StatusOfChange = NDIS_STATUS_FAILURE; ! 3459: ! 3460: } else { ! 3461: ! 3462: // ! 3463: // Queue this request. ! 3464: // ! 3465: ! 3466: PIBMTOK_PEND_DATA PendOp = PIBMTOK_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest); ! 3467: ! 3468: // ! 3469: // Store open block. ! 3470: // ! 3471: ! 3472: PendOp->COMMAND.NDIS.SET_FILTER.Open = Open; ! 3473: ! 3474: // ! 3475: // Hold new Filter value ! 3476: // ! 3477: ! 3478: if (PendOp->RequestType == NdisRequestClose){ ! 3479: ! 3480: PendOp->COMMAND.NDIS.CLOSE.NewFilterValue = NewFilterClasses; ! 3481: ! 3482: } else { ! 3483: ! 3484: PendOp->COMMAND.NDIS.SET_FILTER.NewFilterValue = NewFilterClasses; ! 3485: ! 3486: } ! 3487: ! 3488: ! 3489: // ! 3490: // Insert into queue. ! 3491: // ! 3492: ! 3493: PendOp->Next = NULL; ! 3494: ! 3495: if (Adapter->PendQueue == NULL) { ! 3496: ! 3497: Adapter->PendQueue = Adapter->EndOfPendQueue = PendOp; ! 3498: ! 3499: } else { ! 3500: ! 3501: Adapter->EndOfPendQueue->Next = PendOp; ! 3502: ! 3503: } ! 3504: ! 3505: Open->References++; ! 3506: ! 3507: StatusOfChange = NDIS_STATUS_PENDING; ! 3508: ! 3509: ! 3510: } ! 3511: ! 3512: } ! 3513: ! 3514: return StatusOfChange; ! 3515: ! 3516: } ! 3517: ! 3518: STATIC ! 3519: NDIS_STATUS ! 3520: IbmtokChangeAddress( ! 3521: IN TR_FUNCTIONAL_ADDRESS OldFunctionalAddress, ! 3522: IN TR_FUNCTIONAL_ADDRESS NewFunctionalAddress, ! 3523: IN NDIS_HANDLE MacBindingHandle, ! 3524: IN PNDIS_REQUEST NdisRequest, ! 3525: IN BOOLEAN Set ! 3526: ) ! 3527: ! 3528: ! 3529: /*++ ! 3530: ! 3531: Routine Description: ! 3532: ! 3533: Action routine that will get called when an address is added to ! 3534: the filter that wasn't referenced by any other open binding. ! 3535: ! 3536: NOTE: This routine assumes that it is called with the lock ! 3537: acquired. ! 3538: ! 3539: Arguments: ! 3540: ! 3541: OldFunctionalAddress - The previous functional address. ! 3542: ! 3543: NewFunctionalAddress - The new functional address. ! 3544: ! 3545: MacBindingHandle - The context value returned by the MAC when the ! 3546: adapter was opened. In reality, it is a pointer to IBMTOK_OPEN. ! 3547: ! 3548: NdisRequest - A pointer to the Request that submitted the set command. ! 3549: ! 3550: Set - If true the change resulted from a set, otherwise the ! 3551: change resulted from a open closing. ! 3552: ! 3553: Return Value: ! 3554: ! 3555: None. ! 3556: ! 3557: ! 3558: --*/ ! 3559: ! 3560: { ! 3561: ! 3562: PIBMTOK_ADAPTER Adapter = PIBMTOK_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle); ! 3563: ! 3564: // ! 3565: // Holds the status that should be returned to the filtering package. ! 3566: // ! 3567: NDIS_STATUS StatusOfChange; ! 3568: ! 3569: // ! 3570: // The open that made this request. ! 3571: // ! 3572: PIBMTOK_OPEN Open = PIBMTOK_OPEN_FROM_BINDING_HANDLE(MacBindingHandle); ! 3573: ! 3574: #if DBG ! 3575: if (IbmtokDbg) { ! 3576: DbgPrint("IBMTOK: Queueing:\n"); ! 3577: DbgPrint(" Req : 0x%x\n", NdisRequest); ! 3578: DbgPrint(" Old : 0x%x\n", OldFunctionalAddress); ! 3579: DbgPrint(" New : 0x%x\n", NewFunctionalAddress); ! 3580: } ! 3581: #endif ! 3582: ! 3583: // Check to see if the device is already resetting. If it is ! 3584: // then reject this change. ! 3585: // ! 3586: ! 3587: if (NdisRequest == NULL) { ! 3588: ! 3589: NdisRequest = &(Open->CloseRequestChangeAddress); ! 3590: ! 3591: NdisRequest->RequestType = NdisRequestGeneric2; // Close, set address ! 3592: ! 3593: } ! 3594: ! 3595: ! 3596: if (Adapter->ResetInProgress) { ! 3597: ! 3598: #if DBG ! 3599: if (IbmtokDbg) { ! 3600: DbgPrint("IBMTOK: ResetInProgress\n\n"); ! 3601: } ! 3602: #endif ! 3603: ! 3604: StatusOfChange = NDIS_STATUS_RESET_IN_PROGRESS; ! 3605: ! 3606: } else { ! 3607: ! 3608: // ! 3609: // Queue this request. ! 3610: // ! 3611: ! 3612: PIBMTOK_PEND_DATA PendOp = PIBMTOK_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest); ! 3613: ! 3614: ! 3615: // ! 3616: // Store open block. ! 3617: // ! 3618: ! 3619: PendOp->COMMAND.NDIS.SET_ADDRESS.Open = Open; ! 3620: ! 3621: // ! 3622: // Hold new Address value ! 3623: // ! 3624: ! 3625: PendOp->COMMAND.NDIS.SET_ADDRESS.NewAddressValue = NewFunctionalAddress; ! 3626: ! 3627: ! 3628: // ! 3629: // Insert into queue. ! 3630: // ! 3631: ! 3632: PendOp->Next = NULL; ! 3633: ! 3634: if (Adapter->PendQueue == NULL) { ! 3635: ! 3636: Adapter->PendQueue = Adapter->EndOfPendQueue = PendOp; ! 3637: ! 3638: } else { ! 3639: ! 3640: Adapter->EndOfPendQueue->Next = PendOp; ! 3641: ! 3642: } ! 3643: ! 3644: Open->References++; ! 3645: ! 3646: StatusOfChange = NDIS_STATUS_PENDING; ! 3647: ! 3648: } ! 3649: ! 3650: return StatusOfChange; ! 3651: ! 3652: } ! 3653: ! 3654: STATIC ! 3655: NDIS_STATUS ! 3656: IbmtokChangeGroupAddress( ! 3657: IN TR_FUNCTIONAL_ADDRESS OldGroupAddress, ! 3658: IN TR_FUNCTIONAL_ADDRESS NewGroupAddress, ! 3659: IN NDIS_HANDLE MacBindingHandle, ! 3660: IN PNDIS_REQUEST NdisRequest, ! 3661: IN BOOLEAN Set ! 3662: ) ! 3663: ! 3664: /*++ ! 3665: ! 3666: Routine Description: ! 3667: ! 3668: Action routine that will get called when a group address is to ! 3669: be changed. ! 3670: ! 3671: NOTE: This routine assumes that it is called with the lock ! 3672: acquired. ! 3673: ! 3674: Arguments: ! 3675: ! 3676: OldGroupAddress - The previous group address. ! 3677: ! 3678: NewGroupAddress - The new group address. ! 3679: ! 3680: MacBindingHandle - The context value returned by the MAC when the ! 3681: adapter was opened. In reality, it is a pointer to IBMTOK_OPEN. ! 3682: ! 3683: NdisRequest - A pointer to the Request that submitted the set command. ! 3684: ! 3685: Set - If true the change resulted from a set, otherwise the ! 3686: change resulted from a open closing. ! 3687: ! 3688: Return Value: ! 3689: ! 3690: None. ! 3691: ! 3692: ! 3693: --*/ ! 3694: ! 3695: { ! 3696: ! 3697: PIBMTOK_ADAPTER Adapter = PIBMTOK_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle); ! 3698: ! 3699: // ! 3700: // Holds the status that should be returned to the filtering package. ! 3701: // ! 3702: NDIS_STATUS StatusOfChange; ! 3703: ! 3704: // ! 3705: // The open that made this request. ! 3706: // ! 3707: PIBMTOK_OPEN Open = PIBMTOK_OPEN_FROM_BINDING_HANDLE(MacBindingHandle); ! 3708: ! 3709: ! 3710: if (NdisRequest == NULL) { ! 3711: ! 3712: NdisRequest = &(Open->CloseRequestChangeGroupAddress); ! 3713: ! 3714: NdisRequest->RequestType = NdisRequestGeneric3; // Close, set group address ! 3715: ! 3716: } ! 3717: ! 3718: ! 3719: // ! 3720: // Check to see if the device is already resetting. If it is ! 3721: // then reject this change. ! 3722: // ! 3723: ! 3724: if (Adapter->ResetInProgress) { ! 3725: ! 3726: StatusOfChange = NDIS_STATUS_RESET_IN_PROGRESS; ! 3727: ! 3728: } else { ! 3729: ! 3730: // ! 3731: // Queue this request. ! 3732: // ! 3733: ! 3734: PIBMTOK_PEND_DATA PendOp = PIBMTOK_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest); ! 3735: ! 3736: ! 3737: // ! 3738: // Store open block. ! 3739: // ! 3740: ! 3741: PendOp->COMMAND.NDIS.SET_ADDRESS.Open = Open; ! 3742: ! 3743: // ! 3744: // Hold new Address value ! 3745: // ! 3746: ! 3747: PendOp->COMMAND.NDIS.SET_ADDRESS.NewAddressValue = NewGroupAddress; ! 3748: ! 3749: ! 3750: // ! 3751: // Insert into queue. ! 3752: // ! 3753: ! 3754: PendOp->Next = NULL; ! 3755: ! 3756: if (Adapter->PendQueue == NULL) { ! 3757: ! 3758: Adapter->PendQueue = Adapter->EndOfPendQueue = PendOp; ! 3759: ! 3760: } else { ! 3761: ! 3762: Adapter->EndOfPendQueue->Next = PendOp; ! 3763: ! 3764: } ! 3765: ! 3766: Open->References++; ! 3767: ! 3768: StatusOfChange = NDIS_STATUS_PENDING; ! 3769: ! 3770: } ! 3771: ! 3772: return StatusOfChange; ! 3773: ! 3774: } ! 3775: ! 3776: STATIC ! 3777: VOID ! 3778: IbmtokCloseAction( ! 3779: IN NDIS_HANDLE MacBindingHandle ! 3780: ) ! 3781: ! 3782: /*++ ! 3783: ! 3784: Routine Description: ! 3785: ! 3786: Action routine that will get called when a particular binding ! 3787: was closed while it was indicating through NdisIndicateReceive ! 3788: ! 3789: All this routine needs to do is to decrement the reference count ! 3790: of the binding. ! 3791: ! 3792: NOTE: This routine assumes that it is called with the lock acquired. ! 3793: ! 3794: Arguments: ! 3795: ! 3796: MacBindingHandle - The context value returned by the MAC when the ! 3797: adapter was opened. In reality, it is a pointer to IBMTOK_OPEN. ! 3798: ! 3799: Return Value: ! 3800: ! 3801: None. ! 3802: ! 3803: ! 3804: --*/ ! 3805: ! 3806: { ! 3807: ! 3808: PIBMTOK_OPEN_FROM_BINDING_HANDLE(MacBindingHandle)->References--; ! 3809: ! 3810: } ! 3811: ! 3812: extern ! 3813: VOID ! 3814: IbmtokStartAdapterReset( ! 3815: IN PIBMTOK_ADAPTER Adapter ! 3816: ) ! 3817: ! 3818: /*++ ! 3819: ! 3820: Routine Description: ! 3821: ! 3822: This is the first phase of resetting the adapter hardware. ! 3823: ! 3824: It makes the following assumptions: ! 3825: ! 3826: 1) That the hardware has been stopped. ! 3827: ! 3828: 2) That it can not be preempted. ! 3829: ! 3830: 3) That no other adapter activity can occur. ! 3831: ! 3832: When this routine is finished all of the adapter information ! 3833: will be as if the driver was just initialized. ! 3834: ! 3835: Arguments: ! 3836: ! 3837: Adapter - The adapter whose hardware is to be reset. ! 3838: ! 3839: Return Value: ! 3840: ! 3841: None. ! 3842: ! 3843: --*/ ! 3844: { ! 3845: ! 3846: // ! 3847: // Disable these so no pending interrupts ! 3848: // will fire. ! 3849: // ! 3850: CLEAR_ISRP_BITS(Adapter); ! 3851: ! 3852: // ! 3853: // OK, do the reset as detailed in the Tech Ref... ! 3854: // ! 3855: ! 3856: WRITE_ADAPTER_PORT(Adapter, RESET_LATCH, 0); ! 3857: ! 3858: NdisStallExecution(50000); ! 3859: ! 3860: WRITE_ADAPTER_PORT(Adapter, RESET_RELEASE, 0); ! 3861: ! 3862: // ! 3863: // Have to write this now to enable Shared RAM paging. ! 3864: // ! 3865: if (Adapter->SharedRamPaging) { ! 3866: ! 3867: WRITE_ADAPTER_REGISTER(Adapter, SRPR_LOW, 0xc0); ! 3868: ! 3869: } ! 3870: ! 3871: ! 3872: ! 3873: // ! 3874: // If this is a PC I/O Bus.... ! 3875: // Set up the shared RAM to be right after the MMIO. ! 3876: // ! 3877: ! 3878: if (Adapter->UsingPcIoBus){ ! 3879: WRITE_ADAPTER_REGISTER(Adapter, RRR_LOW, Adapter->RrrLowValue); ! 3880: } ! 3881: ! 3882: ! 3883: ! 3884: // ! 3885: // Allow the reset complete interrupt to be ! 3886: // serviced correctly. ! 3887: // ! 3888: SET_INTERRUPT_RESET_FLAG(Adapter); ! 3889: ! 3890: // ! 3891: // Enable card interrupts to get the reset interrupt. ! 3892: // ! 3893: ! 3894: WRITE_ADAPTER_REGISTER(Adapter, ISRP_LOW, ! 3895: ISRP_LOW_NO_CHANNEL_CHECK | ISRP_LOW_INTERRUPT_ENABLE); ! 3896: ! 3897: ! 3898: // ! 3899: // The remaining processing is done in the ! 3900: // interrupt handler. ! 3901: // ! 3902: ! 3903: ! 3904: ! 3905: // ! 3906: // OK, now abort pending requests before we nuke ! 3907: // everything. ! 3908: // ! 3909: ! 3910: NdisDprAcquireSpinLock (&Adapter->Lock); ! 3911: ! 3912: IbmtokAbortSends (Adapter, NDIS_STATUS_REQUEST_ABORTED); ! 3913: ! 3914: NdisDprReleaseSpinLock (&Adapter->Lock); ! 3915: ! 3916: } ! 3917: ! 3918: extern ! 3919: VOID ! 3920: IbmtokFinishAdapterReset( ! 3921: IN PIBMTOK_ADAPTER Adapter ! 3922: ) ! 3923: ! 3924: /*++ ! 3925: ! 3926: Routine Description: ! 3927: ! 3928: Called by HandleResetStaging when the last piece ! 3929: of the adapter reset is complete and normal ! 3930: operation can resume. ! 3931: ! 3932: Called with the lock held and returns with it held. ! 3933: ! 3934: Arguments: ! 3935: ! 3936: Adapter - The adapter that the reset is for. ! 3937: ! 3938: Return Value: ! 3939: ! 3940: None. ! 3941: ! 3942: --*/ ! 3943: ! 3944: { ! 3945: PLIST_ENTRY CurrentLink; ! 3946: PIBMTOK_OPEN TempOpen; ! 3947: ! 3948: ! 3949: SetResetVariables(Adapter); ! 3950: ! 3951: if (Adapter->UnpluggedResetInProgress) { ! 3952: Adapter->UnpluggedResetInProgress = FALSE; ! 3953: Adapter->Unplugged = FALSE; ! 3954: Adapter->LobeWireFaultIndicated = FALSE; ! 3955: } ! 3956: ! 3957: Adapter->ResetInProgress = FALSE; ! 3958: Adapter->ResetInterruptAllowed = FALSE; ! 3959: Adapter->ResetInterruptHasArrived = FALSE; ! 3960: Adapter->NotAcceptingRequests = FALSE; ! 3961: ! 3962: // ! 3963: // Get any interrupts that have been deferred ! 3964: // while NotAcceptingRequests was TRUE. ! 3965: // ! 3966: IbmtokForceAdapterInterrupt(Adapter); ! 3967: ! 3968: if (Adapter->ResettingOpen != NULL) { ! 3969: ! 3970: PIBMTOK_OPEN ResettingOpen = Adapter->ResettingOpen; ! 3971: ! 3972: // ! 3973: // Indicate reset complete to everybody ! 3974: // ! 3975: ! 3976: CurrentLink = Adapter->OpenBindings.Flink; ! 3977: ! 3978: while (CurrentLink != &(Adapter->OpenBindings)){ ! 3979: ! 3980: TempOpen = CONTAINING_RECORD( ! 3981: CurrentLink, ! 3982: IBMTOK_OPEN, ! 3983: OpenList ! 3984: ); ! 3985: ! 3986: NdisReleaseSpinLock(&Adapter->Lock); ! 3987: ! 3988: NdisIndicateStatus(TempOpen->NdisBindingContext, ! 3989: NDIS_STATUS_RESET_END, ! 3990: NULL, ! 3991: 0 ! 3992: ); ! 3993: ! 3994: NdisIndicateStatusComplete(TempOpen->NdisBindingContext); ! 3995: ! 3996: NdisAcquireSpinLock(&Adapter->Lock); ! 3997: ! 3998: CurrentLink = CurrentLink->Flink; ! 3999: ! 4000: } ! 4001: ! 4002: // ! 4003: // Decrement the reference count that was incremented ! 4004: // in SetupForReset. ! 4005: // ! 4006: ResettingOpen->References--; ! 4007: ! 4008: NdisReleaseSpinLock(&Adapter->Lock); ! 4009: ! 4010: NdisCompleteReset( ! 4011: ResettingOpen->NdisBindingContext, ! 4012: NDIS_STATUS_SUCCESS ! 4013: ); ! 4014: ! 4015: NdisAcquireSpinLock(&Adapter->Lock); ! 4016: ! 4017: } ! 4018: ! 4019: } ! 4020: ! 4021: STATIC ! 4022: VOID ! 4023: IbmtokSetupRegistersAndInit( ! 4024: IN PIBMTOK_ADAPTER Adapter ! 4025: ) ! 4026: ! 4027: /*++ ! 4028: ! 4029: Routine Description: ! 4030: ! 4031: It is this routines responsibility to make sure that the ! 4032: initialization block is filled and the chip is initialized ! 4033: *but not* started. ! 4034: ! 4035: NOTE: This routine assumes that it is called with the lock ! 4036: acquired OR that only a single thread of execution is working ! 4037: with this particular adapter. ! 4038: ! 4039: Arguments: ! 4040: ! 4041: Adapter - The adapter whose hardware is to be initialized. ! 4042: ! 4043: Return Value: ! 4044: ! 4045: None. ! 4046: ! 4047: --*/ ! 4048: { ! 4049: ! 4050: // ! 4051: // Enable card interrupts to get the reset interrupt. ! 4052: // ! 4053: ! 4054: WRITE_ADAPTER_REGISTER(Adapter, ISRP_LOW, ! 4055: ISRP_LOW_NO_CHANNEL_CHECK | ISRP_LOW_INTERRUPT_ENABLE); ! 4056: ! 4057: // ! 4058: // Set the timer to 10 milliseconds...this seems to ! 4059: // be necessary for proper operation (according to ! 4060: // ChandanC). ! 4061: // ! 4062: ! 4063: WRITE_ADAPTER_REGISTER(Adapter, TVR_HIGH, 0x01); ! 4064: ! 4065: ! 4066: // ! 4067: // Start the timer and set it to reload, but not to ! 4068: // interrupt us (TCR_LOW_INTERRUPT_MASK is off). This ! 4069: // will still cause bit 4 in the ISRP Low to go on, ! 4070: // but it won't cause an interrupt. ! 4071: // ! 4072: ! 4073: #if 0 ! 4074: WRITE_ADAPTER_REGISTER(Adapter, TCR_LOW, ! 4075: // TCR_LOW_INTERRUPT_MASK | ! 4076: TCR_LOW_RELOAD_TIMER | TCR_LOW_COUNTER_ENABLE); ! 4077: #endif ! 4078: WRITE_ADAPTER_REGISTER(Adapter, TCR_LOW, 0); ! 4079: ! 4080: ! 4081: ! 4082: // ! 4083: // If this is a PC I/O Bus... ! 4084: // Set up the shared RAM to be right after the MMIO. ! 4085: // ! 4086: ! 4087: if (Adapter->UsingPcIoBus) { ! 4088: WRITE_ADAPTER_REGISTER(Adapter, RRR_LOW, Adapter->RrrLowValue); ! 4089: } ! 4090: ! 4091: ! 4092: // ! 4093: // The remaining initialization processing is done in ! 4094: // the interrupt handler. ! 4095: // ! 4096: ! 4097: } ! 4098: ! 4099: VOID ! 4100: IbmtokSetupForReset( ! 4101: IN PIBMTOK_ADAPTER Adapter, ! 4102: IN PIBMTOK_OPEN Open ! 4103: ) ! 4104: ! 4105: /*++ ! 4106: ! 4107: Routine Description: ! 4108: ! 4109: This routine is used to fill in the who and why a reset is ! 4110: being set up as well as setting the appropriate fields in the ! 4111: adapter. ! 4112: ! 4113: NOTE: This routine must be called with the lock acquired. ! 4114: ! 4115: Arguments: ! 4116: ! 4117: Adapter - The adapter whose hardware is to be initialized. ! 4118: ! 4119: Open - A (possibly NULL) pointer to an sonic open structure. ! 4120: The reason it could be null is if the adapter is initiating the ! 4121: reset on its own. ! 4122: ! 4123: Return Value: ! 4124: ! 4125: None. ! 4126: ! 4127: --*/ ! 4128: { ! 4129: // ! 4130: // Notify of reset start ! 4131: // ! 4132: ! 4133: PLIST_ENTRY CurrentLink; ! 4134: PIBMTOK_OPEN TempOpen; ! 4135: ! 4136: if (Open != NULL) { ! 4137: ! 4138: CurrentLink = Adapter->OpenBindings.Flink; ! 4139: ! 4140: while (CurrentLink != &(Adapter->OpenBindings)){ ! 4141: ! 4142: TempOpen = CONTAINING_RECORD( ! 4143: CurrentLink, ! 4144: IBMTOK_OPEN, ! 4145: OpenList ! 4146: ); ! 4147: ! 4148: NdisReleaseSpinLock(&Adapter->Lock); ! 4149: ! 4150: NdisIndicateStatus(TempOpen->NdisBindingContext, ! 4151: NDIS_STATUS_RESET_START, ! 4152: NULL, ! 4153: 0 ! 4154: ); ! 4155: ! 4156: NdisAcquireSpinLock(&Adapter->Lock); ! 4157: ! 4158: CurrentLink = CurrentLink->Flink; ! 4159: ! 4160: } ! 4161: } ! 4162: ! 4163: ! 4164: Adapter->ResetInProgress = TRUE; ! 4165: Adapter->NotAcceptingRequests = TRUE; ! 4166: ! 4167: Adapter->ResettingOpen = Open; ! 4168: ! 4169: // ! 4170: // This will go to 1 when StartAdapterReset is called. ! 4171: // ! 4172: Adapter->CurrentResetStage = 0; ! 4173: ! 4174: // ! 4175: // If there is a valid open we should up the reference count ! 4176: // so that the open can't be deleted before we indicate that ! 4177: // their request is finished. ! 4178: // ! 4179: ! 4180: if (Open != NULL) { ! 4181: ! 4182: Open->References++; ! 4183: ! 4184: } ! 4185: ! 4186: } ! 4187: ! 4188: NDIS_STATUS ! 4189: IbmtokAddAdapter( ! 4190: IN NDIS_HANDLE MacMacContext, ! 4191: IN NDIS_HANDLE ConfigurationHandle, ! 4192: IN PNDIS_STRING AdapterName ! 4193: ) ! 4194: ! 4195: /*++ ! 4196: ! 4197: Routine Description: ! 4198: ! 4199: This routine is used to initialize each adapter card/chip. ! 4200: ! 4201: Arguments: ! 4202: ! 4203: see NDIS 3.0 spec... ! 4204: ! 4205: Return Value: ! 4206: ! 4207: ! 4208: NDIS_STATUS_SUCCESS - Adapter was successfully added. ! 4209: NDIS_STATUS_FAILURE - Adapter was not added, also MAC deregistered. ! 4210: ! 4211: --*/ ! 4212: ! 4213: { ! 4214: PIBMTOK_ADAPTER Adapter; ! 4215: ! 4216: NDIS_HANDLE ConfigHandle; ! 4217: PNDIS_CONFIGURATION_PARAMETER ReturnedValue; ! 4218: NDIS_STRING BusTypeStr = NDIS_STRING_CONST("BusType"); ! 4219: NDIS_STRING IOAddressStr = NDIS_STRING_CONST("IoBaseAddress"); ! 4220: NDIS_STRING NetworkAddressStr = NDIS_STRING_CONST("NetworkAddress"); ! 4221: NDIS_STRING PacketSizeStr = NDIS_STRING_CONST("MaximumPacketSize"); ! 4222: ! 4223: NDIS_STATUS Status = NDIS_STATUS_SUCCESS; ! 4224: ! 4225: BOOLEAN PrimaryAdapter = TRUE; ! 4226: BOOLEAN ConfigError = FALSE; ! 4227: BOOLEAN McaCard = FALSE; ! 4228: ! 4229: UINT SlotNumber; ! 4230: NDIS_MCA_POS_DATA McaData; ! 4231: ! 4232: PVOID NetAddress; ! 4233: ULONG Length; ! 4234: ! 4235: // ! 4236: // Allocate the Adapter block. ! 4237: // ! 4238: ! 4239: if (IBMTOK_ALLOC_PHYS(&Adapter, sizeof(IBMTOK_ADAPTER)) != ! 4240: NDIS_STATUS_SUCCESS) { ! 4241: ! 4242: return(NDIS_STATUS_RESOURCES); ! 4243: ! 4244: } ! 4245: ! 4246: ! 4247: IBMTOK_ZERO_MEMORY( ! 4248: Adapter, ! 4249: sizeof(IBMTOK_ADAPTER) ! 4250: ); ! 4251: ! 4252: Adapter->MaxTransmittablePacket = 17960; ! 4253: Adapter->CurrentRingState = NdisRingStateClosed; ! 4254: ! 4255: Adapter->NdisMacHandle = ((PIBMTOK_MAC)MacMacContext)->NdisMacHandle; ! 4256: ! 4257: ! 4258: NdisOpenConfiguration( ! 4259: &Status, ! 4260: &ConfigHandle, ! 4261: ConfigurationHandle ! 4262: ); ! 4263: ! 4264: if (Status != NDIS_STATUS_SUCCESS) { ! 4265: ! 4266: IBMTOK_FREE_PHYS(Adapter, sizeof(IBMTOK_ADAPTER)); ! 4267: ! 4268: return NDIS_STATUS_FAILURE; ! 4269: ! 4270: } ! 4271: ! 4272: // ! 4273: // Read Bus Type ! 4274: // ! 4275: ! 4276: NdisReadConfiguration( ! 4277: &Status, ! 4278: &ReturnedValue, ! 4279: ConfigHandle, ! 4280: &BusTypeStr, ! 4281: NdisParameterHexInteger ! 4282: ); ! 4283: ! 4284: if (Status == NDIS_STATUS_SUCCESS) { ! 4285: ! 4286: if (ReturnedValue->ParameterData.IntegerData == (ULONG)NdisInterfaceMca) { ! 4287: ! 4288: McaCard = TRUE; ! 4289: ! 4290: } ! 4291: ! 4292: } ! 4293: ! 4294: // ! 4295: // Get I/O Address ! 4296: // ! 4297: ! 4298: if (McaCard) { ! 4299: ! 4300: // ! 4301: // Get I/O Address from Mca Pos info. ! 4302: // ! 4303: ! 4304: NdisReadMcaPosInformation( ! 4305: &Status, ! 4306: ConfigurationHandle, ! 4307: &SlotNumber, ! 4308: &McaData ! 4309: ); ! 4310: ! 4311: if (Status != NDIS_STATUS_SUCCESS) { ! 4312: ! 4313: ConfigError = TRUE; ! 4314: goto RegisterAdapter; ! 4315: ! 4316: } ! 4317: ! 4318: // ! 4319: // Now interperet the data ! 4320: // ! 4321: ! 4322: switch (McaData.PosData2 & 0x1) { ! 4323: case 0x00: ! 4324: Adapter->IbmtokPortAddress = PRIMARY_ADAPTER_OFFSET; ! 4325: break; ! 4326: ! 4327: case 0x01: ! 4328: Adapter->IbmtokPortAddress = ALTERNATE_ADAPTER_OFFSET; ! 4329: break; ! 4330: ! 4331: } ! 4332: ! 4333: } else { ! 4334: ! 4335: // ! 4336: // Read I/O Address ! 4337: // ! 4338: ! 4339: NdisReadConfiguration( ! 4340: &Status, ! 4341: &ReturnedValue, ! 4342: ConfigHandle, ! 4343: &IOAddressStr, ! 4344: NdisParameterInteger ! 4345: ); ! 4346: ! 4347: if (Status == NDIS_STATUS_SUCCESS) { ! 4348: ! 4349: PrimaryAdapter = (ReturnedValue->ParameterData.IntegerData == 1)?TRUE:FALSE; ! 4350: ! 4351: } ! 4352: ! 4353: if (PrimaryAdapter) { ! 4354: ! 4355: Adapter->IbmtokPortAddress = PRIMARY_ADAPTER_OFFSET; ! 4356: ! 4357: } else { ! 4358: ! 4359: Adapter->IbmtokPortAddress = ALTERNATE_ADAPTER_OFFSET; ! 4360: ! 4361: } ! 4362: ! 4363: } ! 4364: ! 4365: // ! 4366: // Read PacketSize ! 4367: // ! 4368: ! 4369: NdisReadConfiguration( ! 4370: &Status, ! 4371: &ReturnedValue, ! 4372: ConfigHandle, ! 4373: &PacketSizeStr, ! 4374: NdisParameterInteger ! 4375: ); ! 4376: ! 4377: if (Status == NDIS_STATUS_SUCCESS) { ! 4378: ! 4379: Adapter->MaxTransmittablePacket = ReturnedValue->ParameterData.IntegerData; ! 4380: ! 4381: } ! 4382: ! 4383: ! 4384: // ! 4385: // Read net address ! 4386: // ! 4387: ! 4388: NdisReadNetworkAddress( ! 4389: &Status, ! 4390: &NetAddress, ! 4391: &Length, ! 4392: ConfigHandle ! 4393: ); ! 4394: ! 4395: if ((Length == TR_LENGTH_OF_ADDRESS) && (Status == NDIS_STATUS_SUCCESS)) { ! 4396: ! 4397: TR_COPY_NETWORK_ADDRESS( ! 4398: Adapter->NetworkAddress, ! 4399: NetAddress ! 4400: ); ! 4401: ! 4402: } ! 4403: ! 4404: RegisterAdapter: ! 4405: ! 4406: NdisCloseConfiguration(ConfigHandle); ! 4407: ! 4408: Status = IbmtokRegisterAdapter( ! 4409: Adapter, ! 4410: ConfigurationHandle, ! 4411: AdapterName, ! 4412: McaCard, ! 4413: ConfigError ! 4414: ); ! 4415: ! 4416: if (Status != NDIS_STATUS_SUCCESS) { ! 4417: ! 4418: IBMTOK_FREE_PHYS(Adapter, sizeof(IBMTOK_ADAPTER)); ! 4419: ! 4420: } ! 4421: ! 4422: return Status; ! 4423: ! 4424: } ! 4425: ! 4426: VOID ! 4427: IbmtokRemoveAdapter( ! 4428: IN PVOID MacAdapterContext ! 4429: ) ! 4430: ! 4431: ! 4432: /*++ ! 4433: ! 4434: Routine Description: ! 4435: ! 4436: This routine is called when an adapter is to be removed. ! 4437: ! 4438: Arguments: ! 4439: ! 4440: MacAdapterContext - Pointer to global list of adapter blocks. ! 4441: ! 4442: Return Value: ! 4443: ! 4444: None ! 4445: ! 4446: --*/ ! 4447: ! 4448: { ! 4449: PIBMTOK_ADAPTER Adapter; ! 4450: BOOLEAN Canceled; ! 4451: ! 4452: Adapter = PIBMTOK_ADAPTER_FROM_CONTEXT_HANDLE(MacAdapterContext); ! 4453: ! 4454: // ! 4455: // There are no opens left, so remove ourselves. ! 4456: // ! 4457: ! 4458: NdisCancelTimer(&Adapter->WakeUpTimer, &Canceled); ! 4459: ! 4460: if ( !Canceled ) { ! 4461: ! 4462: NdisStallExecution(500000); ! 4463: } ! 4464: ! 4465: NdisRemoveInterrupt(&(Adapter->Interrupt)); ! 4466: ! 4467: NdisUnmapIoSpace(Adapter->NdisAdapterHandle, ! 4468: Adapter->SharedRam, ! 4469: (Adapter->MappedSharedRam == 0x10000) ? ! 4470: 0x8000 : ! 4471: Adapter->MappedSharedRam ! 4472: ); ! 4473: ! 4474: TrDeleteFilter(Adapter->FilterDB); ! 4475: ! 4476: NdisFreeSpinLock(&Adapter->Lock); ! 4477: ! 4478: NdisDeregisterAdapter(Adapter->NdisAdapterHandle); ! 4479: ! 4480: IBMTOK_FREE_PHYS(Adapter, sizeof(IBMTOK_ADAPTER)); ! 4481: ! 4482: return; ! 4483: ! 4484: } ! 4485: ! 4486: VOID ! 4487: IbmtokUnload( ! 4488: IN NDIS_HANDLE MacMacContext ! 4489: ) ! 4490: ! 4491: /*++ ! 4492: ! 4493: Routine Description: ! 4494: ! 4495: IbmtokUnload is called when the MAC is to unload itself. ! 4496: ! 4497: Arguments: ! 4498: ! 4499: MacMacContext - nothing. ! 4500: ! 4501: Return Value: ! 4502: ! 4503: None. ! 4504: ! 4505: --*/ ! 4506: ! 4507: { ! 4508: NDIS_STATUS InitStatus; ! 4509: ! 4510: UNREFERENCED_PARAMETER(MacMacContext); ! 4511: ! 4512: NdisDeregisterMac( ! 4513: &InitStatus, ! 4514: ((PIBMTOK_MAC)MacMacContext)->NdisMacHandle ! 4515: ); ! 4516: ! 4517: NdisTerminateWrapper( ! 4518: ((PIBMTOK_MAC)MacMacContext)->NdisWrapperHandle, ! 4519: NULL ! 4520: ); ! 4521: ! 4522: return; ! 4523: } ! 4524: ! 4525: STATIC ! 4526: BOOLEAN ! 4527: IbmtokHardwareDetails( ! 4528: IN PIBMTOK_ADAPTER Adapter ! 4529: ) ! 4530: ! 4531: /*++ ! 4532: ! 4533: Routine Description: ! 4534: ! 4535: This routine gets the MMIO address and interrupt level. ! 4536: It also maps the MMIO and Shared RAM. ! 4537: ! 4538: Arguments: ! 4539: ! 4540: Adapter - Where to store the network address. ! 4541: ! 4542: Return Value: ! 4543: ! 4544: TRUE if successful. ! 4545: ! 4546: --*/ ! 4547: ! 4548: { ! 4549: ! 4550: NDIS_STATUS Status; ! 4551: ! 4552: // ! 4553: // Holds the value read from the SWITCH_READ_1 port. ! 4554: // ! 4555: UCHAR SwitchRead1; ! 4556: ! 4557: // ! 4558: // Holds the value read from the SWITCH_READ_2 port in ! 4559: // the Microchannel Bus. ! 4560: // ! 4561: UCHAR SwitchRead2; ! 4562: ! 4563: // ! 4564: // Holds the physical address of the MMIO region. ! 4565: // ! 4566: ULONG MmioAddress; ! 4567: ! 4568: NDIS_PHYSICAL_ADDRESS PhysicalAddress; ! 4569: ! 4570: // ! 4571: // The interrupt level; ! 4572: // ! 4573: UINT InterruptLevel; ! 4574: ! 4575: // ! 4576: // The RRR bits indicating the Shared RAM size: ! 4577: // 0 = 8K, 1 = 16K, 2 = 32K, 3 = 64K. ! 4578: // ! 4579: UCHAR SharedRamBits; ! 4580: ! 4581: // ! 4582: // The actual size of Shared RAM from RRR bits 2,3 in ! 4583: // the PC I/O Bus adapter. ! 4584: // ! 4585: UINT RrrSharedRamSize; ! 4586: ! 4587: // ! 4588: // Common variable for storing total Shared RAM Size. ! 4589: // ! 4590: UINT SharedRamSize; ! 4591: ! 4592: // ! 4593: // The actual address of Shared RAM from the SWITCH_READ_2 ! 4594: // port in the Microchannel adapter. ! 4595: // ! 4596: UINT McaSharedRam; ! 4597: ! 4598: // ! 4599: // The boundary needed for the Shared RAM mapping. ! 4600: // ! 4601: UCHAR BoundaryNeeded; ! 4602: ! 4603: // ! 4604: // The value read from the Shared RAM paging byte of ! 4605: // the AIP. ! 4606: // ! 4607: UCHAR AipSharedRamPaging; ! 4608: ! 4609: UCHAR RegValue; ! 4610: ! 4611: // ! 4612: // SwitchRead1 contains the interrupt code in the low 2 bits, ! 4613: // and bits 18 through 13 of the MMIO address in the high ! 4614: // 6 bits. ! 4615: // ! 4616: ! 4617: READ_ADAPTER_PORT(Adapter, SWITCH_READ_1, &SwitchRead1); ! 4618: ! 4619: // ! 4620: // SwitchRead2 contains Bit 19 of the MMIO address in the ! 4621: // low bit. It is always 1 for PC I/O Bus and possibly 0 ! 4622: // for the Microchannel bus ! 4623: // ! 4624: ! 4625: READ_ADAPTER_PORT(Adapter, SWITCH_READ_2, &SwitchRead2); ! 4626: ! 4627: // ! 4628: // To compute MmioAddress, we mask off the low 2 bits of ! 4629: // SwitchRead1, shift it out by 11 (so that the high 6 bits ! 4630: // are moved to the right place), and add in the 19th bit value. ! 4631: // ! 4632: ! 4633: MmioAddress = ((SwitchRead1 & 0xfc) << 11) | ((SwitchRead2 & 1) << 19); ! 4634: ! 4635: NdisSetPhysicalAddressHigh(PhysicalAddress, 0); ! 4636: NdisSetPhysicalAddressLow(PhysicalAddress, MmioAddress); ! 4637: ! 4638: NdisMapIoSpace( ! 4639: &Status, ! 4640: (PVOID *)&(Adapter->MmioRegion), ! 4641: Adapter->NdisAdapterHandle, ! 4642: PhysicalAddress, ! 4643: 0x2000); ! 4644: ! 4645: if (Status != NDIS_STATUS_SUCCESS) { ! 4646: ! 4647: NdisWriteErrorLogEntry( ! 4648: Adapter->NdisAdapterHandle, ! 4649: NDIS_ERROR_CODE_RESOURCE_CONFLICT, ! 4650: 0 ! 4651: ); ! 4652: ! 4653: return(FALSE); ! 4654: ! 4655: } ! 4656: ! 4657: ! 4658: // ! 4659: // Now we have mapped the MMIO, look at the AIP. First ! 4660: // determine the channel identifier. ! 4661: // ! 4662: ! 4663: { ! 4664: // ! 4665: // Will hold the Adapter ID as read from the card. ! 4666: // ! 4667: ULONG AdapterId[3]; ! 4668: ! 4669: // ! 4670: // What AdapterId should contain for a PC I/O bus card. ! 4671: // ! 4672: static ULONG PcIoBusId[3] = { 0x5049434f, 0x36313130, 0x39393020 }; ! 4673: ! 4674: // ! 4675: // What AdapterId should contain for a Micro Channel card. ! 4676: // ! 4677: static ULONG MicroChannelId[3] = { 0x4d415253, 0x36335834, 0x35313820 }; ! 4678: ! 4679: // ! 4680: // Loop counters. ! 4681: // ! 4682: UINT i, j; ! 4683: ! 4684: UCHAR TmpUchar; ! 4685: ! 4686: // ! 4687: // Read in AdapterId. ! 4688: // ! 4689: // Turns out that the bytes which identify the card are stored ! 4690: // in a very odd manner. There are 48 bytes on the card. The ! 4691: // even numbered bytes contain 4 bits of the card signature. ! 4692: // ! 4693: ! 4694: for (i=0; i<3; i++) { ! 4695: ! 4696: AdapterId[i] = 0; ! 4697: ! 4698: for (j=0; j<16; j+=2) { ! 4699: ! 4700: READ_ADAPTER_REGISTER(Adapter, ! 4701: CHANNEL_IDENTIFIER + (i*16 + j), ! 4702: &TmpUchar ! 4703: ); ! 4704: ! 4705: AdapterId[i] = (AdapterId[i] << 4) + TmpUchar; ! 4706: ! 4707: ! 4708: } ! 4709: ! 4710: } ! 4711: ! 4712: if ((AdapterId[0] == PcIoBusId[0]) && ! 4713: (AdapterId[1] == PcIoBusId[1]) && ! 4714: (AdapterId[2] == PcIoBusId[2])) { ! 4715: ! 4716: Adapter->UsingPcIoBus = TRUE; ! 4717: ! 4718: } else if ((AdapterId[0] == MicroChannelId[0]) && ! 4719: (AdapterId[1] == MicroChannelId[1]) && ! 4720: (AdapterId[2] == MicroChannelId[2])) { ! 4721: ! 4722: Adapter->UsingPcIoBus = FALSE; ! 4723: ! 4724: } else { ! 4725: ! 4726: // ! 4727: // Unknown channel type. ! 4728: // ! 4729: ! 4730: ! 4731: NdisUnmapIoSpace(Adapter->NdisAdapterHandle, ! 4732: Adapter->MmioRegion, ! 4733: 0x2000); ! 4734: ! 4735: NdisWriteErrorLogEntry( ! 4736: Adapter->NdisAdapterHandle, ! 4737: NDIS_ERROR_CODE_BAD_IO_BASE_ADDRESS, ! 4738: 0 ! 4739: ); ! 4740: ! 4741: return FALSE; ! 4742: ! 4743: } ! 4744: ! 4745: } ! 4746: ! 4747: // ! 4748: // We can read the network address from the AIP but we won't, ! 4749: // we read it from the bring-up SRB instead. ! 4750: // ! 4751: ! 4752: // ! 4753: // Read the RRR High to get the Shared RAM size (we are ! 4754: // only interested in bits 2 and 3). ! 4755: // ! 4756: ! 4757: READ_ADAPTER_REGISTER(Adapter, RRR_HIGH, &SharedRamBits); ! 4758: ! 4759: SharedRamBits = ((SharedRamBits & 0x0c) >> 2); ! 4760: ! 4761: if (Adapter->UsingPcIoBus) { ! 4762: ! 4763: // ! 4764: // Here we have to tell the Adapter where Shared RAM is ! 4765: // going to be. To do this we first find the lowest ! 4766: // address it could be at, and then advance the address ! 4767: // such that it falls on a correct page boudary. ! 4768: // ! 4769: ! 4770: ! 4771: // ! 4772: // To get value to put in RRR Low, which indicates where ! 4773: // the Shared RAM is mapped, we first compute the lowest ! 4774: // possible value, which is right after the MMIO region. ! 4775: // We take the high six bits of SwitchRead and shift ! 4776: // them right one (so bits 18-13 of the address are in ! 4777: // bits 6-1), then we turn on bit 7 to indicate that bit ! 4778: // 19 of the address is on, and leave bit 0 zero since ! 4779: // it must be. ! 4780: // ! 4781: ! 4782: Adapter->RrrLowValue = (UCHAR) ! 4783: ((((SwitchRead1 & 0xfc) >> 1) | 0x80) + 0x02); ! 4784: ! 4785: // ! 4786: // We now have to move up to a memory boundary ! 4787: // based on the value of SharedRamBits; 0 (8K) = 16K boundary, ! 4788: // 1 (16K) = 16K boundary, 2 (32K) = 32K boundary, and ! 4789: // 3 (64K) = 64K Boundary. Remember that the way the ! 4790: // address bits are shifted over in RrrLowValue, bit 1 ! 4791: // is really bit 13 of the final address (turning it on ! 4792: // adds 8K), bit 2 if bit 14, etc. We compute Boundary ! 4793: // Needed in this frame of reference. ! 4794: // ! 4795: ! 4796: switch (SharedRamBits) { ! 4797: ! 4798: case 0: ! 4799: case 1: ! 4800: ! 4801: // ! 4802: // 8K or 16K needs a 16K boundary. ! 4803: // ! 4804: ! 4805: RrrSharedRamSize = (SharedRamBits == 0) ? 0x2000 : 0x4000; ! 4806: BoundaryNeeded = 0x04; ! 4807: break; ! 4808: ! 4809: case 2: ! 4810: ! 4811: // ! 4812: // 32K needs a 32K boundary. ! 4813: // ! 4814: ! 4815: RrrSharedRamSize = 0x8000; ! 4816: BoundaryNeeded = 0x08; ! 4817: break; ! 4818: ! 4819: case 3: ! 4820: ! 4821: // ! 4822: // 64K needs a 64K boundary. ! 4823: // ! 4824: ! 4825: RrrSharedRamSize = 0x10000; ! 4826: BoundaryNeeded = 0x10; ! 4827: break; ! 4828: ! 4829: } ! 4830: ! 4831: ! 4832: // ! 4833: // If RrrLowValue is not on the proper boundary, move it ! 4834: // forward until it is. ! 4835: // ! 4836: ! 4837: if (Adapter->RrrLowValue & (BoundaryNeeded-1)) { ! 4838: ! 4839: Adapter->RrrLowValue = (UCHAR) ! 4840: ((Adapter->RrrLowValue & ~(BoundaryNeeded-1)) + BoundaryNeeded); ! 4841: ! 4842: } ! 4843: ! 4844: Adapter->MappedSharedRam = SharedRamSize = RrrSharedRamSize; ! 4845: ! 4846: NdisSetPhysicalAddressHigh(PhysicalAddress, 0); ! 4847: NdisSetPhysicalAddressLow(PhysicalAddress, Adapter->RrrLowValue << 12); ! 4848: ! 4849: NdisMapIoSpace(&Status, ! 4850: (PVOID *)&(Adapter->SharedRam), ! 4851: Adapter->NdisAdapterHandle, ! 4852: PhysicalAddress, ! 4853: RrrSharedRamSize ! 4854: ); ! 4855: ! 4856: if (Status != NDIS_STATUS_SUCCESS) { ! 4857: ! 4858: NdisUnmapIoSpace(Adapter->NdisAdapterHandle, ! 4859: Adapter->MmioRegion, ! 4860: 0x2000); ! 4861: ! 4862: NdisWriteErrorLogEntry( ! 4863: Adapter->NdisAdapterHandle, ! 4864: NDIS_ERROR_CODE_RESOURCE_CONFLICT, ! 4865: 0 ! 4866: ); ! 4867: ! 4868: return(FALSE); ! 4869: ! 4870: } ! 4871: ! 4872: } else { ! 4873: ! 4874: // ! 4875: // Using Microchannel ! 4876: // ! 4877: // No need to set Adapter->RrrLowValue since it is not ! 4878: // used in the Microchannel adapter. ! 4879: // ! 4880: ! 4881: switch (SharedRamBits){ ! 4882: case 0: ! 4883: SharedRamSize = 0x2000; ! 4884: break; ! 4885: case 1: ! 4886: SharedRamSize = 0x4000; ! 4887: break; ! 4888: case 2: ! 4889: SharedRamSize = 0x8000; ! 4890: break; ! 4891: case 3: ! 4892: SharedRamSize = 0x10000; ! 4893: break; ! 4894: } ! 4895: ! 4896: McaSharedRam = ((SwitchRead2 & 0xfe) << 12); ! 4897: ! 4898: NdisSetPhysicalAddressHigh(PhysicalAddress, 0); ! 4899: NdisSetPhysicalAddressLow(PhysicalAddress, McaSharedRam); ! 4900: ! 4901: NdisMapIoSpace(&Status, ! 4902: (PVOID *)&(Adapter->SharedRam), ! 4903: Adapter->NdisAdapterHandle, ! 4904: PhysicalAddress, ! 4905: SharedRamSize); ! 4906: ! 4907: if (Status != NDIS_STATUS_SUCCESS) { ! 4908: ! 4909: NdisUnmapIoSpace(Adapter->NdisAdapterHandle, ! 4910: Adapter->MmioRegion, ! 4911: 0x2000); ! 4912: ! 4913: NdisWriteErrorLogEntry( ! 4914: Adapter->NdisAdapterHandle, ! 4915: NDIS_ERROR_CODE_RESOURCE_CONFLICT, ! 4916: 0 ! 4917: ); ! 4918: ! 4919: return(FALSE); ! 4920: ! 4921: } ! 4922: ! 4923: Adapter->MappedSharedRam = SharedRamSize; ! 4924: ! 4925: } ! 4926: ! 4927: ! 4928: ! 4929: // ! 4930: // Get the interrupt level...note that a switch being ! 4931: // "off" shows up as a 1, "on" is 0. ! 4932: // ! 4933: ! 4934: switch (SwitchRead1 & 0x03) { ! 4935: ! 4936: case 0: InterruptLevel = 2; break; ! 4937: case 1: InterruptLevel = 3; break; ! 4938: case 2: InterruptLevel = (Adapter->UsingPcIoBus)?6:10; break; ! 4939: case 3: InterruptLevel = (Adapter->UsingPcIoBus)?7:11; break; ! 4940: ! 4941: } ! 4942: ! 4943: Adapter->InterruptLevel = InterruptLevel; ! 4944: ! 4945: // ! 4946: // Now determine how much memory the adapter has, and ! 4947: // whether to use Shared RAM paging. ! 4948: // ! 4949: ! 4950: Adapter->UpperSharedRamZero = FALSE; ! 4951: ! 4952: READ_ADAPTER_REGISTER(Adapter, TOTAL_ADAPTER_RAM, &RegValue); ! 4953: ! 4954: switch (RegValue) { ! 4955: ! 4956: // ! 4957: // These values are described on page 7-26 of the ! 4958: // Technical Reference. ! 4959: // ! 4960: ! 4961: case 0xf: ! 4962: ! 4963: Adapter->TotalSharedRam = SharedRamSize; ! 4964: break; ! 4965: ! 4966: case 0xe: ! 4967: ! 4968: Adapter->TotalSharedRam = 0x2000; ! 4969: break; ! 4970: ! 4971: case 0xd: ! 4972: ! 4973: Adapter->TotalSharedRam = 0x4000; ! 4974: break; ! 4975: ! 4976: case 0xc: ! 4977: ! 4978: Adapter->TotalSharedRam = 0x8000; ! 4979: break; ! 4980: ! 4981: case 0xb: ! 4982: ! 4983: Adapter->TotalSharedRam = 0x10000; ! 4984: ! 4985: Adapter->UpperSharedRamZero = TRUE; ! 4986: break; ! 4987: ! 4988: case 0xa: ! 4989: ! 4990: Adapter->TotalSharedRam = 0x10000; ! 4991: break; ! 4992: ! 4993: default: ! 4994: ! 4995: NdisWriteErrorLogEntry( ! 4996: Adapter->NdisAdapterHandle, ! 4997: NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION, ! 4998: 3, ! 4999: hardwareDetails, ! 5000: IBMTOK_ERRMSG_UNSUPPORTED_RAM, ! 5001: (ULONG)RegValue ! 5002: ); ! 5003: ! 5004: NdisUnmapIoSpace(Adapter->NdisAdapterHandle, ! 5005: Adapter->MmioRegion, ! 5006: 0x2000); ! 5007: ! 5008: if (Adapter->UsingPcIoBus) { ! 5009: NdisUnmapIoSpace( ! 5010: Adapter->NdisAdapterHandle, ! 5011: Adapter->SharedRam, ! 5012: SharedRamSize); ! 5013: } else { ! 5014: NdisUnmapIoSpace( ! 5015: Adapter->NdisAdapterHandle, ! 5016: Adapter->SharedRam, ! 5017: SharedRamSize); ! 5018: } ! 5019: ! 5020: return FALSE; ! 5021: ! 5022: } ! 5023: ! 5024: // ! 5025: // Only allow Shared RAM paging if we have 16K selected ! 5026: // on SharedRamSize, 64K of total adapter memory, and it is allowed ! 5027: // as specified on p. 7-26 of the Technical Reference. ! 5028: // ! 5029: ! 5030: READ_ADAPTER_REGISTER(Adapter, SHARED_RAM_PAGING, &AipSharedRamPaging); ! 5031: ! 5032: #if 0 ! 5033: if (SharedRamSize == 0x4000 && ! 5034: Adapter->TotalSharedRam == 0x10000 && ! 5035: (AipSharedRamPaging == 0xe || AipSharedRamPaging == 0xc)) { ! 5036: ! 5037: Adapter->SharedRamPaging = TRUE; ! 5038: ! 5039: } else { ! 5040: ! 5041: Adapter->SharedRamPaging = FALSE; ! 5042: ! 5043: } ! 5044: #else ! 5045: Adapter->SharedRamPaging = FALSE; ! 5046: #endif ! 5047: ! 5048: ! 5049: // ! 5050: // Read in the maximum sizes allowed for DHBs based on ! 5051: // the speed of the adapter (which we don't know yet). ! 5052: // ! 5053: ! 5054: READ_ADAPTER_REGISTER(Adapter, MAX_4_MBPS_DHB, &RegValue); ! 5055: ! 5056: switch (RegValue) { ! 5057: ! 5058: case 0xf: ! 5059: default: ! 5060: ! 5061: Adapter->Max4MbpsDhb = 2048; ! 5062: break; ! 5063: ! 5064: case 0xe: ! 5065: ! 5066: Adapter->Max4MbpsDhb = 4096; ! 5067: break; ! 5068: ! 5069: case 0xd: ! 5070: ! 5071: Adapter->Max4MbpsDhb = 4464; ! 5072: break; ! 5073: ! 5074: } ! 5075: ! 5076: READ_ADAPTER_REGISTER(Adapter, MAX_16_MBPS_DHB, &RegValue); ! 5077: ! 5078: switch (RegValue) { ! 5079: ! 5080: case 0xf: ! 5081: default: ! 5082: ! 5083: Adapter->Max16MbpsDhb = 2048; ! 5084: break; ! 5085: ! 5086: case 0xe: ! 5087: ! 5088: Adapter->Max16MbpsDhb = 4096; ! 5089: break; ! 5090: ! 5091: case 0xd: ! 5092: ! 5093: Adapter->Max16MbpsDhb = 8192; ! 5094: break; ! 5095: ! 5096: case 0xc: ! 5097: ! 5098: Adapter->Max16MbpsDhb = 16384; ! 5099: break; ! 5100: ! 5101: case 0xb: ! 5102: ! 5103: Adapter->Max16MbpsDhb = 17960; ! 5104: break; ! 5105: ! 5106: } ! 5107: ! 5108: ! 5109: return TRUE; ! 5110: ! 5111: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.