summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Lo <kevlo@cvs.openbsd.org>2019-11-18 03:03:38 +0000
committerKevin Lo <kevlo@cvs.openbsd.org>2019-11-18 03:03:38 +0000
commitc6ee9af7dbc18ec6690700d639e3a3a7fe718df3 (patch)
tree65ffd5f92b0f6daf4c759fe1fb457db19dff9c35
parentd6a6c7e9619f553eee2e068a54ccd6248072dbe8 (diff)
Introduce rge(4), a new driver for Realtek 8125 PCI Express 2.5Gb Ethernet
device. "just commit!" deraadt@ "looks good to me" jmatthew@
-rw-r--r--sys/arch/amd64/conf/GENERIC3
-rw-r--r--sys/arch/i386/conf/GENERIC3
-rw-r--r--sys/dev/pci/files.pci7
-rw-r--r--sys/dev/pci/if_rge.c2004
-rw-r--r--sys/dev/pci/if_rgereg.h1863
-rw-r--r--sys/dev/pci/pcidevs4
6 files changed, 3880 insertions, 4 deletions
diff --git a/sys/arch/amd64/conf/GENERIC b/sys/arch/amd64/conf/GENERIC
index 0e4baf8a3ac..df72365f784 100644
--- a/sys/arch/amd64/conf/GENERIC
+++ b/sys/arch/amd64/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.480 2019/09/26 12:59:01 brynet Exp $
+# $OpenBSD: GENERIC,v 1.481 2019/11/18 03:03:37 kevlo Exp $
#
# For further information on compiling OpenBSD kernels, see the config(8)
# man page.
@@ -513,6 +513,7 @@ bge* at pci? # Broadcom BCM57xx (aka Tigon3)
bnx* at pci? # Broadcom BCM5706/5708 GigE
re* at pci? # Realtek 8169/8169S/8110S
re* at cardbus? # Realtek 8169/8169S/8110S
+rge* at pci? # Realtek 8125
stge* at pci? # Sundance TC9021 GigE
#lge* at pci? # Level1 LXT1001 GigE
hme* at pci? # Sun Happy Meal
diff --git a/sys/arch/i386/conf/GENERIC b/sys/arch/i386/conf/GENERIC
index 76b93220a68..912fed8da91 100644
--- a/sys/arch/i386/conf/GENERIC
+++ b/sys/arch/i386/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.844 2019/05/28 08:44:27 sf Exp $
+# $OpenBSD: GENERIC,v 1.845 2019/11/18 03:03:37 kevlo Exp $
#
# For further information on compiling OpenBSD kernels, see the config(8)
# man page.
@@ -576,6 +576,7 @@ bge* at pci? # Broadcom BCM57xx (aka Tigon3)
bnx* at pci? # Broadcom BCM5706/5708 GigE
re* at pci? # Realtek 8169/8169S/8110S
re* at cardbus? # Realtek 8169/8169S/8110S
+rge* at pci? # Realtek 8125
stge* at pci? # Sundance TC9021 GigE
lge* at pci? # Level1 LXT1001 GigE
hme* at pci? # Sun Happy Meal
diff --git a/sys/dev/pci/files.pci b/sys/dev/pci/files.pci
index e135e7e51f4..ea0badb4cc2 100644
--- a/sys/dev/pci/files.pci
+++ b/sys/dev/pci/files.pci
@@ -1,4 +1,4 @@
-# $OpenBSD: files.pci,v 1.340 2019/10/16 01:39:32 mlarkin Exp $
+# $OpenBSD: files.pci,v 1.341 2019/11/18 03:03:37 kevlo Exp $
# $NetBSD: files.pci,v 1.20 1996/09/24 17:47:15 christos Exp $
#
# Config file and device description for machine-independent PCI code.
@@ -843,5 +843,10 @@ device iavf: ether, ifnet, ifmedia
attach iavf at pci
file dev/pci/if_iavf.c iavf
+# Realtek 8125
+device rge: ether, ifnet, ifmedia
+attach rge at pci
+file dev/pci/if_rge.c rge
+
include "dev/pci/files.agp"
include "dev/pci/drm/files.drm"
diff --git a/sys/dev/pci/if_rge.c b/sys/dev/pci/if_rge.c
new file mode 100644
index 00000000000..0bff1022de6
--- /dev/null
+++ b/sys/dev/pci/if_rge.c
@@ -0,0 +1,2004 @@
+/* $OpenBSD: if_rge.c,v 1.1 2019/11/18 03:03:37 kevlo Exp $ */
+
+/*
+ * Copyright (c) 2019 Kevin Lo <kevlo@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "bpfilter.h"
+#include "vlan.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sockio.h>
+#include <sys/mbuf.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/device.h>
+#include <sys/endian.h>
+
+#include <net/if.h>
+#include <net/if_media.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#if NBPFILTER > 0
+#include <net/bpf.h>
+#endif
+
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <dev/mii/mii.h>
+
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcidevs.h>
+
+#include <dev/pci/if_rgereg.h>
+
+int rge_match(struct device *, void *, void *);
+void rge_attach(struct device *, struct device *, void *);
+int rge_intr(void *);
+int rge_encap(struct rge_softc *, struct mbuf *, int);
+int rge_ioctl(struct ifnet *, u_long, caddr_t);
+void rge_start(struct ifqueue *);
+void rge_watchdog(struct ifnet *);
+int rge_init(struct ifnet *);
+void rge_stop(struct ifnet *);
+int rge_ifmedia_upd(struct ifnet *);
+void rge_ifmedia_sts(struct ifnet *, struct ifmediareq *);
+int rge_allocmem(struct rge_softc *);
+int rge_newbuf(struct rge_softc *, int);
+void rge_discard_rxbuf(struct rge_softc *, int);
+int rge_rx_list_init(struct rge_softc *);
+void rge_tx_list_init(struct rge_softc *);
+int rge_rxeof(struct rge_softc *);
+int rge_txeof(struct rge_softc *);
+void rge_reset(struct rge_softc *);
+void rge_iff(struct rge_softc *);
+void rge_set_phy_power(struct rge_softc *, int);
+void rge_phy_config(struct rge_softc *);
+void rge_set_macaddr(struct rge_softc *, const uint8_t *);
+void rge_get_macaddr(struct rge_softc *, uint8_t *);
+void rge_hw_init(struct rge_softc *);
+void rge_disable_phy_ocp_pwrsave(struct rge_softc *);
+void rge_patch_phy_mcu(struct rge_softc *, int);
+void rge_add_media_types(struct rge_softc *);
+void rge_config_imtype(struct rge_softc *, int);
+void rge_disable_sim_im(struct rge_softc *);
+void rge_setup_sim_im(struct rge_softc *);
+void rge_setup_intr(struct rge_softc *, int);
+void rge_exit_oob(struct rge_softc *);
+void rge_write_csi(struct rge_softc *, uint32_t, uint32_t);
+uint32_t rge_read_csi(struct rge_softc *, uint32_t);
+void rge_write_mac_ocp(struct rge_softc *, uint16_t, uint16_t);
+uint16_t rge_read_mac_ocp(struct rge_softc *, uint16_t);
+void rge_write_ephy(struct rge_softc *, uint16_t, uint16_t);
+void rge_write_phy(struct rge_softc *, uint16_t, uint16_t, uint16_t);
+void rge_write_phy_ocp(struct rge_softc *, uint16_t, uint16_t);
+uint16_t rge_read_phy_ocp(struct rge_softc *, uint16_t);
+int rge_get_link_status(struct rge_softc *);
+void rge_txstart(void *);
+void rge_tick(void *);
+void rge_link_state(struct rge_softc *);
+
+static const struct {
+ uint16_t reg;
+ uint16_t val;
+} rtl8125_def_bps[] = {
+ RTL8125_DEF_BPS
+}, rtl8125_mac_cfg2_ephy[] = {
+ RTL8125_MAC_CFG2_EPHY
+}, rtl8125_mac_cfg2_mcu[] = {
+ RTL8125_MAC_CFG2_MCU
+}, rtl8125_mac_cfg3_ephy[] = {
+ RTL8125_MAC_CFG3_EPHY
+}, rtl8125_mac_cfg3_mcu[] = {
+ RTL8125_MAC_CFG3_MCU
+};
+
+struct cfattach rge_ca = {
+ sizeof(struct rge_softc), rge_match, rge_attach
+};
+
+struct cfdriver rge_cd = {
+ NULL, "rge", DV_IFNET
+};
+
+const struct pci_matchid rge_devices[] = {
+ { PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_E3000 },
+ { PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RTL8125 }
+};
+
+int
+rge_match(struct device *parent, void *match, void *aux)
+{
+ return (pci_matchbyid((struct pci_attach_args *)aux, rge_devices,
+ nitems(rge_devices)));
+}
+
+void
+rge_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct rge_softc *sc = (struct rge_softc *)self;
+ struct pci_attach_args *pa = aux;
+ pci_chipset_tag_t pc = pa->pa_pc;
+ pci_intr_handle_t ih;
+ const char *intrstr = NULL;
+ struct ifnet *ifp;
+ pcireg_t reg;
+ uint32_t hwrev;
+ uint8_t eaddr[ETHER_ADDR_LEN];
+ int offset;
+
+ pci_set_powerstate(pa->pa_pc, pa->pa_tag, PCI_PMCSR_STATE_D0);
+
+ /*
+ * Map control/status registers.
+ */
+ if (pci_mapreg_map(pa, RGE_PCI_BAR2, PCI_MAPREG_TYPE_MEM |
+ PCI_MAPREG_MEM_TYPE_64BIT, 0, &sc->rge_btag, &sc->rge_bhandle,
+ NULL, &sc->rge_bsize, 0)) {
+ if (pci_mapreg_map(pa, RGE_PCI_BAR1, PCI_MAPREG_TYPE_MEM |
+ PCI_MAPREG_MEM_TYPE_32BIT, 0, &sc->rge_btag,
+ &sc->rge_bhandle, NULL, &sc->rge_bsize, 0)) {
+ if (pci_mapreg_map(pa, RGE_PCI_BAR0, PCI_MAPREG_TYPE_IO,
+ 0, &sc->rge_btag, &sc->rge_bhandle, NULL,
+ &sc->rge_bsize, 0)) {
+ printf(": can't map mem or i/o space\n");
+ return;
+ }
+ }
+ }
+
+ /*
+ * Allocate interrupt.
+ */
+ if (pci_intr_map_msi(pa, &ih) == 0)
+ sc->rge_flags |= RGE_FLAG_MSI;
+ else if (pci_intr_map(pa, &ih) != 0) {
+ printf(": couldn't map interrupt\n");
+ return;
+ }
+ intrstr = pci_intr_string(pc, ih);
+ sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET | IPL_MPSAFE, rge_intr,
+ sc, sc->sc_dev.dv_xname);
+ if (sc->sc_ih == NULL) {
+ printf(": couldn't establish interrupt");
+ if (intrstr != NULL)
+ printf(" at %s", intrstr);
+ printf("\n");
+ return;
+ }
+ printf(": %s", intrstr);
+
+ sc->sc_dmat = pa->pa_dmat;
+ sc->sc_pc = pa->pa_pc;
+ sc->sc_tag = pa->pa_tag;
+
+ /* Determine hardware revision */
+ hwrev = RGE_READ_4(sc, RGE_TXCFG) & RGE_TXCFG_HWREV;
+ switch (hwrev) {
+ case 0x60800000:
+ sc->rge_type = MAC_CFG2;
+ break;
+ case 0x60900000:
+ sc->rge_type = MAC_CFG3;
+ break;
+ default:
+ printf(": unknown version 0x%08x\n", hwrev);
+ return;
+ }
+
+ rge_config_imtype(sc, RGE_IMTYPE_SIM);
+
+ /*
+ * PCI Express check.
+ */
+ if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PCIEXPRESS,
+ &offset, NULL)) {
+ /* Disable PCIe ASPM and ECPM. */
+ reg = pci_conf_read(pa->pa_pc, pa->pa_tag,
+ offset + PCI_PCIE_LCSR);
+ reg &= ~(PCI_PCIE_LCSR_ASPM_L0S | PCI_PCIE_LCSR_ASPM_L1 |
+ PCI_PCIE_LCSR_ECPM);
+ pci_conf_write(pa->pa_pc, pa->pa_tag, offset + PCI_PCIE_LCSR,
+ reg);
+ }
+
+ rge_exit_oob(sc);
+ rge_hw_init(sc);
+
+ rge_get_macaddr(sc, eaddr);
+ printf(", address %s\n", ether_sprintf(eaddr));
+
+ memcpy(sc->sc_arpcom.ac_enaddr, eaddr, ETHER_ADDR_LEN);
+
+ rge_set_phy_power(sc, 1);
+ rge_phy_config(sc);
+
+ if (rge_allocmem(sc))
+ return;
+
+ ifp = &sc->sc_arpcom.ac_if;
+ ifp->if_softc = sc;
+ strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+ ifp->if_xflags = IFXF_MPSAFE;
+ ifp->if_ioctl = rge_ioctl;
+ ifp->if_qstart = rge_start;
+ ifp->if_watchdog = rge_watchdog;
+ IFQ_SET_MAXLEN(&ifp->if_snd, RGE_TX_LIST_CNT);
+ ifp->if_hardmtu = RGE_JUMBO_MTU;
+
+ ifp->if_capabilities = IFCAP_VLAN_MTU | IFCAP_CSUM_IPv4 |
+ IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4;
+
+#if NVLAN > 0
+ ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
+#endif
+
+ timeout_set(&sc->sc_timeout, rge_tick, sc);
+ task_set(&sc->sc_task, rge_txstart, sc);
+
+ /* Initialize ifmedia structures. */
+ ifmedia_init(&sc->sc_media, IFM_IMASK, rge_ifmedia_upd,
+ rge_ifmedia_sts);
+ rge_add_media_types(sc);
+ ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL);
+ ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO);
+ sc->sc_media.ifm_media = sc->sc_media.ifm_cur->ifm_media;
+
+ if_attach(ifp);
+ ether_ifattach(ifp);
+}
+
+int
+rge_intr(void *arg)
+{
+ struct rge_softc *sc = arg;
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+ uint32_t status;
+ int claimed = 0, rx, tx;
+
+ if (!(ifp->if_flags & IFF_RUNNING))
+ return (0);
+
+ /* Disable interrupts. */
+ RGE_WRITE_4(sc, RGE_IMR, 0);
+
+ status = RGE_READ_4(sc, RGE_ISR);
+ if (!(sc->rge_flags & RGE_FLAG_MSI)) {
+ if ((status & RGE_INTRS) == 0 || status == 0xffffffff)
+ return (0);
+ }
+ if (status)
+ RGE_WRITE_4(sc, RGE_ISR, status);
+
+ if (status & RGE_ISR_PCS_TIMEOUT)
+ claimed = 1;
+
+ rx = tx = 0;
+ if (status & RGE_INTRS) {
+ if (status &
+ (sc->rge_rx_ack | RGE_ISR_RX_ERR | RGE_ISR_RX_FIFO_OFLOW)) {
+ rx |= rge_rxeof(sc);
+ claimed = 1;
+ }
+
+ if (status & (sc->rge_tx_ack | RGE_ISR_TX_ERR)) {
+ tx |= rge_txeof(sc);
+ claimed = 1;
+ }
+
+ if (status & RGE_ISR_SYSTEM_ERR) {
+ KERNEL_LOCK();
+ rge_init(ifp);
+ KERNEL_UNLOCK();
+ claimed = 1;
+ }
+ }
+
+ if (sc->rge_timerintr) {
+ if ((tx | rx) == 0) {
+ /*
+ * Nothing needs to be processed, fallback
+ * to use TX/RX interrupts.
+ */
+ rge_setup_intr(sc, RGE_IMTYPE_NONE);
+
+ /*
+ * Recollect, mainly to avoid the possible
+ * race introduced by changing interrupt
+ * masks.
+ */
+ rge_rxeof(sc);
+ rge_txeof(sc);
+ } else
+ RGE_WRITE_4(sc, RGE_TIMERCNT, 1);
+ } else if (tx | rx) {
+ /*
+ * Assume that using simulated interrupt moderation
+ * (hardware timer based) could reduce the interrupt
+ * rate.
+ */
+ rge_setup_intr(sc, RGE_IMTYPE_SIM);
+ }
+
+ RGE_WRITE_4(sc, RGE_IMR, sc->rge_intrs);
+
+ return (claimed);
+}
+
+int
+rge_encap(struct rge_softc *sc, struct mbuf *m, int idx)
+{
+ struct rge_tx_desc *d = NULL;
+ struct rge_txq *txq;
+ bus_dmamap_t txmap;
+ uint32_t cmdsts, cflags = 0;
+ int cur, error, i, last, nsegs;
+
+ /*
+ * Set RGE_TDEXTSTS_IPCSUM if any checksum offloading is requested.
+ * Otherwise, RGE_TDEXTSTS_TCPCSUM / RGE_TDEXTSTS_UDPCSUM does not
+ * take affect.
+ */
+ if ((m->m_pkthdr.csum_flags &
+ (M_IPV4_CSUM_OUT | M_TCP_CSUM_OUT | M_UDP_CSUM_OUT)) != 0) {
+ cflags |= RGE_TDEXTSTS_IPCSUM;
+ if (m->m_pkthdr.csum_flags & M_TCP_CSUM_OUT)
+ cflags |= RGE_TDEXTSTS_TCPCSUM;
+ if (m->m_pkthdr.csum_flags & M_UDP_CSUM_OUT)
+ cflags |= RGE_TDEXTSTS_UDPCSUM;
+ }
+
+ txq = &sc->rge_ldata.rge_txq[idx];
+ txmap = txq->txq_dmamap;
+
+ error = bus_dmamap_load_mbuf(sc->sc_dmat, txmap, m, BUS_DMA_NOWAIT);
+ switch (error) {
+ case 0:
+ break;
+ case EFBIG: /* mbuf chain is too fragmented */
+ if (m_defrag(m, M_DONTWAIT) == 0 &&
+ bus_dmamap_load_mbuf(sc->sc_dmat, txmap, m,
+ BUS_DMA_NOWAIT) == 0)
+ break;
+
+ /* FALLTHROUGH */
+ default:
+ return (0);
+ }
+
+ bus_dmamap_sync(sc->sc_dmat, txmap, 0, txmap->dm_mapsize,
+ BUS_DMASYNC_PREWRITE);
+
+ nsegs = txmap->dm_nsegs;
+
+ /* Set up hardware VLAN tagging. */
+#if NVLAN > 0
+ if (m->m_flags & M_VLANTAG)
+ cflags |= swap16(m->m_pkthdr.ether_vtag | RGE_TDEXTSTS_VTAG);
+#endif
+
+ cur = idx;
+ cmdsts = RGE_TDCMDSTS_SOF;
+
+ for (i = 0; i < txmap->dm_nsegs; i++) {
+ d = &sc->rge_ldata.rge_tx_list[cur];
+
+ d->rge_extsts = htole32(cflags);
+ d->rge_addrlo = htole32(RGE_ADDR_LO(txmap->dm_segs[i].ds_addr));
+ d->rge_addrhi = htole32(RGE_ADDR_HI(txmap->dm_segs[i].ds_addr));
+
+ cmdsts |= txmap->dm_segs[i].ds_len;
+
+ if (cur == RGE_TX_LIST_CNT - 1)
+ cmdsts |= RGE_TDCMDSTS_EOR;
+
+ d->rge_cmdsts = htole32(cmdsts);
+
+ last = cur;
+ cmdsts = RGE_TDCMDSTS_OWN;
+ cur = RGE_NEXT_TX_DESC(cur);
+ }
+
+ /* Set EOF on the last descriptor. */
+ d->rge_cmdsts |= htole32(RGE_TDCMDSTS_EOF);
+
+ /* Transfer ownership of packet to the chip. */
+ d = &sc->rge_ldata.rge_tx_list[idx];
+
+ d->rge_cmdsts |= htole32(RGE_TDCMDSTS_OWN);
+
+ bus_dmamap_sync(sc->sc_dmat, sc->rge_ldata.rge_tx_list_map,
+ cur * sizeof(struct rge_tx_desc), sizeof(struct rge_tx_desc),
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
+ /* Update info of TX queue and descriptors. */
+ txq->txq_mbuf = m;
+ txq->txq_descidx = last;
+
+ return (nsegs);
+}
+
+int
+rge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+{
+ struct rge_softc *sc = ifp->if_softc;
+ struct ifreq *ifr = (struct ifreq *)data;
+ int s, error = 0;
+
+ s = splnet();
+
+ switch (cmd) {
+ case SIOCSIFADDR:
+ ifp->if_flags |= IFF_UP;
+ if (!(ifp->if_flags & IFF_RUNNING))
+ rge_init(ifp);
+ break;
+ case SIOCSIFFLAGS:
+ if (ifp->if_flags & IFF_UP) {
+ if (ifp->if_flags & IFF_RUNNING)
+ error = ENETRESET;
+ else
+ rge_init(ifp);
+ } else {
+ if (ifp->if_flags & IFF_RUNNING)
+ rge_stop(ifp);
+ }
+ break;
+ case SIOCGIFMEDIA:
+ case SIOCSIFMEDIA:
+ error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
+ break;
+ case SIOCSIFMTU:
+ if (ifr->ifr_mtu > ifp->if_hardmtu) {
+ error = EINVAL;
+ break;
+ }
+ ifp->if_mtu = ifr->ifr_mtu;
+ break;
+ default:
+ error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data);
+ }
+
+ if (error == ENETRESET) {
+ if (ifp->if_flags & IFF_RUNNING)
+ rge_iff(sc);
+ error = 0;
+ }
+
+ splx(s);
+ return (error);
+}
+
+void
+rge_start(struct ifqueue *ifq)
+{
+ struct ifnet *ifp = ifq->ifq_if;
+ struct rge_softc *sc = ifp->if_softc;
+ struct mbuf *m;
+ int free, idx, used;
+ int queued = 0;
+
+ if (!LINK_STATE_IS_UP(ifp->if_link_state)) {
+ ifq_purge(ifq);
+ return;
+ }
+
+ /* Calculate free space. */
+ idx = sc->rge_ldata.rge_txq_prodidx;
+ free = sc->rge_ldata.rge_txq_considx;
+ if (free <= idx)
+ free += RGE_TX_LIST_CNT;
+ free -= idx;
+
+ for (;;) {
+ if (RGE_TX_NSEGS >= free + 2) {
+ ifq_set_oactive(&ifp->if_snd);
+ break;
+ }
+
+ m = ifq_dequeue(ifq);
+ if (m == NULL)
+ break;
+
+ used = rge_encap(sc, m, idx);
+ if (used == 0) {
+ m_freem(m);
+ continue;
+ }
+
+ KASSERT(used <= free);
+ free -= used;
+
+#if NBPFILTER > 0
+ if (ifp->if_bpf)
+ bpf_mtap_ether(ifp->if_bpf, m, BPF_DIRECTION_OUT);
+#endif
+
+ idx += used;
+ if (idx >= RGE_TX_LIST_CNT)
+ idx -= RGE_TX_LIST_CNT;
+
+ queued++;
+ }
+
+ if (queued == 0)
+ return;
+
+ /* Set a timeout in case the chip goes out to lunch. */
+ ifp->if_timer = 5;
+
+ sc->rge_ldata.rge_txq_prodidx = idx;
+ ifq_serialize(ifq, &sc->sc_task);
+}
+
+void
+rge_watchdog(struct ifnet *ifp)
+{
+ struct rge_softc *sc = ifp->if_softc;
+
+ printf("%s: watchdog timeout\n", sc->sc_dev.dv_xname);
+ ifp->if_oerrors++;
+
+ rge_init(ifp);
+}
+
+int
+rge_init(struct ifnet *ifp)
+{
+ struct rge_softc *sc = ifp->if_softc;
+ uint32_t val;
+ uint16_t max_frame_size;
+ int i;
+
+ rge_stop(ifp);
+
+ /* Set MAC address. */
+ rge_set_macaddr(sc, sc->sc_arpcom.ac_enaddr);
+
+ /* Set Maximum frame size but don't let MTU be lass than ETHER_MTU. */
+ if (ifp->if_mtu < ETHERMTU)
+ max_frame_size = ETHERMTU;
+ else
+ max_frame_size = ifp->if_mtu;
+
+ max_frame_size += ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN +
+ ETHER_CRC_LEN + 1;
+
+ if (max_frame_size > RGE_JUMBO_FRAMELEN)
+ max_frame_size -= 1;
+
+ RGE_WRITE_2(sc, RGE_RXMAXSIZE, max_frame_size);
+
+ /* Initialize RX descriptors list. */
+ if (rge_rx_list_init(sc) == ENOBUFS) {
+ printf("%s: init failed: no memory for RX buffers\n",
+ sc->sc_dev.dv_xname);
+ rge_stop(ifp);
+ return (ENOBUFS);
+ }
+
+ /* Initialize TX descriptors. */
+ rge_tx_list_init(sc);
+
+ /* Load the addresses of the RX and TX lists into the chip. */
+ RGE_WRITE_4(sc, RGE_RXDESC_ADDR_LO,
+ RGE_ADDR_LO(sc->rge_ldata.rge_rx_list_map->dm_segs[0].ds_addr));
+ RGE_WRITE_4(sc, RGE_RXDESC_ADDR_HI,
+ RGE_ADDR_HI(sc->rge_ldata.rge_rx_list_map->dm_segs[0].ds_addr));
+ RGE_WRITE_4(sc, RGE_TXDESC_ADDR_LO,
+ RGE_ADDR_LO(sc->rge_ldata.rge_tx_list_map->dm_segs[0].ds_addr));
+ RGE_WRITE_4(sc, RGE_TXDESC_ADDR_HI,
+ RGE_ADDR_HI(sc->rge_ldata.rge_tx_list_map->dm_segs[0].ds_addr));
+
+ RGE_SETBIT_1(sc, RGE_EECMD, RGE_EECMD_WRITECFG);
+
+ RGE_CLRBIT_1(sc, 0xf1, 0x80);
+ RGE_CLRBIT_1(sc, RGE_CFG2, RGE_CFG2_CLKREQ_EN);
+ RGE_CLRBIT_1(sc, RGE_CFG5, RGE_CFG5_PME_STS);
+ RGE_CLRBIT_1(sc, RGE_CFG3, RGE_CFG3_RDY_TO_L23);
+
+ /* Clear interrupt moderation timer. */
+ for (i = 0; i < 64; i++)
+ RGE_WRITE_4(sc, RGE_IM(i), 0);
+
+ /* Set the initial RX and TX and configurations. */
+ RGE_WRITE_4(sc, RGE_RXCFG, RGE_RXCFG_CONFIG);
+ RGE_WRITE_4(sc, RGE_TXCFG, RGE_TXCFG_CONFIG);
+
+ val = rge_read_csi(sc, 0x70c) & ~0xff000000;
+ rge_write_csi(sc, 0x70c, val | 0x27000000);
+
+ /* Enable hardware optimization function. */
+ val = pci_conf_read(sc->sc_pc, sc->sc_tag, 0x78) & ~0x00007000;
+ pci_conf_write(sc->sc_pc, sc->sc_tag, 0x78, val | 0x00005000);
+
+ RGE_WRITE_2(sc, 0x0382, 0x221b);
+ RGE_WRITE_1(sc, 0x4500, 0);
+ RGE_WRITE_2(sc, 0x4800, 0);
+ RGE_CLRBIT_1(sc, RGE_CFG1, RGE_CFG1_SPEED_DOWN);
+
+ rge_write_mac_ocp(sc, 0xc140, 0xffff);
+ rge_write_mac_ocp(sc, 0xc142, 0xffff);
+
+ val = rge_read_mac_ocp(sc, 0xd3e2) & ~0x0fff;
+ rge_write_mac_ocp(sc, 0xd3e2, val | 0x03a9);
+
+ RGE_MAC_CLRBIT(sc, 0xd3e4, 0x00ff);
+ RGE_MAC_SETBIT(sc, 0xe860, 0x0080);
+ RGE_MAC_SETBIT(sc, 0xeb58, 0x0001);
+
+ val = rge_read_mac_ocp(sc, 0xe614) & ~0x0700;
+ rge_write_mac_ocp(sc, 0xe614, val | 0x0400);
+
+ RGE_MAC_CLRBIT(sc, 0xe63e, 0x0c00);
+
+ val = rge_read_mac_ocp(sc, 0xe63e) & ~0x0030;
+ rge_write_mac_ocp(sc, 0xe63e, val | 0x0020);
+
+ RGE_MAC_SETBIT(sc, 0xc0b4, 0x000c);
+
+ val = rge_read_mac_ocp(sc, 0xeb6a) & ~0x007f;
+ rge_write_mac_ocp(sc, 0xeb6a, val | 0x0033);
+
+ val = rge_read_mac_ocp(sc, 0xeb50) & ~0x03e0;
+ rge_write_mac_ocp(sc, 0xeb50, val | 0x0040);
+
+ val = rge_read_mac_ocp(sc, 0xe056) & ~0x00f0;
+ rge_write_mac_ocp(sc, 0xe056, val | 0x0030);
+
+ RGE_WRITE_1(sc, RGE_TDFNR, 0x10);
+
+ RGE_MAC_CLRBIT(sc, 0xe040, 0x1000);
+
+ val = rge_read_mac_ocp(sc, 0xe0c0) & ~0x4f0f;
+ rge_write_mac_ocp(sc, 0xe0c0, val | 0x4403);
+
+ RGE_MAC_SETBIT(sc, 0xe052, 0x0068);
+ RGE_MAC_CLRBIT(sc, 0xe052, 0x0080);
+
+ val = rge_read_mac_ocp(sc, 0xc0ac) & ~0x0080;
+ rge_write_mac_ocp(sc, 0xc0ac, val | 0x1f00);
+
+ val = rge_read_mac_ocp(sc, 0xd430) & ~0x0fff;
+ rge_write_mac_ocp(sc, 0xd430, val | 0x047f);
+
+ RGE_MAC_SETBIT(sc, 0xe84c, 0x00c0);
+
+ /* Disable EEE plus. */
+ RGE_MAC_CLRBIT(sc, 0xe080, 0x0002);
+
+ RGE_MAC_CLRBIT(sc, 0xea1c, 0x0004);
+
+ RGE_MAC_SETBIT(sc, 0xeb54, 0x0001);
+ DELAY(1);
+ RGE_MAC_CLRBIT(sc, 0xeb54, 0x0001);
+
+ RGE_CLRBIT_4(sc, 0x1880, 0x0030);
+
+ rge_write_mac_ocp(sc, 0xe098, 0xc302);
+
+ if (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING)
+ RGE_SETBIT_4(sc, RGE_RXCFG, RGE_RXCFG_VLANSTRIP);
+
+ RGE_SETBIT_2(sc, RGE_CPLUSCMD, RGE_CPLUSCMD_RXCSUM);
+
+ for (i = 0; i < 10; i++) {
+ if (!(rge_read_mac_ocp(sc, 0xe00e) & 0x2000))
+ break;
+ DELAY(1000);
+ }
+
+ /* Disable RXDV gate. */
+ RGE_CLRBIT_1(sc, RGE_PPSW, 0x08);
+ DELAY(2000);
+
+ rge_ifmedia_upd(ifp);
+
+ /* Enable transmit and receive. */
+ RGE_WRITE_1(sc, RGE_CMD, RGE_CMD_TXENB | RGE_CMD_RXENB);
+
+ /* Program promiscuous mode and multicast filters. */
+ rge_iff(sc);
+
+ RGE_CLRBIT_1(sc, RGE_CFG2, RGE_CFG2_CLKREQ_EN);
+ RGE_CLRBIT_1(sc, RGE_CFG5, RGE_CFG5_PME_STS);
+
+ RGE_CLRBIT_1(sc, RGE_EECMD, RGE_EECMD_WRITECFG);
+
+ /* Enable interrupts. */
+ rge_setup_intr(sc, RGE_IMTYPE_SIM);
+
+ ifp->if_flags |= IFF_RUNNING;
+ ifq_clr_oactive(&ifp->if_snd);
+
+ timeout_add_sec(&sc->sc_timeout, 1);
+
+ return (0);
+}
+
+/*
+ * Stop the adapter and free any mbufs allocated to the RX and TX lists.
+ */
+void
+rge_stop(struct ifnet *ifp)
+{
+ struct rge_softc *sc = ifp->if_softc;
+ int i;
+
+ timeout_del(&sc->sc_timeout);
+
+ ifp->if_timer = 0;
+ ifp->if_flags &= ~IFF_RUNNING;
+ sc->rge_timerintr = 0;
+
+ RGE_CLRBIT_4(sc, RGE_RXCFG, RGE_RXCFG_ALLPHYS | RGE_RXCFG_INDIV |
+ RGE_RXCFG_MULTI | RGE_RXCFG_BROAD | RGE_RXCFG_RUNT |
+ RGE_RXCFG_ERRPKT);
+
+ RGE_WRITE_4(sc, RGE_IMR, 0);
+ RGE_WRITE_4(sc, RGE_ISR, 0xffffffff);
+
+ rge_reset(sc);
+
+ intr_barrier(sc->sc_ih);
+ ifq_barrier(&ifp->if_snd);
+ ifq_clr_oactive(&ifp->if_snd);
+
+ if (sc->rge_head != NULL) {
+ m_freem(sc->rge_head);
+ sc->rge_head = sc->rge_tail = NULL;
+ }
+
+ /* Free the TX list buffers. */
+ for (i = 0; i < RGE_TX_LIST_CNT; i++) {
+ if (sc->rge_ldata.rge_txq[i].txq_mbuf != NULL) {
+ bus_dmamap_unload(sc->sc_dmat,
+ sc->rge_ldata.rge_txq[i].txq_dmamap);
+ m_freem(sc->rge_ldata.rge_txq[i].txq_mbuf);
+ sc->rge_ldata.rge_txq[i].txq_mbuf = NULL;
+ }
+ }
+
+ /* Free the RX list buffers. */
+ for (i = 0; i < RGE_RX_LIST_CNT; i++) {
+ if (sc->rge_ldata.rge_rxq[i].rxq_mbuf != NULL) {
+ bus_dmamap_unload(sc->sc_dmat,
+ sc->rge_ldata.rge_rxq[i].rxq_dmamap);
+ m_freem(sc->rge_ldata.rge_rxq[i].rxq_mbuf);
+ sc->rge_ldata.rge_rxq[i].rxq_mbuf = NULL;
+ }
+ }
+}
+
+/*
+ * Set media options.
+ */
+int
+rge_ifmedia_upd(struct ifnet *ifp)
+{
+ struct rge_softc *sc = ifp->if_softc;
+ struct ifmedia *ifm = &sc->sc_media;
+ int anar, gig, val;
+
+ if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
+ return (EINVAL);
+
+ /* Disable Gigabit Lite. */
+ RGE_PHY_CLRBIT(sc, 0xa428, 0x0200);
+ RGE_PHY_CLRBIT(sc, 0xa5ea, 0x0001);
+
+ val = rge_read_phy_ocp(sc, 0xa5d4);
+ val &= ~RGE_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;
+ val |= RGE_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;
+ val |= RGE_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->sc_dev.dv_xname);
+ return (EINVAL);
+ }
+
+ rge_write_phy(sc, 0, MII_ANAR, anar | ANAR_PAUSE_ASYM | ANAR_FC);
+ rge_write_phy(sc, 0, MII_100T2CR, gig);
+ rge_write_phy_ocp(sc, 0xa5d4, val);
+ rge_write_phy(sc, 0, MII_BMCR, BMCR_AUTOEN | BMCR_STARTNEG);
+
+ return (0);
+}
+
+/*
+ * Report current media status.
+ */
+void
+rge_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
+{
+ struct rge_softc *sc = ifp->if_softc;
+ uint16_t status = 0;
+
+ ifmr->ifm_status = IFM_AVALID;
+ ifmr->ifm_active = IFM_ETHER;
+
+ if (rge_get_link_status(sc)) {
+ ifmr->ifm_status |= IFM_ACTIVE;
+
+ status = RGE_READ_2(sc, RGE_PHYSTAT);
+ if ((status & RGE_PHYSTAT_FDX) ||
+ (status & RGE_PHYSTAT_2500MBPS))
+ ifmr->ifm_active |= IFM_FDX;
+ else
+ ifmr->ifm_active |= IFM_HDX;
+
+ if (status & RGE_PHYSTAT_10MBPS)
+ ifmr->ifm_active |= IFM_10_T;
+ else if (status & RGE_PHYSTAT_100MBPS)
+ ifmr->ifm_active |= IFM_100_TX;
+ else if (status & RGE_PHYSTAT_1000MBPS)
+ ifmr->ifm_active |= IFM_1000_T;
+ else if (status & RGE_PHYSTAT_2500MBPS)
+ ifmr->ifm_active |= IFM_2500_T;
+ }
+}
+
+/*
+ * Allocate memory for RX/TX rings.
+ */
+int
+rge_allocmem(struct rge_softc *sc)
+{
+ int error, i;
+
+ /* Allocate DMA'able memory for the TX ring. */
+ error = bus_dmamap_create(sc->sc_dmat, RGE_TX_LIST_SZ, 1,
+ RGE_TX_LIST_SZ, 0, BUS_DMA_NOWAIT, &sc->rge_ldata.rge_tx_list_map);
+ if (error) {
+ printf("%s: can't create TX list map\n", sc->sc_dev.dv_xname);
+ return (error);
+ }
+ error = bus_dmamem_alloc(sc->sc_dmat, RGE_TX_LIST_SZ, RGE_ALIGN, 0,
+ &sc->rge_ldata.rge_tx_listseg, 1, &sc->rge_ldata.rge_tx_listnseg,
+ BUS_DMA_NOWAIT| BUS_DMA_ZERO);
+ if (error) {
+ printf("%s: can't alloc TX list\n", sc->sc_dev.dv_xname);
+ return (error);
+ }
+
+ /* Load the map for the TX ring. */
+ error = bus_dmamem_map(sc->sc_dmat, &sc->rge_ldata.rge_tx_listseg,
+ sc->rge_ldata.rge_tx_listnseg, RGE_TX_LIST_SZ,
+ (caddr_t *)&sc->rge_ldata.rge_tx_list,
+ BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
+ if (error) {
+ printf("%s: can't map TX dma buffers\n", sc->sc_dev.dv_xname);
+ bus_dmamem_free(sc->sc_dmat, &sc->rge_ldata.rge_tx_listseg,
+ sc->rge_ldata.rge_tx_listnseg);
+ return (error);
+ }
+ error = bus_dmamap_load(sc->sc_dmat, sc->rge_ldata.rge_tx_list_map,
+ sc->rge_ldata.rge_tx_list, RGE_TX_LIST_SZ, NULL, BUS_DMA_NOWAIT);
+ if (error) {
+ printf("%s: can't load TX dma map\n", sc->sc_dev.dv_xname);
+ bus_dmamap_destroy(sc->sc_dmat, sc->rge_ldata.rge_tx_list_map);
+ bus_dmamem_unmap(sc->sc_dmat,
+ (caddr_t)sc->rge_ldata.rge_tx_list, RGE_TX_LIST_SZ);
+ bus_dmamem_free(sc->sc_dmat, &sc->rge_ldata.rge_tx_listseg,
+ sc->rge_ldata.rge_tx_listnseg);
+ return (error);
+ }
+
+ /* Create DMA maps for TX buffers. */
+ for (i = 0; i < RGE_TX_LIST_CNT; i++) {
+ error = bus_dmamap_create(sc->sc_dmat, RGE_JUMBO_FRAMELEN,
+ RGE_TX_NSEGS, RGE_JUMBO_FRAMELEN, 0, 0,
+ &sc->rge_ldata.rge_txq[i].txq_dmamap);
+ if (error) {
+ printf("%s: can't create DMA map for TX\n",
+ sc->sc_dev.dv_xname);
+ return (error);
+ }
+ }
+
+ /* Allocate DMA'able memory for the RX ring. */
+ error = bus_dmamap_create(sc->sc_dmat, RGE_RX_LIST_SZ, 1,
+ RGE_RX_LIST_SZ, 0, 0, &sc->rge_ldata.rge_rx_list_map);
+ if (error) {
+ printf("%s: can't create RX list map\n", sc->sc_dev.dv_xname);
+ return (error);
+ }
+ error = bus_dmamem_alloc(sc->sc_dmat, RGE_RX_LIST_SZ, RGE_ALIGN, 0,
+ &sc->rge_ldata.rge_rx_listseg, 1, &sc->rge_ldata.rge_rx_listnseg,
+ BUS_DMA_NOWAIT| BUS_DMA_ZERO);
+ if (error) {
+ printf("%s: can't alloc RX list\n", sc->sc_dev.dv_xname);
+ return (error);
+ }
+
+ /* Load the map for the RX ring. */
+ error = bus_dmamem_map(sc->sc_dmat, &sc->rge_ldata.rge_rx_listseg,
+ sc->rge_ldata.rge_rx_listnseg, RGE_RX_LIST_SZ,
+ (caddr_t *)&sc->rge_ldata.rge_rx_list,
+ BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
+ if (error) {
+ printf("%s: can't map RX dma buffers\n", sc->sc_dev.dv_xname);
+ bus_dmamem_free(sc->sc_dmat, &sc->rge_ldata.rge_rx_listseg,
+ sc->rge_ldata.rge_rx_listnseg);
+ return (error);
+ }
+ error = bus_dmamap_load(sc->sc_dmat, sc->rge_ldata.rge_rx_list_map,
+ sc->rge_ldata.rge_rx_list, RGE_RX_LIST_SZ, NULL, BUS_DMA_NOWAIT);
+ if (error) {
+ printf("%s: can't load RX dma map\n", sc->sc_dev.dv_xname);
+ bus_dmamap_destroy(sc->sc_dmat, sc->rge_ldata.rge_rx_list_map);
+ bus_dmamem_unmap(sc->sc_dmat,
+ (caddr_t)sc->rge_ldata.rge_rx_list, RGE_RX_LIST_SZ);
+ bus_dmamem_free(sc->sc_dmat, &sc->rge_ldata.rge_rx_listseg,
+ sc->rge_ldata.rge_rx_listnseg);
+ return (error);
+ }
+
+ /* Create DMA maps for RX buffers. */
+ for (i = 0; i < RGE_RX_LIST_CNT; i++) {
+ error = bus_dmamap_create(sc->sc_dmat, RGE_JUMBO_FRAMELEN, 1,
+ RGE_JUMBO_FRAMELEN, 0, 0,
+ &sc->rge_ldata.rge_rxq[i].rxq_dmamap);
+ if (error) {
+ printf("%s: can't create DMA map for RX\n",
+ sc->sc_dev.dv_xname);
+ return (error);
+ }
+ }
+
+ return (error);
+}
+
+/*
+ * Initialize the RX descriptor and attach an mbuf cluster.
+ */
+int
+rge_newbuf(struct rge_softc *sc, int idx)
+{
+ struct mbuf *m;
+ struct rge_rx_desc *r;
+ struct rge_rxq *rxq;
+ bus_dmamap_t rxmap;
+
+ m = MCLGETI(NULL, M_DONTWAIT, NULL, RGE_JUMBO_FRAMELEN);
+ if (m == NULL)
+ return (ENOBUFS);
+
+ m->m_len = m->m_pkthdr.len = RGE_JUMBO_FRAMELEN;
+
+ rxq = &sc->rge_ldata.rge_rxq[idx];
+ rxmap = rxq->rxq_dmamap;
+
+ if (bus_dmamap_load_mbuf(sc->sc_dmat, rxmap, m, BUS_DMA_NOWAIT))
+ goto out;
+
+ bus_dmamap_sync(sc->sc_dmat, rxmap, 0, rxmap->dm_mapsize,
+ BUS_DMASYNC_PREREAD);
+
+ /* Map the segments into RX descriptors. */
+ r = &sc->rge_ldata.rge_rx_list[idx];
+
+ if (RGE_OWN(r)) {
+ printf("%s: tried to map busy RX descriptor\n",
+ sc->sc_dev.dv_xname);
+ goto out;
+ }
+
+ rxq->rxq_mbuf = m;
+
+ r->rge_extsts = 0;
+ r->rge_addrlo = htole32(RGE_ADDR_LO(rxmap->dm_segs[0].ds_addr));
+ r->rge_addrhi = htole32(RGE_ADDR_HI(rxmap->dm_segs[0].ds_addr));
+
+ r->rge_cmdsts = htole32(rxmap->dm_segs[0].ds_len);
+ if (idx == RGE_RX_LIST_CNT - 1)
+ r->rge_cmdsts |= htole32(RGE_RDCMDSTS_EOR);
+
+ r->rge_cmdsts |= htole32(RGE_RDCMDSTS_OWN);
+
+ bus_dmamap_sync(sc->sc_dmat, sc->rge_ldata.rge_rx_list_map,
+ idx * sizeof(struct rge_rx_desc), sizeof(struct rge_rx_desc),
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
+ return (0);
+out:
+ if (m != NULL)
+ m_freem(m);
+ return (ENOMEM);
+}
+
+void
+rge_discard_rxbuf(struct rge_softc *sc, int idx)
+{
+ struct rge_rx_desc *r;
+
+ r = &sc->rge_ldata.rge_rx_list[idx];
+
+ r->rge_cmdsts = htole32(RGE_JUMBO_FRAMELEN);
+ r->rge_extsts = 0;
+ if (idx == RGE_RX_LIST_CNT - 1)
+ r->rge_cmdsts |= htole32(RGE_RDCMDSTS_EOR);
+ r->rge_cmdsts |= htole32(RGE_RDCMDSTS_OWN);
+
+ bus_dmamap_sync(sc->sc_dmat, sc->rge_ldata.rge_rx_list_map,
+ idx * sizeof(struct rge_rx_desc), sizeof(struct rge_rx_desc),
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+}
+
+int
+rge_rx_list_init(struct rge_softc *sc)
+{
+ int i;
+
+ memset(sc->rge_ldata.rge_rx_list, 0, RGE_RX_LIST_SZ);
+
+ for (i = 0; i < RGE_RX_LIST_CNT; i++) {
+ sc->rge_ldata.rge_rxq[i].rxq_mbuf = NULL;
+ if (rge_newbuf(sc, i) == ENOBUFS)
+ return (ENOBUFS);
+ }
+
+ sc->rge_ldata.rge_rxq_prodidx = 0;
+ sc->rge_head = sc->rge_tail = NULL;
+
+ return (0);
+}
+
+void
+rge_tx_list_init(struct rge_softc *sc)
+{
+ int i;
+
+ memset(sc->rge_ldata.rge_tx_list, 0, RGE_TX_LIST_SZ);
+
+ for (i = 0; i < RGE_TX_LIST_CNT; i++)
+ sc->rge_ldata.rge_txq[i].txq_mbuf = NULL;
+
+ bus_dmamap_sync(sc->sc_dmat, sc->rge_ldata.rge_tx_list_map, 0,
+ sc->rge_ldata.rge_tx_list_map->dm_mapsize,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
+ sc->rge_ldata.rge_txq_prodidx = sc->rge_ldata.rge_txq_considx = 0;
+}
+
+int
+rge_rxeof(struct rge_softc *sc)
+{
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
+ struct mbuf *m;
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+ struct rge_rx_desc *cur_rx;
+ struct rge_rxq *rxq;
+ uint32_t rxstat, extsts;
+ int i, total_len, rx = 0;
+
+ /* Invalidate the descriptor memory. */
+ bus_dmamap_sync(sc->sc_dmat, sc->rge_ldata.rge_rx_list_map,
+ i * sizeof(struct rge_rx_desc), sizeof(struct rge_rx_desc),
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+
+ for (i = sc->rge_ldata.rge_rxq_prodidx; ; i = RGE_NEXT_RX_DESC(i)) {
+ cur_rx = &sc->rge_ldata.rge_rx_list[i];
+
+ if (RGE_OWN(cur_rx))
+ break;
+
+ rxstat = letoh32(cur_rx->rge_cmdsts);
+ extsts = letoh32(cur_rx->rge_extsts);
+
+ total_len = RGE_RXBYTES(cur_rx);
+ rxq = &sc->rge_ldata.rge_rxq[i];
+ m = rxq->rxq_mbuf;
+ rx = 1;
+
+ /* Invalidate the RX mbuf and unload its map. */
+ bus_dmamap_sync(sc->sc_dmat, rxq->rxq_dmamap, 0,
+ rxq->rxq_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
+ bus_dmamap_unload(sc->sc_dmat, rxq->rxq_dmamap);
+
+ if ((rxstat & (RGE_RDCMDSTS_SOF | RGE_RDCMDSTS_EOF)) !=
+ (RGE_RDCMDSTS_SOF | RGE_RDCMDSTS_EOF)) {
+ rge_discard_rxbuf(sc, i);
+ continue;
+ }
+
+ if (rxstat & RGE_RDCMDSTS_RXERRSUM) {
+ ifp->if_ierrors++;
+ /*
+ * If this is part of a multi-fragment packet,
+ * discard all the pieces.
+ */
+ if (sc->rge_head != NULL) {
+ m_freem(sc->rge_head);
+ sc->rge_head = sc->rge_tail = NULL;
+ }
+ rge_discard_rxbuf(sc, i);
+ continue;
+ }
+
+ /*
+ * If allocating a replacement mbuf fails,
+ * reload the current one.
+ */
+
+ if (rge_newbuf(sc, i) == ENOBUFS) {
+ if (sc->rge_head != NULL) {
+ m_freem(sc->rge_head);
+ sc->rge_head = sc->rge_tail = NULL;
+ }
+ rge_discard_rxbuf(sc, i);
+ continue;
+ }
+
+ if (sc->rge_head != NULL) {
+ m->m_len = total_len;
+ /*
+ * Special case: if there's 4 bytes or less
+ * in this buffer, the mbuf can be discarded:
+ * the last 4 bytes is the CRC, which we don't
+ * care about anyway.
+ */
+ if (m->m_len <= ETHER_CRC_LEN) {
+ sc->rge_tail->m_len -=
+ (ETHER_CRC_LEN - m->m_len);
+ m_freem(m);
+ } else {
+ m->m_len -= ETHER_CRC_LEN;
+ m->m_flags &= ~M_PKTHDR;
+ sc->rge_tail->m_next = m;
+ }
+ m = sc->rge_head;
+ sc->rge_head = sc->rge_tail = NULL;
+ m->m_pkthdr.len = total_len - ETHER_CRC_LEN;
+ } else
+ m->m_pkthdr.len = m->m_len =
+ (total_len - ETHER_CRC_LEN);
+
+ /* Check IP header checksum. */
+ if (!(rxstat & RGE_RDCMDSTS_IPCSUMERR) &&
+ (extsts & RGE_RDEXTSTS_IPV4))
+ m->m_pkthdr.csum_flags |= M_IPV4_CSUM_IN_OK;
+
+ /* Check TCP/UDP checksum. */
+ if ((extsts & (RGE_RDEXTSTS_IPV4 | RGE_RDEXTSTS_IPV6)) &&
+ (((rxstat & RGE_RDCMDSTS_TCPPKT) &&
+ !(rxstat & RGE_RDCMDSTS_TCPCSUMERR)) ||
+ ((rxstat & RGE_RDCMDSTS_UDPPKT) &&
+ !(rxstat & RGE_RDCMDSTS_UDPCSUMERR))))
+ m->m_pkthdr.csum_flags |= M_TCP_CSUM_IN_OK |
+ M_UDP_CSUM_IN_OK;
+
+#if NVLAN > 0
+ if (extsts & RGE_RDEXTSTS_VTAG) {
+ m->m_pkthdr.ether_vtag =
+ ntohs(extsts & RGE_RDEXTSTS_VLAN_MASK);
+ m->m_flags |= M_VLANTAG;
+ }
+#endif
+
+ ml_enqueue(&ml, m);
+ }
+
+ sc->rge_ldata.rge_rxq_prodidx = i;
+
+ if_input(ifp, &ml);
+
+ return (rx);
+}
+
+int
+rge_txeof(struct rge_softc *sc)
+{
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+ struct rge_txq *txq;
+ uint32_t txstat;
+ int cons, idx, prod;
+ int free = 0;
+
+ prod = sc->rge_ldata.rge_txq_prodidx;
+ cons = sc->rge_ldata.rge_txq_considx;
+
+ bus_dmamap_sync(sc->sc_dmat, sc->rge_ldata.rge_tx_list_map,
+ idx * sizeof(struct rge_tx_desc), sizeof(struct rge_tx_desc),
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+
+ while (prod != cons) {
+ txq = &sc->rge_ldata.rge_txq[cons];
+ idx = txq->txq_descidx;
+
+ txstat = letoh32(sc->rge_ldata.rge_tx_list[idx].rge_cmdsts);
+
+ if (txstat & RGE_TDCMDSTS_OWN) {
+ free = 2;
+ break;
+ }
+
+ bus_dmamap_sync(sc->sc_dmat, txq->txq_dmamap, 0,
+ txq->txq_dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(sc->sc_dmat, txq->txq_dmamap);
+ m_freem(txq->txq_mbuf);
+ txq->txq_mbuf = NULL;
+
+ if (txstat & (RGE_TDCMDSTS_EXCESSCOLL | RGE_TDCMDSTS_COLL))
+ ifp->if_collisions++;
+ if (txstat & RGE_TDCMDSTS_TXERR)
+ ifp->if_oerrors++;
+
+ bus_dmamap_sync(sc->sc_dmat, sc->rge_ldata.rge_tx_list_map,
+ idx * sizeof(struct rge_tx_desc),
+ sizeof(struct rge_tx_desc),
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
+ cons = RGE_NEXT_TX_DESC(idx);
+ free = 1;
+ }
+
+ if (free == 0)
+ return (0);
+
+ sc->rge_ldata.rge_txq_considx = cons;
+
+ if (ifq_is_oactive(&ifp->if_snd))
+ ifq_restart(&ifp->if_snd);
+ else if (free == 2)
+ ifq_serialize(&ifp->if_snd, &sc->sc_task);
+ else
+ ifp->if_timer = 0;
+
+ return (1);
+}
+
+void
+rge_reset(struct rge_softc *sc)
+{
+ int i;
+
+ /* Enable RXDV gate. */
+ RGE_SETBIT_1(sc, RGE_PPSW, 0x08);
+ DELAY(2000);
+
+ for (i = 0; i < 10; i++) {
+ DELAY(100);
+ if ((RGE_READ_1(sc, RGE_MCUCMD) & (RGE_MCUCMD_RXFIFO_EMPTY |
+ RGE_MCUCMD_TXFIFO_EMPTY)) == (RGE_MCUCMD_RXFIFO_EMPTY |
+ RGE_MCUCMD_TXFIFO_EMPTY))
+ break;
+ }
+
+ /* Soft reset. */
+ RGE_WRITE_1(sc, RGE_CMD, RGE_CMD_RESET);
+
+ for (i = 0; i < RGE_TIMEOUT; i++) {
+ DELAY(100);
+ if (!(RGE_READ_1(sc, RGE_CMD) & RGE_CMD_RESET))
+ break;
+ }
+ if (i == RGE_TIMEOUT)
+ printf("%s: reset never completed!\n", sc->sc_dev.dv_xname);
+}
+
+void
+rge_iff(struct rge_softc *sc)
+{
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+ struct arpcom *ac = &sc->sc_arpcom;
+ struct ether_multi *enm;
+ struct ether_multistep step;
+ uint32_t hashes[2];
+ uint32_t rxfilt;
+ int h = 0;
+
+ rxfilt = RGE_READ_4(sc, RGE_RXCFG);
+ rxfilt &= ~(RGE_RXCFG_ALLPHYS | RGE_RXCFG_MULTI);
+ ifp->if_flags &= ~IFF_ALLMULTI;
+
+ /*
+ * Always accept frames destined to our station address.
+ * Always accept broadcast frames.
+ */
+ rxfilt |= RGE_RXCFG_INDIV | RGE_RXCFG_BROAD;
+
+ if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) {
+ ifp->if_flags |= IFF_ALLMULTI;
+ rxfilt |= RGE_RXCFG_MULTI;
+ if (ifp->if_flags & IFF_PROMISC)
+ rxfilt |= RGE_RXCFG_ALLPHYS;
+ hashes[0] = hashes[1] = 0xffffffff;
+ } else {
+ rxfilt |= RGE_RXCFG_MULTI;
+ /* Program new filter. */
+ memset(hashes, 0, sizeof(hashes));
+
+ ETHER_FIRST_MULTI(step, ac, enm);
+ while (enm != NULL) {
+ h = ether_crc32_be(enm->enm_addrlo,
+ ETHER_ADDR_LEN) >> 26;
+
+ if (h < 32)
+ hashes[0] |= (1 << h);
+ else
+ hashes[1] |= (1 << (h - 32));
+
+ ETHER_NEXT_MULTI(step, enm);
+ }
+ }
+
+ RGE_WRITE_4(sc, RGE_RXCFG, rxfilt);
+ RGE_WRITE_4(sc, RGE_MAR0, swap32(hashes[1]));
+ RGE_WRITE_4(sc, RGE_MAR4, swap32(hashes[0]));
+}
+
+void
+rge_set_phy_power(struct rge_softc *sc, int on)
+{
+ int i;
+
+ if (on) {
+ RGE_SETBIT_1(sc, RGE_PMCH, 0xc0);
+
+ rge_write_phy(sc, 0, MII_BMCR, BMCR_AUTOEN);
+
+ for (i = 0; i < RGE_TIMEOUT; i++) {
+ if ((rge_read_phy_ocp(sc, 0xa420) & 0x0080) == 3)
+ break;
+ DELAY(1000);
+ }
+ } else
+ rge_write_phy(sc, 0, MII_BMCR, BMCR_AUTOEN | BMCR_PDOWN);
+}
+
+void
+rge_phy_config(struct rge_softc *sc)
+{
+ uint16_t mcode_ver, val;
+ int i;
+ static const uint16_t mac_cfg3_a438_value[] =
+ { 0x0043, 0x00a7, 0x00d6, 0x00ec, 0x00f6, 0x00fb, 0x00fd, 0x00ff,
+ 0x00bb, 0x0058, 0x0029, 0x0013, 0x0009, 0x0004, 0x0002 };
+
+ static const uint16_t mac_cfg3_b88e_value[] =
+ { 0xc091, 0x6e12, 0xc092, 0x1214, 0xc094, 0x1516, 0xc096, 0x171b,
+ 0xc098, 0x1b1c, 0xc09a, 0x1f1f, 0xc09c, 0x2021, 0xc09e, 0x2224,
+ 0xc0a0, 0x2424, 0xc0a2, 0x2424, 0xc0a4, 0x2424, 0xc018, 0x0af2,
+ 0xc01a, 0x0d4a, 0xc01c, 0x0f26, 0xc01e, 0x118d, 0xc020, 0x14f3,
+ 0xc022, 0x175a, 0xc024, 0x19c0, 0xc026, 0x1c26, 0xc089, 0x6050,
+ 0xc08a, 0x5f6e, 0xc08c, 0x6e6e, 0xc08e, 0x6e6e, 0xc090, 0x6e12 };
+
+ /* Read microcode version. */
+ rge_write_phy_ocp(sc, 0xa436, 0x801e);
+ mcode_ver = rge_read_phy_ocp(sc, 0xa438);
+
+ if (sc->rge_type == MAC_CFG2) {
+ for (i = 0; i < nitems(rtl8125_mac_cfg2_ephy); i++) {
+ rge_write_ephy(sc, rtl8125_mac_cfg2_ephy[i].reg,
+ rtl8125_mac_cfg2_ephy[i].val);
+ }
+
+ if (mcode_ver != RGE_MAC_CFG2_MCODE_VER) {
+ /* Disable PHY config. */
+ RGE_CLRBIT_1(sc, 0xf2, 0x20);
+ DELAY(1000);
+
+ rge_patch_phy_mcu(sc, 1);
+
+ rge_write_phy_ocp(sc, 0xa436, 0x8024);
+ rge_write_phy_ocp(sc, 0xa438, 0x8600);
+ rge_write_phy_ocp(sc, 0xa436, 0xb82e);
+ rge_write_phy_ocp(sc, 0xa438, 0x0001);
+
+ RGE_PHY_SETBIT(sc, 0xb820, 0x0080);
+ for (i = 0; i < nitems(rtl8125_mac_cfg2_mcu); i++) {
+ rge_write_phy_ocp(sc,
+ rtl8125_mac_cfg2_mcu[i].reg,
+ rtl8125_mac_cfg2_mcu[i].val);
+ }
+ RGE_PHY_CLRBIT(sc, 0xb820, 0x0080);
+
+ rge_write_phy_ocp(sc, 0xa436, 0);
+ rge_write_phy_ocp(sc, 0xa438, 0);
+ RGE_PHY_CLRBIT(sc, 0xb82e, 0x0001);
+ rge_write_phy_ocp(sc, 0xa436, 0x8024);
+ rge_write_phy_ocp(sc, 0xa438, 0);
+
+ rge_patch_phy_mcu(sc, 0);
+
+ /* Enable PHY config. */
+ RGE_SETBIT_1(sc, 0xf2, 0x20);
+
+ /* Write microcode version. */
+ rge_write_phy_ocp(sc, 0xa436, 0x801e);
+ rge_write_phy_ocp(sc, 0xa438, RGE_MAC_CFG2_MCODE_VER);
+ }
+
+ val = rge_read_phy_ocp(sc, 0xad40) & ~0x03ff;
+ rge_write_phy_ocp(sc, 0xad40, val | 0x0084);
+ RGE_PHY_SETBIT(sc, 0xad4e, 0x0010);
+ val = rge_read_phy_ocp(sc, 0xad16) & ~0x03ff;
+ rge_write_phy_ocp(sc, 0xad16, val | 0x0006);
+ val = rge_read_phy_ocp(sc, 0xad32) & ~0x03ff;
+ rge_write_phy_ocp(sc, 0xad32, val | 0x0006);
+ RGE_PHY_CLRBIT(sc, 0xac08, 0x1100);
+ val = rge_read_phy_ocp(sc, 0xac8a) & ~0xf000;
+ rge_write_phy_ocp(sc, 0xac8a, val | 0x7000);
+ RGE_PHY_SETBIT(sc, 0xad18, 0x0400);
+ RGE_PHY_SETBIT(sc, 0xad1a, 0x03ff);
+ RGE_PHY_SETBIT(sc, 0xad1c, 0x03ff);
+
+ rge_write_phy_ocp(sc, 0xa436, 0x80ea);
+ val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
+ rge_write_phy_ocp(sc, 0xa438, val | 0xc400);
+ rge_write_phy_ocp(sc, 0xa436, 0x80eb);
+ val = rge_read_phy_ocp(sc, 0xa438) & ~0x0700;
+ rge_write_phy_ocp(sc, 0xa438, val | 0x0300);
+ rge_write_phy_ocp(sc, 0xa436, 0x80f8);
+ val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
+ rge_write_phy_ocp(sc, 0xa438, val | 0x1c00);
+ rge_write_phy_ocp(sc, 0xa436, 0x80f1);
+ val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
+ rge_write_phy_ocp(sc, 0xa438, val | 0x3000);
+ rge_write_phy_ocp(sc, 0xa436, 0x80fe);
+ val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
+ rge_write_phy_ocp(sc, 0xa438, val | 0xa500);
+ rge_write_phy_ocp(sc, 0xa436, 0x8102);
+ val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
+ rge_write_phy_ocp(sc, 0xa438, val | 0x5000);
+ rge_write_phy_ocp(sc, 0xa436, 0x8105);
+ val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
+ rge_write_phy_ocp(sc, 0xa438, val | 0x3300);
+ rge_write_phy_ocp(sc, 0xa436, 0x8100);
+ val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
+ rge_write_phy_ocp(sc, 0xa438, val | 0x7000);
+ rge_write_phy_ocp(sc, 0xa436, 0x8104);
+ val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
+ rge_write_phy_ocp(sc, 0xa438, val | 0xf000);
+ rge_write_phy_ocp(sc, 0xa436, 0x8106);
+ val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
+ rge_write_phy_ocp(sc, 0xa438, val | 0x6500);
+ rge_write_phy_ocp(sc, 0xa436, 0x80dc);
+ val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
+ rge_write_phy_ocp(sc, 0xa438, val | 0xed00);
+ rge_write_phy_ocp(sc, 0xa436, 0x80df);
+ RGE_PHY_SETBIT(sc, 0xa438, 0x0100);
+ rge_write_phy_ocp(sc, 0xa436, 0x80e1);
+ RGE_PHY_CLRBIT(sc, 0xa438, 0x0100);
+ val = rge_read_phy_ocp(sc, 0xbf06) & ~0x003f;
+ rge_write_phy_ocp(sc, 0xbf06, val | 0x0038);
+ rge_write_phy_ocp(sc, 0xa436, 0x819f);
+ rge_write_phy_ocp(sc, 0xa438, 0xd0b6);
+ rge_write_phy_ocp(sc, 0xbc34, 0x5555);
+ val = rge_read_phy_ocp(sc, 0xbf0a) & ~0x0e00;
+ rge_write_phy_ocp(sc, 0xbf0a, val | 0x0a00);
+ RGE_PHY_CLRBIT(sc, 0xa5c0, 0x0400);
+ RGE_PHY_SETBIT(sc, 0xa442, 0x0800);
+ } else {
+ for (i = 0; i < nitems(rtl8125_mac_cfg3_ephy); i++)
+ rge_write_ephy(sc, rtl8125_mac_cfg3_ephy[i].reg,
+ rtl8125_mac_cfg3_ephy[i].val);
+
+ if (mcode_ver != RGE_MAC_CFG3_MCODE_VER) {
+ /* Disable PHY config. */
+ RGE_CLRBIT_1(sc, 0xf2, 0x20);
+ DELAY(1000);
+
+ rge_patch_phy_mcu(sc, 1);
+
+ rge_write_phy_ocp(sc, 0xa436, 0x8024);
+ rge_write_phy_ocp(sc, 0xa438, 0x8601);
+ rge_write_phy_ocp(sc, 0xa436, 0xb82e);
+ rge_write_phy_ocp(sc, 0xa438, 0x0001);
+
+ RGE_PHY_SETBIT(sc, 0xb820, 0x0080);
+ for (i = 0; i < nitems(rtl8125_mac_cfg3_mcu); i++) {
+ rge_write_phy_ocp(sc,
+ rtl8125_mac_cfg3_mcu[i].reg,
+ rtl8125_mac_cfg3_mcu[i].val);
+ }
+ RGE_PHY_CLRBIT(sc, 0xb820, 0x0080);
+
+ rge_write_phy_ocp(sc, 0xa436, 0);
+ rge_write_phy_ocp(sc, 0xa438, 0);
+ RGE_PHY_CLRBIT(sc, 0xb82e, 0x0001);
+ rge_write_phy_ocp(sc, 0xa436, 0x8024);
+ rge_write_phy_ocp(sc, 0xa438, 0);
+
+ rge_patch_phy_mcu(sc, 0);
+
+ /* Enable PHY config. */
+ RGE_SETBIT_1(sc, 0xf2, 0x20);
+
+ /* Write microcode version. */
+ rge_write_phy_ocp(sc, 0xa436, 0x801e);
+ rge_write_phy_ocp(sc, 0xa438, RGE_MAC_CFG3_MCODE_VER);
+ }
+
+ RGE_PHY_SETBIT(sc, 0xad4e, 0x0010);
+ val = rge_read_phy_ocp(sc, 0xad16) & ~0x03ff;
+ rge_write_phy_ocp(sc, 0xad16, val | 0x03ff);
+ val = rge_read_phy_ocp(sc, 0xad32) & ~0x003f;
+ rge_write_phy_ocp(sc, 0xad32, val | 0x0006);
+ RGE_PHY_CLRBIT(sc, 0xac08, 0x1000);
+ RGE_PHY_CLRBIT(sc, 0xac08, 0x0100);
+ val = rge_read_phy_ocp(sc, 0xacc0) & ~0x0003;
+ rge_write_phy_ocp(sc, 0xacc0, val | 0x0002);
+ val = rge_read_phy_ocp(sc, 0xad40) & ~0x00e0;
+ rge_write_phy_ocp(sc, 0xad40, val | 0x0040);
+ val = rge_read_phy_ocp(sc, 0xad40) & ~0x0007;
+ rge_write_phy_ocp(sc, 0xad40, val | 0x0004);
+ RGE_PHY_CLRBIT(sc, 0xac14, 0x0080);
+ RGE_PHY_CLRBIT(sc, 0xac80, 0x0300);
+ val = rge_read_phy_ocp(sc, 0xac5e) & ~0x0007;
+ rge_write_phy_ocp(sc, 0xac5e, val | 0x0002);
+ rge_write_phy_ocp(sc, 0xad4c, 0x00a8);
+ rge_write_phy_ocp(sc, 0xac5c, 0x01ff);
+ val = rge_read_phy_ocp(sc, 0xac8a) & ~0x00f0;
+ rge_write_phy_ocp(sc, 0xac8a, val | 0x0030);
+ rge_write_phy_ocp(sc, 0xb87c, 0x80a2);
+ rge_write_phy_ocp(sc, 0xb87e, 0x0153);
+ rge_write_phy_ocp(sc, 0xb87c, 0x809c);
+ rge_write_phy_ocp(sc, 0xb87e, 0x0153);
+
+ rge_write_phy_ocp(sc, 0xa436, 0x81b3);
+ for (i = 0; i < nitems(mac_cfg3_a438_value); i++)
+ rge_write_phy_ocp(sc, 0xa438, mac_cfg3_a438_value[i]);
+ for (i = 0; i < 26; i++)
+ rge_write_phy_ocp(sc, 0xa438, 0);
+ rge_write_phy_ocp(sc, 0xa436, 0x8257);
+ rge_write_phy_ocp(sc, 0xa438, 0x020f);
+ rge_write_phy_ocp(sc, 0xa436, 0x80ea);
+ rge_write_phy_ocp(sc, 0xa438, 0x7843);
+
+ rge_patch_phy_mcu(sc, 1);
+ RGE_PHY_CLRBIT(sc, 0xb896, 0x0001);
+ RGE_PHY_CLRBIT(sc, 0xb892, 0xff00);
+ for (i = 0; i < nitems(mac_cfg3_b88e_value); i += 2) {
+ rge_write_phy_ocp(sc, 0xb88e, mac_cfg3_b88e_value[i]);
+ rge_write_phy_ocp(sc, 0xb890,
+ mac_cfg3_b88e_value[i + 1]);
+ }
+ RGE_PHY_SETBIT(sc, 0xb896, 0x0001);
+ rge_patch_phy_mcu(sc, 0);
+
+ RGE_PHY_SETBIT(sc, 0xd068, 0x2000);
+ rge_write_phy_ocp(sc, 0xa436, 0x81a2);
+ RGE_PHY_SETBIT(sc, 0xa438, 0x0100);
+ val = rge_read_phy_ocp(sc, 0xb54c) & ~0xff00;
+ rge_write_phy_ocp(sc, 0xb54c, val | 0xdb00);
+ RGE_PHY_CLRBIT(sc, 0xa454, 0x0001);
+ RGE_PHY_SETBIT(sc, 0xa5d4, 0x0020);
+ RGE_PHY_CLRBIT(sc, 0xad4e, 0x0010);
+ RGE_PHY_CLRBIT(sc, 0xa86a, 0x0001);
+ RGE_PHY_SETBIT(sc, 0xa442, 0x0800);
+ }
+
+ /* Disable EEE. */
+ RGE_MAC_CLRBIT(sc, 0xe040, 0x0003);
+ RGE_MAC_CLRBIT(sc, 0xeb62, 0x0006);
+ RGE_PHY_CLRBIT(sc, 0xa432, 0x0010);
+ RGE_PHY_CLRBIT(sc, 0xa5d0, 0x0006);
+ RGE_PHY_CLRBIT(sc, 0xa6d4, 0x0001);
+ RGE_PHY_CLRBIT(sc, 0xa6d8, 0x0010);
+ RGE_PHY_CLRBIT(sc, 0xa428, 0x0080);
+ RGE_PHY_CLRBIT(sc, 0xa4a2, 0x0200);
+
+ rge_patch_phy_mcu(sc, 1);
+ RGE_MAC_CLRBIT(sc, 0xe052, 0x0001);
+ RGE_PHY_CLRBIT(sc, 0xa442, 0x3000);
+ RGE_PHY_CLRBIT(sc, 0xa430, 0x8000);
+ rge_patch_phy_mcu(sc, 0);
+}
+
+void
+rge_set_macaddr(struct rge_softc *sc, const uint8_t *addr)
+{
+ RGE_SETBIT_1(sc, RGE_EECMD, RGE_EECMD_WRITECFG);
+ RGE_WRITE_4(sc, RGE_MAC0,
+ addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0]);
+ RGE_WRITE_4(sc, RGE_MAC4,
+ addr[5] << 8 | addr[4]);
+ RGE_CLRBIT_1(sc, RGE_EECMD, RGE_EECMD_WRITECFG);
+}
+
+void
+rge_get_macaddr(struct rge_softc *sc, uint8_t *addr)
+{
+ *(uint32_t *)&addr[0] = RGE_READ_4(sc, RGE_ADDR0);
+ *(uint16_t *)&addr[4] = RGE_READ_2(sc, RGE_ADDR1);
+}
+
+void
+rge_hw_init(struct rge_softc *sc)
+{
+ int i;
+
+ RGE_SETBIT_1(sc, RGE_EECMD, RGE_EECMD_WRITECFG);
+ RGE_CLRBIT_1(sc, RGE_CFG5, RGE_CFG5_PME_STS);
+ RGE_CLRBIT_1(sc, RGE_CFG2, RGE_CFG2_CLKREQ_EN);
+ RGE_CLRBIT_1(sc, RGE_EECMD, RGE_EECMD_WRITECFG);
+ RGE_CLRBIT_1(sc, 0xf1, 0x80);
+
+ /* Disable UPS. */
+ RGE_MAC_CLRBIT(sc, 0xd40a, 0x0010);
+
+ /* Configure MAC MCU. */
+ rge_write_mac_ocp(sc, 0xfc38, 0);
+
+ for (i = 0xfc28; i < 0xfc38; i += 2)
+ rge_write_mac_ocp(sc, i, 0);
+
+ DELAY(3000);
+ rge_write_mac_ocp(sc, 0xfc26, 0);
+
+ if (sc->rge_type == MAC_CFG3) {
+ for (i = 0; i < nitems(rtl8125_def_bps); i++)
+ rge_write_mac_ocp(sc, rtl8125_def_bps[i].reg,
+ rtl8125_def_bps[i].val);
+ }
+
+ /* Disable PHY power saving. */
+ rge_disable_phy_ocp_pwrsave(sc);
+
+ /* Set PCIe uncorrectable error status. */
+ rge_write_csi(sc, 0x108,
+ rge_read_csi(sc, 0x108) | 0x00100000);
+}
+
+void
+rge_disable_phy_ocp_pwrsave(struct rge_softc *sc)
+{
+ if (rge_read_phy_ocp(sc, 0xc416) != 0x0500) {
+ rge_patch_phy_mcu(sc, 1);
+ rge_write_phy_ocp(sc, 0xc416, 0);
+ rge_write_phy_ocp(sc, 0xc416, 0x0500);
+ rge_patch_phy_mcu(sc, 0);
+ }
+}
+
+void
+rge_patch_phy_mcu(struct rge_softc *sc, int set)
+{
+ uint16_t val;
+ int i;
+
+ if (set)
+ RGE_PHY_SETBIT(sc, 0xb820, 0x0010);
+ else
+ RGE_PHY_CLRBIT(sc, 0xb820, 0x0010);
+
+ for (i = 0; i < 1000; i++) {
+ val = rge_read_phy_ocp(sc, 0xb800) & 0x0040;
+ DELAY(100);
+ if (val == 0x0040)
+ break;
+ }
+ if (i == 1000)
+ printf("%s: timeout waiting to patch phy mcu\n",
+ sc->sc_dev.dv_xname);
+}
+
+void
+rge_add_media_types(struct rge_softc *sc)
+{
+ ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_10_T, 0, NULL);
+ ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_10_T | IFM_FDX, 0, NULL);
+ ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_100_TX, 0, NULL);
+ ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_100_TX | IFM_FDX, 0, NULL);
+ ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_1000_T, 0, NULL);
+ ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_1000_T | IFM_FDX, 0, NULL);
+ ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_2500_T, 0, NULL);
+ ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_2500_T | IFM_FDX, 0, NULL);
+}
+
+void
+rge_config_imtype(struct rge_softc *sc, int imtype)
+{
+ switch (imtype) {
+ case RGE_IMTYPE_NONE:
+ sc->rge_intrs = RGE_INTRS;
+ sc->rge_rx_ack = RGE_ISR_RX_OK | RGE_ISR_RX_DESC_UNAVAIL |
+ RGE_ISR_RX_FIFO_OFLOW;
+ sc->rge_tx_ack = RGE_ISR_TX_OK;
+ break;
+ case RGE_IMTYPE_SIM:
+ sc->rge_intrs = RGE_INTRS_TIMER;
+ sc->rge_rx_ack = RGE_ISR_PCS_TIMEOUT;
+ sc->rge_tx_ack = RGE_ISR_PCS_TIMEOUT;
+ break;
+ default:
+ panic("%s: unknown imtype %d", sc->sc_dev.dv_xname, imtype);
+ }
+}
+
+void
+rge_disable_sim_im(struct rge_softc *sc)
+{
+ RGE_WRITE_4(sc, RGE_TIMERINT, 0);
+ sc->rge_timerintr = 0;
+}
+
+void
+rge_setup_sim_im(struct rge_softc *sc)
+{
+ RGE_WRITE_4(sc, RGE_TIMERINT, 0x2600);
+ RGE_WRITE_4(sc, RGE_TIMERCNT, 1);
+ sc->rge_timerintr = 1;
+}
+
+void
+rge_setup_intr(struct rge_softc *sc, int imtype)
+{
+ rge_config_imtype(sc, imtype);
+
+ /* Enable interrupts. */
+ RGE_WRITE_4(sc, RGE_IMR, sc->rge_intrs);
+
+ switch (imtype) {
+ case RGE_IMTYPE_NONE:
+ rge_disable_sim_im(sc);
+ break;
+ case RGE_IMTYPE_SIM:
+ rge_setup_sim_im(sc);
+ break;
+ default:
+ panic("%s: unknown imtype %d", sc->sc_dev.dv_xname, imtype);
+ }
+}
+
+void
+rge_exit_oob(struct rge_softc *sc)
+{
+ int i;
+
+ RGE_CLRBIT_4(sc, RGE_RXCFG, RGE_RXCFG_ALLPHYS | RGE_RXCFG_INDIV |
+ RGE_RXCFG_MULTI | RGE_RXCFG_BROAD | RGE_RXCFG_RUNT |
+ RGE_RXCFG_ERRPKT);
+
+ /* Disable RealWoW. */
+ rge_write_mac_ocp(sc, 0xc0bc, 0x00ff);
+
+ rge_reset(sc);
+
+ /* Disable OOB. */
+ RGE_CLRBIT_1(sc, RGE_MCUCMD, RGE_MCUCMD_IS_OOB);
+
+ RGE_MAC_CLRBIT(sc, 0xe8de, 0x4000);
+
+ for (i = 0; i < 10; i++) {
+ DELAY(100);
+ if (RGE_READ_2(sc, RGE_TWICMD) & 0x0200)
+ break;
+ }
+
+ rge_write_mac_ocp(sc, 0xc0aa, 0x07d0);
+ rge_write_mac_ocp(sc, 0xc0a6, 0x0150);
+ rge_write_mac_ocp(sc, 0xc01e, 0x5555);
+
+ for (i = 0; i < 10; i++) {
+ DELAY(100);
+ if (RGE_READ_2(sc, RGE_TWICMD) & 0x0200)
+ break;
+ }
+
+ if (rge_read_mac_ocp(sc, 0xd42c) & 0x0100) {
+ for (i = 0; i < RGE_TIMEOUT; i++) {
+ if ((rge_read_phy_ocp(sc, 0xa420) & 0x0080) == 2)
+ break;
+ DELAY(1000);
+ }
+ RGE_MAC_CLRBIT(sc, 0xd408, 0x0100);
+ RGE_PHY_CLRBIT(sc, 0xa468, 0x000a);
+ }
+}
+
+void
+rge_write_csi(struct rge_softc *sc, uint32_t reg, uint32_t val)
+{
+ int i;
+
+ RGE_WRITE_4(sc, RGE_CSIDR, val);
+ RGE_WRITE_4(sc, RGE_CSIAR, (1 << 16) | (reg & RGE_CSIAR_ADDR_MASK) |
+ (RGE_CSIAR_BYTE_EN << RGE_CSIAR_BYTE_EN_SHIFT) | RGE_CSIAR_BUSY);
+
+ for (i = 0; i < 10; i++) {
+ DELAY(100);
+ if (!(RGE_READ_4(sc, RGE_CSIAR) & RGE_CSIAR_BUSY))
+ break;
+ }
+
+ DELAY(20);
+}
+
+uint32_t
+rge_read_csi(struct rge_softc *sc, uint32_t reg)
+{
+ int i;
+
+ RGE_WRITE_4(sc, RGE_CSIAR, (1 << 16) | (reg & RGE_CSIAR_ADDR_MASK) |
+ (RGE_CSIAR_BYTE_EN << RGE_CSIAR_BYTE_EN_SHIFT));
+
+ for (i = 0; i < 10; i++) {
+ DELAY(100);
+ if (RGE_READ_4(sc, RGE_CSIAR) & RGE_CSIAR_BUSY)
+ break;
+ }
+
+ DELAY(20);
+
+ return (RGE_READ_4(sc, RGE_CSIDR));
+}
+
+void
+rge_write_mac_ocp(struct rge_softc *sc, uint16_t reg, uint16_t val)
+{
+ uint32_t tmp;
+
+ tmp = (reg >> 1) << RGE_MACOCP_ADDR_SHIFT;
+ tmp += val;
+ tmp |= RGE_MACOCP_BUSY;
+ RGE_WRITE_4(sc, RGE_MACOCP, tmp);
+}
+
+uint16_t
+rge_read_mac_ocp(struct rge_softc *sc, uint16_t reg)
+{
+ uint32_t val;
+
+ val = (reg >> 1) << RGE_MACOCP_ADDR_SHIFT;
+ RGE_WRITE_4(sc, RGE_MACOCP, val);
+
+ return (RGE_READ_4(sc, RGE_MACOCP) & RGE_MACOCP_DATA_MASK);
+}
+
+void
+rge_write_ephy(struct rge_softc *sc, uint16_t reg, uint16_t val)
+{
+ uint32_t tmp;
+ int i;
+
+ tmp = (reg & RGE_EPHYAR_ADDR_MASK) << RGE_EPHYAR_ADDR_SHIFT;
+ tmp |= RGE_EPHYAR_BUSY | (val & RGE_EPHYAR_DATA_MASK);
+ RGE_WRITE_4(sc, RGE_EPHYAR, tmp);
+
+ for (i = 0; i < 10; i++) {
+ DELAY(100);
+ if (!(RGE_READ_4(sc, RGE_EPHYAR) & RGE_EPHYAR_BUSY))
+ break;
+ }
+
+ DELAY(20);
+}
+
+void
+rge_write_phy(struct rge_softc *sc, uint16_t addr, uint16_t reg, uint16_t val)
+{
+ uint16_t off, phyaddr;
+
+ phyaddr = addr ? addr : RGE_PHYBASE + (reg / 8);
+ phyaddr <<= 4;
+
+ off = addr ? reg : 0x10 + (reg % 8);
+
+ phyaddr += (off - 16) << 1;
+
+ rge_write_phy_ocp(sc, phyaddr, val);
+}
+
+void
+rge_write_phy_ocp(struct rge_softc *sc, uint16_t reg, uint16_t val)
+{
+ uint32_t tmp;
+ int i;
+
+ tmp = (reg >> 1) << RGE_PHYOCP_ADDR_SHIFT;
+ tmp |= RGE_PHYOCP_BUSY | val;
+ RGE_WRITE_4(sc, RGE_PHYOCP, tmp);
+
+ for (i = 0; i < RGE_TIMEOUT; i++) {
+ DELAY(1);
+ if (!(RGE_READ_4(sc, RGE_PHYOCP) & RGE_PHYOCP_BUSY))
+ break;
+ }
+}
+
+uint16_t
+rge_read_phy_ocp(struct rge_softc *sc, uint16_t reg)
+{
+ uint32_t val;
+ int i;
+
+ val = (reg >> 1) << RGE_PHYOCP_ADDR_SHIFT;
+ RGE_WRITE_4(sc, RGE_PHYOCP, val);
+
+ for (i = 0; i < RGE_TIMEOUT; i++) {
+ DELAY(1);
+ val = RGE_READ_4(sc, RGE_PHYOCP);
+ if (val & RGE_PHYOCP_BUSY)
+ break;
+ }
+
+ return (val & RGE_PHYOCP_DATA_MASK);
+}
+
+int
+rge_get_link_status(struct rge_softc *sc)
+{
+ return ((RGE_READ_2(sc, RGE_PHYSTAT) & RGE_PHYSTAT_LINK) ? 1 : 0);
+}
+
+void
+rge_txstart(void *arg)
+{
+ struct rge_softc *sc = arg;
+
+ RGE_WRITE_2(sc, RGE_TXSTART, RGE_TXSTART_START);
+}
+
+void
+rge_tick(void *arg)
+{
+ struct rge_softc *sc = arg;
+ int s;
+
+ s = splnet();
+ rge_link_state(sc);
+ splx(s);
+
+ timeout_add_sec(&sc->sc_timeout, 1);
+}
+
+void
+rge_link_state(struct rge_softc *sc)
+{
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+ int link = LINK_STATE_DOWN;
+
+ if (rge_get_link_status(sc))
+ link = LINK_STATE_UP;
+
+ if (ifp->if_link_state != link) {
+ ifp->if_link_state = link;
+ if_link_state_change(ifp);
+ }
+}
diff --git a/sys/dev/pci/if_rgereg.h b/sys/dev/pci/if_rgereg.h
new file mode 100644
index 00000000000..17287d1fb20
--- /dev/null
+++ b/sys/dev/pci/if_rgereg.h
@@ -0,0 +1,1863 @@
+/* $OpenBSD: if_rgereg.h,v 1.1 2019/11/18 03:03:37 kevlo Exp $ */
+
+/*
+ * Copyright (c) 2019 Kevin Lo <kevlo@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define RGE_PCI_BAR0 PCI_MAPREG_START
+#define RGE_PCI_BAR1 (PCI_MAPREG_START + 4)
+#define RGE_PCI_BAR2 (PCI_MAPREG_START + 8)
+
+#define RGE_MAC0 0x0000
+#define RGE_MAC4 0x0004
+#define RGE_MAR0 0x0008
+#define RGE_MAR4 0x000c
+#define RGE_TXDESC_ADDR_LO 0x0020
+#define RGE_TXDESC_ADDR_HI 0x0024
+#define RGE_CMD 0x0037
+#define RGE_IMR 0x0038
+#define RGE_ISR 0x003c
+#define RGE_TXCFG 0x0040
+#define RGE_RXCFG 0x0044
+#define RGE_TIMERCNT 0x0048
+#define RGE_EECMD 0x0050
+#define RGE_CFG0 0x0051
+#define RGE_CFG1 0x0052
+#define RGE_CFG2 0x0053
+#define RGE_CFG3 0x0054
+#define RGE_CFG4 0x0055
+#define RGE_CFG5 0x0056
+#define RGE_TDFNR 0x0057
+#define RGE_TIMERINT 0x0058
+#define RGE_CSIDR 0x0064
+#define RGE_CSIAR 0x0068
+#define RGE_PHYSTAT 0x006c
+#define RGE_PMCH 0x006f
+#define RGE_EPHYAR 0x0080
+#define RGE_TXSTART 0x0090
+#define RGE_MACOCP 0x00b0
+#define RGE_PHYOCP 0x00b8
+#define RGE_TWICMD 0x00d2
+#define RGE_MCUCMD 0x00d3
+#define RGE_RXMAXSIZE 0x00da
+#define RGE_CPLUSCMD 0x00e0
+#define RGE_RXDESC_ADDR_LO 0x00e4
+#define RGE_RXDESC_ADDR_HI 0x00e8
+#define RGE_PPSW 0x00f2
+#define RGE_IM(i) (0x0a00 + (i) * 4)
+#define RGE_PHYBASE 0x0a40
+#define RGE_ADDR0 0x19e0
+#define RGE_ADDR1 0x19e4
+
+/* Flags for register RGE_CMD */
+#define RGE_CMD_RXBUF_EMPTY 0x01
+#define RGE_CMD_TXENB 0x04
+#define RGE_CMD_RXENB 0x08
+#define RGE_CMD_RESET 0x10
+
+/* Flags for register RGE_ISR */
+#define RGE_ISR_RX_OK 0x00000001
+#define RGE_ISR_RX_ERR 0x00000002
+#define RGE_ISR_TX_OK 0x00000004
+#define RGE_ISR_TX_ERR 0x00000008
+#define RGE_ISR_RX_DESC_UNAVAIL 0x00000010
+#define RGE_ISR_LINKCHG 0x00000020
+#define RGE_ISR_RX_FIFO_OFLOW 0x00000040
+#define RGE_ISR_TX_DESC_UNAVAIL 0x00000080
+#define RGE_ISR_SWI 0x00000100
+#define RGE_ISR_PCS_TIMEOUT 0x00004000
+#define RGE_ISR_SYSTEM_ERR 0x00008000
+
+#define RGE_INTRS \
+ (RGE_ISR_RX_OK | RGE_ISR_RX_ERR | RGE_ISR_TX_OK | \
+ RGE_ISR_TX_ERR | RGE_ISR_RX_DESC_UNAVAIL | \
+ RGE_ISR_RX_FIFO_OFLOW | RGE_ISR_SYSTEM_ERR)
+
+#define RGE_INTRS_TIMER \
+ (RGE_ISR_RX_ERR | RGE_ISR_TX_ERR | RGE_ISR_PCS_TIMEOUT | \
+ RGE_ISR_SYSTEM_ERR)
+
+/* Flags for register RGE_TXCFG */
+#define RGE_TXCFG_HWREV 0x7cf00000
+
+/* Flags for register RGE_RXCFG */
+#define RGE_RXCFG_ALLPHYS 0x00000001
+#define RGE_RXCFG_INDIV 0x00000002
+#define RGE_RXCFG_MULTI 0x00000004
+#define RGE_RXCFG_BROAD 0x00000008
+#define RGE_RXCFG_RUNT 0x00000010
+#define RGE_RXCFG_ERRPKT 0x00000020
+#define RGE_RXCFG_VLANSTRIP 0x00c00000
+
+/* Flags for register RGE_EECMD */
+#define RGE_EECMD_WRITECFG 0xc0
+
+/* Flags for register RGE_CFG1 */
+#define RGE_CFG1_SPEED_DOWN 0x10
+
+/* Flags for register RGE_CFG2 */
+#define RGE_CFG2_CLKREQ_EN 0x80
+
+/* Flags for register RGE_CFG3 */
+#define RGE_CFG3_RDY_TO_L23 0x02
+
+/* Flags for register RGE_CFG5 */
+#define RGE_CFG5_PME_STS 0x01
+
+/* Flags for register RGE_CSIAR */
+#define RGE_CSIAR_BYTE_EN 0x0000000f
+#define RGE_CSIAR_BYTE_EN_SHIFT 12
+#define RGE_CSIAR_ADDR_MASK 0x00000fff
+#define RGE_CSIAR_BUSY 0x80000000
+
+/* Flags for register RGE_PHYSTAT */
+#define RGE_PHYSTAT_FDX 0x0001
+#define RGE_PHYSTAT_LINK 0x0002
+#define RGE_PHYSTAT_10MBPS 0x0004
+#define RGE_PHYSTAT_100MBPS 0x0008
+#define RGE_PHYSTAT_1000MBPS 0x0010
+#define RGE_PHYSTAT_RXFLOW 0x0020
+#define RGE_PHYSTAT_TXFLOW 0x0040
+#define RGE_PHYSTAT_2500MBPS 0x0400
+
+/* Flags for register RGE_EPHYAR */
+#define RGE_EPHYAR_DATA_MASK 0x0000ffff
+#define RGE_EPHYAR_BUSY 0x80000000
+#define RGE_EPHYAR_ADDR_MASK 0x0000007f
+#define RGE_EPHYAR_ADDR_SHIFT 16
+
+/* Flags for register RGE_TXSTART */
+#define RGE_TXSTART_START 0x0001
+
+/* Flags for register RGE_MACOCP */
+#define RGE_MACOCP_DATA_MASK 0x0000ffff
+#define RGE_MACOCP_BUSY 0x80000000
+#define RGE_MACOCP_ADDR_SHIFT 16
+
+/* Flags for register RGE_PHYOCP */
+#define RGE_PHYOCP_DATA_MASK 0x0000ffff
+#define RGE_PHYOCP_BUSY 0x80000000
+#define RGE_PHYOCP_ADDR_SHIFT 16
+
+/* Flags for register RGE_MCUCMD */
+#define RGE_MCUCMD_RXFIFO_EMPTY 0x10
+#define RGE_MCUCMD_TXFIFO_EMPTY 0x20
+#define RGE_MCUCMD_IS_OOB 0x80
+
+/* Flags for register RGE_CPLUSCMD */
+#define RGE_CPLUSCMD_RXCSUM 0x0020
+
+#define RGE_TX_NSEGS 32
+#define RGE_TX_LIST_CNT 1024
+#define RGE_RX_LIST_CNT 1024
+#define RGE_ALIGN 256
+#define RGE_TX_LIST_SZ (sizeof(struct rge_tx_desc) * RGE_TX_LIST_CNT)
+#define RGE_RX_LIST_SZ (sizeof(struct rge_rx_desc) * RGE_RX_LIST_CNT)
+#define RGE_NEXT_TX_DESC(x) (((x) + 1) % RGE_TX_LIST_CNT)
+#define RGE_NEXT_RX_DESC(x) (((x) + 1) % RGE_RX_LIST_CNT)
+#define RGE_ADDR_LO(y) ((uint64_t) (y) & 0xffffffff)
+#define RGE_ADDR_HI(y) ((uint64_t) (y) >> 32)
+#define RGE_OWN(x) (letoh32((x)->rge_cmdsts) & RGE_RDCMDSTS_OWN)
+#define RGE_RXBYTES(x) (letoh32((x)->rge_cmdsts) & \
+ RGE_RDCMDSTS_FRAGLEN)
+
+#define RGE_ADV_2500TFDX 0x0080
+
+/* Tx descriptor */
+struct rge_tx_desc {
+ uint32_t rge_cmdsts;
+ uint32_t rge_extsts;
+ uint32_t rge_addrlo;
+ uint32_t rge_addrhi;
+ uint32_t reserved[4];
+};
+
+#define RGE_TDCMDSTS_COLL 0x000f0000
+#define RGE_TDCMDSTS_EXCESSCOLL 0x00100000
+#define RGE_TDCMDSTS_TXERR 0x00800000
+#define RGE_TDCMDSTS_EOF 0x10000000
+#define RGE_TDCMDSTS_SOF 0x20000000
+#define RGE_TDCMDSTS_EOR 0x40000000
+#define RGE_TDCMDSTS_OWN 0x80000000
+
+#define RGE_TDEXTSTS_VTAG 0x00020000
+#define RGE_TDEXTSTS_IPCSUM 0x20000000
+#define RGE_TDEXTSTS_TCPCSUM 0x40000000
+#define RGE_TDEXTSTS_UDPCSUM 0x80000000
+
+/* Rx descriptor */
+struct rge_rx_desc {
+ uint32_t rge_cmdsts;
+ uint32_t rge_extsts;
+ uint32_t rge_addrlo;
+ uint32_t rge_addrhi;
+};
+
+#define RGE_RDCMDSTS_TCPCSUMERR 0x00004000
+#define RGE_RDCMDSTS_UDPCSUMERR 0x00008000
+#define RGE_RDCMDSTS_IPCSUMERR 0x00010000
+#define RGE_RDCMDSTS_TCPPKT 0x00020000
+#define RGE_RDCMDSTS_UDPPKT 0x00040000
+#define RGE_RDCMDSTS_RXERRSUM 0x00200000
+#define RGE_RDCMDSTS_EOF 0x10000000
+#define RGE_RDCMDSTS_SOF 0x20000000
+#define RGE_RDCMDSTS_EOR 0x40000000
+#define RGE_RDCMDSTS_OWN 0x80000000
+#define RGE_RDCMDSTS_FRAGLEN 0x00003fff
+
+#define RGE_RDEXTSTS_VTAG 0x00010000
+#define RGE_RDEXTSTS_VLAN_MASK 0x0000ffff
+#define RGE_RDEXTSTS_IPV4 0x40000000
+#define RGE_RDEXTSTS_IPV6 0x80000000
+
+struct rge_txq {
+ struct mbuf *txq_mbuf;
+ bus_dmamap_t txq_dmamap;
+ int txq_descidx;
+};
+
+struct rge_rxq {
+ struct mbuf *rxq_mbuf;
+ bus_dmamap_t rxq_dmamap;
+};
+
+struct rge_list_data {
+ struct rge_txq rge_txq[RGE_TX_LIST_CNT];
+ int rge_txq_prodidx;
+ int rge_txq_considx;
+ struct rge_rxq rge_rxq[RGE_RX_LIST_CNT];
+ int rge_rxq_prodidx;
+
+ bus_dma_segment_t rge_tx_listseg;
+ int rge_tx_listnseg;
+ bus_dmamap_t rge_tx_list_map;
+ struct rge_tx_desc *rge_tx_list;
+ bus_dma_segment_t rge_rx_listseg;
+ int rge_rx_listnseg;
+ bus_dmamap_t rge_rx_list_map;
+ struct rge_rx_desc *rge_rx_list;
+};
+
+/* Microcode version */
+#define RGE_MAC_CFG2_MCODE_VER 0x0b11
+#define RGE_MAC_CFG3_MCODE_VER 0x0b33
+
+enum rge_mac_type {
+ MAC_CFG_UNKNOWN = 1,
+ MAC_CFG2,
+ MAC_CFG3
+};
+
+#define RGE_TIMEOUT 100
+
+#define RGE_JUMBO_FRAMELEN 9216
+#define RGE_JUMBO_MTU \
+ (RGE_JUMBO_FRAMELEN - ETHER_HDR_LEN - ETHER_CRC_LEN - \
+ ETHER_VLAN_ENCAP_LEN)
+
+#define RGE_TXCFG_CONFIG 0x03000700
+#define RGE_RXCFG_CONFIG 0x40c00700
+
+struct rge_softc {
+ struct device sc_dev;
+ struct arpcom sc_arpcom; /* Ethernet common data */
+ void *sc_ih; /* interrupt vectoring */
+ bus_space_handle_t rge_bhandle; /* bus space handle */
+ bus_space_tag_t rge_btag; /* bus space tag */
+ bus_size_t rge_bsize;
+ bus_dma_tag_t sc_dmat;
+ pci_chipset_tag_t sc_pc;
+ pcitag_t sc_tag;
+ bus_dma_segment_t sc_rx_seg;
+ bus_dmamap_t sc_rx_dmamap;
+ struct ifmedia sc_media; /* media info */
+ enum rge_mac_type rge_type;
+ struct mbuf *rge_head;
+ struct mbuf *rge_tail;
+
+ struct rge_list_data rge_ldata;
+
+ struct task sc_task;
+
+ struct timeout sc_timeout; /* tick timeout */
+
+ uint32_t rge_flags;
+#define RGE_FLAG_MSI 0x00000001
+
+ uint32_t rge_intrs;
+ uint32_t rge_tx_ack;
+ uint32_t rge_rx_ack;
+ int rge_timerintr;
+
+#define RGE_IMTYPE_NONE 0
+#define RGE_IMTYPE_SIM 1
+};
+
+/*
+ * Register space access macros.
+ */
+#define RGE_WRITE_RAW_4(sc, reg, val) \
+ bus_space_write_raw_region_4(sc->rge_btag, sc->rge_bhandle, reg, val, 4)
+#define RGE_WRITE_4(sc, reg, val) \
+ bus_space_write_4(sc->rge_btag, sc->rge_bhandle, reg, val)
+#define RGE_WRITE_2(sc, reg, val) \
+ bus_space_write_2(sc->rge_btag, sc->rge_bhandle, reg, val)
+#define RGE_WRITE_1(sc, reg, val) \
+ bus_space_write_1(sc->rge_btag, sc->rge_bhandle, reg, val)
+
+#define RGE_READ_4(sc, reg) \
+ bus_space_read_4(sc->rge_btag, sc->rge_bhandle, reg)
+#define RGE_READ_2(sc, reg) \
+ bus_space_read_2(sc->rge_btag, sc->rge_bhandle, reg)
+#define RGE_READ_1(sc, reg) \
+ bus_space_read_1(sc->rge_btag, sc->rge_bhandle, reg)
+
+#define RGE_SETBIT_4(sc, reg, val) \
+ RGE_WRITE_4(sc, reg, RGE_READ_4(sc, reg) | (val))
+#define RGE_SETBIT_2(sc, reg, val) \
+ RGE_WRITE_2(sc, reg, RGE_READ_2(sc, reg) | (val))
+#define RGE_SETBIT_1(sc, reg, val) \
+ RGE_WRITE_1(sc, reg, RGE_READ_1(sc, reg) | (val))
+
+#define RGE_CLRBIT_4(sc, reg, val) \
+ RGE_WRITE_4(sc, reg, RGE_READ_4(sc, reg) & ~(val))
+#define RGE_CLRBIT_2(sc, reg, val) \
+ RGE_WRITE_2(sc, reg, RGE_READ_2(sc, reg) & ~(val))
+#define RGE_CLRBIT_1(sc, reg, val) \
+ RGE_WRITE_1(sc, reg, RGE_READ_1(sc, reg) & ~(val))
+
+#define RGE_PHY_SETBIT(sc, reg, val) \
+ rge_write_phy_ocp(sc, reg, rge_read_phy_ocp(sc, reg) | (val))
+
+#define RGE_PHY_CLRBIT(sc, reg, val) \
+ rge_write_phy_ocp(sc, reg, rge_read_phy_ocp(sc, reg) & ~(val))
+
+#define RGE_MAC_SETBIT(sc, reg, val) \
+ rge_write_mac_ocp(sc, reg, rge_read_mac_ocp(sc, reg) | (val))
+
+#define RGE_MAC_CLRBIT(sc, reg, val) \
+ rge_write_mac_ocp(sc, reg, rge_read_mac_ocp(sc, reg) & ~(val))
+
+#define RTL8125_DEF_BPS \
+ { 0xf800, 0xe008 }, \
+ { 0xf802, 0xe01e }, \
+ { 0xf804, 0xe02e }, \
+ { 0xf806, 0xe054 }, \
+ { 0xf808, 0xe057 }, \
+ { 0xf80a, 0xe059 }, \
+ { 0xf80c, 0xe05b }, \
+ { 0xf80e, 0xe05d }, \
+ { 0xf810, 0x9996 }, \
+ { 0xf812, 0x49d1 }, \
+ { 0xf814, 0xf005 }, \
+ { 0xf816, 0x49d4 }, \
+ { 0xf818, 0xf10a }, \
+ { 0xf81a, 0x49d8 }, \
+ { 0xf81c, 0xf108 }, \
+ { 0xf81e, 0xc00f }, \
+ { 0xf820, 0x7100 }, \
+ { 0xf822, 0x209c }, \
+ { 0xf824, 0x249c }, \
+ { 0xf826, 0xc009 }, \
+ { 0xf828, 0x9900 }, \
+ { 0xf82a, 0xe004 }, \
+ { 0xf82c, 0xc006 }, \
+ { 0xf82e, 0x1900 }, \
+ { 0xf830, 0x9900 }, \
+ { 0xf832, 0xc602 }, \
+ { 0xf834, 0xbe00 }, \
+ { 0xf836, 0x5a48 }, \
+ { 0xf838, 0xe0c2 }, \
+ { 0xf83a, 0x0004 }, \
+ { 0xf83c, 0xe10a }, \
+ { 0xf83e, 0xc60f }, \
+ { 0xf840, 0x73c4 }, \
+ { 0xf842, 0x49b3 }, \
+ { 0xf844, 0xf106 }, \
+ { 0xf846, 0x73c2 }, \
+ { 0xf848, 0xc608 }, \
+ { 0xf84a, 0xb406 }, \
+ { 0xf84c, 0xc609 }, \
+ { 0xf84e, 0xff80 }, \
+ { 0xf850, 0xc605 }, \
+ { 0xf852, 0xb406 }, \
+ { 0xf854, 0xc605 }, \
+ { 0xf856, 0xff80 }, \
+ { 0xf858, 0x0544 }, \
+ { 0xf85a, 0x0568 }, \
+ { 0xf85c, 0xe906 }, \
+ { 0xf85e, 0xcde8 }, \
+ { 0xf860, 0xc724 }, \
+ { 0xf862, 0xc624 }, \
+ { 0xf864, 0x9ee2 }, \
+ { 0xf866, 0x1e01 }, \
+ { 0xf868, 0x9ee0 }, \
+ { 0xf86a, 0x76e0 }, \
+ { 0xf86c, 0x49e0 }, \
+ { 0xf86e, 0xf1fe }, \
+ { 0xf870, 0x76e6 }, \
+ { 0xf872, 0x486d }, \
+ { 0xf874, 0x4868 }, \
+ { 0xf876, 0x9ee4 }, \
+ { 0xf878, 0x1e03 }, \
+ { 0xf87a, 0x9ee0 }, \
+ { 0xf87c, 0x76e0 }, \
+ { 0xf87e, 0x49e0 }, \
+ { 0xf880, 0xf1fe }, \
+ { 0xf882, 0xc615 }, \
+ { 0xf884, 0x9ee2 }, \
+ { 0xf886, 0x1e01 }, \
+ { 0xf888, 0x9ee0 }, \
+ { 0xf88a, 0x76e0 }, \
+ { 0xf88c, 0x49e0 }, \
+ { 0xf88e, 0xf1fe }, \
+ { 0xf890, 0x76e6 }, \
+ { 0xf892, 0x486f }, \
+ { 0xf894, 0x9ee4 }, \
+ { 0xf896, 0x1e03 }, \
+ { 0xf898, 0x9ee0 }, \
+ { 0xf89a, 0x76e0 }, \
+ { 0xf89c, 0x49e0 }, \
+ { 0xf89e, 0xf1fe }, \
+ { 0xf8a0, 0x7196 }, \
+ { 0xf8a2, 0xc702 }, \
+ { 0xf8a4, 0xbf00 }, \
+ { 0xf8a6, 0x5a44 }, \
+ { 0xf8a8, 0xeb0e }, \
+ { 0xf8aa, 0x0070 }, \
+ { 0xf8ac, 0x00c3 }, \
+ { 0xf8ae, 0x1bc0 }, \
+ { 0xf8b0, 0xc602 }, \
+ { 0xf8b2, 0xbe00 }, \
+ { 0xf8b4, 0x0e26 }, \
+ { 0xf8b6, 0xc602 }, \
+ { 0xf8b8, 0xbe00 }, \
+ { 0xf8ba, 0x0eba }, \
+ { 0xf8bc, 0xc602 }, \
+ { 0xf8be, 0xbe00 }, \
+ { 0xf8c0, 0x0000 }, \
+ { 0xf8c2, 0xc602 }, \
+ { 0xf8c4, 0xbe00 }, \
+ { 0xf8c6, 0x0000 }, \
+ { 0xf8c8, 0xc602 }, \
+ { 0xf8ca, 0xbe00 }, \
+ { 0xf8cc, 0x0000 }, \
+ { 0xfc26, 0x8000 }, \
+ { 0xfc2a, 0x0540 }, \
+ { 0xfc2e, 0x0e24 }, \
+ { 0xfc30, 0x0eb8 }, \
+ { 0xfc48, 0x001a }
+
+#define RTL8125_MAC_CFG2_EPHY \
+ { 0x0001, 0xa812 }, \
+ { 0x0009, 0x520c }, \
+ { 0x0004, 0xd000 }, \
+ { 0x000d, 0xf702 }, \
+ { 0x000a, 0x8653 }, \
+ { 0x0006, 0x001e }, \
+ { 0x0008, 0x3595 }, \
+ { 0x0020, 0x9455 }, \
+ { 0x0021, 0x99ff }, \
+ { 0x0002, 0x6046 }, \
+ { 0x0029, 0xfe00 }, \
+ { 0x0023, 0xab62 }, \
+ { 0x0041, 0xa80c }, \
+ { 0x0049, 0x520c }, \
+ { 0x0044, 0xd000 }, \
+ { 0x004d, 0xf702 }, \
+ { 0x004a, 0x8653 }, \
+ { 0x0046, 0x001e }, \
+ { 0x0048, 0x3595 }, \
+ { 0x0060, 0x9455 }, \
+ { 0x0061, 0x99ff }, \
+ { 0x0042, 0x6046 }, \
+ { 0x0069, 0xfe00 }, \
+ { 0x0063, 0xab62 }
+
+#define RTL8125_MAC_CFG3_EPHY \
+ { 0x0004, 0xd000 }, \
+ { 0x000a, 0x8653 }, \
+ { 0x0023, 0xab66 }, \
+ { 0x0020, 0x9455 }, \
+ { 0x0021, 0x99ff }, \
+ { 0x0029, 0xfe04 }, \
+ { 0x0044, 0xd000 }, \
+ { 0x004a, 0x8653 }, \
+ { 0x0063, 0xab66 }, \
+ { 0x0060, 0x9455 }, \
+ { 0x0061, 0x99ff }, \
+ { 0x0069, 0xfe04 }
+
+#define RTL8125_MAC_CFG2_MCU \
+ { 0xa436, 0xa016 }, \
+ { 0xa438, 0x0000 }, \
+ { 0xa436, 0xa012 }, \
+ { 0xa438, 0x0000 }, \
+ { 0xa436, 0xa014 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x8010 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x8013 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x8021 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x802f }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x803d }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x8042 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x8051 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x8051 }, \
+ { 0xa438, 0xa088 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0a50 }, \
+ { 0xa438, 0x8008 }, \
+ { 0xa438, 0xd014 }, \
+ { 0xa438, 0xd1a3 }, \
+ { 0xa438, 0xd700 }, \
+ { 0xa438, 0x401a }, \
+ { 0xa438, 0xd707 }, \
+ { 0xa438, 0x40c2 }, \
+ { 0xa438, 0x60a6 }, \
+ { 0xa438, 0xd700 }, \
+ { 0xa438, 0x5f8b }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0a86 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0a6c }, \
+ { 0xa438, 0x8080 }, \
+ { 0xa438, 0xd019 }, \
+ { 0xa438, 0xd1a2 }, \
+ { 0xa438, 0xd700 }, \
+ { 0xa438, 0x401a }, \
+ { 0xa438, 0xd707 }, \
+ { 0xa438, 0x40c4 }, \
+ { 0xa438, 0x60a6 }, \
+ { 0xa438, 0xd700 }, \
+ { 0xa438, 0x5f8b }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0a86 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0a84 }, \
+ { 0xa438, 0xd503 }, \
+ { 0xa438, 0x8970 }, \
+ { 0xa438, 0x0c07 }, \
+ { 0xa438, 0x0901 }, \
+ { 0xa438, 0xd500 }, \
+ { 0xa438, 0xce01 }, \
+ { 0xa438, 0xcf09 }, \
+ { 0xa438, 0xd705 }, \
+ { 0xa438, 0x4000 }, \
+ { 0xa438, 0xceff }, \
+ { 0xa438, 0xaf0a }, \
+ { 0xa438, 0xd504 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x1213 }, \
+ { 0xa438, 0x8401 }, \
+ { 0xa438, 0xd500 }, \
+ { 0xa438, 0x8580 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x1253 }, \
+ { 0xa438, 0xd064 }, \
+ { 0xa438, 0xd181 }, \
+ { 0xa438, 0xd704 }, \
+ { 0xa438, 0x4018 }, \
+ { 0xa438, 0xd504 }, \
+ { 0xa438, 0xc50f }, \
+ { 0xa438, 0xd706 }, \
+ { 0xa438, 0x2c59 }, \
+ { 0xa438, 0x804d }, \
+ { 0xa438, 0xc60f }, \
+ { 0xa438, 0xf002 }, \
+ { 0xa438, 0xc605 }, \
+ { 0xa438, 0xae02 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x10fd }, \
+ { 0xa436, 0xa026 }, \
+ { 0xa438, 0xffff }, \
+ { 0xa436, 0xa024 }, \
+ { 0xa438, 0xffff }, \
+ { 0xa436, 0xa022 }, \
+ { 0xa438, 0x10f4 }, \
+ { 0xa436, 0xa020 }, \
+ { 0xa438, 0x1252 }, \
+ { 0xa436, 0xa006 }, \
+ { 0xa438, 0x1206 }, \
+ { 0xa436, 0xa004 }, \
+ { 0xa438, 0x0a78 }, \
+ { 0xa436, 0xa002 }, \
+ { 0xa438, 0x0a60 }, \
+ { 0xa436, 0xa000 }, \
+ { 0xa438, 0x0a4f }, \
+ { 0xa436, 0xa008 }, \
+ { 0xa438, 0x3f00 }, \
+ { 0xa436, 0xa016 }, \
+ { 0xa438, 0x0010 }, \
+ { 0xa436, 0xa012 }, \
+ { 0xa438, 0x0000 }, \
+ { 0xa436, 0xa014 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x8010 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x8066 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x807c }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x8089 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x808e }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x80a0 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x80b2 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x80c2 }, \
+ { 0xa438, 0xd501 }, \
+ { 0xa438, 0xce01 }, \
+ { 0xa438, 0xd700 }, \
+ { 0xa438, 0x62db }, \
+ { 0xa438, 0x655c }, \
+ { 0xa438, 0xd73e }, \
+ { 0xa438, 0x60e9 }, \
+ { 0xa438, 0x614a }, \
+ { 0xa438, 0x61ab }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x0501 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0304 }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x0503 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0304 }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x0505 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0304 }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x0509 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0304 }, \
+ { 0xa438, 0x653c }, \
+ { 0xa438, 0xd73e }, \
+ { 0xa438, 0x60e9 }, \
+ { 0xa438, 0x614a }, \
+ { 0xa438, 0x61ab }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x0503 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0304 }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x0502 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0304 }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x0506 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0304 }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x050a }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0304 }, \
+ { 0xa438, 0xd73e }, \
+ { 0xa438, 0x60e9 }, \
+ { 0xa438, 0x614a }, \
+ { 0xa438, 0x61ab }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x0505 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0304 }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x0506 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0304 }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x0504 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0304 }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x050c }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0304 }, \
+ { 0xa438, 0xd73e }, \
+ { 0xa438, 0x60e9 }, \
+ { 0xa438, 0x614a }, \
+ { 0xa438, 0x61ab }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x0509 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0304 }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x050a }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0304 }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x050c }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0304 }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x0508 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0304 }, \
+ { 0xa438, 0xd501 }, \
+ { 0xa438, 0xce01 }, \
+ { 0xa438, 0xd73e }, \
+ { 0xa438, 0x60e9 }, \
+ { 0xa438, 0x614a }, \
+ { 0xa438, 0x61ab }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x0501 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0321 }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x0502 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0321 }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x0504 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0321 }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x0508 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0321 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x0346 }, \
+ { 0xa438, 0xd501 }, \
+ { 0xa438, 0xce01 }, \
+ { 0xa438, 0x8208 }, \
+ { 0xa438, 0x609d }, \
+ { 0xa438, 0xa50f }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x001a }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x0503 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x001a }, \
+ { 0xa438, 0x607d }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x00ab }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x00ab }, \
+ { 0xa438, 0xd501 }, \
+ { 0xa438, 0xce01 }, \
+ { 0xa438, 0xd700 }, \
+ { 0xa438, 0x60fd }, \
+ { 0xa438, 0xa50f }, \
+ { 0xa438, 0xce00 }, \
+ { 0xa438, 0xd500 }, \
+ { 0xa438, 0xaa0f }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x017b }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x0503 }, \
+ { 0xa438, 0xce00 }, \
+ { 0xa438, 0xd500 }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x0a05 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x017b }, \
+ { 0xa438, 0xd501 }, \
+ { 0xa438, 0xce01 }, \
+ { 0xa438, 0xd700 }, \
+ { 0xa438, 0x60fd }, \
+ { 0xa438, 0xa50f }, \
+ { 0xa438, 0xce00 }, \
+ { 0xa438, 0xd500 }, \
+ { 0xa438, 0xaa0f }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x01e0 }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x0503 }, \
+ { 0xa438, 0xce00 }, \
+ { 0xa438, 0xd500 }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x0a05 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x01e0 }, \
+ { 0xa438, 0xd700 }, \
+ { 0xa438, 0x60fd }, \
+ { 0xa438, 0xa50f }, \
+ { 0xa438, 0xce00 }, \
+ { 0xa438, 0xd500 }, \
+ { 0xa438, 0xaa0f }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0231 }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x0503 }, \
+ { 0xa438, 0xce00 }, \
+ { 0xa438, 0xd500 }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x0a05 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0231 }, \
+ { 0xa436, 0xa08e }, \
+ { 0xa438, 0xffff }, \
+ { 0xa436, 0xa08c }, \
+ { 0xa438, 0x0221 }, \
+ { 0xa436, 0xa08a }, \
+ { 0xa438, 0x01ce }, \
+ { 0xa436, 0xa088 }, \
+ { 0xa438, 0x0169 }, \
+ { 0xa436, 0xa086 }, \
+ { 0xa438, 0x00a6 }, \
+ { 0xa436, 0xa084 }, \
+ { 0xa438, 0x000d }, \
+ { 0xa436, 0xa082 }, \
+ { 0xa438, 0x0308 }, \
+ { 0xa436, 0xa080 }, \
+ { 0xa438, 0x029f }, \
+ { 0xa436, 0xa090 }, \
+ { 0xa438, 0x007f }, \
+ { 0xa436, 0xa016 }, \
+ { 0xa438, 0x0020 }, \
+ { 0xa436, 0xa012 }, \
+ { 0xa438, 0x0000 }, \
+ { 0xa436, 0xa014 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x8010 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x8017 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x801b }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x8029 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x8054 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x805a }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x8064 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x80a7 }, \
+ { 0xa438, 0x9430 }, \
+ { 0xa438, 0x9480 }, \
+ { 0xa438, 0xb408 }, \
+ { 0xa438, 0xd120 }, \
+ { 0xa438, 0xd057 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x064b }, \
+ { 0xa438, 0xcb80 }, \
+ { 0xa438, 0x9906 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0567 }, \
+ { 0xa438, 0xcb94 }, \
+ { 0xa438, 0x8190 }, \
+ { 0xa438, 0x82a0 }, \
+ { 0xa438, 0x800a }, \
+ { 0xa438, 0x8406 }, \
+ { 0xa438, 0x8010 }, \
+ { 0xa438, 0xa740 }, \
+ { 0xa438, 0x8dff }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x07e4 }, \
+ { 0xa438, 0xa840 }, \
+ { 0xa438, 0x0000 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0773 }, \
+ { 0xa438, 0xcb91 }, \
+ { 0xa438, 0x0000 }, \
+ { 0xa438, 0xd700 }, \
+ { 0xa438, 0x4063 }, \
+ { 0xa438, 0xd139 }, \
+ { 0xa438, 0xf002 }, \
+ { 0xa438, 0xd140 }, \
+ { 0xa438, 0xd040 }, \
+ { 0xa438, 0xb404 }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x0d00 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x07dc }, \
+ { 0xa438, 0xa610 }, \
+ { 0xa438, 0xa110 }, \
+ { 0xa438, 0xa2a0 }, \
+ { 0xa438, 0xa404 }, \
+ { 0xa438, 0xd704 }, \
+ { 0xa438, 0x4045 }, \
+ { 0xa438, 0xa180 }, \
+ { 0xa438, 0xd704 }, \
+ { 0xa438, 0x405d }, \
+ { 0xa438, 0xa720 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x0742 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x07ec }, \
+ { 0xa438, 0xd700 }, \
+ { 0xa438, 0x5f74 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x0742 }, \
+ { 0xa438, 0xd702 }, \
+ { 0xa438, 0x7fb6 }, \
+ { 0xa438, 0x8190 }, \
+ { 0xa438, 0x82a0 }, \
+ { 0xa438, 0x8404 }, \
+ { 0xa438, 0x8610 }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x0d01 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x07dc }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x064b }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x07c0 }, \
+ { 0xa438, 0xd700 }, \
+ { 0xa438, 0x5fa7 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0481 }, \
+ { 0xa438, 0x0000 }, \
+ { 0xa438, 0x94bc }, \
+ { 0xa438, 0x870c }, \
+ { 0xa438, 0xa190 }, \
+ { 0xa438, 0xa00a }, \
+ { 0xa438, 0xa280 }, \
+ { 0xa438, 0xa404 }, \
+ { 0xa438, 0x8220 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x078e }, \
+ { 0xa438, 0xcb92 }, \
+ { 0xa438, 0xa840 }, \
+ { 0xa438, 0xd700 }, \
+ { 0xa438, 0x4063 }, \
+ { 0xa438, 0xd140 }, \
+ { 0xa438, 0xf002 }, \
+ { 0xa438, 0xd150 }, \
+ { 0xa438, 0xd040 }, \
+ { 0xa438, 0xd703 }, \
+ { 0xa438, 0x60a0 }, \
+ { 0xa438, 0x6121 }, \
+ { 0xa438, 0x61a2 }, \
+ { 0xa438, 0x6223 }, \
+ { 0xa438, 0xf02f }, \
+ { 0xa438, 0x0cf0 }, \
+ { 0xa438, 0x0d10 }, \
+ { 0xa438, 0x8010 }, \
+ { 0xa438, 0xa740 }, \
+ { 0xa438, 0xf00f }, \
+ { 0xa438, 0x0cf0 }, \
+ { 0xa438, 0x0d20 }, \
+ { 0xa438, 0x8010 }, \
+ { 0xa438, 0xa740 }, \
+ { 0xa438, 0xf00a }, \
+ { 0xa438, 0x0cf0 }, \
+ { 0xa438, 0x0d30 }, \
+ { 0xa438, 0x8010 }, \
+ { 0xa438, 0xa740 }, \
+ { 0xa438, 0xf005 }, \
+ { 0xa438, 0x0cf0 }, \
+ { 0xa438, 0x0d40 }, \
+ { 0xa438, 0x8010 }, \
+ { 0xa438, 0xa740 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x07e4 }, \
+ { 0xa438, 0xa610 }, \
+ { 0xa438, 0xa008 }, \
+ { 0xa438, 0xd704 }, \
+ { 0xa438, 0x4046 }, \
+ { 0xa438, 0xa002 }, \
+ { 0xa438, 0xd704 }, \
+ { 0xa438, 0x405d }, \
+ { 0xa438, 0xa720 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x0742 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x07f7 }, \
+ { 0xa438, 0xd700 }, \
+ { 0xa438, 0x5f74 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x0742 }, \
+ { 0xa438, 0xd702 }, \
+ { 0xa438, 0x7fb5 }, \
+ { 0xa438, 0x800a }, \
+ { 0xa438, 0x0cf0 }, \
+ { 0xa438, 0x0d00 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x07e4 }, \
+ { 0xa438, 0x8010 }, \
+ { 0xa438, 0xa740 }, \
+ { 0xa438, 0xd701 }, \
+ { 0xa438, 0x3ad4 }, \
+ { 0xa438, 0x0537 }, \
+ { 0xa438, 0x8610 }, \
+ { 0xa438, 0x8840 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x064b }, \
+ { 0xa438, 0x8301 }, \
+ { 0xa438, 0x800a }, \
+ { 0xa438, 0x8190 }, \
+ { 0xa438, 0x82a0 }, \
+ { 0xa438, 0x8404 }, \
+ { 0xa438, 0xa70c }, \
+ { 0xa438, 0x9402 }, \
+ { 0xa438, 0x890c }, \
+ { 0xa438, 0x8840 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x064b }, \
+ { 0xa436, 0xa10e }, \
+ { 0xa438, 0x0642 }, \
+ { 0xa436, 0xa10c }, \
+ { 0xa438, 0x0686 }, \
+ { 0xa436, 0xa10a }, \
+ { 0xa438, 0x0788 }, \
+ { 0xa436, 0xa108 }, \
+ { 0xa438, 0x047b }, \
+ { 0xa436, 0xa106 }, \
+ { 0xa438, 0x065c }, \
+ { 0xa436, 0xa104 }, \
+ { 0xa438, 0x0769 }, \
+ { 0xa436, 0xa102 }, \
+ { 0xa438, 0x0565 }, \
+ { 0xa436, 0xa100 }, \
+ { 0xa438, 0x06f9 }, \
+ { 0xa436, 0xa110 }, \
+ { 0xa438, 0x00ff }, \
+ { 0xa436, 0xb87c }, \
+ { 0xa438, 0x8530 }, \
+ { 0xa436, 0xb87e }, \
+ { 0xa438, 0xaf85 }, \
+ { 0xa438, 0x3caf }, \
+ { 0xa438, 0x8593 }, \
+ { 0xa438, 0xaf85 }, \
+ { 0xa438, 0x9caf }, \
+ { 0xa438, 0x85a5 }, \
+ { 0xa438, 0xbf86 }, \
+ { 0xa438, 0xd702 }, \
+ { 0xa438, 0x5afb }, \
+ { 0xa438, 0xe083 }, \
+ { 0xa438, 0xfb0c }, \
+ { 0xa438, 0x020d }, \
+ { 0xa438, 0x021b }, \
+ { 0xa438, 0x10bf }, \
+ { 0xa438, 0x86d7 }, \
+ { 0xa438, 0x025a }, \
+ { 0xa438, 0xb7bf }, \
+ { 0xa438, 0x86da }, \
+ { 0xa438, 0x025a }, \
+ { 0xa438, 0xfbe0 }, \
+ { 0xa438, 0x83fc }, \
+ { 0xa438, 0x0c02 }, \
+ { 0xa438, 0x0d02 }, \
+ { 0xa438, 0x1b10 }, \
+ { 0xa438, 0xbf86 }, \
+ { 0xa438, 0xda02 }, \
+ { 0xa438, 0x5ab7 }, \
+ { 0xa438, 0xbf86 }, \
+ { 0xa438, 0xdd02 }, \
+ { 0xa438, 0x5afb }, \
+ { 0xa438, 0xe083 }, \
+ { 0xa438, 0xfd0c }, \
+ { 0xa438, 0x020d }, \
+ { 0xa438, 0x021b }, \
+ { 0xa438, 0x10bf }, \
+ { 0xa438, 0x86dd }, \
+ { 0xa438, 0x025a }, \
+ { 0xa438, 0xb7bf }, \
+ { 0xa438, 0x86e0 }, \
+ { 0xa438, 0x025a }, \
+ { 0xa438, 0xfbe0 }, \
+ { 0xa438, 0x83fe }, \
+ { 0xa438, 0x0c02 }, \
+ { 0xa438, 0x0d02 }, \
+ { 0xa438, 0x1b10 }, \
+ { 0xa438, 0xbf86 }, \
+ { 0xa438, 0xe002 }, \
+ { 0xa438, 0x5ab7 }, \
+ { 0xa438, 0xaf2f }, \
+ { 0xa438, 0xbd02 }, \
+ { 0xa438, 0x2cac }, \
+ { 0xa438, 0x0286 }, \
+ { 0xa438, 0x65af }, \
+ { 0xa438, 0x212b }, \
+ { 0xa438, 0x022c }, \
+ { 0xa438, 0x6002 }, \
+ { 0xa438, 0x86b6 }, \
+ { 0xa438, 0xaf21 }, \
+ { 0xa438, 0x0cd1 }, \
+ { 0xa438, 0x03bf }, \
+ { 0xa438, 0x8710 }, \
+ { 0xa438, 0x025a }, \
+ { 0xa438, 0xb7bf }, \
+ { 0xa438, 0x870d }, \
+ { 0xa438, 0x025a }, \
+ { 0xa438, 0xb7bf }, \
+ { 0xa438, 0x8719 }, \
+ { 0xa438, 0x025a }, \
+ { 0xa438, 0xb7bf }, \
+ { 0xa438, 0x8716 }, \
+ { 0xa438, 0x025a }, \
+ { 0xa438, 0xb7bf }, \
+ { 0xa438, 0x871f }, \
+ { 0xa438, 0x025a }, \
+ { 0xa438, 0xb7bf }, \
+ { 0xa438, 0x871c }, \
+ { 0xa438, 0x025a }, \
+ { 0xa438, 0xb7bf }, \
+ { 0xa438, 0x8728 }, \
+ { 0xa438, 0x025a }, \
+ { 0xa438, 0xb7bf }, \
+ { 0xa438, 0x8725 }, \
+ { 0xa438, 0x025a }, \
+ { 0xa438, 0xb7bf }, \
+ { 0xa438, 0x8707 }, \
+ { 0xa438, 0x025a }, \
+ { 0xa438, 0xfbad }, \
+ { 0xa438, 0x281c }, \
+ { 0xa438, 0xd100 }, \
+ { 0xa438, 0xbf87 }, \
+ { 0xa438, 0x0a02 }, \
+ { 0xa438, 0x5ab7 }, \
+ { 0xa438, 0xbf87 }, \
+ { 0xa438, 0x1302 }, \
+ { 0xa438, 0x5ab7 }, \
+ { 0xa438, 0xbf87 }, \
+ { 0xa438, 0x2202 }, \
+ { 0xa438, 0x5ab7 }, \
+ { 0xa438, 0xbf87 }, \
+ { 0xa438, 0x2b02 }, \
+ { 0xa438, 0x5ab7 }, \
+ { 0xa438, 0xae1a }, \
+ { 0xa438, 0xd101 }, \
+ { 0xa438, 0xbf87 }, \
+ { 0xa438, 0x0a02 }, \
+ { 0xa438, 0x5ab7 }, \
+ { 0xa438, 0xbf87 }, \
+ { 0xa438, 0x1302 }, \
+ { 0xa438, 0x5ab7 }, \
+ { 0xa438, 0xbf87 }, \
+ { 0xa438, 0x2202 }, \
+ { 0xa438, 0x5ab7 }, \
+ { 0xa438, 0xbf87 }, \
+ { 0xa438, 0x2b02 }, \
+ { 0xa438, 0x5ab7 }, \
+ { 0xa438, 0xd101 }, \
+ { 0xa438, 0xbf87 }, \
+ { 0xa438, 0x3402 }, \
+ { 0xa438, 0x5ab7 }, \
+ { 0xa438, 0xbf87 }, \
+ { 0xa438, 0x3102 }, \
+ { 0xa438, 0x5ab7 }, \
+ { 0xa438, 0xbf87 }, \
+ { 0xa438, 0x3d02 }, \
+ { 0xa438, 0x5ab7 }, \
+ { 0xa438, 0xbf87 }, \
+ { 0xa438, 0x3a02 }, \
+ { 0xa438, 0x5ab7 }, \
+ { 0xa438, 0xbf87 }, \
+ { 0xa438, 0x4302 }, \
+ { 0xa438, 0x5ab7 }, \
+ { 0xa438, 0xbf87 }, \
+ { 0xa438, 0x4002 }, \
+ { 0xa438, 0x5ab7 }, \
+ { 0xa438, 0xbf87 }, \
+ { 0xa438, 0x4c02 }, \
+ { 0xa438, 0x5ab7 }, \
+ { 0xa438, 0xbf87 }, \
+ { 0xa438, 0x4902 }, \
+ { 0xa438, 0x5ab7 }, \
+ { 0xa438, 0xd100 }, \
+ { 0xa438, 0xbf87 }, \
+ { 0xa438, 0x2e02 }, \
+ { 0xa438, 0x5ab7 }, \
+ { 0xa438, 0xbf87 }, \
+ { 0xa438, 0x3702 }, \
+ { 0xa438, 0x5ab7 }, \
+ { 0xa438, 0xbf87 }, \
+ { 0xa438, 0x4602 }, \
+ { 0xa438, 0x5ab7 }, \
+ { 0xa438, 0xbf87 }, \
+ { 0xa438, 0x4f02 }, \
+ { 0xa438, 0x5ab7 }, \
+ { 0xa438, 0xaf35 }, \
+ { 0xa438, 0x7ff8 }, \
+ { 0xa438, 0xfaef }, \
+ { 0xa438, 0x69bf }, \
+ { 0xa438, 0x86e3 }, \
+ { 0xa438, 0x025a }, \
+ { 0xa438, 0xfbbf }, \
+ { 0xa438, 0x86fb }, \
+ { 0xa438, 0x025a }, \
+ { 0xa438, 0xb7bf }, \
+ { 0xa438, 0x86e6 }, \
+ { 0xa438, 0x025a }, \
+ { 0xa438, 0xfbbf }, \
+ { 0xa438, 0x86fe }, \
+ { 0xa438, 0x025a }, \
+ { 0xa438, 0xb7bf }, \
+ { 0xa438, 0x86e9 }, \
+ { 0xa438, 0x025a }, \
+ { 0xa438, 0xfbbf }, \
+ { 0xa438, 0x8701 }, \
+ { 0xa438, 0x025a }, \
+ { 0xa438, 0xb7bf }, \
+ { 0xa438, 0x86ec }, \
+ { 0xa438, 0x025a }, \
+ { 0xa438, 0xfbbf }, \
+ { 0xa438, 0x8704 }, \
+ { 0xa438, 0x025a }, \
+ { 0xa438, 0xb7bf }, \
+ { 0xa438, 0x86ef }, \
+ { 0xa438, 0x0262 }, \
+ { 0xa438, 0x7cbf }, \
+ { 0xa438, 0x86f2 }, \
+ { 0xa438, 0x0262 }, \
+ { 0xa438, 0x7cbf }, \
+ { 0xa438, 0x86f5 }, \
+ { 0xa438, 0x0262 }, \
+ { 0xa438, 0x7cbf }, \
+ { 0xa438, 0x86f8 }, \
+ { 0xa438, 0x0262 }, \
+ { 0xa438, 0x7cef }, \
+ { 0xa438, 0x96fe }, \
+ { 0xa438, 0xfc04 }, \
+ { 0xa438, 0xf8fa }, \
+ { 0xa438, 0xef69 }, \
+ { 0xa438, 0xbf86 }, \
+ { 0xa438, 0xef02 }, \
+ { 0xa438, 0x6273 }, \
+ { 0xa438, 0xbf86 }, \
+ { 0xa438, 0xf202 }, \
+ { 0xa438, 0x6273 }, \
+ { 0xa438, 0xbf86 }, \
+ { 0xa438, 0xf502 }, \
+ { 0xa438, 0x6273 }, \
+ { 0xa438, 0xbf86 }, \
+ { 0xa438, 0xf802 }, \
+ { 0xa438, 0x6273 }, \
+ { 0xa438, 0xef96 }, \
+ { 0xa438, 0xfefc }, \
+ { 0xa438, 0x0420 }, \
+ { 0xa438, 0xb540 }, \
+ { 0xa438, 0x53b5 }, \
+ { 0xa438, 0x4086 }, \
+ { 0xa438, 0xb540 }, \
+ { 0xa438, 0xb9b5 }, \
+ { 0xa438, 0x40c8 }, \
+ { 0xa438, 0xb03a }, \
+ { 0xa438, 0xc8b0 }, \
+ { 0xa438, 0xbac8 }, \
+ { 0xa438, 0xb13a }, \
+ { 0xa438, 0xc8b1 }, \
+ { 0xa438, 0xba77 }, \
+ { 0xa438, 0xbd26 }, \
+ { 0xa438, 0xffbd }, \
+ { 0xa438, 0x2677 }, \
+ { 0xa438, 0xbd28 }, \
+ { 0xa438, 0xffbd }, \
+ { 0xa438, 0x2840 }, \
+ { 0xa438, 0xbd26 }, \
+ { 0xa438, 0xc8bd }, \
+ { 0xa438, 0x2640 }, \
+ { 0xa438, 0xbd28 }, \
+ { 0xa438, 0xc8bd }, \
+ { 0xa438, 0x28bb }, \
+ { 0xa438, 0xa430 }, \
+ { 0xa438, 0x98b0 }, \
+ { 0xa438, 0x1eba }, \
+ { 0xa438, 0xb01e }, \
+ { 0xa438, 0xdcb0 }, \
+ { 0xa438, 0x1e98 }, \
+ { 0xa438, 0xb09e }, \
+ { 0xa438, 0xbab0 }, \
+ { 0xa438, 0x9edc }, \
+ { 0xa438, 0xb09e }, \
+ { 0xa438, 0x98b1 }, \
+ { 0xa438, 0x1eba }, \
+ { 0xa438, 0xb11e }, \
+ { 0xa438, 0xdcb1 }, \
+ { 0xa438, 0x1e98 }, \
+ { 0xa438, 0xb19e }, \
+ { 0xa438, 0xbab1 }, \
+ { 0xa438, 0x9edc }, \
+ { 0xa438, 0xb19e }, \
+ { 0xa438, 0x11b0 }, \
+ { 0xa438, 0x1e22 }, \
+ { 0xa438, 0xb01e }, \
+ { 0xa438, 0x33b0 }, \
+ { 0xa438, 0x1e11 }, \
+ { 0xa438, 0xb09e }, \
+ { 0xa438, 0x22b0 }, \
+ { 0xa438, 0x9e33 }, \
+ { 0xa438, 0xb09e }, \
+ { 0xa438, 0x11b1 }, \
+ { 0xa438, 0x1e22 }, \
+ { 0xa438, 0xb11e }, \
+ { 0xa438, 0x33b1 }, \
+ { 0xa438, 0x1e11 }, \
+ { 0xa438, 0xb19e }, \
+ { 0xa438, 0x22b1 }, \
+ { 0xa438, 0x9e33 }, \
+ { 0xa438, 0xb19e }, \
+ { 0xa436, 0xb85e }, \
+ { 0xa438, 0x2f71 }, \
+ { 0xa436, 0xb860 }, \
+ { 0xa438, 0x20d9 }, \
+ { 0xa436, 0xb862 }, \
+ { 0xa438, 0x2109 }, \
+ { 0xa436, 0xb864 }, \
+ { 0xa438, 0x34e7 }, \
+ { 0xa436, 0xb878 }, \
+ { 0xa438, 0x000f }
+
+#define RTL8125_MAC_CFG3_MCU \
+ { 0xa436, 0xa016 }, \
+ { 0xa438, 0x0000 }, \
+ { 0xa436, 0xa012 }, \
+ { 0xa438, 0x0000 }, \
+ { 0xa436, 0xa014 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x8010 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x808b }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x808f }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x8093 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x8097 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x809d }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x80a1 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x80aa }, \
+ { 0xa438, 0xd718 }, \
+ { 0xa438, 0x607b }, \
+ { 0xa438, 0x40da }, \
+ { 0xa438, 0xf00e }, \
+ { 0xa438, 0x42da }, \
+ { 0xa438, 0xf01e }, \
+ { 0xa438, 0xd718 }, \
+ { 0xa438, 0x615b }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x1456 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x14a4 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x14bc }, \
+ { 0xa438, 0xd718 }, \
+ { 0xa438, 0x5f2e }, \
+ { 0xa438, 0xf01c }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x1456 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x14a4 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x14bc }, \
+ { 0xa438, 0xd718 }, \
+ { 0xa438, 0x5f2e }, \
+ { 0xa438, 0xf024 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x1456 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x14a4 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x14bc }, \
+ { 0xa438, 0xd718 }, \
+ { 0xa438, 0x5f2e }, \
+ { 0xa438, 0xf02c }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x1456 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x14a4 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x14bc }, \
+ { 0xa438, 0xd718 }, \
+ { 0xa438, 0x5f2e }, \
+ { 0xa438, 0xf034 }, \
+ { 0xa438, 0xd719 }, \
+ { 0xa438, 0x4118 }, \
+ { 0xa438, 0xd504 }, \
+ { 0xa438, 0xac11 }, \
+ { 0xa438, 0xd501 }, \
+ { 0xa438, 0xce01 }, \
+ { 0xa438, 0xa410 }, \
+ { 0xa438, 0xce00 }, \
+ { 0xa438, 0xd500 }, \
+ { 0xa438, 0x4779 }, \
+ { 0xa438, 0xd504 }, \
+ { 0xa438, 0xac0f }, \
+ { 0xa438, 0xae01 }, \
+ { 0xa438, 0xd500 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x1444 }, \
+ { 0xa438, 0xf034 }, \
+ { 0xa438, 0xd719 }, \
+ { 0xa438, 0x4118 }, \
+ { 0xa438, 0xd504 }, \
+ { 0xa438, 0xac22 }, \
+ { 0xa438, 0xd501 }, \
+ { 0xa438, 0xce01 }, \
+ { 0xa438, 0xa420 }, \
+ { 0xa438, 0xce00 }, \
+ { 0xa438, 0xd500 }, \
+ { 0xa438, 0x4559 }, \
+ { 0xa438, 0xd504 }, \
+ { 0xa438, 0xac0f }, \
+ { 0xa438, 0xae01 }, \
+ { 0xa438, 0xd500 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x1444 }, \
+ { 0xa438, 0xf023 }, \
+ { 0xa438, 0xd719 }, \
+ { 0xa438, 0x4118 }, \
+ { 0xa438, 0xd504 }, \
+ { 0xa438, 0xac44 }, \
+ { 0xa438, 0xd501 }, \
+ { 0xa438, 0xce01 }, \
+ { 0xa438, 0xa440 }, \
+ { 0xa438, 0xce00 }, \
+ { 0xa438, 0xd500 }, \
+ { 0xa438, 0x4339 }, \
+ { 0xa438, 0xd504 }, \
+ { 0xa438, 0xac0f }, \
+ { 0xa438, 0xae01 }, \
+ { 0xa438, 0xd500 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x1444 }, \
+ { 0xa438, 0xf012 }, \
+ { 0xa438, 0xd719 }, \
+ { 0xa438, 0x4118 }, \
+ { 0xa438, 0xd504 }, \
+ { 0xa438, 0xac88 }, \
+ { 0xa438, 0xd501 }, \
+ { 0xa438, 0xce01 }, \
+ { 0xa438, 0xa480 }, \
+ { 0xa438, 0xce00 }, \
+ { 0xa438, 0xd500 }, \
+ { 0xa438, 0x4119 }, \
+ { 0xa438, 0xd504 }, \
+ { 0xa438, 0xac0f }, \
+ { 0xa438, 0xae01 }, \
+ { 0xa438, 0xd500 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x1444 }, \
+ { 0xa438, 0xf001 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x1456 }, \
+ { 0xa438, 0xd718 }, \
+ { 0xa438, 0x5fac }, \
+ { 0xa438, 0xc48f }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x141b }, \
+ { 0xa438, 0xd504 }, \
+ { 0xa438, 0x8010 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x121a }, \
+ { 0xa438, 0xd0b4 }, \
+ { 0xa438, 0xd1bb }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0898 }, \
+ { 0xa438, 0xd0b4 }, \
+ { 0xa438, 0xd1bb }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0a0e }, \
+ { 0xa438, 0xd064 }, \
+ { 0xa438, 0xd18a }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0b7e }, \
+ { 0xa438, 0x401c }, \
+ { 0xa438, 0xd501 }, \
+ { 0xa438, 0xa804 }, \
+ { 0xa438, 0x8804 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x053b }, \
+ { 0xa438, 0xd500 }, \
+ { 0xa438, 0xa301 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0648 }, \
+ { 0xa438, 0xc520 }, \
+ { 0xa438, 0xa201 }, \
+ { 0xa438, 0xd701 }, \
+ { 0xa438, 0x252d }, \
+ { 0xa438, 0x1646 }, \
+ { 0xa438, 0xd708 }, \
+ { 0xa438, 0x4006 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x1646 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0308 }, \
+ { 0xa436, 0xa026 }, \
+ { 0xa438, 0x0307 }, \
+ { 0xa436, 0xa024 }, \
+ { 0xa438, 0x1645 }, \
+ { 0xa436, 0xa022 }, \
+ { 0xa438, 0x0647 }, \
+ { 0xa436, 0xa020 }, \
+ { 0xa438, 0x053a }, \
+ { 0xa436, 0xa006 }, \
+ { 0xa438, 0x0b7c }, \
+ { 0xa436, 0xa004 }, \
+ { 0xa438, 0x0a0c }, \
+ { 0xa436, 0xa002 }, \
+ { 0xa438, 0x0896 }, \
+ { 0xa436, 0xa000 }, \
+ { 0xa438, 0x11a1 }, \
+ { 0xa436, 0xa008 }, \
+ { 0xa438, 0xff00 }, \
+ { 0xa436, 0xa016 }, \
+ { 0xa438, 0x0010 }, \
+ { 0xa436, 0xa012 }, \
+ { 0xa438, 0x0000 }, \
+ { 0xa436, 0xa014 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x8010 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x8015 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x801a }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x801a }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x801a }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x801a }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x801a }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x801a }, \
+ { 0xa438, 0xad02 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x02d7 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x00ed }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x0509 }, \
+ { 0xa438, 0xc100 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x008f }, \
+ { 0xa436, 0xa08e }, \
+ { 0xa438, 0xffff }, \
+ { 0xa436, 0xa08c }, \
+ { 0xa438, 0xffff }, \
+ { 0xa436, 0xa08a }, \
+ { 0xa438, 0xffff }, \
+ { 0xa436, 0xa088 }, \
+ { 0xa438, 0xffff }, \
+ { 0xa436, 0xa086 }, \
+ { 0xa438, 0xffff }, \
+ { 0xa436, 0xa084 }, \
+ { 0xa438, 0xffff }, \
+ { 0xa436, 0xa082 }, \
+ { 0xa438, 0x008d }, \
+ { 0xa436, 0xa080 }, \
+ { 0xa438, 0x00eb }, \
+ { 0xa436, 0xa090 }, \
+ { 0xa438, 0x0103 }, \
+ { 0xa436, 0xa016 }, \
+ { 0xa438, 0x0020 }, \
+ { 0xa436, 0xa012 }, \
+ { 0xa438, 0x0000 }, \
+ { 0xa436, 0xa014 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x8010 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x8014 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x8018 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x8024 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x8051 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x8055 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x8072 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x80dc }, \
+ { 0xa438, 0x0000 }, \
+ { 0xa438, 0x0000 }, \
+ { 0xa438, 0x0000 }, \
+ { 0xa438, 0xfffd }, \
+ { 0xa438, 0x0000 }, \
+ { 0xa438, 0x0000 }, \
+ { 0xa438, 0x0000 }, \
+ { 0xa438, 0xfffd }, \
+ { 0xa438, 0x8301 }, \
+ { 0xa438, 0x800a }, \
+ { 0xa438, 0x8190 }, \
+ { 0xa438, 0x82a0 }, \
+ { 0xa438, 0x8404 }, \
+ { 0xa438, 0xa70c }, \
+ { 0xa438, 0x9402 }, \
+ { 0xa438, 0x890c }, \
+ { 0xa438, 0x8840 }, \
+ { 0xa438, 0xa380 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x066e }, \
+ { 0xa438, 0xcb91 }, \
+ { 0xa438, 0xd700 }, \
+ { 0xa438, 0x4063 }, \
+ { 0xa438, 0xd139 }, \
+ { 0xa438, 0xf002 }, \
+ { 0xa438, 0xd140 }, \
+ { 0xa438, 0xd040 }, \
+ { 0xa438, 0xb404 }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x0d00 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x07e0 }, \
+ { 0xa438, 0xa610 }, \
+ { 0xa438, 0xa110 }, \
+ { 0xa438, 0xa2a0 }, \
+ { 0xa438, 0xa404 }, \
+ { 0xa438, 0xd704 }, \
+ { 0xa438, 0x4085 }, \
+ { 0xa438, 0xa180 }, \
+ { 0xa438, 0xa404 }, \
+ { 0xa438, 0x8280 }, \
+ { 0xa438, 0xd704 }, \
+ { 0xa438, 0x405d }, \
+ { 0xa438, 0xa720 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x0743 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x07f0 }, \
+ { 0xa438, 0xd700 }, \
+ { 0xa438, 0x5f74 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x0743 }, \
+ { 0xa438, 0xd702 }, \
+ { 0xa438, 0x7fb6 }, \
+ { 0xa438, 0x8190 }, \
+ { 0xa438, 0x82a0 }, \
+ { 0xa438, 0x8404 }, \
+ { 0xa438, 0x8610 }, \
+ { 0xa438, 0x0000 }, \
+ { 0xa438, 0x0c0f }, \
+ { 0xa438, 0x0d01 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x07e0 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x066e }, \
+ { 0xa438, 0xd158 }, \
+ { 0xa438, 0xd04d }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x03d4 }, \
+ { 0xa438, 0x94bc }, \
+ { 0xa438, 0x870c }, \
+ { 0xa438, 0x8380 }, \
+ { 0xa438, 0xd10d }, \
+ { 0xa438, 0xd040 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x07c4 }, \
+ { 0xa438, 0xd700 }, \
+ { 0xa438, 0x5fb4 }, \
+ { 0xa438, 0xa190 }, \
+ { 0xa438, 0xa00a }, \
+ { 0xa438, 0xa280 }, \
+ { 0xa438, 0xa404 }, \
+ { 0xa438, 0xa220 }, \
+ { 0xa438, 0xd130 }, \
+ { 0xa438, 0xd040 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x07c4 }, \
+ { 0xa438, 0xd700 }, \
+ { 0xa438, 0x5fb4 }, \
+ { 0xa438, 0xbb80 }, \
+ { 0xa438, 0xd1c4 }, \
+ { 0xa438, 0xd074 }, \
+ { 0xa438, 0xa301 }, \
+ { 0xa438, 0xd704 }, \
+ { 0xa438, 0x604b }, \
+ { 0xa438, 0xa90c }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x0556 }, \
+ { 0xa438, 0xcb92 }, \
+ { 0xa438, 0xd700 }, \
+ { 0xa438, 0x4063 }, \
+ { 0xa438, 0xd116 }, \
+ { 0xa438, 0xf002 }, \
+ { 0xa438, 0xd119 }, \
+ { 0xa438, 0xd040 }, \
+ { 0xa438, 0xd703 }, \
+ { 0xa438, 0x60a0 }, \
+ { 0xa438, 0x6241 }, \
+ { 0xa438, 0x63e2 }, \
+ { 0xa438, 0x6583 }, \
+ { 0xa438, 0xf054 }, \
+ { 0xa438, 0xd701 }, \
+ { 0xa438, 0x611e }, \
+ { 0xa438, 0xd701 }, \
+ { 0xa438, 0x40da }, \
+ { 0xa438, 0x0cf0 }, \
+ { 0xa438, 0x0d10 }, \
+ { 0xa438, 0xa010 }, \
+ { 0xa438, 0x8740 }, \
+ { 0xa438, 0xf02f }, \
+ { 0xa438, 0x0cf0 }, \
+ { 0xa438, 0x0d50 }, \
+ { 0xa438, 0x8010 }, \
+ { 0xa438, 0xa740 }, \
+ { 0xa438, 0xf02a }, \
+ { 0xa438, 0xd701 }, \
+ { 0xa438, 0x611e }, \
+ { 0xa438, 0xd701 }, \
+ { 0xa438, 0x40da }, \
+ { 0xa438, 0x0cf0 }, \
+ { 0xa438, 0x0d20 }, \
+ { 0xa438, 0xa010 }, \
+ { 0xa438, 0x8740 }, \
+ { 0xa438, 0xf021 }, \
+ { 0xa438, 0x0cf0 }, \
+ { 0xa438, 0x0d60 }, \
+ { 0xa438, 0x8010 }, \
+ { 0xa438, 0xa740 }, \
+ { 0xa438, 0xf01c }, \
+ { 0xa438, 0xd701 }, \
+ { 0xa438, 0x611e }, \
+ { 0xa438, 0xd701 }, \
+ { 0xa438, 0x40da }, \
+ { 0xa438, 0x0cf0 }, \
+ { 0xa438, 0x0d30 }, \
+ { 0xa438, 0xa010 }, \
+ { 0xa438, 0x8740 }, \
+ { 0xa438, 0xf013 }, \
+ { 0xa438, 0x0cf0 }, \
+ { 0xa438, 0x0d70 }, \
+ { 0xa438, 0x8010 }, \
+ { 0xa438, 0xa740 }, \
+ { 0xa438, 0xf00e }, \
+ { 0xa438, 0xd701 }, \
+ { 0xa438, 0x611e }, \
+ { 0xa438, 0xd701 }, \
+ { 0xa438, 0x40da }, \
+ { 0xa438, 0x0cf0 }, \
+ { 0xa438, 0x0d40 }, \
+ { 0xa438, 0xa010 }, \
+ { 0xa438, 0x8740 }, \
+ { 0xa438, 0xf005 }, \
+ { 0xa438, 0x0cf0 }, \
+ { 0xa438, 0x0d80 }, \
+ { 0xa438, 0x8010 }, \
+ { 0xa438, 0xa740 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x07e8 }, \
+ { 0xa438, 0xa610 }, \
+ { 0xa438, 0xd704 }, \
+ { 0xa438, 0x405d }, \
+ { 0xa438, 0xa720 }, \
+ { 0xa438, 0xd700 }, \
+ { 0xa438, 0x5ff4 }, \
+ { 0xa438, 0xa008 }, \
+ { 0xa438, 0xd704 }, \
+ { 0xa438, 0x4046 }, \
+ { 0xa438, 0xa002 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x0743 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x07fb }, \
+ { 0xa438, 0xd703 }, \
+ { 0xa438, 0x7f6f }, \
+ { 0xa438, 0x7f4e }, \
+ { 0xa438, 0x7f2d }, \
+ { 0xa438, 0x7f0c }, \
+ { 0xa438, 0x800a }, \
+ { 0xa438, 0x0cf0 }, \
+ { 0xa438, 0x0d00 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x07e8 }, \
+ { 0xa438, 0x8010 }, \
+ { 0xa438, 0xa740 }, \
+ { 0xa438, 0x1000 }, \
+ { 0xa438, 0x0743 }, \
+ { 0xa438, 0xd702 }, \
+ { 0xa438, 0x7fb5 }, \
+ { 0xa438, 0xd701 }, \
+ { 0xa438, 0x3ad4 }, \
+ { 0xa438, 0x0556 }, \
+ { 0xa438, 0x8610 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x066e }, \
+ { 0xa438, 0xd1f5 }, \
+ { 0xa438, 0xd049 }, \
+ { 0xa438, 0x1800 }, \
+ { 0xa438, 0x01ec }, \
+ { 0xa436, 0xa10e }, \
+ { 0xa438, 0x01ea }, \
+ { 0xa436, 0xa10c }, \
+ { 0xa438, 0x06a9 }, \
+ { 0xa436, 0xa10a }, \
+ { 0xa438, 0x078a }, \
+ { 0xa436, 0xa108 }, \
+ { 0xa438, 0x03d2 }, \
+ { 0xa436, 0xa106 }, \
+ { 0xa438, 0x067f }, \
+ { 0xa436, 0xa104 }, \
+ { 0xa438, 0x0665 }, \
+ { 0xa436, 0xa102 }, \
+ { 0xa438, 0x0000 }, \
+ { 0xa436, 0xa100 }, \
+ { 0xa438, 0x0000 }, \
+ { 0xa436, 0xa110 }, \
+ { 0xa438, 0x00fc }, \
+ { 0xa436, 0xb87c }, \
+ { 0xa438, 0x8530 }, \
+ { 0xa436, 0xb87e }, \
+ { 0xa438, 0xaf85 }, \
+ { 0xa438, 0x3caf }, \
+ { 0xa438, 0x8545 }, \
+ { 0xa438, 0xaf85 }, \
+ { 0xa438, 0x45af }, \
+ { 0xa438, 0x8545 }, \
+ { 0xa438, 0xee82 }, \
+ { 0xa438, 0xf900 }, \
+ { 0xa438, 0x0103 }, \
+ { 0xa438, 0xaf03 }, \
+ { 0xa438, 0xb7f8 }, \
+ { 0xa438, 0xe0a6 }, \
+ { 0xa438, 0x00e1 }, \
+ { 0xa438, 0xa601 }, \
+ { 0xa438, 0xef01 }, \
+ { 0xa438, 0x58f0 }, \
+ { 0xa438, 0xa080 }, \
+ { 0xa438, 0x37a1 }, \
+ { 0xa438, 0x8402 }, \
+ { 0xa438, 0xae16 }, \
+ { 0xa438, 0xa185 }, \
+ { 0xa438, 0x02ae }, \
+ { 0xa438, 0x11a1 }, \
+ { 0xa438, 0x8702 }, \
+ { 0xa438, 0xae0c }, \
+ { 0xa438, 0xa188 }, \
+ { 0xa438, 0x02ae }, \
+ { 0xa438, 0x07a1 }, \
+ { 0xa438, 0x8902 }, \
+ { 0xa438, 0xae02 }, \
+ { 0xa438, 0xae1c }, \
+ { 0xa438, 0xe0b4 }, \
+ { 0xa438, 0x62e1 }, \
+ { 0xa438, 0xb463 }, \
+ { 0xa438, 0x6901 }, \
+ { 0xa438, 0xe4b4 }, \
+ { 0xa438, 0x62e5 }, \
+ { 0xa438, 0xb463 }, \
+ { 0xa438, 0xe0b4 }, \
+ { 0xa438, 0x62e1 }, \
+ { 0xa438, 0xb463 }, \
+ { 0xa438, 0x6901 }, \
+ { 0xa438, 0xe4b4 }, \
+ { 0xa438, 0x62e5 }, \
+ { 0xa438, 0xb463 }, \
+ { 0xa438, 0xfc04 }, \
+ { 0xa436, 0xb85e }, \
+ { 0xa438, 0x03b3 }, \
+ { 0xa436, 0xb860 }, \
+ { 0xa438, 0xffff }, \
+ { 0xa436, 0xb862 }, \
+ { 0xa438, 0xffff }, \
+ { 0xa436, 0xb864 }, \
+ { 0xa438, 0xffff }, \
+ { 0xa436, 0xb878 }, \
+ { 0xa438, 0x0001 }
diff --git a/sys/dev/pci/pcidevs b/sys/dev/pci/pcidevs
index 1dc82464759..5ccc4ba3871 100644
--- a/sys/dev/pci/pcidevs
+++ b/sys/dev/pci/pcidevs
@@ -1,4 +1,4 @@
-$OpenBSD: pcidevs,v 1.1899 2019/10/29 18:47:51 jcs Exp $
+$OpenBSD: pcidevs,v 1.1900 2019/11/18 03:03:37 kevlo Exp $
/* $NetBSD: pcidevs,v 1.30 1997/06/24 06:20:24 thorpej Exp $ */
/*
@@ -7222,6 +7222,7 @@ product RDC R6060_OHCI 0x6060 R6060 USB
product RDC R6061_EHCI 0x6061 R6061 USB2
/* Realtek products */
+product REALTEK E3000 0x3000 Killer E3000
product REALTEK RTS5208 0x5208 RTS5208 Card Reader
product REALTEK RTS5209 0x5209 RTS5209 Card Reader
product REALTEK RTS5227 0x5227 RTS5227 Card Reader
@@ -7234,6 +7235,7 @@ product REALTEK RTL8411B 0x5287 RTL8411B Card Reader
product REALTEK RTL8411 0x5289 RTL8411 Card Reader
product REALTEK RT8029 0x8029 8029
product REALTEK RT8139D 0x8039 8139D
+product REALTEK RTL8125 0x8125 RTL8125
product REALTEK RT8129 0x8129 8129
product REALTEK RT8101E 0x8136 8101E
product REALTEK RT8138 0x8138 8138