Enscript Output

extractedLnx/linux-2.6.9/drivers/net/skfp/pmf.c_smt_set_para.c

int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, int local,
		 int set)
{
#define IFSET(x)	if (set) (x)

	const struct s_p_tab	*pt ;
	int		len ;
	char		*from ;
	char		*to ;
	const char	*swap ;
	char		c ;
	char		*mib_addr ;
	struct fddi_mib	*mib ;
	struct fddi_mib_m	*mib_m = NULL;
	struct fddi_mib_a	*mib_a = NULL;
	struct fddi_mib_p	*mib_p = NULL;
	int		mac ;
	int		path ;
	int		port ;
	SK_LOC_DECL(u_char,byte_val) ;
	SK_LOC_DECL(u_short,word_val) ;
	SK_LOC_DECL(u_long,long_val) ;

	mac = index - INDEX_MAC ;
	path = index - INDEX_PATH ;
	port = index - INDEX_PORT ;
	len = pa->p_len ;
	from = (char *) (pa + 1 ) ;

	mib = &smc->mib ;
	switch (pa->p_type & 0xf000) {
	case 0x1000 :
	default :
		mib_addr = (char *) mib ;
		break ;
	case 0x2000 :
		if (mac < 0 || mac >= NUMMACS) {
			return(SMT_RDF_NOPARAM) ;
		}
		mib_m = &smc->mib.m[mac] ;
		mib_addr = (char *) mib_m ;
		from += 4 ;		/* skip index */
		len -= 4 ;
		break ;
	case 0x3000 :
		if (path < 0 || path >= NUMPATHS) {
			return(SMT_RDF_NOPARAM) ;
		}
		mib_a = &smc->mib.a[path] ;
		mib_addr = (char *) mib_a ;
		from += 4 ;		/* skip index */
		len -= 4 ;
		break ;
	case 0x4000 :
		if (port < 0 || port >= smt_mib_phys(smc)) {
			return(SMT_RDF_NOPARAM) ;
		}
		mib_p = &smc->mib.p[port_to_mib(smc,port)] ;
		mib_addr = (char *) mib_p ;
		from += 4 ;		/* skip index */
		len -= 4 ;
		break ;
	}
	switch (pa->p_type) {
	case SMT_P10F0 :
	case SMT_P10F1 :
#ifdef	ESS
	case SMT_P10F2 :
	case SMT_P10F3 :
	case SMT_P10F4 :
	case SMT_P10F5 :
	case SMT_P10F6 :
	case SMT_P10F7 :
#endif
#ifdef	SBA
	case SMT_P10F8 :
	case SMT_P10F9 :
#endif
	case SMT_P20F1 :
		if (!local) {
			return(SMT_RDF_NOPARAM) ;
		}
		break ;
	}
	pt = smt_get_ptab(pa->p_type) ;
	if (!pt) {
		return( (pa->p_type & 0xff00) ? SMT_RDF_NOPARAM :
						SMT_RDF_ILLEGAL ) ;
	}
	switch (pt->p_access) {
	case AC_GR :
	case AC_S :
		break ;
	default :
		return(SMT_RDF_ILLEGAL) ;
	}
	to = mib_addr + pt->p_offset ;
	swap = pt->p_swap ;		/* pointer to swap string */

	while (swap && (c = *swap++)) {
		switch(c) {
		case 'b' :
			to = (char *) &byte_val ;
			break ;
		case 'w' :
			to = (char *) &word_val ;
			break ;
		case 'l' :
			to = (char *) &long_val ;
			break ;
		case 'S' :
		case 'E' :
		case 'R' :
		case 'r' :
			if (len < 4) {
				goto len_error ;
			}
			if (from[0] | from[1])
				goto val_error ;
#ifdef	LITTLE_ENDIAN
			if (c == 'r') {
				to[0] = from[2] ;
				to[1] = from[3] ;
			}
			else {
				to[1] = from[2] ;
				to[0] = from[3] ;
			}
#else
			to[0] = from[2] ;
			to[1] = from[3] ;
#endif
			from += 4 ;
			to += 2 ;
			len -= 4 ;
			break ;
		case 'F' :
		case 'B' :
			if (len < 4) {
				goto len_error ;
			}
			if (from[0] | from[1] | from[2])
				goto val_error ;
			to[0] = from[3] ;
			len -= 4 ;
			from += 4 ;
			to += 4 ;
			break ;
		case 'C' :
		case 'T' :
		case 'L' :
			if (len < 4) {
				goto len_error ;
			}
#ifdef	LITTLE_ENDIAN
			to[3] = *from++ ;
			to[2] = *from++ ;
			to[1] = *from++ ;
			to[0] = *from++ ;
#else
			to[0] = *from++ ;
			to[1] = *from++ ;
			to[2] = *from++ ;
			to[3] = *from++ ;
#endif
			len -= 4 ;
			to += 4 ;
			break ;
		case 'A' :
			if (len < 8)
				goto len_error ;
			if (set)
				memcpy((char *) to,(char *) from+2,6) ;
			to += 8 ;
			from += 8 ;
			len -= 8 ;
			break ;
		case '4' :
			if (len < 4)
				goto len_error ;
			if (set)
				memcpy((char *) to,(char *) from,4) ;
			to += 4 ;
			from += 4 ;
			len -= 4 ;
			break ;
		case '8' :
			if (len < 8)
				goto len_error ;
			if (set)
				memcpy((char *) to,(char *) from,8) ;
			to += 8 ;
			from += 8 ;
			len -= 8 ;
			break ;
		case 'D' :
			if (len < 32)
				goto len_error ;
			if (set)
				memcpy((char *) to,(char *) from,32) ;
			to += 32 ;
			from += 32 ;
			len -= 32 ;
			break ;
		case 'P' :		/* timestamp is NOT swapped */
			if (set) {
				to[0] = *from++ ;
				to[1] = *from++ ;
				to[2] = *from++ ;
				to[3] = *from++ ;
				to[4] = *from++ ;
				to[5] = *from++ ;
				to[6] = *from++ ;
				to[7] = *from++ ;
			}
			to += 8 ;
			len -= 8 ;
			break ;
		default :
			SMT_PANIC(smc,SMT_E0120, SMT_E0120_MSG) ;
			return(SMT_RDF_ILLEGAL) ;
		}
	}
	/*
	 * actions and internal updates
	 */
	switch (pa->p_type) {
	case SMT_P101A:			/* fddiSMTConfigPolicy */
		if (word_val & ~1)
			goto val_error ;
		IFSET(mib->fddiSMTConfigPolicy = word_val) ;
		break ;
	case SMT_P101B :		/* fddiSMTConnectionPolicy */
		if (!(word_val & POLICY_MM))
			goto val_error ;
		IFSET(mib->fddiSMTConnectionPolicy = word_val) ;
		break ;
	case SMT_P101D : 		/* fddiSMTTT_Notify */
		if (word_val < 2 || word_val > 30)
			goto val_error ;
		IFSET(mib->fddiSMTTT_Notify = word_val) ;
		break ;
	case SMT_P101E :		/* fddiSMTStatRptPolicy */
		if (byte_val & ~1)
			goto val_error ;
		IFSET(mib->fddiSMTStatRptPolicy = byte_val) ;
		break ;
	case SMT_P101F :		/* fddiSMTTrace_MaxExpiration */
		/*
		 * note: lower limit trace_max = 6.001773... s
		 * NO upper limit
		 */
		if (long_val < (long)0x478bf51L)
			goto val_error ;
		IFSET(mib->fddiSMTTrace_MaxExpiration = long_val) ;
		break ;
#ifdef	ESS
	case SMT_P10F2 :		/* fddiESSPayload */
		if (long_val > 1562)
			goto val_error ;
		if (set && smc->mib.fddiESSPayload != long_val) {
			smc->ess.raf_act_timer_poll = TRUE ;
			smc->mib.fddiESSPayload = long_val ;
		}
		break ;
	case SMT_P10F3 :		/* fddiESSOverhead */
		if (long_val < 50 || long_val > 5000)
			goto val_error ;
		if (set && smc->mib.fddiESSPayload &&
			smc->mib.fddiESSOverhead != long_val) {
			smc->ess.raf_act_timer_poll = TRUE ;
			smc->mib.fddiESSOverhead = long_val ;
		}
		break ;
	case SMT_P10F4 :		/* fddiESSMaxTNeg */
		if (long_val > -MS2BCLK(5) || long_val < -MS2BCLK(165))
			goto val_error ;
		IFSET(mib->fddiESSMaxTNeg = long_val) ;
		break ;
	case SMT_P10F5 :		/* fddiESSMinSegmentSize */
		if (long_val < 1 || long_val > 4478)
			goto val_error ;
		IFSET(mib->fddiESSMinSegmentSize = long_val) ;
		break ;
	case SMT_P10F6 :		/* fddiESSCategory */
		if ((long_val & 0xffff) != 1)
			goto val_error ;
		IFSET(mib->fddiESSCategory = long_val) ;
		break ;
	case SMT_P10F7 :		/* fddiESSSyncTxMode */
		if (word_val > 1)
			goto val_error ;
		IFSET(mib->fddiESSSynchTxMode = word_val) ;
		break ;
#endif
#ifdef	SBA
	case SMT_P10F8 :		/* fddiSBACommand */
		if (byte_val != SB_STOP && byte_val != SB_START)
			goto val_error ;
		IFSET(mib->fddiSBACommand = byte_val) ;
		break ;
	case SMT_P10F9 :		/* fddiSBAAvailable */
		if (byte_val > 100)
			goto val_error ;
		IFSET(mib->fddiSBAAvailable = byte_val) ;
		break ;
#endif
	case SMT_P2020 :		/* fddiMACRequestedPaths */
		if ((word_val & (MIB_P_PATH_PRIM_PREFER |
			MIB_P_PATH_PRIM_ALTER)) == 0 )
			goto val_error ;
		IFSET(mib_m->fddiMACRequestedPaths = word_val) ;
		break ;
	case SMT_P205F :		/* fddiMACFrameErrorThreshold */
		/* 0 .. ffff acceptable */
		IFSET(mib_m->fddiMACFrameErrorThreshold = word_val) ;
		break ;
	case SMT_P2067 :		/* fddiMACNotCopiedThreshold */
		/* 0 .. ffff acceptable */
		IFSET(mib_m->fddiMACNotCopiedThreshold = word_val) ;
		break ;
	case SMT_P2076:			/* fddiMACMA_UnitdataEnable */
		if (byte_val & ~1)
			goto val_error ;
		if (set) {
			mib_m->fddiMACMA_UnitdataEnable = byte_val ;
			queue_event(smc,EVENT_RMT,RM_ENABLE_FLAG) ;
		}
		break ;
	case SMT_P20F1 :		/* fddiMACT_Min */
		IFSET(mib_m->fddiMACT_Min = long_val) ;
		break ;
	case SMT_P320F :
		if (long_val > 1562)
			goto val_error ;
		IFSET(mib_a->fddiPATHSbaPayload = long_val) ;
#ifdef	ESS
		if (set)
			ess_para_change(smc) ;
#endif
		break ;
	case SMT_P3210 :
		if (long_val > 5000)
			goto val_error ;
		
		if (long_val != 0 && mib_a->fddiPATHSbaPayload == 0)
			goto val_error ;

		IFSET(mib_a->fddiPATHSbaOverhead = long_val) ;
#ifdef	ESS
		if (set)
			ess_para_change(smc) ;
#endif
		break ;
	case SMT_P3213:			/* fddiPATHT_Rmode */
		/* no limit :
		 * 0 .. 343.597 => 0 .. 2e32 * 80nS
		 */
		if (set) {
			mib_a->fddiPATHT_Rmode = long_val ;
			rtm_set_timer(smc) ;
		}
		break ;
	case SMT_P3214 :		/* fddiPATHSbaAvailable */
		if (long_val > 0x00BEBC20L)
			goto val_error ;
#ifdef SBA 
		if (set && mib->fddiSBACommand == SB_STOP)
			goto val_error ;
#endif
		IFSET(mib_a->fddiPATHSbaAvailable = long_val) ;
		break ;
	case SMT_P3215 :		/* fddiPATHTVXLowerBound */
		IFSET(mib_a->fddiPATHTVXLowerBound = long_val) ;
		goto change_mac_para ;
	case SMT_P3216 :		/* fddiPATHT_MaxLowerBound */
		IFSET(mib_a->fddiPATHT_MaxLowerBound = long_val) ;
		goto change_mac_para ;
	case SMT_P3217 :		/* fddiPATHMaxT_Req */
		IFSET(mib_a->fddiPATHMaxT_Req = long_val) ;

change_mac_para:
		if (set && smt_set_mac_opvalues(smc)) {
			RS_SET(smc,RS_EVENT) ;
			smc->sm.please_reconnect = 1 ;
			queue_event(smc,EVENT_ECM,EC_DISCONNECT) ;
		}
		break ;
	case SMT_P400E :		/* fddiPORTConnectionPolicies */
		if (byte_val > 1)
			goto val_error ;
		IFSET(mib_p->fddiPORTConnectionPolicies = byte_val) ;
		break ;
	case SMT_P4011 :		/* fddiPORTRequestedPaths */
		/* all 3*8 bits allowed */
		IFSET(memcpy((char *)mib_p->fddiPORTRequestedPaths,
			(char *)&long_val,4)) ;
		break ;
	case SMT_P401F:			/* fddiPORTMaint_LS */
		if (word_val > 4)
			goto val_error ;
		IFSET(mib_p->fddiPORTMaint_LS = word_val) ;
		break ;
	case SMT_P403A :		/* fddiPORTLer_Cutoff */
		if (byte_val < 4 || byte_val > 15)
			goto val_error ;
		IFSET(mib_p->fddiPORTLer_Cutoff = byte_val) ;
		break ;
	case SMT_P403B :		/* fddiPORTLer_Alarm */
		if (byte_val < 4 || byte_val > 15)
			goto val_error ;
		IFSET(mib_p->fddiPORTLer_Alarm = byte_val) ;
		break ;

	/*
	 * Actions
	 */
	case SMT_P103C :		/* fddiSMTStationAction */
		if (smt_action(smc,SMT_STATION_ACTION, (int) word_val, 0))
			goto val_error ;
		break ;
	case SMT_P4046:			/* fddiPORTAction */
		if (smt_action(smc,SMT_PORT_ACTION, (int) word_val,
			port_to_mib(smc,port)))
			goto val_error ;
		break ;
	default :
		break ;
	}
	return(0) ;

val_error:
	/* parameter value in frame is out of range */
	return(SMT_RDF_RANGE) ;

len_error:
	/* parameter value in frame is too short */
	return(SMT_RDF_LENGTH) ;

#if	0
no_author_error:
	/* parameter not setable, because the SBA is not active
	 * Please note: we give the return code 'not authorizeed
	 *  because SBA denied is not a valid return code in the
	 * PMF protocol.
	 */
	return(SMT_RDF_AUTHOR) ;
#endif
}

Generated by GNU enscript 1.6.4.