aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Petter Selasky <hselasky@FreeBSD.org>2021-06-04 08:28:58 +0000
committerHans Petter Selasky <hselasky@FreeBSD.org>2021-06-04 08:29:55 +0000
commitd4cf41a99b405c73288aea81e3c4580d1de18435 (patch)
tree173b9bd6db36004d4740dd9f6db5efaf79e6145e
parent73570795e7906ec555b37ff7e20e5d5d559ccdad (diff)
downloadsrc-d4cf41a99b405c73288aea81e3c4580d1de18435.tar.gz
src-d4cf41a99b405c73288aea81e3c4580d1de18435.zip
Add support for RTL8153B, RTL8156 and RTL8156B to if_ure(4).
Submitted by: fbbz@synack.eu PR: 253374 MFC after: 1 week Sponsored by: Mellanox Technologies // NVIDIA Networking
-rw-r--r--sys/dev/usb/net/if_ure.c965
-rw-r--r--sys/dev/usb/net/if_urereg.h200
2 files changed, 890 insertions, 275 deletions
diff --git a/sys/dev/usb/net/if_ure.c b/sys/dev/usb/net/if_ure.c
index 30fcee59cce3..2e4053a0e0c6 100644
--- a/sys/dev/usb/net/if_ure.c
+++ b/sys/dev/usb/net/if_ure.c
@@ -96,16 +96,17 @@ SYSCTL_INT(_hw_usb_ure, OID_AUTO, debug, CTLFLAG_RWTUN, &ure_debug, 0,
*/
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_2(struct ure_softc *, uint16_t, uint16_t, uint32_t);
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 int ure_attach_post_sub(struct usb_ether *);
static void ure_reset(struct ure_softc *);
static int ure_ifmedia_upd(struct ifnet *);
static void ure_ifmedia_sts(struct ifnet *, struct ifmediareq *);
-static int ure_ioctl(struct ifnet *, u_long, caddr_t);
+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 @@ static const struct usb_ether_methods ure_ue_methods = {
.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,13 @@ ure_ocp_reg_write(struct ure_softc *sc, uint16_t addr, uint16_t data)
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 +506,58 @@ ure_attach(device_t dev)
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;
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;
}
@@ -605,8 +586,8 @@ ure_detach(device_t dev)
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 +766,7 @@ tr_setup:
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,21 +876,51 @@ ure_read_chipver(struct ure_softc *sc)
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,
@@ -949,6 +960,8 @@ ure_attach_post(struct usb_ether *ue)
/* 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,7 +985,7 @@ static int
ure_attach_post_sub(struct usb_ether *ue)
{
struct sysctl_ctx_list *sctx;
- struct sysctl_oid *soid;
+ struct sysctl_oid *soid;
struct ure_softc *sc;
struct ifnet *ifp;
int error;
@@ -1001,9 +1014,19 @@ ure_attach_post_sub(struct usb_ether *ue)
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;
+ error = 0;
+ } 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 +1045,7 @@ ure_init(struct usb_ether *ue)
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 +1055,10 @@ ure_init(struct usb_ether *ue)
/* 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 +1066,50 @@ ure_init(struct usb_ether *ue)
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 +1123,9 @@ ure_init(struct usb_ether *ue)
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 +1144,31 @@ ure_tick(struct usb_ether *ue)
{
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 +1236,11 @@ ure_start(struct usb_ether *ue)
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 +1268,73 @@ static int
ure_ifmedia_upd(struct ifnet *ifp)
{
struct ure_softc *sc = ifp->if_softc;
- struct mii_data *mii = GET_MII(sc);
+ struct ifmedia *ifm;
+ struct mii_data *mii;
struct mii_softc *miisc;
+ int gig;
+ int reg;
+ int anar;
+ int locked;
int error;
- URE_LOCK_ASSERT(sc, MA_OWNED);
+ if (sc->sc_flags & (URE_FLAG_8156 | URE_FLAG_8156B)) {
+ ifm = &sc->sc_ifmedia;
+ 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 +1349,34 @@ ure_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
{
struct ure_softc *sc;
struct mii_data *mii;
+ uint16_t status;
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,6 +1386,54 @@ ure_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
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)
{
@@ -1298,8 +1498,17 @@ ure_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
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);
+ break;
}
return (error);
@@ -1310,27 +1519,18 @@ ure_rtl8152_init(struct ure_softc *sc)
{
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_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);
- 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);
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 +1540,11 @@ ure_rtl8152_init(struct ure_softc *sc)
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 +1560,7 @@ ure_rtl8153_init(struct ure_softc *sc)
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 +1587,7 @@ ure_rtl8153_init(struct ure_softc *sc)
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 +1595,10 @@ ure_rtl8153_init(struct ure_softc *sc)
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 +1609,11 @@ ure_rtl8153_init(struct ure_softc *sc)
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,12 +1630,9 @@ ure_rtl8153_init(struct ure_softc *sc)
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,
@@ -1484,17 +1661,41 @@ ure_rtl8153_init(struct ure_softc *sc)
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);
+
+ /* Enable LPF corner auto tune. */
+ ure_sram_write(sc, URE_SRAM_LPF_CFG, 0xf70f);
- ure_init_fifo(sc);
+ /* 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 +1710,266 @@ ure_rtl8153_init(struct ure_softc *sc)
}
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,90 +1984,93 @@ ure_stop(struct usb_ether *ue)
/*
* 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]);
- }
}
static void
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);
-
- ure_disable_teredo(sc);
+ 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;
+ }
+ }
+}
- 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);
+static uint16_t
+ure_phy_status(struct ure_softc *sc, uint16_t desired)
+{
+ uint16_t val;
+ int i;
- 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);
+ 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;
}
- 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);
-
- /* 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);
-
- /* 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);
+ 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");
+
+ return (val);
+}
+
+static void
+ure_rtl8152_nic_reset(struct ure_softc *sc)
+{
+ uint32_t rx_fifo1, rx_fifo2;
+ int i;
+
+ URE_SETBIT_2(sc, URE_PLA_MISC_1, URE_MCU_TYPE_PLA, URE_RXDY_GATED_EN);
+
+ 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 +2080,7 @@ ure_init_fifo(struct ure_softc *sc)
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 +2091,9 @@ ure_init_fifo(struct ure_softc *sc)
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,
diff --git a/sys/dev/usb/net/if_urereg.h b/sys/dev/usb/net/if_urereg.h
index 6b6f99434313..afd378762e85 100644
--- a/sys/dev/usb/net/if_urereg.h
+++ b/sys/dev/usb/net/if_urereg.h
@@ -26,6 +26,9 @@
* $FreeBSD$
*/
+#ifndef _IF_UREREG_H_
+#define _IF_UREREG_H_
+
#define URE_CONFIG_IDX 0 /* config number 1 */
#define URE_IFACE_IDX 0
@@ -40,7 +43,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 +64,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 +83,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 +96,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,22 +116,52 @@
#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
@@ -130,13 +181,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 +246,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 +289,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 +310,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 +346,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 +386,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 +396,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 +433,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 +469,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 +484,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,44 +559,64 @@ struct ure_txpkt {
#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)
#define URE_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
#define URE_LOCK_ASSERT(_sc, t) mtx_assert(&(_sc)->sc_mtx, t)
+
+#endif /* _IF_UREREG_H_ */