]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - usr.sbin/lmcconfig/lmcconfig.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / usr.sbin / lmcconfig / lmcconfig.c
1 /*
2  * First author: Michael Graff.
3  * Copyright (c) 1997-2000 Lan Media Corp. (www.lanmedia.com).
4  * All rights reserved.
5  *
6  * Second author: Andrew Stanley-Jones.
7  * Copyright (c) 2000-2002 SBE Corp. (www.sbei.com).
8  * All rights reserved.
9  *
10  * Third author: David Boggs.
11  * Copyright (c) 2002-2004 David Boggs. (boggs@boggs.palo-alto.ca.us).
12  * All rights reserved.
13  *
14  * BSD License:
15  *
16  * Redistribution and use in source and binary forms, with or without
17  * modification, are permitted provided that the following conditions
18  * are met:
19  * 1. Redistributions of source code must retain the above copyright
20  *    notice, this list of conditions and the following disclaimer.
21  * 2. Redistributions in binary form must reproduce the above copyright
22  *    notice, this list of conditions and the following disclaimer in the
23  *    documentation and/or other materials provided with the distribution.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  *
37  * GNU General Public License:
38  *
39  * This program is free software; you can redistribute it and/or modify it 
40  * under the terms of the GNU General Public License as published by the Free 
41  * Software Foundation; either version 2 of the License, or (at your option) 
42  * any later version.
43  * 
44  * This program is distributed in the hope that it will be useful, but WITHOUT 
45  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
46  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
47  * more details.
48  *
49  * You should have received a copy of the GNU General Public License along with
50  * this program; if not, write to the Free Software Foundation, Inc., 59 
51  * Temple Place - Suite 330, Boston, MA  02111-1307, USA.
52  *
53  * Description:
54  *
55  * This program configures the Unix/Linux device driver for SBE Corp's
56  *  wanADAPT and wanPMC series of Wide Area Network Interface Cards.
57  * There is a man page for this program; go find it.
58  * 
59  * If Netgraph is present (FreeBSD only):
60  *    cc -o lmcconfig -l netgraph -D NETGRAPH lmcconfig.c
61  * If Netgraph is NOT present:
62  *    cc -o lmcconfig lmcconfig.c
63  * Install the executable program in /usr/local/sbin/lmcconfig.
64  *
65  * $FreeBSD$
66  */
67 \f
68 #include <sys/param.h>
69 #include <sys/ioctl.h>
70 #include <sys/socket.h>
71
72 #include <errno.h>
73 #include <inttypes.h>
74 #include <stdio.h>
75 #include <stdlib.h>
76 #include <string.h>
77 #include <strings.h>
78 #include <time.h>
79 #include <unistd.h>
80 #if defined(NETGRAPH)
81 # include <netgraph.h>
82 #endif
83 #include <net/if.h>
84
85 #include <dev/lmc/if_lmc.h>
86
87 /* program global variables */
88 char *          progname;       /* name of this program */
89 char *          ifname;         /* interface name */
90 int             fdcs;           /* ifnet File Desc or ng Ctl Socket */
91 struct status   status;         /* card status (read only) */
92 struct config   config;         /* card configuration (read/write) */
93 int             netgraph = 0;   /* non-zero if netgraph present */
94 int             summary  = 0;   /* print summary at end */
95 int             update   = 0;   /* update driver config */
96 int             verbose  = 0;   /* verbose output */
97 u_int8_t        checksum;       /* gate array ucode file checksum */
98
99 /* Functions currently unused. Keep compiler happy and provide prototypes. */
100 void ioctl_snmp_loop(u_int32_t);
101 void init_srom(int);
102
103 static void
104 usage(void)
105 {
106   fprintf(stderr, "Usage: %s interface [-abBcCdDeEfhiLmMpPsStTuUvVwWxXyYzZ?]\n", progname);
107   fprintf(stderr, "or\n");
108   fprintf(stderr, "Usage: %s interface -1 [-aABcdeEfFgiIlLpPstTuUvxX]\n", progname);
109   fprintf(stderr, "or\n");
110   fprintf(stderr, "Usage: %s interface -3 [-aABcdefFlLsSvV]\n\n", progname);
111   fprintf(stderr, "\tInterface is the interface name, e.g. '%s'\n", ifname);
112 #if defined(NETGRAPH)
113   fprintf(stderr, "\tIf interface name ends with ':' then use netgraph\n");
114 #endif
115   fprintf(stderr, "\t-1 following parameters apply to T1E1 cards\n");
116   fprintf(stderr, "\t-3 following parameters apply to T3 cards\n");
117   fprintf(stderr, "\t-a <number> Set Tx clock source, where:\n");
118   fprintf(stderr, "\t   1:modem Tx clk 2:int src 3:modem Rx Clk 4:ext conn\n");
119   fprintf(stderr, "\t-b Read and print bios rom addrs 0-255\n");
120   fprintf(stderr, "\t-B Write bios rom with address pattern\n");
121   fprintf(stderr, "\t-c Set 16-bit CRC (default)\n");
122   fprintf(stderr, "\t-C Set 32-bit CRC\n");
123   fprintf(stderr, "\t-d Clear driver DEBUG flag\n");
124   fprintf(stderr, "\t-D Set driver DEBUG flag (more log msgs)\n");
125   fprintf(stderr, "\t-e Set DTE mode (default)\n");
126   fprintf(stderr, "\t-E Set DCE mode\n");
127   fprintf(stderr, "\t-f <number> Set synth osc freq in bits/sec\n");
128   fprintf(stderr, "\t-F Set SPPP line protocol to Frame-Relay\n");
129   fprintf(stderr, "\t-h Help: this usage message\n");
130   fprintf(stderr, "\t-i Interface name (eg, lmc0)\n");
131   fprintf(stderr, "\t-L <number> Set loopback: 1:none 2:payload 3:line 4:other\n");
132   fprintf(stderr, "\t   5:inward 6:dual 16:Tulip 17:pins 18:LA/LL 19:LB/RL\n");
133   fprintf(stderr, "\t-m Read and print MII regs\n");
134   fprintf(stderr, "\t-M <addr> <data> Write MII reg\n");
135   fprintf(stderr, "\t-p Read and print PCI config regs\n");
136   fprintf(stderr, "\t-P <addr> <data> Write PCI config reg\n");
137   fprintf(stderr, "\t-s Read and print Tulip SROM\n");
138   fprintf(stderr, "\t-S <number> Initialize Tulip SROM\n");
139   fprintf(stderr, "\t-t Read and print Tulip Control/Status regs\n");
140   fprintf(stderr, "\t-T <addr> <data> Write Tulip Control/status reg\n");
141   fprintf(stderr, "\t-u Reset event counters\n");
142   fprintf(stderr, "\t-U Reset gate array\n");
143   fprintf(stderr, "\t-v Set verbose printout mode\n");
144   fprintf(stderr, "\t-V Print card configuration\n");
145   fprintf(stderr, "\t-w Load gate array from ROM\n");
146   fprintf(stderr, "\t-W <filename> Load gate array from file\n");
147   fprintf(stderr, "\t-x select RAWIP mode and bypass line protocols\n");
148   fprintf(stderr, "\t-X Select line protocols: SPPP, P2P or HDLC\n");
149   fprintf(stderr, "\t-y disable SPPP keep-alive packets\n");
150   fprintf(stderr, "\t-Y enable SPPP keep-alive packets\n");
151   fprintf(stderr, "\t-z Set SPPP line protocol to Cisco-HDLC\n");
152   fprintf(stderr, "\t-Z Set SPPP line protocol to PPP\n");
153
154   fprintf(stderr, "The -1 switch precedes T1/E1 commands.\n");
155   fprintf(stderr, "\t-a <y|b|a> Stop  sending Yellow|Blue|AIS signal\n");
156   fprintf(stderr, "\t-A <y|b|a> Start sending Yellow|Blue|AIS signal\n");
157   fprintf(stderr, "\t-B <number> Send BOP msg 25 times\n");
158   fprintf(stderr, "\t-c <number> Set cable length in meters\n");
159   fprintf(stderr, "\t-d Print status of T1 DSU/CSU\n");
160   fprintf(stderr, "\t-e <number> Set framing format, where:\n");
161   fprintf(stderr, "\t   27:T1-ESF 9:T1-SF 0:E1-FAS 8:E1-FAS+CRC\n");
162   fprintf(stderr, "\t   16:E1-FAS+CAS 24:E1-FAS+CRC+CAS 32:E1-NO-FRAMING\n");
163   fprintf(stderr, "\t-E <32-bit hex number> 1 activates a channel and 0 deactivates it.\n");
164   fprintf(stderr, "\t   Use this to config a link in fractional T1/E1 mode\n");
165   fprintf(stderr, "\t-f Read and print Framer/LIU registers\n");
166   fprintf(stderr, "\t-F <addr> <data> Write Framer/LIU register\n");
167   fprintf(stderr, "\t-g <number> Set receiver gain, where:\n");
168   fprintf(stderr, "\t   0:short range  1:medium range\n");
169   fprintf(stderr, "\t   2:long range   3:extended range\n");
170   fprintf(stderr, "\t   4:auto-set based on cable length\n");
171   fprintf(stderr, "\t-i Send 'CSU Loop Down' inband msg\n");
172   fprintf(stderr, "\t-I Send 'CSU Loop Up' inband msg\n");
173   fprintf(stderr, "\t-l Send 'Line Loop Down' BOP msg\n");
174   fprintf(stderr, "\t-L Send 'Line Loop Up' BOP msg\n");
175   fprintf(stderr, "\t-p Send 'Payload Loop Down' BOP msg\n");
176   fprintf(stderr, "\t-P Send 'Payload Loop Up' BOP msg\n");
177   fprintf(stderr, "\t-s Print status of T1 DSU/CSU\n");
178   fprintf(stderr, "\t-t Stop sending test pattern\n");
179   fprintf(stderr, "\t-T <number> Start sending test pattern, where:\n");
180   fprintf(stderr, "\t    0:unframed 2^11       1:unframed 2^15\n");
181   fprintf(stderr, "\t    2:unframed 2^20       3:unframed 2^23\n");
182   fprintf(stderr, "\t    4:unframed 2^11 w/ZS  5:unframed 2^15 w/ZS\n");
183   fprintf(stderr, "\t    6:unframed QRSS       7:unframed 2^23 w/ZS\n");
184   fprintf(stderr, "\t    8:  framed 2^11       9:  framed 2^15\n");
185   fprintf(stderr, "\t   10:  framed 2^20      11:  framed 2^23\n");
186   fprintf(stderr, "\t   12:  framed 2^11 w/ZS 13:  framed 2^15 w/ZS\n");
187   fprintf(stderr, "\t   14:  framed QRSS      15:  framed 2^23 w/ZS\n");
188   fprintf(stderr, "\t-u <number> Set transmitter pulse shape, where:\n");
189   fprintf(stderr, "\t   0:T1-DSX   0-40m       1:T1-DSX  40-80m\n");
190   fprintf(stderr, "\t   2:T1-DSX  80-120m      3:T1-DSX 120-160m\n");
191   fprintf(stderr, "\t   4:T1-DSX 160-200m      5:E1-G.703 75ohm coax\n");
192   fprintf(stderr, "\t   6:E1-G.703 120ohm TP   7:T1-CSU Long range\n");
193   fprintf(stderr, "\t   8:auto-set based on cable length (T1 only)\n");
194   fprintf(stderr, "\t-U <number> Set line build out where:\n");
195   fprintf(stderr, "\t   0:0dB 1:7.5dB 2:15dB 3:22.5dB\n");
196   fprintf(stderr, "\t   4:auto-set based on cable length\n");
197   fprintf(stderr, "\t-v Set verbose printout mode\n");
198   fprintf(stderr, "\t-x disable Transmitter outputs\n");
199   fprintf(stderr, "\t-X enable  Transmitter outputs\n");
200
201   fprintf(stderr, "The -3 switch precedes T3 commands.\n");
202   fprintf(stderr, "\t-a <y|b|a|i> Stop  sending Yellow|Blue|AIS|Idle signal\n");
203   fprintf(stderr, "\t-A <y|b|a|i> Start sending Yellow|Blue|AIS|Idle signal\n");
204   fprintf(stderr, "\t-B <bopcode> Send BOP msg 10 times\n");
205   fprintf(stderr, "\t-c <number> Set cable length in meters\n");
206   fprintf(stderr, "\t-d Print status of T3 DSU/CSU\n");
207   fprintf(stderr, "\t-e <number> Set T3 frame format, where:\n");
208   fprintf(stderr, "\t   100:C-Bit Parity  101:M13\n");
209   fprintf(stderr, "\t-f Read and print Framer registers\n");
210   fprintf(stderr, "\t-F <addr> <data> Write Framer register\n");
211   fprintf(stderr, "\t-l Send 'Line Loop Down' BOP msg\n");
212   fprintf(stderr, "\t-L Send 'Line Loop Up' BOP msg\n");
213   fprintf(stderr, "\t-s Print status of T3 DSU/CSU\n");
214   fprintf(stderr, "\t-S <number> Set DS3 scrambler mode, where:\n");
215   fprintf(stderr, "\t   1:OFF 2:DigitalLink|Kentrox 3:Larse\n");
216   fprintf(stderr, "\t-v Set verbose printout mode\n");
217   fprintf(stderr, "\t-V <number> Write to T3 VCXO freq control DAC\n");
218 }
219
220 static void
221 call_driver(unsigned long cmd, struct iohdr *iohdr)
222 {
223   int error = 0;
224
225   strncpy(iohdr->ifname, ifname, sizeof(iohdr->ifname));
226   iohdr->cookie = NGM_LMC_COOKIE;
227   iohdr->iohdr = iohdr;
228
229   /* Exchange data with a running device driver. */
230 #if defined(NETGRAPH)
231   if (netgraph)
232     {
233     NgSendMsg(fdcs, ifname, NGM_LMC_COOKIE, cmd, iohdr, IOCPARM_LEN(cmd));
234     if (cmd & IOC_OUT)
235       {
236       int replen = sizeof(struct ng_mesg) + IOCPARM_LEN(cmd);
237       char rep[replen];  /* storage for the reply */
238       struct ng_mesg *reply = (struct ng_mesg *)rep;
239       int rl = NgRecvMsg(fdcs, reply, replen, NULL);
240       if (rl == replen)
241         bcopy(&reply->data, iohdr, IOCPARM_LEN(cmd));
242       else
243         {
244         fprintf(stderr, "%s: NgRecvMsg returned %d bytes, expected %d\n",
245           progname, rl, replen);
246         exit(1);
247         }
248       }
249     }
250   else
251 #endif
252     {
253     if ((error = ioctl(fdcs, cmd, (caddr_t)iohdr)) < 0)
254       {
255       fprintf(stderr, "%s: ioctl() returned error code %d: %s\n",
256        progname, errno, strerror(errno));
257       if (errno == ENETDOWN)
258         printf("Type: 'ifconfig %s up' then try again.\n", ifname);
259       exit(1);
260       }
261     }
262
263   if (iohdr->cookie != NGM_LMC_COOKIE)
264     {
265     fprintf(stderr, "%s: cookie = 0x%08X, expected 0x%08X\n", progname, iohdr->cookie, NGM_LMC_COOKIE);
266     fprintf(stderr, "%s: This version of %s is incompatible with the device driver\n", progname, progname);
267     exit(1);
268     }
269 }
270
271 static u_int32_t
272 read_pci_config(u_int8_t addr)
273 {
274   struct ioctl ioctl;
275
276   ioctl.iohdr.direction = DIR_IOWR;
277   ioctl.iohdr.length = sizeof(struct ioctl);
278   ioctl.cmd = IOCTL_RW_PCI;
279   ioctl.address = addr;
280
281   call_driver(LMCIOCREAD, &ioctl.iohdr);
282
283   return ioctl.data;
284 }
285
286 static void
287 write_pci_config(u_int8_t addr, u_int32_t data)
288 {
289   struct ioctl ioctl;
290
291   ioctl.iohdr.direction = DIR_IOW;
292   ioctl.iohdr.length = sizeof(struct ioctl);
293   ioctl.cmd = IOCTL_RW_PCI;
294   ioctl.address = addr;
295   ioctl.data = data;
296
297   call_driver(LMCIOCWRITE, &ioctl.iohdr);
298 }
299
300 static u_int32_t
301 read_csr(u_int8_t addr)
302 {
303   struct ioctl ioctl;
304
305   ioctl.iohdr.direction = DIR_IOWR;
306   ioctl.iohdr.length = sizeof(struct ioctl);
307   ioctl.cmd = IOCTL_RW_CSR;
308   ioctl.address = addr;
309
310   call_driver(LMCIOCREAD, &ioctl.iohdr);
311
312   return ioctl.data;
313 }
314
315 static void
316 write_csr(u_int8_t addr, u_int32_t data)
317 {
318   struct ioctl ioctl;
319
320   ioctl.iohdr.direction = DIR_IOW;
321   ioctl.iohdr.length = sizeof(struct ioctl);
322   ioctl.cmd = IOCTL_RW_CSR;
323   ioctl.address = addr;
324   ioctl.data = data;
325
326   call_driver(LMCIOCWRITE, &ioctl.iohdr);
327 }
328
329 static u_int16_t
330 read_srom(u_int8_t addr)
331 {
332   struct ioctl ioctl;
333
334   ioctl.iohdr.direction = DIR_IOWR;
335   ioctl.iohdr.length = sizeof(struct ioctl);
336   ioctl.cmd = IOCTL_RW_SROM;
337   ioctl.address = addr;
338
339   call_driver(LMCIOCREAD, &ioctl.iohdr);
340
341   return ioctl.data;
342 }
343
344 static void
345 write_srom(u_int8_t addr, u_int16_t data)
346 {
347   struct ioctl ioctl;
348
349   ioctl.iohdr.direction = DIR_IOW;
350   ioctl.iohdr.length = sizeof(struct ioctl);
351   ioctl.cmd = IOCTL_RW_SROM;
352   ioctl.address = addr;
353   ioctl.data = data;
354
355   call_driver(LMCIOCWRITE, &ioctl.iohdr);
356 }
357
358 static u_int8_t
359 read_bios_rom(u_int32_t addr)
360 {
361   struct ioctl ioctl;
362
363   ioctl.iohdr.direction = DIR_IOWR;
364   ioctl.iohdr.length = sizeof(struct ioctl);
365   ioctl.cmd = IOCTL_RW_BIOS;
366   ioctl.address = addr;
367
368   call_driver(LMCIOCREAD, &ioctl.iohdr);
369
370   return ioctl.data;
371 }
372
373 static void
374 write_bios_rom(u_int32_t addr, u_int8_t data)
375 {
376   struct ioctl ioctl;
377
378   ioctl.iohdr.direction = DIR_IOW;
379   ioctl.iohdr.length = sizeof(struct ioctl);
380   ioctl.cmd = IOCTL_RW_BIOS;
381   ioctl.address = addr;
382   ioctl.data = data;
383
384   call_driver(LMCIOCWRITE, &ioctl.iohdr);
385 }
386
387 static u_int16_t
388 read_mii(u_int8_t addr)
389 {
390   struct ioctl ioctl;
391
392   ioctl.iohdr.direction = DIR_IOWR;
393   ioctl.iohdr.length = sizeof(struct ioctl);
394   ioctl.cmd = IOCTL_RW_MII;
395   ioctl.address = addr;
396
397   call_driver(LMCIOCREAD, &ioctl.iohdr);
398
399   return ioctl.data;
400 }
401
402 static void
403 write_mii(u_int8_t addr, u_int16_t data)
404 {
405   struct ioctl ioctl;
406
407   ioctl.iohdr.direction = DIR_IOW;
408   ioctl.iohdr.length = sizeof(struct ioctl);
409   ioctl.cmd = IOCTL_RW_MII;
410   ioctl.address = addr;
411   ioctl.data = data;
412
413   call_driver(LMCIOCWRITE, &ioctl.iohdr);
414 }
415
416 static unsigned char
417 read_framer(u_int16_t addr)
418 {
419   struct ioctl ioctl;
420
421   ioctl.iohdr.direction = DIR_IOWR;
422   ioctl.iohdr.length = sizeof(struct ioctl);
423   ioctl.cmd = IOCTL_RW_FRAME;
424   ioctl.address = addr;
425
426   call_driver(LMCIOCREAD, &ioctl.iohdr);
427
428   return ioctl.data;
429 }
430
431 static void
432 write_framer(u_int16_t addr, u_int8_t data)
433 {
434   struct ioctl ioctl;
435
436   ioctl.iohdr.direction = DIR_IOW;
437   ioctl.iohdr.length = sizeof(struct ioctl);
438   ioctl.cmd = IOCTL_RW_FRAME;
439   ioctl.address = addr;
440   ioctl.data = data;
441
442   call_driver(LMCIOCWRITE, &ioctl.iohdr);
443 }
444
445 static void
446 write_synth(struct synth synth)
447 {
448   struct ioctl ioctl;
449
450   ioctl.iohdr.direction = DIR_IOW;
451   ioctl.iohdr.length = sizeof(struct ioctl);
452   ioctl.cmd = IOCTL_WO_SYNTH;
453   bcopy(&synth, &ioctl.data, sizeof(synth));
454
455   call_driver(LMCIOCWRITE, &ioctl.iohdr);
456 }
457
458 static void
459 write_dac(u_int16_t data)
460 {
461   struct ioctl ioctl;
462
463   ioctl.iohdr.direction = DIR_IOW;
464   ioctl.iohdr.length = sizeof(struct ioctl);
465   ioctl.cmd = IOCTL_WO_DAC;
466   ioctl.data = data;
467
468   call_driver(LMCIOCWRITE, &ioctl.iohdr);
469 }
470
471 static void
472 reset_xilinx(void)
473 {
474   struct ioctl ioctl;
475
476   ioctl.iohdr.direction = DIR_IOWR;
477   ioctl.iohdr.length = sizeof(struct ioctl);
478   ioctl.cmd = IOCTL_XILINX_RESET;
479
480   call_driver(LMCIOCTL, &ioctl.iohdr);
481 }
482
483 static void
484 load_xilinx_from_rom(void)
485 {
486   struct ioctl ioctl;
487
488   ioctl.iohdr.direction = DIR_IOWR;
489   ioctl.iohdr.length = sizeof(struct ioctl);
490   ioctl.cmd = IOCTL_XILINX_ROM;
491
492   call_driver(LMCIOCTL, &ioctl.iohdr);
493 }
494
495 static void
496 load_xilinx_from_file(char *ucode, u_int32_t len)
497 {
498   struct ioctl ioctl;
499
500   ioctl.iohdr.direction = DIR_IOWR;
501   ioctl.iohdr.length = sizeof(struct ioctl);
502   ioctl.cmd = IOCTL_XILINX_FILE;
503   ioctl.data = len;
504   ioctl.ucode = ucode;
505
506   call_driver(LMCIOCTL, &ioctl.iohdr);
507 }
508
509 static void
510 ioctl_snmp_send(u_int32_t send)
511 {
512   struct ioctl ioctl;
513
514   ioctl.iohdr.direction = DIR_IOWR;
515   ioctl.iohdr.length = sizeof(struct ioctl);
516   ioctl.cmd = IOCTL_SNMP_SEND;
517   ioctl.data = send;
518
519   call_driver(LMCIOCTL, &ioctl.iohdr);
520 }
521
522 void
523 ioctl_snmp_loop(u_int32_t loop)
524 {
525   struct ioctl ioctl;
526
527   ioctl.iohdr.direction = DIR_IOWR;
528   ioctl.iohdr.length = sizeof(struct ioctl);
529   ioctl.cmd = IOCTL_SNMP_LOOP;
530   ioctl.data = loop;
531
532   call_driver(LMCIOCTL, &ioctl.iohdr);
533 }
534
535 static void
536 ioctl_reset_cntrs(void)
537 {
538   struct ioctl ioctl;
539
540   ioctl.iohdr.direction = DIR_IOWR;
541   ioctl.iohdr.length = sizeof(struct ioctl);
542   ioctl.cmd = IOCTL_RESET_CNTRS;
543
544   call_driver(LMCIOCTL, &ioctl.iohdr);
545 }
546
547 static void
548 ioctl_read_config(void)
549 {
550   config.iohdr.direction = DIR_IOWR;
551   config.iohdr.length = sizeof(struct config);
552
553   call_driver(LMCIOCGCFG, &config.iohdr);
554 }
555
556 static void
557 ioctl_write_config(void)
558 {
559   config.iohdr.direction = DIR_IOW;
560   config.iohdr.length = sizeof(struct config);
561
562   call_driver(LMCIOCSCFG, &config.iohdr);
563 }
564
565 static void
566 ioctl_read_status(void)
567 {
568   status.iohdr.direction = DIR_IOWR;
569   status.iohdr.length = sizeof(struct status);
570
571   call_driver(LMCIOCGSTAT, &status.iohdr);
572 }
573
574 static void
575 print_card_name(void)
576 {
577   printf("Card name:\t\t%s\n", ifname);
578 }
579
580 static void
581 print_card_type(void)
582 {
583   printf("Card type:\t\t");
584   switch(status.card_type)
585     {
586     case TLP_CSID_HSSI:
587       printf("HSSI (lmc5200)\n");
588       break;
589     case TLP_CSID_T3:
590       printf("T3 (lmc5245)\n");
591       break;
592     case TLP_CSID_SSI:
593       printf("SSI (lmc1000)\n");
594       break;
595     case TLP_CSID_T1E1:
596       printf("T1E1 (lmc1200)\n");
597       break;
598     case TLP_CSID_HSSIc:
599       printf("HSSI (lmc5200C)\n");
600       break;
601     default:
602       printf("unknown card_type: %d\n", status.card_type);
603       break;
604     }
605 }
606
607 static void
608 print_status(void)
609 {
610   char *status_string;
611
612   if      (status.oper_status == STATUS_UP)
613     status_string = "Up";
614   else if (status.oper_status == STATUS_DOWN)
615     status_string = "Down";
616   else if (status.oper_status == STATUS_TEST)
617     status_string = "Test";
618   else
619     status_string = "Unknown";
620   printf("Link status:\t\t%s\n", status_string);
621 }
622
623 static void
624 print_tx_speed(void)
625 {
626   printf("Tx Speed:\t\t%u\n", status.tx_speed);
627 }
628
629 static void
630 print_debug(void)
631 {
632   if (config.debug != 0)
633     printf("Debug:\t\t\t%s\n", "On");
634 }
635
636 static void
637 print_line_prot(void)
638 {
639   char *on = "On", *off = "Off";
640
641   printf("Line Prot/Pkg:\t\t");
642   switch (status.line_prot)
643     {
644     case 0:
645       printf("NotSet/");
646       break;
647     case PROT_PPP:
648       printf("PPP/");
649       break;
650     case PROT_C_HDLC:
651       printf("Cisco-HDLC/");
652       break;
653     case PROT_FRM_RLY:
654       printf("Frame-Relay/");
655       break;
656     case PROT_IP_HDLC:
657       printf("IP-in-HDLC/");
658       break;
659     case PROT_ETH_HDLC:
660       printf("Ether-in-HDLC/");
661       break;
662     case PROT_X25:
663       printf("X25+LAPB/");
664       break;
665     default:
666       printf("unknown line_prot: %d/", status.line_prot);
667       break;
668     }
669
670   switch (status.line_pkg)
671     {
672     case 0:
673       printf("NotSet\n");
674       break;
675     case PKG_RAWIP:
676       printf("Driver\n");
677       break;
678     case PKG_NG:
679       printf("Netgraph\n");
680       break;
681     case PKG_GEN_HDLC:
682       printf("GenHDLC\n");
683       break;
684     case PKG_SPPP:
685       printf("SPPP\n");
686       break;
687     case PKG_P2P:
688       printf("P2P\n");
689       break;
690     default:
691       printf("unknown line_pkg: %d\n", status.line_pkg);
692       break;
693     }
694
695   if (status.line_pkg == PKG_SPPP)
696     printf("SPPP Keep-alives:\t%s\n",
697      config.keep_alive ? on : off);
698 }
699
700 static void
701 print_crc_len(void)
702 {
703   printf("CRC length:\t\t");
704   if (config.crc_len == CFG_CRC_0)
705     printf("no CRC\n");
706   else if (config.crc_len == CFG_CRC_16)
707     printf("16 bits\n");
708   else if (config.crc_len == CFG_CRC_32)
709     printf("32 bits\n");
710   else
711     printf("bad crc_len: %d\n", config.crc_len);
712 }
713
714 static void
715 print_loop_back(void)
716 {
717   printf("Loopback:\t\t");
718   switch (config.loop_back)
719     {
720     case CFG_LOOP_NONE:
721       printf("None\n");
722       break;
723     case CFG_LOOP_PAYLOAD:
724       printf("Outward thru framer (payload loop)\n");
725       break;
726     case CFG_LOOP_LINE:
727       printf("Outward thru line interface (line loop)\n");
728       break;
729     case CFG_LOOP_OTHER:
730       printf("Inward thru line interface\n");
731       break;
732     case CFG_LOOP_INWARD:
733       printf("Inward thru framer\n");
734       break;
735     case CFG_LOOP_DUAL:
736       printf("Inward & outward (dual loop)\n");
737       break;
738     case CFG_LOOP_TULIP:
739       printf("Inward thru Tulip chip\n");
740       break;
741     case CFG_LOOP_PINS:
742       printf("Inward thru drvrs/rcvrs\n");
743       break;
744     case CFG_LOOP_LL:
745       printf("LA/LL asserted\n");
746       break;
747     case CFG_LOOP_RL:
748       printf("LB/RL asserted\n");
749       break;
750     default:
751       printf("unknown loop_back: %d\n", config.loop_back);
752       break;
753     }
754 }
755
756 static void
757 print_tx_clk_src(void)
758 {
759   printf("Tx Clk src:\t\t");
760   switch (config.tx_clk_src)
761     {
762     case CFG_CLKMUX_ST:
763       printf("Tx Clk from modem\n");
764       break;
765     case CFG_CLKMUX_INT:
766       printf("Internal source\n");
767       break;
768     case CFG_CLKMUX_RT:
769       printf("Rx Clk from modem (loop timed)\n");
770       break;
771     case CFG_CLKMUX_EXT:
772       printf("External connector\n");
773       break;
774     default:
775       printf("unknown tx_clk_src: %d\n", config.tx_clk_src);
776       break;
777     }
778 }
779
780 static void
781 print_format(void)
782 {
783   printf("Format-Frame/Code:\t");
784   switch (config.format)
785     {
786     case CFG_FORMAT_T1SF:
787       printf("T1-SF/AMI\n");
788       break;
789     case CFG_FORMAT_T1ESF:
790       printf("T1-ESF/B8ZS\n");
791       break;
792     case CFG_FORMAT_E1FAS:
793       printf("E1-FAS/HDB3\n");
794       break;
795     case CFG_FORMAT_E1FASCRC:
796       printf("E1-FAS+CRC/HDB3\n");
797       break;
798     case CFG_FORMAT_E1FASCAS:
799       printf("E1-FAS+CAS/HDB3\n");
800       break;
801     case CFG_FORMAT_E1FASCRCCAS:
802       printf("E1-FAS+CRC+CAS/HDB3\n");
803       break;
804     case CFG_FORMAT_E1NONE:
805       printf("E1-NOFRAMING/HDB3\n");
806       break;
807     case CFG_FORMAT_T3CPAR:
808       printf("T3-CParity/B3ZS\n");
809       break;
810     case CFG_FORMAT_T3M13:
811       printf("T3-M13/B3ZS\n");
812       break;
813     default:
814       printf("unknown format: %d\n", config.format);
815       break;
816     }
817 }
818
819 static void
820 print_dte_dce(void)
821 {
822   printf("DTE or DCE:\t\t");
823   switch(config.dte_dce)
824     {
825     case CFG_DTE:
826       printf("DTE (receiving TxClk)\n");
827       break;
828     case CFG_DCE:
829       printf("DCE (driving TxClk)\n");
830       break;
831     default:
832       printf("unknown dte_dce: %d\n", config.dte_dce);
833       break;
834     }
835 }
836
837 static void
838 print_synth_freq(void)
839 {
840   double Fref = 20e6;
841   double Fout, Fvco;
842
843   /* decode the synthesizer params */
844   Fvco = (Fref * (config.synth.n<<(3*config.synth.v)))/config.synth.m;
845   Fout =  Fvco / (1<<(config.synth.x+config.synth.r+config.synth.prescale));
846
847   printf("Synth freq:\t\t%.0f\n", Fout);
848 }
849
850 static void
851 synth_freq(unsigned long target)
852 {
853   unsigned int n, m, v, x, r;
854   double Fout, Fvco, Ftarg;
855   double newdiff, olddiff;
856   double bestF=0.0, bestV=0.0;
857   unsigned prescale = (target < 50000) ? 9:4;
858
859   Ftarg = target<<prescale;
860   for (n=3; n<=127; n++)
861     for (m=3; m<=127; m++)
862       for (v=0;  v<=1;  v++)
863         for (x=0;  x<=3;  x++)
864           for (r=0;  r<=3;  r++)
865             {
866             Fvco = (SYNTH_FREF * (n<<(3*v)))/m;
867             if (Fvco < SYNTH_FMIN || Fvco > SYNTH_FMAX) continue;
868             Fout =  Fvco / (1<<(x+r));
869             if (Fout >= Ftarg)
870               newdiff = Fout - Ftarg;
871             else
872               newdiff = Ftarg - Fout;
873             if (bestF >= Ftarg)
874               olddiff = bestF - Ftarg;
875             else
876               olddiff = Ftarg - bestF;
877             if ((newdiff < olddiff) ||
878                ((newdiff == olddiff) && (Fvco < bestV)))
879               {
880               config.synth.n = n;
881               config.synth.m = m;
882               config.synth.v = v;
883               config.synth.x = x;
884               config.synth.r = r;
885               config.synth.prescale = prescale;
886               bestF = Fout;
887               bestV = Fvco;
888               }
889             }
890 #if 0
891   printf("Fbest=%.0f, Ftarg=%u, Fout=%.0f\n", bestF>>prescale, target, bestF);
892   printf("N=%u, M=%u, V=%u, X=%u, R=%u\n", config.synth.n,
893    config.synth.m, config.synth.v, config.synth.x, config.synth.r);
894 #endif
895 }
896
897 static void
898 print_cable_len(void)
899 {
900   printf("Cable length:\t\t%d meters\n", config.cable_len);
901 }
902
903 static void
904 print_cable_type(void)
905 {
906   printf("Cable type:\t\t");
907   if (status.cable_type > 7)
908     printf("unknown cable_type: %d\n", status.cable_type);
909   else
910     printf("%s\n", ssi_cables[status.cable_type]);
911 }
912
913 static void
914 print_time_slots(void)
915 {
916   printf("TimeSlot [31-0]:\t0x%08X\n", config.time_slots);
917 }
918
919 static void
920 print_scrambler(void)
921 {
922   printf("Scrambler:\t\t");
923   if (config.scrambler == CFG_SCRAM_OFF)
924     printf("off\n");
925   else if (config.scrambler == CFG_SCRAM_DL_KEN)
926     printf("DigLink/Kentrox: X^43+1\n");
927   else if (config.scrambler == CFG_SCRAM_LARS)
928     printf("Larse: X^20+X^17+1 w/28ZS\n");
929   else
930     printf("unknown scrambler: %d\n", config.scrambler);
931 }
932
933 static double
934 vga_dbs(u_int8_t vga)
935 {
936   if  (vga <  0x0F)                   return  0.0;
937   if ((vga >= 0x0F) && (vga <= 0x1B)) return  0.0 + 0.77 * (vga - 0x0F);
938   if ((vga >= 0x1C) && (vga <= 0x33)) return 10.0 + 1.25 * (vga - 0x1C);
939   if ((vga >= 0x34) && (vga <= 0x39)) return 40.0 + 1.67 * (vga - 0x34);
940   if ((vga >= 0x3A) && (vga <  0x3F)) return 50.0 + 2.80 * (vga - 0x3A);
941                                       return 64.0;
942 }
943
944 static void
945 print_rx_gain(void)
946 {
947   printf("Rx gain max:\t\t");
948
949   if (config.rx_gain == CFG_GAIN_AUTO)
950     printf("auto-set to %02.1f dB\n",
951      vga_dbs(read_framer(Bt8370_VGA_MAX) & 0x3F));
952   else
953     printf("up to %02.1f dB\n", vga_dbs(config.rx_gain));
954 }
955
956 static void
957 print_tx_lbo(void)
958 {
959   u_int8_t saved_lbo = config.tx_lbo;
960
961   printf("LBO = ");
962   if (config.tx_lbo == CFG_LBO_AUTO)
963     {
964     config.tx_lbo = read_framer(Bt8370_TLIU_CR) & 0x30;
965     printf("auto-set to ");
966     }
967
968   switch (config.tx_lbo)
969     {
970     case CFG_LBO_0DB:
971       printf("0 dB\n");
972       break;
973     case CFG_LBO_7DB:
974       printf("7.5 dB\n");
975       break;
976     case CFG_LBO_15DB:
977       printf("15 dB\n");
978       break;
979     case CFG_LBO_22DB:
980       printf("22.5 dB\n");
981       break;
982     default:
983       printf("unknown tx_lbo: %d\n", config.tx_lbo);
984       break;
985     }
986
987   if (saved_lbo == CFG_LBO_AUTO)
988     config.tx_lbo = saved_lbo;
989 }
990
991 static void
992 print_tx_pulse(void)
993 {
994   u_int8_t saved_pulse = config.tx_pulse;
995
996   printf("Tx pulse shape:\t\t");
997   if (config.tx_pulse == CFG_PULSE_AUTO)
998     {
999     config.tx_pulse = read_framer(Bt8370_TLIU_CR) & 0x0E;
1000     printf("auto-set to ");
1001     }
1002
1003   switch (config.tx_pulse)
1004     {
1005     case CFG_PULSE_T1DSX0:
1006       printf("T1-DSX: 0 to 40 meters\n");
1007       break;
1008     case CFG_PULSE_T1DSX1:
1009       printf("T1-DSX: 40 to 80 meters\n");
1010       break;
1011     case CFG_PULSE_T1DSX2:
1012       printf("T1-DSX: 80 to 120 meters\n");
1013       break;
1014     case CFG_PULSE_T1DSX3:
1015       printf("T1-DSX: 120 to 160 meters\n");
1016       break;
1017     case CFG_PULSE_T1DSX4:
1018       printf("T1-DSX: 160 to 200 meters\n");
1019       break;
1020     case CFG_PULSE_E1COAX:
1021       printf("E1: Twin Coax\n");
1022       break;
1023     case CFG_PULSE_E1TWIST:
1024       printf("E1: Twisted Pairs\n");
1025       break;
1026     case CFG_PULSE_T1CSU:
1027       printf("T1-CSU; ");
1028       print_tx_lbo();
1029       break;
1030     default:
1031       printf("unknown tx_pulse: %d\n", config.tx_pulse);
1032       break;
1033     }
1034
1035   if (saved_pulse == CFG_PULSE_AUTO)
1036     config.tx_pulse = saved_pulse;
1037 }
1038
1039 static void
1040 print_ssi_sigs(void)
1041 {
1042   u_int32_t mii16 = status.snmp.ssi.sigs;
1043   char *on = "On", *off = "Off";
1044
1045   printf("Modem signals:\t\tDTR=%s DSR=%s RTS=%s CTS=%s\n",
1046    (mii16 & MII16_SSI_DTR) ? on : off,
1047    (mii16 & MII16_SSI_DSR) ? on : off,
1048    (mii16 & MII16_SSI_RTS) ? on : off,
1049    (mii16 & MII16_SSI_CTS) ? on : off);
1050   printf("Modem signals:\t\tDCD=%s RI=%s LL=%s RL=%s TM=%s\n",
1051    (mii16 & MII16_SSI_DCD) ? on : off,
1052    (mii16 & MII16_SSI_RI)  ? on : off,
1053    (mii16 & MII16_SSI_LL)  ? on : off,
1054    (mii16 & MII16_SSI_RL)  ? on : off,
1055    (mii16 & MII16_SSI_TM)  ? on : off);
1056 }
1057
1058 static void
1059 print_hssi_sigs(void)
1060 {
1061   u_int32_t mii16 = status.snmp.hssi.sigs;
1062   char *on = "On", *off = "Off";
1063
1064   printf("Modem signals:\t\tTA=%s CA=%s\n",
1065    (mii16 & MII16_HSSI_TA) ? on : off,
1066    (mii16 & MII16_HSSI_CA) ? on : off);
1067   printf("Modem signals:\t\tLA=%s LB=%s LC=%s TM=%s\n",
1068    (mii16 & MII16_HSSI_LA) ? on : off,
1069    (mii16 & MII16_HSSI_LB) ? on : off,
1070    (mii16 & MII16_HSSI_LC) ? on : off,
1071    (mii16 & MII16_HSSI_TM) ? on : off);
1072 }
1073
1074 static void
1075 print_events(void)
1076 {
1077   const char *reset_time;
1078   time_t now;
1079
1080   now = time(NULL);
1081   printf("Current time:\t\t%s", ctime(&now));
1082   if (status.cntrs.reset_time.tv_sec < 1000)
1083     reset_time = "Never\n";
1084   else
1085     reset_time = ctime(&status.cntrs.reset_time.tv_sec);
1086   printf("Cntrs reset:\t\t%s", reset_time);
1087
1088   if (status.cntrs.ibytes)     printf("Rx bytes:\t\t%ju\n",    (uintmax_t)status.cntrs.ibytes);
1089   if (status.cntrs.obytes)     printf("Tx bytes:\t\t%ju\n",    (uintmax_t)status.cntrs.obytes);
1090   if (status.cntrs.ipackets)   printf("Rx packets:\t\t%ju\n",  (uintmax_t)status.cntrs.ipackets);
1091   if (status.cntrs.opackets)   printf("Tx packets:\t\t%ju\n",  (uintmax_t)status.cntrs.opackets);
1092   if (status.cntrs.ierrors)    printf("Rx errors:\t\t%u\n",    status.cntrs.ierrors);
1093   if (status.cntrs.oerrors)    printf("Tx errors:\t\t%u\n",    status.cntrs.oerrors);
1094   if (status.cntrs.idiscards)  printf("Rx discards:\t\t%u\n",  status.cntrs.idiscards);
1095   if (status.cntrs.odiscards)  printf("Tx discards:\t\t%u\n",  status.cntrs.odiscards);
1096   if (status.cntrs.fifo_over)  printf("Rx fifo overruns:\t%u\n", status.cntrs.fifo_over);
1097   if (status.cntrs.fifo_under) printf("Tx fifo underruns:\t%u\n", status.cntrs.fifo_under);
1098   if (status.cntrs.missed)     printf("Rx missed:\t\t%u\n",    status.cntrs.missed);
1099   if (status.cntrs.overruns)   printf("Rx overruns:\t\t%u\n",  status.cntrs.overruns);
1100   if (status.cntrs.fdl_pkts)   printf("Rx FDL pkts:\t\t%u\n",  status.cntrs.fdl_pkts);
1101   if (status.cntrs.crc_errs)   printf("Rx CRC:\t\t\t%u\n",     status.cntrs.crc_errs);
1102   if (status.cntrs.lcv_errs)   printf("Rx line code:\t\t%u\n", status.cntrs.lcv_errs);
1103   if (status.cntrs.frm_errs)   printf("Rx F-bits:\t\t%u\n",    status.cntrs.frm_errs);
1104   if (status.cntrs.febe_errs)  printf("Rx FEBE:\t\t%u\n",      status.cntrs.febe_errs);
1105   if (status.cntrs.par_errs)   printf("Rx P-parity:\t\t%u\n",  status.cntrs.par_errs);
1106   if (status.cntrs.cpar_errs)  printf("Rx C-parity:\t\t%u\n",  status.cntrs.cpar_errs);
1107   if (status.cntrs.mfrm_errs)  printf("Rx M-bits:\t\t%u\n",    status.cntrs.mfrm_errs);
1108   if (config.debug)
1109     { /* These events are hard to explain and may worry users, */
1110     if (status.cntrs.rxdma)     printf("Rx no buffs:\t\t%u\n", status.cntrs.rxdma);
1111     if (status.cntrs.txdma)     printf("Tx no descs:\t\t%u\n", status.cntrs.txdma);
1112     if (status.cntrs.lck_watch) printf("Lck watch:\t\t%u\n",   status.cntrs.lck_watch);
1113     if (status.cntrs.lck_ioctl) printf("Lck ioctl:\t\t%u\n",   status.cntrs.lck_ioctl);
1114     if (status.cntrs.lck_intr)  printf("Lck intr:\t\t%u\n",    status.cntrs.lck_intr);
1115     }
1116 }
1117
1118 static void
1119 print_summary(void)
1120 {
1121   switch(status.card_type)
1122     {
1123     case TLP_CSID_HSSI:
1124       {
1125       print_card_name();
1126       print_card_type();
1127       print_debug();
1128       print_status();
1129       print_tx_speed();
1130       print_line_prot();
1131       print_crc_len();
1132       print_loop_back();
1133       print_tx_clk_src();
1134       print_hssi_sigs();
1135       print_events();
1136       break;
1137       }
1138     case TLP_CSID_T3:
1139       {
1140       print_card_name();
1141       print_card_type();
1142       print_debug();
1143       print_status();
1144       print_tx_speed();
1145       print_line_prot();
1146       print_crc_len();
1147       print_loop_back();
1148       print_format();
1149       print_cable_len();
1150       print_scrambler();
1151       print_events();
1152       break;
1153       }
1154     case TLP_CSID_SSI:
1155       {
1156       print_card_name();
1157       print_card_type();
1158       print_debug();
1159       print_status();
1160       print_tx_speed();
1161       print_line_prot();
1162       print_crc_len();
1163       print_loop_back();
1164       print_dte_dce();
1165       print_synth_freq();
1166       print_cable_type();
1167       print_ssi_sigs();
1168       print_events();
1169       break;
1170       }
1171     case TLP_CSID_T1E1:
1172       {
1173       print_card_name();
1174       print_card_type();
1175       print_debug();
1176       print_status();
1177       print_tx_speed();
1178       print_line_prot();
1179       print_crc_len();
1180       print_loop_back();
1181       print_tx_clk_src();
1182       print_format();
1183       print_time_slots();
1184       print_cable_len();
1185       print_tx_pulse();
1186       print_rx_gain();
1187       print_events();
1188       break;
1189       }
1190     case TLP_CSID_HSSIc:
1191       {
1192       print_card_name();
1193       print_card_type();
1194       print_debug();
1195       print_status();
1196       print_line_prot();
1197       print_tx_speed();
1198       print_crc_len();
1199       print_loop_back();
1200       print_tx_clk_src();
1201       print_dte_dce();
1202       print_synth_freq();
1203       print_hssi_sigs();
1204       print_events();
1205       break;
1206       }
1207     default:
1208       {
1209       printf("%s: Unknown card type: %d\n", ifname, status.card_type);
1210       break;
1211       }
1212     }
1213 }
1214
1215 static char *
1216 print_t3_bop(int bop_code)
1217 {
1218   switch(bop_code)
1219     {
1220     case 0x00:
1221       return "far end LOF";
1222     case 0x0E:
1223       return "far end LOS";
1224     case 0x16:
1225       return "far end AIS";
1226     case 0x1A:
1227       return "far end IDL";
1228     case 0x07:
1229       return "Line Loopback activate";
1230     case 0x1C:
1231       return "Line Loopback deactivate";
1232     case 0x1B:
1233       return "Entire DS3 line";
1234     default:
1235       return "Unknown BOP code";
1236     }
1237 }
1238
1239 static void
1240 print_t3_snmp(void)
1241 {
1242   printf("SNMP performance data:\n");
1243   printf(" LCV=%d",  status.snmp.t3.lcv);
1244   printf(" LOS=%d", (status.snmp.t3.line & TLINE_LOS)    ? 1 : 0);
1245   printf(" PCV=%d",  status.snmp.t3.pcv);
1246   printf(" CCV=%d",  status.snmp.t3.ccv);
1247   printf(" AIS=%d", (status.snmp.t3.line & TLINE_RX_AIS) ? 1 : 0);
1248   printf(" SEF=%d", (status.snmp.t3.line & T1LINE_SEF)   ? 1 : 0);
1249   printf(" OOF=%d", (status.snmp.t3.line & TLINE_LOF)    ? 1 : 0);
1250   printf("  FEBE=%d", status.snmp.t3.febe);
1251   printf(" RAI=%d", (status.snmp.t3.line & TLINE_RX_RAI) ? 1 : 0);
1252   printf("\n");
1253 }
1254
1255 static void
1256 print_t3_dsu(void)
1257 {
1258   char *no = "No", *yes = "Yes";
1259   u_int16_t mii16 = read_mii(16);
1260   u_int8_t ctl1   = read_framer(T3CSR_CTL1);
1261   u_int8_t ctl8   = read_framer(T3CSR_CTL8);
1262   u_int8_t stat9  = read_framer(T3CSR_STAT9);
1263   u_int8_t ctl12  = read_framer(T3CSR_CTL12);
1264   u_int8_t stat16 = read_framer(T3CSR_STAT16);
1265
1266   printf("Framing:       \t\t%s\n", ctl1   & CTL1_M13MODE    ? "M13" : "CPAR");
1267   print_tx_speed();
1268   printf("Scrambler:     \t\t%s\n", mii16  & MII16_DS3_SCRAM ? yes : no);
1269   printf("Scram poly:    \t\t%s\n", mii16  & MII16_DS3_POLY  ? "X^20" : "X^43");
1270   printf("Cable length   \t\t%s\n", mii16  & MII16_DS3_ZERO  ? "Short" : "Long");
1271   printf("Line    loop:  \t\t%s\n", mii16  & MII16_DS3_LNLBK ? yes : no);
1272   printf("Payload loop:  \t\t%s\n", ctl12  & CTL12_RTPLOOP   ? yes : no);
1273   printf("Frame   loop:  \t\t%s\n", ctl1   & CTL1_3LOOP      ? yes : no);
1274   printf("Host    loop:  \t\t%s\n", mii16  & MII16_DS3_TRLBK ? yes : no);
1275   printf("Transmit RAI:  \t\t%s\n", ctl1   & CTL1_XTX        ? no  : yes);
1276   printf("Receive  RAI   \t\t%s\n", stat16 & STAT16_XERR     ? yes : no);
1277   printf("Transmit AIS:  \t\t%s\n", ctl1   & CTL1_TXAIS      ? yes : no);
1278   printf("Receive  AIS:  \t\t%s\n", stat16 & STAT16_RAIS     ? yes : no);
1279   printf("Transmit IDLE: \t\t%s\n", ctl1   & CTL1_TXIDL      ? yes : no);
1280   printf("Receive  IDLE: \t\t%s\n", stat16 & STAT16_RIDL     ? yes : no);
1281   printf("Transmit BLUE: \t\t%s\n", ctl8   & CTL8_TBLU       ? yes : no);
1282   printf("Receive  BLUE: \t\t%s\n", stat9  & STAT9_RBLU      ? yes : no);
1283   printf("Loss of Signal:\t\t%s\n", stat16 & STAT16_RLOS     ? yes : no);
1284   printf("Loss of Frame: \t\t%s\n", stat16 & STAT16_ROOF     ? yes : no);
1285   printf("Sev Err Frms:  \t\t%s\n", stat16 & STAT16_SEF      ? yes : no);
1286   printf("Code  errors:  \t\t%d\n", read_framer(T3CSR_CVLO) + (read_framer(T3CSR_CVHI)<<8));
1287   printf("C-Par errors:  \t\t%d\n", read_framer(T3CSR_CERR));
1288   printf("P-Par errors:  \t\t%d\n", read_framer(T3CSR_PERR));
1289   printf("F-Bit errors:  \t\t%d\n", read_framer(T3CSR_FERR));
1290   printf("M-Bit errors:  \t\t%d\n", read_framer(T3CSR_MERR));
1291   printf("FarEndBitErrs: \t\t%d\n", read_framer(T3CSR_FEBE));
1292   printf("Last Tx  FEAC msg:\t0x%02X (%s)\n",
1293    read_framer(T3CSR_TX_FEAC)  & 0x3F,
1294    print_t3_bop(read_framer(T3CSR_TX_FEAC) & 0x3F));
1295   printf("Last dbl FEAC msg;\t0x%02X (%s)\n",
1296    read_framer(T3CSR_DBL_FEAC) & 0x3F,
1297    print_t3_bop(read_framer(T3CSR_DBL_FEAC) & 0x3F));
1298   printf("Last Rx  FEAC msg:\t0x%02X (%s)\n",
1299    read_framer(T3CSR_RX_FEAC)  & 0x3F,
1300    print_t3_bop(read_framer(T3CSR_RX_FEAC) & 0x3F));
1301   print_t3_snmp();
1302 }
1303
1304 static void
1305 t3_cmd(int argc, char **argv)
1306 {
1307   int ch;
1308
1309   while ((ch = getopt(argc, argv, "a:A:B:c:de:fF:lLsS:vV:")) != -1)
1310     {
1311     switch (ch)
1312       {
1313       case 'a': /* stop alarms */
1314         {
1315         switch (optarg[0])
1316           {
1317           case 'a': /* Stop sending AIS Signal */
1318             {
1319             write_mii(16,
1320              read_mii(16) & ~MII16_DS3_FRAME);
1321             write_framer(T3CSR_CTL1,
1322              read_framer(T3CSR_CTL1) & ~CTL1_TXAIS);
1323             if (verbose) printf("Stop sending Alarm Indication Signal (AIS)\n");
1324             break;
1325             }
1326           case 'b': /* Stop sending Blue signal */
1327             {
1328             write_mii(16,
1329              read_mii(16) & ~MII16_DS3_FRAME);
1330             write_framer(T3CSR_CTL8,
1331              read_framer(T3CSR_CTL8) & ~CTL8_TBLU);
1332             if (verbose) printf("Stop sending Blue signal\n");
1333             break;
1334             }
1335           case 'i': /* Stop sending IDLE signal */
1336             {
1337             write_framer(T3CSR_CTL1,
1338              read_framer(T3CSR_CTL1) & ~CTL1_TXIDL);
1339             if (verbose) printf("Stop sending IDLE signal\n");
1340             break;
1341             }
1342           case 'y': /* Stop sending Yellow alarm */
1343             {
1344             write_framer(T3CSR_CTL1,
1345              read_framer(T3CSR_CTL1) | CTL1_XTX);
1346             if (verbose) printf("Stop sending Yellow alarm\n");
1347             break;
1348             }
1349           default:
1350             printf("Unknown alarm: %c\n", optarg[0]);
1351             break;
1352           }
1353         break;
1354         }
1355       case 'A': /* start alarms */
1356         {
1357         switch (optarg[0])
1358           {
1359           case 'a': /* Start sending AIS Signal */
1360             {
1361             write_mii(16,
1362              read_mii(16) | MII16_DS3_FRAME);
1363             write_framer(T3CSR_CTL1,
1364              read_framer(T3CSR_CTL1) | CTL1_TXAIS);
1365             if (verbose) printf("Sending AIS signal (framed 1010..)\n");
1366             break;
1367             }
1368           case 'b': /* Start sending Blue signal */
1369             {
1370             write_mii(16,
1371              read_mii(16) | MII16_DS3_FRAME);
1372             write_framer(T3CSR_CTL8,
1373              read_framer(T3CSR_CTL8) | CTL8_TBLU);
1374             if (verbose) printf("Sending Blue signal (unframed all 1s)\n");
1375             break;
1376             }
1377           case 'i': /* Start sending IDLE signal */
1378             {
1379             write_framer(T3CSR_CTL1,
1380              read_framer(T3CSR_CTL1) | CTL1_TXIDL);
1381             if (verbose) printf("Sending IDLE signal (framed 1100..)\n");
1382             break;
1383             }
1384           case 'y': /* Start sending Yellow alarm */
1385             {
1386             write_framer(T3CSR_CTL1,
1387              read_framer(T3CSR_CTL1) & ~CTL1_XTX);
1388             if (verbose) printf("Sending Yellow alarm (X-bits=0)\n");
1389             break;
1390             }
1391           default:
1392             printf("Unknown alarm: %c\n", optarg[0]);
1393             break;
1394           }
1395         break;
1396         }
1397       case 'B': /* send BOP msg */
1398         {
1399         u_int8_t bop = strtoul(optarg, NULL, 0);
1400         write_framer(T3CSR_TX_FEAC,  0xC0 + bop);
1401         if (verbose) printf("Sent '0x%02X' BOP msg 10 times\n", bop);
1402         break;
1403         }
1404       case 'c': /* set cable length */
1405         {
1406         config.cable_len = strtoul(optarg, NULL, 0);
1407         if (verbose) print_cable_len();
1408         update = 1;
1409         break;
1410         }
1411       case 'd': /* DSU status */
1412       case 's': /* deprecated */
1413         {
1414         print_t3_dsu();
1415         break;
1416         }
1417       case 'e': /* set framimg format */
1418         {
1419         config.format = strtoul(optarg, NULL, 0);
1420         if (verbose) print_format();
1421         update = 1;
1422         break;
1423         }
1424       case 'f': /* read and print framer regs */
1425         {
1426         int i;
1427         printf("TXC03401 regs:\n");
1428         printf("     0  1  2  3  4  5  6  7");
1429         for (i=0; i<21; i++)
1430           {
1431           if (i%8 == 0) printf("\n%02X: ", i);
1432           printf("%02X ", read_framer(i));
1433           }
1434         printf("\n\n");
1435         break;
1436         }
1437       case 'F': /* write framer reg */
1438         {
1439         u_int32_t addr = strtoul(optarg, NULL, 0);
1440         u_int32_t data = strtoul(argv[optind++], NULL, 0);
1441         write_framer(addr, data);
1442         if (verbose)
1443           {
1444           data = read_framer(addr);
1445           printf("Write framer register: addr = 0x%02X data = 0x%02X\n", addr, data);
1446           }
1447         break;
1448         }
1449       case 'l': /* send DS3 line loopback deactivate BOP cmd */
1450         {
1451         ioctl_snmp_send(TSEND_RESET);
1452         if (verbose) printf("Sent 'DS3 Line Loopback deactivate' BOP cmd\n");
1453         break;
1454         }
1455       case 'L': /* send DS3 line loopback activate BOP cmd */
1456         {
1457         ioctl_snmp_send(TSEND_LINE);
1458         if (verbose) printf("Sent 'DS3 Line Loopback activate' BOP cmd\n");
1459         break;
1460         }
1461       case 'S': /* set scrambler */
1462         {
1463         config.scrambler = strtoul(optarg, NULL, 0);
1464         if (verbose) print_scrambler();
1465         update = 1;
1466         break;
1467         }
1468       case 'v': /* set verbose mode */
1469         {
1470         verbose = 1;
1471         break;
1472         }
1473       case 'V': /* set T3 freq control DAC */
1474         {
1475         u_int32_t dac = strtoul(optarg, NULL, 0);
1476         write_dac(dac);
1477         if (verbose) printf("VCXO DAC value is %d\n", dac);
1478         break;
1479         }
1480       default:
1481         {
1482         printf("Unknown command char: %c\n", ch);
1483         exit(1);
1484         } /* case */
1485       } /* switch */
1486     } /* while */
1487 } /* proc */
1488
1489 static void
1490 print_test_pattern(int patt)
1491 {
1492   printf("Test Pattern:\t\t");
1493   switch (patt)
1494     {
1495     case 0:
1496       printf("unframed X^11+X^9+1\n");
1497       break;
1498     case 1:
1499       printf("unframed X^15+X^14+1\n");
1500       break;
1501     case 2:
1502       printf("unframed X^20+X^17+1\n");
1503       break;
1504     case 3:
1505       printf("unframed X^23+X^18+1\n");
1506       break;
1507     case 4:
1508       printf("unframed X^11+X^9+1 w/7ZS\n");
1509       break;
1510     case 5:
1511       printf("unframed X^15+X^14+1 w/7ZS\n");
1512       break;
1513     case 6:
1514       printf("unframed X^20+X^17+1 w/14ZS (QRSS)\n");
1515       break;
1516     case 7:
1517       printf("unframed X^23+X^18+1 w/14ZS\n");
1518       break;
1519     case 8:
1520       printf("framed X^11+X^9+1\n");
1521       break;
1522     case 9:
1523       printf("framed X^15+X^14+1\n");
1524       break;
1525     case 10:
1526       printf("framed X^20+X^17+1\n");
1527       break;
1528     case 11:
1529       printf("framed X^23+X^18+1\n");
1530       break;
1531     case 12:;
1532       printf("framed X^11+X^9+1 w/7ZS\n");
1533       break;
1534     case 13:
1535       printf("framed X^15+X^14+1 w/7ZS\n");
1536       break;
1537     case 14:
1538       printf("framed X^20+X^17+1 w/14ZS (QRSS)\n");
1539       break;
1540     case 15:
1541       printf("framed X^23+X^18+1 w/14ZS\n");
1542       break;
1543     }
1544 }
1545
1546 static char *
1547 print_t1_bop(int bop_code)
1548 {
1549   switch(bop_code)
1550     {
1551     case 0x00:
1552       return "Yellow Alarm (far end LOF)";
1553     case 0x07:
1554       return "Line Loop up";
1555     case 0x1C:
1556       return "Line Loop down";
1557     case 0x0A:
1558       return "Payload Loop up";
1559     case 0x19:
1560       return "Payload Loop down";
1561     case 0x09:
1562       return "Network Loop up";
1563     case 0x12:
1564       return "Network Loop down";
1565     default:
1566       return "Unknown BOP code";
1567     }
1568 }
1569
1570 static void
1571 print_far_report(int index)
1572 {
1573   u_int16_t far = status.snmp.t1.prm[index];
1574
1575   printf(" SEQ=%d ", (far & T1PRM_SEQ)>>8);
1576   if      (far & T1PRM_G1) printf("CRC=1");
1577   else if (far & T1PRM_G2) printf("CRC=1 to 5");
1578   else if (far & T1PRM_G3) printf("CRC=5 to 10");
1579   else if (far & T1PRM_G4) printf("CRC=10 to 100");
1580   else if (far & T1PRM_G5) printf("CRC=100 to 319");
1581   else if (far & T1PRM_G6) printf("CRC>=320");
1582   else                     printf("CRC=0");
1583   printf(" SE=%d", (far & T1PRM_SE) ? 1 : 0);
1584   printf(" FE=%d", (far & T1PRM_FE) ? 1 : 0);
1585   printf(" LV=%d", (far & T1PRM_LV) ? 1 : 0);
1586   printf(" SL=%d", (far & T1PRM_SL) ? 1 : 0);
1587   printf(" LB=%d", (far & T1PRM_LB) ? 1 : 0);
1588   printf("\n");
1589 }
1590
1591 static void
1592 print_t1_snmp(void)
1593 {
1594   printf("SNMP Near-end performance data:\n");
1595   printf(" LCV=%d",  status.snmp.t1.lcv);
1596   printf(" LOS=%d", (status.snmp.t1.line & TLINE_LOS)    ? 1 : 0);
1597   printf(" FE=%d",   status.snmp.t1.fe);
1598   printf(" CRC=%d",  status.snmp.t1.crc);
1599   printf(" AIS=%d", (status.snmp.t1.line & TLINE_RX_AIS) ? 1 : 0);
1600   printf(" SEF=%d", (status.snmp.t1.line & T1LINE_SEF)   ? 1 : 0);
1601   printf(" OOF=%d", (status.snmp.t1.line & TLINE_LOF)    ? 1 : 0);
1602   printf("  RAI=%d",(status.snmp.t1.line & TLINE_RX_RAI) ? 1 : 0);
1603   printf("\n");
1604   if (config.format == CFG_FORMAT_T1ESF)
1605     {
1606     printf("ANSI Far-end performance reports:\n");
1607     print_far_report(0);
1608     print_far_report(1);
1609     print_far_report(2);
1610     print_far_report(3);
1611     }
1612 }
1613
1614 static void
1615 print_t1_dsu(void)
1616 {
1617   char *no = "No", *yes = "Yes";
1618   u_int16_t mii16  = read_mii(16);
1619   u_int8_t isr0    = read_framer(Bt8370_ISR0);
1620   u_int8_t loop    = read_framer(Bt8370_LOOP);
1621   u_int8_t vga_max = read_framer(Bt8370_VGA_MAX) & 0x3F;
1622   u_int8_t alm1    = read_framer(Bt8370_ALM1);
1623   u_int8_t alm3    = read_framer(Bt8370_ALM3);
1624   u_int8_t talm    = read_framer(Bt8370_TALM);
1625   u_int8_t tpatt   = read_framer(Bt8370_TPATT);
1626   u_int8_t tpulse  = read_framer(Bt8370_TLIU_CR);
1627   u_int8_t vga;
1628   u_int8_t saved_pulse, saved_lbo;
1629
1630   /* d/c write required before read */
1631   write_framer(Bt8370_VGA, 0);
1632   vga = read_framer(Bt8370_VGA) & 0x3F;
1633
1634   print_format();
1635   print_time_slots();
1636   print_tx_clk_src();
1637   print_tx_speed();
1638
1639   saved_pulse     = config.tx_pulse;
1640   config.tx_pulse = tpulse & 0x0E;
1641   saved_lbo       = config.tx_lbo;
1642   config.tx_lbo   = tpulse & 0x30;
1643   print_tx_pulse();
1644   config.tx_pulse = saved_pulse;
1645   config.tx_lbo   = saved_lbo;
1646
1647   printf("Tx outputs:    \t\t%sabled\n", (mii16 & MII16_T1_XOE) ? "En" : "Dis");
1648   printf("Line impedance:\t\t%s ohms\n", (mii16 & MII16_T1_Z) ? "120" : "100");
1649   printf("Max line loss: \t\t%4.1f dB\n", vga_dbs(vga_max));
1650   printf("Cur line loss: \t\t%4.1f dB\n", vga_dbs(vga));
1651   printf("Invert data:   \t\t%s\n", (mii16 & MII16_T1_INVERT) ? yes : no);
1652   printf("Line    loop:  \t\t%s\n", (loop & LOOP_LINE)    ? yes : no);
1653   printf("Payload loop:  \t\t%s\n", (loop & LOOP_PAYLOAD) ? yes : no);
1654   printf("Framer  loop:  \t\t%s\n", (loop & LOOP_FRAMER)  ? yes : no);
1655   printf("Analog  loop:  \t\t%s\n", (loop & LOOP_ANALOG)  ? yes : no);
1656   printf("Tx AIS:        \t\t%s\n", ((talm & TALM_TAIS) ||
1657    ((talm & TALM_AUTO_AIS) && (alm1 & ALM1_RLOS))) ? yes : no);
1658   printf("Rx AIS:        \t\t%s\n", (alm1 & ALM1_RAIS)  ? yes : no);
1659   if (((config.format & 1)==0) && (config.format != CFG_FORMAT_E1NONE))
1660     {
1661     printf("Tx RAI:        \t\t%s\n", ((talm & TALM_TYEL) ||
1662      ((talm & TALM_AUTO_YEL) && (alm3 & ALM3_FRED))) ? yes : no);
1663     printf("Rx RAI:        \t\t%s\n", (alm1 & ALM1_RYEL)  ? yes : no);
1664     }
1665   if (config.format == CFG_FORMAT_T1ESF)
1666     {
1667     printf("Tx BOP RAI:    \t\t%s\n", (alm1 & ALM1_RLOF)  ? yes : no);
1668     printf("Rx BOP RAI:    \t\t%s\n", (alm1 & ALM1_RMYEL) ? yes : no);
1669     }
1670   if ((config.format & 0x11) == 0x10) /* E1CAS */
1671     {
1672     printf("Rx TS16 AIS:   \t\t%s\n", (alm3 & ALM3_RMAIS) ? yes : no);
1673     printf("Tx TS16 RAI;   \t\t%s\n",
1674      ((talm & TALM_AUTO_MYEL) && (alm3 & ALM3_SRED)) ? yes : no);
1675     }
1676   printf("Rx LOS analog: \t\t%s\n", (alm1 & ALM1_RALOS) ? yes : no);
1677   printf("Rx LOS digital:\t\t%s\n", (alm1 & ALM1_RLOS)  ? yes : no);
1678   printf("Rx LOF:        \t\t%s\n", (alm1 & ALM1_RLOF)  ? yes : no);
1679   printf("Tx QRS:        \t\t%s\n", (tpatt & 0x10)      ? yes : no);
1680   printf("Rx QRS:        \t\t%s\n", (isr0 & 0x10)       ? yes : no);
1681   printf("LCV errors:    \t\t%d\n",
1682    read_framer(Bt8370_LCV_LO)  + (read_framer(Bt8370_LCV_HI)<<8));
1683   if (config.format != CFG_FORMAT_E1NONE)
1684     {
1685     if ((config.format & 1)==0) printf("Far End Block Errors:\t%d\n",
1686      read_framer(Bt8370_FEBE_LO) + (read_framer(Bt8370_FEBE_HI)<<8));
1687     printf("CRC errors:    \t\t%d\n",
1688      read_framer(Bt8370_CRC_LO)  + (read_framer(Bt8370_CRC_HI)<<8));
1689     printf("Frame errors:  \t\t%d\n",
1690      read_framer(Bt8370_FERR_LO) + (read_framer(Bt8370_FERR_HI)<<8));
1691     printf("Sev Err Frms:  \t\t%d\n", read_framer(Bt8370_AERR) & 0x03);
1692     printf("Change of Frm align:\t%d\n",  (read_framer(Bt8370_AERR) & 0x0C)>>2);
1693     printf("Loss of Frame events:\t%d\n", (read_framer(Bt8370_AERR) & 0xF0)>>4);
1694     }
1695   if (config.format == CFG_FORMAT_T1ESF)
1696     {
1697     printf("Last Tx BOP msg:\t0x%02X (%s)\n",
1698      read_framer(Bt8370_TBOP), print_t1_bop(read_framer(Bt8370_TBOP)));
1699     printf("Last Rx BOP msg:\t0x%02X (%s)\n",
1700      read_framer(Bt8370_RBOP), print_t1_bop(read_framer(Bt8370_RBOP)&0x3F));
1701     }
1702   print_t1_snmp();
1703 }
1704
1705 static void
1706 t1_cmd(int argc, char **argv)
1707 {
1708   int ch;
1709
1710   while ((ch = getopt(argc, argv, "a:A:B:c:de:E:fF:g:iIlLpPstT:u:U:vxX")) != -1)
1711     {
1712     switch (ch)
1713       {
1714       case 'a': /* stop alarms */
1715         {
1716         switch (optarg[0])
1717           {
1718           case 'y': /* Stop sending Yellow Alarm */
1719             {
1720             if ((config.format == CFG_FORMAT_T1SF) ||
1721                 (config.format == CFG_FORMAT_E1NONE))
1722               printf("No Yellow alarm for this frame format\n");
1723             else if (config.format == CFG_FORMAT_T1ESF)
1724               write_framer(Bt8370_BOP,  0xE0); /* rbop 25, tbop off */
1725             else
1726               {
1727               u_int8_t talm = read_framer(Bt8370_TALM);
1728               write_framer(Bt8370_TALM, talm & ~TALM_TYEL);
1729               }
1730             if (verbose) printf("Stop sending Yellow alarm\n");
1731             break;
1732             }
1733           case 'a': /* Stop sending AIS */
1734           case 'b': /* Stop sending Blue Alarm */
1735             {
1736             u_int8_t talm = read_framer(Bt8370_TALM);
1737             write_framer(Bt8370_TALM, talm & ~TALM_TAIS);
1738             if (verbose) printf("Stop sending AIS/Blue signal\n");
1739             break;
1740             }
1741           default:
1742             printf("Unknown alarm: %c\n", optarg[0]);
1743           }
1744         break;
1745         }
1746       case 'A': /* start alarms */
1747         {
1748         switch (optarg[0])
1749           {
1750           case 'y': /* Start sending Yellow Alarm */
1751             {
1752             if ((config.format == CFG_FORMAT_T1SF) ||
1753                 (config.format == CFG_FORMAT_E1NONE))
1754               printf("No Yellow alarm for this frame format\n");
1755             else if (config.format == CFG_FORMAT_T1ESF)
1756               {
1757               write_framer(Bt8370_BOP,  0x0F); /* rbop off, tbop cont */
1758               write_framer(Bt8370_TBOP, T1BOP_OOF);
1759               }
1760             else
1761               {
1762               u_int8_t talm = read_framer(Bt8370_TALM);
1763               write_framer(Bt8370_TALM, talm | TALM_TYEL);
1764               }
1765             if (verbose) printf("Sending Yellow alarm\n");
1766             break;
1767             }
1768           case 'a': /* Start sending AIS */
1769           case 'b': /* Start sending Blue Alarm */
1770             {
1771             u_int8_t talm = read_framer(Bt8370_TALM);
1772             write_framer(Bt8370_TALM, talm | TALM_TAIS);
1773             if (verbose) printf("Sending AIS/Blue signal\n");
1774             break;
1775             }
1776           default:
1777             printf("Unknown alarm: %c\n", optarg[0]);
1778           }
1779         break;
1780         }
1781       case 'B': /* send BOP msg */
1782         {
1783         u_int8_t bop = strtoul(optarg, NULL, 0);
1784         if (config.format == CFG_FORMAT_T1ESF)
1785           {
1786           write_framer(Bt8370_BOP, 0x0B); /* rbop off, tbop 25 */
1787           write_framer(Bt8370_TBOP, bop); /* start sending BOP msg */
1788           sleep(1);  /* sending 25 BOP msgs takes about 100 ms. */
1789           write_framer(Bt8370_BOP, 0xE0); /* rbop 25, tbop off */
1790           if (verbose) printf("Sent '0x%02X' BOP msg 25 times\n", bop);
1791           }
1792         else
1793           printf("BOP msgs only work in T1-ESF format\n");
1794         break;
1795         }
1796       case 'c': /* set cable length */
1797         {
1798         config.cable_len = strtoul(optarg, NULL, 0);
1799         if (verbose) print_cable_len();
1800         update = 1;
1801         break;
1802         }
1803       case 'd': /* DSU status */
1804       case 's': /* deprecated */
1805         {
1806         print_t1_dsu();
1807         break;
1808         }
1809       case 'e': /* set framimg format */
1810         {
1811         config.format = strtoul(optarg, NULL, 0);
1812         if (verbose) print_format();
1813         update = 1;
1814         break;
1815         }
1816       case 'E': /* set time slots */
1817         {
1818         config.time_slots = strtoul(optarg, NULL, 16);
1819         if (verbose) print_time_slots();
1820         update = 1;
1821         break;
1822         }
1823       case 'f': /* read and print framer regs */
1824         {
1825         int i;
1826         printf("Bt8370 regs:\n");
1827         printf("     0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F");
1828         for (i=0; i<512; i++)
1829           {
1830           if (i%16 == 0) printf("\n%03X: ", i);
1831           printf("%02X ", read_framer(i));
1832           }
1833         printf("\n\n");
1834         break;
1835         }
1836       case 'F': /* write framer reg */
1837         {
1838         u_int32_t addr = strtoul(optarg, NULL, 0);
1839         u_int32_t data = strtoul(argv[optind++], NULL, 0);
1840         write_framer(addr, data);
1841         if (verbose)
1842           {
1843           data = read_framer(addr);
1844           printf("Write framer register: addr = 0x%02X data = 0x%02X\n", addr, data);
1845           }
1846         break;
1847         }
1848       case 'g': /* set receiver gain */
1849         {
1850         config.rx_gain = strtoul(optarg, NULL, 0);
1851         if (verbose) print_rx_gain();
1852         update = 1;
1853         break;
1854         }
1855       case 'i': /* send CSU loopback deactivate inband cmd */
1856         {
1857         if (config.format == CFG_FORMAT_T1SF)
1858           {
1859           if (verbose) printf("Sending 'CSU loop down' inband cmd for 10 secs...");
1860           ioctl_snmp_send(TSEND_RESET);
1861           sleep(10);
1862           ioctl_snmp_send(TSEND_NORMAL);
1863           if (verbose) printf("done\n");
1864           }
1865         else
1866           printf("Inband loopback cmds only work in T1-SF format");
1867         break;
1868         }
1869       case 'I': /* send CSU loopback activate inband cmd */
1870         {
1871         if (config.format == CFG_FORMAT_T1SF)
1872           {
1873           if (verbose) printf("Sending 'CSU loop up' inband cmd for 10 secs...");
1874           ioctl_snmp_send(TSEND_LINE);
1875           sleep(10);
1876           ioctl_snmp_send(TSEND_NORMAL);
1877           if (verbose) printf("done\n");
1878           }
1879         else
1880           printf("Inband loopback cmds only work in T1-SF format");
1881         break;
1882         }
1883       case 'l': /* send line loopback deactivate BOP msg */
1884         {
1885         if (config.format == CFG_FORMAT_T1ESF)
1886           {
1887           ioctl_snmp_send(TSEND_RESET);
1888           if (verbose) printf("Sent 'Line Loop Down' BOP cmd\n");
1889           }
1890         else
1891           printf("BOP msgs only work in T1-ESF format\n");
1892         break;
1893         }
1894       case 'L': /* send line loopback activate BOP msg */
1895         {
1896         if (config.format == CFG_FORMAT_T1ESF)
1897           {
1898           ioctl_snmp_send(TSEND_LINE);
1899           if (verbose) printf("Sent 'Line Loop Up' BOP cmd\n");
1900           }
1901         else
1902           printf("BOP msgs only work in T1-ESF format\n");
1903         break;
1904         }
1905       case 'p': /* send payload loopback deactivate BOP msg */
1906         {
1907         if (config.format == CFG_FORMAT_T1ESF)
1908           {
1909           ioctl_snmp_send(TSEND_RESET);
1910           if (verbose) printf("Sent 'Payload Loop Down' BOP cmd\n");
1911           }
1912         else
1913           printf("BOP msgs only work in T1-ESF format\n");
1914         break;
1915         }
1916       case 'P': /* send payload loopback activate BOP msg */
1917         {
1918         if (config.format == CFG_FORMAT_T1ESF)
1919           {
1920           ioctl_snmp_send(TSEND_PAYLOAD);
1921           if (verbose) printf("Sent 'Payload Loop Up' BOP cmd\n");
1922           }
1923         else
1924           printf("BOP msgs only work in T1-ESF format\n");
1925         break;
1926         }
1927       case 't': /* stop sending test pattern */
1928         {
1929         ioctl_snmp_send(TSEND_NORMAL);
1930         if (verbose) printf("Stop sending test pattern\n");
1931         break;
1932         }
1933       case 'T': /* start sending test pattern */
1934         {
1935         u_int8_t patt = strtoul(optarg, NULL, 0);
1936         write_framer(Bt8370_TPATT, 0x10 + patt);
1937         write_framer(Bt8370_RPATT, 0x30 + patt);
1938         if (verbose) print_test_pattern(patt);
1939         break;
1940         }
1941       case 'u': /* set transmit pulse shape */
1942         {
1943         config.tx_pulse = strtoul(optarg, NULL, 0);
1944         if (verbose) print_tx_pulse();
1945         update = 1;
1946         break;
1947         }
1948       case 'U': /* set tx line build-out */
1949         {
1950         if (config.tx_pulse == CFG_PULSE_T1CSU)
1951           {
1952           config.tx_lbo = strtoul(optarg, NULL, 0);
1953           if (verbose) print_tx_pulse();
1954           update = 1;
1955           }
1956         else
1957           printf("LBO only meaningful if Tx Pulse is T1CSU\n");
1958         break;
1959         }
1960       case 'v': /* set verbose mode */
1961         {
1962         verbose = 1;
1963         break;
1964         }
1965       case 'x': /* disable transmitter outputs */
1966         {
1967         write_mii(16, read_mii(16) & ~MII16_T1_XOE);
1968         if (verbose) printf("Transmitter outputs disabled\n");
1969         break;
1970         }
1971       case 'X': /* enable transmitter outputs */
1972         {
1973         write_mii(16, read_mii(16) |  MII16_T1_XOE);
1974         if (verbose) printf("Transmitter outputs enabled\n");
1975         break;
1976         }
1977       default:
1978         {
1979         printf("Unknown command char: %c\n", ch);
1980         exit(1);
1981         } /* case */
1982       } /* switch */
1983     } /* while */
1984 } /* proc */
1985
1986 /* used when reading Motorola S-Record format ROM files */
1987 static unsigned char
1988 read_hex(FILE *f)
1989 {
1990   unsigned char a, b, c;
1991   for (a=0, b=0; a<2; a++)
1992     {
1993     c = fgetc(f);
1994     c -= 48;
1995     if (c > 9) c -= 7;
1996     b = (b<<4) | (c & 0xF);
1997     }
1998   checksum += b;
1999   return b;
2000 }
2001
2002 static void
2003 load_xilinx(char *name)
2004 {
2005   FILE *f;
2006   char *ucode;
2007   int i, length;
2008   int c;
2009
2010   if (verbose) printf("Load firmware from file %s...\n", name);
2011   if ((f = fopen(name, "r")) == 0)
2012     {
2013     perror("Failed to open file");
2014     exit(1);
2015     }
2016
2017   ucode = (char *)malloc(8192); bzero(ucode, 8192);
2018
2019   c = fgetc(f);
2020   if (c == 'X')
2021     { /* Xilinx raw bits file (foo.rbt) */
2022     /* skip seven lines of boiler plate */
2023     for (i=0; i<7;) if ((c=fgetc(f))=='\n') i++;
2024     /* build a dense bit array */
2025     i = length = 0;
2026     while ((c=fgetc(f))!=EOF)
2027       {  /* LSB first */
2028       if (c=='1') ucode[length] |= 1<<i++;
2029       if (c=='0') i++;
2030       if (i==8) { i=0; length++; }
2031       }
2032     }
2033   else if (c == 'S')
2034     { /* Motarola S records (foo.exo) */
2035     int blklen;
2036     length = 0;
2037     ungetc(c, f);
2038     while ((c = fgetc(f)) != EOF)
2039       {
2040       if (c != 'S')
2041         {
2042         printf("I'm confused; I expected an 'S'\n");
2043         exit(1);
2044         }
2045       c = fgetc(f);
2046       if (c == '9') break;
2047       else if (c == '1')
2048         {
2049         checksum = 0;
2050         blklen = read_hex(f) -3;
2051         read_hex(f); /* hi blkaddr */
2052         read_hex(f); /* lo blkaddr */
2053         for (i=0; i<blklen; i++)
2054           ucode[length++] = read_hex(f);
2055         read_hex(f); /* process but ignore checksum */
2056         if (checksum != 0xFF)
2057           {
2058           printf("File checksum error\n");
2059           exit(1);
2060           }
2061         c = fgetc(f); /* throw away eol */
2062         c = fgetc(f); /* throw away eol */
2063         }
2064       else
2065         {
2066         printf("I'm confused; I expected a '1' or a '9'\n");
2067         exit(1);
2068         }
2069       } /* while */
2070     } /* Motorola S-Record */
2071   else
2072     {
2073     printf("Unknown file type giving up\n");
2074     exit(1);
2075     }
2076
2077   load_xilinx_from_file(ucode, length);
2078 }
2079
2080 /* 32-bit CRC calculated right-to-left over 8-bit bytes */
2081 static u_int32_t
2082 crc32(char *bufp, int len)
2083 {
2084   int bit, i;
2085   u_int32_t data;
2086   u_int32_t crc  = 0xFFFFFFFFL;
2087   u_int32_t poly = 0xEDB88320L;
2088
2089   for (i = 0; i < len; i++)
2090     for (data = *bufp++, bit = 0; bit < 8; bit++, data >>= 1)
2091       crc = (crc >> 1) ^ (((crc ^ data) & 1) ? poly : 0);
2092
2093   return crc;
2094 }
2095
2096 /* 8-bit CRC calculated left-to-right over 16-bit words */
2097 static u_int8_t
2098 crc8(u_int16_t *bufp, int len)
2099 {
2100   int bit, i;
2101   u_int16_t data;
2102   u_int8_t crc  = 0xFF;
2103   u_int8_t poly = 0x07;
2104
2105   for (i = 0; i < len; i++)
2106     for (data = *bufp++, bit = 15; bit >= 0; bit--)
2107       {
2108       if ((i==8) && (bit==7)) break;
2109       crc = (crc << 1) ^ ((((crc >> 7) ^ (data >> bit)) & 1) ? poly : 0);
2110       }
2111   return crc;
2112 }
2113
2114 /* HSSI=3, DS3=4, SSI=5, T1E1=6, HSSIc=7, SDSL=8 */
2115 void
2116 init_srom(int board)
2117 {
2118   int i;
2119   u_int16_t srom[64];
2120
2121   /* zero the entire rom */
2122   for (i=0; i<64; i++) srom[i] = 0;
2123
2124   srom[0]  = 0x1376; /* subsys vendor id */
2125   srom[1]  = board ? board : (read_mii(3)>>4 & 0xF) +1;
2126   srom[8]  = crc8(srom, 9);
2127   /* Tulip hardware checks this checksum */
2128   srom[10] = 0x6000; /* ethernet address */
2129   srom[11] = 0x0099; /* ethernet address */
2130   srom[12] = 0x0000; /* ethernet address */
2131   /* srom checksum is low 16 bits of Ethernet CRC-32 */
2132   srom[63] = crc32((char *)srom, 126) ^ 0xFFFFFFFFL;
2133
2134   /* write the SROM */
2135 #if 1 /* really write it */
2136   for (i=0; i<64; i++) write_srom(i, srom[i]);
2137 #else /* print what would be written */
2138   printf("     0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F");
2139   for (i=0; i<64; i++)
2140     {
2141     if (i%8 == 0) printf("\n%02X: ", i<<1);
2142     printf("%02X %02X ", srom[i] & 0xFF, srom[i]>>8);
2143     }
2144   printf("\n\n");
2145 #endif
2146 }
2147
2148 int
2149 main(int argc, char **argv)
2150 {
2151   int i, error, ch;
2152   char *optstring = "13a:bBcCdDeEf:Fhi:L:mM:pP:sS:tT:uUvVwW:xXyYzZ?";
2153
2154   progname = (char *)argv[0];
2155
2156   /* Here is the overall plan:
2157    *  1) Read the interface name from the command line.
2158    *  2) Open the device; decide if netgraph is being used.
2159    *  3) Read the current interface configuration from the driver.
2160    *  4) Read the command line args and carry out their actions.
2161    *  5) Write the modified interface configuration to the driver.
2162    */
2163
2164   /* 1) Read the interface name from the command line. */
2165 #if __linux__
2166   ifname = (argc==1) ? "hdlc0" : (char *) argv[1];
2167 #else
2168   ifname = (argc==1) ? DEVICE_NAME"0" : (char *) argv[1];
2169 #endif
2170
2171   /* 2) Open the device; decide if netgraph is being used, */
2172   /* use netgraph if ifname ends with ":" */
2173   for (i=0; i<16; i++) if (ifname[i] == 0) break;
2174
2175   /* Get a socket type file descriptor. */
2176 #if defined(NETGRAPH)
2177   if ((netgraph = (ifname[i-1] == ':')))
2178     error = NgMkSockNode(NULL, &fdcs, NULL);
2179   else
2180 #endif
2181     error = fdcs = socket(AF_INET, SOCK_DGRAM, 0);
2182   if (error < 0)
2183     {
2184     fprintf(stderr, "%s: %s() failed: %s\n", progname,
2185      netgraph? "NgMkSockNode" : "socket", strerror(errno));
2186     exit(1);
2187     }
2188
2189   /* 3) Read the current interface configuration from the driver. */
2190   ioctl_read_config();
2191   ioctl_read_status();
2192
2193   summary = (argc <= 2);  /* print summary at end */
2194   update  = 0;  /* write to card at end */
2195
2196   /* 4) Read the command line args and carry out their actions. */
2197   optind = 2;
2198   while (((ch = getopt(argc, argv, optstring)) != -1) && (argc > 2))
2199     {
2200     switch (ch)
2201       {
2202       case '1': /* T1 commands */
2203         {
2204         if (verbose) printf("Doing T1 settings\n");
2205         if (status.card_type != TLP_CSID_T1E1)
2206           {
2207           printf("T1 settings only apply to T1E1 cards\n");
2208           exit(1);
2209           }
2210         t1_cmd(argc, argv);
2211         break;
2212         }
2213       case '3': /* T3 commands */
2214         {
2215         if (verbose) printf("Doing T3 settings\n");
2216         if (status.card_type != TLP_CSID_T3)
2217           {
2218           printf("T3 settings only apply to T3 cards\n");
2219           exit(1);
2220           }
2221         t3_cmd(argc, argv);
2222         break;
2223         }
2224       case 'a': /* clock source */
2225         {
2226         if ((status.card_type != TLP_CSID_T1E1) ||
2227             (status.card_type != TLP_CSID_HSSI) ||
2228             (status.card_type != TLP_CSID_HSSIc))
2229           {
2230           if (verbose) print_tx_clk_src();
2231           config.tx_clk_src = strtoul(optarg, NULL, 0);
2232           update = 1;
2233           }
2234         else
2235           printf("txclksrc only applies to T1E1 and HSSI card types\n");
2236         break;
2237         }
2238       case 'b': /* read bios rom */
2239         {
2240         int i;
2241         printf("Bios ROM:\n");
2242         printf("     0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F");
2243         for (i=0; i<256; i++)
2244           {
2245           if (i%16 == 0) printf("\n%02X: ", i);
2246           printf("%02X ", read_bios_rom(i));
2247           }
2248         printf("\n\n");
2249         break;
2250         }
2251       case 'B': /* write bios rom */
2252         {
2253         int i;
2254         for (i=0; i<256; i++) write_bios_rom(i, 255-i);
2255         if (verbose) printf("wrote (0..255) to bios rom addrs (0..255)\n");
2256         break;
2257         }
2258       case 'c': /* set crc_len = 16 */
2259         {
2260         config.crc_len = CFG_CRC_16;
2261         if (verbose) print_crc_len();
2262         update = 1;
2263         break;
2264         }
2265       case 'C': /* set crc_len = 32 */
2266         {
2267         config.crc_len = CFG_CRC_32;
2268         if (verbose) print_crc_len();
2269         update = 1;
2270         break;
2271         }
2272       case 'd': /* clear DEBUG flag */
2273         {
2274         config.debug = 0;
2275         if (verbose) printf("DEBUG flag cleared\n");
2276         update = 1;
2277         break;
2278         }
2279       case 'D': /* set DEBUG flag */
2280         {
2281         config.debug = 1;
2282         if (verbose) printf("DEBUG flag set\n");
2283         update = 1;
2284         break;
2285         }
2286       case 'e': /* set DTE (default) */
2287         {
2288         if ((status.card_type == TLP_CSID_SSI) ||
2289             (status.card_type == TLP_CSID_HSSIc))
2290           {
2291           config.dte_dce = CFG_DTE;
2292           if (verbose) print_dte_dce();
2293           update = 1;
2294           }
2295         else
2296           printf("DTE cmd only applies to SSI & HSSIc cards\n");
2297         break;
2298         }
2299       case 'E': /* set DCE */
2300         {
2301         if ((status.card_type == TLP_CSID_SSI) ||
2302             (status.card_type == TLP_CSID_HSSIc))
2303           {
2304           config.dte_dce = CFG_DCE;
2305           if (verbose) print_dte_dce();
2306           update = 1;
2307           }
2308         else
2309           printf("DCE cmd only applies to SSI & HSSIc cards\n");
2310         break;
2311         }
2312       case 'f': /* set synth osc freq */
2313         {
2314         if ((status.card_type == TLP_CSID_SSI) ||
2315             (status.card_type == TLP_CSID_HSSIc))
2316           {
2317           synth_freq(strtoul(optarg, NULL, 0));
2318           write_synth(config.synth);
2319           if (verbose) print_synth_freq();
2320           }
2321         else
2322           printf("synth osc freq only applies to SSI & HSSIc cards\n");
2323         break;
2324         }
2325       case 'F': /* set SPPP line protocol to Frame-Relay */
2326         {
2327         config.line_prot = PROT_FRM_RLY;
2328         config.keep_alive = 1; /* required for LMI operation */
2329         if (verbose) printf("SPPP line protocol set to Frame-Relay\n");
2330         update = 1;
2331         break;
2332         }
2333       case 'h': /* help */
2334       case '?':
2335         {
2336         usage();
2337         exit(0);
2338         }
2339       case 'i': /* interface name */
2340         {
2341         /* already scanned this */
2342         break;
2343         }
2344       case 'L': /* set loopback modes */
2345         {
2346         config.loop_back = strtoul(optarg, NULL, 0);
2347         if (verbose) print_loop_back();
2348         update = 1;
2349         break;
2350         }
2351       case 'm': /* read and print MII regs */
2352         {
2353         printf("MII regs:\n");
2354         printf("      0    1    2    3    4    5    6    7");
2355         for (i=0; i<32; i++)
2356           {
2357           u_int16_t mii = read_mii(i);
2358           if (i%8 == 0) printf("\n%02X: ", i);
2359           printf("%04X ", mii);
2360           }
2361         printf("\n\n");
2362         break;
2363         }
2364       case 'M': /* write MII reg */
2365         {
2366         u_int32_t addr = strtoul(optarg, NULL, 0);
2367         u_int32_t data = strtoul(argv[optind++], NULL, 0);
2368         write_mii(addr, data);
2369         if (verbose)
2370           {
2371           data = read_mii(addr);
2372           printf("Write mii register: addr = 0x%02X data = 0x%04X\n", addr, data);
2373           }
2374         break;
2375         }
2376       case 'p': /* read and print PCI config regs */
2377         {
2378         int i;
2379         printf("21140A PCI Config regs:\n");
2380         printf("       0        1        2        3");
2381         for (i=0; i<16; i++)
2382           {
2383           if (i%4 == 0) printf("\n%X: ", i);
2384           printf("%08X ", read_pci_config(i<<2));
2385           }
2386         printf("\n\n");
2387         break;
2388         }
2389       case 'P': /* write PCI config reg */
2390         {
2391         u_int32_t addr = strtoul(optarg, NULL, 0);
2392         u_int32_t data = strtoul(argv[optind++], NULL, 0);
2393         write_pci_config(addr, data);
2394         if (verbose)
2395           {
2396           data = read_pci_config(addr);
2397           printf("Write PCI config reg: addr = 0x%02X data = 0x%08X\n", addr, data);
2398           }
2399         break;
2400         }
2401       case 's': /* read and print Tulip SROM */
2402         {
2403         int i;
2404         printf("21140A SROM:\n");
2405         printf("     0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F");
2406         for (i=0; i<64; i++)
2407           {
2408           u_int16_t srom = read_srom(i);
2409           if (i%8 == 0) printf("\n%02X: ", i<<1);
2410           printf("%02X %02X ", srom & 0xFF, srom>>8);
2411           }
2412         printf("\n\n");
2413         break;
2414         }
2415       case 'S': /* write Tulip SROM loc */
2416         {
2417 #if 0  /* write a single location -- not too useful */
2418         u_int32_t addr = strtoul(optarg, NULL, 0);
2419         u_int32_t data = strtoul(argv[optind++], NULL, 0);
2420         write_mii(addr, data);
2421         data = read_mii(addr);
2422         printf("Write SROM: addr = 0x%02X data = 0x%04X\n", addr, data);
2423 #endif
2424 #if 0  /* write the whole SROM -- very dangerous */
2425         init_srom(strtoul(optarg, NULL, 0));
2426 #endif
2427         printf("Caution! Recompile %s to enable this.\n", progname);
2428         break;
2429         }
2430       case 't': /* read and print Tulip CSRs */
2431         {
2432         int i;
2433         printf("21140A CSRs:\n");
2434         printf("       0        1        2        3");
2435         for (i=0; i<16; i++)
2436           {
2437           if (i%4 == 0) printf("\n%X: ", i);
2438           printf("%08X ", read_csr(i));
2439           }
2440         printf("\n\n");
2441         break;
2442         }
2443       case 'T': /* write Tulip CSR */
2444         {
2445         u_int32_t addr = strtoul(optarg, NULL, 0);
2446         u_int32_t data = strtoul(argv[optind++], NULL, 0);
2447         write_csr(addr, data);
2448         if (verbose)
2449           {
2450           data = read_csr(addr);
2451           printf("Write 21140A CSR: addr = 0x%02X data = 0x%08X\n", addr, data);
2452           }
2453         break;
2454         }
2455       case 'u': /* reset event counters */
2456         {
2457         ioctl_reset_cntrs();
2458         if (verbose) printf("Event counters reset\n");
2459         break;
2460         }
2461       case 'U': /* reset gate array */
2462         {
2463         reset_xilinx();
2464         if (verbose) printf("gate array reset\n");
2465         break;
2466         }
2467       case 'v': /* set verbose mode */
2468         {
2469         verbose = 1;
2470         break;
2471         }
2472       case 'V': /* print card configuration */
2473         {
2474         summary = 1;
2475         break;
2476         }
2477       case 'w': /* load gate array microcode from ROM */
2478         {
2479         load_xilinx_from_rom();
2480         if (verbose) printf("gate array configured from on-board ROM\n");
2481         break;
2482         }
2483       case 'W': /* load gate array microcode from file */
2484         {
2485         load_xilinx(optarg);
2486         if (verbose) printf("gate array configured from file %s\n", optarg);
2487         break;
2488         }
2489       case 'x': /* select RAWIP protocol */
2490         {
2491         config.line_pkg = PKG_RAWIP;
2492         if (verbose) printf("RAWIP mode selected\n");
2493         update = 1;
2494         break;
2495         }
2496       case 'X': /* Select in-kernel line protocol packages */
2497         {
2498         config.line_pkg = 0;
2499         if (verbose) printf("line protocol mode selected\n");
2500         update = 1;
2501         break;
2502         }
2503       case 'y': /* disable SPPP keep-alive packets */
2504         {
2505         if ((config.line_pkg  == PKG_SPPP) &&
2506             (config.line_prot == PROT_FRM_RLY))
2507           printf("keep-alives must be ON for Frame-Relay/SPPP\n");
2508         else
2509           {
2510           config.keep_alive = 0;
2511           if (verbose) printf("SPPP keep-alive packets disabled\n");
2512           update = 1;
2513           }
2514         break;
2515         }
2516       case 'Y': /* enable SPPP keep-alive packets */
2517         {
2518         config.keep_alive = 1;
2519         if (verbose) printf("SPPP keep-alive packets enabled\n");
2520         update = 1;
2521         break;
2522         }
2523       case 'z': /* set SPPP line protocol to Cisco HDLC */
2524         {
2525         config.line_prot = PROT_C_HDLC;
2526         config.keep_alive = 1;
2527         if (verbose) printf("SPPP line protocol set to Cisco-HDLC\n");
2528         update = 1;
2529         break;
2530         }
2531       case 'Z': /* set SPPP line protocol to PPP */
2532         {
2533         config.line_prot = PROT_PPP;
2534         config.keep_alive = 0;
2535         if (verbose) printf("SPPP line protocol set to PPP\n");
2536         update = 1;
2537         break;
2538         }
2539       default:
2540         {
2541         printf("Unknown command char: %c\n", ch);
2542         exit(1);
2543         }
2544       } /* switch */
2545     } /* while */
2546
2547   if (summary) print_summary();
2548
2549   /*  5) Write the modified interface configuration to the driver. */
2550   if (update) ioctl_write_config();
2551
2552   exit(0);
2553 }