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