root/drivers/net/fddi/skfp/srf.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. smt_init_evc
  2. smt_get_evc
  3. smt_srf_event
  4. clear_all_rep
  5. clear_reported
  6. smt_send_srf

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

/* [<][>][^][v][top][bottom][index][help] */