summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/mii/rgephy.c8
-rw-r--r--sys/dev/usb/if_ure.c266
-rw-r--r--sys/dev/usb/if_urereg.h10
3 files changed, 250 insertions, 34 deletions
diff --git a/sys/dev/mii/rgephy.c b/sys/dev/mii/rgephy.c
index ab0e7c7c687..b4c95d078fa 100644
--- a/sys/dev/mii/rgephy.c
+++ b/sys/dev/mii/rgephy.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rgephy.c,v 1.38 2015/07/19 06:35:18 yuo Exp $ */
+/* $OpenBSD: rgephy.c,v 1.39 2017/03/11 13:40:46 kettenis Exp $ */
/*
* Copyright (c) 2003
* Bill Paul <wpaul@windriver.com>. All rights reserved.
@@ -249,7 +249,7 @@ setit:
* need to restart the autonegotiation process. Read
* the BMSR twice in case it's latched.
*/
- if (strcmp(devname, "re") == 0) {
+ if (strcmp(devname, "re") == 0 || strcmp(devname, "ure") == 0) {
reg = PHY_READ(sc, RL_GMEDIASTAT);
if (reg & RL_GMEDIASTAT_LINK) {
sc->mii_ticks = 0;
@@ -305,7 +305,7 @@ rgephy_status(struct mii_softc *sc)
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
- if (strcmp(devname, "re") == 0) {
+ if (strcmp(devname, "re") == 0 || strcmp(devname, "ure") == 0) {
bmsr = PHY_READ(sc, RL_GMEDIASTAT);
if (bmsr & RL_GMEDIASTAT_LINK)
mii->mii_media_status |= IFM_ACTIVE;
@@ -330,7 +330,7 @@ rgephy_status(struct mii_softc *sc)
}
}
- if (strcmp(devname, "re") == 0) {
+ if (strcmp(devname, "re") == 0 || strcmp(devname, "ure") == 0) {
bmsr = PHY_READ(sc, RL_GMEDIASTAT);
if (bmsr & RL_GMEDIASTAT_1000MBPS)
mii->mii_media_active |= IFM_1000_T;
diff --git a/sys/dev/usb/if_ure.c b/sys/dev/usb/if_ure.c
index 5e6ec3a659a..a9b6b480d12 100644
--- a/sys/dev/usb/if_ure.c
+++ b/sys/dev/usb/if_ure.c
@@ -1,6 +1,6 @@
-/* $OpenBSD: if_ure.c,v 1.3 2017/01/22 10:17:39 dlg Exp $ */
+/* $OpenBSD: if_ure.c,v 1.4 2017/03/11 13:40:46 kettenis Exp $ */
/*-
- * Copyright (c) 2015 Kevin Lo <kevlo@FreeBSD.org>
+ * Copyright (c) 2015-2016 Kevin Lo <kevlo@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -58,7 +58,8 @@
#include <dev/usb/usbdivar.h>
#include <dev/usb/usbdevs.h>
-#include "if_urereg.h"
+#include <dev/ic/rtl81x9reg.h>
+#include <dev/usb/if_urereg.h>
#ifdef URE_DEBUG
#define DPRINTF(x) do { if (uredebug) printf x; } while (0)
@@ -69,9 +70,9 @@ int uredebug = 0;
#define DPRINTFN(n,x)
#endif
-
const struct usb_devno ure_devs[] = {
- { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8152 }
+ { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8152 },
+ { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8153 }
};
int ure_match(struct device *, void *, void *);
@@ -126,6 +127,7 @@ int ure_ifmedia_upd(struct ifnet *);
void ure_ifmedia_sts(struct ifnet *, struct ifmediareq *);
int ure_ioctl(struct ifnet *, u_long, caddr_t);
void ure_rtl8152_init(struct ure_softc *);
+void ure_rtl8153_init(struct ure_softc *);
void ure_disable_teredo(struct ure_softc *);
void ure_init_fifo(struct ure_softc *);
@@ -302,6 +304,10 @@ ure_miibus_readreg(struct device *dev, int phy, int reg)
if (usbd_is_dying(sc->ure_udev))
return 0;
+ /* Let the rgephy driver read the URE_PLA_PHYSTATUS register. */
+ if (reg == RL_GMEDIASTAT)
+ return ure_read_1(sc, URE_PLA_PHYSTATUS, URE_MCU_TYPE_PLA);
+
ure_lock_mii(sc);
val = ure_ocp_reg_read(sc, URE_OCP_BASE_MII + reg * 2);
ure_unlock_mii(sc);
@@ -337,6 +343,11 @@ ure_miibus_statchg(struct device *dev)
case IFM_100_TX:
sc->ure_flags |= URE_FLAG_LINK;
break;
+ case IFM_1000_T:
+ if ((sc->ure_flags & URE_FLAG_8152) != 0)
+ break;
+ sc->ure_flags |= URE_FLAG_LINK;
+ break;
default:
break;
}
@@ -389,7 +400,9 @@ ure_iff(struct ure_softc *sc)
return;
ifp->if_flags &= ~IFF_ALLMULTI;
- rxmode = ure_read_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA);
+ rxmode = URE_RCR_APM;
+ if (ifp->if_flags & IFF_BROADCAST)
+ rxmode |= URE_RCR_AB;
if (ifp->if_flags & IFF_PROMISC || sc->ure_ac.ac_multirangecnt > 0) {
ifp->if_flags |= IFF_ALLMULTI;
if (ifp->if_flags & IFF_PROMISC)
@@ -443,7 +456,6 @@ ure_init(void *xsc)
struct ure_softc *sc = xsc;
struct ure_chain *c;
struct ifnet *ifp = &sc->ure_ac.ac_if;
- uint32_t rxmode;
usbd_status err;
int s, i;
@@ -487,18 +499,6 @@ ure_init(void *xsc)
ure_read_2(sc, URE_PLA_MISC_1, URE_MCU_TYPE_PLA) &
~URE_RXDY_GATED_EN);
- /* Set Rx mode. */
- rxmode = URE_RCR_APM;
-
- /* If we want promiscuous mode, set the allframes bit. */
- if (ifp->if_flags & IFF_PROMISC)
- rxmode |= URE_RCR_AAP;
-
- if (ifp->if_flags & IFF_BROADCAST)
- rxmode |= URE_RCR_AB;
-
- ure_write_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA, rxmode);
-
/* Load the multicast filter. */
ure_iff(sc);
@@ -697,6 +697,156 @@ ure_rtl8152_init(struct ure_softc *sc)
}
void
+ure_rtl8153_init(struct ure_softc *sc)
+{
+ uint16_t val;
+ 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);
+ usbd_delay_ms(sc->ure_udev, 20);
+
+ memset(u1u2, 0x00, sizeof(u1u2));
+ ure_write_mem(sc, URE_USB_TOLERANCE,
+ URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2));
+
+ for (i = 0; i < URE_TIMEOUT; i++) {
+ if (ure_read_2(sc, URE_PLA_BOOT_CTRL, URE_MCU_TYPE_PLA) &
+ URE_AUTOLOAD_DONE)
+ break;
+ usbd_delay_ms(sc->ure_udev, 10);
+ }
+ if (i == URE_TIMEOUT)
+ printf("%s: timeout waiting for chip autoload\n",
+ sc->ure_dev.dv_xname);
+
+ for (i = 0; i < URE_TIMEOUT; i++) {
+ val = ure_ocp_reg_read(sc, URE_OCP_PHY_STATUS) &
+ URE_PHY_STAT_MASK;
+ if (val == URE_PHY_STAT_LAN_ON || val == URE_PHY_STAT_PWRDN)
+ break;
+ usbd_delay_ms(sc->ure_udev, 10);
+ }
+ if (i == URE_TIMEOUT)
+ printf("%s: timeout waiting for phy to stabilize\n",
+ sc->ure_dev.dv_xname);
+
+ 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);
+
+ if (sc->ure_chip & URE_CHIP_VER_5C10) {
+ val = ure_read_2(sc, URE_USB_SSPHYLINK2, URE_MCU_TYPE_USB);
+ val &= ~URE_PWD_DN_SCALE_MASK;
+ 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->ure_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);
+ }
+ if (sc->ure_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) ==
+ 0)
+ val &= ~URE_DYNAMIC_BURST;
+ else
+ val |= URE_DYNAMIC_BURST;
+ 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_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_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);
+
+ if ((sc->ure_chip & URE_CHIP_VER_5C10) &&
+ sc->ure_udev->speed != USB_SPEED_SUPER)
+ val = URE_LPM_TIMER_500MS;
+ else
+ val = URE_LPM_TIMER_500US;
+ ure_write_1(sc, URE_USB_LPM_CTRL, URE_MCU_TYPE_USB,
+ val | URE_FIFO_EMPTY_1FB | URE_ROK_EXIT_LPM);
+
+ val = ure_read_2(sc, URE_USB_AFE_CTRL2, URE_MCU_TYPE_USB);
+ val &= ~URE_SEN_VAL_MASK;
+ val |= URE_SEN_VAL_NORMAL | URE_SEL_RXIDLE;
+ ure_write_2(sc, URE_USB_AFE_CTRL2, URE_MCU_TYPE_USB, val);
+
+ 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);
+
+ memset(u1u2, 0xff, sizeof(u1u2));
+ ure_write_mem(sc, URE_USB_TOLERANCE,
+ URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2));
+
+ ure_write_2(sc, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA,
+ URE_ALDPS_SPDWN_RATIO);
+ ure_write_2(sc, URE_PLA_MAC_PWR_CTRL2, URE_MCU_TYPE_PLA,
+ URE_EEE_SPDWN_RATIO);
+ ure_write_2(sc, URE_PLA_MAC_PWR_CTRL3, URE_MCU_TYPE_PLA,
+ URE_PKT_AVAIL_SPDWN_EN | URE_SUSPEND_SPDWN_EN |
+ URE_U1U2_SPDWN_EN | URE_L1_SPDWN_EN);
+ ure_write_2(sc, URE_PLA_MAC_PWR_CTRL4, URE_MCU_TYPE_PLA,
+ URE_PWRSAVE_SPDWN_EN | URE_RXDV_SPDWN_EN | URE_TX10MIDLE_EN |
+ URE_TP100_SPDWN_EN | URE_TP500_SPDWN_EN | URE_TP1000_SPDWN_EN |
+ URE_EEE_SPDWN_EN);
+
+ val = ure_read_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB);
+ if (!(sc->ure_chip & (URE_CHIP_VER_5C00 | URE_CHIP_VER_5C10)))
+ val |= URE_U2P3_ENABLE;
+ else
+ val &= ~URE_U2P3_ENABLE;
+ ure_write_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, val);
+
+ memset(u1u2, 0x00, sizeof(u1u2));
+ ure_write_mem(sc, URE_USB_TOLERANCE,
+ URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2));
+
+ /* Disable ALDPS. */
+ ure_ocp_reg_write(sc, URE_OCP_POWER_CFG,
+ ure_ocp_reg_read(sc, URE_OCP_POWER_CFG) & ~URE_EN_ALDPS);
+ usbd_delay_ms(sc->ure_udev, 20);
+
+ ure_init_fifo(sc);
+
+ /* Disable 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);
+
+ val = ure_read_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB);
+ if (!(sc->ure_chip & (URE_CHIP_VER_5C00 | URE_CHIP_VER_5C10)))
+ val |= URE_U2P3_ENABLE;
+ else
+ val &= ~URE_U2P3_ENABLE;
+ ure_write_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, val);
+
+ memset(u1u2, 0xff, sizeof(u1u2));
+ ure_write_mem(sc, URE_USB_TOLERANCE,
+ URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2));
+}
+
+void
ure_disable_teredo(struct ure_softc *sc)
{
ure_write_4(sc, URE_PLA_TEREDO_CFG, URE_MCU_TYPE_PLA,
@@ -724,6 +874,43 @@ ure_init_fifo(struct ure_softc *sc)
ure_read_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA) &
~URE_RCR_ACPT_ALL);
+ if (!(sc->ure_flags & URE_FLAG_8152)) {
+ if (sc->ure_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->ure_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);
+
+ /* 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);
+ }
+
ure_reset(sc);
ure_write_1(sc, URE_PLA_CR, URE_MCU_TYPE_PLA, 0);
@@ -742,7 +929,7 @@ ure_init_fifo(struct ure_softc *sc)
usbd_delay_ms(sc->ure_udev, 10);
}
if (i == URE_TIMEOUT)
- printf("%s timeout waiting for OOB control\n",
+ printf("%s: timeout waiting for OOB control\n",
sc->ure_dev.dv_xname);
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) |
@@ -864,6 +1051,9 @@ ure_attach(struct device *parent, struct device *self, void *aux)
sc->ure_udev = uaa->device;
sc->ure_iface = uaa->iface;
+ if (uaa->product == USB_PRODUCT_REALTEK_RTL8152)
+ sc->ure_flags |= URE_FLAG_8152;
+
usb_init_task(&sc->ure_tick_task, ure_tick_task, sc,
USB_TASK_TYPE_GENERIC);
rw_init(&sc->ure_mii_lock, "uremii");
@@ -899,15 +1089,27 @@ ure_attach(struct device *parent, struct device *self, void *aux)
switch (ver) {
case 0x4c00:
sc->ure_chip |= URE_CHIP_VER_4C00;
- ure_read_mem(sc, URE_PLA_IDR, URE_MCU_TYPE_PLA, eaddr,
- sizeof(eaddr));
printf("ver 4c00");
break;
case 0x4c10:
sc->ure_chip |= URE_CHIP_VER_4C10;
- ure_read_mem(sc, URE_PLA_BACKUP, URE_MCU_TYPE_PLA, eaddr,
- sizeof(eaddr));
- printf("ver 4c01");
+ printf("ver 4c10");
+ break;
+ case 0x5c00:
+ sc->ure_chip |= URE_CHIP_VER_5C00;
+ printf("ver 5c00");
+ break;
+ case 0x5c10:
+ sc->ure_chip |= URE_CHIP_VER_5C10;
+ printf("ver 5c10");
+ break;
+ case 0x5c20:
+ sc->ure_chip |= URE_CHIP_VER_5C20;
+ printf("ver 5c20");
+ break;
+ case 0x5c30:
+ sc->ure_chip |= URE_CHIP_VER_5C30;
+ printf("ver 5c30");
break;
default:
printf(", unknown ver %02x", ver);
@@ -915,12 +1117,22 @@ ure_attach(struct device *parent, struct device *self, void *aux)
break;
}
+ if (sc->ure_flags & URE_FLAG_8152)
+ ure_rtl8152_init(sc);
+ else
+ ure_rtl8153_init(sc);
+
+ if (sc->ure_chip & URE_CHIP_VER_4C00)
+ ure_read_mem(sc, URE_PLA_IDR, URE_MCU_TYPE_PLA, eaddr,
+ sizeof(eaddr));
+ else
+ ure_read_mem(sc, URE_PLA_BACKUP, URE_MCU_TYPE_PLA, eaddr,
+ sizeof(eaddr));
+
printf(", address %s\n", ether_sprintf(eaddr));
bcopy(eaddr, (char *)&sc->ure_ac.ac_enaddr, ETHER_ADDR_LEN);
- ure_rtl8152_init(sc);
-
ifp = &sc->ure_ac.ac_if;
ifp->if_softc = sc;
strlcpy(ifp->if_xname, sc->ure_dev.dv_xname, IFNAMSIZ);
diff --git a/sys/dev/usb/if_urereg.h b/sys/dev/usb/if_urereg.h
index 8f885c8cabf..2260ec37890 100644
--- a/sys/dev/usb/if_urereg.h
+++ b/sys/dev/usb/if_urereg.h
@@ -1,6 +1,6 @@
-/* $OpenBSD: if_urereg.h,v 1.2 2016/08/07 00:21:57 jmatthew Exp $ */
+/* $OpenBSD: if_urereg.h,v 1.3 2017/03/11 13:40:46 kettenis Exp $ */
/*-
- * Copyright (c) 2015 Kevin Lo <kevlo@FreeBSD.org>
+ * Copyright (c) 2015-2016 Kevin Lo <kevlo@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -462,9 +462,13 @@ struct ure_softc {
u_int ure_flags;
#define URE_FLAG_LINK 0x0001
+#define URE_FLAG_8152 0x1000 /* RTL8152 */
u_int ure_chip;
#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
};
-