summaryrefslogtreecommitdiffstats
path: root/private/ntos/ndis/htdsu/card.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/ndis/htdsu/card.c
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/ntos/ndis/htdsu/card.c')
-rw-r--r--private/ntos/ndis/htdsu/card.c722
1 files changed, 722 insertions, 0 deletions
diff --git a/private/ntos/ndis/htdsu/card.c b/private/ntos/ndis/htdsu/card.c
new file mode 100644
index 000000000..eb62fba71
--- /dev/null
+++ b/private/ntos/ndis/htdsu/card.c
@@ -0,0 +1,722 @@
+/***************************************************************************\
+|* Copyright (c) 1994 Microsoft Corporation *|
+|* Developed for Microsoft by TriplePoint, Inc. Beaverton, Oregon *|
+|* *|
+|* This file is part of the HT Communications DSU41 WAN Miniport Driver. *|
+\***************************************************************************/
+#include "version.h"
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+Module Name:
+
+ card.c
+
+Abstract:
+
+ This module implements the low-level hardware control functions used by
+ the NDIS Minport driver on the HT DSU41 controller. You will need to
+ replace this module with the control functions required to support your
+ hardware.
+ CardIdentify()
+ CardDoCommand()
+ CardInitialize()
+ CardLineConfig()
+ CardLineDisconnect()
+ CardLineDisconnect()
+ CardPrepareTransmit()
+ CardGetReceiveInfo()
+ CardDialNumber()
+
+ This driver conforms to the NDIS 3.0 Miniport interface.
+
+Author:
+
+ Larry Hattery - TriplePoint, Inc. (larryh@tpi.com) Jun-94
+
+Environment:
+
+ Windows NT 3.5 kernel mode Miniport driver or equivalent.
+
+Revision History:
+
+---------------------------------------------------------------------------*/
+
+#define __FILEID__ 2 // Unique file ID for error logging
+
+#include "htdsu.h"
+
+
+NDIS_STATUS
+CardIdentify(
+ IN PHTDSU_ADAPTER Adapter
+ )
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+Functional Description:
+
+ This routine will attempt to verify that the controller is located in
+ memory where the driver has been configured to expect it.
+
+Parameters:
+
+ Adapter _ A pointer ot our adapter information structure.
+
+Return Values:
+
+ NDIS_STATUS_SUCCESS
+ NDIS_STATUS_ADAPTER_NOT_FOUND
+
+---------------------------------------------------------------------------*/
+
+{
+ DBG_FUNC("CardIdentify")
+
+ NDIS_STATUS Status;
+
+ /*
+ // These values are read from the adapter to make sure this driver will
+ // work with the firmware on the adapter.
+ */
+ USHORT CoProcessorId;
+ USHORT CoProcessorVersion;
+ USHORT DsuId;
+ USHORT DsuVersion;
+
+ DBG_ENTER(Adapter);
+
+ /*
+ // Read the configuration values from the card.
+ */
+ CoProcessorId = READ_REGISTER_USHORT(&Adapter->AdapterRam->CoProcessorId);
+ CoProcessorVersion = READ_REGISTER_USHORT(&Adapter->AdapterRam->CoProcessorVersion);
+ DsuId = READ_REGISTER_USHORT(&Adapter->AdapterRam->DsuId);
+ DsuVersion = READ_REGISTER_USHORT(&Adapter->AdapterRam->DsuVersion);
+
+ /*
+ // Make sure these values are what we expect.
+ */
+ if ((CoProcessorId == HTDSU_COPROCESSOR_ID) &&
+ (CoProcessorVersion >= HTDSU_COPROCESSOR_VERSION) &&
+ ((DsuId & 0x00FF) == HTDSU_DSU_ID) &&
+ (DsuVersion >= HTDSU_DSU_VERSION))
+ {
+ /*
+ // Record the number of lines on this adapter.
+ */
+ Adapter->NumLineDevs = HTDSU_NUM_LINKS;
+ if ((DsuId & 0xFF00) == 0)
+ {
+ --Adapter->NumLineDevs;
+ }
+ DBG_NOTICE(Adapter,("NumLineDevs=%d\n",Adapter->NumLineDevs));
+
+ Status = NDIS_STATUS_SUCCESS;
+ }
+ else
+ {
+ DBG_ERROR(Adapter,("Adapter not found or invalid firmware:\n"
+ "CoProcessorId = %Xh\n"
+ "CoProcessorVersion = %Xh\n"
+ "DsuId = %Xh\n"
+ "DsuVersion = %Xh\n",
+ CoProcessorId,
+ CoProcessorVersion,
+ DsuId,
+ DsuVersion
+ ));
+
+ Status = NDIS_STATUS_ADAPTER_NOT_FOUND;
+ /*
+ // Log error message and return.
+ */
+ NdisWriteErrorLogEntry(
+ Adapter->MiniportAdapterHandle,
+ NDIS_ERROR_CODE_ADAPTER_NOT_FOUND,
+ 7,
+ CoProcessorId,
+ CoProcessorVersion,
+ DsuId,
+ DsuVersion,
+ Status,
+ __FILEID__,
+ __LINE__
+ );
+ }
+
+ DBG_LEAVE(Adapter);
+
+ return (Status);
+}
+
+
+NDIS_STATUS
+CardDoCommand(
+ IN PHTDSU_ADAPTER Adapter,
+ IN USHORT CardLine, /* HTDSU_CMD_LINE1 or HTDSU_CMD_LINE2 */
+ IN USHORT CommandValue
+ )
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+Functional Description:
+
+ This routine routine will execute a command on the card after making
+ sure the previous command has completed properly.
+
+Parameters:
+
+ Adapter _ A pointer ot our adapter information structure.
+
+ CardLine _ Specifies which line to use for the transmit (HTDSU_LINEx_ID).
+
+ CommandValue _ HTDSU_CMD_??? command to be executed.
+
+Return Values:
+
+ NDIS_STATUS_SUCCESS
+ NDIS_STATUS_HARD_ERRORS
+
+---------------------------------------------------------------------------*/
+{
+ DBG_FUNC("CardDoCommand")
+
+ ULONG TimeOut = 0;
+
+ DBG_ENTER(Adapter);
+ DBG_FILTER(Adapter, DBG_PARAMS_ON,("Line=%d, Command=%04X, LineStatus=%Xh\n",
+ CardLine, CommandValue,
+ READ_REGISTER_USHORT(&Adapter->AdapterRam->StatusLine1)
+ ));
+
+ /*
+ // Wait for command register to go idle - but don't wait too long.
+ // If we timeout here, there's gotta be something wrong with the adapter.
+ */
+ while ((READ_REGISTER_USHORT(&Adapter->AdapterRam->Command) !=
+ HTDSU_CMD_NOP) ||
+ (READ_REGISTER_USHORT(&Adapter->AdapterRam->CoProcessorId) !=
+ HTDSU_COPROCESSOR_ID))
+ {
+ if (TimeOut++ > HTDSU_SELFTEST_TIMEOUT)
+ {
+ DBG_ERROR(Adapter,("Timeout waiting for %04X command to clear\n",
+ READ_REGISTER_USHORT(&Adapter->AdapterRam->Command)));
+ /*
+ // Ask for reset, and disable interrupts until we get it.
+ */
+ Adapter->NeedReset = TRUE;
+ Adapter->InterruptEnableFlag = HTDSU_INTR_DISABLE;
+ CardDisableInterrupt(Adapter);
+
+ return (NDIS_STATUS_HARD_ERRORS);
+ }
+ NdisStallExecution(_100_MICROSECONDS);
+ }
+ DBG_NOTICE(Adapter,("Timeout=%d waiting to submit %04X\n",
+ TimeOut, CommandValue));
+
+ /*
+ // Before starting a reset command, we clear the the co-processor ID
+ // which then gets set to the proper value when the reset is complete.
+ */
+ if (CommandValue == HTDSU_CMD_RESET)
+ {
+ WRITE_REGISTER_USHORT(&Adapter->AdapterRam->CoProcessorId, 0);
+ }
+
+ /*
+ // Send the command to the adapter.
+ */
+ WRITE_REGISTER_USHORT(
+ &Adapter->AdapterRam->Command,
+ (USHORT) (CommandValue + CardLine)
+ );
+
+ DBG_LEAVE(Adapter);
+
+ return (NDIS_STATUS_SUCCESS);
+}
+
+
+NDIS_STATUS
+CardInitialize(
+ IN PHTDSU_ADAPTER Adapter,
+ IN BOOLEAN PerformSelfTest
+ )
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+Functional Description:
+
+ This routine will attempt to initialize the controller, but will not
+ enable transmits or receives.
+
+Parameters:
+
+ Adapter _ A pointer ot our adapter information structure.
+
+ PerformSelfTest _ TRUE if caller wants to run selftest diagnostics.
+ This normally takes about 4 seconds to complete, so you
+ wouldn't want to do it every time you start up.
+
+Return Values:
+
+ NDIS_STATUS_HARD_ERRORS
+ NDIS_STATUS_SUCCESS
+
+---------------------------------------------------------------------------*/
+
+{
+ DBG_FUNC("CardInitialize")
+
+ NDIS_STATUS Status;
+
+ USHORT SelfTestStatus;
+
+ UINT TimeOut;
+
+ DBG_ENTER(Adapter);
+
+ /*
+ // First we make sure the adapter is where we think it is.
+ */
+ Status = CardIdentify(Adapter);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ return (Status);
+ }
+
+ /*
+ // Reset the hardware to make sure we're in a known state.
+ */
+ Status = CardDoCommand(Adapter, 0, HTDSU_CMD_RESET);
+
+ if (PerformSelfTest)
+ {
+ /*
+ // Wait for the reset to complete before starting the self-test.
+ // Then issue the self-test command to see if the adapter firmware
+ // is happy with the situation.
+ */
+ Status = CardDoCommand(Adapter, 0, HTDSU_CMD_SELFTEST);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ DBG_ERROR(Adapter,("Failed HTDSU_CMD_RESET\n"));
+ /*
+ // Log error message and return.
+ */
+ NdisWriteErrorLogEntry(
+ Adapter->MiniportAdapterHandle,
+ NDIS_ERROR_CODE_HARDWARE_FAILURE,
+ 3,
+ Status,
+ __FILEID__,
+ __LINE__
+ );
+ return (Status);
+ }
+
+ /*
+ // Wait for the self test to complete, but don't wait forever.
+ */
+ TimeOut = 0;
+ while (Status == NDIS_STATUS_SUCCESS &&
+ READ_REGISTER_USHORT(&Adapter->AdapterRam->Command) !=
+ HTDSU_CMD_NOP)
+ {
+ if (TimeOut++ > HTDSU_SELFTEST_TIMEOUT)
+ {
+ DBG_ERROR(Adapter,("Timeout waiting for SELFTEST to complete\n"));
+ Status = NDIS_STATUS_HARD_ERRORS;
+ }
+ else
+ {
+ NdisStallExecution(_100_MICROSECONDS);
+ }
+ }
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ DBG_ERROR(Adapter,("Failed HTDSU_CMD_SELFTEST\n"));
+ /*
+ // Log error message and return.
+ */
+ NdisWriteErrorLogEntry(
+ Adapter->MiniportAdapterHandle,
+ NDIS_ERROR_CODE_HARDWARE_FAILURE,
+ 3,
+ Status,
+ __FILEID__,
+ __LINE__
+ );
+ return (Status);
+ }
+
+ /*
+ // Verify that self test was successful.
+ */
+ SelfTestStatus = READ_REGISTER_USHORT(&Adapter->AdapterRam->SelfTestStatus);
+ if (SelfTestStatus != 0 && SelfTestStatus != HTDSU_SELFTEST_OK)
+ {
+ DBG_ERROR(Adapter,("Failed HTDSU_CMD_SELFTEST (Status=%X)\n",
+ SelfTestStatus));
+ /*
+ // Log error message and return.
+ */
+ NdisWriteErrorLogEntry(
+ Adapter->MiniportAdapterHandle,
+ NDIS_ERROR_CODE_HARDWARE_FAILURE,
+ 3,
+ SelfTestStatus,
+ __FILEID__,
+ __LINE__
+ );
+ return (NDIS_STATUS_HARD_ERRORS);
+ }
+ }
+
+ DBG_LEAVE(Adapter);
+
+ return (NDIS_STATUS_SUCCESS);
+}
+
+
+VOID
+CardLineConfig(
+ IN PHTDSU_ADAPTER Adapter,
+ IN USHORT CardLine /* HTDSU_CMD_LINE1 or HTDSU_CMD_LINE2 */
+ )
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+Functional Description:
+
+ This routine will ready the controller to send and receive packets.
+
+Parameters:
+
+ Adapter _ A pointer ot our adapter information structure.
+
+ CardLine _ Specifies which line to use for the transmit (HTDSU_LINEx_ID).
+
+Return Values:
+
+ None
+
+---------------------------------------------------------------------------*/
+
+{
+ DBG_FUNC("CardLineConfig")
+
+ USHORT ClockCommand;
+ USHORT LineCommand;
+
+ DBG_ENTER(Adapter);
+
+ ASSERT((CardLine==HTDSU_CMD_LINE1) || (CardLine==HTDSU_CMD_LINE2));
+
+ /*
+ // Configure the line for HDLC framing and for leased or dialup mode.
+ */
+ if (Adapter->LineType == HTDSU_LINEMODE_LEASED)
+ {
+ ClockCommand = HTDSU_CMD_INTERNAL_TX_CLOCK;
+ LineCommand = HTDSU_CMD_LEASED_LINE;
+ }
+ else
+ {
+ ClockCommand = HTDSU_CMD_DDS_TX_CLOCK;
+ LineCommand = HTDSU_CMD_DIALUP_LINE;
+ }
+
+ CardDoCommand(Adapter, CardLine, ClockCommand);
+ CardDoCommand(Adapter, CardLine, HTDSU_CMD_HDLC_PROTOCOL);
+ CardDoCommand(Adapter, CardLine, LineCommand);
+ CardDoCommand(Adapter, CardLine, Adapter->LineRate);
+
+ /*
+ // Clear any pending interrupts.
+ */
+ CardDoCommand(Adapter, 0, HTDSU_CMD_CLEAR_INTERRUPT);
+ CardClearInterrupt(Adapter);
+
+ DBG_LEAVE(Adapter);
+}
+
+
+VOID
+CardLineDisconnect(
+ IN PHTDSU_ADAPTER Adapter,
+ IN USHORT CardLine /* HTDSU_CMD_LINE1 or HTDSU_CMD_LINE2 */
+ )
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+Functional Description:
+
+ This routine will disconnect any call currently on the line.
+
+Parameters:
+
+ Adapter _ A pointer ot our adapter information structure.
+
+ CardLine _ Specifies which line to use for the transmit (HTDSU_LINEx_ID).
+
+Return Values:
+
+ None
+
+---------------------------------------------------------------------------*/
+
+{
+ DBG_FUNC("CardLineDisconnect")
+
+ DBG_ENTER(Adapter);
+
+ ASSERT((CardLine==HTDSU_CMD_LINE1) || (CardLine==HTDSU_CMD_LINE2));
+
+ /*
+ // Disconnect the line and reconfigure the line for next time.
+ */
+ CardDoCommand(Adapter, CardLine, HTDSU_CMD_DISCONNECT);
+ CardLineConfig(Adapter, CardLine);
+
+ DBG_LEAVE(Adapter);
+}
+
+
+VOID
+CardPrepareTransmit(
+ IN PHTDSU_ADAPTER Adapter,
+ IN USHORT CardLine, /* HTDSU_CMD_LINE1 or HTDSU_CMD_LINE2 */
+ IN USHORT BytesToSend
+ )
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+Functional Description:
+
+ This routine will write the packet header information into the
+ transmit buffer. This assumes that the controller has notified the
+ driver that the transmit buffer is empty.
+
+Parameters:
+
+ Adapter _ A pointer ot our adapter information structure.
+
+ CardLine _ Specifies which line to use for the transmit (HTDSU_LINEx_ID).
+
+ BytesToSend _ Number of bytes to transmit.
+
+Return Values:
+
+ None
+
+---------------------------------------------------------------------------*/
+
+{
+ DBG_FUNC("CardPrepareTransmit")
+
+ DBG_ENTER(Adapter);
+
+ ASSERT((CardLine==HTDSU_CMD_LINE1) || (CardLine==HTDSU_CMD_LINE2));
+ ASSERT(READ_REGISTER_USHORT(&Adapter->AdapterRam->TxDataEmpty));
+ ASSERT(BytesToSend > 0);
+
+ /*
+ // Tell the adapter how many bytes are to be sent, and which line to use.
+ */
+ WRITE_REGISTER_USHORT(
+ &Adapter->AdapterRam->TxBuffer.Address,
+ (USHORT) (CardLine - HTDSU_CMD_LINE1)
+ );
+ WRITE_REGISTER_USHORT(
+ &Adapter->AdapterRam->TxBuffer.Length,
+ BytesToSend
+ );
+
+ /*
+ // Mark the end of packet and end of packet list.
+ */
+ WRITE_REGISTER_USHORT(
+ &Adapter->AdapterRam->TxBuffer.Data[(BytesToSend+1)/sizeof(USHORT)],
+ HTDSU_DATA_TERMINATOR
+ );
+ WRITE_REGISTER_USHORT(
+ &Adapter->AdapterRam->TxBuffer.Data[(BytesToSend+3)/sizeof(USHORT)],
+ HTDSU_DATA_TERMINATOR
+ );
+
+ DBG_LEAVE(Adapter);
+}
+
+
+VOID
+CardGetReceiveInfo(
+ IN PHTDSU_ADAPTER Adapter,
+ OUT PUSHORT CardLine, /* HTDSU_CMD_LINE1 or HTDSU_CMD_LINE2 */
+ OUT PUSHORT BytesReceived,
+ OUT PUSHORT RxErrors
+ )
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+Functional Description:
+
+ This routine will retrieve the packet header information from the
+ receive buffer. This assumes that the controller has notified the
+ driver that a packet has been received.
+
+Parameters:
+
+ Adapter _ A pointer ot our adapter information structure.
+
+ CardLine _ Specifies which line the packet was received on (HTDSU_LINEx_ID).
+
+ BytesReceived _ Number of bytes received.
+
+ RxErrors _ Receive error flags non-zero if packet has errors.
+
+Return Values:
+
+ None
+
+---------------------------------------------------------------------------*/
+{
+ DBG_FUNC("CardGetReceiveInfo")
+
+ USHORT Length;
+
+ DBG_ENTER(Adapter);
+
+ /*
+ // This should be true if we're here, but there are race conditions
+ // on hangup where I've seen this condition hit.
+ */
+ if (READ_REGISTER_USHORT(&Adapter->AdapterRam->RxDataAvailable) == 0)
+ {
+ *RxErrors = 0;
+ *BytesReceived = 0;
+ *CardLine = HTDSU_CMD_LINE1; // Don't return a bad line #
+ }
+ else
+ {
+ /*
+ // The length field tells us how many bytes are in the packet, and
+ // the most significant bit tells us whether the packet has a CRC error.
+ */
+ Length = READ_REGISTER_USHORT(&Adapter->AdapterRam->RxBuffer.Length);
+ *BytesReceived = Length & ~HTDSU_CRC_ERROR;
+ *RxErrors = Length & HTDSU_CRC_ERROR;
+
+ /*
+ // The least significant nibble of the address tells us what line the
+ // packet was received on -- at least it better...
+ */
+ *CardLine = (READ_REGISTER_USHORT(
+ &Adapter->AdapterRam->RxBuffer.Address) &
+ 0x000F) + HTDSU_CMD_LINE1;
+
+ if ((*CardLine != HTDSU_CMD_LINE1) && (*CardLine != HTDSU_CMD_LINE2))
+ {
+ *RxErrors |= HTDSU_RX_ERROR;
+ *CardLine = HTDSU_CMD_LINE1; // Don't return a bad line #
+ }
+ else if (*BytesReceived > HTDSU_MAX_PACKET_SIZE)
+ {
+ *RxErrors |= HTDSU_RX_ERROR;
+ }
+ }
+
+ DBG_LEAVE(Adapter);
+}
+
+
+VOID
+CardDialNumber(
+ IN PHTDSU_ADAPTER Adapter,
+ IN USHORT CardLine, /* HTDSU_CMD_LINE1 or HTDSU_CMD_LINE2 */
+ IN PUCHAR DialString,
+ IN ULONG DialStringLength
+ )
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+Functional Description:
+
+ Place a dial string on the adapter and start the dialing sequence.
+
+Parameters:
+
+ Adapter _ A pointer ot our adapter information structure.
+
+ CardLine _ Specifies which line to use for the transmit (HTDSU_LINEx_ID).
+
+ DialString _ A pointer to an ASCII null-terminated string of digits.
+
+ DialStringLength _ Number of bytes in dial string.
+
+Return Values:
+
+ None
+
+---------------------------------------------------------------------------*/
+
+{
+ DBG_FUNC("CardDialNumber")
+
+ UINT Index;
+ UINT NumDigits;
+
+ PUSHORT DialRam;
+
+ DBG_ENTER(Adapter);
+
+ ASSERT(READ_REGISTER_USHORT(&Adapter->AdapterRam->TxDataEmpty));
+ ASSERT(READ_REGISTER_USHORT(&Adapter->AdapterRam->Command) == HTDSU_CMD_NOP);
+
+ /*
+ // Copy the digits to be dialed onto the adapter.
+ // The adapter interprets phone numbers as high byte is valid digit,
+ // low byte is ignored, the last digit gets bit 15 set.
+ */
+ DialRam = (PUSHORT) &Adapter->AdapterRam->TxBuffer;
+
+ for (NumDigits = Index = 0; Index < DialStringLength && *DialString; Index++)
+ {
+ if ((*DialString >= '0') && (*DialString <= '9'))
+ {
+ WRITE_REGISTER_USHORT(
+ DialRam,
+ (USHORT) ((*DialString - '0') << 8)
+ );
+ DialRam++;
+
+ /*
+ // Make sure dial string is within the limit of the adapter.
+ */
+ if (++NumDigits >= HTDSU_MAX_DIALING_DIGITS)
+ {
+ break;
+ }
+ }
+ DialString++;
+ }
+
+ /*
+ // Set the MSB in the last digit.
+ */
+ DialRam--;
+ WRITE_REGISTER_USHORT(
+ DialRam,
+ (USHORT) (READ_REGISTER_USHORT(DialRam) | 0x8000)
+ );
+
+ /*
+ // Initiate the dial sequence.
+ */
+ CardDoCommand(Adapter, CardLine, HTDSU_CMD_DIAL);
+
+ DBG_LEAVE(Adapter);
+}
+