linux/drivers/net/fddi/skfp/pcmplc.c

// SPDX-License-Identifier: GPL-2.0-or-later
/******************************************************************************
 *
 *	(C)Copyright 1998,1999 SysKonnect,
 *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
 *
 *	See the file "skfddi.c" for further information.
 *
 *	The information in this file is provided "AS IS" without warranty.
 *
 ******************************************************************************/

/*
	PCM
	Physical Connection Management
*/

/*
 * Hardware independent state machine implemantation
 * The following external SMT functions are referenced :
 *
 * 		queue_event()
 * 		smt_timer_start()
 * 		smt_timer_stop()
 *
 * 	The following external HW dependent functions are referenced :
 * 		sm_pm_control()
 *		sm_ph_linestate()
 *
 * 	The following HW dependent events are required :
 *		PC_QLS
 *		PC_ILS
 *		PC_HLS
 *		PC_MLS
 *		PC_NSE
 *		PC_LEM
 *
 */


#include "h/types.h"
#include "h/fddi.h"
#include "h/smc.h"
#include "h/supern_2.h"
#define KERNEL
#include "h/smtstate.h"

#ifdef	FDDI_MIB
extern int snmp_fddi_trap(
#ifdef	ANSIC
struct s_smc	* smc, int  type, int  index
#endif
);
#endif
#ifdef	CONCENTRATOR
extern int plc_is_installed(
#ifdef	ANSIC
struct s_smc *smc ,
int p
#endif
) ;
#endif
/*
 * FSM Macros
 */
#define AFLAG
#define GO_STATE(x)
#define ACTIONS_DONE()
#define ACTIONS(x)

/*
 * PCM states
 */
#define PC0_OFF
#define PC1_BREAK
#define PC2_TRACE
#define PC3_CONNECT
#define PC4_NEXT
#define PC5_SIGNAL
#define PC6_JOIN
#define PC7_VERIFY
#define PC8_ACTIVE
#define PC9_MAINT

/*
 * symbolic state names
 */
static const char * const pcm_states[] = ;

/*
 * symbolic event names
 */
static const char * const pcm_events[] = ;

#ifdef	MOT_ELM
/*
 * PCL-S control register
 * this register in the PLC-S controls the scrambling parameters
 */
#define PLCS_CONTROL_C_U
#define PLCS_CONTROL_C_S
#define PLCS_FASSERT_U
#define PLCS_FASSERT_S
#define PLCS_FDEASSERT_U
#define PLCS_FDEASSERT_S
#else	/* nMOT_ELM */
/*
 * PCL-S control register
 * this register in the PLC-S controls the scrambling parameters
 * can be patched for ANSI compliance if standard changes
 */
static const u_char plcs_control_c_u[17] = ;
static const u_char plcs_control_c_s[17] = ;

#define PLCS_CONTROL_C_U
#define PLCS_CONTROL_C_S
#endif	/* nMOT_ELM */

/*
 * external vars
 */
/* struct definition see 'cmtdef.h' (also used by CFM) */

#define PS_OFF
#define PS_BIT3
#define PS_BIT4
#define PS_BIT7
#define PS_LCT
#define PS_BIT8
#define PS_JOIN
#define PS_ACTIVE

#define LCT_LEM_MAX

/*
 * PLC timing parameter
 */

#define PLC_MS(m)
#define SLOW_TL_MIN
#define SLOW_C_MIN

static	const struct plt {} pltm[] = ;

/*
 * interrupt mask
 */
#ifdef	SUPERNET_3
/*
 * Do we need the EBUF error during signaling, too, to detect SUPERNET_3
 * PLL bug?
 */
static const int plc_imsk_na =;
#else	/* SUPERNET_3 */
/*
 * We do NOT need the elasticity buffer error during signaling.
 */
static int plc_imsk_na = PL_PCM_CODE | PL_TRACE_PROP | PL_PCM_BREAK |
			PL_PCM_ENABLED | PL_SELF_TEST ;
#endif	/* SUPERNET_3 */
static const int plc_imsk_act =;

/* internal functions */
static void pcm_fsm(struct s_smc *smc, struct s_phy *phy, int cmd);
static void pc_rcode_actions(struct s_smc *smc, int bit, struct s_phy *phy);
static void pc_tcode_actions(struct s_smc *smc, const int bit, struct s_phy *phy);
static void reset_lem_struct(struct s_phy *phy);
static void plc_init(struct s_smc *smc, int p);
static void sm_ph_lem_start(struct s_smc *smc, int np, int threshold);
static void sm_ph_lem_stop(struct s_smc *smc, int np);
static void sm_ph_linestate(struct s_smc *smc, int phy, int ls);
static void real_init_plc(struct s_smc *smc);

/*
 * SMT timer interface
 *      start PCM timer 0
 */
static void start_pcm_timer0(struct s_smc *smc, u_long value, int event,
			     struct s_phy *phy)
{}
/*
 * SMT timer interface
 *      stop PCM timer 0
 */
