162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/******************************************************************************
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci *	(C)Copyright 1998,1999 SysKonnect,
562306a36Sopenharmony_ci *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci *	See the file "skfddi.c" for further information.
862306a36Sopenharmony_ci *
962306a36Sopenharmony_ci *	The information in this file is provided "AS IS" without warranty.
1062306a36Sopenharmony_ci *
1162306a36Sopenharmony_ci ******************************************************************************/
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci/*
1462306a36Sopenharmony_ci	Parameter Management Frame processing for SMT 7.2
1562306a36Sopenharmony_ci*/
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#include "h/types.h"
1862306a36Sopenharmony_ci#include "h/fddi.h"
1962306a36Sopenharmony_ci#include "h/smc.h"
2062306a36Sopenharmony_ci#include "h/smt_p.h"
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci#define KERNEL
2362306a36Sopenharmony_ci#include "h/smtstate.h"
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci#ifndef	SLIM_SMT
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_cistatic int smt_authorize(struct s_smc *smc, struct smt_header *sm);
2862306a36Sopenharmony_cistatic int smt_check_set_count(struct s_smc *smc, struct smt_header *sm);
2962306a36Sopenharmony_cistatic const struct s_p_tab* smt_get_ptab(u_short para);
3062306a36Sopenharmony_cistatic int smt_mib_phys(struct s_smc *smc);
3162306a36Sopenharmony_cistatic int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index,
3262306a36Sopenharmony_ci			int local, int set);
3362306a36Sopenharmony_civoid smt_add_para(struct s_smc *smc, struct s_pcon *pcon, u_short para,
3462306a36Sopenharmony_ci		  int index, int local);
3562306a36Sopenharmony_cistatic SMbuf *smt_build_pmf_response(struct s_smc *smc, struct smt_header *req,
3662306a36Sopenharmony_ci				     int set, int local);
3762306a36Sopenharmony_cistatic int port_to_mib(struct s_smc *smc, int p);
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci#define MOFFSS(e)	offsetof(struct fddi_mib, e)
4062306a36Sopenharmony_ci#define MOFFMS(e)	offsetof(struct fddi_mib_m, e)
4162306a36Sopenharmony_ci#define MOFFAS(e)	offsetof(struct fddi_mib_a, e)
4262306a36Sopenharmony_ci#define MOFFPS(e)	offsetof(struct fddi_mib_p, e)
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci#define AC_G	0x01		/* Get */
4662306a36Sopenharmony_ci#define AC_GR	0x02		/* Get/Set */
4762306a36Sopenharmony_ci#define AC_S	0x04		/* Set */
4862306a36Sopenharmony_ci#define AC_NA	0x08
4962306a36Sopenharmony_ci#define AC_GROUP	0x10		/* Group */
5062306a36Sopenharmony_ci#define MS2BCLK(x)	((x)*12500L)
5162306a36Sopenharmony_ci/*
5262306a36Sopenharmony_ci	F	LFag (byte)
5362306a36Sopenharmony_ci	B	byte
5462306a36Sopenharmony_ci	S	u_short	16 bit
5562306a36Sopenharmony_ci	C	Counter 32 bit
5662306a36Sopenharmony_ci	L	Long 32 bit
5762306a36Sopenharmony_ci	T	Timer_2	32 bit
5862306a36Sopenharmony_ci	P	TimeStamp ;
5962306a36Sopenharmony_ci	A	LongAddress (6 byte)
6062306a36Sopenharmony_ci	E	Enum 16 bit
6162306a36Sopenharmony_ci	R	ResId 16 Bit
6262306a36Sopenharmony_ci*/
6362306a36Sopenharmony_cistatic const struct s_p_tab {
6462306a36Sopenharmony_ci	u_short	p_num ;		/* parameter code */
6562306a36Sopenharmony_ci	u_char	p_access ;	/* access rights */
6662306a36Sopenharmony_ci	u_short	p_offset ;	/* offset in mib */
6762306a36Sopenharmony_ci	char	p_swap[3] ;	/* format string */
6862306a36Sopenharmony_ci} p_tab[] = {
6962306a36Sopenharmony_ci	/* StationIdGrp */
7062306a36Sopenharmony_ci	{ SMT_P100A,AC_GROUP	} ,
7162306a36Sopenharmony_ci	{ SMT_P100B,AC_G,	MOFFSS(fddiSMTStationId),	"8"	} ,
7262306a36Sopenharmony_ci	{ SMT_P100D,AC_G,	MOFFSS(fddiSMTOpVersionId),	"S"	} ,
7362306a36Sopenharmony_ci	{ SMT_P100E,AC_G,	MOFFSS(fddiSMTHiVersionId),	"S"	} ,
7462306a36Sopenharmony_ci	{ SMT_P100F,AC_G,	MOFFSS(fddiSMTLoVersionId),	"S"	} ,
7562306a36Sopenharmony_ci	{ SMT_P1010,AC_G,	MOFFSS(fddiSMTManufacturerData), "D" } ,
7662306a36Sopenharmony_ci	{ SMT_P1011,AC_GR,	MOFFSS(fddiSMTUserData),	"D"	} ,
7762306a36Sopenharmony_ci	{ SMT_P1012,AC_G,	MOFFSS(fddiSMTMIBVersionId),	"S"	} ,
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci	/* StationConfigGrp */
8062306a36Sopenharmony_ci	{ SMT_P1014,AC_GROUP	} ,
8162306a36Sopenharmony_ci	{ SMT_P1015,AC_G,	MOFFSS(fddiSMTMac_Ct),		"B"	} ,
8262306a36Sopenharmony_ci	{ SMT_P1016,AC_G,	MOFFSS(fddiSMTNonMaster_Ct),	"B"	} ,
8362306a36Sopenharmony_ci	{ SMT_P1017,AC_G,	MOFFSS(fddiSMTMaster_Ct),	"B"	} ,
8462306a36Sopenharmony_ci	{ SMT_P1018,AC_G,	MOFFSS(fddiSMTAvailablePaths),	"B"	} ,
8562306a36Sopenharmony_ci	{ SMT_P1019,AC_G,	MOFFSS(fddiSMTConfigCapabilities),"S"	} ,
8662306a36Sopenharmony_ci	{ SMT_P101A,AC_GR,	MOFFSS(fddiSMTConfigPolicy),	"wS"	} ,
8762306a36Sopenharmony_ci	{ SMT_P101B,AC_GR,	MOFFSS(fddiSMTConnectionPolicy),"wS"	} ,
8862306a36Sopenharmony_ci	{ SMT_P101D,AC_GR,	MOFFSS(fddiSMTTT_Notify),	"wS"	} ,
8962306a36Sopenharmony_ci	{ SMT_P101E,AC_GR,	MOFFSS(fddiSMTStatRptPolicy),	"bB"	} ,
9062306a36Sopenharmony_ci	{ SMT_P101F,AC_GR,	MOFFSS(fddiSMTTrace_MaxExpiration),"lL"	} ,
9162306a36Sopenharmony_ci	{ SMT_P1020,AC_G,	MOFFSS(fddiSMTPORTIndexes),	"II"	} ,
9262306a36Sopenharmony_ci	{ SMT_P1021,AC_G,	MOFFSS(fddiSMTMACIndexes),	"I"	} ,
9362306a36Sopenharmony_ci	{ SMT_P1022,AC_G,	MOFFSS(fddiSMTBypassPresent),	"F"	} ,
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci	/* StatusGrp */
9662306a36Sopenharmony_ci	{ SMT_P1028,AC_GROUP	} ,
9762306a36Sopenharmony_ci	{ SMT_P1029,AC_G,	MOFFSS(fddiSMTECMState),	"E"	} ,
9862306a36Sopenharmony_ci	{ SMT_P102A,AC_G,	MOFFSS(fddiSMTCF_State),	"E"	} ,
9962306a36Sopenharmony_ci	{ SMT_P102C,AC_G,	MOFFSS(fddiSMTRemoteDisconnectFlag),"F"	} ,
10062306a36Sopenharmony_ci	{ SMT_P102D,AC_G,	MOFFSS(fddiSMTStationStatus),	"E"	} ,
10162306a36Sopenharmony_ci	{ SMT_P102E,AC_G,	MOFFSS(fddiSMTPeerWrapFlag),	"F"	} ,
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci	/* MIBOperationGrp */
10462306a36Sopenharmony_ci	{ SMT_P1032,AC_GROUP	} ,
10562306a36Sopenharmony_ci	{ SMT_P1033,AC_G,	MOFFSS(fddiSMTTimeStamp),"P"		} ,
10662306a36Sopenharmony_ci	{ SMT_P1034,AC_G,	MOFFSS(fddiSMTTransitionTimeStamp),"P"	} ,
10762306a36Sopenharmony_ci	/* NOTE : SMT_P1035 is already swapped ! SMT_P_SETCOUNT */
10862306a36Sopenharmony_ci	{ SMT_P1035,AC_G,	MOFFSS(fddiSMTSetCount),"4P"		} ,
10962306a36Sopenharmony_ci	{ SMT_P1036,AC_G,	MOFFSS(fddiSMTLastSetStationId),"8"	} ,
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci	{ SMT_P103C,AC_S,	0,				"wS"	} ,
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci	/*
11462306a36Sopenharmony_ci	 * PRIVATE EXTENSIONS
11562306a36Sopenharmony_ci	 * only accessible locally to get/set passwd
11662306a36Sopenharmony_ci	 */
11762306a36Sopenharmony_ci	{ SMT_P10F0,AC_GR,	MOFFSS(fddiPRPMFPasswd),	"8"	} ,
11862306a36Sopenharmony_ci	{ SMT_P10F1,AC_GR,	MOFFSS(fddiPRPMFStation),	"8"	} ,
11962306a36Sopenharmony_ci#ifdef	ESS
12062306a36Sopenharmony_ci	{ SMT_P10F2,AC_GR,	MOFFSS(fddiESSPayload),		"lL"	} ,
12162306a36Sopenharmony_ci	{ SMT_P10F3,AC_GR,	MOFFSS(fddiESSOverhead),	"lL"	} ,
12262306a36Sopenharmony_ci	{ SMT_P10F4,AC_GR,	MOFFSS(fddiESSMaxTNeg),		"lL"	} ,
12362306a36Sopenharmony_ci	{ SMT_P10F5,AC_GR,	MOFFSS(fddiESSMinSegmentSize),	"lL"	} ,
12462306a36Sopenharmony_ci	{ SMT_P10F6,AC_GR,	MOFFSS(fddiESSCategory),	"lL"	} ,
12562306a36Sopenharmony_ci	{ SMT_P10F7,AC_GR,	MOFFSS(fddiESSSynchTxMode),	"wS"	} ,
12662306a36Sopenharmony_ci#endif
12762306a36Sopenharmony_ci#ifdef	SBA
12862306a36Sopenharmony_ci	{ SMT_P10F8,AC_GR,	MOFFSS(fddiSBACommand),		"bF"	} ,
12962306a36Sopenharmony_ci	{ SMT_P10F9,AC_GR,	MOFFSS(fddiSBAAvailable),	"bF"	} ,
13062306a36Sopenharmony_ci#endif
13162306a36Sopenharmony_ci	/* MAC Attributes */
13262306a36Sopenharmony_ci	{ SMT_P200A,AC_GROUP	} ,
13362306a36Sopenharmony_ci	{ SMT_P200B,AC_G,	MOFFMS(fddiMACFrameStatusFunctions),"S"	} ,
13462306a36Sopenharmony_ci	{ SMT_P200D,AC_G,	MOFFMS(fddiMACT_MaxCapabilitiy),"T"	} ,
13562306a36Sopenharmony_ci	{ SMT_P200E,AC_G,	MOFFMS(fddiMACTVXCapabilitiy),"T"	} ,
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci	/* ConfigGrp */
13862306a36Sopenharmony_ci	{ SMT_P2014,AC_GROUP	} ,
13962306a36Sopenharmony_ci	{ SMT_P2016,AC_G,	MOFFMS(fddiMACAvailablePaths),	"B"	} ,
14062306a36Sopenharmony_ci	{ SMT_P2017,AC_G,	MOFFMS(fddiMACCurrentPath),	"S"	} ,
14162306a36Sopenharmony_ci	{ SMT_P2018,AC_G,	MOFFMS(fddiMACUpstreamNbr),	"A"	} ,
14262306a36Sopenharmony_ci	{ SMT_P2019,AC_G,	MOFFMS(fddiMACDownstreamNbr),	"A"	} ,
14362306a36Sopenharmony_ci	{ SMT_P201A,AC_G,	MOFFMS(fddiMACOldUpstreamNbr),	"A"	} ,
14462306a36Sopenharmony_ci	{ SMT_P201B,AC_G,	MOFFMS(fddiMACOldDownstreamNbr),"A"	} ,
14562306a36Sopenharmony_ci	{ SMT_P201D,AC_G,	MOFFMS(fddiMACDupAddressTest),	"E"	} ,
14662306a36Sopenharmony_ci	{ SMT_P2020,AC_GR,	MOFFMS(fddiMACRequestedPaths),	"wS"	} ,
14762306a36Sopenharmony_ci	{ SMT_P2021,AC_G,	MOFFMS(fddiMACDownstreamPORTType),"E"	} ,
14862306a36Sopenharmony_ci	{ SMT_P2022,AC_G,	MOFFMS(fddiMACIndex),		"S"	} ,
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci	/* AddressGrp */
15162306a36Sopenharmony_ci	{ SMT_P2028,AC_GROUP	} ,
15262306a36Sopenharmony_ci	{ SMT_P2029,AC_G,	MOFFMS(fddiMACSMTAddress),	"A"	} ,
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ci	/* OperationGrp */
15562306a36Sopenharmony_ci	{ SMT_P2032,AC_GROUP	} ,
15662306a36Sopenharmony_ci	{ SMT_P2033,AC_G,	MOFFMS(fddiMACT_Req),		"T"	} ,
15762306a36Sopenharmony_ci	{ SMT_P2034,AC_G,	MOFFMS(fddiMACT_Neg),		"T"	} ,
15862306a36Sopenharmony_ci	{ SMT_P2035,AC_G,	MOFFMS(fddiMACT_Max),		"T"	} ,
15962306a36Sopenharmony_ci	{ SMT_P2036,AC_G,	MOFFMS(fddiMACTvxValue),	"T"	} ,
16062306a36Sopenharmony_ci	{ SMT_P2038,AC_G,	MOFFMS(fddiMACT_Pri0),		"T"	} ,
16162306a36Sopenharmony_ci	{ SMT_P2039,AC_G,	MOFFMS(fddiMACT_Pri1),		"T"	} ,
16262306a36Sopenharmony_ci	{ SMT_P203A,AC_G,	MOFFMS(fddiMACT_Pri2),		"T"	} ,
16362306a36Sopenharmony_ci	{ SMT_P203B,AC_G,	MOFFMS(fddiMACT_Pri3),		"T"	} ,
16462306a36Sopenharmony_ci	{ SMT_P203C,AC_G,	MOFFMS(fddiMACT_Pri4),		"T"	} ,
16562306a36Sopenharmony_ci	{ SMT_P203D,AC_G,	MOFFMS(fddiMACT_Pri5),		"T"	} ,
16662306a36Sopenharmony_ci	{ SMT_P203E,AC_G,	MOFFMS(fddiMACT_Pri6),		"T"	} ,
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci	/* CountersGrp */
17062306a36Sopenharmony_ci	{ SMT_P2046,AC_GROUP	} ,
17162306a36Sopenharmony_ci	{ SMT_P2047,AC_G,	MOFFMS(fddiMACFrame_Ct),	"C"	} ,
17262306a36Sopenharmony_ci	{ SMT_P2048,AC_G,	MOFFMS(fddiMACCopied_Ct),	"C"	} ,
17362306a36Sopenharmony_ci	{ SMT_P2049,AC_G,	MOFFMS(fddiMACTransmit_Ct),	"C"	} ,
17462306a36Sopenharmony_ci	{ SMT_P204A,AC_G,	MOFFMS(fddiMACToken_Ct),	"C"	} ,
17562306a36Sopenharmony_ci	{ SMT_P2051,AC_G,	MOFFMS(fddiMACError_Ct),	"C"	} ,
17662306a36Sopenharmony_ci	{ SMT_P2052,AC_G,	MOFFMS(fddiMACLost_Ct),		"C"	} ,
17762306a36Sopenharmony_ci	{ SMT_P2053,AC_G,	MOFFMS(fddiMACTvxExpired_Ct),	"C"	} ,
17862306a36Sopenharmony_ci	{ SMT_P2054,AC_G,	MOFFMS(fddiMACNotCopied_Ct),	"C"	} ,
17962306a36Sopenharmony_ci	{ SMT_P2056,AC_G,	MOFFMS(fddiMACRingOp_Ct),	"C"	} ,
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci	/* FrameErrorConditionGrp */
18262306a36Sopenharmony_ci	{ SMT_P205A,AC_GROUP	} ,
18362306a36Sopenharmony_ci	{ SMT_P205F,AC_GR,	MOFFMS(fddiMACFrameErrorThreshold),"wS"	} ,
18462306a36Sopenharmony_ci	{ SMT_P2060,AC_G,	MOFFMS(fddiMACFrameErrorRatio),	"S"	} ,
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ci	/* NotCopiedConditionGrp */
18762306a36Sopenharmony_ci	{ SMT_P2064,AC_GROUP	} ,
18862306a36Sopenharmony_ci	{ SMT_P2067,AC_GR,	MOFFMS(fddiMACNotCopiedThreshold),"wS"	} ,
18962306a36Sopenharmony_ci	{ SMT_P2069,AC_G,	MOFFMS(fddiMACNotCopiedRatio),	"S"	} ,
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci	/* StatusGrp */
19262306a36Sopenharmony_ci	{ SMT_P206E,AC_GROUP	} ,
19362306a36Sopenharmony_ci	{ SMT_P206F,AC_G,	MOFFMS(fddiMACRMTState),	"S"	} ,
19462306a36Sopenharmony_ci	{ SMT_P2070,AC_G,	MOFFMS(fddiMACDA_Flag),	"F"	} ,
19562306a36Sopenharmony_ci	{ SMT_P2071,AC_G,	MOFFMS(fddiMACUNDA_Flag),	"F"	} ,
19662306a36Sopenharmony_ci	{ SMT_P2072,AC_G,	MOFFMS(fddiMACFrameErrorFlag),	"F"	} ,
19762306a36Sopenharmony_ci	{ SMT_P2073,AC_G,	MOFFMS(fddiMACNotCopiedFlag),	"F"	} ,
19862306a36Sopenharmony_ci	{ SMT_P2074,AC_G,	MOFFMS(fddiMACMA_UnitdataAvailable),"F"	} ,
19962306a36Sopenharmony_ci	{ SMT_P2075,AC_G,	MOFFMS(fddiMACHardwarePresent),	"F"	} ,
20062306a36Sopenharmony_ci	{ SMT_P2076,AC_GR,	MOFFMS(fddiMACMA_UnitdataEnable),"bF"	} ,
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci	/*
20362306a36Sopenharmony_ci	 * PRIVATE EXTENSIONS
20462306a36Sopenharmony_ci	 * only accessible locally to get/set TMIN
20562306a36Sopenharmony_ci	 */
20662306a36Sopenharmony_ci	{ SMT_P20F0,AC_NA						} ,
20762306a36Sopenharmony_ci	{ SMT_P20F1,AC_GR,	MOFFMS(fddiMACT_Min),		"lT"	} ,
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci	/* Path Attributes */
21062306a36Sopenharmony_ci	/*
21162306a36Sopenharmony_ci	 * DON't swap 320B,320F,3210: they are already swapped in swap_para()
21262306a36Sopenharmony_ci	 */
21362306a36Sopenharmony_ci	{ SMT_P320A,AC_GROUP	} ,
21462306a36Sopenharmony_ci	{ SMT_P320B,AC_G,	MOFFAS(fddiPATHIndex),		"r"	} ,
21562306a36Sopenharmony_ci	{ SMT_P320F,AC_GR,	MOFFAS(fddiPATHSbaPayload),	"l4"	} ,
21662306a36Sopenharmony_ci	{ SMT_P3210,AC_GR,	MOFFAS(fddiPATHSbaOverhead),	"l4"	} ,
21762306a36Sopenharmony_ci	/* fddiPATHConfiguration */
21862306a36Sopenharmony_ci	{ SMT_P3212,AC_G,	0,				""	} ,
21962306a36Sopenharmony_ci	{ SMT_P3213,AC_GR,	MOFFAS(fddiPATHT_Rmode),	"lT"	} ,
22062306a36Sopenharmony_ci	{ SMT_P3214,AC_GR,	MOFFAS(fddiPATHSbaAvailable),	"lL"	} ,
22162306a36Sopenharmony_ci	{ SMT_P3215,AC_GR,	MOFFAS(fddiPATHTVXLowerBound),	"lT"	} ,
22262306a36Sopenharmony_ci	{ SMT_P3216,AC_GR,	MOFFAS(fddiPATHT_MaxLowerBound),"lT"	} ,
22362306a36Sopenharmony_ci	{ SMT_P3217,AC_GR,	MOFFAS(fddiPATHMaxT_Req),	"lT"	} ,
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ci	/* Port Attributes */
22662306a36Sopenharmony_ci	/* ConfigGrp */
22762306a36Sopenharmony_ci	{ SMT_P400A,AC_GROUP	} ,
22862306a36Sopenharmony_ci	{ SMT_P400C,AC_G,	MOFFPS(fddiPORTMy_Type),	"E"	} ,
22962306a36Sopenharmony_ci	{ SMT_P400D,AC_G,	MOFFPS(fddiPORTNeighborType),	"E"	} ,
23062306a36Sopenharmony_ci	{ SMT_P400E,AC_GR,	MOFFPS(fddiPORTConnectionPolicies),"bB"	} ,
23162306a36Sopenharmony_ci	{ SMT_P400F,AC_G,	MOFFPS(fddiPORTMacIndicated),	"2"	} ,
23262306a36Sopenharmony_ci	{ SMT_P4010,AC_G,	MOFFPS(fddiPORTCurrentPath),	"E"	} ,
23362306a36Sopenharmony_ci	{ SMT_P4011,AC_GR,	MOFFPS(fddiPORTRequestedPaths),	"l4"	} ,
23462306a36Sopenharmony_ci	{ SMT_P4012,AC_G,	MOFFPS(fddiPORTMACPlacement),	"S"	} ,
23562306a36Sopenharmony_ci	{ SMT_P4013,AC_G,	MOFFPS(fddiPORTAvailablePaths),	"B"	} ,
23662306a36Sopenharmony_ci	{ SMT_P4016,AC_G,	MOFFPS(fddiPORTPMDClass),	"E"	} ,
23762306a36Sopenharmony_ci	{ SMT_P4017,AC_G,	MOFFPS(fddiPORTConnectionCapabilities),	"B"} ,
23862306a36Sopenharmony_ci	{ SMT_P401D,AC_G,	MOFFPS(fddiPORTIndex),		"R"	} ,
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ci	/* OperationGrp */
24162306a36Sopenharmony_ci	{ SMT_P401E,AC_GROUP	} ,
24262306a36Sopenharmony_ci	{ SMT_P401F,AC_GR,	MOFFPS(fddiPORTMaint_LS),	"wE"	} ,
24362306a36Sopenharmony_ci	{ SMT_P4021,AC_G,	MOFFPS(fddiPORTBS_Flag),	"F"	} ,
24462306a36Sopenharmony_ci	{ SMT_P4022,AC_G,	MOFFPS(fddiPORTPC_LS),		"E"	} ,
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_ci	/* ErrorCtrsGrp */
24762306a36Sopenharmony_ci	{ SMT_P4028,AC_GROUP	} ,
24862306a36Sopenharmony_ci	{ SMT_P4029,AC_G,	MOFFPS(fddiPORTEBError_Ct),	"C"	} ,
24962306a36Sopenharmony_ci	{ SMT_P402A,AC_G,	MOFFPS(fddiPORTLCTFail_Ct),	"C"	} ,
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci	/* LerGrp */
25262306a36Sopenharmony_ci	{ SMT_P4032,AC_GROUP	} ,
25362306a36Sopenharmony_ci	{ SMT_P4033,AC_G,	MOFFPS(fddiPORTLer_Estimate),	"F"	} ,
25462306a36Sopenharmony_ci	{ SMT_P4034,AC_G,	MOFFPS(fddiPORTLem_Reject_Ct),	"C"	} ,
25562306a36Sopenharmony_ci	{ SMT_P4035,AC_G,	MOFFPS(fddiPORTLem_Ct),		"C"	} ,
25662306a36Sopenharmony_ci	{ SMT_P403A,AC_GR,	MOFFPS(fddiPORTLer_Cutoff),	"bB"	} ,
25762306a36Sopenharmony_ci	{ SMT_P403B,AC_GR,	MOFFPS(fddiPORTLer_Alarm),	"bB"	} ,
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci	/* StatusGrp */
26062306a36Sopenharmony_ci	{ SMT_P403C,AC_GROUP	} ,
26162306a36Sopenharmony_ci	{ SMT_P403D,AC_G,	MOFFPS(fddiPORTConnectState),	"E"	} ,
26262306a36Sopenharmony_ci	{ SMT_P403E,AC_G,	MOFFPS(fddiPORTPCMStateX),	"E"	} ,
26362306a36Sopenharmony_ci	{ SMT_P403F,AC_G,	MOFFPS(fddiPORTPC_Withhold),	"E"	} ,
26462306a36Sopenharmony_ci	{ SMT_P4040,AC_G,	MOFFPS(fddiPORTLerFlag),	"F"	} ,
26562306a36Sopenharmony_ci	{ SMT_P4041,AC_G,	MOFFPS(fddiPORTHardwarePresent),"F"	} ,
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_ci	{ SMT_P4046,AC_S,	0,				"wS"	} ,
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_ci	{ 0,	AC_GROUP	} ,
27062306a36Sopenharmony_ci	{ 0 }
27162306a36Sopenharmony_ci} ;
27262306a36Sopenharmony_ci
27362306a36Sopenharmony_civoid smt_pmf_received_pack(struct s_smc *smc, SMbuf *mb, int local)
27462306a36Sopenharmony_ci{
27562306a36Sopenharmony_ci	struct smt_header	*sm ;
27662306a36Sopenharmony_ci	SMbuf		*reply ;
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_ci	sm = smtod(mb,struct smt_header *) ;
27962306a36Sopenharmony_ci	DB_SMT("SMT: processing PMF frame at %p len %d", sm, mb->sm_len);
28062306a36Sopenharmony_ci#ifdef	DEBUG
28162306a36Sopenharmony_ci	dump_smt(smc,sm,"PMF Received") ;
28262306a36Sopenharmony_ci#endif
28362306a36Sopenharmony_ci	/*
28462306a36Sopenharmony_ci	 * Start the watchdog: It may be a long, long packet and
28562306a36Sopenharmony_ci	 * maybe the watchdog occurs ...
28662306a36Sopenharmony_ci	 */
28762306a36Sopenharmony_ci	smt_start_watchdog(smc) ;
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ci	if (sm->smt_class == SMT_PMF_GET ||
29062306a36Sopenharmony_ci	    sm->smt_class == SMT_PMF_SET) {
29162306a36Sopenharmony_ci		reply = smt_build_pmf_response(smc,sm,
29262306a36Sopenharmony_ci			sm->smt_class == SMT_PMF_SET,local) ;
29362306a36Sopenharmony_ci		if (reply) {
29462306a36Sopenharmony_ci			sm = smtod(reply,struct smt_header *) ;
29562306a36Sopenharmony_ci#ifdef	DEBUG
29662306a36Sopenharmony_ci			dump_smt(smc,sm,"PMF Reply") ;
29762306a36Sopenharmony_ci#endif
29862306a36Sopenharmony_ci			smt_send_frame(smc,reply,FC_SMT_INFO,local) ;
29962306a36Sopenharmony_ci		}
30062306a36Sopenharmony_ci	}
30162306a36Sopenharmony_ci}
30262306a36Sopenharmony_ci
30362306a36Sopenharmony_cistatic SMbuf *smt_build_pmf_response(struct s_smc *smc, struct smt_header *req,
30462306a36Sopenharmony_ci				     int set, int local)
30562306a36Sopenharmony_ci{
30662306a36Sopenharmony_ci	SMbuf			*mb ;
30762306a36Sopenharmony_ci	struct smt_header	*smt ;
30862306a36Sopenharmony_ci	struct smt_para		*pa ;
30962306a36Sopenharmony_ci	struct smt_p_reason	*res ;
31062306a36Sopenharmony_ci	const struct s_p_tab	*pt ;
31162306a36Sopenharmony_ci	int			len ;
31262306a36Sopenharmony_ci	int			index ;
31362306a36Sopenharmony_ci	int			idx_end ;
31462306a36Sopenharmony_ci	int			error ;
31562306a36Sopenharmony_ci	int			range ;
31662306a36Sopenharmony_ci	SK_LOC_DECL(struct s_pcon,pcon) ;
31762306a36Sopenharmony_ci	SK_LOC_DECL(struct s_pcon,set_pcon) ;
31862306a36Sopenharmony_ci
31962306a36Sopenharmony_ci	/*
32062306a36Sopenharmony_ci	 * build SMT header
32162306a36Sopenharmony_ci	 */
32262306a36Sopenharmony_ci	if (!(mb = smt_get_mbuf(smc)))
32362306a36Sopenharmony_ci		return mb;
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_ci	smt = smtod(mb, struct smt_header *) ;
32662306a36Sopenharmony_ci	smt->smt_dest = req->smt_source ;	/* DA == source of request */
32762306a36Sopenharmony_ci	smt->smt_class = req->smt_class ;	/* same class (GET/SET) */
32862306a36Sopenharmony_ci	smt->smt_type = SMT_REPLY ;
32962306a36Sopenharmony_ci	smt->smt_version = SMT_VID_2 ;
33062306a36Sopenharmony_ci	smt->smt_tid = req->smt_tid ;		/* same TID */
33162306a36Sopenharmony_ci	smt->smt_pad = 0 ;
33262306a36Sopenharmony_ci	smt->smt_len = 0 ;
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci	/*
33562306a36Sopenharmony_ci	 * setup parameter status
33662306a36Sopenharmony_ci	 */
33762306a36Sopenharmony_ci	pcon.pc_len = SMT_MAX_INFO_LEN ;	/* max para length */
33862306a36Sopenharmony_ci	pcon.pc_err = 0 ;			/* no error */
33962306a36Sopenharmony_ci	pcon.pc_badset = 0 ;			/* no bad set count */
34062306a36Sopenharmony_ci	pcon.pc_p = (void *) (smt + 1) ;	/* paras start here */
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ci	/*
34362306a36Sopenharmony_ci	 * check authoriziation and set count
34462306a36Sopenharmony_ci	 */
34562306a36Sopenharmony_ci	error = 0 ;
34662306a36Sopenharmony_ci	if (set) {
34762306a36Sopenharmony_ci		if (!local && smt_authorize(smc,req))
34862306a36Sopenharmony_ci			error = SMT_RDF_AUTHOR ;
34962306a36Sopenharmony_ci		else if (smt_check_set_count(smc,req))
35062306a36Sopenharmony_ci			pcon.pc_badset = SMT_RDF_BADSET ;
35162306a36Sopenharmony_ci	}
35262306a36Sopenharmony_ci	/*
35362306a36Sopenharmony_ci	 * add reason code and all mandatory parameters
35462306a36Sopenharmony_ci	 */
35562306a36Sopenharmony_ci	res = (struct smt_p_reason *) pcon.pc_p ;
35662306a36Sopenharmony_ci	smt_add_para(smc,&pcon,(u_short) SMT_P_REASON,0,0) ;
35762306a36Sopenharmony_ci	smt_add_para(smc,&pcon,(u_short) SMT_P1033,0,0) ;
35862306a36Sopenharmony_ci	/* update 1035 and 1036 later if set */
35962306a36Sopenharmony_ci	set_pcon = pcon ;
36062306a36Sopenharmony_ci	smt_add_para(smc,&pcon,(u_short) SMT_P1035,0,0) ;
36162306a36Sopenharmony_ci	smt_add_para(smc,&pcon,(u_short) SMT_P1036,0,0) ;
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_ci	pcon.pc_err = error ;
36462306a36Sopenharmony_ci	len = req->smt_len ;
36562306a36Sopenharmony_ci	pa = (struct smt_para *) (req + 1) ;
36662306a36Sopenharmony_ci	/*
36762306a36Sopenharmony_ci	 * process list of paras
36862306a36Sopenharmony_ci	 */
36962306a36Sopenharmony_ci	while (!pcon.pc_err && len > 0 ) {
37062306a36Sopenharmony_ci		if (((u_short)len < pa->p_len + PARA_LEN) || (pa->p_len & 3)) {
37162306a36Sopenharmony_ci			pcon.pc_err = SMT_RDF_LENGTH ;
37262306a36Sopenharmony_ci			break ;
37362306a36Sopenharmony_ci		}
37462306a36Sopenharmony_ci
37562306a36Sopenharmony_ci		if (((range = (pa->p_type & 0xf000)) == 0x2000) ||
37662306a36Sopenharmony_ci			range == 0x3000 || range == 0x4000) {
37762306a36Sopenharmony_ci			/*
37862306a36Sopenharmony_ci			 * get index for PART,MAC ad PATH group
37962306a36Sopenharmony_ci			 */
38062306a36Sopenharmony_ci			index = *((u_char *)pa + PARA_LEN + 3) ;/* index */
38162306a36Sopenharmony_ci			idx_end = index ;
38262306a36Sopenharmony_ci			if (!set && (pa->p_len != 4)) {
38362306a36Sopenharmony_ci				pcon.pc_err = SMT_RDF_LENGTH ;
38462306a36Sopenharmony_ci				break ;
38562306a36Sopenharmony_ci			}
38662306a36Sopenharmony_ci			if (!index && !set) {
38762306a36Sopenharmony_ci				switch (range) {
38862306a36Sopenharmony_ci				case 0x2000 :
38962306a36Sopenharmony_ci					index = INDEX_MAC ;
39062306a36Sopenharmony_ci					idx_end = index - 1 + NUMMACS ;
39162306a36Sopenharmony_ci					break ;
39262306a36Sopenharmony_ci				case 0x3000 :
39362306a36Sopenharmony_ci					index = INDEX_PATH ;
39462306a36Sopenharmony_ci					idx_end = index - 1 + NUMPATHS ;
39562306a36Sopenharmony_ci					break ;
39662306a36Sopenharmony_ci				case 0x4000 :
39762306a36Sopenharmony_ci					index = INDEX_PORT ;
39862306a36Sopenharmony_ci					idx_end = index - 1 + NUMPHYS ;
39962306a36Sopenharmony_ci#ifndef	CONCENTRATOR
40062306a36Sopenharmony_ci					if (smc->s.sas == SMT_SAS)
40162306a36Sopenharmony_ci						idx_end = INDEX_PORT ;
40262306a36Sopenharmony_ci#endif
40362306a36Sopenharmony_ci					break ;
40462306a36Sopenharmony_ci				}
40562306a36Sopenharmony_ci			}
40662306a36Sopenharmony_ci		}
40762306a36Sopenharmony_ci		else {
40862306a36Sopenharmony_ci			/*
40962306a36Sopenharmony_ci			 * smt group has no index
41062306a36Sopenharmony_ci			 */
41162306a36Sopenharmony_ci			if (!set && (pa->p_len != 0)) {
41262306a36Sopenharmony_ci				pcon.pc_err = SMT_RDF_LENGTH ;
41362306a36Sopenharmony_ci				break ;
41462306a36Sopenharmony_ci			}
41562306a36Sopenharmony_ci			index = 0 ;
41662306a36Sopenharmony_ci			idx_end = 0 ;
41762306a36Sopenharmony_ci		}
41862306a36Sopenharmony_ci		while (index <= idx_end) {
41962306a36Sopenharmony_ci			/*
42062306a36Sopenharmony_ci			 * if group
42162306a36Sopenharmony_ci			 *	add all paras of group
42262306a36Sopenharmony_ci			 */
42362306a36Sopenharmony_ci			pt = smt_get_ptab(pa->p_type) ;
42462306a36Sopenharmony_ci			if (pt && pt->p_access == AC_GROUP && !set) {
42562306a36Sopenharmony_ci				pt++ ;
42662306a36Sopenharmony_ci				while (pt->p_access == AC_G ||
42762306a36Sopenharmony_ci					pt->p_access == AC_GR) {
42862306a36Sopenharmony_ci					smt_add_para(smc,&pcon,pt->p_num,
42962306a36Sopenharmony_ci						index,local);
43062306a36Sopenharmony_ci					pt++ ;
43162306a36Sopenharmony_ci				}
43262306a36Sopenharmony_ci			}
43362306a36Sopenharmony_ci			/*
43462306a36Sopenharmony_ci			 * ignore
43562306a36Sopenharmony_ci			 *	AUTHORIZATION in get/set
43662306a36Sopenharmony_ci			 *	SET COUNT in set
43762306a36Sopenharmony_ci			 */
43862306a36Sopenharmony_ci			else if (pa->p_type != SMT_P_AUTHOR &&
43962306a36Sopenharmony_ci				 (!set || (pa->p_type != SMT_P1035))) {
44062306a36Sopenharmony_ci				int	st ;
44162306a36Sopenharmony_ci				if (pcon.pc_badset) {
44262306a36Sopenharmony_ci					smt_add_para(smc,&pcon,pa->p_type,
44362306a36Sopenharmony_ci						index,local) ;
44462306a36Sopenharmony_ci				}
44562306a36Sopenharmony_ci				else if (set) {
44662306a36Sopenharmony_ci					st = smt_set_para(smc,pa,index,local,1);
44762306a36Sopenharmony_ci					/*
44862306a36Sopenharmony_ci					 * return para even if error
44962306a36Sopenharmony_ci					 */
45062306a36Sopenharmony_ci					smt_add_para(smc,&pcon,pa->p_type,
45162306a36Sopenharmony_ci						index,local) ;
45262306a36Sopenharmony_ci					pcon.pc_err = st ;
45362306a36Sopenharmony_ci				}
45462306a36Sopenharmony_ci				else {
45562306a36Sopenharmony_ci					if (pt && pt->p_access == AC_S) {
45662306a36Sopenharmony_ci						pcon.pc_err =
45762306a36Sopenharmony_ci							SMT_RDF_ILLEGAL ;
45862306a36Sopenharmony_ci					}
45962306a36Sopenharmony_ci					smt_add_para(smc,&pcon,pa->p_type,
46062306a36Sopenharmony_ci						index,local) ;
46162306a36Sopenharmony_ci				}
46262306a36Sopenharmony_ci			}
46362306a36Sopenharmony_ci			if (pcon.pc_err)
46462306a36Sopenharmony_ci				break ;
46562306a36Sopenharmony_ci			index++ ;
46662306a36Sopenharmony_ci		}
46762306a36Sopenharmony_ci		len -= pa->p_len + PARA_LEN ;
46862306a36Sopenharmony_ci		pa = (struct smt_para *) ((char *)pa + pa->p_len + PARA_LEN) ;
46962306a36Sopenharmony_ci	}
47062306a36Sopenharmony_ci	smt->smt_len = SMT_MAX_INFO_LEN - pcon.pc_len ;
47162306a36Sopenharmony_ci	mb->sm_len = smt->smt_len + sizeof(struct smt_header) ;
47262306a36Sopenharmony_ci
47362306a36Sopenharmony_ci	/* update reason code */
47462306a36Sopenharmony_ci	res->rdf_reason = pcon.pc_badset ? pcon.pc_badset :
47562306a36Sopenharmony_ci			pcon.pc_err ? pcon.pc_err : SMT_RDF_SUCCESS ;
47662306a36Sopenharmony_ci	if (set && (res->rdf_reason == SMT_RDF_SUCCESS)) {
47762306a36Sopenharmony_ci		/*
47862306a36Sopenharmony_ci		 * increment set count
47962306a36Sopenharmony_ci		 * set time stamp
48062306a36Sopenharmony_ci		 * store station id of last set
48162306a36Sopenharmony_ci		 */
48262306a36Sopenharmony_ci		smc->mib.fddiSMTSetCount.count++ ;
48362306a36Sopenharmony_ci		smt_set_timestamp(smc,smc->mib.fddiSMTSetCount.timestamp) ;
48462306a36Sopenharmony_ci		smc->mib.fddiSMTLastSetStationId = req->smt_sid ;
48562306a36Sopenharmony_ci		smt_add_para(smc,&set_pcon,(u_short) SMT_P1035,0,0) ;
48662306a36Sopenharmony_ci		smt_add_para(smc,&set_pcon,(u_short) SMT_P1036,0,0) ;
48762306a36Sopenharmony_ci	}
48862306a36Sopenharmony_ci	return mb;
48962306a36Sopenharmony_ci}
49062306a36Sopenharmony_ci
49162306a36Sopenharmony_cistatic int smt_authorize(struct s_smc *smc, struct smt_header *sm)
49262306a36Sopenharmony_ci{
49362306a36Sopenharmony_ci	struct smt_para	*pa ;
49462306a36Sopenharmony_ci	int		i ;
49562306a36Sopenharmony_ci	char		*p ;
49662306a36Sopenharmony_ci
49762306a36Sopenharmony_ci	/*
49862306a36Sopenharmony_ci	 * check source station id if not zero
49962306a36Sopenharmony_ci	 */
50062306a36Sopenharmony_ci	p = (char *) &smc->mib.fddiPRPMFStation ;
50162306a36Sopenharmony_ci	for (i = 0 ; i < 8 && !p[i] ; i++)
50262306a36Sopenharmony_ci		;
50362306a36Sopenharmony_ci	if (i != 8) {
50462306a36Sopenharmony_ci		if (memcmp((char *) &sm->smt_sid,
50562306a36Sopenharmony_ci			(char *) &smc->mib.fddiPRPMFStation,8))
50662306a36Sopenharmony_ci			return 1;
50762306a36Sopenharmony_ci	}
50862306a36Sopenharmony_ci	/*
50962306a36Sopenharmony_ci	 * check authoriziation parameter if passwd not zero
51062306a36Sopenharmony_ci	 */
51162306a36Sopenharmony_ci	p = (char *) smc->mib.fddiPRPMFPasswd ;
51262306a36Sopenharmony_ci	for (i = 0 ; i < 8 && !p[i] ; i++)
51362306a36Sopenharmony_ci		;
51462306a36Sopenharmony_ci	if (i != 8) {
51562306a36Sopenharmony_ci		pa = (struct smt_para *) sm_to_para(smc,sm,SMT_P_AUTHOR) ;
51662306a36Sopenharmony_ci		if (!pa)
51762306a36Sopenharmony_ci			return 1;
51862306a36Sopenharmony_ci		if (pa->p_len != 8)
51962306a36Sopenharmony_ci			return 1;
52062306a36Sopenharmony_ci		if (memcmp((char *)(pa+1),(char *)smc->mib.fddiPRPMFPasswd,8))
52162306a36Sopenharmony_ci			return 1;
52262306a36Sopenharmony_ci	}
52362306a36Sopenharmony_ci	return 0;
52462306a36Sopenharmony_ci}
52562306a36Sopenharmony_ci
52662306a36Sopenharmony_cistatic int smt_check_set_count(struct s_smc *smc, struct smt_header *sm)
52762306a36Sopenharmony_ci{
52862306a36Sopenharmony_ci	struct smt_para	*pa ;
52962306a36Sopenharmony_ci	struct smt_p_setcount	*sc ;
53062306a36Sopenharmony_ci
53162306a36Sopenharmony_ci	pa = (struct smt_para *) sm_to_para(smc,sm,SMT_P1035) ;
53262306a36Sopenharmony_ci	if (pa) {
53362306a36Sopenharmony_ci		sc = (struct smt_p_setcount *) pa ;
53462306a36Sopenharmony_ci		if ((smc->mib.fddiSMTSetCount.count != sc->count) ||
53562306a36Sopenharmony_ci			memcmp((char *) smc->mib.fddiSMTSetCount.timestamp,
53662306a36Sopenharmony_ci			(char *)sc->timestamp,8))
53762306a36Sopenharmony_ci			return 1;
53862306a36Sopenharmony_ci	}
53962306a36Sopenharmony_ci	return 0;
54062306a36Sopenharmony_ci}
54162306a36Sopenharmony_ci
54262306a36Sopenharmony_civoid smt_add_para(struct s_smc *smc, struct s_pcon *pcon, u_short para,
54362306a36Sopenharmony_ci		  int index, int local)
54462306a36Sopenharmony_ci{
54562306a36Sopenharmony_ci	struct smt_para	*pa ;
54662306a36Sopenharmony_ci	const struct s_p_tab	*pt ;
54762306a36Sopenharmony_ci	struct fddi_mib_m *mib_m = NULL;
54862306a36Sopenharmony_ci	struct fddi_mib_p *mib_p = NULL;
54962306a36Sopenharmony_ci	int		len ;
55062306a36Sopenharmony_ci	int		plen ;
55162306a36Sopenharmony_ci	char		*from ;
55262306a36Sopenharmony_ci	char		*to ;
55362306a36Sopenharmony_ci	const char	*swap ;
55462306a36Sopenharmony_ci	char		c ;
55562306a36Sopenharmony_ci	int		range ;
55662306a36Sopenharmony_ci	char		*mib_addr ;
55762306a36Sopenharmony_ci	int		mac ;
55862306a36Sopenharmony_ci	int		path ;
55962306a36Sopenharmony_ci	int		port ;
56062306a36Sopenharmony_ci	int		sp_len ;
56162306a36Sopenharmony_ci
56262306a36Sopenharmony_ci	/*
56362306a36Sopenharmony_ci	 * skip if error
56462306a36Sopenharmony_ci	 */
56562306a36Sopenharmony_ci	if (pcon->pc_err)
56662306a36Sopenharmony_ci		return ;
56762306a36Sopenharmony_ci
56862306a36Sopenharmony_ci	/*
56962306a36Sopenharmony_ci	 * actions don't have a value
57062306a36Sopenharmony_ci	 */
57162306a36Sopenharmony_ci	pt = smt_get_ptab(para) ;
57262306a36Sopenharmony_ci	if (pt && pt->p_access == AC_S)
57362306a36Sopenharmony_ci		return ;
57462306a36Sopenharmony_ci
57562306a36Sopenharmony_ci	to = (char *) (pcon->pc_p) ;	/* destination pointer */
57662306a36Sopenharmony_ci	len = pcon->pc_len ;		/* free space */
57762306a36Sopenharmony_ci	plen = len ;			/* remember start length */
57862306a36Sopenharmony_ci	pa = (struct smt_para *) to ;	/* type/length pointer */
57962306a36Sopenharmony_ci	to += PARA_LEN ;		/* skip smt_para */
58062306a36Sopenharmony_ci	len -= PARA_LEN ;
58162306a36Sopenharmony_ci	/*
58262306a36Sopenharmony_ci	 * set index if required
58362306a36Sopenharmony_ci	 */
58462306a36Sopenharmony_ci	if (((range = (para & 0xf000)) == 0x2000) ||
58562306a36Sopenharmony_ci		range == 0x3000 || range == 0x4000) {
58662306a36Sopenharmony_ci		if (len < 4)
58762306a36Sopenharmony_ci			goto wrong_error ;
58862306a36Sopenharmony_ci		to[0] = 0 ;
58962306a36Sopenharmony_ci		to[1] = 0 ;
59062306a36Sopenharmony_ci		to[2] = 0 ;
59162306a36Sopenharmony_ci		to[3] = index ;
59262306a36Sopenharmony_ci		len -= 4 ;
59362306a36Sopenharmony_ci		to += 4 ;
59462306a36Sopenharmony_ci	}
59562306a36Sopenharmony_ci	mac = index - INDEX_MAC ;
59662306a36Sopenharmony_ci	path = index - INDEX_PATH ;
59762306a36Sopenharmony_ci	port = index - INDEX_PORT ;
59862306a36Sopenharmony_ci	/*
59962306a36Sopenharmony_ci	 * get pointer to mib
60062306a36Sopenharmony_ci	 */
60162306a36Sopenharmony_ci	switch (range) {
60262306a36Sopenharmony_ci	case 0x1000 :
60362306a36Sopenharmony_ci	default :
60462306a36Sopenharmony_ci		mib_addr = (char *) (&smc->mib) ;
60562306a36Sopenharmony_ci		break ;
60662306a36Sopenharmony_ci	case 0x2000 :
60762306a36Sopenharmony_ci		if (mac < 0 || mac >= NUMMACS) {
60862306a36Sopenharmony_ci			pcon->pc_err = SMT_RDF_NOPARAM ;
60962306a36Sopenharmony_ci			return ;
61062306a36Sopenharmony_ci		}
61162306a36Sopenharmony_ci		mib_addr = (char *) (&smc->mib.m[mac]) ;
61262306a36Sopenharmony_ci		mib_m = (struct fddi_mib_m *) mib_addr ;
61362306a36Sopenharmony_ci		break ;
61462306a36Sopenharmony_ci	case 0x3000 :
61562306a36Sopenharmony_ci		if (path < 0 || path >= NUMPATHS) {
61662306a36Sopenharmony_ci			pcon->pc_err = SMT_RDF_NOPARAM ;
61762306a36Sopenharmony_ci			return ;
61862306a36Sopenharmony_ci		}
61962306a36Sopenharmony_ci		mib_addr = (char *) (&smc->mib.a[path]) ;
62062306a36Sopenharmony_ci		break ;
62162306a36Sopenharmony_ci	case 0x4000 :
62262306a36Sopenharmony_ci		if (port < 0 || port >= smt_mib_phys(smc)) {
62362306a36Sopenharmony_ci			pcon->pc_err = SMT_RDF_NOPARAM ;
62462306a36Sopenharmony_ci			return ;
62562306a36Sopenharmony_ci		}
62662306a36Sopenharmony_ci		mib_addr = (char *) (&smc->mib.p[port_to_mib(smc,port)]) ;
62762306a36Sopenharmony_ci		mib_p = (struct fddi_mib_p *) mib_addr ;
62862306a36Sopenharmony_ci		break ;
62962306a36Sopenharmony_ci	}
63062306a36Sopenharmony_ci	/*
63162306a36Sopenharmony_ci	 * check special paras
63262306a36Sopenharmony_ci	 */
63362306a36Sopenharmony_ci	swap = NULL;
63462306a36Sopenharmony_ci	switch (para) {
63562306a36Sopenharmony_ci	case SMT_P10F0 :
63662306a36Sopenharmony_ci	case SMT_P10F1 :
63762306a36Sopenharmony_ci#ifdef	ESS
63862306a36Sopenharmony_ci	case SMT_P10F2 :
63962306a36Sopenharmony_ci	case SMT_P10F3 :
64062306a36Sopenharmony_ci	case SMT_P10F4 :
64162306a36Sopenharmony_ci	case SMT_P10F5 :
64262306a36Sopenharmony_ci	case SMT_P10F6 :
64362306a36Sopenharmony_ci	case SMT_P10F7 :
64462306a36Sopenharmony_ci#endif
64562306a36Sopenharmony_ci#ifdef	SBA
64662306a36Sopenharmony_ci	case SMT_P10F8 :
64762306a36Sopenharmony_ci	case SMT_P10F9 :
64862306a36Sopenharmony_ci#endif
64962306a36Sopenharmony_ci	case SMT_P20F1 :
65062306a36Sopenharmony_ci		if (!local) {
65162306a36Sopenharmony_ci			pcon->pc_err = SMT_RDF_NOPARAM ;
65262306a36Sopenharmony_ci			return ;
65362306a36Sopenharmony_ci		}
65462306a36Sopenharmony_ci		break ;
65562306a36Sopenharmony_ci	case SMT_P2034 :
65662306a36Sopenharmony_ci	case SMT_P2046 :
65762306a36Sopenharmony_ci	case SMT_P2047 :
65862306a36Sopenharmony_ci	case SMT_P204A :
65962306a36Sopenharmony_ci	case SMT_P2051 :
66062306a36Sopenharmony_ci	case SMT_P2052 :
66162306a36Sopenharmony_ci		mac_update_counter(smc) ;
66262306a36Sopenharmony_ci		break ;
66362306a36Sopenharmony_ci	case SMT_P4022:
66462306a36Sopenharmony_ci		mib_p->fddiPORTPC_LS = LS2MIB(
66562306a36Sopenharmony_ci			sm_pm_get_ls(smc,port_to_mib(smc,port))) ;
66662306a36Sopenharmony_ci		break ;
66762306a36Sopenharmony_ci	case SMT_P_REASON :
66862306a36Sopenharmony_ci		*(u32 *)to = 0 ;
66962306a36Sopenharmony_ci		sp_len = 4 ;
67062306a36Sopenharmony_ci		goto sp_done ;
67162306a36Sopenharmony_ci	case SMT_P1033 :			/* time stamp */
67262306a36Sopenharmony_ci		smt_set_timestamp(smc,smc->mib.fddiSMTTimeStamp) ;
67362306a36Sopenharmony_ci		break ;
67462306a36Sopenharmony_ci
67562306a36Sopenharmony_ci	case SMT_P1020:				/* port indexes */
67662306a36Sopenharmony_ci#if	NUMPHYS == 12
67762306a36Sopenharmony_ci		swap = "IIIIIIIIIIII" ;
67862306a36Sopenharmony_ci#else
67962306a36Sopenharmony_ci#if	NUMPHYS == 2
68062306a36Sopenharmony_ci		if (smc->s.sas == SMT_SAS)
68162306a36Sopenharmony_ci			swap = "I" ;
68262306a36Sopenharmony_ci		else
68362306a36Sopenharmony_ci			swap = "II" ;
68462306a36Sopenharmony_ci#else
68562306a36Sopenharmony_ci#if	NUMPHYS == 24
68662306a36Sopenharmony_ci		swap = "IIIIIIIIIIIIIIIIIIIIIIII" ;
68762306a36Sopenharmony_ci#else
68862306a36Sopenharmony_ci	????
68962306a36Sopenharmony_ci#endif
69062306a36Sopenharmony_ci#endif
69162306a36Sopenharmony_ci#endif
69262306a36Sopenharmony_ci		break ;
69362306a36Sopenharmony_ci	case SMT_P3212 :
69462306a36Sopenharmony_ci		{
69562306a36Sopenharmony_ci			sp_len = cem_build_path(smc,to,path) ;
69662306a36Sopenharmony_ci			goto sp_done ;
69762306a36Sopenharmony_ci		}
69862306a36Sopenharmony_ci	case SMT_P1048 :		/* peer wrap condition */
69962306a36Sopenharmony_ci		{
70062306a36Sopenharmony_ci			struct smt_p_1048	*sp ;
70162306a36Sopenharmony_ci			sp = (struct smt_p_1048 *) to ;
70262306a36Sopenharmony_ci			sp->p1048_flag = smc->mib.fddiSMTPeerWrapFlag ;
70362306a36Sopenharmony_ci			sp->p1048_cf_state = smc->mib.fddiSMTCF_State ;
70462306a36Sopenharmony_ci			sp_len = sizeof(struct smt_p_1048) ;
70562306a36Sopenharmony_ci			goto sp_done ;
70662306a36Sopenharmony_ci		}
70762306a36Sopenharmony_ci	case SMT_P208C :
70862306a36Sopenharmony_ci		{
70962306a36Sopenharmony_ci			struct smt_p_208c	*sp ;
71062306a36Sopenharmony_ci			sp = (struct smt_p_208c *) to ;
71162306a36Sopenharmony_ci			sp->p208c_flag =
71262306a36Sopenharmony_ci				smc->mib.m[MAC0].fddiMACDuplicateAddressCond ;
71362306a36Sopenharmony_ci			sp->p208c_dupcondition =
71462306a36Sopenharmony_ci				(mib_m->fddiMACDA_Flag ? SMT_ST_MY_DUPA : 0) |
71562306a36Sopenharmony_ci				(mib_m->fddiMACUNDA_Flag ? SMT_ST_UNA_DUPA : 0);
71662306a36Sopenharmony_ci			sp->p208c_fddilong =
71762306a36Sopenharmony_ci				mib_m->fddiMACSMTAddress ;
71862306a36Sopenharmony_ci			sp->p208c_fddiunalong =
71962306a36Sopenharmony_ci				mib_m->fddiMACUpstreamNbr ;
72062306a36Sopenharmony_ci			sp->p208c_pad = 0 ;
72162306a36Sopenharmony_ci			sp_len = sizeof(struct smt_p_208c) ;
72262306a36Sopenharmony_ci			goto sp_done ;
72362306a36Sopenharmony_ci		}
72462306a36Sopenharmony_ci	case SMT_P208D :		/* frame error condition */
72562306a36Sopenharmony_ci		{
72662306a36Sopenharmony_ci			struct smt_p_208d	*sp ;
72762306a36Sopenharmony_ci			sp = (struct smt_p_208d *) to ;
72862306a36Sopenharmony_ci			sp->p208d_flag =
72962306a36Sopenharmony_ci				mib_m->fddiMACFrameErrorFlag ;
73062306a36Sopenharmony_ci			sp->p208d_frame_ct =
73162306a36Sopenharmony_ci				mib_m->fddiMACFrame_Ct ;
73262306a36Sopenharmony_ci			sp->p208d_error_ct =
73362306a36Sopenharmony_ci				mib_m->fddiMACError_Ct ;
73462306a36Sopenharmony_ci			sp->p208d_lost_ct =
73562306a36Sopenharmony_ci				mib_m->fddiMACLost_Ct ;
73662306a36Sopenharmony_ci			sp->p208d_ratio =
73762306a36Sopenharmony_ci				mib_m->fddiMACFrameErrorRatio ;
73862306a36Sopenharmony_ci			sp_len = sizeof(struct smt_p_208d) ;
73962306a36Sopenharmony_ci			goto sp_done ;
74062306a36Sopenharmony_ci		}
74162306a36Sopenharmony_ci	case SMT_P208E :		/* not copied condition */
74262306a36Sopenharmony_ci		{
74362306a36Sopenharmony_ci			struct smt_p_208e	*sp ;
74462306a36Sopenharmony_ci			sp = (struct smt_p_208e *) to ;
74562306a36Sopenharmony_ci			sp->p208e_flag =
74662306a36Sopenharmony_ci				mib_m->fddiMACNotCopiedFlag ;
74762306a36Sopenharmony_ci			sp->p208e_not_copied =
74862306a36Sopenharmony_ci				mib_m->fddiMACNotCopied_Ct ;
74962306a36Sopenharmony_ci			sp->p208e_copied =
75062306a36Sopenharmony_ci				mib_m->fddiMACCopied_Ct ;
75162306a36Sopenharmony_ci			sp->p208e_not_copied_ratio =
75262306a36Sopenharmony_ci				mib_m->fddiMACNotCopiedRatio ;
75362306a36Sopenharmony_ci			sp_len = sizeof(struct smt_p_208e) ;
75462306a36Sopenharmony_ci			goto sp_done ;
75562306a36Sopenharmony_ci		}
75662306a36Sopenharmony_ci	case SMT_P208F :	/* neighbor change event */
75762306a36Sopenharmony_ci		{
75862306a36Sopenharmony_ci			struct smt_p_208f	*sp ;
75962306a36Sopenharmony_ci			sp = (struct smt_p_208f *) to ;
76062306a36Sopenharmony_ci			sp->p208f_multiple =
76162306a36Sopenharmony_ci				mib_m->fddiMACMultiple_N ;
76262306a36Sopenharmony_ci			sp->p208f_nacondition =
76362306a36Sopenharmony_ci				mib_m->fddiMACDuplicateAddressCond ;
76462306a36Sopenharmony_ci			sp->p208f_old_una =
76562306a36Sopenharmony_ci				mib_m->fddiMACOldUpstreamNbr ;
76662306a36Sopenharmony_ci			sp->p208f_new_una =
76762306a36Sopenharmony_ci				mib_m->fddiMACUpstreamNbr ;
76862306a36Sopenharmony_ci			sp->p208f_old_dna =
76962306a36Sopenharmony_ci				mib_m->fddiMACOldDownstreamNbr ;
77062306a36Sopenharmony_ci			sp->p208f_new_dna =
77162306a36Sopenharmony_ci				mib_m->fddiMACDownstreamNbr ;
77262306a36Sopenharmony_ci			sp->p208f_curren_path =
77362306a36Sopenharmony_ci				mib_m->fddiMACCurrentPath ;
77462306a36Sopenharmony_ci			sp->p208f_smt_address =
77562306a36Sopenharmony_ci				mib_m->fddiMACSMTAddress ;
77662306a36Sopenharmony_ci			sp_len = sizeof(struct smt_p_208f) ;
77762306a36Sopenharmony_ci			goto sp_done ;
77862306a36Sopenharmony_ci		}
77962306a36Sopenharmony_ci	case SMT_P2090 :
78062306a36Sopenharmony_ci		{
78162306a36Sopenharmony_ci			struct smt_p_2090	*sp ;
78262306a36Sopenharmony_ci			sp = (struct smt_p_2090 *) to ;
78362306a36Sopenharmony_ci			sp->p2090_multiple =
78462306a36Sopenharmony_ci				mib_m->fddiMACMultiple_P ;
78562306a36Sopenharmony_ci			sp->p2090_availablepaths =
78662306a36Sopenharmony_ci				mib_m->fddiMACAvailablePaths ;
78762306a36Sopenharmony_ci			sp->p2090_currentpath =
78862306a36Sopenharmony_ci				mib_m->fddiMACCurrentPath ;
78962306a36Sopenharmony_ci			sp->p2090_requestedpaths =
79062306a36Sopenharmony_ci				mib_m->fddiMACRequestedPaths ;
79162306a36Sopenharmony_ci			sp_len = sizeof(struct smt_p_2090) ;
79262306a36Sopenharmony_ci			goto sp_done ;
79362306a36Sopenharmony_ci		}
79462306a36Sopenharmony_ci	case SMT_P4050 :
79562306a36Sopenharmony_ci		{
79662306a36Sopenharmony_ci			struct smt_p_4050	*sp ;
79762306a36Sopenharmony_ci			sp = (struct smt_p_4050 *) to ;
79862306a36Sopenharmony_ci			sp->p4050_flag =
79962306a36Sopenharmony_ci				mib_p->fddiPORTLerFlag ;
80062306a36Sopenharmony_ci			sp->p4050_pad = 0 ;
80162306a36Sopenharmony_ci			sp->p4050_cutoff =
80262306a36Sopenharmony_ci				mib_p->fddiPORTLer_Cutoff ;
80362306a36Sopenharmony_ci			sp->p4050_alarm =
80462306a36Sopenharmony_ci				mib_p->fddiPORTLer_Alarm ;
80562306a36Sopenharmony_ci			sp->p4050_estimate =
80662306a36Sopenharmony_ci				mib_p->fddiPORTLer_Estimate ;
80762306a36Sopenharmony_ci			sp->p4050_reject_ct =
80862306a36Sopenharmony_ci				mib_p->fddiPORTLem_Reject_Ct ;
80962306a36Sopenharmony_ci			sp->p4050_ct =
81062306a36Sopenharmony_ci				mib_p->fddiPORTLem_Ct ;
81162306a36Sopenharmony_ci			sp_len = sizeof(struct smt_p_4050) ;
81262306a36Sopenharmony_ci			goto sp_done ;
81362306a36Sopenharmony_ci		}
81462306a36Sopenharmony_ci
81562306a36Sopenharmony_ci	case SMT_P4051 :
81662306a36Sopenharmony_ci		{
81762306a36Sopenharmony_ci			struct smt_p_4051	*sp ;
81862306a36Sopenharmony_ci			sp = (struct smt_p_4051 *) to ;
81962306a36Sopenharmony_ci			sp->p4051_multiple =
82062306a36Sopenharmony_ci				mib_p->fddiPORTMultiple_U ;
82162306a36Sopenharmony_ci			sp->p4051_porttype =
82262306a36Sopenharmony_ci				mib_p->fddiPORTMy_Type ;
82362306a36Sopenharmony_ci			sp->p4051_connectstate =
82462306a36Sopenharmony_ci				mib_p->fddiPORTConnectState ;
82562306a36Sopenharmony_ci			sp->p4051_pc_neighbor =
82662306a36Sopenharmony_ci				mib_p->fddiPORTNeighborType ;
82762306a36Sopenharmony_ci			sp->p4051_pc_withhold =
82862306a36Sopenharmony_ci				mib_p->fddiPORTPC_Withhold ;
82962306a36Sopenharmony_ci			sp_len = sizeof(struct smt_p_4051) ;
83062306a36Sopenharmony_ci			goto sp_done ;
83162306a36Sopenharmony_ci		}
83262306a36Sopenharmony_ci	case SMT_P4052 :
83362306a36Sopenharmony_ci		{
83462306a36Sopenharmony_ci			struct smt_p_4052	*sp ;
83562306a36Sopenharmony_ci			sp = (struct smt_p_4052 *) to ;
83662306a36Sopenharmony_ci			sp->p4052_flag =
83762306a36Sopenharmony_ci				mib_p->fddiPORTEB_Condition ;
83862306a36Sopenharmony_ci			sp->p4052_eberrorcount =
83962306a36Sopenharmony_ci				mib_p->fddiPORTEBError_Ct ;
84062306a36Sopenharmony_ci			sp_len = sizeof(struct smt_p_4052) ;
84162306a36Sopenharmony_ci			goto sp_done ;
84262306a36Sopenharmony_ci		}
84362306a36Sopenharmony_ci	case SMT_P4053 :
84462306a36Sopenharmony_ci		{
84562306a36Sopenharmony_ci			struct smt_p_4053	*sp ;
84662306a36Sopenharmony_ci			sp = (struct smt_p_4053 *) to ;
84762306a36Sopenharmony_ci			sp->p4053_multiple =
84862306a36Sopenharmony_ci				mib_p->fddiPORTMultiple_P ;
84962306a36Sopenharmony_ci			sp->p4053_availablepaths =
85062306a36Sopenharmony_ci				mib_p->fddiPORTAvailablePaths ;
85162306a36Sopenharmony_ci			sp->p4053_currentpath =
85262306a36Sopenharmony_ci				mib_p->fddiPORTCurrentPath ;
85362306a36Sopenharmony_ci			memcpy(	(char *) &sp->p4053_requestedpaths,
85462306a36Sopenharmony_ci				(char *) mib_p->fddiPORTRequestedPaths,4) ;
85562306a36Sopenharmony_ci			sp->p4053_mytype =
85662306a36Sopenharmony_ci				mib_p->fddiPORTMy_Type ;
85762306a36Sopenharmony_ci			sp->p4053_neighbortype =
85862306a36Sopenharmony_ci				mib_p->fddiPORTNeighborType ;
85962306a36Sopenharmony_ci			sp_len = sizeof(struct smt_p_4053) ;
86062306a36Sopenharmony_ci			goto sp_done ;
86162306a36Sopenharmony_ci		}
86262306a36Sopenharmony_ci	default :
86362306a36Sopenharmony_ci		break ;
86462306a36Sopenharmony_ci	}
86562306a36Sopenharmony_ci	/*
86662306a36Sopenharmony_ci	 * in table ?
86762306a36Sopenharmony_ci	 */
86862306a36Sopenharmony_ci	if (!pt) {
86962306a36Sopenharmony_ci		pcon->pc_err = (para & 0xff00) ? SMT_RDF_NOPARAM :
87062306a36Sopenharmony_ci						SMT_RDF_ILLEGAL ;
87162306a36Sopenharmony_ci		return ;
87262306a36Sopenharmony_ci	}
87362306a36Sopenharmony_ci	/*
87462306a36Sopenharmony_ci	 * check access rights
87562306a36Sopenharmony_ci	 */
87662306a36Sopenharmony_ci	switch (pt->p_access) {
87762306a36Sopenharmony_ci	case AC_G :
87862306a36Sopenharmony_ci	case AC_GR :
87962306a36Sopenharmony_ci		break ;
88062306a36Sopenharmony_ci	default :
88162306a36Sopenharmony_ci		pcon->pc_err = SMT_RDF_ILLEGAL ;
88262306a36Sopenharmony_ci		return ;
88362306a36Sopenharmony_ci	}
88462306a36Sopenharmony_ci	from = mib_addr + pt->p_offset ;
88562306a36Sopenharmony_ci	if (!swap)
88662306a36Sopenharmony_ci		swap = pt->p_swap ;		/* pointer to swap string */
88762306a36Sopenharmony_ci
88862306a36Sopenharmony_ci	/*
88962306a36Sopenharmony_ci	 * copy values
89062306a36Sopenharmony_ci	 */
89162306a36Sopenharmony_ci	while ((c = *swap++)) {
89262306a36Sopenharmony_ci		switch(c) {
89362306a36Sopenharmony_ci		case 'b' :
89462306a36Sopenharmony_ci		case 'w' :
89562306a36Sopenharmony_ci		case 'l' :
89662306a36Sopenharmony_ci			break ;
89762306a36Sopenharmony_ci		case 'S' :
89862306a36Sopenharmony_ci		case 'E' :
89962306a36Sopenharmony_ci		case 'R' :
90062306a36Sopenharmony_ci		case 'r' :
90162306a36Sopenharmony_ci			if (len < 4)
90262306a36Sopenharmony_ci				goto len_error ;
90362306a36Sopenharmony_ci			to[0] = 0 ;
90462306a36Sopenharmony_ci			to[1] = 0 ;
90562306a36Sopenharmony_ci#ifdef	LITTLE_ENDIAN
90662306a36Sopenharmony_ci			if (c == 'r') {
90762306a36Sopenharmony_ci				to[2] = *from++ ;
90862306a36Sopenharmony_ci				to[3] = *from++ ;
90962306a36Sopenharmony_ci			}
91062306a36Sopenharmony_ci			else {
91162306a36Sopenharmony_ci				to[3] = *from++ ;
91262306a36Sopenharmony_ci				to[2] = *from++ ;
91362306a36Sopenharmony_ci			}
91462306a36Sopenharmony_ci#else
91562306a36Sopenharmony_ci			to[2] = *from++ ;
91662306a36Sopenharmony_ci			to[3] = *from++ ;
91762306a36Sopenharmony_ci#endif
91862306a36Sopenharmony_ci			to += 4 ;
91962306a36Sopenharmony_ci			len -= 4 ;
92062306a36Sopenharmony_ci			break ;
92162306a36Sopenharmony_ci		case 'I' :		/* for SET of port indexes */
92262306a36Sopenharmony_ci			if (len < 2)
92362306a36Sopenharmony_ci				goto len_error ;
92462306a36Sopenharmony_ci#ifdef	LITTLE_ENDIAN
92562306a36Sopenharmony_ci			to[1] = *from++ ;
92662306a36Sopenharmony_ci			to[0] = *from++ ;
92762306a36Sopenharmony_ci#else
92862306a36Sopenharmony_ci			to[0] = *from++ ;
92962306a36Sopenharmony_ci			to[1] = *from++ ;
93062306a36Sopenharmony_ci#endif
93162306a36Sopenharmony_ci			to += 2 ;
93262306a36Sopenharmony_ci			len -= 2 ;
93362306a36Sopenharmony_ci			break ;
93462306a36Sopenharmony_ci		case 'F' :
93562306a36Sopenharmony_ci		case 'B' :
93662306a36Sopenharmony_ci			if (len < 4)
93762306a36Sopenharmony_ci				goto len_error ;
93862306a36Sopenharmony_ci			len -= 4 ;
93962306a36Sopenharmony_ci			to[0] = 0 ;
94062306a36Sopenharmony_ci			to[1] = 0 ;
94162306a36Sopenharmony_ci			to[2] = 0 ;
94262306a36Sopenharmony_ci			to[3] = *from++ ;
94362306a36Sopenharmony_ci			to += 4 ;
94462306a36Sopenharmony_ci			break ;
94562306a36Sopenharmony_ci		case 'C' :
94662306a36Sopenharmony_ci		case 'T' :
94762306a36Sopenharmony_ci		case 'L' :
94862306a36Sopenharmony_ci			if (len < 4)
94962306a36Sopenharmony_ci				goto len_error ;
95062306a36Sopenharmony_ci#ifdef	LITTLE_ENDIAN
95162306a36Sopenharmony_ci			to[3] = *from++ ;
95262306a36Sopenharmony_ci			to[2] = *from++ ;
95362306a36Sopenharmony_ci			to[1] = *from++ ;
95462306a36Sopenharmony_ci			to[0] = *from++ ;
95562306a36Sopenharmony_ci#else
95662306a36Sopenharmony_ci			to[0] = *from++ ;
95762306a36Sopenharmony_ci			to[1] = *from++ ;
95862306a36Sopenharmony_ci			to[2] = *from++ ;
95962306a36Sopenharmony_ci			to[3] = *from++ ;
96062306a36Sopenharmony_ci#endif
96162306a36Sopenharmony_ci			len -= 4 ;
96262306a36Sopenharmony_ci			to += 4 ;
96362306a36Sopenharmony_ci			break ;
96462306a36Sopenharmony_ci		case '2' :		/* PortMacIndicated */
96562306a36Sopenharmony_ci			if (len < 4)
96662306a36Sopenharmony_ci				goto len_error ;
96762306a36Sopenharmony_ci			to[0] = 0 ;
96862306a36Sopenharmony_ci			to[1] = 0 ;
96962306a36Sopenharmony_ci			to[2] = *from++ ;
97062306a36Sopenharmony_ci			to[3] = *from++ ;
97162306a36Sopenharmony_ci			len -= 4 ;
97262306a36Sopenharmony_ci			to += 4 ;
97362306a36Sopenharmony_ci			break ;
97462306a36Sopenharmony_ci		case '4' :
97562306a36Sopenharmony_ci			if (len < 4)
97662306a36Sopenharmony_ci				goto len_error ;
97762306a36Sopenharmony_ci			to[0] = *from++ ;
97862306a36Sopenharmony_ci			to[1] = *from++ ;
97962306a36Sopenharmony_ci			to[2] = *from++ ;
98062306a36Sopenharmony_ci			to[3] = *from++ ;
98162306a36Sopenharmony_ci			len -= 4 ;
98262306a36Sopenharmony_ci			to += 4 ;
98362306a36Sopenharmony_ci			break ;
98462306a36Sopenharmony_ci		case 'A' :
98562306a36Sopenharmony_ci			if (len < 8)
98662306a36Sopenharmony_ci				goto len_error ;
98762306a36Sopenharmony_ci			to[0] = 0 ;
98862306a36Sopenharmony_ci			to[1] = 0 ;
98962306a36Sopenharmony_ci			memcpy((char *) to+2,(char *) from,6) ;
99062306a36Sopenharmony_ci			to += 8 ;
99162306a36Sopenharmony_ci			from += 8 ;
99262306a36Sopenharmony_ci			len -= 8 ;
99362306a36Sopenharmony_ci			break ;
99462306a36Sopenharmony_ci		case '8' :
99562306a36Sopenharmony_ci			if (len < 8)
99662306a36Sopenharmony_ci				goto len_error ;
99762306a36Sopenharmony_ci			memcpy((char *) to,(char *) from,8) ;
99862306a36Sopenharmony_ci			to += 8 ;
99962306a36Sopenharmony_ci			from += 8 ;
100062306a36Sopenharmony_ci			len -= 8 ;
100162306a36Sopenharmony_ci			break ;
100262306a36Sopenharmony_ci		case 'D' :
100362306a36Sopenharmony_ci			if (len < 32)
100462306a36Sopenharmony_ci				goto len_error ;
100562306a36Sopenharmony_ci			memcpy((char *) to,(char *) from,32) ;
100662306a36Sopenharmony_ci			to += 32 ;
100762306a36Sopenharmony_ci			from += 32 ;
100862306a36Sopenharmony_ci			len -= 32 ;
100962306a36Sopenharmony_ci			break ;
101062306a36Sopenharmony_ci		case 'P' :		/* timestamp is NOT swapped */
101162306a36Sopenharmony_ci			if (len < 8)
101262306a36Sopenharmony_ci				goto len_error ;
101362306a36Sopenharmony_ci			to[0] = *from++ ;
101462306a36Sopenharmony_ci			to[1] = *from++ ;
101562306a36Sopenharmony_ci			to[2] = *from++ ;
101662306a36Sopenharmony_ci			to[3] = *from++ ;
101762306a36Sopenharmony_ci			to[4] = *from++ ;
101862306a36Sopenharmony_ci			to[5] = *from++ ;
101962306a36Sopenharmony_ci			to[6] = *from++ ;
102062306a36Sopenharmony_ci			to[7] = *from++ ;
102162306a36Sopenharmony_ci			to += 8 ;
102262306a36Sopenharmony_ci			len -= 8 ;
102362306a36Sopenharmony_ci			break ;
102462306a36Sopenharmony_ci		default :
102562306a36Sopenharmony_ci			SMT_PANIC(smc,SMT_E0119, SMT_E0119_MSG) ;
102662306a36Sopenharmony_ci			break ;
102762306a36Sopenharmony_ci		}
102862306a36Sopenharmony_ci	}
102962306a36Sopenharmony_ci
103062306a36Sopenharmony_cidone:
103162306a36Sopenharmony_ci	/*
103262306a36Sopenharmony_ci	 * make it even (in case of 'I' encoding)
103362306a36Sopenharmony_ci	 * note: len is DECREMENTED
103462306a36Sopenharmony_ci	 */
103562306a36Sopenharmony_ci	if (len & 3) {
103662306a36Sopenharmony_ci		to[0] = 0 ;
103762306a36Sopenharmony_ci		to[1] = 0 ;
103862306a36Sopenharmony_ci		to += 4 - (len & 3 ) ;
103962306a36Sopenharmony_ci		len = len & ~ 3 ;
104062306a36Sopenharmony_ci	}
104162306a36Sopenharmony_ci
104262306a36Sopenharmony_ci	/* set type and length */
104362306a36Sopenharmony_ci	pa->p_type = para ;
104462306a36Sopenharmony_ci	pa->p_len = plen - len - PARA_LEN ;
104562306a36Sopenharmony_ci	/* return values */
104662306a36Sopenharmony_ci	pcon->pc_p = (void *) to ;
104762306a36Sopenharmony_ci	pcon->pc_len = len ;
104862306a36Sopenharmony_ci	return ;
104962306a36Sopenharmony_ci
105062306a36Sopenharmony_cisp_done:
105162306a36Sopenharmony_ci	len -= sp_len ;
105262306a36Sopenharmony_ci	to += sp_len ;
105362306a36Sopenharmony_ci	goto done ;
105462306a36Sopenharmony_ci
105562306a36Sopenharmony_cilen_error:
105662306a36Sopenharmony_ci	/* parameter does not fit in frame */
105762306a36Sopenharmony_ci	pcon->pc_err = SMT_RDF_TOOLONG ;
105862306a36Sopenharmony_ci	return ;
105962306a36Sopenharmony_ci
106062306a36Sopenharmony_ciwrong_error:
106162306a36Sopenharmony_ci	pcon->pc_err = SMT_RDF_LENGTH ;
106262306a36Sopenharmony_ci}
106362306a36Sopenharmony_ci
106462306a36Sopenharmony_ci/*
106562306a36Sopenharmony_ci * set parameter
106662306a36Sopenharmony_ci */
106762306a36Sopenharmony_cistatic int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index,
106862306a36Sopenharmony_ci			int local, int set)
106962306a36Sopenharmony_ci{
107062306a36Sopenharmony_ci#define IFSET(x)	if (set) (x)
107162306a36Sopenharmony_ci
107262306a36Sopenharmony_ci	const struct s_p_tab	*pt ;
107362306a36Sopenharmony_ci	int		len ;
107462306a36Sopenharmony_ci	char		*from ;
107562306a36Sopenharmony_ci	char		*to ;
107662306a36Sopenharmony_ci	const char	*swap ;
107762306a36Sopenharmony_ci	char		c ;
107862306a36Sopenharmony_ci	char		*mib_addr ;
107962306a36Sopenharmony_ci	struct fddi_mib	*mib ;
108062306a36Sopenharmony_ci	struct fddi_mib_m	*mib_m = NULL;
108162306a36Sopenharmony_ci	struct fddi_mib_a	*mib_a = NULL;
108262306a36Sopenharmony_ci	struct fddi_mib_p	*mib_p = NULL;
108362306a36Sopenharmony_ci	int		mac ;
108462306a36Sopenharmony_ci	int		path ;
108562306a36Sopenharmony_ci	int		port ;
108662306a36Sopenharmony_ci	SK_LOC_DECL(u_char,byte_val) ;
108762306a36Sopenharmony_ci	SK_LOC_DECL(u_short,word_val) ;
108862306a36Sopenharmony_ci	SK_LOC_DECL(u_long,long_val) ;
108962306a36Sopenharmony_ci
109062306a36Sopenharmony_ci	mac = index - INDEX_MAC ;
109162306a36Sopenharmony_ci	path = index - INDEX_PATH ;
109262306a36Sopenharmony_ci	port = index - INDEX_PORT ;
109362306a36Sopenharmony_ci	len = pa->p_len ;
109462306a36Sopenharmony_ci	from = (char *) (pa + 1 ) ;
109562306a36Sopenharmony_ci
109662306a36Sopenharmony_ci	mib = &smc->mib ;
109762306a36Sopenharmony_ci	switch (pa->p_type & 0xf000) {
109862306a36Sopenharmony_ci	case 0x1000 :
109962306a36Sopenharmony_ci	default :
110062306a36Sopenharmony_ci		mib_addr = (char *) mib ;
110162306a36Sopenharmony_ci		break ;
110262306a36Sopenharmony_ci	case 0x2000 :
110362306a36Sopenharmony_ci		if (mac < 0 || mac >= NUMMACS) {
110462306a36Sopenharmony_ci			return SMT_RDF_NOPARAM;
110562306a36Sopenharmony_ci		}
110662306a36Sopenharmony_ci		mib_m = &smc->mib.m[mac] ;
110762306a36Sopenharmony_ci		mib_addr = (char *) mib_m ;
110862306a36Sopenharmony_ci		from += 4 ;		/* skip index */
110962306a36Sopenharmony_ci		len -= 4 ;
111062306a36Sopenharmony_ci		break ;
111162306a36Sopenharmony_ci	case 0x3000 :
111262306a36Sopenharmony_ci		if (path < 0 || path >= NUMPATHS) {
111362306a36Sopenharmony_ci			return SMT_RDF_NOPARAM;
111462306a36Sopenharmony_ci		}
111562306a36Sopenharmony_ci		mib_a = &smc->mib.a[path] ;
111662306a36Sopenharmony_ci		mib_addr = (char *) mib_a ;
111762306a36Sopenharmony_ci		from += 4 ;		/* skip index */
111862306a36Sopenharmony_ci		len -= 4 ;
111962306a36Sopenharmony_ci		break ;
112062306a36Sopenharmony_ci	case 0x4000 :
112162306a36Sopenharmony_ci		if (port < 0 || port >= smt_mib_phys(smc)) {
112262306a36Sopenharmony_ci			return SMT_RDF_NOPARAM;
112362306a36Sopenharmony_ci		}
112462306a36Sopenharmony_ci		mib_p = &smc->mib.p[port_to_mib(smc,port)] ;
112562306a36Sopenharmony_ci		mib_addr = (char *) mib_p ;
112662306a36Sopenharmony_ci		from += 4 ;		/* skip index */
112762306a36Sopenharmony_ci		len -= 4 ;
112862306a36Sopenharmony_ci		break ;
112962306a36Sopenharmony_ci	}
113062306a36Sopenharmony_ci	switch (pa->p_type) {
113162306a36Sopenharmony_ci	case SMT_P10F0 :
113262306a36Sopenharmony_ci	case SMT_P10F1 :
113362306a36Sopenharmony_ci#ifdef	ESS
113462306a36Sopenharmony_ci	case SMT_P10F2 :
113562306a36Sopenharmony_ci	case SMT_P10F3 :
113662306a36Sopenharmony_ci	case SMT_P10F4 :
113762306a36Sopenharmony_ci	case SMT_P10F5 :
113862306a36Sopenharmony_ci	case SMT_P10F6 :
113962306a36Sopenharmony_ci	case SMT_P10F7 :
114062306a36Sopenharmony_ci#endif
114162306a36Sopenharmony_ci#ifdef	SBA
114262306a36Sopenharmony_ci	case SMT_P10F8 :
114362306a36Sopenharmony_ci	case SMT_P10F9 :
114462306a36Sopenharmony_ci#endif
114562306a36Sopenharmony_ci	case SMT_P20F1 :
114662306a36Sopenharmony_ci		if (!local)
114762306a36Sopenharmony_ci			return SMT_RDF_NOPARAM;
114862306a36Sopenharmony_ci		break ;
114962306a36Sopenharmony_ci	}
115062306a36Sopenharmony_ci	pt = smt_get_ptab(pa->p_type) ;
115162306a36Sopenharmony_ci	if (!pt)
115262306a36Sopenharmony_ci		return (pa->p_type & 0xff00) ? SMT_RDF_NOPARAM :
115362306a36Sopenharmony_ci					       SMT_RDF_ILLEGAL;
115462306a36Sopenharmony_ci	switch (pt->p_access) {
115562306a36Sopenharmony_ci	case AC_GR :
115662306a36Sopenharmony_ci	case AC_S :
115762306a36Sopenharmony_ci		break ;
115862306a36Sopenharmony_ci	default :
115962306a36Sopenharmony_ci		return SMT_RDF_ILLEGAL;
116062306a36Sopenharmony_ci	}
116162306a36Sopenharmony_ci	to = mib_addr + pt->p_offset ;
116262306a36Sopenharmony_ci	swap = pt->p_swap ;		/* pointer to swap string */
116362306a36Sopenharmony_ci
116462306a36Sopenharmony_ci	while (swap && (c = *swap++)) {
116562306a36Sopenharmony_ci		switch(c) {
116662306a36Sopenharmony_ci		case 'b' :
116762306a36Sopenharmony_ci			to = (char *) &byte_val ;
116862306a36Sopenharmony_ci			break ;
116962306a36Sopenharmony_ci		case 'w' :
117062306a36Sopenharmony_ci			to = (char *) &word_val ;
117162306a36Sopenharmony_ci			break ;
117262306a36Sopenharmony_ci		case 'l' :
117362306a36Sopenharmony_ci			to = (char *) &long_val ;
117462306a36Sopenharmony_ci			break ;
117562306a36Sopenharmony_ci		case 'S' :
117662306a36Sopenharmony_ci		case 'E' :
117762306a36Sopenharmony_ci		case 'R' :
117862306a36Sopenharmony_ci		case 'r' :
117962306a36Sopenharmony_ci			if (len < 4) {
118062306a36Sopenharmony_ci				goto len_error ;
118162306a36Sopenharmony_ci			}
118262306a36Sopenharmony_ci			if (from[0] | from[1])
118362306a36Sopenharmony_ci				goto val_error ;
118462306a36Sopenharmony_ci#ifdef	LITTLE_ENDIAN
118562306a36Sopenharmony_ci			if (c == 'r') {
118662306a36Sopenharmony_ci				to[0] = from[2] ;
118762306a36Sopenharmony_ci				to[1] = from[3] ;
118862306a36Sopenharmony_ci			}
118962306a36Sopenharmony_ci			else {
119062306a36Sopenharmony_ci				to[1] = from[2] ;
119162306a36Sopenharmony_ci				to[0] = from[3] ;
119262306a36Sopenharmony_ci			}
119362306a36Sopenharmony_ci#else
119462306a36Sopenharmony_ci			to[0] = from[2] ;
119562306a36Sopenharmony_ci			to[1] = from[3] ;
119662306a36Sopenharmony_ci#endif
119762306a36Sopenharmony_ci			from += 4 ;
119862306a36Sopenharmony_ci			to += 2 ;
119962306a36Sopenharmony_ci			len -= 4 ;
120062306a36Sopenharmony_ci			break ;
120162306a36Sopenharmony_ci		case 'F' :
120262306a36Sopenharmony_ci		case 'B' :
120362306a36Sopenharmony_ci			if (len < 4) {
120462306a36Sopenharmony_ci				goto len_error ;
120562306a36Sopenharmony_ci			}
120662306a36Sopenharmony_ci			if (from[0] | from[1] | from[2])
120762306a36Sopenharmony_ci				goto val_error ;
120862306a36Sopenharmony_ci			to[0] = from[3] ;
120962306a36Sopenharmony_ci			len -= 4 ;
121062306a36Sopenharmony_ci			from += 4 ;
121162306a36Sopenharmony_ci			to += 4 ;
121262306a36Sopenharmony_ci			break ;
121362306a36Sopenharmony_ci		case 'C' :
121462306a36Sopenharmony_ci		case 'T' :
121562306a36Sopenharmony_ci		case 'L' :
121662306a36Sopenharmony_ci			if (len < 4) {
121762306a36Sopenharmony_ci				goto len_error ;
121862306a36Sopenharmony_ci			}
121962306a36Sopenharmony_ci#ifdef	LITTLE_ENDIAN
122062306a36Sopenharmony_ci			to[3] = *from++ ;
122162306a36Sopenharmony_ci			to[2] = *from++ ;
122262306a36Sopenharmony_ci			to[1] = *from++ ;
122362306a36Sopenharmony_ci			to[0] = *from++ ;
122462306a36Sopenharmony_ci#else
122562306a36Sopenharmony_ci			to[0] = *from++ ;
122662306a36Sopenharmony_ci			to[1] = *from++ ;
122762306a36Sopenharmony_ci			to[2] = *from++ ;
122862306a36Sopenharmony_ci			to[3] = *from++ ;
122962306a36Sopenharmony_ci#endif
123062306a36Sopenharmony_ci			len -= 4 ;
123162306a36Sopenharmony_ci			to += 4 ;
123262306a36Sopenharmony_ci			break ;
123362306a36Sopenharmony_ci		case 'A' :
123462306a36Sopenharmony_ci			if (len < 8)
123562306a36Sopenharmony_ci				goto len_error ;
123662306a36Sopenharmony_ci			if (set)
123762306a36Sopenharmony_ci				memcpy(to,from+2,6) ;
123862306a36Sopenharmony_ci			to += 8 ;
123962306a36Sopenharmony_ci			from += 8 ;
124062306a36Sopenharmony_ci			len -= 8 ;
124162306a36Sopenharmony_ci			break ;
124262306a36Sopenharmony_ci		case '4' :
124362306a36Sopenharmony_ci			if (len < 4)
124462306a36Sopenharmony_ci				goto len_error ;
124562306a36Sopenharmony_ci			if (set)
124662306a36Sopenharmony_ci				memcpy(to,from,4) ;
124762306a36Sopenharmony_ci			to += 4 ;
124862306a36Sopenharmony_ci			from += 4 ;
124962306a36Sopenharmony_ci			len -= 4 ;
125062306a36Sopenharmony_ci			break ;
125162306a36Sopenharmony_ci		case '8' :
125262306a36Sopenharmony_ci			if (len < 8)
125362306a36Sopenharmony_ci				goto len_error ;
125462306a36Sopenharmony_ci			if (set)
125562306a36Sopenharmony_ci				memcpy(to,from,8) ;
125662306a36Sopenharmony_ci			to += 8 ;
125762306a36Sopenharmony_ci			from += 8 ;
125862306a36Sopenharmony_ci			len -= 8 ;
125962306a36Sopenharmony_ci			break ;
126062306a36Sopenharmony_ci		case 'D' :
126162306a36Sopenharmony_ci			if (len < 32)
126262306a36Sopenharmony_ci				goto len_error ;
126362306a36Sopenharmony_ci			if (set)
126462306a36Sopenharmony_ci				memcpy(to,from,32) ;
126562306a36Sopenharmony_ci			to += 32 ;
126662306a36Sopenharmony_ci			from += 32 ;
126762306a36Sopenharmony_ci			len -= 32 ;
126862306a36Sopenharmony_ci			break ;
126962306a36Sopenharmony_ci		case 'P' :		/* timestamp is NOT swapped */
127062306a36Sopenharmony_ci			if (set) {
127162306a36Sopenharmony_ci				to[0] = *from++ ;
127262306a36Sopenharmony_ci				to[1] = *from++ ;
127362306a36Sopenharmony_ci				to[2] = *from++ ;
127462306a36Sopenharmony_ci				to[3] = *from++ ;
127562306a36Sopenharmony_ci				to[4] = *from++ ;
127662306a36Sopenharmony_ci				to[5] = *from++ ;
127762306a36Sopenharmony_ci				to[6] = *from++ ;
127862306a36Sopenharmony_ci				to[7] = *from++ ;
127962306a36Sopenharmony_ci			}
128062306a36Sopenharmony_ci			to += 8 ;
128162306a36Sopenharmony_ci			len -= 8 ;
128262306a36Sopenharmony_ci			break ;
128362306a36Sopenharmony_ci		default :
128462306a36Sopenharmony_ci			SMT_PANIC(smc,SMT_E0120, SMT_E0120_MSG) ;
128562306a36Sopenharmony_ci			return SMT_RDF_ILLEGAL;
128662306a36Sopenharmony_ci		}
128762306a36Sopenharmony_ci	}
128862306a36Sopenharmony_ci	/*
128962306a36Sopenharmony_ci	 * actions and internal updates
129062306a36Sopenharmony_ci	 */
129162306a36Sopenharmony_ci	switch (pa->p_type) {
129262306a36Sopenharmony_ci	case SMT_P101A:			/* fddiSMTConfigPolicy */
129362306a36Sopenharmony_ci		if (word_val & ~1)
129462306a36Sopenharmony_ci			goto val_error ;
129562306a36Sopenharmony_ci		IFSET(mib->fddiSMTConfigPolicy = word_val) ;
129662306a36Sopenharmony_ci		break ;
129762306a36Sopenharmony_ci	case SMT_P101B :		/* fddiSMTConnectionPolicy */
129862306a36Sopenharmony_ci		if (!(word_val & POLICY_MM))
129962306a36Sopenharmony_ci			goto val_error ;
130062306a36Sopenharmony_ci		IFSET(mib->fddiSMTConnectionPolicy = word_val) ;
130162306a36Sopenharmony_ci		break ;
130262306a36Sopenharmony_ci	case SMT_P101D : 		/* fddiSMTTT_Notify */
130362306a36Sopenharmony_ci		if (word_val < 2 || word_val > 30)
130462306a36Sopenharmony_ci			goto val_error ;
130562306a36Sopenharmony_ci		IFSET(mib->fddiSMTTT_Notify = word_val) ;
130662306a36Sopenharmony_ci		break ;
130762306a36Sopenharmony_ci	case SMT_P101E :		/* fddiSMTStatRptPolicy */
130862306a36Sopenharmony_ci		if (byte_val & ~1)
130962306a36Sopenharmony_ci			goto val_error ;
131062306a36Sopenharmony_ci		IFSET(mib->fddiSMTStatRptPolicy = byte_val) ;
131162306a36Sopenharmony_ci		break ;
131262306a36Sopenharmony_ci	case SMT_P101F :		/* fddiSMTTrace_MaxExpiration */
131362306a36Sopenharmony_ci		/*
131462306a36Sopenharmony_ci		 * note: lower limit trace_max = 6.001773... s
131562306a36Sopenharmony_ci		 * NO upper limit
131662306a36Sopenharmony_ci		 */
131762306a36Sopenharmony_ci		if (long_val < (long)0x478bf51L)
131862306a36Sopenharmony_ci			goto val_error ;
131962306a36Sopenharmony_ci		IFSET(mib->fddiSMTTrace_MaxExpiration = long_val) ;
132062306a36Sopenharmony_ci		break ;
132162306a36Sopenharmony_ci#ifdef	ESS
132262306a36Sopenharmony_ci	case SMT_P10F2 :		/* fddiESSPayload */
132362306a36Sopenharmony_ci		if (long_val > 1562)
132462306a36Sopenharmony_ci			goto val_error ;
132562306a36Sopenharmony_ci		if (set && smc->mib.fddiESSPayload != long_val) {
132662306a36Sopenharmony_ci			smc->ess.raf_act_timer_poll = TRUE ;
132762306a36Sopenharmony_ci			smc->mib.fddiESSPayload = long_val ;
132862306a36Sopenharmony_ci		}
132962306a36Sopenharmony_ci		break ;
133062306a36Sopenharmony_ci	case SMT_P10F3 :		/* fddiESSOverhead */
133162306a36Sopenharmony_ci		if (long_val < 50 || long_val > 5000)
133262306a36Sopenharmony_ci			goto val_error ;
133362306a36Sopenharmony_ci		if (set && smc->mib.fddiESSPayload &&
133462306a36Sopenharmony_ci			smc->mib.fddiESSOverhead != long_val) {
133562306a36Sopenharmony_ci			smc->ess.raf_act_timer_poll = TRUE ;
133662306a36Sopenharmony_ci			smc->mib.fddiESSOverhead = long_val ;
133762306a36Sopenharmony_ci		}
133862306a36Sopenharmony_ci		break ;
133962306a36Sopenharmony_ci	case SMT_P10F4 :		/* fddiESSMaxTNeg */
134062306a36Sopenharmony_ci		if (long_val > -MS2BCLK(5) || long_val < -MS2BCLK(165))
134162306a36Sopenharmony_ci			goto val_error ;
134262306a36Sopenharmony_ci		IFSET(mib->fddiESSMaxTNeg = long_val) ;
134362306a36Sopenharmony_ci		break ;
134462306a36Sopenharmony_ci	case SMT_P10F5 :		/* fddiESSMinSegmentSize */
134562306a36Sopenharmony_ci		if (long_val < 1 || long_val > 4478)
134662306a36Sopenharmony_ci			goto val_error ;
134762306a36Sopenharmony_ci		IFSET(mib->fddiESSMinSegmentSize = long_val) ;
134862306a36Sopenharmony_ci		break ;
134962306a36Sopenharmony_ci	case SMT_P10F6 :		/* fddiESSCategory */
135062306a36Sopenharmony_ci		if ((long_val & 0xffff) != 1)
135162306a36Sopenharmony_ci			goto val_error ;
135262306a36Sopenharmony_ci		IFSET(mib->fddiESSCategory = long_val) ;
135362306a36Sopenharmony_ci		break ;
135462306a36Sopenharmony_ci	case SMT_P10F7 :		/* fddiESSSyncTxMode */
135562306a36Sopenharmony_ci		if (word_val > 1)
135662306a36Sopenharmony_ci			goto val_error ;
135762306a36Sopenharmony_ci		IFSET(mib->fddiESSSynchTxMode = word_val) ;
135862306a36Sopenharmony_ci		break ;
135962306a36Sopenharmony_ci#endif
136062306a36Sopenharmony_ci#ifdef	SBA
136162306a36Sopenharmony_ci	case SMT_P10F8 :		/* fddiSBACommand */
136262306a36Sopenharmony_ci		if (byte_val != SB_STOP && byte_val != SB_START)
136362306a36Sopenharmony_ci			goto val_error ;
136462306a36Sopenharmony_ci		IFSET(mib->fddiSBACommand = byte_val) ;
136562306a36Sopenharmony_ci		break ;
136662306a36Sopenharmony_ci	case SMT_P10F9 :		/* fddiSBAAvailable */
136762306a36Sopenharmony_ci		if (byte_val > 100)
136862306a36Sopenharmony_ci			goto val_error ;
136962306a36Sopenharmony_ci		IFSET(mib->fddiSBAAvailable = byte_val) ;
137062306a36Sopenharmony_ci		break ;
137162306a36Sopenharmony_ci#endif
137262306a36Sopenharmony_ci	case SMT_P2020 :		/* fddiMACRequestedPaths */
137362306a36Sopenharmony_ci		if ((word_val & (MIB_P_PATH_PRIM_PREFER |
137462306a36Sopenharmony_ci			MIB_P_PATH_PRIM_ALTER)) == 0 )
137562306a36Sopenharmony_ci			goto val_error ;
137662306a36Sopenharmony_ci		IFSET(mib_m->fddiMACRequestedPaths = word_val) ;
137762306a36Sopenharmony_ci		break ;
137862306a36Sopenharmony_ci	case SMT_P205F :		/* fddiMACFrameErrorThreshold */
137962306a36Sopenharmony_ci		/* 0 .. ffff acceptable */
138062306a36Sopenharmony_ci		IFSET(mib_m->fddiMACFrameErrorThreshold = word_val) ;
138162306a36Sopenharmony_ci		break ;
138262306a36Sopenharmony_ci	case SMT_P2067 :		/* fddiMACNotCopiedThreshold */
138362306a36Sopenharmony_ci		/* 0 .. ffff acceptable */
138462306a36Sopenharmony_ci		IFSET(mib_m->fddiMACNotCopiedThreshold = word_val) ;
138562306a36Sopenharmony_ci		break ;
138662306a36Sopenharmony_ci	case SMT_P2076:			/* fddiMACMA_UnitdataEnable */
138762306a36Sopenharmony_ci		if (byte_val & ~1)
138862306a36Sopenharmony_ci			goto val_error ;
138962306a36Sopenharmony_ci		if (set) {
139062306a36Sopenharmony_ci			mib_m->fddiMACMA_UnitdataEnable = byte_val ;
139162306a36Sopenharmony_ci			queue_event(smc,EVENT_RMT,RM_ENABLE_FLAG) ;
139262306a36Sopenharmony_ci		}
139362306a36Sopenharmony_ci		break ;
139462306a36Sopenharmony_ci	case SMT_P20F1 :		/* fddiMACT_Min */
139562306a36Sopenharmony_ci		IFSET(mib_m->fddiMACT_Min = long_val) ;
139662306a36Sopenharmony_ci		break ;
139762306a36Sopenharmony_ci	case SMT_P320F :
139862306a36Sopenharmony_ci		if (long_val > 1562)
139962306a36Sopenharmony_ci			goto val_error ;
140062306a36Sopenharmony_ci		IFSET(mib_a->fddiPATHSbaPayload = long_val) ;
140162306a36Sopenharmony_ci#ifdef	ESS
140262306a36Sopenharmony_ci		if (set)
140362306a36Sopenharmony_ci			ess_para_change(smc) ;
140462306a36Sopenharmony_ci#endif
140562306a36Sopenharmony_ci		break ;
140662306a36Sopenharmony_ci	case SMT_P3210 :
140762306a36Sopenharmony_ci		if (long_val > 5000)
140862306a36Sopenharmony_ci			goto val_error ;
140962306a36Sopenharmony_ci
141062306a36Sopenharmony_ci		if (long_val != 0 && mib_a->fddiPATHSbaPayload == 0)
141162306a36Sopenharmony_ci			goto val_error ;
141262306a36Sopenharmony_ci
141362306a36Sopenharmony_ci		IFSET(mib_a->fddiPATHSbaOverhead = long_val) ;
141462306a36Sopenharmony_ci#ifdef	ESS
141562306a36Sopenharmony_ci		if (set)
141662306a36Sopenharmony_ci			ess_para_change(smc) ;
141762306a36Sopenharmony_ci#endif
141862306a36Sopenharmony_ci		break ;
141962306a36Sopenharmony_ci	case SMT_P3213:			/* fddiPATHT_Rmode */
142062306a36Sopenharmony_ci		/* no limit :
142162306a36Sopenharmony_ci		 * 0 .. 343.597 => 0 .. 2e32 * 80nS
142262306a36Sopenharmony_ci		 */
142362306a36Sopenharmony_ci		if (set) {
142462306a36Sopenharmony_ci			mib_a->fddiPATHT_Rmode = long_val ;
142562306a36Sopenharmony_ci			rtm_set_timer(smc) ;
142662306a36Sopenharmony_ci		}
142762306a36Sopenharmony_ci		break ;
142862306a36Sopenharmony_ci	case SMT_P3214 :		/* fddiPATHSbaAvailable */
142962306a36Sopenharmony_ci		if (long_val > 0x00BEBC20L)
143062306a36Sopenharmony_ci			goto val_error ;
143162306a36Sopenharmony_ci#ifdef SBA
143262306a36Sopenharmony_ci		if (set && mib->fddiSBACommand == SB_STOP)
143362306a36Sopenharmony_ci			goto val_error ;
143462306a36Sopenharmony_ci#endif
143562306a36Sopenharmony_ci		IFSET(mib_a->fddiPATHSbaAvailable = long_val) ;
143662306a36Sopenharmony_ci		break ;
143762306a36Sopenharmony_ci	case SMT_P3215 :		/* fddiPATHTVXLowerBound */
143862306a36Sopenharmony_ci		IFSET(mib_a->fddiPATHTVXLowerBound = long_val) ;
143962306a36Sopenharmony_ci		goto change_mac_para ;
144062306a36Sopenharmony_ci	case SMT_P3216 :		/* fddiPATHT_MaxLowerBound */
144162306a36Sopenharmony_ci		IFSET(mib_a->fddiPATHT_MaxLowerBound = long_val) ;
144262306a36Sopenharmony_ci		goto change_mac_para ;
144362306a36Sopenharmony_ci	case SMT_P3217 :		/* fddiPATHMaxT_Req */
144462306a36Sopenharmony_ci		IFSET(mib_a->fddiPATHMaxT_Req = long_val) ;
144562306a36Sopenharmony_ci
144662306a36Sopenharmony_cichange_mac_para:
144762306a36Sopenharmony_ci		if (set && smt_set_mac_opvalues(smc)) {
144862306a36Sopenharmony_ci			RS_SET(smc,RS_EVENT) ;
144962306a36Sopenharmony_ci			smc->sm.please_reconnect = 1 ;
145062306a36Sopenharmony_ci			queue_event(smc,EVENT_ECM,EC_DISCONNECT) ;
145162306a36Sopenharmony_ci		}
145262306a36Sopenharmony_ci		break ;
145362306a36Sopenharmony_ci	case SMT_P400E :		/* fddiPORTConnectionPolicies */
145462306a36Sopenharmony_ci		if (byte_val > 1)
145562306a36Sopenharmony_ci			goto val_error ;
145662306a36Sopenharmony_ci		IFSET(mib_p->fddiPORTConnectionPolicies = byte_val) ;
145762306a36Sopenharmony_ci		break ;
145862306a36Sopenharmony_ci	case SMT_P4011 :		/* fddiPORTRequestedPaths */
145962306a36Sopenharmony_ci		/* all 3*8 bits allowed */
146062306a36Sopenharmony_ci		IFSET(memcpy((char *)mib_p->fddiPORTRequestedPaths,
146162306a36Sopenharmony_ci			(char *)&long_val,4)) ;
146262306a36Sopenharmony_ci		break ;
146362306a36Sopenharmony_ci	case SMT_P401F:			/* fddiPORTMaint_LS */
146462306a36Sopenharmony_ci		if (word_val > 4)
146562306a36Sopenharmony_ci			goto val_error ;
146662306a36Sopenharmony_ci		IFSET(mib_p->fddiPORTMaint_LS = word_val) ;
146762306a36Sopenharmony_ci		break ;
146862306a36Sopenharmony_ci	case SMT_P403A :		/* fddiPORTLer_Cutoff */
146962306a36Sopenharmony_ci		if (byte_val < 4 || byte_val > 15)
147062306a36Sopenharmony_ci			goto val_error ;
147162306a36Sopenharmony_ci		IFSET(mib_p->fddiPORTLer_Cutoff = byte_val) ;
147262306a36Sopenharmony_ci		break ;
147362306a36Sopenharmony_ci	case SMT_P403B :		/* fddiPORTLer_Alarm */
147462306a36Sopenharmony_ci		if (byte_val < 4 || byte_val > 15)
147562306a36Sopenharmony_ci			goto val_error ;
147662306a36Sopenharmony_ci		IFSET(mib_p->fddiPORTLer_Alarm = byte_val) ;
147762306a36Sopenharmony_ci		break ;
147862306a36Sopenharmony_ci
147962306a36Sopenharmony_ci	/*
148062306a36Sopenharmony_ci	 * Actions
148162306a36Sopenharmony_ci	 */
148262306a36Sopenharmony_ci	case SMT_P103C :		/* fddiSMTStationAction */
148362306a36Sopenharmony_ci		if (smt_action(smc,SMT_STATION_ACTION, (int) word_val, 0))
148462306a36Sopenharmony_ci			goto val_error ;
148562306a36Sopenharmony_ci		break ;
148662306a36Sopenharmony_ci	case SMT_P4046:			/* fddiPORTAction */
148762306a36Sopenharmony_ci		if (smt_action(smc,SMT_PORT_ACTION, (int) word_val,
148862306a36Sopenharmony_ci			port_to_mib(smc,port)))
148962306a36Sopenharmony_ci			goto val_error ;
149062306a36Sopenharmony_ci		break ;
149162306a36Sopenharmony_ci	default :
149262306a36Sopenharmony_ci		break ;
149362306a36Sopenharmony_ci	}
149462306a36Sopenharmony_ci	return 0;
149562306a36Sopenharmony_ci
149662306a36Sopenharmony_cival_error:
149762306a36Sopenharmony_ci	/* parameter value in frame is out of range */
149862306a36Sopenharmony_ci	return SMT_RDF_RANGE;
149962306a36Sopenharmony_ci
150062306a36Sopenharmony_cilen_error:
150162306a36Sopenharmony_ci	/* parameter value in frame is too short */
150262306a36Sopenharmony_ci	return SMT_RDF_LENGTH;
150362306a36Sopenharmony_ci
150462306a36Sopenharmony_ci#if	0
150562306a36Sopenharmony_cino_author_error:
150662306a36Sopenharmony_ci	/* parameter not setable, because the SBA is not active
150762306a36Sopenharmony_ci	 * Please note: we give the return code 'not authorizeed
150862306a36Sopenharmony_ci	 *  because SBA denied is not a valid return code in the
150962306a36Sopenharmony_ci	 * PMF protocol.
151062306a36Sopenharmony_ci	 */
151162306a36Sopenharmony_ci	return SMT_RDF_AUTHOR;
151262306a36Sopenharmony_ci#endif
151362306a36Sopenharmony_ci}
151462306a36Sopenharmony_ci
151562306a36Sopenharmony_cistatic const struct s_p_tab *smt_get_ptab(u_short para)
151662306a36Sopenharmony_ci{
151762306a36Sopenharmony_ci	const struct s_p_tab	*pt ;
151862306a36Sopenharmony_ci	for (pt = p_tab ; pt->p_num && pt->p_num != para ; pt++)
151962306a36Sopenharmony_ci		;
152062306a36Sopenharmony_ci	return pt->p_num ? pt : NULL;
152162306a36Sopenharmony_ci}
152262306a36Sopenharmony_ci
152362306a36Sopenharmony_cistatic int smt_mib_phys(struct s_smc *smc)
152462306a36Sopenharmony_ci{
152562306a36Sopenharmony_ci#ifdef	CONCENTRATOR
152662306a36Sopenharmony_ci	SK_UNUSED(smc) ;
152762306a36Sopenharmony_ci
152862306a36Sopenharmony_ci	return NUMPHYS;
152962306a36Sopenharmony_ci#else
153062306a36Sopenharmony_ci	if (smc->s.sas == SMT_SAS)
153162306a36Sopenharmony_ci		return 1;
153262306a36Sopenharmony_ci	return NUMPHYS;
153362306a36Sopenharmony_ci#endif
153462306a36Sopenharmony_ci}
153562306a36Sopenharmony_ci
153662306a36Sopenharmony_cistatic int port_to_mib(struct s_smc *smc, int p)
153762306a36Sopenharmony_ci{
153862306a36Sopenharmony_ci#ifdef	CONCENTRATOR
153962306a36Sopenharmony_ci	SK_UNUSED(smc) ;
154062306a36Sopenharmony_ci
154162306a36Sopenharmony_ci	return p;
154262306a36Sopenharmony_ci#else
154362306a36Sopenharmony_ci	if (smc->s.sas == SMT_SAS)
154462306a36Sopenharmony_ci		return PS;
154562306a36Sopenharmony_ci	return p;
154662306a36Sopenharmony_ci#endif
154762306a36Sopenharmony_ci}
154862306a36Sopenharmony_ci
154962306a36Sopenharmony_ci
155062306a36Sopenharmony_ci#ifdef	DEBUG
155162306a36Sopenharmony_ci#ifndef	BOOT
155262306a36Sopenharmony_civoid dump_smt(struct s_smc *smc, struct smt_header *sm, char *text)
155362306a36Sopenharmony_ci{
155462306a36Sopenharmony_ci	int	len ;
155562306a36Sopenharmony_ci	struct smt_para	*pa ;
155662306a36Sopenharmony_ci	char	*c ;
155762306a36Sopenharmony_ci	int	n ;
155862306a36Sopenharmony_ci	int	nn ;
155962306a36Sopenharmony_ci#ifdef	LITTLE_ENDIAN
156062306a36Sopenharmony_ci	int	smtlen ;
156162306a36Sopenharmony_ci#endif
156262306a36Sopenharmony_ci
156362306a36Sopenharmony_ci	SK_UNUSED(smc) ;
156462306a36Sopenharmony_ci
156562306a36Sopenharmony_ci#ifdef	DEBUG_BRD
156662306a36Sopenharmony_ci	if (smc->debug.d_smtf < 2)
156762306a36Sopenharmony_ci#else
156862306a36Sopenharmony_ci	if (debug.d_smtf < 2)
156962306a36Sopenharmony_ci#endif
157062306a36Sopenharmony_ci		return ;
157162306a36Sopenharmony_ci#ifdef	LITTLE_ENDIAN
157262306a36Sopenharmony_ci	smtlen = sm->smt_len + sizeof(struct smt_header) ;
157362306a36Sopenharmony_ci#endif
157462306a36Sopenharmony_ci	printf("SMT Frame [%s]:\nDA  ",text) ;
157562306a36Sopenharmony_ci	dump_hex((char *) &sm->smt_dest,6) ;
157662306a36Sopenharmony_ci	printf("\tSA ") ;
157762306a36Sopenharmony_ci	dump_hex((char *) &sm->smt_source,6) ;
157862306a36Sopenharmony_ci	printf(" Class %x Type %x Version %x\n",
157962306a36Sopenharmony_ci		sm->smt_class,sm->smt_type,sm->smt_version)  ;
158062306a36Sopenharmony_ci	printf("TID %x\t\tSID ", sm->smt_tid);
158162306a36Sopenharmony_ci	dump_hex((char *) &sm->smt_sid,8) ;
158262306a36Sopenharmony_ci	printf(" LEN %x\n",sm->smt_len) ;
158362306a36Sopenharmony_ci
158462306a36Sopenharmony_ci	len = sm->smt_len ;
158562306a36Sopenharmony_ci	pa = (struct smt_para *) (sm + 1) ;
158662306a36Sopenharmony_ci	while (len > 0 ) {
158762306a36Sopenharmony_ci		int	plen ;
158862306a36Sopenharmony_ci#ifdef UNIX
158962306a36Sopenharmony_ci		printf("TYPE %x LEN %x VALUE\t",pa->p_type,pa->p_len) ;
159062306a36Sopenharmony_ci#else
159162306a36Sopenharmony_ci		printf("TYPE %04x LEN %2x VALUE\t",pa->p_type,pa->p_len) ;
159262306a36Sopenharmony_ci#endif
159362306a36Sopenharmony_ci		n = pa->p_len ;
159462306a36Sopenharmony_ci		if ( (n < 0 ) || (n > (int)(len - PARA_LEN))) {
159562306a36Sopenharmony_ci			n = len - PARA_LEN ;
159662306a36Sopenharmony_ci			printf(" BAD LENGTH\n") ;
159762306a36Sopenharmony_ci			break ;
159862306a36Sopenharmony_ci		}
159962306a36Sopenharmony_ci#ifdef	LITTLE_ENDIAN
160062306a36Sopenharmony_ci		smt_swap_para(sm,smtlen,0) ;
160162306a36Sopenharmony_ci#endif
160262306a36Sopenharmony_ci		if (n < 24) {
160362306a36Sopenharmony_ci			dump_hex((char *)(pa+1),(int) n) ;
160462306a36Sopenharmony_ci			printf("\n") ;
160562306a36Sopenharmony_ci		}
160662306a36Sopenharmony_ci		else {
160762306a36Sopenharmony_ci			int	first = 0 ;
160862306a36Sopenharmony_ci			c = (char *)(pa+1) ;
160962306a36Sopenharmony_ci			dump_hex(c,16) ;
161062306a36Sopenharmony_ci			printf("\n") ;
161162306a36Sopenharmony_ci			n -= 16 ;
161262306a36Sopenharmony_ci			c += 16 ;
161362306a36Sopenharmony_ci			while (n > 0) {
161462306a36Sopenharmony_ci				nn = (n > 16) ? 16 : n ;
161562306a36Sopenharmony_ci				if (n > 64) {
161662306a36Sopenharmony_ci					if (first == 0)
161762306a36Sopenharmony_ci						printf("\t\t\t...\n") ;
161862306a36Sopenharmony_ci					first = 1 ;
161962306a36Sopenharmony_ci				}
162062306a36Sopenharmony_ci				else {
162162306a36Sopenharmony_ci					printf("\t\t\t") ;
162262306a36Sopenharmony_ci					dump_hex(c,nn) ;
162362306a36Sopenharmony_ci					printf("\n") ;
162462306a36Sopenharmony_ci				}
162562306a36Sopenharmony_ci				n -= nn ;
162662306a36Sopenharmony_ci				c += 16 ;
162762306a36Sopenharmony_ci			}
162862306a36Sopenharmony_ci		}
162962306a36Sopenharmony_ci#ifdef	LITTLE_ENDIAN
163062306a36Sopenharmony_ci		smt_swap_para(sm,smtlen,1) ;
163162306a36Sopenharmony_ci#endif
163262306a36Sopenharmony_ci		plen = (pa->p_len + PARA_LEN + 3) & ~3 ;
163362306a36Sopenharmony_ci		len -= plen ;
163462306a36Sopenharmony_ci		pa = (struct smt_para *)((char *)pa + plen) ;
163562306a36Sopenharmony_ci	}
163662306a36Sopenharmony_ci	printf("-------------------------------------------------\n\n") ;
163762306a36Sopenharmony_ci}
163862306a36Sopenharmony_ci
163962306a36Sopenharmony_civoid dump_hex(char *p, int len)
164062306a36Sopenharmony_ci{
164162306a36Sopenharmony_ci	int	n = 0 ;
164262306a36Sopenharmony_ci	while (len--) {
164362306a36Sopenharmony_ci		n++ ;
164462306a36Sopenharmony_ci#ifdef UNIX
164562306a36Sopenharmony_ci		printf("%x%s",*p++ & 0xff,len ? ( (n & 7) ? " " : "-") : "") ;
164662306a36Sopenharmony_ci#else
164762306a36Sopenharmony_ci		printf("%02x%s",*p++ & 0xff,len ? ( (n & 7) ? " " : "-") : "") ;
164862306a36Sopenharmony_ci#endif
164962306a36Sopenharmony_ci	}
165062306a36Sopenharmony_ci}
165162306a36Sopenharmony_ci#endif	/* no BOOT */
165262306a36Sopenharmony_ci#endif	/* DEBUG */
165362306a36Sopenharmony_ci
165462306a36Sopenharmony_ci
165562306a36Sopenharmony_ci#endif	/* no SLIM_SMT */
1656