Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) }