162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/******************************************************************************
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci *	(C)Copyright 1998,1999 SysKonnect,
562306a36Sopenharmony_ci *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci *	See the file "skfddi.c" for further information.
862306a36Sopenharmony_ci *
962306a36Sopenharmony_ci *	The information in this file is provided "AS IS" without warranty.
1062306a36Sopenharmony_ci *
1162306a36Sopenharmony_ci ******************************************************************************/
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci/*
1462306a36Sopenharmony_ci	SMT Event Queue Management
1562306a36Sopenharmony_ci*/
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#include "h/types.h"
1862306a36Sopenharmony_ci#include "h/fddi.h"
1962306a36Sopenharmony_ci#include "h/smc.h"
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci#define PRINTF(a,b,c)
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci/*
2462306a36Sopenharmony_ci * init event queue management
2562306a36Sopenharmony_ci */
2662306a36Sopenharmony_civoid ev_init(struct s_smc *smc)
2762306a36Sopenharmony_ci{
2862306a36Sopenharmony_ci	smc->q.ev_put = smc->q.ev_get = smc->q.ev_queue ;
2962306a36Sopenharmony_ci}
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci/*
3262306a36Sopenharmony_ci * add event to queue
3362306a36Sopenharmony_ci */
3462306a36Sopenharmony_civoid queue_event(struct s_smc *smc, int class, int event)
3562306a36Sopenharmony_ci{
3662306a36Sopenharmony_ci	PRINTF("queue class %d event %d\n",class,event) ;
3762306a36Sopenharmony_ci	smc->q.ev_put->class = class ;
3862306a36Sopenharmony_ci	smc->q.ev_put->event = event ;
3962306a36Sopenharmony_ci	if (++smc->q.ev_put == &smc->q.ev_queue[MAX_EVENT])
4062306a36Sopenharmony_ci		smc->q.ev_put = smc->q.ev_queue ;
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci	if (smc->q.ev_put == smc->q.ev_get) {
4362306a36Sopenharmony_ci		SMT_ERR_LOG(smc,SMT_E0137, SMT_E0137_MSG) ;
4462306a36Sopenharmony_ci	}
4562306a36Sopenharmony_ci}
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci/*
4862306a36Sopenharmony_ci * timer_event is called from HW timer package.
4962306a36Sopenharmony_ci */
5062306a36Sopenharmony_civoid timer_event(struct s_smc *smc, u_long token)
5162306a36Sopenharmony_ci{
5262306a36Sopenharmony_ci	PRINTF("timer event class %d token %d\n",
5362306a36Sopenharmony_ci		EV_T_CLASS(token),
5462306a36Sopenharmony_ci		EV_T_EVENT(token)) ;
5562306a36Sopenharmony_ci	queue_event(smc,EV_T_CLASS(token),EV_T_EVENT(token));
5662306a36Sopenharmony_ci}
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci/*
5962306a36Sopenharmony_ci * event dispatcher
6062306a36Sopenharmony_ci *	while event queue is not empty
6162306a36Sopenharmony_ci *		get event from queue
6262306a36Sopenharmony_ci *		send command to state machine
6362306a36Sopenharmony_ci *	end
6462306a36Sopenharmony_ci */
6562306a36Sopenharmony_civoid ev_dispatcher(struct s_smc *smc)
6662306a36Sopenharmony_ci{
6762306a36Sopenharmony_ci	struct event_queue *ev ;	/* pointer into queue */
6862306a36Sopenharmony_ci	int		class ;
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci	ev = smc->q.ev_get ;
7162306a36Sopenharmony_ci	PRINTF("dispatch get %x put %x\n",ev,smc->q.ev_put) ;
7262306a36Sopenharmony_ci	while (ev != smc->q.ev_put) {
7362306a36Sopenharmony_ci		PRINTF("dispatch class %d event %d\n",ev->class,ev->event) ;
7462306a36Sopenharmony_ci		switch(class = ev->class) {
7562306a36Sopenharmony_ci		case EVENT_ECM :		/* Entity Corordination  Man. */
7662306a36Sopenharmony_ci			ecm(smc,(int)ev->event) ;
7762306a36Sopenharmony_ci			break ;
7862306a36Sopenharmony_ci		case EVENT_CFM :		/* Configuration Man. */
7962306a36Sopenharmony_ci			cfm(smc,(int)ev->event) ;
8062306a36Sopenharmony_ci			break ;
8162306a36Sopenharmony_ci		case EVENT_RMT :		/* Ring Man. */
8262306a36Sopenharmony_ci			rmt(smc,(int)ev->event) ;
8362306a36Sopenharmony_ci			break ;
8462306a36Sopenharmony_ci		case EVENT_SMT :
8562306a36Sopenharmony_ci			smt_event(smc,(int)ev->event) ;
8662306a36Sopenharmony_ci			break ;
8762306a36Sopenharmony_ci#ifdef	CONCENTRATOR
8862306a36Sopenharmony_ci		case 99 :
8962306a36Sopenharmony_ci			timer_test_event(smc,(int)ev->event) ;
9062306a36Sopenharmony_ci			break ;
9162306a36Sopenharmony_ci#endif
9262306a36Sopenharmony_ci		case EVENT_PCMA :		/* PHY A */
9362306a36Sopenharmony_ci		case EVENT_PCMB :		/* PHY B */
9462306a36Sopenharmony_ci		default :
9562306a36Sopenharmony_ci			if (class >= EVENT_PCMA &&
9662306a36Sopenharmony_ci			    class < EVENT_PCMA + NUMPHYS) {
9762306a36Sopenharmony_ci				pcm(smc,class - EVENT_PCMA,(int)ev->event) ;
9862306a36Sopenharmony_ci				break ;
9962306a36Sopenharmony_ci			}
10062306a36Sopenharmony_ci			SMT_PANIC(smc,SMT_E0121, SMT_E0121_MSG) ;
10162306a36Sopenharmony_ci			return ;
10262306a36Sopenharmony_ci		}
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci		if (++ev == &smc->q.ev_queue[MAX_EVENT])
10562306a36Sopenharmony_ci			ev = smc->q.ev_queue ;
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci		/* Renew get: it is used in queue_events to detect overruns */
10862306a36Sopenharmony_ci		smc->q.ev_get = ev;
10962306a36Sopenharmony_ci	}
11062306a36Sopenharmony_ci}
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci/*
11362306a36Sopenharmony_ci * smt_online connects to or disconnects from the ring
11462306a36Sopenharmony_ci * MUST be called to initiate connection establishment
11562306a36Sopenharmony_ci *
11662306a36Sopenharmony_ci *	on	0	disconnect
11762306a36Sopenharmony_ci *	on	1	connect
11862306a36Sopenharmony_ci */
11962306a36Sopenharmony_ciu_short smt_online(struct s_smc *smc, int on)
12062306a36Sopenharmony_ci{
12162306a36Sopenharmony_ci	queue_event(smc,EVENT_ECM,on ? EC_CONNECT : EC_DISCONNECT) ;
12262306a36Sopenharmony_ci	ev_dispatcher(smc) ;
12362306a36Sopenharmony_ci	return smc->mib.fddiSMTCF_State;
12462306a36Sopenharmony_ci}
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci/*
12762306a36Sopenharmony_ci * set SMT flag to value
12862306a36Sopenharmony_ci *	flag		flag name
12962306a36Sopenharmony_ci *	value		flag value
13062306a36Sopenharmony_ci * dump current flag setting
13162306a36Sopenharmony_ci */
13262306a36Sopenharmony_ci#ifdef	CONCENTRATOR
13362306a36Sopenharmony_civoid do_smt_flag(struct s_smc *smc, char *flag, int value)
13462306a36Sopenharmony_ci{
13562306a36Sopenharmony_ci#ifdef	DEBUG
13662306a36Sopenharmony_ci	struct smt_debug	*deb;
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci	SK_UNUSED(smc) ;
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci#ifdef	DEBUG_BRD
14162306a36Sopenharmony_ci	deb = &smc->debug;
14262306a36Sopenharmony_ci#else
14362306a36Sopenharmony_ci	deb = &debug;
14462306a36Sopenharmony_ci#endif
14562306a36Sopenharmony_ci	if (!strcmp(flag,"smt"))
14662306a36Sopenharmony_ci		deb->d_smt = value ;
14762306a36Sopenharmony_ci	else if (!strcmp(flag,"smtf"))
14862306a36Sopenharmony_ci		deb->d_smtf = value ;
14962306a36Sopenharmony_ci	else if (!strcmp(flag,"pcm"))
15062306a36Sopenharmony_ci		deb->d_pcm = value ;
15162306a36Sopenharmony_ci	else if (!strcmp(flag,"rmt"))
15262306a36Sopenharmony_ci		deb->d_rmt = value ;
15362306a36Sopenharmony_ci	else if (!strcmp(flag,"cfm"))
15462306a36Sopenharmony_ci		deb->d_cfm = value ;
15562306a36Sopenharmony_ci	else if (!strcmp(flag,"ecm"))
15662306a36Sopenharmony_ci		deb->d_ecm = value ;
15762306a36Sopenharmony_ci	printf("smt	%d\n",deb->d_smt) ;
15862306a36Sopenharmony_ci	printf("smtf	%d\n",deb->d_smtf) ;
15962306a36Sopenharmony_ci	printf("pcm	%d\n",deb->d_pcm) ;
16062306a36Sopenharmony_ci	printf("rmt	%d\n",deb->d_rmt) ;
16162306a36Sopenharmony_ci	printf("cfm	%d\n",deb->d_cfm) ;
16262306a36Sopenharmony_ci	printf("ecm	%d\n",deb->d_ecm) ;
16362306a36Sopenharmony_ci#endif	/* DEBUG */
16462306a36Sopenharmony_ci}
16562306a36Sopenharmony_ci#endif
166