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

161 lines
3.8 KiB
C

/* $NetBSD: 3c590.c,v 1.8 1998/02/25 12:15:49 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>
#ifdef _STANDALONE
#include <lib/libkern/libkern.h>
#include <bootinfo.h>
#endif
#include "etherdrv.h"
#include "3c509.h"
#define EP_W3_INTERNAL_CONFIG 0x00 /* 32 bits */
#define EP_W3_RESET_OPTIONS 0x08 /* 16 bits */
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"},
};
#ifdef _STANDALONE
static struct btinfo_netif bi_netif;
#endif
/**************************************************************************
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, 0x9000, &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;
/* 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();
#ifdef _STANDALONE
strncpy(bi_netif.ifname, "ep", sizeof(bi_netif.ifname));
bi_netif.bus = BI_BUS_PCI;
bi_netif.addr.tag = hdl;
BI_ADD(&bi_netif, BTINFO_NETIF, sizeof(bi_netif));
#endif
return(1);
}