This source file includes following definitions.
- ef_isapnp_match
- ef_isapnp_attach
- efstart
- efioctl
- efinit
- efreset
- efstop
- efcompletecmd
- efintr
- eftxstat
- efbusyeeprom
- efwatchdog
- efsetmulti
- efread
- efget
- ef_mii_writeb
- ef_mii_sync
- ef_miibus_readreg
- ef_miibus_writereg
- ef_ifmedia_upd
- ef_ifmedia_sts
- ef_miibus_statchg
- ef_tick
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 #include "bpfilter.h"
30
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/mbuf.h>
34 #include <sys/socket.h>
35 #include <sys/ioctl.h>
36 #include <sys/errno.h>
37 #include <sys/syslog.h>
38 #include <sys/selinfo.h>
39 #include <sys/device.h>
40 #include <sys/queue.h>
41 #include <sys/kernel.h>
42 #include <sys/timeout.h>
43
44 #include <net/if.h>
45 #include <net/if_dl.h>
46 #include <net/if_types.h>
47 #include <net/netisr.h>
48 #include <net/if_media.h>
49
50 #ifdef INET
51 #include <netinet/in.h>
52 #include <netinet/in_systm.h>
53 #include <netinet/in_var.h>
54 #include <netinet/ip.h>
55 #include <netinet/if_ether.h>
56 #endif
57
58 #if NBPFILTER > 0
59 #include <net/bpf.h>
60 #endif
61
62 #include <machine/cpu.h>
63 #include <machine/bus.h>
64 #include <machine/intr.h>
65
66 #include <dev/mii/mii.h>
67 #include <dev/mii/miivar.h>
68 #include <dev/isa/isavar.h>
69 #include <dev/isa/isadmavar.h>
70 #include <dev/ic/elink3reg.h>
71
72 #undef EF_DEBUG
73
74 struct ef_softc {
75 struct device sc_dv;
76 bus_space_tag_t sc_iot;
77 bus_space_handle_t sc_ioh;
78 struct arpcom sc_arpcom;
79 struct mii_data sc_mii;
80 struct timeout sc_tick_tmo;
81 void * sc_ih;
82 int sc_tx_start_thresh;
83 int sc_tx_succ_ok;
84 int sc_busmaster;
85 };
86
87 #define EF_W0_EEPROM_COMMAND 0x200a
88 #define EF_EEPROM_BUSY (1 << 9)
89 #define EF_EEPROM_READ (1 << 7)
90 #define EF_W0_EEPROM_DATA 0x200c
91
92 #define EF_W1_TX_PIO_WR_1 0x10
93 #define EF_W1_RX_PIO_RR_1 0x10
94 #define EF_W1_RX_ERRORS 0x14
95 #define EF_W1_RX_STATUS 0x18
96 #define EF_W1_TX_STATUS 0x1b
97 #define EF_W1_FREE_TX 0x1c
98
99 #define EF_W4_MEDIA 0x0a
100 #define EF_MEDIA_SQE 0x0008
101 #define EF_MEDIA_TP 0x00c0
102 #define EF_MEDIA_LNK 0x0080
103 #define EF_MEDIA_LNKBEAT 0x0800
104
105
106 #define EF_MII_CLK 0x01
107 #define EF_MII_DATA 0x02
108 #define EF_MII_DIR 0x04
109
110 int ef_isapnp_match(struct device *, void *, void *);
111 void ef_isapnp_attach(struct device *, struct device *, void *);
112
113 void efstart(struct ifnet *);
114 int efioctl(struct ifnet *, u_long, caddr_t);
115 void efwatchdog(struct ifnet *);
116 void efreset(struct ef_softc *);
117 void efstop(struct ef_softc *);
118 void efsetmulti(struct ef_softc *);
119 int efbusyeeprom(struct ef_softc *);
120 int efintr(void *);
121 void efinit(struct ef_softc *);
122 void efcompletecmd(struct ef_softc *, u_int, u_int);
123 void eftxstat(struct ef_softc *);
124 void efread(struct ef_softc *);
125 struct mbuf *efget(struct ef_softc *, int totlen);
126
127 void ef_miibus_writereg(struct device *, int, int, int);
128 void ef_miibus_statchg(struct device *);
129 int ef_miibus_readreg(struct device *, int, int);
130 void ef_mii_writeb(struct ef_softc *, int);
131 void ef_mii_sync(struct ef_softc *);
132 int ef_ifmedia_upd(struct ifnet *);
133 void ef_ifmedia_sts(struct ifnet *, struct ifmediareq *);
134 void ef_tick(void *);
135
136 struct cfdriver ef_cd = {
137 NULL, "ef", DV_IFNET
138 };
139
140 struct cfattach ef_isapnp_ca = {
141 sizeof(struct ef_softc), ef_isapnp_match, ef_isapnp_attach
142 };
143
144 int
145 ef_isapnp_match(parent, match, aux)
146 struct device *parent;
147 void *match, *aux;
148 {
149 return (1);
150 }
151
152 void
153 ef_isapnp_attach(parent, self, aux)
154 struct device *parent, *self;
155 void *aux;
156 {
157 struct ef_softc *sc = (void *)self;
158 struct isa_attach_args *ia = aux;
159 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
160 bus_space_tag_t iot;
161 bus_space_handle_t ioh;
162 int i;
163 u_int16_t x;
164 u_int32_t cfg;
165
166 sc->sc_iot = iot = ia->ia_iot;
167 sc->sc_ioh = ioh = ia->ipa_io[0].h;
168
169 efcompletecmd(sc, EP_COMMAND, GLOBAL_RESET);
170 DELAY(1500);
171
172 for (i = 0; i < 3; i++) {
173 if (efbusyeeprom(sc))
174 return;
175
176 bus_space_write_2(iot, ioh, EF_W0_EEPROM_COMMAND,
177 EF_EEPROM_READ | i);
178
179 if (efbusyeeprom(sc))
180 return;
181
182 x = bus_space_read_2(iot, ioh, EF_W0_EEPROM_DATA);
183
184 sc->sc_arpcom.ac_enaddr[(i << 1)] = x >> 8;
185 sc->sc_arpcom.ac_enaddr[(i << 1) + 1] = x;
186 }
187
188 printf(": address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr));
189
190 GO_WINDOW(3);
191 cfg = bus_space_read_4(iot, ioh, EP_W3_INTERNAL_CONFIG);
192 cfg &= ~(0x00f00000);
193 cfg |= (0x06 << 20);
194 bus_space_write_4(iot, ioh, EP_W3_INTERNAL_CONFIG, cfg);
195
196 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
197 IPL_NET, efintr, sc, sc->sc_dv.dv_xname);
198
199 if (ia->ia_drq != DRQUNK)
200 isadma_cascade(ia->ia_drq);
201
202 timeout_set(&sc->sc_tick_tmo, ef_tick, sc);
203
204 bcopy(sc->sc_dv.dv_xname, ifp->if_xname, IFNAMSIZ);
205 ifp->if_softc = sc;
206 ifp->if_start = efstart;
207 ifp->if_ioctl = efioctl;
208 ifp->if_watchdog = efwatchdog;
209 ifp->if_flags =
210 IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
211 IFQ_SET_READY(&ifp->if_snd);
212
213 sc->sc_mii.mii_ifp = ifp;
214 sc->sc_mii.mii_readreg = ef_miibus_readreg;
215 sc->sc_mii.mii_writereg = ef_miibus_writereg;
216 sc->sc_mii.mii_statchg = ef_miibus_statchg;
217 ifmedia_init(&sc->sc_mii.mii_media, 0, ef_ifmedia_upd, ef_ifmedia_sts);
218 mii_attach(self, &sc->sc_mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY,
219 0);
220 if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
221 ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL);
222 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE);
223 } else
224 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
225
226 if_attach(ifp);
227 ether_ifattach(ifp);
228
229 sc->sc_tx_start_thresh = 20;
230
231 efcompletecmd(sc, EP_COMMAND, RX_RESET);
232 efcompletecmd(sc, EP_COMMAND, TX_RESET);
233 }
234
235 void
236 efstart(ifp)
237 struct ifnet *ifp;
238 {
239 struct ef_softc *sc = ifp->if_softc;
240 bus_space_tag_t iot = sc->sc_iot;
241 bus_space_handle_t ioh = sc->sc_ioh;
242 struct mbuf *m, *m0;
243 int s, len, pad, i;
244 int fillcnt = 0;
245 u_int32_t filler = 0;
246
247 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
248 return;
249
250 startagain:
251 IFQ_POLL(&ifp->if_snd, m0);
252 if (m0 == NULL)
253 return;
254
255 if ((m0->m_flags & M_PKTHDR) == 0)
256 panic("efstart: no header mbuf");
257 len = m0->m_pkthdr.len;
258 pad = (4 - len) & 3;
259
260 if (len + pad > ETHER_MAX_LEN) {
261 ifp->if_oerrors++;
262 IFQ_DEQUEUE(&ifp->if_snd, m0);
263 m_freem(m0);
264 goto startagain;
265 }
266
267 if (bus_space_read_2(iot, ioh, EF_W1_FREE_TX) < len + pad + 4) {
268 bus_space_write_2(iot, ioh, EP_COMMAND,
269 SET_TX_AVAIL_THRESH | ((len + pad) >> 2));
270 ifp->if_flags |= IFF_OACTIVE;
271 return;
272 } else {
273 bus_space_write_2(iot, ioh, EP_COMMAND,
274 SET_TX_AVAIL_THRESH | EP_THRESH_DISABLE);
275 }
276
277 bus_space_write_2(iot, ioh, EP_COMMAND, SET_TX_START_THRESH |
278 ((len / 4 + sc->sc_tx_start_thresh)));
279
280 #if NBPFILTER
281 if (ifp->if_bpf)
282 bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
283 #endif
284
285 IFQ_DEQUEUE(&ifp->if_snd, m0);
286 if (m0 == NULL)
287 return;
288
289 s = splhigh();
290
291 bus_space_write_4(iot, ioh, EF_W1_TX_PIO_WR_1, len);
292 for (m = m0; m; ) {
293 if (fillcnt) {
294 while (m->m_len && fillcnt < 4) {
295 fillcnt++;
296 filler >>= 8;
297 filler |= m->m_data[0] << 24;
298 m->m_data++;
299 m->m_len--;
300 }
301 if (fillcnt == 4) {
302 bus_space_write_4(iot, ioh,
303 EF_W1_TX_PIO_WR_1, filler);
304 filler = 0;
305 fillcnt = 0;
306 }
307 }
308
309 if (m->m_len & ~3)
310 bus_space_write_multi_4(iot, ioh,
311 EF_W1_TX_PIO_WR_1, (u_int32_t *)m->m_data,
312 m->m_len >> 2);
313 for (i = 0; i < (m->m_len & 3); i++) {
314 fillcnt++;
315 filler >>= 8;
316 filler |= m->m_data[(m->m_len & ~3) + i] << 24;
317 }
318 MFREE(m, m0);
319 m = m0;
320 }
321
322 if (fillcnt) {
323 bus_space_write_4(iot, ioh, EF_W1_TX_PIO_WR_1,
324 filler >> (32 - (8 * fillcnt)));
325 fillcnt = 0;
326 filler = 0;
327 }
328
329 splx(s);
330
331 ifp->if_opackets++;
332
333 goto startagain;
334 }
335
336 int
337 efioctl(ifp, cmd, data)
338 struct ifnet *ifp;
339 u_long cmd;
340 caddr_t data;
341 {
342 struct ef_softc *sc = ifp->if_softc;
343 struct ifaddr *ifa = (struct ifaddr *)data;
344 struct ifreq *ifr = (struct ifreq *)data;
345 int s, error = 0;
346
347 s = splnet();
348
349 if ((error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data)) > 0) {
350 splx(s);
351 return (error);
352 }
353
354 switch (cmd) {
355 case SIOCSIFADDR:
356 ifp->if_flags |= IFF_UP;
357 switch (ifa->ifa_addr->sa_family) {
358 #ifdef INET
359 case AF_INET:
360 efinit(sc);
361 arp_ifinit(&sc->sc_arpcom, ifa);
362 break;
363 #endif
364 default:
365 efinit(sc);
366 break;
367 }
368 break;
369 case SIOCSIFMEDIA:
370 case SIOCGIFMEDIA:
371 error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
372 break;
373 case SIOCSIFFLAGS:
374 if ((ifp->if_flags & IFF_UP) == 0 &&
375 (ifp->if_flags & IFF_RUNNING) != 0) {
376 efstop(sc);
377 ifp->if_flags &= ~IFF_RUNNING;
378 } else if ((ifp->if_flags & IFF_UP) != 0 &&
379 (ifp->if_flags & IFF_RUNNING) == 0) {
380 efinit(sc);
381 }
382 efsetmulti(sc);
383 break;
384
385 case SIOCADDMULTI:
386 case SIOCDELMULTI:
387 error = (cmd == SIOCADDMULTI) ?
388 ether_addmulti(ifr, &sc->sc_arpcom) :
389 ether_delmulti(ifr, &sc->sc_arpcom);
390
391 if (error == ENETRESET) {
392 if (ifp->if_flags & IFF_RUNNING)
393 efreset(sc);
394 error = 0;
395 }
396 efsetmulti(sc);
397 break;
398 default:
399 error = EINVAL;
400 break;
401 }
402
403 splx(s);
404 return (error);
405 }
406
407 void
408 efinit(sc)
409 struct ef_softc *sc;
410 {
411 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
412 bus_space_tag_t iot = sc->sc_iot;
413 bus_space_handle_t ioh = sc->sc_ioh;
414 int i, s;
415
416 s = splnet();
417
418 efstop(sc);
419
420 while (bus_space_read_2(iot, ioh, EP_STATUS) & S_COMMAND_IN_PROGRESS)
421 ;
422
423 GO_WINDOW(2);
424 for (i = 0; i < 6; i++)
425 bus_space_write_1(iot, ioh, EP_W2_ADDR_0 + i,
426 sc->sc_arpcom.ac_enaddr[i]);
427 for (i = 0; i < 3; i += 2)
428 bus_space_write_2(iot, ioh, EP_W2_RECVMASK_0 + (i * 2), 0);
429
430 efcompletecmd(sc, EP_COMMAND, RX_RESET);
431 efcompletecmd(sc, EP_COMMAND, TX_RESET);
432
433 bus_space_write_2(iot, ioh, EP_COMMAND,
434 SET_TX_AVAIL_THRESH | (ETHER_MAX_DIX_LEN >> 2));
435
436 efsetmulti(sc);
437
438 bus_space_write_2(iot, ioh, EP_COMMAND, STATUS_ENABLE | 0);
439
440 GO_WINDOW(6);
441 for (i = 0; i < 10; i++)
442 (void)bus_space_read_1(iot, ioh, i);
443 (void)bus_space_read_2(iot, ioh, 10);
444 (void)bus_space_read_2(iot, ioh, 12);
445 GO_WINDOW(4);
446 (void)bus_space_read_1(iot, ioh, 12);
447 bus_space_write_2(iot, ioh, EP_W4_NET_DIAG, 0x0040);
448
449 GO_WINDOW(7);
450
451 efsetmulti(sc);
452
453 bus_space_write_2(iot, ioh, EP_COMMAND, RX_ENABLE);
454 bus_space_write_2(iot, ioh, EP_COMMAND, TX_ENABLE);
455
456 bus_space_write_2(iot, ioh, EP_COMMAND, STATUS_ENABLE |
457 S_CARD_FAILURE | S_INT_RQD | S_UPD_STATS | S_TX_COMPLETE |
458 S_TX_AVAIL | S_RX_COMPLETE |
459 (sc->sc_busmaster ? S_DMA_DONE : 0));
460 bus_space_write_2(iot, ioh, EP_COMMAND, ACK_INTR |
461 S_INTR_LATCH | S_TX_AVAIL | S_RX_EARLY | S_INT_RQD);
462 bus_space_write_2(iot, ioh, EP_COMMAND, SET_INTR_MASK |
463 S_INTR_LATCH | S_TX_AVAIL | S_RX_COMPLETE | S_UPD_STATS |
464 (sc->sc_busmaster ? S_DMA_DONE : 0) | S_UP_COMPLETE |
465 S_DOWN_COMPLETE | S_CARD_FAILURE | S_TX_COMPLETE);
466
467 mii_mediachg(&sc->sc_mii);
468
469 ifp->if_flags |= IFF_RUNNING;
470 ifp->if_flags &= ~IFF_OACTIVE;
471
472 splx(s);
473
474 timeout_add(&sc->sc_tick_tmo, hz);
475
476 efstart(ifp);
477 }
478
479 void
480 efreset(sc)
481 struct ef_softc *sc;
482 {
483 int s;
484
485 s = splnet();
486 efstop(sc);
487 efinit(sc);
488 splx(s);
489 }
490
491 void
492 efstop(sc)
493 struct ef_softc *sc;
494 {
495 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
496 bus_space_tag_t iot = sc->sc_iot;
497 bus_space_handle_t ioh = sc->sc_ioh;
498
499 ifp->if_timer = 0;
500 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
501
502 timeout_del(&sc->sc_tick_tmo);
503
504 bus_space_write_2(iot, ioh, EP_COMMAND, RX_DISABLE);
505 efcompletecmd(sc, EP_COMMAND, RX_DISCARD_TOP_PACK);
506
507 bus_space_write_2(iot, ioh, EP_COMMAND, TX_DISABLE);
508 bus_space_write_2(iot, ioh, EP_COMMAND, STOP_TRANSCEIVER);
509
510 efcompletecmd(sc, EP_COMMAND, RX_RESET);
511 efcompletecmd(sc, EP_COMMAND, TX_RESET);
512
513 bus_space_write_2(iot, ioh, EP_COMMAND, C_INTR_LATCH);
514 bus_space_write_2(iot, ioh, EP_COMMAND, SET_RD_0_MASK);
515 bus_space_write_2(iot, ioh, EP_COMMAND, SET_INTR_MASK);
516 bus_space_write_2(iot, ioh, EP_COMMAND, SET_RX_FILTER);
517 }
518
519 void
520 efcompletecmd(sc, cmd, arg)
521 struct ef_softc *sc;
522 u_int cmd, arg;
523 {
524 bus_space_tag_t iot = sc->sc_iot;
525 bus_space_handle_t ioh = sc->sc_ioh;
526
527 bus_space_write_2(iot, ioh, cmd, arg);
528 while (bus_space_read_2(iot, ioh, EP_STATUS) & S_COMMAND_IN_PROGRESS)
529 ;
530 }
531
532 int
533 efintr(vsc)
534 void *vsc;
535 {
536 struct ef_softc *sc = vsc;
537 bus_space_tag_t iot = sc->sc_iot;
538 bus_space_handle_t ioh = sc->sc_ioh;
539 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
540 u_int16_t status;
541 int r = 0;
542
543 status = bus_space_read_2(iot, ioh, EP_STATUS);
544
545 do {
546 if (status & S_RX_COMPLETE) {
547 r = 1;
548 bus_space_write_2(iot, ioh, EP_STATUS, C_RX_COMPLETE);
549 efread(sc);
550 }
551 if (status & S_TX_AVAIL) {
552 bus_space_write_2(iot, ioh, EP_STATUS, C_TX_AVAIL);
553 r = 1;
554 sc->sc_arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
555 efstart(&sc->sc_arpcom.ac_if);
556 }
557 if (status & S_CARD_FAILURE) {
558 r = 1;
559 efreset(sc);
560 printf("%s: adapter failure (%x)\n",
561 sc->sc_dv.dv_xname, status);
562 bus_space_write_2(iot, ioh, EP_COMMAND,
563 C_CARD_FAILURE);
564 return (1);
565 }
566 if (status & S_TX_COMPLETE) {
567 r = 1;
568 eftxstat(sc);
569 efstart(ifp);
570 }
571 bus_space_write_2(iot, ioh, EP_COMMAND,
572 C_INTR_LATCH | C_INT_RQD);
573 } while ((status = bus_space_read_2(iot, ioh, EP_STATUS)) &
574 (S_INT_RQD | S_RX_COMPLETE));
575
576 return (r);
577 }
578
579 void
580 eftxstat(sc)
581 struct ef_softc *sc;
582 {
583 bus_space_tag_t iot = sc->sc_iot;
584 bus_space_handle_t ioh = sc->sc_ioh;
585 int i;
586
587 while ((i = bus_space_read_1(iot, ioh, EF_W1_TX_STATUS)) &
588 TXS_COMPLETE) {
589 bus_space_write_1(iot, ioh, EF_W1_TX_STATUS, 0);
590
591 if (i & TXS_JABBER) {
592 sc->sc_arpcom.ac_if.if_oerrors++;
593 #ifdef EF_DEBUG
594 if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG)
595 printf("%s: jabber (%x)\n",
596 sc->sc_dv.dv_xname, i);
597 #endif
598 efreset(sc);
599 }
600 else if (i & TXS_UNDERRUN) {
601 sc->sc_arpcom.ac_if.if_oerrors++;
602 #ifdef EF_DEBUG
603 if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG)
604 printf("%s: fifo underrun (%x) @%d\n",
605 sc->sc_dv.dv_xname, i,
606 sc->sc_tx_start_thresh);
607 #endif
608 if (sc->sc_tx_succ_ok < 100)
609 sc->sc_tx_start_thresh = min(ETHER_MAX_LEN,
610 sc->sc_tx_start_thresh + 20);
611 sc->sc_tx_succ_ok = 0;
612 efreset(sc);
613 }
614 else if (i & TXS_MAX_COLLISION) {
615 sc->sc_arpcom.ac_if.if_collisions++;
616 bus_space_write_2(iot, ioh, EP_COMMAND, TX_ENABLE);
617 sc->sc_arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
618 }
619 else
620 sc->sc_tx_succ_ok = (sc->sc_tx_succ_ok + 1) & 127;
621 }
622 }
623
624 int
625 efbusyeeprom(sc)
626 struct ef_softc *sc;
627 {
628 int i = 100, j;
629
630 while (i--) {
631 j = bus_space_read_2(sc->sc_iot, sc->sc_ioh,
632 EF_W0_EEPROM_COMMAND);
633 if (j & EF_EEPROM_BUSY)
634 delay(100);
635 else
636 break;
637 }
638 if (i == 0) {
639 printf("%s: eeprom failed to come ready\n",
640 sc->sc_dv.dv_xname);
641 return (1);
642 }
643
644 return (0);
645 }
646
647 void
648 efwatchdog(ifp)
649 struct ifnet *ifp;
650 {
651 struct ef_softc *sc = ifp->if_softc;
652
653 printf("%s: device timeout\n", sc->sc_dv.dv_xname);
654 sc->sc_arpcom.ac_if.if_oerrors++;
655 efreset(sc);
656 }
657
658 void
659 efsetmulti(sc)
660 struct ef_softc *sc;
661 {
662 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
663 struct arpcom *ac = &sc->sc_arpcom;
664 bus_space_tag_t iot = sc->sc_iot;
665 bus_space_handle_t ioh = sc->sc_ioh;
666 struct ether_multi *enm;
667 struct ether_multistep step;
668 u_int16_t cmd = SET_RX_FILTER | FIL_INDIVIDUAL | FIL_BRDCST;
669 int mcnt = 0;
670
671 ETHER_FIRST_MULTI(step, ac, enm);
672 while (enm != NULL) {
673 mcnt++;
674 ETHER_NEXT_MULTI(step, enm);
675 }
676 if (mcnt || ifp->if_flags & IFF_ALLMULTI)
677 cmd |= FIL_MULTICAST;
678
679 if (ifp->if_flags & IFF_PROMISC)
680 cmd |= FIL_PROMISC;
681
682 bus_space_write_2(iot, ioh, EP_COMMAND, cmd);
683 }
684
685 void
686 efread(sc)
687 struct ef_softc *sc;
688 {
689 bus_space_tag_t iot = sc->sc_iot;
690 bus_space_handle_t ioh = sc->sc_ioh;
691 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
692 struct mbuf *m;
693 int len;
694
695 len = bus_space_read_2(iot, ioh, EF_W1_RX_STATUS);
696
697 #ifdef EF_DEBUG
698 if (ifp->if_flags & IFF_DEBUG) {
699 int err = len & ERR_MASK;
700 char *s = NULL;
701
702 if (len & ERR_INCOMPLETE)
703 s = "incomplete packet";
704 else if (err == ERR_OVERRUN)
705 s = "packet overrun";
706 else if (err == ERR_RUNT)
707 s = "runt packet";
708 else if (err == ERR_ALIGNMENT)
709 s = "bad alignment";
710 else if (err == ERR_CRC)
711 s = "bad crc";
712 else if (err == ERR_OVERSIZE)
713 s = "oversized packet";
714 else if (err == ERR_DRIBBLE)
715 s = "dribble bits";
716
717 if (s)
718 printf("%s: %s\n", sc->sc_dv.dv_xname, s);
719 }
720 #endif
721
722 if (len & ERR_INCOMPLETE)
723 return;
724
725 if (len & ERR_RX) {
726 ifp->if_ierrors++;
727 efcompletecmd(sc, EP_COMMAND, RX_DISCARD_TOP_PACK);
728 return;
729 }
730
731 len &= RX_BYTES_MASK;
732 m = efget(sc, len);
733 if (m == NULL) {
734 ifp->if_ierrors++;
735 efcompletecmd(sc, EP_COMMAND, RX_DISCARD_TOP_PACK);
736 return;
737 }
738
739 ifp->if_ipackets++;
740
741 #if NBPFILTER > 0
742 if (ifp->if_bpf)
743 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
744 #endif
745
746 ether_input_mbuf(ifp, m);
747 }
748
749 struct mbuf *
750 efget(sc, totlen)
751 struct ef_softc *sc;
752 int totlen;
753 {
754 bus_space_tag_t iot = sc->sc_iot;
755 bus_space_handle_t ioh = sc->sc_ioh;
756 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
757 struct mbuf *top, **mp, *m;
758 int len, pad, s;
759
760 MGETHDR(m, M_DONTWAIT, MT_DATA);
761 if (m == NULL)
762 return (NULL);
763 m->m_pkthdr.rcvif = ifp;
764 m->m_pkthdr.len = totlen;
765 pad = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header);
766 m->m_data += pad;
767 len = MHLEN -pad;
768 top = 0;
769 mp = ⊤
770
771 s = splhigh();
772
773 while (totlen > 0) {
774 if (top) {
775 MGET(m, M_DONTWAIT, MT_DATA);
776 if (m == NULL) {
777 m_freem(top);
778 splx(s);
779 return (NULL);
780 }
781 len = MLEN;
782 }
783 if (top && totlen >= MINCLSIZE) {
784 MCLGET(m, M_DONTWAIT);
785 if (m->m_flags & M_EXT)
786 len = MCLBYTES;
787 }
788 len = min(totlen, len);
789 if (len > 1) {
790 len &= ~1;
791 bus_space_read_raw_multi_2(iot, ioh,
792 EF_W1_RX_PIO_RR_1, mtod(m, u_int8_t *),
793 len);
794 } else
795 *(mtod(m, u_int8_t *)) =
796 bus_space_read_1(iot, ioh, EF_W1_RX_PIO_RR_1);
797
798 m->m_len = len;
799 totlen -= len;
800 *mp = m;
801 mp = &m->m_next;
802 }
803
804 efcompletecmd(sc, EP_COMMAND, RX_DISCARD_TOP_PACK);
805
806 splx(s);
807
808 return (top);
809 }
810
811 #define MII_SET(sc, x) \
812 bus_space_write_2((sc)->sc_iot, (sc)->sc_ioh, EP_W4_CTRLR_STATUS, \
813 bus_space_read_2((sc)->sc_iot, (sc)->sc_ioh, EP_W4_CTRLR_STATUS) \
814 | (x))
815
816 #define MII_CLR(sc, x) \
817 bus_space_write_2((sc)->sc_iot, (sc)->sc_ioh, EP_W4_CTRLR_STATUS, \
818 bus_space_read_2((sc)->sc_iot, (sc)->sc_ioh, EP_W4_CTRLR_STATUS) \
819 & (~(x)))
820
821 void
822 ef_mii_writeb(sc, b)
823 struct ef_softc *sc;
824 int b;
825 {
826 MII_CLR(sc, EF_MII_CLK);
827
828 if (b)
829 MII_SET(sc, EF_MII_DATA);
830 else
831 MII_CLR(sc, EF_MII_DATA);
832
833 MII_CLR(sc, EF_MII_CLK);
834 DELAY(1);
835 MII_SET(sc, EF_MII_CLK);
836 DELAY(1);
837 }
838
839 void
840 ef_mii_sync(sc)
841 struct ef_softc *sc;
842 {
843 int i;
844
845 for (i = 0; i < 32; i++)
846 ef_mii_writeb(sc, 1);
847 }
848
849 int
850 ef_miibus_readreg(dev, phy, reg)
851 struct device *dev;
852 int phy, reg;
853 {
854 struct ef_softc *sc = (struct ef_softc *)dev;
855 int i, ack, s, val = 0;
856
857 s = splnet();
858
859 GO_WINDOW(4);
860 bus_space_write_2(sc->sc_iot, sc->sc_ioh, EP_W4_CTRLR_STATUS, 0);
861
862
863 MII_SET(sc, EF_MII_DIR);
864 MII_CLR(sc, EF_MII_CLK);
865
866 ef_mii_sync(sc);
867
868
869 ef_mii_writeb(sc, 0);
870 ef_mii_writeb(sc, 1);
871
872
873 ef_mii_writeb(sc, 1);
874 ef_mii_writeb(sc, 0);
875
876
877 for (i = 0x10; i; i >>= 1)
878 ef_mii_writeb(sc, (phy & i) ? 1 : 0);
879
880
881 for (i = 0x10; i; i >>= 1)
882 ef_mii_writeb(sc, (reg & i) ? 1 : 0);
883
884
885 MII_CLR(sc, EF_MII_CLK | EF_MII_DATA);
886 DELAY(1);
887 MII_SET(sc, EF_MII_CLK);
888 DELAY(1);
889
890
891 MII_CLR(sc, EF_MII_DIR);
892
893
894 MII_CLR(sc, EF_MII_CLK);
895 DELAY(1);
896 MII_SET(sc, EF_MII_CLK);
897 DELAY(1);
898 ack = bus_space_read_2(sc->sc_iot, sc->sc_ioh, EP_W4_CTRLR_STATUS) &
899 EF_MII_DATA;
900
901
902 for (i = 0x8000; i; i >>= 1) {
903 MII_CLR(sc, EF_MII_CLK);
904 DELAY(1);
905 if (bus_space_read_2(sc->sc_iot, sc->sc_ioh,
906 EP_W4_CTRLR_STATUS) & EF_MII_DATA)
907 val |= i;
908 MII_SET(sc, EF_MII_CLK);
909 DELAY(1);
910 }
911
912 MII_CLR(sc, EF_MII_CLK);
913 DELAY(1);
914 MII_SET(sc, EF_MII_CLK);
915 DELAY(1);
916
917 splx(s);
918
919 return (val);
920 }
921
922 void
923 ef_miibus_writereg(dev, phy, reg, val)
924 struct device *dev;
925 int phy, reg, val;
926 {
927 struct ef_softc *sc = (struct ef_softc *)dev;
928 int s, i;
929
930 s = splnet();
931
932 GO_WINDOW(4);
933 bus_space_write_2(sc->sc_iot, sc->sc_ioh, EP_W4_CTRLR_STATUS, 0);
934
935
936 MII_SET(sc, EF_MII_DIR);
937
938 ef_mii_sync(sc);
939
940 ef_mii_writeb(sc, 0);
941 ef_mii_writeb(sc, 1);
942 ef_mii_writeb(sc, 0);
943 ef_mii_writeb(sc, 1);
944
945 for (i = 0x10; i; i >>= 1)
946 ef_mii_writeb(sc, (phy & i) ? 1 : 0);
947
948 for (i = 0x10; i; i >>= 1)
949 ef_mii_writeb(sc, (reg & i) ? 1 : 0);
950
951 ef_mii_writeb(sc, 1);
952 ef_mii_writeb(sc, 0);
953
954 for (i = 0x8000; i; i >>= 1)
955 ef_mii_writeb(sc, (val & i) ? 1 : 0);
956
957 splx(s);
958 }
959
960 int
961 ef_ifmedia_upd(ifp)
962 struct ifnet *ifp;
963 {
964 struct ef_softc *sc = ifp->if_softc;
965
966 mii_mediachg(&sc->sc_mii);
967 return (0);
968 }
969
970 void
971 ef_ifmedia_sts(ifp, ifmr)
972 struct ifnet *ifp;
973 struct ifmediareq *ifmr;
974 {
975 struct ef_softc *sc = ifp->if_softc;
976
977 mii_pollstat(&sc->sc_mii);
978 ifmr->ifm_status = sc->sc_mii.mii_media_status;
979 ifmr->ifm_active = sc->sc_mii.mii_media_active;
980 }
981
982 void
983 ef_miibus_statchg(self)
984 struct device *self;
985 {
986 struct ef_softc *sc = (struct ef_softc *)self;
987 int s;
988
989 s = splnet();
990 GO_WINDOW(3);
991
992 if ((sc->sc_mii.mii_media_active & IFM_GMASK) == IFM_FDX)
993 bus_space_write_1(sc->sc_iot, sc->sc_ioh,
994 EP_W3_MAC_CONTROL, 0x20);
995 else
996 bus_space_write_1(sc->sc_iot, sc->sc_ioh,
997 EP_W3_MAC_CONTROL, 0x00);
998 GO_WINDOW(7);
999 splx(s);
1000 }
1001
1002 void
1003 ef_tick(v)
1004 void *v;
1005 {
1006 struct ef_softc *sc = v;
1007 int s;
1008
1009 s = splnet();
1010 mii_tick(&sc->sc_mii);
1011 splx(s);
1012 timeout_add(&sc->sc_tick_tmo, hz);
1013 }