0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include "h/types.h"
0019 #include "h/fddi.h"
0020 #include "h/smc.h"
0021 #include "h/smt_p.h"
0022
0023 #define KERNEL
0024 #include "h/smtstate.h"
0025
0026 #ifndef SLIM_SMT
0027 #ifndef BOOT
0028
0029
0030
0031
0032 static void clear_all_rep(struct s_smc *smc);
0033 static void clear_reported(struct s_smc *smc);
0034 static void smt_send_srf(struct s_smc *smc);
0035 static struct s_srf_evc *smt_get_evc(struct s_smc *smc, int code, int index);
0036
0037 #define MAX_EVCS ARRAY_SIZE(smc->evcs)
0038
0039 struct evc_init {
0040 u_char code ;
0041 u_char index ;
0042 u_char n ;
0043 u_short para ;
0044 } ;
0045
0046 static const struct evc_init evc_inits[] = {
0047 { SMT_COND_SMT_PEER_WRAP, 0,1,SMT_P1048 } ,
0048
0049 { SMT_COND_MAC_DUP_ADDR, INDEX_MAC, NUMMACS,SMT_P208C } ,
0050 { SMT_COND_MAC_FRAME_ERROR, INDEX_MAC, NUMMACS,SMT_P208D } ,
0051 { SMT_COND_MAC_NOT_COPIED, INDEX_MAC, NUMMACS,SMT_P208E } ,
0052 { SMT_EVENT_MAC_NEIGHBOR_CHANGE, INDEX_MAC, NUMMACS,SMT_P208F } ,
0053 { SMT_EVENT_MAC_PATH_CHANGE, INDEX_MAC, NUMMACS,SMT_P2090 } ,
0054
0055 { SMT_COND_PORT_LER, INDEX_PORT,NUMPHYS,SMT_P4050 } ,
0056 { SMT_COND_PORT_EB_ERROR, INDEX_PORT,NUMPHYS,SMT_P4052 } ,
0057 { SMT_EVENT_PORT_CONNECTION, INDEX_PORT,NUMPHYS,SMT_P4051 } ,
0058 { SMT_EVENT_PORT_PATH_CHANGE, INDEX_PORT,NUMPHYS,SMT_P4053 } ,
0059 } ;
0060
0061 #define MAX_INIT_EVC ARRAY_SIZE(evc_inits)
0062
0063 void smt_init_evc(struct s_smc *smc)
0064 {
0065 struct s_srf_evc *evc ;
0066 const struct evc_init *init ;
0067 unsigned int i ;
0068 int index ;
0069 int offset ;
0070
0071 static u_char fail_safe = FALSE ;
0072
0073 memset((char *)smc->evcs,0,sizeof(smc->evcs)) ;
0074
0075 evc = smc->evcs ;
0076 init = evc_inits ;
0077
0078 for (i = 0 ; i < MAX_INIT_EVC ; i++) {
0079 for (index = 0 ; index < init->n ; index++) {
0080 evc->evc_code = init->code ;
0081 evc->evc_para = init->para ;
0082 evc->evc_index = init->index + index ;
0083 #ifndef DEBUG
0084 evc->evc_multiple = &fail_safe ;
0085 evc->evc_cond_state = &fail_safe ;
0086 #endif
0087 evc++ ;
0088 }
0089 init++ ;
0090 }
0091
0092 if ((unsigned int) (evc - smc->evcs) > MAX_EVCS) {
0093 SMT_PANIC(smc,SMT_E0127, SMT_E0127_MSG) ;
0094 }
0095
0096
0097
0098
0099 smc->evcs[0].evc_cond_state = &smc->mib.fddiSMTPeerWrapFlag ;
0100 smc->evcs[1].evc_cond_state =
0101 &smc->mib.m[MAC0].fddiMACDuplicateAddressCond ;
0102 smc->evcs[2].evc_cond_state =
0103 &smc->mib.m[MAC0].fddiMACFrameErrorFlag ;
0104 smc->evcs[3].evc_cond_state =
0105 &smc->mib.m[MAC0].fddiMACNotCopiedFlag ;
0106
0107
0108
0109
0110 smc->evcs[4].evc_multiple = &smc->mib.m[MAC0].fddiMACMultiple_N ;
0111 smc->evcs[5].evc_multiple = &smc->mib.m[MAC0].fddiMACMultiple_P ;
0112
0113 offset = 6 ;
0114 for (i = 0 ; i < NUMPHYS ; i++) {
0115
0116
0117
0118 smc->evcs[offset + 0*NUMPHYS].evc_cond_state =
0119 &smc->mib.p[i].fddiPORTLerFlag ;
0120 smc->evcs[offset + 1*NUMPHYS].evc_cond_state =
0121 &smc->mib.p[i].fddiPORTEB_Condition ;
0122
0123
0124
0125
0126 smc->evcs[offset + 2*NUMPHYS].evc_multiple =
0127 &smc->mib.p[i].fddiPORTMultiple_U ;
0128 smc->evcs[offset + 3*NUMPHYS].evc_multiple =
0129 &smc->mib.p[i].fddiPORTMultiple_P ;
0130 offset++ ;
0131 }
0132 #ifdef DEBUG
0133 for (i = 0, evc = smc->evcs ; i < MAX_EVCS ; i++, evc++) {
0134 if (SMT_IS_CONDITION(evc->evc_code)) {
0135 if (!evc->evc_cond_state) {
0136 SMT_PANIC(smc,SMT_E0128, SMT_E0128_MSG) ;
0137 }
0138 evc->evc_multiple = &fail_safe ;
0139 }
0140 else {
0141 if (!evc->evc_multiple) {
0142 SMT_PANIC(smc,SMT_E0129, SMT_E0129_MSG) ;
0143 }
0144 evc->evc_cond_state = &fail_safe ;
0145 }
0146 }
0147 #endif
0148 smc->srf.TSR = smt_get_time() ;
0149 smc->srf.sr_state = SR0_WAIT ;
0150 }
0151
0152 static struct s_srf_evc *smt_get_evc(struct s_smc *smc, int code, int index)
0153 {
0154 unsigned int i ;
0155 struct s_srf_evc *evc ;
0156
0157 for (i = 0, evc = smc->evcs ; i < MAX_EVCS ; i++, evc++) {
0158 if (evc->evc_code == code && evc->evc_index == index)
0159 return evc;
0160 }
0161 return NULL;
0162 }
0163
0164 #define THRESHOLD_2 (2*TICKS_PER_SECOND)
0165 #define THRESHOLD_32 (32*TICKS_PER_SECOND)
0166
0167 static const char * const srf_names[] = {
0168 "None","MACPathChangeEvent", "MACNeighborChangeEvent",
0169 "PORTPathChangeEvent", "PORTUndesiredConnectionAttemptEvent",
0170 "SMTPeerWrapCondition", "SMTHoldCondition",
0171 "MACFrameErrorCondition", "MACDuplicateAddressCondition",
0172 "MACNotCopiedCondition", "PORTEBErrorCondition",
0173 "PORTLerCondition"
0174 } ;
0175
0176 void smt_srf_event(struct s_smc *smc, int code, int index, int cond)
0177 {
0178 struct s_srf_evc *evc ;
0179 int cond_asserted = 0 ;
0180 int cond_deasserted = 0 ;
0181 int event_occurred = 0 ;
0182 int tsr ;
0183 int T_Limit = 2*TICKS_PER_SECOND ;
0184
0185 if (code == SMT_COND_MAC_DUP_ADDR && cond) {
0186 RS_SET(smc,RS_DUPADDR) ;
0187 }
0188
0189 if (code) {
0190 DB_SMT("SRF: %s index %d", srf_names[code], index);
0191
0192 if (!(evc = smt_get_evc(smc,code,index))) {
0193 DB_SMT("SRF : smt_get_evc() failed");
0194 return ;
0195 }
0196
0197
0198
0199 if (SMT_IS_CONDITION(code)) {
0200 if (*evc->evc_cond_state == cond)
0201 return ;
0202 }
0203
0204
0205
0206
0207 smt_set_timestamp(smc,smc->mib.fddiSMTTransitionTimeStamp) ;
0208 if (SMT_IS_CONDITION(code)) {
0209 DB_SMT("SRF: condition is %s", cond ? "ON" : "OFF");
0210 if (cond) {
0211 *evc->evc_cond_state = TRUE ;
0212 evc->evc_rep_required = TRUE ;
0213 smc->srf.any_report = TRUE ;
0214 cond_asserted = TRUE ;
0215 }
0216 else {
0217 *evc->evc_cond_state = FALSE ;
0218 cond_deasserted = TRUE ;
0219 }
0220 }
0221 else {
0222 if (evc->evc_rep_required) {
0223 *evc->evc_multiple = TRUE ;
0224 }
0225 else {
0226 evc->evc_rep_required = TRUE ;
0227 *evc->evc_multiple = FALSE ;
0228 }
0229 smc->srf.any_report = TRUE ;
0230 event_occurred = TRUE ;
0231 }
0232 #ifdef FDDI_MIB
0233 snmp_srf_event(smc,evc) ;
0234 #endif
0235 }
0236 tsr = smt_get_time() - smc->srf.TSR ;
0237
0238 switch (smc->srf.sr_state) {
0239 case SR0_WAIT :
0240
0241 if (cond_asserted && tsr < T_Limit) {
0242 smc->srf.SRThreshold = THRESHOLD_2 ;
0243 smc->srf.sr_state = SR1_HOLDOFF ;
0244 break ;
0245 }
0246
0247 if (cond_deasserted && tsr < T_Limit) {
0248 smc->srf.sr_state = SR1_HOLDOFF ;
0249 break ;
0250 }
0251
0252 if (event_occurred && tsr < T_Limit) {
0253 smc->srf.sr_state = SR1_HOLDOFF ;
0254 break ;
0255 }
0256
0257 if (cond_asserted && tsr >= T_Limit) {
0258 smc->srf.SRThreshold = THRESHOLD_2 ;
0259 smc->srf.TSR = smt_get_time() ;
0260 smt_send_srf(smc) ;
0261 break ;
0262 }
0263
0264 if (cond_deasserted && tsr >= T_Limit) {
0265 smc->srf.TSR = smt_get_time() ;
0266 smt_send_srf(smc) ;
0267 break ;
0268 }
0269
0270 if (event_occurred && tsr >= T_Limit) {
0271 smc->srf.TSR = smt_get_time() ;
0272 smt_send_srf(smc) ;
0273 break ;
0274 }
0275
0276 if (smc->srf.any_report && (u_long) tsr >=
0277 smc->srf.SRThreshold) {
0278 smc->srf.SRThreshold *= 2 ;
0279 if (smc->srf.SRThreshold > THRESHOLD_32)
0280 smc->srf.SRThreshold = THRESHOLD_32 ;
0281 smc->srf.TSR = smt_get_time() ;
0282 smt_send_srf(smc) ;
0283 break ;
0284 }
0285
0286 if (!smc->mib.fddiSMTStatRptPolicy) {
0287 smc->srf.sr_state = SR2_DISABLED ;
0288 break ;
0289 }
0290 break ;
0291 case SR1_HOLDOFF :
0292
0293 if (tsr >= T_Limit) {
0294 smc->srf.sr_state = SR0_WAIT ;
0295 smc->srf.TSR = smt_get_time() ;
0296 smt_send_srf(smc) ;
0297 break ;
0298 }
0299
0300 if (cond_asserted) {
0301 smc->srf.SRThreshold = THRESHOLD_2 ;
0302 }
0303
0304
0305
0306
0307 if (!smc->mib.fddiSMTStatRptPolicy) {
0308 smc->srf.sr_state = SR2_DISABLED ;
0309 break ;
0310 }
0311 break ;
0312 case SR2_DISABLED :
0313 if (smc->mib.fddiSMTStatRptPolicy) {
0314 smc->srf.sr_state = SR0_WAIT ;
0315 smc->srf.TSR = smt_get_time() ;
0316 smc->srf.SRThreshold = THRESHOLD_2 ;
0317 clear_all_rep(smc) ;
0318 break ;
0319 }
0320 break ;
0321 }
0322 }
0323
0324 static void clear_all_rep(struct s_smc *smc)
0325 {
0326 struct s_srf_evc *evc ;
0327 unsigned int i ;
0328
0329 for (i = 0, evc = smc->evcs ; i < MAX_EVCS ; i++, evc++) {
0330 evc->evc_rep_required = FALSE ;
0331 if (SMT_IS_CONDITION(evc->evc_code))
0332 *evc->evc_cond_state = FALSE ;
0333 }
0334 smc->srf.any_report = FALSE ;
0335 }
0336
0337 static void clear_reported(struct s_smc *smc)
0338 {
0339 struct s_srf_evc *evc ;
0340 unsigned int i ;
0341
0342 smc->srf.any_report = FALSE ;
0343 for (i = 0, evc = smc->evcs ; i < MAX_EVCS ; i++, evc++) {
0344 if (SMT_IS_CONDITION(evc->evc_code)) {
0345 if (*evc->evc_cond_state == FALSE)
0346 evc->evc_rep_required = FALSE ;
0347 else
0348 smc->srf.any_report = TRUE ;
0349 }
0350 else {
0351 evc->evc_rep_required = FALSE ;
0352 *evc->evc_multiple = FALSE ;
0353 }
0354 }
0355 }
0356
0357
0358
0359
0360 static void smt_send_srf(struct s_smc *smc)
0361 {
0362
0363 struct smt_header *smt ;
0364 struct s_srf_evc *evc ;
0365 SK_LOC_DECL(struct s_pcon,pcon) ;
0366 SMbuf *mb ;
0367 unsigned int i ;
0368
0369 static const struct fddi_addr SMT_SRF_DA = {
0370 { 0x80, 0x01, 0x43, 0x00, 0x80, 0x08 }
0371 } ;
0372
0373
0374
0375
0376 if (!smc->r.sm_ma_avail)
0377 return ;
0378 if (!(mb = smt_build_frame(smc,SMT_SRF,SMT_ANNOUNCE,0)))
0379 return ;
0380
0381 RS_SET(smc,RS_SOFTERROR) ;
0382
0383 smt = smtod(mb, struct smt_header *) ;
0384 smt->smt_dest = SMT_SRF_DA ;
0385
0386
0387
0388
0389 pcon.pc_len = SMT_MAX_INFO_LEN ;
0390 pcon.pc_err = 0 ;
0391 pcon.pc_badset = 0 ;
0392 pcon.pc_p = (void *) (smt + 1) ;
0393
0394 smt_add_para(smc,&pcon,(u_short) SMT_P1033,0,0) ;
0395 smt_add_para(smc,&pcon,(u_short) SMT_P1034,0,0) ;
0396
0397 for (i = 0, evc = smc->evcs ; i < MAX_EVCS ; i++, evc++) {
0398 if (evc->evc_rep_required) {
0399 smt_add_para(smc,&pcon,evc->evc_para,
0400 (int)evc->evc_index,0) ;
0401 }
0402 }
0403 smt->smt_len = SMT_MAX_INFO_LEN - pcon.pc_len ;
0404 mb->sm_len = smt->smt_len + sizeof(struct smt_header) ;
0405
0406 DB_SMT("SRF: sending SRF at %p, len %d", smt, mb->sm_len);
0407 DB_SMT("SRF: state SR%d Threshold %lu",
0408 smc->srf.sr_state, smc->srf.SRThreshold / TICKS_PER_SECOND);
0409 #ifdef DEBUG
0410 dump_smt(smc,smt,"SRF Send") ;
0411 #endif
0412 smt_send_frame(smc,mb,FC_SMT_INFO,0) ;
0413 clear_reported(smc) ;
0414 }
0415
0416 #endif
0417 #endif
0418