/* at1500.c: Diagnostic program for AT1500 ethercards.

   Written 1993 by Donald Becker.

   The Author may be reached as becker@super.org or
   C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
*/

static char *version =
    "at1500.c:v0.02 10/8/93 Donald Becker (becker@super.org)\n";

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <asm/io.h>
#include "/usr/src/linux/net/inet/iow.h"

#define PORTBASE 0x300

/* Offsets from base I/O address. */
#define LANCE_DATA 0x10
#define LANCE_ADDR 0x12
#define LANCE_RESET 0x14
#define LANCE_BUS_IF 0x16

struct option longopts[] = {
 /* { name  has_arg  *flag  val } */
    {"base-address", 1, 0, 'p'},
    {"all",	   0, 0, 'a'},	/* Print all regsiters. */
    {"help",       0, 0, 'h'},	/* Give help */
    {"interface",  0, 0, 'f'},	/* Interface number (built-in, AUI) */
    {"irq",	   1, 0, 'i'},	/* Interrupt number */
    {"dma",	   1, 0, 'd'},	/* DMA channel. */
    {"verbose",    0, 0, 'v'},	/* Verbose mode */
    {"version",    0, 0, 'V'},	/* Display version number */
    {"write-EEPROM", 1, 0, 'w'},/* Write th EEPROMS with the specified vals */
    { 0, 0, 0, 0 }
};

int
main(int argc, char **argv)
{
    int port_base = 0x300, irq = -1, dma = -1;
    int errflag = 0, verbose = 0, shared_mode = 0;
    int write_eeprom = 0, interface = -1, all_regs = 0;
    int c, longind;
    int i;
    int reg0;
    extern char *optarg;

    while ((c = getopt_long(argc, argv, "af:i:p:svw", longopts, &longind))
	   != -1)
	switch (c) {
	case 'f':
	    interface = atoi(optarg);
	    break;
	case 'i':
	    irq = atoi(optarg);
	    break;
	case 'd':
	    dma = atoi(optarg);
	    break;
	case 'p':
	    port_base = strtol(optarg, NULL, 16);
	    break;
	case 's': shared_mode++; break;
	case 'v': verbose++;		 break;
	case 'w': write_eeprom++;	 break;
	case 'a': all_regs++;		 break;
	case '?':
	    errflag++;
	}
    if (errflag) {
	fprintf(stderr, "usage:");
	return 2;
    }

    if (verbose)
	printf(version);

    if (ioperm(port_base, 26, 1) < 0) {
	perror("at1500:io-perm()");
	return 1;
    }

    printf("I/O base is %#6.3x, station address PROM:\n", port_base);
    for (i = 0; i < 16; i++)
	printf(" %2.2x", inb(port_base + i));

    printf("\n");

    if ( ! all_regs)
	return 0;

    if (verbose > 1) {
	/* Shut down the LANCE so that we can see all the values. */
	outw(0x0000, port_base+LANCE_ADDR);
	reg0 = inw(port_base+LANCE_DATA);
	outw(0x0004, port_base+LANCE_DATA);
    }
    inw(port_base+LANCE_DATA);

    for (i = 0; i < 96; i++) {
	int addr;
	if ((i & 0x07) == 0)
	    printf("\n%3d:", i);
	outw(i, port_base+LANCE_ADDR);
	addr = inw(port_base+LANCE_ADDR);
	printf("%c%4.4x", i == addr ? ' ' : '=', inw(port_base+LANCE_DATA));
    }

    printf("\nBus control:");
    for (i = 0; i < 8; i++) {
	int addr;
	if ((i & 0x07) == 0)
	    printf("\n%3d:", i);
	outw(i, port_base+LANCE_ADDR);
	addr = inw(port_base+LANCE_ADDR);
	printf("%c%4.4x", i == addr ? ' ' : '=', inw(port_base+LANCE_BUS_IF));
    }

    if (verbose > 1) {
	/* Start the LANCE back up. */
	outw(0x0000, port_base+LANCE_ADDR);
	outw(reg0 & ~0x01, port_base+LANCE_DATA);
    }
    printf("\n");

    return 0;

}

/*
 * Local variables:
 *  compile-command: "cc -N -Wall -O -o at1500 at1500.c"
 * End:
 */
