⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smt.c

📁 h内核
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************************************************** * *	(C)Copyright 1998,1999 SysKonnect, *	a business unit of Schneider & Koch & Co. Datensysteme GmbH. * *	See the file "skfddi.c" for further information. * *	This program is free software; you can redistribute it and/or modify *	it under the terms of the GNU General Public License as published by *	the Free Software Foundation; either version 2 of the License, or *	(at your option) any later version. * *	The information in this file is provided "AS IS" without warranty. * ******************************************************************************/#include "h/types.h"#include "h/fddi.h"#include "h/smc.h"#include "h/smt_p.h"#define KERNEL#include "h/smtstate.h"#ifndef	lintstatic const char ID_sccs[] = "@(#)smt.c	2.43 98/11/23 (C) SK " ;#endifextern const u_char canonical[256] ;/* * FC in SMbuf */#define m_fc(mb)	((mb)->sm_data[0])#define SMT_TID_MAGIC	0x1f0a7b3c#ifdef	DEBUGstatic const char *const smt_type_name[] = {	"SMT_00??", "SMT_INFO", "SMT_02??", "SMT_03??",	"SMT_04??", "SMT_05??", "SMT_06??", "SMT_07??",	"SMT_08??", "SMT_09??", "SMT_0A??", "SMT_0B??",	"SMT_0C??", "SMT_0D??", "SMT_0E??", "SMT_NSA"} ;static const char *const smt_class_name[] = {	"UNKNOWN","NIF","SIF_CONFIG","SIF_OPER","ECF","RAF","RDF",	"SRF","PMF_GET","PMF_SET","ESF"} ;#endif#define LAST_CLASS	(SMT_PMF_SET)static const struct fddi_addr SMT_Unknown = {	{ 0,0,0x1f,0,0,0 }} ;/* * external variables */extern const struct fddi_addr fddi_broadcast ;/* * external functions */int pcm_status_twisted(struct s_smc *smc);/* * function prototypes */#ifdef	LITTLE_ENDIANstatic int smt_swap_short(u_short s);#endifstatic int mac_index(struct s_smc *smc, int mac);static int phy_index(struct s_smc *smc, int phy);static int mac_con_resource_index(struct s_smc *smc, int mac);static int phy_con_resource_index(struct s_smc *smc, int phy);static void smt_send_rdf(struct s_smc *smc, SMbuf *rej, int fc, int reason,			 int local);static void smt_send_nif(struct s_smc *smc, const struct fddi_addr *dest, 			 int fc, u_long tid, int type, int local);static void smt_send_ecf(struct s_smc *smc, struct fddi_addr *dest, int fc,                         u_long tid, int type, int len);static void smt_echo_test(struct s_smc *smc, int dna);static void smt_send_sif_config(struct s_smc *smc, struct fddi_addr *dest,				u_long tid, int local);static void smt_send_sif_operation(struct s_smc *smc, struct fddi_addr *dest,				   u_long tid, int local);#ifdef LITTLE_ENDIANstatic void smt_string_swap(void);#endifstatic void smt_add_frame_len(SMbuf *mb, int len);static void smt_fill_una(struct s_smc *smc, struct smt_p_una *una);static void smt_fill_sde(struct s_smc *smc, struct smt_p_sde *sde);static void smt_fill_state(struct s_smc *smc, struct smt_p_state *state);static void smt_fill_timestamp(struct s_smc *smc, struct smt_p_timestamp *ts);static void smt_fill_policy(struct s_smc *smc, struct smt_p_policy *policy);static void smt_fill_latency(struct s_smc *smc, struct smt_p_latency *latency);static void smt_fill_neighbor(struct s_smc *smc, struct smt_p_neighbor *neighbor);static int smt_fill_path(struct s_smc *smc, struct smt_p_path *path);static void smt_fill_mac_status(struct s_smc *smc, struct smt_p_mac_status *st);static void smt_fill_lem(struct s_smc *smc, struct smt_p_lem *lem, int phy);static void smt_fill_version(struct s_smc *smc, struct smt_p_version *vers);static void smt_fill_fsc(struct s_smc *smc, struct smt_p_fsc *fsc);static void smt_fill_mac_counter(struct s_smc *smc, struct smt_p_mac_counter *mc);static void smt_fill_mac_fnc(struct s_smc *smc, struct smt_p_mac_fnc *fnc);static void smt_fill_manufacturer(struct s_smc *smc, 				  struct smp_p_manufacturer *man);static void smt_fill_user(struct s_smc *smc, struct smp_p_user *user);static void smt_fill_setcount(struct s_smc *smc, struct smt_p_setcount *setcount);static void smt_fill_echo(struct s_smc *smc, struct smt_p_echo *echo, u_long seed,			  int len);void smt_clear_una_dna(struct s_smc *smc);static void smt_clear_old_una_dna(struct s_smc *smc);#ifdef	CONCENTRATORstatic int entity_to_index(void);#endifstatic void update_dac(struct s_smc *smc, int report);static int div_ratio(u_long upper, u_long lower);#ifdef  USE_CAN_ADDRvoid	hwm_conv_can(struct s_smc *smc, char *data, int len);#else#define		hwm_conv_can(smc,data,len)#endifstatic inline int is_my_addr(const struct s_smc *smc, 			     const struct fddi_addr *addr){	return(*(short *)(&addr->a[0]) ==		*(short *)(&smc->mib.m[MAC0].fddiMACSMTAddress.a[0])	  && *(short *)(&addr->a[2]) ==		*(short *)(&smc->mib.m[MAC0].fddiMACSMTAddress.a[2])	  && *(short *)(&addr->a[4]) ==		*(short *)(&smc->mib.m[MAC0].fddiMACSMTAddress.a[4])) ;}static inline int is_broadcast(const struct fddi_addr *addr){	return(*(u_short *)(&addr->a[0]) == 0xffff &&	       *(u_short *)(&addr->a[2]) == 0xffff &&	       *(u_short *)(&addr->a[4]) == 0xffff ) ;}static inline int is_individual(const struct fddi_addr *addr){	return(!(addr->a[0] & GROUP_ADDR)) ;}static inline int is_equal(const struct fddi_addr *addr1, 			   const struct fddi_addr *addr2){	return(*(u_short *)(&addr1->a[0]) == *(u_short *)(&addr2->a[0]) &&	       *(u_short *)(&addr1->a[2]) == *(u_short *)(&addr2->a[2]) &&	       *(u_short *)(&addr1->a[4]) == *(u_short *)(&addr2->a[4]) ) ;}/* * list of mandatory paras in frames */static const u_short plist_nif[] = { SMT_P_UNA,SMT_P_SDE,SMT_P_STATE,0 } ;/* * init SMT agent */void smt_agent_init(struct s_smc *smc){	int		i ;	/*	 * get MAC address	 */	smc->mib.m[MAC0].fddiMACSMTAddress = smc->hw.fddi_home_addr ;	/*	 * get OUI address from driver (bia == built-in-address)	 */	smc->mib.fddiSMTStationId.sid_oem[0] = 0 ;	smc->mib.fddiSMTStationId.sid_oem[1] = 0 ;	driver_get_bia(smc,&smc->mib.fddiSMTStationId.sid_node) ;	for (i = 0 ; i < 6 ; i ++) {		smc->mib.fddiSMTStationId.sid_node.a[i] =			canonical[smc->mib.fddiSMTStationId.sid_node.a[i]] ;	}	smc->mib.fddiSMTManufacturerData[0] =		smc->mib.fddiSMTStationId.sid_node.a[0] ;	smc->mib.fddiSMTManufacturerData[1] =		smc->mib.fddiSMTStationId.sid_node.a[1] ;	smc->mib.fddiSMTManufacturerData[2] =		smc->mib.fddiSMTStationId.sid_node.a[2] ;	smc->sm.smt_tid = 0 ;	smc->mib.m[MAC0].fddiMACDupAddressTest = DA_NONE ;	smc->mib.m[MAC0].fddiMACUNDA_Flag = FALSE ;#ifndef	SLIM_SMT	smt_clear_una_dna(smc) ;	smt_clear_old_una_dna(smc) ;#endif	for (i = 0 ; i < SMT_MAX_TEST ; i++)		smc->sm.pend[i] = 0 ;	smc->sm.please_reconnect = 0 ;	smc->sm.uniq_ticks = 0 ;}/* * SMT task * forever *	delay 30 seconds *	send NIF *	check tvu & tvd * end */void smt_agent_task(struct s_smc *smc){	smt_timer_start(smc,&smc->sm.smt_timer, (u_long)1000000L,		EV_TOKEN(EVENT_SMT,SM_TIMER)) ;	DB_SMT("SMT agent task\n",0,0) ;}void smt_please_reconnect(struct s_smc *smc, int reconn_time)/* struct s_smc	*smc;  Pointer to SMT context *//* int reconn_time;    Wait for reconnect time in seconds */{	/*	 * The please reconnect variable is used as a timer.	 * It is decremented each time smt_event is called.	 * This happens every second or when smt_force_irq is called.	 * Note: smt_force_irq () is called on some packet receives and	 *       when a multicast address is changed. Since nothing	 *       is received during the disconnect and the multicast	 *       address changes can be viewed as not very often and	 *       the timer runs out close to its given value	 *       (reconn_time).	 */	smc->sm.please_reconnect = reconn_time ;}#ifndef SMT_REAL_TOKEN_CTvoid smt_emulate_token_ct(struct s_smc *smc, int mac_index){	u_long	count;	u_long	time;	time = smt_get_time();	count =	((time - smc->sm.last_tok_time[mac_index]) *					100)/TICKS_PER_SECOND;	/*	 * Only when ring is up we will have a token count. The	 * flag is unfortunatly a single instance value. This	 * doesn't matter now, because we currently have only	 * one MAC instance.	 */	if (smc->hw.mac_ring_is_up){		smc->mib.m[mac_index].fddiMACToken_Ct += count;	}	/* Remember current time */	smc->sm.last_tok_time[mac_index] = time;}#endif/*ARGSUSED1*/void smt_event(struct s_smc *smc, int event){	u_long		time ;#ifndef SMT_REAL_TOKEN_CT	int		i ;#endif	if (smc->sm.please_reconnect) {		smc->sm.please_reconnect -- ;		if (smc->sm.please_reconnect == 0) {			/* Counted down */			queue_event(smc,EVENT_ECM,EC_CONNECT) ;		}	}	if (event == SM_FAST)		return ;	/*	 * timer for periodic cleanup in driver	 * reset and start the watchdog (FM2)	 * ESS timer	 * SBA timer	 */	smt_timer_poll(smc) ;	smt_start_watchdog(smc) ;#ifndef	SLIM_SMT#ifndef BOOT#ifdef	ESS	ess_timer_poll(smc) ;#endif#endif#ifdef	SBA	sba_timer_poll(smc) ;#endif	smt_srf_event(smc,0,0,0) ;#endif	/* no SLIM_SMT */	time = smt_get_time() ;	if (time - smc->sm.smt_last_lem >= TICKS_PER_SECOND*8) {		/*		 * Use 8 sec. for the time intervall, it simplifies the		 * LER estimation.		 */		struct fddi_mib_m	*mib ;		u_long			upper ;		u_long			lower ;		int			cond ;		int			port;		struct s_phy		*phy ;		/*		 * calculate LEM bit error rate		 */		sm_lem_evaluate(smc) ;		smc->sm.smt_last_lem = time ;		/*		 * check conditions		 */#ifndef	SLIM_SMT		mac_update_counter(smc) ;		mib = smc->mib.m ;		upper =		(mib->fddiMACLost_Ct - mib->fddiMACOld_Lost_Ct) +		(mib->fddiMACError_Ct - mib->fddiMACOld_Error_Ct) ;		lower =		(mib->fddiMACFrame_Ct - mib->fddiMACOld_Frame_Ct) +		(mib->fddiMACLost_Ct - mib->fddiMACOld_Lost_Ct) ;		mib->fddiMACFrameErrorRatio = div_ratio(upper,lower) ;		cond =			((!mib->fddiMACFrameErrorThreshold &&			mib->fddiMACError_Ct != mib->fddiMACOld_Error_Ct) ||			(mib->fddiMACFrameErrorRatio >			mib->fddiMACFrameErrorThreshold)) ;		if (cond != mib->fddiMACFrameErrorFlag)			smt_srf_event(smc,SMT_COND_MAC_FRAME_ERROR,				INDEX_MAC,cond) ;		upper =		(mib->fddiMACNotCopied_Ct - mib->fddiMACOld_NotCopied_Ct) ;		lower =		upper +		(mib->fddiMACCopied_Ct - mib->fddiMACOld_Copied_Ct) ;		mib->fddiMACNotCopiedRatio = div_ratio(upper,lower) ;		cond =			((!mib->fddiMACNotCopiedThreshold &&			mib->fddiMACNotCopied_Ct !=				mib->fddiMACOld_NotCopied_Ct)||			(mib->fddiMACNotCopiedRatio >			mib->fddiMACNotCopiedThreshold)) ;		if (cond != mib->fddiMACNotCopiedFlag)			smt_srf_event(smc,SMT_COND_MAC_NOT_COPIED,				INDEX_MAC,cond) ;		/*		 * set old values		 */		mib->fddiMACOld_Frame_Ct = mib->fddiMACFrame_Ct ;		mib->fddiMACOld_Copied_Ct = mib->fddiMACCopied_Ct ;		mib->fddiMACOld_Error_Ct = mib->fddiMACError_Ct ;		mib->fddiMACOld_Lost_Ct = mib->fddiMACLost_Ct ;		mib->fddiMACOld_NotCopied_Ct = mib->fddiMACNotCopied_Ct ;		/*		 * Check port EBError Condition		 */		for (port = 0; port < NUMPHYS; port ++) {			phy = &smc->y[port] ;			if (!phy->mib->fddiPORTHardwarePresent) {				continue;			}			cond = (phy->mib->fddiPORTEBError_Ct -				phy->mib->fddiPORTOldEBError_Ct > 5) ;			/* If ratio is more than 5 in 8 seconds			 * Set the condition.			 */			smt_srf_event(smc,SMT_COND_PORT_EB_ERROR,				(int) (INDEX_PORT+ phy->np) ,cond) ;			/*			 * set old values			 */			phy->mib->fddiPORTOldEBError_Ct =				phy->mib->fddiPORTEBError_Ct ;		}#endif	/* no SLIM_SMT */	}#ifndef	SLIM_SMT	if (time - smc->sm.smt_last_notify >= (u_long)		(smc->mib.fddiSMTTT_Notify * TICKS_PER_SECOND) ) {		/*		 * we can either send an announcement or a request		 * a request will trigger a reply so that we can update		 * our dna		 * note: same tid must be used until reply is received		 */		if (!smc->sm.pend[SMT_TID_NIF])			smc->sm.pend[SMT_TID_NIF] = smt_get_tid(smc) ;		smt_send_nif(smc,&fddi_broadcast, FC_SMT_NSA,			smc->sm.pend[SMT_TID_NIF], SMT_REQUEST,0) ;		smc->sm.smt_last_notify = time ;	}	/*	 * check timer	 */	if (smc->sm.smt_tvu &&	    time - smc->sm.smt_tvu > 228*TICKS_PER_SECOND) {		DB_SMT("SMT : UNA expired\n",0,0) ;		smc->sm.smt_tvu = 0 ;		if (!is_equal(&smc->mib.m[MAC0].fddiMACUpstreamNbr,			&SMT_Unknown)){			/* Do not update unknown address */			smc->mib.m[MAC0].fddiMACOldUpstreamNbr=				smc->mib.m[MAC0].fddiMACUpstreamNbr ;		}		smc->mib.m[MAC0].fddiMACUpstreamNbr = SMT_Unknown ;		smc->mib.m[MAC0].fddiMACUNDA_Flag = FALSE ;		/*		 * Make sure the fddiMACUNDA_Flag = FALSE is		 * included in the SRF so we don't generate		 * a separate SRF for the deassertion of this		 * condition		 */		update_dac(smc,0) ;		smt_srf_event(smc, SMT_EVENT_MAC_NEIGHBOR_CHANGE,			INDEX_MAC,0) ;	}	if (smc->sm.smt_tvd &&	    time - smc->sm.smt_tvd > 228*TICKS_PER_SECOND) {		DB_SMT("SMT : DNA expired\n",0,0) ;		smc->sm.smt_tvd = 0 ;		if (!is_equal(&smc->mib.m[MAC0].fddiMACDownstreamNbr,			&SMT_Unknown)){			/* Do not update unknown address */			smc->mib.m[MAC0].fddiMACOldDownstreamNbr=				smc->mib.m[MAC0].fddiMACDownstreamNbr ;		}		smc->mib.m[MAC0].fddiMACDownstreamNbr = SMT_Unknown ;		smt_srf_event(smc, SMT_EVENT_MAC_NEIGHBOR_CHANGE,			INDEX_MAC,0) ;	}#endif	/* no SLIM_SMT */#ifndef SMT_REAL_TOKEN_CT	/*	 * Token counter emulation section. If hardware supports the token	 * count, the token counter will be updated in mac_update_counter.	 */	for (i = MAC0; i < NUMMACS; i++ ){		if (time - smc->sm.last_tok_time[i] > 2*TICKS_PER_SECOND ){			smt_emulate_token_ct( smc, i );		}	}#endif	smt_timer_start(smc,&smc->sm.smt_timer, (u_long)1000000L,		EV_TOKEN(EVENT_SMT,SM_TIMER)) ;}static int div_ratio(u_long upper, u_long lower){	if ((upper<<16L) < upper)		upper = 0xffff0000L ;	else		upper <<= 16L ;	if (!lower)		return(0) ;	return((int)(upper/lower)) ;}#ifndef	SLIM_SMT/* * receive packet handler */void smt_received_pack(struct s_smc *smc, SMbuf *mb, int fs)/* int fs;  frame status */{	struct smt_header	*sm ;	int			local ;	int			illegal = 0 ;	switch (m_fc(mb)) {	case FC_SMT_INFO :	case FC_SMT_LAN_LOC :	case FC_SMT_LOC :	case FC_SMT_NSA :		break ;	default :		smt_free_mbuf(smc,mb) ;		return ;	}	smc->mib.m[MAC0].fddiMACSMTCopied_Ct++ ;	sm = smtod(mb,struct smt_header *) ;	local = ((fs & L_INDICATOR) != 0) ;	hwm_conv_can(smc,(char *)sm,12) ;	/* check destination address */	if (is_individual(&sm->smt_dest) && !is_my_addr(smc,&sm->smt_dest)) {		smt_free_mbuf(smc,mb) ;		return ;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -