Lines Matching +full:rev +full:- +full:mii

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
77 #include <dev/mii/mii.h>
78 #include <dev/mii/mii_bitbang.h>
79 #include <dev/mii/miivar.h>
83 #define SMC_LOCK(sc) mtx_lock(&(sc)->smc_mtx)
84 #define SMC_UNLOCK(sc) mtx_unlock(&(sc)->smc_mtx)
85 #define SMC_ASSERT_LOCKED(sc) mtx_assert(&(sc)->smc_mtx, MA_OWNED)
129 * MII bit-bang glue
150 bus_barrier(sc->smc_reg, BSR, 2, in smc_select_bank()
152 bus_write_2(sc->smc_reg, BSR, bank & BSR_BANK_MASK); in smc_select_bank()
153 bus_barrier(sc->smc_reg, BSR, 2, in smc_select_bank()
162 KASSERT((bus_read_2(sc->smc_reg, BSR) & in smc_mmu_wait()
164 device_get_nameunit(sc->smc_dev))); in smc_mmu_wait()
165 while (bus_read_2(sc->smc_reg, MMUCR) & MMUCR_BUSY) in smc_mmu_wait()
173 return (bus_read_1(sc->smc_reg, offset)); in smc_read_1()
180 bus_write_1(sc->smc_reg, offset, val); in smc_write_1()
187 return (bus_read_2(sc->smc_reg, offset)); in smc_read_2()
194 bus_write_2(sc->smc_reg, offset, val); in smc_write_2()
202 bus_read_multi_2(sc->smc_reg, offset, datap, count); in smc_read_multi_2()
210 bus_write_multi_2(sc->smc_reg, offset, datap, count); in smc_write_multi_2()
218 bus_barrier(sc->smc_reg, offset, length, flags); in smc_barrier()
234 if (sc->smc_usemem) in smc_probe()
283 /* Compare REV against known chip revisions. */ in smc_probe()
285 val = bus_read_2(reg, REV); in smc_probe()
313 sc->smc_dev = dev; in smc_attach()
315 ifp = sc->smc_ifp = if_alloc(IFT_ETHER); in smc_attach()
317 mtx_init(&sc->smc_mtx, device_get_nameunit(dev), NULL, MTX_DEF); in smc_attach()
320 callout_init_mtx(&sc->smc_watchdog, &sc->smc_mtx, 0); in smc_attach()
323 if (sc->smc_usemem) in smc_attach()
326 sc->smc_reg_rid = 0; in smc_attach()
327 sc->smc_reg = bus_alloc_resource_anywhere(dev, type, &sc->smc_reg_rid, in smc_attach()
329 if (sc->smc_reg == NULL) { in smc_attach()
334 sc->smc_irq = bus_alloc_resource_anywhere(dev, SYS_RES_IRQ, in smc_attach()
335 &sc->smc_irq_rid, 1, RF_ACTIVE | RF_SHAREABLE); in smc_attach()
336 if (sc->smc_irq == NULL) { in smc_attach()
346 val = smc_read_2(sc, REV); in smc_attach()
347 sc->smc_chip = (val & REV_CHIP_MASK) >> REV_CHIP_SHIFT; in smc_attach()
348 sc->smc_rev = (val * REV_REV_MASK) >> REV_REV_SHIFT; in smc_attach()
350 device_printf(dev, "revision %x\n", sc->smc_rev); in smc_attach()
352 callout_init_mtx(&sc->smc_mii_tick_ch, &sc->smc_mtx, in smc_attach()
354 if (sc->smc_chip >= REV_CHIP_91110FD) { in smc_attach()
355 (void)mii_attach(dev, &sc->smc_miibus, ifp, in smc_attach()
358 if (sc->smc_miibus != NULL) { in smc_attach()
359 sc->smc_mii_tick = smc_mii_tick; in smc_attach()
360 sc->smc_mii_mediachg = smc_mii_mediachg; in smc_attach()
361 sc->smc_mii_mediaioctl = smc_mii_mediaioctl; in smc_attach()
391 TASK_INIT(&sc->smc_intr, SMC_INTR_PRIORITY, smc_task_intr, ifp); in smc_attach()
392 NET_TASK_INIT(&sc->smc_rx, SMC_RX_PRIORITY, smc_task_rx, ifp); in smc_attach()
393 TASK_INIT(&sc->smc_tx, SMC_TX_PRIORITY, smc_task_tx, ifp); in smc_attach()
394 sc->smc_tq = taskqueue_create_fast("smc_taskq", M_NOWAIT, in smc_attach()
395 taskqueue_thread_enqueue, &sc->smc_tq); in smc_attach()
396 taskqueue_start_threads(&sc->smc_tq, 1, PI_NET, "%s taskq", in smc_attach()
397 device_get_nameunit(sc->smc_dev)); in smc_attach()
400 sc->smc_mask = 0; in smc_attach()
404 error = bus_setup_intr(dev, sc->smc_irq, in smc_attach()
405 INTR_TYPE_NET|INTR_MPSAFE, smc_intr, NULL, sc, &sc->smc_ih); in smc_attach()
426 if (sc->smc_ifp != NULL) { in smc_detach()
427 ether_ifdetach(sc->smc_ifp); in smc_detach()
430 callout_drain(&sc->smc_watchdog); in smc_detach()
431 callout_drain(&sc->smc_mii_tick_ch); in smc_detach()
434 if (sc->smc_if_getcapenable(ifp) & IFCAP_POLLING) in smc_detach()
435 ether_poll_deregister(sc->smc_ifp); in smc_detach()
438 if (sc->smc_ih != NULL) in smc_detach()
439 bus_teardown_intr(sc->smc_dev, sc->smc_irq, sc->smc_ih); in smc_detach()
441 if (sc->smc_tq != NULL) { in smc_detach()
442 taskqueue_drain(sc->smc_tq, &sc->smc_intr); in smc_detach()
443 taskqueue_drain(sc->smc_tq, &sc->smc_rx); in smc_detach()
444 taskqueue_drain(sc->smc_tq, &sc->smc_tx); in smc_detach()
445 taskqueue_free(sc->smc_tq); in smc_detach()
446 sc->smc_tq = NULL; in smc_detach()
449 if (sc->smc_ifp != NULL) { in smc_detach()
450 if_free(sc->smc_ifp); in smc_detach()
453 bus_generic_detach(sc->smc_dev); in smc_detach()
455 if (sc->smc_reg != NULL) { in smc_detach()
457 if (sc->smc_usemem) in smc_detach()
460 bus_release_resource(sc->smc_dev, type, sc->smc_reg_rid, in smc_detach()
461 sc->smc_reg); in smc_detach()
464 if (sc->smc_irq != NULL) in smc_detach()
465 bus_release_resource(sc->smc_dev, SYS_RES_IRQ, sc->smc_irq_rid, in smc_detach()
466 sc->smc_irq); in smc_detach()
468 if (mtx_initialized(&sc->smc_mtx)) in smc_detach()
469 mtx_destroy(&sc->smc_mtx); in smc_detach()
479 /* MII interface */
526 if (len > ETHER_MAX_LEN - ETHER_CRC_LEN) { in smc_start_locked()
537 sc->smc_pending = m; in smc_start_locked()
563 } while (--spin_count); in smc_start_locked()
570 sc->smc_mask |= ALLOC_INT; in smc_start_locked()
572 smc_write_1(sc, MSK, sc->smc_mask); in smc_start_locked()
576 taskqueue_enqueue(sc->smc_tq, &sc->smc_tx); in smc_start_locked()
595 if (sc->smc_pending == NULL) { in smc_task_tx()
600 m = m0 = sc->smc_pending; in smc_task_tx()
601 sc->smc_pending = NULL; in smc_task_tx()
640 for (; m != NULL; m = m->m_next) { in smc_task_tx()
642 smc_write_multi_2(sc, DATA0, (uint16_t *)data, m->m_len / 2); in smc_task_tx()
643 last_len = m->m_len; in smc_task_tx()
650 smc_write_2(sc, DATA0, (CTRL_ODD << 8) | data[last_len - 1]); in smc_task_tx()
657 sc->smc_mask |= TX_EMPTY_INT; in smc_task_tx()
659 smc_write_1(sc, MSK, sc->smc_mask); in smc_task_tx()
666 callout_reset(&sc->smc_watchdog, hz * 2, smc_watchdog, sc); in smc_task_tx()
726 len -= 6; in smc_task_rx()
744 m->m_pkthdr.rcvif = ifp; in smc_task_rx()
745 m->m_pkthdr.len = m->m_len = len + 2; /* XXX: Is this right? */ in smc_task_rx()
774 m->m_next = NULL; in smc_task_rx()
776 mtail->m_next = m; in smc_task_rx()
782 sc->smc_mask |= RCV_INT; in smc_task_rx()
784 smc_write_1(sc, MSK, sc->smc_mask); in smc_task_rx()
790 mhead = mhead->m_next; in smc_task_rx()
791 m->m_next = NULL; in smc_task_rx()
813 taskqueue_enqueue(sc->smc_tq, &sc->smc_intr); in smc_poll()
840 taskqueue_enqueue(sc->smc_tq, &sc->smc_intr); in smc_intr()
862 status = smc_read_1(sc, IST) & sc->smc_mask; in smc_task_intr()
869 * Kill off the packet if there is one and re-enable transmit. in smc_task_intr()
873 callout_stop(&sc->smc_watchdog); in smc_task_intr()
882 device_printf(sc->smc_dev, in smc_task_intr()
894 taskqueue_enqueue(sc->smc_tq, &sc->smc_tx); in smc_task_intr()
908 sc->smc_mask &= ~RCV_INT; in smc_task_intr()
909 taskqueue_enqueue(sc->smc_tq, &sc->smc_rx); in smc_task_intr()
917 sc->smc_mask &= ~ALLOC_INT; in smc_task_intr()
918 taskqueue_enqueue(sc->smc_tq, &sc->smc_tx); in smc_task_intr()
934 sc->smc_mask &= ~TX_EMPTY_INT; in smc_task_intr()
935 callout_stop(&sc->smc_watchdog); in smc_task_intr()
950 taskqueue_enqueue(sc->smc_tq, &sc->smc_tx); in smc_task_intr()
958 smc_write_1(sc, MSK, sc->smc_mask); in smc_task_intr()
974 device_get_nameunit(sc->smc_dev), in smc_mii_bitbang_read()
994 device_get_nameunit(sc->smc_dev), in smc_mii_bitbang_write()
1041 struct mii_data *mii; in smc_miibus_statchg() local
1045 mii = device_get_softc(sc->smc_miibus); in smc_miibus_statchg()
1052 if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) in smc_miibus_statchg()
1066 struct mii_data *mii; in smc_mii_ifmedia_upd() local
1069 if (sc->smc_miibus == NULL) in smc_mii_ifmedia_upd()
1072 mii = device_get_softc(sc->smc_miibus); in smc_mii_ifmedia_upd()
1073 return (mii_mediachg(mii)); in smc_mii_ifmedia_upd()
1080 struct mii_data *mii; in smc_mii_ifmedia_sts() local
1083 if (sc->smc_miibus == NULL) in smc_mii_ifmedia_sts()
1086 mii = device_get_softc(sc->smc_miibus); in smc_mii_ifmedia_sts()
1087 mii_pollstat(mii); in smc_mii_ifmedia_sts()
1088 ifmr->ifm_active = mii->mii_media_active; in smc_mii_ifmedia_sts()
1089 ifmr->ifm_status = mii->mii_media_status; in smc_mii_ifmedia_sts()
1099 if (sc->smc_miibus == NULL) in smc_mii_tick()
1104 mii_tick(device_get_softc(sc->smc_miibus)); in smc_mii_tick()
1105 callout_reset(&sc->smc_mii_tick_ch, hz, smc_mii_tick, sc); in smc_mii_tick()
1112 if (sc->smc_miibus == NULL) in smc_mii_mediachg()
1114 mii_mediachg(device_get_softc(sc->smc_miibus)); in smc_mii_mediachg()
1120 struct mii_data *mii; in smc_mii_mediaioctl() local
1122 if (sc->smc_miibus == NULL) in smc_mii_mediaioctl()
1125 mii = device_get_softc(sc->smc_miibus); in smc_mii_mediaioctl()
1126 return (ifmedia_ioctl(sc->smc_ifp, ifr, &mii->mii_media, command)); in smc_mii_mediaioctl()
1185 ifp = sc->smc_ifp; in smc_enable()
1204 sc->smc_mask = EPH_INT | RX_OVRN_INT | RCV_INT | TX_INT; in smc_enable()
1206 smc_write_1(sc, MSK, sc->smc_mask); in smc_enable()
1218 callout_stop(&sc->smc_watchdog); in smc_stop()
1219 callout_stop(&sc->smc_mii_tick_ch); in smc_stop()
1225 sc->smc_mask = 0; in smc_stop()
1228 ether_poll_deregister(sc->smc_ifp); in smc_stop()
1239 if_setdrvflagbits(sc->smc_ifp, 0, IFF_DRV_RUNNING); in smc_stop()
1248 device_printf(sc->smc_dev, "watchdog timeout\n"); in smc_watchdog()
1249 taskqueue_enqueue(sc->smc_tq, &sc->smc_intr); in smc_watchdog()
1269 ifp = sc->smc_ifp; in smc_init_locked()
1281 if (sc->smc_mii_tick != NULL) in smc_init_locked()
1282 callout_reset(&sc->smc_mii_tick_ch, hz, sc->smc_mii_tick, sc); in smc_init_locked()
1310 if (sc->smc_mii_mediachg != NULL) in smc_ioctl()
1311 sc->smc_mii_mediachg(sc); in smc_ioctl()
1327 if (sc->smc_mii_mediaioctl == NULL) { in smc_ioctl()
1331 sc->smc_mii_mediaioctl(sc, (struct ifreq *)data, cmd); in smc_ioctl()