On Tue, Dec 3, 2019 at 5:24 PM Kevin Lo <ke...@kevlo.org> wrote:

> Hi,
>
> This diff adds preliminary support for RTL8156 to ure(4).
> Tested with the Planex USB-LAN2500R.
>
> Index: share/man/man4/ure.4
> ===================================================================
> RCS file: /cvs/src/share/man/man4/ure.4,v
> retrieving revision 1.6
> diff -u -p -u -p -r1.6 ure.4
> --- share/man/man4/ure.4        29 Aug 2019 08:55:05 -0000      1.6
> +++ share/man/man4/ure.4        3 Dec 2019 08:29:40 -0000
> @@ -31,7 +31,7 @@
>  .Os
>  .Sh NAME
>  .Nm ure
> -.Nd RealTek RTL8152/RTL8153/RTL8153B 10/100/Gigabit USB Ethernet device
> +.Nd RealTek RTL8152/RTL8153/RTL8153B/RTL8156 10/100/Gigabit/2.5Gb USB
> Ethernet device
>  .Sh SYNOPSIS
>  .Cd "ure*   at uhub?"
>  .Cd "rgephy* at mii?"
> @@ -40,12 +40,13 @@
>  The
>  .Nm
>  driver provides support for USB Ethernet adapters based on the RealTek
> -RTL8152, RTL8153 and RTL8153B chipsets.
> +RTL8152, RTL8153, RTL8153B and RTL8156 chipsets.
>  .Pp
>  The RTL8152 contains an integrated Fast Ethernet MAC, which supports
>  both 10 and 100Mbps speeds in either full or half duplex.
>  The RTL8153 and RTL8153B have Gigabit Ethernet MACs and additionally
>  support 1000Mbps speeds.
> +NICs based on the RTL8156 are capable of 10, 100, 1000 and 2500Mbps
> operation.
>  .Pp
>  For more information on configuring this device, see
>  .Xr ifconfig 8 .
> Index: share/man/man4/usb.4
> ===================================================================
> RCS file: /cvs/src/share/man/man4/usb.4,v
> retrieving revision 1.197
> diff -u -p -u -p -r1.197 usb.4
> --- share/man/man4/usb.4        29 Aug 2019 08:55:05 -0000      1.197
> +++ share/man/man4/usb.4        3 Dec 2019 08:29:40 -0000
> @@ -128,7 +128,7 @@ SMSC LAN95xx 10/100 USB Ethernet device
>  .It Xr udav 4
>  Davicom DM9601 10/100 USB Ethernet device
>  .It Xr ure 4
> -RealTek RTL8152/RTL8153/RTL8153B 10/100/Gigabit USB Ethernet device
> +RealTek RTL8152/RTL8153/RTL8153B/RTL8156 10/100/Gigabit/2.5Gb USB
> Ethernet device
>  .It Xr url 4
>  Realtek RTL8150L 10/100 USB Ethernet device
>  .It Xr urndis 4
> Index: sys/dev/usb/if_ure.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/usb/if_ure.c,v
> retrieving revision 1.12
> diff -u -p -u -p -r1.12 if_ure.c
> --- sys/dev/usb/if_ure.c        29 Aug 2019 14:04:48 -0000      1.12
> +++ sys/dev/usb/if_ure.c        3 Dec 2019 08:29:41 -0000
> @@ -50,6 +50,7 @@
>  #include <netinet/in.h>
>  #include <netinet/if_ether.h>
>
> +#include <dev/mii/mii.h>
>  #include <dev/mii/miivar.h>
>
>  #include <dev/usb/usb.h>
> @@ -73,7 +74,8 @@ int   uredebug = 0;
>  const struct usb_devno ure_devs[] = {
>         { USB_VENDOR_LENOVO, USB_PRODUCT_LENOVO_DOCK_ETHERNET },
>         { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8152 },
> -       { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8153 }
> +       { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8153 },
> +       { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8156 }
>  };
>
>  int    ure_match(struct device *, void *, void *);
> @@ -107,6 +109,7 @@ void                ure_init(void *);
>  void           ure_stop(struct ure_softc *);
>  void           ure_start(struct ifnet *);
>  void           ure_reset(struct ure_softc *);
> +void           ure_watchdog(struct ifnet *);
>
>  void           ure_miibus_statchg(struct device *);
>  int            ure_miibus_readreg(struct device *, int, int);
> @@ -125,6 +128,9 @@ void                ure_tick(void *);
>
>  int            ure_ifmedia_upd(struct ifnet *);
>  void           ure_ifmedia_sts(struct ifnet *, struct ifmediareq *);
> +void           ure_add_media_types(struct ure_softc *);
> +void           ure_link_state(struct ure_softc *);
> +int            ure_get_link_status(struct ure_softc *);
>  void           ure_iff(struct ure_softc *);
>  void           ure_rxvlan(struct ure_softc *);
>  int            ure_ioctl(struct ifnet *, u_long, caddr_t);
> @@ -379,7 +385,57 @@ ure_ifmedia_upd(struct ifnet *ifp)
>  {
>         struct ure_softc        *sc = ifp->if_softc;
>         struct mii_data         *mii = &sc->ure_mii;
> -       int                     err;
> +       struct ifmedia          *ifm = &sc->ure_ifmedia;
> +       int                     anar, gig, err, reg;
> +
> +       if (sc->ure_flags & URE_FLAG_8156) {
> +               if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
> +                       return (EINVAL);
> +
> +               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:
> +                       printf("%s: unsupported media type\n",
> +                           sc->ure_dev.dv_xname);
> +                       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);
> +
> +               return (0);
> +       }
>
>         if (mii->mii_instance) {
>                 struct mii_softc *miisc;
> @@ -399,6 +455,30 @@ ure_ifmedia_sts(struct ifnet *ifp, struc
>  {
>         struct ure_softc        *sc = ifp->if_softc;
>         struct mii_data         *mii = &sc->ure_mii;
> +       uint16_t                status = 0;
> +
> +       if (sc->ure_flags & URE_FLAG_8156) {
> +               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;
> +               }
> +               return;
> +       }
>
>         mii_pollstat(mii);
>         ifmr->ifm_active = mii->mii_media_active;
> @@ -406,6 +486,50 @@ ure_ifmedia_sts(struct ifnet *ifp, struc
>  }
>
>  void
> +ure_add_media_types(struct ure_softc *sc)
> +{
> +       ifmedia_add(&sc->ure_ifmedia, IFM_ETHER | IFM_10_T, 0, NULL);
> +       ifmedia_add(&sc->ure_ifmedia, IFM_ETHER | IFM_10_T | IFM_FDX, 0,
> NULL);
> +       ifmedia_add(&sc->ure_ifmedia, IFM_ETHER | IFM_100_TX, 0, NULL);
> +       ifmedia_add(&sc->ure_ifmedia, IFM_ETHER | IFM_100_TX | IFM_FDX, 0,
> +           NULL);
> +       ifmedia_add(&sc->ure_ifmedia, IFM_ETHER | IFM_1000_T, 0, NULL);
> +       ifmedia_add(&sc->ure_ifmedia, IFM_ETHER | IFM_1000_T | IFM_FDX, 0,
> +           NULL);
> +       ifmedia_add(&sc->ure_ifmedia, IFM_ETHER | IFM_2500_T, 0, NULL);
> +       ifmedia_add(&sc->ure_ifmedia, IFM_ETHER | IFM_2500_T | IFM_FDX, 0,
> +           NULL);
> +}
> +
> +void
> +ure_link_state(struct ure_softc *sc)
> +{
> +       struct ifnet    *ifp = &sc->ure_ac.ac_if;
> +       int             link = LINK_STATE_DOWN;
> +
> +       if (ure_get_link_status(sc))
> +               link = LINK_STATE_UP;
> +
> +       if (ifp->if_link_state != link) {
> +               ifp->if_link_state = link;
> +               if_link_state_change(ifp);
> +       }
> +}
> +
> +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->ure_flags |= URE_FLAG_LINK;
> +               return (1);
> +       } else {
> +               sc->ure_flags &= ~URE_FLAG_LINK;
> +               return (0);
> +       }
> +}
> +
> +void
>  ure_iff(struct ure_softc *sc)
>  {
>         struct ifnet            *ifp = &sc->ure_ac.ac_if;
> @@ -465,11 +589,19 @@ ure_rxvlan(struct ure_softc *sc)
>         struct ifnet    *ifp = &sc->ure_ac.ac_if;
>         uint16_t        reg;
>
> -       reg = ure_read_2(sc, URE_PLA_CPCR, URE_MCU_TYPE_PLA);
> -       reg &= ~URE_CPCR_RX_VLAN;
> -       if (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING)
> -               reg |= URE_CPCR_RX_VLAN;
> -       ure_write_2(sc, URE_PLA_CPCR, URE_MCU_TYPE_PLA, reg);
> +       if (sc->ure_flags & URE_FLAG_8156) {
> +               reg = ure_read_2(sc, 0xc012, URE_MCU_TYPE_PLA);
> +               reg &= ~0x00c0;
> +               if (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING)
> +                       reg |= 0x00c0;
> +               ure_write_2(sc, 0xc012, URE_MCU_TYPE_PLA, reg);
> +       } else {
> +               reg = ure_read_2(sc, URE_PLA_CPCR, URE_MCU_TYPE_PLA);
> +               reg &= ~URE_CPCR_RX_VLAN;
> +               if (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING)
> +                       reg |= URE_CPCR_RX_VLAN;
> +               ure_write_2(sc, URE_PLA_CPCR, URE_MCU_TYPE_PLA, reg);
> +       }
>  }
>
>  void
> @@ -490,6 +622,27 @@ ure_reset(struct ure_softc *sc)
>  }
>
>  void
> +ure_watchdog(struct ifnet *ifp)
> +{
> +       struct ure_softc        *sc = ifp->if_softc;
> +       struct ure_chain        *c;
> +       usbd_status             stat;
> +       int                     s;
> +
> +       ifp->if_oerrors++;
> +       printf("%s: watchdog timeout\n", sc->ure_dev.dv_xname);
> +
> +       s = splusb();
> +       c = &sc->ure_cdata.tx_chain[0];
> +       usbd_get_xfer_status(c->uc_xfer, NULL, NULL, NULL, &stat);
> +       ure_txeof(c->uc_xfer, c, stat);
> +
> +       if (!IFQ_IS_EMPTY(&ifp->if_snd))
> +               ure_start(ifp);
> +       splx(s);
> +}
> +
> +void
>  ure_init(void *xsc)
>  {
>         struct ure_softc        *sc = xsc;
> @@ -528,16 +681,16 @@ ure_init(void *xsc)
>         ure_write_1(sc, URE_PLA_CRWECR, URE_MCU_TYPE_PLA,
> URE_CRWECR_NORAML);
>
>         if (!(sc->ure_flags & URE_FLAG_8152)) {
> -               reg = URE_BUFSZ - URE_FRAMELEN(ifp->if_mtu) -
> -                   sizeof(struct ure_rxpkt) - URE_RX_BUF_ALIGN;
> -               if (sc->ure_flags & URE_FLAG_8153B) {
> +               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,
> -                           16);
> +                           (sc->ure_flags & URE_FLAG_8153B) ? 16 : 80);
>                         ure_write_2(sc, URE_USB_PM_CTRL_STATUS,
> -                           URE_MCU_TYPE_USB, 15000);
> +                           URE_MCU_TYPE_USB, 1875);
>                 } else {
>                         ure_write_2(sc, URE_USB_RX_EARLY_SIZE,
> URE_MCU_TYPE_USB,
>                             reg / 4);
> @@ -564,7 +717,7 @@ ure_init(void *xsc)
>         /* 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) {
> +       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);
>         }
> @@ -597,12 +750,14 @@ ure_init(void *xsc)
>         for (i = 0; i < URE_RX_LIST_CNT; i++) {
>                 c = &sc->ure_cdata.rx_chain[i];
>                 usbd_setup_xfer(c->uc_xfer, sc->ure_ep[URE_ENDPT_RX],
> -                   c, c->uc_buf, sc->ure_bufsz,
> +                   c, c->uc_buf, sc->ure_rxbufsz,
>                     USBD_SHORT_XFER_OK | USBD_NO_COPY,
>                     USBD_NO_TIMEOUT, ure_rxeof);
>                 usbd_transfer(c->uc_xfer);
>         }
>
> +       ure_ifmedia_upd(ifp);
> +
>         /* Indicate we are up and running. */
>         sc->ure_flags &= ~URE_FLAG_LINK;
>         ifp->if_flags |= IFF_RUNNING;
> @@ -617,30 +772,41 @@ void
>  ure_start(struct ifnet *ifp)
>  {
>         struct ure_softc        *sc = ifp->if_softc;
> +       struct ure_cdata        *cd = &sc->ure_cdata;
>         struct mbuf             *m_head = NULL;
> +       int                     idx;
>
>         if ((sc->ure_flags & URE_FLAG_LINK) == 0 ||
>             ifq_is_oactive(&ifp->if_snd)) {
>                 return;
>         }
>
> -       m_head = ifq_deq_begin(&ifp->if_snd);
> -       if (m_head == NULL) {
> -               return;
> -       }
> +       idx = cd->tx_prod;
>
> -       if (ure_encap(sc, m_head, 0)) {
> -               ifq_deq_rollback(&ifp->if_snd, m_head);
> -               ifq_set_oactive(&ifp->if_snd);
> -               return;
> -       }
> -       ifq_deq_commit(&ifp->if_snd, m_head);
> +       while (cd->tx_cnt < URE_TX_LIST_CNT) {
> +               m_head = ifq_deq_begin(&ifp->if_snd);
> +               if (m_head == NULL)
> +                       break;
> +
> +               if (ure_encap(sc, m_head, idx)) {
> +                       ifq_deq_rollback(&ifp->if_snd, m_head);
> +                       ifq_set_oactive(&ifp->if_snd);
> +                       break;
> +               }
> +               ifq_deq_commit(&ifp->if_snd, m_head);
>
>  #if NBPFILTER > 0
> -       if (ifp->if_bpf)
> -               bpf_mtap(ifp->if_bpf, m_head, BPF_DIRECTION_OUT);
> +               if (ifp->if_bpf)
> +                       bpf_mtap(ifp->if_bpf, m_head, BPF_DIRECTION_OUT);
>  #endif
> -       ifq_set_oactive(&ifp->if_snd);
> +               idx = (idx + 1) % URE_TX_LIST_CNT;
> +               cd->tx_cnt++;
> +       }
> +
> +       cd->tx_prod = idx;
> +
> +       if (cd->tx_cnt >= URE_TX_LIST_CNT)
> +               ifq_set_oactive(&ifp->if_snd);
>  }
>
>  void
> @@ -672,6 +838,7 @@ ure_stop(struct ure_softc *sc)
>         ifq_clr_oactive(&ifp->if_snd);
>
>         timeout_del(&sc->ure_stat_ch);
> +       sc->ure_flags &= ~URE_FLAG_LINK;
>
>         if (sc->ure_ep[URE_ENDPT_RX] != NULL) {
>                 usbd_abort_pipe(sc->ure_ep[URE_ENDPT_RX]);
> @@ -714,8 +881,6 @@ ure_stop(struct ure_softc *sc)
>                         sc->ure_cdata.tx_chain[i].uc_xfer = NULL;
>                 }
>         }
> -
> -       sc->ure_flags &= ~URE_FLAG_LINK;
>  }
>
>  void
> @@ -852,7 +1017,14 @@ ure_rtl8153_init(struct ure_softc *sc)
>  void
>  ure_rtl8153b_init(struct ure_softc *sc)
>  {
> -       int     i;
> +       uint16_t        reg;
> +       int             i;
> +
> +       if (sc->ure_flags & URE_FLAG_8156) {
> +               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);
> +       }
>
>         URE_CLRBIT_2(sc, URE_USB_LPM_CONFIG, URE_MCU_TYPE_USB,
> LPM_U1U2_EN);
>
> @@ -883,8 +1055,12 @@ ure_rtl8153b_init(struct ure_softc *sc)
>         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);
> -       URE_CLRBIT_2(sc, URE_USB_MISC_0, URE_MCU_TYPE_USB,
> URE_PCUT_STATUS);
> -       ure_rtl8153_phy_status(sc, 0);
> +
> +       if (!(sc->ure_flags & URE_FLAG_8156)) {
> +               URE_CLRBIT_2(sc, URE_USB_MISC_0, URE_MCU_TYPE_USB,
> +                   URE_PCUT_STATUS);
> +               ure_rtl8153_phy_status(sc, 0);
> +       }
>
>         URE_CLRBIT_1(sc, URE_PLA_INDICATE_FALG, URE_MCU_TYPE_PLA,
>             URE_UPCOMING_RUNTIME_D3);
> @@ -901,13 +1077,34 @@ ure_rtl8153b_init(struct ure_softc *sc)
>         URE_SETBIT_2(sc, URE_USB_LPM_CONFIG, URE_MCU_TYPE_USB,
> LPM_U1U2_EN);
>
>         /* MAC clock speed down. */
> -       URE_SETBIT_2(sc, URE_PLA_MAC_PWR_CTRL2, URE_MCU_TYPE_PLA,
> -           URE_MAC_CLK_SPDWN_EN);
> +       if (sc->ure_flags & URE_FLAG_8156) {
> +               ure_write_2(sc, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA,
> 0x0403);
> +               reg = ure_read_2(sc, URE_PLA_MAC_PWR_CTRL2,
> URE_MCU_TYPE_PLA) &
> +                   ~0xff;
> +               reg |= URE_MAC_CLK_SPDWN_EN | 0x0003;
> +               ure_write_2(sc, URE_PLA_MAC_PWR_CTRL2, URE_MCU_TYPE_PLA,
> reg);
> +
> +               URE_CLRBIT_2(sc, URE_PLA_MAC_PWR_CTRL3, URE_MCU_TYPE_PLA,
> +                   0x4000);
> +
> +               reg = ure_read_2(sc, URE_PLA_EXTRA_STATUS,
> URE_MCU_TYPE_PLA);
> +               if (ure_get_link_status(sc))
> +                       reg |= 0x8000;
> +               else
> +                       reg &= ~0x8000;
> +               reg |= 0x0001;
> +               ure_write_2(sc, URE_PLA_EXTRA_STATUS, URE_MCU_TYPE_PLA,
> reg);
> +       } else
> +               URE_SETBIT_2(sc, URE_PLA_MAC_PWR_CTRL2, URE_MCU_TYPE_PLA,
> +                   URE_MAC_CLK_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->ure_flags & URE_FLAG_8156)
> +               URE_SETBIT_1(sc, 0xcfd9, URE_MCU_TYPE_USB, 0x04);
> +
>         URE_SETBIT_2(sc, URE_PLA_RSTTALLY, URE_MCU_TYPE_PLA,
> URE_TALLY_RESET);
>  }
>
> @@ -994,7 +1191,7 @@ ure_rtl8153_nic_reset(struct ure_softc *
>         uint8_t         u1u2[8] = { 0 };
>         int             i;
>
> -       if (sc->ure_flags & URE_FLAG_8153B) {
> +       if (sc->ure_flags & (URE_FLAG_8153B | URE_FLAG_8156)) {
>                 URE_CLRBIT_2(sc, URE_USB_LPM_CONFIG, URE_MCU_TYPE_USB,
>                     LPM_U1U2_EN);
>         } else {
> @@ -1017,61 +1214,86 @@ ure_rtl8153_nic_reset(struct ure_softc *
>                     URE_UPS_FLAGS_EN_ALDPS);
>         }
>
> -       ure_write_2(sc, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA, 0);
> -       ure_write_2(sc, URE_PLA_MAC_PWR_CTRL2, URE_MCU_TYPE_PLA, 0);
> -       ure_write_2(sc, URE_PLA_MAC_PWR_CTRL3, URE_MCU_TYPE_PLA, 0);
> -       ure_write_2(sc, URE_PLA_MAC_PWR_CTRL4, URE_MCU_TYPE_PLA, 0);
> +       if (!(sc->ure_flags & URE_FLAG_8156)) {
> +               ure_write_2(sc, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA, 0);
> +               ure_write_2(sc, URE_PLA_MAC_PWR_CTRL2, URE_MCU_TYPE_PLA,
> 0);
> +               ure_write_2(sc, URE_PLA_MAC_PWR_CTRL3, URE_MCU_TYPE_PLA,
> 0);
> +               ure_write_2(sc, URE_PLA_MAC_PWR_CTRL4, URE_MCU_TYPE_PLA,
> 0);
> +       }
>         URE_SETBIT_2(sc, URE_PLA_MISC_1, URE_MCU_TYPE_PLA,
> URE_RXDY_GATED_EN);
>         ure_disable_teredo(sc);
>
>         URE_CLRBIT_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA, URE_RCR_ACPT_ALL);
>
> -       ure_reset(sc);
> +       if (sc->ure_flags & URE_FLAG_8156)
> +               ure_write_1(sc, URE_PLA_CR, URE_MCU_TYPE_PLA, 0);
> +       else
> +               ure_reset(sc);
> +
>         ure_reset_bmu(sc);
>
>         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);
> -       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;
> -               usbd_delay_ms(sc->ure_udev, 1);
> -       }
> -       if (i == URE_TIMEOUT)
> -               printf("%s: timeout waiting for OOB control\n",
> -                   sc->ure_dev.dv_xname);
> -       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;
> -               usbd_delay_ms(sc->ure_udev, 1);
> -       }
> -       if (i == URE_TIMEOUT)
> -               printf("%s: timeout waiting for OOB control\n",
> -                   sc->ure_dev.dv_xname);
>
> +       if (!(sc->ure_flags & URE_FLAG_8156)) {
> +               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;
> +                       usbd_delay_ms(sc->ure_udev, 1);
> +               }
> +               if (i == URE_TIMEOUT)
> +                       printf("%s: timeout waiting for OOB control\n",
> +                           sc->ure_dev.dv_xname);
> +               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;
> +                       usbd_delay_ms(sc->ure_udev, 1);
> +               }
> +               if (i == URE_TIMEOUT)
> +                       printf("%s: timeout waiting for OOB control\n",
> +                           sc->ure_dev.dv_xname);
> +       }
>         ure_rxvlan(sc);
>         ure_write_2(sc, URE_PLA_RMS, URE_MCU_TYPE_PLA,
>             URE_FRAMELEN(ifp->if_mtu));
>         ure_write_1(sc, URE_PLA_MTPS, URE_MCU_TYPE_PLA, MTPS_JUMBO);
> -       URE_SETBIT_2(sc, URE_PLA_TCR0, URE_MCU_TYPE_PLA,
> URE_TCR0_AUTO_FIFO);
>
> -       ure_reset(sc);
> +       if (!(sc->ure_flags & URE_FLAG_8156)) {
> +               URE_SETBIT_2(sc, URE_PLA_TCR0, URE_MCU_TYPE_PLA,
> +                   URE_TCR0_AUTO_FIFO);
> +               ure_reset(sc);
> +       }
>
>         /* Configure Rx FIFO threshold. */
> -       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);
> +       if (sc->ure_flags & URE_FLAG_8156) {
> +               ure_write_2(sc, URE_PLA_RXFIFO_CTRL0 + 2, URE_MCU_TYPE_PLA,
> +                   0x0008);
> +               ure_write_2(sc, URE_PLA_RXFIFO_CTRL1 + 2, URE_MCU_TYPE_PLA,
> +                   0x0100);
> +               ure_write_2(sc, URE_PLA_RXFIFO_CTRL2, URE_MCU_TYPE_PLA, 0);
> +       } else {
> +               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);
> +       }
>
>         /* Configure Tx FIFO threshold. */
>         ure_write_4(sc, URE_PLA_TXFIFO_CTRL, URE_MCU_TYPE_PLA,
>             URE_TXFIFO_THR_NORMAL2);
>
> -       if (sc->ure_flags & URE_FLAG_8153B) {
> +       if (sc->ure_flags & URE_FLAG_8156) {
> +               URE_CLRBIT_2(sc, URE_PLA_MAC_PWR_CTRL3, URE_MCU_TYPE_PLA,
> +                   0x4000);
> +               ure_write_4(sc, URE_USB_RX_BUF_TH, URE_MCU_TYPE_USB,
> +                   0x00600400);
> +       } else if (sc->ure_flags & URE_FLAG_8153B) {
>                 ure_write_4(sc, URE_USB_RX_BUF_TH, URE_MCU_TYPE_USB,
>                     URE_RX_THR_B);
>         }
> @@ -1087,11 +1309,11 @@ ure_rtl8153_nic_reset(struct ure_softc *
>         }
>
>         if ((sc->ure_chip & (URE_CHIP_VER_5C20 | URE_CHIP_VER_5C30)) ||
> -           (sc->ure_flags & URE_FLAG_8153B))
> +           (sc->ure_flags & (URE_FLAG_8153B | URE_FLAG_8156)))
>                 URE_SETBIT_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB,
>                     URE_U2P3_ENABLE);
>
> -       if (sc->ure_flags & URE_FLAG_8153B) {
> +       if (sc->ure_flags & (URE_FLAG_8153B | URE_FLAG_8156)) {
>                 URE_SETBIT_2(sc, URE_USB_LPM_CONFIG, URE_MCU_TYPE_USB,
>                     LPM_U1U2_EN);
>         } else {
> @@ -1125,7 +1347,7 @@ ure_rtl8153_phy_status(struct ure_softc
>                 printf("%s: timeout waiting for phy to stabilize\n",
>                     sc->ure_dev.dv_xname);
>  }
> -
> +
>  void
>  ure_reset_bmu(struct ure_softc *sc)
>  {
> @@ -1138,7 +1360,7 @@ ure_reset_bmu(struct ure_softc *sc)
>  void
>  ure_disable_teredo(struct ure_softc *sc)
>  {
> -       if (sc->ure_flags & URE_FLAG_8153B)
> +       if (sc->ure_flags & (URE_FLAG_8153B | URE_FLAG_8156))
>                 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,
> @@ -1180,7 +1402,11 @@ ure_ioctl(struct ifnet *ifp, u_long cmd,
>
>         case SIOCGIFMEDIA:
>         case SIOCSIFMEDIA:
> -               error = ifmedia_ioctl(ifp, ifr, &sc->ure_mii.mii_media,
> cmd);
> +               if (sc->ure_flags & URE_FLAG_8156)
> +                       error = ifmedia_ioctl(ifp, ifr, &sc->ure_ifmedia,
> cmd);
> +               else
> +                       error = ifmedia_ioctl(ifp, ifr,
> &sc->ure_mii.mii_media,
> +                           cmd);
>                 break;
>
>         default:
> @@ -1217,28 +1443,30 @@ ure_attach(struct device *parent, struct
>         struct usb_attach_arg           *uaa = aux;
>         usb_interface_descriptor_t      *id;
>         usb_endpoint_descriptor_t       *ed;
> -       struct mii_data                 *mii;
>         u_char                          eaddr[8]; /* 4byte padded */
>         struct ifnet                    *ifp;
> -       int                             i, mii_flags, s;
> +       int                             i, mii_flags = 0, s;
>         uint16_t                        ver;
>
>         sc->ure_udev = uaa->device;
>         sc->ure_iface = uaa->iface;
>
> -       if (uaa->product == USB_PRODUCT_REALTEK_RTL8152)
> +       if (uaa->product == USB_PRODUCT_REALTEK_RTL8152) {
>                 sc->ure_flags |= URE_FLAG_8152;
> +               sc->ure_rxbufsz = URE_8152_RXBUFSZ;
> +       } else if (uaa->product == USB_PRODUCT_REALTEK_RTL8156) {
> +               sc->ure_flags |= URE_FLAG_8156;
> +               sc->ure_rxbufsz = URE_8153_RXBUFSZ;
> +       } else
> +               sc->ure_rxbufsz = URE_8153_RXBUFSZ;
>
>         usb_init_task(&sc->ure_tick_task, ure_tick_task, sc,
>             USB_TASK_TYPE_GENERIC);
> -       rw_init(&sc->ure_mii_lock, "uremii");
>         usb_init_task(&sc->ure_stop_task, (void (*)(void *))ure_stop, sc,
>             USB_TASK_TYPE_GENERIC);
>
>         id = usbd_get_interface_descriptor(sc->ure_iface);
>
> -       sc->ure_bufsz = URE_BUFSZ;
> -
>         for (i = 0; i < id->bNumEndpoints; i++) {
>                 ed = usbd_interface2endpoint_descriptor(sc->ure_iface, i);
>                 if (!ed) {
> @@ -1264,35 +1492,41 @@ ure_attach(struct device *parent, struct
>         switch (ver) {
>         case 0x4c00:
>                 sc->ure_chip |= URE_CHIP_VER_4C00;
> -               printf("ver 4c00");
> +               printf("RTL8152 (0x4c00)");
>                 break;
>         case 0x4c10:
>                 sc->ure_chip |= URE_CHIP_VER_4C10;
> -               printf("ver 4c10");
> +               printf("RTL8152 (0x4c10)");
>                 break;
>         case 0x5c00:
>                 sc->ure_chip |= URE_CHIP_VER_5C00;
> -               printf("ver 5c00");
> +               printf("RTL8153 (0x5c00)");
>                 break;
>         case 0x5c10:
>                 sc->ure_chip |= URE_CHIP_VER_5C10;
> -               printf("ver 5c10");
> +               printf("RTL8153 (0x5c10)");
>                 break;
>         case 0x5c20:
>                 sc->ure_chip |= URE_CHIP_VER_5C20;
> -               printf("ver 5c20");
> +               printf("RTL8153 (0x5c20)");
>                 break;
>         case 0x5c30:
>                 sc->ure_chip |= URE_CHIP_VER_5C30;
> -               printf("ver 5c30");
> +               printf("RTL8153 (0x5c30)");
>                 break;
>         case 0x6000:
>                 sc->ure_flags = URE_FLAG_8153B;
> -               printf("ver 6000");
> +               printf("RTL8153B (0x6000)");
>                 break;
>         case 0x6010:
>                 sc->ure_flags = URE_FLAG_8153B;
> -               printf("ver 6010");
> +               printf("RTL8153B (0x6010)");
> +               break;
> +       case 0x7020:
> +               printf("RTL8156 (0x7020)");
> +               break;
> +       case 0x7030:
> +               printf("RTL8156 (0x7030)");
>                 break;
>         default:
>                 printf(", unknown ver %02x", ver);
> @@ -1301,7 +1535,7 @@ ure_attach(struct device *parent, struct
>
>         if (sc->ure_flags & URE_FLAG_8152)
>                 ure_rtl8152_init(sc);
> -       else if (sc->ure_flags & URE_FLAG_8153B)
> +       else if (sc->ure_flags & (URE_FLAG_8153B | URE_FLAG_8156))
>                 ure_rtl8153b_init(sc);
>         else
>                 ure_rtl8153_init(sc);
> @@ -1323,27 +1557,40 @@ ure_attach(struct device *parent, struct
>         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
>         ifp->if_ioctl = ure_ioctl;
>         ifp->if_start = ure_start;
> +       ifp->if_watchdog = ure_watchdog;
>         ifp->if_capabilities = 0;
>
> -       mii = &sc->ure_mii;
> -       mii->mii_ifp = ifp;
> -       mii->mii_readreg = ure_miibus_readreg;
> -       mii->mii_writereg = ure_miibus_writereg;
> -       mii->mii_statchg = ure_miibus_statchg;
> -       mii->mii_flags = MIIF_AUTOTSLEEP;
> -
> -       ifmedia_init(&mii->mii_media, 0, ure_ifmedia_upd, ure_ifmedia_sts);
> -       mii_flags = 0;
> -       if (!(sc->ure_flags & URE_FLAG_8152))
> -               mii_flags |= MIIF_DOPAUSE;
> -       mii_attach(self, mii, 0xffffffff, sc->ure_phyno, MII_OFFSET_ANY,
> -           mii_flags);
> -
> -       if (LIST_FIRST(&mii->mii_phys) == NULL) {
> -               ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0,
> NULL);
> -               ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE);
> -       } else
> -               ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO);
> +       if (sc->ure_flags & URE_FLAG_8156) {
> +               ifmedia_init(&sc->ure_ifmedia, IFM_IMASK, ure_ifmedia_upd,
> +                   ure_ifmedia_sts);
> +               ure_add_media_types(sc);
> +               ifmedia_add(&sc->ure_ifmedia, IFM_ETHER | IFM_AUTO, 0,
> NULL);
> +               ifmedia_set(&sc->ure_ifmedia, IFM_ETHER | IFM_AUTO);
> +               sc->ure_ifmedia.ifm_media =
> sc->ure_ifmedia.ifm_cur->ifm_media;
> +       } else {
> +               rw_init(&sc->ure_mii_lock, "uremii");
> +
> +               sc->ure_mii.mii_ifp = ifp;
> +               sc->ure_mii.mii_readreg = ure_miibus_readreg;
> +               sc->ure_mii.mii_writereg = ure_miibus_writereg;
> +               sc->ure_mii.mii_statchg = ure_miibus_statchg;
> +               sc->ure_mii.mii_flags = MIIF_AUTOTSLEEP;
> +
> +               ifmedia_init(&sc->ure_mii.mii_media, 0, ure_ifmedia_upd,
> +                   ure_ifmedia_sts);
> +               if (!(sc->ure_flags & URE_FLAG_8152))
> +                       mii_flags |= MIIF_DOPAUSE;
> +               mii_attach(self, &sc->ure_mii, 0xffffffff, sc->ure_phyno,
> +                   MII_OFFSET_ANY, mii_flags);
> +               if (LIST_FIRST(&sc->ure_mii.mii_phys) == NULL) {
> +                       ifmedia_add(&sc->ure_mii.mii_media,
> +                           IFM_ETHER | IFM_NONE, 0, NULL);
> +                       ifmedia_set(&sc->ure_mii.mii_media,
> +                           IFM_ETHER | IFM_NONE);
> +               } else
> +                       ifmedia_set(&sc->ure_mii.mii_media,
> +                           IFM_ETHER | IFM_AUTO);
> +       }
>
>         if_attach(ifp);
>         ether_ifattach(ifp);
> @@ -1407,9 +1654,13 @@ ure_tick_task(void *xsc)
>         mii = &sc->ure_mii;
>
>         s = splnet();
> -       mii_tick(mii);
> -       if ((sc->ure_flags & URE_FLAG_LINK) == 0)
> -               ure_miibus_statchg(&sc->ure_dev);
> +       if (sc->ure_flags & URE_FLAG_8156)
> +               ure_link_state(sc);
> +       else {
> +               mii_tick(mii);
> +               if ((sc->ure_flags & URE_FLAG_LINK) == 0)
> +                       ure_miibus_statchg(&sc->ure_dev);
> +       }
>         timeout_add_sec(&sc->ure_stat_ch, 1);
>         splx(s);
>  }
> @@ -1457,7 +1708,8 @@ ure_rxeof(struct usbd_xfer *xfer, void *
>                                 sc->ure_dev.dv_xname, usbd_errstr(status));
>                 }
>                 if (status == USBD_STALLED)
> -
>  usbd_clear_endpoint_stall_async(sc->ure_ep[URE_ENDPT_RX]);
> +                       usbd_clear_endpoint_stall_async(
> +                           sc->ure_ep[URE_ENDPT_RX]);
>                 goto done;
>         }
>
> @@ -1501,10 +1753,10 @@ done:
>         s = splnet();
>         if_input(ifp, &ml);
>         splx(s);
> -       memset(c->uc_buf, 0, sc->ure_bufsz);
> +       memset(c->uc_buf, 0, sc->ure_rxbufsz);
>
>         usbd_setup_xfer(xfer, sc->ure_ep[URE_ENDPT_RX], c, c->uc_buf,
> -           sc->ure_bufsz, USBD_SHORT_XFER_OK | USBD_NO_COPY,
> +           sc->ure_rxbufsz, USBD_SHORT_XFER_OK | USBD_NO_COPY,
>             USBD_NO_TIMEOUT, ure_rxeof);
>         usbd_transfer(xfer);
>  }
> @@ -1515,12 +1767,14 @@ ure_txeof(struct usbd_xfer *xfer, void *
>  {
>         struct ure_softc        *sc;
>         struct ure_chain        *c;
> +       struct ure_cdata        *cd;
>         struct ifnet            *ifp;
>         int                     s;
>
>         c = priv;
>         sc = c->uc_sc;
>         ifp = &sc->ure_ac.ac_if;
> +       cd = &sc->ure_cdata;
>
>         if (usbd_is_dying(sc->ure_udev))
>                 return;
> @@ -1529,6 +1783,7 @@ ure_txeof(struct usbd_xfer *xfer, void *
>
>         s = splnet();
>
> +       cd->tx_cnt--;
>         if (status != USBD_NORMAL_COMPLETION) {
>                 if (status == USBD_NOT_STARTED || status ==
> USBD_CANCELLED) {
>                         splx(s);
> @@ -1538,7 +1793,8 @@ ure_txeof(struct usbd_xfer *xfer, void *
>                 printf("%s: usb error on tx: %s\n", sc->ure_dev.dv_xname,
>                     usbd_errstr(status));
>                 if (status == USBD_STALLED)
> -
>  usbd_clear_endpoint_stall_async(sc->ure_ep[URE_ENDPT_TX]);
> +                       usbd_clear_endpoint_stall_async(
> +                           sc->ure_ep[URE_ENDPT_TX]);
>                 splx(s);
>                 return;
>         }
> @@ -1553,7 +1809,6 @@ ure_txeof(struct usbd_xfer *xfer, void *
>                 ure_start(ifp);
>
>         splx(s);
> -
>  }
>
>  int
> @@ -1573,8 +1828,7 @@ ure_tx_list_init(struct ure_softc *sc)
>                         c->uc_xfer = usbd_alloc_xfer(sc->ure_udev);
>                         if (c->uc_xfer == NULL)
>                                 return ENOBUFS;
> -                       c->uc_buf = usbd_alloc_buffer(c->uc_xfer,
> -                           sc->ure_bufsz);
> +                       c->uc_buf = usbd_alloc_buffer(c->uc_xfer,
> URE_TXBUFSZ);
>                         if (c->uc_buf == NULL) {
>                                 usbd_free_xfer(c->uc_xfer);
>                                 return ENOBUFS;
> @@ -1582,7 +1836,9 @@ ure_tx_list_init(struct ure_softc *sc)
>                 }
>         }
>
> -       return 0;
> +       cd->tx_prod = cd->tx_cnt = 0;
> +
> +       return (0);
>  }
>
>  int
> @@ -1603,7 +1859,7 @@ ure_rx_list_init(struct ure_softc *sc)
>                         if (c->uc_xfer == NULL)
>                                 return ENOBUFS;
>                         c->uc_buf = usbd_alloc_buffer(c->uc_xfer,
> -                           sc->ure_bufsz);
> +                           sc->ure_rxbufsz);
>                         if (c->uc_buf == NULL) {
>                                 usbd_free_xfer(c->uc_xfer);
>                                 return ENOBUFS;
> @@ -1611,7 +1867,7 @@ ure_rx_list_init(struct ure_softc *sc)
>                 }
>         }
>
> -       return 0;
> +       return (0);
>  }
>
>  int
> @@ -1621,21 +1877,18 @@ ure_encap(struct ure_softc *sc, struct m
>         usbd_status             err;
>         struct ure_txpkt        txhdr;
>         uint32_t                frm_len = 0;
> -       u_char                  *buf;
>
>         c = &sc->ure_cdata.tx_chain[idx];
> -       buf = c->uc_buf;
>
>         /* header */
>         htolem32(&txhdr.ure_pktlen, m->m_pkthdr.len | URE_TXPKT_TX_FS |
>             URE_TXPKT_TX_LS);
>         txhdr.ure_rsvd0 = 0;
> -       memcpy(buf, &txhdr, sizeof(txhdr));
> -       buf += sizeof(txhdr);
> +       memcpy(c->uc_buf, &txhdr, sizeof(txhdr));
>         frm_len = sizeof(txhdr);
>
>         /* packet */
> -       m_copydata(m, 0, m->m_pkthdr.len, buf);
> +       m_copydata(m, 0, m->m_pkthdr.len, c->uc_buf + frm_len);
>         frm_len += m->m_pkthdr.len;
>
>         c->uc_mbuf = m;
> @@ -1647,9 +1900,8 @@ ure_encap(struct ure_softc *sc, struct m
>         err = usbd_transfer(c->uc_xfer);
>         if (err != USBD_IN_PROGRESS) {
>                 ure_stop(sc);
> -               return EIO;
> +               return (EIO);
>         }
>
> -       sc->ure_cdata.tx_cnt++;
> -       return 0;
> +       return (0);
>  }
> Index: sys/dev/usb/if_urereg.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/usb/if_urereg.h,v
> retrieving revision 1.7
> diff -u -p -u -p -r1.7 if_urereg.h
> --- sys/dev/usb/if_urereg.h     29 Aug 2019 08:55:06 -0000      1.7
> +++ sys/dev/usb/if_urereg.h     3 Dec 2019 08:29:41 -0000
> @@ -41,10 +41,10 @@
>  #define        URE_BYTE_EN_BYTE        0x11
>  #define        URE_BYTE_EN_SIX_BYTES   0x3f
>
> -#define        URE_FRAMELEN(mtu)       \
> +#define URE_FRAMELEN(mtu)      \
>         (mtu + ETHER_HDR_LEN + ETHER_CRC_LEN + ETHER_VLAN_ENCAP_LEN)
> -#define        URE_JUMBO_FRAMELEN      (9 * 1024)
> -#define        URE_JUMBO_MTU                                           \
> +#define URE_JUMBO_FRAMELEN     (9 * 1024)
> +#define URE_JUMBO_MTU                                          \
>         (URE_JUMBO_FRAMELEN - ETHER_HDR_LEN - ETHER_CRC_LEN -   \
>          ETHER_VLAN_ENCAP_LEN)
>
> @@ -310,6 +310,14 @@
>  /* URE_PLA_EXTRA_STATUS */
>  #define        URE_LINK_CHANGE_FLAG    0x0100
>
> +/* 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_2500MBPS 0x0400
> +
>  /* URE_USB_USB2PHY */
>  #define        URE_USB2PHY_SUSPEND     0x0001
>  #define        URE_USB2PHY_L1          0x0002
> @@ -432,6 +440,8 @@
>  #define        URE_ADC_EN              0x0080
>  #define        URE_CKADSEL_L           0x0100
>
> +#define URE_ADV_2500TFDX       0x0080
> +
>  #define        URE_MCU_TYPE_PLA        0x0100
>  #define        URE_MCU_TYPE_USB        0x0000
>
> @@ -470,11 +480,13 @@ struct ure_txpkt {
>  #define URE_ENDPT_TX           1
>  #define URE_ENDPT_MAX          2
>
> -#define        URE_TX_LIST_CNT         1
> +#define        URE_TX_LIST_CNT         4
>  #define        URE_RX_LIST_CNT         1
>  #define        URE_RX_BUF_ALIGN        sizeof(uint64_t)
>
> -#define        URE_BUFSZ               16384
> +#define        URE_TXBUFSZ             16384
> +#define        URE_8152_RXBUFSZ        16384
> +#define        URE_8153_RXBUFSZ        32768
>
>  struct ure_chain {
>         struct ure_softc        *uc_sc;
> @@ -489,9 +501,7 @@ struct ure_cdata {
>         struct ure_chain        tx_chain[URE_TX_LIST_CNT];
>         struct ure_chain        rx_chain[URE_RX_LIST_CNT];
>         int                     tx_prod;
> -       int                     tx_const;
>         int                     tx_cnt;
> -       int                     rx_prod;
>  };
>
>  struct ure_softc {
> @@ -508,6 +518,7 @@ struct ure_softc {
>         /* ethernet */
>         struct arpcom           ure_ac;
>         struct mii_data         ure_mii;
> +       struct ifmedia          ure_ifmedia;
>         struct rwlock           ure_mii_lock;
>         int                     ure_refcnt;
>
> @@ -515,7 +526,7 @@ struct ure_softc {
>         struct timeout          ure_stat_ch;
>
>         struct timeval          ure_rx_notice;
> -       int                     ure_bufsz;
> +       int                     ure_rxbufsz;
>
>         int                     ure_phyno;
>
> @@ -523,6 +534,7 @@ struct ure_softc {
>  #define        URE_FLAG_LINK           0x0001
>  #define        URE_FLAG_8152           0x1000  /* RTL8152 */
>  #define        URE_FLAG_8153B          0x2000  /* RTL8153B */
> +#define        URE_FLAG_8156           0x4000  /* RTL8156 */
>
>         u_int                   ure_chip;
>  #define        URE_CHIP_VER_4C00       0x01
> Index: sys/dev/usb/usbdevs
> ===================================================================
> RCS file: /cvs/src/sys/dev/usb/usbdevs,v
> retrieving revision 1.701
> diff -u -p -u -p -r1.701 usbdevs
> --- sys/dev/usb/usbdevs 27 Aug 2019 17:59:58 -0000      1.701
> +++ sys/dev/usb/usbdevs 3 Dec 2019 08:29:41 -0000
> @@ -3597,6 +3597,7 @@ product REALTEK RTL8150           0x8150  RTL8150
>  product REALTEK RTL8151                0x8151  RTL8151 PNA
>  product REALTEK RTL8152                0x8152  RTL8152
>  product REALTEK RTL8153                0x8153  RTL8153
> +product REALTEK RTL8156                0x8156  RTL8156
>  product REALTEK RTL8188CE_0    0x8170  RTL8188CE
>  product REALTEK RTL8171                0x8171  RTL8171
>  product REALTEK RTL8172                0x8172  RTL8172
>
>
I've tested with Asustor as-u2.5g.

ure0 at uhub0 port 6 configuration 1 interface 0 "Realtek USB
10/100/1G/2.5G LAN" rev 3.20/30.00 addr 2

ure0: RTL8156 (0x7030), address 00:24:27:88:00:a1

It works properly as usual.

Thank you,

Shawn
-- 


[image: --]

Shawn Chiou
[image: https://]about.me/shawn.chiou
<https://about.me/shawn.chiou?promo=email_sig&utm_source=email_sig&utm_medium=email_sig&utm_campaign=external_links>

Reply via email to