File: /usr/src/linux/drivers/net/skfp/smtparse.c

1     /******************************************************************************
2      *
3      *	(C)Copyright 1998,1999 SysKonnect,
4      *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5      *
6      *	See the file "skfddi.c" for further information.
7      *
8      *	This program is free software; you can redistribute it and/or modify
9      *	it under the terms of the GNU General Public License as published by
10      *	the Free Software Foundation; either version 2 of the License, or
11      *	(at your option) any later version.
12      *
13      *	The information in this file is provided "AS IS" without warranty.
14      *
15      ******************************************************************************/
16     
17     
18     /*
19     	parser for SMT parameters
20     */
21     
22     #include "h/types.h"
23     #include "h/fddi.h"
24     #include "h/smc.h"
25     #include "h/smt_p.h"
26     
27     #define KERNEL
28     #include "h/smtstate.h"
29     
30     #ifndef	lint
31     static const char ID_sccs[] = "@(#)smtparse.c	1.12 98/10/06 (C) SK " ;
32     #endif
33     
34     #ifdef	sun
35     #define _far
36     #endif
37     
38     /*
39      * convert to BCLK units
40      */
41     #define MS2BCLK(x)      ((x)*12500L)
42     #define US2BCLK(x)      ((x/10)*125L)
43     
44     /*
45      * parameter table
46      */
47     static struct s_ptab {
48     	char	*pt_name ;
49     	u_short	pt_num ;
50     	u_short	pt_type ;
51     	u_long	pt_min ;
52     	u_long	pt_max ;
53     } ptab[] = {
54     	{ "PMFPASSWD",0,	0 } ,
55     	{ "USERDATA",1,		0 } ,
56     	{ "LERCUTOFFA",2,	1,	4,	15	} ,
57     	{ "LERCUTOFFB",3,	1,	4,	15	} ,
58     	{ "LERALARMA",4,	1,	4,	15	} ,
59     	{ "LERALARMB",5,	1,	4,	15	} ,
60     	{ "TMAX",6,		1,	5,	165	} ,
61     	{ "TMIN",7,		1,	5,	165	} ,
62     	{ "TREQ",8,		1,	5,	165	} ,
63     	{ "TVX",9,		1,	2500,	10000	} ,
64     #ifdef ESS
65     	{ "SBAPAYLOAD",10,	1,	0,	1562	} ,
66     	{ "SBAOVERHEAD",11,	1,	50,	5000	} ,
67     	{ "MAXTNEG",12,		1,	5,	165	} ,
68     	{ "MINSEGMENTSIZE",13,	1,	0,	4478	} ,
69     	{ "SBACATEGORY",14,	1,	0,	0xffff	} ,
70     	{ "SYNCHTXMODE",15,	0 } ,
71     #endif
72     #ifdef SBA
73     	{ "SBACOMMAND",16,	0 } ,
74     	{ "SBAAVAILABLE",17,	1,	0,	100	} ,
75     #endif
76     	{ 0 }
77     } ;
78     
79     /* Define maximum string size for values and keybuffer */
80     #define MAX_VAL	40
81     
82     /*
83      * local function declarations
84      */
85     static u_long parse_num() ;
86     static int parse_word() ;
87     
88     #ifdef SIM
89     #define DB_MAIN(a,b,c)	printf(a,b,c)
90     #else
91     #define DB_MAIN(a,b,c)
92     #endif
93     
94     /*
95      * BEGIN_MANUAL_ENTRY()
96      *
97      *	int smt_parse_arg(struct s_smc *,char _far *keyword,int type,
98     		char _far *value)
99      *
100      *	parse SMT parameter
101      *	*keyword
102      *		pointer to keyword, must be \0, \n or \r terminated
103      *	*value	pointer to value, either char * or u_long *
104      *		if char *
105      *			pointer to value, must be \0, \n or \r terminated
106      *		if u_long *
107      *			contains binary value
108      *
109      *	type	0: integer
110      *		1: string
111      *	return
112      *		0	parameter parsed ok
113      *		!= 0	error
114      *	NOTE:
115      *		function can be called with DS != SS
116      *
117      *
118      * END_MANUAL_ENTRY()
119      */
120     int smt_parse_arg(smc,keyword,type,value)
121     struct s_smc *smc ;
122     char _far *keyword ;
123     int type ;
124     char _far *value ;
125     {
126     	char		keybuf[MAX_VAL+1];
127     	char		valbuf[MAX_VAL+1];
128     	char		c ;
129     	char 		*p ;
130     	char		*v ;
131     	char		*d ;
132     	u_long		val = 0 ;
133     	struct s_ptab	*pt ;
134     	int		st ;
135     	int		i ;
136     
137     	/*
138     	 * parse keyword
139     	 */
140     	if ((st = parse_word(keybuf,keyword)))
141     		return(st) ;
142     	/*
143     	 * parse value if given as string
144     	 */
145     	if (type == 1) {
146     		if ((st = parse_word(valbuf,value)))
147     			return(st) ;
148     	}
149     	/*
150     	 * search in table
151     	 */
152     	st = 0 ;
153     	for (pt = ptab ; (v = pt->pt_name) ; pt++) {
154     		for (p = keybuf ; (c = *p) ; p++,v++) {
155     			if (c != *v)
156     				break ;
157     		}
158     		if (!c && !*v)
159     			break ;
160     	}
161     	if (!v)
162     		return(-1) ;
163     #if	0
164     	printf("=>%s<==>%s<=\n",pt->pt_name,valbuf) ;
165     #endif
166     	/*
167     	 * set value in MIB
168     	 */
169     	if (pt->pt_type)
170     		val = parse_num(type,value,valbuf,pt->pt_min,pt->pt_max,1) ;
171     	switch (pt->pt_num) {
172     	case 0 :
173     		v = valbuf ;
174     		d = (char *) smc->mib.fddiPRPMFPasswd ;
175     		for (i = 0 ; i < (signed)sizeof(smc->mib.fddiPRPMFPasswd) ; i++)
176     			*d++ = *v++ ;
177     		DB_MAIN("SET %s = %s\n",pt->pt_name,smc->mib.fddiPRPMFPasswd) ;
178     		break ;
179     	case 1 :
180     		v = valbuf ;
181     		d = (char *) smc->mib.fddiSMTUserData ;
182     		for (i = 0 ; i < (signed)sizeof(smc->mib.fddiSMTUserData) ; i++)
183     			*d++ = *v++ ;
184     		DB_MAIN("SET %s = %s\n",pt->pt_name,smc->mib.fddiSMTUserData) ;
185     		break ;
186     	case 2 :
187     		smc->mib.p[PA].fddiPORTLer_Cutoff = (u_char) val ;
188     		DB_MAIN("SET %s = %d\n",
189     			pt->pt_name,smc->mib.p[PA].fddiPORTLer_Cutoff) ;
190     		break ;
191     	case 3 :
192     		smc->mib.p[PB].fddiPORTLer_Cutoff = (u_char) val ;
193     		DB_MAIN("SET %s = %d\n",
194     			pt->pt_name,smc->mib.p[PB].fddiPORTLer_Cutoff) ;
195     		break ;
196     	case 4 :
197     		smc->mib.p[PA].fddiPORTLer_Alarm = (u_char) val ;
198     		DB_MAIN("SET %s = %d\n",
199     			pt->pt_name,smc->mib.p[PA].fddiPORTLer_Alarm) ;
200     		break ;
201     	case 5 :
202     		smc->mib.p[PB].fddiPORTLer_Alarm = (u_char) val ;
203     		DB_MAIN("SET %s = %d\n",
204     			pt->pt_name,smc->mib.p[PB].fddiPORTLer_Alarm) ;
205     		break ;
206     	case 6 :			/* TMAX */
207     		DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
208     		smc->mib.a[PATH0].fddiPATHT_MaxLowerBound =
209     			(u_long) -MS2BCLK((long)val) ;
210     		break ;
211     	case 7 :			/* TMIN */
212     		DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
213     		smc->mib.m[MAC0].fddiMACT_Min =
214     			(u_long) -MS2BCLK((long)val) ;
215     		break ;
216     	case 8 :			/* TREQ */
217     		DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
218     		smc->mib.a[PATH0].fddiPATHMaxT_Req =
219     			(u_long) -MS2BCLK((long)val) ;
220     		break ;
221     	case 9 :			/* TVX */
222     		DB_MAIN("SET %s = %d \n",pt->pt_name,val) ;
223     		smc->mib.a[PATH0].fddiPATHTVXLowerBound =
224     			(u_long) -US2BCLK((long)val) ;
225     		break ;
226     #ifdef	ESS
227     	case 10 :			/* SBAPAYLOAD */
228     		DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
229     		if (smc->mib.fddiESSPayload != val) {
230     			smc->ess.raf_act_timer_poll = TRUE ;
231     			smc->mib.fddiESSPayload = val ;
232     		}
233     		break ;
234     	case 11 :			/* SBAOVERHEAD */
235     		DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
236     		smc->mib.fddiESSOverhead = val ;
237     		break ;
238     	case 12 :			/* MAXTNEG */
239     		DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
240     		smc->mib.fddiESSMaxTNeg = (u_long) -MS2BCLK((long)val) ;
241     		break ;
242     	case 13 :			/* MINSEGMENTSIZE */
243     		DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
244     		smc->mib.fddiESSMinSegmentSize = val ;
245     		break ;
246     	case 14 :			/* SBACATEGORY */
247     		DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
248     		smc->mib.fddiESSCategory =
249     			(smc->mib.fddiESSCategory & 0xffff) |
250     			((u_long)(val << 16)) ;
251     		break ;
252     	case 15 :			/* SYNCHTXMODE */
253     		/* do not use memcmp(valbuf,"ALL",3) because DS != SS */
254     		if (valbuf[0] == 'A' && valbuf[1] == 'L' && valbuf[2] == 'L') {
255     			smc->mib.fddiESSSynchTxMode = TRUE ;
256     			DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ;
257     		}
258     		/* if (!memcmp(valbuf,"SPLIT",5)) { */
259     		if (valbuf[0] == 'S' && valbuf[1] == 'P' && valbuf[2] == 'L' &&
260     			valbuf[3] == 'I' && valbuf[4] == 'T') {
261     			DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ;
262     			smc->mib.fddiESSSynchTxMode = FALSE ;
263     		}
264     		break ;
265     #endif
266     #ifdef	SBA
267     	case 16 :			/* SBACOMMAND */
268     		/* if (!memcmp(valbuf,"START",5)) { */
269     		if (valbuf[0] == 'S' && valbuf[1] == 'T' && valbuf[2] == 'A' &&
270     			valbuf[3] == 'R' && valbuf[4] == 'T') {
271     			DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ;
272     			smc->mib.fddiSBACommand = SB_START ;
273     		}
274     		/* if (!memcmp(valbuf,"STOP",4)) { */
275     		if (valbuf[0] == 'S' && valbuf[1] == 'T' && valbuf[2] == 'O' &&
276     			valbuf[3] == 'P') {
277     			DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ;
278     			smc->mib.fddiSBACommand = SB_STOP ;
279     		}
280     		break ;
281     	case 17 :			/* SBAAVAILABLE */
282     		DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
283     		smc->mib.fddiSBAAvailable = (u_char) val ;
284     		break ;
285     #endif
286     	}
287     	return(0) ;
288     }
289     
290     static int parse_word(buf,text)
291     char *buf ;
292     char _far *text ;
293     {
294     	char		c ;
295     	char 		*p ;
296     	int		p_len ;
297     	int		quote ;
298     	int		i ;
299     	int		ok ;
300     
301     	/*
302     	 * skip leading white space
303     	 */
304     	p = buf ;
305     	for (i = 0 ; i < MAX_VAL ; i++)
306     		*p++ = 0 ;
307     	p = buf ;
308     	p_len = 0 ;
309     	ok = 0 ;
310     	while ( (c = *text++) && (c != '\n') && (c != '\r')) {
311     		if ((c != ' ') && (c != '\t')) {
312     			ok = 1 ;
313     			break ;
314     		}
315     	}
316     	if (!ok)
317     		return(-1) ;
318     	if (c == '"') {
319     		quote = 1 ;
320     	}
321     	else {
322     		quote = 0 ;
323     		text-- ;
324     	}
325     	/*
326     	 * parse valbuf
327     	 */
328     	ok = 0 ;
329     	while (!ok && p_len < MAX_VAL-1 && (c = *text++) && (c != '\n')
330     		&& (c != '\r')) {
331     		switch (quote) {
332     		case 0 :
333     			if ((c == ' ') || (c == '\t') || (c == '=')) {
334     				ok = 1 ;
335     				break ;
336     			}
337     			*p++ = c ;
338     			p_len++ ;
339     			break ;
340     		case 2 :
341     			*p++ = c ;
342     			p_len++ ;
343     			quote = 1 ;
344     			break ;
345     		case 1 :
346     			switch (c) {
347     			case '"' :
348     				ok = 1 ;
349     				break ;
350     			case '\\' :
351     				quote = 2 ;
352     				break ;
353     			default :
354     				*p++ = c ;
355     				p_len++ ;
356     			}
357     		}
358     	}
359     	*p++ = 0 ;
360     	for (p = buf ; (c = *p) ; p++) {
361     		if (c >= 'a' && c <= 'z')
362     			*p = c + 'A' - 'a' ;
363     	}
364     	return(0) ;
365     }
366     
367     static u_long parse_num(type,value,v,mn,mx,scale)
368     int type ;
369     char _far *value ;
370     char *v ;
371     u_long mn ;
372     u_long mx ;
373     int scale ;
374     {
375     	u_long	x = 0 ;
376     	char	c ;
377     
378     	if (type == 0) {		/* integer */
379     		u_long _far	*l ;
380     		u_long		u1 ;
381     
382     		l = (u_long _far *) value ;
383     		u1 = *l ;
384     		/*
385     		 * if the value is negative take the lower limit
386     		 */
387     		if ((long)u1 < 0) {
388     			if (- ((long)u1) > (long) mx) {
389     				u1 = 0 ;
390     			}
391     			else {
392     				u1 = (u_long) - ((long)u1) ;
393     			}
394     		}
395     		x = u1 ;
396     	}
397     	else {				/* string */
398     		int	sign = 0 ;
399     
400     		if (*v == '-') {
401     			sign = 1 ;
402     		}
403     		while ((c = *v++) && (c >= '0') && (c <= '9')) {
404     			x = x * 10 + c - '0' ;
405     		}
406     		if (scale == 10) {
407     			x *= 10 ;
408     			if (c == '.') {
409     				if ((c = *v++) && (c >= '0') && (c <= '9')) {
410     					x += c - '0' ;
411     				}
412     			}
413     		}
414     		if (sign)
415     			x = (u_long) - ((long)x) ;
416     	}
417     	/*
418     	 * if the value is negative
419     	 *	and the absolute value is outside the limits
420     	 *		take the lower limit
421     	 *	else
422     	 *		take the absoute value
423     	 */
424     	if ((long)x < 0) {
425     		if (- ((long)x) > (long) mx) {
426     			x = 0 ;
427     		}
428     		else {
429     			x = (u_long) - ((long)x) ;
430     		}
431     	}
432     	if (x < mn)
433     		return(mn) ;
434     	else if (x > mx)
435     		return(mx) ;
436     	return(x) ;
437     }
438     
439     #if 0
440     struct	s_smc	SMC ;
441     main()
442     {
443     	char	*p ;
444     	char	*v ;
445     	char	buf[100] ;
446     	int	toggle = 0 ;
447     
448     	while (gets(buf)) {
449     		p = buf ;
450     		while (*p && ((*p == ' ') || (*p == '\t')))
451     			p++ ;
452     
453     		while (*p && ((*p != ' ') && (*p != '\t')))
454     			p++ ;
455     
456     		v = p ;
457     		while (*v && ((*v == ' ') || (*v == '\t')))
458     			v++ ;
459     		if ((*v >= '0') && (*v <= '9')) {
460     			toggle = !toggle ;
461     			if (toggle) {
462     				u_long	l ;
463     				l = atol(v) ;
464     				smt_parse_arg(&SMC,buf,0,(char _far *)&l) ;
465     			}
466     			else
467     				smt_parse_arg(&SMC,buf,1,(char _far *)p) ;
468     		}
469     		else {
470     			smt_parse_arg(&SMC,buf,1,(char _far *)p) ;
471     		}
472     	}
473     	exit(0) ;
474     }
475     #endif
476