Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / usr.sbin / eshconfig / eshconfig.c
bloba4418400225d8e0239d6560450027c795ab90529
1 /* $NetBSD: eshconfig.c,v 1.8 2008/05/02 19:59:19 xtraeme Exp $ */
3 /*
4 * Copyright (c) 1998 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code contributed to The NetBSD Foundation by Kevin M. Lahey
8 * of the Numerical Aerospace Simulation Facility, NASA Ames Research
9 * Center.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
33 #include <sys/cdefs.h>
34 #ifndef lint
35 __RCSID("$NetBSD: eshconfig.c,v 1.8 2008/05/02 19:59:19 xtraeme Exp $");
36 #endif /* not lint */
38 #include <sys/param.h>
39 #include <sys/socket.h>
40 #include <sys/ioctl.h>
41 #include <sys/sockio.h>
42 #include <fcntl.h>
44 #include <net/if.h>
45 #include <net/if_dl.h>
46 #include <net/if_media.h>
47 #include <netinet/in.h>
48 #include <arpa/inet.h>
50 #include <ctype.h>
51 #include <err.h>
52 #include <errno.h>
53 #include <stdio.h>
54 #include <stdlib.h>
55 #include <string.h>
56 #include <unistd.h>
58 #include <dev/ic/rrunnerreg.h>
59 #include <dev/ic/rrunnervar.h>
62 * Create a simple pair of tables to map possible burst DMA values
63 * to the values required by the RoadRunner.
66 struct map_dma {
67 int value;
68 u_int32_t rr_value;
71 struct map_dma read_dma_map[] = {{0, RR_PS_READ_DISABLE},
72 {4, RR_PS_READ_4},
73 {16, RR_PS_READ_16},
74 {32, RR_PS_READ_32},
75 {64, RR_PS_READ_64},
76 {128, RR_PS_READ_128},
77 {256, RR_PS_READ_256},
78 {1024, RR_PS_READ_1024},
79 {-1, 0}};
81 struct map_dma write_dma_map[] = {{0, RR_PS_WRITE_DISABLE},
82 {4, RR_PS_WRITE_4},
83 {16, RR_PS_WRITE_16},
84 {32, RR_PS_WRITE_32},
85 {64, RR_PS_WRITE_64},
86 {128, RR_PS_WRITE_128},
87 {256, RR_PS_WRITE_256},
88 {1024, RR_PS_WRITE_1024},
89 {-1, 0}};
92 * The RunCode is composed of separate segments, each of which has a
93 * starting address in SRAM memory (for running) and in EEPROM
94 * (for storage).
98 struct rr_seg_descr {
99 u_int32_t start_addr;
100 u_int32_t length;
101 u_int32_t ee_addr;
104 static u_int32_t do_map __P((int, struct map_dma *));
105 static void eeprom_upload __P((const char *));
106 static void eeprom_download __P((const char *));
107 static u_int32_t rr_checksum __P((const u_int32_t *, int));
108 static void esh_tune __P((void));
109 static void esh_tune_eeprom __P((void));
110 static void esh_tuning_stats __P((void));
111 static void esh_stats __P((int));
112 static void esh_reset __P((void));
113 static int drvspec_ioctl __P((char *, int, int, int, caddr_t));
114 static void usage __P((void));
115 int main __P((int, char *[]));
118 struct ifreq ifr;
119 char name[30] = "esh0";
120 int s;
122 #define RR_EE_SIZE 8192
123 u_int32_t eeprom[RR_EE_SIZE];
124 u_int32_t runcode[RR_EE_SIZE];
126 struct ifdrv ifd;
128 /* drvspec_ioctl
130 * We defined a driver-specific socket ioctl to allow us to tweak
131 * the characteristics of network devices. This routine will
132 * provide a shortcut to calling this routine, which would otherwise
133 * require lots of costly and annoying setup.
136 static int
137 drvspec_ioctl(char *lname, int fd, int cmd, int len, caddr_t data)
139 strcpy(ifd.ifd_name, lname);
140 ifd.ifd_cmd = cmd;
141 ifd.ifd_len = len;
142 ifd.ifd_data = data;
144 return ioctl(fd, SIOCSDRVSPEC, (caddr_t) &ifd);
147 static void
148 usage()
150 fprintf(stderr, "eshconfig -- configure Essential Communications "
151 "HIPPI driver\n");
152 fprintf(stderr, "-b burst size for read\n");
153 fprintf(stderr, "-c burst size for write:\n");
154 fprintf(stderr, "\t0 (no limit), 5, 16, 32, 64, 128, 256, 1024\n");
155 fprintf(stderr, "-d download filename\n");
156 fprintf(stderr, "-e write data to EEPROM\n");
157 fprintf(stderr, "-m minimum bytes DMA per direction\n");
158 fprintf(stderr, "-r bytes before DMA starts for read\n");
159 fprintf(stderr, "-s show statistics (-ss to display only non-zero)\n");
160 fprintf(stderr, "-t show tuning parameters\n");
161 fprintf(stderr, "-u upload filename [not working]\n");
162 fprintf(stderr, "-w bytes before DMA starts for write\n");
163 fprintf(stderr, "-i interrupt delay in usecs\n");
164 fprintf(stderr, "-x reset interface\n");
165 exit(1);
168 /* do_map
170 * Map between values for burst DMA sizes and the values expected by
171 * the RoadRunner chip.
174 static u_int32_t
175 do_map(int value, struct map_dma *map)
177 int i;
179 for (i = 0; map[i].value != -1; i++)
180 if (value == map[i].value)
181 return map[i].rr_value;
183 return -1;
186 /* do_map_dma
188 * Reverse the mapping.
191 static int
192 do_map_dma(uint32_t value, struct map_dma *map)
194 int i;
196 for (i = 0; map[i].value != -1; i++)
197 if (value == map[i].rr_value)
198 return map[i].value;
200 return 0;
204 int dma_thresh_read = -1;
205 int dma_thresh_write = -1;
206 int dma_min_grab = -1;
207 int dma_max_read = -1;
208 int dma_max_write = -1;
210 int interrupt_delay = -1;
212 int get_stats = 0;
213 int get_tuning_stats = 0;
214 int eeprom_write = 0;
215 char *eeprom_download_filename = NULL;
216 char *eeprom_upload_filename = NULL;
217 int reset = 0;
219 struct rr_tuning rr_tune;
220 struct rr_eeprom rr_eeprom;
221 struct rr_stats rr_stats;
224 main(argc, argv)
225 int argc;
226 char *argv[];
228 int ch;
230 /* Parse command-line options */
232 while ((ch = getopt(argc, argv, "b:c:d:ei:m:r:stu:w:x")) != -1) {
233 switch (ch) {
234 case 'b':
235 dma_max_read = atoi(optarg);
236 break;
237 case 'c':
238 dma_max_write = atoi(optarg);
239 break;
240 case 'd':
241 eeprom_download_filename = optarg;
242 break;
243 case 'e':
244 eeprom_write++;
245 break;
246 case 'i':
247 interrupt_delay = atoi(optarg);
248 break;
249 case 'm':
250 dma_min_grab = atoi(optarg);
251 break;
252 case 'r':
253 dma_thresh_read = atoi(optarg);
254 break;
255 case 's':
256 get_stats++;
257 break;
258 case 't':
259 get_tuning_stats++;
260 break;
261 case 'u':
262 eeprom_upload_filename = optarg;
263 break;
264 case 'w':
265 dma_thresh_write = atoi(optarg);
266 break;
267 case 'x':
268 reset = 1;
269 break;
270 default:
271 usage();
272 /* NOTREACHED */
275 argc -= optind;
276 argv += optind;
278 if (argc > 1)
279 usage();
280 if (argc == 1) {
281 (void) strncpy(name, argv[0], sizeof(name));
282 argc--; argv++;
285 s = socket(AF_INET, SOCK_DGRAM, 0);
286 if (s < 0)
287 err(1, "socket");
289 if (eeprom_upload_filename)
290 eeprom_upload(eeprom_upload_filename);
292 if (eeprom_download_filename)
293 eeprom_download(eeprom_download_filename);
295 if (get_stats) {
296 esh_stats(get_stats);
299 if (drvspec_ioctl(name, s, EIOCGTUNE, sizeof(struct rr_tuning),
300 (caddr_t) &rr_tune) < 0) {
301 err(1, "ioctl(EIOCGTUNE)");
304 if (get_tuning_stats) {
305 if (get_stats)
306 printf("\n");
307 esh_tuning_stats();
310 if (eeprom_write || dma_thresh_read != -1 ||
311 dma_thresh_write != -1 ||
312 dma_min_grab != -1 ||
313 dma_max_read != -1 ||
314 dma_max_write != -1 ||
315 interrupt_delay != -1) {
316 esh_tune();
319 if (eeprom_write)
320 esh_tune_eeprom();
322 if (reset)
323 esh_reset();
325 exit(0);
328 static void
329 esh_tune()
331 dma_max_read = do_map(dma_max_read, read_dma_map);
332 if (dma_max_read != -1) {
333 rr_tune.rt_pci_state &= ~RR_PS_READ_MASK;
334 rr_tune.rt_pci_state |= dma_max_read;
337 dma_max_write = do_map(dma_max_write, write_dma_map);
338 if (dma_max_write != -1) {
339 rr_tune.rt_pci_state &= ~RR_PS_WRITE_MASK;
340 rr_tune.rt_pci_state |= dma_max_write;
343 if (dma_min_grab != -1) {
344 if ((dma_min_grab & (RR_PS_MIN_DMA_MASK >> RR_PS_MIN_DMA_SHIFT))
345 != dma_min_grab)
346 usage();
347 rr_tune.rt_pci_state &= ~RR_PS_MIN_DMA_MASK;
348 rr_tune.rt_pci_state |=
349 (dma_min_grab << RR_PS_MIN_DMA_SHIFT);
352 if (dma_thresh_write != -1) {
353 if (dma_thresh_write < 1 || dma_thresh_write > RR_DW_THRESHOLD_MAX)
354 usage();
355 rr_tune.rt_dma_write_state &= ~RR_DW_THRESHOLD_MASK;
356 rr_tune.rt_dma_write_state |=
357 dma_thresh_write << RR_DW_THRESHOLD_SHIFT;
360 if (dma_thresh_read != -1) {
361 if (dma_thresh_read < 1 || dma_thresh_read > RR_DR_THRESHOLD_MAX)
362 usage();
363 rr_tune.rt_dma_read_state &= ~RR_DR_THRESHOLD_MASK;
364 rr_tune.rt_dma_read_state |=
365 dma_thresh_read << RR_DR_THRESHOLD_SHIFT;
368 rr_tune.rt_stats_timer = ESH_STATS_TIMER_DEFAULT;
370 if (interrupt_delay != -1)
371 rr_tune.rt_interrupt_timer = interrupt_delay;
373 if (drvspec_ioctl(name, s, EIOCSTUNE, sizeof(struct rr_tuning),
374 (caddr_t) &rr_tune) < 0)
375 err(1, "EIOCSTUNE");
378 /* esh_tune_eeprom
380 * Store the current tuning data into the eeprom.
383 static void
384 esh_tune_eeprom()
386 #define LAST (RR_EE_HEADER_CHECKSUM / RR_EE_WORD_LEN)
387 #define FIRST (RR_EE_HEADER_CHECKSUM / RR_EE_WORD_LEN)
389 u_int32_t tuning_data[LAST + 1];
391 rr_eeprom.ifr_buffer = tuning_data;
392 rr_eeprom.ifr_length = sizeof(tuning_data);
393 rr_eeprom.ifr_offset = 0;
395 if (drvspec_ioctl(name, s, EIOCGEEPROM, sizeof(struct rr_eeprom),
396 (caddr_t) &rr_eeprom) == -1)
397 err(6, "ioctl to retrieve tuning information from EEPROM");
399 tuning_data[RR_EE_PCI_STATE / RR_EE_WORD_LEN] =
400 rr_tune.rt_pci_state;
401 tuning_data[RR_EE_DMA_WRITE_STATE / RR_EE_WORD_LEN] =
402 rr_tune.rt_dma_write_state;
403 tuning_data[RR_EE_DMA_READ_STATE / RR_EE_WORD_LEN] =
404 rr_tune.rt_dma_read_state;
405 tuning_data[RR_EE_INTERRUPT_TIMER / RR_EE_WORD_LEN] = rr_tune.rt_interrupt_timer;
406 tuning_data[RR_EE_STATS_TIMER / RR_EE_WORD_LEN] =
407 ESH_STATS_TIMER_DEFAULT;
409 tuning_data[RR_EE_HEADER_CHECKSUM / RR_EE_WORD_LEN] =
410 rr_checksum(&tuning_data[FIRST], LAST - FIRST);
412 rr_eeprom.ifr_buffer = tuning_data;
413 rr_eeprom.ifr_length = sizeof(tuning_data);
414 rr_eeprom.ifr_offset = 0;
416 if (drvspec_ioctl(name, s, EIOCSEEPROM, sizeof(struct rr_eeprom),
417 (caddr_t) &rr_eeprom) == -1)
418 err(7, "ioctl to set tuning information from EEPROM");
421 /* eeprom_upload
423 * Upload the EEPROM from the card and store in the data file.
426 static void
427 eeprom_upload(const char *filename)
429 int fd;
431 bzero(eeprom, sizeof(eeprom));
432 if ((fd = open(filename, O_WRONLY | O_CREAT, 0644)) < 0)
433 err(4, "Couldn't open %s for output", filename);
435 rr_eeprom.ifr_buffer = eeprom;
436 rr_eeprom.ifr_length = sizeof(eeprom);
437 rr_eeprom.ifr_offset = 0;
439 if (drvspec_ioctl(name, s, EIOCGEEPROM, sizeof(struct rr_eeprom),
440 (caddr_t) &rr_eeprom) == -1)
441 err(5, "ioctl to retrieve all of EEPROM");
443 write(fd, eeprom, sizeof(eeprom));
444 close(fd);
447 /* eeprom_download
449 * Download into eeprom the contents of a file. The file is made up
450 * of ASCII text; the first three characters can be ignored, the next
451 * four hex characters define an address, the next two characters can
452 * be ignored, and the final eight hex characters are the data.
455 static void
456 eeprom_download(const char *filename)
458 FILE *fp;
459 struct rr_seg_descr *segd = NULL, *nsegd;
460 char id[BUFSIZ];
461 char pad[BUFSIZ];
462 char buffer[BUFSIZ];
463 u_int32_t address = 0;
464 u_int32_t last_address = 0;
465 u_int32_t value;
466 u_int32_t length = 0;
467 int segment_start = 0;
468 int seg_table_start;
469 int seg_count_offset;
470 int phase2_start;
471 int phase2_checksum;
472 int in_segment = 0;
473 int segment = 0;
474 int eof = 0;
475 int line = 0;
476 int zero_count = 0;
477 int i;
479 /* Clear out eeprom storage space, then read in the value on the card */
481 bzero(eeprom, sizeof(eeprom));
482 bzero(runcode, sizeof(runcode));
484 rr_eeprom.ifr_buffer = eeprom;
485 rr_eeprom.ifr_length = sizeof(eeprom);
486 rr_eeprom.ifr_offset = 0;
487 if (drvspec_ioctl(name, s, EIOCGEEPROM, sizeof(struct rr_eeprom),
488 (caddr_t) &rr_eeprom) == -1)
489 err(5, "ioctl to retrieve EEPROM");
492 * Open the input file and proceed to read the data file, storing
493 * the data and counting the number of segments.
496 if ((fp = fopen(filename, "r")) == NULL)
497 err(2, "fopen");
499 do {
500 if (fgets(buffer, sizeof(buffer), fp) == NULL)
501 errx(3, "premature, unmarked end of file, line %d", line);
502 line++;
504 if (!strncmp(buffer + 7, "01", 2)) { /* check for EOF marker... */
505 eof = 1;
506 } else {
507 sscanf(buffer, "%3s%4x%2s%8x%2s",
508 id, &address, pad, &value, pad);
509 if (strcmp(id, ":04") != 0)
510 errx(3, "bad initial id on line %d", line);
514 * Check to see if we terminated a segment; this happens
515 * when we are at end of file, or we hit a non-sequential
516 * address value, or we see three or more zeroes in a row.
519 if ((length == RR_EE_SEG_SIZE || eof || zero_count >= 3 ||
520 (last_address && last_address != address - 1)) && in_segment) {
522 length -= zero_count;
523 segment_start += length;
524 segd[segment].length = length;
526 printf("segment %d, %d words\n", segment, length);
527 last_address = in_segment = zero_count = length = 0;
528 segment++;
531 if (eof)
532 break;
534 /* Skip zero values starting a segment */
536 if (!in_segment && value == 0)
537 continue;
538 last_address = address;
541 * If we haven't started a segment yet, do so now.
542 * Store away the address at which this code should be placed
543 * in memory and the address of the code in the EEPROM.
546 if (!in_segment) {
547 in_segment = 1;
549 nsegd = realloc(segd, sizeof(struct rr_seg_descr) * (segment + 1));
550 if (nsegd == NULL)
551 err(6, "couldn't realloc segment descriptor space");
552 segd = nsegd;
554 segd[segment].start_addr = address * sizeof(u_int32_t);
555 segd[segment].ee_addr = segment_start;
558 /* Keep track of consecutive zeroes */
560 if (in_segment && value == 0)
561 zero_count++;
562 else
563 zero_count = 0;
565 /* Store away the actual data */
567 runcode[segment_start + length++] = value;
568 } while (!eof);
569 fclose(fp);
571 /* Now that we have a segment count, fill in the EEPROM image. */
573 seg_count_offset = eeprom[RR_EE_RUNCODE_SEGMENTS / RR_EE_WORD_LEN];
574 seg_count_offset = (seg_count_offset - RR_EE_OFFSET) / RR_EE_WORD_LEN;
575 seg_table_start = seg_count_offset + 1;
576 phase2_checksum = seg_table_start + 3 * segment;
577 phase2_start = eeprom[RR_EE_PHASE2_EE_START / RR_EE_WORD_LEN];
578 phase2_start = (phase2_start - RR_EE_OFFSET) / RR_EE_WORD_LEN;
580 printf("segment table start = %x, segments = %d\n",
581 seg_table_start, eeprom[seg_count_offset]);
583 /* We'll fill in anything after the segment count, so clear it */
585 bzero(eeprom + seg_count_offset,
586 sizeof(eeprom) - seg_count_offset * sizeof(eeprom[0]));
588 eeprom[seg_count_offset] = segment;
590 for (i = 0; i < segment; i++)
591 segd[i].ee_addr = RR_EE_OFFSET +
592 (segd[i].ee_addr + phase2_checksum + 1) * RR_EE_WORD_LEN;
594 bcopy(segd, &eeprom[seg_table_start],
595 sizeof(struct rr_seg_descr) * segment);
597 bcopy(runcode, &eeprom[phase2_checksum + 1],
598 segment_start * sizeof(u_int32_t));
600 eeprom[phase2_checksum] = rr_checksum(&eeprom[phase2_start],
601 phase2_checksum - phase2_start);
603 eeprom[segment_start + phase2_checksum + 1] =
604 rr_checksum(&eeprom[phase2_checksum + 1], segment_start);
606 printf("phase2 checksum %x, runcode checksum %x\n",
607 eeprom[phase2_checksum],
608 eeprom[segment_start + phase2_checksum + 1]);
610 rr_eeprom.ifr_buffer = eeprom;
611 rr_eeprom.ifr_length = sizeof(eeprom);
612 rr_eeprom.ifr_offset = 0;
613 if (drvspec_ioctl(name, s, EIOCSEEPROM, sizeof(struct rr_eeprom),
614 (caddr_t) &rr_eeprom) == -1)
615 err(5, "ioctl to retrieve EEPROM");
618 /* rr_checksum
620 * Perform checksum on RunCode. Length is in words. Ugh.
623 static u_int32_t
624 rr_checksum(const u_int32_t *data, int length)
626 u_int32_t checksum = 0;
628 while (length--)
629 checksum += *data++;
631 checksum = 0 - checksum;
632 return checksum;
635 struct stats_values {
636 int offset;
637 const char *name;
640 struct stats_values stats_values[] = {
641 {0x04, "receive rings created"},
642 {0x08, "receive rings deleted"},
643 {0x0c, "interrupts"},
644 {0x10, "event overflows"},
645 {0x14, "invalid commands"},
646 {0x18, "DMA read errors"},
647 {0x1c, "DMA write errors"},
648 {0x20, "stats updates per timer"},
649 {0x24, "stats updates per host"},
650 {0x28, "watchdog"},
651 {0x2c, "trace"},
652 {0x30, "link ready sync established"},
653 {0x34, "GLink errors"},
654 {0x38, "alternating flag errors"},
655 {0x3c, "overhead bit 8 synchronized"},
656 {0x40, "remote serial parity errors"},
657 {0x44, "remote parallel parity errors"},
658 {0x48, "remote loopback requested"},
659 {0x50, "transmit connections established"},
660 {0x54, "transmit connections rejected"},
661 {0x58, "transmit connections retried"},
662 {0x5c, "transmit connections timed out"},
663 {0x60, "transmit connections disconnected"},
664 {0x64, "transmit parity errors"},
665 {0x68, "packets sent"},
666 {0x74, "short first burst sent"},
667 {0x80, "transmit data not moving"},
668 {0x90, "receive connections accepted"},
669 {0x94, "receive connections rejected -- bad parity"},
670 {0x98, "receive connections rejected -- 64-bit width"},
671 {0x9c, "receive connections rejected -- buffers low"},
672 {0xa0, "receive connections disconnected"},
673 {0xa4, "receive connections with no data"},
674 {0xa8, "packets received"},
675 {0xb4, "short first burst received"},
676 {0xc0, "receive parity error"},
677 {0xc4, "receive LLRC error"},
678 {0xc8, "receive burst size error"},
679 {0xcc, "receive state error"},
680 {0xd0, "receive ready ULP"},
681 {0xd4, "receive invalid ULP"},
682 {0xd8, "receive packets flow control due to buffer space"},
683 {0xdc, "receive packets flow control due to descriptors"},
684 {0xe0, "receive ring fulls"},
685 {0xe4, "packet length errors"},
686 {0xe8, "packets with checksum error"},
687 {0xec, "packets dropped"},
688 {0xf0, "ring low on space"},
689 {0xf4, "data in ring at close"},
690 {0xf8, "receives to ring not moving data"},
691 {0xfc, "receiver idles"},
692 {0, 0},
695 static void
696 esh_reset()
698 if (drvspec_ioctl(name, s, EIOCRESET, 0, 0) < 0)
699 err(1, "ioctl(EIOCRESET)");
702 static void
703 esh_stats(int lget_stats)
705 u_int32_t *stats;
706 long long value;
707 int offset;
709 if (drvspec_ioctl(name, s, EIOCGSTATS, sizeof(struct rr_stats),
710 (caddr_t) &rr_stats) < 0)
711 err(1, "ioctl(EIOCGTUNE)");
713 stats = rr_stats.rs_stats;
715 value = (((long long) stats[0x78 / 4]) << 32) | stats[0x7c / 4];
716 if (lget_stats == 1 || value > 0)
717 printf("%12lld bytes sent\n", value);
718 value = ((long long) stats[0xb8 / 4] << 32) | stats[0xbc / 4];
719 if (lget_stats == 1 || value > 0)
720 printf("%12lld bytes received\n", value);
722 for (offset = 0; stats_values[offset].offset != 0; offset++) {
723 if (lget_stats == 1 || stats[stats_values[offset].offset / 4] > 0)
724 printf("%12d %s\n", stats[stats_values[offset].offset / 4],
725 stats_values[offset].name);
730 static void
731 esh_tuning_stats()
733 printf("rt_mode_and_status = %x\n",
734 rr_tune.rt_mode_and_status);
735 printf("rt_conn_retry_count = %x\n",
736 rr_tune.rt_conn_retry_count);
737 printf("rt_conn_retry_timer = %x\n",
738 rr_tune.rt_conn_retry_timer);
739 printf("rt_conn_timeout = %x\n", rr_tune.rt_conn_timeout);
740 printf("rt_stats_timer = %x\n", rr_tune.rt_stats_timer);
741 printf("rt_interrupt_timer = %x\n",
742 rr_tune.rt_interrupt_timer);
743 printf("rt_tx_timeout = %x\n", rr_tune.rt_tx_timeout);
744 printf("rt_rx_timeout = %x\n", rr_tune.rt_rx_timeout);
745 printf("rt_pci_state = %x"
746 " min DMA %x read max %x write max %x\n",
747 rr_tune.rt_pci_state,
748 (rr_tune.rt_pci_state & RR_PS_MIN_DMA_MASK)
749 >> RR_PS_MIN_DMA_SHIFT,
750 do_map_dma(rr_tune.rt_pci_state & RR_PS_READ_MASK,
751 read_dma_map),
752 do_map_dma(rr_tune.rt_pci_state & RR_PS_WRITE_MASK,
753 write_dma_map));
754 printf("rt_dma_write_state = %x\n",
755 rr_tune.rt_dma_write_state);
756 printf("rt_dma_read_state = %x\n", rr_tune.rt_dma_read_state);
757 printf("rt_driver_param = %x\n", rr_tune.rt_driver_param);