From: Kirill A. Korinsky Subject: sys/ure: add support of RTL8159 To: OpenBSD tech , Kevin Lo Date: Mon, 05 Oct 2026 13:20:58 +0200 Kevin, tech@, this is stright forward implementation of support of RTL8159 which reuses RTL8157 logic and claim support of 10Gb PHY. Tested on Ocnvlia RTL8159 with direct connect to USW Flex 2.5G 8 PoE, it claims on OpenBSD side: media: Ethernet autoselect (10GbaseT full-duplex) and I see 10Gb connection in Unifi UI as well. But I haven't got the second 10Gb NIC here, so that speed is untested. Anyway, Linux folks claimed that 10Gb PHY requires a firmware which is missed at linux-firmware, but I found some extractor https://gitlab.com/koblitz-rtlnic/rtlnic_fw with very unclear license policy. Thus, adding firmware to ure brings more complexity which I avoided. Notable to say that this linux patch series was very helpful with explanation how that chip should be implemented: https://patchew.org/linux/20260505-rtl8159._5Fnet._5Fnext-v4-0-1a648a9c4d8d@birger-koblitz.de/ Ok? Index: sys/dev/usb/if_ure.c =================================================================== RCS file: /home/cvs/src/sys/dev/usb/if_ure.c,v diff -u -p -r1.37 if_ure.c --- sys/dev/usb/if_ure.c 4 Jun 2025 00:06:17 -0000 1.37 +++ sys/dev/usb/if_ure.c 1 Oct 2026 20:55:39 -0000 @@ -120,6 +120,7 @@ const struct usb_devno ure_devs[] = { { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8153 }, { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8156 }, { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8157 }, + { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8159 }, { USB_VENDOR_SAMSUNG2, USB_PRODUCT_SAMSUNG2_RTL8153 }, { USB_VENDOR_TOSHIBA, USB_PRODUCT_TOSHIBA_RTL8153B }, { USB_VENDOR_TPLINK, USB_PRODUCT_TPLINK_EU300 }, @@ -602,21 +603,22 @@ ure_ifmedia_init(struct ifnet *ifp) ure_write_1(sc, URE_PLA_CRWECR, URE_MCU_TYPE_PLA, URE_CRWECR_NORAML); if (!(sc->ure_flags & URE_FLAG_8152)) { - if (sc->ure_flags & (URE_FLAG_8156B | URE_FLAG_8157)) + if (sc->ure_flags & + (URE_FLAG_8156B | URE_FLAG_8157 | URE_FLAG_8159)) URE_CLRBIT_2(sc, URE_USB_RX_AGGR_NUM, URE_MCU_TYPE_USB, URE_RX_AGGR_NUM_MASK); reg = sc->ure_rxbufsz - URE_FRAMELEN(ifp->if_mtu); - if (sc->ure_flags & URE_FLAG_8157) + if (sc->ure_flags & (URE_FLAG_8157 | URE_FLAG_8159)) reg -= sizeof(struct ure_rxpkt_v2) + URE_8157_BUF_ALIGN; else reg -= sizeof(struct ure_rxpkt) + URE_RX_BUF_ALIGN; if (sc->ure_flags & (URE_FLAG_8153B | URE_FLAG_8156 | URE_FLAG_8156B | - URE_FLAG_8157)) { + URE_FLAG_8157 | URE_FLAG_8159)) { ure_write_2(sc, URE_USB_RX_EARLY_SIZE, URE_MCU_TYPE_USB, - (sc->ure_flags & URE_FLAG_8157) ? + (sc->ure_flags & (URE_FLAG_8157 | URE_FLAG_8159)) ? reg / URE_8157_BUF_ALIGN : reg / URE_RX_BUF_ALIGN); ure_write_2(sc, URE_USB_RX_EARLY_AGG, URE_MCU_TYPE_USB, @@ -672,7 +674,8 @@ ure_ifmedia_init(struct ifnet *ifp) URE_SETBIT_1(sc, URE_PLA_CR, URE_MCU_TYPE_PLA, URE_CR_RE | URE_CR_TE); if (sc->ure_flags & - (URE_FLAG_8153B | URE_FLAG_8156 | URE_FLAG_8156B | URE_FLAG_8157)) { + (URE_FLAG_8153B | URE_FLAG_8156 | URE_FLAG_8156B | URE_FLAG_8157 | + URE_FLAG_8159)) { ure_write_1(sc, URE_USB_UPT_RXDMA_OWN, URE_MCU_TYPE_USB, URE_OWN_UPDATE | URE_OWN_CLEAR); } @@ -688,7 +691,8 @@ ure_ifmedia_upd(struct ifnet *ifp) struct ifmedia *ifm = &sc->ure_ifmedia; int anar, gig, err, reg; - if (sc->ure_flags & (URE_FLAG_8156 | URE_FLAG_8156B | URE_FLAG_8157)) { + if (sc->ure_flags & (URE_FLAG_8156 | URE_FLAG_8156B | URE_FLAG_8157 | + URE_FLAG_8159)) { if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) return (EINVAL); @@ -698,8 +702,10 @@ ure_ifmedia_upd(struct ifnet *ifp) return (EINVAL); reg &= ~URE_ADV_2500TFDX; } - if (sc->ure_flags & URE_FLAG_8157) + if (sc->ure_flags & (URE_FLAG_8157 | URE_FLAG_8159)) reg &= ~URE_ADV_5000TFDX; + if (sc->ure_flags & URE_FLAG_8159) + reg &= ~URE_ADV_10000TFDX; anar = ANAR_TX_FD | ANAR_TX | ANAR_10_FD | ANAR_10; gig = GTCR_ADV_1000TFDX | GTCR_ADV_1000THDX; @@ -708,8 +714,15 @@ ure_ifmedia_upd(struct ifnet *ifp) case IFM_AUTO: if (!(sc->ure_chip & URE_CHIP_VER_7420)) reg |= URE_ADV_2500TFDX; - if (sc->ure_flags & URE_FLAG_8157) + if (sc->ure_flags & (URE_FLAG_8157 | URE_FLAG_8159)) reg |= URE_ADV_5000TFDX; + if (sc->ure_flags & URE_FLAG_8159) + reg |= URE_ADV_10000TFDX; + break; + case IFM_10G_T: + reg |= URE_ADV_2500TFDX | URE_ADV_5000TFDX | + URE_ADV_10000TFDX; + ifp->if_baudrate = IF_Gbps(10); break; case IFM_5000_T: reg |= URE_ADV_2500TFDX | URE_ADV_5000TFDX; @@ -769,7 +782,8 @@ ure_ifmedia_sts(struct ifnet *ifp, struc struct mii_data *mii = &sc->ure_mii; uint16_t status = 0; - if (sc->ure_flags & (URE_FLAG_8156 | URE_FLAG_8156B | URE_FLAG_8157)) { + if (sc->ure_flags & (URE_FLAG_8156 | URE_FLAG_8156B | URE_FLAG_8157 | + URE_FLAG_8159)) { ifmr->ifm_status = IFM_AVALID; if (ure_get_link_status(sc)) { ifmr->ifm_status |= IFM_ACTIVE; @@ -778,7 +792,8 @@ ure_ifmedia_sts(struct ifnet *ifp, struc URE_MCU_TYPE_PLA); if ((status & URE_PHYSTATUS_FDX) || (status & URE_PHYSTATUS_2500MBPS) || - (status & URE_PHYSTATUS_5000MBPS)) + (status & URE_PHYSTATUS_5000MBPS) || + (status & URE_PHYSTATUS_10000MBPS)) ifmr->ifm_active |= IFM_FDX; else ifmr->ifm_active |= IFM_HDX; @@ -792,6 +807,8 @@ ure_ifmedia_sts(struct ifnet *ifp, struc ifmr->ifm_active |= IFM_2500_T; else if (status & URE_PHYSTATUS_5000MBPS) ifmr->ifm_active |= IFM_5000_T; + else if (status & URE_PHYSTATUS_10000MBPS) + ifmr->ifm_active |= IFM_10G_T; } return; } @@ -817,11 +834,16 @@ ure_add_media_types(struct ure_softc *sc ifmedia_add(&sc->ure_ifmedia, IFM_ETHER | IFM_2500_T | IFM_FDX, 0, NULL); } - if (sc->ure_flags & URE_FLAG_8157) { + if (sc->ure_flags & (URE_FLAG_8157 | URE_FLAG_8159)) { ifmedia_add(&sc->ure_ifmedia, IFM_ETHER | IFM_5000_T, 0, NULL); ifmedia_add(&sc->ure_ifmedia, IFM_ETHER | IFM_5000_T | IFM_FDX, 0, NULL); } + if (sc->ure_flags & URE_FLAG_8159) { + ifmedia_add(&sc->ure_ifmedia, IFM_ETHER | IFM_10G_T, 0, NULL); + ifmedia_add(&sc->ure_ifmedia, IFM_ETHER | IFM_10G_T | IFM_FDX, + 0, NULL); + } } void @@ -916,7 +938,8 @@ ure_rxvlan(struct ure_softc *sc) struct ifnet *ifp = &sc->ure_ac.ac_if; uint16_t reg; - if (sc->ure_flags & (URE_FLAG_8156 | URE_FLAG_8156B | URE_FLAG_8157)) { + if (sc->ure_flags & (URE_FLAG_8156 | URE_FLAG_8156B | URE_FLAG_8157 | + URE_FLAG_8159)) { reg = ure_read_2(sc, URE_PLA_RCR1, URE_MCU_TYPE_PLA); reg &= ~(URE_INNER_VLAN | URE_OUTER_VLAN); if (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING) @@ -936,7 +959,7 @@ ure_reset(struct ure_softc *sc) { int i; - if (sc->ure_flags & URE_FLAG_8157) + if (sc->ure_flags & (URE_FLAG_8157 | URE_FLAG_8159)) URE_CLRBIT_1(sc, URE_PLA_CR, URE_MCU_TYPE_PLA, URE_CR_TE | URE_CR_RE); else if (sc->ure_flags & URE_FLAG_8156) { @@ -1118,7 +1141,7 @@ ure_start(struct ifnet *ifp) mlen = m->m_pkthdr.len; - descsize = (sc->ure_flags & URE_FLAG_8157) ? + descsize = (sc->ure_flags & (URE_FLAG_8157 | URE_FLAG_8159)) ? sizeof(struct ure_txpkt_v2) : sizeof(struct ure_txpkt); /* Discard packet larger than buffer. */ if (mlen + descsize >= c->uc_bufmax) { @@ -1133,7 +1156,7 @@ ure_start(struct ifnet *ifp) * continue. */ new_buflen = roundup(c->uc_buflen, - (sc->ure_flags & URE_FLAG_8157) ? + (sc->ure_flags & (URE_FLAG_8157 | URE_FLAG_8159)) ? URE_8157_BUF_ALIGN : URE_TX_BUF_ALIGN); if (new_buflen + descsize + mlen >= c->uc_bufmax) { ifq_deq_rollback(&ifp->if_snd, m); @@ -1665,8 +1688,10 @@ ure_rtl8157_init(struct ure_softc *sc) reg | URE_POLL_LINK_CHG); /* Enable Rx aggregation. */ - URE_CLRBIT_2(sc, URE_USB_USB_CTRL, URE_MCU_TYPE_USB, - URE_RX_AGG_DISABLE | 0x0400); + reg = URE_RX_AGG_DISABLE | URE_RX_DESC_16B; + if (sc->ure_flags & URE_FLAG_8159) + reg |= URE_RX_END_TRANSFER_EN; + URE_CLRBIT_2(sc, URE_USB_USB_CTRL, URE_MCU_TYPE_USB, reg); /* Disable Rx zero len. */ URE_OCP_CMD_CLRBIT(sc, 0x2300, URE_CMD_TYPE_BMU, 0x00000008); @@ -1777,6 +1802,7 @@ ure_rtl8153_nic_reset(struct ure_softc * case URE_FLAG_8156: case URE_FLAG_8156B: case URE_FLAG_8157: + case URE_FLAG_8159: URE_CLRBIT_2(sc, URE_USB_LPM_CONFIG, URE_MCU_TYPE_USB, LPM_U1U2_EN); break; @@ -1809,7 +1835,8 @@ ure_rtl8153_nic_reset(struct ure_softc * URE_CLRBIT_2(sc, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA, URE_MCU_BORW_EN); if (!(sc->ure_flags & - (URE_FLAG_8156 | URE_FLAG_8156B | URE_FLAG_8157))) { + (URE_FLAG_8156 | URE_FLAG_8156B | URE_FLAG_8157 | + URE_FLAG_8159))) { for (i = 0; i < URE_TIMEOUT; i++) { if (ure_read_1(sc, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA) & URE_LINK_LIST_READY) @@ -1841,9 +1868,11 @@ ure_rtl8153_nic_reset(struct ure_softc * ure_write_2(sc, URE_PLA_RMS, URE_MCU_TYPE_PLA, URE_FRAMELEN(ifp->if_mtu)); ure_write_1(sc, URE_PLA_MTPS, URE_MCU_TYPE_PLA, - (sc->ure_flags & URE_FLAG_8157) ? MTPS_MAX : MTPS_JUMBO); + (sc->ure_flags & (URE_FLAG_8157 | URE_FLAG_8159)) ? + MTPS_MAX : MTPS_JUMBO); - if (sc->ure_flags & (URE_FLAG_8156 | URE_FLAG_8156B | URE_FLAG_8157)) { + if (sc->ure_flags & (URE_FLAG_8156 | URE_FLAG_8156B | URE_FLAG_8157 | + URE_FLAG_8159)) { ure_write_2(sc, URE_PLA_RX_FIFO_FULL, URE_MCU_TYPE_PLA, (sc->ure_flags & URE_FLAG_8156) ? 1024 : 512); ure_write_2(sc, URE_PLA_RX_FIFO_EMPTY, URE_MCU_TYPE_PLA, @@ -1866,7 +1895,7 @@ ure_rtl8153_nic_reset(struct ure_softc * URE_CLRBIT_2(sc, URE_PLA_MAC_PWR_CTRL3, URE_MCU_TYPE_PLA, URE_PLA_MCU_SPDWN_EN); - if (!(sc->ure_flags & URE_FLAG_8157)) + if (!(sc->ure_flags & (URE_FLAG_8157 | URE_FLAG_8159))) URE_CLRBIT_2(sc, URE_USB_SPEED_OPTION, URE_MCU_TYPE_USB, URE_RG_PWRDN_EN | URE_ALL_SPEED_OFF); @@ -1909,7 +1938,7 @@ ure_rtl8153_nic_reset(struct ure_softc * ure_phy_write(sc, URE_OCP_POWER_CFG, ure_phy_read(sc, URE_OCP_POWER_CFG) | URE_EN_ALDPS); - if (sc->ure_flags & URE_FLAG_8157) { + if (sc->ure_flags & (URE_FLAG_8157 | URE_FLAG_8159)) { /* Clear SDR. */ URE_SETBIT_1(sc, 0xd378, URE_MCU_TYPE_USB, 0x0080); URE_CLRBIT_2(sc, 0xcd06, URE_MCU_TYPE_USB, 0x8000); @@ -1923,7 +1952,7 @@ ure_rtl8153_nic_reset(struct ure_softc * if (sc->ure_udev->speed == USB_SPEED_SUPER) URE_SETBIT_2(sc, URE_USB_LPM_CONFIG, URE_MCU_TYPE_USB, LPM_U1U2_EN); - } else if (!(sc->ure_flags & URE_FLAG_8157)) { + } else if (!(sc->ure_flags & (URE_FLAG_8157 | URE_FLAG_8159))) { memset(u1u2, 0xff, sizeof(u1u2)); ure_write_mem(sc, URE_USB_TOLERANCE, URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2)); @@ -1989,7 +2018,7 @@ ure_reset_bmu(struct ure_softc *sc) { uint8_t reg; - if (sc->ure_flags & URE_FLAG_8157) { + if (sc->ure_flags & (URE_FLAG_8157 | URE_FLAG_8159)) { URE_OCP_CMD_SETBIT(sc, 0x2350, URE_CMD_TYPE_BMU, 0x00000002); URE_OCP_CMD_SETBIT(sc, 0x2360, URE_CMD_TYPE_BMU, 0x00000001); URE_OCP_CMD_SETBIT(sc, 0x2350, URE_CMD_TYPE_BMU, 0x00000001); @@ -2009,7 +2038,8 @@ void ure_disable_teredo(struct ure_softc *sc) { if (sc->ure_flags & - (URE_FLAG_8153B | URE_FLAG_8156 | URE_FLAG_8156B | URE_FLAG_8157)) + (URE_FLAG_8153B | URE_FLAG_8156 | URE_FLAG_8156B | URE_FLAG_8157 | + URE_FLAG_8159)) ure_write_1(sc, URE_PLA_TEREDO_CFG, URE_MCU_TYPE_PLA, 0xff); else { URE_CLRBIT_2(sc, URE_PLA_TEREDO_CFG, URE_MCU_TYPE_PLA, @@ -2052,7 +2082,8 @@ ure_ioctl(struct ifnet *ifp, u_long cmd, case SIOCGIFMEDIA: case SIOCSIFMEDIA: if (sc->ure_flags & - (URE_FLAG_8156 | URE_FLAG_8156B | URE_FLAG_8157)) + (URE_FLAG_8156 | URE_FLAG_8156B | URE_FLAG_8157 | + URE_FLAG_8159)) error = ifmedia_ioctl(ifp, ifr, &sc->ure_ifmedia, cmd); else error = ifmedia_ioctl(ifp, ifr, &sc->ure_mii.mii_media, @@ -2141,6 +2172,13 @@ ure_attach(struct device *parent, struct sc->ure_phy_write = ure_rtl8157_ocp_reg_write; printf("RTL8157 (0x1030)"); break; + case 0x2020: + sc->ure_flags = URE_FLAG_8159; + sc->ure_txbufsz = URE_8156_TX_BUFSZ; + sc->ure_phy_read = ure_rtl8157_ocp_reg_read; + sc->ure_phy_write = ure_rtl8157_ocp_reg_write; + printf("RTL8159 (0x2020)"); + break; case 0x4c00: sc->ure_flags = URE_FLAG_8152; sc->ure_rxbufsz = URE_8152_RX_BUFSZ; @@ -2213,6 +2251,7 @@ ure_attach(struct device *parent, struct return; break; case URE_FLAG_8157: + case URE_FLAG_8159: if (ure_rtl8157_init(sc) != 0) return; break; @@ -2248,7 +2287,8 @@ ure_attach(struct device *parent, struct ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING; #endif - if (sc->ure_flags & (URE_FLAG_8156 | URE_FLAG_8156B | URE_FLAG_8157)) { + if (sc->ure_flags & (URE_FLAG_8156 | URE_FLAG_8156B | URE_FLAG_8157 | + URE_FLAG_8159)) { ifmedia_init(&sc->ure_ifmedia, IFM_IMASK, ure_ifmedia_upd, ure_ifmedia_sts); ure_add_media_types(sc); @@ -2341,7 +2381,8 @@ ure_tick_task(void *xsc) mii = &sc->ure_mii; s = splnet(); - if (sc->ure_flags & (URE_FLAG_8156 | URE_FLAG_8156B | URE_FLAG_8157)) + if (sc->ure_flags & (URE_FLAG_8156 | URE_FLAG_8156B | URE_FLAG_8157 | + URE_FLAG_8159)) ure_link_state(sc); else { mii_tick(mii); @@ -2521,9 +2562,9 @@ ure_decap(struct ure_softc *sc, struct u struct ure_rxpkt rxhdr; struct ure_rxpkt_v2 rxhdr2; - align = (sc->ure_flags & URE_FLAG_8157) ? + align = (sc->ure_flags & (URE_FLAG_8157 | URE_FLAG_8159)) ? URE_8157_BUF_ALIGN : URE_RX_BUF_ALIGN; - hdrsize = (sc->ure_flags & URE_FLAG_8157) ? + hdrsize = (sc->ure_flags & (URE_FLAG_8157 | URE_FLAG_8159)) ? sizeof(rxhdr2) : sizeof(rxhdr); do { @@ -2535,7 +2576,7 @@ ure_decap(struct ure_softc *sc, struct u buf += roundup(pktlen, align); - if (sc->ure_flags & URE_FLAG_8157) { + if (sc->ure_flags & (URE_FLAG_8157 | URE_FLAG_8159)) { memcpy(&rxhdr2, buf, hdrsize); pktlen = letoh32(rxhdr2.ure_pktlen) & URE_RXPKT_V2_LEN_MASK; @@ -2563,7 +2604,7 @@ ure_decap(struct ure_softc *sc, struct u break; } - if (sc->ure_flags & URE_FLAG_8157) + if (sc->ure_flags & (URE_FLAG_8157 | URE_FLAG_8159)) ure_rxcsum_v2(&rxhdr2, m); else ure_rxcsum(&rxhdr, m); @@ -2585,7 +2626,8 @@ ure_encap_txpkt(struct ure_softc *sc, st struct ure_txpkt_v2 txhdr2; uint32_t len, cflags = 0; - len = (sc->ure_flags & URE_FLAG_8157) ? sizeof(txhdr2) : sizeof(txhdr); + len = (sc->ure_flags & (URE_FLAG_8157 | URE_FLAG_8159)) ? + sizeof(txhdr2) : sizeof(txhdr); if (len + m->m_pkthdr.len > maxlen) return (-1); @@ -2603,7 +2645,7 @@ ure_encap_txpkt(struct ure_softc *sc, st cflags |= URE_TXPKT_VLAN_TAG | swap16(m->m_pkthdr.ether_vtag); #endif - if (sc->ure_flags & URE_FLAG_8157) { + if (sc->ure_flags & (URE_FLAG_8157 | URE_FLAG_8159)) { txhdr2.ure_cmdstat = htole32(URE_TXPKT_TX_FS | URE_TXPKT_TX_LS); txhdr2.ure_vlan = htole32(cflags); txhdr2.ure_pktlen = htole32(m->m_pkthdr.len << 4); Index: sys/dev/usb/if_urereg.h =================================================================== RCS file: /home/cvs/src/sys/dev/usb/if_urereg.h,v diff -u -p -r1.14 if_urereg.h --- sys/dev/usb/if_urereg.h 23 May 2025 03:06:09 -0000 1.14 +++ sys/dev/usb/if_urereg.h 1 Oct 2026 20:55:39 -0000 @@ -371,6 +371,7 @@ #define URE_PHYSTATUS_1000MBPS 0x0010 #define URE_PHYSTATUS_2500MBPS 0x0400 #define URE_PHYSTATUS_5000MBPS 0x1000 +#define URE_PHYSTATUS_10000MBPS 0x4000 /* URE_PLA_CONFIG6 */ #define URE_LANWAKE_CLR_EN 0x01 @@ -476,6 +477,8 @@ #define URE_CDC_ECM_EN 0x0008 #define URE_RX_AGG_DISABLE 0x0010 #define URE_RX_ZERO_EN 0x0080 +#define URE_RX_DESC_16B 0x0400 +#define URE_RX_END_TRANSFER_EN 0x0800 /* URE_USB_U2P3_CTRL */ #define URE_U2P3_ENABLE 0x0001 @@ -552,6 +555,7 @@ #define URE_ADV_2500TFDX 0x0080 #define URE_ADV_5000TFDX 0x0100 +#define URE_ADV_10000TFDX 0x1000 #define URE_MCU_TYPE_PLA 0x0100 #define URE_MCU_TYPE_USB 0x0000 @@ -697,7 +701,8 @@ struct ure_softc { #define URE_FLAG_8156 0x0040 /* RTL8156 */ #define URE_FLAG_8156B 0x0080 /* RTL8156B */ #define URE_FLAG_8157 0x0100 /* RTL8157 */ -#define URE_FLAG_CHIP_MASK 0x01f0 +#define URE_FLAG_8159 0x0200 /* RTL8159 */ +#define URE_FLAG_CHIP_MASK 0x03f0 u_int ure_chip; #define URE_CHIP_VER_4C00 0x01 Index: sys/dev/usb/usbdevs =================================================================== RCS file: /home/cvs/src/sys/dev/usb/usbdevs,v diff -u -p -r1.790 usbdevs --- sys/dev/usb/usbdevs 9 Sep 2026 03:51:32 -0000 1.790 +++ sys/dev/usb/usbdevs 30 Sep 2026 12:01:17 -0000 @@ -3859,6 +3859,7 @@ product REALTEK RTL8152 0x8152 RTL8152 product REALTEK RTL8153 0x8153 RTL8153 product REALTEK RTL8156 0x8156 RTL8156 product REALTEK RTL8157 0x8157 RTL8157 +product REALTEK RTL8159 0x815a RTL8159 product REALTEK RTL8188CE_0 0x8170 RTL8188CE product REALTEK RTL8171 0x8171 RTL8171 product REALTEK RTL8172 0x8172 RTL8172 Index: share/man/man4/ure.4 =================================================================== RCS file: /home/cvs/src/share/man/man4/ure.4,v diff -u -p -r1.11 ure.4 --- share/man/man4/ure.4 23 May 2025 03:06:09 -0000 1.11 +++ share/man/man4/ure.4 1 Oct 2026 21:41:58 -0000 @@ -31,8 +31,8 @@ .Os .Sh NAME .Nm ure -.Nd Realtek RTL8152/RTL8153/RTL8156/RTL8157 10/100/1Gb/2.5Gb/5Gb \ -USB Ethernet device +.Nd Realtek RTL8152/RTL8153/RTL8156/RTL8157/RTL8159 \ +10/100/1Gb/2.5Gb/5Gb/10Gb USB Ethernet device .Sh SYNOPSIS .Cd "ure* at uhub?" .Cd "rgephy* at mii?" @@ -41,7 +41,8 @@ USB Ethernet device The .Nm driver provides support for USB Ethernet adapters based on the Realtek -RTL8152, RTL8153, RTL8153B, RTL8153D, RTL8156, RTL8156B and RTL8157 chipsets. +RTL8152, RTL8153, RTL8153B, RTL8153D, RTL8156, RTL8156B, RTL8157 and +RTL8159 chipsets. .Pp The RTL8152 contains an integrated Fast Ethernet MAC, which supports both 10 and 100Mbps speeds in either full or half duplex. @@ -51,6 +52,8 @@ NICs based on the RTL8156 and RTL8156B a 2500Mbps operation. The RTL8157 is a USB 3.0 device, which contains a 10/100/1Gb/2.5Gb/5Gb Ethernet MAC. +The RTL8159 is a USB 3.2 device with a 10/100/1Gb/2.5Gb/5Gb/10Gb +Ethernet MAC. .Pp For more information on configuring this device, see .Xr ifconfig 8 . @@ -75,3 +78,8 @@ The .Nm driver was written by .An Kevin Lo Aq Mt kevlo@FreeBSD.org . +.Sh CAVEATS +RTL8159 adapters require firmware for 10Gb operation. +The +.Nm +driver does not support loading this firmware. -- wbr, Kirill