/*++
*******************************************************************************
* 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:

	pppcsu.c

Abstract:

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

Author:

	Michael Zarns

--*/
#include "digippp.h"

#define MAXIOCBSZ 1024		// From stream.h

#include "iwan_control.h"
#include "iwan_proto.h"
#include "m32api.h"


NTSTATUS
PPPCsuInitCircuit( 
	IN PDIGI_PPP_ADAPTER pAdapter,
	IN PDIGI_PPP_LINE    pLine,
	IN ULONG             iCircuit,
	IN ULONG             TimeslotMask,
	IN ULONG             Speed )
{
	NTSTATUS Status;

	// Send W_SETSNID - ties a SNID to a logical channel
	{
		ULONG Error;
		iwan_snioc_t SetSnid = {0};
		SetSnid.w_type   = WAN_SNID;
		SetSnid.w_class  = FRAME_RELAY;
		SetSnid.w_chanid = iCircuit+1;
		SetSnid.w_snid   = pLine->Snid;
		DigiDump( DIGIINIT, ( "PPP!CsuInit: SetSnid\n"
		                      "   w_type   0x%x\n"
		                      "   w_class  0x%x\n"
		                      "   w_chanid 0x%x\n"
		                      "   w_snid   0x%x\n",
		                      SetSnid.w_type, SetSnid.w_class, SetSnid.w_chanid, SetSnid.w_snid ) );
		Status = DsIoctl( pLine->hStream, N_SETSNID, &SetSnid, sizeof SetSnid, &Error );
		if ( NT_ERROR(Status) )
		{
			DigiDump( DIGIWARN, ( "PPP!CsuInit: SetSnid failed, Status 0x%x, Error 0x%x\n", Status, Error ) );
		}
	}

	// Send WC_CONNECT
	if ( NT_SUCCESS(Status) )
	{
		struct wan_ctl Ctrl = {0};
		connect_cfg_t Connect = {0};

		Ctrl.wan_type    = WAN_CTL;
		Ctrl.wan_command = WC_CONNECT;
		Ctrl.wan_remtype = WAN_TYPE_DIGI;
		Ctrl.wan_status  = WAN_SUCCESS;

		Connect.timeslot_mask = TimeslotMask;
		switch ( Speed )
		{
			#define FILLMASK_56K 0x7F
			#define FILLMASK_64K 0xFF
			default: // Fallthrough to default of 64000
			case 64000:	Connect.fill_mask[iCircuit] = FILLMASK_64K;	break;
			case 56000:	Connect.fill_mask[iCircuit] = FILLMASK_56K;	break;
		}

		Connect.fnum = 2;								// Min count of flags between frames - recommended value by Chrisk
		Connect.mode = HDLC;
		Connect.bsize = pAdapter->MaxFrameSize;

		DigiDump( DIGIINIT, ( "PPP!CsuInit: WC_CONNECT\n"
		                      "   timeslot_mask 0x%08x\n"
		                      "   fill_mask     0x%x\n"
		                      "   bsize         0x%x\n",
		                      Connect.timeslot_mask, Connect.fill_mask[iCircuit], Connect.bsize ) );
		Status = DsPutMsg( pLine->hStream, &Ctrl, sizeof Ctrl, NULL, 0, DS_PRIORITY_HIGH );
	}

	// Send GetMsg - get a WC_CONCNF 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!CsuInitCircuit: DsGetMsg failed, Status 0x%x\n", Status ) );
		}
		else
		{
			if ( Ctrl.wan_type    != WAN_CTL   ||
			     Ctrl.wan_command != WC_CONCNF ||
			     Ctrl.wan_status  != WAN_SUCCESS )
			{
				DigiDump( DIGIWARN, ( "PPP!CsuInitCircuit: GetMsg error: type 0x%x, command 0x%x, status 0x%x\n", Ctrl.wan_type, Ctrl.wan_command, Ctrl.wan_status ) );
				Status = STATUS_UNSUCCESSFUL;
			}
		}
	}

	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;
}