This source file includes following definitions.
- cas_match
- cas_pci_enaddr
- cas_attach
- cas_config
- cas_tick
- cas_bitwait
- cas_reset
- cas_rxdrain
- cas_stop
- cas_reset_rx
- cas_reset_tx
- cas_disable_rx
- cas_disable_tx
- cas_meminit
- cas_ringsize
- cas_cringsize
- cas_init
- cas_init_regs
- cas_rint
- cas_add_rxbuf
- cas_eint
- cas_pint
- cas_intr
- cas_watchdog
- cas_mifinit
- cas_mii_readreg
- cas_mii_writereg
- cas_mii_statchg
- cas_pcs_readreg
- cas_pcs_writereg
- cas_mediachange
- cas_mediastatus
- cas_ioctl
- cas_shutdown
- cas_setladrf
- cas_encap
- cas_tint
- cas_start
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 #include "bpfilter.h"
38
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/timeout.h>
42 #include <sys/mbuf.h>
43 #include <sys/syslog.h>
44 #include <sys/malloc.h>
45 #include <sys/kernel.h>
46 #include <sys/socket.h>
47 #include <sys/ioctl.h>
48 #include <sys/errno.h>
49 #include <sys/device.h>
50
51 #include <machine/endian.h>
52
53 #include <net/if.h>
54 #include <net/if_dl.h>
55 #include <net/if_media.h>
56
57 #ifdef INET
58 #include <netinet/in.h>
59 #include <netinet/if_ether.h>
60 #endif
61
62 #if NBPFILTER > 0
63 #include <net/bpf.h>
64 #endif
65
66 #include <machine/bus.h>
67 #include <machine/intr.h>
68
69 #include <dev/mii/mii.h>
70 #include <dev/mii/miivar.h>
71 #include <dev/mii/mii_bitbang.h>
72
73 #include <dev/pci/if_casreg.h>
74 #include <dev/pci/if_casvar.h>
75
76 #include <dev/pci/pcivar.h>
77 #include <dev/pci/pcireg.h>
78 #include <dev/pci/pcidevs.h>
79
80 #ifdef __sparc64__
81 #include <dev/ofw/openfirm.h>
82 #endif
83
84 #define TRIES 10000
85
86 struct cfdriver cas_cd = {
87 NULL, "cas", DV_IFNET
88 };
89
90 int cas_match(struct device *, void *, void *);
91 void cas_attach(struct device *, struct device *, void *);
92 int cas_pci_enaddr(struct cas_softc *, struct pci_attach_args *);
93
94 struct cfattach cas_ca = {
95 sizeof(struct cas_softc), cas_match, cas_attach
96 };
97
98 void cas_config(struct cas_softc *);
99 void cas_start(struct ifnet *);
100 void cas_stop(struct ifnet *, int);
101 int cas_ioctl(struct ifnet *, u_long, caddr_t);
102 void cas_tick(void *);
103 void cas_watchdog(struct ifnet *);
104 void cas_shutdown(void *);
105 int cas_init(struct ifnet *);
106 void cas_init_regs(struct cas_softc *);
107 int cas_ringsize(int);
108 int cas_cringsize(int);
109 int cas_meminit(struct cas_softc *);
110 void cas_mifinit(struct cas_softc *);
111 int cas_bitwait(struct cas_softc *, bus_space_handle_t, int,
112 u_int32_t, u_int32_t);
113 void cas_reset(struct cas_softc *);
114 int cas_reset_rx(struct cas_softc *);
115 int cas_reset_tx(struct cas_softc *);
116 int cas_disable_rx(struct cas_softc *);
117 int cas_disable_tx(struct cas_softc *);
118 void cas_rxdrain(struct cas_softc *);
119 int cas_add_rxbuf(struct cas_softc *, int idx);
120 void cas_setladrf(struct cas_softc *);
121 int cas_encap(struct cas_softc *, struct mbuf *, u_int32_t *);
122
123
124 int cas_mii_readreg(struct device *, int, int);
125 void cas_mii_writereg(struct device *, int, int, int);
126 void cas_mii_statchg(struct device *);
127 int cas_pcs_readreg(struct device *, int, int);
128 void cas_pcs_writereg(struct device *, int, int, int);
129
130 int cas_mediachange(struct ifnet *);
131 void cas_mediastatus(struct ifnet *, struct ifmediareq *);
132
133 int cas_eint(struct cas_softc *, u_int);
134 int cas_rint(struct cas_softc *);
135 int cas_tint(struct cas_softc *, u_int32_t);
136 int cas_pint(struct cas_softc *);
137 int cas_intr(void *);
138
139 #ifdef CAS_DEBUG
140 #define DPRINTF(sc, x) if ((sc)->sc_arpcom.ac_if.if_flags & IFF_DEBUG) \
141 printf x
142 #else
143 #define DPRINTF(sc, x)
144 #endif
145
146 const struct pci_matchid cas_pci_devices[] = {
147 { PCI_VENDOR_SUN, PCI_PRODUCT_SUN_CASSINI }
148 };
149
150 int
151 cas_match(struct device *parent, void *cf, void *aux)
152 {
153 return (pci_matchbyid((struct pci_attach_args *)aux, cas_pci_devices,
154 sizeof(cas_pci_devices)/sizeof(cas_pci_devices[0])));
155 }
156
157 #define PROMHDR_PTR_DATA 0x18
158 #define PROMDATA_PTR_VPD 0x08
159 #define PROMDATA_DATA2 0x0a
160
161 static const u_int8_t cas_promhdr[] = { 0x55, 0xaa };
162 static const u_int8_t cas_promdat[] = {
163 'P', 'C', 'I', 'R',
164 PCI_VENDOR_SUN & 0xff, PCI_VENDOR_SUN >> 8,
165 PCI_PRODUCT_SUN_CASSINI & 0xff, PCI_PRODUCT_SUN_CASSINI >> 8
166 };
167
168 static const u_int8_t cas_promdat2[] = {
169 0x18, 0x00,
170 0x00,
171 0x00,
172 PCI_SUBCLASS_NETWORK_ETHERNET,
173 PCI_CLASS_NETWORK
174 };
175
176 int
177 cas_pci_enaddr(struct cas_softc *sc, struct pci_attach_args *pa)
178 {
179 struct pci_vpd_largeres *res;
180 struct pci_vpd *vpd;
181 bus_space_handle_t romh;
182 bus_space_tag_t romt;
183 bus_size_t romsize;
184 u_int8_t buf[32], *desc;
185 pcireg_t address, mask;
186 int dataoff, vpdoff, len;
187 int rv = -1;
188
189 address = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG);
190 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, 0xfffffffe);
191 mask = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG);
192 address |= PCI_ROM_ENABLE;
193 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, address);
194
195 romt = pa->pa_memt;
196 romsize = PCI_ROM_SIZE(mask);
197 if (bus_space_map(romt, PCI_ROM_ADDR(address), romsize, 0, &romh)) {
198 romsize = 0;
199 goto fail;
200 }
201
202 bus_space_read_region_1(romt, romh, 0, buf, sizeof(buf));
203 if (bcmp(buf, cas_promhdr, sizeof(cas_promhdr)))
204 goto fail;
205
206 dataoff = buf[PROMHDR_PTR_DATA] | (buf[PROMHDR_PTR_DATA + 1] << 8);
207 if (dataoff < 0x1c)
208 goto fail;
209
210 bus_space_read_region_1(romt, romh, dataoff, buf, sizeof(buf));
211 if (bcmp(buf, cas_promdat, sizeof(cas_promdat)) ||
212 bcmp(buf + PROMDATA_DATA2, cas_promdat2, sizeof(cas_promdat2)))
213 goto fail;
214
215 vpdoff = buf[PROMDATA_PTR_VPD] | (buf[PROMDATA_PTR_VPD + 1] << 8);
216 if (vpdoff < 0x1c)
217 goto fail;
218
219 next:
220 bus_space_read_region_1(romt, romh, vpdoff, buf, sizeof(buf));
221 if (!PCI_VPDRES_ISLARGE(buf[0]))
222 goto fail;
223
224 res = (struct pci_vpd_largeres *)buf;
225 vpdoff += sizeof(*res);
226
227 len = ((res->vpdres_len_msb << 8) + res->vpdres_len_lsb);
228 switch(PCI_VPDRES_LARGE_NAME(res->vpdres_byte0)) {
229 case PCI_VPDRES_TYPE_IDENTIFIER_STRING:
230
231 vpdoff += len;
232 goto next;
233
234 case PCI_VPDRES_TYPE_VPD:
235 while (len > 0) {
236 bus_space_read_region_1(romt, romh, vpdoff,
237 buf, sizeof(buf));
238
239 vpd = (struct pci_vpd *)buf;
240 vpdoff += sizeof(*vpd) + vpd->vpd_len;
241 len -= sizeof(*vpd) + vpd->vpd_len;
242
243
244
245
246 if (vpd->vpd_key0 != 'Z')
247 continue;
248
249 desc = buf + sizeof(*vpd);
250
251
252
253
254 if (desc[0] != 'I')
255 continue;
256 desc += 3;
257
258
259
260
261
262 if (desc[0] != 'B' || desc[1] != ETHER_ADDR_LEN)
263 continue;
264 desc += 2;
265
266
267
268
269 if (strcmp(desc, "local-mac-address") != 0)
270 continue;
271 desc += strlen("local-mac-address") + 1;
272
273 bcopy(desc, sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN);
274 rv = 0;
275 }
276 break;
277
278 default:
279 goto fail;
280 }
281
282 fail:
283 if (romsize != 0)
284 bus_space_unmap(romt, romh, romsize);
285
286 address = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG);
287 address &= ~PCI_ROM_ENABLE;
288 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, address);
289
290 return (rv);
291 }
292
293 void
294 cas_attach(struct device *parent, struct device *self, void *aux)
295 {
296 struct pci_attach_args *pa = aux;
297 struct cas_softc *sc = (void *)self;
298 pci_intr_handle_t ih;
299 #ifdef __sparc64__
300
301 extern void myetheraddr(u_char *);
302 #endif
303 const char *intrstr = NULL;
304 bus_size_t size;
305 int gotenaddr = 0;
306
307 sc->sc_dmatag = pa->pa_dmat;
308
309 #define PCI_CAS_BASEADDR 0x10
310 if (pci_mapreg_map(pa, PCI_CAS_BASEADDR, PCI_MAPREG_TYPE_MEM, 0,
311 &sc->sc_memt, &sc->sc_memh, NULL, &size, 0) != 0) {
312 printf(": could not map registers\n");
313 return;
314 }
315
316 if (cas_pci_enaddr(sc, pa) == 0)
317 gotenaddr = 1;
318
319 #ifdef __sparc64__
320 if (!gotenaddr) {
321 if (OF_getprop(PCITAG_NODE(pa->pa_tag), "local-mac-address",
322 sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN) <= 0)
323 myetheraddr(sc->sc_arpcom.ac_enaddr);
324 gotenaddr = 1;
325 }
326 #endif
327 #ifdef __powerpc__
328 if (!gotenaddr) {
329 pci_ether_hw_addr(pa->pa_pc, sc->sc_arpcom.ac_enaddr);
330 gotenaddr = 1;
331 }
332 #endif
333
334 sc->sc_burst = 16;
335
336 if (pci_intr_map(pa, &ih) != 0) {
337 printf(": couldn't map interrupt\n");
338 bus_space_unmap(sc->sc_memt, sc->sc_memh, size);
339 return;
340 }
341 intrstr = pci_intr_string(pa->pa_pc, ih);
342 sc->sc_ih = pci_intr_establish(pa->pa_pc,
343 ih, IPL_NET, cas_intr, sc, self->dv_xname);
344 if (sc->sc_ih == NULL) {
345 printf(": couldn't establish interrupt");
346 if (intrstr != NULL)
347 printf(" at %s", intrstr);
348 printf("\n");
349 bus_space_unmap(sc->sc_memt, sc->sc_memh, size);
350 return;
351 }
352
353 printf(": %s", intrstr);
354
355
356
357
358 cas_config(sc);
359 }
360
361
362
363
364
365
366 void
367 cas_config(struct cas_softc *sc)
368 {
369 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
370 struct mii_data *mii = &sc->sc_mii;
371 struct mii_softc *child;
372 int i, error;
373
374
375 ifp->if_softc = sc;
376 cas_reset(sc);
377
378
379
380
381
382 if ((error = bus_dmamem_alloc(sc->sc_dmatag,
383 sizeof(struct cas_control_data), CAS_PAGE_SIZE, 0, &sc->sc_cdseg,
384 1, &sc->sc_cdnseg, 0)) != 0) {
385 printf("\n%s: unable to allocate control data, error = %d\n",
386 sc->sc_dev.dv_xname, error);
387 goto fail_0;
388 }
389
390
391 if ((error = bus_dmamem_map(sc->sc_dmatag, &sc->sc_cdseg, sc->sc_cdnseg,
392 sizeof(struct cas_control_data), (caddr_t *)&sc->sc_control_data,
393 BUS_DMA_COHERENT)) != 0) {
394 printf("\n%s: unable to map control data, error = %d\n",
395 sc->sc_dev.dv_xname, error);
396 goto fail_1;
397 }
398
399 if ((error = bus_dmamap_create(sc->sc_dmatag,
400 sizeof(struct cas_control_data), 1,
401 sizeof(struct cas_control_data), 0, 0, &sc->sc_cddmamap)) != 0) {
402 printf("\n%s: unable to create control data DMA map, "
403 "error = %d\n", sc->sc_dev.dv_xname, error);
404 goto fail_2;
405 }
406
407 if ((error = bus_dmamap_load(sc->sc_dmatag, sc->sc_cddmamap,
408 sc->sc_control_data, sizeof(struct cas_control_data), NULL,
409 0)) != 0) {
410 printf("\n%s: unable to load control data DMA map, error = %d\n",
411 sc->sc_dev.dv_xname, error);
412 goto fail_3;
413 }
414
415
416
417
418 for (i = 0; i < CAS_NRXDESC; i++) {
419 bus_dma_segment_t seg;
420 caddr_t kva;
421 int rseg;
422
423 if ((error = bus_dmamem_alloc(sc->sc_dmatag, CAS_PAGE_SIZE,
424 CAS_PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
425 printf("\n%s: unable to alloc rx DMA mem %d, "
426 "error = %d\n", sc->sc_dev.dv_xname, i, error);
427 goto fail_5;
428 }
429 sc->sc_rxsoft[i].rxs_dmaseg = seg;
430
431 if ((error = bus_dmamem_map(sc->sc_dmatag, &seg, rseg,
432 CAS_PAGE_SIZE, &kva, BUS_DMA_NOWAIT)) != 0) {
433 printf("\n%s: unable to alloc rx DMA mem %d, "
434 "error = %d\n", sc->sc_dev.dv_xname, i, error);
435 goto fail_5;
436 }
437 sc->sc_rxsoft[i].rxs_kva = kva;
438
439 if ((error = bus_dmamap_create(sc->sc_dmatag, CAS_PAGE_SIZE, 1,
440 CAS_PAGE_SIZE, 0, 0, &sc->sc_rxsoft[i].rxs_dmamap)) != 0) {
441 printf("\n%s: unable to create rx DMA map %d, "
442 "error = %d\n", sc->sc_dev.dv_xname, i, error);
443 goto fail_5;
444 }
445
446 if ((error = bus_dmamap_load(sc->sc_dmatag,
447 sc->sc_rxsoft[i].rxs_dmamap, kva, CAS_PAGE_SIZE, NULL,
448 BUS_DMA_NOWAIT)) != 0) {
449 printf("\n%s: unable to load rx DMA map %d, "
450 "error = %d\n", sc->sc_dev.dv_xname, i, error);
451 goto fail_5;
452 }
453 }
454
455
456
457
458 for (i = 0; i < CAS_NTXDESC; i++) {
459 if ((error = bus_dmamap_create(sc->sc_dmatag, MCLBYTES,
460 CAS_NTXSEGS, MCLBYTES, 0, BUS_DMA_NOWAIT,
461 &sc->sc_txd[i].sd_map)) != 0) {
462 printf("\n%s: unable to create tx DMA map %d, "
463 "error = %d\n", sc->sc_dev.dv_xname, i, error);
464 goto fail_6;
465 }
466 sc->sc_txd[i].sd_mbuf = NULL;
467 }
468
469
470
471
472
473
474
475
476 printf(", address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr));
477
478
479 sc->sc_rxfifosize = 16 * 1024;
480
481
482 strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, sizeof ifp->if_xname);
483 ifp->if_softc = sc;
484 ifp->if_flags =
485 IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
486 ifp->if_start = cas_start;
487 ifp->if_ioctl = cas_ioctl;
488 ifp->if_watchdog = cas_watchdog;
489 IFQ_SET_MAXLEN(&ifp->if_snd, CAS_NTXDESC - 1);
490 IFQ_SET_READY(&ifp->if_snd);
491
492 ifp->if_capabilities = IFCAP_VLAN_MTU;
493
494
495 mii->mii_ifp = ifp;
496 mii->mii_readreg = cas_mii_readreg;
497 mii->mii_writereg = cas_mii_writereg;
498 mii->mii_statchg = cas_mii_statchg;
499
500 ifmedia_init(&mii->mii_media, 0, cas_mediachange, cas_mediastatus);
501
502 bus_space_write_4(sc->sc_memt, sc->sc_memh, CAS_MII_DATAPATH_MODE, 0);
503
504 cas_mifinit(sc);
505
506 if (sc->sc_mif_config & CAS_MIF_CONFIG_MDI1) {
507 sc->sc_mif_config |= CAS_MIF_CONFIG_PHY_SEL;
508 bus_space_write_4(sc->sc_memt, sc->sc_memh,
509 CAS_MIF_CONFIG, sc->sc_mif_config);
510 }
511
512 mii_attach(&sc->sc_dev, mii, 0xffffffff, MII_PHY_ANY,
513 MII_OFFSET_ANY, 0);
514
515 child = LIST_FIRST(&mii->mii_phys);
516 if (child == NULL &&
517 sc->sc_mif_config & (CAS_MIF_CONFIG_MDI0|CAS_MIF_CONFIG_MDI1)) {
518
519
520
521
522 bus_space_write_4(sc->sc_memt, sc->sc_memh,
523 CAS_MII_DATAPATH_MODE, CAS_MII_DATAPATH_SERDES);
524
525 bus_space_write_4(sc->sc_memt, sc->sc_memh,
526 CAS_MII_SLINK_CONTROL,
527 CAS_MII_SLINK_LOOPBACK|CAS_MII_SLINK_EN_SYNC_D);
528
529 bus_space_write_4(sc->sc_memt, sc->sc_memh,
530 CAS_MII_CONFIG, CAS_MII_CONFIG_ENABLE);
531
532 mii->mii_readreg = cas_pcs_readreg;
533 mii->mii_writereg = cas_pcs_writereg;
534
535 mii_attach(&sc->sc_dev, mii, 0xffffffff, MII_PHY_ANY,
536 MII_OFFSET_ANY, MIIF_NOISOLATE);
537 }
538
539 child = LIST_FIRST(&mii->mii_phys);
540 if (child == NULL) {
541
542 ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
543 ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL);
544 } else {
545
546
547
548
549
550
551
552 for (; child != NULL; child = LIST_NEXT(child, mii_list)) {
553
554
555
556
557
558 if (child->mii_phy > 1 || child->mii_inst > 1) {
559 printf("%s: cannot accommodate MII device %s"
560 " at phy %d, instance %d\n",
561 sc->sc_dev.dv_xname,
562 child->mii_dev.dv_xname,
563 child->mii_phy, child->mii_inst);
564 continue;
565 }
566
567 sc->sc_phys[child->mii_inst] = child->mii_phy;
568 }
569
570
571
572
573
574 ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_AUTO);
575 }
576
577
578 if_attach(ifp);
579 ether_ifattach(ifp);
580
581 sc->sc_sh = shutdownhook_establish(cas_shutdown, sc);
582 if (sc->sc_sh == NULL)
583 panic("cas_config: can't establish shutdownhook");
584
585 timeout_set(&sc->sc_tick_ch, cas_tick, sc);
586 return;
587
588
589
590
591
592 fail_6:
593 for (i = 0; i < CAS_NTXDESC; i++) {
594 if (sc->sc_txd[i].sd_map != NULL)
595 bus_dmamap_destroy(sc->sc_dmatag,
596 sc->sc_txd[i].sd_map);
597 }
598 fail_5:
599 for (i = 0; i < CAS_NRXDESC; i++) {
600 if (sc->sc_rxsoft[i].rxs_dmamap != NULL)
601 bus_dmamap_destroy(sc->sc_dmatag,
602 sc->sc_rxsoft[i].rxs_dmamap);
603 }
604 bus_dmamap_unload(sc->sc_dmatag, sc->sc_cddmamap);
605 fail_3:
606 bus_dmamap_destroy(sc->sc_dmatag, sc->sc_cddmamap);
607 fail_2:
608 bus_dmamem_unmap(sc->sc_dmatag, (caddr_t)sc->sc_control_data,
609 sizeof(struct cas_control_data));
610 fail_1:
611 bus_dmamem_free(sc->sc_dmatag, &sc->sc_cdseg, sc->sc_cdnseg);
612 fail_0:
613 return;
614 }
615
616
617 void
618 cas_tick(void *arg)
619 {
620 struct cas_softc *sc = arg;
621 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
622 bus_space_tag_t t = sc->sc_memt;
623 bus_space_handle_t mac = sc->sc_memh;
624 int s;
625
626
627 ifp->if_collisions +=
628 bus_space_read_4(t, mac, CAS_MAC_NORM_COLL_CNT) +
629 bus_space_read_4(t, mac, CAS_MAC_FIRST_COLL_CNT) +
630 bus_space_read_4(t, mac, CAS_MAC_EXCESS_COLL_CNT) +
631 bus_space_read_4(t, mac, CAS_MAC_LATE_COLL_CNT);
632
633
634 bus_space_write_4(t, mac, CAS_MAC_NORM_COLL_CNT, 0);
635 bus_space_write_4(t, mac, CAS_MAC_FIRST_COLL_CNT, 0);
636 bus_space_write_4(t, mac, CAS_MAC_EXCESS_COLL_CNT, 0);
637 bus_space_write_4(t, mac, CAS_MAC_LATE_COLL_CNT, 0);
638
639 s = splnet();
640 mii_tick(&sc->sc_mii);
641 splx(s);
642
643 timeout_add(&sc->sc_tick_ch, hz);
644 }
645
646 int
647 cas_bitwait(struct cas_softc *sc, bus_space_handle_t h, int r,
648 u_int32_t clr, u_int32_t set)
649 {
650 int i;
651 u_int32_t reg;
652
653 for (i = TRIES; i--; DELAY(100)) {
654 reg = bus_space_read_4(sc->sc_memt, h, r);
655 if ((reg & clr) == 0 && (reg & set) == set)
656 return (1);
657 }
658
659 return (0);
660 }
661
662 void
663 cas_reset(struct cas_softc *sc)
664 {
665 bus_space_tag_t t = sc->sc_memt;
666 bus_space_handle_t h = sc->sc_memh;
667 int s;
668
669 s = splnet();
670 DPRINTF(sc, ("%s: cas_reset\n", sc->sc_dev.dv_xname));
671 cas_reset_rx(sc);
672 cas_reset_tx(sc);
673
674
675 bus_space_write_4(t, h, CAS_RESET, CAS_RESET_RX|CAS_RESET_TX);
676 if (!cas_bitwait(sc, h, CAS_RESET, CAS_RESET_RX | CAS_RESET_TX, 0))
677 printf("%s: cannot reset device\n", sc->sc_dev.dv_xname);
678 splx(s);
679 }
680
681
682
683
684
685
686
687 void
688 cas_rxdrain(struct cas_softc *sc)
689 {
690
691 }
692
693
694
695
696 void
697 cas_stop(struct ifnet *ifp, int disable)
698 {
699 struct cas_softc *sc = (struct cas_softc *)ifp->if_softc;
700 struct cas_sxd *sd;
701 u_int32_t i;
702
703 DPRINTF(sc, ("%s: cas_stop\n", sc->sc_dev.dv_xname));
704
705 timeout_del(&sc->sc_tick_ch);
706
707
708
709
710 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
711 ifp->if_timer = 0;
712
713 mii_down(&sc->sc_mii);
714
715 cas_reset_rx(sc);
716 cas_reset_tx(sc);
717
718
719
720
721 for (i = 0; i < CAS_NTXDESC; i++) {
722 sd = &sc->sc_txd[i];
723 if (sd->sd_mbuf != NULL) {
724 bus_dmamap_sync(sc->sc_dmatag, sd->sd_map, 0,
725 sd->sd_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
726 bus_dmamap_unload(sc->sc_dmatag, sd->sd_map);
727 m_freem(sd->sd_mbuf);
728 sd->sd_mbuf = NULL;
729 }
730 }
731 sc->sc_tx_cnt = sc->sc_tx_prod = sc->sc_tx_cons = 0;
732
733 if (disable)
734 cas_rxdrain(sc);
735 }
736
737
738
739
740
741 int
742 cas_reset_rx(struct cas_softc *sc)
743 {
744 bus_space_tag_t t = sc->sc_memt;
745 bus_space_handle_t h = sc->sc_memh;
746
747
748
749
750
751 cas_disable_rx(sc);
752 bus_space_write_4(t, h, CAS_RX_CONFIG, 0);
753
754 if (!cas_bitwait(sc, h, CAS_RX_CONFIG, 1, 0))
755 printf("%s: cannot disable rx dma\n", sc->sc_dev.dv_xname);
756
757 delay(5000);
758
759
760 bus_space_write_4(t, h, CAS_RESET, CAS_RESET_RX);
761
762 if (!cas_bitwait(sc, h, CAS_RESET, CAS_RESET_RX, 0)) {
763 printf("%s: cannot reset receiver\n", sc->sc_dev.dv_xname);
764 return (1);
765 }
766 return (0);
767 }
768
769
770
771
772
773 int
774 cas_reset_tx(struct cas_softc *sc)
775 {
776 bus_space_tag_t t = sc->sc_memt;
777 bus_space_handle_t h = sc->sc_memh;
778
779
780
781
782
783 cas_disable_tx(sc);
784 bus_space_write_4(t, h, CAS_TX_CONFIG, 0);
785
786 if (!cas_bitwait(sc, h, CAS_TX_CONFIG, 1, 0))
787 printf("%s: cannot disable tx dma\n", sc->sc_dev.dv_xname);
788
789 delay(5000);
790
791
792 bus_space_write_4(t, h, CAS_RESET, CAS_RESET_TX);
793
794 if (!cas_bitwait(sc, h, CAS_RESET, CAS_RESET_TX, 0)) {
795 printf("%s: cannot reset transmitter\n",
796 sc->sc_dev.dv_xname);
797 return (1);
798 }
799 return (0);
800 }
801
802
803
804
805 int
806 cas_disable_rx(struct cas_softc *sc)
807 {
808 bus_space_tag_t t = sc->sc_memt;
809 bus_space_handle_t h = sc->sc_memh;
810 u_int32_t cfg;
811
812
813 cfg = bus_space_read_4(t, h, CAS_MAC_RX_CONFIG);
814 cfg &= ~CAS_MAC_RX_ENABLE;
815 bus_space_write_4(t, h, CAS_MAC_RX_CONFIG, cfg);
816
817
818 return (cas_bitwait(sc, h, CAS_MAC_RX_CONFIG, CAS_MAC_RX_ENABLE, 0));
819 }
820
821
822
823
824 int
825 cas_disable_tx(struct cas_softc *sc)
826 {
827 bus_space_tag_t t = sc->sc_memt;
828 bus_space_handle_t h = sc->sc_memh;
829 u_int32_t cfg;
830
831
832 cfg = bus_space_read_4(t, h, CAS_MAC_TX_CONFIG);
833 cfg &= ~CAS_MAC_TX_ENABLE;
834 bus_space_write_4(t, h, CAS_MAC_TX_CONFIG, cfg);
835
836
837 return (cas_bitwait(sc, h, CAS_MAC_TX_CONFIG, CAS_MAC_TX_ENABLE, 0));
838 }
839
840
841
842
843 int
844 cas_meminit(struct cas_softc *sc)
845 {
846 struct cas_rxsoft *rxs;
847 int i, error;
848
849 rxs = (void *)&error;
850
851
852
853
854 for (i = 0; i < CAS_NTXDESC; i++) {
855 sc->sc_txdescs[i].cd_flags = 0;
856 sc->sc_txdescs[i].cd_addr = 0;
857 }
858 CAS_CDTXSYNC(sc, 0, CAS_NTXDESC,
859 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
860
861
862
863
864
865 for (i = 0; i < CAS_NRXDESC; i++)
866 CAS_INIT_RXDESC(sc, i, i);
867 sc->sc_rxdptr = 0;
868 sc->sc_rxptr = 0;
869
870
871
872
873 for (i = 0; i < CAS_NRXCOMP; i++) {
874 sc->sc_rxcomps[i].cc_word[0] = 0;
875 sc->sc_rxcomps[i].cc_word[1] = 0;
876 sc->sc_rxcomps[i].cc_word[2] = 0;
877 sc->sc_rxcomps[i].cc_word[3] = CAS_DMA_WRITE(CAS_RC3_OWN);
878 CAS_CDRXCSYNC(sc, i,
879 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
880 }
881
882 return (0);
883 }
884
885 int
886 cas_ringsize(int sz)
887 {
888 switch (sz) {
889 case 32:
890 return CAS_RING_SZ_32;
891 case 64:
892 return CAS_RING_SZ_64;
893 case 128:
894 return CAS_RING_SZ_128;
895 case 256:
896 return CAS_RING_SZ_256;
897 case 512:
898 return CAS_RING_SZ_512;
899 case 1024:
900 return CAS_RING_SZ_1024;
901 case 2048:
902 return CAS_RING_SZ_2048;
903 case 4096:
904 return CAS_RING_SZ_4096;
905 case 8192:
906 return CAS_RING_SZ_8192;
907 default:
908 printf("cas: invalid Receive Descriptor ring size %d\n", sz);
909 return CAS_RING_SZ_32;
910 }
911 }
912
913 int
914 cas_cringsize(int sz)
915 {
916 int i;
917
918 for (i = 0; i < 9; i++)
919 if (sz == (128 << i))
920 return i;
921
922 printf("cas: invalid completion ring size %d\n", sz);
923 return 128;
924 }
925
926
927
928
929
930 int
931 cas_init(struct ifnet *ifp)
932 {
933
934 struct cas_softc *sc = (struct cas_softc *)ifp->if_softc;
935 bus_space_tag_t t = sc->sc_memt;
936 bus_space_handle_t h = sc->sc_memh;
937 int s;
938 u_int max_frame_size;
939 u_int32_t v;
940
941 s = splnet();
942
943 DPRINTF(sc, ("%s: cas_init: calling stop\n", sc->sc_dev.dv_xname));
944
945
946
947
948
949
950
951
952 cas_stop(ifp, 0);
953 cas_reset(sc);
954 DPRINTF(sc, ("%s: cas_init: restarting\n", sc->sc_dev.dv_xname));
955
956
957 cas_mifinit(sc);
958
959
960 cas_meminit(sc);
961
962
963 cas_init_regs(sc);
964 max_frame_size = ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN;
965 v = (max_frame_size) | (0x2000 << 16) ;
966 bus_space_write_4(t, h, CAS_MAC_MAC_MAX_FRAME, v);
967
968
969 cas_setladrf(sc);
970
971
972 KASSERT((CAS_CDTXADDR(sc, 0) & 0x1fff) == 0);
973 bus_space_write_4(t, h, CAS_TX_RING_PTR_HI,
974 (((uint64_t)CAS_CDTXADDR(sc,0)) >> 32));
975 bus_space_write_4(t, h, CAS_TX_RING_PTR_LO, CAS_CDTXADDR(sc, 0));
976
977 KASSERT((CAS_CDRXADDR(sc, 0) & 0x1fff) == 0);
978 bus_space_write_4(t, h, CAS_RX_DRING_PTR_HI,
979 (((uint64_t)CAS_CDRXADDR(sc,0)) >> 32));
980 bus_space_write_4(t, h, CAS_RX_DRING_PTR_LO, CAS_CDRXADDR(sc, 0));
981
982 KASSERT((CAS_CDRXCADDR(sc, 0) & 0x1fff) == 0);
983 bus_space_write_4(t, h, CAS_RX_CRING_PTR_HI,
984 (((uint64_t)CAS_CDRXCADDR(sc,0)) >> 32));
985 bus_space_write_4(t, h, CAS_RX_CRING_PTR_LO, CAS_CDRXCADDR(sc, 0));
986
987
988 bus_space_write_4(t, h, CAS_INTMASK,
989 ~(CAS_INTR_TX_INTME|CAS_INTR_TX_EMPTY|
990 CAS_INTR_TX_TAG_ERR|
991 CAS_INTR_RX_DONE|CAS_INTR_RX_NOBUF|
992 CAS_INTR_RX_TAG_ERR|
993 CAS_INTR_RX_COMP_FULL|CAS_INTR_PCS|
994 CAS_INTR_MAC_CONTROL|CAS_INTR_MIF|
995 CAS_INTR_BERR));
996 bus_space_write_4(t, h, CAS_MAC_RX_MASK,
997 CAS_MAC_RX_DONE|CAS_MAC_RX_FRAME_CNT);
998 bus_space_write_4(t, h, CAS_MAC_TX_MASK, CAS_MAC_TX_XMIT_DONE);
999 bus_space_write_4(t, h, CAS_MAC_CONTROL_MASK, 0);
1000
1001
1002
1003
1004 v = cas_ringsize(CAS_NTXDESC ) << 10;
1005 bus_space_write_4(t, h, CAS_TX_CONFIG,
1006 v|CAS_TX_CONFIG_TXDMA_EN|(1<<24)|(1<<29));
1007 bus_space_write_4(t, h, CAS_TX_KICK, 0);
1008
1009
1010
1011
1012 v = cas_ringsize(CAS_NRXDESC) << CAS_RX_CONFIG_RXDRNG_SZ_SHIFT;
1013
1014
1015 v |= cas_cringsize(CAS_NRXCOMP) << CAS_RX_CONFIG_RXCRNG_SZ_SHIFT;
1016
1017
1018 bus_space_write_4(t, h, CAS_RX_CONFIG,
1019 v|(2<<CAS_RX_CONFIG_FBOFF_SHFT)|CAS_RX_CONFIG_RXDMA_EN);
1020
1021
1022
1023
1024
1025 bus_space_write_4(t, h, CAS_RX_PAUSE_THRESH,
1026 (3 * sc->sc_rxfifosize / 256) |
1027 ( (sc->sc_rxfifosize / 256) << 12));
1028 bus_space_write_4(t, h, CAS_RX_BLANKING, (6<<12)|6);
1029
1030
1031 mii_mediachg(&sc->sc_mii);
1032
1033
1034 v = bus_space_read_4(t, h, CAS_MAC_RX_CONFIG);
1035 v |= CAS_MAC_RX_ENABLE | CAS_MAC_RX_STRIP_CRC;
1036 bus_space_write_4(t, h, CAS_MAC_RX_CONFIG, v);
1037
1038
1039
1040
1041 bus_space_write_4(t, h, CAS_RX_KICK, CAS_NRXDESC-4);
1042
1043
1044 timeout_add(&sc->sc_tick_ch, hz);
1045
1046 ifp->if_flags |= IFF_RUNNING;
1047 ifp->if_flags &= ~IFF_OACTIVE;
1048 ifp->if_timer = 0;
1049 splx(s);
1050
1051 return (0);
1052 }
1053
1054 void
1055 cas_init_regs(struct cas_softc *sc)
1056 {
1057 bus_space_tag_t t = sc->sc_memt;
1058 bus_space_handle_t h = sc->sc_memh;
1059 u_int32_t v, r;
1060
1061
1062 sc->sc_inited = 0;
1063 if (!sc->sc_inited) {
1064
1065
1066 bus_space_write_4(t, h, CAS_MAC_IPG0, 0);
1067 bus_space_write_4(t, h, CAS_MAC_IPG1, 8);
1068 bus_space_write_4(t, h, CAS_MAC_IPG2, 4);
1069
1070 bus_space_write_4(t, h, CAS_MAC_MAC_MIN_FRAME, ETHER_MIN_LEN);
1071
1072 v = ETHER_MAX_LEN | (0x2000 << 16) ;
1073 bus_space_write_4(t, h, CAS_MAC_MAC_MAX_FRAME, v);
1074
1075 bus_space_write_4(t, h, CAS_MAC_PREAMBLE_LEN, 0x7);
1076 bus_space_write_4(t, h, CAS_MAC_JAM_SIZE, 0x4);
1077 bus_space_write_4(t, h, CAS_MAC_ATTEMPT_LIMIT, 0x10);
1078
1079 bus_space_write_4(t, h, CAS_MAC_CONTROL_TYPE, 0x8088);
1080 bus_space_write_4(t, h, CAS_MAC_RANDOM_SEED,
1081 ((sc->sc_arpcom.ac_enaddr[5]<<8)|sc->sc_arpcom.ac_enaddr[4])&0x3ff);
1082
1083
1084 for (r = CAS_MAC_ADDR3; r < CAS_MAC_ADDR42; r += 4)
1085 bus_space_write_4(t, h, r, 0);
1086
1087
1088 bus_space_write_4(t, h, CAS_MAC_ADDR42, 0x0001);
1089 bus_space_write_4(t, h, CAS_MAC_ADDR43, 0xc200);
1090 bus_space_write_4(t, h, CAS_MAC_ADDR44, 0x0180);
1091
1092
1093 bus_space_write_4(t, h, CAS_MAC_ADDR_FILTER0, 0);
1094 bus_space_write_4(t, h, CAS_MAC_ADDR_FILTER1, 0);
1095 bus_space_write_4(t, h, CAS_MAC_ADDR_FILTER2, 0);
1096
1097 bus_space_write_4(t, h, CAS_MAC_ADR_FLT_MASK1_2, 0);
1098 bus_space_write_4(t, h, CAS_MAC_ADR_FLT_MASK0, 0);
1099
1100
1101 for (r = CAS_MAC_HASH0; r <= CAS_MAC_HASH15; r += 4)
1102 bus_space_write_4(t, h, r, 0);
1103
1104 sc->sc_inited = 1;
1105 }
1106
1107
1108 bus_space_write_4(t, h, CAS_MAC_NORM_COLL_CNT, 0);
1109 bus_space_write_4(t, h, CAS_MAC_FIRST_COLL_CNT, 0);
1110 bus_space_write_4(t, h, CAS_MAC_EXCESS_COLL_CNT, 0);
1111 bus_space_write_4(t, h, CAS_MAC_LATE_COLL_CNT, 0);
1112 bus_space_write_4(t, h, CAS_MAC_DEFER_TMR_CNT, 0);
1113 bus_space_write_4(t, h, CAS_MAC_PEAK_ATTEMPTS, 0);
1114 bus_space_write_4(t, h, CAS_MAC_RX_FRAME_COUNT, 0);
1115 bus_space_write_4(t, h, CAS_MAC_RX_LEN_ERR_CNT, 0);
1116 bus_space_write_4(t, h, CAS_MAC_RX_ALIGN_ERR, 0);
1117 bus_space_write_4(t, h, CAS_MAC_RX_CRC_ERR_CNT, 0);
1118 bus_space_write_4(t, h, CAS_MAC_RX_CODE_VIOL, 0);
1119
1120
1121 bus_space_write_4(t, h, CAS_MAC_SEND_PAUSE_CMD, 0);
1122
1123
1124
1125
1126 bus_space_write_4(t, h, CAS_MAC_ADDR0,
1127 (sc->sc_arpcom.ac_enaddr[4]<<8) | sc->sc_arpcom.ac_enaddr[5]);
1128 bus_space_write_4(t, h, CAS_MAC_ADDR1,
1129 (sc->sc_arpcom.ac_enaddr[2]<<8) | sc->sc_arpcom.ac_enaddr[3]);
1130 bus_space_write_4(t, h, CAS_MAC_ADDR2,
1131 (sc->sc_arpcom.ac_enaddr[0]<<8) | sc->sc_arpcom.ac_enaddr[1]);
1132 }
1133
1134
1135
1136
1137 int
1138 cas_rint(struct cas_softc *sc)
1139 {
1140 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1141 bus_space_tag_t t = sc->sc_memt;
1142 bus_space_handle_t h = sc->sc_memh;
1143 struct cas_rxsoft *rxs;
1144 struct mbuf *m;
1145 u_int64_t word[4];
1146 int len, off, idx;
1147 int i, skip;
1148 caddr_t cp;
1149
1150 for (i = sc->sc_rxptr;; i = CAS_NEXTRX(i + skip)) {
1151 CAS_CDRXCSYNC(sc, i,
1152 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1153
1154 word[0] = CAS_DMA_READ(sc->sc_rxcomps[i].cc_word[0]);
1155 word[1] = CAS_DMA_READ(sc->sc_rxcomps[i].cc_word[1]);
1156 word[2] = CAS_DMA_READ(sc->sc_rxcomps[i].cc_word[2]);
1157 word[3] = CAS_DMA_READ(sc->sc_rxcomps[i].cc_word[3]);
1158
1159
1160 if ((word[0] & CAS_RC0_TYPE) == 0 || word[3] & CAS_RC3_OWN)
1161 break;
1162
1163 len = CAS_RC1_HDR_LEN(word[1]);
1164 if (len > 0) {
1165 off = CAS_RC1_HDR_OFF(word[1]);
1166 idx = CAS_RC1_HDR_IDX(word[1]);
1167 rxs = &sc->sc_rxsoft[idx];
1168
1169 DPRINTF(sc, ("hdr at idx %d, off %d, len %d\n",
1170 idx, off, len));
1171
1172 bus_dmamap_sync(sc->sc_dmatag, rxs->rxs_dmamap, 0,
1173 rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
1174
1175 cp = rxs->rxs_kva + off * 256;
1176 m = m_devget(cp, len + ETHER_ALIGN, 0, ifp, NULL);
1177
1178 if (word[0] & CAS_RC0_RELEASE_HDR)
1179 cas_add_rxbuf(sc, idx);
1180
1181 if (m != NULL) {
1182 m_adj(m, ETHER_ALIGN);
1183
1184 #if NBPFILTER > 0
1185
1186
1187
1188
1189 if (ifp->if_bpf)
1190 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
1191 #endif
1192
1193 ifp->if_ipackets++;
1194 ether_input_mbuf(ifp, m);
1195 } else
1196 ifp->if_ierrors++;
1197 }
1198
1199 len = CAS_RC0_DATA_LEN(word[0]);
1200 if (len > 0) {
1201 off = CAS_RC0_DATA_OFF(word[0]);
1202 idx = CAS_RC0_DATA_IDX(word[0]);
1203 rxs = &sc->sc_rxsoft[idx];
1204
1205 DPRINTF(sc, ("data at idx %d, off %d, len %d\n",
1206 idx, off, len));
1207
1208 bus_dmamap_sync(sc->sc_dmatag, rxs->rxs_dmamap, 0,
1209 rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
1210
1211
1212 cp = rxs->rxs_kva + off;
1213 m = m_devget(cp, len + ETHER_ALIGN, 0, ifp, NULL);
1214
1215 if (word[0] & CAS_RC0_RELEASE_DATA)
1216 cas_add_rxbuf(sc, idx);
1217
1218 if (m != NULL) {
1219 m_adj(m, ETHER_ALIGN);
1220
1221 #if NBPFILTER > 0
1222
1223
1224
1225
1226 if (ifp->if_bpf)
1227 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
1228 #endif
1229
1230 ifp->if_ipackets++;
1231 ether_input_mbuf(ifp, m);
1232 } else
1233 ifp->if_ierrors++;
1234 }
1235
1236 if (word[0] & CAS_RC0_SPLIT)
1237 printf("split packet\n");
1238
1239 skip = CAS_RC0_SKIP(word[0]);
1240 }
1241
1242 while (sc->sc_rxptr != i) {
1243 sc->sc_rxcomps[sc->sc_rxptr].cc_word[0] = 0;
1244 sc->sc_rxcomps[sc->sc_rxptr].cc_word[1] = 0;
1245 sc->sc_rxcomps[sc->sc_rxptr].cc_word[2] = 0;
1246 sc->sc_rxcomps[sc->sc_rxptr].cc_word[3] =
1247 CAS_DMA_WRITE(CAS_RC3_OWN);
1248 CAS_CDRXCSYNC(sc, sc->sc_rxptr,
1249 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1250
1251 sc->sc_rxptr = CAS_NEXTRX(sc->sc_rxptr);
1252 }
1253
1254 bus_space_write_4(t, h, CAS_RX_COMP_TAIL, sc->sc_rxptr);
1255
1256 DPRINTF(sc, ("cas_rint: done sc->rxptr %d, complete %d\n",
1257 sc->sc_rxptr, bus_space_read_4(t, h, CAS_RX_COMPLETION)));
1258
1259 return (1);
1260 }
1261
1262
1263
1264
1265
1266
1267 int
1268 cas_add_rxbuf(struct cas_softc *sc, int idx)
1269 {
1270 bus_space_tag_t t = sc->sc_memt;
1271 bus_space_handle_t h = sc->sc_memh;
1272
1273 CAS_INIT_RXDESC(sc, sc->sc_rxdptr, idx);
1274
1275 if ((sc->sc_rxdptr % 4) == 0)
1276 bus_space_write_4(t, h, CAS_RX_KICK, sc->sc_rxdptr);
1277
1278 sc->sc_rxdptr++;
1279 return (0);
1280 }
1281
1282 int
1283 cas_eint(struct cas_softc *sc, u_int status)
1284 {
1285 if ((status & CAS_INTR_MIF) != 0) {
1286 #ifdef CAS_DEBUG
1287 printf("%s: link status changed\n", sc->sc_dev.dv_xname);
1288 #endif
1289 return (1);
1290 }
1291
1292 printf("%s: status=%b\n", sc->sc_dev.dv_xname, status, CAS_INTR_BITS);
1293 return (1);
1294 }
1295
1296 int
1297 cas_pint(struct cas_softc *sc)
1298 {
1299 bus_space_tag_t t = sc->sc_memt;
1300 bus_space_handle_t seb = sc->sc_memh;
1301 u_int32_t status;
1302
1303 status = bus_space_read_4(t, seb, CAS_MII_INTERRUP_STATUS);
1304 status |= bus_space_read_4(t, seb, CAS_MII_INTERRUP_STATUS);
1305 #ifdef CAS_DEBUG
1306 if (status)
1307 printf("%s: link status changed\n", sc->sc_dev.dv_xname);
1308 #endif
1309 return (1);
1310 }
1311
1312 int
1313 cas_intr(void *v)
1314 {
1315 struct cas_softc *sc = (struct cas_softc *)v;
1316 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1317 bus_space_tag_t t = sc->sc_memt;
1318 bus_space_handle_t seb = sc->sc_memh;
1319 u_int32_t status;
1320 int r = 0;
1321
1322 status = bus_space_read_4(t, seb, CAS_STATUS);
1323 DPRINTF(sc, ("%s: cas_intr: cplt %xstatus %b\n",
1324 sc->sc_dev.dv_xname, (status>>19), status, CAS_INTR_BITS));
1325
1326 if ((status & CAS_INTR_PCS) != 0)
1327 r |= cas_pint(sc);
1328
1329 if ((status & (CAS_INTR_TX_TAG_ERR | CAS_INTR_RX_TAG_ERR |
1330 CAS_INTR_RX_COMP_FULL | CAS_INTR_BERR)) != 0)
1331 r |= cas_eint(sc, status);
1332
1333 if ((status & (CAS_INTR_TX_EMPTY | CAS_INTR_TX_INTME)) != 0)
1334 r |= cas_tint(sc, status);
1335
1336 if ((status & (CAS_INTR_RX_DONE | CAS_INTR_RX_NOBUF)) != 0)
1337 r |= cas_rint(sc);
1338
1339
1340 if (status & CAS_INTR_TX_MAC) {
1341 int txstat = bus_space_read_4(t, seb, CAS_MAC_TX_STATUS);
1342 #ifdef CAS_DEBUG
1343 if (txstat & ~CAS_MAC_TX_XMIT_DONE)
1344 printf("%s: MAC tx fault, status %x\n",
1345 sc->sc_dev.dv_xname, txstat);
1346 #endif
1347 if (txstat & (CAS_MAC_TX_UNDERRUN | CAS_MAC_TX_PKT_TOO_LONG))
1348 cas_init(ifp);
1349 }
1350 if (status & CAS_INTR_RX_MAC) {
1351 int rxstat = bus_space_read_4(t, seb, CAS_MAC_RX_STATUS);
1352 #ifdef CAS_DEBUG
1353 if (rxstat & ~CAS_MAC_RX_DONE)
1354 printf("%s: MAC rx fault, status %x\n",
1355 sc->sc_dev.dv_xname, rxstat);
1356 #endif
1357
1358
1359
1360
1361 if (rxstat & CAS_MAC_RX_OVERFLOW) {
1362 ifp->if_ierrors++;
1363 cas_init(ifp);
1364 }
1365 #ifdef CAS_DEBUG
1366 else if (rxstat & ~(CAS_MAC_RX_DONE | CAS_MAC_RX_FRAME_CNT))
1367 printf("%s: MAC rx fault, status %x\n",
1368 sc->sc_dev.dv_xname, rxstat);
1369 #endif
1370 }
1371 return (r);
1372 }
1373
1374
1375 void
1376 cas_watchdog(struct ifnet *ifp)
1377 {
1378 struct cas_softc *sc = ifp->if_softc;
1379
1380 DPRINTF(sc, ("cas_watchdog: CAS_RX_CONFIG %x CAS_MAC_RX_STATUS %x "
1381 "CAS_MAC_RX_CONFIG %x\n",
1382 bus_space_read_4(sc->sc_memt, sc->sc_memh, CAS_RX_CONFIG),
1383 bus_space_read_4(sc->sc_memt, sc->sc_memh, CAS_MAC_RX_STATUS),
1384 bus_space_read_4(sc->sc_memt, sc->sc_memh, CAS_MAC_RX_CONFIG)));
1385
1386 log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
1387 ++ifp->if_oerrors;
1388
1389
1390 cas_init(ifp);
1391 }
1392
1393
1394
1395
1396 void
1397 cas_mifinit(struct cas_softc *sc)
1398 {
1399 bus_space_tag_t t = sc->sc_memt;
1400 bus_space_handle_t mif = sc->sc_memh;
1401
1402
1403 sc->sc_mif_config = bus_space_read_4(t, mif, CAS_MIF_CONFIG);
1404 sc->sc_mif_config &= ~CAS_MIF_CONFIG_BB_ENA;
1405 bus_space_write_4(t, mif, CAS_MIF_CONFIG, sc->sc_mif_config);
1406 }
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422 int
1423 cas_mii_readreg(struct device *self, int phy, int reg)
1424 {
1425 struct cas_softc *sc = (void *)self;
1426 bus_space_tag_t t = sc->sc_memt;
1427 bus_space_handle_t mif = sc->sc_memh;
1428 int n;
1429 u_int32_t v;
1430
1431 #ifdef CAS_DEBUG
1432 if (sc->sc_debug)
1433 printf("cas_mii_readreg: phy %d reg %d\n", phy, reg);
1434 #endif
1435
1436
1437 v = (reg << CAS_MIF_REG_SHIFT) | (phy << CAS_MIF_PHY_SHIFT) |
1438 CAS_MIF_FRAME_READ;
1439
1440 bus_space_write_4(t, mif, CAS_MIF_FRAME, v);
1441 for (n = 0; n < 100; n++) {
1442 DELAY(1);
1443 v = bus_space_read_4(t, mif, CAS_MIF_FRAME);
1444 if (v & CAS_MIF_FRAME_TA0)
1445 return (v & CAS_MIF_FRAME_DATA);
1446 }
1447
1448 printf("%s: mii_read timeout\n", sc->sc_dev.dv_xname);
1449 return (0);
1450 }
1451
1452 void
1453 cas_mii_writereg(struct device *self, int phy, int reg, int val)
1454 {
1455 struct cas_softc *sc = (void *)self;
1456 bus_space_tag_t t = sc->sc_memt;
1457 bus_space_handle_t mif = sc->sc_memh;
1458 int n;
1459 u_int32_t v;
1460
1461 #ifdef CAS_DEBUG
1462 if (sc->sc_debug)
1463 printf("cas_mii_writereg: phy %d reg %d val %x\n",
1464 phy, reg, val);
1465 #endif
1466
1467 #if 0
1468
1469 v = bus_space_read_4(t, mif, CAS_MIF_CONFIG);
1470
1471 v &= ~CAS_MIF_CONFIG_PHY_SEL;
1472 if (phy == CAS_PHYAD_EXTERNAL)
1473
1474 v |= CAS_MIF_CONFIG_PHY_SEL;
1475 bus_space_write_4(t, mif, CAS_MIF_CONFIG, v);
1476 #endif
1477
1478 v = CAS_MIF_FRAME_WRITE |
1479 (phy << CAS_MIF_PHY_SHIFT) |
1480 (reg << CAS_MIF_REG_SHIFT) |
1481 (val & CAS_MIF_FRAME_DATA);
1482
1483 bus_space_write_4(t, mif, CAS_MIF_FRAME, v);
1484 for (n = 0; n < 100; n++) {
1485 DELAY(1);
1486 v = bus_space_read_4(t, mif, CAS_MIF_FRAME);
1487 if (v & CAS_MIF_FRAME_TA0)
1488 return;
1489 }
1490
1491 printf("%s: mii_write timeout\n", sc->sc_dev.dv_xname);
1492 }
1493
1494 void
1495 cas_mii_statchg(struct device *dev)
1496 {
1497 struct cas_softc *sc = (void *)dev;
1498 #ifdef CAS_DEBUG
1499 int instance = IFM_INST(sc->sc_mii.mii_media.ifm_cur->ifm_media);
1500 #endif
1501 bus_space_tag_t t = sc->sc_memt;
1502 bus_space_handle_t mac = sc->sc_memh;
1503 u_int32_t v;
1504
1505 #ifdef CAS_DEBUG
1506 if (sc->sc_debug)
1507 printf("cas_mii_statchg: status change: phy = %d\n",
1508 sc->sc_phys[instance]);
1509 #endif
1510
1511
1512 bus_space_write_4(t, mac, CAS_MAC_TX_CONFIG, 0);
1513 delay(10000);
1514 v = CAS_MAC_TX_ENA_IPG0|CAS_MAC_TX_NGU|CAS_MAC_TX_NGU_LIMIT|
1515 CAS_MAC_TX_ENABLE;
1516 if ((IFM_OPTIONS(sc->sc_mii.mii_media_active) & IFM_FDX) != 0) {
1517 v |= CAS_MAC_TX_IGN_CARRIER|CAS_MAC_TX_IGN_COLLIS;
1518 }
1519 bus_space_write_4(t, mac, CAS_MAC_TX_CONFIG, v);
1520
1521
1522 v = CAS_MAC_XIF_TX_MII_ENA;
1523 v |= CAS_MAC_XIF_LINK_LED;
1524
1525
1526 if ((IFM_OPTIONS(sc->sc_mii.mii_media_active) & IFM_FDX) != 0)
1527
1528 v |= CAS_MAC_XIF_FDPLX_LED;
1529 else
1530
1531 v |= CAS_MAC_XIF_ECHO_DISABL;
1532
1533 switch (IFM_SUBTYPE(sc->sc_mii.mii_media_active)) {
1534 case IFM_1000_T:
1535 case IFM_1000_SX:
1536 v |= CAS_MAC_XIF_GMII_MODE;
1537 break;
1538 default:
1539 v &= ~CAS_MAC_XIF_GMII_MODE;
1540 }
1541 bus_space_write_4(t, mac, CAS_MAC_XIF_CONFIG, v);
1542 }
1543
1544 int
1545 cas_pcs_readreg(struct device *self, int phy, int reg)
1546 {
1547 struct cas_softc *sc = (void *)self;
1548 bus_space_tag_t t = sc->sc_memt;
1549 bus_space_handle_t pcs = sc->sc_memh;
1550
1551 #ifdef CAS_DEBUG
1552 if (sc->sc_debug)
1553 printf("cas_pcs_readreg: phy %d reg %d\n", phy, reg);
1554 #endif
1555
1556 if (phy != CAS_PHYAD_EXTERNAL)
1557 return (0);
1558
1559 switch (reg) {
1560 case MII_BMCR:
1561 reg = CAS_MII_CONTROL;
1562 break;
1563 case MII_BMSR:
1564 reg = CAS_MII_STATUS;
1565 break;
1566 case MII_ANAR:
1567 reg = CAS_MII_ANAR;
1568 break;
1569 case MII_ANLPAR:
1570 reg = CAS_MII_ANLPAR;
1571 break;
1572 case MII_EXTSR:
1573 return (EXTSR_1000XFDX|EXTSR_1000XHDX);
1574 default:
1575 return (0);
1576 }
1577
1578 return bus_space_read_4(t, pcs, reg);
1579 }
1580
1581 void
1582 cas_pcs_writereg(struct device *self, int phy, int reg, int val)
1583 {
1584 struct cas_softc *sc = (void *)self;
1585 bus_space_tag_t t = sc->sc_memt;
1586 bus_space_handle_t pcs = sc->sc_memh;
1587
1588 #ifdef CAS_DEBUG
1589 if (sc->sc_debug)
1590 printf("cas_pcs_writereg: phy %d reg %d val %x\n",
1591 phy, reg, val);
1592 #endif
1593
1594 if (phy != CAS_PHYAD_EXTERNAL)
1595 return;
1596
1597 switch (reg) {
1598 case MII_BMCR:
1599 reg = CAS_MII_CONTROL;
1600 break;
1601 case MII_BMSR:
1602 reg = CAS_MII_STATUS;
1603 break;
1604 case MII_ANAR:
1605 reg = CAS_MII_ANAR;
1606 break;
1607 case MII_ANLPAR:
1608 reg = CAS_MII_ANLPAR;
1609 break;
1610 default:
1611 return;
1612 }
1613
1614 bus_space_write_4(t, pcs, reg, val);
1615
1616 if (reg == CAS_MII_ANAR) {
1617 bus_space_write_4(t, pcs, CAS_MII_SLINK_CONTROL,
1618 CAS_MII_SLINK_LOOPBACK|CAS_MII_SLINK_EN_SYNC_D);
1619 bus_space_write_4(t, pcs, CAS_MII_CONFIG,
1620 CAS_MII_CONFIG_ENABLE);
1621 }
1622 }
1623
1624 int
1625 cas_mediachange(struct ifnet *ifp)
1626 {
1627 struct cas_softc *sc = ifp->if_softc;
1628 struct mii_data *mii = &sc->sc_mii;
1629
1630 if (mii->mii_instance) {
1631 struct mii_softc *miisc;
1632 LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
1633 mii_phy_reset(miisc);
1634 }
1635
1636 return (mii_mediachg(&sc->sc_mii));
1637 }
1638
1639 void
1640 cas_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
1641 {
1642 struct cas_softc *sc = ifp->if_softc;
1643
1644 mii_pollstat(&sc->sc_mii);
1645 ifmr->ifm_active = sc->sc_mii.mii_media_active;
1646 ifmr->ifm_status = sc->sc_mii.mii_media_status;
1647 }
1648
1649
1650
1651
1652 int
1653 cas_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1654 {
1655 struct cas_softc *sc = ifp->if_softc;
1656 struct ifaddr *ifa = (struct ifaddr *)data;
1657 struct ifreq *ifr = (struct ifreq *)data;
1658 int s, error = 0;
1659
1660 s = splnet();
1661
1662 if ((error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data)) > 0) {
1663 splx(s);
1664 return (error);
1665 }
1666
1667 switch (cmd) {
1668
1669 case SIOCSIFADDR:
1670 ifp->if_flags |= IFF_UP;
1671 if ((ifp->if_flags & IFF_RUNNING) == 0)
1672 cas_init(ifp);
1673 #ifdef INET
1674 if (ifa->ifa_addr->sa_family == AF_INET)
1675 arp_ifinit(&sc->sc_arpcom, ifa);
1676 #endif
1677 break;
1678
1679 case SIOCSIFFLAGS:
1680 if (ifp->if_flags & IFF_UP) {
1681 if ((ifp->if_flags & IFF_RUNNING) &&
1682 ((ifp->if_flags ^ sc->sc_if_flags) &
1683 (IFF_ALLMULTI | IFF_PROMISC)) != 0)
1684 cas_setladrf(sc);
1685 else {
1686 if ((ifp->if_flags & IFF_RUNNING) == 0)
1687 cas_init(ifp);
1688 }
1689 } else {
1690 if (ifp->if_flags & IFF_RUNNING)
1691 cas_stop(ifp, 1);
1692 }
1693 sc->sc_if_flags = ifp->if_flags;
1694
1695 #ifdef CAS_DEBUG
1696 sc->sc_debug = (ifp->if_flags & IFF_DEBUG) != 0 ? 1 : 0;
1697 #endif
1698 break;
1699
1700 case SIOCSIFMTU:
1701 if (ifr->ifr_mtu > ETHERMTU || ifr->ifr_mtu < ETHERMIN) {
1702 error = EINVAL;
1703 } else if (ifp->if_mtu != ifr->ifr_mtu) {
1704 ifp->if_mtu = ifr->ifr_mtu;
1705 }
1706 break;
1707
1708 case SIOCADDMULTI:
1709 case SIOCDELMULTI:
1710 error = (cmd == SIOCADDMULTI) ?
1711 ether_addmulti(ifr, &sc->sc_arpcom) :
1712 ether_delmulti(ifr, &sc->sc_arpcom);
1713
1714 if (error == ENETRESET) {
1715
1716
1717
1718
1719 if (ifp->if_flags & IFF_RUNNING)
1720 cas_setladrf(sc);
1721 error = 0;
1722 }
1723 break;
1724
1725 case SIOCGIFMEDIA:
1726 case SIOCSIFMEDIA:
1727 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
1728 break;
1729
1730 default:
1731 error = EINVAL;
1732 break;
1733 }
1734
1735 splx(s);
1736 return (error);
1737 }
1738
1739
1740 void
1741 cas_shutdown(void *arg)
1742 {
1743 struct cas_softc *sc = (struct cas_softc *)arg;
1744 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1745
1746 cas_stop(ifp, 1);
1747 }
1748
1749
1750
1751
1752 void
1753 cas_setladrf(struct cas_softc *sc)
1754 {
1755 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1756 struct ether_multi *enm;
1757 struct ether_multistep step;
1758 struct arpcom *ac = &sc->sc_arpcom;
1759 bus_space_tag_t t = sc->sc_memt;
1760 bus_space_handle_t h = sc->sc_memh;
1761 u_int32_t crc, hash[16], v;
1762 int i;
1763
1764
1765 v = bus_space_read_4(t, h, CAS_MAC_RX_CONFIG);
1766
1767
1768
1769
1770
1771
1772
1773 v &= ~(CAS_MAC_RX_PROMISCUOUS|CAS_MAC_RX_HASH_FILTER|
1774 CAS_MAC_RX_PROMISC_GRP);
1775
1776 if ((ifp->if_flags & IFF_PROMISC) != 0) {
1777
1778 v |= CAS_MAC_RX_PROMISCUOUS;
1779 ifp->if_flags |= IFF_ALLMULTI;
1780 goto chipit;
1781 }
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792 for (i = 0; i < 16; i++)
1793 hash[i] = 0;
1794
1795
1796 ETHER_FIRST_MULTI(step, ac, enm);
1797 while (enm != NULL) {
1798 if (bcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808 ifp->if_flags |= IFF_ALLMULTI;
1809 v |= CAS_MAC_RX_PROMISC_GRP;
1810 goto chipit;
1811 }
1812
1813 crc = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN);
1814
1815
1816 crc >>= 24;
1817
1818
1819 hash[crc >> 4] |= 1 << (15 - (crc & 15));
1820
1821 ETHER_NEXT_MULTI(step, enm);
1822 }
1823
1824 v |= CAS_MAC_RX_HASH_FILTER;
1825 ifp->if_flags &= ~IFF_ALLMULTI;
1826
1827
1828 for (i = 0; i < 16; i++) {
1829 bus_space_write_4(t, h,
1830 CAS_MAC_HASH0 + i * (CAS_MAC_HASH1-CAS_MAC_HASH0),
1831 hash[i]);
1832 }
1833
1834 chipit:
1835 bus_space_write_4(t, h, CAS_MAC_RX_CONFIG, v);
1836 }
1837
1838 int
1839 cas_encap(struct cas_softc *sc, struct mbuf *mhead, u_int32_t *bixp)
1840 {
1841 u_int64_t flags;
1842 u_int32_t cur, frag, i;
1843 bus_dmamap_t map;
1844
1845 cur = frag = *bixp;
1846 map = sc->sc_txd[cur].sd_map;
1847
1848 if (bus_dmamap_load_mbuf(sc->sc_dmatag, map, mhead,
1849 BUS_DMA_NOWAIT) != 0) {
1850 return (ENOBUFS);
1851 }
1852
1853 if ((sc->sc_tx_cnt + map->dm_nsegs) > (CAS_NTXDESC - 2)) {
1854 bus_dmamap_unload(sc->sc_dmatag, map);
1855 return (ENOBUFS);
1856 }
1857
1858 bus_dmamap_sync(sc->sc_dmatag, map, 0, map->dm_mapsize,
1859 BUS_DMASYNC_PREWRITE);
1860
1861 for (i = 0; i < map->dm_nsegs; i++) {
1862 sc->sc_txdescs[frag].cd_addr =
1863 CAS_DMA_WRITE(map->dm_segs[i].ds_addr);
1864 flags = (map->dm_segs[i].ds_len & CAS_TD_BUFSIZE) |
1865 (i == 0 ? CAS_TD_START_OF_PACKET : 0) |
1866 ((i == (map->dm_nsegs - 1)) ? CAS_TD_END_OF_PACKET : 0);
1867 sc->sc_txdescs[frag].cd_flags = CAS_DMA_WRITE(flags);
1868 bus_dmamap_sync(sc->sc_dmatag, sc->sc_cddmamap,
1869 CAS_CDTXOFF(frag), sizeof(struct cas_desc),
1870 BUS_DMASYNC_PREWRITE);
1871 cur = frag;
1872 if (++frag == CAS_NTXDESC)
1873 frag = 0;
1874 }
1875
1876 sc->sc_tx_cnt += map->dm_nsegs;
1877 sc->sc_txd[*bixp].sd_map = sc->sc_txd[cur].sd_map;
1878 sc->sc_txd[cur].sd_map = map;
1879 sc->sc_txd[cur].sd_mbuf = mhead;
1880
1881 bus_space_write_4(sc->sc_memt, sc->sc_memh, CAS_TX_KICK, frag);
1882
1883 *bixp = frag;
1884
1885
1886
1887 return (0);
1888 }
1889
1890
1891
1892
1893 int
1894 cas_tint(struct cas_softc *sc, u_int32_t status)
1895 {
1896 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1897 struct cas_sxd *sd;
1898 u_int32_t cons, hwcons;
1899
1900 hwcons = status >> 19;
1901 cons = sc->sc_tx_cons;
1902 while (cons != hwcons) {
1903 sd = &sc->sc_txd[cons];
1904 if (sd->sd_mbuf != NULL) {
1905 bus_dmamap_sync(sc->sc_dmatag, sd->sd_map, 0,
1906 sd->sd_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
1907 bus_dmamap_unload(sc->sc_dmatag, sd->sd_map);
1908 m_freem(sd->sd_mbuf);
1909 sd->sd_mbuf = NULL;
1910 }
1911 sc->sc_tx_cnt--;
1912 ifp->if_opackets++;
1913 if (++cons == CAS_NTXDESC)
1914 cons = 0;
1915 }
1916 sc->sc_tx_cons = cons;
1917
1918 cas_start(ifp);
1919
1920 if (sc->sc_tx_cnt == 0)
1921 ifp->if_timer = 0;
1922
1923 return (1);
1924 }
1925
1926 void
1927 cas_start(struct ifnet *ifp)
1928 {
1929 struct cas_softc *sc = ifp->if_softc;
1930 struct mbuf *m;
1931 u_int32_t bix;
1932
1933 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
1934 return;
1935
1936 bix = sc->sc_tx_prod;
1937 while (sc->sc_txd[bix].sd_mbuf == NULL) {
1938 IFQ_POLL(&ifp->if_snd, m);
1939 if (m == NULL)
1940 break;
1941
1942 #if NBPFILTER > 0
1943
1944
1945
1946
1947 if (ifp->if_bpf)
1948 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
1949 #endif
1950
1951
1952
1953
1954
1955 if (cas_encap(sc, m, &bix)) {
1956 ifp->if_timer = 2;
1957 break;
1958 }
1959
1960 IFQ_DEQUEUE(&ifp->if_snd, m);
1961 ifp->if_timer = 5;
1962 }
1963
1964 sc->sc_tx_prod = bix;
1965 }