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