Linux-2.6.12-rc2
[linux-flexiantxendom0-natty.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         { NULL }
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(int type, char _far *value, char *v, u_long mn,
86                         u_long mx, int scale);
87 static int parse_word(char *buf, char _far *text);
88
89 #ifdef SIM
90 #define DB_MAIN(a,b,c)  printf(a,b,c)
91 #else
92 #define DB_MAIN(a,b,c)
93 #endif
94
95 /*
96  * BEGIN_MANUAL_ENTRY()
97  *
98  *      int smt_parse_arg(struct s_smc *,char _far *keyword,int type,
99                 char _far *value)
100  *
101  *      parse SMT parameter
102  *      *keyword
103  *              pointer to keyword, must be \0, \n or \r terminated
104  *      *value  pointer to value, either char * or u_long *
105  *              if char *
106  *                      pointer to value, must be \0, \n or \r terminated
107  *              if u_long *
108  *                      contains binary value
109  *
110  *      type    0: integer
111  *              1: string
112  *      return
113  *              0       parameter parsed ok
114  *              != 0    error
115  *      NOTE:
116  *              function can be called with DS != SS
117  *
118  *
119  * END_MANUAL_ENTRY()
120  */
121 int smt_parse_arg(struct s_smc *smc, char _far *keyword, int type,
122                   char _far *value)
123 {
124         char            keybuf[MAX_VAL+1];
125         char            valbuf[MAX_VAL+1];
126         char            c ;
127         char            *p ;
128         char            *v ;
129         char            *d ;
130         u_long          val = 0 ;
131         struct s_ptab   *pt ;
132         int             st ;
133         int             i ;
134
135         /*
136          * parse keyword
137          */
138         if ((st = parse_word(keybuf,keyword)))
139                 return(st) ;
140         /*
141          * parse value if given as string
142          */
143         if (type == 1) {
144                 if ((st = parse_word(valbuf,value)))
145                         return(st) ;
146         }
147         /*
148          * search in table
149          */
150         st = 0 ;
151         for (pt = ptab ; (v = pt->pt_name) ; pt++) {
152                 for (p = keybuf ; (c = *p) ; p++,v++) {
153                         if (c != *v)
154                                 break ;
155                 }
156                 if (!c && !*v)
157                         break ;
158         }
159         if (!v)
160                 return(-1) ;
161 #if     0
162         printf("=>%s<==>%s<=\n",pt->pt_name,valbuf) ;
163 #endif
164         /*
165          * set value in MIB
166          */
167         if (pt->pt_type)
168                 val = parse_num(type,value,valbuf,pt->pt_min,pt->pt_max,1) ;
169         switch (pt->pt_num) {
170         case 0 :
171                 v = valbuf ;
172                 d = (char *) smc->mib.fddiPRPMFPasswd ;
173                 for (i = 0 ; i < (signed)sizeof(smc->mib.fddiPRPMFPasswd) ; i++)
174                         *d++ = *v++ ;
175                 DB_MAIN("SET %s = %s\n",pt->pt_name,smc->mib.fddiPRPMFPasswd) ;
176                 break ;
177         case 1 :
178                 v = valbuf ;
179                 d = (char *) smc->mib.fddiSMTUserData ;
180                 for (i = 0 ; i < (signed)sizeof(smc->mib.fddiSMTUserData) ; i++)
181                         *d++ = *v++ ;
182                 DB_MAIN("SET %s = %s\n",pt->pt_name,smc->mib.fddiSMTUserData) ;
183                 break ;
184         case 2 :
185                 smc->mib.p[PA].fddiPORTLer_Cutoff = (u_char) val ;
186                 DB_MAIN("SET %s = %d\n",
187                         pt->pt_name,smc->mib.p[PA].fddiPORTLer_Cutoff) ;
188                 break ;
189         case 3 :
190                 smc->mib.p[PB].fddiPORTLer_Cutoff = (u_char) val ;
191                 DB_MAIN("SET %s = %d\n",
192                         pt->pt_name,smc->mib.p[PB].fddiPORTLer_Cutoff) ;
193                 break ;
194         case 4 :
195                 smc->mib.p[PA].fddiPORTLer_Alarm = (u_char) val ;
196                 DB_MAIN("SET %s = %d\n",
197                         pt->pt_name,smc->mib.p[PA].fddiPORTLer_Alarm) ;
198                 break ;
199         case 5 :
200                 smc->mib.p[PB].fddiPORTLer_Alarm = (u_char) val ;
201                 DB_MAIN("SET %s = %d\n",
202                         pt->pt_name,smc->mib.p[PB].fddiPORTLer_Alarm) ;
203                 break ;
204         case 6 :                        /* TMAX */
205                 DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
206                 smc->mib.a[PATH0].fddiPATHT_MaxLowerBound =
207                         (u_long) -MS2BCLK((long)val) ;
208                 break ;
209         case 7 :                        /* TMIN */
210                 DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
211                 smc->mib.m[MAC0].fddiMACT_Min =
212                         (u_long) -MS2BCLK((long)val) ;
213                 break ;
214         case 8 :                        /* TREQ */
215                 DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
216                 smc->mib.a[PATH0].fddiPATHMaxT_Req =
217                         (u_long) -MS2BCLK((long)val) ;
218                 break ;
219         case 9 :                        /* TVX */
220                 DB_MAIN("SET %s = %d \n",pt->pt_name,val) ;
221                 smc->mib.a[PATH0].fddiPATHTVXLowerBound =
222                         (u_long) -US2BCLK((long)val) ;
223                 break ;
224 #ifdef  ESS
225         case 10 :                       /* SBAPAYLOAD */
226                 DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
227                 if (smc->mib.fddiESSPayload != val) {
228                         smc->ess.raf_act_timer_poll = TRUE ;
229                         smc->mib.fddiESSPayload = val ;
230                 }
231                 break ;
232         case 11 :                       /* SBAOVERHEAD */
233                 DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
234                 smc->mib.fddiESSOverhead = val ;
235                 break ;
236         case 12 :                       /* MAXTNEG */
237                 DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
238                 smc->mib.fddiESSMaxTNeg = (u_long) -MS2BCLK((long)val) ;
239                 break ;
240         case 13 :                       /* MINSEGMENTSIZE */
241                 DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
242                 smc->mib.fddiESSMinSegmentSize = val ;
243                 break ;
244         case 14 :                       /* SBACATEGORY */
245                 DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
246                 smc->mib.fddiESSCategory =
247                         (smc->mib.fddiESSCategory & 0xffff) |
248                         ((u_long)(val << 16)) ;
249                 break ;
250         case 15 :                       /* SYNCHTXMODE */
251                 /* do not use memcmp(valbuf,"ALL",3) because DS != SS */
252                 if (valbuf[0] == 'A' && valbuf[1] == 'L' && valbuf[2] == 'L') {
253                         smc->mib.fddiESSSynchTxMode = TRUE ;
254                         DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ;
255                 }
256                 /* if (!memcmp(valbuf,"SPLIT",5)) { */
257                 if (valbuf[0] == 'S' && valbuf[1] == 'P' && valbuf[2] == 'L' &&
258                         valbuf[3] == 'I' && valbuf[4] == 'T') {
259                         DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ;
260                         smc->mib.fddiESSSynchTxMode = FALSE ;
261                 }
262                 break ;
263 #endif
264 #ifdef  SBA
265         case 16 :                       /* SBACOMMAND */
266                 /* if (!memcmp(valbuf,"START",5)) { */
267                 if (valbuf[0] == 'S' && valbuf[1] == 'T' && valbuf[2] == 'A' &&
268                         valbuf[3] == 'R' && valbuf[4] == 'T') {
269                         DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ;
270                         smc->mib.fddiSBACommand = SB_START ;
271                 }
272                 /* if (!memcmp(valbuf,"STOP",4)) { */
273                 if (valbuf[0] == 'S' && valbuf[1] == 'T' && valbuf[2] == 'O' &&
274                         valbuf[3] == 'P') {
275                         DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ;
276                         smc->mib.fddiSBACommand = SB_STOP ;
277                 }
278                 break ;
279         case 17 :                       /* SBAAVAILABLE */
280                 DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
281                 smc->mib.fddiSBAAvailable = (u_char) val ;
282                 break ;
283 #endif
284         }
285         return(0) ;
286 }
287
288 static int parse_word(char *buf, char _far *text)
289 {
290         char            c ;
291         char            *p ;
292         int             p_len ;
293         int             quote ;
294         int             i ;
295         int             ok ;
296
297         /*
298          * skip leading white space
299          */
300         p = buf ;
301         for (i = 0 ; i < MAX_VAL ; i++)
302                 *p++ = 0 ;
303         p = buf ;
304         p_len = 0 ;
305         ok = 0 ;
306         while ( (c = *text++) && (c != '\n') && (c != '\r')) {
307                 if ((c != ' ') && (c != '\t')) {
308                         ok = 1 ;
309                         break ;
310                 }
311         }
312         if (!ok)
313                 return(-1) ;
314         if (c == '"') {
315                 quote = 1 ;
316         }
317         else {
318                 quote = 0 ;
319                 text-- ;
320         }
321         /*
322          * parse valbuf
323          */
324         ok = 0 ;
325         while (!ok && p_len < MAX_VAL-1 && (c = *text++) && (c != '\n')
326                 && (c != '\r')) {
327                 switch (quote) {
328                 case 0 :
329                         if ((c == ' ') || (c == '\t') || (c == '=')) {
330                                 ok = 1 ;
331                                 break ;
332                         }
333                         *p++ = c ;
334                         p_len++ ;
335                         break ;
336                 case 2 :
337                         *p++ = c ;
338                         p_len++ ;
339                         quote = 1 ;
340                         break ;
341                 case 1 :
342                         switch (c) {
343                         case '"' :
344                                 ok = 1 ;
345                                 break ;
346                         case '\\' :
347                                 quote = 2 ;
348                                 break ;
349                         default :
350                                 *p++ = c ;
351                                 p_len++ ;
352                         }
353                 }
354         }
355         *p++ = 0 ;
356         for (p = buf ; (c = *p) ; p++) {
357                 if (c >= 'a' && c <= 'z')
358                         *p = c + 'A' - 'a' ;
359         }
360         return(0) ;
361 }
362
363 static u_long parse_num(int type, char _far *value, char *v, u_long mn,
364                         u_long mx, int scale)
365 {
366         u_long  x = 0 ;
367         char    c ;
368
369         if (type == 0) {                /* integer */
370                 u_long _far     *l ;
371                 u_long          u1 ;
372
373                 l = (u_long _far *) value ;
374                 u1 = *l ;
375                 /*
376                  * if the value is negative take the lower limit
377                  */
378                 if ((long)u1 < 0) {
379                         if (- ((long)u1) > (long) mx) {
380                                 u1 = 0 ;
381                         }
382                         else {
383                                 u1 = (u_long) - ((long)u1) ;
384                         }
385                 }
386                 x = u1 ;
387         }
388         else {                          /* string */
389                 int     sign = 0 ;
390
391                 if (*v == '-') {
392                         sign = 1 ;
393                 }
394                 while ((c = *v++) && (c >= '0') && (c <= '9')) {
395                         x = x * 10 + c - '0' ;
396                 }
397                 if (scale == 10) {
398                         x *= 10 ;
399                         if (c == '.') {
400                                 if ((c = *v++) && (c >= '0') && (c <= '9')) {
401                                         x += c - '0' ;
402                                 }
403                         }
404                 }
405                 if (sign)
406                         x = (u_long) - ((long)x) ;
407         }
408         /*
409          * if the value is negative
410          *      and the absolute value is outside the limits
411          *              take the lower limit
412          *      else
413          *              take the absoute value
414          */
415         if ((long)x < 0) {
416                 if (- ((long)x) > (long) mx) {
417                         x = 0 ;
418                 }
419                 else {
420                         x = (u_long) - ((long)x) ;
421                 }
422         }
423         if (x < mn)
424                 return(mn) ;
425         else if (x > mx)
426                 return(mx) ;
427         return(x) ;
428 }
429
430 #if 0
431 struct  s_smc   SMC ;
432 main()
433 {
434         char    *p ;
435         char    *v ;
436         char    buf[100] ;
437         int     toggle = 0 ;
438
439         while (gets(buf)) {
440                 p = buf ;
441                 while (*p && ((*p == ' ') || (*p == '\t')))
442                         p++ ;
443
444                 while (*p && ((*p != ' ') && (*p != '\t')))
445                         p++ ;
446
447                 v = p ;
448                 while (*v && ((*v == ' ') || (*v == '\t')))
449                         v++ ;
450                 if ((*v >= '0') && (*v <= '9')) {
451                         toggle = !toggle ;
452                         if (toggle) {
453                                 u_long  l ;
454                                 l = atol(v) ;
455                                 smt_parse_arg(&SMC,buf,0,(char _far *)&l) ;
456                         }
457                         else
458                                 smt_parse_arg(&SMC,buf,1,(char _far *)p) ;
459                 }
460                 else {
461                         smt_parse_arg(&SMC,buf,1,(char _far *)p) ;
462                 }
463         }
464         exit(0) ;
465 }
466 #endif
467