1606 lines
49 KiB
C
1606 lines
49 KiB
C
//**********************************************************************
|
||
//**********************************************************************
|
||
//
|
||
// File Name: INIT.C
|
||
//
|
||
// Program Name: NetFlex NDIS 3.0 Miniport Driver
|
||
//
|
||
// Companion Files: None
|
||
//
|
||
// Function: This module contains the NetFlex Miniport Driver
|
||
// interface routines called by the Wrapper and the
|
||
// configuration manager.
|
||
//
|
||
// (c) Compaq Computer Corporation, 1992,1993,1994
|
||
//
|
||
// This file is licensed by Compaq Computer Corporation to Microsoft
|
||
// Corporation pursuant to the letter of August 20, 1992 from
|
||
// Gary Stimac to Mark Baber.
|
||
//
|
||
// History:
|
||
//
|
||
// 04/15/94 Robert Van Cleve - Converted from NDIS Mac Driver
|
||
//
|
||
//**********************************************************************
|
||
//**********************************************************************
|
||
|
||
|
||
//-------------------------------------
|
||
// Include all general companion files
|
||
//-------------------------------------
|
||
|
||
#include <ndis.h>
|
||
#include "tmsstrct.h"
|
||
#include "macstrct.h"
|
||
#include "adapter.h"
|
||
#include "protos.h"
|
||
|
||
//-----------------
|
||
// Variables
|
||
//-----------------
|
||
|
||
MAC macgbls = {0};
|
||
USHORT gbl_addingdualport = 0;
|
||
USHORT gbl_portnumbertoadd = 0;
|
||
|
||
USHORT RxIntRatio = 1;
|
||
#ifdef XMIT_INTS
|
||
USHORT TxIntRatio = 1;
|
||
#endif
|
||
|
||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
//
|
||
// Routine Name: DriverEntry
|
||
//
|
||
// Description: This routine is the initialization entry
|
||
// point into the driver. In this routine,
|
||
// the driver registers itself with the wrapper
|
||
// and initializes the global variables for the
|
||
// driver.
|
||
//
|
||
// Input: DriverObject Pointer to the driver object
|
||
// assigned to the MAC driver.
|
||
//
|
||
// Output: Returns NDIS_STATUS_SUCCESS for a successful
|
||
// completion and returns an error code if an
|
||
// error is encountered.
|
||
//
|
||
// Called_By: OS
|
||
//
|
||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
#pragma NDIS_INIT_FUNCTION(DriverEntry)
|
||
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
||
IN PUNICODE_STRING RegistryPath)
|
||
|
||
{
|
||
NDIS_STATUS Status;
|
||
|
||
//
|
||
// The characteristics table
|
||
//
|
||
NDIS_MINIPORT_CHARACTERISTICS NetFlexChar;
|
||
|
||
DebugPrint(1,("NetFlex: Dynamic Ratio Version\n"));
|
||
|
||
#ifdef XMIT_INTS
|
||
DebugPrint(1,("NetFlex: with Transmit Interrupts\n"));
|
||
#endif
|
||
|
||
//
|
||
// Indicate that we are in initialization mode.
|
||
//
|
||
macgbls.Initializing = TRUE;
|
||
|
||
//
|
||
// Initialize the Wrapper
|
||
//
|
||
NdisMInitializeWrapper(
|
||
&macgbls.mac_wrapper,
|
||
DriverObject,
|
||
RegistryPath,
|
||
NULL);
|
||
|
||
//
|
||
// Store the driver object. We will need this for Unloading
|
||
// the driver.
|
||
|
||
macgbls.mac_object = DriverObject;
|
||
|
||
//
|
||
// Initialize the Miniport characteristics for the call to
|
||
// NdisMRegisterMiniport.
|
||
//
|
||
NetFlexChar.MajorNdisVersion = NETFLEX_MAJ_VER;
|
||
NetFlexChar.MinorNdisVersion = NETFLEX_MIN_VER;
|
||
NetFlexChar.CheckForHangHandler = NetFlexCheckForHang;
|
||
NetFlexChar.DisableInterruptHandler = NetFlexDisableInterrupt;
|
||
NetFlexChar.EnableInterruptHandler = NetFlexEnableInterrupt;
|
||
NetFlexChar.HaltHandler = NetFlexHalt;
|
||
NetFlexChar.HandleInterruptHandler = NetFlexHandleInterrupt;
|
||
NetFlexChar.InitializeHandler = NetFlexInitialize;
|
||
NetFlexChar.ISRHandler = NetFlexISR;
|
||
NetFlexChar.QueryInformationHandler = NetFlexQueryInformation;
|
||
NetFlexChar.ReconfigureHandler = NULL;
|
||
NetFlexChar.ResetHandler = NetFlexResetDispatch;
|
||
NetFlexChar.SendHandler = NetFlexSend;
|
||
NetFlexChar.SetInformationHandler = NetFlexSetInformation;
|
||
NetFlexChar.TransferDataHandler = NetFlexTransferData;
|
||
NetFlexChar.ReturnPacketHandler = NULL;
|
||
NetFlexChar.SendPacketsHandler = NULL;
|
||
NetFlexChar.AllocateCompleteHandler = NULL;
|
||
|
||
//
|
||
// Register this driver with NDIS
|
||
//
|
||
Status = NdisMRegisterMiniport( macgbls.mac_wrapper,
|
||
&NetFlexChar,
|
||
sizeof(NetFlexChar) );
|
||
|
||
//
|
||
// Set to non-initializing mode
|
||
//
|
||
macgbls.Initializing = FALSE;
|
||
|
||
if (Status == NDIS_STATUS_SUCCESS)
|
||
{
|
||
|
||
return STATUS_SUCCESS;
|
||
}
|
||
|
||
//
|
||
// We can only get here if something went wrong with registering
|
||
// the driver or *ALL* of the adapters.
|
||
//
|
||
if ((macgbls.mac_adapters == NULL) &&
|
||
(macgbls.mac_wrapper != NULL))
|
||
{
|
||
NdisTerminateWrapper(macgbls.mac_wrapper, NULL);
|
||
}
|
||
return STATUS_UNSUCCESSFUL;
|
||
}
|
||
|
||
|
||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
//
|
||
// Routine Name: NetFlexInitialize
|
||
//
|
||
// Description: See NDIS 3.0 Miniport spec.
|
||
// Called to initialize each adapter
|
||
//
|
||
// Input: See NDIS 3.0 Miniport spec.
|
||
//
|
||
// Output: NDIS_STATUS_SUCCESS or NDIS_STATUS_PENDING
|
||
//
|
||
// Called_By: NDIS Miniport Wrapper
|
||
//
|
||
//----------------------------------------------------------------
|
||
NDIS_STATUS
|
||
NetFlexInitialize(
|
||
OUT PNDIS_STATUS OpenErrorStatus,
|
||
OUT PUINT SelectedMediumIndex,
|
||
IN PNDIS_MEDIUM MediumArray,
|
||
IN UINT MediumArraySize,
|
||
IN NDIS_HANDLE MiniportAdapterHandle,
|
||
IN NDIS_HANDLE ConfigurationHandle
|
||
)
|
||
|
||
{
|
||
NDIS_STATUS status;
|
||
PACB acb = NULL;
|
||
PACB FirstHeadsAcb = NULL;
|
||
USHORT baseaddr;
|
||
UINT slot,i;
|
||
NDIS_STRING portnumber = NDIS_STRING_CONST("PortNumber");
|
||
NDIS_HANDLE ConfigHandle = NULL;
|
||
|
||
NDIS_EISA_FUNCTION_INFORMATION EisaData;
|
||
PNDIS_CONFIGURATION_PARAMETER cfgp;
|
||
|
||
DebugPrint(2,("NetFlex: NetFlexInitialize\n"));
|
||
|
||
//
|
||
// Make sure we still have the wrapper, this is needed if an adapter
|
||
// fails to open and there isn't any already opened, the halt routine
|
||
// will remove the wrapper, and thus all adapters fail. I don't know
|
||
// if this means that I should remove the code from the halt routine
|
||
// or if I need to come up with aditional logic...
|
||
//
|
||
if (macgbls.mac_wrapper == NULL)
|
||
{
|
||
DebugPrint(0,("NetFlex: Don't have a handle to the Wrapper!\n"));
|
||
status = NDIS_STATUS_FAILURE;
|
||
goto ConfigError;
|
||
}
|
||
|
||
//
|
||
// Check if we have a configuration handle before proceeding.
|
||
//
|
||
if (ConfigurationHandle == NULL)
|
||
{
|
||
DebugPrint(0,("NetFlex: Adapter not set up properly - no config handle\n"));
|
||
status = NDIS_STATUS_FAILURE;
|
||
goto ConfigError;
|
||
}
|
||
|
||
//
|
||
// Open the configuration handle
|
||
//
|
||
NdisOpenConfiguration( &status,
|
||
&ConfigHandle,
|
||
ConfigurationHandle );
|
||
|
||
if (status != NDIS_STATUS_SUCCESS)
|
||
{
|
||
DebugPrint(0,("NetFlex: Adapter not set up properly - couldn't open config\n"));
|
||
status = NDIS_STATUS_FAILURE;
|
||
ConfigHandle = NULL;
|
||
goto ConfigError;
|
||
}
|
||
|
||
//
|
||
// Find out what slot number the adapter associated with
|
||
// this name is in.
|
||
//
|
||
NdisReadEisaSlotInformation( &status,
|
||
ConfigurationHandle,
|
||
&slot,
|
||
&EisaData );
|
||
|
||
if (status != NDIS_STATUS_SUCCESS)
|
||
{
|
||
DebugPrint(0,("NetFlex: Slot number not set up\n"));
|
||
status = NDIS_ERROR_CODE_ADAPTER_NOT_FOUND;
|
||
goto ConfigError;
|
||
}
|
||
|
||
baseaddr = slot * 0x1000;
|
||
|
||
NdisReadConfiguration( &status,
|
||
&cfgp,
|
||
ConfigHandle,
|
||
&portnumber,
|
||
NdisParameterInteger);
|
||
|
||
//
|
||
// If we didn't read a portnumber, that means we're adding a
|
||
// non-dual port card - NETFLX, MAPLE, CPQTOK
|
||
//
|
||
if (status != NDIS_STATUS_SUCCESS)
|
||
{
|
||
gbl_portnumbertoadd = 0;
|
||
gbl_addingdualport = FALSE;
|
||
}
|
||
else
|
||
{
|
||
gbl_portnumbertoadd = (USHORT)cfgp->ParameterData.IntegerData;
|
||
if (gbl_portnumbertoadd == PORT0)
|
||
gbl_addingdualport = FALSE;
|
||
else
|
||
gbl_addingdualport = TRUE;
|
||
}
|
||
|
||
//
|
||
// See if this adapter has been added. If so return an error.
|
||
// The very first time we are called, acb should be NULL.
|
||
//
|
||
|
||
if (macgbls.DownloadCode == NULL)
|
||
{
|
||
// On Initial Init, We need to get the global stuff...
|
||
//
|
||
status = NetFlexInitGlobals();
|
||
if (status != NDIS_STATUS_SUCCESS)
|
||
{
|
||
goto ConfigError;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
acb = macgbls.mac_adapters;
|
||
|
||
while (acb)
|
||
{
|
||
if ( acb->acb_baseaddr == baseaddr)
|
||
{
|
||
//
|
||
// If the card has the same slot and we're adding a dual port
|
||
// then go to the next acb, otherwise it is an error.
|
||
//
|
||
if ( gbl_addingdualport )
|
||
{
|
||
FirstHeadsAcb = acb;
|
||
acb = acb->acb_next;
|
||
}
|
||
else
|
||
{
|
||
DebugPrint(0,("NetFlex: Adapter already added\n"));
|
||
status = NDIS_STATUS_FAILURE;
|
||
goto ConfigError;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
acb = acb->acb_next;
|
||
}
|
||
}
|
||
}
|
||
|
||
//
|
||
// Allocate adapter control block and register adapter.
|
||
//
|
||
|
||
status = NetFlexRegisterAdapter( &acb,
|
||
FirstHeadsAcb,
|
||
ConfigHandle,
|
||
baseaddr,
|
||
MiniportAdapterHandle
|
||
);
|
||
|
||
if (status != NDIS_STATUS_SUCCESS)
|
||
{
|
||
goto ConfigError;
|
||
}
|
||
|
||
|
||
//
|
||
// Search for the medium type supported matches adapter configuration
|
||
//
|
||
|
||
for (i = 0; i < MediumArraySize; i++)
|
||
{
|
||
if (MediumArray[i] == acb->acb_gen_objs.media_type_in_use)
|
||
{
|
||
*SelectedMediumIndex = i;
|
||
break;
|
||
}
|
||
}
|
||
|
||
//
|
||
// If supported medium not found. Return an error.
|
||
//
|
||
if (i == MediumArraySize)
|
||
{
|
||
DebugPrint(0,("NetFlex: No supported media found!\n"));
|
||
status = NDIS_STATUS_UNSUPPORTED_MEDIA;
|
||
goto ConfigError;
|
||
}
|
||
|
||
//
|
||
// Now, initialize the board and the data structures.
|
||
// glb_ErrorCode will be set if there was an error.
|
||
//
|
||
status = NetFlexBoardInitandReg(acb,&EisaData);
|
||
if (status != NDIS_STATUS_SUCCESS)
|
||
{
|
||
DebugPrint(0,("NF(%d): Board Init and Reg Failed\n",acb->anum));
|
||
goto ConfigError;
|
||
}
|
||
|
||
ConfigError:
|
||
|
||
//
|
||
// Were there any errors?
|
||
//
|
||
if (status != NDIS_STATUS_SUCCESS)
|
||
{
|
||
//
|
||
// if we allocated an acb, we need to get rid of it...
|
||
//
|
||
if (acb != NULL)
|
||
{
|
||
//
|
||
// Since there was an acb, the error data and section code will be in
|
||
// the acb instead of the globals.
|
||
//
|
||
NetFlexDeregisterAdapter(acb);
|
||
}
|
||
|
||
DebugPrint(0, ("NF: NetFlexInitialize Failed!\n"));
|
||
}
|
||
|
||
if (ConfigHandle != NULL)
|
||
{
|
||
NdisCloseConfiguration(ConfigHandle);
|
||
}
|
||
return status;
|
||
}
|
||
|
||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
//
|
||
// Routine Name: NetFlexRegisterAdapter
|
||
//
|
||
// Description: This routine allocates memory for the adapter
|
||
// control block and registers with the wrapper.
|
||
//
|
||
// Input: acbp - pointer to adapter control block
|
||
//
|
||
//
|
||
// Output: Returns NDIS_STATUS_SUCCESS for a successful
|
||
// completion. Otherwise, an error code is
|
||
// returned.
|
||
//
|
||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
NDIS_STATUS
|
||
NetFlexRegisterAdapter(
|
||
PACB *acbp,
|
||
PACB FirstHeadsAcb,
|
||
NDIS_HANDLE ConfigHandle,
|
||
USHORT baseaddr,
|
||
NDIS_HANDLE MiniportAdapterHandle
|
||
)
|
||
{
|
||
PACB acb;
|
||
USHORT cpqid, boardid, reg_value;
|
||
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
|
||
|
||
//
|
||
// Allocate the Memory for the adapter's acb.
|
||
//
|
||
NdisAllocateMemory( (PVOID *)&acb,
|
||
(UINT) (sizeof (ACB)),
|
||
(UINT) 0,
|
||
NetFlexHighestAddress );
|
||
//
|
||
// If we did not get the memory, flag any error.
|
||
//
|
||
if (acb == NULL)
|
||
{
|
||
return(NDIS_STATUS_RESOURCES);
|
||
}
|
||
|
||
//
|
||
// Zero out the memory. Save configuration handle.
|
||
//
|
||
NdisZeroMemory(acb, sizeof (ACB));
|
||
acb->acb_state = AS_REGISTERING;
|
||
acb->acb_baseaddr = baseaddr;
|
||
|
||
//
|
||
// Indicate that we are initializing the adapter.
|
||
//
|
||
acb->AdapterInitializing = TRUE;
|
||
|
||
//
|
||
// link in this acb
|
||
//
|
||
*acbp = acb;
|
||
macgbls.mac_numadpts++;
|
||
#if (DBG || DBGPRINT)
|
||
acb->anum = macgbls.mac_numadpts;
|
||
#endif
|
||
|
||
//
|
||
// save reference to our Miniport Handle
|
||
//
|
||
acb->acb_handle = MiniportAdapterHandle;
|
||
|
||
//
|
||
// Initialize reset timer
|
||
//
|
||
NdisMInitializeTimer(
|
||
&acb->ResetTimer,
|
||
acb->acb_handle,
|
||
(PVOID) NetFlexResetHandler,
|
||
(PVOID) acb );
|
||
|
||
//
|
||
// Initialize DPC timer
|
||
//
|
||
NdisMInitializeTimer(
|
||
&acb->DpcTimer,
|
||
acb->acb_handle,
|
||
(PVOID) NetFlexDeferredTimer,
|
||
(PVOID) acb );
|
||
|
||
//
|
||
// Set the attributes for this adapter
|
||
//
|
||
NdisMSetAttributes( MiniportAdapterHandle,
|
||
(NDIS_HANDLE) acb,
|
||
TRUE,
|
||
NdisInterfaceEisa );
|
||
|
||
//
|
||
// Register our shutdown handler.
|
||
//
|
||
|
||
NdisMRegisterAdapterShutdownHandler(
|
||
MiniportAdapterHandle, // wrapper miniport handle.
|
||
acb, // shutdown context.
|
||
NetFlexShutdown // shutdown handler.
|
||
);
|
||
|
||
//
|
||
// Reserve this adapters IO ports, if they haven't allready been added by the first
|
||
// head...
|
||
//
|
||
|
||
if (gbl_addingdualport)
|
||
{
|
||
if (FirstHeadsAcb == NULL)
|
||
{
|
||
// This is the first instance of a head on a dual port board,
|
||
// so register all the io ports for both heads.
|
||
|
||
acb->FirstHeadsAcb = acb;
|
||
|
||
//
|
||
// grab ports z000 - z02f
|
||
//
|
||
Status = NdisMRegisterIoPortRange( (PVOID *)&acb->BasePorts,
|
||
MiniportAdapterHandle,
|
||
baseaddr,
|
||
NUM_DUALHEAD_CFG_PORTS );
|
||
|
||
if (Status == NDIS_STATUS_SUCCESS)
|
||
{
|
||
// Save the master base port addresses
|
||
//
|
||
acb->MasterBasePorts = acb->BasePorts;
|
||
|
||
// grab zc80 - zc85
|
||
//
|
||
Status = NdisMRegisterIoPortRange( (PVOID *)&acb->ConfigPorts,
|
||
MiniportAdapterHandle,
|
||
baseaddr + CFG_PORT_OFFSET,
|
||
NUM_CFG_PORTS );
|
||
|
||
if (Status == NDIS_STATUS_SUCCESS)
|
||
{
|
||
// grab zc63 - zc67
|
||
//
|
||
Status = NdisMRegisterIoPortRange( (PVOID *)&acb->ExtConfigPorts,
|
||
MiniportAdapterHandle,
|
||
baseaddr + EXTCFG_PORT_OFFSET,
|
||
NUM_EXTCFG_PORTS );
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// Get the pointers to the other head's ports, which are already mapped.
|
||
//
|
||
acb->FirstHeadsAcb = FirstHeadsAcb;
|
||
acb->BasePorts = FirstHeadsAcb->MasterBasePorts;
|
||
acb->ConfigPorts = FirstHeadsAcb->ConfigPorts;
|
||
acb->ExtConfigPorts = FirstHeadsAcb->ExtConfigPorts;
|
||
acb->MasterBasePorts= FirstHeadsAcb->MasterBasePorts;
|
||
Status = NDIS_STATUS_SUCCESS;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// grab ports z000 - z01f
|
||
//
|
||
Status = NdisMRegisterIoPortRange( (PVOID *)&acb->BasePorts,
|
||
MiniportAdapterHandle,
|
||
baseaddr,
|
||
NUM_BASE_PORTS );
|
||
|
||
if (Status == NDIS_STATUS_SUCCESS)
|
||
{
|
||
// grab zc80 - zc85
|
||
//
|
||
Status = NdisMRegisterIoPortRange( (PVOID *)&acb->ConfigPorts,
|
||
MiniportAdapterHandle,
|
||
baseaddr + CFG_PORT_OFFSET,
|
||
NUM_CFG_PORTS );
|
||
|
||
if (Status == NDIS_STATUS_SUCCESS)
|
||
{
|
||
// grab zc63 - zc67
|
||
//
|
||
Status = NdisMRegisterIoPortRange( (PVOID *)&acb->ExtConfigPorts,
|
||
MiniportAdapterHandle,
|
||
baseaddr + EXTCFG_PORT_OFFSET,
|
||
NUM_EXTCFG_PORTS );
|
||
}
|
||
}
|
||
}
|
||
|
||
//
|
||
// If the registration fails, free up the memory we allocated
|
||
// for the acb.
|
||
//
|
||
if (Status != NDIS_STATUS_SUCCESS)
|
||
{
|
||
DebugPrint(0,("NF: Registration FAILED for slot#%d\n",(baseaddr / 1000)));
|
||
goto HandleRegisterError;
|
||
}
|
||
|
||
//
|
||
// Read in the company product id.
|
||
//
|
||
NdisRawReadPortUshort( acb->ConfigPorts, (PUSHORT) &cpqid);
|
||
//
|
||
// Read in the board product id.
|
||
//
|
||
NdisRawReadPortUshort( acb->ConfigPorts + 2, (PUSHORT) &boardid);
|
||
//
|
||
// Does it have a Compaq id?
|
||
//
|
||
// NETFLEX_ID covers NetFlex and NetFlex-2
|
||
// CPQTOK_ID covers DualSpeed and 16/4 Token-Ring
|
||
|
||
if ( !( (cpqid == COMPAQ_ID) &&
|
||
( ((boardid & NETFLEX_REVMASK) == NETFLEX_ID) ||
|
||
((boardid & NETFLEX_REVMASK) == CPQTOK_ID) ||
|
||
((boardid & NETFLEX_REVMASK) == RODAN_ID) ||
|
||
((boardid & NETFLEX_REVMASK) == BONSAI_ID)
|
||
) ) )
|
||
{
|
||
//
|
||
// Not a Compaq id.
|
||
//
|
||
DebugPrint(0,("NF(%d): No Compaq adapter found\n",acb->anum));
|
||
Status = NDIS_STATUS_ADAPTER_NOT_FOUND;
|
||
goto HandleRegisterError;
|
||
}
|
||
|
||
//
|
||
// Make sure this is our board.
|
||
//
|
||
NdisRawReadPortUshort( acb->ConfigPorts + CFG_REGISTER, ®_value);
|
||
|
||
if (!(reg_value & CFG_ENABLE))
|
||
{
|
||
DebugPrint(0,("NF(%d): Adapter is not enabled\n",acb->anum));
|
||
DebugPrint(0,("NF(%d): Board Test Failed\n",acb->anum));
|
||
Status = NDIS_STATUS_ADAPTER_NOT_FOUND;
|
||
goto HandleRegisterError;
|
||
}
|
||
|
||
//
|
||
// Check to see if it's a card with FPA or a dual port adapter
|
||
//
|
||
|
||
if ( (boardid == MAPLE_ID) ||
|
||
(boardid == DURANGO_ID) )
|
||
{
|
||
DebugPrint(1,("NF(%d): We're adding a card using FPA ! \n",acb->anum));
|
||
acb->acb_usefpa = TRUE;
|
||
}
|
||
else if ( ((boardid & NETFLEX_REVMASK) == BONSAI_ID) ||
|
||
((boardid & NETFLEX_REVMASK) == RODAN_ID ) )
|
||
{
|
||
acb->acb_usefpa = TRUE;
|
||
acb->acb_dualport = TRUE;
|
||
acb->acb_portnumber = gbl_portnumbertoadd;
|
||
DebugPrint(1,("NF(%d): We're adding BONSAI or RODAN port #%d\n",acb->anum,acb->acb_portnumber));
|
||
}
|
||
|
||
//
|
||
// Set up the Config register location and the extended sif address
|
||
// register location.
|
||
//
|
||
acb->AdapterConfigPort = acb->ConfigPorts + CFG_REGISTER;
|
||
|
||
if (acb->acb_dualport && (acb->acb_portnumber == PORT2) )
|
||
{
|
||
//
|
||
// Align the ports right for the head #2's ports
|
||
//
|
||
acb->BasePorts = acb->FirstHeadsAcb->BasePorts + DUALHEAD_CFG_PORT_OFFSET;
|
||
|
||
if ((boardid & NETFLEX_REVMASK) == RODAN_ID)
|
||
{
|
||
acb->AdapterConfigPort = acb->MasterBasePorts + CFG_REGRODAN;
|
||
}
|
||
}
|
||
|
||
acb->SifDataPort = acb->BasePorts + SIF_DATA_OFF; /* SIF data register */
|
||
acb->SifDIncPort = acb->BasePorts + SIF_DINC_OFF; /* SIF data autoincrment reg */
|
||
acb->SifAddrPort = acb->BasePorts + SIF_ADDR_OFF; /* SIF address register */
|
||
acb->SifIntPort = acb->BasePorts + SIF_INT_OFF; /* SIF interrupt register */
|
||
acb->SifActlPort = acb->BasePorts + SIF_ACTL_OFF; /* SIF ACTL register */
|
||
acb->SifAddrxPort = acb->BasePorts + SIF_ACTL_EXT_OFF;/* SIF SIF extended address reg */
|
||
|
||
//
|
||
// Save the Board ID
|
||
//
|
||
acb->acb_boardid = boardid;
|
||
|
||
//
|
||
// Do a reset to the adapter
|
||
//
|
||
NdisRawWritePortUshort(acb->SifActlPort, 0xEE);
|
||
|
||
//
|
||
// Wait 15 milliseconds to let the reset take place.
|
||
//
|
||
NdisStallExecution((UINT)15000); // Wait 15 milliseconds
|
||
|
||
//
|
||
// Get the Network type and speed from the eisa config info.
|
||
//
|
||
NetFlexSetupNetType(acb);
|
||
|
||
//
|
||
// Read configuration parameters from the registry if there are any
|
||
//
|
||
|
||
Status = NetFlexReadConfigurationParameters(acb,ConfigHandle);
|
||
if (Status != NDIS_STATUS_SUCCESS)
|
||
{
|
||
DebugPrint(0,("NF(%d): NetFlexReadConfigurationParameters Failed\n",acb->anum));
|
||
Status = NDIS_STATUS_RESOURCES;
|
||
goto HandleRegisterError;
|
||
}
|
||
|
||
HandleRegisterError:
|
||
|
||
if (Status != NDIS_STATUS_SUCCESS)
|
||
{
|
||
if (acb!=NULL)
|
||
{
|
||
if (acb->acb_parms != NULL)
|
||
{
|
||
NdisFreeMemory( (PVOID) acb->acb_parms, (UINT) sizeof(PNETFLEX_PARMS), (UINT) 0);
|
||
}
|
||
*acbp = NULL;
|
||
NdisFreeMemory( (PVOID) acb, (UINT) sizeof(ACB), (UINT) 0);
|
||
}
|
||
}
|
||
|
||
return(Status);
|
||
}
|
||
|
||
|
||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
//
|
||
// Routine Name: NetFlexReadConfigurationParameters
|
||
//
|
||
// Description: This routine reads configuration parameters
|
||
// set by the user in the registry if exist.
|
||
//
|
||
// Input: acb - Adapter Context
|
||
// ConfigHandle
|
||
//
|
||
// Output: Returns NDIS_STATUS_SUCCESS for a successful
|
||
// completion. Otherwise, an error code is
|
||
// returned.
|
||
//
|
||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
NDIS_STATUS
|
||
NetFlexReadConfigurationParameters(
|
||
PACB acb,
|
||
NDIS_HANDLE ConfigHandle
|
||
)
|
||
|
||
{
|
||
NDIS_STATUS status;
|
||
PNETFLEX_PARMS pParms = NULL;
|
||
ULONG length;
|
||
PVOID NetworkAddress;
|
||
BOOLEAN WriteError;
|
||
PNDIS_CONFIGURATION_PARAMETER cfgp;
|
||
|
||
ULONG netspeed = acb->acb_gen_objs.link_speed;
|
||
|
||
NDIS_STRING maxreceives = NDIS_STRING_CONST("MAXRECEIVES");
|
||
NDIS_STRING productid = NDIS_STRING_CONST("PRODUCTID");
|
||
NDIS_STRING earlyrelease = NDIS_STRING_CONST("EARLYRELEASE");
|
||
NDIS_STRING maxtransmits = NDIS_STRING_CONST("MAXTRANSMITS");
|
||
NDIS_STRING maxframesz = NDIS_STRING_CONST("MAXFRAMESIZE");
|
||
NDIS_STRING maxmulticast = NDIS_STRING_CONST("MAXMULTICAST");
|
||
NDIS_STRING maxinternalreqs = NDIS_STRING_CONST("MAXINTERNALREQS");
|
||
NDIS_STRING maxinternalbufs = NDIS_STRING_CONST("MAXINTERNALBUFS");
|
||
NDIS_STRING maxtxbuf = NDIS_STRING_CONST("MAXTXBUF");
|
||
NDIS_STRING mintxbuf = NDIS_STRING_CONST("MINTXBUF");
|
||
NDIS_STRING extremecheckforhang = NDIS_STRING_CONST("ExtremeCheckForHang");
|
||
|
||
#ifdef XMIT_INTS
|
||
NDIS_STRING xmitintratio = NDIS_STRING_CONST("TXINTRATIO");
|
||
#endif
|
||
NDIS_STRING rcvintratio = NDIS_STRING_CONST("RXINTRATIO");
|
||
|
||
//
|
||
// Allocate the Memory for the adapter's parms structure.
|
||
//
|
||
NdisAllocateMemory( (PVOID *)&pParms,
|
||
(UINT) (sizeof (NETFLEX_PARMS)),
|
||
(UINT) 0,
|
||
NetFlexHighestAddress );
|
||
//
|
||
// If we did not get the memory, flag any error.
|
||
//
|
||
if (pParms == NULL)
|
||
{
|
||
return(NDIS_STATUS_RESOURCES);
|
||
}
|
||
|
||
NdisMoveMemory(pParms, &NetFlex_Defaults, sizeof(NETFLEX_PARMS));
|
||
|
||
|
||
//
|
||
// See if the user has specified the maximum number of internal
|
||
// transmit buffers
|
||
//
|
||
NdisReadConfiguration( &status,
|
||
&cfgp,
|
||
ConfigHandle,
|
||
&maxinternalbufs,
|
||
NdisParameterInteger);
|
||
|
||
if (status == NDIS_STATUS_SUCCESS)
|
||
{
|
||
if ( (cfgp->ParameterData.IntegerData <= MAX_INTERNALBUFS) &&
|
||
(cfgp->ParameterData.IntegerData >= MIN_INTERNALBUFS) )
|
||
{
|
||
pParms->utd_maxinternalbufs = (USHORT)cfgp->ParameterData.IntegerData;
|
||
}
|
||
else
|
||
{
|
||
// The parameter is out of range.
|
||
DebugPrint(0,("NF(%d): MAXINTERNALBUFS parameter is out of range, using default\n",acb->anum));
|
||
NdisWriteErrorLogEntry( acb->acb_handle,
|
||
EVENT_NDIS_MAXINTERNALBUFS_ERROR,
|
||
2,
|
||
(ULONG)cfgp->ParameterData.IntegerData,
|
||
(ULONG)pParms->utd_maxinternalbufs);
|
||
}
|
||
}
|
||
|
||
//
|
||
// Read the network specific information from the registry
|
||
//
|
||
if (acb->acb_gen_objs.media_type_in_use == NdisMedium802_5)
|
||
{
|
||
// TokenRing
|
||
//
|
||
//
|
||
// See if early token release has been selected.
|
||
//
|
||
if (netspeed == 16)
|
||
{
|
||
// Default to early token release.
|
||
//
|
||
pParms->utd_open.OPEN_Options |= SWAPS(OOPTS_ETR);
|
||
|
||
NdisReadConfiguration( &status,
|
||
&cfgp,
|
||
ConfigHandle,
|
||
&earlyrelease,
|
||
NdisParameterInteger );
|
||
|
||
if (status == NDIS_STATUS_SUCCESS)
|
||
{
|
||
if ( cfgp->ParameterData.IntegerData == 0)
|
||
{
|
||
// The user does not want early token release.
|
||
//
|
||
pParms->utd_open.OPEN_Options &= SWAPS((~OOPTS_ETR));
|
||
}
|
||
}
|
||
}
|
||
|
||
//
|
||
// Set the framehold bit so that we can allow promiscuous mode
|
||
// to be set later on. We don't necessarily have to set
|
||
// promiscuous mode but if we do, this is a requirement.
|
||
//
|
||
pParms->utd_open.OPEN_Options |= SWAPS(OOPTS_FHOLD);
|
||
|
||
//
|
||
// Set MaxTransmits
|
||
//
|
||
pParms->utd_numsmallbufs = pParms->utd_maxtrans = DF_XMITS_TR;
|
||
//
|
||
// See if the user has specified the maximum number of transmit
|
||
// lists supported.
|
||
//
|
||
|
||
NdisReadConfiguration( &status,
|
||
&cfgp,
|
||
ConfigHandle,
|
||
&maxtransmits,
|
||
NdisParameterInteger);
|
||
|
||
if (status == NDIS_STATUS_SUCCESS)
|
||
{
|
||
if ( (cfgp->ParameterData.IntegerData <= MAX_XMITS_TR) &&
|
||
(cfgp->ParameterData.IntegerData >= MIN_XMITS) )
|
||
{
|
||
pParms->utd_numsmallbufs = pParms->utd_maxtrans = (USHORT)cfgp->ParameterData.IntegerData;
|
||
}
|
||
else
|
||
{
|
||
// The parameter is out of range.
|
||
DebugPrint(0,("NF(%d): MAXTRANSMITS parameter is out of range, using default\n",acb->anum));
|
||
NdisWriteErrorLogEntry( acb->acb_handle,
|
||
EVENT_NDIS_MAXTRANSMITS_ERROR,
|
||
2,
|
||
(ULONG)cfgp->ParameterData.IntegerData,
|
||
(ULONG)pParms->utd_maxtrans);
|
||
}
|
||
}
|
||
|
||
//
|
||
// See if the user has specified the maximum frame size.
|
||
//
|
||
pParms->utd_maxframesz = DF_FRAMESIZE_TR;
|
||
WriteError = FALSE;
|
||
NdisReadConfiguration( &status,
|
||
&cfgp,
|
||
ConfigHandle,
|
||
&maxframesz,
|
||
NdisParameterInteger);
|
||
|
||
if (status == NDIS_STATUS_SUCCESS)
|
||
{
|
||
if (cfgp->ParameterData.IntegerData < MIN_FRAMESIZE)
|
||
{
|
||
pParms->utd_maxframesz = MIN_FRAMESIZE;
|
||
WriteError = TRUE;
|
||
}
|
||
else if (netspeed == 16)
|
||
{
|
||
// 16 Mb
|
||
//
|
||
if (cfgp->ParameterData.IntegerData > MAX_FRAMESIZE_TR16)
|
||
{
|
||
pParms->utd_maxframesz = MAX_FRAMESIZE_TR16;
|
||
WriteError = TRUE;
|
||
}
|
||
else
|
||
{
|
||
pParms->utd_maxframesz = (USHORT)cfgp->ParameterData.IntegerData;
|
||
}
|
||
}
|
||
//
|
||
// 4Mb
|
||
//
|
||
else if (cfgp->ParameterData.IntegerData > MAX_FRAMESIZE_TR4)
|
||
{
|
||
pParms->utd_maxframesz = MAX_FRAMESIZE_TR4;
|
||
WriteError = TRUE;
|
||
}
|
||
else
|
||
{
|
||
pParms->utd_maxframesz = (USHORT)cfgp->ParameterData.IntegerData;
|
||
}
|
||
|
||
if (WriteError)
|
||
{
|
||
// The parameter is out of range.
|
||
NdisWriteErrorLogEntry( acb->acb_handle,
|
||
EVENT_NDIS_MAXFRAMESIZE_ERROR,
|
||
2,
|
||
(ULONG)cfgp->ParameterData.IntegerData,
|
||
(ULONG)pParms->utd_maxframesz);
|
||
|
||
DebugPrint(0,("NF(%d): MaxFrameSize parameter is out of range, using default\n",acb->anum));
|
||
}
|
||
}
|
||
|
||
//
|
||
// See if the user has specified the maximum number of Receive
|
||
// lists supported.
|
||
//
|
||
pParms->utd_maxrcvs = DF_RCVS_TR;
|
||
|
||
NdisReadConfiguration( &status,
|
||
&cfgp,
|
||
ConfigHandle,
|
||
&maxreceives,
|
||
NdisParameterInteger);
|
||
|
||
if (status == NDIS_STATUS_SUCCESS)
|
||
{
|
||
if ( (cfgp->ParameterData.IntegerData <= MAX_RCVS_TR) &&
|
||
(cfgp->ParameterData.IntegerData >= MIN_RCVS) )
|
||
{
|
||
pParms->utd_maxrcvs = (USHORT)cfgp->ParameterData.IntegerData;
|
||
}
|
||
else
|
||
{
|
||
// The parameter is out of range.
|
||
NdisWriteErrorLogEntry( acb->acb_handle,
|
||
EVENT_NDIS_MAXRECEIVES_ERROR,
|
||
2,
|
||
(ULONG)cfgp->ParameterData.IntegerData,
|
||
(ULONG)pParms->utd_maxrcvs);
|
||
|
||
DebugPrint(0,("NF(%d): MAXReceives parameter is out of range, using default\n",acb->anum));
|
||
}
|
||
}
|
||
|
||
//
|
||
// Adjust Number of Lists based on size of Max TR Frame Size
|
||
//
|
||
//
|
||
// For every frame size which is greater than a multiple of 4096,
|
||
// decrease number of transmits, Receives, and internal buffers.
|
||
//
|
||
if (pParms->utd_maxframesz > DF_FRAMESIZE_TR)
|
||
{
|
||
if (pParms->utd_maxframesz < ( (DF_FRAMESIZE_TR*2)+2) )
|
||
{
|
||
pParms->utd_maxtrans = MAX_XMITS_TR-2; /* 6 xmits, 30 mapregs */
|
||
pParms->utd_maxrcvs = MAX_XMITS_TR-2;
|
||
pParms->utd_maxinternalbufs = pParms->utd_maxtrans / 2;
|
||
}
|
||
else
|
||
{
|
||
pParms->utd_maxtrans = MAX_XMITS_TR-4; /* 4 xmits, 25 mapregs */
|
||
pParms->utd_maxrcvs = MAX_XMITS_TR-4;
|
||
pParms->utd_maxinternalbufs = pParms->utd_maxtrans / 2;
|
||
}
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
// Ethernet
|
||
//
|
||
//
|
||
// Set the framehold bit so that we can allow promiscuous mode
|
||
// to be set later on. We don't necessarily have to set
|
||
// promiscuous mode but if we do, this is a requirement.
|
||
//
|
||
pParms->utd_open.OPEN_Options |= SWAPS(OOPTS_REQ + OOPTS_FHOLD);
|
||
pParms->utd_maxframesz = DF_FRAMESIZE_ETH;
|
||
|
||
//
|
||
// See if the user has specified the maximum number of multicast
|
||
// addresses supported.
|
||
//
|
||
|
||
pParms->utd_maxmulticast = DF_MULTICASTS;
|
||
|
||
NdisReadConfiguration( &status,
|
||
&cfgp,
|
||
ConfigHandle,
|
||
&maxmulticast,
|
||
NdisParameterInteger);
|
||
|
||
if (status == NDIS_STATUS_SUCCESS)
|
||
{
|
||
if ( (cfgp->ParameterData.IntegerData <= MAX_MULTICASTS) &&
|
||
(cfgp->ParameterData.IntegerData >= MIN_MULTICASTS) )
|
||
{
|
||
pParms->utd_maxmulticast = (USHORT)cfgp->ParameterData.IntegerData;
|
||
}
|
||
else
|
||
{
|
||
// The parameter is out of range.
|
||
DebugPrint(0,("NF(%d): MAXMULTICAST Parameter is out of range, using default\n",acb->anum));
|
||
NdisWriteErrorLogEntry( acb->acb_handle,
|
||
EVENT_NDIS_MAXMULTICAST_ERROR,
|
||
2,
|
||
(ULONG)cfgp->ParameterData.IntegerData,
|
||
(ULONG)pParms->utd_maxmulticast);
|
||
}
|
||
}
|
||
|
||
//
|
||
// See if the user has specified the maximum number of transmit lists.
|
||
//
|
||
|
||
pParms->utd_numsmallbufs = pParms->utd_maxtrans = DF_XMITS_ETH;
|
||
|
||
NdisReadConfiguration( &status,
|
||
&cfgp,
|
||
ConfigHandle,
|
||
&maxtransmits,
|
||
NdisParameterInteger);
|
||
|
||
if (status == NDIS_STATUS_SUCCESS)
|
||
{
|
||
if ( (cfgp->ParameterData.IntegerData <= MAX_XMITS_ETH) &&
|
||
(cfgp->ParameterData.IntegerData >= MIN_XMITS) )
|
||
{
|
||
pParms->utd_numsmallbufs = pParms->utd_maxtrans = (USHORT)cfgp->ParameterData.IntegerData;
|
||
}
|
||
else
|
||
{
|
||
// The parameter is out of range.
|
||
DebugPrint(0,("NF(%d): MAXTRANSMITS parameter is out of range, using default\n",acb->anum));
|
||
NdisWriteErrorLogEntry( acb->acb_handle,
|
||
EVENT_NDIS_MAXTRANSMITS_ERROR,
|
||
2,
|
||
(ULONG)cfgp->ParameterData.IntegerData,
|
||
(ULONG)pParms->utd_maxtrans);
|
||
}
|
||
}
|
||
|
||
//
|
||
// See if the user has specified the maximum frame size.
|
||
//
|
||
WriteError = FALSE;
|
||
pParms->utd_maxframesz = MAX_FRAMESIZE_ETH;
|
||
|
||
NdisReadConfiguration( &status,
|
||
&cfgp,
|
||
ConfigHandle,
|
||
&maxframesz,
|
||
NdisParameterInteger);
|
||
|
||
if (status == NDIS_STATUS_SUCCESS)
|
||
{
|
||
if (cfgp->ParameterData.IntegerData < MIN_FRAMESIZE)
|
||
{
|
||
pParms->utd_maxframesz = MIN_FRAMESIZE;
|
||
WriteError = TRUE;
|
||
}
|
||
else if (cfgp->ParameterData.IntegerData > MAX_FRAMESIZE_ETH)
|
||
{
|
||
pParms->utd_maxframesz = MAX_FRAMESIZE_ETH;
|
||
WriteError = TRUE;
|
||
}
|
||
else
|
||
{
|
||
pParms->utd_maxframesz = (USHORT)cfgp->ParameterData.IntegerData;
|
||
}
|
||
|
||
if (WriteError)
|
||
{
|
||
// The parameter is out of range.
|
||
NdisWriteErrorLogEntry( acb->acb_handle,
|
||
EVENT_NDIS_MAXFRAMESIZE_ERROR,
|
||
2,
|
||
(ULONG)cfgp->ParameterData.IntegerData,
|
||
(ULONG)pParms->utd_maxframesz);
|
||
|
||
DebugPrint(0,("NF(%d): MaxFrameSize parameter is out of range, using default\n",acb->anum));
|
||
}
|
||
}
|
||
|
||
//
|
||
// See if the user has specified the maximum number of Receive
|
||
// lists supported.
|
||
//
|
||
|
||
pParms->utd_maxrcvs = DF_RCVS_ETH;
|
||
|
||
NdisReadConfiguration( &status,
|
||
&cfgp,
|
||
ConfigHandle,
|
||
&maxreceives,
|
||
NdisParameterInteger);
|
||
|
||
if (status == NDIS_STATUS_SUCCESS)
|
||
{
|
||
if ( (cfgp->ParameterData.IntegerData <= MAX_RCVS_ETH) &&
|
||
(cfgp->ParameterData.IntegerData >= MIN_RCVS) )
|
||
{
|
||
pParms->utd_maxrcvs = (USHORT)cfgp->ParameterData.IntegerData;
|
||
}
|
||
else
|
||
{
|
||
// The parameter is out of range.
|
||
NdisWriteErrorLogEntry( acb->acb_handle,
|
||
EVENT_NDIS_MAXRECEIVES_ERROR,
|
||
(ULONG)cfgp->ParameterData.IntegerData,
|
||
(ULONG)pParms->utd_maxrcvs);
|
||
DebugPrint(0,("NF(%d): MAXReceives parameter is out of range, using default\n",acb->anum));
|
||
}
|
||
}
|
||
}
|
||
|
||
DebugPrint(1,("NF(%d): MaxFrameSize = %d\n",acb->anum,pParms->utd_maxframesz));
|
||
DebugPrint(1,("NF(%d): MaxTransmits = %d\n",acb->anum,pParms->utd_maxtrans));
|
||
DebugPrint(1,("NF(%d): MaxReceives = %d\n",acb->anum,pParms->utd_maxrcvs));
|
||
|
||
//
|
||
// Common Configuration settings for both Ethernet and TokenRing
|
||
//
|
||
|
||
//
|
||
// See if the user has specified extreme checking for adapter hang.
|
||
//
|
||
NdisReadConfiguration(&status,
|
||
&cfgp,
|
||
ConfigHandle,
|
||
&extremecheckforhang,
|
||
NdisParameterInteger);
|
||
if ((NDIS_STATUS_SUCCESS == status) &&
|
||
(cfgp->ParameterData.IntegerData != 0))
|
||
{
|
||
//
|
||
// They want the extreme checking to see if this adapter is
|
||
// hung.
|
||
//
|
||
pParms->utd_extremecheckforhang = TRUE;
|
||
}
|
||
|
||
//
|
||
// See if the user has specified the maximum number of adapter transmit buffers.
|
||
//
|
||
NdisReadConfiguration( &status,
|
||
&cfgp,
|
||
ConfigHandle,
|
||
&maxtxbuf,
|
||
NdisParameterInteger);
|
||
|
||
//
|
||
// Set default Transmist_Buffer_Maximum_Count based on the max frame size * 2 tx lists
|
||
//
|
||
|
||
pParms->utd_open.OPEN_Xbufmax = ((pParms->utd_maxframesz / 1024) + 1 ) * 2;
|
||
|
||
if (status == NDIS_STATUS_SUCCESS)
|
||
{
|
||
// Make Sure the value doesn't preclude us from transmiting a max frame size
|
||
//
|
||
if (cfgp->ParameterData.IntegerData > (UINT) (pParms->utd_maxframesz / 1024))
|
||
{
|
||
pParms->utd_open.OPEN_Xbufmax = (UCHAR)cfgp->ParameterData.IntegerData;
|
||
}
|
||
else
|
||
{
|
||
// The parameter is out of range.
|
||
DebugPrint(0,("NF(%d): MaxTXBuf parameter is out of range, using default\n",acb->anum));
|
||
}
|
||
}
|
||
|
||
DebugPrint(1,("NF(%d): MaxTXBuf = 0x%x\n",acb->anum,pParms->utd_open.OPEN_Xbufmax));
|
||
|
||
//
|
||
// See if the user has specified the minimum number of adapter transmit buffers.
|
||
//
|
||
NdisReadConfiguration( &status,
|
||
&cfgp,
|
||
ConfigHandle,
|
||
&mintxbuf,
|
||
NdisParameterInteger);
|
||
|
||
//
|
||
// Set default Transmist_Buffer_Minimum_Count based on the max
|
||
//
|
||
pParms->utd_open.OPEN_Xbufmin = pParms->utd_open.OPEN_Xbufmax;
|
||
|
||
if (status == NDIS_STATUS_SUCCESS)
|
||
{
|
||
|
||
if ((cfgp->ParameterData.IntegerData >= 0) &&
|
||
(cfgp->ParameterData.IntegerData <= pParms->utd_open.OPEN_Xbufmax) )
|
||
{
|
||
pParms->utd_open.OPEN_Xbufmin = (UCHAR)cfgp->ParameterData.IntegerData;
|
||
}
|
||
else
|
||
{
|
||
// The parameter is out of range.
|
||
DebugPrint(0,("NF(%d): MinTXBuf parameter is out of range, using default\n",acb->anum));
|
||
}
|
||
}
|
||
|
||
DebugPrint(1,("NF(%d): MinTXBuf = 0x%x\n",acb->anum,pParms->utd_open.OPEN_Xbufmin));
|
||
|
||
|
||
//
|
||
// See if the user has specified the maximum number of internal
|
||
// requests supported.
|
||
//
|
||
NdisReadConfiguration( &status,
|
||
&cfgp,
|
||
ConfigHandle,
|
||
&maxinternalreqs,
|
||
NdisParameterInteger);
|
||
|
||
if (status == NDIS_STATUS_SUCCESS)
|
||
{
|
||
if ( (cfgp->ParameterData.IntegerData <= MAX_INTERNALREQS) &&
|
||
(cfgp->ParameterData.IntegerData >= MIN_INTERNALREQS) )
|
||
{
|
||
pParms->utd_maxinternalreqs = (USHORT)cfgp->ParameterData.IntegerData;
|
||
}
|
||
else
|
||
{
|
||
// The parameter is out of range.
|
||
DebugPrint(0,("NF(%d): MAXINTERNALREQS parameter is out of range, using default\n",acb->anum));
|
||
}
|
||
}
|
||
|
||
//
|
||
// See if the user has specified the node address
|
||
//
|
||
NdisReadNetworkAddress( &status,
|
||
&NetworkAddress,
|
||
&length,
|
||
ConfigHandle );
|
||
|
||
if ((length == NET_ADDR_SIZE) && (status == NDIS_STATUS_SUCCESS))
|
||
{
|
||
NdisMoveMemory((PUCHAR)pParms->utd_open.OPEN_NodeAddr,
|
||
(PUCHAR)NetworkAddress,
|
||
NET_ADDR_SIZE);
|
||
}
|
||
else
|
||
{
|
||
DebugPrint(1,("NF(%d): Error in NdisReadNetworkAddress or none specified\n",acb->anum));
|
||
}
|
||
|
||
//
|
||
// See if the user has specified the product id
|
||
//
|
||
NdisReadConfiguration( &status,
|
||
&cfgp,
|
||
ConfigHandle,
|
||
&productid,NdisParameterString );
|
||
|
||
if (status == NDIS_STATUS_SUCCESS)
|
||
{
|
||
status = NetFlexAsciiToHex( &(cfgp->ParameterData.StringData),
|
||
(PUCHAR)pParms->utd_open.OPEN_ProdID,
|
||
(USHORT)(18) );
|
||
if (status != NDIS_STATUS_SUCCESS)
|
||
{
|
||
// The parameter is out of range.
|
||
DebugPrint(1,("NF(%d): PRODUCTID parameter is invalid, using default\n",acb->anum));
|
||
NdisWriteErrorLogEntry( acb->acb_handle,
|
||
EVENT_NDIS_PRODUCTID_ERROR,
|
||
0);
|
||
}
|
||
}
|
||
|
||
//
|
||
// See if we need to open in Full Duplex
|
||
//
|
||
if (acb->FullDuplexEnabled)
|
||
{
|
||
//
|
||
// Allocate the xmit spin lock.
|
||
//
|
||
NdisAllocateSpinLock(&acb->XmitLock);
|
||
|
||
pParms->utd_open.OPEN_Options |= SWAPS(OOPTS_FULLDUP);
|
||
}
|
||
|
||
acb->acb_parms = pParms;
|
||
|
||
#ifdef XMIT_INTS
|
||
//
|
||
// See if the user has specified the xmit_int_ratio
|
||
//
|
||
|
||
acb->XmitIntRatio = TxIntRatio;
|
||
|
||
NdisReadConfiguration( &status,
|
||
&cfgp,
|
||
ConfigHandle,
|
||
&xmitintratio,
|
||
NdisParameterInteger);
|
||
|
||
if (status == NDIS_STATUS_SUCCESS) {
|
||
acb->XmitIntRatio = (USHORT)cfgp->ParameterData.IntegerData;
|
||
}
|
||
DebugPrint(1,("NF(%d): TxIntRatio = 1:%d\n",acb->anum,acb->XmitIntRatio));
|
||
#endif
|
||
|
||
//
|
||
// See if the user has specified the rcv_int_ratio
|
||
//
|
||
|
||
acb->RcvIntRatio = RxIntRatio;
|
||
|
||
NdisReadConfiguration( &status,
|
||
&cfgp,
|
||
ConfigHandle,
|
||
&rcvintratio,
|
||
NdisParameterInteger);
|
||
|
||
if (status == NDIS_STATUS_SUCCESS)
|
||
{
|
||
acb->RcvIntRatio = (USHORT)cfgp->ParameterData.IntegerData;
|
||
}
|
||
DebugPrint(1,("NF(%d): Rx Int Ratio = 1:%d\n",acb->anum,acb->RcvIntRatio));
|
||
|
||
return NDIS_STATUS_SUCCESS;
|
||
}
|
||
|
||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
//
|
||
// Routine Name: NetFlexBoardInitandReg
|
||
//
|
||
// Description: This routine initiailizes the board, downloads
|
||
// the mac code, and registers the adapter with
|
||
// the wrapper.
|
||
//
|
||
// Input: acbp - Pointer to an acb ptr.
|
||
// pParms - Settable parameters
|
||
//
|
||
// Output: acbp - Pointer to allocated acb
|
||
// Returns NDIS_STATUS_SUCCESS for a successful
|
||
// completion. Otherwise, an error code is
|
||
// returned.
|
||
//
|
||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
NDIS_STATUS
|
||
NetFlexBoardInitandReg(
|
||
PACB acb,
|
||
PNDIS_EISA_FUNCTION_INFORMATION EisaData
|
||
)
|
||
{
|
||
UINT int_vector;
|
||
NDIS_INTERRUPT_MODE int_mode;
|
||
NDIS_STATUS status;
|
||
UINT i=0;
|
||
|
||
//
|
||
// Initialize the fields of the acb.
|
||
//
|
||
if ((status = NetFlexInitializeAcb(acb)) != NDIS_STATUS_SUCCESS)
|
||
{
|
||
// Failed, get out now...
|
||
//
|
||
return status;
|
||
}
|
||
|
||
//
|
||
// Get EISA Config Data so we can set the interrupt data
|
||
//
|
||
int_vector = EisaData->EisaIrq[0].ConfigurationByte.Interrupt;
|
||
|
||
if (!int_vector)
|
||
{
|
||
return NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION;
|
||
}
|
||
|
||
if (gbl_addingdualport)
|
||
{
|
||
// Dualport boards share the same interupt between heads
|
||
//
|
||
acb->InterruptsShared = TRUE;
|
||
}
|
||
else
|
||
{
|
||
acb->InterruptsShared = EisaData->EisaIrq[0].ConfigurationByte.Shared;
|
||
}
|
||
|
||
int_mode = EisaData->EisaIrq[0].ConfigurationByte.LevelTriggered ? NdisInterruptLevelSensitive : NdisInterruptLatched;
|
||
|
||
//
|
||
// Add this acb to the global list
|
||
//
|
||
acb->acb_next = macgbls.mac_adapters;
|
||
macgbls.mac_adapters = acb;
|
||
|
||
//
|
||
// Initialize the interrupt.
|
||
//
|
||
status = NdisMRegisterInterrupt( &acb->acb_interrupt,
|
||
acb->acb_handle,
|
||
int_vector,
|
||
int_vector,
|
||
FALSE, // TRUE,
|
||
acb->InterruptsShared,
|
||
int_mode );
|
||
|
||
if (status != NDIS_STATUS_SUCCESS)
|
||
{
|
||
DebugPrint(0,("NF(%d): Initialization of the Interrupt FAILED\n",acb->anum));
|
||
|
||
NetFlexDequeue_OnePtrQ( (PVOID *)&macgbls.mac_adapters,
|
||
(PVOID)acb);
|
||
|
||
return status;
|
||
}
|
||
|
||
//
|
||
// Ok, we're set, so reset the adapter and open'er up!
|
||
// Try three times...
|
||
//
|
||
do
|
||
{
|
||
status = NetFlexAdapterReset(acb,HARD_RESET);
|
||
if (status == NDIS_STATUS_SUCCESS)
|
||
{
|
||
//
|
||
// Send the Open Command
|
||
//
|
||
status = NetFlexOpenAdapter(acb);
|
||
}
|
||
|
||
} while ((++i < 3) && (status != NDIS_STATUS_SUCCESS));
|
||
|
||
if (status != NDIS_STATUS_SUCCESS)
|
||
{
|
||
// Something failed, so get out.
|
||
//
|
||
return status;
|
||
}
|
||
|
||
//
|
||
// Get the Burned In Address
|
||
//
|
||
|
||
NetFlexGetBIA(acb);
|
||
|
||
//
|
||
// Set the Default DPC timer
|
||
//
|
||
|
||
NdisMSetTimer(&acb->DpcTimer, 10);
|
||
|
||
//
|
||
// Indidicate that we're done with initializing this adapter.
|
||
//
|
||
acb->AdapterInitializing = FALSE;
|
||
|
||
return NDIS_STATUS_SUCCESS;
|
||
}
|
||
|
||
|
||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
//
|
||
// Routine Name: NetFlexInitGlobals
|
||
//
|
||
// Description: This routine initializes the global
|
||
// variables and downloads the mac download
|
||
// code into our map buffer area.
|
||
//
|
||
// Input: None.
|
||
//
|
||
// Output: Status = SUCCESS .
|
||
//
|
||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
NDIS_STATUS
|
||
NetFlexInitGlobals(
|
||
)
|
||
{
|
||
NDIS_STRING maccode = NDIS_STRING_CONST("NETFLX.BIN");
|
||
UINT length;
|
||
NDIS_STATUS status;
|
||
PUSHORT MappedBuffer;
|
||
NDIS_HANDLE mac_filehandle;
|
||
|
||
//
|
||
// Open the file containing the MAC download code.
|
||
//
|
||
NdisOpenFile( &status,
|
||
&mac_filehandle,
|
||
&length,
|
||
&maccode,
|
||
NetFlexHighestAddress);
|
||
|
||
if (status != NDIS_STATUS_SUCCESS)
|
||
{
|
||
DebugPrint(0,("NF: Download file could not be opened\n"));
|
||
return status;
|
||
}
|
||
|
||
//
|
||
// Allocate the buffer.
|
||
//
|
||
NdisAllocateMemory( (PVOID *)&macgbls.DownloadCode,
|
||
length,
|
||
FALSE,
|
||
NetFlexHighestAddress);
|
||
|
||
if (macgbls.DownloadCode == NULL)
|
||
{
|
||
status = NDIS_STATUS_FAILURE;
|
||
}
|
||
else
|
||
{
|
||
// Store the length
|
||
//
|
||
macgbls.DownloadLength = length;
|
||
//
|
||
// Get a mapping to the opened download file.
|
||
//
|
||
NdisMapFile( &status,
|
||
(PVOID *)&MappedBuffer,
|
||
mac_filehandle);
|
||
|
||
if (status != NDIS_STATUS_SUCCESS)
|
||
{
|
||
DebugPrint(0,("NF: Download file could not be mapped\n"));
|
||
}
|
||
else
|
||
{
|
||
// Copy the download code into the shared memory space
|
||
//
|
||
NdisMoveMemory(macgbls.DownloadCode,MappedBuffer,length);
|
||
NdisUnmapFile(mac_filehandle);
|
||
}
|
||
|
||
//
|
||
// Done with the file
|
||
NdisCloseFile(mac_filehandle);
|
||
}
|
||
|
||
return status;
|
||
}
|