ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / 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