xref: /netbsd/sys/arch/i386/stand/lib/netif/3c590.c (revision bf9ec67e)
1 /*	$NetBSD: 3c590.c,v 1.11 1999/11/05 22:57:39 drochner 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 int ether_medium;
50 unsigned short eth_base;
51 
52 extern void epreset __P((void));
53 extern int ep_get_e __P((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(myadr)
76 	unsigned char *myadr;
77 {
78 	/* common variables */
79 	int i, j;
80 	/* variables for 3C509 */
81 	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