/*++
 * Copyright (c) 1990-96 Digi International Inc., All Rights Reserved
 * 
 * This software contains proprietary and confidential information of Digi
 * International Inc.  By accepting transfer of this copy, Recipient agrees
 * to retain this software in confidence, to prevent disclosure to others,
 * and to make no use of this software other than that for which it was
 * delivered.  This is an unpublished copyrighted work of Digi International
 * Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly
 * prohibited.
 * 
 * Restricted Rights Legend
 *
 * Use, duplication, or disclosure by the Government is subject to
 * restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in
 * Technical Data and Computer Software clause at DFARS 252.227-7031 or
 * subparagraphs (c)(1) and (2) of the Commercial Computer Software -
 * Restricted Rights at 48 CFR 52.227-19, as applicable.
 *
 * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
 *
 *
 * Last Update: $Date: 10/22/97 11:56a $
 *
 * $Header: /Components/Windows/NT/Sync/Build/Mp570/hwsca.c 4     10/22/97 11:56a Darinh $
 *
 * Revision History:
 * $Log: /Components/Windows/NT/Sync/Build/Mp570/hwsca.c $
 * 
 * 4     10/22/97 11:56a Darinh
 * Changes to make multiple board installations work better.
 * 
 * 3     6/06/97 1:48p Darinh
 * Everything seems functional, but more testing is required.
 * 
 * 2     4/08/97 4:55p Darinh
 * Changes made to correspond to the new DigiUtil library.  It
 * successfully transmits data!  I don't know about receiving data yet.
 * 
 * 1     4/02/97 10:08a Darinh
 * Initial checkin; ISA cards initialize, but do not pass data.
 * 
--*/
#include "digilib.h"

#include <ntddk.h>
#include "def570.h"
#include "def64570.h"
#include "board.h"
#include "io.h"
#include "dsmp.h"
#include "hwsca.h"
#include "debug.h"


VOID
fnDisableScaInterrupts (
	IN PDEVICE_EXT	pDeviceExt)
/*++

Description:

	This function disables all of the interrupt sources from the SCA.

Parameters:

	pControllerExt
		Address of the Controller Extension

Return Value:

	None.

--*/
{
	int     i;


	DigiDump (DIGIFLOW, ("Entering fnDisableScaInterrupts()\n"));

	EnableScaMemMap (pDeviceExt);

	// Disable all SCA interrupts, 2 channels
	for (i = 0; i < 2; i++)
	{
		// Channel Reset
		WRT_REG_UCHAR (&pDeviceExt->pSca->MsciRegs[i].Cmd, 0x21);
		WRT_REG_UCHAR (&pDeviceExt->pSca->MsciRegs[i].Ie0, 0);
		WRT_REG_UCHAR (&pDeviceExt->pSca->MsciRegs[i].Ie1, 0);
		WRT_REG_UCHAR (&pDeviceExt->pSca->MsciRegs[i].Ie2, 0);
		WRT_REG_UCHAR (&pDeviceExt->pSca->MsciRegs[i].Fie, 0);
	}

	// Disable all DMAC interrupts, 4 channels
	for (i = 0; i < 4; i++)
	{
		WRT_REG_UCHAR (&pDeviceExt->pSca->DmacRegs[i].Dir, 0);
	}

	// Disable all common interrupts
	WRT_REG_UCHAR (&pDeviceExt->pSca->ComIer0, 0);
	WRT_REG_UCHAR (&pDeviceExt->pSca->ComIer1, 0);
	WRT_REG_UCHAR (&pDeviceExt->pSca->ComIer2, 0);

	DisableMemory (pDeviceExt);

	DigiDump (DIGIFLOW, ("Exiting fnDisableScaInterrupts()\n"));
}


BOOLEAN
fnSetScaLinkConfig (
	IN PDEVICE_EXT	pDeviceExt)
