diff options
author | Marcus Glocker <mglocker@cvs.openbsd.org> | 2021-08-05 20:53:29 +0000 |
---|---|---|
committer | Marcus Glocker <mglocker@cvs.openbsd.org> | 2021-08-05 20:53:29 +0000 |
commit | b3744ca7ef36cb96e1ee8a71877c00f0d7572ff6 (patch) | |
tree | 6ca15577b3caa257a93110ba2a4a2e2ce373e41e /sys | |
parent | 6aabec409dbe85b0f8abe1961db2cb47f997ea1e (diff) |
After a media link change, the media settings on the hardware need to be
re-initialized, otherwise TX/RX keeps disabled. Fixes the issue on the
RTL8153/B devices, but unfortunately not on the RTL8152 devices. I have
no RTL8152 device available.
Tested by a few on RTL8153/B devices.
ok sthen@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/usb/if_ure.c | 119 |
1 files changed, 68 insertions, 51 deletions
diff --git a/sys/dev/usb/if_ure.c b/sys/dev/usb/if_ure.c index 2bde9f36443..ea73db00954 100644 --- a/sys/dev/usb/if_ure.c +++ b/sys/dev/usb/if_ure.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ure.c,v 1.24 2021/04/15 02:23:17 kevlo Exp $ */ +/* $OpenBSD: if_ure.c,v 1.25 2021/08/05 20:53:28 mglocker Exp $ */ /*- * Copyright (c) 2015, 2016, 2019 Kevin Lo <kevlo@openbsd.org> * Copyright (c) 2020 Jonathon Fletcher <jonathon.fletcher@gmail.com> @@ -183,6 +183,7 @@ void ure_xfer_list_free(struct ure_softc *, struct ure_chain *, int); void ure_tick_task(void *); void ure_tick(void *); +void ure_ifmedia_init(struct ifnet *); int ure_ifmedia_upd(struct ifnet *); void ure_ifmedia_sts(struct ifnet *, struct ifmediareq *); void ure_add_media_types(struct ure_softc *); @@ -435,6 +436,70 @@ ure_miibus_statchg(struct device *dev) /* Lost link, do nothing. */ if ((sc->ure_flags & URE_FLAG_LINK) == 0) return; + + /* + * After a link change the media settings are getting reset on the + * hardware, and need to be re-initialized again for communication + * to continue work. + */ + ure_ifmedia_init(ifp); +} + +void +ure_ifmedia_init(struct ifnet *ifp) +{ + struct ure_softc *sc = ifp->if_softc; + uint32_t reg = 0; + + /* Set MAC address. */ + ure_write_1(sc, URE_PLA_CRWECR, URE_MCU_TYPE_PLA, URE_CRWECR_CONFIG); + ure_write_mem(sc, URE_PLA_IDR, URE_MCU_TYPE_PLA | URE_BYTE_EN_SIX_BYTES, + sc->ure_ac.ac_enaddr, 8); + ure_write_1(sc, URE_PLA_CRWECR, URE_MCU_TYPE_PLA, URE_CRWECR_NORAML); + + if (!(sc->ure_flags & URE_FLAG_8152)) { + reg = sc->ure_rxbufsz - URE_FRAMELEN(ifp->if_mtu) - + sizeof(struct ure_rxpkt) - URE_RX_BUF_ALIGN; + if (sc->ure_flags & (URE_FLAG_8153B | URE_FLAG_8156)) { + ure_write_2(sc, URE_USB_RX_EARLY_SIZE, URE_MCU_TYPE_USB, + reg / 8); + + ure_write_2(sc, URE_USB_RX_EARLY_AGG, URE_MCU_TYPE_USB, + (sc->ure_flags & URE_FLAG_8153B) ? 16 : 80); + ure_write_2(sc, URE_USB_PM_CTRL_STATUS, + URE_MCU_TYPE_USB, 1875); + } else { + ure_write_2(sc, URE_USB_RX_EARLY_SIZE, URE_MCU_TYPE_USB, + reg / 4); + switch (sc->ure_udev->speed) { + 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); + } + } + + /* Reset the packet filter. */ + 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 transmit and receive. */ + 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_write_1(sc, URE_USB_UPT_RXDMA_OWN, URE_MCU_TYPE_USB, + URE_OWN_UPDATE | URE_OWN_CLEAR); + } + + URE_CLRBIT_2(sc, URE_PLA_MISC_1, URE_MCU_TYPE_PLA, URE_RXDY_GATED_EN); } int @@ -721,7 +786,6 @@ ure_init(void *xsc) struct ure_chain *c; struct ifnet *ifp = &sc->ure_ac.ac_if; usbd_status err; - uint32_t reg = 0; int s, i; s = splnet(); @@ -754,55 +818,8 @@ ure_init(void *xsc) SLIST_INSERT_HEAD(&sc->ure_cdata.ure_tx_free, &sc->ure_cdata.ure_tx_chain[i], uc_list); - /* Set MAC address. */ - ure_write_1(sc, URE_PLA_CRWECR, URE_MCU_TYPE_PLA, URE_CRWECR_CONFIG); - ure_write_mem(sc, URE_PLA_IDR, URE_MCU_TYPE_PLA | URE_BYTE_EN_SIX_BYTES, - sc->ure_ac.ac_enaddr, 8); - ure_write_1(sc, URE_PLA_CRWECR, URE_MCU_TYPE_PLA, URE_CRWECR_NORAML); - - if (!(sc->ure_flags & URE_FLAG_8152)) { - reg = sc->ure_rxbufsz - URE_FRAMELEN(ifp->if_mtu) - - sizeof(struct ure_rxpkt) - URE_RX_BUF_ALIGN; - if (sc->ure_flags & (URE_FLAG_8153B | URE_FLAG_8156)) { - ure_write_2(sc, URE_USB_RX_EARLY_SIZE, URE_MCU_TYPE_USB, - reg / 8); - - ure_write_2(sc, URE_USB_RX_EARLY_AGG, URE_MCU_TYPE_USB, - (sc->ure_flags & URE_FLAG_8153B) ? 16 : 80); - ure_write_2(sc, URE_USB_PM_CTRL_STATUS, - URE_MCU_TYPE_USB, 1875); - } else { - ure_write_2(sc, URE_USB_RX_EARLY_SIZE, URE_MCU_TYPE_USB, - reg / 4); - switch (sc->ure_udev->speed) { - 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); - } - } - - /* Reset the packet filter. */ - 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 transmit and receive. */ - 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_write_1(sc, URE_USB_UPT_RXDMA_OWN, URE_MCU_TYPE_USB, - URE_OWN_UPDATE | URE_OWN_CLEAR); - } - - URE_CLRBIT_2(sc, URE_PLA_MISC_1, URE_MCU_TYPE_PLA, URE_RXDY_GATED_EN); + /* Setup MAC address, and enable TX/RX. */ + ure_ifmedia_init(ifp); /* Load the multicast filter. */ ure_iff(sc); |