Lines Matching +full:multi +full:- +full:cluster
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2012-2014 Thomas Skibo <thomasskibo@yahoo.com>
31 * interface such as the one used in Xilinx Zynq-7000 SoC.
33 * Reference: Zynq-7000 All Programmable SoC Technical Reference Manual.
106 { "cdns,zynq-gem", HWQUIRK_RXHANGWAR }, /* Deprecated */
107 { "cdns,zynqmp-gem", HWQUIRK_NEEDNULLQS }, /* Deprecated */
108 { "xlnx,zynq-gem", HWQUIRK_RXHANGWAR },
109 { "xlnx,zynqmp-gem", HWQUIRK_NEEDNULLQS },
110 { "microchip,mpfs-mss-gem", HWQUIRK_NEEDNULLQS },
111 { "sifive,fu540-c000-gem", HWQUIRK_NONE },
112 { "sifive,fu740-c000-gem", HWQUIRK_NONE },
150 int rxhangwar; /* rx hang work-around */
220 #define RD4(sc, off) (bus_read_4((sc)->mem_res, (off)))
221 #define WR4(sc, off, val) (bus_write_4((sc)->mem_res, (off), (val)))
223 (bus_barrier((sc)->mem_res, (off), (len), (flags))
225 #define CGEM_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
226 #define CGEM_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
227 #define CGEM_LOCK_INIT(sc) mtx_init(&(sc)->sc_mtx, \
228 device_get_nameunit((sc)->dev), MTX_NETWORK_LOCK, MTX_DEF)
229 #define CGEM_LOCK_DESTROY(sc) mtx_destroy(&(sc)->sc_mtx)
230 #define CGEM_ASSERT_LOCKED(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED)
275 device_printf(sc->dev, "no mac address found, assigning " in cgem_get_mac()
292 * cgem_mac_hash(): map 48-bit address to a 6-bit hash. The 6-bit hash
293 * corresponds to a bit in a 64-bit hash register. Setting that bit in the
295 * that hashes to that 6-bit value.
297 * The hash function is described in sec. 16.2.3 in the Zynq-7000 Tech
298 * Reference Manual. Bits 0-5 in the hash are the exclusive-or of
324 hashes[0] |= (1U << (index - 32)); in cgem_hash_maddr()
332 * After any change in rx flags or multi-cast addresses, set up hash registers
338 if_t ifp = sc->ifp; in cgem_rx_filter()
341 sc->net_cfg_shadow &= ~(CGEM_NET_CFG_MULTI_HASH_EN | in cgem_rx_filter()
345 sc->net_cfg_shadow |= CGEM_NET_CFG_COPY_ALL; in cgem_rx_filter()
348 sc->net_cfg_shadow |= CGEM_NET_CFG_NO_BCAST; in cgem_rx_filter()
356 sc->net_cfg_shadow |= CGEM_NET_CFG_MULTI_HASH_EN; in cgem_rx_filter()
361 WR4(sc, CGEM_NET_CFG, sc->net_cfg_shadow); in cgem_rx_filter()
390 memset(sc->null_qs, 0, sizeof(struct cgem_rx_desc) + in cgem_null_qs()
392 rx_desc = sc->null_qs; in cgem_null_qs()
393 rx_desc->addr = CGEM_RXDESC_OWN | CGEM_RXDESC_WRAP; in cgem_null_qs()
395 tx_desc->ctl = CGEM_TXDESC_USED | CGEM_TXDESC_WRAP; in cgem_null_qs()
399 WR4(sc, CGEM_RX_QN_BAR(n), sc->null_qs_physaddr); in cgem_null_qs()
400 WR4(sc, CGEM_TX_QN_BAR(n), sc->null_qs_physaddr + in cgem_null_qs()
413 if (sc->neednullqs) in cgem_setup_descs()
417 sc->txring = NULL; in cgem_setup_descs()
418 sc->rxring = NULL; in cgem_setup_descs()
420 /* Allocate non-cached DMA space for RX and TX descriptors. */ in cgem_setup_descs()
421 err = bus_dma_tag_create(bus_get_dma_tag(sc->dev), 1, in cgem_setup_descs()
429 busdma_lock_mutex, &sc->sc_mtx, &sc->desc_dma_tag); in cgem_setup_descs()
434 err = bus_dma_tag_create(bus_get_dma_tag(sc->dev), 1, 0, in cgem_setup_descs()
436 TX_MAX_DMA_SEGS, MCLBYTES, 0, busdma_lock_mutex, &sc->sc_mtx, in cgem_setup_descs()
437 &sc->mbuf_dma_tag); in cgem_setup_descs()
447 err = bus_dmamem_alloc(sc->desc_dma_tag, (void **)&sc->rxring, in cgem_setup_descs()
449 &sc->rxring_dma_map); in cgem_setup_descs()
454 err = bus_dmamap_load(sc->desc_dma_tag, sc->rxring_dma_map, in cgem_setup_descs()
455 (void *)sc->rxring, desc_rings_size, in cgem_setup_descs()
456 cgem_getaddr, &sc->rxring_physaddr, BUS_DMA_NOWAIT); in cgem_setup_descs()
462 sc->rxring[i].addr = CGEM_RXDESC_OWN; in cgem_setup_descs()
463 sc->rxring[i].ctl = 0; in cgem_setup_descs()
464 sc->rxring_m[i] = NULL; in cgem_setup_descs()
465 sc->rxring_m_dmamap[i] = NULL; in cgem_setup_descs()
467 sc->rxring[CGEM_NUM_RX_DESCS - 1].addr |= CGEM_RXDESC_WRAP; in cgem_setup_descs()
469 sc->rxring_hd_ptr = 0; in cgem_setup_descs()
470 sc->rxring_tl_ptr = 0; in cgem_setup_descs()
471 sc->rxring_queued = 0; in cgem_setup_descs()
473 sc->txring = (struct cgem_tx_desc *)(sc->rxring + CGEM_NUM_RX_DESCS); in cgem_setup_descs()
474 sc->txring_physaddr = sc->rxring_physaddr + CGEM_NUM_RX_DESCS * in cgem_setup_descs()
479 sc->txring[i].addr = 0; in cgem_setup_descs()
480 sc->txring[i].ctl = CGEM_TXDESC_USED; in cgem_setup_descs()
481 sc->txring_m[i] = NULL; in cgem_setup_descs()
482 sc->txring_m_dmamap[i] = NULL; in cgem_setup_descs()
484 sc->txring[CGEM_NUM_TX_DESCS - 1].ctl |= CGEM_TXDESC_WRAP; in cgem_setup_descs()
486 sc->txring_hd_ptr = 0; in cgem_setup_descs()
487 sc->txring_tl_ptr = 0; in cgem_setup_descs()
488 sc->txring_queued = 0; in cgem_setup_descs()
490 if (sc->neednullqs) { in cgem_setup_descs()
491 sc->null_qs = (void *)(sc->txring + CGEM_NUM_TX_DESCS); in cgem_setup_descs()
492 sc->null_qs_physaddr = sc->txring_physaddr + in cgem_setup_descs()
511 while (sc->rxring_queued < sc->rxbufs) { in cgem_fill_rqueue()
512 /* Get a cluster mbuf. */ in cgem_fill_rqueue()
517 m->m_len = MCLBYTES; in cgem_fill_rqueue()
518 m->m_pkthdr.len = MCLBYTES; in cgem_fill_rqueue()
519 m->m_pkthdr.rcvif = sc->ifp; in cgem_fill_rqueue()
522 if (bus_dmamap_create(sc->mbuf_dma_tag, 0, in cgem_fill_rqueue()
523 &sc->rxring_m_dmamap[sc->rxring_hd_ptr])) { in cgem_fill_rqueue()
524 sc->rxdmamapfails++; in cgem_fill_rqueue()
528 if (bus_dmamap_load_mbuf_sg(sc->mbuf_dma_tag, in cgem_fill_rqueue()
529 sc->rxring_m_dmamap[sc->rxring_hd_ptr], m, in cgem_fill_rqueue()
531 sc->rxdmamapfails++; in cgem_fill_rqueue()
532 bus_dmamap_destroy(sc->mbuf_dma_tag, in cgem_fill_rqueue()
533 sc->rxring_m_dmamap[sc->rxring_hd_ptr]); in cgem_fill_rqueue()
534 sc->rxring_m_dmamap[sc->rxring_hd_ptr] = NULL; in cgem_fill_rqueue()
538 sc->rxring_m[sc->rxring_hd_ptr] = m; in cgem_fill_rqueue()
541 bus_dmamap_sync(sc->mbuf_dma_tag, in cgem_fill_rqueue()
542 sc->rxring_m_dmamap[sc->rxring_hd_ptr], in cgem_fill_rqueue()
546 sc->rxring[sc->rxring_hd_ptr].ctl = 0; in cgem_fill_rqueue()
548 sc->rxring[sc->rxring_hd_ptr].addrhi = segs[0].ds_addr >> 32; in cgem_fill_rqueue()
550 if (sc->rxring_hd_ptr == CGEM_NUM_RX_DESCS - 1) { in cgem_fill_rqueue()
551 sc->rxring[sc->rxring_hd_ptr].addr = segs[0].ds_addr | in cgem_fill_rqueue()
553 sc->rxring_hd_ptr = 0; in cgem_fill_rqueue()
555 sc->rxring[sc->rxring_hd_ptr++].addr = segs[0].ds_addr; in cgem_fill_rqueue()
557 sc->rxring_queued++; in cgem_fill_rqueue()
565 if_t ifp = sc->ifp; in cgem_recv()
574 while (sc->rxring_queued > 0 && in cgem_recv()
575 (sc->rxring[sc->rxring_tl_ptr].addr & CGEM_RXDESC_OWN) != 0) { in cgem_recv()
576 ctl = sc->rxring[sc->rxring_tl_ptr].ctl; in cgem_recv()
579 m = sc->rxring_m[sc->rxring_tl_ptr]; in cgem_recv()
580 sc->rxring_m[sc->rxring_tl_ptr] = NULL; in cgem_recv()
583 bus_dmamap_sync(sc->mbuf_dma_tag, in cgem_recv()
584 sc->rxring_m_dmamap[sc->rxring_tl_ptr], in cgem_recv()
588 bus_dmamap_unload(sc->mbuf_dma_tag, in cgem_recv()
589 sc->rxring_m_dmamap[sc->rxring_tl_ptr]); in cgem_recv()
590 bus_dmamap_destroy(sc->mbuf_dma_tag, in cgem_recv()
591 sc->rxring_m_dmamap[sc->rxring_tl_ptr]); in cgem_recv()
592 sc->rxring_m_dmamap[sc->rxring_tl_ptr] = NULL; in cgem_recv()
595 if (++sc->rxring_tl_ptr == CGEM_NUM_RX_DESCS) in cgem_recv()
596 sc->rxring_tl_ptr = 0; in cgem_recv()
597 sc->rxring_queued--; in cgem_recv()
601 * cluster (which is much bigger than the largest ethernet in cgem_recv()
614 m->m_data += ETHER_ALIGN; in cgem_recv()
615 m->m_len = (ctl & CGEM_RXDESC_LENGTH_MASK); in cgem_recv()
616 m->m_pkthdr.rcvif = ifp; in cgem_recv()
617 m->m_pkthdr.len = m->m_len; in cgem_recv()
629 m->m_pkthdr.csum_flags |= in cgem_recv()
632 m->m_pkthdr.csum_data = 0xffff; in cgem_recv()
636 m->m_pkthdr.csum_flags |= in cgem_recv()
638 m->m_pkthdr.csum_data = 0xffff; in cgem_recv()
644 m_tl = &m->m_next; in cgem_recv()
654 m_hd = m_hd->m_next; in cgem_recv()
655 m->m_next = NULL; in cgem_recv()
672 while (sc->txring_queued > 0 && in cgem_clean_tx()
673 ((ctl = sc->txring[sc->txring_tl_ptr].ctl) & in cgem_clean_tx()
676 bus_dmamap_sync(sc->mbuf_dma_tag, in cgem_clean_tx()
677 sc->txring_m_dmamap[sc->txring_tl_ptr], in cgem_clean_tx()
681 bus_dmamap_unload(sc->mbuf_dma_tag, in cgem_clean_tx()
682 sc->txring_m_dmamap[sc->txring_tl_ptr]); in cgem_clean_tx()
683 bus_dmamap_destroy(sc->mbuf_dma_tag, in cgem_clean_tx()
684 sc->txring_m_dmamap[sc->txring_tl_ptr]); in cgem_clean_tx()
685 sc->txring_m_dmamap[sc->txring_tl_ptr] = NULL; in cgem_clean_tx()
688 m = sc->txring_m[sc->txring_tl_ptr]; in cgem_clean_tx()
689 sc->txring_m[sc->txring_tl_ptr] = NULL; in cgem_clean_tx()
696 device_printf(sc->dev, in cgem_clean_tx()
698 sc->txring[sc->txring_tl_ptr].addrhi, in cgem_clean_tx()
699 sc->txring[sc->txring_tl_ptr].addr); in cgem_clean_tx()
701 device_printf(sc->dev, in cgem_clean_tx()
703 sc->txring[sc->txring_tl_ptr].addr); in cgem_clean_tx()
707 if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1); in cgem_clean_tx()
709 if_inc_counter(sc->ifp, IFCOUNTER_OPACKETS, 1); in cgem_clean_tx()
714 * start-of-frame descriptors are processed. in cgem_clean_tx()
718 sc->txring_tl_ptr = 0; in cgem_clean_tx()
720 sc->txring_tl_ptr++; in cgem_clean_tx()
721 sc->txring_queued--; in cgem_clean_tx()
723 ctl = sc->txring[sc->txring_tl_ptr].ctl; in cgem_clean_tx()
725 sc->txring[sc->txring_tl_ptr].ctl = in cgem_clean_tx()
731 sc->txring_tl_ptr = 0; in cgem_clean_tx()
733 sc->txring_tl_ptr++; in cgem_clean_tx()
734 sc->txring_queued--; in cgem_clean_tx()
736 if_setdrvflagbits(sc->ifp, 0, IFF_DRV_OACTIVE); in cgem_clean_tx()
757 if (sc->txring_queued >= in cgem_start_locked()
758 CGEM_NUM_TX_DESCS - TX_MAX_DMA_SEGS * 2) { in cgem_start_locked()
763 if (sc->txring_queued >= in cgem_start_locked()
764 CGEM_NUM_TX_DESCS - TX_MAX_DMA_SEGS * 2) { in cgem_start_locked()
766 sc->txfull++; in cgem_start_locked()
777 if (bus_dmamap_create(sc->mbuf_dma_tag, 0, in cgem_start_locked()
778 &sc->txring_m_dmamap[sc->txring_hd_ptr])) { in cgem_start_locked()
780 sc->txdmamapfails++; in cgem_start_locked()
783 err = bus_dmamap_load_mbuf_sg(sc->mbuf_dma_tag, in cgem_start_locked()
784 sc->txring_m_dmamap[sc->txring_hd_ptr], m, segs, &nsegs, in cgem_start_locked()
791 sc->txdefragfails++; in cgem_start_locked()
793 bus_dmamap_destroy(sc->mbuf_dma_tag, in cgem_start_locked()
794 sc->txring_m_dmamap[sc->txring_hd_ptr]); in cgem_start_locked()
795 sc->txring_m_dmamap[sc->txring_hd_ptr] = NULL; in cgem_start_locked()
799 err = bus_dmamap_load_mbuf_sg(sc->mbuf_dma_tag, in cgem_start_locked()
800 sc->txring_m_dmamap[sc->txring_hd_ptr], m, segs, in cgem_start_locked()
802 sc->txdefrags++; in cgem_start_locked()
807 bus_dmamap_destroy(sc->mbuf_dma_tag, in cgem_start_locked()
808 sc->txring_m_dmamap[sc->txring_hd_ptr]); in cgem_start_locked()
809 sc->txring_m_dmamap[sc->txring_hd_ptr] = NULL; in cgem_start_locked()
810 sc->txdmamapfails++; in cgem_start_locked()
813 sc->txring_m[sc->txring_hd_ptr] = m; in cgem_start_locked()
816 bus_dmamap_sync(sc->mbuf_dma_tag, in cgem_start_locked()
817 sc->txring_m_dmamap[sc->txring_hd_ptr], in cgem_start_locked()
821 wrap = sc->txring_hd_ptr + nsegs + TX_MAX_DMA_SEGS >= in cgem_start_locked()
828 for (i = nsegs - 1; i >= 0; i--) { in cgem_start_locked()
830 sc->txring[sc->txring_hd_ptr + i].addr = in cgem_start_locked()
833 sc->txring[sc->txring_hd_ptr + i].addrhi = in cgem_start_locked()
838 if (i == nsegs - 1) { in cgem_start_locked()
843 sc->txring[sc->txring_hd_ptr + i].ctl = ctl; in cgem_start_locked()
846 sc->txring_m[sc->txring_hd_ptr + i] = NULL; in cgem_start_locked()
850 sc->txring_hd_ptr = 0; in cgem_start_locked()
852 sc->txring_hd_ptr += nsegs; in cgem_start_locked()
853 sc->txring_queued += nsegs; in cgem_start_locked()
856 WR4(sc, CGEM_NET_CTRL, sc->net_ctl_shadow | in cgem_start_locked()
881 sc->stats.tx_bytes += RD4(sc, CGEM_OCTETS_TX_BOT); in cgem_poll_hw_stats()
882 sc->stats.tx_bytes += (uint64_t)RD4(sc, CGEM_OCTETS_TX_TOP) << 32; in cgem_poll_hw_stats()
884 sc->stats.tx_frames += RD4(sc, CGEM_FRAMES_TX); in cgem_poll_hw_stats()
885 sc->stats.tx_frames_bcast += RD4(sc, CGEM_BCAST_FRAMES_TX); in cgem_poll_hw_stats()
886 sc->stats.tx_frames_multi += RD4(sc, CGEM_MULTI_FRAMES_TX); in cgem_poll_hw_stats()
887 sc->stats.tx_frames_pause += RD4(sc, CGEM_PAUSE_FRAMES_TX); in cgem_poll_hw_stats()
888 sc->stats.tx_frames_64b += RD4(sc, CGEM_FRAMES_64B_TX); in cgem_poll_hw_stats()
889 sc->stats.tx_frames_65to127b += RD4(sc, CGEM_FRAMES_65_127B_TX); in cgem_poll_hw_stats()
890 sc->stats.tx_frames_128to255b += RD4(sc, CGEM_FRAMES_128_255B_TX); in cgem_poll_hw_stats()
891 sc->stats.tx_frames_256to511b += RD4(sc, CGEM_FRAMES_256_511B_TX); in cgem_poll_hw_stats()
892 sc->stats.tx_frames_512to1023b += RD4(sc, CGEM_FRAMES_512_1023B_TX); in cgem_poll_hw_stats()
893 sc->stats.tx_frames_1024to1536b += RD4(sc, CGEM_FRAMES_1024_1518B_TX); in cgem_poll_hw_stats()
894 sc->stats.tx_under_runs += RD4(sc, CGEM_TX_UNDERRUNS); in cgem_poll_hw_stats()
897 sc->stats.tx_single_collisn += n; in cgem_poll_hw_stats()
898 if_inc_counter(sc->ifp, IFCOUNTER_COLLISIONS, n); in cgem_poll_hw_stats()
900 sc->stats.tx_multi_collisn += n; in cgem_poll_hw_stats()
901 if_inc_counter(sc->ifp, IFCOUNTER_COLLISIONS, n); in cgem_poll_hw_stats()
903 sc->stats.tx_excsv_collisn += n; in cgem_poll_hw_stats()
904 if_inc_counter(sc->ifp, IFCOUNTER_COLLISIONS, n); in cgem_poll_hw_stats()
906 sc->stats.tx_late_collisn += n; in cgem_poll_hw_stats()
907 if_inc_counter(sc->ifp, IFCOUNTER_COLLISIONS, n); in cgem_poll_hw_stats()
909 sc->stats.tx_deferred_frames += RD4(sc, CGEM_DEFERRED_TX_FRAMES); in cgem_poll_hw_stats()
910 sc->stats.tx_carrier_sense_errs += RD4(sc, CGEM_CARRIER_SENSE_ERRS); in cgem_poll_hw_stats()
912 sc->stats.rx_bytes += RD4(sc, CGEM_OCTETS_RX_BOT); in cgem_poll_hw_stats()
913 sc->stats.rx_bytes += (uint64_t)RD4(sc, CGEM_OCTETS_RX_TOP) << 32; in cgem_poll_hw_stats()
915 sc->stats.rx_frames += RD4(sc, CGEM_FRAMES_RX); in cgem_poll_hw_stats()
916 sc->stats.rx_frames_bcast += RD4(sc, CGEM_BCAST_FRAMES_RX); in cgem_poll_hw_stats()
917 sc->stats.rx_frames_multi += RD4(sc, CGEM_MULTI_FRAMES_RX); in cgem_poll_hw_stats()
918 sc->stats.rx_frames_pause += RD4(sc, CGEM_PAUSE_FRAMES_RX); in cgem_poll_hw_stats()
919 sc->stats.rx_frames_64b += RD4(sc, CGEM_FRAMES_64B_RX); in cgem_poll_hw_stats()
920 sc->stats.rx_frames_65to127b += RD4(sc, CGEM_FRAMES_65_127B_RX); in cgem_poll_hw_stats()
921 sc->stats.rx_frames_128to255b += RD4(sc, CGEM_FRAMES_128_255B_RX); in cgem_poll_hw_stats()
922 sc->stats.rx_frames_256to511b += RD4(sc, CGEM_FRAMES_256_511B_RX); in cgem_poll_hw_stats()
923 sc->stats.rx_frames_512to1023b += RD4(sc, CGEM_FRAMES_512_1023B_RX); in cgem_poll_hw_stats()
924 sc->stats.rx_frames_1024to1536b += RD4(sc, CGEM_FRAMES_1024_1518B_RX); in cgem_poll_hw_stats()
925 sc->stats.rx_frames_undersize += RD4(sc, CGEM_UNDERSZ_RX); in cgem_poll_hw_stats()
926 sc->stats.rx_frames_oversize += RD4(sc, CGEM_OVERSZ_RX); in cgem_poll_hw_stats()
927 sc->stats.rx_frames_jabber += RD4(sc, CGEM_JABBERS_RX); in cgem_poll_hw_stats()
928 sc->stats.rx_frames_fcs_errs += RD4(sc, CGEM_FCS_ERRS); in cgem_poll_hw_stats()
929 sc->stats.rx_frames_length_errs += RD4(sc, CGEM_LENGTH_FIELD_ERRS); in cgem_poll_hw_stats()
930 sc->stats.rx_symbol_errs += RD4(sc, CGEM_RX_SYMBOL_ERRS); in cgem_poll_hw_stats()
931 sc->stats.rx_align_errs += RD4(sc, CGEM_ALIGN_ERRS); in cgem_poll_hw_stats()
932 sc->stats.rx_resource_errs += RD4(sc, CGEM_RX_RESOURCE_ERRS); in cgem_poll_hw_stats()
933 sc->stats.rx_overrun_errs += RD4(sc, CGEM_RX_OVERRUN_ERRS); in cgem_poll_hw_stats()
934 sc->stats.rx_ip_hdr_csum_errs += RD4(sc, CGEM_IP_HDR_CKSUM_ERRS); in cgem_poll_hw_stats()
935 sc->stats.rx_tcp_csum_errs += RD4(sc, CGEM_TCP_CKSUM_ERRS); in cgem_poll_hw_stats()
936 sc->stats.rx_udp_csum_errs += RD4(sc, CGEM_UDP_CKSUM_ERRS); in cgem_poll_hw_stats()
948 if (sc->miibus != NULL) { in cgem_tick()
949 mii = device_get_softc(sc->miibus); in cgem_tick()
957 if (sc->rxhangwar && sc->rx_frames_prev == sc->stats.rx_frames) { in cgem_tick()
963 WR4(sc, CGEM_NET_CTRL, sc->net_ctl_shadow & in cgem_tick()
966 WR4(sc, CGEM_NET_CTRL, sc->net_ctl_shadow); in cgem_tick()
968 sc->rx_frames_prev = sc->stats.rx_frames; in cgem_tick()
971 callout_reset(&sc->tick_ch, hz, cgem_tick, sc); in cgem_tick()
979 if_t ifp = sc->ifp; in cgem_intr()
1002 device_printf(sc->dev, in cgem_intr()
1012 sc->rxoverruns++; in cgem_intr()
1017 WR4(sc, CGEM_NET_CTRL, sc->net_ctl_shadow | in cgem_intr()
1020 sc->rxnobufs++; in cgem_intr()
1041 sc->net_cfg_shadow = CGEM_NET_CFG_DBUS_WIDTH_64; in cgem_reset()
1044 sc->net_cfg_shadow = CGEM_NET_CFG_DBUS_WIDTH_128; in cgem_reset()
1047 sc->net_cfg_shadow = CGEM_NET_CFG_DBUS_WIDTH_32; in cgem_reset()
1051 WR4(sc, CGEM_NET_CFG, sc->net_cfg_shadow); in cgem_reset()
1062 sc->net_cfg_shadow |= CGEM_NET_CFG_MDC_CLK_DIV_48; in cgem_reset()
1063 WR4(sc, CGEM_NET_CFG, sc->net_cfg_shadow); in cgem_reset()
1065 sc->net_ctl_shadow = CGEM_NET_CTRL_MGMT_PORT_EN; in cgem_reset()
1066 WR4(sc, CGEM_NET_CTRL, sc->net_ctl_shadow); in cgem_reset()
1073 if_t ifp = sc->ifp; in cgem_config()
1080 sc->net_cfg_shadow &= (CGEM_NET_CFG_MDC_CLK_DIV_MASK | in cgem_config()
1082 sc->net_cfg_shadow |= (CGEM_NET_CFG_FCS_REMOVE | in cgem_config()
1088 if (sc->phy_contype == MII_CONTYPE_SGMII) { in cgem_config()
1089 sc->net_cfg_shadow |= CGEM_NET_CFG_SGMII_EN; in cgem_config()
1090 sc->net_cfg_shadow |= CGEM_NET_CFG_PCS_SEL; in cgem_config()
1095 sc->net_cfg_shadow |= CGEM_NET_CFG_RX_CHKSUM_OFFLD_EN; in cgem_config()
1097 WR4(sc, CGEM_NET_CFG, sc->net_cfg_shadow); in cgem_config()
1116 WR4(sc, CGEM_RX_QBAR, (uint32_t)sc->rxring_physaddr); in cgem_config()
1117 WR4(sc, CGEM_TX_QBAR, (uint32_t)sc->txring_physaddr); in cgem_config()
1119 WR4(sc, CGEM_RX_QBAR_HI, (uint32_t)(sc->rxring_physaddr >> 32)); in cgem_config()
1120 WR4(sc, CGEM_TX_QBAR_HI, (uint32_t)(sc->txring_physaddr >> 32)); in cgem_config()
1124 sc->net_ctl_shadow |= (CGEM_NET_CTRL_TX_EN | CGEM_NET_CTRL_RX_EN); in cgem_config()
1125 WR4(sc, CGEM_NET_CTRL, sc->net_ctl_shadow); in cgem_config()
1146 if ((if_getdrvflags(sc->ifp) & IFF_DRV_RUNNING) != 0) in cgem_init_locked()
1152 if_setdrvflagbits(sc->ifp, IFF_DRV_RUNNING, IFF_DRV_OACTIVE); in cgem_init_locked()
1154 if (sc->miibus != NULL) { in cgem_init_locked()
1155 mii = device_get_softc(sc->miibus); in cgem_init_locked()
1159 callout_reset(&sc->tick_ch, hz, cgem_tick, sc); in cgem_init_locked()
1180 callout_stop(&sc->tick_ch); in cgem_stop()
1186 memset(sc->txring, 0, CGEM_NUM_TX_DESCS * sizeof(struct cgem_tx_desc)); in cgem_stop()
1188 sc->txring[i].ctl = CGEM_TXDESC_USED; in cgem_stop()
1189 if (sc->txring_m[i]) { in cgem_stop()
1191 bus_dmamap_unload(sc->mbuf_dma_tag, in cgem_stop()
1192 sc->txring_m_dmamap[i]); in cgem_stop()
1193 bus_dmamap_destroy(sc->mbuf_dma_tag, in cgem_stop()
1194 sc->txring_m_dmamap[i]); in cgem_stop()
1195 sc->txring_m_dmamap[i] = NULL; in cgem_stop()
1196 m_freem(sc->txring_m[i]); in cgem_stop()
1197 sc->txring_m[i] = NULL; in cgem_stop()
1200 sc->txring[CGEM_NUM_TX_DESCS - 1].ctl |= CGEM_TXDESC_WRAP; in cgem_stop()
1202 sc->txring_hd_ptr = 0; in cgem_stop()
1203 sc->txring_tl_ptr = 0; in cgem_stop()
1204 sc->txring_queued = 0; in cgem_stop()
1207 memset(sc->rxring, 0, CGEM_NUM_RX_DESCS * sizeof(struct cgem_rx_desc)); in cgem_stop()
1209 sc->rxring[i].addr = CGEM_RXDESC_OWN; in cgem_stop()
1210 if (sc->rxring_m[i]) { in cgem_stop()
1212 bus_dmamap_unload(sc->mbuf_dma_tag, in cgem_stop()
1213 sc->rxring_m_dmamap[i]); in cgem_stop()
1214 bus_dmamap_destroy(sc->mbuf_dma_tag, in cgem_stop()
1215 sc->rxring_m_dmamap[i]); in cgem_stop()
1216 sc->rxring_m_dmamap[i] = NULL; in cgem_stop()
1218 m_freem(sc->rxring_m[i]); in cgem_stop()
1219 sc->rxring_m[i] = NULL; in cgem_stop()
1222 sc->rxring[CGEM_NUM_RX_DESCS - 1].addr |= CGEM_RXDESC_WRAP; in cgem_stop()
1224 sc->rxring_hd_ptr = 0; in cgem_stop()
1225 sc->rxring_tl_ptr = 0; in cgem_stop()
1226 sc->rxring_queued = 0; in cgem_stop()
1229 sc->mii_media_active = 0; in cgem_stop()
1245 if (((if_getflags(ifp) ^ sc->if_old_flags) & in cgem_ioctl()
1256 sc->if_old_flags = if_getflags(ifp); in cgem_ioctl()
1262 /* Set up multi-cast filters. */ in cgem_ioctl()
1272 if (sc->miibus == NULL) in cgem_ioctl()
1274 mii = device_get_softc(sc->miibus); in cgem_ioctl()
1275 error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd); in cgem_ioctl()
1280 mask = if_getcapenable(ifp) ^ ifr->ifr_reqcap; in cgem_ioctl()
1283 if ((ifr->ifr_reqcap & IFCAP_TXCSUM) != 0) { in cgem_ioctl()
1304 if ((ifr->ifr_reqcap & IFCAP_RXCSUM) != 0) { in cgem_ioctl()
1308 sc->net_cfg_shadow |= in cgem_ioctl()
1310 WR4(sc, CGEM_NET_CFG, sc->net_cfg_shadow); in cgem_ioctl()
1315 sc->net_cfg_shadow &= in cgem_ioctl()
1317 WR4(sc, CGEM_NET_CFG, sc->net_cfg_shadow); in cgem_ioctl()
1346 mii = device_get_softc(sc->miibus); in cgem_ifmedia_upd()
1349 LIST_FOREACH(miisc, &mii->mii_phys, mii_list) in cgem_ifmedia_upd()
1364 mii = device_get_softc(sc->miibus); in cgem_ifmedia_sts()
1367 ifmr->ifm_active = mii->mii_media_active; in cgem_ifmedia_sts()
1368 ifmr->ifm_status = mii->mii_media_status; in cgem_ifmedia_sts()
1389 return (-1); in cgem_miibus_readreg()
1397 * MAC does not support half-duplex at gig speeds. in cgem_miibus_readreg()
1423 return (-1); in cgem_miibus_writereg()
1434 struct mii_data *mii = device_get_softc(sc->miibus); in cgem_miibus_statchg()
1438 if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == in cgem_miibus_statchg()
1440 sc->mii_media_active != mii->mii_media_active) in cgem_miibus_statchg()
1448 struct mii_data *mii = device_get_softc(sc->miibus); in cgem_miibus_linkchg()
1452 if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == in cgem_miibus_linkchg()
1454 sc->mii_media_active != mii->mii_media_active) in cgem_miibus_linkchg()
1479 sc->net_cfg_shadow &= ~(CGEM_NET_CFG_SPEED100 | CGEM_NET_CFG_GIGE_EN | in cgem_mediachange()
1482 switch (IFM_SUBTYPE(mii->mii_media_active)) { in cgem_mediachange()
1484 sc->net_cfg_shadow |= (CGEM_NET_CFG_SPEED100 | in cgem_mediachange()
1489 sc->net_cfg_shadow |= CGEM_NET_CFG_SPEED100; in cgem_mediachange()
1496 if ((mii->mii_media_active & IFM_FDX) != 0) in cgem_mediachange()
1497 sc->net_cfg_shadow |= CGEM_NET_CFG_FULL_DUPLEX; in cgem_mediachange()
1499 WR4(sc, CGEM_NET_CFG, sc->net_cfg_shadow); in cgem_mediachange()
1501 if (sc->clk_pclk != NULL) { in cgem_mediachange()
1503 if (clk_set_freq(sc->clk_pclk, ref_clk_freq, 0)) in cgem_mediachange()
1504 device_printf(sc->dev, "could not set ref clk to %d\n", in cgem_mediachange()
1509 sc->mii_media_active = mii->mii_media_active; in cgem_mediachange()
1524 &sc->rxbufs, 0, "Number receive buffers to provide"); in cgem_add_sysctls()
1527 &sc->rxhangwar, 0, "Enable receive hang work-around"); in cgem_add_sysctls()
1530 &sc->rxoverruns, 0, "Receive overrun events"); in cgem_add_sysctls()
1533 &sc->rxnobufs, 0, "Receive buf queue empty events"); in cgem_add_sysctls()
1536 &sc->rxdmamapfails, 0, "Receive DMA map failures"); in cgem_add_sysctls()
1539 &sc->txfull, 0, "Transmit ring full events"); in cgem_add_sysctls()
1542 &sc->txdmamapfails, 0, "Transmit DMA map failures"); in cgem_add_sysctls()
1545 &sc->txdefrags, 0, "Transmit m_defrag() calls"); in cgem_add_sysctls()
1548 &sc->txdefragfails, 0, "Transmit m_defrag() failures"); in cgem_add_sysctls()
1555 &sc->stats.tx_bytes, "Total bytes transmitted"); in cgem_add_sysctls()
1558 &sc->stats.tx_frames, 0, "Total frames transmitted"); in cgem_add_sysctls()
1561 &sc->stats.tx_frames_bcast, 0, in cgem_add_sysctls()
1565 &sc->stats.tx_frames_multi, 0, in cgem_add_sysctls()
1569 CTLFLAG_RD, &sc->stats.tx_frames_pause, 0, in cgem_add_sysctls()
1573 &sc->stats.tx_frames_64b, 0, in cgem_add_sysctls()
1577 &sc->stats.tx_frames_65to127b, 0, in cgem_add_sysctls()
1578 "Number frames transmitted of size 65-127 bytes"); in cgem_add_sysctls()
1581 CTLFLAG_RD, &sc->stats.tx_frames_128to255b, 0, in cgem_add_sysctls()
1582 "Number frames transmitted of size 128-255 bytes"); in cgem_add_sysctls()
1585 CTLFLAG_RD, &sc->stats.tx_frames_256to511b, 0, in cgem_add_sysctls()
1586 "Number frames transmitted of size 256-511 bytes"); in cgem_add_sysctls()
1589 CTLFLAG_RD, &sc->stats.tx_frames_512to1023b, 0, in cgem_add_sysctls()
1590 "Number frames transmitted of size 512-1023 bytes"); in cgem_add_sysctls()
1593 CTLFLAG_RD, &sc->stats.tx_frames_1024to1536b, 0, in cgem_add_sysctls()
1594 "Number frames transmitted of size 1024-1536 bytes"); in cgem_add_sysctls()
1597 CTLFLAG_RD, &sc->stats.tx_under_runs, 0, in cgem_add_sysctls()
1598 "Number transmit under-run events"); in cgem_add_sysctls()
1601 CTLFLAG_RD, &sc->stats.tx_single_collisn, 0, in cgem_add_sysctls()
1602 "Number single-collision transmit frames"); in cgem_add_sysctls()
1605 CTLFLAG_RD, &sc->stats.tx_multi_collisn, 0, in cgem_add_sysctls()
1606 "Number multi-collision transmit frames"); in cgem_add_sysctls()
1609 CTLFLAG_RD, &sc->stats.tx_excsv_collisn, 0, in cgem_add_sysctls()
1613 CTLFLAG_RD, &sc->stats.tx_late_collisn, 0, in cgem_add_sysctls()
1614 "Number late-collision transmit frames"); in cgem_add_sysctls()
1617 CTLFLAG_RD, &sc->stats.tx_deferred_frames, 0, in cgem_add_sysctls()
1621 CTLFLAG_RD, &sc->stats.tx_carrier_sense_errs, 0, in cgem_add_sysctls()
1625 &sc->stats.rx_bytes, "Total bytes received"); in cgem_add_sysctls()
1628 &sc->stats.rx_frames, 0, "Total frames received"); in cgem_add_sysctls()
1631 CTLFLAG_RD, &sc->stats.rx_frames_bcast, 0, in cgem_add_sysctls()
1635 CTLFLAG_RD, &sc->stats.rx_frames_multi, 0, in cgem_add_sysctls()
1639 CTLFLAG_RD, &sc->stats.rx_frames_pause, 0, in cgem_add_sysctls()
1643 CTLFLAG_RD, &sc->stats.rx_frames_64b, 0, in cgem_add_sysctls()
1647 CTLFLAG_RD, &sc->stats.rx_frames_65to127b, 0, in cgem_add_sysctls()
1648 "Number frames received of size 65-127 bytes"); in cgem_add_sysctls()
1651 CTLFLAG_RD, &sc->stats.rx_frames_128to255b, 0, in cgem_add_sysctls()
1652 "Number frames received of size 128-255 bytes"); in cgem_add_sysctls()
1655 CTLFLAG_RD, &sc->stats.rx_frames_256to511b, 0, in cgem_add_sysctls()
1656 "Number frames received of size 256-511 bytes"); in cgem_add_sysctls()
1659 CTLFLAG_RD, &sc->stats.rx_frames_512to1023b, 0, in cgem_add_sysctls()
1660 "Number frames received of size 512-1023 bytes"); in cgem_add_sysctls()
1663 CTLFLAG_RD, &sc->stats.rx_frames_1024to1536b, 0, in cgem_add_sysctls()
1664 "Number frames received of size 1024-1536 bytes"); in cgem_add_sysctls()
1667 CTLFLAG_RD, &sc->stats.rx_frames_undersize, 0, in cgem_add_sysctls()
1671 CTLFLAG_RD, &sc->stats.rx_frames_oversize, 0, in cgem_add_sysctls()
1675 CTLFLAG_RD, &sc->stats.rx_frames_jabber, 0, in cgem_add_sysctls()
1679 CTLFLAG_RD, &sc->stats.rx_frames_fcs_errs, 0, in cgem_add_sysctls()
1683 CTLFLAG_RD, &sc->stats.rx_frames_length_errs, 0, in cgem_add_sysctls()
1687 CTLFLAG_RD, &sc->stats.rx_symbol_errs, 0, in cgem_add_sysctls()
1691 CTLFLAG_RD, &sc->stats.rx_align_errs, 0, in cgem_add_sysctls()
1695 CTLFLAG_RD, &sc->stats.rx_resource_errs, 0, in cgem_add_sysctls()
1699 CTLFLAG_RD, &sc->stats.rx_overrun_errs, 0, in cgem_add_sysctls()
1703 CTLFLAG_RD, &sc->stats.rx_ip_hdr_csum_errs, 0, in cgem_add_sysctls()
1707 CTLFLAG_RD, &sc->stats.rx_tcp_csum_errs, 0, in cgem_add_sysctls()
1711 CTLFLAG_RD, &sc->stats.rx_udp_csum_errs, 0, in cgem_add_sysctls()
1722 if (ofw_bus_search_compatible(dev, compat_data)->ocd_str == NULL) in cgem_probe()
1739 sc->dev = dev; in cgem_attach()
1742 /* Key off of compatible string and set hardware-specific options. */ in cgem_attach()
1743 hwquirks = ofw_bus_search_compatible(dev, compat_data)->ocd_data; in cgem_attach()
1745 sc->neednullqs = 1; in cgem_attach()
1747 sc->rxhangwar = 1; in cgem_attach()
1753 if (clk_get_by_ofw_name(dev, 0, "pclk", &sc->clk_pclk) != 0) in cgem_attach()
1757 if (clk_enable(sc->clk_pclk) != 0) in cgem_attach()
1760 if (clk_get_by_ofw_name(dev, 0, "hclk", &sc->clk_hclk) != 0) in cgem_attach()
1764 if (clk_enable(sc->clk_hclk) != 0) in cgem_attach()
1769 if (clk_get_by_ofw_name(dev, 0, "tx_clk", &sc->clk_txclk) == 0) { in cgem_attach()
1770 if (clk_enable(sc->clk_txclk) != 0) { in cgem_attach()
1776 if (clk_get_by_ofw_name(dev, 0, "rx_clk", &sc->clk_rxclk) == 0) { in cgem_attach()
1777 if (clk_enable(sc->clk_rxclk) != 0) { in cgem_attach()
1783 if (clk_get_by_ofw_name(dev, 0, "tsu_clk", &sc->clk_tsuclk) == 0) { in cgem_attach()
1784 if (clk_enable(sc->clk_tsuclk) != 0) { in cgem_attach()
1792 sc->phy_contype = mii_fdt_get_contype(node); in cgem_attach()
1796 sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, in cgem_attach()
1798 if (sc->mem_res == NULL) { in cgem_attach()
1806 sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, in cgem_attach()
1808 if (sc->irq_res == NULL) { in cgem_attach()
1815 ifp = sc->ifp = if_alloc(IFT_ETHER); in cgem_attach()
1832 sc->if_old_flags = if_getflags(ifp); in cgem_attach()
1833 sc->rxbufs = DEFAULT_NUM_RX_BUFS; in cgem_attach()
1841 err = mii_attach(dev, &sc->miibus, ifp, in cgem_attach()
1859 callout_init_mtx(&sc->tick_ch, &sc->sc_mtx, 0); in cgem_attach()
1863 err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE | in cgem_attach()
1864 INTR_EXCL, NULL, cgem_intr, sc, &sc->intrhand); in cgem_attach()
1877 if (sc->clk_tsuclk) in cgem_attach()
1878 clk_release(sc->clk_tsuclk); in cgem_attach()
1880 if (sc->clk_rxclk) in cgem_attach()
1881 clk_release(sc->clk_rxclk); in cgem_attach()
1883 if (sc->clk_txclk) in cgem_attach()
1884 clk_release(sc->clk_txclk); in cgem_attach()
1886 if (sc->clk_pclk) in cgem_attach()
1887 clk_release(sc->clk_pclk); in cgem_attach()
1888 if (sc->clk_hclk) in cgem_attach()
1889 clk_release(sc->clk_hclk); in cgem_attach()
1907 callout_drain(&sc->tick_ch); in cgem_detach()
1908 if_setflagbits(sc->ifp, 0, IFF_UP); in cgem_detach()
1909 ether_ifdetach(sc->ifp); in cgem_detach()
1915 if (sc->mem_res != NULL) { in cgem_detach()
1917 rman_get_rid(sc->mem_res), sc->mem_res); in cgem_detach()
1918 sc->mem_res = NULL; in cgem_detach()
1920 if (sc->irq_res != NULL) { in cgem_detach()
1921 if (sc->intrhand) in cgem_detach()
1922 bus_teardown_intr(dev, sc->irq_res, sc->intrhand); in cgem_detach()
1924 rman_get_rid(sc->irq_res), sc->irq_res); in cgem_detach()
1925 sc->irq_res = NULL; in cgem_detach()
1929 if (sc->rxring != NULL) { in cgem_detach()
1930 if (sc->rxring_physaddr != 0) { in cgem_detach()
1931 bus_dmamap_unload(sc->desc_dma_tag, in cgem_detach()
1932 sc->rxring_dma_map); in cgem_detach()
1933 sc->rxring_physaddr = 0; in cgem_detach()
1934 sc->txring_physaddr = 0; in cgem_detach()
1935 sc->null_qs_physaddr = 0; in cgem_detach()
1937 bus_dmamem_free(sc->desc_dma_tag, sc->rxring, in cgem_detach()
1938 sc->rxring_dma_map); in cgem_detach()
1939 sc->rxring = NULL; in cgem_detach()
1940 sc->txring = NULL; in cgem_detach()
1941 sc->null_qs = NULL; in cgem_detach()
1944 if (sc->rxring_m_dmamap[i] != NULL) { in cgem_detach()
1945 bus_dmamap_destroy(sc->mbuf_dma_tag, in cgem_detach()
1946 sc->rxring_m_dmamap[i]); in cgem_detach()
1947 sc->rxring_m_dmamap[i] = NULL; in cgem_detach()
1950 if (sc->txring_m_dmamap[i] != NULL) { in cgem_detach()
1951 bus_dmamap_destroy(sc->mbuf_dma_tag, in cgem_detach()
1952 sc->txring_m_dmamap[i]); in cgem_detach()
1953 sc->txring_m_dmamap[i] = NULL; in cgem_detach()
1956 if (sc->desc_dma_tag != NULL) { in cgem_detach()
1957 bus_dma_tag_destroy(sc->desc_dma_tag); in cgem_detach()
1958 sc->desc_dma_tag = NULL; in cgem_detach()
1960 if (sc->mbuf_dma_tag != NULL) { in cgem_detach()
1961 bus_dma_tag_destroy(sc->mbuf_dma_tag); in cgem_detach()
1962 sc->mbuf_dma_tag = NULL; in cgem_detach()
1965 if (sc->clk_tsuclk) in cgem_detach()
1966 clk_release(sc->clk_tsuclk); in cgem_detach()
1967 if (sc->clk_rxclk) in cgem_detach()
1968 clk_release(sc->clk_rxclk); in cgem_detach()
1969 if (sc->clk_txclk) in cgem_detach()
1970 clk_release(sc->clk_txclk); in cgem_detach()
1971 if (sc->clk_pclk) in cgem_detach()
1972 clk_release(sc->clk_pclk); in cgem_detach()
1973 if (sc->clk_hclk) in cgem_detach()
1974 clk_release(sc->clk_hclk); in cgem_detach()