This source file includes following definitions.
- fxp_lwcopy
- fxp_scb_wait
- fxp_eeprom_shiftin
- fxp_eeprom_putword
- fxp_write_eeprom
- fxp_shutdown
- fxp_power
- fxp_attach
- fxp_autosize_eeprom
- fxp_read_eeprom
- fxp_start
- fxp_intr
- fxp_stats_update
- fxp_stop
- fxp_watchdog
- fxp_scb_cmd
- fxp_init
- fxp_mediachange
- fxp_mediastatus
- fxp_add_rfabuf
- fxp_mdi_read
- fxp_statchg
- fxp_mdi_write
- fxp_ioctl
- fxp_mc_setup
- fxp_load_ucode
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 #include "bpfilter.h"
41
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/mbuf.h>
45 #include <sys/malloc.h>
46 #include <sys/kernel.h>
47 #include <sys/socket.h>
48 #include <sys/syslog.h>
49 #include <sys/timeout.h>
50
51 #include <net/if.h>
52 #include <net/if_dl.h>
53 #include <net/if_media.h>
54 #include <net/if_types.h>
55
56 #ifdef INET
57 #include <netinet/in.h>
58 #include <netinet/in_systm.h>
59 #include <netinet/in_var.h>
60 #include <netinet/ip.h>
61 #endif
62
63 #if NBPFILTER > 0
64 #include <net/bpf.h>
65 #endif
66
67 #include <sys/ioctl.h>
68 #include <sys/errno.h>
69 #include <sys/device.h>
70
71 #include <netinet/if_ether.h>
72
73 #include <machine/cpu.h>
74 #include <machine/bus.h>
75 #include <machine/intr.h>
76
77 #include <dev/mii/miivar.h>
78
79 #include <dev/ic/fxpreg.h>
80 #include <dev/ic/fxpvar.h>
81
82
83
84
85
86
87
88
89
90
91 #define RFA_ALIGNMENT_FUDGE (2 + sizeof(bus_dmamap_t *))
92
93
94
95
96 static __inline void fxp_lwcopy(volatile u_int32_t *,
97 volatile u_int32_t *);
98
99 static __inline void
100 fxp_lwcopy(volatile u_int32_t *src, volatile u_int32_t *dst)
101 {
102 volatile u_int16_t *a = (u_int16_t *)src;
103 volatile u_int16_t *b = (u_int16_t *)dst;
104
105 b[0] = a[0];
106 b[1] = a[1];
107 }
108
109
110
111
112
113
114 static u_char fxp_cb_config_template[] = {
115 0x0, 0x0,
116 0x0, 0x0,
117 0xff, 0xff, 0xff, 0xff,
118 0x16,
119 0x08,
120 0x00,
121 0x00,
122 0x00,
123 0x80,
124 0xb2,
125 0x03,
126 0x01,
127 0x00,
128 0x26,
129 0x00,
130 0x60,
131 0x00,
132 0xf2,
133 0x48,
134 0x00,
135 0x40,
136 0xf3,
137 0x00,
138 0x3f,
139 0x05
140 };
141
142 void fxp_eeprom_shiftin(struct fxp_softc *, int, int);
143 void fxp_eeprom_putword(struct fxp_softc *, int, u_int16_t);
144 void fxp_write_eeprom(struct fxp_softc *, u_short *, int, int);
145 int fxp_mediachange(struct ifnet *);
146 void fxp_mediastatus(struct ifnet *, struct ifmediareq *);
147 void fxp_scb_wait(struct fxp_softc *);
148 void fxp_start(struct ifnet *);
149 int fxp_ioctl(struct ifnet *, u_long, caddr_t);
150 void fxp_init(void *);
151 void fxp_load_ucode(struct fxp_softc *);
152 void fxp_stop(struct fxp_softc *, int);
153 void fxp_watchdog(struct ifnet *);
154 int fxp_add_rfabuf(struct fxp_softc *, struct mbuf *);
155 int fxp_mdi_read(struct device *, int, int);
156 void fxp_mdi_write(struct device *, int, int, int);
157 void fxp_autosize_eeprom(struct fxp_softc *);
158 void fxp_statchg(struct device *);
159 void fxp_read_eeprom(struct fxp_softc *, u_int16_t *,
160 int, int);
161 void fxp_stats_update(void *);
162 void fxp_mc_setup(struct fxp_softc *, int);
163 void fxp_scb_cmd(struct fxp_softc *, u_int8_t);
164
165
166
167
168
169
170 static int tx_threshold = 64;
171
172
173
174
175 int fxp_int_delay = FXP_INT_DELAY;
176 int fxp_bundle_max = FXP_BUNDLE_MAX;
177 int fxp_min_size_mask = FXP_MIN_SIZE_MASK;
178
179
180
181
182 #define FXP_TXCB_MASK (FXP_NTXCB - 1)
183
184
185
186
187
188
189
190 #define FXP_MAX_RX_IDLE 15
191
192
193
194
195
196 void
197 fxp_scb_wait(struct fxp_softc *sc)
198 {
199 int i = 10000;
200
201 while (CSR_READ_1(sc, FXP_CSR_SCB_COMMAND) && --i)
202 DELAY(2);
203 if (i == 0)
204 printf("%s: warning: SCB timed out\n", sc->sc_dev.dv_xname);
205 }
206
207 void
208 fxp_eeprom_shiftin(struct fxp_softc *sc, int data, int length)
209 {
210 u_int16_t reg;
211 int x;
212
213
214
215
216 for (x = 1 << (length - 1); x; x >>= 1) {
217 if (data & x)
218 reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI;
219 else
220 reg = FXP_EEPROM_EECS;
221 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
222 DELAY(1);
223 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg | FXP_EEPROM_EESK);
224 DELAY(1);
225 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
226 DELAY(1);
227 }
228 }
229
230 void
231 fxp_eeprom_putword(struct fxp_softc *sc, int offset, u_int16_t data)
232 {
233 int i;
234
235
236
237
238 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
239 fxp_eeprom_shiftin(sc, 0x4, 3);
240 fxp_eeprom_shiftin(sc, 0x03 << (sc->eeprom_size - 2), sc->eeprom_size);
241 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
242 DELAY(1);
243
244
245
246 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
247 fxp_eeprom_shiftin(sc, FXP_EEPROM_OPC_WRITE, 3);
248 fxp_eeprom_shiftin(sc, offset, sc->eeprom_size);
249 fxp_eeprom_shiftin(sc, data, 16);
250 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
251 DELAY(1);
252
253
254
255 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
256 DELAY(1);
257 for (i = 0; i < 1000; i++) {
258 if (CSR_READ_2(sc, FXP_CSR_EEPROMCONTROL) & FXP_EEPROM_EEDO)
259 break;
260 DELAY(50);
261 }
262 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
263 DELAY(1);
264
265
266
267 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
268 fxp_eeprom_shiftin(sc, 0x4, 3);
269 fxp_eeprom_shiftin(sc, 0, sc->eeprom_size);
270 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
271 DELAY(1);
272 }
273
274 void
275 fxp_write_eeprom(struct fxp_softc *sc, u_short *data, int offset, int words)
276 {
277 int i;
278
279 for (i = 0; i < words; i++)
280 fxp_eeprom_putword(sc, offset + i, data[i]);
281 }
282
283
284
285
286
287 void fxp_shutdown(void *);
288 void fxp_power(int, void *);
289
290 struct cfdriver fxp_cd = {
291 NULL, "fxp", DV_IFNET
292 };
293
294
295
296
297
298
299 void
300 fxp_shutdown(void *sc)
301 {
302 fxp_stop((struct fxp_softc *) sc, 0);
303 }
304
305
306
307
308
309
310
311 void
312 fxp_power(int why, void *arg)
313 {
314 struct fxp_softc *sc = arg;
315 struct ifnet *ifp;
316 int s;
317
318 s = splnet();
319 if (why != PWR_RESUME)
320 fxp_stop(sc, 0);
321 else {
322 ifp = &sc->sc_arpcom.ac_if;
323 if (ifp->if_flags & IFF_UP)
324 fxp_init(sc);
325 }
326 splx(s);
327 }
328
329
330
331
332
333
334
335
336 int
337 fxp_attach(struct fxp_softc *sc, const char *intrstr)
338 {
339 struct ifnet *ifp;
340 struct mbuf *m;
341 bus_dmamap_t rxmap;
342 u_int16_t data;
343 u_int8_t enaddr[6];
344 int i, err;
345
346
347
348
349 CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SOFTWARE_RESET);
350 DELAY(10);
351
352 if (bus_dmamem_alloc(sc->sc_dmat, sizeof(struct fxp_ctrl),
353 PAGE_SIZE, 0, &sc->sc_cb_seg, 1, &sc->sc_cb_nseg, BUS_DMA_NOWAIT))
354 goto fail;
355 if (bus_dmamem_map(sc->sc_dmat, &sc->sc_cb_seg, sc->sc_cb_nseg,
356 sizeof(struct fxp_ctrl), (caddr_t *)&sc->sc_ctrl,
357 BUS_DMA_NOWAIT)) {
358 bus_dmamem_free(sc->sc_dmat, &sc->sc_cb_seg, sc->sc_cb_nseg);
359 goto fail;
360 }
361 if (bus_dmamap_create(sc->sc_dmat, sizeof(struct fxp_ctrl),
362 1, sizeof(struct fxp_ctrl), 0, BUS_DMA_NOWAIT,
363 &sc->tx_cb_map)) {
364 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_ctrl,
365 sizeof(struct fxp_ctrl));
366 bus_dmamem_free(sc->sc_dmat, &sc->sc_cb_seg, sc->sc_cb_nseg);
367 goto fail;
368 }
369 if (bus_dmamap_load(sc->sc_dmat, sc->tx_cb_map, (caddr_t)sc->sc_ctrl,
370 sizeof(struct fxp_ctrl), NULL, BUS_DMA_NOWAIT)) {
371 bus_dmamap_destroy(sc->sc_dmat, sc->tx_cb_map);
372 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_ctrl,
373 sizeof(struct fxp_ctrl));
374 bus_dmamem_free(sc->sc_dmat, &sc->sc_cb_seg, sc->sc_cb_nseg);
375 goto fail;
376 }
377
378 for (i = 0; i < FXP_NTXCB; i++) {
379 if ((err = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
380 FXP_NTXSEG, MCLBYTES, 0, 0, &sc->txs[i].tx_map)) != 0) {
381 printf("%s: unable to create tx dma map %d, error %d\n",
382 sc->sc_dev.dv_xname, i, err);
383 goto fail;
384 }
385 sc->txs[i].tx_mbuf = NULL;
386 sc->txs[i].tx_cb = sc->sc_ctrl->tx_cb + i;
387 sc->txs[i].tx_off = offsetof(struct fxp_ctrl, tx_cb[i]);
388 sc->txs[i].tx_next = &sc->txs[(i + 1) & FXP_TXCB_MASK];
389 }
390 bzero(sc->sc_ctrl, sizeof(struct fxp_ctrl));
391
392
393
394
395 sc->sc_rxfree = 0;
396 for (i = 0; i < FXP_NRFABUFS_MIN; i++) {
397 if ((err = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
398 MCLBYTES, 0, 0, &sc->sc_rxmaps[i])) != 0) {
399 printf("%s: unable to create rx dma map %d, error %d\n",
400 sc->sc_dev.dv_xname, i, err);
401 goto fail;
402 }
403 sc->rx_bufs++;
404 }
405 for (i = 0; i < FXP_NRFABUFS_MIN; i++)
406 if (fxp_add_rfabuf(sc, NULL) != 0)
407 goto fail;
408
409
410
411
412 fxp_autosize_eeprom(sc);
413
414
415
416
417 fxp_read_eeprom(sc, (u_int16_t *)&data, 6, 1);
418 sc->phy_primary_addr = data & 0xff;
419 sc->phy_primary_device = (data >> 8) & 0x3f;
420 sc->phy_10Mbps_only = data >> 15;
421
422
423
424
425 if (sc->sc_revision >= FXP_REV_82558_A4) {
426 sc->sc_int_delay = fxp_int_delay;
427 sc->sc_bundle_max = fxp_bundle_max;
428 sc->sc_min_size_mask = fxp_min_size_mask;
429 }
430
431
432
433 fxp_read_eeprom(sc, (u_int16_t *)enaddr, 0, 3);
434
435 ifp = &sc->sc_arpcom.ac_if;
436 bcopy(enaddr, sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN);
437 bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
438 ifp->if_softc = sc;
439 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
440 ifp->if_ioctl = fxp_ioctl;
441 ifp->if_start = fxp_start;
442 ifp->if_watchdog = fxp_watchdog;
443 IFQ_SET_MAXLEN(&ifp->if_snd, FXP_NTXCB - 1);
444 IFQ_SET_READY(&ifp->if_snd);
445
446 ifp->if_capabilities = IFCAP_VLAN_MTU;
447
448 printf(": %s, address %s\n", intrstr,
449 ether_sprintf(sc->sc_arpcom.ac_enaddr));
450
451 if (sc->sc_flags & FXPF_DISABLE_STANDBY) {
452 fxp_read_eeprom(sc, &data, 10, 1);
453 if (data & 0x02) {
454 u_int16_t cksum;
455 int i;
456
457 printf("%s: Disabling dynamic standby mode in EEPROM",
458 sc->sc_dev.dv_xname);
459 data &= ~0x02;
460 fxp_write_eeprom(sc, &data, 10, 1);
461 printf(", New ID 0x%x", data);
462 cksum = 0;
463 for (i = 0; i < (1 << sc->eeprom_size) - 1; i++) {
464 fxp_read_eeprom(sc, &data, i, 1);
465 cksum += data;
466 }
467 i = (1 << sc->eeprom_size) - 1;
468 cksum = 0xBABA - cksum;
469 fxp_read_eeprom(sc, &data, i, 1);
470 fxp_write_eeprom(sc, &cksum, i, 1);
471 printf(", cksum @ 0x%x: 0x%x -> 0x%x\n",
472 i, data, cksum);
473 }
474 }
475
476
477 fxp_read_eeprom(sc, &data, 3, 1);
478 if ((data & 0x03) != 0x03)
479 sc->sc_flags |= FXPF_RECV_WORKAROUND;
480
481
482
483
484 sc->sc_mii.mii_ifp = ifp;
485 sc->sc_mii.mii_readreg = fxp_mdi_read;
486 sc->sc_mii.mii_writereg = fxp_mdi_write;
487 sc->sc_mii.mii_statchg = fxp_statchg;
488 ifmedia_init(&sc->sc_mii.mii_media, 0, fxp_mediachange,
489 fxp_mediastatus);
490 mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
491 MII_OFFSET_ANY, MIIF_NOISOLATE);
492
493 if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
494 ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_MANUAL,
495 0, NULL);
496 printf("%s: no phy found, using manual mode\n",
497 sc->sc_dev.dv_xname);
498 }
499
500 if (ifmedia_match(&sc->sc_mii.mii_media, IFM_ETHER|IFM_MANUAL, 0))
501 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_MANUAL);
502 else if (ifmedia_match(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO, 0))
503 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
504 else
505 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_10_T);
506
507
508
509
510 if_attach(ifp);
511 ether_ifattach(ifp);
512
513
514
515
516
517
518 sc->sc_sdhook = shutdownhook_establish(fxp_shutdown, sc);
519
520
521
522
523 sc->sc_powerhook = powerhook_establish(fxp_power, sc);
524
525
526
527
528 timeout_set(&sc->stats_update_to, fxp_stats_update, sc);
529
530 return (0);
531
532 fail:
533 printf("%s: Failed to malloc memory\n", sc->sc_dev.dv_xname);
534 if (sc->tx_cb_map != NULL) {
535 bus_dmamap_unload(sc->sc_dmat, sc->tx_cb_map);
536 bus_dmamap_destroy(sc->sc_dmat, sc->tx_cb_map);
537 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_ctrl,
538 sizeof(struct fxp_cb_tx) * FXP_NTXCB);
539 bus_dmamem_free(sc->sc_dmat, &sc->sc_cb_seg, sc->sc_cb_nseg);
540 }
541 m = sc->rfa_headm;
542 while (m != NULL) {
543 rxmap = *((bus_dmamap_t *)m->m_ext.ext_buf);
544 bus_dmamap_unload(sc->sc_dmat, rxmap);
545 FXP_RXMAP_PUT(sc, rxmap);
546 m = m_free(m);
547 }
548 return (ENOMEM);
549 }
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579 void
580 fxp_autosize_eeprom(struct fxp_softc *sc)
581 {
582 u_int16_t reg;
583 int x;
584
585 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
586
587
588
589 for (x = 3; x > 0; x--) {
590 if (FXP_EEPROM_OPC_READ & (1 << (x - 1))) {
591 reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI;
592 } else {
593 reg = FXP_EEPROM_EECS;
594 }
595 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
596 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL,
597 reg | FXP_EEPROM_EESK);
598 DELAY(4);
599 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
600 DELAY(4);
601 }
602
603
604
605
606 for (x = 1; x <= 8; x++) {
607 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
608 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL,
609 FXP_EEPROM_EECS | FXP_EEPROM_EESK);
610 DELAY(4);
611 if ((CSR_READ_2(sc, FXP_CSR_EEPROMCONTROL) & FXP_EEPROM_EEDO) == 0)
612 break;
613 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
614 DELAY(4);
615 }
616 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
617 DELAY(4);
618 sc->eeprom_size = x;
619 }
620
621
622
623
624
625
626
627
628 void
629 fxp_read_eeprom(struct fxp_softc *sc, u_short *data, int offset,
630 int words)
631 {
632 u_int16_t reg;
633 int i, x;
634
635 for (i = 0; i < words; i++) {
636 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
637
638
639
640 for (x = 3; x > 0; x--) {
641 if (FXP_EEPROM_OPC_READ & (1 << (x - 1))) {
642 reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI;
643 } else {
644 reg = FXP_EEPROM_EECS;
645 }
646 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
647 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL,
648 reg | FXP_EEPROM_EESK);
649 DELAY(4);
650 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
651 DELAY(4);
652 }
653
654
655
656 for (x = sc->eeprom_size; x > 0; x--) {
657 if ((i + offset) & (1 << (x - 1))) {
658 reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI;
659 } else {
660 reg = FXP_EEPROM_EECS;
661 }
662 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
663 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL,
664 reg | FXP_EEPROM_EESK);
665 DELAY(4);
666 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
667 DELAY(4);
668 }
669 reg = FXP_EEPROM_EECS;
670 data[i] = 0;
671
672
673
674 for (x = 16; x > 0; x--) {
675 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL,
676 reg | FXP_EEPROM_EESK);
677 DELAY(4);
678 if (CSR_READ_2(sc, FXP_CSR_EEPROMCONTROL) &
679 FXP_EEPROM_EEDO)
680 data[i] |= (1 << (x - 1));
681 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
682 DELAY(4);
683 }
684 data[i] = letoh16(data[i]);
685 CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
686 DELAY(4);
687 }
688 }
689
690
691
692
693 void
694 fxp_start(struct ifnet *ifp)
695 {
696 struct fxp_softc *sc = ifp->if_softc;
697 struct fxp_txsw *txs = sc->sc_cbt_prod;
698 struct fxp_cb_tx *txc;
699 struct mbuf *m0, *m = NULL;
700 int cnt = sc->sc_cbt_cnt, seg;
701
702 if ((ifp->if_flags & (IFF_OACTIVE | IFF_RUNNING)) != IFF_RUNNING)
703 return;
704
705 while (1) {
706 if (cnt >= (FXP_NTXCB - 2)) {
707 ifp->if_flags |= IFF_OACTIVE;
708 break;
709 }
710
711 txs = txs->tx_next;
712
713 IFQ_POLL(&ifp->if_snd, m0);
714 if (m0 == NULL)
715 break;
716
717 if (bus_dmamap_load_mbuf(sc->sc_dmat, txs->tx_map,
718 m0, BUS_DMA_NOWAIT) != 0) {
719 MGETHDR(m, M_DONTWAIT, MT_DATA);
720 if (m == NULL)
721 break;
722 if (m0->m_pkthdr.len > MHLEN) {
723 MCLGET(m, M_DONTWAIT);
724 if (!(m->m_flags & M_EXT)) {
725 m_freem(m);
726 break;
727 }
728 }
729 m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, caddr_t));
730 m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len;
731 if (bus_dmamap_load_mbuf(sc->sc_dmat, txs->tx_map,
732 m, BUS_DMA_NOWAIT) != 0) {
733 m_freem(m);
734 break;
735 }
736 }
737
738 IFQ_DEQUEUE(&ifp->if_snd, m0);
739 if (m != NULL) {
740 m_freem(m0);
741 m0 = m;
742 m = NULL;
743 }
744
745 txs->tx_mbuf = m0;
746
747 #if NBPFILTER > 0
748 if (ifp->if_bpf)
749 bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
750 #endif
751
752 FXP_MBUF_SYNC(sc, txs->tx_map, BUS_DMASYNC_PREWRITE);
753
754 txc = txs->tx_cb;
755 txc->tbd_number = txs->tx_map->dm_nsegs;
756 txc->cb_status = 0;
757 txc->cb_command = htole16(FXP_CB_COMMAND_XMIT | FXP_CB_COMMAND_SF);
758 txc->tx_threshold = tx_threshold;
759 for (seg = 0; seg < txs->tx_map->dm_nsegs; seg++) {
760 txc->tbd[seg].tb_addr =
761 htole32(txs->tx_map->dm_segs[seg].ds_addr);
762 txc->tbd[seg].tb_size =
763 htole32(txs->tx_map->dm_segs[seg].ds_len);
764 }
765 FXP_TXCB_SYNC(sc, txs,
766 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
767
768 ++cnt;
769 sc->sc_cbt_prod = txs;
770 }
771
772 if (cnt != sc->sc_cbt_cnt) {
773
774 ifp->if_timer = 5;
775
776 txs = sc->sc_cbt_prod;
777 txs = txs->tx_next;
778 sc->sc_cbt_prod = txs;
779 txs->tx_cb->cb_command =
780 htole16(FXP_CB_COMMAND_I | FXP_CB_COMMAND_NOP | FXP_CB_COMMAND_S);
781 FXP_TXCB_SYNC(sc, txs,
782 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
783
784 FXP_TXCB_SYNC(sc, sc->sc_cbt_prev,
785 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
786 sc->sc_cbt_prev->tx_cb->cb_command &=
787 htole16(~(FXP_CB_COMMAND_S | FXP_CB_COMMAND_I));
788 FXP_TXCB_SYNC(sc, sc->sc_cbt_prev,
789 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
790
791 sc->sc_cbt_prev = txs;
792
793 fxp_scb_wait(sc);
794 fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_RESUME);
795
796 sc->sc_cbt_cnt = cnt + 1;
797 }
798 }
799
800
801
802
803 int
804 fxp_intr(void *arg)
805 {
806 struct fxp_softc *sc = arg;
807 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
808 u_int8_t statack;
809 bus_dmamap_t rxmap;
810 int claimed = 0;
811 int rnr = 0;
812
813
814
815
816
817 if ((ifp->if_flags & IFF_RUNNING) == 0) {
818 statack = CSR_READ_1(sc, FXP_CSR_SCB_STATACK);
819 if (statack) {
820 claimed = 1;
821 CSR_WRITE_1(sc, FXP_CSR_SCB_STATACK, statack);
822 }
823 return claimed;
824 }
825
826 while ((statack = CSR_READ_1(sc, FXP_CSR_SCB_STATACK)) != 0) {
827 claimed = 1;
828 rnr = (statack & (FXP_SCB_STATACK_RNR |
829 FXP_SCB_STATACK_SWI)) ? 1 : 0;
830
831
832
833 CSR_WRITE_1(sc, FXP_CSR_SCB_STATACK, statack);
834
835
836
837
838 if (statack & (FXP_SCB_STATACK_CXTNO|FXP_SCB_STATACK_CNA)) {
839 int txcnt = sc->sc_cbt_cnt;
840 struct fxp_txsw *txs = sc->sc_cbt_cons;
841
842 FXP_TXCB_SYNC(sc, txs,
843 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
844
845 while ((txcnt > 0) &&
846 ((txs->tx_cb->cb_status & htole16(FXP_CB_STATUS_C)) ||
847 (txs->tx_cb->cb_command & htole16(FXP_CB_COMMAND_NOP)))) {
848 if (txs->tx_mbuf != NULL) {
849 FXP_MBUF_SYNC(sc, txs->tx_map,
850 BUS_DMASYNC_POSTWRITE);
851 bus_dmamap_unload(sc->sc_dmat,
852 txs->tx_map);
853 m_freem(txs->tx_mbuf);
854 txs->tx_mbuf = NULL;
855 }
856 --txcnt;
857 txs = txs->tx_next;
858 FXP_TXCB_SYNC(sc, txs,
859 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
860 }
861 sc->sc_cbt_cons = txs;
862 sc->sc_cbt_cnt = txcnt;
863 ifp->if_timer = 0;
864 ifp->if_flags &= ~IFF_OACTIVE;
865
866 if (!IFQ_IS_EMPTY(&ifp->if_snd)) {
867
868
869
870 fxp_start(ifp);
871 }
872 }
873
874
875
876
877
878 if (statack & (FXP_SCB_STATACK_FR | FXP_SCB_STATACK_RNR |
879 FXP_SCB_STATACK_SWI)) {
880 struct mbuf *m;
881 u_int8_t *rfap;
882 rcvloop:
883 m = sc->rfa_headm;
884 rfap = m->m_ext.ext_buf + RFA_ALIGNMENT_FUDGE;
885 rxmap = *((bus_dmamap_t *)m->m_ext.ext_buf);
886 bus_dmamap_sync(sc->sc_dmat, rxmap,
887 0, MCLBYTES, BUS_DMASYNC_POSTREAD |
888 BUS_DMASYNC_POSTWRITE);
889
890 if (*(u_int16_t *)(rfap +
891 offsetof(struct fxp_rfa, rfa_status)) &
892 htole16(FXP_RFA_STATUS_C)) {
893 if (*(u_int16_t *)(rfap +
894 offsetof(struct fxp_rfa, rfa_status)) &
895 htole16(FXP_RFA_STATUS_RNR))
896 rnr = 1;
897
898
899
900
901 sc->rfa_headm = m->m_next;
902 m->m_next = NULL;
903
904
905
906
907
908
909 if (fxp_add_rfabuf(sc, m) == 0) {
910 u_int16_t total_len;
911
912 total_len = htole16(*(u_int16_t *)(rfap +
913 offsetof(struct fxp_rfa,
914 actual_size))) &
915 (MCLBYTES - 1);
916 if (total_len <
917 sizeof(struct ether_header)) {
918 m_freem(m);
919 goto rcvloop;
920 }
921 if (*(u_int16_t *)(rfap +
922 offsetof(struct fxp_rfa,
923 rfa_status)) &
924 htole16(FXP_RFA_STATUS_CRC)) {
925 m_freem(m);
926 goto rcvloop;
927 }
928
929 m->m_pkthdr.rcvif = ifp;
930 m->m_pkthdr.len = m->m_len =
931 total_len;
932 #if NBPFILTER > 0
933 if (ifp->if_bpf)
934 bpf_mtap(ifp->if_bpf, m,
935 BPF_DIRECTION_IN);
936 #endif
937 ether_input_mbuf(ifp, m);
938 }
939 goto rcvloop;
940 }
941 }
942 if (rnr) {
943 rxmap = *((bus_dmamap_t *)
944 sc->rfa_headm->m_ext.ext_buf);
945 fxp_scb_wait(sc);
946 CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL,
947 rxmap->dm_segs[0].ds_addr +
948 RFA_ALIGNMENT_FUDGE);
949 fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_START);
950
951 }
952 }
953 return (claimed);
954 }
955
956
957
958
959
960
961
962
963
964
965
966
967 void
968 fxp_stats_update(void *arg)
969 {
970 struct fxp_softc *sc = arg;
971 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
972 struct fxp_stats *sp = &sc->sc_ctrl->stats;
973 int s;
974
975 FXP_STATS_SYNC(sc, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
976 ifp->if_opackets += letoh32(sp->tx_good);
977 ifp->if_collisions += letoh32(sp->tx_total_collisions);
978 if (sp->rx_good) {
979 ifp->if_ipackets += letoh32(sp->rx_good);
980 sc->rx_idle_secs = 0;
981 } else if (sc->sc_flags & FXPF_RECV_WORKAROUND)
982 sc->rx_idle_secs++;
983 ifp->if_ierrors +=
984 letoh32(sp->rx_crc_errors) +
985 letoh32(sp->rx_alignment_errors) +
986 letoh32(sp->rx_rnr_errors) +
987 letoh32(sp->rx_overrun_errors);
988
989
990
991
992 if (sp->tx_underruns) {
993 ifp->if_oerrors += letoh32(sp->tx_underruns);
994 if (tx_threshold < 192)
995 tx_threshold += 64;
996 }
997 s = splnet();
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008 if (sc->rx_idle_secs > FXP_MAX_RX_IDLE) {
1009 sc->rx_idle_secs = 0;
1010 fxp_init(sc);
1011 splx(s);
1012 return;
1013 }
1014
1015
1016
1017
1018 FXP_STATS_SYNC(sc, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1019 if (CSR_READ_1(sc, FXP_CSR_SCB_COMMAND) == 0) {
1020
1021
1022
1023 fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_DUMPRESET);
1024 } else {
1025
1026
1027
1028
1029
1030 sp->tx_good = 0;
1031 sp->tx_underruns = 0;
1032 sp->tx_total_collisions = 0;
1033
1034 sp->rx_good = 0;
1035 sp->rx_crc_errors = 0;
1036 sp->rx_alignment_errors = 0;
1037 sp->rx_rnr_errors = 0;
1038 sp->rx_overrun_errors = 0;
1039 }
1040
1041
1042 mii_tick(&sc->sc_mii);
1043
1044 splx(s);
1045
1046
1047
1048 timeout_add(&sc->stats_update_to, hz);
1049 }
1050
1051
1052
1053
1054
1055 void
1056 fxp_stop(struct fxp_softc *sc, int drain)
1057 {
1058 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1059 int i;
1060
1061
1062
1063
1064
1065 ifp->if_timer = 0;
1066 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1067
1068
1069
1070
1071 timeout_del(&sc->stats_update_to);
1072 mii_down(&sc->sc_mii);
1073
1074
1075
1076
1077 CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SELECTIVE_RESET);
1078 DELAY(10);
1079
1080
1081
1082
1083 for (i = 0; i < FXP_NTXCB; i++) {
1084 if (sc->txs[i].tx_mbuf != NULL) {
1085 bus_dmamap_unload(sc->sc_dmat, sc->txs[i].tx_map);
1086 m_freem(sc->txs[i].tx_mbuf);
1087 sc->txs[i].tx_mbuf = NULL;
1088 }
1089 }
1090 sc->sc_cbt_cnt = 0;
1091
1092 if (drain) {
1093 bus_dmamap_t rxmap;
1094 struct mbuf *m;
1095
1096
1097
1098
1099 m = sc->rfa_headm;
1100 while (m != NULL) {
1101 rxmap = *((bus_dmamap_t *)m->m_ext.ext_buf);
1102 bus_dmamap_unload(sc->sc_dmat, rxmap);
1103 FXP_RXMAP_PUT(sc, rxmap);
1104 m = m_free(m);
1105 sc->rx_bufs--;
1106 }
1107 sc->rfa_headm = NULL;
1108 sc->rfa_tailm = NULL;
1109 for (i = 0; i < FXP_NRFABUFS_MIN; i++) {
1110 if (fxp_add_rfabuf(sc, NULL) != 0) {
1111
1112
1113
1114
1115
1116 panic("fxp_stop: no buffers!");
1117 }
1118 sc->rx_bufs++;
1119 }
1120 }
1121 }
1122
1123
1124
1125
1126
1127
1128
1129 void
1130 fxp_watchdog(struct ifnet *ifp)
1131 {
1132 struct fxp_softc *sc = ifp->if_softc;
1133
1134 log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
1135 ifp->if_oerrors++;
1136
1137 fxp_init(sc);
1138 }
1139
1140
1141
1142
1143 void
1144 fxp_scb_cmd(struct fxp_softc *sc, u_int8_t cmd)
1145 {
1146 CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, cmd);
1147 }
1148
1149 void
1150 fxp_init(void *xsc)
1151 {
1152 struct fxp_softc *sc = xsc;
1153 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1154 struct fxp_cb_config *cbp;
1155 struct fxp_cb_ias *cb_ias;
1156 struct fxp_cb_tx *txp;
1157 bus_dmamap_t rxmap;
1158 int i, prm, save_bf, lrxen, allm, s, bufs;
1159
1160 s = splnet();
1161
1162
1163
1164
1165 fxp_stop(sc, 0);
1166
1167
1168
1169
1170
1171 fxp_scb_wait(sc);
1172 CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, 0);
1173 fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_BASE);
1174
1175 fxp_scb_wait(sc);
1176 CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, 0);
1177 fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_BASE);
1178
1179 #ifndef SMALL_KERNEL
1180 fxp_load_ucode(sc);
1181 #endif
1182
1183 fxp_mc_setup(sc, 0);
1184
1185
1186
1187
1188
1189
1190
1191 save_bf = 0;
1192 lrxen = 0;
1193
1194 if (sc->sc_revision >= FXP_REV_82558_A4)
1195 lrxen = 1;
1196 else
1197 save_bf = 1;
1198
1199
1200
1201
1202 fxp_scb_wait(sc);
1203 CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL,
1204 sc->tx_cb_map->dm_segs->ds_addr +
1205 offsetof(struct fxp_ctrl, stats));
1206 fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_DUMP_ADR);
1207
1208 cbp = &sc->sc_ctrl->u.cfg;
1209
1210
1211
1212
1213
1214 bcopy(fxp_cb_config_template, (void *)&cbp->cb_status,
1215 sizeof(fxp_cb_config_template));
1216
1217 prm = (ifp->if_flags & IFF_PROMISC) ? 1 : 0;
1218 allm = (ifp->if_flags & IFF_ALLMULTI) ? 1 : 0;
1219
1220 #if 0
1221 cbp->cb_status = 0;
1222 cbp->cb_command = FXP_CB_COMMAND_CONFIG | FXP_CB_COMMAND_EL;
1223 cbp->link_addr = 0xffffffff;
1224 cbp->byte_count = 22;
1225 cbp->rx_fifo_limit = 8;
1226 cbp->tx_fifo_limit = 0;
1227 cbp->adaptive_ifs = 0;
1228 cbp->rx_dma_bytecount = 0;
1229 cbp->tx_dma_bytecount = 0;
1230 cbp->dma_bce = 0;
1231 cbp->late_scb = 0;
1232 cbp->tno_int = 0;
1233 cbp->ci_int = 1;
1234 cbp->save_bf = save_bf ? 1 : prm;
1235 cbp->disc_short_rx = !prm;
1236 cbp->underrun_retry = 1;
1237 cbp->mediatype = !sc->phy_10Mbps_only;
1238 cbp->nsai = 1;
1239 cbp->preamble_length = 2;
1240 cbp->loopback = 0;
1241 cbp->linear_priority = 0;
1242 cbp->linear_pri_mode = 0;
1243 cbp->interfrm_spacing = 6;
1244 cbp->promiscuous = prm;
1245 cbp->bcast_disable = 0;
1246 cbp->crscdt = 0;
1247 cbp->stripping = !prm;
1248 cbp->padding = 1;
1249 cbp->rcv_crc_xfer = 0;
1250 cbp->long_rx = lrxen;
1251 cbp->force_fdx = 0;
1252 cbp->fdx_pin_en = 1;
1253 cbp->multi_ia = 0;
1254 cbp->mc_all = allm;
1255 #else
1256 cbp->cb_command = htole16(FXP_CB_COMMAND_CONFIG | FXP_CB_COMMAND_EL);
1257 if (allm)
1258 cbp->mc_all |= 0x08;
1259 else
1260 cbp->mc_all &= ~0x08;
1261
1262 if (prm) {
1263 cbp->promiscuous |= 1;
1264 cbp->ctrl2 &= ~0x01;
1265 cbp->stripping &= ~0x01;
1266 } else {
1267 cbp->promiscuous &= ~1;
1268 cbp->ctrl2 |= 0x01;
1269 cbp->stripping |= 0x01;
1270 }
1271
1272 if (prm || save_bf)
1273 cbp->ctrl1 |= 0x80;
1274 else
1275 cbp->ctrl1 &= ~0x80;
1276
1277 if (sc->sc_flags & FXPF_MWI_ENABLE)
1278 cbp->ctrl0 |= 0x01;
1279
1280 if(!sc->phy_10Mbps_only)
1281 cbp->mediatype |= 0x01;
1282 else
1283 cbp->mediatype &= ~0x01;
1284
1285 if(lrxen)
1286 cbp->stripping |= 0x08;
1287 else
1288 cbp->stripping &= ~0x08;
1289
1290 cbp->tx_dma_bytecount = 0;
1291 cbp->ctrl1 |= 0x08;
1292 cbp->ctrl3 |= 0x08;
1293 cbp->fifo_limit = 0x08;
1294 cbp->fdx_pin |= 0x80;
1295 #endif
1296
1297
1298
1299
1300 fxp_scb_wait(sc);
1301 FXP_CFG_SYNC(sc, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1302 CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, sc->tx_cb_map->dm_segs->ds_addr +
1303 offsetof(struct fxp_ctrl, u.cfg));
1304 fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
1305
1306 do {
1307 DELAY(1);
1308 FXP_CFG_SYNC(sc, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1309 } while ((cbp->cb_status & htole16(FXP_CB_STATUS_C)) == 0);
1310
1311
1312
1313
1314 cb_ias = &sc->sc_ctrl->u.ias;
1315 cb_ias->cb_status = htole16(0);
1316 cb_ias->cb_command = htole16(FXP_CB_COMMAND_IAS | FXP_CB_COMMAND_EL);
1317 cb_ias->link_addr = htole32(0xffffffff);
1318 bcopy(sc->sc_arpcom.ac_enaddr, (void *)cb_ias->macaddr,
1319 sizeof(sc->sc_arpcom.ac_enaddr));
1320
1321
1322
1323
1324 fxp_scb_wait(sc);
1325 FXP_IAS_SYNC(sc, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1326 CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, sc->tx_cb_map->dm_segs->ds_addr +
1327 offsetof(struct fxp_ctrl, u.ias));
1328 fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
1329
1330 do {
1331 DELAY(1);
1332 FXP_IAS_SYNC(sc, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1333 } while (!(cb_ias->cb_status & htole16(FXP_CB_STATUS_C)));
1334
1335
1336 fxp_mc_setup(sc, 1);
1337
1338
1339
1340
1341 bzero(sc->sc_ctrl->tx_cb, sizeof(struct fxp_cb_tx) * FXP_NTXCB);
1342 txp = sc->sc_ctrl->tx_cb;
1343 for (i = 0; i < FXP_NTXCB; i++) {
1344 txp[i].cb_command = htole16(FXP_CB_COMMAND_NOP);
1345 txp[i].link_addr = htole32(sc->tx_cb_map->dm_segs->ds_addr +
1346 offsetof(struct fxp_ctrl, tx_cb[(i + 1) & FXP_TXCB_MASK]));
1347 txp[i].tbd_array_addr =htole32(sc->tx_cb_map->dm_segs->ds_addr +
1348 offsetof(struct fxp_ctrl, tx_cb[i].tbd[0]));
1349 }
1350
1351
1352
1353
1354 sc->sc_cbt_prev = sc->sc_cbt_prod = sc->sc_cbt_cons = sc->txs;
1355 sc->sc_cbt_cnt = 1;
1356 sc->sc_ctrl->tx_cb[0].cb_command = htole16(FXP_CB_COMMAND_NOP |
1357 FXP_CB_COMMAND_S | FXP_CB_COMMAND_I);
1358 bus_dmamap_sync(sc->sc_dmat, sc->tx_cb_map, 0,
1359 sc->tx_cb_map->dm_mapsize,
1360 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
1361
1362 fxp_scb_wait(sc);
1363 CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, sc->tx_cb_map->dm_segs->ds_addr +
1364 offsetof(struct fxp_ctrl, tx_cb[0]));
1365 fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
1366
1367
1368
1369
1370 if (ifp->if_flags & IFF_UP)
1371 bufs = FXP_NRFABUFS_MAX;
1372 else
1373 bufs = FXP_NRFABUFS_MIN;
1374 if (sc->rx_bufs > bufs) {
1375 while (sc->rfa_headm != NULL && sc->rx_bufs-- > bufs) {
1376 rxmap = *((bus_dmamap_t *)sc->rfa_headm->m_ext.ext_buf);
1377 bus_dmamap_unload(sc->sc_dmat, rxmap);
1378 FXP_RXMAP_PUT(sc, rxmap);
1379 sc->rfa_headm = m_free(sc->rfa_headm);
1380 }
1381 } else if (sc->rx_bufs < bufs) {
1382 int err, tmp_rx_bufs = sc->rx_bufs;
1383 for (i = sc->rx_bufs; i < bufs; i++) {
1384 if ((err = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
1385 MCLBYTES, 0, 0, &sc->sc_rxmaps[i])) != 0) {
1386 printf("%s: unable to create rx dma map %d, "
1387 "error %d\n", sc->sc_dev.dv_xname, i, err);
1388 break;
1389 }
1390 sc->rx_bufs++;
1391 }
1392 for (i = tmp_rx_bufs; i < sc->rx_bufs; i++)
1393 if (fxp_add_rfabuf(sc, NULL) != 0)
1394 break;
1395 }
1396 fxp_scb_wait(sc);
1397
1398
1399
1400
1401 mii_mediachg(&sc->sc_mii);
1402
1403 ifp->if_flags |= IFF_RUNNING;
1404 ifp->if_flags &= ~IFF_OACTIVE;
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414 CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL, FXP_SCB_INTRCNTL_REQUEST_SWI);
1415 splx(s);
1416
1417
1418
1419
1420 timeout_add(&sc->stats_update_to, hz);
1421 }
1422
1423
1424
1425
1426 int
1427 fxp_mediachange(struct ifnet *ifp)
1428 {
1429 struct fxp_softc *sc = ifp->if_softc;
1430 struct mii_data *mii = &sc->sc_mii;
1431
1432 if (mii->mii_instance) {
1433 struct mii_softc *miisc;
1434 LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
1435 mii_phy_reset(miisc);
1436 }
1437 mii_mediachg(&sc->sc_mii);
1438 return (0);
1439 }
1440
1441
1442
1443
1444 void
1445 fxp_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
1446 {
1447 struct fxp_softc *sc = ifp->if_softc;
1448
1449 mii_pollstat(&sc->sc_mii);
1450 ifmr->ifm_status = sc->sc_mii.mii_media_status;
1451 ifmr->ifm_active = sc->sc_mii.mii_media_active;
1452 }
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462 int
1463 fxp_add_rfabuf(struct fxp_softc *sc, struct mbuf *oldm)
1464 {
1465 u_int32_t v;
1466 struct mbuf *m;
1467 u_int8_t *rfap;
1468 bus_dmamap_t rxmap = NULL;
1469
1470 MGETHDR(m, M_DONTWAIT, MT_DATA);
1471 if (m != NULL) {
1472 MCLGET(m, M_DONTWAIT);
1473 if ((m->m_flags & M_EXT) == 0) {
1474 m_freem(m);
1475 if (oldm == NULL)
1476 return 1;
1477 m = oldm;
1478 m->m_data = m->m_ext.ext_buf;
1479 }
1480 if (oldm == NULL) {
1481 rxmap = FXP_RXMAP_GET(sc);
1482 *((bus_dmamap_t *)m->m_ext.ext_buf) = rxmap;
1483 bus_dmamap_load(sc->sc_dmat, rxmap,
1484 m->m_ext.ext_buf, m->m_ext.ext_size, NULL,
1485 BUS_DMA_NOWAIT);
1486 } else if (oldm == m)
1487 rxmap = *((bus_dmamap_t *)oldm->m_ext.ext_buf);
1488 else {
1489 rxmap = *((bus_dmamap_t *)oldm->m_ext.ext_buf);
1490 bus_dmamap_unload(sc->sc_dmat, rxmap);
1491 bus_dmamap_load(sc->sc_dmat, rxmap,
1492 m->m_ext.ext_buf, m->m_ext.ext_size, NULL,
1493 BUS_DMA_NOWAIT);
1494 *mtod(m, bus_dmamap_t *) = rxmap;
1495 }
1496 } else {
1497 if (oldm == NULL)
1498 return 1;
1499 m = oldm;
1500 m->m_data = m->m_ext.ext_buf;
1501 rxmap = *mtod(m, bus_dmamap_t *);
1502 }
1503
1504
1505
1506
1507
1508 m->m_data += RFA_ALIGNMENT_FUDGE;
1509
1510
1511
1512
1513
1514 rfap = m->m_data;
1515 m->m_data += sizeof(struct fxp_rfa);
1516 *(u_int16_t *)(rfap + offsetof(struct fxp_rfa, size)) =
1517 htole16(MCLBYTES - sizeof(struct fxp_rfa) - RFA_ALIGNMENT_FUDGE);
1518
1519
1520
1521
1522
1523
1524 *(u_int16_t *)(rfap + offsetof(struct fxp_rfa, rfa_status)) = 0;
1525 *(u_int16_t *)(rfap + offsetof(struct fxp_rfa, rfa_control)) =
1526 htole16(FXP_RFA_CONTROL_EL);
1527 *(u_int16_t *)(rfap + offsetof(struct fxp_rfa, actual_size)) = 0;
1528
1529 v = -1;
1530 fxp_lwcopy(&v,
1531 (u_int32_t *)(rfap + offsetof(struct fxp_rfa, link_addr)));
1532 fxp_lwcopy(&v,
1533 (u_int32_t *)(rfap + offsetof(struct fxp_rfa, rbd_addr)));
1534
1535 bus_dmamap_sync(sc->sc_dmat, rxmap, 0, MCLBYTES,
1536 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
1537
1538
1539
1540
1541
1542 if (sc->rfa_headm != NULL) {
1543 sc->rfa_tailm->m_next = m;
1544 v = htole32(rxmap->dm_segs[0].ds_addr + RFA_ALIGNMENT_FUDGE);
1545 rfap = sc->rfa_tailm->m_ext.ext_buf + RFA_ALIGNMENT_FUDGE;
1546 fxp_lwcopy(&v,
1547 (u_int32_t *)(rfap + offsetof(struct fxp_rfa, link_addr)));
1548 *(u_int16_t *)(rfap + offsetof(struct fxp_rfa, rfa_control)) &=
1549 htole16((u_int16_t)~FXP_RFA_CONTROL_EL);
1550
1551 bus_dmamap_sync(sc->sc_dmat,
1552 *((bus_dmamap_t *)sc->rfa_tailm->m_ext.ext_buf), 0,
1553 MCLBYTES, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
1554 } else
1555 sc->rfa_headm = m;
1556
1557 sc->rfa_tailm = m;
1558
1559 return (m == oldm);
1560 }
1561
1562 int
1563 fxp_mdi_read(struct device *self, int phy, int reg)
1564 {
1565 struct fxp_softc *sc = (struct fxp_softc *)self;
1566 int count = 10000;
1567 int value;
1568
1569 CSR_WRITE_4(sc, FXP_CSR_MDICONTROL,
1570 (FXP_MDI_READ << 26) | (reg << 16) | (phy << 21));
1571
1572 while (((value = CSR_READ_4(sc, FXP_CSR_MDICONTROL)) & 0x10000000) == 0
1573 && count--)
1574 DELAY(10);
1575
1576 if (count <= 0)
1577 printf("%s: fxp_mdi_read: timed out\n", sc->sc_dev.dv_xname);
1578
1579 return (value & 0xffff);
1580 }
1581
1582 void
1583 fxp_statchg(struct device *self)
1584 {
1585
1586 }
1587
1588 void
1589 fxp_mdi_write(struct device *self, int phy, int reg, int value)
1590 {
1591 struct fxp_softc *sc = (struct fxp_softc *)self;
1592 int count = 10000;
1593
1594 CSR_WRITE_4(sc, FXP_CSR_MDICONTROL,
1595 (FXP_MDI_WRITE << 26) | (reg << 16) | (phy << 21) |
1596 (value & 0xffff));
1597
1598 while((CSR_READ_4(sc, FXP_CSR_MDICONTROL) & 0x10000000) == 0 &&
1599 count--)
1600 DELAY(10);
1601
1602 if (count <= 0)
1603 printf("%s: fxp_mdi_write: timed out\n", sc->sc_dev.dv_xname);
1604 }
1605
1606 int
1607 fxp_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
1608 {
1609 struct fxp_softc *sc = ifp->if_softc;
1610 struct ifreq *ifr = (struct ifreq *)data;
1611 struct ifaddr *ifa = (struct ifaddr *)data;
1612 int s, error = 0;
1613
1614 s = splnet();
1615
1616 if ((error = ether_ioctl(ifp, &sc->sc_arpcom, command, data)) > 0) {
1617 splx(s);
1618 return (error);
1619 }
1620
1621 switch (command) {
1622 case SIOCSIFADDR:
1623 ifp->if_flags |= IFF_UP;
1624 if (!(ifp->if_flags & IFF_RUNNING))
1625 fxp_init(sc);
1626 #ifdef INET
1627 if (ifa->ifa_addr->sa_family == AF_INET)
1628 arp_ifinit(&sc->sc_arpcom, ifa);
1629 #endif
1630 break;
1631
1632 case SIOCSIFMTU:
1633 if (ifr->ifr_mtu > ETHERMTU || ifr->ifr_mtu < ETHERMIN)
1634 error = EINVAL;
1635 else if (ifp->if_mtu != ifr->ifr_mtu)
1636 ifp->if_mtu = ifr->ifr_mtu;
1637 break;
1638
1639 case SIOCSIFFLAGS:
1640
1641
1642
1643
1644
1645
1646 if (ifp->if_flags & IFF_UP)
1647 fxp_init(sc);
1648 else if (ifp->if_flags & IFF_RUNNING)
1649 fxp_stop(sc, 1);
1650 break;
1651
1652 case SIOCADDMULTI:
1653 case SIOCDELMULTI:
1654 error = (command == SIOCADDMULTI) ?
1655 ether_addmulti(ifr, &sc->sc_arpcom) :
1656 ether_delmulti(ifr, &sc->sc_arpcom);
1657 if (error == ENETRESET) {
1658
1659
1660
1661
1662 if (ifp->if_flags & IFF_RUNNING)
1663 fxp_init(sc);
1664 error = 0;
1665 }
1666 break;
1667
1668 case SIOCSIFMEDIA:
1669 case SIOCGIFMEDIA:
1670 error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, command);
1671 break;
1672
1673 default:
1674 error = EINVAL;
1675 }
1676 splx(s);
1677 return (error);
1678 }
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694 void
1695 fxp_mc_setup(struct fxp_softc *sc, int doit)
1696 {
1697 struct fxp_cb_mcs *mcsp = &sc->sc_ctrl->u.mcs;
1698 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1699 struct ether_multistep step;
1700 struct ether_multi *enm;
1701 int nmcasts;
1702
1703
1704
1705
1706 mcsp->cb_status = htole16(0);
1707 mcsp->cb_command = htole16(FXP_CB_COMMAND_MCAS | FXP_CB_COMMAND_EL);
1708 mcsp->link_addr = htole32(-1);
1709
1710 nmcasts = 0;
1711 if (!(ifp->if_flags & IFF_ALLMULTI)) {
1712 ETHER_FIRST_MULTI(step, &sc->sc_arpcom, enm);
1713 while (enm != NULL) {
1714 if (nmcasts >= MAXMCADDR) {
1715 ifp->if_flags |= IFF_ALLMULTI;
1716 nmcasts = 0;
1717 break;
1718 }
1719
1720
1721 if (bcmp(enm->enm_addrlo, enm->enm_addrhi,
1722 sizeof(enm->enm_addrlo)) != 0) {
1723 ifp->if_flags |= IFF_ALLMULTI;
1724 nmcasts = 0;
1725 break;
1726 }
1727 bcopy(enm->enm_addrlo,
1728 (void *)&mcsp->mc_addr[nmcasts][0], ETHER_ADDR_LEN);
1729 nmcasts++;
1730 ETHER_NEXT_MULTI(step, enm);
1731 }
1732 }
1733 if (doit == 0)
1734 return;
1735 mcsp->mc_cnt = htole16(nmcasts * ETHER_ADDR_LEN);
1736
1737
1738
1739
1740
1741 while ((CSR_READ_1(sc, FXP_CSR_SCB_RUSCUS) >> 6) != FXP_SCB_CUS_IDLE);
1742
1743
1744
1745
1746 fxp_scb_wait(sc);
1747 FXP_MCS_SYNC(sc, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1748 CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, sc->tx_cb_map->dm_segs->ds_addr +
1749 offsetof(struct fxp_ctrl, u.mcs));
1750 fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
1751
1752 do {
1753 DELAY(1);
1754 FXP_MCS_SYNC(sc, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1755 } while (!(mcsp->cb_status & htole16(FXP_CB_STATUS_C)));
1756 }
1757
1758 #ifndef SMALL_KERNEL
1759 #include <dev/microcode/fxp/rcvbundl.h>
1760 struct ucode {
1761 u_int16_t revision;
1762 u_int16_t int_delay_offset;
1763 u_int16_t bundle_max_offset;
1764 u_int16_t min_size_mask_offset;
1765 const char *uname;
1766 } const ucode_table[] = {
1767 { FXP_REV_82558_A4, D101_CPUSAVER_DWORD,
1768 0, 0,
1769 "fxp-d101a" },
1770
1771 { FXP_REV_82558_B0, D101_CPUSAVER_DWORD,
1772 0, 0,
1773 "fxp-d101b0" },
1774
1775 { FXP_REV_82559_A0, D101M_CPUSAVER_DWORD,
1776 D101M_CPUSAVER_BUNDLE_MAX_DWORD, D101M_CPUSAVER_MIN_SIZE_DWORD,
1777 "fxp-d101ma" },
1778
1779 { FXP_REV_82559S_A, D101S_CPUSAVER_DWORD,
1780 D101S_CPUSAVER_BUNDLE_MAX_DWORD, D101S_CPUSAVER_MIN_SIZE_DWORD,
1781 "fxp-d101s" },
1782
1783 { FXP_REV_82550, D102_B_CPUSAVER_DWORD,
1784 D102_B_CPUSAVER_BUNDLE_MAX_DWORD, D102_B_CPUSAVER_MIN_SIZE_DWORD,
1785 "fxp-d102" },
1786
1787 { FXP_REV_82550_C, D102_C_CPUSAVER_DWORD,
1788 D102_C_CPUSAVER_BUNDLE_MAX_DWORD, D102_C_CPUSAVER_MIN_SIZE_DWORD,
1789 "fxp-d102c" },
1790
1791 { FXP_REV_82551_F, D102_E_CPUSAVER_DWORD,
1792 D102_E_CPUSAVER_BUNDLE_MAX_DWORD, D102_E_CPUSAVER_MIN_SIZE_DWORD,
1793 "fxp-d102e" },
1794
1795 { FXP_REV_82551_10, D102_E_CPUSAVER_DWORD,
1796 D102_E_CPUSAVER_BUNDLE_MAX_DWORD, D102_E_CPUSAVER_MIN_SIZE_DWORD,
1797 "fxp-d102e" },
1798
1799 { 0, 0,
1800 0, 0,
1801 NULL }
1802 };
1803
1804 void
1805 fxp_load_ucode(struct fxp_softc *sc)
1806 {
1807 const struct ucode *uc;
1808 struct fxp_cb_ucode *cbp = &sc->sc_ctrl->u.code;
1809 int i, error;
1810 u_int32_t *ucode_buf;
1811 size_t ucode_len;
1812
1813 if (sc->sc_flags & FXPF_UCODE)
1814 return;
1815
1816 for (uc = ucode_table; uc->revision != 0; uc++)
1817 if (sc->sc_revision == uc->revision)
1818 break;
1819 if (uc->revision == NULL)
1820 return;
1821
1822 error = loadfirmware(uc->uname, (u_char **)&ucode_buf, &ucode_len);
1823 if (error) {
1824 printf("%s: failed loadfirmware of file %s: errno %d\n",
1825 sc->sc_dev.dv_xname, uc->uname, error);
1826 sc->sc_flags |= FXPF_UCODE;
1827 return;
1828 }
1829
1830 cbp->cb_status = 0;
1831 cbp->cb_command = htole16(FXP_CB_COMMAND_UCODE|FXP_CB_COMMAND_EL);
1832 cbp->link_addr = 0xffffffff;
1833 for (i = 0; i < (ucode_len / sizeof(u_int32_t)); i++)
1834 cbp->ucode[i] = ucode_buf[i];
1835
1836 if (uc->int_delay_offset)
1837 *((u_int16_t *)&cbp->ucode[uc->int_delay_offset]) =
1838 htole16(sc->sc_int_delay + sc->sc_int_delay / 2);
1839
1840 if (uc->bundle_max_offset)
1841 *((u_int16_t *)&cbp->ucode[uc->bundle_max_offset]) =
1842 htole16(sc->sc_bundle_max);
1843
1844 if (uc->min_size_mask_offset)
1845 *((u_int16_t *)&cbp->ucode[uc->min_size_mask_offset]) =
1846 htole16(sc->sc_min_size_mask);
1847
1848 FXP_UCODE_SYNC(sc, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1849
1850
1851
1852
1853 fxp_scb_wait(sc);
1854 CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, sc->tx_cb_map->dm_segs->ds_addr
1855 + offsetof(struct fxp_ctrl, u.code));
1856 fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
1857
1858
1859 i = 10000;
1860 do {
1861 DELAY(2);
1862 FXP_UCODE_SYNC(sc, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1863 } while (((cbp->cb_status & htole16(FXP_CB_STATUS_C)) == 0) && --i);
1864 if (i == 0) {
1865 printf("%s: timeout loading microcode\n", sc->sc_dev.dv_xname);
1866 free(ucode_buf, M_DEVBUF);
1867 return;
1868 }
1869
1870 #ifdef DEBUG
1871 printf("%s: microcode loaded, int_delay: %d usec",
1872 sc->sc_dev.dv_xname, sc->sc_int_delay);
1873
1874 if (uc->bundle_max_offset)
1875 printf(", bundle_max %d\n", sc->sc_bundle_max);
1876 else
1877 printf("\n");
1878 #endif
1879
1880 free(ucode_buf, M_DEVBUF);
1881 sc->sc_flags |= FXPF_UCODE;
1882 }
1883 #endif