Home | History | Annotate | Line # | Download | only in pci
      1  1.34  jmcneill /*	$NetBSD: if_rge.c,v 1.34 2025/02/04 23:55:23 jmcneill Exp $	*/
      2  1.17  jakllsch /*	$OpenBSD: if_rge.c,v 1.9 2020/12/12 11:48:53 jan Exp $	*/
      3   1.1     sevan 
      4   1.1     sevan /*
      5  1.17  jakllsch  * Copyright (c) 2019, 2020 Kevin Lo <kevlo (at) openbsd.org>
      6   1.1     sevan  *
      7   1.1     sevan  * Permission to use, copy, modify, and distribute this software for any
      8   1.1     sevan  * purpose with or without fee is hereby granted, provided that the above
      9   1.1     sevan  * copyright notice and this permission notice appear in all copies.
     10   1.1     sevan  *
     11   1.1     sevan  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     12   1.1     sevan  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     13   1.1     sevan  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     14   1.1     sevan  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     15   1.1     sevan  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     16   1.1     sevan  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     17   1.1     sevan  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     18   1.1     sevan  */
     19   1.1     sevan 
     20   1.2     sevan #include <sys/cdefs.h>
     21  1.34  jmcneill __KERNEL_RCSID(0, "$NetBSD: if_rge.c,v 1.34 2025/02/04 23:55:23 jmcneill Exp $");
     22  1.30     skrll 
     23  1.30     skrll #if defined(_KERNEL_OPT)
     24  1.30     skrll #include "opt_net_mpsafe.h"
     25  1.30     skrll #endif
     26   1.2     sevan 
     27   1.2     sevan #include <sys/types.h>
     28   1.1     sevan 
     29   1.1     sevan #include <sys/param.h>
     30   1.1     sevan #include <sys/systm.h>
     31   1.1     sevan #include <sys/sockio.h>
     32   1.1     sevan #include <sys/mbuf.h>
     33   1.1     sevan #include <sys/kernel.h>
     34   1.1     sevan #include <sys/socket.h>
     35   1.1     sevan #include <sys/device.h>
     36   1.1     sevan #include <sys/endian.h>
     37   1.3     sevan #include <sys/callout.h>
     38   1.3     sevan #include <sys/workqueue.h>
     39   1.1     sevan 
     40   1.1     sevan #include <net/if.h>
     41   1.2     sevan 
     42   1.2     sevan #include <net/if_dl.h>
     43   1.2     sevan #include <net/if_ether.h>
     44   1.2     sevan 
     45   1.1     sevan #include <net/if_media.h>
     46   1.1     sevan 
     47   1.1     sevan #include <netinet/in.h>
     48   1.2     sevan #include <net/if_ether.h>
     49   1.1     sevan 
     50   1.1     sevan #include <net/bpf.h>
     51   1.1     sevan 
     52   1.2     sevan #include <sys/bus.h>
     53   1.1     sevan #include <machine/intr.h>
     54   1.1     sevan 
     55   1.1     sevan #include <dev/mii/mii.h>
     56   1.1     sevan 
     57   1.1     sevan #include <dev/pci/pcivar.h>
     58   1.1     sevan #include <dev/pci/pcireg.h>
     59   1.1     sevan #include <dev/pci/pcidevs.h>
     60   1.1     sevan 
     61   1.1     sevan #include <dev/pci/if_rgereg.h>
     62   1.1     sevan 
     63   1.2     sevan #ifdef __NetBSD__
     64   1.2     sevan #define letoh32 	htole32
     65   1.2     sevan #define nitems(x) 	__arraycount(x)
     66   1.7     sevan 
     67   1.7     sevan static struct mbuf *
     68  1.17  jakllsch MCLGETL(struct rge_softc *sc __unused, int how,
     69  1.17  jakllsch     u_int size)
     70   1.7     sevan {
     71   1.7     sevan 	struct mbuf *m;
     72   1.7     sevan 
     73   1.7     sevan 	MGETHDR(m, how, MT_DATA);
     74   1.7     sevan 	if (m == NULL)
     75   1.7     sevan 		return NULL;
     76   1.7     sevan 
     77   1.7     sevan 	MEXTMALLOC(m, size, how);
     78   1.7     sevan 	if ((m->m_flags & M_EXT) == 0) {
     79   1.7     sevan 		m_freem(m);
     80   1.7     sevan 		return NULL;
     81   1.7     sevan 	}
     82   1.7     sevan 	return m;
     83   1.7     sevan }
     84   1.7     sevan 
     85   1.3     sevan #ifdef NET_MPSAFE
     86   1.3     sevan #define 	RGE_MPSAFE	1
     87   1.3     sevan #define 	CALLOUT_FLAGS	CALLOUT_MPSAFE
     88   1.3     sevan #else
     89   1.3     sevan #define 	CALLOUT_FLAGS	0
     90   1.3     sevan #endif
     91   1.2     sevan #endif
     92   1.2     sevan 
     93  1.17  jakllsch #ifdef RGE_DEBUG
     94  1.17  jakllsch #define DPRINTF(x)	do { if (rge_debug > 0) printf x; } while (0)
     95  1.17  jakllsch int rge_debug = 0;
     96  1.17  jakllsch #else
     97  1.17  jakllsch #define DPRINTF(x)
     98  1.17  jakllsch #endif
     99  1.17  jakllsch 
    100   1.2     sevan static int		rge_match(device_t, cfdata_t, void *);
    101   1.5     skrll static void		rge_attach(device_t, device_t, void *);
    102   1.1     sevan int		rge_intr(void *);
    103   1.1     sevan int		rge_encap(struct rge_softc *, struct mbuf *, int);
    104   1.2     sevan int		rge_ioctl(struct ifnet *, u_long, void *);
    105   1.2     sevan void		rge_start(struct ifnet *);
    106   1.1     sevan void		rge_watchdog(struct ifnet *);
    107   1.1     sevan int		rge_init(struct ifnet *);
    108  1.17  jakllsch void		rge_stop(struct ifnet *, int);
    109   1.1     sevan int		rge_ifmedia_upd(struct ifnet *);
    110   1.1     sevan void		rge_ifmedia_sts(struct ifnet *, struct ifmediareq *);
    111   1.1     sevan int		rge_allocmem(struct rge_softc *);
    112   1.1     sevan int		rge_newbuf(struct rge_softc *, int);
    113  1.26       mrg static int	rge_rx_list_init(struct rge_softc *);
    114  1.26       mrg static void	rge_rx_list_fini(struct rge_softc *);
    115  1.26       mrg static void	rge_tx_list_init(struct rge_softc *);
    116  1.26       mrg static void	rge_tx_list_fini(struct rge_softc *);
    117   1.1     sevan int		rge_rxeof(struct rge_softc *);
    118   1.1     sevan int		rge_txeof(struct rge_softc *);
    119   1.1     sevan void		rge_reset(struct rge_softc *);
    120   1.1     sevan void		rge_iff(struct rge_softc *);
    121   1.1     sevan void		rge_set_phy_power(struct rge_softc *, int);
    122   1.1     sevan void		rge_phy_config(struct rge_softc *);
    123  1.34  jmcneill void		rge_phy_config_mac_cfg2_8126(struct rge_softc *);
    124  1.17  jakllsch void		rge_phy_config_mac_cfg2(struct rge_softc *);
    125  1.17  jakllsch void		rge_phy_config_mac_cfg3(struct rge_softc *);
    126  1.17  jakllsch void		rge_phy_config_mac_cfg4(struct rge_softc *);
    127  1.17  jakllsch void		rge_phy_config_mac_cfg5(struct rge_softc *);
    128  1.17  jakllsch void		rge_phy_config_mcu(struct rge_softc *, uint16_t);
    129   1.1     sevan void		rge_set_macaddr(struct rge_softc *, const uint8_t *);
    130   1.1     sevan void		rge_get_macaddr(struct rge_softc *, uint8_t *);
    131   1.1     sevan void		rge_hw_init(struct rge_softc *);
    132   1.1     sevan void		rge_disable_phy_ocp_pwrsave(struct rge_softc *);
    133   1.1     sevan void		rge_patch_phy_mcu(struct rge_softc *, int);
    134   1.1     sevan void		rge_add_media_types(struct rge_softc *);
    135   1.1     sevan void		rge_config_imtype(struct rge_softc *, int);
    136  1.17  jakllsch void		rge_disable_hw_im(struct rge_softc *);
    137   1.1     sevan void		rge_disable_sim_im(struct rge_softc *);
    138   1.1     sevan void		rge_setup_sim_im(struct rge_softc *);
    139   1.1     sevan void		rge_setup_intr(struct rge_softc *, int);
    140   1.1     sevan void		rge_exit_oob(struct rge_softc *);
    141   1.1     sevan void		rge_write_csi(struct rge_softc *, uint32_t, uint32_t);
    142   1.1     sevan uint32_t	rge_read_csi(struct rge_softc *, uint32_t);
    143   1.1     sevan void		rge_write_mac_ocp(struct rge_softc *, uint16_t, uint16_t);
    144   1.1     sevan uint16_t	rge_read_mac_ocp(struct rge_softc *, uint16_t);
    145   1.1     sevan void		rge_write_ephy(struct rge_softc *, uint16_t, uint16_t);
    146  1.17  jakllsch uint16_t	rge_read_ephy(struct rge_softc *, uint16_t);
    147   1.1     sevan void		rge_write_phy(struct rge_softc *, uint16_t, uint16_t, uint16_t);
    148  1.17  jakllsch uint16_t	rge_read_phy(struct rge_softc *, uint16_t, uint16_t);
    149   1.1     sevan void		rge_write_phy_ocp(struct rge_softc *, uint16_t, uint16_t);
    150   1.1     sevan uint16_t	rge_read_phy_ocp(struct rge_softc *, uint16_t);
    151   1.1     sevan int		rge_get_link_status(struct rge_softc *);
    152  1.30     skrll void		rge_txstart(void *);
    153   1.1     sevan void		rge_tick(void *);
    154   1.1     sevan void		rge_link_state(struct rge_softc *);
    155   1.1     sevan 
    156   1.1     sevan static const struct {
    157   1.1     sevan 	uint16_t reg;
    158   1.1     sevan 	uint16_t val;
    159  1.17  jakllsch }  rtl8125_mac_cfg2_mcu[] = {
    160   1.1     sevan 	RTL8125_MAC_CFG2_MCU
    161   1.1     sevan }, rtl8125_mac_cfg3_mcu[] = {
    162   1.1     sevan 	RTL8125_MAC_CFG3_MCU
    163  1.17  jakllsch }, rtl8125_mac_cfg4_mcu[] = {
    164  1.17  jakllsch 	RTL8125_MAC_CFG4_MCU
    165  1.17  jakllsch }, rtl8125_mac_cfg5_mcu[] = {
    166  1.17  jakllsch 	RTL8125_MAC_CFG5_MCU
    167  1.34  jmcneill }, rtl8126_mac_cfg2_mcu[] = {
    168  1.34  jmcneill 	RTL8126_MAC_CFG2_MCU
    169   1.1     sevan };
    170   1.1     sevan 
    171   1.2     sevan CFATTACH_DECL_NEW(rge, sizeof(struct rge_softc), rge_match, rge_attach,
    172   1.2     sevan 		NULL, NULL); /* Sevan - detach function? */
    173   1.1     sevan 
    174  1.19   thorpej static const struct device_compatible_entry compat_data[] = {
    175  1.19   thorpej 	{ .id = PCI_ID_CODE(PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_E3000) },
    176  1.19   thorpej 	{ .id = PCI_ID_CODE(PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8125) },
    177  1.34  jmcneill 	{ .id = PCI_ID_CODE(PCI_VENDOR_REALTEK, PCI_PRODUCT_REALTEK_RT8126) },
    178  1.19   thorpej 
    179  1.19   thorpej 	PCI_COMPAT_EOL
    180   1.1     sevan };
    181   1.1     sevan 
    182   1.2     sevan static int
    183   1.2     sevan rge_match(device_t parent, cfdata_t match, void *aux)
    184   1.1     sevan {
    185   1.2     sevan 	struct pci_attach_args *pa =aux;
    186   1.2     sevan 
    187  1.19   thorpej 	return pci_compatible_match(pa, compat_data);
    188   1.1     sevan }
    189   1.1     sevan 
    190   1.1     sevan void
    191   1.2     sevan rge_attach(device_t parent, device_t self, void *aux)
    192   1.1     sevan {
    193  1.11     sevan 	struct rge_softc *sc = device_private(self);
    194   1.1     sevan 	struct pci_attach_args *pa = aux;
    195   1.1     sevan 	pci_chipset_tag_t pc = pa->pa_pc;
    196  1.17  jakllsch 	pci_intr_handle_t *ihp;
    197   1.2     sevan 	char intrbuf[PCI_INTRSTR_LEN];
    198   1.1     sevan 	const char *intrstr = NULL;
    199   1.1     sevan 	struct ifnet *ifp;
    200   1.1     sevan 	pcireg_t reg;
    201   1.1     sevan 	uint32_t hwrev;
    202   1.1     sevan 	uint8_t eaddr[ETHER_ADDR_LEN];
    203   1.1     sevan 	int offset;
    204  1.17  jakllsch 	pcireg_t command;
    205  1.31   msaitoh 	const char *revstr;
    206   1.1     sevan 
    207   1.1     sevan 	pci_set_powerstate(pa->pa_pc, pa->pa_tag, PCI_PMCSR_STATE_D0);
    208   1.1     sevan 
    209  1.12     sevan 	sc->sc_dev = self;
    210  1.12     sevan 
    211  1.17  jakllsch 	pci_aprint_devinfo(pa, "Ethernet controller");
    212  1.17  jakllsch 
    213   1.5     skrll 	/*
    214   1.1     sevan 	 * Map control/status registers.
    215   1.1     sevan 	 */
    216   1.1     sevan 	if (pci_mapreg_map(pa, RGE_PCI_BAR2, PCI_MAPREG_TYPE_MEM |
    217   1.1     sevan 	    PCI_MAPREG_MEM_TYPE_64BIT, 0, &sc->rge_btag, &sc->rge_bhandle,
    218   1.2     sevan 	    NULL, &sc->rge_bsize)) {
    219   1.1     sevan 		if (pci_mapreg_map(pa, RGE_PCI_BAR1, PCI_MAPREG_TYPE_MEM |
    220   1.1     sevan 		    PCI_MAPREG_MEM_TYPE_32BIT, 0, &sc->rge_btag,
    221   1.2     sevan 		    &sc->rge_bhandle, NULL, &sc->rge_bsize)) {
    222   1.1     sevan 			if (pci_mapreg_map(pa, RGE_PCI_BAR0, PCI_MAPREG_TYPE_IO,
    223   1.1     sevan 			    0, &sc->rge_btag, &sc->rge_bhandle, NULL,
    224   1.2     sevan 			    &sc->rge_bsize)) {
    225  1.13     sevan 				aprint_error(": can't map mem or i/o space\n");
    226   1.1     sevan 				return;
    227   1.1     sevan 			}
    228   1.1     sevan 		}
    229   1.1     sevan 	}
    230   1.1     sevan 
    231  1.17  jakllsch 	int counts[PCI_INTR_TYPE_SIZE] = {
    232  1.17  jakllsch  		[PCI_INTR_TYPE_INTX] = 1,
    233  1.17  jakllsch  		[PCI_INTR_TYPE_MSI] = 1,
    234  1.17  jakllsch  		[PCI_INTR_TYPE_MSIX] = 1,
    235  1.17  jakllsch  	};
    236  1.17  jakllsch 	int max_type = PCI_INTR_TYPE_MSIX;
    237   1.5     skrll 	/*
    238   1.1     sevan 	 * Allocate interrupt.
    239   1.1     sevan 	 */
    240  1.17  jakllsch 	if (pci_intr_alloc(pa, &ihp, counts, max_type) != 0) {
    241  1.13     sevan 		aprint_error(": couldn't map interrupt\n");
    242   1.1     sevan 		return;
    243   1.1     sevan 	}
    244  1.17  jakllsch 	switch (pci_intr_type(pc, ihp[0])) {
    245  1.17  jakllsch 	case PCI_INTR_TYPE_MSIX:
    246  1.17  jakllsch 	case PCI_INTR_TYPE_MSI:
    247  1.17  jakllsch 		sc->rge_flags |= RGE_FLAG_MSI;
    248  1.17  jakllsch 		break;
    249  1.17  jakllsch 	default:
    250  1.17  jakllsch 		break;
    251  1.17  jakllsch 	}
    252  1.17  jakllsch 	intrstr = pci_intr_string(pc, ihp[0], intrbuf, sizeof(intrbuf));
    253  1.17  jakllsch 	sc->sc_ih = pci_intr_establish_xname(pc, ihp[0], IPL_NET, rge_intr,
    254  1.14     sevan 	    sc, device_xname(sc->sc_dev));
    255   1.1     sevan 	if (sc->sc_ih == NULL) {
    256  1.13     sevan 		aprint_error_dev(sc->sc_dev, ": couldn't establish interrupt");
    257   1.1     sevan 		if (intrstr != NULL)
    258  1.13     sevan 			aprint_error(" at %s\n", intrstr);
    259  1.13     sevan 		aprint_error("\n");
    260   1.1     sevan 		return;
    261   1.1     sevan 	}
    262  1.13     sevan 	aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr);
    263   1.1     sevan 
    264   1.9   thorpej 	if (pci_dma64_available(pa))
    265   1.9   thorpej 		sc->sc_dmat = pa->pa_dmat64;
    266   1.9   thorpej 	else
    267   1.9   thorpej 		sc->sc_dmat = pa->pa_dmat;
    268   1.9   thorpej 
    269   1.1     sevan 	sc->sc_pc = pa->pa_pc;
    270   1.1     sevan 	sc->sc_tag = pa->pa_tag;
    271   1.1     sevan 
    272   1.1     sevan 	/* Determine hardware revision */
    273   1.1     sevan 	hwrev = RGE_READ_4(sc, RGE_TXCFG) & RGE_TXCFG_HWREV;
    274   1.1     sevan 	switch (hwrev) {
    275   1.1     sevan 	case 0x60800000:
    276   1.1     sevan 		sc->rge_type = MAC_CFG2;
    277  1.31   msaitoh 		revstr = "Z1";
    278   1.1     sevan 		break;
    279   1.1     sevan 	case 0x60900000:
    280   1.1     sevan 		sc->rge_type = MAC_CFG3;
    281  1.31   msaitoh 		revstr = "Z2";
    282   1.1     sevan 		break;
    283  1.17  jakllsch 	case 0x64000000:
    284  1.17  jakllsch 		sc->rge_type = MAC_CFG4;
    285  1.31   msaitoh 		revstr = "A";
    286  1.17  jakllsch 		break;
    287  1.17  jakllsch 	case 0x64100000:
    288  1.17  jakllsch 		sc->rge_type = MAC_CFG5;
    289  1.31   msaitoh 		revstr = "B";
    290  1.17  jakllsch 		break;
    291  1.34  jmcneill 	case 0x64900000:
    292  1.34  jmcneill 		sc->rge_type = MAC_CFG2_8126;
    293  1.34  jmcneill 		revstr = "A";
    294  1.34  jmcneill 		break;
    295   1.1     sevan 	default:
    296  1.13     sevan 		aprint_error(": unknown version 0x%08x\n", hwrev);
    297   1.1     sevan 		return;
    298   1.1     sevan 	}
    299   1.1     sevan 
    300  1.31   msaitoh 	aprint_normal_dev(sc->sc_dev, "HW rev. %s\n", revstr);
    301   1.1     sevan 	rge_config_imtype(sc, RGE_IMTYPE_SIM);
    302   1.1     sevan 
    303   1.5     skrll 	/*
    304   1.1     sevan 	 * PCI Express check.
    305   1.1     sevan 	 */
    306   1.1     sevan 	if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PCIEXPRESS,
    307   1.1     sevan 	    &offset, NULL)) {
    308  1.17  jakllsch 		/* Disable PCIe ASPM and ECPM. */
    309   1.1     sevan 		reg = pci_conf_read(pa->pa_pc, pa->pa_tag,
    310   1.2     sevan 		    offset + PCIE_LCSR);
    311  1.17  jakllsch 		reg &= ~(PCIE_LCSR_ASPM_L0S | PCIE_LCSR_ASPM_L1 |
    312  1.17  jakllsch 		    PCIE_LCSR_ENCLKPM);
    313   1.2     sevan 		pci_conf_write(pa->pa_pc, pa->pa_tag, offset + PCIE_LCSR,
    314   1.1     sevan 		    reg);
    315   1.1     sevan 	}
    316   1.1     sevan 
    317   1.1     sevan 	rge_exit_oob(sc);
    318   1.1     sevan 	rge_hw_init(sc);
    319   1.1     sevan 
    320   1.1     sevan 	rge_get_macaddr(sc, eaddr);
    321  1.13     sevan 	aprint_normal_dev(sc->sc_dev, "Ethernet address %s\n",
    322  1.13     sevan 	    ether_sprintf(eaddr));
    323   1.1     sevan 
    324   1.2     sevan 	memcpy(sc->sc_enaddr, eaddr, ETHER_ADDR_LEN);
    325   1.1     sevan 
    326   1.1     sevan 	rge_set_phy_power(sc, 1);
    327   1.1     sevan 	rge_phy_config(sc);
    328   1.1     sevan 
    329   1.1     sevan 	if (rge_allocmem(sc))
    330   1.1     sevan 		return;
    331   1.1     sevan 
    332   1.2     sevan 	ifp = &sc->sc_ec.ec_if;
    333   1.1     sevan 	ifp->if_softc = sc;
    334  1.14     sevan 	strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
    335   1.1     sevan 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
    336   1.2     sevan #ifdef RGE_MPSAFE
    337  1.18  knakahar 	ifp->if_extflags = IFEF_MPSAFE;
    338   1.2     sevan #endif
    339   1.1     sevan 	ifp->if_ioctl = rge_ioctl;
    340  1.17  jakllsch 	ifp->if_stop = rge_stop;
    341   1.2     sevan 	ifp->if_start = rge_start;
    342  1.17  jakllsch 	ifp->if_init = rge_init;
    343   1.1     sevan 	ifp->if_watchdog = rge_watchdog;
    344  1.17  jakllsch 	IFQ_SET_MAXLEN(&ifp->if_snd, RGE_TX_LIST_CNT - 1);
    345   1.1     sevan 
    346  1.17  jakllsch #if notyet
    347  1.17  jakllsch 	ifp->if_capabilities = IFCAP_CSUM_IPv4_Rx |
    348   1.2     sevan 	    IFCAP_CSUM_IPv4_Tx |IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_TCPv4_Tx|
    349   1.2     sevan 	    IFCAP_CSUM_UDPv4_Rx | IFCAP_CSUM_UDPv4_Tx;
    350  1.17  jakllsch #endif
    351   1.1     sevan 
    352  1.17  jakllsch 	sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_MTU;
    353  1.17  jakllsch 	sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_HWTAGGING;
    354   1.1     sevan 
    355   1.3     sevan 	callout_init(&sc->sc_timeout, CALLOUT_FLAGS);
    356   1.3     sevan 	callout_setfunc(&sc->sc_timeout, rge_tick, sc);
    357  1.17  jakllsch 
    358  1.17  jakllsch 	command = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
    359  1.17  jakllsch 	command |= PCI_COMMAND_MASTER_ENABLE;
    360  1.17  jakllsch 	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, command);
    361   1.1     sevan 
    362   1.1     sevan 	/* Initialize ifmedia structures. */
    363  1.17  jakllsch 	sc->sc_ec.ec_ifmedia = &sc->sc_media;
    364   1.1     sevan 	ifmedia_init(&sc->sc_media, IFM_IMASK, rge_ifmedia_upd,
    365   1.1     sevan 	    rge_ifmedia_sts);
    366   1.1     sevan 	rge_add_media_types(sc);
    367   1.1     sevan 	ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL);
    368   1.1     sevan 	ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO);
    369   1.1     sevan 	sc->sc_media.ifm_media = sc->sc_media.ifm_cur->ifm_media;
    370   1.1     sevan 
    371   1.1     sevan 	if_attach(ifp);
    372  1.29   mlelstv 	if_deferred_start_init(ifp, NULL);
    373   1.2     sevan 	ether_ifattach(ifp, eaddr);
    374  1.20   msaitoh 
    375  1.20   msaitoh 	if (pmf_device_register(self, NULL, NULL))
    376  1.20   msaitoh 		pmf_class_network_register(self, ifp);
    377  1.20   msaitoh 	else
    378  1.20   msaitoh 		aprint_error_dev(self, "couldn't establish power handler\n");
    379   1.1     sevan }
    380   1.1     sevan 
    381   1.1     sevan int
    382   1.1     sevan rge_intr(void *arg)
    383   1.1     sevan {
    384   1.1     sevan 	struct rge_softc *sc = arg;
    385   1.2     sevan 	struct ifnet *ifp = &sc->sc_ec.ec_if;
    386   1.1     sevan 	uint32_t status;
    387   1.1     sevan 	int claimed = 0, rx, tx;
    388   1.1     sevan 
    389   1.1     sevan 	if (!(ifp->if_flags & IFF_RUNNING))
    390   1.1     sevan 		return (0);
    391   1.1     sevan 
    392   1.1     sevan 	/* Disable interrupts. */
    393   1.1     sevan 	RGE_WRITE_4(sc, RGE_IMR, 0);
    394   1.1     sevan 
    395   1.1     sevan 	if (!(sc->rge_flags & RGE_FLAG_MSI)) {
    396  1.17  jakllsch 		if ((RGE_READ_4(sc, RGE_ISR) & sc->rge_intrs) == 0)
    397   1.1     sevan 			return (0);
    398   1.1     sevan 	}
    399  1.17  jakllsch 
    400  1.17  jakllsch 	status = RGE_READ_4(sc, RGE_ISR);
    401   1.1     sevan 	if (status)
    402   1.1     sevan 		RGE_WRITE_4(sc, RGE_ISR, status);
    403   1.1     sevan 
    404   1.1     sevan 	if (status & RGE_ISR_PCS_TIMEOUT)
    405   1.1     sevan 		claimed = 1;
    406   1.1     sevan 
    407   1.1     sevan 	rx = tx = 0;
    408  1.17  jakllsch 	if (status & sc->rge_intrs) {
    409   1.1     sevan 		if (status &
    410   1.1     sevan 		    (sc->rge_rx_ack | RGE_ISR_RX_ERR | RGE_ISR_RX_FIFO_OFLOW)) {
    411   1.1     sevan 			rx |= rge_rxeof(sc);
    412   1.1     sevan 			claimed = 1;
    413   1.1     sevan 		}
    414   1.1     sevan 
    415   1.1     sevan 		if (status & (sc->rge_tx_ack | RGE_ISR_TX_ERR)) {
    416   1.1     sevan 			tx |= rge_txeof(sc);
    417   1.1     sevan 			claimed = 1;
    418   1.1     sevan 		}
    419   1.1     sevan 
    420   1.1     sevan 		if (status & RGE_ISR_SYSTEM_ERR) {
    421   1.2     sevan 			KERNEL_LOCK(1, NULL);
    422   1.1     sevan 			rge_init(ifp);
    423   1.2     sevan 			KERNEL_UNLOCK_ONE(NULL);
    424   1.1     sevan 			claimed = 1;
    425   1.1     sevan 		}
    426   1.1     sevan 	}
    427   1.1     sevan 
    428   1.1     sevan 	if (sc->rge_timerintr) {
    429   1.1     sevan 		if ((tx | rx) == 0) {
    430   1.1     sevan 			/*
    431   1.1     sevan 			 * Nothing needs to be processed, fallback
    432   1.1     sevan 			 * to use TX/RX interrupts.
    433   1.1     sevan 			 */
    434   1.1     sevan 			rge_setup_intr(sc, RGE_IMTYPE_NONE);
    435   1.1     sevan 
    436   1.1     sevan 			/*
    437   1.1     sevan 			 * Recollect, mainly to avoid the possible
    438   1.1     sevan 			 * race introduced by changing interrupt
    439   1.1     sevan 			 * masks.
    440   1.1     sevan 			 */
    441   1.1     sevan 			rge_rxeof(sc);
    442   1.1     sevan 			rge_txeof(sc);
    443   1.1     sevan 		} else
    444   1.1     sevan 			RGE_WRITE_4(sc, RGE_TIMERCNT, 1);
    445   1.1     sevan 	} else if (tx | rx) {
    446   1.1     sevan 		/*
    447   1.1     sevan 		 * Assume that using simulated interrupt moderation
    448   1.1     sevan 		 * (hardware timer based) could reduce the interrupt
    449   1.1     sevan 		 * rate.
    450   1.1     sevan 		 */
    451   1.1     sevan 		rge_setup_intr(sc, RGE_IMTYPE_SIM);
    452   1.1     sevan 	}
    453   1.1     sevan 
    454   1.1     sevan 	RGE_WRITE_4(sc, RGE_IMR, sc->rge_intrs);
    455   1.1     sevan 
    456   1.1     sevan 	return (claimed);
    457   1.1     sevan }
    458   1.1     sevan 
    459   1.1     sevan int
    460   1.1     sevan rge_encap(struct rge_softc *sc, struct mbuf *m, int idx)
    461   1.1     sevan {
    462   1.1     sevan 	struct rge_tx_desc *d = NULL;
    463   1.1     sevan 	struct rge_txq *txq;
    464   1.1     sevan 	bus_dmamap_t txmap;
    465   1.1     sevan 	uint32_t cmdsts, cflags = 0;
    466   1.1     sevan 	int cur, error, i, last, nsegs;
    467   1.1     sevan 
    468  1.17  jakllsch #if notyet
    469   1.1     sevan 	/*
    470   1.1     sevan 	 * Set RGE_TDEXTSTS_IPCSUM if any checksum offloading is requested.
    471   1.1     sevan 	 * Otherwise, RGE_TDEXTSTS_TCPCSUM / RGE_TDEXTSTS_UDPCSUM does not
    472   1.1     sevan 	 * take affect.
    473   1.1     sevan 	 */
    474   1.1     sevan 	if ((m->m_pkthdr.csum_flags &
    475   1.2     sevan 	    (M_CSUM_IPv4 | M_CSUM_TCPv4 | M_CSUM_UDPv4)) != 0) {
    476   1.1     sevan 		cflags |= RGE_TDEXTSTS_IPCSUM;
    477   1.1     sevan 		if (m->m_pkthdr.csum_flags & M_TCP_CSUM_OUT)
    478   1.1     sevan 			cflags |= RGE_TDEXTSTS_TCPCSUM;
    479   1.1     sevan 		if (m->m_pkthdr.csum_flags & M_UDP_CSUM_OUT)
    480   1.1     sevan 			cflags |= RGE_TDEXTSTS_UDPCSUM;
    481   1.1     sevan 	}
    482  1.17  jakllsch #endif
    483   1.1     sevan 
    484   1.1     sevan 	txq = &sc->rge_ldata.rge_txq[idx];
    485   1.1     sevan 	txmap = txq->txq_dmamap;
    486   1.1     sevan 
    487   1.1     sevan 	error = bus_dmamap_load_mbuf(sc->sc_dmat, txmap, m, BUS_DMA_NOWAIT);
    488   1.1     sevan 	switch (error) {
    489   1.1     sevan 	case 0:
    490   1.1     sevan 		break;
    491   1.1     sevan 	case EFBIG: /* mbuf chain is too fragmented */
    492   1.1     sevan 		if (m_defrag(m, M_DONTWAIT) == 0 &&
    493   1.1     sevan 		    bus_dmamap_load_mbuf(sc->sc_dmat, txmap, m,
    494   1.1     sevan 		    BUS_DMA_NOWAIT) == 0)
    495   1.1     sevan 			break;
    496   1.1     sevan 
    497   1.1     sevan 		/* FALLTHROUGH */
    498   1.1     sevan 	default:
    499   1.1     sevan 		return (0);
    500   1.1     sevan 	}
    501   1.1     sevan 
    502   1.1     sevan 	bus_dmamap_sync(sc->sc_dmat, txmap, 0, txmap->dm_mapsize,
    503   1.1     sevan 	    BUS_DMASYNC_PREWRITE);
    504   1.1     sevan 
    505   1.1     sevan 	nsegs = txmap->dm_nsegs;
    506   1.1     sevan 
    507   1.1     sevan 	/* Set up hardware VLAN tagging. */
    508  1.17  jakllsch 	if (vlan_has_tag(m))
    509  1.17  jakllsch 		cflags |= bswap16(vlan_get_tag(m)) | RGE_TDEXTSTS_VTAG;
    510   1.1     sevan 
    511  1.17  jakllsch 	last = cur = idx;
    512   1.1     sevan 	cmdsts = RGE_TDCMDSTS_SOF;
    513   1.1     sevan 
    514   1.1     sevan 	for (i = 0; i < txmap->dm_nsegs; i++) {
    515   1.1     sevan 		d = &sc->rge_ldata.rge_tx_list[cur];
    516   1.1     sevan 
    517   1.1     sevan 		d->rge_extsts = htole32(cflags);
    518   1.1     sevan 		d->rge_addrlo = htole32(RGE_ADDR_LO(txmap->dm_segs[i].ds_addr));
    519   1.1     sevan 		d->rge_addrhi = htole32(RGE_ADDR_HI(txmap->dm_segs[i].ds_addr));
    520   1.1     sevan 
    521   1.1     sevan 		cmdsts |= txmap->dm_segs[i].ds_len;
    522   1.1     sevan 
    523   1.1     sevan 		if (cur == RGE_TX_LIST_CNT - 1)
    524   1.1     sevan 			cmdsts |= RGE_TDCMDSTS_EOR;
    525   1.1     sevan 
    526   1.1     sevan 		d->rge_cmdsts = htole32(cmdsts);
    527   1.1     sevan 
    528   1.1     sevan 		last = cur;
    529   1.1     sevan 		cmdsts = RGE_TDCMDSTS_OWN;
    530   1.1     sevan 		cur = RGE_NEXT_TX_DESC(cur);
    531   1.1     sevan 	}
    532   1.1     sevan 
    533   1.1     sevan 	/* Set EOF on the last descriptor. */
    534   1.1     sevan 	d->rge_cmdsts |= htole32(RGE_TDCMDSTS_EOF);
    535   1.1     sevan 
    536   1.1     sevan 	/* Transfer ownership of packet to the chip. */
    537   1.1     sevan 	d = &sc->rge_ldata.rge_tx_list[idx];
    538   1.1     sevan 
    539   1.1     sevan 	d->rge_cmdsts |= htole32(RGE_TDCMDSTS_OWN);
    540   1.1     sevan 
    541   1.1     sevan 	bus_dmamap_sync(sc->sc_dmat, sc->rge_ldata.rge_tx_list_map,
    542   1.1     sevan 	    cur * sizeof(struct rge_tx_desc), sizeof(struct rge_tx_desc),
    543   1.1     sevan 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
    544   1.1     sevan 
    545   1.1     sevan 	/* Update info of TX queue and descriptors. */
    546   1.1     sevan 	txq->txq_mbuf = m;
    547   1.1     sevan 	txq->txq_descidx = last;
    548   1.1     sevan 
    549   1.1     sevan 	return (nsegs);
    550   1.1     sevan }
    551   1.1     sevan 
    552   1.1     sevan int
    553   1.2     sevan rge_ioctl(struct ifnet *ifp, u_long cmd, void *data)
    554   1.1     sevan {
    555   1.1     sevan 	struct rge_softc *sc = ifp->if_softc;
    556  1.17  jakllsch 	//struct ifreq *ifr = (struct ifreq *)data;
    557   1.1     sevan 	int s, error = 0;
    558   1.1     sevan 
    559   1.1     sevan 	s = splnet();
    560   1.1     sevan 
    561   1.1     sevan 	switch (cmd) {
    562   1.1     sevan 	case SIOCSIFFLAGS:
    563  1.17  jakllsch 		if ((error = ifioctl_common(ifp, cmd, data)) != 0)
    564  1.17  jakllsch 			break;
    565  1.17  jakllsch 		/* XXX set an ifflags callback and let ether_ioctl
    566  1.17  jakllsch 		 * handle all of this.
    567  1.17  jakllsch 		 */
    568   1.1     sevan 		if (ifp->if_flags & IFF_UP) {
    569   1.1     sevan 			if (ifp->if_flags & IFF_RUNNING)
    570   1.1     sevan 				error = ENETRESET;
    571   1.1     sevan 			else
    572   1.1     sevan 				rge_init(ifp);
    573   1.1     sevan 		} else {
    574   1.1     sevan 			if (ifp->if_flags & IFF_RUNNING)
    575  1.17  jakllsch 				rge_stop(ifp, 1);
    576   1.1     sevan 		}
    577   1.1     sevan 		break;
    578   1.1     sevan 	default:
    579   1.2     sevan 		error = ether_ioctl(ifp, cmd, data);
    580   1.1     sevan 	}
    581   1.1     sevan 
    582   1.1     sevan 	if (error == ENETRESET) {
    583   1.1     sevan 		if (ifp->if_flags & IFF_RUNNING)
    584   1.1     sevan 			rge_iff(sc);
    585   1.1     sevan 		error = 0;
    586   1.1     sevan 	}
    587   1.1     sevan 
    588   1.1     sevan 	splx(s);
    589   1.1     sevan 	return (error);
    590   1.1     sevan }
    591   1.1     sevan 
    592   1.1     sevan void
    593   1.3     sevan rge_start(struct ifnet *ifp)
    594   1.1     sevan {
    595   1.1     sevan 	struct rge_softc *sc = ifp->if_softc;
    596   1.1     sevan 	struct mbuf *m;
    597   1.1     sevan 	int free, idx, used;
    598   1.1     sevan 	int queued = 0;
    599   1.1     sevan 
    600   1.2     sevan #define LINK_STATE_IS_UP(_s)    \
    601   1.2     sevan 	((_s) >= LINK_STATE_UP || (_s) == LINK_STATE_UNKNOWN)
    602   1.2     sevan 
    603   1.1     sevan 	if (!LINK_STATE_IS_UP(ifp->if_link_state)) {
    604  1.17  jakllsch 		IFQ_PURGE(&ifp->if_snd);
    605   1.1     sevan 		return;
    606   1.1     sevan 	}
    607   1.1     sevan 
    608   1.1     sevan 	/* Calculate free space. */
    609   1.1     sevan 	idx = sc->rge_ldata.rge_txq_prodidx;
    610   1.1     sevan 	free = sc->rge_ldata.rge_txq_considx;
    611   1.1     sevan 	if (free <= idx)
    612   1.1     sevan 		free += RGE_TX_LIST_CNT;
    613   1.1     sevan 	free -= idx;
    614   1.1     sevan 
    615   1.1     sevan 	for (;;) {
    616   1.1     sevan 		if (RGE_TX_NSEGS >= free + 2) {
    617   1.3     sevan 			SET(ifp->if_flags, IFF_OACTIVE);
    618   1.1     sevan 			break;
    619   1.1     sevan 		}
    620   1.1     sevan 
    621   1.3     sevan 		IFQ_DEQUEUE(&ifp->if_snd, m);
    622   1.1     sevan 		if (m == NULL)
    623   1.1     sevan 			break;
    624   1.1     sevan 
    625   1.1     sevan 		used = rge_encap(sc, m, idx);
    626   1.1     sevan 		if (used == 0) {
    627   1.1     sevan 			m_freem(m);
    628   1.1     sevan 			continue;
    629   1.1     sevan 		}
    630   1.1     sevan 
    631   1.1     sevan 		KASSERT(used <= free);
    632   1.1     sevan 		free -= used;
    633   1.1     sevan 
    634  1.17  jakllsch 		bpf_mtap(ifp, m, BPF_D_OUT);
    635   1.1     sevan 
    636   1.1     sevan 		idx += used;
    637   1.1     sevan 		if (idx >= RGE_TX_LIST_CNT)
    638   1.1     sevan 			idx -= RGE_TX_LIST_CNT;
    639   1.1     sevan 
    640   1.1     sevan 		queued++;
    641   1.1     sevan 	}
    642   1.1     sevan 
    643   1.1     sevan 	if (queued == 0)
    644   1.1     sevan 		return;
    645   1.1     sevan 
    646   1.1     sevan 	/* Set a timeout in case the chip goes out to lunch. */
    647   1.1     sevan 	ifp->if_timer = 5;
    648   1.1     sevan 
    649   1.1     sevan 	sc->rge_ldata.rge_txq_prodidx = idx;
    650  1.30     skrll 	rge_txstart(sc);
    651   1.1     sevan }
    652   1.1     sevan 
    653   1.1     sevan void
    654   1.1     sevan rge_watchdog(struct ifnet *ifp)
    655   1.1     sevan {
    656   1.1     sevan 	struct rge_softc *sc = ifp->if_softc;
    657   1.1     sevan 
    658  1.16  jakllsch 	device_printf(sc->sc_dev, "watchdog timeout\n");
    659   1.4     skrll 	if_statinc(ifp, if_oerrors);
    660   1.1     sevan 
    661   1.1     sevan 	rge_init(ifp);
    662   1.1     sevan }
    663   1.1     sevan 
    664   1.1     sevan int
    665   1.1     sevan rge_init(struct ifnet *ifp)
    666   1.1     sevan {
    667   1.1     sevan 	struct rge_softc *sc = ifp->if_softc;
    668   1.1     sevan 	uint32_t val;
    669  1.26       mrg 	unsigned i;
    670   1.1     sevan 
    671  1.17  jakllsch 	rge_stop(ifp, 0);
    672   1.1     sevan 
    673   1.1     sevan 	/* Set MAC address. */
    674  1.17  jakllsch 	rge_set_macaddr(sc, CLLADDR(ifp->if_sadl));
    675   1.1     sevan 
    676  1.17  jakllsch 	/* Set Maximum frame size. */
    677  1.17  jakllsch 	RGE_WRITE_2(sc, RGE_RXMAXSIZE, RGE_JUMBO_FRAMELEN);
    678   1.1     sevan 
    679   1.1     sevan 	/* Initialize RX descriptors list. */
    680  1.26       mrg 	int error = rge_rx_list_init(sc);
    681  1.26       mrg 	if (error != 0) {
    682  1.16  jakllsch 		device_printf(sc->sc_dev,
    683  1.13     sevan 		    "init failed: no memory for RX buffers\n");
    684  1.17  jakllsch 		rge_stop(ifp, 1);
    685  1.26       mrg 		return error;
    686   1.1     sevan 	}
    687   1.1     sevan 
    688   1.1     sevan 	/* Initialize TX descriptors. */
    689   1.1     sevan 	rge_tx_list_init(sc);
    690   1.1     sevan 
    691   1.1     sevan 	/* Load the addresses of the RX and TX lists into the chip. */
    692   1.1     sevan 	RGE_WRITE_4(sc, RGE_RXDESC_ADDR_LO,
    693   1.1     sevan 	    RGE_ADDR_LO(sc->rge_ldata.rge_rx_list_map->dm_segs[0].ds_addr));
    694   1.1     sevan 	RGE_WRITE_4(sc, RGE_RXDESC_ADDR_HI,
    695   1.1     sevan 	    RGE_ADDR_HI(sc->rge_ldata.rge_rx_list_map->dm_segs[0].ds_addr));
    696   1.1     sevan 	RGE_WRITE_4(sc, RGE_TXDESC_ADDR_LO,
    697   1.1     sevan 	    RGE_ADDR_LO(sc->rge_ldata.rge_tx_list_map->dm_segs[0].ds_addr));
    698   1.1     sevan 	RGE_WRITE_4(sc, RGE_TXDESC_ADDR_HI,
    699   1.1     sevan 	    RGE_ADDR_HI(sc->rge_ldata.rge_tx_list_map->dm_segs[0].ds_addr));
    700   1.1     sevan 
    701   1.1     sevan 	RGE_SETBIT_1(sc, RGE_EECMD, RGE_EECMD_WRITECFG);
    702   1.1     sevan 
    703   1.1     sevan 	RGE_CLRBIT_1(sc, 0xf1, 0x80);
    704  1.34  jmcneill 	if (sc->rge_type == MAC_CFG2_8126)
    705  1.34  jmcneill 		RGE_CLRBIT_1(sc, RGE_INT_CFG0, 0x08);
    706  1.34  jmcneill 	else
    707  1.34  jmcneill 		RGE_CLRBIT_1(sc, RGE_CFG2, RGE_CFG2_CLKREQ_EN);
    708   1.1     sevan 	RGE_CLRBIT_1(sc, RGE_CFG5, RGE_CFG5_PME_STS);
    709  1.34  jmcneill 	if (sc->rge_type != MAC_CFG2_8126)
    710  1.34  jmcneill 		RGE_CLRBIT_1(sc, RGE_CFG3, RGE_CFG3_RDY_TO_L23);
    711   1.1     sevan 
    712   1.1     sevan 	/* Clear interrupt moderation timer. */
    713   1.1     sevan 	for (i = 0; i < 64; i++)
    714  1.17  jakllsch 		RGE_WRITE_4(sc, RGE_INTMITI(i), 0);
    715   1.1     sevan 
    716   1.1     sevan 	/* Set the initial RX and TX configurations. */
    717  1.34  jmcneill 	if (sc->rge_type == MAC_CFG2_8126)
    718  1.34  jmcneill 		RGE_WRITE_4(sc, RGE_RXCFG, RGE_RXCFG_CONFIG_8126);
    719  1.34  jmcneill 	else
    720  1.34  jmcneill 		RGE_WRITE_4(sc, RGE_RXCFG, RGE_RXCFG_CONFIG);
    721   1.1     sevan 	RGE_WRITE_4(sc, RGE_TXCFG, RGE_TXCFG_CONFIG);
    722   1.1     sevan 
    723   1.1     sevan 	val = rge_read_csi(sc, 0x70c) & ~0xff000000;
    724   1.1     sevan 	rge_write_csi(sc, 0x70c, val | 0x27000000);
    725   1.1     sevan 
    726   1.1     sevan 	/* Enable hardware optimization function. */
    727   1.1     sevan 	val = pci_conf_read(sc->sc_pc, sc->sc_tag, 0x78) & ~0x00007000;
    728   1.1     sevan 	pci_conf_write(sc->sc_pc, sc->sc_tag, 0x78, val | 0x00005000);
    729   1.1     sevan 
    730  1.34  jmcneill 	if (sc->rge_type == MAC_CFG2_8126) {
    731  1.34  jmcneill 		/* Disable L1 timeout. */
    732  1.34  jmcneill 		val = rge_read_csi(sc, 0x890) & ~0x00000001;
    733  1.34  jmcneill 		rge_write_csi(sc, 0x890, val);
    734  1.34  jmcneill 	} else
    735  1.34  jmcneill 		RGE_WRITE_2(sc, 0x0382, 0x221b);
    736   1.1     sevan 	RGE_WRITE_1(sc, 0x4500, 0);
    737   1.1     sevan 	RGE_WRITE_2(sc, 0x4800, 0);
    738   1.1     sevan 	RGE_CLRBIT_1(sc, RGE_CFG1, RGE_CFG1_SPEED_DOWN);
    739   1.1     sevan 
    740   1.1     sevan 	rge_write_mac_ocp(sc, 0xc140, 0xffff);
    741   1.1     sevan 	rge_write_mac_ocp(sc, 0xc142, 0xffff);
    742   1.1     sevan 
    743   1.1     sevan 	val = rge_read_mac_ocp(sc, 0xd3e2) & ~0x0fff;
    744   1.1     sevan 	rge_write_mac_ocp(sc, 0xd3e2, val | 0x03a9);
    745   1.1     sevan 
    746   1.1     sevan 	RGE_MAC_CLRBIT(sc, 0xd3e4, 0x00ff);
    747   1.1     sevan 	RGE_MAC_SETBIT(sc, 0xe860, 0x0080);
    748   1.1     sevan 	RGE_MAC_SETBIT(sc, 0xeb58, 0x0001);
    749   1.1     sevan 
    750  1.34  jmcneill 	if (sc->rge_type == MAC_CFG2_8126)
    751  1.34  jmcneill 		RGE_CLRBIT_1(sc, 0xd8, 0x02);
    752  1.34  jmcneill 
    753   1.1     sevan 	val = rge_read_mac_ocp(sc, 0xe614) & ~0x0700;
    754  1.34  jmcneill 	if (sc->rge_type == MAC_CFG2 || sc->rge_type == MAC_CFG3 ||
    755  1.34  jmcneill 	    sc->rge_type == MAC_CFG2_8126)
    756  1.17  jakllsch 		rge_write_mac_ocp(sc, 0xe614, val | 0x0400);
    757  1.17  jakllsch 	else
    758  1.17  jakllsch 		rge_write_mac_ocp(sc, 0xe614, val | 0x0200);
    759   1.1     sevan 
    760   1.1     sevan 	RGE_MAC_CLRBIT(sc, 0xe63e, 0x0c00);
    761   1.1     sevan 
    762  1.34  jmcneill 	if (sc->rge_type == MAC_CFG2 || sc->rge_type == MAC_CFG3 ||
    763  1.34  jmcneill 	    sc->rge_type == MAC_CFG2_8126) {
    764  1.17  jakllsch 		val = rge_read_mac_ocp(sc, 0xe63e) & ~0x0030;
    765  1.17  jakllsch 		rge_write_mac_ocp(sc, 0xe63e, val | 0x0020);
    766  1.17  jakllsch 	} else
    767  1.17  jakllsch 		RGE_MAC_CLRBIT(sc, 0xe63e, 0x0030);
    768   1.1     sevan 
    769   1.1     sevan 	RGE_MAC_SETBIT(sc, 0xc0b4, 0x000c);
    770   1.1     sevan 
    771  1.17  jakllsch 	val = rge_read_mac_ocp(sc, 0xeb6a) & ~0x00ff;
    772   1.1     sevan 	rge_write_mac_ocp(sc, 0xeb6a, val | 0x0033);
    773   1.1     sevan 
    774   1.1     sevan 	val = rge_read_mac_ocp(sc, 0xeb50) & ~0x03e0;
    775   1.1     sevan 	rge_write_mac_ocp(sc, 0xeb50, val | 0x0040);
    776   1.1     sevan 
    777   1.1     sevan 	val = rge_read_mac_ocp(sc, 0xe056) & ~0x00f0;
    778   1.1     sevan 	rge_write_mac_ocp(sc, 0xe056, val | 0x0030);
    779   1.1     sevan 
    780   1.1     sevan 	RGE_WRITE_1(sc, RGE_TDFNR, 0x10);
    781   1.1     sevan 
    782  1.17  jakllsch 	RGE_SETBIT_1(sc, RGE_DLLPR, RGE_DLLPR_TX_10M_PS_EN);
    783  1.17  jakllsch 
    784   1.1     sevan 	RGE_MAC_CLRBIT(sc, 0xe040, 0x1000);
    785   1.1     sevan 
    786  1.17  jakllsch 	val = rge_read_mac_ocp(sc, 0xea1c) & ~0x0003;
    787  1.17  jakllsch 	rge_write_mac_ocp(sc, 0xea1c, val | 0x0001);
    788  1.17  jakllsch 
    789   1.1     sevan 	val = rge_read_mac_ocp(sc, 0xe0c0) & ~0x4f0f;
    790   1.1     sevan 	rge_write_mac_ocp(sc, 0xe0c0, val | 0x4403);
    791   1.1     sevan 
    792   1.1     sevan 	RGE_MAC_SETBIT(sc, 0xe052, 0x0068);
    793   1.1     sevan 	RGE_MAC_CLRBIT(sc, 0xe052, 0x0080);
    794   1.1     sevan 
    795   1.1     sevan 	val = rge_read_mac_ocp(sc, 0xc0ac) & ~0x0080;
    796   1.1     sevan 	rge_write_mac_ocp(sc, 0xc0ac, val | 0x1f00);
    797   1.1     sevan 
    798   1.1     sevan 	val = rge_read_mac_ocp(sc, 0xd430) & ~0x0fff;
    799   1.1     sevan 	rge_write_mac_ocp(sc, 0xd430, val | 0x047f);
    800   1.1     sevan 
    801  1.17  jakllsch 	val = rge_read_mac_ocp(sc, 0xe84c) & ~0x0040;
    802  1.17  jakllsch 	if (sc->rge_type == MAC_CFG2 || sc->rge_type == MAC_CFG3)
    803  1.17  jakllsch 		rge_write_mac_ocp(sc, 0xe84c, 0x00c0);
    804  1.17  jakllsch 	else
    805  1.17  jakllsch 		rge_write_mac_ocp(sc, 0xe84c, 0x0080);
    806  1.17  jakllsch 
    807  1.17  jakllsch 	RGE_SETBIT_1(sc, RGE_DLLPR, RGE_DLLPR_PFM_EN);
    808  1.17  jakllsch 
    809  1.17  jakllsch 	if (sc->rge_type == MAC_CFG2 || sc->rge_type == MAC_CFG3)
    810  1.17  jakllsch 		RGE_SETBIT_1(sc, RGE_MCUCMD, 0x01);
    811   1.1     sevan 
    812   1.1     sevan 	/* Disable EEE plus. */
    813   1.1     sevan 	RGE_MAC_CLRBIT(sc, 0xe080, 0x0002);
    814   1.1     sevan 
    815  1.34  jmcneill 	if (sc->rge_type == MAC_CFG2_8126)
    816  1.34  jmcneill 		RGE_MAC_CLRBIT(sc, 0xea1c, 0x0304);
    817  1.34  jmcneill 	else
    818  1.34  jmcneill 		RGE_MAC_CLRBIT(sc, 0xea1c, 0x0004);
    819   1.1     sevan 
    820   1.1     sevan 	RGE_MAC_SETBIT(sc, 0xeb54, 0x0001);
    821   1.1     sevan 	DELAY(1);
    822   1.1     sevan 	RGE_MAC_CLRBIT(sc, 0xeb54, 0x0001);
    823   1.1     sevan 
    824   1.1     sevan 	RGE_CLRBIT_4(sc, 0x1880, 0x0030);
    825   1.1     sevan 
    826   1.1     sevan 	rge_write_mac_ocp(sc, 0xe098, 0xc302);
    827   1.1     sevan 
    828  1.17  jakllsch 	if ((sc->sc_ec.ec_capenable & ETHERCAP_VLAN_HWTAGGING) != 0)
    829   1.1     sevan 		RGE_SETBIT_4(sc, RGE_RXCFG, RGE_RXCFG_VLANSTRIP);
    830  1.17  jakllsch 	else
    831  1.17  jakllsch 		RGE_CLRBIT_4(sc, RGE_RXCFG, RGE_RXCFG_VLANSTRIP);
    832   1.1     sevan 
    833   1.1     sevan 	RGE_SETBIT_2(sc, RGE_CPLUSCMD, RGE_CPLUSCMD_RXCSUM);
    834   1.1     sevan 
    835   1.1     sevan 	for (i = 0; i < 10; i++) {
    836   1.1     sevan 		if (!(rge_read_mac_ocp(sc, 0xe00e) & 0x2000))
    837   1.1     sevan 			break;
    838   1.1     sevan 		DELAY(1000);
    839   1.1     sevan 	}
    840   1.1     sevan 
    841   1.1     sevan 	/* Disable RXDV gate. */
    842   1.1     sevan 	RGE_CLRBIT_1(sc, RGE_PPSW, 0x08);
    843   1.1     sevan 	DELAY(2000);
    844   1.1     sevan 
    845   1.1     sevan 	rge_ifmedia_upd(ifp);
    846   1.1     sevan 
    847   1.1     sevan 	/* Enable transmit and receive. */
    848   1.1     sevan 	RGE_WRITE_1(sc, RGE_CMD, RGE_CMD_TXENB | RGE_CMD_RXENB);
    849   1.1     sevan 
    850   1.1     sevan 	/* Program promiscuous mode and multicast filters. */
    851   1.1     sevan 	rge_iff(sc);
    852   1.1     sevan 
    853  1.34  jmcneill 	if (sc->rge_type == MAC_CFG2_8126)
    854  1.34  jmcneill 		RGE_CLRBIT_1(sc, RGE_INT_CFG0, 0x08);
    855  1.34  jmcneill 	else
    856  1.34  jmcneill 		RGE_CLRBIT_1(sc, RGE_CFG2, RGE_CFG2_CLKREQ_EN);
    857   1.1     sevan 	RGE_CLRBIT_1(sc, RGE_CFG5, RGE_CFG5_PME_STS);
    858   1.1     sevan 
    859   1.1     sevan 	RGE_CLRBIT_1(sc, RGE_EECMD, RGE_EECMD_WRITECFG);
    860   1.1     sevan 
    861   1.1     sevan 	/* Enable interrupts. */
    862   1.1     sevan 	rge_setup_intr(sc, RGE_IMTYPE_SIM);
    863   1.1     sevan 
    864   1.1     sevan 	ifp->if_flags |= IFF_RUNNING;
    865   1.3     sevan 	CLR(ifp->if_flags, IFF_OACTIVE);
    866   1.1     sevan 
    867   1.3     sevan 	callout_schedule(&sc->sc_timeout, 1);
    868   1.1     sevan 
    869   1.1     sevan 	return (0);
    870   1.1     sevan }
    871   1.1     sevan 
    872   1.1     sevan /*
    873   1.1     sevan  * Stop the adapter and free any mbufs allocated to the RX and TX lists.
    874   1.1     sevan  */
    875   1.1     sevan void
    876  1.17  jakllsch rge_stop(struct ifnet *ifp, int disable)
    877   1.1     sevan {
    878   1.1     sevan 	struct rge_softc *sc = ifp->if_softc;
    879   1.1     sevan 
    880  1.27  riastrad 	callout_halt(&sc->sc_timeout, NULL);
    881   1.1     sevan 
    882   1.1     sevan 	ifp->if_timer = 0;
    883   1.1     sevan 	ifp->if_flags &= ~IFF_RUNNING;
    884   1.1     sevan 	sc->rge_timerintr = 0;
    885   1.1     sevan 
    886   1.1     sevan 	RGE_CLRBIT_4(sc, RGE_RXCFG, RGE_RXCFG_ALLPHYS | RGE_RXCFG_INDIV |
    887   1.1     sevan 	    RGE_RXCFG_MULTI | RGE_RXCFG_BROAD | RGE_RXCFG_RUNT |
    888   1.1     sevan 	    RGE_RXCFG_ERRPKT);
    889   1.1     sevan 
    890   1.1     sevan 	RGE_WRITE_4(sc, RGE_IMR, 0);
    891  1.17  jakllsch 
    892  1.34  jmcneill 	/* Config interrupt type for RTL8126. */
    893  1.34  jmcneill 	if (sc->rge_type == MAC_CFG2_8126)
    894  1.34  jmcneill 		RGE_CLRBIT_1(sc, RGE_INT_CFG0, RGE_INT_CFG0_EN);
    895  1.34  jmcneill 
    896  1.17  jakllsch 	/* Clear timer interrupts. */
    897  1.17  jakllsch 	RGE_WRITE_4(sc, RGE_TIMERINT0, 0);
    898  1.17  jakllsch 	RGE_WRITE_4(sc, RGE_TIMERINT1, 0);
    899  1.17  jakllsch 	RGE_WRITE_4(sc, RGE_TIMERINT2, 0);
    900  1.17  jakllsch 	RGE_WRITE_4(sc, RGE_TIMERINT3, 0);
    901   1.1     sevan 
    902   1.1     sevan 	rge_reset(sc);
    903   1.1     sevan 
    904  1.17  jakllsch //	intr_barrier(sc->sc_ih);
    905  1.17  jakllsch //	ifq_barrier(&ifp->if_snd);
    906   1.2     sevan /*	ifq_clr_oactive(&ifp->if_snd); Sevan - OpenBSD queue API */
    907   1.1     sevan 
    908   1.1     sevan 	if (sc->rge_head != NULL) {
    909   1.1     sevan 		m_freem(sc->rge_head);
    910   1.1     sevan 		sc->rge_head = sc->rge_tail = NULL;
    911   1.1     sevan 	}
    912   1.1     sevan 
    913  1.26       mrg 	rge_tx_list_fini(sc);
    914  1.26       mrg 	rge_rx_list_fini(sc);
    915   1.1     sevan }
    916   1.1     sevan 
    917   1.1     sevan /*
    918   1.1     sevan  * Set media options.
    919   1.1     sevan  */
    920   1.1     sevan int
    921   1.1     sevan rge_ifmedia_upd(struct ifnet *ifp)
    922   1.1     sevan {
    923   1.1     sevan 	struct rge_softc *sc = ifp->if_softc;
    924   1.1     sevan 	struct ifmedia *ifm = &sc->sc_media;
    925   1.1     sevan 	int anar, gig, val;
    926   1.1     sevan 
    927   1.1     sevan 	if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
    928   1.1     sevan 		return (EINVAL);
    929   1.1     sevan 
    930   1.1     sevan 	/* Disable Gigabit Lite. */
    931   1.1     sevan 	RGE_PHY_CLRBIT(sc, 0xa428, 0x0200);
    932   1.1     sevan 	RGE_PHY_CLRBIT(sc, 0xa5ea, 0x0001);
    933  1.34  jmcneill 	if (sc->rge_type == MAC_CFG2_8126)
    934  1.34  jmcneill 		RGE_PHY_CLRBIT(sc, 0xa5ea, 0x0002);
    935   1.1     sevan 
    936   1.1     sevan 	val = rge_read_phy_ocp(sc, 0xa5d4);
    937   1.1     sevan 	val &= ~RGE_ADV_2500TFDX;
    938  1.34  jmcneill 	if (sc->rge_type == MAC_CFG2_8126)
    939  1.34  jmcneill 		val &= ~RGE_ADV_5000TFDX;
    940  1.34  jmcneill 
    941  1.34  jmcneill 	anar = ANAR_TX_FD | ANAR_TX | ANAR_10_FD | ANAR_10;
    942  1.34  jmcneill 	gig = GTCR_ADV_1000TFDX | GTCR_ADV_1000THDX;
    943   1.1     sevan 
    944   1.1     sevan 	switch (IFM_SUBTYPE(ifm->ifm_media)) {
    945   1.1     sevan 	case IFM_AUTO:
    946  1.34  jmcneill 		val |= (sc->rge_type != MAC_CFG2_8126) ?
    947  1.34  jmcneill 		    RGE_ADV_2500TFDX : (RGE_ADV_2500TFDX | RGE_ADV_5000TFDX);
    948  1.34  jmcneill 		break;
    949  1.34  jmcneill 	case IFM_5000_T:
    950  1.34  jmcneill 		val |= RGE_ADV_5000TFDX;
    951  1.34  jmcneill 		ifp->if_baudrate = IF_Gbps(5);
    952   1.1     sevan 		break;
    953   1.1     sevan 	case IFM_2500_T:
    954   1.1     sevan 		val |= RGE_ADV_2500TFDX;
    955   1.1     sevan 		ifp->if_baudrate = IF_Mbps(2500);
    956   1.1     sevan 		break;
    957   1.1     sevan 	case IFM_1000_T:
    958   1.1     sevan 		ifp->if_baudrate = IF_Gbps(1);
    959   1.1     sevan 		break;
    960   1.1     sevan 	case IFM_100_TX:
    961  1.17  jakllsch 		gig = rge_read_phy(sc, 0, MII_100T2CR) &
    962  1.17  jakllsch 		    ~(GTCR_ADV_1000TFDX | GTCR_ADV_1000THDX);
    963  1.17  jakllsch 		anar = ((ifm->ifm_media & IFM_GMASK) == IFM_FDX) ?
    964  1.17  jakllsch 		    ANAR_TX | ANAR_TX_FD | ANAR_10_FD | ANAR_10 :
    965  1.17  jakllsch 		    ANAR_TX | ANAR_10_FD | ANAR_10;
    966   1.1     sevan 		ifp->if_baudrate = IF_Mbps(100);
    967   1.1     sevan 		break;
    968   1.1     sevan 	case IFM_10_T:
    969  1.17  jakllsch 		gig = rge_read_phy(sc, 0, MII_100T2CR) &
    970  1.17  jakllsch 		    ~(GTCR_ADV_1000TFDX | GTCR_ADV_1000THDX);
    971  1.17  jakllsch 		anar = ((ifm->ifm_media & IFM_GMASK) == IFM_FDX) ?
    972  1.17  jakllsch 		    ANAR_10_FD | ANAR_10 : ANAR_10;
    973   1.1     sevan 		ifp->if_baudrate = IF_Mbps(10);
    974   1.1     sevan 		break;
    975   1.1     sevan 	default:
    976  1.16  jakllsch 		device_printf(sc->sc_dev,
    977  1.13     sevan 		    "unsupported media type\n");
    978   1.1     sevan 		return (EINVAL);
    979   1.1     sevan 	}
    980   1.1     sevan 
    981   1.1     sevan 	rge_write_phy(sc, 0, MII_ANAR, anar | ANAR_PAUSE_ASYM | ANAR_FC);
    982   1.1     sevan 	rge_write_phy(sc, 0, MII_100T2CR, gig);
    983   1.1     sevan 	rge_write_phy_ocp(sc, 0xa5d4, val);
    984  1.17  jakllsch 	rge_write_phy(sc, 0, MII_BMCR, BMCR_RESET | BMCR_AUTOEN |
    985  1.17  jakllsch 	    BMCR_STARTNEG);
    986   1.1     sevan 
    987   1.1     sevan 	return (0);
    988   1.1     sevan }
    989   1.1     sevan 
    990   1.1     sevan /*
    991   1.1     sevan  * Report current media status.
    992   1.1     sevan  */
    993   1.1     sevan void
    994   1.1     sevan rge_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
    995   1.1     sevan {
    996   1.1     sevan 	struct rge_softc *sc = ifp->if_softc;
    997   1.1     sevan 	uint16_t status = 0;
    998   1.1     sevan 
    999   1.1     sevan 	ifmr->ifm_status = IFM_AVALID;
   1000   1.1     sevan 	ifmr->ifm_active = IFM_ETHER;
   1001   1.1     sevan 
   1002   1.1     sevan 	if (rge_get_link_status(sc)) {
   1003   1.1     sevan 		ifmr->ifm_status |= IFM_ACTIVE;
   1004   1.1     sevan 
   1005   1.1     sevan 		status = RGE_READ_2(sc, RGE_PHYSTAT);
   1006   1.1     sevan 		if ((status & RGE_PHYSTAT_FDX) ||
   1007  1.34  jmcneill 		    (status & (RGE_PHYSTAT_2500MBPS | RGE_PHYSTAT_5000MBPS)))
   1008   1.1     sevan 			ifmr->ifm_active |= IFM_FDX;
   1009   1.1     sevan 		else
   1010   1.1     sevan 			ifmr->ifm_active |= IFM_HDX;
   1011   1.1     sevan 
   1012   1.1     sevan 		if (status & RGE_PHYSTAT_10MBPS)
   1013   1.1     sevan 			ifmr->ifm_active |= IFM_10_T;
   1014   1.1     sevan 		else if (status & RGE_PHYSTAT_100MBPS)
   1015   1.1     sevan 			ifmr->ifm_active |= IFM_100_TX;
   1016   1.1     sevan 		else if (status & RGE_PHYSTAT_1000MBPS)
   1017   1.1     sevan 			ifmr->ifm_active |= IFM_1000_T;
   1018   1.1     sevan 		else if (status & RGE_PHYSTAT_2500MBPS)
   1019   1.1     sevan 			ifmr->ifm_active |= IFM_2500_T;
   1020  1.34  jmcneill 		else if (status & RGE_PHYSTAT_5000MBPS)
   1021  1.34  jmcneill 			ifmr->ifm_active |= IFM_5000_T;
   1022   1.1     sevan 	}
   1023   1.1     sevan }
   1024   1.1     sevan 
   1025   1.5     skrll /*
   1026   1.1     sevan  * Allocate memory for RX/TX rings.
   1027  1.28       mrg  *
   1028  1.28       mrg  * XXX There is no tear-down for this if it any part fails, so everything
   1029  1.28       mrg  * remains allocated.
   1030   1.1     sevan  */
   1031   1.1     sevan int
   1032   1.1     sevan rge_allocmem(struct rge_softc *sc)
   1033   1.1     sevan {
   1034   1.1     sevan 	int error, i;
   1035   1.1     sevan 
   1036   1.1     sevan 	/* Allocate DMA'able memory for the TX ring. */
   1037   1.1     sevan 	error = bus_dmamap_create(sc->sc_dmat, RGE_TX_LIST_SZ, 1,
   1038   1.1     sevan 	    RGE_TX_LIST_SZ, 0, BUS_DMA_NOWAIT, &sc->rge_ldata.rge_tx_list_map);
   1039   1.1     sevan 	if (error) {
   1040  1.13     sevan 		aprint_error_dev(sc->sc_dev, "can't create TX list map\n");
   1041   1.1     sevan 		return (error);
   1042   1.1     sevan 	}
   1043   1.1     sevan 	error = bus_dmamem_alloc(sc->sc_dmat, RGE_TX_LIST_SZ, RGE_ALIGN, 0,
   1044   1.1     sevan 	    &sc->rge_ldata.rge_tx_listseg, 1, &sc->rge_ldata.rge_tx_listnseg,
   1045  1.17  jakllsch 	    BUS_DMA_NOWAIT);
   1046   1.1     sevan 	if (error) {
   1047  1.13     sevan 		aprint_error_dev(sc->sc_dev, "can't alloc TX list\n");
   1048   1.1     sevan 		return (error);
   1049   1.1     sevan 	}
   1050   1.1     sevan 
   1051   1.1     sevan 	/* Load the map for the TX ring. */
   1052   1.1     sevan 	error = bus_dmamem_map(sc->sc_dmat, &sc->rge_ldata.rge_tx_listseg,
   1053   1.1     sevan 	    sc->rge_ldata.rge_tx_listnseg, RGE_TX_LIST_SZ,
   1054   1.8     sevan 	    (void **) &sc->rge_ldata.rge_tx_list,
   1055  1.17  jakllsch 	    BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
   1056   1.1     sevan 	if (error) {
   1057  1.13     sevan 		aprint_error_dev(sc->sc_dev, "can't map TX dma buffers\n");
   1058   1.1     sevan 		bus_dmamem_free(sc->sc_dmat, &sc->rge_ldata.rge_tx_listseg,
   1059   1.1     sevan 		    sc->rge_ldata.rge_tx_listnseg);
   1060   1.1     sevan 		return (error);
   1061   1.1     sevan 	}
   1062  1.17  jakllsch 	memset(sc->rge_ldata.rge_tx_list, 0, RGE_TX_LIST_SZ);
   1063   1.1     sevan 	error = bus_dmamap_load(sc->sc_dmat, sc->rge_ldata.rge_tx_list_map,
   1064   1.1     sevan 	    sc->rge_ldata.rge_tx_list, RGE_TX_LIST_SZ, NULL, BUS_DMA_NOWAIT);
   1065   1.1     sevan 	if (error) {
   1066  1.13     sevan 		aprint_error_dev(sc->sc_dev, "can't load TX dma map\n");
   1067   1.1     sevan 		bus_dmamap_destroy(sc->sc_dmat, sc->rge_ldata.rge_tx_list_map);
   1068   1.1     sevan 		bus_dmamem_unmap(sc->sc_dmat,
   1069   1.2     sevan 		    sc->rge_ldata.rge_tx_list, RGE_TX_LIST_SZ);
   1070   1.1     sevan 		bus_dmamem_free(sc->sc_dmat, &sc->rge_ldata.rge_tx_listseg,
   1071   1.1     sevan 		    sc->rge_ldata.rge_tx_listnseg);
   1072   1.1     sevan 		return (error);
   1073   1.1     sevan 	}
   1074   1.1     sevan 
   1075   1.1     sevan 	/* Create DMA maps for TX buffers. */
   1076   1.1     sevan 	for (i = 0; i < RGE_TX_LIST_CNT; i++) {
   1077   1.1     sevan 		error = bus_dmamap_create(sc->sc_dmat, RGE_JUMBO_FRAMELEN,
   1078   1.1     sevan 		    RGE_TX_NSEGS, RGE_JUMBO_FRAMELEN, 0, 0,
   1079   1.1     sevan 		    &sc->rge_ldata.rge_txq[i].txq_dmamap);
   1080   1.1     sevan 		if (error) {
   1081  1.13     sevan 			aprint_error_dev(sc->sc_dev, "can't create DMA map for TX\n");
   1082   1.1     sevan 			return (error);
   1083   1.1     sevan 		}
   1084   1.1     sevan 	}
   1085   1.1     sevan 
   1086   1.1     sevan 	/* Allocate DMA'able memory for the RX ring. */
   1087   1.1     sevan 	error = bus_dmamap_create(sc->sc_dmat, RGE_RX_LIST_SZ, 1,
   1088   1.1     sevan 	    RGE_RX_LIST_SZ, 0, 0, &sc->rge_ldata.rge_rx_list_map);
   1089   1.1     sevan 	if (error) {
   1090  1.13     sevan 		aprint_error_dev(sc->sc_dev, "can't create RX list map\n");
   1091   1.1     sevan 		return (error);
   1092   1.1     sevan 	}
   1093   1.1     sevan 	error = bus_dmamem_alloc(sc->sc_dmat, RGE_RX_LIST_SZ, RGE_ALIGN, 0,
   1094   1.1     sevan 	    &sc->rge_ldata.rge_rx_listseg, 1, &sc->rge_ldata.rge_rx_listnseg,
   1095  1.17  jakllsch 	    BUS_DMA_NOWAIT);
   1096   1.1     sevan 	if (error) {
   1097  1.13     sevan 		aprint_error_dev(sc->sc_dev, "can't alloc RX list\n");
   1098   1.1     sevan 		return (error);
   1099   1.1     sevan 	}
   1100   1.1     sevan 
   1101   1.1     sevan 	/* Load the map for the RX ring. */
   1102   1.1     sevan 	error = bus_dmamem_map(sc->sc_dmat, &sc->rge_ldata.rge_rx_listseg,
   1103   1.1     sevan 	    sc->rge_ldata.rge_rx_listnseg, RGE_RX_LIST_SZ,
   1104   1.8     sevan 	    (void **) &sc->rge_ldata.rge_rx_list,
   1105  1.17  jakllsch 	    BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
   1106   1.1     sevan 	if (error) {
   1107  1.13     sevan 		aprint_error_dev(sc->sc_dev, "can't map RX dma buffers\n");
   1108   1.1     sevan 		bus_dmamem_free(sc->sc_dmat, &sc->rge_ldata.rge_rx_listseg,
   1109   1.1     sevan 		    sc->rge_ldata.rge_rx_listnseg);
   1110   1.1     sevan 		return (error);
   1111   1.1     sevan 	}
   1112  1.17  jakllsch 	memset(sc->rge_ldata.rge_rx_list, 0, RGE_RX_LIST_SZ);
   1113   1.1     sevan 	error = bus_dmamap_load(sc->sc_dmat, sc->rge_ldata.rge_rx_list_map,
   1114   1.1     sevan 	    sc->rge_ldata.rge_rx_list, RGE_RX_LIST_SZ, NULL, BUS_DMA_NOWAIT);
   1115   1.1     sevan 	if (error) {
   1116  1.13     sevan 		aprint_error_dev(sc->sc_dev, "can't load RX dma map\n");
   1117   1.1     sevan 		bus_dmamap_destroy(sc->sc_dmat, sc->rge_ldata.rge_rx_list_map);
   1118   1.1     sevan 		bus_dmamem_unmap(sc->sc_dmat,
   1119   1.2     sevan 		    sc->rge_ldata.rge_rx_list, RGE_RX_LIST_SZ);
   1120   1.1     sevan 		bus_dmamem_free(sc->sc_dmat, &sc->rge_ldata.rge_rx_listseg,
   1121   1.1     sevan 		    sc->rge_ldata.rge_rx_listnseg);
   1122   1.1     sevan 		return (error);
   1123   1.1     sevan 	}
   1124   1.1     sevan 
   1125  1.28       mrg 	/*
   1126  1.28       mrg 	 * Create DMA maps for RX buffers.  Use BUS_DMA_ALLOCNOW to avoid any
   1127  1.28       mrg 	 * potential failure in bus_dmamap_load_mbuf() in the RX path.
   1128  1.28       mrg 	 */
   1129   1.1     sevan 	for (i = 0; i < RGE_RX_LIST_CNT; i++) {
   1130   1.1     sevan 		error = bus_dmamap_create(sc->sc_dmat, RGE_JUMBO_FRAMELEN, 1,
   1131  1.28       mrg 		    RGE_JUMBO_FRAMELEN, 0, BUS_DMA_ALLOCNOW,
   1132   1.1     sevan 		    &sc->rge_ldata.rge_rxq[i].rxq_dmamap);
   1133   1.1     sevan 		if (error) {
   1134  1.13     sevan 			aprint_error_dev(sc->sc_dev, "can't create DMA map for RX\n");
   1135   1.1     sevan 			return (error);
   1136   1.1     sevan 		}
   1137   1.1     sevan 	}
   1138   1.1     sevan 
   1139   1.1     sevan 	return (error);
   1140   1.1     sevan }
   1141   1.1     sevan 
   1142   1.1     sevan /*
   1143  1.28       mrg  * Set an RX descriptor and sync it.
   1144  1.28       mrg  */
   1145  1.28       mrg static void
   1146  1.28       mrg rge_load_rxbuf(struct rge_softc *sc, int idx)
   1147  1.28       mrg {
   1148  1.28       mrg 	struct rge_rx_desc *r = &sc->rge_ldata.rge_rx_list[idx];
   1149  1.28       mrg 	struct rge_rxq *rxq = &sc->rge_ldata.rge_rxq[idx];
   1150  1.28       mrg 	bus_dmamap_t rxmap = rxq->rxq_dmamap;
   1151  1.28       mrg 	uint32_t cmdsts;
   1152  1.28       mrg 
   1153  1.28       mrg 	cmdsts = rxmap->dm_segs[0].ds_len | RGE_RDCMDSTS_OWN;
   1154  1.28       mrg 	if (idx == RGE_RX_LIST_CNT - 1)
   1155  1.28       mrg 		cmdsts |= RGE_RDCMDSTS_EOR;
   1156  1.28       mrg 
   1157  1.28       mrg 	r->hi_qword0.rge_addr = htole64(rxmap->dm_segs[0].ds_addr);
   1158  1.28       mrg 	r->hi_qword1.rx_qword4.rge_extsts = 0;
   1159  1.28       mrg 	r->hi_qword1.rx_qword4.rge_cmdsts = htole32(cmdsts);
   1160  1.28       mrg 
   1161  1.28       mrg 	bus_dmamap_sync(sc->sc_dmat, sc->rge_ldata.rge_rx_list_map,
   1162  1.28       mrg 	    idx * sizeof(struct rge_rx_desc), sizeof(struct rge_rx_desc),
   1163  1.28       mrg 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   1164  1.28       mrg }
   1165  1.28       mrg 
   1166  1.28       mrg /*
   1167   1.1     sevan  * Initialize the RX descriptor and attach an mbuf cluster.
   1168   1.1     sevan  */
   1169   1.1     sevan int
   1170   1.1     sevan rge_newbuf(struct rge_softc *sc, int idx)
   1171   1.1     sevan {
   1172   1.1     sevan 	struct mbuf *m;
   1173   1.1     sevan 	struct rge_rxq *rxq;
   1174   1.1     sevan 	bus_dmamap_t rxmap;
   1175  1.28       mrg 	int error __diagused;
   1176   1.1     sevan 
   1177  1.17  jakllsch 	m = MCLGETL(NULL, M_DONTWAIT, RGE_JUMBO_FRAMELEN);
   1178   1.1     sevan 	if (m == NULL)
   1179   1.1     sevan 		return (ENOBUFS);
   1180  1.33   mlelstv 	MCLAIM(m, &sc->sc_ec.ec_rx_mowner);
   1181   1.1     sevan 
   1182   1.1     sevan 	m->m_len = m->m_pkthdr.len = RGE_JUMBO_FRAMELEN;
   1183   1.1     sevan 
   1184   1.1     sevan 	rxq = &sc->rge_ldata.rge_rxq[idx];
   1185   1.1     sevan 	rxmap = rxq->rxq_dmamap;
   1186   1.1     sevan 
   1187  1.28       mrg 	if (rxq->rxq_mbuf != NULL)
   1188  1.28       mrg 		bus_dmamap_unload(sc->sc_dmat, rxq->rxq_dmamap);
   1189  1.28       mrg 
   1190  1.28       mrg 	/* This map was created with BUS_DMA_ALLOCNOW so should never fail. */
   1191  1.28       mrg 	error = bus_dmamap_load_mbuf(sc->sc_dmat, rxmap, m, BUS_DMA_NOWAIT);
   1192  1.28       mrg 	KASSERTMSG(error == 0, "error=%d", error);
   1193   1.1     sevan 
   1194   1.1     sevan 	bus_dmamap_sync(sc->sc_dmat, rxmap, 0, rxmap->dm_mapsize,
   1195   1.1     sevan 	    BUS_DMASYNC_PREREAD);
   1196   1.1     sevan 
   1197   1.1     sevan 	/* Map the segments into RX descriptors. */
   1198   1.1     sevan 
   1199   1.1     sevan 	rxq->rxq_mbuf = m;
   1200  1.28       mrg 	rge_load_rxbuf(sc, idx);
   1201   1.1     sevan 
   1202  1.28       mrg 	return 0;
   1203   1.1     sevan }
   1204   1.1     sevan 
   1205  1.26       mrg static int
   1206   1.1     sevan rge_rx_list_init(struct rge_softc *sc)
   1207   1.1     sevan {
   1208  1.26       mrg 	unsigned i;
   1209   1.1     sevan 
   1210   1.1     sevan 	memset(sc->rge_ldata.rge_rx_list, 0, RGE_RX_LIST_SZ);
   1211   1.1     sevan 
   1212   1.1     sevan 	for (i = 0; i < RGE_RX_LIST_CNT; i++) {
   1213   1.1     sevan 		sc->rge_ldata.rge_rxq[i].rxq_mbuf = NULL;
   1214  1.26       mrg 		if (rge_newbuf(sc, i) != 0) {
   1215  1.26       mrg 			rge_rx_list_fini(sc);
   1216   1.1     sevan 			return (ENOBUFS);
   1217  1.26       mrg 		}
   1218   1.1     sevan 	}
   1219   1.1     sevan 
   1220  1.17  jakllsch 	sc->rge_ldata.rge_rxq_prodidx = sc->rge_ldata.rge_rxq_considx = 0;
   1221   1.1     sevan 	sc->rge_head = sc->rge_tail = NULL;
   1222   1.1     sevan 
   1223   1.1     sevan 	return (0);
   1224   1.1     sevan }
   1225   1.1     sevan 
   1226  1.26       mrg static void
   1227  1.26       mrg rge_rx_list_fini(struct rge_softc *sc)
   1228  1.26       mrg {
   1229  1.26       mrg 	unsigned i;
   1230  1.26       mrg 
   1231  1.26       mrg 	/* Free the RX list buffers. */
   1232  1.26       mrg 	for (i = 0; i < RGE_RX_LIST_CNT; i++) {
   1233  1.26       mrg 		if (sc->rge_ldata.rge_rxq[i].rxq_mbuf != NULL) {
   1234  1.26       mrg 			bus_dmamap_unload(sc->sc_dmat,
   1235  1.26       mrg 			    sc->rge_ldata.rge_rxq[i].rxq_dmamap);
   1236  1.26       mrg 			m_freem(sc->rge_ldata.rge_rxq[i].rxq_mbuf);
   1237  1.26       mrg 			sc->rge_ldata.rge_rxq[i].rxq_mbuf = NULL;
   1238  1.26       mrg 		}
   1239  1.26       mrg 	}
   1240  1.26       mrg }
   1241  1.26       mrg 
   1242  1.26       mrg static void
   1243   1.1     sevan rge_tx_list_init(struct rge_softc *sc)
   1244   1.1     sevan {
   1245  1.26       mrg 	unsigned i;
   1246   1.1     sevan 
   1247   1.1     sevan 	memset(sc->rge_ldata.rge_tx_list, 0, RGE_TX_LIST_SZ);
   1248   1.1     sevan 
   1249   1.1     sevan 	for (i = 0; i < RGE_TX_LIST_CNT; i++)
   1250   1.1     sevan 		sc->rge_ldata.rge_txq[i].txq_mbuf = NULL;
   1251   1.1     sevan 
   1252   1.1     sevan 	bus_dmamap_sync(sc->sc_dmat, sc->rge_ldata.rge_tx_list_map, 0,
   1253   1.1     sevan 	    sc->rge_ldata.rge_tx_list_map->dm_mapsize,
   1254   1.1     sevan 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   1255   1.1     sevan 
   1256   1.1     sevan 	sc->rge_ldata.rge_txq_prodidx = sc->rge_ldata.rge_txq_considx = 0;
   1257   1.1     sevan }
   1258   1.1     sevan 
   1259  1.26       mrg static void
   1260  1.26       mrg rge_tx_list_fini(struct rge_softc *sc)
   1261  1.26       mrg {
   1262  1.26       mrg 	unsigned i;
   1263  1.26       mrg 
   1264  1.26       mrg 	/* Free the TX list buffers. */
   1265  1.26       mrg 	for (i = 0; i < RGE_TX_LIST_CNT; i++) {
   1266  1.26       mrg 		if (sc->rge_ldata.rge_txq[i].txq_mbuf != NULL) {
   1267  1.26       mrg 			bus_dmamap_unload(sc->sc_dmat,
   1268  1.26       mrg 			    sc->rge_ldata.rge_txq[i].txq_dmamap);
   1269  1.26       mrg 			m_freem(sc->rge_ldata.rge_txq[i].txq_mbuf);
   1270  1.26       mrg 			sc->rge_ldata.rge_txq[i].txq_mbuf = NULL;
   1271  1.26       mrg 		}
   1272  1.26       mrg 	}
   1273  1.26       mrg }
   1274  1.26       mrg 
   1275   1.1     sevan int
   1276   1.1     sevan rge_rxeof(struct rge_softc *sc)
   1277   1.1     sevan {
   1278   1.1     sevan 	struct mbuf *m;
   1279   1.2     sevan 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   1280   1.1     sevan 	struct rge_rx_desc *cur_rx;
   1281   1.1     sevan 	struct rge_rxq *rxq;
   1282   1.1     sevan 	uint32_t rxstat, extsts;
   1283   1.1     sevan 	int i, total_len, rx = 0;
   1284   1.1     sevan 
   1285  1.17  jakllsch 	for (i = sc->rge_ldata.rge_rxq_considx; ; i = RGE_NEXT_RX_DESC(i)) {
   1286   1.1     sevan 		/* Invalidate the descriptor memory. */
   1287   1.1     sevan 		bus_dmamap_sync(sc->sc_dmat, sc->rge_ldata.rge_rx_list_map,
   1288   1.1     sevan 		    i * sizeof(struct rge_rx_desc), sizeof(struct rge_rx_desc),
   1289   1.1     sevan 		    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
   1290   1.1     sevan 
   1291   1.1     sevan 		cur_rx = &sc->rge_ldata.rge_rx_list[i];
   1292   1.1     sevan 
   1293   1.1     sevan 		if (RGE_OWN(cur_rx))
   1294   1.1     sevan 			break;
   1295   1.1     sevan 
   1296  1.25    nonaka 		rxstat = letoh32(cur_rx->hi_qword1.rx_qword4.rge_cmdsts);
   1297  1.25    nonaka 		extsts = letoh32(cur_rx->hi_qword1.rx_qword4.rge_extsts);
   1298   1.5     skrll 
   1299   1.1     sevan 		total_len = RGE_RXBYTES(cur_rx);
   1300   1.1     sevan 		rxq = &sc->rge_ldata.rge_rxq[i];
   1301   1.1     sevan 		m = rxq->rxq_mbuf;
   1302   1.1     sevan 		rx = 1;
   1303   1.1     sevan 
   1304  1.28       mrg 		/* Invalidate the RX mbuf. */
   1305   1.1     sevan 		bus_dmamap_sync(sc->sc_dmat, rxq->rxq_dmamap, 0,
   1306   1.1     sevan 		    rxq->rxq_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
   1307   1.1     sevan 
   1308   1.1     sevan 		if ((rxstat & (RGE_RDCMDSTS_SOF | RGE_RDCMDSTS_EOF)) !=
   1309   1.1     sevan 		    (RGE_RDCMDSTS_SOF | RGE_RDCMDSTS_EOF)) {
   1310  1.28       mrg 			if_statinc(ifp, if_ierrors);
   1311  1.28       mrg 			rge_load_rxbuf(sc, i);
   1312   1.1     sevan 			continue;
   1313   1.1     sevan 		}
   1314   1.1     sevan 
   1315   1.1     sevan 		if (rxstat & RGE_RDCMDSTS_RXERRSUM) {
   1316   1.4     skrll 			if_statinc(ifp, if_ierrors);
   1317   1.1     sevan 			/*
   1318   1.1     sevan 			 * If this is part of a multi-fragment packet,
   1319   1.1     sevan 			 * discard all the pieces.
   1320   1.1     sevan 			 */
   1321  1.28       mrg 			if (sc->rge_head != NULL) {
   1322   1.1     sevan 				m_freem(sc->rge_head);
   1323   1.1     sevan 				sc->rge_head = sc->rge_tail = NULL;
   1324   1.1     sevan 			}
   1325  1.28       mrg 			rge_load_rxbuf(sc, i);
   1326   1.1     sevan 			continue;
   1327   1.1     sevan 		}
   1328   1.1     sevan 
   1329   1.1     sevan 		/*
   1330   1.1     sevan 		 * If allocating a replacement mbuf fails,
   1331   1.1     sevan 		 * reload the current one.
   1332   1.1     sevan 		 */
   1333  1.26       mrg 		if (rge_newbuf(sc, i) != 0) {
   1334  1.28       mrg 			if_statinc(ifp, if_iqdrops);
   1335   1.1     sevan 			if (sc->rge_head != NULL) {
   1336   1.1     sevan 				m_freem(sc->rge_head);
   1337   1.1     sevan 				sc->rge_head = sc->rge_tail = NULL;
   1338   1.1     sevan 			}
   1339  1.28       mrg 			rge_load_rxbuf(sc, i);
   1340   1.1     sevan 			continue;
   1341   1.1     sevan 		}
   1342   1.1     sevan 
   1343  1.17  jakllsch 		m_set_rcvif(m, ifp);
   1344   1.1     sevan 		if (sc->rge_head != NULL) {
   1345   1.1     sevan 			m->m_len = total_len;
   1346   1.1     sevan 			/*
   1347   1.1     sevan 			 * Special case: if there's 4 bytes or less
   1348   1.1     sevan 			 * in this buffer, the mbuf can be discarded:
   1349   1.1     sevan 			 * the last 4 bytes is the CRC, which we don't
   1350   1.1     sevan 			 * care about anyway.
   1351   1.1     sevan 			 */
   1352   1.1     sevan 			if (m->m_len <= ETHER_CRC_LEN) {
   1353   1.1     sevan 				sc->rge_tail->m_len -=
   1354   1.1     sevan 				    (ETHER_CRC_LEN - m->m_len);
   1355   1.1     sevan 				m_freem(m);
   1356   1.1     sevan 			} else {
   1357   1.1     sevan 				m->m_len -= ETHER_CRC_LEN;
   1358   1.1     sevan 				m->m_flags &= ~M_PKTHDR;
   1359   1.1     sevan 				sc->rge_tail->m_next = m;
   1360   1.1     sevan 			}
   1361   1.1     sevan 			m = sc->rge_head;
   1362   1.1     sevan 			sc->rge_head = sc->rge_tail = NULL;
   1363   1.1     sevan 			m->m_pkthdr.len = total_len - ETHER_CRC_LEN;
   1364   1.1     sevan 		} else
   1365  1.17  jakllsch 	#if 0
   1366   1.1     sevan 			m->m_pkthdr.len = m->m_len =
   1367   1.1     sevan 			    (total_len - ETHER_CRC_LEN);
   1368  1.17  jakllsch 	#else
   1369  1.17  jakllsch 		{
   1370  1.17  jakllsch 			m->m_pkthdr.len = m->m_len = total_len;
   1371  1.17  jakllsch 			m->m_flags |= M_HASFCS;
   1372  1.17  jakllsch 		}
   1373  1.17  jakllsch 	#endif
   1374   1.1     sevan 
   1375  1.17  jakllsch #if notyet
   1376   1.1     sevan 		/* Check IP header checksum. */
   1377  1.25    nonaka 		if (!(extsts & RGE_RDEXTSTS_IPCSUMERR) &&
   1378   1.1     sevan 		    (extsts & RGE_RDEXTSTS_IPV4))
   1379   1.1     sevan 			m->m_pkthdr.csum_flags |= M_IPV4_CSUM_IN_OK;
   1380   1.1     sevan 
   1381   1.1     sevan 		/* Check TCP/UDP checksum. */
   1382   1.1     sevan 		if ((extsts & (RGE_RDEXTSTS_IPV4 | RGE_RDEXTSTS_IPV6)) &&
   1383  1.25    nonaka 		    (((extsts & RGE_RDEXTSTS_TCPPKT) &&
   1384  1.25    nonaka 		    !(extsts & RGE_RDEXTSTS_TCPCSUMERR)) ||
   1385  1.25    nonaka 		    ((extsts & RGE_RDEXTSTS_UDPPKT) &&
   1386  1.25    nonaka 		    !(extsts & RGE_RDEXTSTS_UDPCSUMERR))))
   1387   1.1     sevan 			m->m_pkthdr.csum_flags |= M_TCP_CSUM_IN_OK |
   1388   1.1     sevan 			    M_UDP_CSUM_IN_OK;
   1389  1.17  jakllsch #endif
   1390   1.1     sevan 
   1391   1.1     sevan 		if (extsts & RGE_RDEXTSTS_VTAG) {
   1392  1.17  jakllsch 			vlan_set_tag(m,
   1393  1.17  jakllsch 			    bswap16(extsts & RGE_RDEXTSTS_VLAN_MASK));
   1394   1.1     sevan 		}
   1395   1.1     sevan 
   1396  1.17  jakllsch 		if_percpuq_enqueue(ifp->if_percpuq, m);
   1397   1.1     sevan 	}
   1398   1.1     sevan 
   1399  1.17  jakllsch 	sc->rge_ldata.rge_rxq_considx = i;
   1400   1.1     sevan 
   1401   1.1     sevan 	return (rx);
   1402   1.1     sevan }
   1403   1.1     sevan 
   1404   1.1     sevan int
   1405   1.1     sevan rge_txeof(struct rge_softc *sc)
   1406   1.1     sevan {
   1407   1.2     sevan 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   1408   1.1     sevan 	struct rge_txq *txq;
   1409   1.1     sevan 	uint32_t txstat;
   1410   1.1     sevan 	int cons, idx, prod;
   1411   1.1     sevan 	int free = 0;
   1412   1.1     sevan 
   1413   1.1     sevan 	prod = sc->rge_ldata.rge_txq_prodidx;
   1414   1.1     sevan 	cons = sc->rge_ldata.rge_txq_considx;
   1415   1.1     sevan 
   1416   1.1     sevan 	while (prod != cons) {
   1417   1.1     sevan 		txq = &sc->rge_ldata.rge_txq[cons];
   1418   1.1     sevan 		idx = txq->txq_descidx;
   1419   1.1     sevan 
   1420   1.1     sevan 		bus_dmamap_sync(sc->sc_dmat, sc->rge_ldata.rge_tx_list_map,
   1421   1.1     sevan 		    idx * sizeof(struct rge_tx_desc),
   1422   1.1     sevan 		    sizeof(struct rge_tx_desc),
   1423   1.1     sevan 		    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
   1424   1.1     sevan 
   1425   1.1     sevan 		txstat = letoh32(sc->rge_ldata.rge_tx_list[idx].rge_cmdsts);
   1426   1.1     sevan 
   1427   1.1     sevan 		if (txstat & RGE_TDCMDSTS_OWN) {
   1428   1.1     sevan 			free = 2;
   1429   1.1     sevan 			break;
   1430   1.1     sevan 		}
   1431   1.1     sevan 
   1432   1.5     skrll 		bus_dmamap_sync(sc->sc_dmat, txq->txq_dmamap, 0,
   1433   1.1     sevan 		    txq->txq_dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
   1434   1.1     sevan 		bus_dmamap_unload(sc->sc_dmat, txq->txq_dmamap);
   1435   1.1     sevan 		m_freem(txq->txq_mbuf);
   1436   1.1     sevan 		txq->txq_mbuf = NULL;
   1437   1.1     sevan 
   1438  1.29   mlelstv 		net_stat_ref_t nsr = IF_STAT_GETREF(ifp);
   1439   1.1     sevan 		if (txstat & (RGE_TDCMDSTS_EXCESSCOLL | RGE_TDCMDSTS_COLL))
   1440  1.32  riastrad 			if_statinc_ref(ifp, nsr, if_collisions);
   1441   1.1     sevan 		if (txstat & RGE_TDCMDSTS_TXERR)
   1442  1.32  riastrad 			if_statinc_ref(ifp, nsr, if_oerrors);
   1443  1.29   mlelstv 		else
   1444  1.32  riastrad 			if_statinc_ref(ifp, nsr, if_opackets);
   1445  1.29   mlelstv 		IF_STAT_PUTREF(ifp);
   1446   1.1     sevan 
   1447   1.1     sevan 		bus_dmamap_sync(sc->sc_dmat, sc->rge_ldata.rge_tx_list_map,
   1448   1.1     sevan 		    idx * sizeof(struct rge_tx_desc),
   1449   1.1     sevan 		    sizeof(struct rge_tx_desc),
   1450   1.1     sevan 		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   1451   1.1     sevan 
   1452   1.1     sevan 		cons = RGE_NEXT_TX_DESC(idx);
   1453   1.1     sevan 		free = 1;
   1454   1.1     sevan 	}
   1455   1.1     sevan 
   1456   1.1     sevan 	if (free == 0)
   1457   1.1     sevan 		return (0);
   1458   1.1     sevan 
   1459   1.1     sevan 	sc->rge_ldata.rge_txq_considx = cons;
   1460   1.1     sevan 
   1461  1.17  jakllsch 	if (free == 2)
   1462  1.30     skrll 		rge_txstart(sc);
   1463  1.29   mlelstv 
   1464  1.29   mlelstv 	CLR(ifp->if_flags, IFF_OACTIVE);
   1465  1.29   mlelstv 	ifp->if_timer = 0;
   1466  1.29   mlelstv 	if_schedule_deferred_start(ifp);
   1467   1.1     sevan 
   1468   1.1     sevan 	return (1);
   1469   1.1     sevan }
   1470   1.1     sevan 
   1471   1.1     sevan void
   1472   1.1     sevan rge_reset(struct rge_softc *sc)
   1473   1.1     sevan {
   1474   1.1     sevan 	int i;
   1475   1.1     sevan 
   1476   1.1     sevan 	/* Enable RXDV gate. */
   1477   1.1     sevan 	RGE_SETBIT_1(sc, RGE_PPSW, 0x08);
   1478   1.1     sevan 	DELAY(2000);
   1479   1.1     sevan 
   1480  1.17  jakllsch 	for (i = 0; i < 3000; i++) {
   1481  1.17  jakllsch 		DELAY(50);
   1482   1.1     sevan 		if ((RGE_READ_1(sc, RGE_MCUCMD) & (RGE_MCUCMD_RXFIFO_EMPTY |
   1483   1.1     sevan 		    RGE_MCUCMD_TXFIFO_EMPTY)) == (RGE_MCUCMD_RXFIFO_EMPTY |
   1484   1.1     sevan 		    RGE_MCUCMD_TXFIFO_EMPTY))
   1485   1.1     sevan 			break;
   1486   1.1     sevan 	}
   1487  1.17  jakllsch 	if (sc->rge_type == MAC_CFG4 || sc->rge_type == MAC_CFG5) {
   1488  1.17  jakllsch 		for (i = 0; i < 3000; i++) {
   1489  1.17  jakllsch 			DELAY(50);
   1490  1.17  jakllsch 			if ((RGE_READ_2(sc, RGE_IM) & 0x0103) == 0x0103)
   1491  1.17  jakllsch 				break;
   1492  1.17  jakllsch 		}
   1493  1.17  jakllsch 	}
   1494  1.17  jakllsch 
   1495  1.17  jakllsch 	DELAY(2000);
   1496   1.1     sevan 
   1497   1.1     sevan 	/* Soft reset. */
   1498   1.1     sevan 	RGE_WRITE_1(sc, RGE_CMD, RGE_CMD_RESET);
   1499   1.1     sevan 
   1500   1.1     sevan 	for (i = 0; i < RGE_TIMEOUT; i++) {
   1501   1.1     sevan 		DELAY(100);
   1502   1.1     sevan 		if (!(RGE_READ_1(sc, RGE_CMD) & RGE_CMD_RESET))
   1503   1.1     sevan 			break;
   1504   1.1     sevan 	}
   1505   1.1     sevan 	if (i == RGE_TIMEOUT)
   1506  1.16  jakllsch 		device_printf(sc->sc_dev, "reset never completed!\n");
   1507   1.1     sevan }
   1508   1.1     sevan 
   1509   1.1     sevan void
   1510   1.1     sevan rge_iff(struct rge_softc *sc)
   1511   1.1     sevan {
   1512   1.2     sevan 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   1513  1.17  jakllsch 	struct ethercom *ec = &sc->sc_ec;
   1514   1.1     sevan 	struct ether_multi *enm;
   1515   1.1     sevan 	struct ether_multistep step;
   1516   1.1     sevan 	uint32_t hashes[2];
   1517   1.1     sevan 	uint32_t rxfilt;
   1518   1.1     sevan 	int h = 0;
   1519   1.1     sevan 
   1520   1.1     sevan 	rxfilt = RGE_READ_4(sc, RGE_RXCFG);
   1521   1.1     sevan 	rxfilt &= ~(RGE_RXCFG_ALLPHYS | RGE_RXCFG_MULTI);
   1522   1.1     sevan 	ifp->if_flags &= ~IFF_ALLMULTI;
   1523   1.1     sevan 
   1524   1.1     sevan 	/*
   1525   1.1     sevan 	 * Always accept frames destined to our station address.
   1526   1.1     sevan 	 * Always accept broadcast frames.
   1527   1.1     sevan 	 */
   1528   1.1     sevan 	rxfilt |= RGE_RXCFG_INDIV | RGE_RXCFG_BROAD;
   1529   1.1     sevan 
   1530  1.17  jakllsch 	if (ifp->if_flags & IFF_PROMISC) {
   1531  1.17  jakllsch  allmulti:
   1532   1.1     sevan 		ifp->if_flags |= IFF_ALLMULTI;
   1533   1.1     sevan 		rxfilt |= RGE_RXCFG_MULTI;
   1534   1.1     sevan 		if (ifp->if_flags & IFF_PROMISC)
   1535   1.1     sevan 			rxfilt |= RGE_RXCFG_ALLPHYS;
   1536   1.1     sevan 		hashes[0] = hashes[1] = 0xffffffff;
   1537   1.1     sevan 	} else {
   1538   1.1     sevan 		rxfilt |= RGE_RXCFG_MULTI;
   1539   1.1     sevan 		/* Program new filter. */
   1540   1.1     sevan 		memset(hashes, 0, sizeof(hashes));
   1541   1.1     sevan 
   1542  1.17  jakllsch 		ETHER_LOCK(ec);
   1543  1.17  jakllsch 		ETHER_FIRST_MULTI(step, ec, enm);
   1544   1.1     sevan 		while (enm != NULL) {
   1545  1.17  jakllsch 			if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
   1546  1.17  jakllsch 			    ETHER_ADDR_LEN) != 0) {
   1547  1.17  jakllsch 			    	ETHER_UNLOCK(ec);
   1548  1.17  jakllsch 				goto allmulti;
   1549  1.17  jakllsch 			}
   1550   1.1     sevan 			h = ether_crc32_be(enm->enm_addrlo,
   1551   1.1     sevan 			    ETHER_ADDR_LEN) >> 26;
   1552   1.1     sevan 
   1553   1.1     sevan 			if (h < 32)
   1554  1.21   msaitoh 				hashes[0] |= (1U << h);
   1555   1.1     sevan 			else
   1556  1.21   msaitoh 				hashes[1] |= (1U << (h - 32));
   1557   1.1     sevan 
   1558   1.1     sevan 			ETHER_NEXT_MULTI(step, enm);
   1559   1.1     sevan 		}
   1560  1.17  jakllsch 		ETHER_UNLOCK(ec);
   1561   1.1     sevan 	}
   1562   1.1     sevan 
   1563   1.1     sevan 	RGE_WRITE_4(sc, RGE_RXCFG, rxfilt);
   1564   1.2     sevan 	RGE_WRITE_4(sc, RGE_MAR0, bswap32(hashes[1]));
   1565   1.2     sevan 	RGE_WRITE_4(sc, RGE_MAR4, bswap32(hashes[0]));
   1566   1.1     sevan }
   1567   1.1     sevan 
   1568   1.1     sevan void
   1569   1.1     sevan rge_set_phy_power(struct rge_softc *sc, int on)
   1570   1.1     sevan {
   1571   1.1     sevan 	int i;
   1572   1.1     sevan 
   1573   1.1     sevan 	if (on) {
   1574   1.1     sevan 		RGE_SETBIT_1(sc, RGE_PMCH, 0xc0);
   1575   1.1     sevan 
   1576   1.1     sevan 		rge_write_phy(sc, 0, MII_BMCR, BMCR_AUTOEN);
   1577   1.1     sevan 
   1578   1.1     sevan 		for (i = 0; i < RGE_TIMEOUT; i++) {
   1579  1.10     sevan 			if ((rge_read_phy_ocp(sc, 0xa420) & 0x0007) == 3)
   1580   1.1     sevan 				break;
   1581   1.1     sevan 			DELAY(1000);
   1582   1.1     sevan 		}
   1583  1.17  jakllsch 	} else {
   1584   1.1     sevan 		rge_write_phy(sc, 0, MII_BMCR, BMCR_AUTOEN | BMCR_PDOWN);
   1585  1.17  jakllsch 		RGE_CLRBIT_1(sc, RGE_PMCH, 0x80);
   1586  1.17  jakllsch 		RGE_CLRBIT_1(sc, RGE_PPSW, 0x40);
   1587  1.17  jakllsch 	}
   1588   1.1     sevan }
   1589   1.1     sevan 
   1590   1.1     sevan void
   1591   1.1     sevan rge_phy_config(struct rge_softc *sc)
   1592   1.1     sevan {
   1593  1.17  jakllsch 	/* Read microcode version. */
   1594  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x801e);
   1595  1.17  jakllsch 	sc->rge_mcodever = rge_read_phy_ocp(sc, 0xa438);
   1596  1.17  jakllsch 
   1597  1.17  jakllsch 	switch (sc->rge_type) {
   1598  1.34  jmcneill 	case MAC_CFG2_8126:
   1599  1.34  jmcneill 		rge_phy_config_mac_cfg2_8126(sc);
   1600  1.34  jmcneill 		break;
   1601  1.17  jakllsch 	case MAC_CFG2:
   1602  1.17  jakllsch 		rge_phy_config_mac_cfg2(sc);
   1603  1.17  jakllsch 		break;
   1604  1.17  jakllsch 	case MAC_CFG3:
   1605  1.17  jakllsch 		rge_phy_config_mac_cfg3(sc);
   1606  1.17  jakllsch 		break;
   1607  1.17  jakllsch 	case MAC_CFG4:
   1608  1.17  jakllsch 		rge_phy_config_mac_cfg4(sc);
   1609  1.17  jakllsch 		break;
   1610  1.17  jakllsch 	case MAC_CFG5:
   1611  1.17  jakllsch 		rge_phy_config_mac_cfg5(sc);
   1612  1.17  jakllsch 		break;
   1613  1.17  jakllsch 	default:
   1614  1.17  jakllsch 		break;	/* Can't happen. */
   1615  1.17  jakllsch 	}
   1616  1.17  jakllsch 
   1617  1.17  jakllsch 	rge_write_phy(sc, 0x0a5b, 0x12,
   1618  1.17  jakllsch 	    rge_read_phy(sc, 0x0a5b, 0x12) & ~0x8000);
   1619  1.17  jakllsch 
   1620  1.17  jakllsch 	/* Disable EEE. */
   1621  1.17  jakllsch 	RGE_MAC_CLRBIT(sc, 0xe040, 0x0003);
   1622  1.17  jakllsch 	if (sc->rge_type == MAC_CFG2 || sc->rge_type == MAC_CFG3) {
   1623  1.17  jakllsch 		RGE_MAC_CLRBIT(sc, 0xeb62, 0x0006);
   1624  1.17  jakllsch 		RGE_PHY_CLRBIT(sc, 0xa432, 0x0010);
   1625  1.17  jakllsch 	}
   1626  1.17  jakllsch 	RGE_PHY_CLRBIT(sc, 0xa5d0, 0x0006);
   1627  1.17  jakllsch 	RGE_PHY_CLRBIT(sc, 0xa6d4, 0x0001);
   1628  1.34  jmcneill 	if (sc->rge_type == MAC_CFG2_8126)
   1629  1.34  jmcneill 		RGE_PHY_CLRBIT(sc, 0xa6d4, 0x0002);
   1630  1.17  jakllsch 	RGE_PHY_CLRBIT(sc, 0xa6d8, 0x0010);
   1631  1.17  jakllsch 	RGE_PHY_CLRBIT(sc, 0xa428, 0x0080);
   1632  1.17  jakllsch 	RGE_PHY_CLRBIT(sc, 0xa4a2, 0x0200);
   1633  1.17  jakllsch 
   1634  1.34  jmcneill 	/* Disable advanced EEE. */
   1635  1.34  jmcneill 	if (sc->rge_type != MAC_CFG2_8126)
   1636  1.34  jmcneill 		rge_patch_phy_mcu(sc, 1);
   1637  1.17  jakllsch 	RGE_MAC_CLRBIT(sc, 0xe052, 0x0001);
   1638  1.17  jakllsch 	RGE_PHY_CLRBIT(sc, 0xa442, 0x3000);
   1639  1.17  jakllsch 	RGE_PHY_CLRBIT(sc, 0xa430, 0x8000);
   1640  1.34  jmcneill 	if (sc->rge_type != MAC_CFG2_8126)
   1641  1.34  jmcneill 		rge_patch_phy_mcu(sc, 0);
   1642  1.34  jmcneill }
   1643  1.34  jmcneill 
   1644  1.34  jmcneill void
   1645  1.34  jmcneill rge_phy_config_mac_cfg2_8126(struct rge_softc *sc)
   1646  1.34  jmcneill {
   1647  1.34  jmcneill 	uint16_t val;
   1648  1.34  jmcneill 	int i;
   1649  1.34  jmcneill 	static const uint16_t mac_cfg2_a438_value[] =
   1650  1.34  jmcneill 	    { 0x0044, 0x00a8, 0x00d6, 0x00ec, 0x00f6, 0x00fc, 0x00fe,
   1651  1.34  jmcneill 	      0x00fe, 0x00bc, 0x0058, 0x002a, 0x003f, 0x3f02, 0x023c,
   1652  1.34  jmcneill 	      0x3b0a, 0x1c00, 0x0000, 0x0000, 0x0000, 0x0000 };
   1653  1.34  jmcneill 
   1654  1.34  jmcneill 	static const uint16_t mac_cfg2_b87e_value[] =
   1655  1.34  jmcneill 	    { 0x03ed, 0x03ff, 0x0009, 0x03fe, 0x000b, 0x0021, 0x03f7,
   1656  1.34  jmcneill 	      0x03b8, 0x03e0, 0x0049, 0x0049, 0x03e0, 0x03b8, 0x03f7,
   1657  1.34  jmcneill 	      0x0021, 0x000b, 0x03fe, 0x0009, 0x03ff, 0x03ed, 0x000e,
   1658  1.34  jmcneill 	      0x03fe, 0x03ed, 0x0006, 0x001a, 0x03f1, 0x03d8, 0x0023,
   1659  1.34  jmcneill 	      0x0054, 0x0322, 0x00dd, 0x03ab, 0x03dc, 0x0027, 0x000e,
   1660  1.34  jmcneill 	      0x03e5, 0x03f9, 0x0012, 0x0001, 0x03f1 };
   1661  1.34  jmcneill 
   1662  1.34  jmcneill 	rge_phy_config_mcu(sc, RGE_MAC_CFG2_8126_MCODE_VER);
   1663  1.34  jmcneill 
   1664  1.34  jmcneill 	RGE_PHY_SETBIT(sc, 0xa442, 0x0800);
   1665  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xa436, 0x80bf);
   1666  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   1667  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xa438, val | 0xed00);
   1668  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xa436, 0x80cd);
   1669  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   1670  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xa438, val | 0x1000);
   1671  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xa436, 0x80d1);
   1672  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   1673  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xa438, val | 0xc800);
   1674  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xa436, 0x80d4);
   1675  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   1676  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xa438, val | 0xc800);
   1677  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xa436, 0x80e1);
   1678  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xa438, 0x10cc);
   1679  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xa436, 0x80e5);
   1680  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xa438, 0x4f0c);
   1681  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xa436, 0x8387);
   1682  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   1683  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xa438, val | 0x4700);
   1684  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xa80c) & ~0x00c0;
   1685  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xa80c, val | 0x0080);
   1686  1.34  jmcneill 	RGE_PHY_CLRBIT(sc, 0xac90, 0x0010);
   1687  1.34  jmcneill 	RGE_PHY_CLRBIT(sc, 0xad2c, 0x8000);
   1688  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8321);
   1689  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1690  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x1100);
   1691  1.34  jmcneill 	RGE_PHY_SETBIT(sc, 0xacf8, 0x000c);
   1692  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xa436, 0x8183);
   1693  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   1694  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xa438, val | 0x5900);
   1695  1.34  jmcneill 	RGE_PHY_SETBIT(sc, 0xad94, 0x0020);
   1696  1.34  jmcneill 	RGE_PHY_CLRBIT(sc, 0xa654, 0x0800);
   1697  1.34  jmcneill 	RGE_PHY_SETBIT(sc, 0xb648, 0x4000);
   1698  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x839e);
   1699  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1700  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x2f00);
   1701  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x83f2);
   1702  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1703  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x0800);
   1704  1.34  jmcneill 	RGE_PHY_SETBIT(sc, 0xada0, 0x0002);
   1705  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x80f3);
   1706  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1707  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x9900);
   1708  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8126);
   1709  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1710  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0xc100);
   1711  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x893a);
   1712  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, 0x8080);
   1713  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8647);
   1714  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1715  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0xe600);
   1716  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x862c);
   1717  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1718  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x1200);
   1719  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x864a);
   1720  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1721  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0xe600);
   1722  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x80a0);
   1723  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, 0xbcbc);
   1724  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x805e);
   1725  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, 0xbcbc);
   1726  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8056);
   1727  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, 0x3077);
   1728  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8058);
   1729  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1730  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x5a00);
   1731  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8098);
   1732  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, 0x3077);
   1733  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x809a);
   1734  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1735  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x5a00);
   1736  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8052);
   1737  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, 0x3733);
   1738  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8094);
   1739  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, 0x3733);
   1740  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x807f);
   1741  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, 0x7c75);
   1742  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x803d);
   1743  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, 0x7c75);
   1744  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8036);
   1745  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1746  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x3000);
   1747  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8078);
   1748  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1749  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x3000);
   1750  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8031);
   1751  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1752  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x3300);
   1753  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8073);
   1754  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1755  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x3300);
   1756  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xae06) & ~0xfc00;
   1757  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xae06, val | 0x7c00);
   1758  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x89D1);
   1759  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, 0x0004);
   1760  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xa436, 0x8fbd);
   1761  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   1762  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xa438, val | 0x0a00);
   1763  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xa436, 0x8fbe);
   1764  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xa438, 0x0d09);
   1765  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x89cd);
   1766  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, 0x0f0f);
   1767  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x89cf);
   1768  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, 0x0f0f);
   1769  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x83a4);
   1770  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, 0x6600);
   1771  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x83a6);
   1772  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, 0x6601);
   1773  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x83c0);
   1774  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, 0x6600);
   1775  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x83c2);
   1776  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, 0x6601);
   1777  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8414);
   1778  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, 0x6600);
   1779  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8416);
   1780  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, 0x6601);
   1781  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x83f8);
   1782  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, 0x6600);
   1783  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x83fa);
   1784  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, 0x6601);
   1785  1.34  jmcneill 
   1786  1.34  jmcneill 	rge_patch_phy_mcu(sc, 1);
   1787  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xbd96) & ~0x1f00;
   1788  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xbd96, val | 0x1000);
   1789  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xbf1c) & ~0x0007;
   1790  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xbf1c, val | 0x0007);
   1791  1.34  jmcneill 	RGE_PHY_CLRBIT(sc, 0xbfbe, 0x8000);
   1792  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xbf40) & ~0x0380;
   1793  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xbf40, val | 0x0280);
   1794  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xbf90) & ~0x0080;
   1795  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xbf90, val | 0x0060);
   1796  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xbf90) & ~0x0010;
   1797  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xbf90, val | 0x000c);
   1798  1.17  jakllsch 	rge_patch_phy_mcu(sc, 0);
   1799  1.34  jmcneill 
   1800  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xa436, 0x843b);
   1801  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   1802  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xa438, val | 0x2000);
   1803  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xa436, 0x843d);
   1804  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   1805  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xa438, val | 0x2000);
   1806  1.34  jmcneill 	RGE_PHY_CLRBIT(sc, 0xb516, 0x007f);
   1807  1.34  jmcneill 	RGE_PHY_CLRBIT(sc, 0xbf80, 0x0030);
   1808  1.34  jmcneill 
   1809  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xa436, 0x8188);
   1810  1.34  jmcneill 	for (i = 0; i < 11; i++)
   1811  1.34  jmcneill 		rge_write_phy_ocp(sc, 0xa438, mac_cfg2_a438_value[i]);
   1812  1.34  jmcneill 
   1813  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8015);
   1814  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1815  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x0800);
   1816  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8ffd);
   1817  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1818  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0);
   1819  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8fff);
   1820  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1821  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x7f00);
   1822  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8ffb);
   1823  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1824  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x0100);
   1825  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8fe9);
   1826  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, 0x0002);
   1827  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8fef);
   1828  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, 0x00a5);
   1829  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8ff1);
   1830  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, 0x0106);
   1831  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8fe1);
   1832  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, 0x0102);
   1833  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8fe3);
   1834  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1835  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x0400);
   1836  1.34  jmcneill 	RGE_PHY_SETBIT(sc, 0xa654, 0x0800);
   1837  1.34  jmcneill 	RGE_PHY_CLRBIT(sc, 0xa654, 0x0003);
   1838  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xac3a, 0x5851);
   1839  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xac3c) & ~0xd000;
   1840  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xac3c, val | 0x2000);
   1841  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xac42) & ~0x0200;
   1842  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xac42, val | 0x01c0);
   1843  1.34  jmcneill 	RGE_PHY_CLRBIT(sc, 0xac3e, 0xe000);
   1844  1.34  jmcneill 	RGE_PHY_CLRBIT(sc, 0xac42, 0x0038);
   1845  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xac42) & ~0x0002;
   1846  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xac42, val | 0x0005);
   1847  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xac1a, 0x00db);
   1848  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xade4, 0x01b5);
   1849  1.34  jmcneill 	RGE_PHY_CLRBIT(sc, 0xad9c, 0x0c00);
   1850  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x814b);
   1851  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1852  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x1100);
   1853  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x814d);
   1854  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1855  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x1100);
   1856  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x814f);
   1857  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1858  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x0b00);
   1859  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8142);
   1860  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1861  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x0100);
   1862  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8144);
   1863  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1864  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x0100);
   1865  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8150);
   1866  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1867  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x0100);
   1868  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8118);
   1869  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1870  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x0700);
   1871  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x811a);
   1872  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1873  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x0700);
   1874  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x811c);
   1875  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1876  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x0500);
   1877  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x810f);
   1878  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1879  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x0100);
   1880  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8111);
   1881  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1882  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x0100);
   1883  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x811d);
   1884  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1885  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x0100);
   1886  1.34  jmcneill 	RGE_PHY_SETBIT(sc, 0xac36, 0x1000);
   1887  1.34  jmcneill 	RGE_PHY_CLRBIT(sc, 0xad1c, 0x0100);
   1888  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xade8) & ~0xffc0;
   1889  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xade8, val | 0x1400);
   1890  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x864b);
   1891  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1892  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x9d00);
   1893  1.34  jmcneill 
   1894  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xa436, 0x8f97);
   1895  1.34  jmcneill 	for (; i < nitems(mac_cfg2_a438_value); i++)
   1896  1.34  jmcneill 		rge_write_phy_ocp(sc, 0xa438, mac_cfg2_a438_value[i]);
   1897  1.34  jmcneill 
   1898  1.34  jmcneill 	RGE_PHY_SETBIT(sc, 0xad9c, 0x0020);
   1899  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8122);
   1900  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1901  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x0c00);
   1902  1.34  jmcneill 
   1903  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x82c8);
   1904  1.34  jmcneill 	for (i = 0; i < 20; i++)
   1905  1.34  jmcneill 		rge_write_phy_ocp(sc, 0xb87e, mac_cfg2_b87e_value[i]);
   1906  1.34  jmcneill 
   1907  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x80ef);
   1908  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1909  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0x0c00);
   1910  1.34  jmcneill 
   1911  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x82a0);
   1912  1.34  jmcneill 	for (; i < nitems(mac_cfg2_b87e_value); i++)
   1913  1.34  jmcneill 		rge_write_phy_ocp(sc, 0xb87e, mac_cfg2_b87e_value[i]);
   1914  1.34  jmcneill 
   1915  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xa436, 0x8018);
   1916  1.34  jmcneill 	RGE_PHY_SETBIT(sc, 0xa438, 0x2000);
   1917  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87c, 0x8fe4);
   1918  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   1919  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb87e, val | 0);
   1920  1.34  jmcneill 	val = rge_read_phy_ocp(sc, 0xb54c) & ~0xffc0;
   1921  1.34  jmcneill 	rge_write_phy_ocp(sc, 0xb54c, val | 0x3700);
   1922  1.17  jakllsch }
   1923  1.17  jakllsch 
   1924  1.17  jakllsch void
   1925  1.17  jakllsch rge_phy_config_mac_cfg2(struct rge_softc *sc)
   1926  1.17  jakllsch {
   1927  1.17  jakllsch 	uint16_t val;
   1928  1.17  jakllsch 	int i;
   1929  1.17  jakllsch 
   1930  1.17  jakllsch 	for (i = 0; i < nitems(rtl8125_mac_cfg2_ephy); i++)
   1931  1.17  jakllsch 		rge_write_ephy(sc, rtl8125_mac_cfg2_ephy[i].reg,
   1932  1.17  jakllsch 		    rtl8125_mac_cfg2_ephy[i].val);
   1933  1.17  jakllsch 
   1934  1.17  jakllsch 	rge_phy_config_mcu(sc, RGE_MAC_CFG2_MCODE_VER);
   1935  1.17  jakllsch 
   1936  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xad40) & ~0x03ff;
   1937  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xad40, val | 0x0084);
   1938  1.17  jakllsch 	RGE_PHY_SETBIT(sc, 0xad4e, 0x0010);
   1939  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xad16) & ~0x03ff;
   1940  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xad16, val | 0x0006);
   1941  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xad32) & ~0x03ff;
   1942  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xad32, val | 0x0006);
   1943  1.17  jakllsch 	RGE_PHY_CLRBIT(sc, 0xac08, 0x1100);
   1944  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xac8a) & ~0xf000;
   1945  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xac8a, val | 0x7000);
   1946  1.17  jakllsch 	RGE_PHY_SETBIT(sc, 0xad18, 0x0400);
   1947  1.17  jakllsch 	RGE_PHY_SETBIT(sc, 0xad1a, 0x03ff);
   1948  1.17  jakllsch 	RGE_PHY_SETBIT(sc, 0xad1c, 0x03ff);
   1949  1.17  jakllsch 
   1950  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x80ea);
   1951  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   1952  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, val | 0xc400);
   1953  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x80eb);
   1954  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xa438) & ~0x0700;
   1955  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, val | 0x0300);
   1956  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x80f8);
   1957  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   1958  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, val | 0x1c00);
   1959  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x80f1);
   1960  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   1961  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, val | 0x3000);
   1962  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x80fe);
   1963  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   1964  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, val | 0xa500);
   1965  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x8102);
   1966  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   1967  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, val | 0x5000);
   1968  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x8105);
   1969  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   1970  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, val | 0x3300);
   1971  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x8100);
   1972  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   1973  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, val | 0x7000);
   1974  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x8104);
   1975  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   1976  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, val | 0xf000);
   1977  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x8106);
   1978  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   1979  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, val | 0x6500);
   1980  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x80dc);
   1981  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   1982  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, val | 0xed00);
   1983  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x80df);
   1984  1.17  jakllsch 	RGE_PHY_SETBIT(sc, 0xa438, 0x0100);
   1985  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x80e1);
   1986  1.17  jakllsch 	RGE_PHY_CLRBIT(sc, 0xa438, 0x0100);
   1987  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xbf06) & ~0x003f;
   1988  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xbf06, val | 0x0038);
   1989  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x819f);
   1990  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, 0xd0b6);
   1991  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xbc34, 0x5555);
   1992  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xbf0a) & ~0x0e00;
   1993  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xbf0a, val | 0x0a00);
   1994  1.17  jakllsch 	RGE_PHY_CLRBIT(sc, 0xa5c0, 0x0400);
   1995  1.17  jakllsch 	RGE_PHY_SETBIT(sc, 0xa442, 0x0800);
   1996  1.17  jakllsch }
   1997  1.17  jakllsch 
   1998  1.17  jakllsch void
   1999  1.17  jakllsch rge_phy_config_mac_cfg3(struct rge_softc *sc)
   2000  1.17  jakllsch {
   2001  1.17  jakllsch 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   2002  1.17  jakllsch 	uint16_t val;
   2003   1.1     sevan 	int i;
   2004   1.1     sevan 	static const uint16_t mac_cfg3_a438_value[] =
   2005   1.1     sevan 	    { 0x0043, 0x00a7, 0x00d6, 0x00ec, 0x00f6, 0x00fb, 0x00fd, 0x00ff,
   2006   1.1     sevan 	      0x00bb, 0x0058, 0x0029, 0x0013, 0x0009, 0x0004, 0x0002 };
   2007   1.1     sevan 
   2008   1.1     sevan 	static const uint16_t mac_cfg3_b88e_value[] =
   2009   1.5     skrll 	    { 0xc091, 0x6e12, 0xc092, 0x1214, 0xc094, 0x1516, 0xc096, 0x171b,
   2010   1.1     sevan 	      0xc098, 0x1b1c, 0xc09a, 0x1f1f, 0xc09c, 0x2021, 0xc09e, 0x2224,
   2011   1.1     sevan 	      0xc0a0, 0x2424, 0xc0a2, 0x2424, 0xc0a4, 0x2424, 0xc018, 0x0af2,
   2012   1.1     sevan 	      0xc01a, 0x0d4a, 0xc01c, 0x0f26, 0xc01e, 0x118d, 0xc020, 0x14f3,
   2013   1.1     sevan 	      0xc022, 0x175a, 0xc024, 0x19c0, 0xc026, 0x1c26, 0xc089, 0x6050,
   2014   1.1     sevan 	      0xc08a, 0x5f6e, 0xc08c, 0x6e6e, 0xc08e, 0x6e6e, 0xc090, 0x6e12 };
   2015   1.1     sevan 
   2016  1.17  jakllsch 	for (i = 0; i < nitems(rtl8125_mac_cfg3_ephy); i++)
   2017  1.17  jakllsch 		rge_write_ephy(sc, rtl8125_mac_cfg3_ephy[i].reg,
   2018  1.17  jakllsch 		    rtl8125_mac_cfg3_ephy[i].val);
   2019  1.17  jakllsch 
   2020  1.17  jakllsch 	val = rge_read_ephy(sc, 0x002a) & ~0x7000;
   2021  1.17  jakllsch 	rge_write_ephy(sc, 0x002a, val | 0x3000);
   2022  1.17  jakllsch 	RGE_EPHY_CLRBIT(sc, 0x0019, 0x0040);
   2023  1.17  jakllsch 	RGE_EPHY_SETBIT(sc, 0x001b, 0x0e00);
   2024  1.17  jakllsch 	RGE_EPHY_CLRBIT(sc, 0x001b, 0x7000);
   2025  1.17  jakllsch 	rge_write_ephy(sc, 0x0002, 0x6042);
   2026  1.17  jakllsch 	rge_write_ephy(sc, 0x0006, 0x0014);
   2027  1.17  jakllsch 	val = rge_read_ephy(sc, 0x006a) & ~0x7000;
   2028  1.17  jakllsch 	rge_write_ephy(sc, 0x006a, val | 0x3000);
   2029  1.17  jakllsch 	RGE_EPHY_CLRBIT(sc, 0x0059, 0x0040);
   2030  1.17  jakllsch 	RGE_EPHY_SETBIT(sc, 0x005b, 0x0e00);
   2031  1.17  jakllsch 	RGE_EPHY_CLRBIT(sc, 0x005b, 0x7000);
   2032  1.17  jakllsch 	rge_write_ephy(sc, 0x0042, 0x6042);
   2033  1.17  jakllsch 	rge_write_ephy(sc, 0x0046, 0x0014);
   2034  1.17  jakllsch 
   2035  1.17  jakllsch 	rge_phy_config_mcu(sc, RGE_MAC_CFG3_MCODE_VER);
   2036  1.17  jakllsch 
   2037  1.17  jakllsch 	RGE_PHY_SETBIT(sc, 0xad4e, 0x0010);
   2038  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xad16) & ~0x03ff;
   2039  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xad16, val | 0x03ff);
   2040  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xad32) & ~0x003f;
   2041  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xad32, val | 0x0006);
   2042  1.17  jakllsch 	RGE_PHY_CLRBIT(sc, 0xac08, 0x1000);
   2043  1.17  jakllsch 	RGE_PHY_CLRBIT(sc, 0xac08, 0x0100);
   2044  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xacc0) & ~0x0003;
   2045  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xacc0, val | 0x0002);
   2046  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xad40) & ~0x00e0;
   2047  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xad40, val | 0x0040);
   2048  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xad40) & ~0x0007;
   2049  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xad40, val | 0x0004);
   2050  1.17  jakllsch 	RGE_PHY_CLRBIT(sc, 0xac14, 0x0080);
   2051  1.17  jakllsch 	RGE_PHY_CLRBIT(sc, 0xac80, 0x0300);
   2052  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xac5e) & ~0x0007;
   2053  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xac5e, val | 0x0002);
   2054  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xad4c, 0x00a8);
   2055  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xac5c, 0x01ff);
   2056  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xac8a) & ~0x00f0;
   2057  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xac8a, val | 0x0030);
   2058  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87c, 0x8157);
   2059  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   2060  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87e, val | 0x0500);
   2061  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87c, 0x8159);
   2062  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   2063  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87e, val | 0x0700);
   2064  1.17  jakllsch 	RGE_WRITE_2(sc, RGE_EEE_TXIDLE_TIMER, ifp->if_mtu + ETHER_HDR_LEN +
   2065  1.17  jakllsch 	    32);
   2066  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87c, 0x80a2);
   2067  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87e, 0x0153);
   2068  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87c, 0x809c);
   2069  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87e, 0x0153);
   2070  1.17  jakllsch 
   2071  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x81b3);
   2072  1.17  jakllsch 	for (i = 0; i < nitems(mac_cfg3_a438_value); i++)
   2073  1.17  jakllsch 		rge_write_phy_ocp(sc, 0xa438, mac_cfg3_a438_value[i]);
   2074  1.17  jakllsch 	for (i = 0; i < 26; i++)
   2075  1.17  jakllsch 		rge_write_phy_ocp(sc, 0xa438, 0);
   2076  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x8257);
   2077  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, 0x020f);
   2078  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x80ea);
   2079  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, 0x7843);
   2080  1.17  jakllsch 
   2081  1.17  jakllsch 	rge_patch_phy_mcu(sc, 1);
   2082  1.17  jakllsch 	RGE_PHY_CLRBIT(sc, 0xb896, 0x0001);
   2083  1.17  jakllsch 	RGE_PHY_CLRBIT(sc, 0xb892, 0xff00);
   2084  1.17  jakllsch 	for (i = 0; i < nitems(mac_cfg3_b88e_value); i += 2) {
   2085  1.17  jakllsch 		rge_write_phy_ocp(sc, 0xb88e, mac_cfg3_b88e_value[i]);
   2086  1.17  jakllsch 		rge_write_phy_ocp(sc, 0xb890, mac_cfg3_b88e_value[i + 1]);
   2087  1.17  jakllsch 	}
   2088  1.17  jakllsch 	RGE_PHY_SETBIT(sc, 0xb896, 0x0001);
   2089  1.17  jakllsch 	rge_patch_phy_mcu(sc, 0);
   2090  1.17  jakllsch 
   2091  1.17  jakllsch 	RGE_PHY_SETBIT(sc, 0xd068, 0x2000);
   2092  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x81a2);
   2093  1.17  jakllsch 	RGE_PHY_SETBIT(sc, 0xa438, 0x0100);
   2094  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xb54c) & ~0xff00;
   2095  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb54c, val | 0xdb00);
   2096  1.17  jakllsch 	RGE_PHY_CLRBIT(sc, 0xa454, 0x0001);
   2097  1.17  jakllsch 	RGE_PHY_SETBIT(sc, 0xa5d4, 0x0020);
   2098  1.17  jakllsch 	RGE_PHY_CLRBIT(sc, 0xad4e, 0x0010);
   2099  1.17  jakllsch 	RGE_PHY_CLRBIT(sc, 0xa86a, 0x0001);
   2100  1.17  jakllsch 	RGE_PHY_SETBIT(sc, 0xa442, 0x0800);
   2101  1.17  jakllsch }
   2102  1.17  jakllsch 
   2103  1.17  jakllsch void
   2104  1.17  jakllsch rge_phy_config_mac_cfg4(struct rge_softc *sc)
   2105  1.17  jakllsch {
   2106  1.17  jakllsch 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   2107  1.17  jakllsch 	uint16_t val;
   2108  1.17  jakllsch 	int i;
   2109  1.17  jakllsch 	static const uint16_t mac_cfg4_b87c_value[] =
   2110  1.23     skrll 	    { 0x8013, 0x0700, 0x8fb9, 0x2801, 0x8fba, 0x0100, 0x8fbc, 0x1900,
   2111  1.23     skrll 	      0x8fbe, 0xe100, 0x8fc0, 0x0800, 0x8fc2, 0xe500, 0x8fc4, 0x0f00,
   2112  1.23     skrll 	      0x8fc6, 0xf100, 0x8fc8, 0x0400, 0x8fca, 0xf300, 0x8fcc, 0xfd00,
   2113  1.23     skrll 	      0x8fce, 0xff00, 0x8fd0, 0xfb00, 0x8fd2, 0x0100, 0x8fd4, 0xf400,
   2114  1.23     skrll 	      0x8fd6, 0xff00, 0x8fd8, 0xf600, 0x813d, 0x390e, 0x814f, 0x790e,
   2115  1.17  jakllsch 	      0x80b0, 0x0f31 };
   2116  1.17  jakllsch 
   2117  1.17  jakllsch 	for (i = 0; i < nitems(rtl8125_mac_cfg4_ephy); i++)
   2118  1.17  jakllsch 		rge_write_ephy(sc, rtl8125_mac_cfg4_ephy[i].reg,
   2119  1.17  jakllsch 		    rtl8125_mac_cfg4_ephy[i].val);
   2120  1.17  jakllsch 
   2121  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xbf86, 0x9000);
   2122  1.17  jakllsch 	RGE_PHY_SETBIT(sc, 0xc402, 0x0400);
   2123  1.17  jakllsch 	RGE_PHY_CLRBIT(sc, 0xc402, 0x0400);
   2124  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xbd86, 0x1010);
   2125  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xbd88, 0x1010);
   2126  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xbd4e) & ~0x0c00;
   2127  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xbd4e, val | 0x0800);
   2128  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xbf46) & ~0x0f00;
   2129  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xbf46, val | 0x0700);
   2130  1.17  jakllsch 
   2131  1.17  jakllsch 	rge_phy_config_mcu(sc, RGE_MAC_CFG4_MCODE_VER);
   2132  1.17  jakllsch 
   2133  1.17  jakllsch 	RGE_PHY_SETBIT(sc, 0xa442, 0x0800);
   2134  1.17  jakllsch 	RGE_PHY_SETBIT(sc, 0xbc08, 0x000c);
   2135  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x8fff);
   2136  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   2137  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, val | 0x0400);
   2138  1.17  jakllsch 	for (i = 0; i < 6; i++) {
   2139  1.17  jakllsch 		rge_write_phy_ocp(sc, 0xb87c, 0x8560 + i * 2);
   2140  1.17  jakllsch 		if (i < 3)
   2141  1.17  jakllsch 			rge_write_phy_ocp(sc, 0xb87e, 0x19cc);
   2142  1.17  jakllsch 		else
   2143  1.17  jakllsch 			rge_write_phy_ocp(sc, 0xb87e, 0x147d);
   2144  1.17  jakllsch 	}
   2145  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87c, 0x8ffe);
   2146  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87e, 0x0907);
   2147  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xacda) & ~0xff00;
   2148  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xacda, val | 0xff00);
   2149  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xacde) & ~0xf000;
   2150  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xacde, val | 0xf000);
   2151  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87c, 0x80d6);
   2152  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87e, 0x2801);
   2153  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87c, 0x80F2);
   2154  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87e, 0x2801);
   2155  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87c, 0x80f4);
   2156  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87e, 0x6077);
   2157  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb506, 0x01e7);
   2158  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xac8c, 0x0ffc);
   2159  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xac46, 0xb7b4);
   2160  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xac50, 0x0fbc);
   2161  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xac3c, 0x9240);
   2162  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xac4E, 0x0db4);
   2163  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xacc6, 0x0707);
   2164  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xacc8, 0xa0d3);
   2165  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xad08, 0x0007);
   2166  1.17  jakllsch 	for (i = 0; i < nitems(mac_cfg4_b87c_value); i += 2) {
   2167  1.17  jakllsch 		rge_write_phy_ocp(sc, 0xb87c, mac_cfg4_b87c_value[i]);
   2168  1.17  jakllsch 		rge_write_phy_ocp(sc, 0xb87e, mac_cfg4_b87c_value[i + 1]);
   2169  1.17  jakllsch 	}
   2170  1.17  jakllsch 	RGE_PHY_SETBIT(sc, 0xbf4c, 0x0002);
   2171  1.17  jakllsch 	RGE_PHY_SETBIT(sc, 0xbcca, 0x0300);
   2172  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87c, 0x8141);
   2173  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87e, 0x320e);
   2174  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87c, 0x8153);
   2175  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87e, 0x720e);
   2176  1.17  jakllsch 	RGE_PHY_CLRBIT(sc, 0xa432, 0x0040);
   2177  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87c, 0x8529);
   2178  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87e, 0x050e);
   2179  1.17  jakllsch 	RGE_WRITE_2(sc, RGE_EEE_TXIDLE_TIMER, ifp->if_mtu + ETHER_HDR_LEN +
   2180  1.17  jakllsch 	    32);
   2181  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x816c);
   2182  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, 0xc4a0);
   2183  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x8170);
   2184  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, 0xc4a0);
   2185  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x8174);
   2186  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, 0x04a0);
   2187  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x8178);
   2188  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, 0x04a0);
   2189  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x817c);
   2190  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, 0x0719);
   2191  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x8ff4);
   2192  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, 0x0400);
   2193  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x8ff1);
   2194  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, 0x0404);
   2195  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xbf4a, 0x001b);
   2196  1.17  jakllsch 	for (i = 0; i < 6; i++) {
   2197  1.17  jakllsch 		rge_write_phy_ocp(sc, 0xb87c, 0x8033 + i * 4);
   2198  1.17  jakllsch 		if (i == 2)
   2199  1.17  jakllsch 			rge_write_phy_ocp(sc, 0xb87e, 0xfc32);
   2200  1.17  jakllsch 		else
   2201  1.17  jakllsch 			rge_write_phy_ocp(sc, 0xb87e, 0x7c13);
   2202  1.17  jakllsch 	}
   2203  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87c, 0x8145);
   2204  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87e, 0x370e);
   2205  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87c, 0x8157);
   2206  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87e, 0x770e);
   2207  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87c, 0x8169);
   2208  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87e, 0x0d0a);
   2209  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87c, 0x817b);
   2210  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87e, 0x1d0a);
   2211  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x8217);
   2212  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   2213  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, val | 0x5000);
   2214  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x821a);
   2215  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   2216  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, val | 0x5000);
   2217  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x80da);
   2218  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, 0x0403);
   2219  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x80dc);
   2220  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   2221  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, val | 0x1000);
   2222  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x80b3);
   2223  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, 0x0384);
   2224  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x80b7);
   2225  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, 0x2007);
   2226  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x80ba);
   2227  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   2228  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, val | 0x6c00);
   2229  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x80b5);
   2230  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, 0xf009);
   2231  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x80bd);
   2232  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   2233  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, val | 0x9f00);
   2234  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x80c7);
   2235  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, 0xf083);
   2236  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x80dd);
   2237  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, 0x03f0);
   2238  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x80df);
   2239  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   2240  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, val | 0x1000);
   2241  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x80cb);
   2242  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, 0x2007);
   2243  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x80ce);
   2244  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   2245  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, val | 0x6c00);
   2246  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x80c9);
   2247  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, 0x8009);
   2248  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x80d1);
   2249  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   2250  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, val | 0x8000);
   2251  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x80a3);
   2252  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, 0x200a);
   2253  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x80a5);
   2254  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, 0xf0ad);
   2255  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x809f);
   2256  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, 0x6073);
   2257  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x80a1);
   2258  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, 0x000b);
   2259  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x80a9);
   2260  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
   2261  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa438, val | 0xc000);
   2262  1.17  jakllsch 	rge_patch_phy_mcu(sc, 1);
   2263  1.23     skrll 	RGE_PHY_CLRBIT(sc, 0xb896, 0x0001);
   2264  1.23     skrll 	RGE_PHY_CLRBIT(sc, 0xb892, 0xff00);
   2265  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb88e, 0xc23e);
   2266  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb890, 0x0000);
   2267  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb88e, 0xc240);
   2268  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb890, 0x0103);
   2269  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb88e, 0xc242);
   2270  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb890, 0x0507);
   2271  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb88e, 0xc244);
   2272  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb890, 0x090b);
   2273  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb88e, 0xc246);
   2274  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb890, 0x0c0e);
   2275  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb88e, 0xc248);
   2276  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb890, 0x1012);
   2277  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb88e, 0xc24a);
   2278  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb890, 0x1416);
   2279  1.23     skrll 	RGE_PHY_SETBIT(sc, 0xb896, 0x0001);
   2280  1.17  jakllsch 	rge_patch_phy_mcu(sc, 0);
   2281  1.23     skrll 	RGE_PHY_SETBIT(sc, 0xa86a, 0x0001);
   2282  1.23     skrll 	RGE_PHY_SETBIT(sc, 0xa6f0, 0x0001);
   2283  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xbfa0, 0xd70d);
   2284  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xbfa2, 0x4100);
   2285  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xbfa4, 0xe868);
   2286  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xbfa6, 0xdc59);
   2287  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb54c, 0x3c18);
   2288  1.17  jakllsch 	RGE_PHY_CLRBIT(sc, 0xbfa4, 0x0020);
   2289  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xa436, 0x817d);
   2290  1.23     skrll 	RGE_PHY_SETBIT(sc, 0xa438, 0x1000);
   2291  1.17  jakllsch }
   2292  1.17  jakllsch 
   2293  1.17  jakllsch void
   2294  1.17  jakllsch rge_phy_config_mac_cfg5(struct rge_softc *sc)
   2295  1.17  jakllsch {
   2296  1.17  jakllsch 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   2297  1.17  jakllsch 	uint16_t val;
   2298  1.17  jakllsch 	int i;
   2299   1.1     sevan 
   2300  1.17  jakllsch 	for (i = 0; i < nitems(rtl8125_mac_cfg5_ephy); i++)
   2301  1.17  jakllsch 		rge_write_ephy(sc, rtl8125_mac_cfg5_ephy[i].reg,
   2302  1.17  jakllsch 		    rtl8125_mac_cfg5_ephy[i].val);
   2303  1.17  jakllsch 
   2304  1.17  jakllsch 	val = rge_read_ephy(sc, 0x0022) & ~0x0030;
   2305  1.17  jakllsch 	rge_write_ephy(sc, 0x0022, val | 0x0020);
   2306  1.17  jakllsch 	val = rge_read_ephy(sc, 0x0062) & ~0x0030;
   2307  1.17  jakllsch 	rge_write_ephy(sc, 0x0062, val | 0x0020);
   2308  1.17  jakllsch 
   2309  1.17  jakllsch 	rge_phy_config_mcu(sc, RGE_MAC_CFG5_MCODE_VER);
   2310  1.17  jakllsch 
   2311  1.17  jakllsch 	RGE_PHY_SETBIT(sc, 0xa442, 0x0800);
   2312  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xac46) & ~0x00f0;
   2313  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xac46, val | 0x0090);
   2314  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xad30) & ~0x0003;
   2315  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xad30, val | 0x0001);
   2316  1.17  jakllsch 	RGE_WRITE_2(sc, RGE_EEE_TXIDLE_TIMER, ifp->if_mtu + ETHER_HDR_LEN +
   2317  1.17  jakllsch 	    32);
   2318  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87c, 0x80f5);
   2319  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87e, 0x760e);
   2320  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87c, 0x8107);
   2321  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87e, 0x360e);
   2322  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87c, 0x8551);
   2323  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
   2324  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xb87e, val | 0x0800);
   2325  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xbf00) & ~0xe000;
   2326  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xbf00, val | 0xa000);
   2327  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xbf46) & ~0x0f00;
   2328  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xbf46, val | 0x0300);
   2329  1.17  jakllsch 	for (i = 0; i < 10; i++) {
   2330  1.17  jakllsch 		rge_write_phy_ocp(sc, 0xa436, 0x8044 + i * 6);
   2331  1.17  jakllsch 		rge_write_phy_ocp(sc, 0xa438, 0x2417);
   2332  1.17  jakllsch 	}
   2333  1.17  jakllsch 	RGE_PHY_SETBIT(sc, 0xa4ca, 0x0040);
   2334  1.17  jakllsch 	val = rge_read_phy_ocp(sc, 0xbf84) & ~0xe000;
   2335  1.17  jakllsch 	rge_write_phy_ocp(sc, 0xbf84, val | 0xa000);
   2336  1.17  jakllsch }
   2337   1.1     sevan 
   2338  1.17  jakllsch void
   2339  1.17  jakllsch rge_phy_config_mcu(struct rge_softc *sc, uint16_t mcode_version)
   2340  1.17  jakllsch {
   2341  1.17  jakllsch 	if (sc->rge_mcodever != mcode_version) {
   2342  1.17  jakllsch 		int i;
   2343   1.1     sevan 
   2344  1.17  jakllsch 		rge_patch_phy_mcu(sc, 1);
   2345   1.1     sevan 
   2346  1.17  jakllsch 		if (sc->rge_type == MAC_CFG2 || sc->rge_type == MAC_CFG3) {
   2347   1.1     sevan 			rge_write_phy_ocp(sc, 0xa436, 0x8024);
   2348  1.17  jakllsch 			if (sc->rge_type == MAC_CFG2)
   2349  1.17  jakllsch 				rge_write_phy_ocp(sc, 0xa438, 0x8600);
   2350  1.17  jakllsch 			else
   2351  1.17  jakllsch 				rge_write_phy_ocp(sc, 0xa438, 0x8601);
   2352   1.1     sevan 			rge_write_phy_ocp(sc, 0xa436, 0xb82e);
   2353   1.1     sevan 			rge_write_phy_ocp(sc, 0xa438, 0x0001);
   2354   1.1     sevan 
   2355   1.1     sevan 			RGE_PHY_SETBIT(sc, 0xb820, 0x0080);
   2356  1.17  jakllsch 		}
   2357  1.17  jakllsch 
   2358  1.17  jakllsch 		if (sc->rge_type == MAC_CFG2) {
   2359   1.1     sevan 			for (i = 0; i < nitems(rtl8125_mac_cfg2_mcu); i++) {
   2360   1.1     sevan 				rge_write_phy_ocp(sc,
   2361   1.1     sevan 				    rtl8125_mac_cfg2_mcu[i].reg,
   2362   1.1     sevan 				    rtl8125_mac_cfg2_mcu[i].val);
   2363   1.1     sevan 			}
   2364  1.17  jakllsch 		} else if (sc->rge_type == MAC_CFG3) {
   2365   1.1     sevan 			for (i = 0; i < nitems(rtl8125_mac_cfg3_mcu); i++) {
   2366   1.1     sevan 				rge_write_phy_ocp(sc,
   2367   1.1     sevan 				    rtl8125_mac_cfg3_mcu[i].reg,
   2368   1.1     sevan 				    rtl8125_mac_cfg3_mcu[i].val);
   2369   1.1     sevan 			}
   2370  1.17  jakllsch 		} else if (sc->rge_type == MAC_CFG4) {
   2371  1.17  jakllsch 			for (i = 0; i < nitems(rtl8125_mac_cfg4_mcu); i++) {
   2372  1.17  jakllsch 				rge_write_phy_ocp(sc,
   2373  1.17  jakllsch 				    rtl8125_mac_cfg4_mcu[i].reg,
   2374  1.17  jakllsch 				    rtl8125_mac_cfg4_mcu[i].val);
   2375  1.17  jakllsch 			}
   2376  1.17  jakllsch 		} else if (sc->rge_type == MAC_CFG5) {
   2377  1.17  jakllsch 			for (i = 0; i < nitems(rtl8125_mac_cfg5_mcu); i++) {
   2378  1.17  jakllsch 				rge_write_phy_ocp(sc,
   2379  1.17  jakllsch 				    rtl8125_mac_cfg5_mcu[i].reg,
   2380  1.17  jakllsch 				    rtl8125_mac_cfg5_mcu[i].val);
   2381  1.17  jakllsch 			}
   2382  1.34  jmcneill 		} else if (sc->rge_type == MAC_CFG2_8126) {
   2383  1.34  jmcneill 			for (i = 0; i < nitems(rtl8126_mac_cfg2_mcu); i++) {
   2384  1.34  jmcneill 				rge_write_phy_ocp(sc,
   2385  1.34  jmcneill 				    rtl8126_mac_cfg2_mcu[i].reg,
   2386  1.34  jmcneill 				    rtl8126_mac_cfg2_mcu[i].val);
   2387  1.34  jmcneill 			}
   2388  1.17  jakllsch 		}
   2389  1.17  jakllsch 
   2390  1.17  jakllsch 		if (sc->rge_type == MAC_CFG2 || sc->rge_type == MAC_CFG3) {
   2391   1.1     sevan 			RGE_PHY_CLRBIT(sc, 0xb820, 0x0080);
   2392   1.1     sevan 
   2393   1.1     sevan 			rge_write_phy_ocp(sc, 0xa436, 0);
   2394   1.1     sevan 			rge_write_phy_ocp(sc, 0xa438, 0);
   2395   1.1     sevan 			RGE_PHY_CLRBIT(sc, 0xb82e, 0x0001);
   2396   1.1     sevan 			rge_write_phy_ocp(sc, 0xa436, 0x8024);
   2397   1.1     sevan 			rge_write_phy_ocp(sc, 0xa438, 0);
   2398  1.17  jakllsch 		}
   2399   1.1     sevan 
   2400   1.1     sevan 		rge_patch_phy_mcu(sc, 0);
   2401   1.1     sevan 
   2402  1.17  jakllsch 		/* Write microcode version. */
   2403  1.17  jakllsch 		rge_write_phy_ocp(sc, 0xa436, 0x801e);
   2404  1.17  jakllsch 		rge_write_phy_ocp(sc, 0xa438, mcode_version);
   2405   1.1     sevan 	}
   2406   1.1     sevan }
   2407   1.1     sevan 
   2408   1.1     sevan void
   2409   1.1     sevan rge_set_macaddr(struct rge_softc *sc, const uint8_t *addr)
   2410   1.1     sevan {
   2411   1.1     sevan 	RGE_SETBIT_1(sc, RGE_EECMD, RGE_EECMD_WRITECFG);
   2412   1.1     sevan 	RGE_WRITE_4(sc, RGE_MAC0,
   2413  1.21   msaitoh 	    (uint32_t)addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0]);
   2414   1.1     sevan 	RGE_WRITE_4(sc, RGE_MAC4,
   2415   1.1     sevan 	    addr[5] <<  8 | addr[4]);
   2416   1.1     sevan 	RGE_CLRBIT_1(sc, RGE_EECMD, RGE_EECMD_WRITECFG);
   2417   1.1     sevan }
   2418   1.1     sevan 
   2419   1.1     sevan void
   2420   1.1     sevan rge_get_macaddr(struct rge_softc *sc, uint8_t *addr)
   2421   1.1     sevan {
   2422  1.22   msaitoh 	int i;
   2423  1.22   msaitoh 
   2424  1.22   msaitoh 	for (i = 0; i < ETHER_ADDR_LEN; i++)
   2425  1.22   msaitoh 		addr[i] = RGE_READ_1(sc, RGE_ADDR0 + i);
   2426   1.1     sevan }
   2427   1.1     sevan 
   2428   1.1     sevan void
   2429   1.1     sevan rge_hw_init(struct rge_softc *sc)
   2430   1.1     sevan {
   2431   1.1     sevan 	int i;
   2432   1.1     sevan 
   2433   1.1     sevan 	RGE_SETBIT_1(sc, RGE_EECMD, RGE_EECMD_WRITECFG);
   2434   1.1     sevan 	RGE_CLRBIT_1(sc, RGE_CFG5, RGE_CFG5_PME_STS);
   2435  1.34  jmcneill 	if (sc->rge_type == MAC_CFG2_8126)
   2436  1.34  jmcneill 		RGE_CLRBIT_1(sc, RGE_INT_CFG0, 0x08);
   2437  1.34  jmcneill 	else
   2438  1.34  jmcneill 		RGE_CLRBIT_1(sc, RGE_CFG2, RGE_CFG2_CLKREQ_EN);
   2439   1.1     sevan 	RGE_CLRBIT_1(sc, RGE_EECMD, RGE_EECMD_WRITECFG);
   2440   1.1     sevan 	RGE_CLRBIT_1(sc, 0xf1, 0x80);
   2441   1.1     sevan 
   2442   1.1     sevan 	/* Disable UPS. */
   2443   1.1     sevan 	RGE_MAC_CLRBIT(sc, 0xd40a, 0x0010);
   2444   1.1     sevan 
   2445   1.1     sevan 	/* Configure MAC MCU. */
   2446   1.1     sevan 	rge_write_mac_ocp(sc, 0xfc38, 0);
   2447   1.1     sevan 
   2448   1.1     sevan 	for (i = 0xfc28; i < 0xfc38; i += 2)
   2449   1.1     sevan 		rge_write_mac_ocp(sc, i, 0);
   2450   1.1     sevan 
   2451   1.1     sevan 	DELAY(3000);
   2452   1.1     sevan 	rge_write_mac_ocp(sc, 0xfc26, 0);
   2453   1.1     sevan 
   2454   1.1     sevan 	if (sc->rge_type == MAC_CFG3) {
   2455  1.17  jakllsch 		for (i = 0; i < nitems(rtl8125_mac_bps); i++) {
   2456  1.17  jakllsch 			rge_write_mac_ocp(sc, rtl8125_mac_bps[i].reg,
   2457  1.17  jakllsch 			    rtl8125_mac_bps[i].val);
   2458  1.17  jakllsch 		}
   2459  1.17  jakllsch 	} else if (sc->rge_type == MAC_CFG5) {
   2460  1.17  jakllsch 		for (i = 0; i < nitems(rtl8125b_mac_bps); i++) {
   2461  1.17  jakllsch 			rge_write_mac_ocp(sc, rtl8125b_mac_bps[i].reg,
   2462  1.17  jakllsch 			    rtl8125b_mac_bps[i].val);
   2463  1.17  jakllsch 		}
   2464   1.1     sevan 	}
   2465   1.1     sevan 
   2466   1.1     sevan 	/* Disable PHY power saving. */
   2467  1.34  jmcneill 	if (sc->rge_type != MAC_CFG2_8126)
   2468  1.34  jmcneill 		rge_disable_phy_ocp_pwrsave(sc);
   2469   1.1     sevan 
   2470   1.1     sevan 	/* Set PCIe uncorrectable error status. */
   2471   1.1     sevan 	rge_write_csi(sc, 0x108,
   2472   1.1     sevan 	    rge_read_csi(sc, 0x108) | 0x00100000);
   2473   1.1     sevan }
   2474   1.1     sevan 
   2475   1.1     sevan void
   2476   1.1     sevan rge_disable_phy_ocp_pwrsave(struct rge_softc *sc)
   2477   1.1     sevan {
   2478   1.1     sevan 	if (rge_read_phy_ocp(sc, 0xc416) != 0x0500) {
   2479   1.1     sevan 		rge_patch_phy_mcu(sc, 1);
   2480   1.1     sevan 		rge_write_phy_ocp(sc, 0xc416, 0);
   2481   1.1     sevan 		rge_write_phy_ocp(sc, 0xc416, 0x0500);
   2482   1.1     sevan 		rge_patch_phy_mcu(sc, 0);
   2483   1.1     sevan 	}
   2484   1.1     sevan }
   2485   1.1     sevan 
   2486   1.1     sevan void
   2487   1.1     sevan rge_patch_phy_mcu(struct rge_softc *sc, int set)
   2488   1.1     sevan {
   2489   1.1     sevan 	int i;
   2490   1.1     sevan 
   2491   1.1     sevan 	if (set)
   2492   1.1     sevan 		RGE_PHY_SETBIT(sc, 0xb820, 0x0010);
   2493   1.1     sevan 	else
   2494   1.1     sevan 		RGE_PHY_CLRBIT(sc, 0xb820, 0x0010);
   2495   1.1     sevan 
   2496   1.1     sevan 	for (i = 0; i < 1000; i++) {
   2497  1.17  jakllsch 		if ((rge_read_phy_ocp(sc, 0xb800) & 0x0040) == 0x0040)
   2498  1.17  jakllsch 			break;
   2499   1.1     sevan 		DELAY(100);
   2500   1.1     sevan 	}
   2501  1.17  jakllsch 	if (i == 1000) {
   2502  1.17  jakllsch 		DPRINTF(("timeout waiting to patch phy mcu\n"));
   2503  1.17  jakllsch 		return;
   2504  1.17  jakllsch 	}
   2505   1.1     sevan }
   2506   1.1     sevan 
   2507   1.1     sevan void
   2508   1.1     sevan rge_add_media_types(struct rge_softc *sc)
   2509   1.1     sevan {
   2510   1.1     sevan 	ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_10_T, 0, NULL);
   2511   1.1     sevan 	ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_10_T | IFM_FDX, 0, NULL);
   2512   1.1     sevan 	ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_100_TX, 0, NULL);
   2513   1.1     sevan 	ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_100_TX | IFM_FDX, 0, NULL);
   2514   1.1     sevan 	ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_1000_T, 0, NULL);
   2515   1.1     sevan 	ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_1000_T | IFM_FDX, 0, NULL);
   2516   1.1     sevan 	ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_2500_T, 0, NULL);
   2517   1.1     sevan 	ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_2500_T | IFM_FDX, 0, NULL);
   2518  1.34  jmcneill 
   2519  1.34  jmcneill 	if (sc->rge_type == MAC_CFG2_8126) {
   2520  1.34  jmcneill 		ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_5000_T, 0, NULL);
   2521  1.34  jmcneill 		ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_5000_T | IFM_FDX,
   2522  1.34  jmcneill 		    0, NULL);
   2523  1.34  jmcneill 	}
   2524   1.1     sevan }
   2525   1.1     sevan 
   2526   1.1     sevan void
   2527   1.1     sevan rge_config_imtype(struct rge_softc *sc, int imtype)
   2528   1.1     sevan {
   2529   1.1     sevan 	switch (imtype) {
   2530   1.1     sevan 	case RGE_IMTYPE_NONE:
   2531   1.1     sevan 		sc->rge_intrs = RGE_INTRS;
   2532   1.1     sevan 		sc->rge_rx_ack = RGE_ISR_RX_OK | RGE_ISR_RX_DESC_UNAVAIL |
   2533   1.1     sevan 		    RGE_ISR_RX_FIFO_OFLOW;
   2534   1.1     sevan 		sc->rge_tx_ack = RGE_ISR_TX_OK;
   2535   1.1     sevan 		break;
   2536   1.1     sevan 	case RGE_IMTYPE_SIM:
   2537   1.1     sevan 		sc->rge_intrs = RGE_INTRS_TIMER;
   2538   1.1     sevan 		sc->rge_rx_ack = RGE_ISR_PCS_TIMEOUT;
   2539   1.1     sevan 		sc->rge_tx_ack = RGE_ISR_PCS_TIMEOUT;
   2540   1.1     sevan 		break;
   2541   1.1     sevan 	default:
   2542  1.14     sevan 		panic("%s: unknown imtype %d", device_xname(sc->sc_dev), imtype);
   2543   1.1     sevan 	}
   2544   1.1     sevan }
   2545   1.1     sevan 
   2546   1.1     sevan void
   2547  1.17  jakllsch rge_disable_hw_im(struct rge_softc *sc)
   2548  1.17  jakllsch {
   2549  1.17  jakllsch 	RGE_WRITE_2(sc, RGE_IM, 0);
   2550  1.17  jakllsch }
   2551  1.17  jakllsch 
   2552  1.17  jakllsch void
   2553   1.1     sevan rge_disable_sim_im(struct rge_softc *sc)
   2554   1.1     sevan {
   2555  1.17  jakllsch 	RGE_WRITE_4(sc, RGE_TIMERINT0, 0);
   2556   1.1     sevan 	sc->rge_timerintr = 0;
   2557   1.1     sevan }
   2558   1.1     sevan 
   2559   1.1     sevan void
   2560   1.1     sevan rge_setup_sim_im(struct rge_softc *sc)
   2561   1.1     sevan {
   2562  1.17  jakllsch 	RGE_WRITE_4(sc, RGE_TIMERINT0, 0x2600);
   2563   1.1     sevan 	RGE_WRITE_4(sc, RGE_TIMERCNT, 1);
   2564   1.1     sevan 	sc->rge_timerintr = 1;
   2565   1.1     sevan }
   2566   1.1     sevan 
   2567   1.1     sevan void
   2568   1.1     sevan rge_setup_intr(struct rge_softc *sc, int imtype)
   2569   1.1     sevan {
   2570   1.1     sevan 	rge_config_imtype(sc, imtype);
   2571   1.1     sevan 
   2572   1.1     sevan 	/* Enable interrupts. */
   2573   1.1     sevan 	RGE_WRITE_4(sc, RGE_IMR, sc->rge_intrs);
   2574   1.1     sevan 
   2575   1.1     sevan 	switch (imtype) {
   2576   1.1     sevan 	case RGE_IMTYPE_NONE:
   2577   1.1     sevan 		rge_disable_sim_im(sc);
   2578  1.17  jakllsch 		rge_disable_hw_im(sc);
   2579   1.1     sevan 		break;
   2580   1.1     sevan 	case RGE_IMTYPE_SIM:
   2581  1.17  jakllsch 		rge_disable_hw_im(sc);
   2582   1.1     sevan 		rge_setup_sim_im(sc);
   2583   1.1     sevan 		break;
   2584   1.1     sevan 	default:
   2585  1.14     sevan 		panic("%s: unknown imtype %d", device_xname(sc->sc_dev), imtype);
   2586   1.1     sevan 	}
   2587   1.1     sevan }
   2588   1.1     sevan 
   2589   1.1     sevan void
   2590   1.1     sevan rge_exit_oob(struct rge_softc *sc)
   2591   1.1     sevan {
   2592   1.1     sevan 	int i;
   2593   1.1     sevan 
   2594   1.1     sevan 	RGE_CLRBIT_4(sc, RGE_RXCFG, RGE_RXCFG_ALLPHYS | RGE_RXCFG_INDIV |
   2595   1.1     sevan 	    RGE_RXCFG_MULTI | RGE_RXCFG_BROAD | RGE_RXCFG_RUNT |
   2596   1.1     sevan 	    RGE_RXCFG_ERRPKT);
   2597   1.1     sevan 
   2598   1.1     sevan 	/* Disable RealWoW. */
   2599   1.1     sevan 	rge_write_mac_ocp(sc, 0xc0bc, 0x00ff);
   2600   1.1     sevan 
   2601   1.1     sevan 	rge_reset(sc);
   2602   1.1     sevan 
   2603   1.1     sevan 	/* Disable OOB. */
   2604   1.1     sevan 	RGE_CLRBIT_1(sc, RGE_MCUCMD, RGE_MCUCMD_IS_OOB);
   2605   1.1     sevan 
   2606   1.1     sevan 	RGE_MAC_CLRBIT(sc, 0xe8de, 0x4000);
   2607   1.1     sevan 
   2608   1.1     sevan 	for (i = 0; i < 10; i++) {
   2609   1.1     sevan 		DELAY(100);
   2610   1.1     sevan 		if (RGE_READ_2(sc, RGE_TWICMD) & 0x0200)
   2611   1.1     sevan 			break;
   2612   1.1     sevan 	}
   2613   1.1     sevan 
   2614   1.1     sevan 	rge_write_mac_ocp(sc, 0xc0aa, 0x07d0);
   2615  1.17  jakllsch 	rge_write_mac_ocp(sc, 0xc0a6, 0x01b5);
   2616   1.1     sevan 	rge_write_mac_ocp(sc, 0xc01e, 0x5555);
   2617   1.1     sevan 
   2618   1.1     sevan 	for (i = 0; i < 10; i++) {
   2619   1.1     sevan 		DELAY(100);
   2620   1.1     sevan 		if (RGE_READ_2(sc, RGE_TWICMD) & 0x0200)
   2621   1.1     sevan 			break;
   2622   1.1     sevan 	}
   2623   1.1     sevan 
   2624   1.1     sevan 	if (rge_read_mac_ocp(sc, 0xd42c) & 0x0100) {
   2625  1.17  jakllsch 		printf("%s: rge_exit_oob(): rtl8125_is_ups_resume!!\n",
   2626  1.17  jakllsch 		    device_xname(sc->sc_dev));
   2627   1.1     sevan 		for (i = 0; i < RGE_TIMEOUT; i++) {
   2628  1.10     sevan 			if ((rge_read_phy_ocp(sc, 0xa420) & 0x0007) == 2)
   2629   1.1     sevan 				break;
   2630   1.1     sevan 			DELAY(1000);
   2631   1.1     sevan 		}
   2632   1.1     sevan 		RGE_MAC_CLRBIT(sc, 0xd408, 0x0100);
   2633  1.17  jakllsch 		if (sc->rge_type == MAC_CFG4 || sc->rge_type == MAC_CFG5)
   2634  1.17  jakllsch 			RGE_PHY_CLRBIT(sc, 0xa466, 0x0001);
   2635   1.1     sevan 		RGE_PHY_CLRBIT(sc, 0xa468, 0x000a);
   2636   1.1     sevan 	}
   2637   1.1     sevan }
   2638   1.1     sevan 
   2639   1.1     sevan void
   2640   1.1     sevan rge_write_csi(struct rge_softc *sc, uint32_t reg, uint32_t val)
   2641   1.1     sevan {
   2642   1.1     sevan 	int i;
   2643   1.1     sevan 
   2644   1.1     sevan 	RGE_WRITE_4(sc, RGE_CSIDR, val);
   2645  1.17  jakllsch 	RGE_WRITE_4(sc, RGE_CSIAR, (reg & RGE_CSIAR_ADDR_MASK) |
   2646   1.1     sevan 	    (RGE_CSIAR_BYTE_EN << RGE_CSIAR_BYTE_EN_SHIFT) | RGE_CSIAR_BUSY);
   2647   1.1     sevan 
   2648   1.1     sevan 	for (i = 0; i < 10; i++) {
   2649   1.1     sevan 		 DELAY(100);
   2650   1.1     sevan 		 if (!(RGE_READ_4(sc, RGE_CSIAR) & RGE_CSIAR_BUSY))
   2651   1.1     sevan 			break;
   2652   1.1     sevan 	}
   2653   1.1     sevan 
   2654   1.1     sevan 	DELAY(20);
   2655   1.1     sevan }
   2656   1.1     sevan 
   2657   1.1     sevan uint32_t
   2658   1.1     sevan rge_read_csi(struct rge_softc *sc, uint32_t reg)
   2659   1.1     sevan {
   2660   1.1     sevan 	int i;
   2661   1.1     sevan 
   2662  1.17  jakllsch 	RGE_WRITE_4(sc, RGE_CSIAR, (reg & RGE_CSIAR_ADDR_MASK) |
   2663   1.1     sevan 	    (RGE_CSIAR_BYTE_EN << RGE_CSIAR_BYTE_EN_SHIFT));
   2664   1.1     sevan 
   2665   1.1     sevan 	for (i = 0; i < 10; i++) {
   2666   1.1     sevan 		 DELAY(100);
   2667   1.1     sevan 		 if (RGE_READ_4(sc, RGE_CSIAR) & RGE_CSIAR_BUSY)
   2668   1.1     sevan 			break;
   2669   1.1     sevan 	}
   2670   1.1     sevan 
   2671   1.1     sevan 	DELAY(20);
   2672   1.1     sevan 
   2673   1.1     sevan 	return (RGE_READ_4(sc, RGE_CSIDR));
   2674   1.1     sevan }
   2675   1.1     sevan 
   2676   1.1     sevan void
   2677   1.1     sevan rge_write_mac_ocp(struct rge_softc *sc, uint16_t reg, uint16_t val)
   2678   1.1     sevan {
   2679   1.1     sevan 	uint32_t tmp;
   2680   1.1     sevan 
   2681   1.1     sevan 	tmp = (reg >> 1) << RGE_MACOCP_ADDR_SHIFT;
   2682   1.1     sevan 	tmp += val;
   2683   1.1     sevan 	tmp |= RGE_MACOCP_BUSY;
   2684   1.1     sevan 	RGE_WRITE_4(sc, RGE_MACOCP, tmp);
   2685   1.1     sevan }
   2686   1.1     sevan 
   2687   1.1     sevan uint16_t
   2688   1.1     sevan rge_read_mac_ocp(struct rge_softc *sc, uint16_t reg)
   2689   1.1     sevan {
   2690   1.1     sevan 	uint32_t val;
   2691   1.1     sevan 
   2692   1.1     sevan 	val = (reg >> 1) << RGE_MACOCP_ADDR_SHIFT;
   2693   1.1     sevan 	RGE_WRITE_4(sc, RGE_MACOCP, val);
   2694   1.1     sevan 
   2695   1.1     sevan 	return (RGE_READ_4(sc, RGE_MACOCP) & RGE_MACOCP_DATA_MASK);
   2696   1.1     sevan }
   2697   1.1     sevan 
   2698   1.1     sevan void
   2699   1.1     sevan rge_write_ephy(struct rge_softc *sc, uint16_t reg, uint16_t val)
   2700   1.1     sevan {
   2701   1.1     sevan 	uint32_t tmp;
   2702   1.1     sevan 	int i;
   2703   1.1     sevan 
   2704   1.1     sevan 	tmp = (reg & RGE_EPHYAR_ADDR_MASK) << RGE_EPHYAR_ADDR_SHIFT;
   2705   1.1     sevan 	tmp |= RGE_EPHYAR_BUSY | (val & RGE_EPHYAR_DATA_MASK);
   2706   1.1     sevan 	RGE_WRITE_4(sc, RGE_EPHYAR, tmp);
   2707   1.1     sevan 
   2708   1.1     sevan 	for (i = 0; i < 10; i++) {
   2709   1.1     sevan 		DELAY(100);
   2710   1.1     sevan 		if (!(RGE_READ_4(sc, RGE_EPHYAR) & RGE_EPHYAR_BUSY))
   2711   1.1     sevan 			break;
   2712   1.1     sevan 	}
   2713   1.1     sevan 
   2714   1.1     sevan 	DELAY(20);
   2715   1.1     sevan }
   2716   1.1     sevan 
   2717  1.17  jakllsch uint16_t
   2718  1.17  jakllsch rge_read_ephy(struct rge_softc *sc, uint16_t reg)
   2719  1.17  jakllsch {
   2720  1.17  jakllsch 	uint32_t val;
   2721  1.17  jakllsch 	int i;
   2722  1.17  jakllsch 
   2723  1.17  jakllsch 	val = (reg & RGE_EPHYAR_ADDR_MASK) << RGE_EPHYAR_ADDR_SHIFT;
   2724  1.17  jakllsch 	RGE_WRITE_4(sc, RGE_EPHYAR, val);
   2725  1.17  jakllsch 
   2726  1.17  jakllsch 	for (i = 0; i < 10; i++) {
   2727  1.17  jakllsch 		DELAY(100);
   2728  1.17  jakllsch 		val = RGE_READ_4(sc, RGE_EPHYAR);
   2729  1.17  jakllsch 		if (val & RGE_EPHYAR_BUSY)
   2730  1.17  jakllsch 			break;
   2731  1.17  jakllsch 	}
   2732  1.17  jakllsch 
   2733  1.17  jakllsch 	DELAY(20);
   2734  1.17  jakllsch 
   2735  1.17  jakllsch 	return (val & RGE_EPHYAR_DATA_MASK);
   2736  1.17  jakllsch }
   2737  1.17  jakllsch 
   2738   1.1     sevan void
   2739   1.1     sevan rge_write_phy(struct rge_softc *sc, uint16_t addr, uint16_t reg, uint16_t val)
   2740   1.1     sevan {
   2741   1.1     sevan 	uint16_t off, phyaddr;
   2742   1.1     sevan 
   2743   1.1     sevan 	phyaddr = addr ? addr : RGE_PHYBASE + (reg / 8);
   2744   1.1     sevan 	phyaddr <<= 4;
   2745   1.1     sevan 
   2746   1.1     sevan 	off = addr ? reg : 0x10 + (reg % 8);
   2747   1.1     sevan 
   2748   1.1     sevan 	phyaddr += (off - 16) << 1;
   2749   1.1     sevan 
   2750   1.1     sevan 	rge_write_phy_ocp(sc, phyaddr, val);
   2751   1.1     sevan }
   2752   1.1     sevan 
   2753  1.17  jakllsch uint16_t
   2754  1.17  jakllsch rge_read_phy(struct rge_softc *sc, uint16_t addr, uint16_t reg)
   2755  1.17  jakllsch {
   2756  1.17  jakllsch 	uint16_t off, phyaddr;
   2757  1.17  jakllsch 
   2758  1.17  jakllsch 	phyaddr = addr ? addr : RGE_PHYBASE + (reg / 8);
   2759  1.17  jakllsch 	phyaddr <<= 4;
   2760  1.17  jakllsch 
   2761  1.17  jakllsch 	off = addr ? reg : 0x10 + (reg % 8);
   2762  1.17  jakllsch 
   2763  1.17  jakllsch 	phyaddr += (off - 16) << 1;
   2764  1.17  jakllsch 
   2765  1.17  jakllsch 	return (rge_read_phy_ocp(sc, phyaddr));
   2766  1.17  jakllsch }
   2767  1.17  jakllsch 
   2768   1.1     sevan void
   2769   1.1     sevan rge_write_phy_ocp(struct rge_softc *sc, uint16_t reg, uint16_t val)
   2770   1.1     sevan {
   2771   1.1     sevan 	uint32_t tmp;
   2772   1.1     sevan 	int i;
   2773   1.1     sevan 
   2774   1.1     sevan 	tmp = (reg >> 1) << RGE_PHYOCP_ADDR_SHIFT;
   2775   1.1     sevan 	tmp |= RGE_PHYOCP_BUSY | val;
   2776   1.1     sevan 	RGE_WRITE_4(sc, RGE_PHYOCP, tmp);
   2777   1.1     sevan 
   2778   1.1     sevan 	for (i = 0; i < RGE_TIMEOUT; i++) {
   2779   1.1     sevan 		DELAY(1);
   2780   1.1     sevan 		if (!(RGE_READ_4(sc, RGE_PHYOCP) & RGE_PHYOCP_BUSY))
   2781   1.1     sevan 			break;
   2782   1.1     sevan 	}
   2783   1.1     sevan }
   2784   1.1     sevan 
   2785   1.1     sevan uint16_t
   2786   1.1     sevan rge_read_phy_ocp(struct rge_softc *sc, uint16_t reg)
   2787   1.1     sevan {
   2788   1.1     sevan 	uint32_t val;
   2789   1.1     sevan 	int i;
   2790   1.1     sevan 
   2791   1.1     sevan 	val = (reg >> 1) << RGE_PHYOCP_ADDR_SHIFT;
   2792   1.1     sevan 	RGE_WRITE_4(sc, RGE_PHYOCP, val);
   2793   1.1     sevan 
   2794   1.1     sevan 	for (i = 0; i < RGE_TIMEOUT; i++) {
   2795   1.1     sevan 		DELAY(1);
   2796   1.1     sevan 		val = RGE_READ_4(sc, RGE_PHYOCP);
   2797   1.1     sevan 		if (val & RGE_PHYOCP_BUSY)
   2798   1.1     sevan 			break;
   2799   1.1     sevan 	}
   2800   1.1     sevan 
   2801   1.1     sevan 	return (val & RGE_PHYOCP_DATA_MASK);
   2802   1.1     sevan }
   2803   1.1     sevan 
   2804   1.1     sevan int
   2805   1.1     sevan rge_get_link_status(struct rge_softc *sc)
   2806   1.1     sevan {
   2807   1.1     sevan 	return ((RGE_READ_2(sc, RGE_PHYSTAT) & RGE_PHYSTAT_LINK) ? 1 : 0);
   2808   1.1     sevan }
   2809   1.1     sevan 
   2810   1.1     sevan void
   2811  1.30     skrll rge_txstart(void *arg)
   2812   1.1     sevan {
   2813   1.1     sevan 	struct rge_softc *sc = arg;
   2814   1.1     sevan 
   2815   1.1     sevan 	RGE_WRITE_2(sc, RGE_TXSTART, RGE_TXSTART_START);
   2816   1.1     sevan }
   2817   1.1     sevan 
   2818   1.1     sevan void
   2819   1.1     sevan rge_tick(void *arg)
   2820   1.1     sevan {
   2821   1.1     sevan 	struct rge_softc *sc = arg;
   2822   1.1     sevan 	int s;
   2823   1.1     sevan 
   2824   1.1     sevan 	s = splnet();
   2825   1.1     sevan 	rge_link_state(sc);
   2826   1.1     sevan 	splx(s);
   2827   1.1     sevan 
   2828  1.17  jakllsch 	callout_schedule(&sc->sc_timeout, hz);
   2829   1.1     sevan }
   2830   1.1     sevan 
   2831   1.1     sevan void
   2832   1.1     sevan rge_link_state(struct rge_softc *sc)
   2833   1.1     sevan {
   2834   1.2     sevan 	struct ifnet *ifp = &sc->sc_ec.ec_if;
   2835   1.1     sevan 	int link = LINK_STATE_DOWN;
   2836   1.1     sevan 
   2837   1.1     sevan 	if (rge_get_link_status(sc))
   2838   1.1     sevan 		link = LINK_STATE_UP;
   2839   1.1     sevan 
   2840  1.17  jakllsch 	if (ifp->if_link_state != link) { /* XXX not safe to access */
   2841  1.17  jakllsch 		if_link_state_change(ifp, link);
   2842   1.1     sevan 	}
   2843   1.1     sevan }
   2844