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