Lines Matching +full:m +full:- +full:phy
1 /*-
2 * SPDX-License-Identifier: BSD-4-Clause
4 * Copyright (c) 1997, 1998, 1999, 2000-2003
18 * 4. Neither the name of the author nor the names of any co-contributors
52 * It uses an external PHY (reference designs use a RealTek chip),
53 * and has a 64-bit multicast hash filter. There is some information
57 * - You must set bit 7 in the RX control register, otherwise the
59 * - You must initialize all 3 IPG registers, or you won't be able
312 err = uether_do_request(&sc->sc_ue, &req, buf, 1000); in axe_cmd()
318 axe_miibus_readreg(device_t dev, int phy, int reg) in axe_miibus_readreg() argument
324 locked = mtx_owned(&sc->sc_mtx); in axe_miibus_readreg()
329 axe_cmd(sc, AXE_CMD_MII_READ_REG, reg, phy, &val); in axe_miibus_readreg()
337 * revered for embedded ethernet PHY. So clear the in axe_miibus_readreg()
349 axe_miibus_writereg(device_t dev, int phy, int reg, int val) in axe_miibus_writereg() argument
355 locked = mtx_owned(&sc->sc_mtx); in axe_miibus_writereg()
360 axe_cmd(sc, AXE_CMD_MII_WRITE_REG, reg, phy, &val); in axe_miibus_writereg()
377 locked = mtx_owned(&sc->sc_mtx); in axe_miibus_statchg()
381 ifp = uether_getifp(&sc->sc_ue); in axe_miibus_statchg()
386 sc->sc_flags &= ~AXE_FLAG_LINK; in axe_miibus_statchg()
387 if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == in axe_miibus_statchg()
389 switch (IFM_SUBTYPE(mii->mii_media_active)) { in axe_miibus_statchg()
392 sc->sc_flags |= AXE_FLAG_LINK; in axe_miibus_statchg()
395 if ((sc->sc_flags & AXE_FLAG_178) == 0) in axe_miibus_statchg()
397 sc->sc_flags |= AXE_FLAG_LINK; in axe_miibus_statchg()
405 if ((sc->sc_flags & AXE_FLAG_LINK) == 0) in axe_miibus_statchg()
409 if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) { in axe_miibus_statchg()
412 if ((IFM_OPTIONS(mii->mii_media_active) & in axe_miibus_statchg()
415 if ((IFM_OPTIONS(mii->mii_media_active) & in axe_miibus_statchg()
422 if ((sc->sc_flags & AXE_FLAG_178) != 0) in axe_miibus_statchg()
424 switch (IFM_SUBTYPE(mii->mii_media_active)) { in axe_miibus_statchg()
457 LIST_FOREACH(miisc, &mii->mii_phys, mii_list) in axe_ifmedia_upd()
474 ifmr->ifm_active = mii->mii_media_active; in axe_ifmedia_sts()
475 ifmr->ifm_status = mii->mii_media_status; in axe_ifmedia_sts()
522 switch (AXE_PHY_TYPE(sc->sc_phyaddrs[sel])) { in axe_get_phyno()
525 phyno = AXE_PHY_NO(sc->sc_phyaddrs[sel]); in axe_get_phyno()
534 phyno = -1; in axe_get_phyno()
553 ue = &sc->sc_ue; in axe_ax88178_init()
572 device_printf(sc->sc_ue.ue_dev, in axe_ax88178_init()
575 /* Program GPIOs depending on PHY hardware. */ in axe_ax88178_init()
632 axe_miibus_writereg(ue->ue_dev, sc->sc_phyno, in axe_ax88178_init()
634 axe_miibus_writereg(ue->ue_dev, sc->sc_phyno, in axe_ax88178_init()
636 val = axe_miibus_readreg(ue->ue_dev, sc->sc_phyno, in axe_ax88178_init()
638 axe_miibus_writereg(ue->ue_dev, sc->sc_phyno, in axe_ax88178_init()
640 axe_miibus_writereg(ue->ue_dev, sc->sc_phyno, in axe_ax88178_init()
645 /* Unknown PHY model or no need to program GPIOs. */ in axe_ax88178_init()
656 /* Enable MII/GMII/RGMII interface to work with external PHY. */ in axe_ax88178_init()
667 uether_pause(&sc->sc_ue, hz / 16); in axe_ax88772_init()
669 if (sc->sc_phyno == AXE_772_PHY_NO_EPHY) { in axe_ax88772_init()
670 /* ask for the embedded PHY */ in axe_ax88772_init()
672 uether_pause(&sc->sc_ue, hz / 64); in axe_ax88772_init()
677 uether_pause(&sc->sc_ue, hz / 16); in axe_ax88772_init()
682 uether_pause(&sc->sc_ue, hz / 4); in axe_ax88772_init()
691 /* ask for external PHY */ in axe_ax88772_init()
693 uether_pause(&sc->sc_ue, hz / 64); in axe_ax88772_init()
695 /* power down internal PHY */ in axe_ax88772_init()
700 uether_pause(&sc->sc_ue, hz / 4); in axe_ax88772_init()
707 if (sc->sc_phyno == AXE_772_PHY_NO_EPHY) { in axe_ax88772_phywake()
708 /* Manually select internal(embedded) PHY - MAC mode. */ in axe_ax88772_phywake()
712 uether_pause(&sc->sc_ue, hz / 32); in axe_ax88772_phywake()
715 * Manually select external PHY - MAC mode. in axe_ax88772_phywake()
716 * Reverse MII/RMII is for AX88772A PHY mode. in axe_ax88772_phywake()
720 uether_pause(&sc->sc_ue, hz / 32); in axe_ax88772_phywake()
722 /* Take PHY out of power down. */ in axe_ax88772_phywake()
725 uether_pause(&sc->sc_ue, hz / 4); in axe_ax88772_phywake()
727 uether_pause(&sc->sc_ue, hz); in axe_ax88772_phywake()
729 uether_pause(&sc->sc_ue, hz / 32); in axe_ax88772_phywake()
731 uether_pause(&sc->sc_ue, hz / 32); in axe_ax88772_phywake()
739 ue = &sc->sc_ue; in axe_ax88772a_init()
755 ue = &sc->sc_ue; in axe_ax88772b_init()
759 * Save PHY power saving configuration(high byte) and in axe_ax88772b_init()
763 sc->sc_pwrcfg = le16toh(eeprom) & 0xFF00; in axe_ax88772b_init()
766 * Auto-loaded default station address from internal ROM is in axe_ax88772b_init()
770 eaddr = ue->ue_eaddr; in axe_ax88772b_init()
778 /* Wakeup PHY. */ in axe_ax88772b_init()
792 cd = usbd_get_config_descriptor(sc->sc_ue.ue_udev); in axe_reset()
794 err = usbd_req_set_config(sc->sc_ue.ue_udev, &sc->sc_mtx, in axe_reset()
795 cd->bConfigurationValue); in axe_reset()
800 uether_pause(&sc->sc_ue, hz / 100); in axe_reset()
803 if (sc->sc_flags & AXE_FLAG_178) in axe_reset()
805 else if (sc->sc_flags & AXE_FLAG_772) in axe_reset()
807 else if (sc->sc_flags & AXE_FLAG_772A) in axe_reset()
809 else if (sc->sc_flags & AXE_FLAG_772B) in axe_reset()
819 * Load PHY indexes first. Needed by axe_xxx_init(). in axe_attach_post()
821 axe_cmd(sc, AXE_CMD_READ_PHYID, 0, 0, sc->sc_phyaddrs); in axe_attach_post()
823 device_printf(sc->sc_ue.ue_dev, "PHYADDR 0x%02x:0x%02x\n", in axe_attach_post()
824 sc->sc_phyaddrs[0], sc->sc_phyaddrs[1]); in axe_attach_post()
825 sc->sc_phyno = axe_get_phyno(sc, AXE_PHY_SEL_PRI); in axe_attach_post()
826 if (sc->sc_phyno == -1) in axe_attach_post()
827 sc->sc_phyno = axe_get_phyno(sc, AXE_PHY_SEL_SEC); in axe_attach_post()
828 if (sc->sc_phyno == -1) { in axe_attach_post()
829 device_printf(sc->sc_ue.ue_dev, in axe_attach_post()
830 "no valid PHY address found, assuming PHY address 0\n"); in axe_attach_post()
831 sc->sc_phyno = 0; in axe_attach_post()
835 if (sc->sc_flags & AXE_FLAG_178) { in axe_attach_post()
837 axe_cmd(sc, AXE_178_CMD_READ_NODEID, 0, 0, ue->ue_eaddr); in axe_attach_post()
838 } else if (sc->sc_flags & AXE_FLAG_772) { in axe_attach_post()
840 axe_cmd(sc, AXE_178_CMD_READ_NODEID, 0, 0, ue->ue_eaddr); in axe_attach_post()
841 } else if (sc->sc_flags & AXE_FLAG_772A) { in axe_attach_post()
843 axe_cmd(sc, AXE_178_CMD_READ_NODEID, 0, 0, ue->ue_eaddr); in axe_attach_post()
844 } else if (sc->sc_flags & AXE_FLAG_772B) { in axe_attach_post()
847 axe_cmd(sc, AXE_172_CMD_READ_NODEID, 0, 0, ue->ue_eaddr); in axe_attach_post()
852 if (sc->sc_flags & (AXE_FLAG_772A | AXE_FLAG_772B)) { in axe_attach_post()
854 sc->sc_ipgs[0] = 0x15; in axe_attach_post()
855 sc->sc_ipgs[1] = 0x16; in axe_attach_post()
856 sc->sc_ipgs[2] = 0x1A; in axe_attach_post()
858 axe_cmd(sc, AXE_CMD_READ_IPG012, 0, 0, sc->sc_ipgs); in axe_attach_post()
870 ifp = ue->ue_ifp; in axe_attach_post_sub()
880 if (sc->sc_flags & AXE_FLAG_772B) { in axe_attach_post_sub()
894 if (sc->sc_flags & (AXE_FLAG_772A | AXE_FLAG_772B | AXE_FLAG_178)) in axe_attach_post_sub()
899 error = mii_attach(ue->ue_dev, &ue->ue_miibus, ifp, in axe_attach_post_sub()
900 uether_ifmedia_upd, ue->ue_methods->ue_mii_sts, in axe_attach_post_sub()
901 BMSR_DEFCAPMASK, sc->sc_phyno, MII_OFFSET_ANY, adv_pause); in axe_attach_post_sub()
915 if (uaa->usb_mode != USB_MODE_HOST) in axe_probe()
917 if (uaa->info.bConfigIndex != AXE_CONFIG_IDX) in axe_probe()
919 if (uaa->info.bIfaceIndex != AXE_IFACE_IDX) in axe_probe()
934 struct usb_ether *ue = &sc->sc_ue; in axe_attach()
938 sc->sc_flags = USB_GET_DRIVER_INFO(uaa); in axe_attach()
942 mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF); in axe_attach()
945 error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer, in axe_attach()
946 axe_config, AXE_N_TRANSFER, sc, &sc->sc_mtx); in axe_attach()
952 ue->ue_sc = sc; in axe_attach()
953 ue->ue_dev = dev; in axe_attach()
954 ue->ue_udev = uaa->device; in axe_attach()
955 ue->ue_mtx = &sc->sc_mtx; in axe_attach()
956 ue->ue_methods = &axe_ue_methods; in axe_attach()
974 struct usb_ether *ue = &sc->sc_ue; in axe_detach()
976 usbd_transfer_unsetup(sc->sc_xfer, AXE_N_TRANSFER); in axe_detach()
978 mtx_destroy(&sc->sc_mtx); in axe_detach()
991 struct usb_ether *ue = &sc->sc_ue; in axe_bulk_read_callback()
1034 if ((sc->sc_flags & AXE_FLAG_STD_FRAME) != 0) { in axe_rx_frame()
1043 if ((hdr.len ^ hdr.ilen) != sc->sc_lenmask) { in axe_rx_frame()
1058 } else if ((sc->sc_flags & AXE_FLAG_CSUM_FRAME) != 0) { in axe_rx_frame()
1072 sc->sc_lenmask) { in axe_rx_frame()
1097 if_inc_counter(ue->ue_ifp, IFCOUNTER_IERRORS, 1); in axe_rx_frame()
1105 if_t ifp = ue->ue_ifp; in axe_rxeof()
1106 struct mbuf *m; in axe_rxeof() local
1108 if (len < ETHER_HDR_LEN || len > MCLBYTES - ETHER_ALIGN) { in axe_rxeof()
1113 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); in axe_rxeof()
1114 if (m == NULL) { in axe_rxeof()
1118 m->m_len = m->m_pkthdr.len = MCLBYTES; in axe_rxeof()
1119 m_adj(m, ETHER_ALIGN); in axe_rxeof()
1121 usbd_copy_out(pc, offset, mtod(m, uint8_t *), len); in axe_rxeof()
1124 m->m_pkthdr.rcvif = ifp; in axe_rxeof()
1125 m->m_pkthdr.len = m->m_len = len; in axe_rxeof()
1127 if (csum_hdr != NULL && csum_hdr->cstatus & AXE_CSUM_HDR_L3_TYPE_IPV4) { in axe_rxeof()
1128 if ((csum_hdr->cstatus & (AXE_CSUM_HDR_L4_CSUM_ERR | in axe_rxeof()
1130 m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED | in axe_rxeof()
1132 if ((csum_hdr->cstatus & AXE_CSUM_HDR_L4_TYPE_MASK) == in axe_rxeof()
1134 (csum_hdr->cstatus & AXE_CSUM_HDR_L4_TYPE_MASK) == in axe_rxeof()
1136 m->m_pkthdr.csum_flags |= in axe_rxeof()
1138 m->m_pkthdr.csum_data = 0xffff; in axe_rxeof()
1143 (void)mbufq_enqueue(&ue->ue_rxq, m); in axe_rxeof()
1156 if_t ifp = uether_getifp(&sc->sc_ue); in axe_bulk_write_callback()
1158 struct mbuf *m; in axe_bulk_write_callback() local
1168 if ((sc->sc_flags & AXE_FLAG_LINK) == 0 || in axe_bulk_write_callback()
1179 m = if_dequeue(ifp); in axe_bulk_write_callback()
1180 if (m == NULL) in axe_bulk_write_callback()
1187 hdr.len = htole16(m->m_pkthdr.len); in axe_bulk_write_callback()
1196 if ((m->m_pkthdr.csum_flags & in axe_bulk_write_callback()
1206 usbd_m_copy_in(pc, pos, m, 0, m->m_pkthdr.len); in axe_bulk_write_callback()
1207 pos += m->m_pkthdr.len; in axe_bulk_write_callback()
1216 usbd_m_copy_in(pc, pos, m, 0, m->m_pkthdr.len); in axe_bulk_write_callback()
1217 pos += m->m_pkthdr.len; in axe_bulk_write_callback()
1235 BPF_MTAP(ifp, m); in axe_bulk_write_callback()
1237 m_freem(m); in axe_bulk_write_callback()
1274 if ((sc->sc_flags & AXE_FLAG_LINK) == 0) { in axe_tick()
1275 axe_miibus_statchg(ue->ue_dev); in axe_tick()
1276 if ((sc->sc_flags & AXE_FLAG_LINK) != 0) in axe_tick()
1289 usbd_transfer_start(sc->sc_xfer[AXE_BULK_DT_RD]); in axe_start()
1290 usbd_transfer_start(sc->sc_xfer[AXE_BULK_DT_WR]); in axe_start()
1303 if ((sc->sc_flags & AXE_FLAG_772B) != 0) { in axe_csum_cfg()
1341 axe_cmd(sc, AXE_178_CMD_WRITE_IPG012, sc->sc_ipgs[2], in axe_init()
1342 (sc->sc_ipgs[1] << 8) | (sc->sc_ipgs[0]), NULL); in axe_init()
1345 axe_cmd(sc, AXE_172_CMD_WRITE_IPG0, 0, sc->sc_ipgs[0], NULL); in axe_init()
1346 axe_cmd(sc, AXE_172_CMD_WRITE_IPG1, 0, sc->sc_ipgs[1], NULL); in axe_init()
1347 axe_cmd(sc, AXE_172_CMD_WRITE_IPG2, 0, sc->sc_ipgs[2], NULL); in axe_init()
1351 sc->sc_flags &= ~(AXE_FLAG_STD_FRAME | AXE_FLAG_CSUM_FRAME); in axe_init()
1352 if ((sc->sc_flags & AXE_FLAG_772B) != 0 && in axe_init()
1354 sc->sc_lenmask = AXE_CSUM_HDR_LEN_MASK; in axe_init()
1355 sc->sc_flags |= AXE_FLAG_CSUM_FRAME; in axe_init()
1357 sc->sc_lenmask = AXE_HDR_LEN_MASK; in axe_init()
1358 sc->sc_flags |= AXE_FLAG_STD_FRAME; in axe_init()
1365 if (sc->sc_flags & AXE_FLAG_772B) { in axe_init()
1375 if (sc->sc_flags & AXE_FLAG_772B) { in axe_init()
1412 usbd_xfer_set_stall(sc->sc_xfer[AXE_BULK_DT_WR]); in axe_init()
1450 sc->sc_flags &= ~AXE_FLAG_LINK; in axe_stop()
1455 usbd_transfer_stop(sc->sc_xfer[AXE_BULK_DT_WR]); in axe_stop()
1456 usbd_transfer_stop(sc->sc_xfer[AXE_BULK_DT_RD]); in axe_stop()
1473 mask = ifr->ifr_reqcap ^ if_getcapenable(ifp); in axe_ioctl()