1150850Sscottl/*
2150850Sscottl * First author: Michael Graff.
3150850Sscottl * Copyright (c) 1997-2000 Lan Media Corp. (www.lanmedia.com).
4150850Sscottl * All rights reserved.
5150850Sscottl *
6150850Sscottl * Second author: Andrew Stanley-Jones.
7150850Sscottl * Copyright (c) 2000-2002 SBE Corp. (www.sbei.com).
8150850Sscottl * All rights reserved.
9150850Sscottl *
10150850Sscottl * Third author: David Boggs.
11150850Sscottl * Copyright (c) 2002-2004 David Boggs. (boggs@boggs.palo-alto.ca.us).
12150850Sscottl * All rights reserved.
13150850Sscottl *
14150850Sscottl * BSD License:
15150850Sscottl *
16150850Sscottl * Redistribution and use in source and binary forms, with or without
17150850Sscottl * modification, are permitted provided that the following conditions
18150850Sscottl * are met:
19150850Sscottl * 1. Redistributions of source code must retain the above copyright
20150850Sscottl *    notice, this list of conditions and the following disclaimer.
21150850Sscottl * 2. Redistributions in binary form must reproduce the above copyright
22150850Sscottl *    notice, this list of conditions and the following disclaimer in the
23150850Sscottl *    documentation and/or other materials provided with the distribution.
24150850Sscottl *
25150850Sscottl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
26150850Sscottl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27150850Sscottl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28150850Sscottl * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
29150850Sscottl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30150850Sscottl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31150850Sscottl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32150850Sscottl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33150850Sscottl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34150850Sscottl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35150850Sscottl * SUCH DAMAGE.
36150850Sscottl *
37150850Sscottl * GNU General Public License:
38150850Sscottl *
39150850Sscottl * This program is free software; you can redistribute it and/or modify it
40150850Sscottl * under the terms of the GNU General Public License as published by the Free
41150850Sscottl * Software Foundation; either version 2 of the License, or (at your option)
42150850Sscottl * any later version.
43150850Sscottl *
44150850Sscottl * This program is distributed in the hope that it will be useful, but WITHOUT
45150850Sscottl * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
46150850Sscottl * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
47150850Sscottl * more details.
48150850Sscottl *
49150850Sscottl * You should have received a copy of the GNU General Public License along with
50150850Sscottl * this program; if not, write to the Free Software Foundation, Inc., 59
51150850Sscottl * Temple Place - Suite 330, Boston, MA  02111-1307, USA.
52150850Sscottl *
53150850Sscottl * Description:
54150850Sscottl *
55150850Sscottl * This program configures the Unix/Linux device driver for SBE Corp's
56150850Sscottl *  wanADAPT and wanPMC series of Wide Area Network Interface Cards.
57150850Sscottl * There is a man page for this program; go find it.
58150850Sscottl *
59150850Sscottl * If Netgraph is present (FreeBSD only):
60150850Sscottl *    cc -o lmcconfig -l netgraph -D NETGRAPH lmcconfig.c
61150850Sscottl * If Netgraph is NOT present:
62150850Sscottl *    cc -o lmcconfig lmcconfig.c
63150850Sscottl * Install the executable program in /usr/local/sbin/lmcconfig.
64150850Sscottl *
65150850Sscottl * $FreeBSD: stable/11/usr.sbin/lmcconfig/lmcconfig.c 360675 2020-05-05 21:01:43Z dim $
66150850Sscottl */
67150850Sscottl
68216600Suqs#include <sys/param.h>
69216600Suqs#include <sys/ioctl.h>
70216600Suqs#include <sys/socket.h>
71216600Suqs
72216600Suqs#include <errno.h>
73216600Suqs#include <inttypes.h>
74150850Sscottl#include <stdio.h>
75150850Sscottl#include <stdlib.h>
76188826Simp#include <string.h>
77188826Simp#include <strings.h>
78216600Suqs#include <time.h>
79150850Sscottl#include <unistd.h>
80150850Sscottl#if defined(NETGRAPH)
81150850Sscottl# include <netgraph.h>
82150850Sscottl#endif
83150850Sscottl#include <net/if.h>
84150850Sscottl
85150850Sscottl#include <dev/lmc/if_lmc.h>
86150850Sscottl
87150850Sscottl/* program global variables */
88150850Sscottlchar *		progname;	/* name of this program */
89150850Sscottlchar *		ifname;		/* interface name */
90150850Sscottlint		fdcs;		/* ifnet File Desc or ng Ctl Socket */
91150850Sscottlstruct status	status;		/* card status (read only) */
92150850Sscottlstruct config	config;		/* card configuration (read/write) */
93150850Sscottlint		netgraph = 0;	/* non-zero if netgraph present */
94150850Sscottlint		summary  = 0;	/* print summary at end */
95150850Sscottlint		update   = 0;	/* update driver config */
96150850Sscottlint             verbose  = 0;	/* verbose output */
97150850Sscottlu_int8_t	checksum;	/* gate array ucode file checksum */
98150850Sscottl
99216600Suqs/* Functions currently unused. Keep compiler happy and provide prototypes. */
100216600Suqsvoid ioctl_snmp_loop(u_int32_t);
101216600Suqsvoid init_srom(int);
102216600Suqs
103216600Suqsstatic void
104216600Suqsusage(void)
105216600Suqs{
106150850Sscottl  fprintf(stderr, "Usage: %s interface [-abBcCdDeEfhiLmMpPsStTuUvVwWxXyYzZ?]\n", progname);
107150850Sscottl  fprintf(stderr, "or\n");
108150850Sscottl  fprintf(stderr, "Usage: %s interface -1 [-aABcdeEfFgiIlLpPstTuUvxX]\n", progname);
109150850Sscottl  fprintf(stderr, "or\n");
110150850Sscottl  fprintf(stderr, "Usage: %s interface -3 [-aABcdefFlLsSvV]\n\n", progname);
111150850Sscottl  fprintf(stderr, "\tInterface is the interface name, e.g. '%s'\n", ifname);
112150850Sscottl#if defined(NETGRAPH)
113150850Sscottl  fprintf(stderr, "\tIf interface name ends with ':' then use netgraph\n");
114150850Sscottl#endif
115150850Sscottl  fprintf(stderr, "\t-1 following parameters apply to T1E1 cards\n");
116150850Sscottl  fprintf(stderr, "\t-3 following parameters apply to T3 cards\n");
117150850Sscottl  fprintf(stderr, "\t-a <number> Set Tx clock source, where:\n");
118150850Sscottl  fprintf(stderr, "\t   1:modem Tx clk 2:int src 3:modem Rx Clk 4:ext conn\n");
119150850Sscottl  fprintf(stderr, "\t-b Read and print bios rom addrs 0-255\n");
120150850Sscottl  fprintf(stderr, "\t-B Write bios rom with address pattern\n");
121150850Sscottl  fprintf(stderr, "\t-c Set 16-bit CRC (default)\n");
122150850Sscottl  fprintf(stderr, "\t-C Set 32-bit CRC\n");
123150850Sscottl  fprintf(stderr, "\t-d Clear driver DEBUG flag\n");
124150850Sscottl  fprintf(stderr, "\t-D Set driver DEBUG flag (more log msgs)\n");
125150850Sscottl  fprintf(stderr, "\t-e Set DTE mode (default)\n");
126150850Sscottl  fprintf(stderr, "\t-E Set DCE mode\n");
127150850Sscottl  fprintf(stderr, "\t-f <number> Set synth osc freq in bits/sec\n");
128150850Sscottl  fprintf(stderr, "\t-F Set SPPP line protocol to Frame-Relay\n");
129150850Sscottl  fprintf(stderr, "\t-h Help: this usage message\n");
130150850Sscottl  fprintf(stderr, "\t-i Interface name (eg, lmc0)\n");
131150850Sscottl  fprintf(stderr, "\t-L <number> Set loopback: 1:none 2:payload 3:line 4:other\n");
132150850Sscottl  fprintf(stderr, "\t   5:inward 6:dual 16:Tulip 17:pins 18:LA/LL 19:LB/RL\n");
133150850Sscottl  fprintf(stderr, "\t-m Read and print MII regs\n");
134150850Sscottl  fprintf(stderr, "\t-M <addr> <data> Write MII reg\n");
135150850Sscottl  fprintf(stderr, "\t-p Read and print PCI config regs\n");
136150850Sscottl  fprintf(stderr, "\t-P <addr> <data> Write PCI config reg\n");
137150850Sscottl  fprintf(stderr, "\t-s Read and print Tulip SROM\n");
138150850Sscottl  fprintf(stderr, "\t-S <number> Initialize Tulip SROM\n");
139150850Sscottl  fprintf(stderr, "\t-t Read and print Tulip Control/Status regs\n");
140150850Sscottl  fprintf(stderr, "\t-T <addr> <data> Write Tulip Control/status reg\n");
141150850Sscottl  fprintf(stderr, "\t-u Reset event counters\n");
142150850Sscottl  fprintf(stderr, "\t-U Reset gate array\n");
143150850Sscottl  fprintf(stderr, "\t-v Set verbose printout mode\n");
144150850Sscottl  fprintf(stderr, "\t-V Print card configuration\n");
145150850Sscottl  fprintf(stderr, "\t-w Load gate array from ROM\n");
146150850Sscottl  fprintf(stderr, "\t-W <filename> Load gate array from file\n");
147150850Sscottl  fprintf(stderr, "\t-x select RAWIP mode and bypass line protocols\n");
148150850Sscottl  fprintf(stderr, "\t-X Select line protocols: SPPP, P2P or HDLC\n");
149150850Sscottl  fprintf(stderr, "\t-y disable SPPP keep-alive packets\n");
150150850Sscottl  fprintf(stderr, "\t-Y enable SPPP keep-alive packets\n");
151150850Sscottl  fprintf(stderr, "\t-z Set SPPP line protocol to Cisco-HDLC\n");
152150850Sscottl  fprintf(stderr, "\t-Z Set SPPP line protocol to PPP\n");
153150850Sscottl
154150850Sscottl  fprintf(stderr, "The -1 switch precedes T1/E1 commands.\n");
155150850Sscottl  fprintf(stderr, "\t-a <y|b|a> Stop  sending Yellow|Blue|AIS signal\n");
156216600Suqs  fprintf(stderr, "\t-A <y|b|a> Start sending Yellow|Blue|AIS signal\n");
157150850Sscottl  fprintf(stderr, "\t-B <number> Send BOP msg 25 times\n");
158150850Sscottl  fprintf(stderr, "\t-c <number> Set cable length in meters\n");
159150850Sscottl  fprintf(stderr, "\t-d Print status of T1 DSU/CSU\n");
160150850Sscottl  fprintf(stderr, "\t-e <number> Set framing format, where:\n");
161150850Sscottl  fprintf(stderr, "\t   27:T1-ESF 9:T1-SF 0:E1-FAS 8:E1-FAS+CRC\n");
162150850Sscottl  fprintf(stderr, "\t   16:E1-FAS+CAS 24:E1-FAS+CRC+CAS 32:E1-NO-FRAMING\n");
163150850Sscottl  fprintf(stderr, "\t-E <32-bit hex number> 1 activates a channel and 0 deactivates it.\n");
164150850Sscottl  fprintf(stderr, "\t   Use this to config a link in fractional T1/E1 mode\n");
165150850Sscottl  fprintf(stderr, "\t-f Read and print Framer/LIU registers\n");
166150850Sscottl  fprintf(stderr, "\t-F <addr> <data> Write Framer/LIU register\n");
167150850Sscottl  fprintf(stderr, "\t-g <number> Set receiver gain, where:\n");
168150850Sscottl  fprintf(stderr, "\t   0:short range  1:medium range\n");
169150850Sscottl  fprintf(stderr, "\t   2:long range   3:extended range\n");
170150850Sscottl  fprintf(stderr, "\t   4:auto-set based on cable length\n");
171150850Sscottl  fprintf(stderr, "\t-i Send 'CSU Loop Down' inband msg\n");
172150850Sscottl  fprintf(stderr, "\t-I Send 'CSU Loop Up' inband msg\n");
173150850Sscottl  fprintf(stderr, "\t-l Send 'Line Loop Down' BOP msg\n");
174150850Sscottl  fprintf(stderr, "\t-L Send 'Line Loop Up' BOP msg\n");
175150850Sscottl  fprintf(stderr, "\t-p Send 'Payload Loop Down' BOP msg\n");
176150850Sscottl  fprintf(stderr, "\t-P Send 'Payload Loop Up' BOP msg\n");
177150850Sscottl  fprintf(stderr, "\t-s Print status of T1 DSU/CSU\n");
178150850Sscottl  fprintf(stderr, "\t-t Stop sending test pattern\n");
179150850Sscottl  fprintf(stderr, "\t-T <number> Start sending test pattern, where:\n");
180150850Sscottl  fprintf(stderr, "\t    0:unframed 2^11       1:unframed 2^15\n");
181150850Sscottl  fprintf(stderr, "\t    2:unframed 2^20       3:unframed 2^23\n");
182150850Sscottl  fprintf(stderr, "\t    4:unframed 2^11 w/ZS  5:unframed 2^15 w/ZS\n");
183150850Sscottl  fprintf(stderr, "\t    6:unframed QRSS       7:unframed 2^23 w/ZS\n");
184150850Sscottl  fprintf(stderr, "\t    8:  framed 2^11       9:  framed 2^15\n");
185150850Sscottl  fprintf(stderr, "\t   10:  framed 2^20      11:  framed 2^23\n");
186150850Sscottl  fprintf(stderr, "\t   12:  framed 2^11 w/ZS 13:  framed 2^15 w/ZS\n");
187150850Sscottl  fprintf(stderr, "\t   14:  framed QRSS      15:  framed 2^23 w/ZS\n");
188150850Sscottl  fprintf(stderr, "\t-u <number> Set transmitter pulse shape, where:\n");
189150850Sscottl  fprintf(stderr, "\t   0:T1-DSX   0-40m       1:T1-DSX  40-80m\n");
190150850Sscottl  fprintf(stderr, "\t   2:T1-DSX  80-120m      3:T1-DSX 120-160m\n");
191150850Sscottl  fprintf(stderr, "\t   4:T1-DSX 160-200m      5:E1-G.703 75ohm coax\n");
192150850Sscottl  fprintf(stderr, "\t   6:E1-G.703 120ohm TP   7:T1-CSU Long range\n");
193150850Sscottl  fprintf(stderr, "\t   8:auto-set based on cable length (T1 only)\n");
194150850Sscottl  fprintf(stderr, "\t-U <number> Set line build out where:\n");
195150850Sscottl  fprintf(stderr, "\t   0:0dB 1:7.5dB 2:15dB 3:22.5dB\n");
196150850Sscottl  fprintf(stderr, "\t   4:auto-set based on cable length\n");
197150850Sscottl  fprintf(stderr, "\t-v Set verbose printout mode\n");
198150850Sscottl  fprintf(stderr, "\t-x disable Transmitter outputs\n");
199150850Sscottl  fprintf(stderr, "\t-X enable  Transmitter outputs\n");
200150850Sscottl
201150850Sscottl  fprintf(stderr, "The -3 switch precedes T3 commands.\n");
202150850Sscottl  fprintf(stderr, "\t-a <y|b|a|i> Stop  sending Yellow|Blue|AIS|Idle signal\n");
203150850Sscottl  fprintf(stderr, "\t-A <y|b|a|i> Start sending Yellow|Blue|AIS|Idle signal\n");
204150850Sscottl  fprintf(stderr, "\t-B <bopcode> Send BOP msg 10 times\n");
205150850Sscottl  fprintf(stderr, "\t-c <number> Set cable length in meters\n");
206150850Sscottl  fprintf(stderr, "\t-d Print status of T3 DSU/CSU\n");
207150850Sscottl  fprintf(stderr, "\t-e <number> Set T3 frame format, where:\n");
208150850Sscottl  fprintf(stderr, "\t   100:C-Bit Parity  101:M13\n");
209150850Sscottl  fprintf(stderr, "\t-f Read and print Framer registers\n");
210150850Sscottl  fprintf(stderr, "\t-F <addr> <data> Write Framer register\n");
211150850Sscottl  fprintf(stderr, "\t-l Send 'Line Loop Down' BOP msg\n");
212150850Sscottl  fprintf(stderr, "\t-L Send 'Line Loop Up' BOP msg\n");
213150850Sscottl  fprintf(stderr, "\t-s Print status of T3 DSU/CSU\n");
214150850Sscottl  fprintf(stderr, "\t-S <number> Set DS3 scrambler mode, where:\n");
215150850Sscottl  fprintf(stderr, "\t   1:OFF 2:DigitalLink|Kentrox 3:Larse\n");
216150850Sscottl  fprintf(stderr, "\t-v Set verbose printout mode\n");
217150850Sscottl  fprintf(stderr, "\t-V <number> Write to T3 VCXO freq control DAC\n");
218216600Suqs}
219150850Sscottl
220216600Suqsstatic void
221216600Suqscall_driver(unsigned long cmd, struct iohdr *iohdr)
222216600Suqs{
223150850Sscottl  int error = 0;
224150850Sscottl
225299866Struckman  strlcpy(iohdr->ifname, ifname, sizeof(iohdr->ifname));
226150850Sscottl  iohdr->cookie = NGM_LMC_COOKIE;
227150850Sscottl  iohdr->iohdr = iohdr;
228150850Sscottl
229150850Sscottl  /* Exchange data with a running device driver. */
230150850Sscottl#if defined(NETGRAPH)
231150850Sscottl  if (netgraph)
232150850Sscottl    {
233150850Sscottl    NgSendMsg(fdcs, ifname, NGM_LMC_COOKIE, cmd, iohdr, IOCPARM_LEN(cmd));
234150850Sscottl    if (cmd & IOC_OUT)
235150850Sscottl      {
236150850Sscottl      int replen = sizeof(struct ng_mesg) + IOCPARM_LEN(cmd);
237150850Sscottl      char rep[replen];  /* storage for the reply */
238150850Sscottl      struct ng_mesg *reply = (struct ng_mesg *)rep;
239150850Sscottl      int rl = NgRecvMsg(fdcs, reply, replen, NULL);
240150850Sscottl      if (rl == replen)
241150850Sscottl        bcopy(&reply->data, iohdr, IOCPARM_LEN(cmd));
242150850Sscottl      else
243150850Sscottl        {
244150850Sscottl        fprintf(stderr, "%s: NgRecvMsg returned %d bytes, expected %d\n",
245150850Sscottl          progname, rl, replen);
246150850Sscottl        exit(1);
247150850Sscottl	}
248150850Sscottl      }
249150850Sscottl    }
250150850Sscottl  else
251150850Sscottl#endif
252150850Sscottl    {
253150850Sscottl    if ((error = ioctl(fdcs, cmd, (caddr_t)iohdr)) < 0)
254150850Sscottl      {
255150850Sscottl      fprintf(stderr, "%s: ioctl() returned error code %d: %s\n",
256150850Sscottl       progname, errno, strerror(errno));
257150850Sscottl      if (errno == ENETDOWN)
258150850Sscottl        printf("Type: 'ifconfig %s up' then try again.\n", ifname);
259150850Sscottl      exit(1);
260150850Sscottl      }
261150850Sscottl    }
262150850Sscottl
263150850Sscottl  if (iohdr->cookie != NGM_LMC_COOKIE)
264150850Sscottl    {
265150850Sscottl    fprintf(stderr, "%s: cookie = 0x%08X, expected 0x%08X\n", progname, iohdr->cookie, NGM_LMC_COOKIE);
266150850Sscottl    fprintf(stderr, "%s: This version of %s is incompatible with the device driver\n", progname, progname);
267150850Sscottl    exit(1);
268150850Sscottl    }
269216600Suqs}
270150850Sscottl
271216600Suqsstatic u_int32_t
272216600Suqsread_pci_config(u_int8_t addr)
273216600Suqs{
274150850Sscottl  struct ioctl ioctl;
275150850Sscottl
276150850Sscottl  ioctl.iohdr.direction = DIR_IOWR;
277150850Sscottl  ioctl.iohdr.length = sizeof(struct ioctl);
278150850Sscottl  ioctl.cmd = IOCTL_RW_PCI;
279150850Sscottl  ioctl.address = addr;
280150850Sscottl
281150850Sscottl  call_driver(LMCIOCREAD, &ioctl.iohdr);
282150850Sscottl
283150850Sscottl  return ioctl.data;
284216600Suqs}
285150850Sscottl
286216600Suqsstatic void
287216600Suqswrite_pci_config(u_int8_t addr, u_int32_t data)
288216600Suqs{
289150850Sscottl  struct ioctl ioctl;
290150850Sscottl
291150850Sscottl  ioctl.iohdr.direction = DIR_IOW;
292150850Sscottl  ioctl.iohdr.length = sizeof(struct ioctl);
293150850Sscottl  ioctl.cmd = IOCTL_RW_PCI;
294150850Sscottl  ioctl.address = addr;
295150850Sscottl  ioctl.data = data;
296150850Sscottl
297150850Sscottl  call_driver(LMCIOCWRITE, &ioctl.iohdr);
298216600Suqs}
299150850Sscottl
300216600Suqsstatic u_int32_t
301216600Suqsread_csr(u_int8_t addr)
302216600Suqs{
303150850Sscottl  struct ioctl ioctl;
304150850Sscottl
305150850Sscottl  ioctl.iohdr.direction = DIR_IOWR;
306150850Sscottl  ioctl.iohdr.length = sizeof(struct ioctl);
307150850Sscottl  ioctl.cmd = IOCTL_RW_CSR;
308150850Sscottl  ioctl.address = addr;
309150850Sscottl
310150850Sscottl  call_driver(LMCIOCREAD, &ioctl.iohdr);
311150850Sscottl
312150850Sscottl  return ioctl.data;
313216600Suqs}
314150850Sscottl
315216600Suqsstatic void
316216600Suqswrite_csr(u_int8_t addr, u_int32_t data)
317216600Suqs{
318150850Sscottl  struct ioctl ioctl;
319150850Sscottl
320150850Sscottl  ioctl.iohdr.direction = DIR_IOW;
321150850Sscottl  ioctl.iohdr.length = sizeof(struct ioctl);
322150850Sscottl  ioctl.cmd = IOCTL_RW_CSR;
323150850Sscottl  ioctl.address = addr;
324150850Sscottl  ioctl.data = data;
325150850Sscottl
326150850Sscottl  call_driver(LMCIOCWRITE, &ioctl.iohdr);
327216600Suqs}
328150850Sscottl
329216600Suqsstatic u_int16_t
330216600Suqsread_srom(u_int8_t addr)
331216600Suqs{
332150850Sscottl  struct ioctl ioctl;
333150850Sscottl
334150850Sscottl  ioctl.iohdr.direction = DIR_IOWR;
335150850Sscottl  ioctl.iohdr.length = sizeof(struct ioctl);
336150850Sscottl  ioctl.cmd = IOCTL_RW_SROM;
337150850Sscottl  ioctl.address = addr;
338150850Sscottl
339150850Sscottl  call_driver(LMCIOCREAD, &ioctl.iohdr);
340150850Sscottl
341150850Sscottl  return ioctl.data;
342216600Suqs}
343150850Sscottl
344216600Suqsstatic void
345216600Suqswrite_srom(u_int8_t addr, u_int16_t data)
346216600Suqs{
347150850Sscottl  struct ioctl ioctl;
348150850Sscottl
349150850Sscottl  ioctl.iohdr.direction = DIR_IOW;
350150850Sscottl  ioctl.iohdr.length = sizeof(struct ioctl);
351150850Sscottl  ioctl.cmd = IOCTL_RW_SROM;
352150850Sscottl  ioctl.address = addr;
353150850Sscottl  ioctl.data = data;
354150850Sscottl
355150850Sscottl  call_driver(LMCIOCWRITE, &ioctl.iohdr);
356216600Suqs}
357150850Sscottl
358216600Suqsstatic u_int8_t
359216600Suqsread_bios_rom(u_int32_t addr)
360216600Suqs{
361150850Sscottl  struct ioctl ioctl;
362150850Sscottl
363150850Sscottl  ioctl.iohdr.direction = DIR_IOWR;
364150850Sscottl  ioctl.iohdr.length = sizeof(struct ioctl);
365150850Sscottl  ioctl.cmd = IOCTL_RW_BIOS;
366150850Sscottl  ioctl.address = addr;
367150850Sscottl
368150850Sscottl  call_driver(LMCIOCREAD, &ioctl.iohdr);
369150850Sscottl
370150850Sscottl  return ioctl.data;
371216600Suqs}
372150850Sscottl
373216600Suqsstatic void
374216600Suqswrite_bios_rom(u_int32_t addr, u_int8_t data)
375216600Suqs{
376150850Sscottl  struct ioctl ioctl;
377150850Sscottl
378150850Sscottl  ioctl.iohdr.direction = DIR_IOW;
379150850Sscottl  ioctl.iohdr.length = sizeof(struct ioctl);
380150850Sscottl  ioctl.cmd = IOCTL_RW_BIOS;
381150850Sscottl  ioctl.address = addr;
382150850Sscottl  ioctl.data = data;
383150850Sscottl
384150850Sscottl  call_driver(LMCIOCWRITE, &ioctl.iohdr);
385216600Suqs}
386150850Sscottl
387216600Suqsstatic u_int16_t
388216600Suqsread_mii(u_int8_t addr)
389216600Suqs{
390150850Sscottl  struct ioctl ioctl;
391150850Sscottl
392150850Sscottl  ioctl.iohdr.direction = DIR_IOWR;
393150850Sscottl  ioctl.iohdr.length = sizeof(struct ioctl);
394150850Sscottl  ioctl.cmd = IOCTL_RW_MII;
395150850Sscottl  ioctl.address = addr;
396150850Sscottl
397150850Sscottl  call_driver(LMCIOCREAD, &ioctl.iohdr);
398150850Sscottl
399150850Sscottl  return ioctl.data;
400216600Suqs}
401150850Sscottl
402216600Suqsstatic void
403216600Suqswrite_mii(u_int8_t addr, u_int16_t data)
404216600Suqs{
405150850Sscottl  struct ioctl ioctl;
406150850Sscottl
407150850Sscottl  ioctl.iohdr.direction = DIR_IOW;
408150850Sscottl  ioctl.iohdr.length = sizeof(struct ioctl);
409150850Sscottl  ioctl.cmd = IOCTL_RW_MII;
410150850Sscottl  ioctl.address = addr;
411150850Sscottl  ioctl.data = data;
412150850Sscottl
413150850Sscottl  call_driver(LMCIOCWRITE, &ioctl.iohdr);
414216600Suqs}
415150850Sscottl
416216600Suqsstatic unsigned char
417216600Suqsread_framer(u_int16_t addr)
418216600Suqs{
419150850Sscottl  struct ioctl ioctl;
420150850Sscottl
421150850Sscottl  ioctl.iohdr.direction = DIR_IOWR;
422150850Sscottl  ioctl.iohdr.length = sizeof(struct ioctl);
423150850Sscottl  ioctl.cmd = IOCTL_RW_FRAME;
424150850Sscottl  ioctl.address = addr;
425150850Sscottl
426150850Sscottl  call_driver(LMCIOCREAD, &ioctl.iohdr);
427150850Sscottl
428150850Sscottl  return ioctl.data;
429216600Suqs}
430150850Sscottl
431216600Suqsstatic void
432216600Suqswrite_framer(u_int16_t addr, u_int8_t data)
433216600Suqs{
434150850Sscottl  struct ioctl ioctl;
435150850Sscottl
436150850Sscottl  ioctl.iohdr.direction = DIR_IOW;
437150850Sscottl  ioctl.iohdr.length = sizeof(struct ioctl);
438150850Sscottl  ioctl.cmd = IOCTL_RW_FRAME;
439150850Sscottl  ioctl.address = addr;
440150850Sscottl  ioctl.data = data;
441150850Sscottl
442150850Sscottl  call_driver(LMCIOCWRITE, &ioctl.iohdr);
443216600Suqs}
444150850Sscottl
445216600Suqsstatic void
446216600Suqswrite_synth(struct synth synth)
447216600Suqs{
448150850Sscottl  struct ioctl ioctl;
449150850Sscottl
450150850Sscottl  ioctl.iohdr.direction = DIR_IOW;
451150850Sscottl  ioctl.iohdr.length = sizeof(struct ioctl);
452150850Sscottl  ioctl.cmd = IOCTL_WO_SYNTH;
453150850Sscottl  bcopy(&synth, &ioctl.data, sizeof(synth));
454150850Sscottl
455150850Sscottl  call_driver(LMCIOCWRITE, &ioctl.iohdr);
456216600Suqs}
457150850Sscottl
458216600Suqsstatic void
459216600Suqswrite_dac(u_int16_t data)
460216600Suqs{
461150850Sscottl  struct ioctl ioctl;
462150850Sscottl
463150850Sscottl  ioctl.iohdr.direction = DIR_IOW;
464150850Sscottl  ioctl.iohdr.length = sizeof(struct ioctl);
465150850Sscottl  ioctl.cmd = IOCTL_WO_DAC;
466150850Sscottl  ioctl.data = data;
467150850Sscottl
468150850Sscottl  call_driver(LMCIOCWRITE, &ioctl.iohdr);
469216600Suqs}
470150850Sscottl
471216600Suqsstatic void
472216600Suqsreset_xilinx(void)
473216600Suqs{
474150850Sscottl  struct ioctl ioctl;
475150850Sscottl
476150850Sscottl  ioctl.iohdr.direction = DIR_IOWR;
477150850Sscottl  ioctl.iohdr.length = sizeof(struct ioctl);
478150850Sscottl  ioctl.cmd = IOCTL_XILINX_RESET;
479150850Sscottl
480150850Sscottl  call_driver(LMCIOCTL, &ioctl.iohdr);
481216600Suqs}
482150850Sscottl
483216600Suqsstatic void
484216600Suqsload_xilinx_from_rom(void)
485216600Suqs{
486150850Sscottl  struct ioctl ioctl;
487150850Sscottl
488150850Sscottl  ioctl.iohdr.direction = DIR_IOWR;
489150850Sscottl  ioctl.iohdr.length = sizeof(struct ioctl);
490150850Sscottl  ioctl.cmd = IOCTL_XILINX_ROM;
491150850Sscottl
492150850Sscottl  call_driver(LMCIOCTL, &ioctl.iohdr);
493216600Suqs}
494150850Sscottl
495216600Suqsstatic void
496216600Suqsload_xilinx_from_file(char *ucode, u_int32_t len)
497216600Suqs{
498150850Sscottl  struct ioctl ioctl;
499150850Sscottl
500150850Sscottl  ioctl.iohdr.direction = DIR_IOWR;
501150850Sscottl  ioctl.iohdr.length = sizeof(struct ioctl);
502150850Sscottl  ioctl.cmd = IOCTL_XILINX_FILE;
503150850Sscottl  ioctl.data = len;
504150850Sscottl  ioctl.ucode = ucode;
505150850Sscottl
506150850Sscottl  call_driver(LMCIOCTL, &ioctl.iohdr);
507216600Suqs}
508150850Sscottl
509216600Suqsstatic void
510216600Suqsioctl_snmp_send(u_int32_t send)
511216600Suqs{
512150850Sscottl  struct ioctl ioctl;
513150850Sscottl
514150850Sscottl  ioctl.iohdr.direction = DIR_IOWR;
515150850Sscottl  ioctl.iohdr.length = sizeof(struct ioctl);
516150850Sscottl  ioctl.cmd = IOCTL_SNMP_SEND;
517150850Sscottl  ioctl.data = send;
518150850Sscottl
519150850Sscottl  call_driver(LMCIOCTL, &ioctl.iohdr);
520216600Suqs}
521150850Sscottl
522216600Suqsvoid
523216600Suqsioctl_snmp_loop(u_int32_t loop)
524216600Suqs{
525150850Sscottl  struct ioctl ioctl;
526150850Sscottl
527150850Sscottl  ioctl.iohdr.direction = DIR_IOWR;
528150850Sscottl  ioctl.iohdr.length = sizeof(struct ioctl);
529150850Sscottl  ioctl.cmd = IOCTL_SNMP_LOOP;
530150850Sscottl  ioctl.data = loop;
531150850Sscottl
532150850Sscottl  call_driver(LMCIOCTL, &ioctl.iohdr);
533216600Suqs}
534150850Sscottl
535216600Suqsstatic void
536216600Suqsioctl_reset_cntrs(void)
537216600Suqs{
538150850Sscottl  struct ioctl ioctl;
539150850Sscottl
540150850Sscottl  ioctl.iohdr.direction = DIR_IOWR;
541150850Sscottl  ioctl.iohdr.length = sizeof(struct ioctl);
542150850Sscottl  ioctl.cmd = IOCTL_RESET_CNTRS;
543150850Sscottl
544150850Sscottl  call_driver(LMCIOCTL, &ioctl.iohdr);
545216600Suqs}
546150850Sscottl
547216600Suqsstatic void
548216600Suqsioctl_read_config(void)
549216600Suqs{
550150850Sscottl  config.iohdr.direction = DIR_IOWR;
551150850Sscottl  config.iohdr.length = sizeof(struct config);
552150850Sscottl
553150850Sscottl  call_driver(LMCIOCGCFG, &config.iohdr);
554216600Suqs}
555150850Sscottl
556216600Suqsstatic void
557216600Suqsioctl_write_config(void)
558216600Suqs{
559150850Sscottl  config.iohdr.direction = DIR_IOW;
560150850Sscottl  config.iohdr.length = sizeof(struct config);
561150850Sscottl
562150850Sscottl  call_driver(LMCIOCSCFG, &config.iohdr);
563216600Suqs}
564150850Sscottl
565216600Suqsstatic void
566216600Suqsioctl_read_status(void)
567216600Suqs{
568150850Sscottl  status.iohdr.direction = DIR_IOWR;
569150850Sscottl  status.iohdr.length = sizeof(struct status);
570150850Sscottl
571150850Sscottl  call_driver(LMCIOCGSTAT, &status.iohdr);
572216600Suqs}
573150850Sscottl
574216600Suqsstatic void
575216600Suqsprint_card_name(void)
576216600Suqs{
577150850Sscottl  printf("Card name:\t\t%s\n", ifname);
578216600Suqs}
579150850Sscottl
580216600Suqsstatic void
581216600Suqsprint_card_type(void)
582216600Suqs{
583150850Sscottl  printf("Card type:\t\t");
584150850Sscottl  switch(status.card_type)
585150850Sscottl    {
586150850Sscottl    case TLP_CSID_HSSI:
587150850Sscottl      printf("HSSI (lmc5200)\n");
588150850Sscottl      break;
589150850Sscottl    case TLP_CSID_T3:
590150850Sscottl      printf("T3 (lmc5245)\n");
591150850Sscottl      break;
592150850Sscottl    case TLP_CSID_SSI:
593150850Sscottl      printf("SSI (lmc1000)\n");
594150850Sscottl      break;
595150850Sscottl    case TLP_CSID_T1E1:
596150850Sscottl      printf("T1E1 (lmc1200)\n");
597150850Sscottl      break;
598150850Sscottl    case TLP_CSID_HSSIc:
599150850Sscottl      printf("HSSI (lmc5200C)\n");
600150850Sscottl      break;
601150850Sscottl    default:
602150850Sscottl      printf("unknown card_type: %d\n", status.card_type);
603150850Sscottl      break;
604150850Sscottl    }
605216600Suqs}
606150850Sscottl
607216600Suqsstatic void
608216600Suqsprint_status(void)
609216600Suqs{
610150850Sscottl  char *status_string;
611150850Sscottl
612150850Sscottl  if      (status.oper_status == STATUS_UP)
613150850Sscottl    status_string = "Up";
614150850Sscottl  else if (status.oper_status == STATUS_DOWN)
615150850Sscottl    status_string = "Down";
616150850Sscottl  else if (status.oper_status == STATUS_TEST)
617150850Sscottl    status_string = "Test";
618150850Sscottl  else
619150850Sscottl    status_string = "Unknown";
620150850Sscottl  printf("Link status:\t\t%s\n", status_string);
621216600Suqs}
622150850Sscottl
623216600Suqsstatic void
624216600Suqsprint_tx_speed(void)
625216600Suqs{
626150850Sscottl  printf("Tx Speed:\t\t%u\n", status.tx_speed);
627216600Suqs}
628150850Sscottl
629216600Suqsstatic void
630216600Suqsprint_debug(void)
631216600Suqs{
632150850Sscottl  if (config.debug != 0)
633150850Sscottl    printf("Debug:\t\t\t%s\n", "On");
634216600Suqs}
635150850Sscottl
636216600Suqsstatic void
637216600Suqsprint_line_prot(void)
638216600Suqs{
639150850Sscottl  char *on = "On", *off = "Off";
640150850Sscottl
641150850Sscottl  printf("Line Prot/Pkg:\t\t");
642150850Sscottl  switch (status.line_prot)
643150850Sscottl    {
644150850Sscottl    case 0:
645150850Sscottl      printf("NotSet/");
646150850Sscottl      break;
647150850Sscottl    case PROT_PPP:
648150850Sscottl      printf("PPP/");
649150850Sscottl      break;
650150850Sscottl    case PROT_C_HDLC:
651150850Sscottl      printf("Cisco-HDLC/");
652150850Sscottl      break;
653150850Sscottl    case PROT_FRM_RLY:
654150850Sscottl      printf("Frame-Relay/");
655150850Sscottl      break;
656150850Sscottl    case PROT_IP_HDLC:
657150850Sscottl      printf("IP-in-HDLC/");
658150850Sscottl      break;
659150850Sscottl    case PROT_ETH_HDLC:
660150850Sscottl      printf("Ether-in-HDLC/");
661150850Sscottl      break;
662150850Sscottl    case PROT_X25:
663150850Sscottl      printf("X25+LAPB/");
664150850Sscottl      break;
665150850Sscottl    default:
666150850Sscottl      printf("unknown line_prot: %d/", status.line_prot);
667150850Sscottl      break;
668150850Sscottl    }
669150850Sscottl
670150850Sscottl  switch (status.line_pkg)
671150850Sscottl    {
672150850Sscottl    case 0:
673150850Sscottl      printf("NotSet\n");
674150850Sscottl      break;
675150850Sscottl    case PKG_RAWIP:
676150850Sscottl      printf("Driver\n");
677150850Sscottl      break;
678150850Sscottl    case PKG_NG:
679150850Sscottl      printf("Netgraph\n");
680150850Sscottl      break;
681150850Sscottl    case PKG_GEN_HDLC:
682150850Sscottl      printf("GenHDLC\n");
683150850Sscottl      break;
684150850Sscottl    case PKG_SPPP:
685150850Sscottl      printf("SPPP\n");
686150850Sscottl      break;
687150850Sscottl    case PKG_P2P:
688150850Sscottl      printf("P2P\n");
689150850Sscottl      break;
690150850Sscottl    default:
691150850Sscottl      printf("unknown line_pkg: %d\n", status.line_pkg);
692150850Sscottl      break;
693150850Sscottl    }
694150850Sscottl
695150850Sscottl  if (status.line_pkg == PKG_SPPP)
696150850Sscottl    printf("SPPP Keep-alives:\t%s\n",
697150850Sscottl     config.keep_alive ? on : off);
698216600Suqs}
699150850Sscottl
700216600Suqsstatic void
701216600Suqsprint_crc_len(void)
702216600Suqs{
703150850Sscottl  printf("CRC length:\t\t");
704150850Sscottl  if (config.crc_len == CFG_CRC_0)
705150850Sscottl    printf("no CRC\n");
706150850Sscottl  else if (config.crc_len == CFG_CRC_16)
707150850Sscottl    printf("16 bits\n");
708150850Sscottl  else if (config.crc_len == CFG_CRC_32)
709150850Sscottl    printf("32 bits\n");
710150850Sscottl  else
711150850Sscottl    printf("bad crc_len: %d\n", config.crc_len);
712216600Suqs}
713150850Sscottl
714216600Suqsstatic void
715216600Suqsprint_loop_back(void)
716216600Suqs{
717150850Sscottl  printf("Loopback:\t\t");
718150850Sscottl  switch (config.loop_back)
719150850Sscottl    {
720150850Sscottl    case CFG_LOOP_NONE:
721150850Sscottl      printf("None\n");
722150850Sscottl      break;
723150850Sscottl    case CFG_LOOP_PAYLOAD:
724150850Sscottl      printf("Outward thru framer (payload loop)\n");
725150850Sscottl      break;
726150850Sscottl    case CFG_LOOP_LINE:
727150850Sscottl      printf("Outward thru line interface (line loop)\n");
728150850Sscottl      break;
729150850Sscottl    case CFG_LOOP_OTHER:
730150850Sscottl      printf("Inward thru line interface\n");
731150850Sscottl      break;
732150850Sscottl    case CFG_LOOP_INWARD:
733150850Sscottl      printf("Inward thru framer\n");
734150850Sscottl      break;
735150850Sscottl    case CFG_LOOP_DUAL:
736150850Sscottl      printf("Inward & outward (dual loop)\n");
737150850Sscottl      break;
738150850Sscottl    case CFG_LOOP_TULIP:
739150850Sscottl      printf("Inward thru Tulip chip\n");
740150850Sscottl      break;
741150850Sscottl    case CFG_LOOP_PINS:
742150850Sscottl      printf("Inward thru drvrs/rcvrs\n");
743150850Sscottl      break;
744150850Sscottl    case CFG_LOOP_LL:
745150850Sscottl      printf("LA/LL asserted\n");
746150850Sscottl      break;
747150850Sscottl    case CFG_LOOP_RL:
748150850Sscottl      printf("LB/RL asserted\n");
749150850Sscottl      break;
750150850Sscottl    default:
751150850Sscottl      printf("unknown loop_back: %d\n", config.loop_back);
752150850Sscottl      break;
753150850Sscottl    }
754216600Suqs}
755150850Sscottl
756216600Suqsstatic void
757216600Suqsprint_tx_clk_src(void)
758216600Suqs{
759150850Sscottl  printf("Tx Clk src:\t\t");
760150850Sscottl  switch (config.tx_clk_src)
761150850Sscottl    {
762150850Sscottl    case CFG_CLKMUX_ST:
763150850Sscottl      printf("Tx Clk from modem\n");
764150850Sscottl      break;
765150850Sscottl    case CFG_CLKMUX_INT:
766150850Sscottl      printf("Internal source\n");
767150850Sscottl      break;
768150850Sscottl    case CFG_CLKMUX_RT:
769150850Sscottl      printf("Rx Clk from modem (loop timed)\n");
770150850Sscottl      break;
771150850Sscottl    case CFG_CLKMUX_EXT:
772150850Sscottl      printf("External connector\n");
773150850Sscottl      break;
774150850Sscottl    default:
775150850Sscottl      printf("unknown tx_clk_src: %d\n", config.tx_clk_src);
776150850Sscottl      break;
777150850Sscottl    }
778216600Suqs}
779150850Sscottl
780216600Suqsstatic void
781216600Suqsprint_format(void)
782216600Suqs{
783150850Sscottl  printf("Format-Frame/Code:\t");
784150850Sscottl  switch (config.format)
785150850Sscottl    {
786150850Sscottl    case CFG_FORMAT_T1SF:
787150850Sscottl      printf("T1-SF/AMI\n");
788150850Sscottl      break;
789150850Sscottl    case CFG_FORMAT_T1ESF:
790150850Sscottl      printf("T1-ESF/B8ZS\n");
791150850Sscottl      break;
792150850Sscottl    case CFG_FORMAT_E1FAS:
793150850Sscottl      printf("E1-FAS/HDB3\n");
794150850Sscottl      break;
795150850Sscottl    case CFG_FORMAT_E1FASCRC:
796150850Sscottl      printf("E1-FAS+CRC/HDB3\n");
797150850Sscottl      break;
798150850Sscottl    case CFG_FORMAT_E1FASCAS:
799150850Sscottl      printf("E1-FAS+CAS/HDB3\n");
800150850Sscottl      break;
801150850Sscottl    case CFG_FORMAT_E1FASCRCCAS:
802150850Sscottl      printf("E1-FAS+CRC+CAS/HDB3\n");
803150850Sscottl      break;
804150850Sscottl    case CFG_FORMAT_E1NONE:
805150850Sscottl      printf("E1-NOFRAMING/HDB3\n");
806150850Sscottl      break;
807150850Sscottl    case CFG_FORMAT_T3CPAR:
808150850Sscottl      printf("T3-CParity/B3ZS\n");
809150850Sscottl      break;
810150850Sscottl    case CFG_FORMAT_T3M13:
811150850Sscottl      printf("T3-M13/B3ZS\n");
812150850Sscottl      break;
813150850Sscottl    default:
814150850Sscottl      printf("unknown format: %d\n", config.format);
815150850Sscottl      break;
816150850Sscottl    }
817216600Suqs}
818150850Sscottl
819216600Suqsstatic void
820216600Suqsprint_dte_dce(void)
821216600Suqs{
822150850Sscottl  printf("DTE or DCE:\t\t");
823150850Sscottl  switch(config.dte_dce)
824150850Sscottl    {
825150850Sscottl    case CFG_DTE:
826150850Sscottl      printf("DTE (receiving TxClk)\n");
827150850Sscottl      break;
828150850Sscottl    case CFG_DCE:
829150850Sscottl      printf("DCE (driving TxClk)\n");
830150850Sscottl      break;
831150850Sscottl    default:
832150850Sscottl      printf("unknown dte_dce: %d\n", config.dte_dce);
833150850Sscottl      break;
834150850Sscottl    }
835216600Suqs}
836150850Sscottl
837216600Suqsstatic void
838216600Suqsprint_synth_freq(void)
839216600Suqs{
840150850Sscottl  double Fref = 20e6;
841150850Sscottl  double Fout, Fvco;
842150850Sscottl
843150850Sscottl  /* decode the synthesizer params */
844150850Sscottl  Fvco = (Fref * (config.synth.n<<(3*config.synth.v)))/config.synth.m;
845150850Sscottl  Fout =  Fvco / (1<<(config.synth.x+config.synth.r+config.synth.prescale));
846150850Sscottl
847150850Sscottl  printf("Synth freq:\t\t%.0f\n", Fout);
848216600Suqs}
849150850Sscottl
850216600Suqsstatic void
851216600Suqssynth_freq(unsigned long target)
852216600Suqs{
853150850Sscottl  unsigned int n, m, v, x, r;
854150850Sscottl  double Fout, Fvco, Ftarg;
855150850Sscottl  double newdiff, olddiff;
856150850Sscottl  double bestF=0.0, bestV=0.0;
857150850Sscottl  unsigned prescale = (target < 50000) ? 9:4;
858150850Sscottl
859150850Sscottl  Ftarg = target<<prescale;
860150850Sscottl  for (n=3; n<=127; n++)
861150850Sscottl    for (m=3; m<=127; m++)
862150850Sscottl      for (v=0;  v<=1;  v++)
863150850Sscottl        for (x=0;  x<=3;  x++)
864150850Sscottl          for (r=0;  r<=3;  r++)
865150850Sscottl            {
866150850Sscottl            Fvco = (SYNTH_FREF * (n<<(3*v)))/m;
867150850Sscottl            if (Fvco < SYNTH_FMIN || Fvco > SYNTH_FMAX) continue;
868150850Sscottl            Fout =  Fvco / (1<<(x+r));
869150850Sscottl            if (Fout >= Ftarg)
870150850Sscottl              newdiff = Fout - Ftarg;
871150850Sscottl            else
872150850Sscottl              newdiff = Ftarg - Fout;
873150850Sscottl            if (bestF >= Ftarg)
874150850Sscottl              olddiff = bestF - Ftarg;
875150850Sscottl            else
876150850Sscottl              olddiff = Ftarg - bestF;
877150850Sscottl            if ((newdiff < olddiff) ||
878150850Sscottl               ((newdiff == olddiff) && (Fvco < bestV)))
879150850Sscottl              {
880150850Sscottl              config.synth.n = n;
881150850Sscottl              config.synth.m = m;
882150850Sscottl              config.synth.v = v;
883150850Sscottl              config.synth.x = x;
884150850Sscottl              config.synth.r = r;
885150850Sscottl              config.synth.prescale = prescale;
886150850Sscottl              bestF = Fout;
887150850Sscottl              bestV = Fvco;
888150850Sscottl	      }
889150850Sscottl            }
890150850Sscottl#if 0
891150850Sscottl  printf("Fbest=%.0f, Ftarg=%u, Fout=%.0f\n", bestF>>prescale, target, bestF);
892150850Sscottl  printf("N=%u, M=%u, V=%u, X=%u, R=%u\n", config.synth.n,
893150850Sscottl   config.synth.m, config.synth.v, config.synth.x, config.synth.r);
894150850Sscottl#endif
895216600Suqs}
896150850Sscottl
897216600Suqsstatic void
898216600Suqsprint_cable_len(void)
899216600Suqs{
900150850Sscottl  printf("Cable length:\t\t%d meters\n", config.cable_len);
901216600Suqs}
902150850Sscottl
903216600Suqsstatic void
904216600Suqsprint_cable_type(void)
905216600Suqs{
906150850Sscottl  printf("Cable type:\t\t");
907150850Sscottl  if (status.cable_type > 7)
908150850Sscottl    printf("unknown cable_type: %d\n", status.cable_type);
909150850Sscottl  else
910150850Sscottl    printf("%s\n", ssi_cables[status.cable_type]);
911216600Suqs}
912150850Sscottl
913216600Suqsstatic void
914216600Suqsprint_time_slots(void)
915216600Suqs{
916150850Sscottl  printf("TimeSlot [31-0]:\t0x%08X\n", config.time_slots);
917216600Suqs}
918150850Sscottl
919216600Suqsstatic void
920216600Suqsprint_scrambler(void)
921216600Suqs{
922150850Sscottl  printf("Scrambler:\t\t");
923150850Sscottl  if (config.scrambler == CFG_SCRAM_OFF)
924150850Sscottl    printf("off\n");
925150850Sscottl  else if (config.scrambler == CFG_SCRAM_DL_KEN)
926150850Sscottl    printf("DigLink/Kentrox: X^43+1\n");
927150850Sscottl  else if (config.scrambler == CFG_SCRAM_LARS)
928150850Sscottl    printf("Larse: X^20+X^17+1 w/28ZS\n");
929150850Sscottl  else
930150850Sscottl    printf("unknown scrambler: %d\n", config.scrambler);
931216600Suqs}
932150850Sscottl
933216600Suqsstatic double
934216600Suqsvga_dbs(u_int8_t vga)
935216600Suqs{
936150850Sscottl  if  (vga <  0x0F)                   return  0.0;
937150850Sscottl  if ((vga >= 0x0F) && (vga <= 0x1B)) return  0.0 + 0.77 * (vga - 0x0F);
938150850Sscottl  if ((vga >= 0x1C) && (vga <= 0x33)) return 10.0 + 1.25 * (vga - 0x1C);
939150850Sscottl  if ((vga >= 0x34) && (vga <= 0x39)) return 40.0 + 1.67 * (vga - 0x34);
940216597Suqs  if ((vga >= 0x3A) && (vga <  0x3F)) return 50.0 + 2.80 * (vga - 0x3A);
941360675Sdim  return 64.0;
942216600Suqs}
943150850Sscottl
944216600Suqsstatic void
945216600Suqsprint_rx_gain(void)
946216600Suqs{
947150850Sscottl  printf("Rx gain max:\t\t");
948150850Sscottl
949150850Sscottl  if (config.rx_gain == CFG_GAIN_AUTO)
950150850Sscottl    printf("auto-set to %02.1f dB\n",
951150850Sscottl     vga_dbs(read_framer(Bt8370_VGA_MAX) & 0x3F));
952150850Sscottl  else
953150850Sscottl    printf("up to %02.1f dB\n", vga_dbs(config.rx_gain));
954216600Suqs}
955150850Sscottl
956216600Suqsstatic void
957216600Suqsprint_tx_lbo(void)
958216600Suqs{
959150850Sscottl  u_int8_t saved_lbo = config.tx_lbo;
960150850Sscottl
961150850Sscottl  printf("LBO = ");
962150850Sscottl  if (config.tx_lbo == CFG_LBO_AUTO)
963150850Sscottl    {
964150850Sscottl    config.tx_lbo = read_framer(Bt8370_TLIU_CR) & 0x30;
965150850Sscottl    printf("auto-set to ");
966150850Sscottl    }
967150850Sscottl
968150850Sscottl  switch (config.tx_lbo)
969150850Sscottl    {
970150850Sscottl    case CFG_LBO_0DB:
971150850Sscottl      printf("0 dB\n");
972150850Sscottl      break;
973150850Sscottl    case CFG_LBO_7DB:
974150850Sscottl      printf("7.5 dB\n");
975150850Sscottl      break;
976150850Sscottl    case CFG_LBO_15DB:
977150850Sscottl      printf("15 dB\n");
978150850Sscottl      break;
979150850Sscottl    case CFG_LBO_22DB:
980150850Sscottl      printf("22.5 dB\n");
981150850Sscottl      break;
982150850Sscottl    default:
983150850Sscottl      printf("unknown tx_lbo: %d\n", config.tx_lbo);
984150850Sscottl      break;
985150850Sscottl    }
986150850Sscottl
987150850Sscottl  if (saved_lbo == CFG_LBO_AUTO)
988150850Sscottl    config.tx_lbo = saved_lbo;
989216600Suqs}
990150850Sscottl
991216600Suqsstatic void
992216600Suqsprint_tx_pulse(void)
993216600Suqs{
994150850Sscottl  u_int8_t saved_pulse = config.tx_pulse;
995150850Sscottl
996150850Sscottl  printf("Tx pulse shape:\t\t");
997150850Sscottl  if (config.tx_pulse == CFG_PULSE_AUTO)
998150850Sscottl    {
999150850Sscottl    config.tx_pulse = read_framer(Bt8370_TLIU_CR) & 0x0E;
1000150850Sscottl    printf("auto-set to ");
1001150850Sscottl    }
1002150850Sscottl
1003150850Sscottl  switch (config.tx_pulse)
1004150850Sscottl    {
1005150850Sscottl    case CFG_PULSE_T1DSX0:
1006150850Sscottl      printf("T1-DSX: 0 to 40 meters\n");
1007150850Sscottl      break;
1008150850Sscottl    case CFG_PULSE_T1DSX1:
1009150850Sscottl      printf("T1-DSX: 40 to 80 meters\n");
1010150850Sscottl      break;
1011150850Sscottl    case CFG_PULSE_T1DSX2:
1012150850Sscottl      printf("T1-DSX: 80 to 120 meters\n");
1013150850Sscottl      break;
1014150850Sscottl    case CFG_PULSE_T1DSX3:
1015150850Sscottl      printf("T1-DSX: 120 to 160 meters\n");
1016150850Sscottl      break;
1017150850Sscottl    case CFG_PULSE_T1DSX4:
1018150850Sscottl      printf("T1-DSX: 160 to 200 meters\n");
1019150850Sscottl      break;
1020150850Sscottl    case CFG_PULSE_E1COAX:
1021150850Sscottl      printf("E1: Twin Coax\n");
1022150850Sscottl      break;
1023150850Sscottl    case CFG_PULSE_E1TWIST:
1024150850Sscottl      printf("E1: Twisted Pairs\n");
1025150850Sscottl      break;
1026150850Sscottl    case CFG_PULSE_T1CSU:
1027150850Sscottl      printf("T1-CSU; ");
1028150850Sscottl      print_tx_lbo();
1029150850Sscottl      break;
1030150850Sscottl    default:
1031150850Sscottl      printf("unknown tx_pulse: %d\n", config.tx_pulse);
1032150850Sscottl      break;
1033150850Sscottl    }
1034150850Sscottl
1035150850Sscottl  if (saved_pulse == CFG_PULSE_AUTO)
1036150850Sscottl    config.tx_pulse = saved_pulse;
1037216600Suqs}
1038150850Sscottl
1039216600Suqsstatic void
1040216600Suqsprint_ssi_sigs(void)
1041216600Suqs{
1042150850Sscottl  u_int32_t mii16 = status.snmp.ssi.sigs;
1043150850Sscottl  char *on = "On", *off = "Off";
1044150850Sscottl
1045150850Sscottl  printf("Modem signals:\t\tDTR=%s DSR=%s RTS=%s CTS=%s\n",
1046150850Sscottl   (mii16 & MII16_SSI_DTR) ? on : off,
1047150850Sscottl   (mii16 & MII16_SSI_DSR) ? on : off,
1048150850Sscottl   (mii16 & MII16_SSI_RTS) ? on : off,
1049150850Sscottl   (mii16 & MII16_SSI_CTS) ? on : off);
1050150850Sscottl  printf("Modem signals:\t\tDCD=%s RI=%s LL=%s RL=%s TM=%s\n",
1051150850Sscottl   (mii16 & MII16_SSI_DCD) ? on : off,
1052150850Sscottl   (mii16 & MII16_SSI_RI)  ? on : off,
1053150850Sscottl   (mii16 & MII16_SSI_LL)  ? on : off,
1054150850Sscottl   (mii16 & MII16_SSI_RL)  ? on : off,
1055150850Sscottl   (mii16 & MII16_SSI_TM)  ? on : off);
1056216600Suqs}
1057150850Sscottl
1058216600Suqsstatic void
1059216600Suqsprint_hssi_sigs(void)
1060216600Suqs{
1061150850Sscottl  u_int32_t mii16 = status.snmp.hssi.sigs;
1062150850Sscottl  char *on = "On", *off = "Off";
1063150850Sscottl
1064150850Sscottl  printf("Modem signals:\t\tTA=%s CA=%s\n",
1065150850Sscottl   (mii16 & MII16_HSSI_TA) ? on : off,
1066150850Sscottl   (mii16 & MII16_HSSI_CA) ? on : off);
1067150850Sscottl  printf("Modem signals:\t\tLA=%s LB=%s LC=%s TM=%s\n",
1068150850Sscottl   (mii16 & MII16_HSSI_LA) ? on : off,
1069150850Sscottl   (mii16 & MII16_HSSI_LB) ? on : off,
1070150850Sscottl   (mii16 & MII16_HSSI_LC) ? on : off,
1071150850Sscottl   (mii16 & MII16_HSSI_TM) ? on : off);
1072216600Suqs}
1073150850Sscottl
1074216600Suqsstatic void
1075216600Suqsprint_events(void)
1076216600Suqs{
1077239988Sed  const char *reset_time;
1078239988Sed  time_t now;
1079150850Sscottl
1080239988Sed  now = time(NULL);
1081239988Sed  printf("Current time:\t\t%s", ctime(&now));
1082150850Sscottl  if (status.cntrs.reset_time.tv_sec < 1000)
1083239988Sed    reset_time = "Never\n";
1084150850Sscottl  else
1085239988Sed    reset_time = ctime(&status.cntrs.reset_time.tv_sec);
1086239988Sed  printf("Cntrs reset:\t\t%s", reset_time);
1087150850Sscottl
1088216600Suqs  if (status.cntrs.ibytes)     printf("Rx bytes:\t\t%ju\n",    (uintmax_t)status.cntrs.ibytes);
1089216600Suqs  if (status.cntrs.obytes)     printf("Tx bytes:\t\t%ju\n",    (uintmax_t)status.cntrs.obytes);
1090216600Suqs  if (status.cntrs.ipackets)   printf("Rx packets:\t\t%ju\n",  (uintmax_t)status.cntrs.ipackets);
1091216600Suqs  if (status.cntrs.opackets)   printf("Tx packets:\t\t%ju\n",  (uintmax_t)status.cntrs.opackets);
1092150850Sscottl  if (status.cntrs.ierrors)    printf("Rx errors:\t\t%u\n",    status.cntrs.ierrors);
1093150850Sscottl  if (status.cntrs.oerrors)    printf("Tx errors:\t\t%u\n",    status.cntrs.oerrors);
1094150850Sscottl  if (status.cntrs.idiscards)  printf("Rx discards:\t\t%u\n",  status.cntrs.idiscards);
1095150850Sscottl  if (status.cntrs.odiscards)  printf("Tx discards:\t\t%u\n",  status.cntrs.odiscards);
1096150850Sscottl  if (status.cntrs.fifo_over)  printf("Rx fifo overruns:\t%u\n", status.cntrs.fifo_over);
1097150850Sscottl  if (status.cntrs.fifo_under) printf("Tx fifo underruns:\t%u\n", status.cntrs.fifo_under);
1098150850Sscottl  if (status.cntrs.missed)     printf("Rx missed:\t\t%u\n",    status.cntrs.missed);
1099150850Sscottl  if (status.cntrs.overruns)   printf("Rx overruns:\t\t%u\n",  status.cntrs.overruns);
1100150850Sscottl  if (status.cntrs.fdl_pkts)   printf("Rx FDL pkts:\t\t%u\n",  status.cntrs.fdl_pkts);
1101150850Sscottl  if (status.cntrs.crc_errs)   printf("Rx CRC:\t\t\t%u\n",     status.cntrs.crc_errs);
1102150850Sscottl  if (status.cntrs.lcv_errs)   printf("Rx line code:\t\t%u\n", status.cntrs.lcv_errs);
1103150850Sscottl  if (status.cntrs.frm_errs)   printf("Rx F-bits:\t\t%u\n",    status.cntrs.frm_errs);
1104150850Sscottl  if (status.cntrs.febe_errs)  printf("Rx FEBE:\t\t%u\n",      status.cntrs.febe_errs);
1105150850Sscottl  if (status.cntrs.par_errs)   printf("Rx P-parity:\t\t%u\n",  status.cntrs.par_errs);
1106150850Sscottl  if (status.cntrs.cpar_errs)  printf("Rx C-parity:\t\t%u\n",  status.cntrs.cpar_errs);
1107150850Sscottl  if (status.cntrs.mfrm_errs)  printf("Rx M-bits:\t\t%u\n",    status.cntrs.mfrm_errs);
1108150850Sscottl  if (config.debug)
1109150850Sscottl    { /* These events are hard to explain and may worry users, */
1110150850Sscottl    if (status.cntrs.rxdma)     printf("Rx no buffs:\t\t%u\n", status.cntrs.rxdma);
1111150850Sscottl    if (status.cntrs.txdma)     printf("Tx no descs:\t\t%u\n", status.cntrs.txdma);
1112150850Sscottl    if (status.cntrs.lck_watch) printf("Lck watch:\t\t%u\n",   status.cntrs.lck_watch);
1113150850Sscottl    if (status.cntrs.lck_ioctl) printf("Lck ioctl:\t\t%u\n",   status.cntrs.lck_ioctl);
1114150850Sscottl    if (status.cntrs.lck_intr)  printf("Lck intr:\t\t%u\n",    status.cntrs.lck_intr);
1115150850Sscottl    }
1116216600Suqs}
1117150850Sscottl
1118216600Suqsstatic void
1119216600Suqsprint_summary(void)
1120216600Suqs{
1121150850Sscottl  switch(status.card_type)
1122150850Sscottl    {
1123150850Sscottl    case TLP_CSID_HSSI:
1124150850Sscottl      {
1125150850Sscottl      print_card_name();
1126150850Sscottl      print_card_type();
1127150850Sscottl      print_debug();
1128150850Sscottl      print_status();
1129150850Sscottl      print_tx_speed();
1130150850Sscottl      print_line_prot();
1131150850Sscottl      print_crc_len();
1132150850Sscottl      print_loop_back();
1133150850Sscottl      print_tx_clk_src();
1134150850Sscottl      print_hssi_sigs();
1135150850Sscottl      print_events();
1136150850Sscottl      break;
1137150850Sscottl      }
1138150850Sscottl    case TLP_CSID_T3:
1139150850Sscottl      {
1140150850Sscottl      print_card_name();
1141150850Sscottl      print_card_type();
1142150850Sscottl      print_debug();
1143150850Sscottl      print_status();
1144150850Sscottl      print_tx_speed();
1145150850Sscottl      print_line_prot();
1146150850Sscottl      print_crc_len();
1147150850Sscottl      print_loop_back();
1148150850Sscottl      print_format();
1149150850Sscottl      print_cable_len();
1150150850Sscottl      print_scrambler();
1151150850Sscottl      print_events();
1152150850Sscottl      break;
1153150850Sscottl      }
1154150850Sscottl    case TLP_CSID_SSI:
1155150850Sscottl      {
1156150850Sscottl      print_card_name();
1157150850Sscottl      print_card_type();
1158150850Sscottl      print_debug();
1159150850Sscottl      print_status();
1160150850Sscottl      print_tx_speed();
1161150850Sscottl      print_line_prot();
1162150850Sscottl      print_crc_len();
1163150850Sscottl      print_loop_back();
1164150850Sscottl      print_dte_dce();
1165150850Sscottl      print_synth_freq();
1166150850Sscottl      print_cable_type();
1167150850Sscottl      print_ssi_sigs();
1168150850Sscottl      print_events();
1169150850Sscottl      break;
1170150850Sscottl      }
1171150850Sscottl    case TLP_CSID_T1E1:
1172150850Sscottl      {
1173150850Sscottl      print_card_name();
1174150850Sscottl      print_card_type();
1175150850Sscottl      print_debug();
1176150850Sscottl      print_status();
1177150850Sscottl      print_tx_speed();
1178150850Sscottl      print_line_prot();
1179150850Sscottl      print_crc_len();
1180150850Sscottl      print_loop_back();
1181150850Sscottl      print_tx_clk_src();
1182150850Sscottl      print_format();
1183150850Sscottl      print_time_slots();
1184150850Sscottl      print_cable_len();
1185150850Sscottl      print_tx_pulse();
1186150850Sscottl      print_rx_gain();
1187150850Sscottl      print_events();
1188150850Sscottl      break;
1189150850Sscottl      }
1190150850Sscottl    case TLP_CSID_HSSIc:
1191150850Sscottl      {
1192150850Sscottl      print_card_name();
1193150850Sscottl      print_card_type();
1194150850Sscottl      print_debug();
1195150850Sscottl      print_status();
1196150850Sscottl      print_line_prot();
1197150850Sscottl      print_tx_speed();
1198150850Sscottl      print_crc_len();
1199150850Sscottl      print_loop_back();
1200150850Sscottl      print_tx_clk_src();
1201150850Sscottl      print_dte_dce();
1202150850Sscottl      print_synth_freq();
1203150850Sscottl      print_hssi_sigs();
1204150850Sscottl      print_events();
1205150850Sscottl      break;
1206150850Sscottl      }
1207150850Sscottl    default:
1208150850Sscottl      {
1209150850Sscottl      printf("%s: Unknown card type: %d\n", ifname, status.card_type);
1210150850Sscottl      break;
1211150850Sscottl      }
1212150850Sscottl    }
1213216600Suqs}
1214150850Sscottl
1215216600Suqsstatic char *
1216216600Suqsprint_t3_bop(int bop_code)
1217216600Suqs{
1218150850Sscottl  switch(bop_code)
1219150850Sscottl    {
1220150850Sscottl    case 0x00:
1221150850Sscottl      return "far end LOF";
1222150850Sscottl    case 0x0E:
1223150850Sscottl      return "far end LOS";
1224150850Sscottl    case 0x16:
1225150850Sscottl      return "far end AIS";
1226150850Sscottl    case 0x1A:
1227150850Sscottl      return "far end IDL";
1228150850Sscottl    case 0x07:
1229150850Sscottl      return "Line Loopback activate";
1230150850Sscottl    case 0x1C:
1231150850Sscottl      return "Line Loopback deactivate";
1232150850Sscottl    case 0x1B:
1233150850Sscottl      return "Entire DS3 line";
1234150850Sscottl    default:
1235150850Sscottl      return "Unknown BOP code";
1236150850Sscottl    }
1237216600Suqs}
1238150850Sscottl
1239216600Suqsstatic void
1240216600Suqsprint_t3_snmp(void)
1241216600Suqs{
1242150850Sscottl  printf("SNMP performance data:\n");
1243150850Sscottl  printf(" LCV=%d",  status.snmp.t3.lcv);
1244150850Sscottl  printf(" LOS=%d", (status.snmp.t3.line & TLINE_LOS)    ? 1 : 0);
1245150850Sscottl  printf(" PCV=%d",  status.snmp.t3.pcv);
1246150850Sscottl  printf(" CCV=%d",  status.snmp.t3.ccv);
1247150850Sscottl  printf(" AIS=%d", (status.snmp.t3.line & TLINE_RX_AIS) ? 1 : 0);
1248150850Sscottl  printf(" SEF=%d", (status.snmp.t3.line & T1LINE_SEF)   ? 1 : 0);
1249150850Sscottl  printf(" OOF=%d", (status.snmp.t3.line & TLINE_LOF)    ? 1 : 0);
1250150850Sscottl  printf("  FEBE=%d", status.snmp.t3.febe);
1251150850Sscottl  printf(" RAI=%d", (status.snmp.t3.line & TLINE_RX_RAI) ? 1 : 0);
1252150850Sscottl  printf("\n");
1253216600Suqs}
1254150850Sscottl
1255216600Suqsstatic void
1256216600Suqsprint_t3_dsu(void)
1257216600Suqs{
1258150850Sscottl  char *no = "No", *yes = "Yes";
1259150850Sscottl  u_int16_t mii16 = read_mii(16);
1260150850Sscottl  u_int8_t ctl1   = read_framer(T3CSR_CTL1);
1261150850Sscottl  u_int8_t ctl8   = read_framer(T3CSR_CTL8);
1262150850Sscottl  u_int8_t stat9  = read_framer(T3CSR_STAT9);
1263150850Sscottl  u_int8_t ctl12  = read_framer(T3CSR_CTL12);
1264150850Sscottl  u_int8_t stat16 = read_framer(T3CSR_STAT16);
1265150850Sscottl
1266150850Sscottl  printf("Framing:       \t\t%s\n", ctl1   & CTL1_M13MODE    ? "M13" : "CPAR");
1267150850Sscottl  print_tx_speed();
1268150850Sscottl  printf("Scrambler:     \t\t%s\n", mii16  & MII16_DS3_SCRAM ? yes : no);
1269150850Sscottl  printf("Scram poly:    \t\t%s\n", mii16  & MII16_DS3_POLY  ? "X^20" : "X^43");
1270150850Sscottl  printf("Cable length   \t\t%s\n", mii16  & MII16_DS3_ZERO  ? "Short" : "Long");
1271150850Sscottl  printf("Line    loop:  \t\t%s\n", mii16  & MII16_DS3_LNLBK ? yes : no);
1272150850Sscottl  printf("Payload loop:  \t\t%s\n", ctl12  & CTL12_RTPLOOP   ? yes : no);
1273150850Sscottl  printf("Frame   loop:  \t\t%s\n", ctl1   & CTL1_3LOOP      ? yes : no);
1274150850Sscottl  printf("Host    loop:  \t\t%s\n", mii16  & MII16_DS3_TRLBK ? yes : no);
1275150850Sscottl  printf("Transmit RAI:  \t\t%s\n", ctl1   & CTL1_XTX        ? no  : yes);
1276150850Sscottl  printf("Receive  RAI   \t\t%s\n", stat16 & STAT16_XERR     ? yes : no);
1277150850Sscottl  printf("Transmit AIS:  \t\t%s\n", ctl1   & CTL1_TXAIS      ? yes : no);
1278150850Sscottl  printf("Receive  AIS:  \t\t%s\n", stat16 & STAT16_RAIS     ? yes : no);
1279150850Sscottl  printf("Transmit IDLE: \t\t%s\n", ctl1   & CTL1_TXIDL      ? yes : no);
1280150850Sscottl  printf("Receive  IDLE: \t\t%s\n", stat16 & STAT16_RIDL     ? yes : no);
1281150850Sscottl  printf("Transmit BLUE: \t\t%s\n", ctl8   & CTL8_TBLU       ? yes : no);
1282150850Sscottl  printf("Receive  BLUE: \t\t%s\n", stat9  & STAT9_RBLU      ? yes : no);
1283150850Sscottl  printf("Loss of Signal:\t\t%s\n", stat16 & STAT16_RLOS     ? yes : no);
1284150850Sscottl  printf("Loss of Frame: \t\t%s\n", stat16 & STAT16_ROOF     ? yes : no);
1285150850Sscottl  printf("Sev Err Frms:  \t\t%s\n", stat16 & STAT16_SEF      ? yes : no);
1286150850Sscottl  printf("Code  errors:  \t\t%d\n", read_framer(T3CSR_CVLO) + (read_framer(T3CSR_CVHI)<<8));
1287150850Sscottl  printf("C-Par errors:  \t\t%d\n", read_framer(T3CSR_CERR));
1288150850Sscottl  printf("P-Par errors:  \t\t%d\n", read_framer(T3CSR_PERR));
1289150850Sscottl  printf("F-Bit errors:  \t\t%d\n", read_framer(T3CSR_FERR));
1290150850Sscottl  printf("M-Bit errors:  \t\t%d\n", read_framer(T3CSR_MERR));
1291150850Sscottl  printf("FarEndBitErrs: \t\t%d\n", read_framer(T3CSR_FEBE));
1292150850Sscottl  printf("Last Tx  FEAC msg:\t0x%02X (%s)\n",
1293150850Sscottl   read_framer(T3CSR_TX_FEAC)  & 0x3F,
1294150850Sscottl   print_t3_bop(read_framer(T3CSR_TX_FEAC) & 0x3F));
1295150850Sscottl  printf("Last dbl FEAC msg;\t0x%02X (%s)\n",
1296150850Sscottl   read_framer(T3CSR_DBL_FEAC) & 0x3F,
1297150850Sscottl   print_t3_bop(read_framer(T3CSR_DBL_FEAC) & 0x3F));
1298150850Sscottl  printf("Last Rx  FEAC msg:\t0x%02X (%s)\n",
1299150850Sscottl   read_framer(T3CSR_RX_FEAC)  & 0x3F,
1300150850Sscottl   print_t3_bop(read_framer(T3CSR_RX_FEAC) & 0x3F));
1301150850Sscottl  print_t3_snmp();
1302216600Suqs}
1303150850Sscottl
1304216600Suqsstatic void
1305216600Suqst3_cmd(int argc, char **argv)
1306216600Suqs{
1307150850Sscottl  int ch;
1308150850Sscottl
1309150850Sscottl  while ((ch = getopt(argc, argv, "a:A:B:c:de:fF:lLsS:vV:")) != -1)
1310150850Sscottl    {
1311150850Sscottl    switch (ch)
1312150850Sscottl      {
1313150850Sscottl      case 'a': /* stop alarms */
1314150850Sscottl        {
1315150850Sscottl        switch (optarg[0])
1316150850Sscottl          {
1317150850Sscottl          case 'a': /* Stop sending AIS Signal */
1318150850Sscottl            {
1319150850Sscottl            write_mii(16,
1320150850Sscottl             read_mii(16) & ~MII16_DS3_FRAME);
1321150850Sscottl            write_framer(T3CSR_CTL1,
1322150850Sscottl             read_framer(T3CSR_CTL1) & ~CTL1_TXAIS);
1323150850Sscottl            if (verbose) printf("Stop sending Alarm Indication Signal (AIS)\n");
1324150850Sscottl            break;
1325150850Sscottl            }
1326150850Sscottl          case 'b': /* Stop sending Blue signal */
1327150850Sscottl            {
1328150850Sscottl            write_mii(16,
1329150850Sscottl             read_mii(16) & ~MII16_DS3_FRAME);
1330150850Sscottl            write_framer(T3CSR_CTL8,
1331150850Sscottl             read_framer(T3CSR_CTL8) & ~CTL8_TBLU);
1332150850Sscottl            if (verbose) printf("Stop sending Blue signal\n");
1333150850Sscottl            break;
1334150850Sscottl            }
1335150850Sscottl          case 'i': /* Stop sending IDLE signal */
1336150850Sscottl            {
1337150850Sscottl            write_framer(T3CSR_CTL1,
1338150850Sscottl             read_framer(T3CSR_CTL1) & ~CTL1_TXIDL);
1339150850Sscottl            if (verbose) printf("Stop sending IDLE signal\n");
1340150850Sscottl            break;
1341150850Sscottl            }
1342150850Sscottl          case 'y': /* Stop sending Yellow alarm */
1343150850Sscottl            {
1344150850Sscottl            write_framer(T3CSR_CTL1,
1345150850Sscottl             read_framer(T3CSR_CTL1) | CTL1_XTX);
1346150850Sscottl            if (verbose) printf("Stop sending Yellow alarm\n");
1347150850Sscottl            break;
1348150850Sscottl            }
1349150850Sscottl          default:
1350150850Sscottl            printf("Unknown alarm: %c\n", optarg[0]);
1351150850Sscottl            break;
1352150850Sscottl          }
1353150850Sscottl        break;
1354150850Sscottl        }
1355150850Sscottl      case 'A': /* start alarms */
1356150850Sscottl        {
1357150850Sscottl        switch (optarg[0])
1358150850Sscottl          {
1359150850Sscottl          case 'a': /* Start sending AIS Signal */
1360150850Sscottl            {
1361150850Sscottl            write_mii(16,
1362150850Sscottl             read_mii(16) | MII16_DS3_FRAME);
1363150850Sscottl            write_framer(T3CSR_CTL1,
1364150850Sscottl             read_framer(T3CSR_CTL1) | CTL1_TXAIS);
1365150850Sscottl            if (verbose) printf("Sending AIS signal (framed 1010..)\n");
1366150850Sscottl            break;
1367150850Sscottl            }
1368150850Sscottl          case 'b': /* Start sending Blue signal */
1369150850Sscottl            {
1370150850Sscottl            write_mii(16,
1371150850Sscottl             read_mii(16) | MII16_DS3_FRAME);
1372150850Sscottl            write_framer(T3CSR_CTL8,
1373150850Sscottl             read_framer(T3CSR_CTL8) | CTL8_TBLU);
1374150850Sscottl            if (verbose) printf("Sending Blue signal (unframed all 1s)\n");
1375150850Sscottl            break;
1376150850Sscottl            }
1377150850Sscottl          case 'i': /* Start sending IDLE signal */
1378150850Sscottl            {
1379150850Sscottl            write_framer(T3CSR_CTL1,
1380150850Sscottl             read_framer(T3CSR_CTL1) | CTL1_TXIDL);
1381150850Sscottl            if (verbose) printf("Sending IDLE signal (framed 1100..)\n");
1382150850Sscottl            break;
1383150850Sscottl            }
1384150850Sscottl          case 'y': /* Start sending Yellow alarm */
1385150850Sscottl            {
1386150850Sscottl            write_framer(T3CSR_CTL1,
1387150850Sscottl             read_framer(T3CSR_CTL1) & ~CTL1_XTX);
1388150850Sscottl            if (verbose) printf("Sending Yellow alarm (X-bits=0)\n");
1389150850Sscottl            break;
1390150850Sscottl            }
1391150850Sscottl          default:
1392150850Sscottl            printf("Unknown alarm: %c\n", optarg[0]);
1393150850Sscottl            break;
1394150850Sscottl          }
1395150850Sscottl        break;
1396150850Sscottl        }
1397150850Sscottl      case 'B': /* send BOP msg */
1398150850Sscottl        {
1399150850Sscottl        u_int8_t bop = strtoul(optarg, NULL, 0);
1400150850Sscottl        write_framer(T3CSR_TX_FEAC,  0xC0 + bop);
1401150850Sscottl        if (verbose) printf("Sent '0x%02X' BOP msg 10 times\n", bop);
1402150850Sscottl        break;
1403150850Sscottl	}
1404150850Sscottl      case 'c': /* set cable length */
1405150850Sscottl        {
1406150850Sscottl        config.cable_len = strtoul(optarg, NULL, 0);
1407150850Sscottl        if (verbose) print_cable_len();
1408150850Sscottl        update = 1;
1409150850Sscottl        break;
1410150850Sscottl        }
1411150850Sscottl      case 'd': /* DSU status */
1412150850Sscottl      case 's': /* deprecated */
1413150850Sscottl        {
1414150850Sscottl        print_t3_dsu();
1415150850Sscottl        break;
1416150850Sscottl        }
1417150850Sscottl      case 'e': /* set framimg format */
1418150850Sscottl        {
1419150850Sscottl        config.format = strtoul(optarg, NULL, 0);
1420150850Sscottl        if (verbose) print_format();
1421150850Sscottl        update = 1;
1422150850Sscottl        break;
1423150850Sscottl        }
1424150850Sscottl      case 'f': /* read and print framer regs */
1425150850Sscottl        {
1426150850Sscottl        int i;
1427150850Sscottl        printf("TXC03401 regs:\n");
1428150850Sscottl        printf("     0  1  2  3  4  5  6  7");
1429150850Sscottl        for (i=0; i<21; i++)
1430150850Sscottl          {
1431150850Sscottl          if (i%8 == 0) printf("\n%02X: ", i);
1432150850Sscottl          printf("%02X ", read_framer(i));
1433150850Sscottl          }
1434150850Sscottl        printf("\n\n");
1435150850Sscottl        break;
1436150850Sscottl        }
1437150850Sscottl      case 'F': /* write framer reg */
1438150850Sscottl        {
1439150850Sscottl        u_int32_t addr = strtoul(optarg, NULL, 0);
1440150850Sscottl        u_int32_t data = strtoul(argv[optind++], NULL, 0);
1441150850Sscottl        write_framer(addr, data);
1442150850Sscottl        if (verbose)
1443150850Sscottl          {
1444150850Sscottl          data = read_framer(addr);
1445150850Sscottl          printf("Write framer register: addr = 0x%02X data = 0x%02X\n", addr, data);
1446150850Sscottl	  }
1447150850Sscottl        break;
1448150850Sscottl        }
1449150850Sscottl      case 'l': /* send DS3 line loopback deactivate BOP cmd */
1450150850Sscottl        {
1451150850Sscottl        ioctl_snmp_send(TSEND_RESET);
1452150850Sscottl        if (verbose) printf("Sent 'DS3 Line Loopback deactivate' BOP cmd\n");
1453150850Sscottl        break;
1454150850Sscottl        }
1455150850Sscottl      case 'L': /* send DS3 line loopback activate BOP cmd */
1456150850Sscottl        {
1457150850Sscottl        ioctl_snmp_send(TSEND_LINE);
1458150850Sscottl        if (verbose) printf("Sent 'DS3 Line Loopback activate' BOP cmd\n");
1459150850Sscottl        break;
1460150850Sscottl        }
1461150850Sscottl      case 'S': /* set scrambler */
1462150850Sscottl        {
1463150850Sscottl        config.scrambler = strtoul(optarg, NULL, 0);
1464150850Sscottl        if (verbose) print_scrambler();
1465150850Sscottl        update = 1;
1466150850Sscottl        break;
1467150850Sscottl        }
1468150850Sscottl      case 'v': /* set verbose mode */
1469150850Sscottl        {
1470150850Sscottl        verbose = 1;
1471150850Sscottl        break;
1472150850Sscottl        }
1473150850Sscottl      case 'V': /* set T3 freq control DAC */
1474150850Sscottl        {
1475150850Sscottl        u_int32_t dac = strtoul(optarg, NULL, 0);
1476150850Sscottl        write_dac(dac);
1477150850Sscottl        if (verbose) printf("VCXO DAC value is %d\n", dac);
1478150850Sscottl        break;
1479150850Sscottl        }
1480150850Sscottl      default:
1481150850Sscottl        {
1482150850Sscottl        printf("Unknown command char: %c\n", ch);
1483150850Sscottl        exit(1);
1484150850Sscottl        } /* case */
1485150850Sscottl      } /* switch */
1486150850Sscottl    } /* while */
1487216600Suqs} /* proc */
1488150850Sscottl
1489216600Suqsstatic void
1490216600Suqsprint_test_pattern(int patt)
1491216600Suqs{
1492150850Sscottl  printf("Test Pattern:\t\t");
1493150850Sscottl  switch (patt)
1494150850Sscottl    {
1495150850Sscottl    case 0:
1496150850Sscottl      printf("unframed X^11+X^9+1\n");
1497150850Sscottl      break;
1498150850Sscottl    case 1:
1499150850Sscottl      printf("unframed X^15+X^14+1\n");
1500150850Sscottl      break;
1501150850Sscottl    case 2:
1502150850Sscottl      printf("unframed X^20+X^17+1\n");
1503150850Sscottl      break;
1504150850Sscottl    case 3:
1505150850Sscottl      printf("unframed X^23+X^18+1\n");
1506150850Sscottl      break;
1507150850Sscottl    case 4:
1508150850Sscottl      printf("unframed X^11+X^9+1 w/7ZS\n");
1509150850Sscottl      break;
1510150850Sscottl    case 5:
1511150850Sscottl      printf("unframed X^15+X^14+1 w/7ZS\n");
1512150850Sscottl      break;
1513150850Sscottl    case 6:
1514150850Sscottl      printf("unframed X^20+X^17+1 w/14ZS (QRSS)\n");
1515150850Sscottl      break;
1516150850Sscottl    case 7:
1517150850Sscottl      printf("unframed X^23+X^18+1 w/14ZS\n");
1518150850Sscottl      break;
1519150850Sscottl    case 8:
1520150850Sscottl      printf("framed X^11+X^9+1\n");
1521150850Sscottl      break;
1522150850Sscottl    case 9:
1523150850Sscottl      printf("framed X^15+X^14+1\n");
1524150850Sscottl      break;
1525150850Sscottl    case 10:
1526150850Sscottl      printf("framed X^20+X^17+1\n");
1527150850Sscottl      break;
1528150850Sscottl    case 11:
1529150850Sscottl      printf("framed X^23+X^18+1\n");
1530150850Sscottl      break;
1531298089Spfg    case 12:
1532150850Sscottl      printf("framed X^11+X^9+1 w/7ZS\n");
1533150850Sscottl      break;
1534150850Sscottl    case 13:
1535150850Sscottl      printf("framed X^15+X^14+1 w/7ZS\n");
1536150850Sscottl      break;
1537150850Sscottl    case 14:
1538150850Sscottl      printf("framed X^20+X^17+1 w/14ZS (QRSS)\n");
1539150850Sscottl      break;
1540150850Sscottl    case 15:
1541150850Sscottl      printf("framed X^23+X^18+1 w/14ZS\n");
1542150850Sscottl      break;
1543150850Sscottl    }
1544216600Suqs}
1545150850Sscottl
1546216600Suqsstatic char *
1547216600Suqsprint_t1_bop(int bop_code)
1548216600Suqs{
1549150850Sscottl  switch(bop_code)
1550150850Sscottl    {
1551150850Sscottl    case 0x00:
1552150850Sscottl      return "Yellow Alarm (far end LOF)";
1553150850Sscottl    case 0x07:
1554150850Sscottl      return "Line Loop up";
1555150850Sscottl    case 0x1C:
1556150850Sscottl      return "Line Loop down";
1557150850Sscottl    case 0x0A:
1558150850Sscottl      return "Payload Loop up";
1559150850Sscottl    case 0x19:
1560150850Sscottl      return "Payload Loop down";
1561150850Sscottl    case 0x09:
1562150850Sscottl      return "Network Loop up";
1563150850Sscottl    case 0x12:
1564150850Sscottl      return "Network Loop down";
1565150850Sscottl    default:
1566150850Sscottl      return "Unknown BOP code";
1567150850Sscottl    }
1568216600Suqs}
1569150850Sscottl
1570216600Suqsstatic void
1571216600Suqsprint_far_report(int index)
1572216600Suqs{
1573150850Sscottl  u_int16_t far = status.snmp.t1.prm[index];
1574150850Sscottl
1575150850Sscottl  printf(" SEQ=%d ", (far & T1PRM_SEQ)>>8);
1576150850Sscottl  if      (far & T1PRM_G1) printf("CRC=1");
1577150850Sscottl  else if (far & T1PRM_G2) printf("CRC=1 to 5");
1578150850Sscottl  else if (far & T1PRM_G3) printf("CRC=5 to 10");
1579150850Sscottl  else if (far & T1PRM_G4) printf("CRC=10 to 100");
1580150850Sscottl  else if (far & T1PRM_G5) printf("CRC=100 to 319");
1581150850Sscottl  else if (far & T1PRM_G6) printf("CRC>=320");
1582150850Sscottl  else                     printf("CRC=0");
1583150850Sscottl  printf(" SE=%d", (far & T1PRM_SE) ? 1 : 0);
1584150850Sscottl  printf(" FE=%d", (far & T1PRM_FE) ? 1 : 0);
1585150850Sscottl  printf(" LV=%d", (far & T1PRM_LV) ? 1 : 0);
1586150850Sscottl  printf(" SL=%d", (far & T1PRM_SL) ? 1 : 0);
1587150850Sscottl  printf(" LB=%d", (far & T1PRM_LB) ? 1 : 0);
1588150850Sscottl  printf("\n");
1589216600Suqs}
1590150850Sscottl
1591216600Suqsstatic void
1592216600Suqsprint_t1_snmp(void)
1593216600Suqs{
1594150850Sscottl  printf("SNMP Near-end performance data:\n");
1595150850Sscottl  printf(" LCV=%d",  status.snmp.t1.lcv);
1596150850Sscottl  printf(" LOS=%d", (status.snmp.t1.line & TLINE_LOS)    ? 1 : 0);
1597150850Sscottl  printf(" FE=%d",   status.snmp.t1.fe);
1598150850Sscottl  printf(" CRC=%d",  status.snmp.t1.crc);
1599150850Sscottl  printf(" AIS=%d", (status.snmp.t1.line & TLINE_RX_AIS) ? 1 : 0);
1600150850Sscottl  printf(" SEF=%d", (status.snmp.t1.line & T1LINE_SEF)   ? 1 : 0);
1601150850Sscottl  printf(" OOF=%d", (status.snmp.t1.line & TLINE_LOF)    ? 1 : 0);
1602150850Sscottl  printf("  RAI=%d",(status.snmp.t1.line & TLINE_RX_RAI) ? 1 : 0);
1603150850Sscottl  printf("\n");
1604150850Sscottl  if (config.format == CFG_FORMAT_T1ESF)
1605150850Sscottl    {
1606150850Sscottl    printf("ANSI Far-end performance reports:\n");
1607150850Sscottl    print_far_report(0);
1608150850Sscottl    print_far_report(1);
1609150850Sscottl    print_far_report(2);
1610150850Sscottl    print_far_report(3);
1611150850Sscottl    }
1612216600Suqs}
1613150850Sscottl
1614216600Suqsstatic void
1615216600Suqsprint_t1_dsu(void)
1616216600Suqs{
1617150850Sscottl  char *no = "No", *yes = "Yes";
1618150850Sscottl  u_int16_t mii16  = read_mii(16);
1619150850Sscottl  u_int8_t isr0    = read_framer(Bt8370_ISR0);
1620150850Sscottl  u_int8_t loop    = read_framer(Bt8370_LOOP);
1621150850Sscottl  u_int8_t vga_max = read_framer(Bt8370_VGA_MAX) & 0x3F;
1622150850Sscottl  u_int8_t alm1    = read_framer(Bt8370_ALM1);
1623150850Sscottl  u_int8_t alm3    = read_framer(Bt8370_ALM3);
1624150850Sscottl  u_int8_t talm    = read_framer(Bt8370_TALM);
1625150850Sscottl  u_int8_t tpatt   = read_framer(Bt8370_TPATT);
1626150850Sscottl  u_int8_t tpulse  = read_framer(Bt8370_TLIU_CR);
1627150850Sscottl  u_int8_t vga;
1628150850Sscottl  u_int8_t saved_pulse, saved_lbo;
1629150850Sscottl
1630150850Sscottl  /* d/c write required before read */
1631150850Sscottl  write_framer(Bt8370_VGA, 0);
1632150850Sscottl  vga = read_framer(Bt8370_VGA) & 0x3F;
1633150850Sscottl
1634150850Sscottl  print_format();
1635150850Sscottl  print_time_slots();
1636150850Sscottl  print_tx_clk_src();
1637150850Sscottl  print_tx_speed();
1638150850Sscottl
1639150850Sscottl  saved_pulse     = config.tx_pulse;
1640150850Sscottl  config.tx_pulse = tpulse & 0x0E;
1641150850Sscottl  saved_lbo       = config.tx_lbo;
1642150850Sscottl  config.tx_lbo   = tpulse & 0x30;
1643150850Sscottl  print_tx_pulse();
1644150850Sscottl  config.tx_pulse = saved_pulse;
1645150850Sscottl  config.tx_lbo   = saved_lbo;
1646150850Sscottl
1647150850Sscottl  printf("Tx outputs:    \t\t%sabled\n", (mii16 & MII16_T1_XOE) ? "En" : "Dis");
1648150850Sscottl  printf("Line impedance:\t\t%s ohms\n", (mii16 & MII16_T1_Z) ? "120" : "100");
1649150850Sscottl  printf("Max line loss: \t\t%4.1f dB\n", vga_dbs(vga_max));
1650150850Sscottl  printf("Cur line loss: \t\t%4.1f dB\n", vga_dbs(vga));
1651150850Sscottl  printf("Invert data:   \t\t%s\n", (mii16 & MII16_T1_INVERT) ? yes : no);
1652150850Sscottl  printf("Line    loop:  \t\t%s\n", (loop & LOOP_LINE)    ? yes : no);
1653150850Sscottl  printf("Payload loop:  \t\t%s\n", (loop & LOOP_PAYLOAD) ? yes : no);
1654150850Sscottl  printf("Framer  loop:  \t\t%s\n", (loop & LOOP_FRAMER)  ? yes : no);
1655150850Sscottl  printf("Analog  loop:  \t\t%s\n", (loop & LOOP_ANALOG)  ? yes : no);
1656150850Sscottl  printf("Tx AIS:        \t\t%s\n", ((talm & TALM_TAIS) ||
1657150850Sscottl   ((talm & TALM_AUTO_AIS) && (alm1 & ALM1_RLOS))) ? yes : no);
1658150850Sscottl  printf("Rx AIS:        \t\t%s\n", (alm1 & ALM1_RAIS)  ? yes : no);
1659150850Sscottl  if (((config.format & 1)==0) && (config.format != CFG_FORMAT_E1NONE))
1660150850Sscottl    {
1661150850Sscottl    printf("Tx RAI:        \t\t%s\n", ((talm & TALM_TYEL) ||
1662150850Sscottl     ((talm & TALM_AUTO_YEL) && (alm3 & ALM3_FRED))) ? yes : no);
1663150850Sscottl    printf("Rx RAI:        \t\t%s\n", (alm1 & ALM1_RYEL)  ? yes : no);
1664150850Sscottl    }
1665150850Sscottl  if (config.format == CFG_FORMAT_T1ESF)
1666150850Sscottl    {
1667150850Sscottl    printf("Tx BOP RAI:    \t\t%s\n", (alm1 & ALM1_RLOF)  ? yes : no);
1668150850Sscottl    printf("Rx BOP RAI:    \t\t%s\n", (alm1 & ALM1_RMYEL) ? yes : no);
1669150850Sscottl    }
1670150850Sscottl  if ((config.format & 0x11) == 0x10) /* E1CAS */
1671150850Sscottl    {
1672150850Sscottl    printf("Rx TS16 AIS:   \t\t%s\n", (alm3 & ALM3_RMAIS) ? yes : no);
1673150850Sscottl    printf("Tx TS16 RAI;   \t\t%s\n",
1674150850Sscottl     ((talm & TALM_AUTO_MYEL) && (alm3 & ALM3_SRED)) ? yes : no);
1675150850Sscottl    }
1676150850Sscottl  printf("Rx LOS analog: \t\t%s\n", (alm1 & ALM1_RALOS) ? yes : no);
1677150850Sscottl  printf("Rx LOS digital:\t\t%s\n", (alm1 & ALM1_RLOS)  ? yes : no);
1678150850Sscottl  printf("Rx LOF:        \t\t%s\n", (alm1 & ALM1_RLOF)  ? yes : no);
1679150850Sscottl  printf("Tx QRS:        \t\t%s\n", (tpatt & 0x10)      ? yes : no);
1680150850Sscottl  printf("Rx QRS:        \t\t%s\n", (isr0 & 0x10)       ? yes : no);
1681150850Sscottl  printf("LCV errors:    \t\t%d\n",
1682150850Sscottl   read_framer(Bt8370_LCV_LO)  + (read_framer(Bt8370_LCV_HI)<<8));
1683150850Sscottl  if (config.format != CFG_FORMAT_E1NONE)
1684150850Sscottl    {
1685150850Sscottl    if ((config.format & 1)==0) printf("Far End Block Errors:\t%d\n",
1686150850Sscottl     read_framer(Bt8370_FEBE_LO) + (read_framer(Bt8370_FEBE_HI)<<8));
1687150850Sscottl    printf("CRC errors:    \t\t%d\n",
1688150850Sscottl     read_framer(Bt8370_CRC_LO)  + (read_framer(Bt8370_CRC_HI)<<8));
1689150850Sscottl    printf("Frame errors:  \t\t%d\n",
1690150850Sscottl     read_framer(Bt8370_FERR_LO) + (read_framer(Bt8370_FERR_HI)<<8));
1691150850Sscottl    printf("Sev Err Frms:  \t\t%d\n", read_framer(Bt8370_AERR) & 0x03);
1692150850Sscottl    printf("Change of Frm align:\t%d\n",  (read_framer(Bt8370_AERR) & 0x0C)>>2);
1693150850Sscottl    printf("Loss of Frame events:\t%d\n", (read_framer(Bt8370_AERR) & 0xF0)>>4);
1694150850Sscottl    }
1695150850Sscottl  if (config.format == CFG_FORMAT_T1ESF)
1696150850Sscottl    {
1697150850Sscottl    printf("Last Tx BOP msg:\t0x%02X (%s)\n",
1698150850Sscottl     read_framer(Bt8370_TBOP), print_t1_bop(read_framer(Bt8370_TBOP)));
1699150850Sscottl    printf("Last Rx BOP msg:\t0x%02X (%s)\n",
1700150850Sscottl     read_framer(Bt8370_RBOP), print_t1_bop(read_framer(Bt8370_RBOP)&0x3F));
1701150850Sscottl    }
1702150850Sscottl  print_t1_snmp();
1703216600Suqs}
1704150850Sscottl
1705216600Suqsstatic void
1706216600Suqst1_cmd(int argc, char **argv)
1707216600Suqs{
1708150850Sscottl  int ch;
1709150850Sscottl
1710150850Sscottl  while ((ch = getopt(argc, argv, "a:A:B:c:de:E:fF:g:iIlLpPstT:u:U:vxX")) != -1)
1711150850Sscottl    {
1712150850Sscottl    switch (ch)
1713150850Sscottl      {
1714150850Sscottl      case 'a': /* stop alarms */
1715150850Sscottl        {
1716150850Sscottl        switch (optarg[0])
1717150850Sscottl          {
1718150850Sscottl          case 'y': /* Stop sending Yellow Alarm */
1719150850Sscottl            {
1720150850Sscottl            if ((config.format == CFG_FORMAT_T1SF) ||
1721150850Sscottl                (config.format == CFG_FORMAT_E1NONE))
1722150850Sscottl              printf("No Yellow alarm for this frame format\n");
1723150850Sscottl            else if (config.format == CFG_FORMAT_T1ESF)
1724150850Sscottl              write_framer(Bt8370_BOP,  0xE0); /* rbop 25, tbop off */
1725150850Sscottl            else
1726150850Sscottl              {
1727150850Sscottl              u_int8_t talm = read_framer(Bt8370_TALM);
1728150850Sscottl              write_framer(Bt8370_TALM, talm & ~TALM_TYEL);
1729150850Sscottl	      }
1730150850Sscottl            if (verbose) printf("Stop sending Yellow alarm\n");
1731150850Sscottl            break;
1732150850Sscottl            }
1733150850Sscottl          case 'a': /* Stop sending AIS */
1734150850Sscottl          case 'b': /* Stop sending Blue Alarm */
1735150850Sscottl            {
1736150850Sscottl            u_int8_t talm = read_framer(Bt8370_TALM);
1737150850Sscottl            write_framer(Bt8370_TALM, talm & ~TALM_TAIS);
1738150850Sscottl            if (verbose) printf("Stop sending AIS/Blue signal\n");
1739150850Sscottl            break;
1740150850Sscottl            }
1741150850Sscottl          default:
1742150850Sscottl            printf("Unknown alarm: %c\n", optarg[0]);
1743150850Sscottl          }
1744150850Sscottl        break;
1745150850Sscottl        }
1746150850Sscottl      case 'A': /* start alarms */
1747150850Sscottl        {
1748150850Sscottl        switch (optarg[0])
1749150850Sscottl          {
1750150850Sscottl          case 'y': /* Start sending Yellow Alarm */
1751150850Sscottl            {
1752150850Sscottl            if ((config.format == CFG_FORMAT_T1SF) ||
1753150850Sscottl                (config.format == CFG_FORMAT_E1NONE))
1754150850Sscottl              printf("No Yellow alarm for this frame format\n");
1755150850Sscottl            else if (config.format == CFG_FORMAT_T1ESF)
1756150850Sscottl              {
1757150850Sscottl              write_framer(Bt8370_BOP,  0x0F); /* rbop off, tbop cont */
1758150850Sscottl              write_framer(Bt8370_TBOP, T1BOP_OOF);
1759150850Sscottl	      }
1760150850Sscottl            else
1761150850Sscottl              {
1762150850Sscottl              u_int8_t talm = read_framer(Bt8370_TALM);
1763150850Sscottl              write_framer(Bt8370_TALM, talm | TALM_TYEL);
1764150850Sscottl	      }
1765150850Sscottl            if (verbose) printf("Sending Yellow alarm\n");
1766150850Sscottl            break;
1767150850Sscottl            }
1768150850Sscottl          case 'a': /* Start sending AIS */
1769150850Sscottl          case 'b': /* Start sending Blue Alarm */
1770150850Sscottl            {
1771150850Sscottl            u_int8_t talm = read_framer(Bt8370_TALM);
1772150850Sscottl            write_framer(Bt8370_TALM, talm | TALM_TAIS);
1773150850Sscottl            if (verbose) printf("Sending AIS/Blue signal\n");
1774150850Sscottl            break;
1775150850Sscottl            }
1776150850Sscottl          default:
1777150850Sscottl            printf("Unknown alarm: %c\n", optarg[0]);
1778150850Sscottl          }
1779150850Sscottl        break;
1780150850Sscottl        }
1781150850Sscottl      case 'B': /* send BOP msg */
1782150850Sscottl        {
1783150850Sscottl        u_int8_t bop = strtoul(optarg, NULL, 0);
1784150850Sscottl        if (config.format == CFG_FORMAT_T1ESF)
1785150850Sscottl          {
1786150850Sscottl          write_framer(Bt8370_BOP, 0x0B); /* rbop off, tbop 25 */
1787150850Sscottl          write_framer(Bt8370_TBOP, bop); /* start sending BOP msg */
1788150850Sscottl          sleep(1);  /* sending 25 BOP msgs takes about 100 ms. */
1789150850Sscottl          write_framer(Bt8370_BOP, 0xE0); /* rbop 25, tbop off */
1790150850Sscottl          if (verbose) printf("Sent '0x%02X' BOP msg 25 times\n", bop);
1791150850Sscottl	  }
1792150850Sscottl        else
1793150850Sscottl          printf("BOP msgs only work in T1-ESF format\n");
1794150850Sscottl        break;
1795150850Sscottl	}
1796150850Sscottl      case 'c': /* set cable length */
1797150850Sscottl        {
1798150850Sscottl        config.cable_len = strtoul(optarg, NULL, 0);
1799150850Sscottl        if (verbose) print_cable_len();
1800150850Sscottl        update = 1;
1801150850Sscottl        break;
1802150850Sscottl        }
1803150850Sscottl      case 'd': /* DSU status */
1804150850Sscottl      case 's': /* deprecated */
1805150850Sscottl        {
1806150850Sscottl        print_t1_dsu();
1807150850Sscottl        break;
1808150850Sscottl        }
1809150850Sscottl      case 'e': /* set framimg format */
1810150850Sscottl        {
1811150850Sscottl        config.format = strtoul(optarg, NULL, 0);
1812150850Sscottl        if (verbose) print_format();
1813150850Sscottl        update = 1;
1814150850Sscottl        break;
1815150850Sscottl        }
1816150850Sscottl      case 'E': /* set time slots */
1817150850Sscottl        {
1818150850Sscottl        config.time_slots = strtoul(optarg, NULL, 16);
1819150850Sscottl        if (verbose) print_time_slots();
1820150850Sscottl        update = 1;
1821150850Sscottl        break;
1822150850Sscottl        }
1823150850Sscottl      case 'f': /* read and print framer regs */
1824150850Sscottl        {
1825150850Sscottl        int i;
1826150850Sscottl        printf("Bt8370 regs:\n");
1827150850Sscottl        printf("     0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F");
1828150850Sscottl        for (i=0; i<512; i++)
1829150850Sscottl          {
1830150850Sscottl          if (i%16 == 0) printf("\n%03X: ", i);
1831150850Sscottl          printf("%02X ", read_framer(i));
1832150850Sscottl	  }
1833150850Sscottl        printf("\n\n");
1834150850Sscottl        break;
1835150850Sscottl	}
1836150850Sscottl      case 'F': /* write framer reg */
1837150850Sscottl        {
1838150850Sscottl        u_int32_t addr = strtoul(optarg, NULL, 0);
1839150850Sscottl        u_int32_t data = strtoul(argv[optind++], NULL, 0);
1840150850Sscottl        write_framer(addr, data);
1841150850Sscottl        if (verbose)
1842150850Sscottl          {
1843150850Sscottl          data = read_framer(addr);
1844150850Sscottl          printf("Write framer register: addr = 0x%02X data = 0x%02X\n", addr, data);
1845150850Sscottl	  }
1846150850Sscottl        break;
1847150850Sscottl	}
1848150850Sscottl      case 'g': /* set receiver gain */
1849150850Sscottl        {
1850150850Sscottl        config.rx_gain = strtoul(optarg, NULL, 0);
1851150850Sscottl        if (verbose) print_rx_gain();
1852150850Sscottl        update = 1;
1853150850Sscottl        break;
1854150850Sscottl        }
1855150850Sscottl      case 'i': /* send CSU loopback deactivate inband cmd */
1856150850Sscottl        {
1857150850Sscottl        if (config.format == CFG_FORMAT_T1SF)
1858150850Sscottl          {
1859150850Sscottl          if (verbose) printf("Sending 'CSU loop down' inband cmd for 10 secs...");
1860150850Sscottl          ioctl_snmp_send(TSEND_RESET);
1861150850Sscottl          sleep(10);
1862150850Sscottl          ioctl_snmp_send(TSEND_NORMAL);
1863150850Sscottl          if (verbose) printf("done\n");
1864150850Sscottl	  }
1865150850Sscottl        else
1866150850Sscottl          printf("Inband loopback cmds only work in T1-SF format");
1867150850Sscottl        break;
1868150850Sscottl        }
1869150850Sscottl      case 'I': /* send CSU loopback activate inband cmd */
1870150850Sscottl        {
1871150850Sscottl        if (config.format == CFG_FORMAT_T1SF)
1872150850Sscottl          {
1873150850Sscottl          if (verbose) printf("Sending 'CSU loop up' inband cmd for 10 secs...");
1874150850Sscottl          ioctl_snmp_send(TSEND_LINE);
1875150850Sscottl          sleep(10);
1876150850Sscottl          ioctl_snmp_send(TSEND_NORMAL);
1877150850Sscottl          if (verbose) printf("done\n");
1878150850Sscottl	  }
1879150850Sscottl        else
1880150850Sscottl          printf("Inband loopback cmds only work in T1-SF format");
1881150850Sscottl        break;
1882150850Sscottl        }
1883150850Sscottl      case 'l': /* send line loopback deactivate BOP msg */
1884150850Sscottl        {
1885150850Sscottl        if (config.format == CFG_FORMAT_T1ESF)
1886150850Sscottl          {
1887150850Sscottl          ioctl_snmp_send(TSEND_RESET);
1888150850Sscottl          if (verbose) printf("Sent 'Line Loop Down' BOP cmd\n");
1889150850Sscottl	  }
1890150850Sscottl        else
1891150850Sscottl          printf("BOP msgs only work in T1-ESF format\n");
1892150850Sscottl        break;
1893150850Sscottl        }
1894150850Sscottl      case 'L': /* send line loopback activate BOP msg */
1895150850Sscottl        {
1896150850Sscottl        if (config.format == CFG_FORMAT_T1ESF)
1897150850Sscottl          {
1898150850Sscottl          ioctl_snmp_send(TSEND_LINE);
1899150850Sscottl          if (verbose) printf("Sent 'Line Loop Up' BOP cmd\n");
1900150850Sscottl	  }
1901150850Sscottl        else
1902150850Sscottl          printf("BOP msgs only work in T1-ESF format\n");
1903150850Sscottl        break;
1904150850Sscottl        }
1905150850Sscottl      case 'p': /* send payload loopback deactivate BOP msg */
1906150850Sscottl        {
1907150850Sscottl        if (config.format == CFG_FORMAT_T1ESF)
1908150850Sscottl          {
1909150850Sscottl          ioctl_snmp_send(TSEND_RESET);
1910150850Sscottl          if (verbose) printf("Sent 'Payload Loop Down' BOP cmd\n");
1911150850Sscottl	  }
1912150850Sscottl        else
1913150850Sscottl          printf("BOP msgs only work in T1-ESF format\n");
1914150850Sscottl        break;
1915150850Sscottl        }
1916150850Sscottl      case 'P': /* send payload loopback activate BOP msg */
1917150850Sscottl        {
1918150850Sscottl        if (config.format == CFG_FORMAT_T1ESF)
1919150850Sscottl          {
1920150850Sscottl          ioctl_snmp_send(TSEND_PAYLOAD);
1921150850Sscottl          if (verbose) printf("Sent 'Payload Loop Up' BOP cmd\n");
1922150850Sscottl	  }
1923150850Sscottl        else
1924150850Sscottl          printf("BOP msgs only work in T1-ESF format\n");
1925150850Sscottl        break;
1926150850Sscottl        }
1927150850Sscottl      case 't': /* stop sending test pattern */
1928150850Sscottl        {
1929150850Sscottl        ioctl_snmp_send(TSEND_NORMAL);
1930150850Sscottl        if (verbose) printf("Stop sending test pattern\n");
1931150850Sscottl        break;
1932150850Sscottl        }
1933150850Sscottl      case 'T': /* start sending test pattern */
1934150850Sscottl        {
1935150850Sscottl        u_int8_t patt = strtoul(optarg, NULL, 0);
1936150850Sscottl        write_framer(Bt8370_TPATT, 0x10 + patt);
1937150850Sscottl        write_framer(Bt8370_RPATT, 0x30 + patt);
1938150850Sscottl        if (verbose) print_test_pattern(patt);
1939150850Sscottl        break;
1940150850Sscottl        }
1941150850Sscottl      case 'u': /* set transmit pulse shape */
1942150850Sscottl        {
1943150850Sscottl        config.tx_pulse = strtoul(optarg, NULL, 0);
1944150850Sscottl        if (verbose) print_tx_pulse();
1945150850Sscottl        update = 1;
1946150850Sscottl        break;
1947150850Sscottl        }
1948150850Sscottl      case 'U': /* set tx line build-out */
1949150850Sscottl        {
1950150850Sscottl        if (config.tx_pulse == CFG_PULSE_T1CSU)
1951150850Sscottl          {
1952150850Sscottl          config.tx_lbo = strtoul(optarg, NULL, 0);
1953150850Sscottl          if (verbose) print_tx_pulse();
1954150850Sscottl          update = 1;
1955150850Sscottl	  }
1956150850Sscottl        else
1957150850Sscottl          printf("LBO only meaningful if Tx Pulse is T1CSU\n");
1958150850Sscottl        break;
1959150850Sscottl        }
1960150850Sscottl      case 'v': /* set verbose mode */
1961150850Sscottl        {
1962150850Sscottl        verbose = 1;
1963150850Sscottl        break;
1964150850Sscottl        }
1965150850Sscottl      case 'x': /* disable transmitter outputs */
1966150850Sscottl        {
1967150850Sscottl        write_mii(16, read_mii(16) & ~MII16_T1_XOE);
1968150850Sscottl        if (verbose) printf("Transmitter outputs disabled\n");
1969150850Sscottl        break;
1970150850Sscottl	}
1971150850Sscottl      case 'X': /* enable transmitter outputs */
1972150850Sscottl        {
1973150850Sscottl        write_mii(16, read_mii(16) |  MII16_T1_XOE);
1974150850Sscottl        if (verbose) printf("Transmitter outputs enabled\n");
1975150850Sscottl        break;
1976150850Sscottl        }
1977150850Sscottl      default:
1978150850Sscottl        {
1979150850Sscottl        printf("Unknown command char: %c\n", ch);
1980150850Sscottl        exit(1);
1981150850Sscottl        } /* case */
1982150850Sscottl      } /* switch */
1983150850Sscottl    } /* while */
1984216600Suqs} /* proc */
1985150850Sscottl
1986150850Sscottl/* used when reading Motorola S-Record format ROM files */
1987216600Suqsstatic unsigned char
1988216600Suqsread_hex(FILE *f)
1989216600Suqs{
1990150850Sscottl  unsigned char a, b, c;
1991150850Sscottl  for (a=0, b=0; a<2; a++)
1992150850Sscottl    {
1993150850Sscottl    c = fgetc(f);
1994150850Sscottl    c -= 48;
1995150850Sscottl    if (c > 9) c -= 7;
1996150850Sscottl    b = (b<<4) | (c & 0xF);
1997150850Sscottl    }
1998150850Sscottl  checksum += b;
1999150850Sscottl  return b;
2000216600Suqs}
2001150850Sscottl
2002216600Suqsstatic void
2003216600Suqsload_xilinx(char *name)
2004216600Suqs{
2005150850Sscottl  FILE *f;
2006150850Sscottl  char *ucode;
2007150850Sscottl  int i, length;
2008216599Suqs  int c;
2009150850Sscottl
2010150850Sscottl  if (verbose) printf("Load firmware from file %s...\n", name);
2011297965Saraujo  if ((f = fopen(name, "r")) == NULL)
2012150850Sscottl    {
2013150850Sscottl    perror("Failed to open file");
2014150850Sscottl    exit(1);
2015150850Sscottl    }
2016150850Sscottl
2017150850Sscottl  ucode = (char *)malloc(8192); bzero(ucode, 8192);
2018150850Sscottl
2019150850Sscottl  c = fgetc(f);
2020150850Sscottl  if (c == 'X')
2021150850Sscottl    { /* Xilinx raw bits file (foo.rbt) */
2022150850Sscottl    /* skip seven lines of boiler plate */
2023150850Sscottl    for (i=0; i<7;) if ((c=fgetc(f))=='\n') i++;
2024150850Sscottl    /* build a dense bit array */
2025150850Sscottl    i = length = 0;
2026150850Sscottl    while ((c=fgetc(f))!=EOF)
2027150850Sscottl      {  /* LSB first */
2028150850Sscottl      if (c=='1') ucode[length] |= 1<<i++;
2029150850Sscottl      if (c=='0') i++;
2030150850Sscottl      if (i==8) { i=0; length++; }
2031150850Sscottl      }
2032150850Sscottl    }
2033150850Sscottl  else if (c == 'S')
2034150850Sscottl    { /* Motarola S records (foo.exo) */
2035150850Sscottl    int blklen;
2036150850Sscottl    length = 0;
2037150850Sscottl    ungetc(c, f);
2038150850Sscottl    while ((c = fgetc(f)) != EOF)
2039150850Sscottl      {
2040150850Sscottl      if (c != 'S')
2041150850Sscottl        {
2042150850Sscottl        printf("I'm confused; I expected an 'S'\n");
2043150850Sscottl        exit(1);
2044150850Sscottl        }
2045150850Sscottl      c = fgetc(f);
2046150850Sscottl      if (c == '9') break;
2047150850Sscottl      else if (c == '1')
2048150850Sscottl        {
2049150850Sscottl        checksum = 0;
2050150850Sscottl        blklen = read_hex(f) -3;
2051150850Sscottl        read_hex(f); /* hi blkaddr */
2052150850Sscottl        read_hex(f); /* lo blkaddr */
2053150850Sscottl        for (i=0; i<blklen; i++)
2054150850Sscottl          ucode[length++] = read_hex(f);
2055150850Sscottl        read_hex(f); /* process but ignore checksum */
2056150850Sscottl        if (checksum != 0xFF)
2057150850Sscottl          {
2058150850Sscottl          printf("File checksum error\n");
2059150850Sscottl          exit(1);
2060150850Sscottl          }
2061150850Sscottl        c = fgetc(f); /* throw away eol */
2062150850Sscottl        c = fgetc(f); /* throw away eol */
2063150850Sscottl        }
2064150850Sscottl      else
2065150850Sscottl        {
2066150850Sscottl        printf("I'm confused; I expected a '1' or a '9'\n");
2067150850Sscottl        exit(1);
2068150850Sscottl        }
2069150850Sscottl      } /* while */
2070150850Sscottl    } /* Motorola S-Record */
2071150850Sscottl  else
2072150850Sscottl    {
2073150850Sscottl    printf("Unknown file type giving up\n");
2074150850Sscottl    exit(1);
2075150850Sscottl    }
2076150850Sscottl
2077150850Sscottl  load_xilinx_from_file(ucode, length);
2078216600Suqs}
2079150850Sscottl
2080150850Sscottl/* 32-bit CRC calculated right-to-left over 8-bit bytes */
2081216600Suqsstatic u_int32_t
2082216600Suqscrc32(char *bufp, int len)
2083216600Suqs{
2084150850Sscottl  int bit, i;
2085150850Sscottl  u_int32_t data;
2086150850Sscottl  u_int32_t crc  = 0xFFFFFFFFL;
2087150850Sscottl  u_int32_t poly = 0xEDB88320L;
2088150850Sscottl
2089150850Sscottl  for (i = 0; i < len; i++)
2090150850Sscottl    for (data = *bufp++, bit = 0; bit < 8; bit++, data >>= 1)
2091150850Sscottl      crc = (crc >> 1) ^ (((crc ^ data) & 1) ? poly : 0);
2092150850Sscottl
2093150850Sscottl  return crc;
2094216600Suqs}
2095150850Sscottl
2096150850Sscottl/* 8-bit CRC calculated left-to-right over 16-bit words */
2097216600Suqsstatic u_int8_t
2098216600Suqscrc8(u_int16_t *bufp, int len)
2099216600Suqs{
2100150850Sscottl  int bit, i;
2101150850Sscottl  u_int16_t data;
2102150850Sscottl  u_int8_t crc  = 0xFF;
2103150850Sscottl  u_int8_t poly = 0x07;
2104150850Sscottl
2105150850Sscottl  for (i = 0; i < len; i++)
2106150850Sscottl    for (data = *bufp++, bit = 15; bit >= 0; bit--)
2107150850Sscottl      {
2108150850Sscottl      if ((i==8) && (bit==7)) break;
2109150850Sscottl      crc = (crc << 1) ^ ((((crc >> 7) ^ (data >> bit)) & 1) ? poly : 0);
2110150850Sscottl      }
2111150850Sscottl  return crc;
2112216600Suqs}
2113150850Sscottl
2114150850Sscottl/* HSSI=3, DS3=4, SSI=5, T1E1=6, HSSIc=7, SDSL=8 */
2115216600Suqsvoid
2116216600Suqsinit_srom(int board)
2117216600Suqs{
2118150850Sscottl  int i;
2119150850Sscottl  u_int16_t srom[64];
2120150850Sscottl
2121150850Sscottl  /* zero the entire rom */
2122150850Sscottl  for (i=0; i<64; i++) srom[i] = 0;
2123150850Sscottl
2124150850Sscottl  srom[0]  = 0x1376; /* subsys vendor id */
2125150850Sscottl  srom[1]  = board ? board : (read_mii(3)>>4 & 0xF) +1;
2126150850Sscottl  srom[8]  = crc8(srom, 9);
2127150850Sscottl  /* Tulip hardware checks this checksum */
2128150850Sscottl  srom[10] = 0x6000; /* ethernet address */
2129150850Sscottl  srom[11] = 0x0099; /* ethernet address */
2130150850Sscottl  srom[12] = 0x0000; /* ethernet address */
2131150850Sscottl  /* srom checksum is low 16 bits of Ethernet CRC-32 */
2132150850Sscottl  srom[63] = crc32((char *)srom, 126) ^ 0xFFFFFFFFL;
2133150850Sscottl
2134150850Sscottl  /* write the SROM */
2135150850Sscottl#if 1 /* really write it */
2136150850Sscottl  for (i=0; i<64; i++) write_srom(i, srom[i]);
2137150850Sscottl#else /* print what would be written */
2138150850Sscottl  printf("     0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F");
2139150850Sscottl  for (i=0; i<64; i++)
2140150850Sscottl    {
2141150850Sscottl    if (i%8 == 0) printf("\n%02X: ", i<<1);
2142150850Sscottl    printf("%02X %02X ", srom[i] & 0xFF, srom[i]>>8);
2143150850Sscottl    }
2144150850Sscottl  printf("\n\n");
2145150850Sscottl#endif
2146216600Suqs}
2147150850Sscottl
2148216600Suqsint
2149216600Suqsmain(int argc, char **argv)
2150216600Suqs{
2151150850Sscottl  int i, error, ch;
2152150850Sscottl  char *optstring = "13a:bBcCdDeEf:Fhi:L:mM:pP:sS:tT:uUvVwW:xXyYzZ?";
2153150850Sscottl
2154150850Sscottl  progname = (char *)argv[0];
2155150850Sscottl
2156150850Sscottl  /* Here is the overall plan:
2157150850Sscottl   *  1) Read the interface name from the command line.
2158150850Sscottl   *  2) Open the device; decide if netgraph is being used.
2159150850Sscottl   *  3) Read the current interface configuration from the driver.
2160150850Sscottl   *  4) Read the command line args and carry out their actions.
2161150850Sscottl   *  5) Write the modified interface configuration to the driver.
2162150850Sscottl   */
2163150850Sscottl
2164150850Sscottl  /* 1) Read the interface name from the command line. */
2165150850Sscottl#if __linux__
2166150850Sscottl  ifname = (argc==1) ? "hdlc0" : (char *) argv[1];
2167150850Sscottl#else
2168150850Sscottl  ifname = (argc==1) ? DEVICE_NAME"0" : (char *) argv[1];
2169150850Sscottl#endif
2170150850Sscottl
2171150850Sscottl  /* 2) Open the device; decide if netgraph is being used, */
2172150850Sscottl  /* use netgraph if ifname ends with ":" */
2173150850Sscottl  for (i=0; i<16; i++) if (ifname[i] == 0) break;
2174150850Sscottl
2175150850Sscottl  /* Get a socket type file descriptor. */
2176150850Sscottl#if defined(NETGRAPH)
2177150850Sscottl  if ((netgraph = (ifname[i-1] == ':')))
2178150850Sscottl    error = NgMkSockNode(NULL, &fdcs, NULL);
2179150850Sscottl  else
2180150850Sscottl#endif
2181150850Sscottl    error = fdcs = socket(AF_INET, SOCK_DGRAM, 0);
2182150850Sscottl  if (error < 0)
2183150850Sscottl    {
2184150850Sscottl    fprintf(stderr, "%s: %s() failed: %s\n", progname,
2185150850Sscottl     netgraph? "NgMkSockNode" : "socket", strerror(errno));
2186150850Sscottl    exit(1);
2187150850Sscottl    }
2188150850Sscottl
2189150850Sscottl  /* 3) Read the current interface configuration from the driver. */
2190150850Sscottl  ioctl_read_config();
2191150850Sscottl  ioctl_read_status();
2192150850Sscottl
2193150850Sscottl  summary = (argc <= 2);  /* print summary at end */
2194150850Sscottl  update  = 0;	/* write to card at end */
2195150850Sscottl
2196150850Sscottl  /* 4) Read the command line args and carry out their actions. */
2197150850Sscottl  optind = 2;
2198150850Sscottl  while (((ch = getopt(argc, argv, optstring)) != -1) && (argc > 2))
2199150850Sscottl    {
2200150850Sscottl    switch (ch)
2201150850Sscottl      {
2202150850Sscottl      case '1': /* T1 commands */
2203150850Sscottl        {
2204150850Sscottl        if (verbose) printf("Doing T1 settings\n");
2205150850Sscottl        if (status.card_type != TLP_CSID_T1E1)
2206150850Sscottl          {
2207150850Sscottl          printf("T1 settings only apply to T1E1 cards\n");
2208150850Sscottl          exit(1);
2209150850Sscottl          }
2210150850Sscottl        t1_cmd(argc, argv);
2211150850Sscottl        break;
2212150850Sscottl        }
2213150850Sscottl      case '3': /* T3 commands */
2214150850Sscottl        {
2215150850Sscottl        if (verbose) printf("Doing T3 settings\n");
2216150850Sscottl        if (status.card_type != TLP_CSID_T3)
2217150850Sscottl          {
2218150850Sscottl          printf("T3 settings only apply to T3 cards\n");
2219150850Sscottl          exit(1);
2220150850Sscottl          }
2221150850Sscottl        t3_cmd(argc, argv);
2222150850Sscottl        break;
2223150850Sscottl        }
2224150850Sscottl      case 'a': /* clock source */
2225150850Sscottl        {
2226150850Sscottl        if ((status.card_type != TLP_CSID_T1E1) ||
2227150850Sscottl            (status.card_type != TLP_CSID_HSSI) ||
2228150850Sscottl            (status.card_type != TLP_CSID_HSSIc))
2229150850Sscottl          {
2230150850Sscottl          if (verbose) print_tx_clk_src();
2231150850Sscottl          config.tx_clk_src = strtoul(optarg, NULL, 0);
2232150850Sscottl          update = 1;
2233150850Sscottl	  }
2234150850Sscottl        else
2235150850Sscottl          printf("txclksrc only applies to T1E1 and HSSI card types\n");
2236150850Sscottl        break;
2237150850Sscottl        }
2238150850Sscottl      case 'b': /* read bios rom */
2239150850Sscottl        {
2240150850Sscottl        int i;
2241150850Sscottl        printf("Bios ROM:\n");
2242150850Sscottl        printf("     0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F");
2243150850Sscottl        for (i=0; i<256; i++)
2244150850Sscottl          {
2245150850Sscottl          if (i%16 == 0) printf("\n%02X: ", i);
2246150850Sscottl          printf("%02X ", read_bios_rom(i));
2247150850Sscottl	  }
2248150850Sscottl        printf("\n\n");
2249150850Sscottl        break;
2250150850Sscottl	}
2251150850Sscottl      case 'B': /* write bios rom */
2252150850Sscottl        {
2253150850Sscottl        int i;
2254150850Sscottl        for (i=0; i<256; i++) write_bios_rom(i, 255-i);
2255150850Sscottl        if (verbose) printf("wrote (0..255) to bios rom addrs (0..255)\n");
2256150850Sscottl        break;
2257150850Sscottl	}
2258150850Sscottl      case 'c': /* set crc_len = 16 */
2259150850Sscottl        {
2260150850Sscottl        config.crc_len = CFG_CRC_16;
2261150850Sscottl        if (verbose) print_crc_len();
2262150850Sscottl        update = 1;
2263150850Sscottl        break;
2264150850Sscottl        }
2265150850Sscottl      case 'C': /* set crc_len = 32 */
2266150850Sscottl        {
2267150850Sscottl        config.crc_len = CFG_CRC_32;
2268150850Sscottl        if (verbose) print_crc_len();
2269150850Sscottl        update = 1;
2270150850Sscottl        break;
2271150850Sscottl        }
2272150850Sscottl      case 'd': /* clear DEBUG flag */
2273150850Sscottl        {
2274150850Sscottl        config.debug = 0;
2275150850Sscottl        if (verbose) printf("DEBUG flag cleared\n");
2276150850Sscottl        update = 1;
2277150850Sscottl        break;
2278150850Sscottl	}
2279150850Sscottl      case 'D': /* set DEBUG flag */
2280150850Sscottl        {
2281150850Sscottl        config.debug = 1;
2282150850Sscottl        if (verbose) printf("DEBUG flag set\n");
2283150850Sscottl        update = 1;
2284150850Sscottl        break;
2285150850Sscottl	}
2286150850Sscottl      case 'e': /* set DTE (default) */
2287150850Sscottl        {
2288150850Sscottl        if ((status.card_type == TLP_CSID_SSI) ||
2289150850Sscottl            (status.card_type == TLP_CSID_HSSIc))
2290150850Sscottl          {
2291150850Sscottl          config.dte_dce = CFG_DTE;
2292150850Sscottl          if (verbose) print_dte_dce();
2293150850Sscottl          update = 1;
2294150850Sscottl	  }
2295150850Sscottl        else
2296150850Sscottl          printf("DTE cmd only applies to SSI & HSSIc cards\n");
2297150850Sscottl        break;
2298150850Sscottl	}
2299150850Sscottl      case 'E': /* set DCE */
2300150850Sscottl        {
2301150850Sscottl        if ((status.card_type == TLP_CSID_SSI) ||
2302150850Sscottl            (status.card_type == TLP_CSID_HSSIc))
2303150850Sscottl          {
2304150850Sscottl          config.dte_dce = CFG_DCE;
2305150850Sscottl          if (verbose) print_dte_dce();
2306150850Sscottl          update = 1;
2307150850Sscottl	  }
2308150850Sscottl        else
2309150850Sscottl          printf("DCE cmd only applies to SSI & HSSIc cards\n");
2310150850Sscottl        break;
2311150850Sscottl	}
2312150850Sscottl      case 'f': /* set synth osc freq */
2313150850Sscottl        {
2314150850Sscottl        if ((status.card_type == TLP_CSID_SSI) ||
2315150850Sscottl            (status.card_type == TLP_CSID_HSSIc))
2316150850Sscottl          {
2317150850Sscottl          synth_freq(strtoul(optarg, NULL, 0));
2318150850Sscottl          write_synth(config.synth);
2319150850Sscottl          if (verbose) print_synth_freq();
2320150850Sscottl	  }
2321150850Sscottl        else
2322150850Sscottl          printf("synth osc freq only applies to SSI & HSSIc cards\n");
2323150850Sscottl        break;
2324150850Sscottl        }
2325150850Sscottl      case 'F': /* set SPPP line protocol to Frame-Relay */
2326150850Sscottl        {
2327150850Sscottl        config.line_prot = PROT_FRM_RLY;
2328150850Sscottl        config.keep_alive = 1; /* required for LMI operation */
2329150850Sscottl        if (verbose) printf("SPPP line protocol set to Frame-Relay\n");
2330150850Sscottl        update = 1;
2331150850Sscottl        break;
2332150850Sscottl	}
2333150850Sscottl      case 'h': /* help */
2334150850Sscottl      case '?':
2335150850Sscottl        {
2336150850Sscottl        usage();
2337150850Sscottl        exit(0);
2338150850Sscottl        }
2339150850Sscottl      case 'i': /* interface name */
2340150850Sscottl        {
2341150850Sscottl        /* already scanned this */
2342150850Sscottl        break;
2343150850Sscottl        }
2344150850Sscottl      case 'L': /* set loopback modes */
2345150850Sscottl        {
2346150850Sscottl        config.loop_back = strtoul(optarg, NULL, 0);
2347150850Sscottl        if (verbose) print_loop_back();
2348150850Sscottl        update = 1;
2349150850Sscottl        break;
2350150850Sscottl	}
2351150850Sscottl      case 'm': /* read and print MII regs */
2352150850Sscottl        {
2353150850Sscottl        printf("MII regs:\n");
2354150850Sscottl        printf("      0    1    2    3    4    5    6    7");
2355150850Sscottl        for (i=0; i<32; i++)
2356150850Sscottl          {
2357150850Sscottl          u_int16_t mii = read_mii(i);
2358150850Sscottl          if (i%8 == 0) printf("\n%02X: ", i);
2359150850Sscottl          printf("%04X ", mii);
2360150850Sscottl	  }
2361150850Sscottl        printf("\n\n");
2362150850Sscottl        break;
2363150850Sscottl        }
2364150850Sscottl      case 'M': /* write MII reg */
2365150850Sscottl        {
2366150850Sscottl        u_int32_t addr = strtoul(optarg, NULL, 0);
2367150850Sscottl        u_int32_t data = strtoul(argv[optind++], NULL, 0);
2368150850Sscottl        write_mii(addr, data);
2369150850Sscottl        if (verbose)
2370150850Sscottl          {
2371150850Sscottl          data = read_mii(addr);
2372150850Sscottl          printf("Write mii register: addr = 0x%02X data = 0x%04X\n", addr, data);
2373150850Sscottl	  }
2374150850Sscottl        break;
2375150850Sscottl        }
2376150850Sscottl      case 'p': /* read and print PCI config regs */
2377150850Sscottl        {
2378150850Sscottl        int i;
2379150850Sscottl        printf("21140A PCI Config regs:\n");
2380150850Sscottl        printf("       0        1        2        3");
2381150850Sscottl        for (i=0; i<16; i++)
2382150850Sscottl          {
2383150850Sscottl          if (i%4 == 0) printf("\n%X: ", i);
2384150850Sscottl          printf("%08X ", read_pci_config(i<<2));
2385150850Sscottl	  }
2386150850Sscottl        printf("\n\n");
2387150850Sscottl        break;
2388150850Sscottl	}
2389150850Sscottl      case 'P': /* write PCI config reg */
2390150850Sscottl        {
2391150850Sscottl        u_int32_t addr = strtoul(optarg, NULL, 0);
2392150850Sscottl        u_int32_t data = strtoul(argv[optind++], NULL, 0);
2393150850Sscottl        write_pci_config(addr, data);
2394150850Sscottl        if (verbose)
2395150850Sscottl          {
2396150850Sscottl          data = read_pci_config(addr);
2397150850Sscottl          printf("Write PCI config reg: addr = 0x%02X data = 0x%08X\n", addr, data);
2398150850Sscottl	  }
2399150850Sscottl        break;
2400150850Sscottl	}
2401150850Sscottl      case 's': /* read and print Tulip SROM */
2402150850Sscottl        {
2403150850Sscottl        int i;
2404150850Sscottl        printf("21140A SROM:\n");
2405150850Sscottl        printf("     0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F");
2406150850Sscottl        for (i=0; i<64; i++)
2407150850Sscottl          {
2408150850Sscottl          u_int16_t srom = read_srom(i);
2409150850Sscottl          if (i%8 == 0) printf("\n%02X: ", i<<1);
2410150850Sscottl          printf("%02X %02X ", srom & 0xFF, srom>>8);
2411150850Sscottl	  }
2412150850Sscottl        printf("\n\n");
2413150850Sscottl        break;
2414150850Sscottl	}
2415150850Sscottl      case 'S': /* write Tulip SROM loc */
2416150850Sscottl        {
2417150850Sscottl#if 0  /* write a single location -- not too useful */
2418150850Sscottl        u_int32_t addr = strtoul(optarg, NULL, 0);
2419150850Sscottl        u_int32_t data = strtoul(argv[optind++], NULL, 0);
2420150850Sscottl        write_mii(addr, data);
2421150850Sscottl        data = read_mii(addr);
2422150850Sscottl        printf("Write SROM: addr = 0x%02X data = 0x%04X\n", addr, data);
2423150850Sscottl#endif
2424150850Sscottl#if 0  /* write the whole SROM -- very dangerous */
2425150850Sscottl        init_srom(strtoul(optarg, NULL, 0));
2426150850Sscottl#endif
2427150850Sscottl        printf("Caution! Recompile %s to enable this.\n", progname);
2428150850Sscottl        break;
2429150850Sscottl	}
2430150850Sscottl      case 't': /* read and print Tulip CSRs */
2431150850Sscottl        {
2432150850Sscottl        int i;
2433150850Sscottl        printf("21140A CSRs:\n");
2434150850Sscottl        printf("       0        1        2        3");
2435150850Sscottl        for (i=0; i<16; i++)
2436150850Sscottl          {
2437150850Sscottl          if (i%4 == 0) printf("\n%X: ", i);
2438150850Sscottl          printf("%08X ", read_csr(i));
2439150850Sscottl	  }
2440150850Sscottl        printf("\n\n");
2441150850Sscottl        break;
2442150850Sscottl	}
2443150850Sscottl      case 'T': /* write Tulip CSR */
2444150850Sscottl        {
2445150850Sscottl        u_int32_t addr = strtoul(optarg, NULL, 0);
2446150850Sscottl        u_int32_t data = strtoul(argv[optind++], NULL, 0);
2447150850Sscottl        write_csr(addr, data);
2448150850Sscottl        if (verbose)
2449150850Sscottl          {
2450150850Sscottl          data = read_csr(addr);
2451150850Sscottl          printf("Write 21140A CSR: addr = 0x%02X data = 0x%08X\n", addr, data);
2452150850Sscottl	  }
2453150850Sscottl        break;
2454150850Sscottl	}
2455150850Sscottl      case 'u': /* reset event counters */
2456150850Sscottl        {
2457150850Sscottl        ioctl_reset_cntrs();
2458150850Sscottl        if (verbose) printf("Event counters reset\n");
2459150850Sscottl        break;
2460150850Sscottl	}
2461150850Sscottl      case 'U': /* reset gate array */
2462150850Sscottl        {
2463150850Sscottl        reset_xilinx();
2464150850Sscottl        if (verbose) printf("gate array reset\n");
2465150850Sscottl        break;
2466150850Sscottl        }
2467150850Sscottl      case 'v': /* set verbose mode */
2468150850Sscottl        {
2469150850Sscottl        verbose = 1;
2470150850Sscottl        break;
2471150850Sscottl        }
2472150850Sscottl      case 'V': /* print card configuration */
2473150850Sscottl        {
2474150850Sscottl        summary = 1;
2475150850Sscottl        break;
2476150850Sscottl	}
2477150850Sscottl      case 'w': /* load gate array microcode from ROM */
2478150850Sscottl        {
2479150850Sscottl        load_xilinx_from_rom();
2480150850Sscottl        if (verbose) printf("gate array configured from on-board ROM\n");
2481150850Sscottl        break;
2482150850Sscottl        }
2483150850Sscottl      case 'W': /* load gate array microcode from file */
2484150850Sscottl        {
2485150850Sscottl        load_xilinx(optarg);
2486150850Sscottl        if (verbose) printf("gate array configured from file %s\n", optarg);
2487150850Sscottl        break;
2488150850Sscottl        }
2489150850Sscottl      case 'x': /* select RAWIP protocol */
2490150850Sscottl        {
2491150850Sscottl        config.line_pkg = PKG_RAWIP;
2492150850Sscottl        if (verbose) printf("RAWIP mode selected\n");
2493150850Sscottl        update = 1;
2494150850Sscottl        break;
2495150850Sscottl	}
2496150850Sscottl      case 'X': /* Select in-kernel line protocol packages */
2497150850Sscottl        {
2498150850Sscottl        config.line_pkg = 0;
2499150850Sscottl        if (verbose) printf("line protocol mode selected\n");
2500150850Sscottl        update = 1;
2501150850Sscottl        break;
2502150850Sscottl	}
2503150850Sscottl      case 'y': /* disable SPPP keep-alive packets */
2504150850Sscottl        {
2505150850Sscottl        if ((config.line_pkg  == PKG_SPPP) &&
2506150850Sscottl            (config.line_prot == PROT_FRM_RLY))
2507150850Sscottl          printf("keep-alives must be ON for Frame-Relay/SPPP\n");
2508150850Sscottl        else
2509150850Sscottl          {
2510150850Sscottl          config.keep_alive = 0;
2511150850Sscottl          if (verbose) printf("SPPP keep-alive packets disabled\n");
2512150850Sscottl          update = 1;
2513150850Sscottl	  }
2514150850Sscottl        break;
2515150850Sscottl	}
2516150850Sscottl      case 'Y': /* enable SPPP keep-alive packets */
2517150850Sscottl        {
2518150850Sscottl        config.keep_alive = 1;
2519150850Sscottl        if (verbose) printf("SPPP keep-alive packets enabled\n");
2520150850Sscottl        update = 1;
2521150850Sscottl        break;
2522150850Sscottl	}
2523150850Sscottl      case 'z': /* set SPPP line protocol to Cisco HDLC */
2524150850Sscottl        {
2525150850Sscottl        config.line_prot = PROT_C_HDLC;
2526150850Sscottl        config.keep_alive = 1;
2527150850Sscottl        if (verbose) printf("SPPP line protocol set to Cisco-HDLC\n");
2528150850Sscottl        update = 1;
2529150850Sscottl        break;
2530150850Sscottl	}
2531150850Sscottl      case 'Z': /* set SPPP line protocol to PPP */
2532150850Sscottl        {
2533150850Sscottl        config.line_prot = PROT_PPP;
2534150850Sscottl        config.keep_alive = 0;
2535150850Sscottl        if (verbose) printf("SPPP line protocol set to PPP\n");
2536150850Sscottl        update = 1;
2537150850Sscottl        break;
2538150850Sscottl	}
2539150850Sscottl      default:
2540150850Sscottl        {
2541150850Sscottl        printf("Unknown command char: %c\n", ch);
2542150850Sscottl        exit(1);
2543150850Sscottl	}
2544150850Sscottl      } /* switch */
2545150850Sscottl    } /* while */
2546150850Sscottl
2547150850Sscottl  if (summary) print_summary();
2548150850Sscottl
2549150850Sscottl  /*  5) Write the modified interface configuration to the driver. */
2550150850Sscottl  if (update) ioctl_write_config();
2551150850Sscottl
2552150850Sscottl  exit(0);
2553216600Suqs}
2554