Add missing parameter.
[dragonfly.git] / sys / dev / netif / ep / if_ep_eisa.c
CommitLineData
984263bc
MD
1/*
2 * Product specific probe and attach routines for:
3 * 3COM 3C579 and 3C509(in eisa config mode) ethernet controllers
4 *
5 * Copyright (c) 1996 Justin T. Gibbs
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice immediately at the beginning of the file, without modification,
13 * this list of conditions, and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Absolutely no warranty of function or purpose is made by the author
18 * Justin T. Gibbs.
19 * 4. Modifications may be freely made to this file if the above conditions
20 * are met.
21 *
22 * $FreeBSD: src/sys/dev/ep/if_ep_eisa.c,v 1.18 2000/01/14 07:14:00 peter Exp $
5a2ce713 23 * $DragonFly: src/sys/dev/netif/ep/if_ep_eisa.c,v 1.9 2005/06/03 23:05:22 joerg Exp $
984263bc
MD
24 */
25
26#include <sys/param.h>
27#include <sys/systm.h>
28#include <sys/kernel.h>
29#include <sys/socket.h>
30
31#include <sys/module.h>
32#include <sys/bus.h>
33
34#include <machine/bus.h>
35#include <machine/resource.h>
36#include <sys/rman.h>
37
38#include <net/if.h>
39#include <net/if_arp.h>
40#include <net/if_media.h>
41
42#include <machine/clock.h>
43
1f2de5d4 44#include <bus/eisa/eisaconf.h>
984263bc 45
1f2de5d4
MD
46#include "if_epreg.h"
47#include "if_epvar.h"
984263bc
MD
48
49#define EISA_DEVICE_ID_3COM_3C509_TP 0x506d5090
50#define EISA_DEVICE_ID_3COM_3C509_BNC 0x506d5091
51#define EISA_DEVICE_ID_3COM_3C579_TP 0x506d5092
52#define EISA_DEVICE_ID_3COM_3C579_BNC 0x506d5093
53#define EISA_DEVICE_ID_3COM_3C509_COMBO 0x506d5094
54#define EISA_DEVICE_ID_3COM_3C509_TPO 0x506d5095
55
56#define EP_EISA_SLOT_OFFSET 0x0c80
57#define EP_EISA_IOSIZE 0x000a
58
59#define EISA_IOCONF 0x0008
60#define IRQ_CHANNEL 0xf000
61#define INT_3 0x3000
62#define INT_5 0x5000
63#define INT_7 0x7000
64#define INT_9 0x9000
65#define INT_10 0xa000
66#define INT_11 0xb000
67#define INT_12 0xc000
68#define INT_15 0xf000
69#define EISA_BPROM_MEDIA_CONF 0x0006
70#define TRANS_TYPE 0xc000
71#define TRANS_TP 0x0000
72#define TRANS_AUI 0x4000
73#define TRANS_BNC 0xc000
74
b5101a88 75static const char *ep_match (eisa_id_t type);
984263bc
MD
76
77static const char*
78ep_match(eisa_id_t type)
79{
80 switch(type) {
81 case EISA_DEVICE_ID_3COM_3C509_TP:
82 return "3Com 3C509-TP Network Adapter";
83 break;
84 case EISA_DEVICE_ID_3COM_3C509_BNC:
85 return "3Com 3C509-BNC Network Adapter";
86 break;
87 case EISA_DEVICE_ID_3COM_3C579_TP:
88 return "3Com 3C579-TP EISA Network Adapter";
89 break;
90 case EISA_DEVICE_ID_3COM_3C579_BNC:
91 return "3Com 3C579-BNC EISA Network Adapter";
92 break;
93 case EISA_DEVICE_ID_3COM_3C509_COMBO:
94 return "3Com 3C509-Combo Network Adapter";
95 break;
96 case EISA_DEVICE_ID_3COM_3C509_TPO:
97 return "3Com 3C509-TPO Network Adapter";
98 break;
99 default:
100 break;
101 }
102 return (NULL);
103}
104
105static int
106ep_eisa_probe(device_t dev)
107{
108 const char *desc;
109 u_long iobase;
110 u_short conf;
111 u_long port;
112 int irq;
113 int int_trig;
114
115 desc = ep_match(eisa_get_id(dev));
116 if (!desc)
117 return (ENXIO);
118 device_set_desc(dev, desc);
119
120 port = (eisa_get_slot(dev) * EISA_SLOT_SIZE);
121 iobase = port + EP_EISA_SLOT_OFFSET;
122
123 /* We must be in EISA configuration mode */
124 if ((inw(iobase + EP_W0_ADDRESS_CFG) & 0x1f) != 0x1f)
125 return ENXIO;
126
127 eisa_add_iospace(dev, iobase, EP_EISA_IOSIZE, RESVADDR_NONE);
128 eisa_add_iospace(dev, port, EP_IOSIZE, RESVADDR_NONE);
129
130 conf = inw(iobase + EISA_IOCONF);
131 /* Determine our IRQ */
132 switch (conf & IRQ_CHANNEL) {
133 case INT_3:
134 irq = 3;
135 break;
136 case INT_5:
137 irq = 5;
138 break;
139 case INT_7:
140 irq = 7;
141 break;
142 case INT_9:
143 irq = 9;
144 break;
145 case INT_10:
146 irq = 10;
147 break;
148 case INT_11:
149 irq = 11;
150 break;
151 case INT_12:
152 irq = 12;
153 break;
154 case INT_15:
155 irq = 15;
156 break;
157 default:
158 /* Disabled */
5a2ce713 159 device_printf(dev, "3COM Network Adapter at "
d303dd07
JS
160 "slot %d has its IRQ disabled. "
161 "Probe failed.\n",
162 eisa_get_slot(dev));
984263bc
MD
163 return ENXIO;
164 }
165
166 switch(eisa_get_id(dev)) {
167 case EISA_DEVICE_ID_3COM_3C579_BNC:
168 case EISA_DEVICE_ID_3COM_3C579_TP:
169 int_trig = EISA_TRIGGER_LEVEL;
170 break;
171 default:
172 int_trig = EISA_TRIGGER_EDGE;
173 break;
174 }
175
176 eisa_add_intr(dev, irq, int_trig);
177
178 return 0;
179}
180
181static int
182ep_eisa_attach(device_t dev)
183{
184 struct ep_softc * sc = device_get_softc(dev);
185 struct resource * eisa_io = NULL;
186 u_int32_t eisa_iobase;
187 int irq;
188 int error = 0;
189 int rid;
190
191 rid = 1;
4e6d744d 192 eisa_io = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
984263bc
MD
193 if (!eisa_io) {
194 device_printf(dev, "No I/O space?!\n");
195 error = ENXIO;
196 goto bad;
197 }
198 eisa_iobase = rman_get_start(eisa_io);
199
200 /* Reset and Enable the card */
201 outb(eisa_iobase + EP_W0_CONFIG_CTRL, W0_P4_CMD_RESET_ADAPTER);
202 DELAY(1000); /* we must wait at least 1 ms */
203 outb(eisa_iobase + EP_W0_CONFIG_CTRL, W0_P4_CMD_ENABLE_ADAPTER);
204 /* Now the registers are availible through the lower ioport */
205
206 if ((error = ep_alloc(dev))) {
207 device_printf(dev, "ep_alloc() failed! (%d)\n", error);
208 goto bad;
209 }
210
211 switch(eisa_get_id(dev)) {
212 case EISA_DEVICE_ID_3COM_3C579_BNC:
213 case EISA_DEVICE_ID_3COM_3C579_TP:
214 sc->stat = F_ACCESS_32_BITS;
215 break;
216 default:
217 break;
218 }
219
220 ep_get_media(sc);
221
222 irq = rman_get_start(sc->irq);
223 if (irq == 9)
224 irq = 2;
225
226 GO_WINDOW(0);
227 SET_IRQ(BASE, irq);
228
229 if ((error = ep_attach(sc))) {
230 device_printf(dev, "ep_attach() failed! (%d)\n", error);
231 goto bad;
232 }
233
234 if ((error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET, ep_intr,
e9cb6d99 235 sc, &sc->ep_intrhand, NULL))) {
984263bc
MD
236 device_printf(dev, "bus_setup_intr() failed! (%d)\n", error);
237 goto bad;
238 }
239
240 return (0);
241
242 bad:
243 if (eisa_io)
244 bus_release_resource(dev, SYS_RES_IOPORT, 0, eisa_io);
245
246 ep_free(dev);
247 return (error);
248}
249
250static device_method_t ep_eisa_methods[] = {
251 /* Device interface */
252 DEVMETHOD(device_probe, ep_eisa_probe),
253 DEVMETHOD(device_attach, ep_eisa_attach),
254
255 { 0, 0 }
256};
257
258static driver_t ep_eisa_driver = {
259 "ep",
260 ep_eisa_methods,
261 sizeof(struct ep_softc),
262};
263
264extern devclass_t ep_devclass;
265
32832096 266DRIVER_MODULE(if_ep, eisa, ep_eisa_driver, ep_devclass, 0, 0);