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