summaryrefslogtreecommitdiffstats
path: root/private/ntos/ndis/dc21x4/init.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--private/ntos/ndis/dc21x4/init.c881
1 files changed, 881 insertions, 0 deletions
diff --git a/private/ntos/ndis/dc21x4/init.c b/private/ntos/ndis/dc21x4/init.c
new file mode 100644
index 000000000..915a085fc
--- /dev/null
+++ b/private/ntos/ndis/dc21x4/init.c
@@ -0,0 +1,881 @@
+/*+
+ * file: init.c
+ *
+ * Copyright (C) 1992-1995 by
+ * Digital Equipment Corporation, Maynard, Massachusetts.
+ * All rights reserved.
+ *
+ * This software is furnished under a license and may be used and copied
+ * only in accordance of the terms of such license and with the
+ * inclusion of the above copyright notice. This software or any other
+ * copies thereof may not be provided or otherwise made available to any
+ * other person. No title to and ownership of the software is hereby
+ * transferred.
+ *
+ * The information in this software is subject to change without notice
+ * and should not be construed as a commitment by digital equipment
+ * corporation.
+ *
+ * Digital assumes no responsibility for the use or reliability of its
+ * software on equipment which is not supplied by digital.
+ *
+ *
+ * Abstract: This file is part of the NDIS 4.0 miniport driver for
+ * DEC's DC21X4 Ethernet Adapter family.
+ * It contains the adapter's register initialization routines
+ *
+ * Author: Philippe Klein
+ *
+ * Revision History:
+ *
+ * phk 28-Aug-1992 Initial entry
+ *
+-*/
+
+#include <precomp.h>
+
+
+
+
+
+
+
+
+
+
+/*+
+ *
+ * DC21X4InitPciConfigurationRegisters
+ *
+ * Routine Description:
+ *
+ * This routine initialize the DC21X4 PCI Configuration
+ * Registers
+ *
+ * Arguments:
+ *
+ * Adapter - The adapter whose hardware is to be initialized.
+ *
+ * Return Value:
+ *
+ * NONE
+ *
+-*/
+extern
+VOID
+DC21X4InitPciConfigurationRegisters(
+ IN PDC21X4_ADAPTER Adapter
+ )
+{
+
+ ULONG Value;
+ BOOLEAN SetTimer = FALSE;
+
+#if _DBG
+ DbgPrint("DC21X4InitPciConfigurationRegisters\n");
+#endif
+
+ switch (Adapter->AdapterType) {
+
+ case NdisInterfacePci:
+
+ //initialize the Command Register
+
+ NdisWritePciSlotInformation(
+ Adapter->MiniportAdapterHandle,
+ Adapter->SlotNumber,
+ PCI_CFCS_OFFSET,
+ &Adapter->PciCommand,
+ sizeof(Adapter->PciCommand)
+ );
+
+ //initialize the latency timer if not initialized already
+ //or if a latency value has been stored in the Registry
+
+ if (Adapter->PciLatencyTimer) {
+ SetTimer = TRUE;
+ }
+ else {
+ NdisReadPciSlotInformation(
+ Adapter->MiniportAdapterHandle,
+ Adapter->SlotNumber,
+ PCI_CFLT_OFFSET,
+ &Adapter->PciLatencyTimer,
+ sizeof(Adapter->PciLatencyTimer)
+ );
+
+ if (Adapter->PciLatencyTimer == 0) {
+ Adapter->PciLatencyTimer =
+ DC21X4_PCI_LATENCY_TIMER_DEFAULT_VALUE;
+ SetTimer = TRUE;
+ }
+ }
+
+ if (SetTimer) {
+
+ NdisWritePciSlotInformation(
+ Adapter->MiniportAdapterHandle,
+ Adapter->SlotNumber,
+ PCI_CFLT_OFFSET,
+ &Adapter->PciLatencyTimer,
+ sizeof(Adapter->PciLatencyTimer)
+ );
+ }
+
+ // Initialize the CFDA Register
+
+ NdisWritePciSlotInformation(
+ Adapter->MiniportAdapterHandle,
+ Adapter->SlotNumber,
+ PCI_CFDA_OFFSET,
+ &Adapter->PciDriverArea,
+ sizeof(Adapter->PciDriverArea)
+ );
+
+#if __DBG
+ NdisReadPciSlotInformation(
+ Adapter->MiniportAdapterHandle,
+ Adapter->SlotNumber,
+ PCI_CFCS_OFFSET,
+ &Value,
+ sizeof(Value)
+ );
+
+ DbgPrint("CFCS = %08x\n",Value);
+
+ NdisReadPciSlotInformation(
+ Adapter->MiniportAdapterHandle,
+ Adapter->SlotNumber,
+ PCI_CFLT_OFFSET,
+ &Value,
+ sizeof(Value)
+ );
+
+ DbgPrint("CFLT = %08x\n",Value);
+
+
+ NdisReadPciSlotInformation(
+ Adapter->MiniportAdapterHandle,
+ Adapter->SlotNumber,
+ PCI_CBIO_OFFSET,
+ &Value,
+ sizeof(Value)
+ );
+
+ DbgPrint("CBIO = %08x\n",Value);
+
+ NdisReadPciSlotInformation(
+ Adapter->MiniportAdapterHandle,
+ Adapter->SlotNumber,
+ PCI_CFDA_OFFSET,
+ &Value,
+ sizeof(Value)
+ );
+
+ DbgPrint("CFDA = %08x\n",Value);
+
+#endif
+
+ break;
+
+ case NdisInterfaceEisa:
+
+ DC21X4_WRITE_PCI_REGISTER(
+ DC21X4_PCI_COMMAND,
+ Adapter->PciCommand
+ );
+
+ DC21X4_WRITE_PCI_REGISTER(
+ DC21X4_PCI_LATENCY_TIMER,
+ DC21X4_PCI_LATENCY_TIMER_DEFAULT_VALUE
+ );
+
+ DC21X4_WRITE_PCI_REGISTER(
+ DC21X4_PCI_BASE_IO_ADDRESS,
+ (Adapter->IOBaseAddress | DC21X4_IO_SPACE)
+ );
+ }
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*+
+ *
+ * DC21X4InitializeRegisters
+ *
+ * Routine Description:
+ *
+ * This routine initialize the DC21X4 CSRs
+ *
+ * Arguments:
+ *
+ * Adapter - The adapter whose hardware is to be initialized.
+ *
+ * Return Value:
+ *
+ * NONE
+ *
+-*/
+extern
+VOID
+DC21X4InitializeRegisters(
+ IN PDC21X4_ADAPTER Adapter
+ )
+{
+
+ UINT i;
+
+ PDC21X4_TRANSMIT_DESCRIPTOR TransmitDescriptor;
+ PDC21X4_RECEIVE_DESCRIPTOR ReceiveDescriptor;
+
+ // Reset DC21X4
+
+ DC21X4StopAdapter(Adapter);
+
+ switch (Adapter->AdapterType) {
+
+ case NdisInterfaceEisa:
+
+ DC21X4InitPciConfigurationRegisters (Adapter);
+ break;
+
+ case NdisInterfacePci:
+
+ switch (Adapter->DeviceId) {
+
+ case DC21040_CFID :
+
+ if (Adapter->RevisionNumber == DC21040_REV1) {
+
+ // The PCI configuration registers should
+ // be reinitialized after reset
+
+ DC21X4InitPciConfigurationRegisters (Adapter);
+ }
+ break;
+
+ case DC21140_CFID :
+
+ //Initialize PortSelect and reset the chip
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Adapter->OperationMode & ~(DC21X4_RCV_START | DC21X4_TXM_START)
+ );
+
+ DC21X4StopAdapter(Adapter);
+
+ break;
+ }
+ }
+
+ // Initialize the descriptor ownership in the
+ // Transmit and Receive descriptor rings
+
+ for (i=0,
+ TransmitDescriptor = (PDC21X4_TRANSMIT_DESCRIPTOR)Adapter->TransmitDescriptorRingVa;
+ i < TRANSMIT_RING_SIZE;
+ i++) {
+ TransmitDescriptor->Status = DESC_OWNED_BY_SYSTEM;
+ TransmitDescriptor = TransmitDescriptor->Next;
+ }
+
+ for (i=0,
+ ReceiveDescriptor = (PDC21X4_RECEIVE_DESCRIPTOR)Adapter->ReceiveDescriptorRingVa;
+ i < Adapter->ReceiveRingSize;
+ i++) {
+ ReceiveDescriptor->Status = DESC_OWNED_BY_DC21X4;
+ ReceiveDescriptor = ReceiveDescriptor->Next;
+ }
+
+ // Initialize the DC21X4 CSRs
+
+#if _DBG
+ DbgPrint(" Init DC21X4 CSRs\n");
+#endif
+
+#if __DBG
+ DbgPrint(" CSR0 (bus mode): %08x\n",
+ Adapter->BusMode);
+#endif
+ DC21X4_WRITE_PORT(
+ DC21X4_BUS_MODE,
+ Adapter->BusMode
+ );
+
+#if __DBG
+ DbgPrint(" CSR3 (Rx desc Ring): %08x\n",
+ Adapter->ReceiveDescriptorRingPa);
+#endif
+ DC21X4_WRITE_PORT(
+ DC21X4_RCV_DESC_RING,
+ Adapter->ReceiveDescriptorRingPa
+ );
+#if _DBG
+ DbgPrint(" CSR4 (Tx desc Ring): %08x\n",
+ Adapter->TransmitDescriptorRingPa);
+#endif
+ DC21X4_WRITE_PORT(
+ DC21X4_TXM_DESC_RING,
+ Adapter->TransmitDescriptorRingPa
+ );
+
+
+ switch (Adapter->DeviceId) {
+
+ case DC21040_CFID :
+
+ DC21X4_WRITE_PORT(
+ DC21X4_RESERVED,
+ 0
+ );
+
+ }
+
+}
+
+
+
+
+
+
+
+
+
+
+/*+
+ *
+ * DC21X4StopAdapter
+ *
+ *
+ * Routine Description:
+ *
+ * This routine stops the DC21X4 by resetting
+ * the chip.
+ *
+ * NOTE: This is not a gracefull stop.
+ *
+ * Arguments:
+ *
+ * Adapter - The adapter for the DC21X4 to stop.
+ *
+ * Return Value:
+ *
+ * None.
+ *
+-*/
+extern
+VOID
+DC21X4StopAdapter(
+ IN PDC21X4_ADAPTER Adapter
+ )
+{
+
+#if __DBG
+ DbgPrint("DC21X4StopAdapter\n");
+#endif
+
+ DC21X4IndicateMediaStatus(Adapter,LinkFail);
+
+ switch (Adapter->AdapterType) {
+
+ case NdisInterfaceEisa:
+
+ // Use HW reset instead of SW reset
+
+#if _DBG
+ DbgPrint(" HW reset\n");
+#endif
+
+ NdisRawWritePortUchar (
+ Adapter->PortOffset + EISA_REG1_OFFSET,
+ 0x01
+ );
+
+ NdisRawWritePortUchar (
+ Adapter->PortOffset + EISA_REG1_OFFSET,
+ 0
+ );
+
+ break;
+
+ default:
+
+ // Set the SW Reset bit in BUS_MODE register
+
+#if _DBG
+ DbgPrint(" SW reset\n");
+#endif
+
+ DC21X4_WRITE_PORT(
+ DC21X4_BUS_MODE,
+ DC21X4_SW_RESET);
+ }
+
+ // Wait 50 PCI bus cycles to wait for reset completion
+
+ NdisStallExecution(2*MILLISECOND); // Wait for 2 ms
+
+}
+
+
+
+
+
+
+
+
+
+
+/*+
+ *
+ * DC21X4StartAdapter
+ *
+ *
+ * Routine Description:
+ *
+ * This routine starts DC21X4's Txm & Rcv processes.
+ *
+ * At this point The Txm descriptor ring should be empty
+ * and the TxM process should enter the SUSPENDED state
+ *
+ * The 1st Rxm descriptor of the Rcv ring should available
+ * and the RxM process should enter the RUNNING state
+ *
+ * Note:
+ *
+ * This routine assume that only a single thread of
+ * execution is working with this particular adapter.
+ *
+ * Arguments:
+ *
+ * Adapter - The adapter for the DC21X4 to stop.
+ *
+ * Return Value:
+ *
+ * None.
+ *
+-*/
+extern
+VOID
+DC21X4StartAdapter(
+ IN PDC21X4_ADAPTER Adapter
+ )
+{
+
+#if __DBG
+ DbgPrint("DC21X4StartAdapter\n");
+#endif
+
+ // Set the RCV_START and TXM_START bits in
+ // the OPERATION_MODE register
+
+ Adapter->OperationMode |= (DC21X4_RCV_START | DC21X4_TXM_START );
+
+ switch (Adapter->DeviceId) {
+
+ case DC21040_CFID :
+
+ if (Adapter->RevisionNumber == DC21040_REV1) {
+
+ // Txm hang workaround : Disable the SIA before
+ // writing the Operation Mode register
+
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_MODE_0,
+ DC21X4_RESET_SIA
+ );
+
+ NdisStallExecution(1*MILLISECOND); // Wait 1 ms
+
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Adapter->OperationMode
+ );
+
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_MODE_0,
+ Adapter->Media[Adapter->SelectedMedium].SiaRegister[0]
+ );
+
+ break;
+
+ }
+
+ default:
+
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Adapter->OperationMode
+ );
+ }
+
+}
+
+
+
+/*+
+ *
+ * DC21X4WriteGepRegister
+ *
+ *
+ * Routine Description:
+ *
+ * Write the DC21X4 General Purpose Register
+ *
+ *
+ * Arguments:
+ *
+ * Adapter
+ * Data
+ *
+ * Return Value:
+ *
+ * None.
+ *
+-*/
+extern
+VOID
+DC21X4WriteGepRegister(
+ IN PDC21X4_ADAPTER Adapter,
+ IN ULONG Data
+ )
+{
+
+ switch (Adapter->DeviceId) {
+
+ case DC21142_CFID:
+
+ Adapter->Gep_Sia2 = (Data << DC21142_GEP_SHIFT)
+ | (Adapter->Gep_Sia2 & DC21142_SIA2_MASK);
+
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_MODE_2,
+ Adapter->Gep_Sia2
+ );
+ break;
+
+ default:
+
+ DC21X4_WRITE_PORT(
+ DC21X4_GEN_PURPOSE,
+ Data
+ );
+
+ }
+}
+
+
+
+/*+
+ *
+ * DC21X4InitializeGepRegisters
+ *
+ *
+ * Routine Description:
+ *
+ * This routine initializes the GEP registers of the DC21140 adapters
+ *
+ *
+ * Arguments:
+ *
+ * Adapter - The adapter for the DC21X4 to initialize
+ *
+ * Return Value:
+ *
+ * None.
+ *
+-*/
+extern
+VOID
+DC21X4InitializeGepRegisters(
+ IN PDC21X4_ADAPTER Adapter,
+ IN BOOLEAN Phy
+ )
+{
+
+ INT Seq;
+
+#if __DBG
+ DbgPrint("InitializeGepRegisters\n");
+#endif
+
+
+ if (Phy) {
+
+ // Write the Gen Purpose register with the PHY's required sequence:
+ // Control,Data_1,...,Data_n
+
+#if __DBG
+ DbgPrint("InitializeGepRegisters: Control=%08x\n",
+ Adapter->Phy[Adapter->PhyNumber].GeneralPurposeCtrl);
+#endif
+ DC21X4WriteGepRegister(
+ Adapter,
+ (ULONG)Adapter->Phy[Adapter->PhyNumber].GeneralPurposeCtrl
+ );
+
+ for (Seq=0; Seq < Adapter->Phy[Adapter->PhyNumber].GepSequenceLength; Seq++) {
+#if __DBG
+ DbgPrint("InitializeGepRegisters: DATA[%d]=%04x\n",
+ Seq, Adapter->Phy[Adapter->PhyNumber].GepSequence[Seq]);
+#endif
+ DC21X4WriteGepRegister(
+ Adapter,
+ (ULONG)Adapter->Phy[Adapter->PhyNumber].GepSequence[Seq]
+ );
+ }
+ }
+ else {
+
+#if __DBG
+ DbgPrint("InitializeGepRegisters:\n");
+ DbgPrint(" GeneralPurpose Ctrl : %08x\n",
+ Adapter->Media[Adapter->SelectedMedium].GeneralPurposeCtrl);
+ DbgPrint(" GeneralPurpose Data : %08x\n",
+ Adapter->Media[Adapter->SelectedMedium].GeneralPurposeData);
+#endif
+
+ DC21X4WriteGepRegister(
+ Adapter,
+ (ULONG)Adapter->Media[Adapter->SelectedMedium].GeneralPurposeCtrl
+ );
+
+ DC21X4WriteGepRegister(
+ Adapter,
+ (ULONG)Adapter->Media[Adapter->SelectedMedium].GeneralPurposeData
+ );
+ }
+
+}
+
+
+
+/*+
+ * DC21X4InitializeMediaRegisters
+ *
+ * Routine Description:
+ *
+ * Initialize the DC21X4 Media (GEP &internal SIA) registers
+ *
+ *
+ * Arguments:
+ *
+ * Adapter
+ *
+ *
+ * Return Value:
+ *
+ * None.
+ *
+-*/
+extern
+VOID
+DC21X4InitializeMediaRegisters(
+ IN PDC21X4_ADAPTER Adapter,
+ IN BOOLEAN Phy
+ )
+{
+#if __DBG
+ DbgPrint("InitializeMediaRegisters\n");
+#endif
+
+ switch (Adapter->DeviceId) {
+
+ case DC21040_CFID :
+ case DC21041_CFID :
+
+ DC2104InitializeSiaRegisters(Adapter);
+ break;
+
+ case DC21140_CFID :
+
+ DC21X4InitializeGepRegisters(Adapter,Phy);
+ break;
+
+ case DC21142_CFID :
+
+ DC21X4InitializeGepRegisters(Adapter,Phy);
+ DC2104InitializeSiaRegisters(Adapter);
+ break;
+
+ }
+}
+
+
+
+
+
+
+
+
+
+/*+
+ *
+ * DC2104InitializeSiaRegisters
+ *
+ *
+ * Routine Description:
+ *
+ * This routine initializes the SIA register of the DC2104x adapters
+ *
+ *
+ * Arguments:
+ *
+ * Adapter - The adapter for the DC21X4 to initialize
+ *
+ * Return Value:
+ *
+ * None.
+ *
+-*/
+extern
+VOID
+DC2104InitializeSiaRegisters(
+ IN PDC21X4_ADAPTER Adapter
+ )
+
+{
+ UINT i;
+
+#if __DBG
+ DbgPrint("DC2104InitializeSiaRegisters\n");
+#endif
+
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_MODE_0,
+ DC21X4_RESET_SIA
+ );
+
+ for (i=0;i<2;i++) {
+ NdisStallExecution(5*MILLISECOND);
+ }
+
+#if __DBG
+ DbgPrint(" CSR15: %08x\n",Adapter->Media[Adapter->SelectedMedium].SiaRegister[2]);
+ DbgPrint(" CSR14: %08x\n",Adapter->Media[Adapter->SelectedMedium].SiaRegister[1]);
+ DbgPrint(" CSR13: %08x\n",Adapter->Media[Adapter->SelectedMedium].SiaRegister[0]);
+
+#endif
+
+ switch (Adapter->DeviceId) {
+
+ case DC21142_CFID:
+
+ Adapter->Gep_Sia2 =
+ (Adapter->Media[Adapter->SelectedMedium].SiaRegister[2] & DC21142_SIA2_MASK)
+ | (Adapter->Gep_Sia2 & DC21142_GEP_MASK);
+
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_MODE_2,
+ Adapter->Gep_Sia2
+ );
+
+ break;
+
+ default:
+
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_MODE_2,
+ Adapter->Media[Adapter->SelectedMedium].SiaRegister[2]
+ );
+ }
+
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_MODE_1,
+ Adapter->Media[Adapter->SelectedMedium].SiaRegister[1]
+ );
+
+ DC21X4_WRITE_PORT(
+ DC21X4_SIA_MODE_0,
+ Adapter->Media[Adapter->SelectedMedium].SiaRegister[0]
+ );
+
+#if 0
+ //Restart the Receiver and Transmitter
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ Adapter->OperationMode
+ );
+#endif
+
+}
+
+
+
+
+
+
+
+
+
+
+
+/*+
+ *
+ * DC21X4StopReceiverAndTransmitter
+ *
+ *
+ * Routine Description:
+ *
+ * Gracefull stop the Receiver and Transmitter and
+ * synchronize on completion
+ *
+ *
+ * Arguments:
+ *
+ * Adapter - The adapter for the DC21X4 to initialize
+ *
+ * Return Value:
+ *
+ * None.
+ *
+-*/
+extern
+VOID
+DC21X4StopReceiverAndTransmitter(
+ IN PDC21X4_ADAPTER Adapter
+ )
+
+{
+
+ ULONG Status;
+ UINT Time=50;
+
+ //Request the Receiver and Transmitter to stop
+
+ DC21X4_WRITE_PORT(
+ DC21X4_OPERATION_MODE,
+ 0
+ );
+
+ //Wait for completion
+
+ while (Time--) {
+
+ DC21X4_READ_PORT(
+ DC21X4_STATUS,
+ &Status
+ );
+
+ if (Status & (DC21X4_RCV_PROCESS_STATE
+ | DC21X4_TXM_PROCESS_STATE) == 0) {
+ break;
+ }
+
+ NdisStallExecution(2*MILLISECOND);
+ }
+
+ return;
+
+}