static void stop_pcm_timer0(struct s_smc *smc, struct s_phy *phy)
{}

/*
	init PCM state machine (called by driver)
	clear all PCM vars and flags
*/
void pcm_init(struct s_smc *smc)
{}

void init_plc(struct s_smc *smc)
{}

static void real_init_plc(struct s_smc *smc)
{}

static void plc_init(struct s_smc *smc, int p)
{}

/*
 * control PCM state machine
 */
static void plc_go_state(struct s_smc *smc, int p, int state)
{}

/*
 * read current line state (called by ECM & PCM)
 */
int sm_pm_get_ls(struct s_smc *smc, int phy)
{}

static int plc_send_bits(struct s_smc *smc, struct s_phy *phy, int len)
{}

/*
 * config plc muxes
 */
void plc_config_mux(struct s_smc *smc, int mux)
{}

/*
	PCM state machine
	called by dispatcher  & fddi_init() (driver)
	do
		display state change
		process event
	until SM is stable
*/
void pcm(struct s_smc *smc, const int np, int event)
{}

/*
 * PCM state machine
 */
static void pcm_fsm(struct s_smc *smc, struct s_phy *phy, int cmd)
{}

/*
 * force line state on a PHY output	(only in MAINT state)
 */
static void sm_ph_linestate(struct s_smc *smc, int phy, int ls)
{}

static void reset_lem_struct(struct s_phy *phy)
{}

/*
 * link error monitor
 */
static void lem_evaluate(struct s_smc *smc, struct s_phy *phy)
{}

/*
 * called by SMT to calculate LEM bit error rate
 */
void sm_lem_evaluate(struct s_smc *smc)
{}

static void lem_check_lct(struct s_smc *smc, struct s_phy *phy)
{}

/*
 * LEM functions
 */
static void sm_ph_lem_start(struct s_smc *smc, int np, int threshold)
{}

static void sm_ph_lem_stop(struct s_smc *smc, int np)
{}

/*
 * PCM pseudo code
 * receive actions are called AFTER the bit n is received,
 * i.e. if pc_rcode_actions(5) is called, bit 6 is the next bit to be received
 */

/*
 * PCM pseudo code 5.1 .. 6.1
 */
static void pc_rcode_actions(struct s_smc *smc, int bit, struct s_phy *phy)
{}

/*
 * PCM pseudo code 5.1 .. 6.1
 */
static void pc_tcode_actions(struct s_smc *smc, const int bit, struct s_phy *phy)
{}

/*
 * return status twisted (called by SMT)
 */
int pcm_status_twisted(struct s_smc *smc)
{}

/*
 * return status	(called by SMT)
 *	type
 *	state
 *	remote phy type
 *	remote mac yes/no
 */
void pcm_status_state(struct s_smc *smc, int np, int *type, int *state,
		      int *remote, int *mac)
{}

/*
 * return rooted station status (called by SMT)
 */
int pcm_rooted_station(struct s_smc *smc)
{}

/*
 * Interrupt actions for PLC & PCM events
 */
void plc_irq(struct s_smc *smc, int np, unsigned int cmd)
/* int np;	PHY index */
{}

#ifdef	DEBUG
/*
 * fill state struct
 */
void pcm_get_state(struct s_smc *smc, struct smt_state *state)
{
	struct s_phy	*phy ;
	struct pcm_state *pcs ;
	int	i ;
	int	ii ;
	short	rbits ;
	short	tbits ;
	struct fddi_mib_p	*mib ;

	for (i = 0, phy = smc->y, pcs = state->pcm_state ; i < NUMPHYS ;
		i++ , phy++, pcs++ ) {
		mib = phy->mib ;
		pcs->pcm_type = (u_char) mib->fddiPORTMy_Type ;
		pcs->pcm_state = (u_char) mib->fddiPORTPCMState ;
		pcs->pcm_mode = phy->pc_mode ;
		pcs->pcm_neighbor = (u_char) mib->fddiPORTNeighborType ;
		pcs->pcm_bsf = mib->fddiPORTBS_Flag ;
		pcs->pcm_lsf = phy->ls_flag ;
		pcs->pcm_lct_fail = (u_char) mib->fddiPORTLCTFail_Ct ;
		pcs->pcm_ls_rx = LS2MIB(sm_pm_get_ls(smc,i)) ;
		for (ii = 0, rbits = tbits = 0 ; ii < NUMBITS ; ii++) {
			rbits <<= 1 ;
			tbits <<= 1 ;
			if (phy->r_val[NUMBITS-1-ii])
				rbits |= 1 ;
			if (phy->t_val[NUMBITS-1-ii])
				tbits |= 1 ;
		}
		pcs->pcm_r_val = rbits ;
		pcs->pcm_t_val = tbits ;
	}
}

