xref: /minix3/sys/arch/i386/stand/lib/netif/3c590.c (revision 58a2b0008e28f606a7f7f5faaeaba4faac57a1ea)
1*58a2b000SEvgeniy Ivanov /*	$NetBSD: 3c590.c,v 1.15 2008/12/14 18:46:33 christos Exp $	*/
2*58a2b000SEvgeniy Ivanov 
3*58a2b000SEvgeniy Ivanov /* stripped down from freebsd:sys/i386/netboot/3c509.c */
4*58a2b000SEvgeniy Ivanov 
5*58a2b000SEvgeniy Ivanov 
6*58a2b000SEvgeniy Ivanov /**************************************************************************
7*58a2b000SEvgeniy Ivanov NETBOOT -  BOOTP/TFTP Bootstrap Program
8*58a2b000SEvgeniy Ivanov 
9*58a2b000SEvgeniy Ivanov Author: Martin Renters.
10*58a2b000SEvgeniy Ivanov   Date: Mar 22 1995
11*58a2b000SEvgeniy Ivanov 
12*58a2b000SEvgeniy Ivanov  This code is based heavily on David Greenman's if_ed.c driver and
13*58a2b000SEvgeniy Ivanov   Andres Vega Garcia's if_ep.c driver.
14*58a2b000SEvgeniy Ivanov 
15*58a2b000SEvgeniy Ivanov  Copyright (C) 1993-1994, David Greenman, Martin Renters.
16*58a2b000SEvgeniy Ivanov  Copyright (C) 1993-1995, Andres Vega Garcia.
17*58a2b000SEvgeniy Ivanov  Copyright (C) 1995, Serge Babkin.
18*58a2b000SEvgeniy Ivanov   This software may be used, modified, copied, distributed, and sold, in
19*58a2b000SEvgeniy Ivanov   both source and binary form provided that the above copyright and these
20*58a2b000SEvgeniy Ivanov   terms are retained. Under no circumstances are the authors responsible for
21*58a2b000SEvgeniy Ivanov   the proper functioning of this software, nor do the authors assume any
22*58a2b000SEvgeniy Ivanov   responsibility for damages incurred with its use.
23*58a2b000SEvgeniy Ivanov 
24*58a2b000SEvgeniy Ivanov 3c509 support added by Serge Babkin (babkin@hq.icb.chel.su)
25*58a2b000SEvgeniy Ivanov 
26*58a2b000SEvgeniy Ivanov 3c509.c,v 1.2 1995/05/30 07:58:52 rgrimes Exp
27*58a2b000SEvgeniy Ivanov 
28*58a2b000SEvgeniy Ivanov ***************************************************************************/
29*58a2b000SEvgeniy Ivanov 
30*58a2b000SEvgeniy Ivanov #include <sys/types.h>
31*58a2b000SEvgeniy Ivanov #include <machine/pio.h>
32*58a2b000SEvgeniy Ivanov 
33*58a2b000SEvgeniy Ivanov #include <lib/libsa/stand.h>
34*58a2b000SEvgeniy Ivanov 
35*58a2b000SEvgeniy Ivanov #include <libi386.h>
36*58a2b000SEvgeniy Ivanov #include <pcivar.h>
37*58a2b000SEvgeniy Ivanov 
38*58a2b000SEvgeniy Ivanov #if defined(_STANDALONE) && !defined(SUPPORT_NO_NETBSD)
39*58a2b000SEvgeniy Ivanov #include <lib/libkern/libkern.h>
40*58a2b000SEvgeniy Ivanov #include <bootinfo.h>
41*58a2b000SEvgeniy Ivanov #endif
42*58a2b000SEvgeniy Ivanov 
43*58a2b000SEvgeniy Ivanov #include "etherdrv.h"
44*58a2b000SEvgeniy Ivanov #include "3c509.h"
45*58a2b000SEvgeniy Ivanov 
46*58a2b000SEvgeniy Ivanov #define EP_W3_INTERNAL_CONFIG	0x00	/* 32 bits */
47*58a2b000SEvgeniy Ivanov #define EP_W3_RESET_OPTIONS	0x08	/* 16 bits */
48*58a2b000SEvgeniy Ivanov 
49*58a2b000SEvgeniy Ivanov unsigned ether_medium;
50*58a2b000SEvgeniy Ivanov unsigned short eth_base;
51*58a2b000SEvgeniy Ivanov 
52*58a2b000SEvgeniy Ivanov extern void epreset(void);
53*58a2b000SEvgeniy Ivanov extern int ep_get_e(int);
54*58a2b000SEvgeniy Ivanov 
55*58a2b000SEvgeniy Ivanov u_char eth_myaddr[6];
56*58a2b000SEvgeniy Ivanov 
57*58a2b000SEvgeniy Ivanov static struct mtabentry {
58*58a2b000SEvgeniy Ivanov     int address_cfg; /* configured connector */
59*58a2b000SEvgeniy Ivanov     int config_bit; /* connector present */
60*58a2b000SEvgeniy Ivanov     char *name;
61*58a2b000SEvgeniy Ivanov } mediatab[] = { /* indexed by media type - etherdrv.h */
62*58a2b000SEvgeniy Ivanov     {3, 0x10, "BNC"},
63*58a2b000SEvgeniy Ivanov     {0, 0x08, "UTP"},
64*58a2b000SEvgeniy Ivanov     {1, 0x20, "AUI"},
65*58a2b000SEvgeniy Ivanov     {6, 0x40, "MII"},
66*58a2b000SEvgeniy Ivanov };
67*58a2b000SEvgeniy Ivanov 
68*58a2b000SEvgeniy Ivanov #if defined(_STANDALONE) && !defined(SUPPORT_NO_NETBSD)
69*58a2b000SEvgeniy Ivanov static struct btinfo_netif bi_netif;
70*58a2b000SEvgeniy Ivanov #endif
71*58a2b000SEvgeniy Ivanov 
72*58a2b000SEvgeniy Ivanov /**************************************************************************
73*58a2b000SEvgeniy Ivanov ETH_PROBE - Look for an adapter
74*58a2b000SEvgeniy Ivanov ***************************************************************************/
75*58a2b000SEvgeniy Ivanov int
EtherInit(unsigned char * myadr)76*58a2b000SEvgeniy Ivanov EtherInit(unsigned char *myadr)
77*58a2b000SEvgeniy Ivanov {
78*58a2b000SEvgeniy Ivanov 	/* common variables */
79*58a2b000SEvgeniy Ivanov 	int i, j;
80*58a2b000SEvgeniy Ivanov 	/* variables for 3C509 */
81*58a2b000SEvgeniy Ivanov 	u_short *p;
82*58a2b000SEvgeniy Ivanov 	struct mtabentry *m;
83*58a2b000SEvgeniy Ivanov 
84*58a2b000SEvgeniy Ivanov 	/*********************************************************
85*58a2b000SEvgeniy Ivanov 			Search for 3Com 590 card
86*58a2b000SEvgeniy Ivanov 	***********************************************************/
87*58a2b000SEvgeniy Ivanov 
88*58a2b000SEvgeniy Ivanov 	pcihdl_t hdl;
89*58a2b000SEvgeniy Ivanov 	int iobase;
90*58a2b000SEvgeniy Ivanov 
91*58a2b000SEvgeniy Ivanov 	if (pcicheck() == -1) {
92*58a2b000SEvgeniy Ivanov 		printf("cannot access PCI\n");
93*58a2b000SEvgeniy Ivanov 		return 0;
94*58a2b000SEvgeniy Ivanov 	}
95*58a2b000SEvgeniy Ivanov 
96*58a2b000SEvgeniy Ivanov 	if (pcifinddev(0x10b7, 0x5900, &hdl) &&
97*58a2b000SEvgeniy Ivanov 	    pcifinddev(0x10b7, 0x5950, &hdl) &&
98*58a2b000SEvgeniy Ivanov 	    pcifinddev(0x10b7, 0x9000, &hdl) &&
99*58a2b000SEvgeniy Ivanov 	    pcifinddev(0x10b7, 0x9001, &hdl) &&
100*58a2b000SEvgeniy Ivanov 	    pcifinddev(0x10b7, 0x9050, &hdl)) {
101*58a2b000SEvgeniy Ivanov 		printf("cannot find 3c59x / 3c90x\n");
102*58a2b000SEvgeniy Ivanov 		return 0;
103*58a2b000SEvgeniy Ivanov 	}
104*58a2b000SEvgeniy Ivanov 
105*58a2b000SEvgeniy Ivanov 	if (pcicfgread(&hdl, 0x10, &iobase) || !(iobase & 1)) {
106*58a2b000SEvgeniy Ivanov 		printf("cannot map IO space\n");
107*58a2b000SEvgeniy Ivanov 		return 0;
108*58a2b000SEvgeniy Ivanov 	}
109*58a2b000SEvgeniy Ivanov 	eth_base = iobase & 0xfffffffc;
110*58a2b000SEvgeniy Ivanov 
111*58a2b000SEvgeniy Ivanov 	/* test for presence of connectors */
112*58a2b000SEvgeniy Ivanov 	GO_WINDOW(3);
113*58a2b000SEvgeniy Ivanov 	i = inb(IS_BASE + EP_W3_RESET_OPTIONS);
114*58a2b000SEvgeniy Ivanov 	j = (inw(IS_BASE + EP_W3_INTERNAL_CONFIG + 2) >> 4) & 7;
115*58a2b000SEvgeniy Ivanov 
116*58a2b000SEvgeniy Ivanov 	GO_WINDOW(0);
117*58a2b000SEvgeniy Ivanov 
118*58a2b000SEvgeniy Ivanov 	for (ether_medium = 0, m = mediatab;
119*58a2b000SEvgeniy Ivanov 	     ether_medium < sizeof(mediatab) / sizeof(mediatab[0]);
120*58a2b000SEvgeniy Ivanov 	     ether_medium++, m++) {
121*58a2b000SEvgeniy Ivanov 		if (j == m->address_cfg) {
122*58a2b000SEvgeniy Ivanov 			if (!(i & m->config_bit)) {
123*58a2b000SEvgeniy Ivanov 				printf("%s not present\n", m->name);
124*58a2b000SEvgeniy Ivanov 				return 0;
125*58a2b000SEvgeniy Ivanov 			}
126*58a2b000SEvgeniy Ivanov 			printf("using %s\n", m->name);
127*58a2b000SEvgeniy Ivanov 			goto ok;
128*58a2b000SEvgeniy Ivanov 		}
129*58a2b000SEvgeniy Ivanov 	}
130*58a2b000SEvgeniy Ivanov 	printf("unknown connector\n");
131*58a2b000SEvgeniy Ivanov 	return 0;
132*58a2b000SEvgeniy Ivanov 
133*58a2b000SEvgeniy Ivanov  ok:
134*58a2b000SEvgeniy Ivanov 	/*
135*58a2b000SEvgeniy Ivanov 	 * Read the station address from the eeprom
136*58a2b000SEvgeniy Ivanov 	 */
137*58a2b000SEvgeniy Ivanov 	p = (u_short *) eth_myaddr;
138*58a2b000SEvgeniy Ivanov 	for (i = 0; i < 3; i++) {
139*58a2b000SEvgeniy Ivanov 		u_short help;
140*58a2b000SEvgeniy Ivanov 		GO_WINDOW(0);
141*58a2b000SEvgeniy Ivanov 		help = ep_get_e(i);
142*58a2b000SEvgeniy Ivanov 		p[i] = ((help & 0xff) << 8) | ((help & 0xff00) >> 8);
143*58a2b000SEvgeniy Ivanov 		GO_WINDOW(2);
144*58a2b000SEvgeniy Ivanov 		outw(BASE + EP_W2_ADDR_0 + (i * 2), help);
145*58a2b000SEvgeniy Ivanov 	}
146*58a2b000SEvgeniy Ivanov 	for (i = 0; i < 6; i++)
147*58a2b000SEvgeniy Ivanov 		myadr[i] = eth_myaddr[i];
148*58a2b000SEvgeniy Ivanov 
149*58a2b000SEvgeniy Ivanov 	epreset();
150*58a2b000SEvgeniy Ivanov 
151*58a2b000SEvgeniy Ivanov 
152*58a2b000SEvgeniy Ivanov #if defined(_STANDALONE) && !defined(SUPPORT_NO_NETBSD)
153*58a2b000SEvgeniy Ivanov 	strncpy(bi_netif.ifname, "ep", sizeof(bi_netif.ifname));
154*58a2b000SEvgeniy Ivanov 	bi_netif.bus = BI_BUS_PCI;
155*58a2b000SEvgeniy Ivanov 	bi_netif.addr.tag = hdl;
156*58a2b000SEvgeniy Ivanov 
157*58a2b000SEvgeniy Ivanov 	BI_ADD(&bi_netif, BTINFO_NETIF, sizeof(bi_netif));
158*58a2b000SEvgeniy Ivanov #endif
159*58a2b000SEvgeniy Ivanov 
160*58a2b000SEvgeniy Ivanov 	return 1;
161*58a2b000SEvgeniy Ivanov }
162