xref: /OK3568_Linux_fs/kernel/drivers/net/fddi/skfp/srf.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /******************************************************************************
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  *	(C)Copyright 1998,1999 SysKonnect,
5*4882a593Smuzhiyun  *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  *	See the file "skfddi.c" for further information.
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  *	The information in this file is provided "AS IS" without warranty.
10*4882a593Smuzhiyun  *
11*4882a593Smuzhiyun  ******************************************************************************/
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun /*
14*4882a593Smuzhiyun 	SMT 7.2 Status Response Frame Implementation
15*4882a593Smuzhiyun 	SRF state machine and frame generation
16*4882a593Smuzhiyun */
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun #include "h/types.h"
19*4882a593Smuzhiyun #include "h/fddi.h"
20*4882a593Smuzhiyun #include "h/smc.h"
21*4882a593Smuzhiyun #include "h/smt_p.h"
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun #define KERNEL
24*4882a593Smuzhiyun #include "h/smtstate.h"
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun #ifndef	SLIM_SMT
27*4882a593Smuzhiyun #ifndef	BOOT
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun #ifndef	lint
30*4882a593Smuzhiyun static const char ID_sccs[] = "@(#)srf.c	1.18 97/08/04 (C) SK " ;
31*4882a593Smuzhiyun #endif
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun /*
35*4882a593Smuzhiyun  * function declarations
36*4882a593Smuzhiyun  */
37*4882a593Smuzhiyun static void clear_all_rep(struct s_smc *smc);
38*4882a593Smuzhiyun static void clear_reported(struct s_smc *smc);
39*4882a593Smuzhiyun static void smt_send_srf(struct s_smc *smc);
40*4882a593Smuzhiyun static struct s_srf_evc *smt_get_evc(struct s_smc *smc, int code, int index);
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun #define MAX_EVCS	ARRAY_SIZE(smc->evcs)
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun struct evc_init {
45*4882a593Smuzhiyun 	u_char code ;
46*4882a593Smuzhiyun 	u_char index ;
47*4882a593Smuzhiyun 	u_char n ;
48*4882a593Smuzhiyun 	u_short	para ;
49*4882a593Smuzhiyun }  ;
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun static const struct evc_init evc_inits[] = {
52*4882a593Smuzhiyun 	{ SMT_COND_SMT_PEER_WRAP,		0,1,SMT_P1048	} ,
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun 	{ SMT_COND_MAC_DUP_ADDR,		INDEX_MAC, NUMMACS,SMT_P208C } ,
55*4882a593Smuzhiyun 	{ SMT_COND_MAC_FRAME_ERROR,		INDEX_MAC, NUMMACS,SMT_P208D } ,
56*4882a593Smuzhiyun 	{ SMT_COND_MAC_NOT_COPIED,		INDEX_MAC, NUMMACS,SMT_P208E } ,
57*4882a593Smuzhiyun 	{ SMT_EVENT_MAC_NEIGHBOR_CHANGE,	INDEX_MAC, NUMMACS,SMT_P208F } ,
58*4882a593Smuzhiyun 	{ SMT_EVENT_MAC_PATH_CHANGE,		INDEX_MAC, NUMMACS,SMT_P2090 } ,
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun 	{ SMT_COND_PORT_LER,			INDEX_PORT,NUMPHYS,SMT_P4050 } ,
61*4882a593Smuzhiyun 	{ SMT_COND_PORT_EB_ERROR,		INDEX_PORT,NUMPHYS,SMT_P4052 } ,
62*4882a593Smuzhiyun 	{ SMT_EVENT_PORT_CONNECTION,		INDEX_PORT,NUMPHYS,SMT_P4051 } ,
63*4882a593Smuzhiyun 	{ SMT_EVENT_PORT_PATH_CHANGE,		INDEX_PORT,NUMPHYS,SMT_P4053 } ,
64*4882a593Smuzhiyun } ;
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun #define MAX_INIT_EVC	ARRAY_SIZE(evc_inits)
67*4882a593Smuzhiyun 
smt_init_evc(struct s_smc * smc)68*4882a593Smuzhiyun void smt_init_evc(struct s_smc *smc)
69*4882a593Smuzhiyun {
70*4882a593Smuzhiyun 	struct s_srf_evc	*evc ;
71*4882a593Smuzhiyun 	const struct evc_init 	*init ;
72*4882a593Smuzhiyun 	unsigned int		i ;
73*4882a593Smuzhiyun 	int			index ;
74*4882a593Smuzhiyun 	int			offset ;
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun 	static u_char		fail_safe = FALSE ;
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun 	memset((char *)smc->evcs,0,sizeof(smc->evcs)) ;
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun 	evc = smc->evcs ;
81*4882a593Smuzhiyun 	init = evc_inits ;
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun 	for (i = 0 ; i < MAX_INIT_EVC ; i++) {
84*4882a593Smuzhiyun 		for (index = 0 ; index < init->n ; index++) {
85*4882a593Smuzhiyun 			evc->evc_code = init->code ;
86*4882a593Smuzhiyun 			evc->evc_para = init->para ;
87*4882a593Smuzhiyun 			evc->evc_index = init->index + index ;
88*4882a593Smuzhiyun #ifndef	DEBUG
89*4882a593Smuzhiyun 			evc->evc_multiple = &fail_safe ;
90*4882a593Smuzhiyun 			evc->evc_cond_state = &fail_safe ;
91*4882a593Smuzhiyun #endif
92*4882a593Smuzhiyun 			evc++ ;
93*4882a593Smuzhiyun 		}
94*4882a593Smuzhiyun 		init++ ;
95*4882a593Smuzhiyun 	}
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun 	if ((unsigned int) (evc - smc->evcs) > MAX_EVCS) {
98*4882a593Smuzhiyun 		SMT_PANIC(smc,SMT_E0127, SMT_E0127_MSG) ;
99*4882a593Smuzhiyun 	}
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun 	/*
102*4882a593Smuzhiyun 	 * conditions
103*4882a593Smuzhiyun 	 */
104*4882a593Smuzhiyun 	smc->evcs[0].evc_cond_state = &smc->mib.fddiSMTPeerWrapFlag ;
105*4882a593Smuzhiyun 	smc->evcs[1].evc_cond_state =
106*4882a593Smuzhiyun 		&smc->mib.m[MAC0].fddiMACDuplicateAddressCond ;
107*4882a593Smuzhiyun 	smc->evcs[2].evc_cond_state =
108*4882a593Smuzhiyun 		&smc->mib.m[MAC0].fddiMACFrameErrorFlag ;
109*4882a593Smuzhiyun 	smc->evcs[3].evc_cond_state =
110*4882a593Smuzhiyun 		&smc->mib.m[MAC0].fddiMACNotCopiedFlag ;
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun 	/*
113*4882a593Smuzhiyun 	 * events
114*4882a593Smuzhiyun 	 */
115*4882a593Smuzhiyun 	smc->evcs[4].evc_multiple = &smc->mib.m[MAC0].fddiMACMultiple_N ;
116*4882a593Smuzhiyun 	smc->evcs[5].evc_multiple = &smc->mib.m[MAC0].fddiMACMultiple_P ;
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun 	offset = 6 ;
119*4882a593Smuzhiyun 	for (i = 0 ; i < NUMPHYS ; i++) {
120*4882a593Smuzhiyun 		/*
121*4882a593Smuzhiyun 		 * conditions
122*4882a593Smuzhiyun 		 */
123*4882a593Smuzhiyun 		smc->evcs[offset + 0*NUMPHYS].evc_cond_state =
124*4882a593Smuzhiyun 			&smc->mib.p[i].fddiPORTLerFlag ;
125*4882a593Smuzhiyun 		smc->evcs[offset + 1*NUMPHYS].evc_cond_state =
126*4882a593Smuzhiyun 			&smc->mib.p[i].fddiPORTEB_Condition ;
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun 		/*
129*4882a593Smuzhiyun 		 * events
130*4882a593Smuzhiyun 		 */
131*4882a593Smuzhiyun 		smc->evcs[offset + 2*NUMPHYS].evc_multiple =
132*4882a593Smuzhiyun 			&smc->mib.p[i].fddiPORTMultiple_U ;
133*4882a593Smuzhiyun 		smc->evcs[offset + 3*NUMPHYS].evc_multiple =
134*4882a593Smuzhiyun 			&smc->mib.p[i].fddiPORTMultiple_P ;
135*4882a593Smuzhiyun 		offset++ ;
136*4882a593Smuzhiyun 	}
137*4882a593Smuzhiyun #ifdef	DEBUG
138*4882a593Smuzhiyun 	for (i = 0, evc = smc->evcs ; i < MAX_EVCS ; i++, evc++) {
139*4882a593Smuzhiyun 		if (SMT_IS_CONDITION(evc->evc_code)) {
140*4882a593Smuzhiyun 			if (!evc->evc_cond_state) {
141*4882a593Smuzhiyun 				SMT_PANIC(smc,SMT_E0128, SMT_E0128_MSG) ;
142*4882a593Smuzhiyun 			}
143*4882a593Smuzhiyun 			evc->evc_multiple = &fail_safe ;
144*4882a593Smuzhiyun 		}
145*4882a593Smuzhiyun 		else {
146*4882a593Smuzhiyun 			if (!evc->evc_multiple) {
147*4882a593Smuzhiyun 				SMT_PANIC(smc,SMT_E0129, SMT_E0129_MSG) ;
148*4882a593Smuzhiyun 			}
149*4882a593Smuzhiyun 			evc->evc_cond_state = &fail_safe ;
150*4882a593Smuzhiyun 		}
151*4882a593Smuzhiyun 	}
152*4882a593Smuzhiyun #endif
153*4882a593Smuzhiyun 	smc->srf.TSR = smt_get_time() ;
154*4882a593Smuzhiyun 	smc->srf.sr_state = SR0_WAIT ;
155*4882a593Smuzhiyun }
156*4882a593Smuzhiyun 
smt_get_evc(struct s_smc * smc,int code,int index)157*4882a593Smuzhiyun static struct s_srf_evc *smt_get_evc(struct s_smc *smc, int code, int index)
158*4882a593Smuzhiyun {
159*4882a593Smuzhiyun 	unsigned int		i ;
160*4882a593Smuzhiyun 	struct s_srf_evc	*evc ;
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun 	for (i = 0, evc = smc->evcs ; i < MAX_EVCS ; i++, evc++) {
163*4882a593Smuzhiyun 		if (evc->evc_code == code && evc->evc_index == index)
164*4882a593Smuzhiyun 			return evc;
165*4882a593Smuzhiyun 	}
166*4882a593Smuzhiyun 	return NULL;
167*4882a593Smuzhiyun }
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun #define THRESHOLD_2	(2*TICKS_PER_SECOND)
170*4882a593Smuzhiyun #define THRESHOLD_32	(32*TICKS_PER_SECOND)
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun static const char * const srf_names[] = {
173*4882a593Smuzhiyun 	"None","MACPathChangeEvent",	"MACNeighborChangeEvent",
174*4882a593Smuzhiyun 	"PORTPathChangeEvent",		"PORTUndesiredConnectionAttemptEvent",
175*4882a593Smuzhiyun 	"SMTPeerWrapCondition",		"SMTHoldCondition",
176*4882a593Smuzhiyun 	"MACFrameErrorCondition",	"MACDuplicateAddressCondition",
177*4882a593Smuzhiyun 	"MACNotCopiedCondition",	"PORTEBErrorCondition",
178*4882a593Smuzhiyun 	"PORTLerCondition"
179*4882a593Smuzhiyun } ;
180*4882a593Smuzhiyun 
smt_srf_event(struct s_smc * smc,int code,int index,int cond)181*4882a593Smuzhiyun void smt_srf_event(struct s_smc *smc, int code, int index, int cond)
182*4882a593Smuzhiyun {
183*4882a593Smuzhiyun 	struct s_srf_evc	*evc ;
184*4882a593Smuzhiyun 	int			cond_asserted = 0 ;
185*4882a593Smuzhiyun 	int			cond_deasserted = 0 ;
186*4882a593Smuzhiyun 	int			event_occurred = 0 ;
187*4882a593Smuzhiyun 	int			tsr ;
188*4882a593Smuzhiyun 	int			T_Limit = 2*TICKS_PER_SECOND ;
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 	if (code == SMT_COND_MAC_DUP_ADDR && cond) {
191*4882a593Smuzhiyun 		RS_SET(smc,RS_DUPADDR) ;
192*4882a593Smuzhiyun 	}
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun 	if (code) {
195*4882a593Smuzhiyun 		DB_SMT("SRF: %s index %d", srf_names[code], index);
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 		if (!(evc = smt_get_evc(smc,code,index))) {
198*4882a593Smuzhiyun 			DB_SMT("SRF : smt_get_evc() failed");
199*4882a593Smuzhiyun 			return ;
200*4882a593Smuzhiyun 		}
201*4882a593Smuzhiyun 		/*
202*4882a593Smuzhiyun 		 * ignore condition if no change
203*4882a593Smuzhiyun 		 */
204*4882a593Smuzhiyun 		if (SMT_IS_CONDITION(code)) {
205*4882a593Smuzhiyun 			if (*evc->evc_cond_state == cond)
206*4882a593Smuzhiyun 				return ;
207*4882a593Smuzhiyun 		}
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun 		/*
210*4882a593Smuzhiyun 		 * set transition time stamp
211*4882a593Smuzhiyun 		 */
212*4882a593Smuzhiyun 		smt_set_timestamp(smc,smc->mib.fddiSMTTransitionTimeStamp) ;
213*4882a593Smuzhiyun 		if (SMT_IS_CONDITION(code)) {
214*4882a593Smuzhiyun 			DB_SMT("SRF: condition is %s", cond ? "ON" : "OFF");
215*4882a593Smuzhiyun 			if (cond) {
216*4882a593Smuzhiyun 				*evc->evc_cond_state = TRUE ;
217*4882a593Smuzhiyun 				evc->evc_rep_required = TRUE ;
218*4882a593Smuzhiyun 				smc->srf.any_report = TRUE ;
219*4882a593Smuzhiyun 				cond_asserted = TRUE ;
220*4882a593Smuzhiyun 			}
221*4882a593Smuzhiyun 			else {
222*4882a593Smuzhiyun 				*evc->evc_cond_state = FALSE ;
223*4882a593Smuzhiyun 				cond_deasserted = TRUE ;
224*4882a593Smuzhiyun 			}
225*4882a593Smuzhiyun 		}
226*4882a593Smuzhiyun 		else {
227*4882a593Smuzhiyun 			if (evc->evc_rep_required) {
228*4882a593Smuzhiyun 				*evc->evc_multiple  = TRUE ;
229*4882a593Smuzhiyun 			}
230*4882a593Smuzhiyun 			else {
231*4882a593Smuzhiyun 				evc->evc_rep_required = TRUE ;
232*4882a593Smuzhiyun 				*evc->evc_multiple  = FALSE ;
233*4882a593Smuzhiyun 			}
234*4882a593Smuzhiyun 			smc->srf.any_report = TRUE ;
235*4882a593Smuzhiyun 			event_occurred = TRUE ;
236*4882a593Smuzhiyun 		}
237*4882a593Smuzhiyun #ifdef	FDDI_MIB
238*4882a593Smuzhiyun 		snmp_srf_event(smc,evc) ;
239*4882a593Smuzhiyun #endif	/* FDDI_MIB */
240*4882a593Smuzhiyun 	}
241*4882a593Smuzhiyun 	tsr = smt_get_time() - smc->srf.TSR ;
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun 	switch (smc->srf.sr_state) {
244*4882a593Smuzhiyun 	case SR0_WAIT :
245*4882a593Smuzhiyun 		/* SR01a */
246*4882a593Smuzhiyun 		if (cond_asserted && tsr < T_Limit) {
247*4882a593Smuzhiyun 			smc->srf.SRThreshold = THRESHOLD_2 ;
248*4882a593Smuzhiyun 			smc->srf.sr_state = SR1_HOLDOFF ;
249*4882a593Smuzhiyun 			break ;
250*4882a593Smuzhiyun 		}
251*4882a593Smuzhiyun 		/* SR01b */
252*4882a593Smuzhiyun 		if (cond_deasserted && tsr < T_Limit) {
253*4882a593Smuzhiyun 			smc->srf.sr_state = SR1_HOLDOFF ;
254*4882a593Smuzhiyun 			break ;
255*4882a593Smuzhiyun 		}
256*4882a593Smuzhiyun 		/* SR01c */
257*4882a593Smuzhiyun 		if (event_occurred && tsr < T_Limit) {
258*4882a593Smuzhiyun 			smc->srf.sr_state = SR1_HOLDOFF ;
259*4882a593Smuzhiyun 			break ;
260*4882a593Smuzhiyun 		}
261*4882a593Smuzhiyun 		/* SR00b */
262*4882a593Smuzhiyun 		if (cond_asserted && tsr >= T_Limit) {
263*4882a593Smuzhiyun 			smc->srf.SRThreshold = THRESHOLD_2 ;
264*4882a593Smuzhiyun 			smc->srf.TSR = smt_get_time() ;
265*4882a593Smuzhiyun 			smt_send_srf(smc) ;
266*4882a593Smuzhiyun 			break ;
267*4882a593Smuzhiyun 		}
268*4882a593Smuzhiyun 		/* SR00c */
269*4882a593Smuzhiyun 		if (cond_deasserted && tsr >= T_Limit) {
270*4882a593Smuzhiyun 			smc->srf.TSR = smt_get_time() ;
271*4882a593Smuzhiyun 			smt_send_srf(smc) ;
272*4882a593Smuzhiyun 			break ;
273*4882a593Smuzhiyun 		}
274*4882a593Smuzhiyun 		/* SR00d */
275*4882a593Smuzhiyun 		if (event_occurred && tsr >= T_Limit) {
276*4882a593Smuzhiyun 			smc->srf.TSR = smt_get_time() ;
277*4882a593Smuzhiyun 			smt_send_srf(smc) ;
278*4882a593Smuzhiyun 			break ;
279*4882a593Smuzhiyun 		}
280*4882a593Smuzhiyun 		/* SR00e */
281*4882a593Smuzhiyun 		if (smc->srf.any_report && (u_long) tsr >=
282*4882a593Smuzhiyun 			smc->srf.SRThreshold) {
283*4882a593Smuzhiyun 			smc->srf.SRThreshold *= 2 ;
284*4882a593Smuzhiyun 			if (smc->srf.SRThreshold > THRESHOLD_32)
285*4882a593Smuzhiyun 				smc->srf.SRThreshold = THRESHOLD_32 ;
286*4882a593Smuzhiyun 			smc->srf.TSR = smt_get_time() ;
287*4882a593Smuzhiyun 			smt_send_srf(smc) ;
288*4882a593Smuzhiyun 			break ;
289*4882a593Smuzhiyun 		}
290*4882a593Smuzhiyun 		/* SR02 */
291*4882a593Smuzhiyun 		if (!smc->mib.fddiSMTStatRptPolicy) {
292*4882a593Smuzhiyun 			smc->srf.sr_state = SR2_DISABLED ;
293*4882a593Smuzhiyun 			break ;
294*4882a593Smuzhiyun 		}
295*4882a593Smuzhiyun 		break ;
296*4882a593Smuzhiyun 	case SR1_HOLDOFF :
297*4882a593Smuzhiyun 		/* SR10b */
298*4882a593Smuzhiyun 		if (tsr >= T_Limit) {
299*4882a593Smuzhiyun 			smc->srf.sr_state = SR0_WAIT ;
300*4882a593Smuzhiyun 			smc->srf.TSR = smt_get_time() ;
301*4882a593Smuzhiyun 			smt_send_srf(smc) ;
302*4882a593Smuzhiyun 			break ;
303*4882a593Smuzhiyun 		}
304*4882a593Smuzhiyun 		/* SR11a */
305*4882a593Smuzhiyun 		if (cond_asserted) {
306*4882a593Smuzhiyun 			smc->srf.SRThreshold = THRESHOLD_2 ;
307*4882a593Smuzhiyun 		}
308*4882a593Smuzhiyun 		/* SR11b */
309*4882a593Smuzhiyun 		/* SR11c */
310*4882a593Smuzhiyun 		/* handled above */
311*4882a593Smuzhiyun 		/* SR12 */
312*4882a593Smuzhiyun 		if (!smc->mib.fddiSMTStatRptPolicy) {
313*4882a593Smuzhiyun 			smc->srf.sr_state = SR2_DISABLED ;
314*4882a593Smuzhiyun 			break ;
315*4882a593Smuzhiyun 		}
316*4882a593Smuzhiyun 		break ;
317*4882a593Smuzhiyun 	case SR2_DISABLED :
318*4882a593Smuzhiyun 		if (smc->mib.fddiSMTStatRptPolicy) {
319*4882a593Smuzhiyun 			smc->srf.sr_state = SR0_WAIT ;
320*4882a593Smuzhiyun 			smc->srf.TSR = smt_get_time() ;
321*4882a593Smuzhiyun 			smc->srf.SRThreshold = THRESHOLD_2 ;
322*4882a593Smuzhiyun 			clear_all_rep(smc) ;
323*4882a593Smuzhiyun 			break ;
324*4882a593Smuzhiyun 		}
325*4882a593Smuzhiyun 		break ;
326*4882a593Smuzhiyun 	}
327*4882a593Smuzhiyun }
328*4882a593Smuzhiyun 
clear_all_rep(struct s_smc * smc)329*4882a593Smuzhiyun static void clear_all_rep(struct s_smc *smc)
330*4882a593Smuzhiyun {
331*4882a593Smuzhiyun 	struct s_srf_evc	*evc ;
332*4882a593Smuzhiyun 	unsigned int		i ;
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun 	for (i = 0, evc = smc->evcs ; i < MAX_EVCS ; i++, evc++) {
335*4882a593Smuzhiyun 		evc->evc_rep_required = FALSE ;
336*4882a593Smuzhiyun 		if (SMT_IS_CONDITION(evc->evc_code))
337*4882a593Smuzhiyun 			*evc->evc_cond_state = FALSE ;
338*4882a593Smuzhiyun 	}
339*4882a593Smuzhiyun 	smc->srf.any_report = FALSE ;
340*4882a593Smuzhiyun }
341*4882a593Smuzhiyun 
clear_reported(struct s_smc * smc)342*4882a593Smuzhiyun static void clear_reported(struct s_smc *smc)
343*4882a593Smuzhiyun {
344*4882a593Smuzhiyun 	struct s_srf_evc	*evc ;
345*4882a593Smuzhiyun 	unsigned int		i ;
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun 	smc->srf.any_report = FALSE ;
348*4882a593Smuzhiyun 	for (i = 0, evc = smc->evcs ; i < MAX_EVCS ; i++, evc++) {
349*4882a593Smuzhiyun 		if (SMT_IS_CONDITION(evc->evc_code)) {
350*4882a593Smuzhiyun 			if (*evc->evc_cond_state == FALSE)
351*4882a593Smuzhiyun 				evc->evc_rep_required = FALSE ;
352*4882a593Smuzhiyun 			else
353*4882a593Smuzhiyun 				smc->srf.any_report = TRUE ;
354*4882a593Smuzhiyun 		}
355*4882a593Smuzhiyun 		else {
356*4882a593Smuzhiyun 			evc->evc_rep_required = FALSE ;
357*4882a593Smuzhiyun 			*evc->evc_multiple = FALSE ;
358*4882a593Smuzhiyun 		}
359*4882a593Smuzhiyun 	}
360*4882a593Smuzhiyun }
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun /*
363*4882a593Smuzhiyun  * build and send SMT SRF frame
364*4882a593Smuzhiyun  */
smt_send_srf(struct s_smc * smc)365*4882a593Smuzhiyun static void smt_send_srf(struct s_smc *smc)
366*4882a593Smuzhiyun {
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun 	struct smt_header	*smt ;
369*4882a593Smuzhiyun 	struct s_srf_evc	*evc ;
370*4882a593Smuzhiyun 	SK_LOC_DECL(struct s_pcon,pcon) ;
371*4882a593Smuzhiyun 	SMbuf			*mb ;
372*4882a593Smuzhiyun 	unsigned int		i ;
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun 	static const struct fddi_addr SMT_SRF_DA = {
375*4882a593Smuzhiyun 		{ 0x80, 0x01, 0x43, 0x00, 0x80, 0x08 }
376*4882a593Smuzhiyun 	} ;
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun 	/*
379*4882a593Smuzhiyun 	 * build SMT header
380*4882a593Smuzhiyun 	 */
381*4882a593Smuzhiyun 	if (!smc->r.sm_ma_avail)
382*4882a593Smuzhiyun 		return ;
383*4882a593Smuzhiyun 	if (!(mb = smt_build_frame(smc,SMT_SRF,SMT_ANNOUNCE,0)))
384*4882a593Smuzhiyun 		return ;
385*4882a593Smuzhiyun 
386*4882a593Smuzhiyun 	RS_SET(smc,RS_SOFTERROR) ;
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun 	smt = smtod(mb, struct smt_header *) ;
389*4882a593Smuzhiyun 	smt->smt_dest = SMT_SRF_DA ;		/* DA == SRF multicast */
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun 	/*
392*4882a593Smuzhiyun 	 * setup parameter status
393*4882a593Smuzhiyun 	 */
394*4882a593Smuzhiyun 	pcon.pc_len = SMT_MAX_INFO_LEN ;	/* max para length */
395*4882a593Smuzhiyun 	pcon.pc_err = 0 ;			/* no error */
396*4882a593Smuzhiyun 	pcon.pc_badset = 0 ;			/* no bad set count */
397*4882a593Smuzhiyun 	pcon.pc_p = (void *) (smt + 1) ;	/* paras start here */
398*4882a593Smuzhiyun 
399*4882a593Smuzhiyun 	smt_add_para(smc,&pcon,(u_short) SMT_P1033,0,0) ;
400*4882a593Smuzhiyun 	smt_add_para(smc,&pcon,(u_short) SMT_P1034,0,0) ;
401*4882a593Smuzhiyun 
402*4882a593Smuzhiyun 	for (i = 0, evc = smc->evcs ; i < MAX_EVCS ; i++, evc++) {
403*4882a593Smuzhiyun 		if (evc->evc_rep_required) {
404*4882a593Smuzhiyun 			smt_add_para(smc,&pcon,evc->evc_para,
405*4882a593Smuzhiyun 				(int)evc->evc_index,0) ;
406*4882a593Smuzhiyun 		}
407*4882a593Smuzhiyun 	}
408*4882a593Smuzhiyun 	smt->smt_len = SMT_MAX_INFO_LEN - pcon.pc_len ;
409*4882a593Smuzhiyun 	mb->sm_len = smt->smt_len + sizeof(struct smt_header) ;
410*4882a593Smuzhiyun 
411*4882a593Smuzhiyun 	DB_SMT("SRF: sending SRF at %p, len %d", smt, mb->sm_len);
412*4882a593Smuzhiyun 	DB_SMT("SRF: state SR%d Threshold %lu",
413*4882a593Smuzhiyun 	       smc->srf.sr_state, smc->srf.SRThreshold / TICKS_PER_SECOND);
414*4882a593Smuzhiyun #ifdef	DEBUG
415*4882a593Smuzhiyun 	dump_smt(smc,smt,"SRF Send") ;
416*4882a593Smuzhiyun #endif
417*4882a593Smuzhiyun 	smt_send_frame(smc,mb,FC_SMT_INFO,0) ;
418*4882a593Smuzhiyun 	clear_reported(smc) ;
419*4882a593Smuzhiyun }
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun #endif	/* no BOOT */
422*4882a593Smuzhiyun #endif	/* no SLIM_SMT */
423*4882a593Smuzhiyun 
424