--- /usr/src/sys/dev/usb/net/if_ure.c 2021-01-26 11:43:20.961155000 +0100 +++ /usr/src/sys/dev/usb/net/if_ure.c.new 2021-02-09 10:09:51.000000000 +0100 @@ -96,16 +96,17 @@ */ static const STRUCT_USB_HOST_ID ure_devs[] = { #define URE_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) } - URE_DEV(LENOVO, RTL8153, 0), + URE_DEV(LENOVO, RTL8153, URE_FLAG_8153), URE_DEV(LENOVO, TBT3LAN, 0), URE_DEV(LENOVO, TBT3LANGEN2, 0), URE_DEV(LENOVO, ONELINK, 0), URE_DEV(LENOVO, USBCLAN, 0), URE_DEV(LENOVO, USBCLANGEN2, 0), - URE_DEV(NVIDIA, RTL8153, 0), + URE_DEV(NVIDIA, RTL8153, URE_FLAG_8153), URE_DEV(REALTEK, RTL8152, URE_FLAG_8152), - URE_DEV(REALTEK, RTL8153, 0), - URE_DEV(TPLINK, RTL8153, 0), + URE_DEV(REALTEK, RTL8153, URE_FLAG_8153), + URE_DEV(TPLINK, RTL8153, URE_FLAG_8153), + URE_DEV(REALTEK, RTL8156, URE_FLAG_8156), #undef URE_DEV }; @@ -141,6 +142,7 @@ static int ure_write_4(struct ure_softc *, uint16_t, uint16_t, uint32_t); static uint16_t ure_ocp_reg_read(struct ure_softc *, uint16_t); static void ure_ocp_reg_write(struct ure_softc *, uint16_t, uint16_t); +static void ure_sram_write(struct ure_softc *, uint16_t, uint16_t); static int ure_sysctl_chipver(SYSCTL_HANDLER_ARGS); @@ -149,96 +151,21 @@ static void ure_reset(struct ure_softc *); static int ure_ifmedia_upd(struct ifnet *); static void ure_ifmedia_sts(struct ifnet *, struct ifmediareq *); +static void ure_add_media_types(struct ure_softc *); +static void ure_link_state(struct ure_softc *sc); +static int ure_get_link_status(struct ure_softc *); static int ure_ioctl(struct ifnet *, u_long, caddr_t); static void ure_rtl8152_init(struct ure_softc *); +static void ure_rtl8152_nic_reset(struct ure_softc *); static void ure_rtl8153_init(struct ure_softc *); +static void ure_rtl8153b_init(struct ure_softc *); +static void ure_rtl8153b_nic_reset(struct ure_softc *); static void ure_disable_teredo(struct ure_softc *); -static void ure_init_fifo(struct ure_softc *); +static void ure_enable_aldps(struct ure_softc *, bool); +static uint16_t ure_phy_status(struct ure_softc *, uint16_t); static void ure_rxcsum(int capenb, struct ure_rxpkt *rp, struct mbuf *m); static int ure_txcsum(struct mbuf *m, int caps, uint32_t *regout); -static const struct usb_config ure_config_rx[URE_N_TRANSFER] = { - { - .type = UE_BULK, - .endpoint = UE_ADDR_ANY, - .direction = UE_DIR_IN, - .bufsize = URE_TRANSFER_SIZE, - .flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, - .callback = ure_bulk_read_callback, - .timeout = 0, /* no timeout */ - }, - { - .type = UE_BULK, - .endpoint = UE_ADDR_ANY, - .direction = UE_DIR_IN, - .bufsize = URE_TRANSFER_SIZE, - .flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, - .callback = ure_bulk_read_callback, - .timeout = 0, /* no timeout */ - }, -#if URE_N_TRANSFER == 4 - { - .type = UE_BULK, - .endpoint = UE_ADDR_ANY, - .direction = UE_DIR_IN, - .bufsize = URE_TRANSFER_SIZE, - .flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, - .callback = ure_bulk_read_callback, - .timeout = 0, /* no timeout */ - }, - { - .type = UE_BULK, - .endpoint = UE_ADDR_ANY, - .direction = UE_DIR_IN, - .bufsize = URE_TRANSFER_SIZE, - .flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, - .callback = ure_bulk_read_callback, - .timeout = 0, /* no timeout */ - }, -#endif -}; - -static const struct usb_config ure_config_tx[URE_N_TRANSFER] = { - { - .type = UE_BULK, - .endpoint = UE_ADDR_ANY, - .direction = UE_DIR_OUT, - .bufsize = URE_TRANSFER_SIZE, - .flags = {.pipe_bof = 1,.force_short_xfer = 1,}, - .callback = ure_bulk_write_callback, - .timeout = 10000, /* 10 seconds */ - }, - { - .type = UE_BULK, - .endpoint = UE_ADDR_ANY, - .direction = UE_DIR_OUT, - .bufsize = URE_TRANSFER_SIZE, - .flags = {.pipe_bof = 1,.force_short_xfer = 1,}, - .callback = ure_bulk_write_callback, - .timeout = 10000, /* 10 seconds */ - }, -#if URE_N_TRANSFER == 4 - { - .type = UE_BULK, - .endpoint = UE_ADDR_ANY, - .direction = UE_DIR_OUT, - .bufsize = URE_TRANSFER_SIZE, - .flags = {.pipe_bof = 1,.force_short_xfer = 1,}, - .callback = ure_bulk_write_callback, - .timeout = 10000, /* 10 seconds */ - }, - { - .type = UE_BULK, - .endpoint = UE_ADDR_ANY, - .direction = UE_DIR_OUT, - .bufsize = URE_TRANSFER_SIZE, - .flags = {.pipe_bof = 1,.force_short_xfer = 1,}, - .callback = ure_bulk_write_callback, - .timeout = 10000, /* 10 seconds */ - }, -#endif -}; - static device_method_t ure_methods[] = { /* Device interface. */ DEVMETHOD(device_probe, ure_probe), @@ -283,6 +210,20 @@ .ue_mii_sts = ure_ifmedia_sts, }; +#define URE_SETBIT_1(sc, reg, index, x) \ + ure_write_1(sc, reg, index, ure_read_1(sc, reg, index) | (x)) +#define URE_SETBIT_2(sc, reg, index, x) \ + ure_write_2(sc, reg, index, ure_read_2(sc, reg, index) | (x)) +#define URE_SETBIT_4(sc, reg, index, x) \ + ure_write_4(sc, reg, index, ure_read_4(sc, reg, index) | (x)) + +#define URE_CLRBIT_1(sc, reg, index, x) \ + ure_write_1(sc, reg, index, ure_read_1(sc, reg, index) & ~(x)) +#define URE_CLRBIT_2(sc, reg, index, x) \ + ure_write_2(sc, reg, index, ure_read_2(sc, reg, index) & ~(x)) +#define URE_CLRBIT_4(sc, reg, index, x) \ + ure_write_4(sc, reg, index, ure_read_4(sc, reg, index) & ~(x)) + static int ure_ctl(struct ure_softc *sc, uint8_t rw, uint16_t val, uint16_t index, void *buf, int len) @@ -435,6 +376,14 @@ ure_write_2(sc, reg, URE_MCU_TYPE_PLA, data); } +static void +ure_sram_write(struct ure_softc *sc, uint16_t addr, uint16_t data) +{ + + ure_ocp_reg_write(sc, URE_OCP_SRAM_ADDR, addr); + ure_ocp_reg_write(sc, URE_OCP_SRAM_DATA, data); +} + static int ure_miibus_readreg(device_t dev, int phy, int reg) { @@ -558,25 +507,57 @@ struct usb_attach_arg *uaa = device_get_ivars(dev); struct ure_softc *sc = device_get_softc(dev); struct usb_ether *ue = &sc->sc_ue; + struct usb_config ure_config_rx[URE_MAX_RX]; + struct usb_config ure_config_tx[URE_MAX_TX]; uint8_t iface_index; - int error; + int i, error; sc->sc_flags = USB_GET_DRIVER_INFO(uaa); device_set_usb_desc(dev); mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF); iface_index = URE_IFACE_IDX; + + if (sc->sc_flags & (URE_FLAG_8153 | URE_FLAG_8153B)) + sc->sc_rxbufsz = URE_8153_RX_BUFSZ; + else if (sc->sc_flags & (URE_FLAG_8156 | URE_FLAG_8156B)) + sc->sc_rxbufsz = URE_8156_RX_BUFSZ; + else + sc->sc_rxbufsz = URE_8152_RX_BUFSZ; + + for (i = 0; i < URE_MAX_RX; i++) { + ure_config_rx[i] = (struct usb_config) { + .type = UE_BULK, + .endpoint = UE_ADDR_ANY, + .direction = UE_DIR_IN, + .bufsize = sc->sc_rxbufsz, + .flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, + .callback = ure_bulk_read_callback, + .timeout = 0, /* no timeout */ + }; + } error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_rx_xfer, - ure_config_rx, URE_N_TRANSFER, sc, &sc->sc_mtx); + ure_config_rx, URE_MAX_RX, sc, &sc->sc_mtx); if (error != 0) { device_printf(dev, "allocating USB RX transfers failed\n"); goto detach; } + for (i = 0; i < URE_MAX_TX; i++) { + ure_config_tx[i] = (struct usb_config) { + .type = UE_BULK, + .endpoint = UE_ADDR_ANY, + .direction = UE_DIR_OUT, + .bufsize = URE_TX_BUFSZ, + .flags = {.pipe_bof = 1,.force_short_xfer = 1,}, + .callback = ure_bulk_write_callback, + .timeout = 10000, /* 10 seconds */ + }; + } error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_tx_xfer, - ure_config_tx, URE_N_TRANSFER, sc, &sc->sc_mtx); + ure_config_tx, URE_MAX_TX, sc, &sc->sc_mtx); if (error != 0) { - usbd_transfer_unsetup(sc->sc_rx_xfer, URE_N_TRANSFER); + usbd_transfer_unsetup(sc->sc_rx_xfer, URE_MAX_RX); device_printf(dev, "allocating USB TX transfers failed\n"); goto detach; } @@ -592,6 +573,7 @@ device_printf(dev, "could not attach interface\n"); goto detach; } + return (0); /* success */ detach: @@ -605,8 +587,8 @@ struct ure_softc *sc = device_get_softc(dev); struct usb_ether *ue = &sc->sc_ue; - usbd_transfer_unsetup(sc->sc_tx_xfer, URE_N_TRANSFER); - usbd_transfer_unsetup(sc->sc_rx_xfer, URE_N_TRANSFER); + usbd_transfer_unsetup(sc->sc_tx_xfer, URE_MAX_TX); + usbd_transfer_unsetup(sc->sc_rx_xfer, URE_MAX_RX); uether_ifdetach(ue); mtx_destroy(&sc->sc_mtx); @@ -785,7 +767,7 @@ caps = if_getcapenable(ifp); pos = 0; - rem = URE_TRANSFER_SIZE; + rem = URE_TX_BUFSZ; while (rem > sizeof(txpkt)) { IFQ_DRV_DEQUEUE(&ifp->if_snd, m); if (m == NULL) @@ -895,22 +877,52 @@ switch (ver) { case 0x4c00: sc->sc_chip |= URE_CHIP_VER_4C00; + sc->sc_flags = URE_FLAG_8152; break; case 0x4c10: sc->sc_chip |= URE_CHIP_VER_4C10; + sc->sc_flags = URE_FLAG_8152; break; case 0x5c00: sc->sc_chip |= URE_CHIP_VER_5C00; + sc->sc_flags = URE_FLAG_8153; break; case 0x5c10: sc->sc_chip |= URE_CHIP_VER_5C10; + sc->sc_flags = URE_FLAG_8153; break; case 0x5c20: sc->sc_chip |= URE_CHIP_VER_5C20; + sc->sc_flags = URE_FLAG_8153; break; case 0x5c30: sc->sc_chip |= URE_CHIP_VER_5C30; + sc->sc_flags = URE_FLAG_8153; break; + case 0x6000: + sc->sc_flags = URE_FLAG_8153B; + sc->sc_chip |= URE_CHIP_VER_6000; + break; + case 0x6010: + sc->sc_flags = URE_FLAG_8153B; + sc->sc_chip |= URE_CHIP_VER_6010; + break; + case 0x7020: + sc->sc_flags = URE_FLAG_8156; + sc->sc_chip |= URE_CHIP_VER_7020; + break; + case 0x7030: + sc->sc_flags = URE_FLAG_8156; + sc->sc_chip |= URE_CHIP_VER_7030; + break; + case 0x7400: + sc->sc_flags = URE_FLAG_8156B; + sc->sc_chip |= URE_CHIP_VER_7400; + break; + case 0x7410: + sc->sc_flags = URE_FLAG_8156B; + sc->sc_chip |= URE_CHIP_VER_7410; + break; default: device_printf(sc->sc_ue.ue_dev, "unknown version 0x%04x\n", ver); @@ -949,6 +961,8 @@ /* Initialize controller and get station address. */ if (sc->sc_flags & URE_FLAG_8152) ure_rtl8152_init(sc); + else if (sc->sc_flags & (URE_FLAG_8153B | URE_FLAG_8156 | URE_FLAG_8156B)) + ure_rtl8153b_init(sc); else ure_rtl8153_init(sc); @@ -972,13 +986,11 @@ ure_attach_post_sub(struct usb_ether *ue) { struct sysctl_ctx_list *sctx; - struct sysctl_oid *soid; - struct ure_softc *sc; - struct ifnet *ifp; - int error; + struct sysctl_oid *soid; + struct ure_softc *sc = uether_getsc(ue); + struct ifnet *ifp = ue->ue_ifp; + int error = 0; - sc = uether_getsc(ue); - ifp = ue->ue_ifp; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_start = uether_start; ifp->if_ioctl = ure_ioctl; @@ -1001,9 +1013,18 @@ if_setcapenable(ifp, if_getcapabilities(ifp)); mtx_lock(&Giant); - error = mii_attach(ue->ue_dev, &ue->ue_miibus, ifp, - uether_ifmedia_upd, ue->ue_methods->ue_mii_sts, - BMSR_DEFCAPMASK, sc->sc_phyno, MII_OFFSET_ANY, 0); + if (sc->sc_flags & (URE_FLAG_8156 | URE_FLAG_8156B)) { + ifmedia_init(&sc->sc_ifmedia, IFM_IMASK, ure_ifmedia_upd, + ure_ifmedia_sts); + ure_add_media_types(sc); + ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_AUTO, 0, NULL); + ifmedia_set(&sc->sc_ifmedia, IFM_ETHER | IFM_AUTO); + sc->sc_ifmedia.ifm_media = IFM_ETHER | IFM_AUTO; + } else { + error = mii_attach(ue->ue_dev, &ue->ue_miibus, ifp, + uether_ifmedia_upd, ue->ue_methods->ue_mii_sts, + BMSR_DEFCAPMASK, sc->sc_phyno, MII_OFFSET_ANY, 0); + } mtx_unlock(&Giant); sctx = device_get_sysctl_ctx(sc->sc_ue.ue_dev); @@ -1022,6 +1043,7 @@ struct ure_softc *sc = uether_getsc(ue); struct ifnet *ifp = uether_getifp(ue); uint16_t cpcr; + uint32_t reg; URE_LOCK_ASSERT(sc, MA_OWNED); @@ -1031,7 +1053,10 @@ /* Cancel pending I/O. */ ure_stop(ue); - ure_reset(sc); + if (sc->sc_flags & (URE_FLAG_8153B | URE_FLAG_8156 | URE_FLAG_8156B)) + ure_rtl8153b_nic_reset(sc); + else + ure_reset(sc); /* Set MAC address. */ ure_write_1(sc, URE_PLA_CRWECR, URE_MCU_TYPE_PLA, URE_CRWECR_CONFIG); @@ -1039,13 +1064,50 @@ IF_LLADDR(ifp), 8); ure_write_1(sc, URE_PLA_CRWECR, URE_MCU_TYPE_PLA, URE_CRWECR_NORAML); + /* Set RX EARLY timeout and size */ + if (sc->sc_flags & URE_FLAG_8153) { + switch (usbd_get_speed(sc->sc_ue.ue_udev)) { + case USB_SPEED_SUPER: + reg = URE_COALESCE_SUPER / 8; + break; + case USB_SPEED_HIGH: + reg = URE_COALESCE_HIGH / 8; + break; + default: + reg = URE_COALESCE_SLOW / 8; + break; + } + ure_write_2(sc, URE_USB_RX_EARLY_AGG, URE_MCU_TYPE_USB, reg); + reg = URE_8153_RX_BUFSZ - (URE_FRAMELEN(if_getmtu(ifp)) + + sizeof(struct ure_rxpkt) + URE_RXPKT_ALIGN); + ure_write_2(sc, URE_USB_RX_EARLY_SIZE, URE_MCU_TYPE_USB, reg / 4); + } else if (sc->sc_flags & URE_FLAG_8153B) { + ure_write_2(sc, URE_USB_RX_EARLY_AGG, URE_MCU_TYPE_USB, 158); + ure_write_2(sc, URE_USB_RX_EXTRA_AGG_TMR, URE_MCU_TYPE_USB, 1875); + reg = URE_8153_RX_BUFSZ - (URE_FRAMELEN(if_getmtu(ifp)) + + sizeof(struct ure_rxpkt) + URE_RXPKT_ALIGN); + ure_write_2(sc, URE_USB_RX_EARLY_SIZE, URE_MCU_TYPE_USB, reg / 8); + ure_write_1(sc, URE_USB_UPT_RXDMA_OWN, URE_MCU_TYPE_USB, + URE_OWN_UPDATE | URE_OWN_CLEAR); + } else if (sc->sc_flags & (URE_FLAG_8156 | URE_FLAG_8156B)) { + ure_write_2(sc, URE_USB_RX_EARLY_AGG, URE_MCU_TYPE_USB, 80); + ure_write_2(sc, URE_USB_RX_EXTRA_AGG_TMR, URE_MCU_TYPE_USB, 1875); + reg = URE_8156_RX_BUFSZ - (URE_FRAMELEN(if_getmtu(ifp)) + + sizeof(struct ure_rxpkt) + URE_RXPKT_ALIGN); + ure_write_2(sc, URE_USB_RX_EARLY_SIZE, URE_MCU_TYPE_USB, reg / 8); + ure_write_1(sc, URE_USB_UPT_RXDMA_OWN, URE_MCU_TYPE_USB, + URE_OWN_UPDATE | URE_OWN_CLEAR); + } + + if (sc->sc_flags & URE_FLAG_8156B) { + URE_CLRBIT_2(sc, URE_USB_FW_TASK, URE_MCU_TYPE_USB, URE_FC_PATCH_TASK); + uether_pause(&sc->sc_ue, hz / 500); + URE_SETBIT_2(sc, URE_USB_FW_TASK, URE_MCU_TYPE_USB, URE_FC_PATCH_TASK); + } + /* Reset the packet filter. */ - ure_write_2(sc, URE_PLA_FMC, URE_MCU_TYPE_PLA, - ure_read_2(sc, URE_PLA_FMC, URE_MCU_TYPE_PLA) & - ~URE_FMC_FCR_MCU_EN); - ure_write_2(sc, URE_PLA_FMC, URE_MCU_TYPE_PLA, - ure_read_2(sc, URE_PLA_FMC, URE_MCU_TYPE_PLA) | - URE_FMC_FCR_MCU_EN); + URE_CLRBIT_2(sc, URE_PLA_FMC, URE_MCU_TYPE_PLA, URE_FMC_FCR_MCU_EN); + URE_SETBIT_2(sc, URE_PLA_FMC, URE_MCU_TYPE_PLA, URE_FMC_FCR_MCU_EN); /* Enable RX VLANs if enabled */ cpcr = ure_read_2(sc, URE_PLA_CPCR, URE_MCU_TYPE_PLA); @@ -1059,13 +1121,9 @@ ure_write_2(sc, URE_PLA_CPCR, URE_MCU_TYPE_PLA, cpcr); /* Enable transmit and receive. */ - ure_write_1(sc, URE_PLA_CR, URE_MCU_TYPE_PLA, - ure_read_1(sc, URE_PLA_CR, URE_MCU_TYPE_PLA) | URE_CR_RE | - URE_CR_TE); + URE_SETBIT_1(sc, URE_PLA_CR, URE_MCU_TYPE_PLA, URE_CR_RE | URE_CR_TE); - ure_write_2(sc, URE_PLA_MISC_1, URE_MCU_TYPE_PLA, - ure_read_2(sc, URE_PLA_MISC_1, URE_MCU_TYPE_PLA) & - ~URE_RXDY_GATED_EN); + URE_CLRBIT_2(sc, URE_PLA_MISC_1, URE_MCU_TYPE_PLA, URE_RXDY_GATED_EN); /* Configure RX filters. */ ure_rxfilter(ue); @@ -1084,26 +1142,31 @@ { struct ure_softc *sc = uether_getsc(ue); struct ifnet *ifp = uether_getifp(ue); - struct mii_data *mii = GET_MII(sc); + struct mii_data *mii; URE_LOCK_ASSERT(sc, MA_OWNED); (void)ifp; - for (int i = 0; i < URE_N_TRANSFER; i++) + for (int i = 0; i < URE_MAX_RX; i++) DEVPRINTFN(13, sc->sc_ue.ue_dev, "rx[%d] = %d\n", i, USB_GET_STATE(sc->sc_rx_xfer[i])); - for (int i = 0; i < URE_N_TRANSFER; i++) + for (int i = 0; i < URE_MAX_TX; i++) DEVPRINTFN(13, sc->sc_ue.ue_dev, "tx[%d] = %d\n", i, USB_GET_STATE(sc->sc_tx_xfer[i])); - mii_tick(mii); - if ((sc->sc_flags & URE_FLAG_LINK) == 0 - && mii->mii_media_status & IFM_ACTIVE && - IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { - sc->sc_flags |= URE_FLAG_LINK; - sc->sc_rxstarted = 0; - ure_start(ue); + if (sc->sc_flags & (URE_FLAG_8156 | URE_FLAG_8156B)) + ure_link_state(sc); + else { + mii = GET_MII(sc); + mii_tick(mii); + if ((sc->sc_flags & URE_FLAG_LINK) == 0 + && mii->mii_media_status & IFM_ACTIVE && + IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { + sc->sc_flags |= URE_FLAG_LINK; + sc->sc_rxstarted = 0; + ure_start(ue); + } } } @@ -1171,11 +1234,11 @@ if (!sc->sc_rxstarted) { sc->sc_rxstarted = 1; - for (i = 0; i != URE_N_TRANSFER; i++) + for (i = 0; i != URE_MAX_RX; i++) usbd_transfer_start(sc->sc_rx_xfer[i]); } - for (i = 0; i != URE_N_TRANSFER; i++) + for (i = 0; i != URE_MAX_TX; i++) usbd_transfer_start(sc->sc_tx_xfer[i]); } @@ -1203,12 +1266,68 @@ ure_ifmedia_upd(struct ifnet *ifp) { struct ure_softc *sc = ifp->if_softc; - struct mii_data *mii = GET_MII(sc); + struct ifmedia *ifm = &sc->sc_ifmedia; + struct mii_data *mii; struct mii_softc *miisc; - int error; + int anar, gig, reg, locked, error; - URE_LOCK_ASSERT(sc, MA_OWNED); + if (sc->sc_flags & (URE_FLAG_8156 | URE_FLAG_8156B)) { + if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) + return (EINVAL); + locked = mtx_owned(&sc->sc_mtx); + if (!locked) + URE_LOCK(sc); + reg = ure_ocp_reg_read(sc, 0xa5d4); + reg &= ~URE_ADV_2500TFDX; + + anar = gig = 0; + switch (IFM_SUBTYPE(ifm->ifm_media)) { + case IFM_AUTO: + anar |= ANAR_TX_FD | ANAR_TX | ANAR_10_FD | ANAR_10; + gig |= GTCR_ADV_1000TFDX | GTCR_ADV_1000THDX; + reg |= URE_ADV_2500TFDX; + break; + case IFM_2500_T: + anar |= ANAR_TX_FD | ANAR_TX | ANAR_10_FD | ANAR_10; + gig |= GTCR_ADV_1000TFDX | GTCR_ADV_1000THDX; + reg |= URE_ADV_2500TFDX; + ifp->if_baudrate = IF_Mbps(2500); + break; + case IFM_1000_T: + anar |= ANAR_TX_FD | ANAR_TX | ANAR_10_FD | ANAR_10; + gig |= GTCR_ADV_1000TFDX | GTCR_ADV_1000THDX; + ifp->if_baudrate = IF_Gbps(1); + break; + case IFM_100_TX: + anar |= ANAR_TX | ANAR_TX_FD; + ifp->if_baudrate = IF_Mbps(100); + break; + case IFM_10_T: + anar |= ANAR_10 | ANAR_10_FD; + ifp->if_baudrate = IF_Mbps(10); + break; + default: + device_printf(sc->sc_ue.ue_dev, "unsupported media type\n"); + if (!locked) + URE_UNLOCK(sc); + return (EINVAL); + } + + ure_ocp_reg_write(sc, URE_OCP_BASE_MII + MII_ANAR * 2, + anar | ANAR_PAUSE_ASYM | ANAR_FC); + ure_ocp_reg_write(sc, URE_OCP_BASE_MII + MII_100T2CR * 2, gig); + ure_ocp_reg_write(sc, 0xa5d4, reg); + ure_ocp_reg_write(sc, URE_OCP_BASE_MII + MII_BMCR, + BMCR_AUTOEN | BMCR_STARTNEG); + if (!locked) + URE_UNLOCK(sc); + return (0); + } + + mii = GET_MII(sc); + + URE_LOCK_ASSERT(sc, MA_OWNED); LIST_FOREACH(miisc, &mii->mii_phys, mii_list) PHY_RESET(miisc); error = mii_mediachg(mii); @@ -1223,8 +1342,34 @@ { struct ure_softc *sc; struct mii_data *mii; + uint16_t status=0; sc = ifp->if_softc; + if (sc->sc_flags & (URE_FLAG_8156 | URE_FLAG_8156B)) { + URE_LOCK(sc); + ifmr->ifm_status = IFM_AVALID; + if (ure_get_link_status(sc)) { + ifmr->ifm_status |= IFM_ACTIVE; + status = ure_read_2(sc, URE_PLA_PHYSTATUS, + URE_MCU_TYPE_PLA); + if ((status & URE_PHYSTATUS_FDX) || + (status & URE_PHYSTATUS_2500MBPS)) + ifmr->ifm_active |= IFM_FDX; + else + ifmr->ifm_active |= IFM_HDX; + if (status & URE_PHYSTATUS_10MBPS) + ifmr->ifm_active |= IFM_10_T; + else if (status & URE_PHYSTATUS_100MBPS) + ifmr->ifm_active |= IFM_100_TX; + else if (status & URE_PHYSTATUS_1000MBPS) + ifmr->ifm_active |= IFM_1000_T; + else if (status & URE_PHYSTATUS_2500MBPS) + ifmr->ifm_active |= IFM_2500_T; + } + URE_UNLOCK(sc); + return; + } + mii = GET_MII(sc); URE_LOCK(sc); @@ -1234,15 +1379,65 @@ URE_UNLOCK(sc); } +static void +ure_add_media_types(struct ure_softc *sc) +{ + + ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_10_T, 0, NULL); + ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_10_T | IFM_FDX, 0, NULL); + ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_100_TX, 0, NULL); + ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_100_TX | IFM_FDX, 0, NULL); + ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_1000_T | IFM_FDX, 0, NULL); + ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_2500_T | IFM_FDX, 0, NULL); +} + +static void +ure_link_state(struct ure_softc *sc) +{ + struct ifnet *ifp = uether_getifp(&sc->sc_ue); + + if (ure_get_link_status(sc)) { + if (ifp->if_link_state != LINK_STATE_UP) { + if_link_state_change(ifp, LINK_STATE_UP); + /* Enable transmit and receive. */ + URE_SETBIT_1(sc, URE_PLA_CR, URE_MCU_TYPE_PLA, URE_CR_RE | URE_CR_TE); + + if (ure_read_2(sc, URE_PLA_PHYSTATUS, URE_MCU_TYPE_PLA) & + URE_PHYSTATUS_2500MBPS) + URE_CLRBIT_2(sc, URE_PLA_MAC_PWR_CTRL4, URE_MCU_TYPE_PLA, 0x40); + else + URE_SETBIT_2(sc, URE_PLA_MAC_PWR_CTRL4, URE_MCU_TYPE_PLA, 0x40); + } + } else { + if (ifp->if_link_state != LINK_STATE_DOWN) { + if_link_state_change(ifp, LINK_STATE_DOWN); + } + } +} + static int +ure_get_link_status(struct ure_softc *sc) +{ + + if (ure_read_2(sc, URE_PLA_PHYSTATUS, URE_MCU_TYPE_PLA) & + URE_PHYSTATUS_LINK) { + sc->sc_flags |= URE_FLAG_LINK; + return (1); + } else { + + sc->sc_flags &= ~URE_FLAG_LINK; + return (0); + } +} + +static int ure_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { struct usb_ether *ue = ifp->if_softc; - struct ure_softc *sc; + struct ure_softc *sc = uether_getsc(ue);; struct ifreq *ifr; int error, mask, reinit; - sc = uether_getsc(ue); ifr = (struct ifreq *)data; error = 0; reinit = 0; @@ -1297,6 +1492,14 @@ if_setmtu(ifp, ifr->ifr_mtu); URE_UNLOCK(sc); break; + + case SIOCGIFMEDIA: + case SIOCSIFMEDIA: + if (sc->sc_flags & (URE_FLAG_8156 | URE_FLAG_8156B)) + error = ifmedia_ioctl(ifp, ifr, &sc->sc_ifmedia, cmd); + else + error = uether_ioctl(ifp, cmd, data); + break; default: error = uether_ioctl(ifp, cmd, data); @@ -1310,27 +1513,18 @@ { uint32_t pwrctrl; - /* Disable ALDPS. */ - ure_ocp_reg_write(sc, URE_OCP_ALDPS_CONFIG, URE_ENPDNPS | URE_LINKENA | - URE_DIS_SDSAVE); - uether_pause(&sc->sc_ue, hz / 50); + ure_enable_aldps(sc, false); if (sc->sc_chip & URE_CHIP_VER_4C00) { - ure_write_2(sc, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA, - ure_read_2(sc, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA) & - ~URE_LED_MODE_MASK); + URE_CLRBIT_2(sc, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA, URE_LED_MODE_MASK); } - ure_write_2(sc, URE_USB_UPS_CTRL, URE_MCU_TYPE_USB, - ure_read_2(sc, URE_USB_UPS_CTRL, URE_MCU_TYPE_USB) & - ~URE_POWER_CUT); - ure_write_2(sc, URE_USB_PM_CTRL_STATUS, URE_MCU_TYPE_USB, - ure_read_2(sc, URE_USB_PM_CTRL_STATUS, URE_MCU_TYPE_USB) & - ~URE_RESUME_INDICATE); + URE_CLRBIT_2(sc, URE_USB_UPS_CTRL, URE_MCU_TYPE_USB, URE_POWER_CUT); - ure_write_2(sc, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA, - ure_read_2(sc, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA) | - URE_TX_10M_IDLE_EN | URE_PFM_PWM_SWITCH); + URE_CLRBIT_2(sc, URE_USB_PM_CTRL_STATUS, URE_MCU_TYPE_USB, URE_RESUME_INDICATE); + + URE_SETBIT_2(sc, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA, URE_TX_10M_IDLE_EN | URE_PFM_PWM_SWITCH); + pwrctrl = ure_read_4(sc, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA); pwrctrl &= ~URE_MCU_CLK_RATIO_MASK; pwrctrl |= URE_MCU_CLK_RATIO | URE_D3_CLK_GATED_EN; @@ -1340,16 +1534,11 @@ URE_SPDWN_LINKCHG_MSK); /* Enable Rx aggregation. */ - ure_write_2(sc, URE_USB_USB_CTRL, URE_MCU_TYPE_USB, - ure_read_2(sc, URE_USB_USB_CTRL, URE_MCU_TYPE_USB) & - ~URE_RX_AGG_DISABLE); + URE_CLRBIT_2(sc, URE_USB_USB_CTRL, URE_MCU_TYPE_USB, URE_RX_AGG_DISABLE | URE_RX_ZERO_EN); - /* Disable ALDPS. */ - ure_ocp_reg_write(sc, URE_OCP_ALDPS_CONFIG, URE_ENPDNPS | URE_LINKENA | - URE_DIS_SDSAVE); - uether_pause(&sc->sc_ue, hz / 50); + ure_enable_aldps(sc, false); - ure_init_fifo(sc); + ure_rtl8152_nic_reset(sc); ure_write_1(sc, URE_USB_TX_AGG, URE_MCU_TYPE_USB, URE_TX_AGG_MAX_THRESHOLD); @@ -1365,10 +1554,7 @@ uint8_t u1u2[8]; int i; - /* Disable ALDPS. */ - ure_ocp_reg_write(sc, URE_OCP_POWER_CFG, - ure_ocp_reg_read(sc, URE_OCP_POWER_CFG) & ~URE_EN_ALDPS); - uether_pause(&sc->sc_ue, hz / 50); + ure_enable_aldps(sc, false); memset(u1u2, 0x00, sizeof(u1u2)); ure_write_mem(sc, URE_USB_TOLERANCE, @@ -1395,9 +1581,7 @@ device_printf(sc->sc_ue.ue_dev, "timeout waiting for phy to stabilize\n"); - ure_write_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, - ure_read_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB) & - ~URE_U2P3_ENABLE); + URE_CLRBIT_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, URE_U2P3_ENABLE); if (sc->sc_chip & URE_CHIP_VER_5C10) { val = ure_read_2(sc, URE_USB_SSPHYLINK2, URE_MCU_TYPE_USB); @@ -1405,14 +1589,10 @@ val |= URE_PWD_DN_SCALE(96); ure_write_2(sc, URE_USB_SSPHYLINK2, URE_MCU_TYPE_USB, val); - ure_write_1(sc, URE_USB_USB2PHY, URE_MCU_TYPE_USB, - ure_read_1(sc, URE_USB_USB2PHY, URE_MCU_TYPE_USB) | - URE_USB2PHY_L1 | URE_USB2PHY_SUSPEND); - } else if (sc->sc_chip & URE_CHIP_VER_5C20) { - ure_write_1(sc, URE_PLA_DMY_REG0, URE_MCU_TYPE_PLA, - ure_read_1(sc, URE_PLA_DMY_REG0, URE_MCU_TYPE_PLA) & - ~URE_ECM_ALDPS); - } + URE_SETBIT_1(sc, URE_USB_USB2PHY, URE_MCU_TYPE_USB, URE_USB2PHY_L1 | URE_USB2PHY_SUSPEND); + } else if (sc->sc_chip & URE_CHIP_VER_5C20) + URE_CLRBIT_1(sc, URE_PLA_DMY_REG0, URE_MCU_TYPE_PLA, URE_ECM_ALDPS); + if (sc->sc_chip & (URE_CHIP_VER_5C20 | URE_CHIP_VER_5C30)) { val = ure_read_1(sc, URE_USB_CSR_DUMMY1, URE_MCU_TYPE_USB); if (ure_read_2(sc, URE_USB_BURST_SIZE, URE_MCU_TYPE_USB) == @@ -1423,17 +1603,11 @@ ure_write_1(sc, URE_USB_CSR_DUMMY1, URE_MCU_TYPE_USB, val); } - ure_write_1(sc, URE_USB_CSR_DUMMY2, URE_MCU_TYPE_USB, - ure_read_1(sc, URE_USB_CSR_DUMMY2, URE_MCU_TYPE_USB) | - URE_EP4_FULL_FC); + URE_SETBIT_1(sc, URE_USB_CSR_DUMMY2, URE_MCU_TYPE_USB, URE_EP4_FULL_FC); - ure_write_2(sc, URE_USB_WDT11_CTRL, URE_MCU_TYPE_USB, - ure_read_2(sc, URE_USB_WDT11_CTRL, URE_MCU_TYPE_USB) & - ~URE_TIMER11_EN); + URE_CLRBIT_2(sc, URE_USB_WDT11_CTRL, URE_MCU_TYPE_USB, URE_TIMER11_EN); - ure_write_2(sc, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA, - ure_read_2(sc, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA) & - ~URE_LED_MODE_MASK); + URE_CLRBIT_2(sc, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA, URE_LED_MODE_MASK); if ((sc->sc_chip & URE_CHIP_VER_5C10) && usbd_get_speed(sc->sc_ue.ue_udev) != USB_SPEED_SUPER) @@ -1450,13 +1624,10 @@ ure_write_2(sc, URE_USB_CONNECT_TIMER, URE_MCU_TYPE_USB, 0x0001); - ure_write_2(sc, URE_USB_POWER_CUT, URE_MCU_TYPE_USB, - ure_read_2(sc, URE_USB_POWER_CUT, URE_MCU_TYPE_USB) & - ~(URE_PWR_EN | URE_PHASE2_EN)); - ure_write_2(sc, URE_USB_MISC_0, URE_MCU_TYPE_USB, - ure_read_2(sc, URE_USB_MISC_0, URE_MCU_TYPE_USB) & - ~URE_PCUT_STATUS); + URE_CLRBIT_2(sc, URE_USB_POWER_CUT, URE_MCU_TYPE_USB, URE_PWR_EN | URE_PHASE2_EN); + URE_CLRBIT_2(sc, URE_USB_MISC_0, URE_MCU_TYPE_USB, URE_PCUT_STATUS); + memset(u1u2, 0xff, sizeof(u1u2)); ure_write_mem(sc, URE_USB_TOLERANCE, URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2)); @@ -1484,17 +1655,41 @@ ure_write_mem(sc, URE_USB_TOLERANCE, URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2)); - /* Disable ALDPS. */ + ure_enable_aldps(sc, false); + + if (sc->sc_chip & (URE_CHIP_VER_5C00 | URE_CHIP_VER_5C10 | + URE_CHIP_VER_5C20)) { + ure_ocp_reg_write(sc, URE_OCP_ADC_CFG, + URE_CKADSEL_L | URE_ADC_EN | URE_EN_EMI_L); + } + if (sc->sc_chip & URE_CHIP_VER_5C00) { + ure_ocp_reg_write(sc, URE_OCP_EEE_CFG, + ure_ocp_reg_read(sc, URE_OCP_EEE_CFG) & + ~URE_CTAP_SHORT_EN); + } ure_ocp_reg_write(sc, URE_OCP_POWER_CFG, - ure_ocp_reg_read(sc, URE_OCP_POWER_CFG) & ~URE_EN_ALDPS); - uether_pause(&sc->sc_ue, hz / 50); + ure_ocp_reg_read(sc, URE_OCP_POWER_CFG) | + URE_EEE_CLKDIV_EN); + ure_ocp_reg_write(sc, URE_OCP_DOWN_SPEED, + ure_ocp_reg_read(sc, URE_OCP_DOWN_SPEED) | + URE_EN_10M_BGOFF); + ure_ocp_reg_write(sc, URE_OCP_POWER_CFG, + ure_ocp_reg_read(sc, URE_OCP_POWER_CFG) | + URE_EN_10M_PLLOFF); + ure_sram_write(sc, URE_SRAM_IMPEDANCE, 0x0b13); + URE_SETBIT_2(sc, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA, URE_PFM_PWM_SWITCH); - ure_init_fifo(sc); + /* Enable LPF corner auto tune. */ + ure_sram_write(sc, URE_SRAM_LPF_CFG, 0xf70f); + /* Adjust 10M amplitude. */ + ure_sram_write(sc, URE_SRAM_10M_AMP1, 0x00af); + ure_sram_write(sc, URE_SRAM_10M_AMP2, 0x0208); + + ure_rtl8152_nic_reset(sc); + /* Enable Rx aggregation. */ - ure_write_2(sc, URE_USB_USB_CTRL, URE_MCU_TYPE_USB, - ure_read_2(sc, URE_USB_USB_CTRL, URE_MCU_TYPE_USB) & - ~URE_RX_AGG_DISABLE); + URE_CLRBIT_2(sc, URE_USB_USB_CTRL, URE_MCU_TYPE_USB, URE_RX_AGG_DISABLE | URE_RX_ZERO_EN); val = ure_read_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB); if (!(sc->sc_chip & (URE_CHIP_VER_5C00 | URE_CHIP_VER_5C10))) @@ -1509,6 +1704,265 @@ } static void +ure_rtl8153b_init(struct ure_softc *sc) +{ + uint16_t val; + int i; + + if (sc->sc_flags & (URE_FLAG_8156 | URE_FLAG_8156B)) { + URE_CLRBIT_1(sc, 0xd26b, URE_MCU_TYPE_USB, 0x01); + ure_write_2(sc, 0xd32a, URE_MCU_TYPE_USB, 0); + URE_SETBIT_2(sc, 0xcfee, URE_MCU_TYPE_USB, 0x0020); + } + + if (sc->sc_flags & URE_FLAG_8156B) { + URE_SETBIT_2(sc, 0xb460, URE_MCU_TYPE_USB, 0x08); + } + + ure_enable_aldps(sc, false); + + /* Disable U1U2 */ + URE_CLRBIT_2(sc, URE_USB_LPM_CONFIG, URE_MCU_TYPE_USB, URE_LPM_U1U2_EN); + + /* Wait loading flash */ + if (sc->sc_chip == URE_CHIP_VER_7410) + if ((ure_read_2(sc, 0xd3ae, URE_MCU_TYPE_PLA) & 0x0002) && + !(ure_read_2(sc, 0xd284, URE_MCU_TYPE_USB) & 0x0020)) { + for (i=0; i < 100; i++) { + if (ure_read_2(sc, 0xd284, URE_MCU_TYPE_USB) & 0x0004) + break; + uether_pause(&sc->sc_ue, hz / 1000); + } + } + + for (i = 0; i < URE_TIMEOUT; i++) { + if (ure_read_2(sc, URE_PLA_BOOT_CTRL, URE_MCU_TYPE_PLA) & + URE_AUTOLOAD_DONE) + break; + uether_pause(&sc->sc_ue, hz / 100); + } + if (i == URE_TIMEOUT) + device_printf(sc->sc_ue.ue_dev, + "timeout waiting for chip autoload\n"); + + val = ure_phy_status(sc, 0); + if ((val == URE_PHY_STAT_EXT_INIT) & + (sc->sc_flags & (URE_FLAG_8156 | URE_FLAG_8156B))) { + ure_ocp_reg_write(sc, 0xa468, + ure_ocp_reg_read(sc, 0xa468) & ~0x0a); + if (sc->sc_flags & URE_FLAG_8156B) + ure_ocp_reg_write(sc, 0xa466, + ure_ocp_reg_read(sc, 0xa466) & ~0x01); + } + + val = ure_ocp_reg_read(sc, URE_OCP_BASE_MII + MII_BMCR); + if (val & BMCR_PDOWN) { + val &= ~BMCR_PDOWN; + ure_ocp_reg_write(sc, URE_OCP_BASE_MII + MII_BMCR, val); + } + + ure_phy_status(sc, URE_PHY_STAT_LAN_ON); + + /* Disable U2P3 */ + URE_CLRBIT_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, URE_U2P3_ENABLE); + + /* MSC timer, 32760 ms. */ + ure_write_2(sc, URE_USB_MSC_TIMER, URE_MCU_TYPE_USB, 0x0fff); + + /* U1/U2/L1 idle timer, 500 us. */ + ure_write_2(sc, URE_USB_U1U2_TIMER, URE_MCU_TYPE_USB, 500); + + /* Disable power cut */ + URE_CLRBIT_2(sc, URE_USB_POWER_CUT, URE_MCU_TYPE_USB, URE_PWR_EN); + URE_CLRBIT_2(sc, URE_USB_MISC_0, URE_MCU_TYPE_USB, URE_PCUT_STATUS); + + /* Disable ups */ + URE_CLRBIT_1(sc, URE_USB_POWER_CUT, URE_MCU_TYPE_USB, URE_UPS_EN | URE_USP_PREWAKE); + URE_CLRBIT_1(sc, 0xcfff, URE_MCU_TYPE_USB, 0x01); + + /* Disable queue wake */ + URE_CLRBIT_1(sc, URE_PLA_INDICATE_FALG, URE_MCU_TYPE_USB, URE_UPCOMING_RUNTIME_D3); + URE_CLRBIT_1(sc, URE_PLA_SUSPEND_FLAG, URE_MCU_TYPE_USB, URE_LINK_CHG_EVENT); + URE_CLRBIT_2(sc, URE_PLA_EXTRA_STATUS, URE_MCU_TYPE_USB, URE_LINK_CHANGE_FLAG); + + /* Disable runtime suspend */ + ure_write_1(sc, URE_PLA_CRWECR, URE_MCU_TYPE_PLA, URE_CRWECR_CONFIG); + URE_CLRBIT_2(sc, URE_PLA_CONFIG34, URE_MCU_TYPE_USB, URE_LINK_OFF_WAKE_EN); + ure_write_1(sc, URE_PLA_CRWECR, URE_MCU_TYPE_PLA, URE_CRWECR_NORAML); + + /* Enable U1U2 */ + if (usbd_get_speed(sc->sc_ue.ue_udev) == USB_SPEED_SUPER) + URE_SETBIT_2(sc, URE_USB_LPM_CONFIG, URE_MCU_TYPE_USB, URE_LPM_U1U2_EN); + + if (sc->sc_flags & URE_FLAG_8156B) { + URE_CLRBIT_2(sc, 0xc010, URE_MCU_TYPE_PLA, 0x0800); + URE_SETBIT_2(sc, 0xe854, URE_MCU_TYPE_PLA, 0x0001); + + /* enable fc timer and set timer to 600 ms. */ + ure_write_2(sc, URE_USB_FC_TIMER, URE_MCU_TYPE_USB, URE_CTRL_TIMER_EN | (600 / 8)); + + if (!(ure_read_1(sc, 0xdc6b, URE_MCU_TYPE_PLA) & 0x80)) { + val = ure_read_2(sc, URE_USB_FW_CTRL, URE_MCU_TYPE_USB); + val |= URE_FLOW_CTRL_PATCH_OPT | 0x0100; + val &= ~0x08; + ure_write_2(sc, URE_USB_FW_CTRL, URE_MCU_TYPE_USB, val); + } + + URE_SETBIT_2(sc, URE_USB_FW_TASK, URE_MCU_TYPE_USB, URE_FC_PATCH_TASK); + } + + val = ure_read_2(sc, URE_PLA_EXTRA_STATUS, URE_MCU_TYPE_PLA); + if (ure_get_link_status(sc)) + val |= URE_CUR_LINK_OK; + else + val &= ~URE_CUR_LINK_OK; + val |= URE_POLL_LINK_CHG; + ure_write_2(sc, URE_PLA_EXTRA_STATUS, URE_MCU_TYPE_PLA, val); + + /* MAC clock speed down */ + if (sc->sc_flags & (URE_FLAG_8156 | URE_FLAG_8156B)) { + ure_write_2(sc, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA, 0x0403); + val = ure_read_2(sc, URE_PLA_MAC_PWR_CTRL2, URE_MCU_TYPE_PLA); + val &= ~0xff; + val |= URE_MAC_CLK_SPDWN_EN | 0x03; + ure_write_2(sc, URE_PLA_MAC_PWR_CTRL2, URE_MCU_TYPE_PLA, val); + } else { + URE_SETBIT_2(sc, URE_PLA_MAC_PWR_CTRL2, URE_MCU_TYPE_USB, URE_MAC_CLK_SPDWN_EN); + } + URE_CLRBIT_2(sc, URE_PLA_MAC_PWR_CTRL3, URE_MCU_TYPE_PLA, URE_PLA_MCU_SPDWN_EN); + + /* Enable Rx aggregation. */ + URE_CLRBIT_2(sc, URE_USB_USB_CTRL, URE_MCU_TYPE_USB, URE_RX_AGG_DISABLE | URE_RX_ZERO_EN); + + if (sc->sc_flags & URE_FLAG_8156) + URE_SETBIT_1(sc, 0xd4b4, URE_MCU_TYPE_USB, 0x02); + + /* Reset tally */ + URE_SETBIT_2(sc, URE_PLA_RSTTALLY, URE_MCU_TYPE_USB, URE_TALLY_RESET); +} + +static void +ure_rtl8153b_nic_reset(struct ure_softc *sc) +{ + struct ifnet *ifp = uether_getifp(&sc->sc_ue); + uint16_t val; + int i; + + /* Disable U1U2 */ + URE_CLRBIT_2(sc, URE_USB_LPM_CONFIG, URE_MCU_TYPE_USB, URE_LPM_U1U2_EN); + + /* Disable U2P3 */ + URE_CLRBIT_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, URE_U2P3_ENABLE); + + ure_enable_aldps(sc, false); + + /* Enable rxdy_gated */ + URE_SETBIT_2(sc, URE_PLA_MISC_1, URE_MCU_TYPE_PLA, URE_RXDY_GATED_EN); + + /* Disable teredo */ + ure_disable_teredo(sc); + + DEVPRINTFN(14, sc->sc_ue.ue_dev, "rtl8153b_nic_reset: RCR: %#x\n", ure_read_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA)); + URE_CLRBIT_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA, URE_RCR_ACPT_ALL); + + ure_reset(sc); + + /* Reset BMU */ + URE_CLRBIT_1(sc, URE_USB_BMU_RESET, URE_MCU_TYPE_USB, URE_BMU_RESET_EP_IN | URE_BMU_RESET_EP_OUT); + URE_SETBIT_1(sc, URE_USB_BMU_RESET, URE_MCU_TYPE_USB, URE_BMU_RESET_EP_IN | URE_BMU_RESET_EP_OUT); + + URE_CLRBIT_1(sc, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA, URE_NOW_IS_OOB); + URE_CLRBIT_2(sc, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA, URE_MCU_BORW_EN); + if (sc->sc_flags & URE_FLAG_8153B) { + for (i = 0; i < URE_TIMEOUT; i++) { + if (ure_read_1(sc, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA) & + URE_LINK_LIST_READY) + break; + uether_pause(&sc->sc_ue, hz / 100); + } + if (i == URE_TIMEOUT) + device_printf(sc->sc_ue.ue_dev, + "timeout waiting for OOB control\n"); + + URE_SETBIT_2(sc, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA, URE_RE_INIT_LL); + for (i = 0; i < URE_TIMEOUT; i++) { + if (ure_read_1(sc, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA) & + URE_LINK_LIST_READY) + break; + uether_pause(&sc->sc_ue, hz / 100); + } + if (i == URE_TIMEOUT) + device_printf(sc->sc_ue.ue_dev, + "timeout waiting for OOB control\n"); + } + + /* Configure rxvlan */ + val = ure_read_2(sc, 0xc012, URE_MCU_TYPE_PLA); + val &= ~0x00c0; + if (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING) + val |= 0x00c0; + ure_write_2(sc, 0xc012, URE_MCU_TYPE_PLA, val); + + val = if_getmtu(ifp); + ure_write_2(sc, URE_PLA_RMS, URE_MCU_TYPE_PLA, URE_FRAMELEN(val)); + ure_write_1(sc, URE_PLA_MTPS, URE_MCU_TYPE_PLA, URE_MTPS_JUMBO); + + if (sc->sc_flags & URE_FLAG_8153B) { + URE_SETBIT_2(sc, URE_PLA_TCR0, URE_MCU_TYPE_PLA, URE_TCR0_AUTO_FIFO); + ure_reset(sc); + } + + /* Configure fc parameter */ + if (sc->sc_flags & URE_FLAG_8156) { + ure_write_2(sc, 0xc0a6, URE_MCU_TYPE_PLA, 0x0400); + ure_write_2(sc, 0xc0aa, URE_MCU_TYPE_PLA, 0x0800); + } else if (sc->sc_flags & URE_FLAG_8156B) { + ure_write_2(sc, 0xc0a6, URE_MCU_TYPE_PLA, 0x0200); + ure_write_2(sc, 0xc0aa, URE_MCU_TYPE_PLA, 0x0400); + } + + /* Configure Rx FIFO threshold. */ + if (sc->sc_flags & URE_FLAG_8153B) { + ure_write_4(sc, URE_PLA_RXFIFO_CTRL0, URE_MCU_TYPE_PLA, URE_RXFIFO_THR1_NORMAL); + ure_write_2(sc, URE_PLA_RXFIFO_CTRL1, URE_MCU_TYPE_PLA, URE_RXFIFO_THR2_NORMAL); + ure_write_2(sc, URE_PLA_RXFIFO_CTRL2, URE_MCU_TYPE_PLA, URE_RXFIFO_THR3_NORMAL); + ure_write_4(sc, URE_USB_RX_BUF_TH, URE_MCU_TYPE_USB, URE_RX_THR_B); + } else { + ure_write_2(sc, 0xc0a2, URE_MCU_TYPE_PLA, + (ure_read_2(sc, 0xc0a2, URE_MCU_TYPE_PLA) & ~0xfff) | 0x08); + ure_write_4(sc, URE_USB_RX_BUF_TH, URE_MCU_TYPE_USB, 0x00600400); + } + + /* Configure Tx FIFO threshold. */ + if (sc->sc_flags & URE_FLAG_8153B) { + ure_write_4(sc, URE_PLA_TXFIFO_CTRL, URE_MCU_TYPE_PLA, URE_TXFIFO_THR_NORMAL2); + } else if (sc->sc_flags & URE_FLAG_8156) { + ure_write_2(sc, URE_PLA_TXFIFO_CTRL, URE_MCU_TYPE_PLA, URE_TXFIFO_THR_NORMAL2); + URE_SETBIT_2(sc, 0xd4b4, URE_MCU_TYPE_USB, 0x0002); + } else if (sc->sc_flags & URE_FLAG_8156B) { + ure_write_2(sc, URE_PLA_TXFIFO_CTRL, URE_MCU_TYPE_PLA, 0x0008); + ure_write_2(sc, 0xe61a, URE_MCU_TYPE_PLA, + (URE_FRAMELEN(val) + 0x100) / 16 ); + } + + URE_CLRBIT_2(sc, URE_PLA_MAC_PWR_CTRL3, URE_MCU_TYPE_PLA, URE_PLA_MCU_SPDWN_EN); + + if (sc->sc_flags & (URE_FLAG_8156 | URE_FLAG_8156B)) + URE_CLRBIT_2(sc, 0xd32a, URE_MCU_TYPE_USB, 0x300); + + ure_enable_aldps(sc, true); + + if (sc->sc_flags & (URE_FLAG_8156 | URE_FLAG_8156B)) { + /* Enable U2P3 */ + URE_SETBIT_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, URE_U2P3_ENABLE); + } + + /* Enable U1U2 */ + if (usbd_get_speed(sc->sc_ue.ue_udev) == USB_SPEED_SUPER) + URE_SETBIT_2(sc, URE_USB_LPM_CONFIG, URE_MCU_TYPE_USB, URE_LPM_U1U2_EN); +} + +static void ure_stop(struct usb_ether *ue) { struct ure_softc *sc = uether_getsc(ue); @@ -1523,8 +1977,10 @@ /* * stop all the transfers, if not already stopped: */ - for (int i = 0; i < URE_N_TRANSFER; i++) { + for (int i = 0; i < URE_MAX_RX; i++) { usbd_transfer_stop(sc->sc_rx_xfer[i]); + } + for (int i = 0; i < URE_MAX_TX; i++) { usbd_transfer_stop(sc->sc_tx_xfer[i]); } } @@ -1533,80 +1989,83 @@ ure_disable_teredo(struct ure_softc *sc) { - ure_write_4(sc, URE_PLA_TEREDO_CFG, URE_MCU_TYPE_PLA, - ure_read_4(sc, URE_PLA_TEREDO_CFG, URE_MCU_TYPE_PLA) & - ~(URE_TEREDO_SEL | URE_TEREDO_RS_EVENT_MASK | URE_OOB_TEREDO_EN)); - ure_write_2(sc, URE_PLA_WDT6_CTRL, URE_MCU_TYPE_PLA, - URE_WDT6_SET_MODE); + if (sc->sc_flags & (URE_FLAG_8153B | URE_FLAG_8156 | URE_FLAG_8156B)) + 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, + (URE_TEREDO_SEL | URE_TEREDO_RS_EVENT_MASK | URE_OOB_TEREDO_EN)); + } + ure_write_2(sc, URE_PLA_WDT6_CTRL, URE_MCU_TYPE_PLA, URE_WDT6_SET_MODE); ure_write_2(sc, URE_PLA_REALWOW_TIMER, URE_MCU_TYPE_PLA, 0); ure_write_4(sc, URE_PLA_TEREDO_TIMER, URE_MCU_TYPE_PLA, 0); } static void -ure_init_fifo(struct ure_softc *sc) +ure_enable_aldps(struct ure_softc *sc, bool enable) { - uint32_t rx_fifo1, rx_fifo2; int i; - ure_write_2(sc, URE_PLA_MISC_1, URE_MCU_TYPE_PLA, - ure_read_2(sc, URE_PLA_MISC_1, URE_MCU_TYPE_PLA) | - URE_RXDY_GATED_EN); + if (enable) + ure_ocp_reg_write(sc, URE_OCP_POWER_CFG, + ure_ocp_reg_read(sc, URE_OCP_POWER_CFG) | URE_EN_ALDPS); + else { + ure_ocp_reg_write(sc, URE_OCP_ALDPS_CONFIG, URE_ENPDNPS | URE_LINKENA | + URE_DIS_SDSAVE); + for (i = 0; i < 20; i++) { + uether_pause(&sc->sc_ue, hz / 1000); + if (ure_ocp_reg_read(sc, 0xe000) & 0x0100) + break; + } + } +} - ure_disable_teredo(sc); +static uint16_t +ure_phy_status(struct ure_softc *sc, uint16_t desired) +{ + uint16_t val; + int i; + + for (i = 0; i < URE_TIMEOUT; i++) { + val = ure_ocp_reg_read(sc, URE_OCP_PHY_STATUS) & + URE_PHY_STAT_MASK; + if (desired) { + if (val == desired) + break; + } else { + if (val == URE_PHY_STAT_LAN_ON || + val == URE_PHY_STAT_PWRDN || + val == URE_PHY_STAT_EXT_INIT) + break; + } + uether_pause(&sc->sc_ue, hz / 100); + } + if (i == URE_TIMEOUT) + device_printf(sc->sc_ue.ue_dev, + "timeout waiting for phy to stabilize\n"); - DEVPRINTFN(14, sc->sc_ue.ue_dev, "init_fifo: RCR: %#x\n", ure_read_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA)); - ure_write_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA, - ure_read_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA) & - ~URE_RCR_ACPT_ALL); + return val; +} - if (!(sc->sc_flags & URE_FLAG_8152)) { - if (sc->sc_chip & (URE_CHIP_VER_5C00 | URE_CHIP_VER_5C10 | - URE_CHIP_VER_5C20)) { - ure_ocp_reg_write(sc, URE_OCP_ADC_CFG, - URE_CKADSEL_L | URE_ADC_EN | URE_EN_EMI_L); - } - if (sc->sc_chip & URE_CHIP_VER_5C00) { - ure_ocp_reg_write(sc, URE_OCP_EEE_CFG, - ure_ocp_reg_read(sc, URE_OCP_EEE_CFG) & - ~URE_CTAP_SHORT_EN); - } - ure_ocp_reg_write(sc, URE_OCP_POWER_CFG, - ure_ocp_reg_read(sc, URE_OCP_POWER_CFG) | - URE_EEE_CLKDIV_EN); - ure_ocp_reg_write(sc, URE_OCP_DOWN_SPEED, - ure_ocp_reg_read(sc, URE_OCP_DOWN_SPEED) | - URE_EN_10M_BGOFF); - ure_ocp_reg_write(sc, URE_OCP_POWER_CFG, - ure_ocp_reg_read(sc, URE_OCP_POWER_CFG) | - URE_EN_10M_PLLOFF); - ure_ocp_reg_write(sc, URE_OCP_SRAM_ADDR, URE_SRAM_IMPEDANCE); - ure_ocp_reg_write(sc, URE_OCP_SRAM_DATA, 0x0b13); - ure_write_2(sc, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA, - ure_read_2(sc, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA) | - URE_PFM_PWM_SWITCH); +static void +ure_rtl8152_nic_reset(struct ure_softc *sc) +{ + uint32_t rx_fifo1, rx_fifo2; + int i; - /* Enable LPF corner auto tune. */ - ure_ocp_reg_write(sc, URE_OCP_SRAM_ADDR, URE_SRAM_LPF_CFG); - ure_ocp_reg_write(sc, URE_OCP_SRAM_DATA, 0xf70f); + URE_SETBIT_2(sc, URE_PLA_MISC_1, URE_MCU_TYPE_PLA, URE_RXDY_GATED_EN); - /* Adjust 10M amplitude. */ - ure_ocp_reg_write(sc, URE_OCP_SRAM_ADDR, URE_SRAM_10M_AMP1); - ure_ocp_reg_write(sc, URE_OCP_SRAM_DATA, 0x00af); - ure_ocp_reg_write(sc, URE_OCP_SRAM_ADDR, URE_SRAM_10M_AMP2); - ure_ocp_reg_write(sc, URE_OCP_SRAM_DATA, 0x0208); - } + ure_disable_teredo(sc); + DEVPRINTFN(14, sc->sc_ue.ue_dev, "rtl8152_nic_reset: RCR: %#x\n", ure_read_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA)); + URE_CLRBIT_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA, URE_RCR_ACPT_ALL); + ure_reset(sc); ure_write_1(sc, URE_PLA_CR, URE_MCU_TYPE_PLA, 0); - ure_write_1(sc, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA, - ure_read_1(sc, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA) & - ~URE_NOW_IS_OOB); + URE_CLRBIT_1(sc, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA, URE_NOW_IS_OOB); - ure_write_2(sc, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA, - ure_read_2(sc, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA) & - ~URE_MCU_BORW_EN); + URE_CLRBIT_2(sc, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA, URE_MCU_BORW_EN); for (i = 0; i < URE_TIMEOUT; i++) { if (ure_read_1(sc, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA) & URE_LINK_LIST_READY) @@ -1616,9 +2075,7 @@ if (i == URE_TIMEOUT) device_printf(sc->sc_ue.ue_dev, "timeout waiting for OOB control\n"); - ure_write_2(sc, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA, - ure_read_2(sc, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA) | - URE_RE_INIT_LL); + URE_SETBIT_2(sc, URE_PLA_SFF_STS_7, URE_MCU_TYPE_PLA, URE_RE_INIT_LL); for (i = 0; i < URE_TIMEOUT; i++) { if (ure_read_1(sc, URE_PLA_OOB_CTRL, URE_MCU_TYPE_PLA) & URE_LINK_LIST_READY) @@ -1629,12 +2086,9 @@ device_printf(sc->sc_ue.ue_dev, "timeout waiting for OOB control\n"); - ure_write_2(sc, URE_PLA_CPCR, URE_MCU_TYPE_PLA, - ure_read_2(sc, URE_PLA_CPCR, URE_MCU_TYPE_PLA) & - ~URE_CPCR_RX_VLAN); - ure_write_2(sc, URE_PLA_TCR0, URE_MCU_TYPE_PLA, - ure_read_2(sc, URE_PLA_TCR0, URE_MCU_TYPE_PLA) | - URE_TCR0_AUTO_FIFO); + URE_CLRBIT_2(sc, URE_PLA_CPCR, URE_MCU_TYPE_PLA, URE_CPCR_RX_VLAN); + + URE_SETBIT_2(sc, URE_PLA_TCR0, URE_MCU_TYPE_PLA, URE_TCR0_AUTO_FIFO); /* Configure Rx FIFO threshold. */ ure_write_4(sc, URE_PLA_RXFIFO_CTRL0, URE_MCU_TYPE_PLA, --- /usr/src/sys/dev/usb/net/if_urereg.h 2021-01-26 11:43:47.000917000 +0100 +++ /usr/src/sys/dev/usb/net/if_urereg.h.new 2021-02-03 15:39:50.000000000 +0100 @@ -40,7 +40,10 @@ #define URE_BYTE_EN_BYTE 0x11 #define URE_BYTE_EN_SIX_BYTES 0x3f +#define URE_FRAMELEN(mtu) (mtu + ETHER_HDR_LEN + ETHER_CRC_LEN + ETHER_VLAN_ENCAP_LEN) #define URE_MAX_FRAMELEN (ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN) +#define URE_JUMBO_FRAMELEN (9*1024) +#define URE_JUMBO_MTU (URE_JUMBO_FRAMELEN - ETHER_HDR_LEN - ETHER_CRC_LEN - ETHER_VLAN_ENCAP_LEN) #define URE_PLA_IDR 0xc000 #define URE_PLA_RCR 0xc010 @@ -58,6 +61,9 @@ #define URE_PAL_BDC_CR 0xd1a0 #define URE_PLA_TEREDO_TIMER 0xd2cc #define URE_PLA_REALWOW_TIMER 0xd2e8 +#define URE_PLA_SUSPEND_FLAG 0xd38a +#define URE_PLA_INDICATE_FALG 0xd38c +#define URE_PLA_EXTRA_STATUS 0xd398 #define URE_PLA_LEDSEL 0xdd90 #define URE_PLA_LED_FEATURE 0xdd92 #define URE_PLA_PHYAR 0xde00 @@ -74,9 +80,10 @@ #define URE_PLA_TCR1 0xe612 #define URE_PLA_MTPS 0xe615 #define URE_PLA_TXFIFO_CTRL 0xe618 -#define URE_PLA_RSTTELLY 0xe800 +#define URE_PLA_RSTTALLY 0xe800 #define URE_PLA_CR 0xe813 #define URE_PLA_CRWECR 0xe81c +#define URE_PLA_CONFIG34 0xe820 #define URE_PLA_CONFIG5 0xe822 #define URE_PLA_PHY_PWR 0xe84c #define URE_PLA_OOB_CTRL 0xe84f @@ -86,7 +93,18 @@ #define URE_PLA_OCP_GPHY_BASE 0xe86c #define URE_PLA_TELLYCNT 0xe890 #define URE_PLA_SFF_STS_7 0xe8de +#define URE_PLA_PHYSTATUS 0xe908 #define URE_GMEDIASTAT 0xe908 +#define URE_PLA_BP_BA 0xfc26 +#define URE_PLA_BP_0 0xfc28 +#define URE_PLA_BP_1 0xfc2a +#define URE_PLA_BP_2 0xfc2c +#define URE_PLA_BP_3 0xfc2e +#define URE_PLA_BP_4 0xfc30 +#define URE_PLA_BP_5 0xfc32 +#define URE_PLA_BP_6 0xfc34 +#define URE_PLA_BP_7 0xfc36 +#define URE_PLA_BP_EN 0xfc38 #define URE_USB_USB2PHY 0xb41e #define URE_USB_SSPHYLINK2 0xb428 @@ -95,23 +113,53 @@ #define URE_USB_CSR_DUMMY2 0xb466 #define URE_USB_DEV_STAT 0xb808 #define URE_USB_CONNECT_TIMER 0xcbf8 +#define URE_USB_MSC_TIMER 0xcbfc #define URE_USB_BURST_SIZE 0xcfc0 +#define URE_USB_LPM_CONFIG 0xcfd8 +#define URE_USB_FW_CTRL 0xd334 /* RTL8153B */ #define URE_USB_USB_CTRL 0xd406 #define URE_USB_PHY_CTRL 0xd408 #define URE_USB_TX_AGG 0xd40a #define URE_USB_RX_BUF_TH 0xd40c +#define URE_USB_FW_TASK 0xd4e8 /* RTL8153B */ #define URE_USB_USB_TIMER 0xd428 #define URE_USB_RX_EARLY_AGG 0xd42c -#define URE_USB_PM_CTRL_STATUS 0xd432 +#define URE_USB_RX_EARLY_SIZE 0xd42e +#define URE_USB_PM_CTRL_STATUS 0xd432 /* RTL8153A */ +#define URE_USB_RX_EXTRA_AGG_TMR 0xd432 /* RTL8153B */ #define URE_USB_TX_DMA 0xd434 +#define URE_USB_UPT_RXDMA_OWN 0xd437 +#define URE_USB_FC_TIMER 0xd340 #define URE_USB_TOLERANCE 0xd490 #define URE_USB_LPM_CTRL 0xd41a +#define URE_USB_BMU_RESET 0xd4b0 +#define URE_USB_U1U2_TIMER 0xd4da #define URE_USB_UPS_CTRL 0xd800 -#define URE_USB_MISC_0 0xd81a #define URE_USB_POWER_CUT 0xd80a +#define URE_USB_MISC_0 0xd81a #define URE_USB_AFE_CTRL2 0xd824 #define URE_USB_WDT11_CTRL 0xe43c +#define URE_USB_BP_BA URE_PLA_BP_BA +#define URE_USB_BP_0 URE_PLA_BP_0 +#define URE_USB_BP_1 URE_PLA_BP_1 +#define URE_USB_BP_2 URE_PLA_BP_2 +#define URE_USB_BP_3 URE_PLA_BP_3 +#define URE_USB_BP_4 URE_PLA_BP_4 +#define URE_USB_BP_5 URE_PLA_BP_5 +#define URE_USB_BP_6 URE_PLA_BP_6 +#define URE_USB_BP_7 URE_PLA_BP_7 +#define URE_USB_BP_EN URE_PLA_BP_EN /* RTL8153A */ +#define URE_USB_BP_8 0xfc38 /* RTL8153B */ +#define URE_USB_BP_9 0xfc3a +#define URE_USB_BP_10 0xfc3c +#define URE_USB_BP_11 0xfc3e +#define URE_USB_BP_12 0xfc40 +#define URE_USB_BP_13 0xfc42 +#define URE_USB_BP_14 0xfc44 +#define URE_USB_BP_15 0xfc46 +#define URE_USB_BP2_EN 0xfc48 + /* OCP Registers. */ #define URE_OCP_ALDPS_CONFIG 0x2010 #define URE_OCP_EEE_CONFIG1 0x2080 @@ -130,13 +178,19 @@ #define URE_OCP_EEE_ADV 0xa5d0 #define URE_OCP_EEE_LPABLE 0xa5d2 #define URE_OCP_PHY_STATE 0xa708 +#define URE_OCP_PHY_PATCH_STAT 0xb800 +#define URE_OCP_PHY_PATCH_CMD 0xb820 +#define URE_OCP_PHY_LOCK 0xb82e #define URE_OCP_ADC_CFG 0xbc06 /* SRAM Register. */ +#define URE_SRAM_GREEN_CFG 0x8011 #define URE_SRAM_LPF_CFG 0x8012 +#define URE_SRAM_GPHY_FW_VER 0x801e #define URE_SRAM_10M_AMP1 0x8080 #define URE_SRAM_10M_AMP2 0x8082 #define URE_SRAM_IMPEDANCE 0x8084 +#define URE_SRAM_PHY_LOCK 0xb82e /* PLA_RCR */ #define URE_RCR_AAP 0x00000001 @@ -189,6 +243,13 @@ /* PLA_TCR1 */ #define URE_VERSION_MASK 0x7cf0 +/* PLA_MTPS */ +#define URE_MTPS_DEFAULT 96 +#define URE_MTPS_JUMBO 192 + +/* PLA_RSTTALLY */ +#define URE_TALLY_RESET 0x0001 + /* PLA_CR */ #define URE_CR_RST 0x10 #define URE_CR_RE 0x08 @@ -225,6 +286,10 @@ /* PAL_BDC_CR */ #define URE_ALDPS_PROXY_MODE 0x0001 +/* URE_PLA_CONFIG34 */ +#define URE_LINK_OFF_WAKE_EN 0x0008 +#define URE_LINK_ON_WAKE_EN 0x0010 + /* PLA_CONFIG5 */ #define URE_LAN_WAKE_EN 0x0002 @@ -242,9 +307,11 @@ #define URE_ALDPS_SPDWN_RATIO 0x0f87 /* PLA_MAC_PWR_CTRL2 */ +#define URE_MAC_CLK_SPDWN_EN 0x8000 #define URE_EEE_SPDWN_RATIO 0x8007 /* PLA_MAC_PWR_CTRL3 */ +#define URE_PLA_MCU_SPDWN_EN 0x4000 #define URE_PKT_AVAIL_SPDWN_EN 0x0100 #define URE_SUSPEND_SPDWN_EN 0x0004 #define URE_U1U2_SPDWN_EN 0x0002 @@ -276,6 +343,27 @@ /* PLA_BOOT_CTRL */ #define URE_AUTOLOAD_DONE 0x0002 +/* PLA_SUSPEND_FLAG */ +#define URE_LINK_CHG_EVENT 0x01 + +/* PLA_INDICATE_FALG */ +#define URE_UPCOMING_RUNTIME_D3 0x01 + +/* PLA_EXTRA_STATUS */ +#define URE_POLL_LINK_CHG 0x0001 +#define URE_LINK_CHANGE_FLAG 0x0100 +#define URE_CUR_LINK_OK 0x8000 + +/* URE_PLA_PHYSTATUS */ +#define URE_PHYSTATUS_FDX 0x0001 +#define URE_PHYSTATUS_LINK 0x0002 +#define URE_PHYSTATUS_10MBPS 0x0004 +#define URE_PHYSTATUS_100MBPS 0x0008 +#define URE_PHYSTATUS_1000MBPS 0x0010 +#define URE_PHYSTATUS_500MBPS 0x0100 +#define URE_PHYSTATUS_1250MBPS 0x0200 +#define URE_PHYSTATUS_2500MBPS 0x0400 + /* USB_USB2PHY */ #define URE_USB2PHY_SUSPEND 0x0001 #define URE_USB2PHY_L1 0x0002 @@ -295,6 +383,9 @@ #define URE_STAT_SPEED_HIGH 0x0000 #define URE_STAT_SPEED_FULL 0x0001 +/* URE_USB_LPM_CONFIG */ +#define URE_LPM_U1U2_EN 0x0001 + /* USB_TX_AGG */ #define URE_TX_AGG_MAX_THRESHOLD 0x03 @@ -302,17 +393,35 @@ #define URE_RX_THR_SUPER 0x0c350180 #define URE_RX_THR_HIGH 0x7a120180 #define URE_RX_THR_SLOW 0xffff0180 +#define URE_RX_THR_B 0x00010001 /* USB_TX_DMA */ #define URE_TEST_MODE_DISABLE 0x00000001 #define URE_TX_SIZE_ADJUST1 0x00000100 +/* USB_BMU_RESET */ +#define URE_BMU_RESET_EP_IN 0x01 +#define URE_BMU_RESET_EP_OUT 0x02 + +/* USB_UPT_RXDMA_OWN */ +#define URE_OWN_UPDATE 0x01 +#define URE_OWN_CLEAR 0x02 + +/* USB_FW_TASK */ +#define URE_FC_PATCH_TASK 0x0001 + /* USB_UPS_CTRL */ #define URE_POWER_CUT 0x0100 /* USB_PM_CTRL_STATUS */ #define URE_RESUME_INDICATE 0x0001 +/* USB_FW_CTRL */ +#define URE_FLOW_CTRL_PATCH_OPT 0x01 + +/* USB_FC_TIMER */ +#define URE_CTRL_TIMER_EN 0x8000 + /* USB_USB_CTRL */ #define URE_RX_AGG_DISABLE 0x0010 #define URE_RX_ZERO_EN 0x0080 @@ -321,8 +430,10 @@ #define URE_U2P3_ENABLE 0x0001 /* USB_POWER_CUT */ -#define URE_PWR_EN 0x0001 +#define URE_PWR_EN 0x0001 #define URE_PHASE2_EN 0x0008 +#define URE_UPS_EN 0x0010 +#define URE_USP_PREWAKE 0x0020 /* USB_MISC_0 */ #define URE_PCUT_STATUS 0x0001 @@ -355,6 +466,7 @@ /* OCP_PHY_STATUS */ #define URE_PHY_STAT_MASK 0x0007 +#define URE_PHY_STAT_EXT_INIT 2 #define URE_PHY_STAT_LAN_ON 3 #define URE_PHY_STAT_PWRDN 5 @@ -369,16 +481,37 @@ /* OCP_DOWN_SPEED */ #define URE_EN_10M_BGOFF 0x0080 +#define URE_EN_10M_CLKDIV 0x0800 +#define URE_EN_EEE_100 0x1000 +#define URE_EN_EEE_1000 0x2000 +#define URE_EN_EEE_CMODE 0x4000 /* OCP_PHY_STATE */ #define URE_TXDIS_STATE 0x01 #define URE_ABD_STATE 0x02 +/* OCP_PHY_PATCH_STAT */ +#define URE_PATCH_READY 0x40 + +/* OCP_PHY_PATCH_CMD */ +#define URE_PATCH_REQUEST 0x10 + +/* OCP_PHY_LOCK */ +#define URE_PATCH_LOCK 0x01 + /* OCP_ADC_CFG */ #define URE_CKADSEL_L 0x0100 #define URE_ADC_EN 0x0080 #define URE_EN_EMI_L 0x0040 +/* SRAM_GREEN_CFG */ +#define URE_GREEN_ETH_EN 0x8000 + +/* SRAM_PHY_LOCK */ +#define URE_PHY_PATCH_LOCK 0x0001 + +#define URE_ADV_2500TFDX 0x0080 + #define URE_MCU_TYPE_PLA 0x0100 #define URE_MCU_TYPE_USB 0x0000 @@ -423,42 +556,60 @@ #define URE_TKPKT_TX_LS (1 << 30) #define URE_TXPKT_LEN_MASK 0xffff uint32_t ure_csum; -#define URE_L4_OFFSET_MAX 0x7ff -#define URE_L4_OFFSET_SHIFT 17 +#define URE_L4_OFFSET_MAX 0x7ff +#define URE_L4_OFFSET_SHIFT 17 #define URE_TXPKT_VLAN_MASK 0xffff -#define URE_TXPKT_VLAN (1 << 16) -#define URE_TXPKT_IPV6_CS (1 << 28) -#define URE_TXPKT_IPV4_CS (1 << 29) -#define URE_TXPKT_TCP_CS (1 << 30) -#define URE_TXPKT_UDP_CS (1 << 31) +#define URE_TXPKT_VLAN (1 << 16) +#define URE_TXPKT_IPV6_CS (1 << 28) +#define URE_TXPKT_IPV4_CS (1 << 29) +#define URE_TXPKT_TCP_CS (1 << 30) +#define URE_TXPKT_UDP_CS (1 << 31) /* Lower 12 bits are the VLAN tag */ } __packed; -#define URE_N_TRANSFER 4 -#define URE_TRANSFER_SIZE 16384 +#define URE_MAX_TX 4 +#define URE_MAX_RX 4 +#define URE_TX_BUFSZ 16384 +#define URE_8152_RX_BUFSZ 16 * 1024 +#define URE_8153_RX_BUFSZ 32 * 1024 +#define URE_8156_RX_BUFSZ 48 * 1024 + + struct ure_softc { struct usb_ether sc_ue; + struct ifmedia sc_ifmedia; struct mtx sc_mtx; - struct usb_xfer *sc_rx_xfer[URE_N_TRANSFER]; - struct usb_xfer *sc_tx_xfer[URE_N_TRANSFER]; + struct usb_xfer *sc_rx_xfer[URE_MAX_RX]; + struct usb_xfer *sc_tx_xfer[URE_MAX_TX]; + int sc_rxbufsz; int sc_rxstarted; int sc_phyno; u_int sc_flags; #define URE_FLAG_LINK 0x0001 -#define URE_FLAG_8152 0x1000 /* RTL8152 */ +#define URE_FLAG_8152 0x0100 /* RTL8152 */ +#define URE_FLAG_8153 0x0200 /* RTL8153 */ +#define URE_FLAG_8153B 0x0400 /* RTL8153B */ +#define URE_FLAG_8156 0x0800 /* RTL8156 */ +#define URE_FLAG_8156B 0x1000 /* RTL8156B */ u_int sc_chip; u_int sc_ver; -#define URE_CHIP_VER_4C00 0x01 -#define URE_CHIP_VER_4C10 0x02 -#define URE_CHIP_VER_5C00 0x04 -#define URE_CHIP_VER_5C10 0x08 -#define URE_CHIP_VER_5C20 0x10 -#define URE_CHIP_VER_5C30 0x20 +#define URE_CHIP_VER_4C00 0x0001 +#define URE_CHIP_VER_4C10 0x0002 +#define URE_CHIP_VER_5C00 0x0004 +#define URE_CHIP_VER_5C10 0x0008 +#define URE_CHIP_VER_5C20 0x0010 +#define URE_CHIP_VER_5C30 0x0020 +#define URE_CHIP_VER_6000 0x0040 +#define URE_CHIP_VER_6010 0x0080 +#define URE_CHIP_VER_7020 0x0100 +#define URE_CHIP_VER_7030 0x0200 +#define URE_CHIP_VER_7400 0x0400 +#define URE_CHIP_VER_7410 0x0800 }; #define URE_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)