📄 smt.c
字号:
} 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 */EXPORT_PMF SMbuf *smt_build_frame(smc,class,type,length)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(mb,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(smc,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(smc,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(smc,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(smc,ts)struct s_smc *smc ;struct smt_p_timestamp *ts ;{ SMTSETPARA(ts,SMT_P_TIMESTAMP) ; smt_set_timestamp(smc,ts->ts_time) ;}EXPORT_PMF void smt_set_timestamp(smc,p)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(smc,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(smc,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(smc,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(smc,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(smc,st)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(smc,lem,phy)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(smc,vers)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(smc,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(smc,mc)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(smc,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(smc,man)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(smc,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(smc,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(smc,echo,seed,len)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 */void smt_clear_una_dna(smc)struct s_smc *smc ;{ smc->mib.m[MAC0].fddiMACUpstreamNbr = SMT_Unknown ; smc->mib.m[MAC0].fddiMACDownstreamNbr = SMT_Unknown ;}static void smt_clear_old_una_dna(smc)struct s_smc *smc ;{ smc->mib.m[MAC0].fddiMACOldUpstreamNbr = SMT_Unknown ; smc->mib.m[MAC0].fddiMACOldDownstreamNbr = SMT_Unknown ;}u_long smt_get_tid(smc)struct s_smc *smc ;{ u_long tid ; while ((tid = ++(smc->sm.smt_tid) ^ SMT_TID_MAGIC) == 0) ; return(tid & 0x3fffffffL) ;}/* * table of parameter lengths */static const struct smt_pdef { int ptype ; int plen ; const char *pswap ;} smt_pdef[] = { { SMT_P_UNA, sizeof(struct smt_p_una) , SWAP_SMT_P_UNA } , { SMT_P_SDE, sizeof(struct smt_p_sde) , SWAP_SMT_P_SDE } , { SMT_P_STATE, sizeof(struct smt_p_state) , SWAP_SMT_P_STATE } , { SMT_P_TIMESTAMP,sizeof(struct smt_p_timestamp) , SWAP_SMT_P_TIMESTAMP } , { SMT_P_POLICY, sizeof(struct smt_p_policy) , SWAP_SMT_P_POLICY } , { SMT_P_LATENCY, sizeof(struct smt_p_latency) , SWAP_SMT_P_LATENCY } , { SMT_P_NEIGHBORS,sizeof(struct smt_p_neighbor) , SWAP_SMT_P_NEIGHBORS } , { SMT_P_PATH, sizeof(struct smt_p_path) , SWAP_SMT_P_PATH } , { SMT_P_MAC_STATUS,sizeof(struct smt_p_mac_status) , SWAP_SMT_P_MAC_STATUS } ,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -