/*++
*******************************************************************************
* Copyright (c) 1990-97 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:

   sohlapb.c

Abstract:

   This module contains functions to set up LAPB module for the X25 Stack.

Author:

   Jeff Romatoski

Revision History:


--*/


////////////////////////////////////////////////////////////////////////////////

#include "digisoh.h"
#include "sohlapb.h"

#if !NT5_BUILD
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT,SohLapbSetSnid)
#pragma alloc_text(INIT,SohLapbTune)
#endif
#endif


NTSTATUS
SohLapbSetSnid(
	IN HANDLE hLapb,
	IN ULONG  MuxId,
	IN ULONG  Snid
	)
/*++

Description:

	Tell Lapb about the snid.

Parameters:

	hLapb
		Handle to previously opened stream to firmware LAPB device.

	MuxId
		Id returned from Link request

	Snid
		SubNetwork ID identifies the port

Return Value:

	STATUS_SUCCESS, or failure status

--*/
{
	NTSTATUS Status;
	ULONG Error;
	struct ll_snioc SetSnid = {0};

	DigiDump( DIGIINIT, ( "SOH!SohLapbSetSnid: Enter, Snid 0x%x\n", Snid ) );

	SetSnid.lli_type  = LI_SNID;
	SetSnid.lli_snid  = Snid;
	SetSnid.lli_index = MuxId;
	Status = DsIoctl( hLapb, L_SETSNID, &SetSnid, sizeof SetSnid, &Error );

	DigiDump( DIGIINIT, ( "SOH!SohLapbSetSnid: Leave, Status 0x%x, Error 0x%x\n", Status, Error ) );
	return Status;
}



