Lines Matching refs:sc

197 #define	FFEC_LOCK(sc)			mtx_lock(&(sc)->mtx)  argument
198 #define FFEC_UNLOCK(sc) mtx_unlock(&(sc)->mtx) argument
199 #define FFEC_LOCK_INIT(sc) mtx_init(&(sc)->mtx, \ argument
200 device_get_nameunit((sc)->dev), MTX_NETWORK_LOCK, MTX_DEF)
201 #define FFEC_LOCK_DESTROY(sc) mtx_destroy(&(sc)->mtx); argument
202 #define FFEC_ASSERT_LOCKED(sc) mtx_assert(&(sc)->mtx, MA_OWNED); argument
203 #define FFEC_ASSERT_UNLOCKED(sc) mtx_assert(&(sc)->mtx, MA_NOTOWNED); argument
205 static void ffec_init_locked(struct ffec_softc *sc);
206 static void ffec_stop_locked(struct ffec_softc *sc);
207 static void ffec_txstart_locked(struct ffec_softc *sc);
208 static void ffec_txfinish_locked(struct ffec_softc *sc);
211 RD2(struct ffec_softc *sc, bus_size_t off) in RD2() argument
214 return (bus_read_2(sc->mem_res, off)); in RD2()
218 WR2(struct ffec_softc *sc, bus_size_t off, uint16_t val) in WR2() argument
221 bus_write_2(sc->mem_res, off, val); in WR2()
225 RD4(struct ffec_softc *sc, bus_size_t off) in RD4() argument
228 return (bus_read_4(sc->mem_res, off)); in RD4()
232 WR4(struct ffec_softc *sc, bus_size_t off, uint32_t val) in WR4() argument
235 bus_write_4(sc->mem_res, off, val); in WR4()
239 next_rxidx(struct ffec_softc *sc, uint32_t curidx) in next_rxidx() argument
246 next_txidx(struct ffec_softc *sc, uint32_t curidx) in next_txidx() argument
262 ffec_miigasket_setup(struct ffec_softc *sc) in ffec_miigasket_setup() argument
270 switch (sc->fectype) in ffec_miigasket_setup()
278 switch (sc->phy_conn_type) in ffec_miigasket_setup()
294 WR2(sc, FEC_MIIGSK_ENR, 0); in ffec_miigasket_setup()
295 while (RD2(sc, FEC_MIIGSK_ENR) & FEC_MIIGSK_ENR_READY) in ffec_miigasket_setup()
298 WR2(sc, FEC_MIIGSK_CFGR, ifmode); in ffec_miigasket_setup()
300 WR2(sc, FEC_MIIGSK_ENR, FEC_MIIGSK_ENR_EN); in ffec_miigasket_setup()
301 while (!(RD2(sc, FEC_MIIGSK_ENR) & FEC_MIIGSK_ENR_READY)) in ffec_miigasket_setup()
306 ffec_miibus_iowait(struct ffec_softc *sc) in ffec_miibus_iowait() argument
311 if (RD4(sc, FEC_IER_REG) & FEC_IER_MII) in ffec_miibus_iowait()
320 struct ffec_softc *sc; in ffec_miibus_readreg() local
323 sc = device_get_softc(dev); in ffec_miibus_readreg()
325 WR4(sc, FEC_IER_REG, FEC_IER_MII); in ffec_miibus_readreg()
327 WR4(sc, FEC_MMFR_REG, FEC_MMFR_OP_READ | in ffec_miibus_readreg()
332 if (!ffec_miibus_iowait(sc)) { in ffec_miibus_readreg()
337 val = RD4(sc, FEC_MMFR_REG) & FEC_MMFR_DATA_MASK; in ffec_miibus_readreg()
345 struct ffec_softc *sc; in ffec_miibus_writereg() local
347 sc = device_get_softc(dev); in ffec_miibus_writereg()
349 WR4(sc, FEC_IER_REG, FEC_IER_MII); in ffec_miibus_writereg()
351 WR4(sc, FEC_MMFR_REG, FEC_MMFR_OP_WRITE | in ffec_miibus_writereg()
357 if (!ffec_miibus_iowait(sc)) { in ffec_miibus_writereg()
368 struct ffec_softc *sc; in ffec_miibus_statchg() local
377 sc = device_get_softc(dev); in ffec_miibus_statchg()
379 FFEC_ASSERT_LOCKED(sc); in ffec_miibus_statchg()
381 mii = sc->mii_softc; in ffec_miibus_statchg()
384 sc->link_is_up = true; in ffec_miibus_statchg()
386 sc->link_is_up = false; in ffec_miibus_statchg()
388 ecr = RD4(sc, FEC_ECR_REG) & ~FEC_ECR_SPEED; in ffec_miibus_statchg()
389 rcr = RD4(sc, FEC_RCR_REG) & ~(FEC_RCR_RMII_10T | FEC_RCR_RMII_MODE | in ffec_miibus_statchg()
391 tcr = RD4(sc, FEC_TCR_REG) & ~FEC_TCR_FDEN; in ffec_miibus_statchg()
394 switch (sc->phy_conn_type) { in ffec_miibus_statchg()
420 sc->link_is_up = false; in ffec_miibus_statchg()
423 sc->link_is_up = false; in ffec_miibus_statchg()
437 WR4(sc, FEC_RCR_REG, rcr); in ffec_miibus_statchg()
438 WR4(sc, FEC_TCR_REG, tcr); in ffec_miibus_statchg()
439 WR4(sc, FEC_ECR_REG, ecr); in ffec_miibus_statchg()
445 struct ffec_softc *sc; in ffec_media_status() local
449 sc = ifp->if_softc; in ffec_media_status()
450 mii = sc->mii_softc; in ffec_media_status()
451 FFEC_LOCK(sc); in ffec_media_status()
455 FFEC_UNLOCK(sc); in ffec_media_status()
459 ffec_media_change_locked(struct ffec_softc *sc) in ffec_media_change_locked() argument
462 return (mii_mediachg(sc->mii_softc)); in ffec_media_change_locked()
468 struct ffec_softc *sc; in ffec_media_change() local
471 sc = ifp->if_softc; in ffec_media_change()
473 FFEC_LOCK(sc); in ffec_media_change()
474 error = ffec_media_change_locked(sc); in ffec_media_change()
475 FFEC_UNLOCK(sc); in ffec_media_change()
479 static void ffec_clear_stats(struct ffec_softc *sc) in ffec_clear_stats() argument
483 mibc = RD4(sc, FEC_MIBC_REG); in ffec_clear_stats()
490 if (sc->fectype == FECTYPE_IMX6 || sc->fectype == FECTYPE_MVF) { in ffec_clear_stats()
491 WR4(sc, FEC_MIBC_REG, mibc | FEC_MIBC_CLEAR); in ffec_clear_stats()
492 WR4(sc, FEC_MIBC_REG, mibc & ~FEC_MIBC_CLEAR); in ffec_clear_stats()
494 WR4(sc, FEC_MIBC_REG, mibc | FEC_MIBC_DIS); in ffec_clear_stats()
496 WR4(sc, FEC_IEEE_R_DROP, 0); in ffec_clear_stats()
497 WR4(sc, FEC_IEEE_R_MACERR, 0); in ffec_clear_stats()
498 WR4(sc, FEC_RMON_R_CRC_ALIGN, 0); in ffec_clear_stats()
499 WR4(sc, FEC_RMON_R_FRAG, 0); in ffec_clear_stats()
500 WR4(sc, FEC_RMON_R_JAB, 0); in ffec_clear_stats()
501 WR4(sc, FEC_RMON_R_MC_PKT, 0); in ffec_clear_stats()
502 WR4(sc, FEC_RMON_R_OVERSIZE, 0); in ffec_clear_stats()
503 WR4(sc, FEC_RMON_R_PACKETS, 0); in ffec_clear_stats()
504 WR4(sc, FEC_RMON_R_UNDERSIZE, 0); in ffec_clear_stats()
505 WR4(sc, FEC_RMON_T_COL, 0); in ffec_clear_stats()
506 WR4(sc, FEC_RMON_T_CRC_ALIGN, 0); in ffec_clear_stats()
507 WR4(sc, FEC_RMON_T_FRAG, 0); in ffec_clear_stats()
508 WR4(sc, FEC_RMON_T_JAB, 0); in ffec_clear_stats()
509 WR4(sc, FEC_RMON_T_MC_PKT, 0); in ffec_clear_stats()
510 WR4(sc, FEC_RMON_T_OVERSIZE , 0); in ffec_clear_stats()
511 WR4(sc, FEC_RMON_T_PACKETS, 0); in ffec_clear_stats()
512 WR4(sc, FEC_RMON_T_UNDERSIZE, 0); in ffec_clear_stats()
514 WR4(sc, FEC_MIBC_REG, mibc); in ffec_clear_stats()
519 ffec_harvest_stats(struct ffec_softc *sc) in ffec_harvest_stats() argument
523 ifp = sc->ifp; in ffec_harvest_stats()
530 if_inc_counter(ifp, IFCOUNTER_IPACKETS, RD4(sc, FEC_RMON_R_PACKETS)); in ffec_harvest_stats()
531 if_inc_counter(ifp, IFCOUNTER_IMCASTS, RD4(sc, FEC_RMON_R_MC_PKT)); in ffec_harvest_stats()
533 RD4(sc, FEC_RMON_R_CRC_ALIGN) + RD4(sc, FEC_RMON_R_UNDERSIZE) + in ffec_harvest_stats()
534 RD4(sc, FEC_RMON_R_OVERSIZE) + RD4(sc, FEC_RMON_R_FRAG) + in ffec_harvest_stats()
535 RD4(sc, FEC_RMON_R_JAB) + RD4(sc, FEC_IEEE_R_DROP)); in ffec_harvest_stats()
537 if_inc_counter(ifp, IFCOUNTER_IQDROPS, RD4(sc, FEC_IEEE_R_MACERR)); in ffec_harvest_stats()
539 if_inc_counter(ifp, IFCOUNTER_OPACKETS, RD4(sc, FEC_RMON_T_PACKETS)); in ffec_harvest_stats()
540 if_inc_counter(ifp, IFCOUNTER_OMCASTS, RD4(sc, FEC_RMON_T_MC_PKT)); in ffec_harvest_stats()
542 RD4(sc, FEC_RMON_T_CRC_ALIGN) + RD4(sc, FEC_RMON_T_UNDERSIZE) + in ffec_harvest_stats()
543 RD4(sc, FEC_RMON_T_OVERSIZE) + RD4(sc, FEC_RMON_T_FRAG) + in ffec_harvest_stats()
544 RD4(sc, FEC_RMON_T_JAB)); in ffec_harvest_stats()
546 if_inc_counter(ifp, IFCOUNTER_COLLISIONS, RD4(sc, FEC_RMON_T_COL)); in ffec_harvest_stats()
548 ffec_clear_stats(sc); in ffec_harvest_stats()
554 struct ffec_softc *sc; in ffec_tick() local
558 sc = arg; in ffec_tick()
560 FFEC_ASSERT_LOCKED(sc); in ffec_tick()
562 ifp = sc->ifp; in ffec_tick()
572 if (sc->tx_watchdog_count > 0) { in ffec_tick()
573 if (--sc->tx_watchdog_count == 0) { in ffec_tick()
574 ffec_txfinish_locked(sc); in ffec_tick()
579 ffec_harvest_stats(sc); in ffec_tick()
582 link_was_up = sc->link_is_up; in ffec_tick()
583 mii_tick(sc->mii_softc); in ffec_tick()
584 if (sc->link_is_up && !link_was_up) in ffec_tick()
585 ffec_txstart_locked(sc); in ffec_tick()
588 callout_reset(&sc->ffec_callout, hz, ffec_tick, sc); in ffec_tick()
592 ffec_setup_txdesc(struct ffec_softc *sc, int idx, bus_addr_t paddr, in ffec_setup_txdesc() argument
598 nidx = next_txidx(sc, idx); in ffec_setup_txdesc()
603 --sc->txcount; in ffec_setup_txdesc()
606 ++sc->txcount; in ffec_setup_txdesc()
616 sc->txdesc_ring[idx].buf_paddr = (uint32_t)paddr; in ffec_setup_txdesc()
617 sc->txdesc_ring[idx].flags_len = flags | len; /* Must be set last! */ in ffec_setup_txdesc()
623 ffec_setup_txbuf(struct ffec_softc *sc, int idx, struct mbuf **mp) in ffec_setup_txbuf() argument
633 error = bus_dmamap_load_mbuf_sg(sc->txbuf_tag, sc->txbuf_map[idx].map, in ffec_setup_txbuf()
638 bus_dmamap_sync(sc->txbuf_tag, sc->txbuf_map[idx].map, in ffec_setup_txbuf()
641 sc->txbuf_map[idx].mbuf = m; in ffec_setup_txbuf()
642 ffec_setup_txdesc(sc, idx, seg.ds_addr, seg.ds_len); in ffec_setup_txbuf()
649 ffec_txstart_locked(struct ffec_softc *sc) in ffec_txstart_locked() argument
655 FFEC_ASSERT_LOCKED(sc); in ffec_txstart_locked()
657 if (!sc->link_is_up) in ffec_txstart_locked()
660 ifp = sc->ifp; in ffec_txstart_locked()
668 if (sc->txcount == (TX_DESC_COUNT-1)) { in ffec_txstart_locked()
675 if (ffec_setup_txbuf(sc, sc->tx_idx_head, &m) != 0) { in ffec_txstart_locked()
680 sc->tx_idx_head = next_txidx(sc, sc->tx_idx_head); in ffec_txstart_locked()
685 bus_dmamap_sync(sc->txdesc_tag, sc->txdesc_map, BUS_DMASYNC_PREWRITE); in ffec_txstart_locked()
686 WR4(sc, FEC_TDAR_REG, FEC_TDAR_TDAR); in ffec_txstart_locked()
687 bus_dmamap_sync(sc->txdesc_tag, sc->txdesc_map, BUS_DMASYNC_POSTWRITE); in ffec_txstart_locked()
688 sc->tx_watchdog_count = WATCHDOG_TIMEOUT_SECS; in ffec_txstart_locked()
695 struct ffec_softc *sc = ifp->if_softc; in ffec_txstart() local
697 FFEC_LOCK(sc); in ffec_txstart()
698 ffec_txstart_locked(sc); in ffec_txstart()
699 FFEC_UNLOCK(sc); in ffec_txstart()
703 ffec_txfinish_locked(struct ffec_softc *sc) in ffec_txfinish_locked() argument
710 FFEC_ASSERT_LOCKED(sc); in ffec_txfinish_locked()
713 bus_dmamap_sync(sc->txdesc_tag, sc->txdesc_map, BUS_DMASYNC_PREREAD); in ffec_txfinish_locked()
714 bus_dmamap_sync(sc->txdesc_tag, sc->txdesc_map, BUS_DMASYNC_POSTREAD); in ffec_txfinish_locked()
715 ifp = sc->ifp; in ffec_txfinish_locked()
717 while (sc->tx_idx_tail != sc->tx_idx_head) { in ffec_txfinish_locked()
718 desc = &sc->txdesc_ring[sc->tx_idx_tail]; in ffec_txfinish_locked()
722 bmap = &sc->txbuf_map[sc->tx_idx_tail]; in ffec_txfinish_locked()
723 bus_dmamap_sync(sc->txbuf_tag, bmap->map, in ffec_txfinish_locked()
725 bus_dmamap_unload(sc->txbuf_tag, bmap->map); in ffec_txfinish_locked()
728 ffec_setup_txdesc(sc, sc->tx_idx_tail, 0, 0); in ffec_txfinish_locked()
729 sc->tx_idx_tail = next_txidx(sc, sc->tx_idx_tail); in ffec_txfinish_locked()
738 ffec_txstart_locked(sc); in ffec_txfinish_locked()
742 if (sc->tx_idx_tail == sc->tx_idx_head) { in ffec_txfinish_locked()
743 sc->tx_watchdog_count = 0; in ffec_txfinish_locked()
748 ffec_setup_rxdesc(struct ffec_softc *sc, int idx, bus_addr_t paddr) in ffec_setup_rxdesc() argument
757 nidx = next_rxidx(sc, idx); in ffec_setup_rxdesc()
758 sc->rxdesc_ring[idx].buf_paddr = (uint32_t)paddr; in ffec_setup_rxdesc()
759 sc->rxdesc_ring[idx].flags_len = FEC_RXDESC_EMPTY | in ffec_setup_rxdesc()
766 ffec_setup_rxbuf(struct ffec_softc *sc, int idx, struct mbuf * m) in ffec_setup_rxbuf() argument
771 if (!(sc->fecflags & FECFLAG_RACC)) { in ffec_setup_rxbuf()
780 m_adj(m, roundup(ETHER_ALIGN, sc->rxbuf_align)); in ffec_setup_rxbuf()
783 error = bus_dmamap_load_mbuf_sg(sc->rxbuf_tag, sc->rxbuf_map[idx].map, in ffec_setup_rxbuf()
789 bus_dmamap_sync(sc->rxbuf_tag, sc->rxbuf_map[idx].map, in ffec_setup_rxbuf()
792 sc->rxbuf_map[idx].mbuf = m; in ffec_setup_rxbuf()
793 ffec_setup_rxdesc(sc, idx, seg.ds_addr); in ffec_setup_rxbuf()
799 ffec_alloc_mbufcl(struct ffec_softc *sc) in ffec_alloc_mbufcl() argument
811 ffec_rxfinish_onebuf(struct ffec_softc *sc, int len) in ffec_rxfinish_onebuf() argument
823 if ((newmbuf = ffec_alloc_mbufcl(sc)) == NULL) { in ffec_rxfinish_onebuf()
824 if_inc_counter(sc->ifp, IFCOUNTER_IQDROPS, 1); in ffec_rxfinish_onebuf()
825 ffec_setup_rxdesc(sc, sc->rx_idx, in ffec_rxfinish_onebuf()
826 sc->rxdesc_ring[sc->rx_idx].buf_paddr); in ffec_rxfinish_onebuf()
830 FFEC_UNLOCK(sc); in ffec_rxfinish_onebuf()
832 bmap = &sc->rxbuf_map[sc->rx_idx]; in ffec_rxfinish_onebuf()
834 bus_dmamap_sync(sc->rxbuf_tag, bmap->map, BUS_DMASYNC_POSTREAD); in ffec_rxfinish_onebuf()
835 bus_dmamap_unload(sc->rxbuf_tag, bmap->map); in ffec_rxfinish_onebuf()
840 m->m_pkthdr.rcvif = sc->ifp; in ffec_rxfinish_onebuf()
852 if (sc->fecflags & FECFLAG_RACC) { in ffec_rxfinish_onebuf()
860 sc->ifp->if_input(sc->ifp, m); in ffec_rxfinish_onebuf()
862 FFEC_LOCK(sc); in ffec_rxfinish_onebuf()
864 if ((error = ffec_setup_rxbuf(sc, sc->rx_idx, newmbuf)) != 0) { in ffec_rxfinish_onebuf()
865 device_printf(sc->dev, "ffec_setup_rxbuf error %d\n", error); in ffec_rxfinish_onebuf()
872 ffec_rxfinish_locked(struct ffec_softc *sc) in ffec_rxfinish_locked() argument
878 FFEC_ASSERT_LOCKED(sc); in ffec_rxfinish_locked()
881 bus_dmamap_sync(sc->rxdesc_tag, sc->rxdesc_map, BUS_DMASYNC_PREREAD); in ffec_rxfinish_locked()
882 bus_dmamap_sync(sc->rxdesc_tag, sc->rxdesc_map, BUS_DMASYNC_POSTREAD); in ffec_rxfinish_locked()
885 desc = &sc->rxdesc_ring[sc->rx_idx]; in ffec_rxfinish_locked()
894 ffec_setup_rxdesc(sc, sc->rx_idx, in ffec_rxfinish_locked()
895 sc->rxdesc_ring[sc->rx_idx].buf_paddr); in ffec_rxfinish_locked()
906 device_printf(sc->dev, in ffec_rxfinish_locked()
908 ffec_setup_rxdesc(sc, sc->rx_idx, in ffec_rxfinish_locked()
909 sc->rxdesc_ring[sc->rx_idx].buf_paddr); in ffec_rxfinish_locked()
918 ffec_setup_rxdesc(sc, sc->rx_idx, in ffec_rxfinish_locked()
919 sc->rxdesc_ring[sc->rx_idx].buf_paddr); in ffec_rxfinish_locked()
924 ffec_rxfinish_onebuf(sc, len); in ffec_rxfinish_locked()
926 sc->rx_idx = next_rxidx(sc, sc->rx_idx); in ffec_rxfinish_locked()
930 bus_dmamap_sync(sc->rxdesc_tag, sc->rxdesc_map, BUS_DMASYNC_PREWRITE); in ffec_rxfinish_locked()
931 WR4(sc, FEC_RDAR_REG, FEC_RDAR_RDAR); in ffec_rxfinish_locked()
932 bus_dmamap_sync(sc->rxdesc_tag, sc->rxdesc_map, BUS_DMASYNC_POSTWRITE); in ffec_rxfinish_locked()
937 ffec_get_hwaddr(struct ffec_softc *sc, uint8_t *hwaddr) in ffec_get_hwaddr() argument
950 palr = RD4(sc, FEC_PALR_REG); in ffec_get_hwaddr()
951 paur = RD4(sc, FEC_PAUR_REG) & FEC_PAUR_PADDR2_MASK; in ffec_get_hwaddr()
970 device_printf(sc->dev, in ffec_get_hwaddr()
991 ffec_setup_rxfilter(struct ffec_softc *sc) in ffec_setup_rxfilter() argument
997 FFEC_ASSERT_LOCKED(sc); in ffec_setup_rxfilter()
999 ifp = sc->ifp; in ffec_setup_rxfilter()
1010 WR4(sc, FEC_GAUR_REG, (uint32_t)(ghash >> 32)); in ffec_setup_rxfilter()
1011 WR4(sc, FEC_GALR_REG, (uint32_t)ghash); in ffec_setup_rxfilter()
1025 WR4(sc, FEC_IAUR_REG, (uint32_t)(ihash >> 32)); in ffec_setup_rxfilter()
1026 WR4(sc, FEC_IALR_REG, (uint32_t)ihash); in ffec_setup_rxfilter()
1032 WR4(sc, FEC_PALR_REG, (eaddr[0] << 24) | (eaddr[1] << 16) | in ffec_setup_rxfilter()
1034 WR4(sc, FEC_PAUR_REG, (eaddr[4] << 24) | (eaddr[5] << 16)); in ffec_setup_rxfilter()
1038 ffec_stop_locked(struct ffec_softc *sc) in ffec_stop_locked() argument
1045 FFEC_ASSERT_LOCKED(sc); in ffec_stop_locked()
1047 ifp = sc->ifp; in ffec_stop_locked()
1049 sc->tx_watchdog_count = 0; in ffec_stop_locked()
1055 WR4(sc, FEC_ECR_REG, RD4(sc, FEC_ECR_REG) & ~FEC_ECR_ETHEREN); in ffec_stop_locked()
1056 WR4(sc, FEC_IEM_REG, 0x00000000); in ffec_stop_locked()
1057 WR4(sc, FEC_IER_REG, 0xffffffff); in ffec_stop_locked()
1066 callout_stop(&sc->ffec_callout); in ffec_stop_locked()
1075 idx = sc->tx_idx_tail; in ffec_stop_locked()
1076 while (idx != sc->tx_idx_head) { in ffec_stop_locked()
1077 desc = &sc->txdesc_ring[idx]; in ffec_stop_locked()
1078 bmap = &sc->txbuf_map[idx]; in ffec_stop_locked()
1080 bus_dmamap_unload(sc->txbuf_tag, bmap->map); in ffec_stop_locked()
1083 ffec_setup_txdesc(sc, idx, 0, 0); in ffec_stop_locked()
1085 idx = next_txidx(sc, idx); in ffec_stop_locked()
1095 desc = &sc->rxdesc_ring[idx]; in ffec_stop_locked()
1096 ffec_setup_rxdesc(sc, idx, desc->buf_paddr); in ffec_stop_locked()
1101 ffec_init_locked(struct ffec_softc *sc) in ffec_init_locked() argument
1103 struct ifnet *ifp = sc->ifp; in ffec_init_locked()
1106 FFEC_ASSERT_LOCKED(sc); in ffec_init_locked()
1125 maxbuf = MCLBYTES - roundup(ETHER_ALIGN, sc->rxbuf_align); in ffec_init_locked()
1132 WR4(sc, FEC_IEM_REG, 0x00000000); in ffec_init_locked()
1133 WR4(sc, FEC_IER_REG, 0xffffffff); in ffec_init_locked()
1138 ffec_setup_rxfilter(sc); in ffec_init_locked()
1150 WR4(sc, FEC_TFWR_REG, FEC_TFWR_STRFWD | FEC_TFWR_TWFR_128BYTE); in ffec_init_locked()
1156 WR4(sc, FEC_RCR_REG, (maxfl << FEC_RCR_MAX_FL_SHIFT)); in ffec_init_locked()
1164 WR4(sc, FEC_TCR_REG, 0); in ffec_init_locked()
1171 WR4(sc, FEC_OPD_REG, 0x00010020); in ffec_init_locked()
1195 WR4(sc, FEC_MRBR_REG, maxfl << FEC_MRBR_R_BUF_SIZE_SHIFT); in ffec_init_locked()
1202 WR4(sc, FEC_FTRL_REG, maxfl); in ffec_init_locked()
1211 sc->rx_idx = 0; in ffec_init_locked()
1212 sc->tx_idx_head = sc->tx_idx_tail = 0; in ffec_init_locked()
1213 sc->txcount = 0; in ffec_init_locked()
1214 WR4(sc, FEC_RDSR_REG, sc->rxdesc_ring_paddr); in ffec_init_locked()
1215 WR4(sc, FEC_TDSR_REG, sc->txdesc_ring_paddr); in ffec_init_locked()
1224 WR4(sc, FEC_IEM_REG, FEC_IER_TXF | FEC_IER_RXF | FEC_IER_EBERR); in ffec_init_locked()
1230 regval = RD4(sc, FEC_MIBC_REG); in ffec_init_locked()
1231 WR4(sc, FEC_MIBC_REG, regval | FEC_MIBC_DIS); in ffec_init_locked()
1232 ffec_clear_stats(sc); in ffec_init_locked()
1233 WR4(sc, FEC_MIBC_REG, regval & ~FEC_MIBC_DIS); in ffec_init_locked()
1235 if (sc->fecflags & FECFLAG_RACC) { in ffec_init_locked()
1239 regval = RD4(sc, FEC_RACC_REG); in ffec_init_locked()
1240 WR4(sc, FEC_RACC_REG, regval | FEC_RACC_SHIFT16); in ffec_init_locked()
1252 regval = RD4(sc, FEC_ECR_REG); in ffec_init_locked()
1257 WR4(sc, FEC_ECR_REG, regval); in ffec_init_locked()
1265 mii_mediachg(sc->mii_softc); in ffec_init_locked()
1266 callout_reset(&sc->ffec_callout, hz, ffec_tick, sc); in ffec_init_locked()
1272 WR4(sc, FEC_RDAR_REG, FEC_RDAR_RDAR); in ffec_init_locked()
1278 struct ffec_softc *sc = if_softc; in ffec_init() local
1280 FFEC_LOCK(sc); in ffec_init()
1281 ffec_init_locked(sc); in ffec_init()
1282 FFEC_UNLOCK(sc); in ffec_init()
1288 struct ffec_softc *sc; in ffec_intr() local
1291 sc = arg; in ffec_intr()
1293 FFEC_LOCK(sc); in ffec_intr()
1295 ier = RD4(sc, FEC_IER_REG); in ffec_intr()
1298 WR4(sc, FEC_IER_REG, FEC_IER_TXF); in ffec_intr()
1299 ffec_txfinish_locked(sc); in ffec_intr()
1303 WR4(sc, FEC_IER_REG, FEC_IER_RXF); in ffec_intr()
1304 ffec_rxfinish_locked(sc); in ffec_intr()
1316 WR4(sc, FEC_IER_REG, FEC_IER_EBERR); in ffec_intr()
1317 device_printf(sc->dev, in ffec_intr()
1319 ffec_stop_locked(sc); in ffec_intr()
1320 ffec_init_locked(sc); in ffec_intr()
1323 FFEC_UNLOCK(sc); in ffec_intr()
1330 struct ffec_softc *sc; in ffec_ioctl() local
1335 sc = ifp->if_softc; in ffec_ioctl()
1341 FFEC_LOCK(sc); in ffec_ioctl()
1344 if ((ifp->if_flags ^ sc->if_flags) & in ffec_ioctl()
1346 ffec_setup_rxfilter(sc); in ffec_ioctl()
1348 if (!sc->is_detaching) in ffec_ioctl()
1349 ffec_init_locked(sc); in ffec_ioctl()
1353 ffec_stop_locked(sc); in ffec_ioctl()
1355 sc->if_flags = ifp->if_flags; in ffec_ioctl()
1356 FFEC_UNLOCK(sc); in ffec_ioctl()
1362 FFEC_LOCK(sc); in ffec_ioctl()
1363 ffec_setup_rxfilter(sc); in ffec_ioctl()
1364 FFEC_UNLOCK(sc); in ffec_ioctl()
1370 mii = sc->mii_softc; in ffec_ioctl()
1393 struct ffec_softc *sc; in ffec_detach() local
1402 sc = device_get_softc(dev); in ffec_detach()
1404 if (sc->is_attached) { in ffec_detach()
1405 FFEC_LOCK(sc); in ffec_detach()
1406 sc->is_detaching = true; in ffec_detach()
1407 ffec_stop_locked(sc); in ffec_detach()
1408 FFEC_UNLOCK(sc); in ffec_detach()
1409 callout_drain(&sc->ffec_callout); in ffec_detach()
1410 ether_ifdetach(sc->ifp); in ffec_detach()
1417 if ((map = sc->rxbuf_map[idx].map) != NULL) { in ffec_detach()
1418 bus_dmamap_unload(sc->rxbuf_tag, map); in ffec_detach()
1419 bus_dmamap_destroy(sc->rxbuf_tag, map); in ffec_detach()
1420 m_freem(sc->rxbuf_map[idx].mbuf); in ffec_detach()
1423 if (sc->rxbuf_tag != NULL) in ffec_detach()
1424 bus_dma_tag_destroy(sc->rxbuf_tag); in ffec_detach()
1425 if (sc->rxdesc_map != NULL) { in ffec_detach()
1426 bus_dmamap_unload(sc->rxdesc_tag, sc->rxdesc_map); in ffec_detach()
1427 bus_dmamem_free(sc->rxdesc_tag, sc->rxdesc_ring, in ffec_detach()
1428 sc->rxdesc_map); in ffec_detach()
1430 if (sc->rxdesc_tag != NULL) in ffec_detach()
1431 bus_dma_tag_destroy(sc->rxdesc_tag); in ffec_detach()
1435 if ((map = sc->txbuf_map[idx].map) != NULL) { in ffec_detach()
1437 bus_dmamap_destroy(sc->txbuf_tag, map); in ffec_detach()
1440 if (sc->txbuf_tag != NULL) in ffec_detach()
1441 bus_dma_tag_destroy(sc->txbuf_tag); in ffec_detach()
1442 if (sc->txdesc_map != NULL) { in ffec_detach()
1443 bus_dmamap_unload(sc->txdesc_tag, sc->txdesc_map); in ffec_detach()
1444 bus_dmamem_free(sc->txdesc_tag, sc->txdesc_ring, in ffec_detach()
1445 sc->txdesc_map); in ffec_detach()
1447 if (sc->txdesc_tag != NULL) in ffec_detach()
1448 bus_dma_tag_destroy(sc->txdesc_tag); in ffec_detach()
1452 if (sc->intr_cookie[irq] != NULL) { in ffec_detach()
1453 bus_teardown_intr(dev, sc->irq_res[irq], in ffec_detach()
1454 sc->intr_cookie[irq]); in ffec_detach()
1457 bus_release_resources(dev, irq_res_spec, sc->irq_res); in ffec_detach()
1459 if (sc->mem_res != NULL) in ffec_detach()
1460 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res); in ffec_detach()
1462 FFEC_LOCK_DESTROY(sc); in ffec_detach()
1469 struct ffec_softc *sc; in ffec_attach() local
1479 sc = device_get_softc(dev); in ffec_attach()
1480 sc->dev = dev; in ffec_attach()
1482 FFEC_LOCK_INIT(sc); in ffec_attach()
1489 sc->fectype = (uint8_t)(typeflags & FECTYPE_MASK); in ffec_attach()
1490 sc->fecflags = (uint32_t)(typeflags & ~FECTYPE_MASK); in ffec_attach()
1492 if (sc->fecflags & FECFLAG_AVB) { in ffec_attach()
1493 sc->rxbuf_align = 64; in ffec_attach()
1494 sc->txbuf_align = 1; in ffec_attach()
1496 sc->rxbuf_align = 16; in ffec_attach()
1497 sc->txbuf_align = 16; in ffec_attach()
1509 sc->phy_conn_type = mii_fdt_get_contype(ofw_node); in ffec_attach()
1510 if (sc->phy_conn_type == MII_CONTYPE_UNKNOWN) { in ffec_attach()
1511 device_printf(sc->dev, "No valid 'phy-mode' " in ffec_attach()
1517 callout_init_mtx(&sc->ffec_callout, &sc->mtx, 0); in ffec_attach()
1521 sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, in ffec_attach()
1523 if (sc->mem_res == NULL) { in ffec_attach()
1529 error = bus_alloc_resources(dev, irq_res_spec, sc->irq_res); in ffec_attach()
1548 &sc->txdesc_tag); in ffec_attach()
1550 device_printf(sc->dev, in ffec_attach()
1555 error = bus_dmamem_alloc(sc->txdesc_tag, (void**)&sc->txdesc_ring, in ffec_attach()
1556 BUS_DMA_COHERENT | BUS_DMA_WAITOK | BUS_DMA_ZERO, &sc->txdesc_map); in ffec_attach()
1558 device_printf(sc->dev, in ffec_attach()
1563 error = bus_dmamap_load(sc->txdesc_tag, sc->txdesc_map, sc->txdesc_ring, in ffec_attach()
1564 TX_DESC_SIZE, ffec_get1paddr, &sc->txdesc_ring_paddr, 0); in ffec_attach()
1566 device_printf(sc->dev, in ffec_attach()
1573 sc->txbuf_align, 0, /* alignment, boundary */ in ffec_attach()
1581 &sc->txbuf_tag); in ffec_attach()
1583 device_printf(sc->dev, in ffec_attach()
1589 error = bus_dmamap_create(sc->txbuf_tag, 0, in ffec_attach()
1590 &sc->txbuf_map[idx].map); in ffec_attach()
1592 device_printf(sc->dev, in ffec_attach()
1596 ffec_setup_txdesc(sc, idx, 0, 0); in ffec_attach()
1612 &sc->rxdesc_tag); in ffec_attach()
1614 device_printf(sc->dev, in ffec_attach()
1619 error = bus_dmamem_alloc(sc->rxdesc_tag, (void **)&sc->rxdesc_ring, in ffec_attach()
1620 BUS_DMA_COHERENT | BUS_DMA_WAITOK | BUS_DMA_ZERO, &sc->rxdesc_map); in ffec_attach()
1622 device_printf(sc->dev, in ffec_attach()
1627 error = bus_dmamap_load(sc->rxdesc_tag, sc->rxdesc_map, sc->rxdesc_ring, in ffec_attach()
1628 RX_DESC_SIZE, ffec_get1paddr, &sc->rxdesc_ring_paddr, 0); in ffec_attach()
1630 device_printf(sc->dev, in ffec_attach()
1645 &sc->rxbuf_tag); in ffec_attach()
1647 device_printf(sc->dev, in ffec_attach()
1653 error = bus_dmamap_create(sc->rxbuf_tag, 0, in ffec_attach()
1654 &sc->rxbuf_map[idx].map); in ffec_attach()
1656 device_printf(sc->dev, in ffec_attach()
1660 if ((m = ffec_alloc_mbufcl(sc)) == NULL) { in ffec_attach()
1665 if ((error = ffec_setup_rxbuf(sc, idx, m)) != 0) { in ffec_attach()
1666 device_printf(sc->dev, in ffec_attach()
1673 ffec_get_hwaddr(sc, eaddr); in ffec_attach()
1686 if (sc->fecflags & FECFLAG_AVB) in ffec_attach()
1687 WR4(sc, FEC_ECR_REG, 0); in ffec_attach()
1689 WR4(sc, FEC_ECR_REG, FEC_ECR_RESET); in ffec_attach()
1693 if (sc->irq_res[irq] != NULL) { in ffec_attach()
1694 error = bus_setup_intr(dev, sc->irq_res[irq], in ffec_attach()
1695 INTR_TYPE_NET | INTR_MPSAFE, NULL, ffec_intr, sc, in ffec_attach()
1696 &sc->intr_cookie[irq]); in ffec_attach()
1736 WR4(sc, FEC_MSCR_REG, mscr); in ffec_attach()
1739 sc->ifp = ifp = if_alloc(IFT_ETHER); in ffec_attach()
1741 ifp->if_softc = sc; in ffec_attach()
1755 ifp->if_linkmib = &sc->mibdata; in ffec_attach()
1756 ifp->if_linkmiblen = sizeof(sc->mibdata); in ffec_attach()
1760 ffec_miigasket_setup(sc); in ffec_attach()
1766 error = mii_attach(dev, &sc->miibus, ifp, ffec_media_change, in ffec_attach()
1768 (sc->fecflags & FECTYPE_MVF) ? MIIF_FORCEANEG : 0); in ffec_attach()
1773 sc->mii_softc = device_get_softc(sc->miibus); in ffec_attach()
1777 sc->is_attached = true; in ffec_attach()