NetBSD/sys/arch/i386/stand/lib/netif/3c590.c

145 lines
3.6 KiB
C

/* $NetBSD: 3c590.c,v 1.5 1997/07/15 11:23:07 drochner Exp $ */
/* stripped down from freebsd:sys/i386/netboot/3c509.c */
/**************************************************************************
NETBOOT - BOOTP/TFTP Bootstrap Program
Author: Martin Renters.
Date: Mar 22 1995
This code is based heavily on David Greenman's if_ed.c driver and
Andres Vega Garcia's if_ep.c driver.
Copyright (C) 1993-1994, David Greenman, Martin Renters.
Copyright (C) 1993-1995, Andres Vega Garcia.
Copyright (C) 1995, Serge Babkin.
This software may be used, modified, copied, distributed, and sold, in
both source and binary form provided that the above copyright and these
terms are retained. Under no circumstances are the authors responsible for
the proper functioning of this software, nor do the authors assume any
responsibility for damages incurred with its use.
3c509 support added by Serge Babkin (babkin@hq.icb.chel.su)
3c509.c,v 1.2 1995/05/30 07:58:52 rgrimes Exp
***************************************************************************/
#include <sys/types.h>
#include <machine/pio.h>
#include <lib/libsa/stand.h>
#include <libi386.h>
#include <pcivar.h>
#include "etherdrv.h"
#include "3c509.h"
#define EP_W3_INTERNAL_CONFIG 0x00 /* 32 bits */
#define EP_W3_RESET_OPTIONS 0x08 /* 16 bits */
char etherdev[20];
int ether_medium;
unsigned short eth_base;
extern void epreset __P((void));
extern int ep_get_e __P((int));
u_char eth_myaddr[6];
static struct mtabentry {
int address_cfg; /* configured connector */
int config_bit; /* connector present */
char *name;
} mediatab[] = { /* indexed by media type - etherdrv.h */
{3, 0x10, "BNC"},
{0, 0x08, "UTP"},
{1, 0x20, "AUI"},
{6, 0x40, "MII"},
};
/**************************************************************************
ETH_PROBE - Look for an adapter
***************************************************************************/
int EtherInit(myadr)
char *myadr;
{
/* common variables */
int i, j;
/* variables for 3C509 */
short *p;
struct mtabentry *m;
/*********************************************************
Search for 3Com 590 card
***********************************************************/
pcihdl_t hdl;
int iobase;
if(pcicheck() == -1) {
printf("cannot access PCI\n");
return(0);
}
if(pcifinddev(0x10b7, 0x5900, &hdl) &&
pcifinddev(0x10b7, 0x9001, &hdl) &&
pcifinddev(0x10b7, 0x9050, &hdl)) {
printf("cannot find 3c590 / 3c900\n");
return(0);
}
if(pcicfgread(&hdl, 0x10, &iobase) || !(iobase & 1)) {
printf("cannot map IO space\n");
return(0);
}
eth_base = iobase & 0xfffffffc;
ether_medium = ETHERMEDIUM_BNC; /* XXX */
/* test for presence of connectors */
GO_WINDOW(3);
i = inb(IS_BASE + EP_W3_RESET_OPTIONS);
j = (inw(IS_BASE + EP_W3_INTERNAL_CONFIG + 2) >> 4) & 7;
GO_WINDOW(0);
for(ether_medium = 0, m = mediatab;
ether_medium < sizeof(mediatab) / sizeof(mediatab[0]);
ether_medium++, m++) {
if(j == m->address_cfg) {
if(!(i & m->config_bit)) {
printf("%s not present\n", m->name);
return(0);
}
printf("using %s\n", m->name);
goto ok;
}
}
printf("unknown connector\n");
return(0);
ok:
/*
* Read the station address from the eeprom
*/
p = (u_short *) eth_myaddr;
for (i = 0; i < 3; i++) {
u_short help;
GO_WINDOW(0);
help = ep_get_e(i);
p[i] = ((help & 0xff) << 8) | ((help & 0xff00) >> 8);
GO_WINDOW(2);
outw(BASE + EP_W2_ADDR_0 + (i * 2), help);
}
for(i = 0; i < 6; i++) myadr[i] = eth_myaddr[i];
epreset();
sprintf(etherdev, "ep@pci,0x%x", eth_base);
return(1);
}