NTSTATUS
SohLapbTune(
	IN PSOH_DEV_EXT		pDevExt,
	IN HANDLE           hKeyPort,
	IN ULONG            Snid,
	IN USHORT           iPort
)
/*++

Description:

	Configure (or Tune) Lapb on the specified port.  Read line configuration from 
	registry and send it down to the adapter.  

Parameters:

	pDevExt
		Device extension identifying the adapter being configured

	hKeyPort
		Handle to Port registry key containing configuration parameters

	iPort
		Zero-based index of the port being configured

	Snid
		SubNetwork ID identifies the port

Return Value:

	STATUS_SUCCESS or failure status.

--*/
{
	NTSTATUS Status;
	struct lapb_tnioc Tune = {0};
	HANDLE hKeyLapb;
	ULONG Error = 0;
	HANDLE hStream;

	DigiDump( DIGIINIT, ( "SOH!SohLapbTune: Enter, Port 0x%x\n", iPort ) );

	Tune.lli_type = LI_LAPBTUNE;
	Tune.lli_snid = Snid;

	Status = DigiRegOpenSubkey( &hKeyLapb, hKeyPort, DXB_REGKEY_LAPB );
	if ( NT_SUCCESS( Status ) )
	{

		Status = DigiRegQueryDword( hKeyLapb, DXB_REGVAL_LAPB_N2, &Tune.lapb_tune.N2, DigiRegFlagRequired, 0 );
		if ( NT_SUCCESS( Status ) )
			Status = DigiRegQueryDword( hKeyLapb, DXB_REGVAL_LAPB_T1, &Tune.lapb_tune.T1, DigiRegFlagRequired, 0 );
		if ( NT_SUCCESS( Status ) )
			Status = DigiRegQueryDword( hKeyLapb, DXB_REGVAL_LAPB_TPF, &Tune.lapb_tune.Tpf, DigiRegFlagRequired, 0 );
		if ( NT_SUCCESS( Status ) )
			Status = DigiRegQueryDword( hKeyLapb, DXB_REGVAL_LAPB_TREJ, &Tune.lapb_tune.Trej, DigiRegFlagRequired, 0 );
		if ( NT_SUCCESS( Status ) )
			Status = DigiRegQueryDword( hKeyLapb, DXB_REGVAL_LAPB_TBUSY, &Tune.lapb_tune.Tbusy, DigiRegFlagRequired, 0 );
		if ( NT_SUCCESS( Status ) )
			Status = DigiRegQueryDword( hKeyLapb, DXB_REGVAL_LAPB_TIDLE, &Tune.lapb_tune.Tidle, DigiRegFlagRequired, 0 );
		if ( NT_SUCCESS( Status ) )
			Status = DigiRegQueryDword( hKeyLapb, DXB_REGVAL_LAPB_ACK_DELAY, &Tune.lapb_tune.ack_delay, DigiRegFlagRequired, 0 );
		if ( NT_SUCCESS( Status ) )
			Status = DigiRegQueryDword( hKeyLapb, DXB_REGVAL_LAPB_NOTACK_MAX, &Tune.lapb_tune.notack_max, DigiRegFlagRequired, 0 );
		if ( NT_SUCCESS( Status ) )
			Status = DigiRegQueryDword( hKeyLapb, DXB_REGVAL_LAPB_TX_WINDOW, &Tune.lapb_tune.tx_window, DigiRegFlagRequired, 0 );
		if ( NT_SUCCESS( Status ) )
			Status = DigiRegQueryDword( hKeyLapb, DXB_REGVAL_LAPB_TX_PROBE, &Tune.lapb_tune.tx_probe, DigiRegFlagRequired, 0 );
		if ( NT_SUCCESS( Status ) )
			Status = DigiRegQueryDword( hKeyLapb, DXB_REGVAL_LAPB_MAX_I_LEN, &Tune.lapb_tune.max_I_len, DigiRegFlagRequired, 0 );
		if ( NT_SUCCESS( Status ) )
			Status = DigiRegQueryDword( hKeyLapb, DXB_REGVAL_LAPB_LLCONFORM, &Tune.lapb_tune.llconform, DigiRegFlagRequired, 0 );

		DigiRegCloseKey( hKeyLapb );
	}

	Status = DsOpen( gSohRuntimeEnv.hDevice, "LAPB", NULL, NULL, 0, &hStream, &Error );
	if ( NT_SUCCESS( Status ) )
	{
	   DigiDump( DIGIINIT, ( "SOH: Lapb line config, line %d:\n"
		                       "   lli_type   = 0x%x\n"
		                       "   lli_snid   = 0x%x\n"
	                          "   N2         = 0x%x\n"
	                          "   T1         = 0x%x\n"
	                          "   Tpf        = 0x%x\n"
	                          "   Trej       = 0x%x\n"
	                          "   Tbusy      = 0x%x\n"
	                          "   Tidle      = 0x%x\n"
	                          "   ack_delay  = 0x%x\n"
	                          "   notack_max = 0x%x\n"
	                          "   tx_window  = 0x%x\n"
	                          "   tx_probe   = 0x%x\n"
	                          "   max_I_len  = 0x%x\n"
	                          "   llconform  = 0x%x\n",
							  iPort,
	                          Tune.lli_type,
	                          Tune.lli_snid,
	                          Tune.lapb_tune.N2,
	                          Tune.lapb_tune.T1,
	                          Tune.lapb_tune.Tpf,
	                          Tune.lapb_tune.Trej,
	                          Tune.lapb_tune.Tbusy,
	                          Tune.lapb_tune.Tidle,
	                          Tune.lapb_tune.ack_delay,
	                          Tune.lapb_tune.notack_max,
	                          Tune.lapb_tune.tx_window,
	                          Tune.lapb_tune.tx_probe,
	                          Tune.lapb_tune.max_I_len,
	                          Tune.lapb_tune.llconform ) );
		
		Status = DsIoctl( hStream, L_SETTUNE, &Tune, sizeof Tune, &Error );
		if ( NT_ERROR( Status ) )
		{
			DigiDump( DIGIERRORS, ( "SOH!SohLapbTune: DsIoctl failed, Status 0x%x, Error 0x%x\n", Status, Error ) );
		}

		(void)DsClose( hStream );
	}

	DigiDump( DIGIINIT, ( "SOH!SohLapbTune: Leave, Status 0x%x\n", Status ) );
	return Status;
}