int get_pcm_state(struct s_smc *smc, int np)
{
	int pcs ;

	SK_UNUSED(smc) ;

	switch (inpw(PLC(np,PL_STATUS_B)) & PL_PCM_STATE) {
		case PL_PC0 :	pcs = PC_STOP ;		break ;
		case PL_PC1 :	pcs = PC_START ;	break ;
		case PL_PC2 :	pcs = PC_TRACE ;	break ;
		case PL_PC3 :	pcs = PC_SIGNAL ;	break ;
		case PL_PC4 :	pcs = PC_SIGNAL ;	break ;
		case PL_PC5 :	pcs = PC_SIGNAL ;	break ;
		case PL_PC6 :	pcs = PC_JOIN ;		break ;
		case PL_PC7 :	pcs = PC_JOIN ;		break ;
		case PL_PC8 :	pcs = PC_ENABLE ;	break ;
		case PL_PC9 :	pcs = PC_MAINT ;	break ;
		default :	pcs = PC_DISABLE ; 	break ;
	}
	return pcs;
}

char *get_linestate(struct s_smc *smc, int np)
{
	char *ls = "" ;

	SK_UNUSED(smc) ;

	switch (inpw(PLC(np,PL_STATUS_A)) & PL_LINE_ST) {
		case PL_L_NLS :	ls = "NOISE" ;	break ;
		case PL_L_ALS :	ls = "ACTIV" ;	break ;
		case PL_L_UND :	ls = "UNDEF" ;	break ;
		case PL_L_ILS4:	ls = "ILS 4" ;	break ;
		case PL_L_QLS :	ls = "QLS" ;	break ;
		case PL_L_MLS :	ls = "MLS" ;	break ;
		case PL_L_HLS :	ls = "HLS" ;	break ;
		case PL_L_ILS16:ls = "ILS16" ;	break ;
#ifdef	lint
		default:	ls = "unknown" ; break ;
#endif
	}
	return ls;
}

char *get_pcmstate(struct s_smc *smc, int np)
{
	char *pcs ;
	
	SK_UNUSED(smc) ;

	switch (inpw(PLC(np,PL_STATUS_B)) & PL_PCM_STATE) {
		case PL_PC0 :	pcs = "OFF" ;		break ;
		case PL_PC1 :	pcs = "BREAK" ;		break ;
		case PL_PC2 :	pcs = "TRACE" ;		break ;
		case PL_PC3 :	pcs = "CONNECT";	break ;
		case PL_PC4 :	pcs = "NEXT" ;		break ;
		case PL_PC5 :	pcs = "SIGNAL" ;	break ;
		case PL_PC6 :	pcs = "JOIN" ;		break ;
		case PL_PC7 :	pcs = "VERIFY" ;	break ;
		case PL_PC8 :	pcs = "ACTIV" ;		break ;
		case PL_PC9 :	pcs = "MAINT" ;		break ;
		default :	pcs = "UNKNOWN" ; 	break ;
	}
	return pcs;
}

void list_phy(struct s_smc *smc)
{
	struct s_plc *plc ;
	int np ;

	for (np = 0 ; np < NUMPHYS ; np++) {
		plc  = &smc->y[np].plc ;
		printf("PHY %d:\tERRORS\t\t\tBREAK_REASONS\t\tSTATES:\n",np) ;
		printf("\tsoft_error: %ld \t\tPC_Start : %ld\n",
						plc->soft_err,plc->b_pcs);
		printf("\tparity_err: %ld \t\tTPC exp. : %ld\t\tLine: %s\n",
			plc->parity_err,plc->b_tpc,get_linestate(smc,np)) ;
		printf("\tebuf_error: %ld \t\tTNE exp. : %ld\n",
						plc->ebuf_err,plc->b_tne) ;
		printf("\tphyinvalid: %ld \t\tQLS det. : %ld\t\tPCM : %s\n",
			plc->phyinv,plc->b_qls,get_pcmstate(smc,np)) ;
		printf("\tviosym_ctr: %ld \t\tILS det. : %ld\n",
						plc->vsym_ctr,plc->b_ils)  ;
		printf("\tmingap_ctr: %ld \t\tHLS det. : %ld\n",
						plc->mini_ctr,plc->b_hls) ;
		printf("\tnodepr_err: %ld\n",plc->np_err) ;
		printf("\tTPC_exp : %ld\n",plc->tpc_exp) ;
		printf("\tLEM_err : %ld\n",smc->y[np].lem.lem_errors) ;
	}
}


#ifdef	CONCENTRATOR
void pcm_lem_dump(struct s_smc *smc)
{
	int		i ;
	struct s_phy	*phy ;
	struct fddi_mib_p	*mib ;

	char		*entostring() ;

	printf("PHY	errors	BER\n") ;
	printf("----------------------\n") ;
	for (i = 0,phy = smc->y ; i < NUMPHYS ; i++,phy++) {
		if (!plc_is_installed(smc,i))
			continue ;
		mib = phy->mib ;
		printf("%s\t%ld\t10E-%d\n",
			entostring(smc,ENTITY_PHY(i)),
			mib->fddiPORTLem_Ct,
			mib->fddiPORTLer_Estimate) ;
	}
}
#endif
#endif