📄 smt.c
字号:
*/static void smt_send_sif_config(struct s_smc *smc, struct fddi_addr *dest, u_long tid, int local)/* struct fddi_addr *dest; dest address *//* u_long tid; transaction id */{ struct smt_sif_config *sif ; SMbuf *mb ; int len ; if (!(mb = smt_build_frame(smc,SMT_SIF_CONFIG,SMT_REPLY, SIZEOF_SMT_SIF_CONFIG))) return ; sif = smtod(mb, struct smt_sif_config *) ; smt_fill_timestamp(smc,&sif->ts) ; /* set time stamp */ smt_fill_sde(smc,&sif->sde) ; /* set station descriptor */ smt_fill_version(smc,&sif->version) ; /* set version information */ smt_fill_state(smc,&sif->state) ; /* set state information */ smt_fill_policy(smc,&sif->policy) ; /* set station policy */ smt_fill_latency(smc,&sif->latency); /* set station latency */ smt_fill_neighbor(smc,&sif->neighbor); /* set station neighbor */ smt_fill_setcount(smc,&sif->setcount) ; /* set count */ len = smt_fill_path(smc,&sif->path); /* set station path descriptor*/ sif->smt.smt_dest = *dest ; /* destination address */ sif->smt.smt_tid = tid ; /* transaction ID */ smt_add_frame_len(mb,len) ; /* adjust length fields */ dump_smt(smc,(struct smt_header *)sif,"SIF Configuration Reply") ; smt_send_frame(smc,mb,FC_SMT_INFO,local) ;}/* * generate and send SIF operation response */static void smt_send_sif_operation(struct s_smc *smc, struct fddi_addr *dest, u_long tid, int local)/* struct fddi_addr *dest; dest address *//* u_long tid; transaction id */{ struct smt_sif_operation *sif ; SMbuf *mb ; int ports ; int i ; ports = NUMPHYS ;#ifndef CONCENTRATOR if (smc->s.sas == SMT_SAS) ports = 1 ;#endif if (!(mb = smt_build_frame(smc,SMT_SIF_OPER,SMT_REPLY, SIZEOF_SMT_SIF_OPERATION+ports*sizeof(struct smt_p_lem)))) return ; sif = smtod(mb, struct smt_sif_operation *) ; smt_fill_timestamp(smc,&sif->ts) ; /* set time stamp */ smt_fill_mac_status(smc,&sif->status) ; /* set mac status */ smt_fill_mac_counter(smc,&sif->mc) ; /* set mac counter field */ smt_fill_mac_fnc(smc,&sif->fnc) ; /* set frame not copied counter */ smt_fill_manufacturer(smc,&sif->man) ; /* set manufacturer field */ smt_fill_user(smc,&sif->user) ; /* set user field */ smt_fill_setcount(smc,&sif->setcount) ; /* set count */ /* * set link error mon information */ if (ports == 1) { smt_fill_lem(smc,sif->lem,PS) ; } else { for (i = 0 ; i < ports ; i++) { smt_fill_lem(smc,&sif->lem[i],i) ; } } sif->smt.smt_dest = *dest ; /* destination address */ sif->smt.smt_tid = tid ; /* transaction ID */ dump_smt(smc,(struct smt_header *)sif,"SIF Operation Reply") ; smt_send_frame(smc,mb,FC_SMT_INFO,local) ;}/* * get and initialize SMT frame */SMbuf *smt_build_frame(struct s_smc *smc, int class, int type, int length){ SMbuf *mb ; struct smt_header *smt ;#if 0 if (!smc->r.sm_ma_avail) { return(0) ; }#endif if (!(mb = smt_get_mbuf(smc))) return(mb) ; mb->sm_len = length ; smt = smtod(mb, struct smt_header *) ; smt->smt_dest = fddi_broadcast ; /* set dest = broadcast */ smt->smt_class = class ; smt->smt_type = type ; switch (class) { case SMT_NIF : case SMT_SIF_CONFIG : case SMT_SIF_OPER : case SMT_ECF : smt->smt_version = SMT_VID ; break ; default : smt->smt_version = SMT_VID_2 ; break ; } smt->smt_tid = smt_get_tid(smc) ; /* set transaction ID */ smt->smt_pad = 0 ; smt->smt_len = length - sizeof(struct smt_header) ; return(mb) ;}static void smt_add_frame_len(SMbuf *mb, int len){ struct smt_header *smt ; smt = smtod(mb, struct smt_header *) ; smt->smt_len += len ; mb->sm_len += len ;}/* * fill values in UNA parameter */static void smt_fill_una(struct s_smc *smc, struct smt_p_una *una){ SMTSETPARA(una,SMT_P_UNA) ; una->una_pad = 0 ; una->una_node = smc->mib.m[MAC0].fddiMACUpstreamNbr ;}/* * fill values in SDE parameter */static void smt_fill_sde(struct s_smc *smc, struct smt_p_sde *sde){ SMTSETPARA(sde,SMT_P_SDE) ; sde->sde_non_master = smc->mib.fddiSMTNonMaster_Ct ; sde->sde_master = smc->mib.fddiSMTMaster_Ct ; sde->sde_mac_count = NUMMACS ; /* only 1 MAC */#ifdef CONCENTRATOR sde->sde_type = SMT_SDE_CONCENTRATOR ;#else sde->sde_type = SMT_SDE_STATION ;#endif}/* * fill in values in station state parameter */static void smt_fill_state(struct s_smc *smc, struct smt_p_state *state){ int top ; int twist ; SMTSETPARA(state,SMT_P_STATE) ; state->st_pad = 0 ; /* determine topology */ top = 0 ; if (smc->mib.fddiSMTPeerWrapFlag) { top |= SMT_ST_WRAPPED ; /* state wrapped */ }#ifdef CONCENTRATOR if (cfm_status_unattached(smc)) { top |= SMT_ST_UNATTACHED ; /* unattached concentrator */ }#endif if ((twist = pcm_status_twisted(smc)) & 1) { top |= SMT_ST_TWISTED_A ; /* twisted cable */ } if (twist & 2) { top |= SMT_ST_TWISTED_B ; /* twisted cable */ }#ifdef OPT_SRF top |= SMT_ST_SRF ;#endif if (pcm_rooted_station(smc)) top |= SMT_ST_ROOTED_S ; if (smc->mib.a[0].fddiPATHSbaPayload != 0) top |= SMT_ST_SYNC_SERVICE ; state->st_topology = top ; state->st_dupl_addr = ((smc->mib.m[MAC0].fddiMACDA_Flag ? SMT_ST_MY_DUPA : 0 ) | (smc->mib.m[MAC0].fddiMACUNDA_Flag ? SMT_ST_UNA_DUPA : 0)) ;}/* * fill values in timestamp parameter */static void smt_fill_timestamp(struct s_smc *smc, struct smt_p_timestamp *ts){ SMTSETPARA(ts,SMT_P_TIMESTAMP) ; smt_set_timestamp(smc,ts->ts_time) ;}void smt_set_timestamp(struct s_smc *smc, u_char *p){ u_long time ; u_long utime ; /* * timestamp is 64 bits long ; resolution is 80 nS * our clock resolution is 10mS * 10mS/80ns = 125000 ~ 2^17 = 131072 */ utime = smt_get_time() ; time = utime * 100 ; time /= TICKS_PER_SECOND ; p[0] = 0 ; p[1] = (u_char)((time>>(8+8+8+8-1)) & 1) ; p[2] = (u_char)(time>>(8+8+8-1)) ; p[3] = (u_char)(time>>(8+8-1)) ; p[4] = (u_char)(time>>(8-1)) ; p[5] = (u_char)(time<<1) ; p[6] = (u_char)(smc->sm.uniq_ticks>>8) ; p[7] = (u_char)smc->sm.uniq_ticks ; /* * make sure we don't wrap: restart whenever the upper digits change */ if (utime != smc->sm.uniq_time) { smc->sm.uniq_ticks = 0 ; } smc->sm.uniq_ticks++ ; smc->sm.uniq_time = utime ;}/* * fill values in station policy parameter */static void smt_fill_policy(struct s_smc *smc, struct smt_p_policy *policy){ int i ; u_char *map ; u_short in ; u_short out ; /* * MIB para 101b (fddiSMTConnectionPolicy) coding * is different from 0005 coding */ static u_char ansi_weirdness[16] = { 0,7,5,3,8,1,6,4,9,10,2,11,12,13,14,15 } ; SMTSETPARA(policy,SMT_P_POLICY) ; out = 0 ; in = smc->mib.fddiSMTConnectionPolicy ; for (i = 0, map = ansi_weirdness ; i < 16 ; i++) { if (in & 1) out |= (1<<*map) ; in >>= 1 ; map++ ; } policy->pl_config = smc->mib.fddiSMTConfigPolicy ; policy->pl_connect = out ;}/* * fill values in latency equivalent parameter */static void smt_fill_latency(struct s_smc *smc, struct smt_p_latency *latency){ SMTSETPARA(latency,SMT_P_LATENCY) ; latency->lt_phyout_idx1 = phy_index(smc,0) ; latency->lt_latency1 = 10 ; /* in octets (byte clock) */ /* * note: latency has two phy entries by definition * for a SAS, the 2nd one is null */ if (smc->s.sas == SMT_DAS) { latency->lt_phyout_idx2 = phy_index(smc,1) ; latency->lt_latency2 = 10 ; /* in octets (byte clock) */ } else { latency->lt_phyout_idx2 = 0 ; latency->lt_latency2 = 0 ; }}/* * fill values in MAC neighbors parameter */static void smt_fill_neighbor(struct s_smc *smc, struct smt_p_neighbor *neighbor){ SMTSETPARA(neighbor,SMT_P_NEIGHBORS) ; neighbor->nb_mib_index = INDEX_MAC ; neighbor->nb_mac_index = mac_index(smc,1) ; neighbor->nb_una = smc->mib.m[MAC0].fddiMACUpstreamNbr ; neighbor->nb_dna = smc->mib.m[MAC0].fddiMACDownstreamNbr ;}/* * fill values in path descriptor */#ifdef CONCENTRATOR#define ALLPHYS NUMPHYS#else#define ALLPHYS ((smc->s.sas == SMT_SAS) ? 1 : 2)#endifstatic int smt_fill_path(struct s_smc *smc, struct smt_p_path *path){ SK_LOC_DECL(int,type) ; SK_LOC_DECL(int,state) ; SK_LOC_DECL(int,remote) ; SK_LOC_DECL(int,mac) ; int len ; int p ; int physp ; struct smt_phy_rec *phy ; struct smt_mac_rec *pd_mac ; len = PARA_LEN + sizeof(struct smt_mac_rec) * NUMMACS + sizeof(struct smt_phy_rec) * ALLPHYS ; path->para.p_type = SMT_P_PATH ; path->para.p_len = len - PARA_LEN ; /* PHYs */ for (p = 0,phy = path->pd_phy ; p < ALLPHYS ; p++, phy++) { physp = p ;#ifndef CONCENTRATOR if (smc->s.sas == SMT_SAS) physp = PS ;#endif pcm_status_state(smc,physp,&type,&state,&remote,&mac) ;#ifdef LITTLE_ENDIAN phy->phy_mib_index = smt_swap_short((u_short)p+INDEX_PORT) ;#else phy->phy_mib_index = p+INDEX_PORT ;#endif phy->phy_type = type ; phy->phy_connect_state = state ; phy->phy_remote_type = remote ; phy->phy_remote_mac = mac ; phy->phy_resource_idx = phy_con_resource_index(smc,p) ; } /* MAC */ pd_mac = (struct smt_mac_rec *) phy ; pd_mac->mac_addr = smc->mib.m[MAC0].fddiMACSMTAddress ; pd_mac->mac_resource_idx = mac_con_resource_index(smc,1) ; return(len) ;}/* * fill values in mac status */static void smt_fill_mac_status(struct s_smc *smc, struct smt_p_mac_status *st){ SMTSETPARA(st,SMT_P_MAC_STATUS) ; st->st_mib_index = INDEX_MAC ; st->st_mac_index = mac_index(smc,1) ; mac_update_counter(smc) ; /* * timer values are represented in SMT as 2's complement numbers * units : internal : 2's complement BCLK */ st->st_t_req = smc->mib.m[MAC0].fddiMACT_Req ; st->st_t_neg = smc->mib.m[MAC0].fddiMACT_Neg ; st->st_t_max = smc->mib.m[MAC0].fddiMACT_Max ; st->st_tvx_value = smc->mib.m[MAC0].fddiMACTvxValue ; st->st_t_min = smc->mib.m[MAC0].fddiMACT_Min ; st->st_sba = smc->mib.a[PATH0].fddiPATHSbaPayload ; st->st_frame_ct = smc->mib.m[MAC0].fddiMACFrame_Ct ; st->st_error_ct = smc->mib.m[MAC0].fddiMACError_Ct ; st->st_lost_ct = smc->mib.m[MAC0].fddiMACLost_Ct ;}/* * fill values in LEM status */static void smt_fill_lem(struct s_smc *smc, struct smt_p_lem *lem, int phy){ struct fddi_mib_p *mib ; mib = smc->y[phy].mib ; SMTSETPARA(lem,SMT_P_LEM) ; lem->lem_mib_index = phy+INDEX_PORT ; lem->lem_phy_index = phy_index(smc,phy) ; lem->lem_pad2 = 0 ; lem->lem_cutoff = mib->fddiPORTLer_Cutoff ; lem->lem_alarm = mib->fddiPORTLer_Alarm ; /* long term bit error rate */ lem->lem_estimate = mib->fddiPORTLer_Estimate ; /* # of rejected connections */ lem->lem_reject_ct = mib->fddiPORTLem_Reject_Ct ; lem->lem_ct = mib->fddiPORTLem_Ct ; /* total number of errors */}/* * fill version parameter */static void smt_fill_version(struct s_smc *smc, struct smt_p_version *vers){ SK_UNUSED(smc) ; SMTSETPARA(vers,SMT_P_VERSION) ; vers->v_pad = 0 ; vers->v_n = 1 ; /* one version is enough .. */ vers->v_index = 1 ; vers->v_version[0] = SMT_VID_2 ; vers->v_pad2 = 0 ;}#ifdef SMT6_10/* * fill frame status capabilities *//* * note: this para 200B is NOT in swap table, because it's also set in * PMF add_para */static void smt_fill_fsc(struct s_smc *smc, struct smt_p_fsc *fsc){ SK_UNUSED(smc) ; SMTSETPARA(fsc,SMT_P_FSC) ; fsc->fsc_pad0 = 0 ; fsc->fsc_mac_index = INDEX_MAC ; /* this is MIB ; MIB is NOT * mac_index ()i ! */ fsc->fsc_pad1 = 0 ; fsc->fsc_value = FSC_TYPE0 ; /* "normal" node */#ifdef LITTLE_ENDIAN fsc->fsc_mac_index = smt_swap_short(INDEX_MAC) ; fsc->fsc_value = smt_swap_short(FSC_TYPE0) ;#endif}#endif/* * fill mac counter field */static void smt_fill_mac_counter(struct s_smc *smc, struct smt_p_mac_counter *mc){ SMTSETPARA(mc,SMT_P_MAC_COUNTER) ; mc->mc_mib_index = INDEX_MAC ; mc->mc_index = mac_index(smc,1) ; mc->mc_receive_ct = smc->mib.m[MAC0].fddiMACCopied_Ct ; mc->mc_transmit_ct = smc->mib.m[MAC0].fddiMACTransmit_Ct ;}/* * fill mac frame not copied counter */static void smt_fill_mac_fnc(struct s_smc *smc, struct smt_p_mac_fnc *fnc){ SMTSETPARA(fnc,SMT_P_MAC_FNC) ; fnc->nc_mib_index = INDEX_MAC ; fnc->nc_index = mac_index(smc,1) ; fnc->nc_counter = smc->mib.m[MAC0].fddiMACNotCopied_Ct ;}/* * fill manufacturer field */static void smt_fill_manufacturer(struct s_smc *smc, struct smp_p_manufacturer *man){ SMTSETPARA(man,SMT_P_MANUFACTURER) ; memcpy((char *) man->mf_data, (char *) smc->mib.fddiSMTManufacturerData, sizeof(man->mf_data)) ;}/* * fill user field */static void smt_fill_user(struct s_smc *smc, struct smp_p_user *user){ SMTSETPARA(user,SMT_P_USER) ; memcpy((char *) user->us_data, (char *) smc->mib.fddiSMTUserData, sizeof(user->us_data)) ;}/* * fill set count */static void smt_fill_setcount(struct s_smc *smc, struct smt_p_setcount *setcount){ SK_UNUSED(smc) ; SMTSETPARA(setcount,SMT_P_SETCOUNT) ; setcount->count = smc->mib.fddiSMTSetCount.count ; memcpy((char *)setcount->timestamp, (char *)smc->mib.fddiSMTSetCount.timestamp,8) ;}/* * fill echo data */static void smt_fill_echo(struct s_smc *smc, struct smt_p_echo *echo, u_long seed, int len){ u_char *p ; SK_UNUSED(smc) ; SMTSETPARA(echo,SMT_P_ECHODATA) ; echo->para.p_len = len ; for (p = echo->ec_data ; len ; len--) { *p++ = (u_char) seed ; seed += 13 ; }}/* * clear DNA and UNA * called from CFM if configuration changes
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -