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