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

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

DEFINITIONS

This source file includes following definitions.
  1. cfm_init
  2. selection_criteria
  3. all_selection_criteria
  4. cem_priv_state
  5. cfm
  6. cfm_fsm
  7. cfm_get_mac_input
  8. cfm_get_mac_output
  9. cem_build_path

   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 CFM
  15         Configuration Management
  16         DAS with single MAC
  17 */
  18 
  19 /*
  20  *      Hardware independent state machine implemantation
  21  *      The following external SMT functions are referenced :
  22  *
  23  *              queue_event()
  24  *
  25  *      The following external HW dependent functions are referenced :
  26  *              config_mux()
  27  *
  28  *      The following HW dependent events are required :
  29  *              NONE 
  30  */
  31 
  32 #include "h/types.h"
  33 #include "h/fddi.h"
  34 #include "h/smc.h"
  35 
  36 #define KERNEL
  37 #include "h/smtstate.h"
  38 
  39 #ifndef lint
  40 static const char ID_sccs[] = "@(#)cfm.c        2.18 98/10/06 (C) SK " ;
  41 #endif
  42 
  43 /*
  44  * FSM Macros
  45  */
  46 #define AFLAG   0x10
  47 #define GO_STATE(x)     (smc->mib.fddiSMTCF_State = (x)|AFLAG)
  48 #define ACTIONS_DONE()  (smc->mib.fddiSMTCF_State &= ~AFLAG)
  49 #define ACTIONS(x)      (x|AFLAG)
  50 
  51 /*
  52  * symbolic state names
  53  */
  54 static const char * const cfm_states[] = {
  55         "SC0_ISOLATED","CF1","CF2","CF3","CF4",
  56         "SC1_WRAP_A","SC2_WRAP_B","SC5_TRHU_B","SC7_WRAP_S",
  57         "SC9_C_WRAP_A","SC10_C_WRAP_B","SC11_C_WRAP_S","SC4_THRU_A"
  58 } ;
  59 
  60 /*
  61  * symbolic event names
  62  */
  63 static const char * const cfm_events[] = {
  64         "NONE","CF_LOOP_A","CF_LOOP_B","CF_JOIN_A","CF_JOIN_B"
  65 } ;
  66 
  67 /*
  68  * map from state to downstream port type
  69  */
  70 static const unsigned char cf_to_ptype[] = {
  71         TNONE,TNONE,TNONE,TNONE,TNONE,
  72         TNONE,TB,TB,TS,
  73         TA,TB,TS,TB
  74 } ;
  75 
  76 /*
  77  * CEM port states
  78  */
  79 #define CEM_PST_DOWN    0
  80 #define CEM_PST_UP      1
  81 #define CEM_PST_HOLD    2
  82 /* define portstate array only for A and B port */
  83 /* Do this within the smc structure (use in multiple cards) */
  84 
  85 /*
  86  * all Globals  are defined in smc.h
  87  * struct s_cfm
  88  */
  89 
  90 /*
  91  * function declarations
  92  */
  93 static void cfm_fsm(struct s_smc *smc, int cmd);
  94 
  95 /*
  96         init CFM state machine
  97         clear all CFM vars and flags
  98 */
  99 void cfm_init(struct s_smc *smc)
 100 {
 101         smc->mib.fddiSMTCF_State = ACTIONS(SC0_ISOLATED) ;
 102         smc->r.rm_join = 0 ;
 103         smc->r.rm_loop = 0 ;
 104         smc->y[PA].scrub = 0 ;
 105         smc->y[PB].scrub = 0 ;
 106         smc->y[PA].cem_pst = CEM_PST_DOWN ;
 107         smc->y[PB].cem_pst = CEM_PST_DOWN ;
 108 }
 109 
 110 /* Some terms conditions used by the selection criteria */
 111 #define THRU_ENABLED(smc)       (smc->y[PA].pc_mode != PM_TREE && \
 112                                  smc->y[PB].pc_mode != PM_TREE)
 113 /* Selection criteria for the ports */
 114 static void selection_criteria (struct s_smc *smc, struct s_phy *phy)
 115 {
 116 
 117         switch (phy->mib->fddiPORTMy_Type) {
 118         case TA:
 119                 if ( !THRU_ENABLED(smc) && smc->y[PB].cf_join ) {
 120                         phy->wc_flag = TRUE ;
 121                 } else {
 122                         phy->wc_flag = FALSE ;
 123                 }
 124 
 125                 break;
 126         case TB:
 127                 /* take precedence over PA */
 128                 phy->wc_flag = FALSE ;
 129                 break;
 130         case TS:
 131                 phy->wc_flag = FALSE ;
 132                 break;
 133         case TM:
 134                 phy->wc_flag = FALSE ;
 135                 break;
 136         }
 137 
 138 }
 139 
 140 void all_selection_criteria(struct s_smc *smc)
 141 {
 142         struct s_phy    *phy ;
 143         int             p ;
 144 
 145         for ( p = 0,phy = smc->y ; p < NUMPHYS; p++, phy++ ) {
 146                 /* Do the selection criteria */
 147                 selection_criteria (smc,phy);
 148         }
 149 }
 150 
 151 static void cem_priv_state(struct s_smc *smc, int event)
 152 /* State machine for private PORT states: used to optimize dual homing */
 153 {
 154         int     np;     /* Number of the port */
 155         int     i;
 156 
 157         /* Do this only in a DAS */
 158         if (smc->s.sas != SMT_DAS )
 159                 return ;
 160 
 161         np = event - CF_JOIN;
 162 
 163         if (np != PA && np != PB) {
 164                 return ;
 165         }
 166         /* Change the port state according to the event (portnumber) */
 167         if (smc->y[np].cf_join) {
 168                 smc->y[np].cem_pst = CEM_PST_UP ;
 169         } else if (!smc->y[np].wc_flag) {
 170                 /* set the port to done only if it is not withheld */
 171                 smc->y[np].cem_pst = CEM_PST_DOWN ;
 172         }
 173 
 174         /* Don't set an hold port to down */
 175 
 176         /* Check all ports of restart conditions */
 177         for (i = 0 ; i < 2 ; i ++ ) {
 178                 /* Check all port for PORT is on hold and no withhold is done */
 179                 if ( smc->y[i].cem_pst == CEM_PST_HOLD && !smc->y[i].wc_flag ) {
 180                         smc->y[i].cem_pst = CEM_PST_DOWN;
 181                         queue_event(smc,(int)(EVENT_PCM+i),PC_START) ;
 182                 }
 183                 if ( smc->y[i].cem_pst == CEM_PST_UP && smc->y[i].wc_flag ) {
 184                         smc->y[i].cem_pst = CEM_PST_HOLD;
 185                         queue_event(smc,(int)(EVENT_PCM+i),PC_START) ;
 186                 }
 187                 if ( smc->y[i].cem_pst == CEM_PST_DOWN && smc->y[i].wc_flag ) {
 188                         /*
 189                          * The port must be restarted when the wc_flag
 190                          * will be reset. So set the port on hold.
 191                          */
 192                         smc->y[i].cem_pst = CEM_PST_HOLD;
 193                 }
 194         }
 195         return ;
 196 }
 197 
 198 /*
 199         CFM state machine
 200         called by dispatcher
 201 
 202         do
 203                 display state change
 204                 process event
 205         until SM is stable
 206 */
 207 void cfm(struct s_smc *smc, int event)
 208 {
 209         int     state ;         /* remember last state */
 210         int     cond ;
 211         int     oldstate ;
 212 
 213         /* We will do the following: */
 214         /*  - compute the variable WC_Flag for every port (This is where */
 215         /*    we can extend the requested path checking !!) */
 216         /*  - do the old (SMT 6.2 like) state machine */
 217         /*  - do the resulting station states */
 218 
 219         all_selection_criteria (smc);
 220 
 221         /* We will check now whether a state transition is allowed or not */
 222         /*  - change the portstates */
 223         cem_priv_state (smc, event);
 224 
 225         oldstate = smc->mib.fddiSMTCF_State ;
 226         do {
 227                 DB_CFM("CFM : state %s%s event %s",
 228                        smc->mib.fddiSMTCF_State & AFLAG ? "ACTIONS " : "",
 229                        cfm_states[smc->mib.fddiSMTCF_State & ~AFLAG],
 230                        cfm_events[event]);
 231                 state = smc->mib.fddiSMTCF_State ;
 232                 cfm_fsm(smc,event) ;
 233                 event = 0 ;
 234         } while (state != smc->mib.fddiSMTCF_State) ;
 235 
 236 #ifndef SLIM_SMT
 237         /*
 238          * check peer wrap condition
 239          */
 240         cond = FALSE ;
 241         if (    (smc->mib.fddiSMTCF_State == SC9_C_WRAP_A &&
 242                 smc->y[PA].pc_mode == PM_PEER)  ||
 243                 (smc->mib.fddiSMTCF_State == SC10_C_WRAP_B &&
 244                 smc->y[PB].pc_mode == PM_PEER)  ||
 245                 (smc->mib.fddiSMTCF_State == SC11_C_WRAP_S &&
 246                 smc->y[PS].pc_mode == PM_PEER &&
 247                 smc->y[PS].mib->fddiPORTNeighborType != TS ) ) {
 248                         cond = TRUE ;
 249         }
 250         if (cond != smc->mib.fddiSMTPeerWrapFlag)
 251                 smt_srf_event(smc,SMT_COND_SMT_PEER_WRAP,0,cond) ;
 252 
 253 #if     0
 254         /*
 255          * Don't send ever MAC_PATH_CHANGE events. Our MAC is hard-wired
 256          * to the primary path.
 257          */
 258         /*
 259          * path change
 260          */
 261         if (smc->mib.fddiSMTCF_State != oldstate) {
 262                 smt_srf_event(smc,SMT_EVENT_MAC_PATH_CHANGE,INDEX_MAC,0) ;
 263         }
 264 #endif
 265 #endif  /* no SLIM_SMT */
 266 
 267         /*
 268          * set MAC port type
 269          */
 270         smc->mib.m[MAC0].fddiMACDownstreamPORTType =
 271                 cf_to_ptype[smc->mib.fddiSMTCF_State] ;
 272         cfm_state_change(smc,(int)smc->mib.fddiSMTCF_State) ;
 273 }
 274 
 275 /*
 276         process CFM event
 277 */
 278 /*ARGSUSED1*/
 279 static void cfm_fsm(struct s_smc *smc, int cmd)
 280 {
 281         switch(smc->mib.fddiSMTCF_State) {
 282         case ACTIONS(SC0_ISOLATED) :
 283                 smc->mib.p[PA].fddiPORTCurrentPath = MIB_PATH_ISOLATED ;
 284                 smc->mib.p[PB].fddiPORTCurrentPath = MIB_PATH_ISOLATED ;
 285                 smc->mib.p[PA].fddiPORTMACPlacement = 0 ;
 286                 smc->mib.p[PB].fddiPORTMACPlacement = 0 ;
 287                 smc->mib.fddiSMTStationStatus = MIB_SMT_STASTA_SEPA ;
 288                 config_mux(smc,MUX_ISOLATE) ;   /* configure PHY Mux */
 289                 smc->r.rm_loop = FALSE ;
 290                 smc->r.rm_join = FALSE ;
 291                 queue_event(smc,EVENT_RMT,RM_JOIN) ;/* signal RMT */
 292                 /* Don't do the WC-Flag changing here */
 293                 ACTIONS_DONE() ;
 294                 DB_CFMN(1, "CFM : %s", cfm_states[smc->mib.fddiSMTCF_State]);
 295                 break;
 296         case SC0_ISOLATED :
 297                 /*SC07*/
 298                 /*SAS port can be PA or PB ! */
 299                 if (smc->s.sas && (smc->y[PA].cf_join || smc->y[PA].cf_loop ||
 300                                 smc->y[PB].cf_join || smc->y[PB].cf_loop)) {
 301                         GO_STATE(SC11_C_WRAP_S) ;
 302                         break ;
 303                 }
 304                 /*SC01*/
 305                 if ((smc->y[PA].cem_pst == CEM_PST_UP && smc->y[PA].cf_join &&
 306                      !smc->y[PA].wc_flag) || smc->y[PA].cf_loop) {
 307                         GO_STATE(SC9_C_WRAP_A) ;
 308                         break ;
 309                 }
 310                 /*SC02*/
 311                 if ((smc->y[PB].cem_pst == CEM_PST_UP && smc->y[PB].cf_join &&
 312                      !smc->y[PB].wc_flag) || smc->y[PB].cf_loop) {
 313                         GO_STATE(SC10_C_WRAP_B) ;
 314                         break ;
 315                 }
 316                 break ;
 317         case ACTIONS(SC9_C_WRAP_A) :
 318                 smc->mib.p[PA].fddiPORTCurrentPath = MIB_PATH_CONCATENATED ;
 319                 smc->mib.p[PB].fddiPORTCurrentPath = MIB_PATH_ISOLATED ;
 320                 smc->mib.p[PA].fddiPORTMACPlacement = INDEX_MAC ;
 321                 smc->mib.p[PB].fddiPORTMACPlacement = 0 ;
 322                 smc->mib.fddiSMTStationStatus = MIB_SMT_STASTA_CON ;
 323                 config_mux(smc,MUX_WRAPA) ;             /* configure PHY mux */
 324                 if (smc->y[PA].cf_loop) {
 325                         smc->r.rm_join = FALSE ;
 326                         smc->r.rm_loop = TRUE ;
 327                         queue_event(smc,EVENT_RMT,RM_LOOP) ;/* signal RMT */
 328                 }
 329                 if (smc->y[PA].cf_join) {
 330                         smc->r.rm_loop = FALSE ;
 331                         smc->r.rm_join = TRUE ;
 332                         queue_event(smc,EVENT_RMT,RM_JOIN) ;/* signal RMT */
 333                 }
 334                 ACTIONS_DONE() ;
 335                 DB_CFMN(1, "CFM : %s", cfm_states[smc->mib.fddiSMTCF_State]);
 336                 break ;
 337         case SC9_C_WRAP_A :
 338                 /*SC10*/
 339                 if ( (smc->y[PA].wc_flag || !smc->y[PA].cf_join) &&
 340                       !smc->y[PA].cf_loop ) {
 341                         GO_STATE(SC0_ISOLATED) ;
 342                         break ;
 343                 }
 344                 /*SC12*/
 345                 else if ( (smc->y[PB].cf_loop && smc->y[PA].cf_join &&
 346                            smc->y[PA].cem_pst == CEM_PST_UP) ||
 347                           ((smc->y[PB].cf_loop ||
 348                            (smc->y[PB].cf_join &&
 349                             smc->y[PB].cem_pst == CEM_PST_UP)) &&
 350                             (smc->y[PA].pc_mode == PM_TREE ||
 351                              smc->y[PB].pc_mode == PM_TREE))) {
 352                         smc->y[PA].scrub = TRUE ;
 353                         GO_STATE(SC10_C_WRAP_B) ;
 354                         break ;
 355                 }
 356                 /*SC14*/
 357                 else if (!smc->s.attach_s &&
 358                           smc->y[PA].cf_join &&
 359                           smc->y[PA].cem_pst == CEM_PST_UP &&
 360                           smc->y[PA].pc_mode == PM_PEER && smc->y[PB].cf_join &&
 361                           smc->y[PB].cem_pst == CEM_PST_UP &&
 362                           smc->y[PB].pc_mode == PM_PEER) {
 363                         smc->y[PA].scrub = TRUE ;
 364                         smc->y[PB].scrub = TRUE ;
 365                         GO_STATE(SC4_THRU_A) ;
 366                         break ;
 367                 }
 368                 /*SC15*/
 369                 else if ( smc->s.attach_s &&
 370                           smc->y[PA].cf_join &&
 371                           smc->y[PA].cem_pst == CEM_PST_UP &&
 372                           smc->y[PA].pc_mode == PM_PEER &&
 373                           smc->y[PB].cf_join &&
 374                           smc->y[PB].cem_pst == CEM_PST_UP &&
 375                           smc->y[PB].pc_mode == PM_PEER) {
 376                         smc->y[PA].scrub = TRUE ;
 377                         smc->y[PB].scrub = TRUE ;
 378                         GO_STATE(SC5_THRU_B) ;
 379                         break ;
 380                 }
 381                 break ;
 382         case ACTIONS(SC10_C_WRAP_B) :
 383                 smc->mib.p[PA].fddiPORTCurrentPath = MIB_PATH_ISOLATED ;
 384                 smc->mib.p[PB].fddiPORTCurrentPath = MIB_PATH_CONCATENATED ;
 385                 smc->mib.p[PA].fddiPORTMACPlacement = 0 ;
 386                 smc->mib.p[PB].fddiPORTMACPlacement = INDEX_MAC ;
 387                 smc->mib.fddiSMTStationStatus = MIB_SMT_STASTA_CON ;
 388                 config_mux(smc,MUX_WRAPB) ;             /* configure PHY mux */
 389                 if (smc->y[PB].cf_loop) {
 390                         smc->r.rm_join = FALSE ;
 391                         smc->r.rm_loop = TRUE ;
 392                         queue_event(smc,EVENT_RMT,RM_LOOP) ;/* signal RMT */
 393                 }
 394                 if (smc->y[PB].cf_join) {
 395                         smc->r.rm_loop = FALSE ;
 396                         smc->r.rm_join = TRUE ;
 397                         queue_event(smc,EVENT_RMT,RM_JOIN) ;/* signal RMT */
 398                 }
 399                 ACTIONS_DONE() ;
 400                 DB_CFMN(1, "CFM : %s", cfm_states[smc->mib.fddiSMTCF_State]);
 401                 break ;
 402         case SC10_C_WRAP_B :
 403                 /*SC20*/
 404                 if ( !smc->y[PB].cf_join && !smc->y[PB].cf_loop ) {
 405                         GO_STATE(SC0_ISOLATED) ;
 406                         break ;
 407                 }
 408                 /*SC21*/
 409                 else if ( smc->y[PA].cf_loop && smc->y[PA].pc_mode == PM_PEER &&
 410                           smc->y[PB].cf_join && smc->y[PB].pc_mode == PM_PEER) {
 411                         smc->y[PB].scrub = TRUE ;
 412                         GO_STATE(SC9_C_WRAP_A) ;
 413                         break ;
 414                 }
 415                 /*SC24*/
 416                 else if (!smc->s.attach_s &&
 417                          smc->y[PA].cf_join && smc->y[PA].pc_mode == PM_PEER &&
 418                          smc->y[PB].cf_join && smc->y[PB].pc_mode == PM_PEER) {
 419                         smc->y[PA].scrub = TRUE ;
 420                         smc->y[PB].scrub = TRUE ;
 421                         GO_STATE(SC4_THRU_A) ;
 422                         break ;
 423                 }
 424                 /*SC25*/
 425                 else if ( smc->s.attach_s &&
 426                          smc->y[PA].cf_join && smc->y[PA].pc_mode == PM_PEER &&
 427                          smc->y[PB].cf_join && smc->y[PB].pc_mode == PM_PEER) {
 428                         smc->y[PA].scrub = TRUE ;
 429                         smc->y[PB].scrub = TRUE ;
 430                         GO_STATE(SC5_THRU_B) ;
 431                         break ;
 432                 }
 433                 break ;
 434         case ACTIONS(SC4_THRU_A) :
 435                 smc->mib.p[PA].fddiPORTCurrentPath = MIB_PATH_THRU ;
 436                 smc->mib.p[PB].fddiPORTCurrentPath = MIB_PATH_THRU ;
 437                 smc->mib.p[PA].fddiPORTMACPlacement = 0 ;
 438                 smc->mib.p[PB].fddiPORTMACPlacement = INDEX_MAC ;
 439                 smc->mib.fddiSMTStationStatus = MIB_SMT_STASTA_THRU ;
 440                 config_mux(smc,MUX_THRUA) ;             /* configure PHY mux */
 441                 smc->r.rm_loop = FALSE ;
 442                 smc->r.rm_join = TRUE ;
 443                 queue_event(smc,EVENT_RMT,RM_JOIN) ;/* signal RMT */
 444                 ACTIONS_DONE() ;
 445                 DB_CFMN(1, "CFM : %s", cfm_states[smc->mib.fddiSMTCF_State]);
 446                 break ;
 447         case SC4_THRU_A :
 448                 /*SC41*/
 449                 if (smc->y[PB].wc_flag || !smc->y[PB].cf_join) {
 450                         smc->y[PA].scrub = TRUE ;
 451                         GO_STATE(SC9_C_WRAP_A) ;
 452                         break ;
 453                 }
 454                 /*SC42*/
 455                 else if (!smc->y[PA].cf_join || smc->y[PA].wc_flag) {
 456                         smc->y[PB].scrub = TRUE ;
 457                         GO_STATE(SC10_C_WRAP_B) ;
 458                         break ;
 459                 }
 460                 /*SC45*/
 461                 else if (smc->s.attach_s) {
 462                         smc->y[PB].scrub = TRUE ;
 463                         GO_STATE(SC5_THRU_B) ;
 464                         break ;
 465                 }
 466                 break ;
 467         case ACTIONS(SC5_THRU_B) :
 468                 smc->mib.p[PA].fddiPORTCurrentPath = MIB_PATH_THRU ;
 469                 smc->mib.p[PB].fddiPORTCurrentPath = MIB_PATH_THRU ;
 470                 smc->mib.p[PA].fddiPORTMACPlacement = INDEX_MAC ;
 471                 smc->mib.p[PB].fddiPORTMACPlacement = 0 ;
 472                 smc->mib.fddiSMTStationStatus = MIB_SMT_STASTA_THRU ;
 473                 config_mux(smc,MUX_THRUB) ;             /* configure PHY mux */
 474                 smc->r.rm_loop = FALSE ;
 475                 smc->r.rm_join = TRUE ;
 476                 queue_event(smc,EVENT_RMT,RM_JOIN) ;/* signal RMT */
 477                 ACTIONS_DONE() ;
 478                 DB_CFMN(1, "CFM : %s", cfm_states[smc->mib.fddiSMTCF_State]);
 479                 break ;
 480         case SC5_THRU_B :
 481                 /*SC51*/
 482                 if (!smc->y[PB].cf_join || smc->y[PB].wc_flag) {
 483                         smc->y[PA].scrub = TRUE ;
 484                         GO_STATE(SC9_C_WRAP_A) ;
 485                         break ;
 486                 }
 487                 /*SC52*/
 488                 else if (!smc->y[PA].cf_join || smc->y[PA].wc_flag) {
 489                         smc->y[PB].scrub = TRUE ;
 490                         GO_STATE(SC10_C_WRAP_B) ;
 491                         break ;
 492                 }
 493                 /*SC54*/
 494                 else if (!smc->s.attach_s) {
 495                         smc->y[PA].scrub = TRUE ;
 496                         GO_STATE(SC4_THRU_A) ;
 497                         break ;
 498                 }
 499                 break ;
 500         case ACTIONS(SC11_C_WRAP_S) :
 501                 smc->mib.p[PS].fddiPORTCurrentPath = MIB_PATH_CONCATENATED ;
 502                 smc->mib.p[PS].fddiPORTMACPlacement = INDEX_MAC ;
 503                 smc->mib.fddiSMTStationStatus = MIB_SMT_STASTA_CON ;
 504                 config_mux(smc,MUX_WRAPS) ;             /* configure PHY mux */
 505                 if (smc->y[PA].cf_loop || smc->y[PB].cf_loop) {
 506                         smc->r.rm_join = FALSE ;
 507                         smc->r.rm_loop = TRUE ;
 508                         queue_event(smc,EVENT_RMT,RM_LOOP) ;/* signal RMT */
 509                 }
 510                 if (smc->y[PA].cf_join || smc->y[PB].cf_join) {
 511                         smc->r.rm_loop = FALSE ;
 512                         smc->r.rm_join = TRUE ;
 513                         queue_event(smc,EVENT_RMT,RM_JOIN) ;/* signal RMT */
 514                 }
 515                 ACTIONS_DONE() ;
 516                 DB_CFMN(1, "CFM : %s", cfm_states[smc->mib.fddiSMTCF_State]);
 517                 break ;
 518         case SC11_C_WRAP_S :
 519                 /*SC70*/
 520                 if ( !smc->y[PA].cf_join && !smc->y[PA].cf_loop &&
 521                      !smc->y[PB].cf_join && !smc->y[PB].cf_loop) {
 522                         GO_STATE(SC0_ISOLATED) ;
 523                         break ;
 524                 }
 525                 break ;
 526         default:
 527                 SMT_PANIC(smc,SMT_E0106, SMT_E0106_MSG) ;
 528                 break;
 529         }
 530 }
 531 
 532 /*
 533  * get MAC's input Port
 534  *      return :
 535  *              PA or PB
 536  */
 537 int cfm_get_mac_input(struct s_smc *smc)
 538 {
 539         return (smc->mib.fddiSMTCF_State == SC10_C_WRAP_B ||
 540                 smc->mib.fddiSMTCF_State == SC5_THRU_B) ? PB : PA;
 541 }
 542 
 543 /*
 544  * get MAC's output Port
 545  *      return :
 546  *              PA or PB
 547  */
 548 int cfm_get_mac_output(struct s_smc *smc)
 549 {
 550         return (smc->mib.fddiSMTCF_State == SC10_C_WRAP_B ||
 551                 smc->mib.fddiSMTCF_State == SC4_THRU_A) ? PB : PA;
 552 }
 553 
 554 static char path_iso[] = {
 555         0,0,    0,RES_PORT,     0,PA + INDEX_PORT,      0,PATH_ISO,
 556         0,0,    0,RES_MAC,      0,INDEX_MAC,            0,PATH_ISO,
 557         0,0,    0,RES_PORT,     0,PB + INDEX_PORT,      0,PATH_ISO
 558 } ;
 559 
 560 static char path_wrap_a[] = {
 561         0,0,    0,RES_PORT,     0,PA + INDEX_PORT,      0,PATH_PRIM,
 562         0,0,    0,RES_MAC,      0,INDEX_MAC,            0,PATH_PRIM,
 563         0,0,    0,RES_PORT,     0,PB + INDEX_PORT,      0,PATH_ISO
 564 } ;
 565 
 566 static char path_wrap_b[] = {
 567         0,0,    0,RES_PORT,     0,PB + INDEX_PORT,      0,PATH_PRIM,
 568         0,0,    0,RES_MAC,      0,INDEX_MAC,            0,PATH_PRIM,
 569         0,0,    0,RES_PORT,     0,PA + INDEX_PORT,      0,PATH_ISO
 570 } ;
 571 
 572 static char path_thru[] = {
 573         0,0,    0,RES_PORT,     0,PA + INDEX_PORT,      0,PATH_PRIM,
 574         0,0,    0,RES_MAC,      0,INDEX_MAC,            0,PATH_PRIM,
 575         0,0,    0,RES_PORT,     0,PB + INDEX_PORT,      0,PATH_PRIM
 576 } ;
 577 
 578 static char path_wrap_s[] = {
 579         0,0,    0,RES_PORT,     0,PS + INDEX_PORT,      0,PATH_PRIM,
 580         0,0,    0,RES_MAC,      0,INDEX_MAC,            0,PATH_PRIM,
 581 } ;
 582 
 583 static char path_iso_s[] = {
 584         0,0,    0,RES_PORT,     0,PS + INDEX_PORT,      0,PATH_ISO,
 585         0,0,    0,RES_MAC,      0,INDEX_MAC,            0,PATH_ISO,
 586 } ;
 587 
 588 int cem_build_path(struct s_smc *smc, char *to, int path_index)
 589 {
 590         char    *path ;
 591         int     len ;
 592 
 593         switch (smc->mib.fddiSMTCF_State) {
 594         default :
 595         case SC0_ISOLATED :
 596                 path = smc->s.sas ? path_iso_s : path_iso ;
 597                 len = smc->s.sas ? sizeof(path_iso_s) :  sizeof(path_iso) ;
 598                 break ;
 599         case SC9_C_WRAP_A :
 600                 path = path_wrap_a ;
 601                 len = sizeof(path_wrap_a) ;
 602                 break ;
 603         case SC10_C_WRAP_B :
 604                 path = path_wrap_b ;
 605                 len = sizeof(path_wrap_b) ;
 606                 break ;
 607         case SC4_THRU_A :
 608                 path = path_thru ;
 609                 len = sizeof(path_thru) ;
 610                 break ;
 611         case SC11_C_WRAP_S :
 612                 path = path_wrap_s ;
 613                 len = sizeof(path_wrap_s) ;
 614                 break ;
 615         }
 616         memcpy(to,path,len) ;
 617 
 618         LINT_USE(path_index);
 619 
 620         return len;
 621 }

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