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