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