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

   dxbfr.c

Abstract:

   Frame Relay specific initialization routines.

Author:

   Michael Zarns

--*/
#include "digidxb.h"
#pragma hdrstop 	// Stop precomiled header generation
#include "frreg.h"

STATIC INLINE USHORT
dxbFrPortToLink( ULONG iPort )
/*++

Description:

	Convert the zero-based Port index to one-based Frame Relay Link number.

Parameters:

	iPort
		Port index

Return Value:

	Port Number

--*/
{
	ASSERT( iPort < MAXUSHORT );
	return (USHORT)iPort + 1;
}


NTSTATUS
dxbFrSetSnid(
	IN PDXB_DEVICE_EXTENSION pExt,
	IN ULONG                 MuxId,
	IN ULONG                 Snid )
/*++

Description:

	Sends the adapter an FRI_SETSNID ioctl.

Parameters:

	pExt
		Device extension defining adapter being configured

	MuxId
		Id returned from Link request

	Snid
		SubNetwork ID identifies the port

Return Value:

	STATUS_SUCCESS, or failure status

--*/
{
	NTSTATUS Status;
	FRI_SETSNID_t SetSnid = {0};
	ULONG Error;
	HANDLE hStream;

	SRAPRINT2(DIGIINITLOUD, SRA_MED_LEVEL, 
                  ( "DXB!dxbFrSetSnid: Enter, device %S, Snid 0x%x\n", pExt->Name.Buffer, Snid ) );

	SetSnid.fri_snid = Snid;
	SetSnid.fri_index = MuxId;

	Status = DsOpen( pExt->hDsDevice, "FR", NULL, NULL, 0, &hStream, &Error );
	if ( NT_ERROR( Status ) )
		goto Exit;

	Status = DsIoctl( hStream, FRI_SETSNID, &SetSnid, sizeof SetSnid, &Error );

	(void)DsClose( hStream );

Exit:
	SRAPRINT2(DIGIINITLOUD, SRA_MED_LEVEL, 
                  ( "DXB!dxbFrSetSnid: Leave, Status 0x%x\n", Status ) );
	return Status;
}


NTSTATUS
dxbFrTune(
	IN PDXB_DEVICE_EXTENSION pExt,
	IN HANDLE                hKeyPort,
	IN USHORT                iPort,
	IN ULONG                 Snid )
