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