Lines Matching +full:ring +full:- +full:disable +full:- +full:pullup

1 /*-
80 #define RD4(sc, reg) bus_read_4((sc)->res[_RES_MAC], (reg))
81 #define WR4(sc, reg, val) bus_write_4((sc)->res[_RES_MAC], (reg), (val))
83 #define GEN_LOCK(sc) mtx_lock(&(sc)->mtx)
84 #define GEN_UNLOCK(sc) mtx_unlock(&(sc)->mtx)
85 #define GEN_ASSERT_LOCKED(sc) mtx_assert(&(sc)->mtx, MA_OWNED)
86 #define GEN_ASSERT_UNLOCKED(sc) mtx_assert(&(sc)->mtx, MA_NOTOWNED)
91 #define TX_NEXT(n, count) (((n) + 1) & ((count) - 1))
92 #define RX_NEXT(n, count) (((n) + 1) & ((count) - 1))
119 { "brcm,genet-v1", 1 },
120 { "brcm,genet-v2", 2 },
121 { "brcm,genet-v3", 3 },
122 { "brcm,genet-v4", 4 },
123 { "brcm,genet-v5", 5 },
124 { "brcm,bcm2711-genet-v5", 5 },
139 { -1, 0 }
142 /* structure per ring entry */
193 struct gen_ring_ent tx_ring_ent[TX_DESC_COUNT]; /* ring entries */
199 struct gen_ring_ent rx_ring_ent[RX_DESC_COUNT]; /* ring entries */
238 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) in gen_probe()
254 sc->dev = dev; in gen_attach()
255 sc->type = ofw_bus_search_compatible(dev, compat_data)->ocd_data; in gen_attach()
257 if (bus_alloc_resources(dev, gen_spec, sc->res) != 0) { in gen_attach()
273 mtx_init(&sc->mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF); in gen_attach()
274 callout_init_mtx(&sc->stat_ch, &sc->mtx, 0); in gen_attach()
275 TASK_INIT(&sc->link_task, 0, gen_link_task, sc); in gen_attach()
297 sc->ifp = if_alloc(IFT_ETHER); in gen_attach()
298 if_setsoftc(sc->ifp, sc); in gen_attach()
299 if_initname(sc->ifp, device_get_name(dev), device_get_unit(dev)); in gen_attach()
300 if_setflags(sc->ifp, IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST); in gen_attach()
301 if_setstartfn(sc->ifp, gen_start); in gen_attach()
302 if_setioctlfn(sc->ifp, gen_ioctl); in gen_attach()
303 if_setinitfn(sc->ifp, gen_init); in gen_attach()
304 if_setsendqlen(sc->ifp, TX_DESC_COUNT - 1); in gen_attach()
305 if_setsendqready(sc->ifp); in gen_attach()
307 if_sethwassist(sc->ifp, GEN_CSUM_FEATURES); in gen_attach()
308 if_setcapabilities(sc->ifp, IFCAP_VLAN_MTU | IFCAP_HWCSUM | in gen_attach()
310 if_setcapenable(sc->ifp, if_getcapabilities(sc->ifp)); in gen_attach()
313 error = bus_setup_intr(dev, sc->res[_RES_IRQ1], in gen_attach()
314 INTR_TYPE_NET | INTR_MPSAFE, NULL, gen_intr, sc, &sc->ih); in gen_attach()
320 error = bus_setup_intr(dev, sc->res[_RES_IRQ2], in gen_attach()
321 INTR_TYPE_NET | INTR_MPSAFE, NULL, gen_intr2, sc, &sc->ih2); in gen_attach()
329 switch (sc->phy_mode) in gen_attach()
343 error = mii_attach(dev, &sc->miibus, sc->ifp, gen_media_change, in gen_attach()
353 ether_gen_addr(sc->ifp, &eaddr); in gen_attach()
355 ether_ifattach(sc->ifp, eaddr.octet); in gen_attach()
368 device_delete_children(sc->dev); in gen_destroy()
369 bus_teardown_intr(sc->dev, sc->res[_RES_IRQ1], sc->ih); in gen_destroy()
370 bus_teardown_intr(sc->dev, sc->res[_RES_IRQ2], sc->ih2); in gen_destroy()
372 callout_drain(&sc->stat_ch); in gen_destroy()
373 if (mtx_initialized(&sc->mtx)) in gen_destroy()
374 mtx_destroy(&sc->mtx); in gen_destroy()
375 bus_release_resources(sc->dev, gen_spec, sc->res); in gen_destroy()
376 if (sc->ifp != NULL) { in gen_destroy()
377 if_free(sc->ifp); in gen_destroy()
378 sc->ifp = NULL; in gen_destroy()
399 sc->phy_mode = type; in gen_get_phy_mode()
402 device_printf(dev, "unknown phy-mode '%s'\n", in gen_get_phy_mode()
421 if (OF_getprop(node, "mac-address", eaddr->octet, in gen_get_eaddr()
422 ETHER_ADDR_LEN) != -1 || in gen_get_eaddr()
423 OF_getprop(node, "local-mac-address", eaddr->octet, in gen_get_eaddr()
424 ETHER_ADDR_LEN) != -1 || in gen_get_eaddr()
425 OF_getprop(node, "address", eaddr->octet, ETHER_ADDR_LEN) != -1) in gen_get_eaddr()
443 eaddr->octet[0] = maclo & 0xff; in gen_get_eaddr()
444 eaddr->octet[1] = (maclo >> 8) & 0xff; in gen_get_eaddr()
445 eaddr->octet[2] = (maclo >> 16) & 0xff; in gen_get_eaddr()
446 eaddr->octet[3] = (maclo >> 24) & 0xff; in gen_get_eaddr()
447 eaddr->octet[4] = machi & 0xff; in gen_get_eaddr()
448 eaddr->octet[5] = (machi >> 8) & 0xff; in gen_get_eaddr()
509 /* Disable interrupts */ in gen_disable_intr()
529 /* Disable Interrupt */ in gen_disable()
540 if ((if_getcapenable(sc->ifp) & IFCAP_RXCSUM) != 0) { in gen_enable_offload()
551 if ((if_getcapenable(sc->ifp) & (IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6)) != in gen_enable_offload()
578 device_t dev = sc->dev; in gen_bus_dma_init()
591 &sc->tx_buf_tag); in gen_bus_dma_init()
598 error = bus_dmamap_create(sc->tx_buf_tag, 0, in gen_bus_dma_init()
599 &sc->tx_ring_ent[i].map); in gen_bus_dma_init()
616 &sc->rx_buf_tag); in gen_bus_dma_init()
623 error = bus_dmamap_create(sc->rx_buf_tag, 0, in gen_bus_dma_init()
624 &sc->rx_ring_ent[i].map); in gen_bus_dma_init()
638 if (sc->tx_buf_tag != NULL) { in gen_bus_dma_teardown()
640 error = bus_dmamap_destroy(sc->tx_buf_tag, in gen_bus_dma_teardown()
641 sc->tx_ring_ent[i].map); in gen_bus_dma_teardown()
642 sc->tx_ring_ent[i].map = NULL; in gen_bus_dma_teardown()
644 device_printf(sc->dev, in gen_bus_dma_teardown()
648 error = bus_dma_tag_destroy(sc->tx_buf_tag); in gen_bus_dma_teardown()
649 sc->tx_buf_tag = NULL; in gen_bus_dma_teardown()
651 device_printf(sc->dev, in gen_bus_dma_teardown()
656 if (sc->tx_buf_tag != NULL) { in gen_bus_dma_teardown()
658 error = bus_dmamap_destroy(sc->rx_buf_tag, in gen_bus_dma_teardown()
659 sc->rx_ring_ent[i].map); in gen_bus_dma_teardown()
660 sc->rx_ring_ent[i].map = NULL; in gen_bus_dma_teardown()
662 device_printf(sc->dev, in gen_bus_dma_teardown()
666 error = bus_dma_tag_destroy(sc->rx_buf_tag); in gen_bus_dma_teardown()
667 sc->rx_buf_tag = NULL; in gen_bus_dma_teardown()
669 device_printf(sc->dev, in gen_bus_dma_teardown()
684 * "queue" is the software queue index (0-4); "qid" is the hardware index
685 * (0-16). "base" is the starting index in the ring array.
694 q = &sc->tx_queue[queue]; in gen_init_txring()
695 q->entries = &sc->tx_ring_ent[base]; in gen_init_txring()
696 q->hwindex = qid; in gen_init_txring()
697 q->nentries = nentries; in gen_init_txring()
699 /* TX ring */ in gen_init_txring()
701 q->queued = 0; in gen_init_txring()
702 q->cons_idx = q->prod_idx = 0; in gen_init_txring()
716 TX_DESC_COUNT * GENET_DMA_DESC_SIZE / 4 - 1); in gen_init_txring()
733 * "queue" is the software queue index (0-4); "qid" is the hardware index
734 * (0-16). "base" is the starting index in the ring array.
744 q = &sc->rx_queue[queue]; in gen_init_rxring()
745 q->entries = &sc->rx_ring_ent[base]; in gen_init_rxring()
746 q->hwindex = qid; in gen_init_rxring()
747 q->nentries = nentries; in gen_init_rxring()
748 q->cons_idx = q->prod_idx = 0; in gen_init_rxring()
762 RX_DESC_COUNT * GENET_DMA_DESC_SIZE / 4 - 1); in gen_init_rxring()
771 /* fill ring */ in gen_init_rxring()
773 gen_newbuf_rx(sc, &sc->rx_queue[DEF_RXQUEUE], i); in gen_init_rxring()
792 sc->tx_queue[i].queue = i; in gen_init_txrings()
802 sc->tx_queue[DEF_TXQUEUE].hwindex = GENET_DMA_DEFAULT_QUEUE; in gen_init_txrings()
815 sc->rx_queue[i].queue = i; in gen_init_rxrings()
825 sc->rx_queue[DEF_RXQUEUE].hwindex = GENET_DMA_DEFAULT_QUEUE; in gen_init_rxrings()
837 callout_stop(&sc->stat_ch); in gen_stop()
838 if_setdrvflagbits(sc->ifp, 0, IFF_DRV_RUNNING); in gen_stop()
843 /* Clear the tx/rx ring buffer */ in gen_stop()
845 ent = &sc->tx_ring_ent[i]; in gen_stop()
846 if (ent->mbuf != NULL) { in gen_stop()
847 bus_dmamap_sync(sc->tx_buf_tag, ent->map, in gen_stop()
849 bus_dmamap_unload(sc->tx_buf_tag, ent->map); in gen_stop()
850 m_freem(ent->mbuf); in gen_stop()
851 ent->mbuf = NULL; in gen_stop()
856 ent = &sc->rx_ring_ent[i]; in gen_stop()
857 if (ent->mbuf != NULL) { in gen_stop()
858 bus_dmamap_sync(sc->rx_buf_tag, ent->map, in gen_stop()
860 bus_dmamap_unload(sc->rx_buf_tag, ent->map); in gen_stop()
861 m_freem(ent->mbuf); in gen_stop()
862 ent->mbuf = NULL; in gen_stop()
873 mii = device_get_softc(sc->miibus); in gen_init_locked()
874 ifp = sc->ifp; in gen_init_locked()
881 switch (sc->phy_mode) in gen_init_locked()
906 callout_reset(&sc->stat_ch, hz, gen_tick, sc); in gen_init_locked()
945 if_t ifp = sc->ifp; in gen_setup_rxfilter()
973 mdf_ctrl = (__BIT(GENET_MAX_MDF_FILTER) - 1) &~ in gen_setup_rxfilter()
974 (__BIT(GENET_MAX_MDF_FILTER - n) - 1); in gen_setup_rxfilter()
990 ifp = sc->ifp; in gen_set_enaddr()
1011 if (!sc->link) in gen_start_locked()
1014 ifp = sc->ifp; in gen_start_locked()
1068 q = &sc->tx_queue[DEF_TXQUEUE]; in gen_encap()
1069 if (q->queued == q->nentries) { in gen_encap()
1080 if (m->m_len == sizeof(struct ether_header)) { in gen_encap()
1081 m = m_pullup(m, MIN(m->m_pkthdr.len, gen_tx_hdr_min)); in gen_encap()
1083 if (if_getflags(sc->ifp) & IFF_DEBUG) in gen_encap()
1084 device_printf(sc->dev, in gen_encap()
1085 "header pullup fail\n"); in gen_encap()
1091 if ((if_getcapenable(sc->ifp) & (IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6)) != in gen_encap()
1093 csum_flags = m->m_pkthdr.csum_flags; in gen_encap()
1094 csumdata = m->m_pkthdr.csum_data; in gen_encap()
1097 if (if_getflags(sc->ifp) & IFF_DEBUG) in gen_encap()
1098 device_printf(sc->dev, "prepend fail\n"); in gen_encap()
1110 sb->txcsuminfo = csuminfo; in gen_encap()
1112 sb->txcsuminfo = 0; in gen_encap()
1117 cur = first = q->cur; in gen_encap()
1118 ent = &q->entries[cur]; in gen_encap()
1119 map = ent->map; in gen_encap()
1120 error = bus_dmamap_load_mbuf_sg(sc->tx_buf_tag, map, m, segs, in gen_encap()
1125 device_printf(sc->dev, in gen_encap()
1132 error = bus_dmamap_load_mbuf_sg(sc->tx_buf_tag, map, m, in gen_encap()
1140 device_printf(sc->dev, in gen_encap()
1152 m->m_data += sizeof(struct statusblock); in gen_encap()
1153 m->m_len -= sizeof(struct statusblock); in gen_encap()
1154 m->m_pkthdr.len -= sizeof(struct statusblock); in gen_encap()
1156 if (q->queued + nsegs > q->nentries) { in gen_encap()
1157 bus_dmamap_unload(sc->tx_buf_tag, map); in gen_encap()
1161 bus_dmamap_sync(sc->tx_buf_tag, map, BUS_DMASYNC_PREWRITE); in gen_encap()
1163 index = q->prod_idx & (q->nentries - 1); in gen_encap()
1165 ent = &q->entries[cur]; in gen_encap()
1173 if (i == nsegs - 1) in gen_encap()
1185 ++q->queued; in gen_encap()
1186 cur = TX_NEXT(cur, q->nentries); in gen_encap()
1187 index = TX_NEXT(index, q->nentries); in gen_encap()
1190 q->prod_idx += nsegs; in gen_encap()
1191 q->prod_idx &= GENET_TX_DMA_PROD_CONS_MASK; in gen_encap()
1194 WR4(sc, GENET_TX_DMA_PROD_INDEX(q->hwindex), q->prod_idx); in gen_encap()
1195 q->cur = cur; in gen_encap()
1198 q->entries[first].mbuf = m; in gen_encap()
1217 if (m->m_len == sizeof(struct statusblock)) { in gen_parse_tx()
1219 m->m_data = m->m_pktdat; in gen_parse_tx()
1221 m = m->m_next; in gen_parse_tx()
1231 if ((m->m_flags & M_EXT) == 0 && m->m_data != m->m_pktdat) in gen_parse_tx()
1250 m0->m_data = m0->m_pktdat; \ in gen_parse_tx()
1252 m0->m_len - sizeof(struct statusblock)); \ in gen_parse_tx()
1253 copy_p = mtodo(m0, m0->m_len); \ in gen_parse_tx()
1256 m0->m_len += hsize; \ in gen_parse_tx()
1257 m->m_len -= hsize; \ in gen_parse_tx()
1258 m->m_data += hsize; \ in gen_parse_tx()
1266 if (((struct ether_header *)p)->ether_type == htons(ETHERTYPE_VLAN)) { in gen_parse_tx()
1268 ether_type = ntohs(((struct ether_vlan_header *)p)->evl_proto); in gen_parse_tx()
1270 if (m->m_len == off_in_m + sizeof(struct ether_vlan_header)) { in gen_parse_tx()
1271 m = m->m_next; in gen_parse_tx()
1281 ether_type = ntohs(((struct ether_header *)p)->ether_type); in gen_parse_tx()
1283 if (m->m_len == off_in_m + sizeof(struct ether_header)) { in gen_parse_tx()
1284 m = m->m_next; in gen_parse_tx()
1294 COPY(((struct ip *)p)->ip_hl << 2); in gen_parse_tx()
1295 offset += ((struct ip *)p)->ip_hl << 2; in gen_parse_tx()
1305 COPY(MIN(gen_tx_hdr_min, m->m_len)); in gen_parse_tx()
1306 offset += MIN(gen_tx_hdr_min, m->m_len); in gen_parse_tx()
1325 gen_rxintr(sc, &sc->rx_queue[DEF_RXQUEUE]); in gen_intr()
1328 gen_txintr(sc, &sc->tx_queue[DEF_TXQUEUE]); in gen_intr()
1329 if (!if_sendq_empty(sc->ifp)) in gen_intr()
1345 ifp = sc->ifp; in gen_rxintr()
1350 prod_idx = RD4(sc, GENET_RX_DMA_PROD_INDEX(q->hwindex)) & in gen_rxintr()
1352 total = (prod_idx - q->cons_idx) & GENET_RX_DMA_PROD_CONS_MASK; in gen_rxintr()
1354 index = q->cons_idx & (RX_DESC_COUNT - 1); in gen_rxintr()
1356 bus_dmamap_sync(sc->rx_buf_tag, q->entries[index].map, in gen_rxintr()
1358 bus_dmamap_unload(sc->rx_buf_tag, q->entries[index].map); in gen_rxintr()
1360 m = q->entries[index].mbuf; in gen_rxintr()
1364 status = sb->status_buflen; in gen_rxintr()
1377 device_printf(sc->dev, in gen_rxintr()
1379 sb->rxcsum); in gen_rxintr()
1388 device_printf(sc->dev, "gen_newbuf_rx %d\n", in gen_rxintr()
1398 m->m_pkthdr.csum_flags = CSUM_DATA_VALID | in gen_rxintr()
1400 m->m_pkthdr.csum_data = 0xffff; in gen_rxintr()
1402 m->m_data += sizeof(struct statusblock); in gen_rxintr()
1403 m->m_len -= sizeof(struct statusblock); in gen_rxintr()
1404 len -= sizeof(struct statusblock); in gen_rxintr()
1408 len -= ETHER_ALIGN; in gen_rxintr()
1411 m->m_pkthdr.rcvif = ifp; in gen_rxintr()
1412 m->m_pkthdr.len = len; in gen_rxintr()
1413 m->m_len = len; in gen_rxintr()
1416 m->m_nextpkt = NULL; in gen_rxintr()
1420 mt->m_nextpkt = m; in gen_rxintr()
1425 index = RX_NEXT(index, q->nentries); in gen_rxintr()
1427 q->cons_idx = (q->cons_idx + 1) & GENET_RX_DMA_PROD_CONS_MASK; in gen_rxintr()
1428 WR4(sc, GENET_RX_DMA_CONS_INDEX(q->hwindex), q->cons_idx); in gen_rxintr()
1458 ifp = sc->ifp; in gen_txintr()
1460 cons_idx = RD4(sc, GENET_TX_DMA_CONS_INDEX(q->hwindex)) & in gen_txintr()
1462 total = (cons_idx - q->cons_idx) & GENET_TX_DMA_PROD_CONS_MASK; in gen_txintr()
1465 for (i = q->next; q->queued > 0 && total > 0; in gen_txintr()
1466 i = TX_NEXT(i, q->nentries), total--) { in gen_txintr()
1469 ent = &q->entries[i]; in gen_txintr()
1470 if (ent->mbuf != NULL) { in gen_txintr()
1471 bus_dmamap_sync(sc->tx_buf_tag, ent->map, in gen_txintr()
1473 bus_dmamap_unload(sc->tx_buf_tag, ent->map); in gen_txintr()
1474 m_freem(ent->mbuf); in gen_txintr()
1475 ent->mbuf = NULL; in gen_txintr()
1480 --q->queued; in gen_txintr()
1484 q->next = i; in gen_txintr()
1488 q->cons_idx = cons_idx; in gen_txintr()
1496 device_printf(sc->dev, "gen_intr2\n"); in gen_intr2()
1508 m->m_pkthdr.len = m->m_len = m->m_ext.ext_size; in gen_newbuf_rx()
1522 map = q->entries[index].map; in gen_mapbuf_rx()
1523 if (bus_dmamap_load_mbuf_sg(sc->rx_buf_tag, map, m, &seg, &nsegs, in gen_mapbuf_rx()
1529 bus_dmamap_sync(sc->rx_buf_tag, map, BUS_DMASYNC_PREREAD); in gen_mapbuf_rx()
1531 q->entries[index].mbuf = m; in gen_mapbuf_rx()
1547 mii = device_get_softc(sc->miibus); in gen_ioctl()
1556 flags = if_getflags(ifp) ^ sc->if_flags; in gen_ioctl()
1565 sc->if_flags = if_getflags(ifp); in gen_ioctl()
1580 error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd); in gen_ioctl()
1585 flags = ifr->ifr_reqcap ^ enable; in gen_ioctl()
1619 ifp = sc->ifp; in gen_tick()
1620 mii = device_get_softc(sc->miibus); in gen_tick()
1627 link = sc->link; in gen_tick()
1629 if (sc->link && !link) in gen_tick()
1632 callout_reset(&sc->stat_ch, hz, gen_tick, sc); in gen_tick()
1650 for (retry = MII_BUSY_RETRY; retry > 0; retry--) { in gen_miibus_readreg()
1654 return (0); /* -1? */ in gen_miibus_readreg()
1681 for (retry = MII_BUSY_RETRY; retry > 0; retry--) { in gen_miibus_writereg()
1703 if ((if_getdrvflags(sc->ifp) & IFF_DRV_RUNNING) == 0) in gen_update_link_locked()
1705 mii = device_get_softc(sc->miibus); in gen_update_link_locked()
1707 if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == in gen_update_link_locked()
1709 switch (IFM_SUBTYPE(mii->mii_media_active)) { in gen_update_link_locked()
1713 sc->link = 1; in gen_update_link_locked()
1717 sc->link = 1; in gen_update_link_locked()
1721 sc->link = 1; in gen_update_link_locked()
1724 sc->link = 0; in gen_update_link_locked()
1728 sc->link = 0; in gen_update_link_locked()
1730 if (sc->link == 0) in gen_update_link_locked()
1737 if (sc->phy_mode == MII_CONTYPE_RGMII) in gen_update_link_locked()
1768 taskqueue_enqueue(taskqueue_swi, &sc->link_task); in gen_miibus_statchg()
1778 mii = device_get_softc(sc->miibus); in gen_media_status()
1782 ifmr->ifm_active = mii->mii_media_active; in gen_media_status()
1783 ifmr->ifm_status = mii->mii_media_status; in gen_media_status()
1795 mii = device_get_softc(sc->miibus); in gen_media_change()