/*++
*******************************************************************************
* Copyright (c) 1999-2000 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          *
*                                                                             *
*******************************************************************************

Module Name:

	pppsync.c

Abstract:

	Init code for Sync Cards.  Firmware header overlap requires that this code be in 
	a separate file from CSU card init code.

Author:

	Michael Zarns

--*/
#include "digippp.h"
#include "wan_control.h"
#include "wan_proto.h"
#include "m32api.h"

NTSTATUS
PPPSyncInitCircuit( 
	IN PDIGI_PPP_ADAPTER pAdapter,
	IN PDIGI_PPP_LINE    pLine )
{
	NTSTATUS Status;
	// Send WAN_SID - ties a SNID to the WANx instance (e.g. to the physical line)
	{
		struct wan_sid sid = {0};
		sid.wan_type = WAN_SID;
		sid.wan_snid = pLine->Snid;

		DigiDump( DIGIINIT, ( "PPP!SyncInitCircuit: WAN_SID\n"
		                      "   wan_type = 0x%x\n"
		                      "   wan_snid = 0x%x\n",
		                      sid.wan_type, sid.wan_snid ) );
		Status = DsPutMsg( pLine->hStream, &sid, sizeof (sid) , NULL, 0, DS_PRIORITY_LOW );
		
	}

	// Send SETTUNE - configure line properties
	if ( NT_SUCCESS(Status) )
	{
		ULONG Error;
		struct wan_tnioc Tune = {0};
		Tune.lli_type = LI_WANTUNE;
		Tune.lli_snid = pLine->Snid;
		Tune.wan_tune.WAN_options          = pAdapter->Sync.IsNrzi ? WAN_NRZI | WAN_HDLC : WAN_HDLC;
		Tune.wan_tune.WAN_hd.WAN_baud      = pAdapter->Sync.ExternalClocking ? 0 : pAdapter->Sync.LineSpeed;
		Tune.wan_tune.WAN_hd.WAN_maxframe  = pAdapter->MaxFrameSize;
		Tune.wan_tune.WAN_hd.WAN_cpdef.WAN_cptype = WAN_NONE;
		DigiDump( DIGIINIT, ( "PPP!SyncInitCircuit: W_SETTUNE\n"
		                      "   lli_type     = 0x%x\n"
		                      "   lli_snid     = 0x%x\n"
		                      "   WAN_options  = 0x%x\n"
		                      "   WAN_baud     = 0x%x\n"
		                      "   WAN_maxframe = 0x%x\n"
		                      "   WAN_cptype   = 0x%x\n",
		                      Tune.lli_type, Tune.lli_snid, Tune.wan_tune.WAN_options, Tune.wan_tune.WAN_hd.WAN_baud, Tune.wan_tune.WAN_hd.WAN_maxframe, Tune.wan_tune.WAN_hd.WAN_cpdef.WAN_cptype) );
		Status = DsIoctl( pLine->hStream, W_SETTUNE, &Tune, sizeof Tune, &Error );
	}

	// Send WAN_REG
	if ( NT_SUCCESS(Status) )
	{
		ULONG Error;
		struct wan_reg Reg = {0};
		Reg.wan_type = WAN_REG;
		Reg.wan_snid = pLine->Snid;
		DigiDump( DIGIINIT, ( "PPP!SyncInitCircuit: WAN_REG\n"
		                      "   wan_type = 0x%x\n"
		                      "   wan_snid = 0x%x\n",
		                      Reg.wan_type, Reg.wan_snid ) );
		Status = DsPutMsg( pLine->hStream, &Reg, sizeof Reg, NULL, 0, DS_PRIORITY_LOW );
	}

	// Send GetMsg - get a WC_CONNECT msg from firmware
	if ( NT_SUCCESS(Status) )
	{
		struct wan_ctl Ctrl;
		ULONG cbCtrl, cbData;
		Status = DsGetMsg( pLine->hStream, &Ctrl, sizeof Ctrl, &cbCtrl, NULL, 0, &cbData, DS_PRIORITY_LOW );
		if ( NT_ERROR(Status) )
		{
			DigiDump( DIGIERROR, ( "PPP!SyncInitCircuit: DsGetMsg failed, Status 0x%x\n", Status ) );
		}
		else
		{
			if ( Ctrl.wan_type    != WAN_CTL    ||
			     Ctrl.wan_command != WC_CONNECT 
// Will be fixed in firmware soon.  Currently this field is uninitialized by firmware
//			     || Ctrl.wan_status  != WAN_SUCCESS 
			     )
			{
				DigiDump( DIGIWARN, ( "PPP!SyncInitCircuit: GetMsg error: type 0x%x, command 0x%x, status 0x%x\n", Ctrl.wan_type, Ctrl.wan_command, Ctrl.wan_status ) );
				Status = STATUS_UNSUCCESSFUL;
			}
		}
	}

   // Send WC_CONCNF - confirms the WC_CONNECT
	if ( NT_SUCCESS(Status) )
	{
		struct wan_ctl Ctrl = {0};
		Ctrl.wan_type    = WAN_CTL;
		Ctrl.wan_command = WC_CONCNF;
		Ctrl.wan_status  = WAN_SUCCESS;
		Status = DsPutMsg( pLine->hStream, &Ctrl, sizeof Ctrl, NULL, 0, DS_PRIORITY_HIGH );
	}

	if ( NT_SUCCESS(Status) )
		Status = RxEngineStart( &pLine->RxEngine, pAdapter->hMiniport, pLine->hStream, pLine, &CircuitEventHandlers, sizeof (union WAN_primitives), DIGI_PPP_MAX_FRAME_SIZE );

	return Status;
}

VOID
PPPMdmEngineStart( PDIGI_PPP_CALL pCall )
{
	NTSTATUS Status;
	PDIGI_PPP_ADAPTER pAdapter = pCall->pAdapter;
	PDIGI_PPP_LINE pLine = &pCall->pAdapter->pLines[pCall->hdLine];
	PDIGI_PPP_MDMENGINE	pEngine = &pLine->MdmEngine;

	NdisZeroMemory( pEngine, sizeof *pEngine );
	pEngine->pAdapter = pAdapter;

	DigiDump( DIGIMDMENGINE, ( "PPP!StopListening: pAdapter 0x%x\n", pAdapter ) );

	Status = MdmEngineStart( pEngine, pAdapter, pLine->hStream);

	if ( NT_ERROR( Status ) )
		MdmEngineStop( &pLine->MdmEngine );

}	

VOID
PPPMdmEngineStop( PDIGI_PPP_CALL pCall )
{
	PDIGI_PPP_LINE pLine = &pCall->pAdapter->pLines[pCall->hdLine];

	DigiDump( DIGIMDMENGINE, ( "PPP!StopListening: pCall 0x%x\n", pCall ) );
	MdmEngineStop(&pLine->MdmEngine);

}