/*++

Description:

	This function set up the communication mode for receive and
	transmit. The following are the setting for MSCI registers:
		. MSCI Mode Register 0 (MD0)
		. MSCI Mode Register 1 (MD1)
		. MSCI Command Register (CMD)
		. MSCI Mode Register 2 (MD2)
		. MSCI Control Register (CTL)
		. MSCI RX Clock Source Register (RXS)
		. MSCI TX Clock Source Register (TXS)
		. DMAC Master Enable Register (DMER)
		. MSCI Synchronous/Address Register 0

Parameters:

	pDeviceExt
		Address of the Device extension.

Return Value:

	None.

--*/
{
	DigiDump (DIGIFLOW, ("Entering fnSetScaLinkConfig()\n"));

	EnableScaMemMap (pDeviceExt);

	WRT_REG_UCHAR (&pDeviceExt->pScaMsci->Md0, pDeviceExt->ScaMd0);
	WRT_REG_UCHAR (&pDeviceExt->pScaMsci->Md1, pDeviceExt->ScaMd1);
	WRT_REG_UCHAR (&pDeviceExt->pScaMsci->Cmd, CMD_RX_RESET);
	WRT_REG_UCHAR (&pDeviceExt->pScaMsci->Md2, pDeviceExt->ScaMd2);
	WRT_REG_UCHAR (&pDeviceExt->pScaMsci->Idl, 0x7E);
	WRT_REG_UCHAR (&pDeviceExt->pScaMsci->Ctl, pDeviceExt->ScaCtl);
	WRT_REG_UCHAR (&pDeviceExt->pScaMsci->Tmc, pDeviceExt->ScaTmc);
	WRT_REG_UCHAR (&pDeviceExt->pScaMsci->Rxs, pDeviceExt->ScaRxs);
	WRT_REG_UCHAR (&pDeviceExt->pScaMsci->Txs, pDeviceExt->ScaTxs);
	WRT_REG_UCHAR (&pDeviceExt->pSca->ComDmer, DMAC_DMER_ENABLE);
   WRT_REG_UCHAR (&pDeviceExt->pSca->ComPcr,  DMAC_PCR_CCC_ROUND_ROBIN);

	if (pDeviceExt->ScaMd1 & MD1_SINGLE_ADDR1)
		WRT_REG_UCHAR (&pDeviceExt->pScaMsci->Sa0, pDeviceExt->StationAddress1);

	DisableMemory (pDeviceExt);

	DigiDump (DIGIFLOW, ("Exiting fnSetScaLinkConfig()\n"));

	return (TRUE);
}


VOID
fnSetupScaIMVR (
	IN PDEVICE_EXT	pDeviceExt)
/*++

Description:

	This function will setup the Interrupt Modified Vector Register (IMVR).
	This is used when the Digi card generates an interrupt, the interrupt
	vector output from the SCA will indicate what type of interrupt
	(RXINT, TXINT, TIMER, DMIA, or DMIB), and from which SCA chip.  This
	will be called once for each line on the adapter.

Parameters:

	pDeviceExt
		Address of the Device Extension

Return Value:

	None.

--*/
{
	volatile UCHAR	ImvrRegVal;


	DigiDump (DIGIFLOW, ("Entering fnSetupScaIMVR()\n"));

	EnableScaMemMap (pDeviceExt);

#ifdef DBG_INTERRUPT
	WRT_REG_UCHAR (&pDeviceExt->pSca->ComItcr, ICR_IAK_SINGLE_ACK);
#endif


	ImvrRegVal = READ_REGISTER_UCHAR ((PUCHAR) &pDeviceExt->pSca->ComImvr);

	switch (pDeviceExt->PortNumber)
	{
	case FIRST_PORT:			   // For the first SCA chip
	case SECOND_PORT:
		if (0 != ImvrRegVal)
			WRT_REG_UCHAR (&pDeviceExt->pSca->ComImvr, 0);
		break;

	case THIRD_PORT:			   // For the second SCA chip
	case FOURTH_PORT:
		if ((UCHAR) 0x40 != ImvrRegVal)
			WRT_REG_UCHAR (&pDeviceExt->pSca->ComImvr, (UCHAR) 0x40);
		break;
	}

	DisableMemory (pDeviceExt);

	DigiDump (DIGIFLOW, ("Exiting fnSetupScaIMVR()\n"));
}


BOOLEAN
fnStopChannel (
	IN PDEVICE_EXT	pDeviceExt)
/*++

Description:

	This function will stop and disable the following:
		1.	The Receive channel
		2.	The Transmit channel
		3.	The Time.

Parameters:

	pDeviceExt
		Address of the Device extension.

Return Value:

	None.

--*/
{
	DigiDump (DIGIFLOW, ("Entering fnStopChannel()\n"));


	fnStopReceiver (pDeviceExt);
	fnDisableRxInterrupts (pDeviceExt);
	fnStopTransmit (pDeviceExt);
	fnDisableTxInterrupts (pDeviceExt);
	fnStopTimer (pDeviceExt);
	fnDisableTimerInterrupt (pDeviceExt);

	DigiDump (DIGIFLOW, ("Exiting fnStopChannel()\n"));

	return (TRUE);
}


BOOLEAN
fnStartChannel (
	IN PDEVICE_EXT	pDeviceExt)
/*++

Description:

	This function will enable the interrupts for the following:
		1.	The Receive channel
		2.	The Transmit channel
		3.	The Timer
		Then it will start the receiver.

Parameters:

	pDeviceExt
		Address of the Device extension.

Return Value:

	None.

--*/
{
	DigiDump (DIGIFLOW, ("Entering fnStartChannel()\n"));

	// Enable Receive Interrupts
	fnEnableRxInterrupts (pDeviceExt);

	// Enable Transmit Interrupts
	fnEnableTxInterrupts (pDeviceExt);

	// Enable Timer Interrupts
	fnEnableTimerInterrupt (pDeviceExt);

	// Start receiver
	fnStartReceiver (pDeviceExt);

	DigiDump (DIGIFLOW, ("Exiting fnStartChannel()\n"));

	return (TRUE);
}