/*++

Description:

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

Parameters:

	pExt
		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;
	FRSCONF_InitLink_t InitLink = {0};
	HANDLE hKeyFr;
	ULONG Error;
	HANDLE hStream;

	SRAPRINT2(DIGIINITLOUD, SRA_MED_LEVEL, 
                  ( "DXB!dxbFrTune: Enter, device %S, Port 0x%x\n", pExt->Name.Buffer, iPort ) );

	Status = DigiRegOpenSubkey( &hKeyFr, hKeyPort, DXB_REGKEY_FRAME_RELAY );
	if ( NT_ERROR( Status ) )
		goto Exit;

	InitLink.cfgInfo.frs_conf_name[0] = '0' + iPort;	// Name is based on port index.

	InitLink.cfgInfo.frs_link_snid = Snid;

	DigiRegQueryDword( hKeyFr, DXB_REGVAL_FR_LINK_FLAGS, &InitLink.cfgInfo.frs_link_flags,
	                   DigiRegFlagOptional, DXB_REGVAL_FR_LINK_FLAGS_DEFAULT );
	DigiRegQueryDword( hKeyFr, DXB_REGVAL_FR_LINK_LMI_DLCI, &InitLink.cfgInfo.frs_link_lmi_dlci,
	                   DigiRegFlagOptional, DXB_REGVAL_FR_LINK_LMI_DLCI_DEFAULT );
	DigiRegQueryDword( hKeyFr, DXB_REGVAL_FR_LINK_MAX_FRAMESIZE, &InitLink.cfgInfo.frs_link_max_frsize,
	                   DigiRegFlagOptional, DXB_REGVAL_FR_LINK_MAX_FRAMESIZE_DEFAULT );
	DigiRegQueryDword( hKeyFr, DXB_REGVAL_FR_LINK_MN1, &InitLink.cfgInfo.frs_link_mN1,
	                   DigiRegFlagOptional, DXB_REGVAL_FR_LINK_MN1_DEFAULT );
	DigiRegQueryDword( hKeyFr, DXB_REGVAL_FR_LINK_MN2, &InitLink.cfgInfo.frs_link_mN2,
	                   DigiRegFlagOptional, DXB_REGVAL_FR_LINK_MN2_DEFAULT );
	DigiRegQueryDword( hKeyFr, DXB_REGVAL_FR_LINK_MN3, &InitLink.cfgInfo.frs_link_mN3,
	                   DigiRegFlagOptional, DXB_REGVAL_FR_LINK_MN3_DEFAULT );
	DigiRegQueryDword( hKeyFr, DXB_REGVAL_FR_LINK_MN4, &InitLink.cfgInfo.frs_link_mN4,
	                   DigiRegFlagOptional, DXB_REGVAL_FR_LINK_MN4_DEFAULT );
	DigiRegQueryDword( hKeyFr, DXB_REGVAL_FR_LINK_MP1, &InitLink.cfgInfo.frs_link_mP1,
	                   DigiRegFlagOptional, DXB_REGVAL_FR_LINK_MP1_DEFAULT );
	DigiRegQueryDword( hKeyFr, DXB_REGVAL_FR_LINK_MP10, &InitLink.cfgInfo.frs_link_mP10,
	                   DigiRegFlagOptional, DXB_REGVAL_FR_LINK_MP10_DEFAULT );
	DigiRegQueryDword( hKeyFr, DXB_REGVAL_FR_LINK_MT1, &InitLink.cfgInfo.frs_link_mT1,
	                   DigiRegFlagOptional, DXB_REGVAL_FR_LINK_MT1_DEFAULT );
	DigiRegQueryDword( hKeyFr, DXB_REGVAL_FR_LINK_MT2, &InitLink.cfgInfo.frs_link_mT2,
	                   DigiRegFlagOptional, DXB_REGVAL_FR_LINK_MT2_DEFAULT );
	DigiRegQueryDword( hKeyFr, DXB_REGVAL_FR_LINK_MT3, &InitLink.cfgInfo.frs_link_mT3,
	                   DigiRegFlagOptional, DXB_REGVAL_FR_LINK_MT3_DEFAULT );

	// Get FracT1 values from DS1 key 
	{
		HANDLE hkDs1;
		Status = DigiRegOpenSubkey( &hkDs1, hKeyPort, DXB_REGKEY_DS1 );
		if ( NT_SUCCESS( Status ) )
		{
			DigiRegQueryDword( hkDs1, DXB_REGVAL_CSU_FRACT1_TS_MASK, &InitLink.cfgInfo.frs_link_tslotmap,
			                   DigiRegFlagOptional, DXB_REGVAL_CSU_FRACT1_TS_MASK_DEFAULT );
		}
		else
		{
			// Optional override of TSlotMap - not written by config!
			DigiRegQueryDword( hKeyFr, DXB_REGVAL_FR_LINK_TSLOTMAP, &InitLink.cfgInfo.frs_link_tslotmap,
			                   DigiRegFlagOptional, DXB_REGVAL_FR_LINK_TSLOTMAP_DEFAULT );
		}
	}

	SRAPRINT2(DIGICONFIG, SRA_MED_LEVEL, 
                  ( "DXB: Frame Relay line config, line %d:\n"
                    "   conf_name       = %s\n"
                    "   link_snid       = 0x%x\n"
                    "   link_flags      = 0x%x\n"
                    "   link_lmi_dlci   = 0x%x\n"
                    "   link_1st_pllcfg = 0x%x\n"
                    "   link_max_frsize = 0x%x\n"
                    "   link_mN1  = 0x%x\n"
                    "   link_mN2  = 0x%x\n"
                    "   link_mN3  = 0x%x\n"
                    "   link_mN4  = 0x%x\n"
                    "   link_mP1  = 0x%x\n"
                    "   link_mP10 = 0x%x\n"
                    "   link_mT1  = 0x%x\n"
                    "   link_mT2  = 0x%x\n"
                    "   link_mT3  = 0x%x\n"
                    "   link_state      = 0x%x\n"
                    "   link_tslotmap   = 0x%08x\n",
                    iPort,
                    InitLink.cfgInfo.frs_conf_name,
                    InitLink.cfgInfo.frs_link_snid,
                    InitLink.cfgInfo.frs_link_flags,
                    InitLink.cfgInfo.frs_link_lmi_dlci,
                    InitLink.cfgInfo.frs_link_1st_pllcfg,
                    InitLink.cfgInfo.frs_link_max_frsize,
                    InitLink.cfgInfo.frs_link_mN1,
                    InitLink.cfgInfo.frs_link_mN2,
                    InitLink.cfgInfo.frs_link_mN3,
                    InitLink.cfgInfo.frs_link_mN4,
                    InitLink.cfgInfo.frs_link_mP1,
                    InitLink.cfgInfo.frs_link_mP10,
                    InitLink.cfgInfo.frs_link_mT1,
                    InitLink.cfgInfo.frs_link_mT2,
                    InitLink.cfgInfo.frs_link_mT3,
                    InitLink.cfgInfo.frs_link_state,
                    InitLink.cfgInfo.frs_link_tslotmap) );

	Status = DsOpen( pExt->hDsDevice, "FR", NULL, NULL, 0, &hStream, &Error );
	if ( NT_ERROR( Status ) )
		goto Exit;

	Status = DsIoctl( hStream, FRI_FRSCONF_InitLink, &InitLink, 
	                  sizeof InitLink, &Error );

	(void)DsClose( hStream );

Exit:
	SRAPRINT2(DIGIINITLOUD, SRA_MED_LEVEL, 
                  ( "DXB!dxbFrTune: Leave, Status 0x%x\n", Status ) );
	return Status;
}


NTSTATUS
dxbFrSnIdent(
	IN PDXB_DEVICE_EXTENSION pExt,
	IN ULONG                 Snid,
	IN USHORT                iPort )
/*++

Description:

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

Parameters:

	pExt
		Device extension identifying the adapter being configured

	Snid
		SubNetwork ID to be assigned to this port

	iPort
		Zero-based index of the port being configured

Return Value:

	STATUS_SUCCESS or failure status.

--*/
{
	NTSTATUS Status;
	FRI_SNIDENT_t SnIdent = {0};
	ULONG Error;
	HANDLE hStream;

	SRAPRINT2(DIGIINITLOUD, SRA_MED_LEVEL, 
                  ( "DXB!dxbFrSnIdent: device %S, Snid 0x%x, Port 0x%x\n", pExt->Name.Buffer, Snid, iPort ) );

	SnIdent.fr_snid = Snid;
	SnIdent.fr_link = dxbFrPortToLink( iPort );

	Status = DsOpen( pExt->hDsDevice, "FR", NULL, NULL, 0, &hStream, &Error );
	if ( NT_ERROR( Status ) )
		goto Exit;

	Status = DsIoctl( hStream, FRI_SNIDENT, &SnIdent, sizeof SnIdent, &Error );
	(void)DsClose( hStream );

Exit:
	SRAPRINT2(DIGIINITLOUD, SRA_MED_LEVEL, 
                  ( "DXB!dxbFrSnIdent: Leave, Status 0x%x\n", Status ) );
	return Status;
}
