This source file includes following definitions.
- ep_pcmcia_lookup
- ep_pcmcia_match
- ep_pcmcia_enable
- ep_pcmcia_enable1
- ep_pcmcia_disable
- ep_pcmcia_disable1
- ep_pcmcia_attach
- ep_pcmcia_detach
- ep_pcmcia_activate
- ep_pcmcia_get_enaddr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 #include "bpfilter.h"
71
72 #include <sys/param.h>
73 #include <sys/systm.h>
74 #include <sys/mbuf.h>
75 #include <sys/socket.h>
76 #include <sys/ioctl.h>
77 #include <sys/errno.h>
78 #include <sys/syslog.h>
79 #include <sys/selinfo.h>
80 #include <sys/timeout.h>
81 #include <sys/device.h>
82
83 #include <net/if.h>
84 #include <net/if_dl.h>
85 #include <net/if_types.h>
86 #include <net/netisr.h>
87 #include <net/if_media.h>
88
89 #ifdef INET
90 #include <netinet/in.h>
91 #include <netinet/in_systm.h>
92 #include <netinet/in_var.h>
93 #include <netinet/ip.h>
94 #include <netinet/if_ether.h>
95 #endif
96
97 #if NBPFILTER > 0
98 #include <net/bpf.h>
99 #endif
100
101 #include <machine/cpu.h>
102 #include <machine/bus.h>
103
104 #include <dev/mii/mii.h>
105 #include <dev/mii/miivar.h>
106
107 #include <dev/ic/elink3var.h>
108 #include <dev/ic/elink3reg.h>
109
110 #include <dev/pcmcia/pcmciareg.h>
111 #include <dev/pcmcia/pcmciavar.h>
112 #include <dev/pcmcia/pcmciadevs.h>
113
114 int ep_pcmcia_match(struct device *, void *, void *);
115 void ep_pcmcia_attach(struct device *, struct device *, void *);
116 int ep_pcmcia_detach(struct device *, int);
117 int ep_pcmcia_activate(struct device *, enum devact);
118
119 int ep_pcmcia_get_enaddr(struct pcmcia_tuple *, void *);
120 #ifdef notyet
121 int ep_pcmcia_enable(struct ep_softc *);
122 void ep_pcmcia_disable(struct ep_softc *);
123 void ep_pcmcia_disable1(struct ep_softc *);
124 #endif
125
126 int ep_pcmcia_enable1(struct ep_softc *);
127
128 struct ep_pcmcia_softc {
129 struct ep_softc sc_ep;
130
131
132 struct pcmcia_io_handle sc_pcioh;
133 int sc_io_window;
134 struct pcmcia_function *sc_pf;
135 };
136
137 struct cfattach ep_pcmcia_ca = {
138 sizeof(struct ep_pcmcia_softc), ep_pcmcia_match, ep_pcmcia_attach,
139 ep_pcmcia_detach, ep_pcmcia_activate
140 };
141
142 struct ep_pcmcia_product {
143 u_int16_t epp_product;
144 u_short epp_chipset;
145 int epp_flags;
146 int epp_expfunc;
147 } ep_pcmcia_prod[] = {
148 { PCMCIA_PRODUCT_3COM_3C562, EP_CHIPSET_3C509,
149 0, 0 },
150
151 { PCMCIA_PRODUCT_3COM_3C589, EP_CHIPSET_3C509,
152 0, 0 },
153
154 { PCMCIA_PRODUCT_3COM_3CXEM556, EP_CHIPSET_3C509,
155 0, 0 },
156
157 { PCMCIA_PRODUCT_3COM_3CXEM556B,EP_CHIPSET_3C509,
158 0, 0 },
159
160 { PCMCIA_PRODUCT_3COM_3C1, EP_CHIPSET_3C509,
161 0, 0 },
162
163 { PCMCIA_PRODUCT_3COM_3CCFEM556BI, EP_CHIPSET_ROADRUNNER,
164 EP_FLAGS_MII, 0 },
165
166 { PCMCIA_PRODUCT_3COM_3C574, EP_CHIPSET_ROADRUNNER,
167 EP_FLAGS_MII, 0 }
168 };
169
170 struct ep_pcmcia_product *ep_pcmcia_lookup(struct pcmcia_attach_args *);
171
172 struct ep_pcmcia_product *
173 ep_pcmcia_lookup(pa)
174 struct pcmcia_attach_args *pa;
175 {
176 int i;
177
178 for (i = 0; i < sizeof(ep_pcmcia_prod)/sizeof(ep_pcmcia_prod[0]); i++)
179 if (pa->product == ep_pcmcia_prod[i].epp_product &&
180 pa->pf->number == ep_pcmcia_prod[i].epp_expfunc)
181 return &ep_pcmcia_prod[i];
182
183 return (NULL);
184 }
185
186 int
187 ep_pcmcia_match(parent, match, aux)
188 struct device *parent;
189 void *match, *aux;
190 {
191 struct pcmcia_attach_args *pa = aux;
192
193 if (pa->manufacturer != PCMCIA_VENDOR_3COM)
194 return (0);
195
196 if (ep_pcmcia_lookup(pa) != NULL)
197 return (1);
198
199 return (0);
200 }
201
202 #ifdef notdef
203 int
204 ep_pcmcia_enable(sc)
205 struct ep_softc *sc;
206 {
207 struct ep_pcmcia_softc *psc = (struct ep_pcmcia_softc *) sc;
208 struct pcmcia_function *pf = psc->sc_pf;
209
210
211 sc->sc_ih = pcmcia_intr_establish(pf, IPL_NET, epintr,
212 sc, sc->sc_dev.dv_xname);
213 if (sc->sc_ih == NULL) {
214 printf("%s: couldn't establish interrupt\n",
215 sc->sc_dev.dv_xname);
216 return (1);
217 }
218
219 return (ep_pcmcia_enable1(sc));
220 }
221 #endif
222
223 int
224 ep_pcmcia_enable1(sc)
225 struct ep_softc *sc;
226 {
227 struct ep_pcmcia_softc *psc = (struct ep_pcmcia_softc *) sc;
228 struct pcmcia_function *pf = psc->sc_pf;
229 int ret;
230
231 if ((ret = pcmcia_function_enable(pf)))
232 return (ret);
233
234 if ((psc->sc_pf->sc->card.product == PCMCIA_PRODUCT_3COM_3C562) ||
235 (psc->sc_pf->sc->card.product == PCMCIA_PRODUCT_3COM_3CXEM556) ||
236 (psc->sc_pf->sc->card.product == PCMCIA_PRODUCT_3COM_3CXEM556B)) {
237 int reg;
238
239
240
241 reg = pcmcia_ccr_read(pf, PCMCIA_CCR_OPTION);
242 if (reg & 0x08) {
243 reg &= ~0x08;
244 pcmcia_ccr_write(pf, PCMCIA_CCR_OPTION, reg);
245 }
246
247 }
248
249 return (ret);
250 }
251
252 #ifdef notyet
253 void
254 ep_pcmcia_disable(sc)
255 struct ep_softc *sc;
256 {
257 struct ep_pcmcia_softc *psc = (struct ep_pcmcia_softc *) sc;
258
259 pcmcia_intr_disestablish(psc->sc_pf, sc->sc_ih);
260 ep_pcmcia_disable1(sc);
261 }
262
263 void
264 ep_pcmcia_disable1(sc)
265 struct ep_softc *sc;
266 {
267 struct ep_pcmcia_softc *psc = (struct ep_pcmcia_softc *) sc;
268
269 pcmcia_function_disable(psc->sc_pf);
270 }
271 #endif
272
273 void
274 ep_pcmcia_attach(parent, self, aux)
275 struct device *parent, *self;
276 void *aux;
277 {
278 struct ep_pcmcia_softc *psc = (void *) self;
279 struct ep_softc *sc = &psc->sc_ep;
280 struct pcmcia_attach_args *pa = aux;
281 struct pcmcia_config_entry *cfe;
282 struct ep_pcmcia_product *epp;
283 u_int8_t myla[ETHER_ADDR_LEN];
284 u_int8_t *enaddr = NULL;
285 const char *intrstr;
286 int i;
287
288 psc->sc_pf = pa->pf;
289 cfe = SIMPLEQ_FIRST(&pa->pf->cfe_head);
290
291
292 pcmcia_function_init(pa->pf, cfe);
293 if (ep_pcmcia_enable1(sc))
294 printf(": function enable failed\n");
295
296 #ifdef notyet
297 sc->enabled = 1;
298 #endif
299
300 if (cfe->num_memspace != 0)
301 printf(": unexpected number of memory spaces %d should be 0\n",
302 cfe->num_memspace);
303
304 if (cfe->num_iospace != 1)
305 printf(": unexpected number of I/O spaces %d should be 1\n",
306 cfe->num_iospace);
307
308 if (pa->product == PCMCIA_PRODUCT_3COM_3C562) {
309 bus_addr_t maxaddr = (pa->pf->sc->iobase + pa->pf->sc->iosize);
310
311 for (i = pa->pf->sc->iobase; i < maxaddr; i += 0x10) {
312
313
314
315
316 if (i & 0x80)
317 continue;
318 if (pcmcia_io_alloc(pa->pf, i, cfe->iospace[0].length,
319 cfe->iospace[0].length, &psc->sc_pcioh) == 0)
320 break;
321 }
322 if (i >= maxaddr) {
323 printf(": can't allocate i/o space\n");
324 return;
325 }
326 } else {
327 if (pcmcia_io_alloc(pa->pf, 0, cfe->iospace[0].length,
328 cfe->iospace[0].length, &psc->sc_pcioh))
329 printf(": can't allocate i/o space\n");
330 }
331
332 sc->sc_iot = psc->sc_pcioh.iot;
333 sc->sc_ioh = psc->sc_pcioh.ioh;
334
335 if (pcmcia_io_map(pa->pf, ((cfe->flags & PCMCIA_CFE_IO16) ?
336 PCMCIA_WIDTH_IO16 : PCMCIA_WIDTH_IO8), 0, cfe->iospace[0].length,
337 &psc->sc_pcioh, &psc->sc_io_window)) {
338 printf(": can't map i/o space\n");
339 return;
340 }
341
342 printf(" port 0x%lx/%d", psc->sc_pcioh.addr, psc->sc_pcioh.size);
343
344 switch (pa->product) {
345 case PCMCIA_PRODUCT_3COM_3C562:
346
347
348
349
350
351
352 case PCMCIA_PRODUCT_3COM_3C574:
353 case PCMCIA_PRODUCT_3COM_3CCFEM556BI:
354
355
356
357 if (pcmcia_scan_cis(parent, ep_pcmcia_get_enaddr, myla))
358 enaddr = myla;
359 break;
360 }
361
362 sc->bustype = EP_BUS_PCMCIA;
363
364 epp = ep_pcmcia_lookup(pa);
365 if (epp == NULL)
366 panic("ep_pcmcia_attach: impossible");
367
368 sc->ep_flags = epp->epp_flags;
369
370 #ifdef notyet
371 sc->enable = ep_pcmcia_enable;
372 sc->disable = ep_pcmcia_disable;
373 #endif
374
375
376 sc->sc_ih = pcmcia_intr_establish(pa->pf, IPL_NET, epintr, sc,
377 sc->sc_dev.dv_xname);
378 intrstr = pcmcia_intr_string(psc->sc_pf, sc->sc_ih);
379 if (*intrstr)
380 printf(", %s", intrstr);
381
382 printf(":");
383
384 epconfig(sc, epp->epp_chipset, enaddr);
385
386 #ifdef notyet
387 sc->enabled = 0;
388
389 ep_pcmcia_disable1(sc);
390 #endif
391 }
392
393 int
394 ep_pcmcia_detach(dev, flags)
395 struct device *dev;
396 int flags;
397 {
398 int rv;
399 struct ep_pcmcia_softc *psc = (struct ep_pcmcia_softc *)dev;
400
401 if ((rv = ep_detach(dev)) != 0)
402 return (rv);
403
404 pcmcia_io_unmap(psc->sc_pf, psc->sc_io_window);
405 pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
406
407 return (0);
408 }
409
410 int
411 ep_pcmcia_activate(dev, act)
412 struct device *dev;
413 enum devact act;
414 {
415 struct ep_pcmcia_softc *sc = (struct ep_pcmcia_softc *)dev;
416 struct ep_softc *esc = &sc->sc_ep;
417 struct ifnet *ifp = &esc->sc_arpcom.ac_if;
418 int s;
419
420 s = splnet();
421 switch (act) {
422 case DVACT_ACTIVATE:
423 pcmcia_function_enable(sc->sc_pf);
424 sc->sc_ep.sc_ih = pcmcia_intr_establish(sc->sc_pf, IPL_NET,
425 epintr, sc, esc->sc_dev.dv_xname);
426 epinit(esc);
427 break;
428
429 case DVACT_DEACTIVATE:
430 ifp->if_timer = 0;
431 if (ifp->if_flags & IFF_RUNNING)
432 epstop(esc);
433 pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ep.sc_ih);
434 pcmcia_function_disable(sc->sc_pf);
435 break;
436 }
437 splx(s);
438 return (0);
439 }
440
441 int
442 ep_pcmcia_get_enaddr(tuple, arg)
443 struct pcmcia_tuple *tuple;
444 void *arg;
445 {
446 u_int8_t *myla = arg;
447 int i;
448
449
450 if (tuple->code == 0x88) {
451 if (tuple->length < ETHER_ADDR_LEN)
452 return (0);
453
454 for (i = 0; i < ETHER_ADDR_LEN; i += 2) {
455 myla[i] = pcmcia_tuple_read_1(tuple, i + 1);
456 myla[i + 1] = pcmcia_tuple_read_1(tuple, i);
457 }
458
459 return (1);
460 }
461 return (0);
462 }