1*4bf8ce03SAdrian Chadd /*-
2*4bf8ce03SAdrian Chadd * SPDX-License-Identifier: BSD-2-Clause
3*4bf8ce03SAdrian Chadd *
4*4bf8ce03SAdrian Chadd * Copyright (c) 2019, 2020, 2023-2025 Kevin Lo <kevlo@openbsd.org>
5*4bf8ce03SAdrian Chadd * Copyright (c) 2025 Adrian Chadd <adrian@FreeBSD.org>
6*4bf8ce03SAdrian Chadd *
7*4bf8ce03SAdrian Chadd * Hardware programming portions from Realtek Semiconductor.
8*4bf8ce03SAdrian Chadd *
9*4bf8ce03SAdrian Chadd * Permission to use, copy, modify, and distribute this software for any
10*4bf8ce03SAdrian Chadd * purpose with or without fee is hereby granted, provided that the above
11*4bf8ce03SAdrian Chadd * copyright notice and this permission notice appear in all copies.
12*4bf8ce03SAdrian Chadd *
13*4bf8ce03SAdrian Chadd * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14*4bf8ce03SAdrian Chadd * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15*4bf8ce03SAdrian Chadd * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16*4bf8ce03SAdrian Chadd * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17*4bf8ce03SAdrian Chadd * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18*4bf8ce03SAdrian Chadd * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19*4bf8ce03SAdrian Chadd * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20*4bf8ce03SAdrian Chadd */
21*4bf8ce03SAdrian Chadd
22*4bf8ce03SAdrian Chadd /* $OpenBSD: if_rge.c,v 1.38 2025/09/19 00:41:14 kevlo Exp $ */
23*4bf8ce03SAdrian Chadd
24*4bf8ce03SAdrian Chadd #include <sys/param.h>
25*4bf8ce03SAdrian Chadd #include <sys/systm.h>
26*4bf8ce03SAdrian Chadd #include <sys/sockio.h>
27*4bf8ce03SAdrian Chadd #include <sys/mbuf.h>
28*4bf8ce03SAdrian Chadd #include <sys/malloc.h>
29*4bf8ce03SAdrian Chadd #include <sys/endian.h>
30*4bf8ce03SAdrian Chadd #include <sys/socket.h>
31*4bf8ce03SAdrian Chadd #include <net/if.h>
32*4bf8ce03SAdrian Chadd #include <net/if_media.h>
33*4bf8ce03SAdrian Chadd #include <sys/queue.h>
34*4bf8ce03SAdrian Chadd #include <sys/taskqueue.h>
35*4bf8ce03SAdrian Chadd #include <sys/bus.h>
36*4bf8ce03SAdrian Chadd #include <sys/module.h>
37*4bf8ce03SAdrian Chadd #include <sys/rman.h>
38*4bf8ce03SAdrian Chadd
39*4bf8ce03SAdrian Chadd #include <netinet/in.h>
40*4bf8ce03SAdrian Chadd #include <netinet/if_ether.h>
41*4bf8ce03SAdrian Chadd
42*4bf8ce03SAdrian Chadd #include <net/bpf.h>
43*4bf8ce03SAdrian Chadd #include <net/ethernet.h>
44*4bf8ce03SAdrian Chadd #include <net/if.h>
45*4bf8ce03SAdrian Chadd #include <net/if_var.h>
46*4bf8ce03SAdrian Chadd #include <net/if_arp.h>
47*4bf8ce03SAdrian Chadd #include <net/if_dl.h>
48*4bf8ce03SAdrian Chadd #include <net/if_media.h>
49*4bf8ce03SAdrian Chadd #include <net/if_types.h>
50*4bf8ce03SAdrian Chadd #include <net/if_vlan_var.h>
51*4bf8ce03SAdrian Chadd
52*4bf8ce03SAdrian Chadd #include <machine/bus.h>
53*4bf8ce03SAdrian Chadd #include <machine/resource.h>
54*4bf8ce03SAdrian Chadd
55*4bf8ce03SAdrian Chadd #include <dev/mii/mii.h>
56*4bf8ce03SAdrian Chadd
57*4bf8ce03SAdrian Chadd #include <dev/pci/pcivar.h>
58*4bf8ce03SAdrian Chadd #include <dev/pci/pcireg.h>
59*4bf8ce03SAdrian Chadd
60*4bf8ce03SAdrian Chadd #include "if_rge_vendor.h"
61*4bf8ce03SAdrian Chadd #include "if_rgereg.h"
62*4bf8ce03SAdrian Chadd #include "if_rgevar.h"
63*4bf8ce03SAdrian Chadd #include "if_rge_microcode.h"
64*4bf8ce03SAdrian Chadd #include "if_rge_debug.h"
65*4bf8ce03SAdrian Chadd
66*4bf8ce03SAdrian Chadd #include "if_rge_hw.h"
67*4bf8ce03SAdrian Chadd
68*4bf8ce03SAdrian Chadd static int rge_reset(struct rge_softc *sc);
69*4bf8ce03SAdrian Chadd static void rge_set_phy_power(struct rge_softc *sc, int on);
70*4bf8ce03SAdrian Chadd static uint64_t rge_mcu_get_bin_version(uint16_t entries);
71*4bf8ce03SAdrian Chadd static void rge_mcu_set_version(struct rge_softc *sc, uint64_t mcodever);
72*4bf8ce03SAdrian Chadd static void rge_ephy_config_mac_r25(struct rge_softc *sc);
73*4bf8ce03SAdrian Chadd static void rge_ephy_config_mac_r25b(struct rge_softc *sc);
74*4bf8ce03SAdrian Chadd static void rge_ephy_config_mac_r27(struct rge_softc *sc);
75*4bf8ce03SAdrian Chadd static void rge_phy_config_mac_r27(struct rge_softc *sc);
76*4bf8ce03SAdrian Chadd static void rge_phy_config_mac_r26(struct rge_softc *sc);
77*4bf8ce03SAdrian Chadd static void rge_phy_config_mac_r25(struct rge_softc *sc);
78*4bf8ce03SAdrian Chadd static void rge_phy_config_mac_r25b(struct rge_softc *sc);
79*4bf8ce03SAdrian Chadd static void rge_phy_config_mac_r25d(struct rge_softc *sc);
80*4bf8ce03SAdrian Chadd static void rge_phy_config_mcu(struct rge_softc *sc, uint16_t rcodever);
81*4bf8ce03SAdrian Chadd static void rge_hw_init(struct rge_softc *sc);
82*4bf8ce03SAdrian Chadd static void rge_disable_phy_ocp_pwrsave(struct rge_softc *sc);
83*4bf8ce03SAdrian Chadd static void rge_patch_phy_mcu(struct rge_softc *sc, int set);
84*4bf8ce03SAdrian Chadd static void rge_disable_hw_im(struct rge_softc *sc);
85*4bf8ce03SAdrian Chadd static void rge_disable_sim_im(struct rge_softc *sc);
86*4bf8ce03SAdrian Chadd static void rge_setup_sim_im(struct rge_softc *sc);
87*4bf8ce03SAdrian Chadd static void rge_switch_mcu_ram_page(struct rge_softc *sc, int page);
88*4bf8ce03SAdrian Chadd static int rge_exit_oob(struct rge_softc *sc);
89*4bf8ce03SAdrian Chadd static void rge_write_ephy(struct rge_softc *sc, uint16_t reg, uint16_t val);
90*4bf8ce03SAdrian Chadd static uint16_t rge_read_ephy(struct rge_softc *sc, uint16_t reg);
91*4bf8ce03SAdrian Chadd static uint16_t rge_check_ephy_ext_add(struct rge_softc *sc, uint16_t reg);
92*4bf8ce03SAdrian Chadd static void rge_r27_write_ephy(struct rge_softc *sc, uint16_t reg, uint16_t val);
93*4bf8ce03SAdrian Chadd
94*4bf8ce03SAdrian Chadd static int
rge_reset(struct rge_softc * sc)95*4bf8ce03SAdrian Chadd rge_reset(struct rge_softc *sc)
96*4bf8ce03SAdrian Chadd {
97*4bf8ce03SAdrian Chadd int i;
98*4bf8ce03SAdrian Chadd
99*4bf8ce03SAdrian Chadd RGE_CLRBIT_4(sc, RGE_RXCFG, RGE_RXCFG_ALLPHYS | RGE_RXCFG_INDIV |
100*4bf8ce03SAdrian Chadd RGE_RXCFG_MULTI | RGE_RXCFG_BROAD | RGE_RXCFG_RUNT |
101*4bf8ce03SAdrian Chadd RGE_RXCFG_ERRPKT);
102*4bf8ce03SAdrian Chadd
103*4bf8ce03SAdrian Chadd /* Enable RXDV gate. */
104*4bf8ce03SAdrian Chadd RGE_SETBIT_1(sc, RGE_PPSW, 0x08);
105*4bf8ce03SAdrian Chadd
106*4bf8ce03SAdrian Chadd RGE_SETBIT_1(sc, RGE_CMD, RGE_CMD_STOPREQ);
107*4bf8ce03SAdrian Chadd if (sc->rge_type == MAC_R25) {
108*4bf8ce03SAdrian Chadd for (i = 0; i < 20; i++) {
109*4bf8ce03SAdrian Chadd DELAY(10);
110*4bf8ce03SAdrian Chadd if (!(RGE_READ_1(sc, RGE_CMD) & RGE_CMD_STOPREQ))
111*4bf8ce03SAdrian Chadd break;
112*4bf8ce03SAdrian Chadd }
113*4bf8ce03SAdrian Chadd if (i == 20) {
114*4bf8ce03SAdrian Chadd RGE_PRINT_ERROR(sc, "failed to stop all requests\n");
115*4bf8ce03SAdrian Chadd return ETIMEDOUT;
116*4bf8ce03SAdrian Chadd }
117*4bf8ce03SAdrian Chadd } else
118*4bf8ce03SAdrian Chadd DELAY(200);
119*4bf8ce03SAdrian Chadd
120*4bf8ce03SAdrian Chadd for (i = 0; i < 3000; i++) {
121*4bf8ce03SAdrian Chadd DELAY(50);
122*4bf8ce03SAdrian Chadd if ((RGE_READ_1(sc, RGE_MCUCMD) & (RGE_MCUCMD_RXFIFO_EMPTY |
123*4bf8ce03SAdrian Chadd RGE_MCUCMD_TXFIFO_EMPTY)) == (RGE_MCUCMD_RXFIFO_EMPTY |
124*4bf8ce03SAdrian Chadd RGE_MCUCMD_TXFIFO_EMPTY))
125*4bf8ce03SAdrian Chadd break;
126*4bf8ce03SAdrian Chadd }
127*4bf8ce03SAdrian Chadd if (sc->rge_type != MAC_R25) {
128*4bf8ce03SAdrian Chadd for (i = 0; i < 3000; i++) {
129*4bf8ce03SAdrian Chadd DELAY(50);
130*4bf8ce03SAdrian Chadd if ((RGE_READ_2(sc, RGE_IM) & 0x0103) == 0x0103)
131*4bf8ce03SAdrian Chadd break;
132*4bf8ce03SAdrian Chadd }
133*4bf8ce03SAdrian Chadd }
134*4bf8ce03SAdrian Chadd
135*4bf8ce03SAdrian Chadd RGE_WRITE_1(sc, RGE_CMD,
136*4bf8ce03SAdrian Chadd RGE_READ_1(sc, RGE_CMD) & (RGE_CMD_TXENB | RGE_CMD_RXENB));
137*4bf8ce03SAdrian Chadd
138*4bf8ce03SAdrian Chadd /* Soft reset. */
139*4bf8ce03SAdrian Chadd RGE_WRITE_1(sc, RGE_CMD, RGE_CMD_RESET);
140*4bf8ce03SAdrian Chadd
141*4bf8ce03SAdrian Chadd for (i = 0; i < RGE_TIMEOUT; i++) {
142*4bf8ce03SAdrian Chadd DELAY(100);
143*4bf8ce03SAdrian Chadd if (!(RGE_READ_1(sc, RGE_CMD) & RGE_CMD_RESET))
144*4bf8ce03SAdrian Chadd break;
145*4bf8ce03SAdrian Chadd }
146*4bf8ce03SAdrian Chadd if (i == RGE_TIMEOUT) {
147*4bf8ce03SAdrian Chadd RGE_PRINT_ERROR(sc, "reset never completed!\n");
148*4bf8ce03SAdrian Chadd return ETIMEDOUT;
149*4bf8ce03SAdrian Chadd }
150*4bf8ce03SAdrian Chadd
151*4bf8ce03SAdrian Chadd return 0;
152*4bf8ce03SAdrian Chadd }
153*4bf8ce03SAdrian Chadd
154*4bf8ce03SAdrian Chadd /**
155*4bf8ce03SAdrian Chadd * @brief Do initial chip power-on and setup.
156*4bf8ce03SAdrian Chadd *
157*4bf8ce03SAdrian Chadd * Must be called with the driver lock held.
158*4bf8ce03SAdrian Chadd */
159*4bf8ce03SAdrian Chadd int
rge_chipinit(struct rge_softc * sc)160*4bf8ce03SAdrian Chadd rge_chipinit(struct rge_softc *sc)
161*4bf8ce03SAdrian Chadd {
162*4bf8ce03SAdrian Chadd int error;
163*4bf8ce03SAdrian Chadd
164*4bf8ce03SAdrian Chadd RGE_ASSERT_LOCKED(sc);
165*4bf8ce03SAdrian Chadd
166*4bf8ce03SAdrian Chadd if ((error = rge_exit_oob(sc)) != 0)
167*4bf8ce03SAdrian Chadd return error;
168*4bf8ce03SAdrian Chadd rge_set_phy_power(sc, 1);
169*4bf8ce03SAdrian Chadd rge_hw_init(sc);
170*4bf8ce03SAdrian Chadd rge_hw_reset(sc);
171*4bf8ce03SAdrian Chadd
172*4bf8ce03SAdrian Chadd return 0;
173*4bf8ce03SAdrian Chadd }
174*4bf8ce03SAdrian Chadd
175*4bf8ce03SAdrian Chadd static void
rge_set_phy_power(struct rge_softc * sc,int on)176*4bf8ce03SAdrian Chadd rge_set_phy_power(struct rge_softc *sc, int on)
177*4bf8ce03SAdrian Chadd {
178*4bf8ce03SAdrian Chadd int i;
179*4bf8ce03SAdrian Chadd
180*4bf8ce03SAdrian Chadd if (on) {
181*4bf8ce03SAdrian Chadd RGE_SETBIT_1(sc, RGE_PMCH, 0xc0);
182*4bf8ce03SAdrian Chadd
183*4bf8ce03SAdrian Chadd rge_write_phy(sc, 0, MII_BMCR, BMCR_AUTOEN);
184*4bf8ce03SAdrian Chadd
185*4bf8ce03SAdrian Chadd for (i = 0; i < RGE_TIMEOUT; i++) {
186*4bf8ce03SAdrian Chadd if ((rge_read_phy_ocp(sc, 0xa420) & 0x0007) == 3)
187*4bf8ce03SAdrian Chadd break;
188*4bf8ce03SAdrian Chadd DELAY(1000);
189*4bf8ce03SAdrian Chadd }
190*4bf8ce03SAdrian Chadd } else {
191*4bf8ce03SAdrian Chadd rge_write_phy(sc, 0, MII_BMCR, BMCR_AUTOEN | BMCR_PDOWN);
192*4bf8ce03SAdrian Chadd RGE_CLRBIT_1(sc, RGE_PMCH, 0x80);
193*4bf8ce03SAdrian Chadd RGE_CLRBIT_1(sc, RGE_PPSW, 0x40);
194*4bf8ce03SAdrian Chadd }
195*4bf8ce03SAdrian Chadd }
196*4bf8ce03SAdrian Chadd
197*4bf8ce03SAdrian Chadd void
rge_mac_config_mcu(struct rge_softc * sc,enum rge_mac_type type)198*4bf8ce03SAdrian Chadd rge_mac_config_mcu(struct rge_softc *sc, enum rge_mac_type type)
199*4bf8ce03SAdrian Chadd {
200*4bf8ce03SAdrian Chadd uint64_t mcodever;
201*4bf8ce03SAdrian Chadd uint16_t reg;
202*4bf8ce03SAdrian Chadd int i, npages;
203*4bf8ce03SAdrian Chadd
204*4bf8ce03SAdrian Chadd if (type == MAC_R25) {
205*4bf8ce03SAdrian Chadd for (npages = 0; npages < 3; npages++) {
206*4bf8ce03SAdrian Chadd rge_switch_mcu_ram_page(sc, npages);
207*4bf8ce03SAdrian Chadd for (i = 0; i < nitems(rtl8125_mac_bps); i++) {
208*4bf8ce03SAdrian Chadd if (npages == 0)
209*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc,
210*4bf8ce03SAdrian Chadd rtl8125_mac_bps[i].reg,
211*4bf8ce03SAdrian Chadd rtl8125_mac_bps[i].val);
212*4bf8ce03SAdrian Chadd else if (npages == 1)
213*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc,
214*4bf8ce03SAdrian Chadd rtl8125_mac_bps[i].reg, 0);
215*4bf8ce03SAdrian Chadd else {
216*4bf8ce03SAdrian Chadd if (rtl8125_mac_bps[i].reg < 0xf9f8)
217*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc,
218*4bf8ce03SAdrian Chadd rtl8125_mac_bps[i].reg, 0);
219*4bf8ce03SAdrian Chadd }
220*4bf8ce03SAdrian Chadd }
221*4bf8ce03SAdrian Chadd if (npages == 2) {
222*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xf9f8, 0x6486);
223*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xf9fa, 0x0b15);
224*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xf9fc, 0x090e);
225*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xf9fe, 0x1139);
226*4bf8ce03SAdrian Chadd }
227*4bf8ce03SAdrian Chadd }
228*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xfc26, 0x8000);
229*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xfc2a, 0x0540);
230*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xfc2e, 0x0a06);
231*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xfc30, 0x0eb8);
232*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xfc32, 0x3a5c);
233*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xfc34, 0x10a8);
234*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xfc40, 0x0d54);
235*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xfc42, 0x0e24);
236*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xfc48, 0x307a);
237*4bf8ce03SAdrian Chadd } else if (type == MAC_R25B) {
238*4bf8ce03SAdrian Chadd rge_switch_mcu_ram_page(sc, 0);
239*4bf8ce03SAdrian Chadd for (i = 0; i < nitems(rtl8125b_mac_bps); i++) {
240*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, rtl8125b_mac_bps[i].reg,
241*4bf8ce03SAdrian Chadd rtl8125b_mac_bps[i].val);
242*4bf8ce03SAdrian Chadd }
243*4bf8ce03SAdrian Chadd } else if (type == MAC_R25D) {
244*4bf8ce03SAdrian Chadd for (npages = 0; npages < 3; npages++) {
245*4bf8ce03SAdrian Chadd rge_switch_mcu_ram_page(sc, npages);
246*4bf8ce03SAdrian Chadd
247*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xf800,
248*4bf8ce03SAdrian Chadd (npages == 0) ? 0xe002 : 0);
249*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xf802,
250*4bf8ce03SAdrian Chadd (npages == 0) ? 0xe006 : 0);
251*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xf804,
252*4bf8ce03SAdrian Chadd (npages == 0) ? 0x4166 : 0);
253*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xf806,
254*4bf8ce03SAdrian Chadd (npages == 0) ? 0x9cf6 : 0);
255*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xf808,
256*4bf8ce03SAdrian Chadd (npages == 0) ? 0xc002 : 0);
257*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xf80a,
258*4bf8ce03SAdrian Chadd (npages == 0) ? 0xb800 : 0);
259*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xf80c,
260*4bf8ce03SAdrian Chadd (npages == 0) ? 0x14a4 : 0);
261*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xf80e,
262*4bf8ce03SAdrian Chadd (npages == 0) ? 0xc102 : 0);
263*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xf810,
264*4bf8ce03SAdrian Chadd (npages == 0) ? 0xb900 : 0);
265*4bf8ce03SAdrian Chadd
266*4bf8ce03SAdrian Chadd for (reg = 0xf812; reg <= 0xf9f6; reg += 2)
267*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, reg, 0);
268*4bf8ce03SAdrian Chadd
269*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xf9f8,
270*4bf8ce03SAdrian Chadd (npages == 2) ? 0x6938 : 0);
271*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xf9fa,
272*4bf8ce03SAdrian Chadd (npages == 2) ? 0x0a18 : 0);
273*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xf9fc,
274*4bf8ce03SAdrian Chadd (npages == 2) ? 0x0217 : 0);
275*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xf9fe,
276*4bf8ce03SAdrian Chadd (npages == 2) ? 0x0d2a : 0);
277*4bf8ce03SAdrian Chadd }
278*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xfc26, 0x8000);
279*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xfc28, 0x14a2);
280*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xfc48, 0x0001);
281*4bf8ce03SAdrian Chadd } else if (type == MAC_R27) {
282*4bf8ce03SAdrian Chadd mcodever = rge_mcu_get_bin_version(nitems(rtl8127_mac_bps));
283*4bf8ce03SAdrian Chadd if (sc->rge_mcodever != mcodever) {
284*4bf8ce03SAdrian Chadd /* Switch to page 0. */
285*4bf8ce03SAdrian Chadd rge_switch_mcu_ram_page(sc, 0);
286*4bf8ce03SAdrian Chadd for (i = 0; i < 256; i++)
287*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, rtl8127_mac_bps[i].reg,
288*4bf8ce03SAdrian Chadd rtl8127_mac_bps[i].val);
289*4bf8ce03SAdrian Chadd /* Switch to page 1. */
290*4bf8ce03SAdrian Chadd rge_switch_mcu_ram_page(sc, 1);
291*4bf8ce03SAdrian Chadd for (; i < nitems(rtl8127_mac_bps); i++)
292*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, rtl8127_mac_bps[i].reg,
293*4bf8ce03SAdrian Chadd rtl8127_mac_bps[i].val);
294*4bf8ce03SAdrian Chadd }
295*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xfc26, 0x8000);
296*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xfc28, 0x1520);
297*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xfc2a, 0x41e0);
298*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xfc2c, 0x508c);
299*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xfc2e, 0x50f6);
300*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xfc30, 0x34fa);
301*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xfc32, 0x0166);
302*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xfc34, 0x1a6a);
303*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xfc36, 0x1a2c);
304*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xfc48, 0x00ff);
305*4bf8ce03SAdrian Chadd
306*4bf8ce03SAdrian Chadd /* Write microcode version. */
307*4bf8ce03SAdrian Chadd rge_mcu_set_version(sc, mcodever);
308*4bf8ce03SAdrian Chadd }
309*4bf8ce03SAdrian Chadd }
310*4bf8ce03SAdrian Chadd
311*4bf8ce03SAdrian Chadd static uint64_t
rge_mcu_get_bin_version(uint16_t entries)312*4bf8ce03SAdrian Chadd rge_mcu_get_bin_version(uint16_t entries)
313*4bf8ce03SAdrian Chadd {
314*4bf8ce03SAdrian Chadd uint64_t binver = 0;
315*4bf8ce03SAdrian Chadd int i;
316*4bf8ce03SAdrian Chadd
317*4bf8ce03SAdrian Chadd for (i = 0; i < 4; i++) {
318*4bf8ce03SAdrian Chadd binver <<= 16;
319*4bf8ce03SAdrian Chadd binver |= rtl8127_mac_bps[entries - 4 + i].val;
320*4bf8ce03SAdrian Chadd }
321*4bf8ce03SAdrian Chadd
322*4bf8ce03SAdrian Chadd return binver;
323*4bf8ce03SAdrian Chadd }
324*4bf8ce03SAdrian Chadd
325*4bf8ce03SAdrian Chadd static void
rge_mcu_set_version(struct rge_softc * sc,uint64_t mcodever)326*4bf8ce03SAdrian Chadd rge_mcu_set_version(struct rge_softc *sc, uint64_t mcodever)
327*4bf8ce03SAdrian Chadd {
328*4bf8ce03SAdrian Chadd int i;
329*4bf8ce03SAdrian Chadd
330*4bf8ce03SAdrian Chadd /* Switch to page 2. */
331*4bf8ce03SAdrian Chadd rge_switch_mcu_ram_page(sc, 2);
332*4bf8ce03SAdrian Chadd
333*4bf8ce03SAdrian Chadd for (i = 0; i < 8; i += 2) {
334*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xf9f8 + 6 - i, (uint16_t)mcodever);
335*4bf8ce03SAdrian Chadd mcodever >>= 16;
336*4bf8ce03SAdrian Chadd }
337*4bf8ce03SAdrian Chadd
338*4bf8ce03SAdrian Chadd /* Switch back to page 0. */
339*4bf8ce03SAdrian Chadd rge_switch_mcu_ram_page(sc, 0);
340*4bf8ce03SAdrian Chadd }
341*4bf8ce03SAdrian Chadd
342*4bf8ce03SAdrian Chadd void
rge_ephy_config(struct rge_softc * sc)343*4bf8ce03SAdrian Chadd rge_ephy_config(struct rge_softc *sc)
344*4bf8ce03SAdrian Chadd {
345*4bf8ce03SAdrian Chadd switch (sc->rge_type) {
346*4bf8ce03SAdrian Chadd case MAC_R25:
347*4bf8ce03SAdrian Chadd rge_ephy_config_mac_r25(sc);
348*4bf8ce03SAdrian Chadd break;
349*4bf8ce03SAdrian Chadd case MAC_R25B:
350*4bf8ce03SAdrian Chadd rge_ephy_config_mac_r25b(sc);
351*4bf8ce03SAdrian Chadd break;
352*4bf8ce03SAdrian Chadd case MAC_R27:
353*4bf8ce03SAdrian Chadd rge_ephy_config_mac_r27(sc);
354*4bf8ce03SAdrian Chadd break;
355*4bf8ce03SAdrian Chadd default:
356*4bf8ce03SAdrian Chadd break; /* Nothing to do. */
357*4bf8ce03SAdrian Chadd }
358*4bf8ce03SAdrian Chadd }
359*4bf8ce03SAdrian Chadd
360*4bf8ce03SAdrian Chadd static void
rge_ephy_config_mac_r25(struct rge_softc * sc)361*4bf8ce03SAdrian Chadd rge_ephy_config_mac_r25(struct rge_softc *sc)
362*4bf8ce03SAdrian Chadd {
363*4bf8ce03SAdrian Chadd uint16_t val;
364*4bf8ce03SAdrian Chadd int i;
365*4bf8ce03SAdrian Chadd
366*4bf8ce03SAdrian Chadd for (i = 0; i < nitems(mac_r25_ephy); i++)
367*4bf8ce03SAdrian Chadd rge_write_ephy(sc, mac_r25_ephy[i].reg, mac_r25_ephy[i].val);
368*4bf8ce03SAdrian Chadd
369*4bf8ce03SAdrian Chadd val = rge_read_ephy(sc, 0x002a) & ~0x7000;
370*4bf8ce03SAdrian Chadd rge_write_ephy(sc, 0x002a, val | 0x3000);
371*4bf8ce03SAdrian Chadd RGE_EPHY_CLRBIT(sc, 0x0019, 0x0040);
372*4bf8ce03SAdrian Chadd RGE_EPHY_SETBIT(sc, 0x001b, 0x0e00);
373*4bf8ce03SAdrian Chadd RGE_EPHY_CLRBIT(sc, 0x001b, 0x7000);
374*4bf8ce03SAdrian Chadd rge_write_ephy(sc, 0x0002, 0x6042);
375*4bf8ce03SAdrian Chadd rge_write_ephy(sc, 0x0006, 0x0014);
376*4bf8ce03SAdrian Chadd val = rge_read_ephy(sc, 0x006a) & ~0x7000;
377*4bf8ce03SAdrian Chadd rge_write_ephy(sc, 0x006a, val | 0x3000);
378*4bf8ce03SAdrian Chadd RGE_EPHY_CLRBIT(sc, 0x0059, 0x0040);
379*4bf8ce03SAdrian Chadd RGE_EPHY_SETBIT(sc, 0x005b, 0x0e00);
380*4bf8ce03SAdrian Chadd RGE_EPHY_CLRBIT(sc, 0x005b, 0x7000);
381*4bf8ce03SAdrian Chadd rge_write_ephy(sc, 0x0042, 0x6042);
382*4bf8ce03SAdrian Chadd rge_write_ephy(sc, 0x0046, 0x0014);
383*4bf8ce03SAdrian Chadd }
384*4bf8ce03SAdrian Chadd
385*4bf8ce03SAdrian Chadd static void
rge_ephy_config_mac_r25b(struct rge_softc * sc)386*4bf8ce03SAdrian Chadd rge_ephy_config_mac_r25b(struct rge_softc *sc)
387*4bf8ce03SAdrian Chadd {
388*4bf8ce03SAdrian Chadd int i;
389*4bf8ce03SAdrian Chadd
390*4bf8ce03SAdrian Chadd for (i = 0; i < nitems(mac_r25b_ephy); i++)
391*4bf8ce03SAdrian Chadd rge_write_ephy(sc, mac_r25b_ephy[i].reg, mac_r25b_ephy[i].val);
392*4bf8ce03SAdrian Chadd }
393*4bf8ce03SAdrian Chadd
394*4bf8ce03SAdrian Chadd static void
rge_ephy_config_mac_r27(struct rge_softc * sc)395*4bf8ce03SAdrian Chadd rge_ephy_config_mac_r27(struct rge_softc *sc)
396*4bf8ce03SAdrian Chadd {
397*4bf8ce03SAdrian Chadd int i;
398*4bf8ce03SAdrian Chadd
399*4bf8ce03SAdrian Chadd for (i = 0; i < nitems(mac_r27_ephy); i++)
400*4bf8ce03SAdrian Chadd rge_r27_write_ephy(sc, mac_r27_ephy[i].reg,
401*4bf8ce03SAdrian Chadd mac_r27_ephy[i].val);
402*4bf8ce03SAdrian Chadd
403*4bf8ce03SAdrian Chadd /* Clear extended address. */
404*4bf8ce03SAdrian Chadd rge_write_ephy(sc, RGE_EPHYAR_EXT_ADDR, 0);
405*4bf8ce03SAdrian Chadd }
406*4bf8ce03SAdrian Chadd
407*4bf8ce03SAdrian Chadd int
rge_phy_config(struct rge_softc * sc)408*4bf8ce03SAdrian Chadd rge_phy_config(struct rge_softc *sc)
409*4bf8ce03SAdrian Chadd {
410*4bf8ce03SAdrian Chadd uint16_t val = 0;
411*4bf8ce03SAdrian Chadd int i;
412*4bf8ce03SAdrian Chadd
413*4bf8ce03SAdrian Chadd rge_ephy_config(sc);
414*4bf8ce03SAdrian Chadd
415*4bf8ce03SAdrian Chadd /* PHY reset. */
416*4bf8ce03SAdrian Chadd rge_write_phy(sc, 0, MII_ANAR,
417*4bf8ce03SAdrian Chadd rge_read_phy(sc, 0, MII_ANAR) &
418*4bf8ce03SAdrian Chadd ~(ANAR_TX_FD | ANAR_TX | ANAR_10_FD | ANAR_10));
419*4bf8ce03SAdrian Chadd rge_write_phy(sc, 0, MII_100T2CR,
420*4bf8ce03SAdrian Chadd rge_read_phy(sc, 0, MII_100T2CR) &
421*4bf8ce03SAdrian Chadd ~(GTCR_ADV_1000TFDX | GTCR_ADV_1000THDX));
422*4bf8ce03SAdrian Chadd switch (sc->rge_type) {
423*4bf8ce03SAdrian Chadd case MAC_R27:
424*4bf8ce03SAdrian Chadd val |= RGE_ADV_10000TFDX;
425*4bf8ce03SAdrian Chadd /* fallthrough */
426*4bf8ce03SAdrian Chadd case MAC_R26:
427*4bf8ce03SAdrian Chadd val |= RGE_ADV_5000TFDX;
428*4bf8ce03SAdrian Chadd /* fallthrough */
429*4bf8ce03SAdrian Chadd default:
430*4bf8ce03SAdrian Chadd val |= RGE_ADV_2500TFDX;
431*4bf8ce03SAdrian Chadd break;
432*4bf8ce03SAdrian Chadd }
433*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xa5d4, val);
434*4bf8ce03SAdrian Chadd rge_write_phy(sc, 0, MII_BMCR, BMCR_RESET | BMCR_AUTOEN |
435*4bf8ce03SAdrian Chadd BMCR_STARTNEG);
436*4bf8ce03SAdrian Chadd for (i = 0; i < 2500; i++) {
437*4bf8ce03SAdrian Chadd if (!(rge_read_phy(sc, 0, MII_BMCR) & BMCR_RESET))
438*4bf8ce03SAdrian Chadd break;
439*4bf8ce03SAdrian Chadd DELAY(1000);
440*4bf8ce03SAdrian Chadd }
441*4bf8ce03SAdrian Chadd if (i == 2500) {
442*4bf8ce03SAdrian Chadd RGE_PRINT_ERROR(sc, "PHY reset failed\n");
443*4bf8ce03SAdrian Chadd return (ETIMEDOUT);
444*4bf8ce03SAdrian Chadd }
445*4bf8ce03SAdrian Chadd
446*4bf8ce03SAdrian Chadd /* Read ram code version. */
447*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x801e);
448*4bf8ce03SAdrian Chadd sc->rge_rcodever = rge_read_phy_ocp(sc, 0xa438);
449*4bf8ce03SAdrian Chadd
450*4bf8ce03SAdrian Chadd switch (sc->rge_type) {
451*4bf8ce03SAdrian Chadd case MAC_R25:
452*4bf8ce03SAdrian Chadd rge_phy_config_mac_r25(sc);
453*4bf8ce03SAdrian Chadd break;
454*4bf8ce03SAdrian Chadd case MAC_R25B:
455*4bf8ce03SAdrian Chadd rge_phy_config_mac_r25b(sc);
456*4bf8ce03SAdrian Chadd break;
457*4bf8ce03SAdrian Chadd case MAC_R25D:
458*4bf8ce03SAdrian Chadd rge_phy_config_mac_r25d(sc);
459*4bf8ce03SAdrian Chadd break;
460*4bf8ce03SAdrian Chadd case MAC_R26:
461*4bf8ce03SAdrian Chadd rge_phy_config_mac_r26(sc);
462*4bf8ce03SAdrian Chadd break;
463*4bf8ce03SAdrian Chadd case MAC_R27:
464*4bf8ce03SAdrian Chadd rge_phy_config_mac_r27(sc);
465*4bf8ce03SAdrian Chadd break;
466*4bf8ce03SAdrian Chadd default:
467*4bf8ce03SAdrian Chadd break; /* Can't happen. */
468*4bf8ce03SAdrian Chadd }
469*4bf8ce03SAdrian Chadd
470*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xa5b4, 0x8000);
471*4bf8ce03SAdrian Chadd
472*4bf8ce03SAdrian Chadd /* Disable EEE. */
473*4bf8ce03SAdrian Chadd RGE_MAC_CLRBIT(sc, 0xe040, 0x0003);
474*4bf8ce03SAdrian Chadd if (sc->rge_type == MAC_R25) {
475*4bf8ce03SAdrian Chadd RGE_MAC_CLRBIT(sc, 0xeb62, 0x0006);
476*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xa432, 0x0010);
477*4bf8ce03SAdrian Chadd } else if (sc->rge_type == MAC_R25B || sc->rge_type == MAC_R25D)
478*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xa432, 0x0010);
479*4bf8ce03SAdrian Chadd
480*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xa5d0, (sc->rge_type == MAC_R27) ? 0x000e : 0x0006);
481*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xa6d4, 0x0001);
482*4bf8ce03SAdrian Chadd if (sc->rge_type == MAC_R26 || sc->rge_type == MAC_R27)
483*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xa6d4, 0x0002);
484*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xa6d8, 0x0010);
485*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xa428, 0x0080);
486*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xa4a2, 0x0200);
487*4bf8ce03SAdrian Chadd
488*4bf8ce03SAdrian Chadd /* Disable advanced EEE. */
489*4bf8ce03SAdrian Chadd RGE_MAC_CLRBIT(sc, 0xe052, 0x0001);
490*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xa442, 0x3000);
491*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xa430, 0x8000);
492*4bf8ce03SAdrian Chadd
493*4bf8ce03SAdrian Chadd return (0);
494*4bf8ce03SAdrian Chadd }
495*4bf8ce03SAdrian Chadd
496*4bf8ce03SAdrian Chadd static void
rge_phy_config_mac_r27(struct rge_softc * sc)497*4bf8ce03SAdrian Chadd rge_phy_config_mac_r27(struct rge_softc *sc)
498*4bf8ce03SAdrian Chadd {
499*4bf8ce03SAdrian Chadd uint16_t val;
500*4bf8ce03SAdrian Chadd int i;
501*4bf8ce03SAdrian Chadd static const uint16_t mac_cfg_value[] =
502*4bf8ce03SAdrian Chadd { 0x815a, 0x0150, 0x81f4, 0x0150, 0x828e, 0x0150, 0x81b1, 0x0000,
503*4bf8ce03SAdrian Chadd 0x824b, 0x0000, 0x82e5, 0x0000 };
504*4bf8ce03SAdrian Chadd
505*4bf8ce03SAdrian Chadd static const uint16_t mac_cfg2_value[] =
506*4bf8ce03SAdrian Chadd { 0x88d7, 0x01a0, 0x88d9, 0x01a0, 0x8ffa, 0x002a, 0x8fee, 0xffdf,
507*4bf8ce03SAdrian Chadd 0x8ff0, 0xffff, 0x8ff2, 0x0a4a, 0x8ff4, 0xaa5a, 0x8ff6, 0x0a4a,
508*4bf8ce03SAdrian Chadd 0x8ff8, 0xaa5a };
509*4bf8ce03SAdrian Chadd
510*4bf8ce03SAdrian Chadd static const uint16_t mac_cfg_a438_value[] =
511*4bf8ce03SAdrian Chadd { 0x003b, 0x0086, 0x00b7, 0x00db, 0x00fe, 0x00fe, 0x00fe, 0x00fe,
512*4bf8ce03SAdrian Chadd 0x00c3, 0x0078, 0x0047, 0x0023 };
513*4bf8ce03SAdrian Chadd
514*4bf8ce03SAdrian Chadd rge_phy_config_mcu(sc, RGE_MAC_R27_RCODE_VER);
515*4bf8ce03SAdrian Chadd
516*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa4d2, 0x0000);
517*4bf8ce03SAdrian Chadd rge_read_phy_ocp(sc, 0xa4d4);
518*4bf8ce03SAdrian Chadd
519*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xa442, 0x0800);
520*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8415);
521*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
522*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x9300);
523*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x81a3);
524*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
525*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x0f00);
526*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x81ae);
527*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
528*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x0f00);
529*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x81b9);
530*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
531*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0xb900);
532*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x83b0);
533*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc,0xb87e, 0x0e00);
534*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x83c5);
535*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xb87e, 0x0e00);
536*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x83da);
537*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xb87e, 0x0e00);
538*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x83ef);
539*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xb87e, 0x0e00);
540*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xbf38) & ~0x01f0;
541*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xbf38, val | 0x0160);
542*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xbf3a) & ~0x001f;
543*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xbf3a, val | 0x0014);
544*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xbf28, 0x6000);
545*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xbf2c, 0xc000);
546*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xbf28) & ~0x1fff;
547*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xbf28, val | 0x0187);
548*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xbf2a) & ~0x003f;
549*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xbf2a, val | 0x0003);
550*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8173);
551*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x8620);
552*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8175);
553*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x8671);
554*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x817c);
555*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xa438, 0x2000);
556*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8187);
557*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xa438, 0x2000);
558*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xA436, 0x8192);
559*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xA438, 0x2000);
560*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xA436, 0x819D);
561*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xA438, 0x2000);
562*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xA436, 0x81A8);
563*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xA438, 0x2000);
564*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xA436, 0x81B3);
565*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xA438, 0x2000);
566*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xA436, 0x81BE);
567*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xA438, 0x2000);
568*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x817d);
569*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
570*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0xa600);
571*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8188);
572*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
573*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0xa600);
574*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8193);
575*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
576*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0xa600);
577*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x819e);
578*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
579*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0xa600);
580*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x81a9);
581*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
582*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x1400);
583*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x81b4);
584*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
585*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x1400);
586*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x81bf);
587*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
588*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0xa600);
589*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xaeaa, 0x0028);
590*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x84f0);
591*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x201c);
592*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x84f2);
593*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x3117);
594*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xaec6, 0x0000);
595*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xae20, 0xffff);
596*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xaece, 0xffff);
597*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xaed2, 0xffff);
598*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xaec8, 0x0000);
599*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xaed0, 0x0001);
600*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xadb8, 0x0150);
601*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8197);
602*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
603*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x5000);
604*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8231);
605*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
606*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x5000);
607*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x82cb);
608*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
609*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x5000);
610*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x82cd);
611*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
612*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x5700);
613*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8233);
614*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
615*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x5700);
616*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8199);
617*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
618*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x5700);
619*4bf8ce03SAdrian Chadd for (i = 0; i < nitems(mac_cfg_value); i+=2) {
620*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, mac_cfg_value[i]);
621*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, mac_cfg_value[i + 1]);
622*4bf8ce03SAdrian Chadd }
623*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x84f7);
624*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
625*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x2800);
626*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xaec2, 0x1000);
627*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x81b3);
628*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
629*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0xad00);
630*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x824d);
631*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
632*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0xad00);
633*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x82e7);
634*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
635*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0xad00);
636*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xae4e) & ~0x000f;
637*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xae4e, val | 0x0001);
638*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x82ce);
639*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xf000;
640*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x4000);
641*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x84ac);
642*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x0000);
643*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x84ae);
644*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x0000);
645*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x84b0);
646*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0xf818);
647*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x84b2);
648*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
649*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x6000);
650*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8ffc);
651*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x6008);
652*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8ffe);
653*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0xf450);
654*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8015);
655*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xb87e, 0x0200);
656*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8016);
657*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xb87e, 0x0800);
658*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8fe6);
659*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
660*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x0800);
661*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8fe4);
662*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x2114);
663*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8647);
664*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0xa7B1);
665*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8649);
666*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0xbbca);
667*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x864b);
668*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
669*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0xdc00);
670*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8154);
671*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xc000;
672*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x4000);
673*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8158);
674*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xb87e, 0xc000);
675*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x826c);
676*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0xffff);
677*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x826e);
678*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0xffff);
679*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8872);
680*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
681*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x0e00);
682*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8012);
683*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xa438, 0x0800);
684*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8012);
685*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xa438, 0x4000);
686*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xb576, 0x0001);
687*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x834a);
688*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
689*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x0700);
690*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8217);
691*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0x3f00;
692*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x2a00);
693*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x81b1);
694*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
695*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x0b00);
696*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8fed);
697*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
698*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x4e00);
699*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x88ac);
700*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
701*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x2300);
702*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xbf0c, 0x3800);
703*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x88de);
704*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xb87e, 0xFF00);
705*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x80B4);
706*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x5195);
707*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8370);
708*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x8671);
709*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8372);
710*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x86c8);
711*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8401);
712*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x86c8);
713*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8403);
714*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x86da);
715*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8406);
716*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0x1800;
717*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x1000);
718*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8408);
719*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0x1800;
720*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x1000);
721*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x840a);
722*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0x1800;
723*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x1000);
724*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x840c);
725*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0x1800;
726*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x1000);
727*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x840e);
728*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0x1800;
729*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x1000);
730*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8410);
731*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0x1800;
732*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x1000);
733*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8412);
734*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0x1800;
735*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x1000);
736*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8414);
737*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0x1800;
738*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x1000);
739*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8416);
740*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0x1800;
741*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x1000);
742*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x82bd);
743*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x1f40);
744*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xbfb4) & ~0x07ff;
745*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xbfb4, val | 0x0328);
746*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xbfb6, 0x3e14);
747*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x81c4);
748*4bf8ce03SAdrian Chadd for (i = 0; i < nitems(mac_cfg_a438_value); i++)
749*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, mac_cfg_a438_value[i]);
750*4bf8ce03SAdrian Chadd for (i = 0; i < nitems(mac_cfg2_value); i+=2) {
751*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, mac_cfg2_value[i]);
752*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, mac_cfg2_value[i + 1]);
753*4bf8ce03SAdrian Chadd }
754*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x88d5);
755*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
756*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x0200);
757*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x84bb);
758*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
759*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x0a00);
760*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x84c0);
761*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
762*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x1600);
763*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xa430, 0x0003);
764*4bf8ce03SAdrian Chadd }
765*4bf8ce03SAdrian Chadd
766*4bf8ce03SAdrian Chadd static void
rge_phy_config_mac_r26(struct rge_softc * sc)767*4bf8ce03SAdrian Chadd rge_phy_config_mac_r26(struct rge_softc *sc)
768*4bf8ce03SAdrian Chadd {
769*4bf8ce03SAdrian Chadd uint16_t val;
770*4bf8ce03SAdrian Chadd int i;
771*4bf8ce03SAdrian Chadd static const uint16_t mac_cfg2_a438_value[] =
772*4bf8ce03SAdrian Chadd { 0x0044, 0x00a8, 0x00d6, 0x00ec, 0x00f6, 0x00fc, 0x00fe,
773*4bf8ce03SAdrian Chadd 0x00fe, 0x00bc, 0x0058, 0x002a, 0x003f, 0x3f02, 0x023c,
774*4bf8ce03SAdrian Chadd 0x3b0a, 0x1c00, 0x0000, 0x0000, 0x0000, 0x0000 };
775*4bf8ce03SAdrian Chadd
776*4bf8ce03SAdrian Chadd static const uint16_t mac_cfg2_b87e_value[] =
777*4bf8ce03SAdrian Chadd { 0x03ed, 0x03ff, 0x0009, 0x03fe, 0x000b, 0x0021, 0x03f7,
778*4bf8ce03SAdrian Chadd 0x03b8, 0x03e0, 0x0049, 0x0049, 0x03e0, 0x03b8, 0x03f7,
779*4bf8ce03SAdrian Chadd 0x0021, 0x000b, 0x03fe, 0x0009, 0x03ff, 0x03ed, 0x000e,
780*4bf8ce03SAdrian Chadd 0x03fe, 0x03ed, 0x0006, 0x001a, 0x03f1, 0x03d8, 0x0023,
781*4bf8ce03SAdrian Chadd 0x0054, 0x0322, 0x00dd, 0x03ab, 0x03dc, 0x0027, 0x000e,
782*4bf8ce03SAdrian Chadd 0x03e5, 0x03f9, 0x0012, 0x0001, 0x03f1 };
783*4bf8ce03SAdrian Chadd
784*4bf8ce03SAdrian Chadd rge_phy_config_mcu(sc, RGE_MAC_R26_RCODE_VER);
785*4bf8ce03SAdrian Chadd
786*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xa442, 0x0800);
787*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x80bf);
788*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
789*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0xed00);
790*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x80cd);
791*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
792*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x1000);
793*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x80d1);
794*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
795*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0xc800);
796*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x80d4);
797*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
798*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0xc800);
799*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x80e1);
800*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x10cc);
801*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x80e5);
802*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x4f0c);
803*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8387);
804*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
805*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x4700);
806*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa80c) & ~0x00c0;
807*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa80c, val | 0x0080);
808*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xac90, 0x0010);
809*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xad2c, 0x8000);
810*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8321);
811*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
812*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x1100);
813*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xacf8, 0x000c);
814*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8183);
815*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
816*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x5900);
817*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xad94, 0x0020);
818*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xa654, 0x0800);
819*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xb648, 0x4000);
820*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x839e);
821*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
822*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x2f00);
823*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x83f2);
824*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
825*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x0800);
826*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xada0, 0x0002);
827*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x80f3);
828*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
829*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x9900);
830*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8126);
831*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
832*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0xc100);
833*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x893a);
834*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x8080);
835*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8647);
836*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
837*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0xe600);
838*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x862c);
839*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
840*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x1200);
841*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x864a);
842*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
843*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0xe600);
844*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x80a0);
845*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0xbcbc);
846*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x805e);
847*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0xbcbc);
848*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8056);
849*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x3077);
850*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8058);
851*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
852*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x5a00);
853*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8098);
854*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x3077);
855*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x809a);
856*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
857*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x5a00);
858*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8052);
859*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x3733);
860*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8094);
861*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x3733);
862*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x807f);
863*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x7c75);
864*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x803d);
865*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x7c75);
866*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8036);
867*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
868*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x3000);
869*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8078);
870*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
871*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x3000);
872*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8031);
873*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
874*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x3300);
875*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8073);
876*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
877*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x3300);
878*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xae06) & ~0xfc00;
879*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xae06, val | 0x7c00);
880*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x89D1);
881*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x0004);
882*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8fbd);
883*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
884*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x0a00);
885*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8fbe);
886*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x0d09);
887*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x89cd);
888*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x0f0f);
889*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x89cf);
890*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x0f0f);
891*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x83a4);
892*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x6600);
893*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x83a6);
894*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x6601);
895*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x83c0);
896*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x6600);
897*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x83c2);
898*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x6601);
899*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8414);
900*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x6600);
901*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8416);
902*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x6601);
903*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x83f8);
904*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x6600);
905*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x83fa);
906*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x6601);
907*4bf8ce03SAdrian Chadd
908*4bf8ce03SAdrian Chadd rge_patch_phy_mcu(sc, 1);
909*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xbd96) & ~0x1f00;
910*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xbd96, val | 0x1000);
911*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xbf1c) & ~0x0007;
912*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xbf1c, val | 0x0007);
913*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xbfbe, 0x8000);
914*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xbf40) & ~0x0380;
915*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xbf40, val | 0x0280);
916*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xbf90) & ~0x0080;
917*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xbf90, val | 0x0060);
918*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xbf90) & ~0x0010;
919*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xbf90, val | 0x000c);
920*4bf8ce03SAdrian Chadd rge_patch_phy_mcu(sc, 0);
921*4bf8ce03SAdrian Chadd
922*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x843b);
923*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
924*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x2000);
925*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x843d);
926*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
927*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x2000);
928*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xb516, 0x007f);
929*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xbf80, 0x0030);
930*4bf8ce03SAdrian Chadd
931*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8188);
932*4bf8ce03SAdrian Chadd for (i = 0; i < 11; i++)
933*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, mac_cfg2_a438_value[i]);
934*4bf8ce03SAdrian Chadd
935*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8015);
936*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
937*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x0800);
938*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8ffd);
939*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
940*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0);
941*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8fff);
942*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
943*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x7f00);
944*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8ffb);
945*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
946*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x0100);
947*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8fe9);
948*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x0002);
949*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8fef);
950*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x00a5);
951*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8ff1);
952*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x0106);
953*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8fe1);
954*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x0102);
955*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8fe3);
956*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
957*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x0400);
958*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xa654, 0x0800);
959*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xa654, 0x0003);
960*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xac3a, 0x5851);
961*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xac3c) & ~0xd000;
962*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xac3c, val | 0x2000);
963*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xac42) & ~0x0200;
964*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xac42, val | 0x01c0);
965*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xac3e, 0xe000);
966*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xac42, 0x0038);
967*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xac42) & ~0x0002;
968*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xac42, val | 0x0005);
969*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xac1a, 0x00db);
970*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xade4, 0x01b5);
971*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xad9c, 0x0c00);
972*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x814b);
973*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
974*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x1100);
975*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x814d);
976*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
977*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x1100);
978*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x814f);
979*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
980*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x0b00);
981*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8142);
982*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
983*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x0100);
984*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8144);
985*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
986*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x0100);
987*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8150);
988*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
989*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x0100);
990*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8118);
991*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
992*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x0700);
993*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x811a);
994*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
995*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x0700);
996*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x811c);
997*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
998*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x0500);
999*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x810f);
1000*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
1001*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x0100);
1002*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8111);
1003*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
1004*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x0100);
1005*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x811d);
1006*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
1007*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x0100);
1008*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xac36, 0x1000);
1009*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xad1c, 0x0100);
1010*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xade8) & ~0xffc0;
1011*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xade8, val | 0x1400);
1012*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x864b);
1013*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
1014*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x9d00);
1015*4bf8ce03SAdrian Chadd
1016*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8f97);
1017*4bf8ce03SAdrian Chadd for (; i < nitems(mac_cfg2_a438_value); i++)
1018*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, mac_cfg2_a438_value[i]);
1019*4bf8ce03SAdrian Chadd
1020*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xad9c, 0x0020);
1021*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8122);
1022*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
1023*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x0c00);
1024*4bf8ce03SAdrian Chadd
1025*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x82c8);
1026*4bf8ce03SAdrian Chadd for (i = 0; i < 20; i++)
1027*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, mac_cfg2_b87e_value[i]);
1028*4bf8ce03SAdrian Chadd
1029*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x80ef);
1030*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
1031*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x0c00);
1032*4bf8ce03SAdrian Chadd
1033*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x82a0);
1034*4bf8ce03SAdrian Chadd for (; i < nitems(mac_cfg2_b87e_value); i++)
1035*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, mac_cfg2_b87e_value[i]);
1036*4bf8ce03SAdrian Chadd
1037*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8018);
1038*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xa438, 0x2000);
1039*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8fe4);
1040*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
1041*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0);
1042*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb54c) & ~0xffc0;
1043*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb54c, val | 0x3700);
1044*4bf8ce03SAdrian Chadd }
1045*4bf8ce03SAdrian Chadd
1046*4bf8ce03SAdrian Chadd static void
rge_phy_config_mac_r25(struct rge_softc * sc)1047*4bf8ce03SAdrian Chadd rge_phy_config_mac_r25(struct rge_softc *sc)
1048*4bf8ce03SAdrian Chadd {
1049*4bf8ce03SAdrian Chadd uint16_t val;
1050*4bf8ce03SAdrian Chadd int i;
1051*4bf8ce03SAdrian Chadd static const uint16_t mac_cfg3_a438_value[] =
1052*4bf8ce03SAdrian Chadd { 0x0043, 0x00a7, 0x00d6, 0x00ec, 0x00f6, 0x00fb, 0x00fd, 0x00ff,
1053*4bf8ce03SAdrian Chadd 0x00bb, 0x0058, 0x0029, 0x0013, 0x0009, 0x0004, 0x0002 };
1054*4bf8ce03SAdrian Chadd
1055*4bf8ce03SAdrian Chadd static const uint16_t mac_cfg3_b88e_value[] =
1056*4bf8ce03SAdrian Chadd { 0xc091, 0x6e12, 0xc092, 0x1214, 0xc094, 0x1516, 0xc096, 0x171b,
1057*4bf8ce03SAdrian Chadd 0xc098, 0x1b1c, 0xc09a, 0x1f1f, 0xc09c, 0x2021, 0xc09e, 0x2224,
1058*4bf8ce03SAdrian Chadd 0xc0a0, 0x2424, 0xc0a2, 0x2424, 0xc0a4, 0x2424, 0xc018, 0x0af2,
1059*4bf8ce03SAdrian Chadd 0xc01a, 0x0d4a, 0xc01c, 0x0f26, 0xc01e, 0x118d, 0xc020, 0x14f3,
1060*4bf8ce03SAdrian Chadd 0xc022, 0x175a, 0xc024, 0x19c0, 0xc026, 0x1c26, 0xc089, 0x6050,
1061*4bf8ce03SAdrian Chadd 0xc08a, 0x5f6e, 0xc08c, 0x6e6e, 0xc08e, 0x6e6e, 0xc090, 0x6e12 };
1062*4bf8ce03SAdrian Chadd
1063*4bf8ce03SAdrian Chadd rge_phy_config_mcu(sc, RGE_MAC_R25_RCODE_VER);
1064*4bf8ce03SAdrian Chadd
1065*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xad4e, 0x0010);
1066*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xad16) & ~0x03ff;
1067*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xad16, val | 0x03ff);
1068*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xad32) & ~0x003f;
1069*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xad32, val | 0x0006);
1070*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xac08, 0x1000);
1071*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xac08, 0x0100);
1072*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xacc0) & ~0x0003;
1073*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xacc0, val | 0x0002);
1074*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xad40) & ~0x00e0;
1075*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xad40, val | 0x0040);
1076*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xad40) & ~0x0007;
1077*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xad40, val | 0x0004);
1078*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xac14, 0x0080);
1079*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xac80, 0x0300);
1080*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xac5e) & ~0x0007;
1081*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xac5e, val | 0x0002);
1082*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xad4c, 0x00a8);
1083*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xac5c, 0x01ff);
1084*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xac8a) & ~0x00f0;
1085*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xac8a, val | 0x0030);
1086*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8157);
1087*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
1088*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x0500);
1089*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8159);
1090*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
1091*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x0700);
1092*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x80a2);
1093*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x0153);
1094*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x809c);
1095*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x0153);
1096*4bf8ce03SAdrian Chadd
1097*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x81b3);
1098*4bf8ce03SAdrian Chadd for (i = 0; i < nitems(mac_cfg3_a438_value); i++)
1099*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, mac_cfg3_a438_value[i]);
1100*4bf8ce03SAdrian Chadd for (i = 0; i < 26; i++)
1101*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0);
1102*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8257);
1103*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x020f);
1104*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x80ea);
1105*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x7843);
1106*4bf8ce03SAdrian Chadd
1107*4bf8ce03SAdrian Chadd rge_patch_phy_mcu(sc, 1);
1108*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xb896, 0x0001);
1109*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xb892, 0xff00);
1110*4bf8ce03SAdrian Chadd for (i = 0; i < nitems(mac_cfg3_b88e_value); i += 2) {
1111*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb88e, mac_cfg3_b88e_value[i]);
1112*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb890, mac_cfg3_b88e_value[i + 1]);
1113*4bf8ce03SAdrian Chadd }
1114*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xb896, 0x0001);
1115*4bf8ce03SAdrian Chadd rge_patch_phy_mcu(sc, 0);
1116*4bf8ce03SAdrian Chadd
1117*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xd068, 0x2000);
1118*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x81a2);
1119*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xa438, 0x0100);
1120*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb54c) & ~0xff00;
1121*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb54c, val | 0xdb00);
1122*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xa454, 0x0001);
1123*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xa5d4, 0x0020);
1124*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xad4e, 0x0010);
1125*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xa86a, 0x0001);
1126*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xa442, 0x0800);
1127*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xa424, 0x0008);
1128*4bf8ce03SAdrian Chadd }
1129*4bf8ce03SAdrian Chadd
1130*4bf8ce03SAdrian Chadd static void
rge_phy_config_mac_r25b(struct rge_softc * sc)1131*4bf8ce03SAdrian Chadd rge_phy_config_mac_r25b(struct rge_softc *sc)
1132*4bf8ce03SAdrian Chadd {
1133*4bf8ce03SAdrian Chadd uint16_t val;
1134*4bf8ce03SAdrian Chadd int i;
1135*4bf8ce03SAdrian Chadd
1136*4bf8ce03SAdrian Chadd rge_phy_config_mcu(sc, RGE_MAC_R25B_RCODE_VER);
1137*4bf8ce03SAdrian Chadd
1138*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xa442, 0x0800);
1139*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xac46) & ~0x00f0;
1140*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xac46, val | 0x0090);
1141*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xad30) & ~0x0003;
1142*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xad30, val | 0x0001);
1143*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x80f5);
1144*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x760e);
1145*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8107);
1146*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, 0x360e);
1147*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8551);
1148*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
1149*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x0800);
1150*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xbf00) & ~0xe000;
1151*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xbf00, val | 0xa000);
1152*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xbf46) & ~0x0f00;
1153*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xbf46, val | 0x0300);
1154*4bf8ce03SAdrian Chadd for (i = 0; i < 10; i++) {
1155*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8044 + i * 6);
1156*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x2417);
1157*4bf8ce03SAdrian Chadd }
1158*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xa4ca, 0x0040);
1159*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xbf84) & ~0xe000;
1160*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xbf84, val | 0xa000);
1161*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8170);
1162*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0x2700;
1163*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0xd800);
1164*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xa424, 0x0008);
1165*4bf8ce03SAdrian Chadd }
1166*4bf8ce03SAdrian Chadd
1167*4bf8ce03SAdrian Chadd static void
rge_phy_config_mac_r25d(struct rge_softc * sc)1168*4bf8ce03SAdrian Chadd rge_phy_config_mac_r25d(struct rge_softc *sc)
1169*4bf8ce03SAdrian Chadd {
1170*4bf8ce03SAdrian Chadd uint16_t val;
1171*4bf8ce03SAdrian Chadd int i;
1172*4bf8ce03SAdrian Chadd
1173*4bf8ce03SAdrian Chadd rge_phy_config_mcu(sc, RGE_MAC_R25D_RCODE_VER);
1174*4bf8ce03SAdrian Chadd
1175*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xa442, 0x0800);
1176*4bf8ce03SAdrian Chadd
1177*4bf8ce03SAdrian Chadd rge_patch_phy_mcu(sc, 1);
1178*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xbf96, 0x8000);
1179*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xbf94) & ~0x0007;
1180*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xbf94, val | 0x0005);
1181*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xbf8e) & ~0x3c00;
1182*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xbf8e, val | 0x2800);
1183*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xbcd8) & ~0xc000;
1184*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xbcd8, val | 0x4000);
1185*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xbcd8, 0xc000);
1186*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xbcd8) & ~0xc000;
1187*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xbcd8, val | 0x4000);
1188*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xbc80) & ~0x001f;
1189*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xbc80, val | 0x0004);
1190*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xbc82, 0xe000);
1191*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xbc82, 0x1c00);
1192*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xbc80) & ~0x001f;
1193*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xbc80, val | 0x0005);
1194*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xbc82) & ~0x00e0;
1195*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xbc82, val | 0x0040);
1196*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xbc82, 0x001c);
1197*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xbcd8, 0xc000);
1198*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xbcd8) & ~0xc000;
1199*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xbcd8, val | 0x8000);
1200*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xbcd8, 0xc000);
1201*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xbd70, 0x0100);
1202*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xa466, 0x0002);
1203*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x836a);
1204*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xa438, 0xff00);
1205*4bf8ce03SAdrian Chadd rge_patch_phy_mcu(sc, 0);
1206*4bf8ce03SAdrian Chadd
1207*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x832c);
1208*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
1209*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x0500);
1210*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb106) & ~0x0700;
1211*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb106, val | 0x0100);
1212*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb206) & ~0x0700;
1213*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb206, val | 0x0200);
1214*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb306) & ~0x0700;
1215*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb306, val | 0x0300);
1216*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x80cb);
1217*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
1218*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x0300);
1219*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xbcf4, 0x0000);
1220*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xbcf6, 0x0000);
1221*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xbc12, 0x0000);
1222*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x844d);
1223*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
1224*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x0200);
1225*4bf8ce03SAdrian Chadd
1226*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8feb);
1227*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
1228*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x0100);
1229*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8fe9);
1230*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
1231*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x0600);
1232*4bf8ce03SAdrian Chadd
1233*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xac7e) & ~0x01fc;
1234*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xac7e, val | 0x00B4);
1235*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8105);
1236*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
1237*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x7a00);
1238*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8117);
1239*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
1240*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x3a00);
1241*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8103);
1242*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
1243*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x7400);
1244*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87c, 0x8115);
1245*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xb87e) & ~0xff00;
1246*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xb87e, val | 0x3400);
1247*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xad40, 0x0030);
1248*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xad66) & ~0x000f;
1249*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xad66, val | 0x0007);
1250*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xad68) & ~0xf000;
1251*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xad68, val | 0x8000);
1252*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xad68) & ~0x0f00;
1253*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xad68, val | 0x0500);
1254*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xad68) & ~0x000f;
1255*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xad68, val | 0x0002);
1256*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xad6a) & ~0xf000;
1257*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xad6a, val | 0x7000);
1258*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xac50, 0x01e8);
1259*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x81fa);
1260*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
1261*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x5400);
1262*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa864) & ~0x00f0;
1263*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa864, val | 0x00c0);
1264*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa42c) & ~0x00ff;
1265*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa42c, val | 0x0002);
1266*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x80e1);
1267*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
1268*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x0f00);
1269*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x80de);
1270*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xf000;
1271*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x0700);
1272*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xa846, 0x0080);
1273*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x80ba);
1274*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x8a04);
1275*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x80bd);
1276*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
1277*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0xca00);
1278*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x80b7);
1279*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
1280*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0xb300);
1281*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x80ce);
1282*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x8a04);
1283*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x80d1);
1284*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
1285*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0xca00);
1286*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x80cb);
1287*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
1288*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0xbb00);
1289*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x80a6);
1290*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x4909);
1291*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x80a8);
1292*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x05b8);
1293*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8200);
1294*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
1295*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x5800);
1296*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8ff1);
1297*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x7078);
1298*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8ff3);
1299*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x5d78);
1300*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8ff5);
1301*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x7862);
1302*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8ff7);
1303*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
1304*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x1400);
1305*4bf8ce03SAdrian Chadd
1306*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x814c);
1307*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x8455);
1308*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x814e);
1309*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x84a6);
1310*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8163);
1311*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
1312*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x0600);
1313*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x816a);
1314*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
1315*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x0500);
1316*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8171);
1317*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
1318*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x1f00);
1319*4bf8ce03SAdrian Chadd
1320*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xbc3a) & ~0x000f;
1321*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xbc3a, val | 0x0006);
1322*4bf8ce03SAdrian Chadd for (i = 0; i < 10; i++) {
1323*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8064 + i * 3);
1324*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xa438, 0x0700);
1325*4bf8ce03SAdrian Chadd }
1326*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xbfa0) & ~0xff70;
1327*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xbfa0, val | 0x5500);
1328*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xbfa2, 0x9d00);
1329*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8165);
1330*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0x0700;
1331*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x0200);
1332*4bf8ce03SAdrian Chadd
1333*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8019);
1334*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xa438, 0x0100);
1335*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8fe3);
1336*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x0005);
1337*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x0000);
1338*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x00ed);
1339*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x0502);
1340*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x0b00);
1341*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0xd401);
1342*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
1343*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x2900);
1344*4bf8ce03SAdrian Chadd
1345*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8018);
1346*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
1347*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x1700);
1348*4bf8ce03SAdrian Chadd
1349*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x815b);
1350*4bf8ce03SAdrian Chadd val = rge_read_phy_ocp(sc, 0xa438) & ~0xff00;
1351*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, val | 0x1700);
1352*4bf8ce03SAdrian Chadd
1353*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xa4e0, 0x8000);
1354*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xa5d4, 0x0020);
1355*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xa654, 0x0800);
1356*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xa430, 0x1001);
1357*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xa442, 0x0080);
1358*4bf8ce03SAdrian Chadd }
1359*4bf8ce03SAdrian Chadd
1360*4bf8ce03SAdrian Chadd static void
rge_phy_config_mcu(struct rge_softc * sc,uint16_t rcodever)1361*4bf8ce03SAdrian Chadd rge_phy_config_mcu(struct rge_softc *sc, uint16_t rcodever)
1362*4bf8ce03SAdrian Chadd {
1363*4bf8ce03SAdrian Chadd if (sc->rge_rcodever != rcodever) {
1364*4bf8ce03SAdrian Chadd int i;
1365*4bf8ce03SAdrian Chadd
1366*4bf8ce03SAdrian Chadd rge_patch_phy_mcu(sc, 1);
1367*4bf8ce03SAdrian Chadd
1368*4bf8ce03SAdrian Chadd if (sc->rge_type == MAC_R25) {
1369*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8024);
1370*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x8601);
1371*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0xb82e);
1372*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0x0001);
1373*4bf8ce03SAdrian Chadd
1374*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xb820, 0x0080);
1375*4bf8ce03SAdrian Chadd
1376*4bf8ce03SAdrian Chadd for (i = 0; i < nitems(mac_r25_mcu); i++)
1377*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc,
1378*4bf8ce03SAdrian Chadd mac_r25_mcu[i].reg, mac_r25_mcu[i].val);
1379*4bf8ce03SAdrian Chadd
1380*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xb820, 0x0080);
1381*4bf8ce03SAdrian Chadd
1382*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0);
1383*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0);
1384*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xb82e, 0x0001);
1385*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x8024);
1386*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, 0);
1387*4bf8ce03SAdrian Chadd } else if (sc->rge_type == MAC_R25B) {
1388*4bf8ce03SAdrian Chadd for (i = 0; i < nitems(mac_r25b_mcu); i++)
1389*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc,
1390*4bf8ce03SAdrian Chadd mac_r25b_mcu[i].reg, mac_r25b_mcu[i].val);
1391*4bf8ce03SAdrian Chadd } else if (sc->rge_type == MAC_R25D) {
1392*4bf8ce03SAdrian Chadd for (i = 0; i < 2403; i++)
1393*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc,
1394*4bf8ce03SAdrian Chadd mac_r25d_mcu[i].reg, mac_r25d_mcu[i].val);
1395*4bf8ce03SAdrian Chadd rge_patch_phy_mcu(sc, 0);
1396*4bf8ce03SAdrian Chadd
1397*4bf8ce03SAdrian Chadd rge_patch_phy_mcu(sc, 1);
1398*4bf8ce03SAdrian Chadd for (; i < 2528; i++)
1399*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc,
1400*4bf8ce03SAdrian Chadd mac_r25d_mcu[i].reg, mac_r25d_mcu[i].val);
1401*4bf8ce03SAdrian Chadd rge_patch_phy_mcu(sc, 0);
1402*4bf8ce03SAdrian Chadd
1403*4bf8ce03SAdrian Chadd rge_patch_phy_mcu(sc, 1);
1404*4bf8ce03SAdrian Chadd for (; i < nitems(mac_r25d_mcu); i++)
1405*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc,
1406*4bf8ce03SAdrian Chadd mac_r25d_mcu[i].reg, mac_r25d_mcu[i].val);
1407*4bf8ce03SAdrian Chadd } else if (sc->rge_type == MAC_R26) {
1408*4bf8ce03SAdrian Chadd for (i = 0; i < nitems(mac_r26_mcu); i++)
1409*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc,
1410*4bf8ce03SAdrian Chadd mac_r26_mcu[i].reg, mac_r26_mcu[i].val);
1411*4bf8ce03SAdrian Chadd } else if (sc->rge_type == MAC_R27) {
1412*4bf8ce03SAdrian Chadd for (i = 0; i < 1887; i++)
1413*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc,
1414*4bf8ce03SAdrian Chadd mac_r27_mcu[i].reg, mac_r27_mcu[i].val);
1415*4bf8ce03SAdrian Chadd rge_patch_phy_mcu(sc, 0);
1416*4bf8ce03SAdrian Chadd
1417*4bf8ce03SAdrian Chadd rge_patch_phy_mcu(sc, 1);
1418*4bf8ce03SAdrian Chadd for (; i < nitems(mac_r27_mcu); i++)
1419*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc,
1420*4bf8ce03SAdrian Chadd mac_r27_mcu[i].reg, mac_r27_mcu[i].val);
1421*4bf8ce03SAdrian Chadd }
1422*4bf8ce03SAdrian Chadd
1423*4bf8ce03SAdrian Chadd rge_patch_phy_mcu(sc, 0);
1424*4bf8ce03SAdrian Chadd
1425*4bf8ce03SAdrian Chadd /* Write ram code version. */
1426*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa436, 0x801e);
1427*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xa438, rcodever);
1428*4bf8ce03SAdrian Chadd }
1429*4bf8ce03SAdrian Chadd }
1430*4bf8ce03SAdrian Chadd
1431*4bf8ce03SAdrian Chadd void
rge_set_macaddr(struct rge_softc * sc,const uint8_t * addr)1432*4bf8ce03SAdrian Chadd rge_set_macaddr(struct rge_softc *sc, const uint8_t *addr)
1433*4bf8ce03SAdrian Chadd {
1434*4bf8ce03SAdrian Chadd RGE_SETBIT_1(sc, RGE_EECMD, RGE_EECMD_WRITECFG);
1435*4bf8ce03SAdrian Chadd RGE_WRITE_4(sc, RGE_MAC0,
1436*4bf8ce03SAdrian Chadd addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0]);
1437*4bf8ce03SAdrian Chadd RGE_WRITE_4(sc, RGE_MAC4,
1438*4bf8ce03SAdrian Chadd addr[5] << 8 | addr[4]);
1439*4bf8ce03SAdrian Chadd RGE_CLRBIT_1(sc, RGE_EECMD, RGE_EECMD_WRITECFG);
1440*4bf8ce03SAdrian Chadd }
1441*4bf8ce03SAdrian Chadd
1442*4bf8ce03SAdrian Chadd /**
1443*4bf8ce03SAdrian Chadd * @brief Read the mac address from the NIC EEPROM.
1444*4bf8ce03SAdrian Chadd *
1445*4bf8ce03SAdrian Chadd * Note this also calls rge_set_macaddr() which programs
1446*4bf8ce03SAdrian Chadd * it into the PPROM; I'm not sure why.
1447*4bf8ce03SAdrian Chadd *
1448*4bf8ce03SAdrian Chadd * Must be called with the driver lock held.
1449*4bf8ce03SAdrian Chadd */
1450*4bf8ce03SAdrian Chadd void
rge_get_macaddr(struct rge_softc * sc,uint8_t * addr)1451*4bf8ce03SAdrian Chadd rge_get_macaddr(struct rge_softc *sc, uint8_t *addr)
1452*4bf8ce03SAdrian Chadd {
1453*4bf8ce03SAdrian Chadd int i;
1454*4bf8ce03SAdrian Chadd
1455*4bf8ce03SAdrian Chadd RGE_ASSERT_LOCKED(sc);
1456*4bf8ce03SAdrian Chadd
1457*4bf8ce03SAdrian Chadd for (i = 0; i < ETHER_ADDR_LEN; i++)
1458*4bf8ce03SAdrian Chadd addr[i] = RGE_READ_1(sc, RGE_MAC0 + i);
1459*4bf8ce03SAdrian Chadd
1460*4bf8ce03SAdrian Chadd *(uint32_t *)&addr[0] = RGE_READ_4(sc, RGE_ADDR0);
1461*4bf8ce03SAdrian Chadd *(uint16_t *)&addr[4] = RGE_READ_2(sc, RGE_ADDR1);
1462*4bf8ce03SAdrian Chadd
1463*4bf8ce03SAdrian Chadd rge_set_macaddr(sc, addr);
1464*4bf8ce03SAdrian Chadd }
1465*4bf8ce03SAdrian Chadd
1466*4bf8ce03SAdrian Chadd /**
1467*4bf8ce03SAdrian Chadd * @brief MAC hardware initialisation
1468*4bf8ce03SAdrian Chadd *
1469*4bf8ce03SAdrian Chadd * Must be called with the driver lock held.
1470*4bf8ce03SAdrian Chadd */
1471*4bf8ce03SAdrian Chadd static void
rge_hw_init(struct rge_softc * sc)1472*4bf8ce03SAdrian Chadd rge_hw_init(struct rge_softc *sc)
1473*4bf8ce03SAdrian Chadd {
1474*4bf8ce03SAdrian Chadd uint16_t reg;
1475*4bf8ce03SAdrian Chadd int i;
1476*4bf8ce03SAdrian Chadd
1477*4bf8ce03SAdrian Chadd RGE_ASSERT_LOCKED(sc);
1478*4bf8ce03SAdrian Chadd
1479*4bf8ce03SAdrian Chadd rge_disable_aspm_clkreq(sc);
1480*4bf8ce03SAdrian Chadd RGE_CLRBIT_1(sc, 0xf1, 0x80);
1481*4bf8ce03SAdrian Chadd
1482*4bf8ce03SAdrian Chadd /* Disable UPS. */
1483*4bf8ce03SAdrian Chadd RGE_MAC_CLRBIT(sc, 0xd40a, 0x0010);
1484*4bf8ce03SAdrian Chadd
1485*4bf8ce03SAdrian Chadd /* Disable MAC MCU. */
1486*4bf8ce03SAdrian Chadd rge_disable_aspm_clkreq(sc);
1487*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xfc48, 0);
1488*4bf8ce03SAdrian Chadd for (reg = 0xfc28; reg < 0xfc48; reg += 2)
1489*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, reg, 0);
1490*4bf8ce03SAdrian Chadd DELAY(3000);
1491*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xfc26, 0);
1492*4bf8ce03SAdrian Chadd
1493*4bf8ce03SAdrian Chadd /* Read microcode version. */
1494*4bf8ce03SAdrian Chadd rge_switch_mcu_ram_page(sc, 2);
1495*4bf8ce03SAdrian Chadd sc->rge_mcodever = 0;
1496*4bf8ce03SAdrian Chadd for (i = 0; i < 8; i += 2) {
1497*4bf8ce03SAdrian Chadd sc->rge_mcodever <<= 16;
1498*4bf8ce03SAdrian Chadd sc->rge_mcodever |= rge_read_mac_ocp(sc, 0xf9f8 + i);
1499*4bf8ce03SAdrian Chadd }
1500*4bf8ce03SAdrian Chadd rge_switch_mcu_ram_page(sc, 0);
1501*4bf8ce03SAdrian Chadd
1502*4bf8ce03SAdrian Chadd rge_mac_config_mcu(sc, sc->rge_type);
1503*4bf8ce03SAdrian Chadd
1504*4bf8ce03SAdrian Chadd /* Disable PHY power saving. */
1505*4bf8ce03SAdrian Chadd if (sc->rge_type == MAC_R25)
1506*4bf8ce03SAdrian Chadd rge_disable_phy_ocp_pwrsave(sc);
1507*4bf8ce03SAdrian Chadd
1508*4bf8ce03SAdrian Chadd /* Set PCIe uncorrectable error status. */
1509*4bf8ce03SAdrian Chadd rge_write_csi(sc, 0x108,
1510*4bf8ce03SAdrian Chadd rge_read_csi(sc, 0x108) | 0x00100000);
1511*4bf8ce03SAdrian Chadd }
1512*4bf8ce03SAdrian Chadd
1513*4bf8ce03SAdrian Chadd void
rge_hw_reset(struct rge_softc * sc)1514*4bf8ce03SAdrian Chadd rge_hw_reset(struct rge_softc *sc)
1515*4bf8ce03SAdrian Chadd {
1516*4bf8ce03SAdrian Chadd /* Disable interrupts */
1517*4bf8ce03SAdrian Chadd RGE_WRITE_4(sc, RGE_IMR, 0);
1518*4bf8ce03SAdrian Chadd RGE_WRITE_4(sc, RGE_ISR, RGE_READ_4(sc, RGE_ISR));
1519*4bf8ce03SAdrian Chadd
1520*4bf8ce03SAdrian Chadd /* Clear timer interrupts. */
1521*4bf8ce03SAdrian Chadd RGE_WRITE_4(sc, RGE_TIMERINT0, 0);
1522*4bf8ce03SAdrian Chadd RGE_WRITE_4(sc, RGE_TIMERINT1, 0);
1523*4bf8ce03SAdrian Chadd RGE_WRITE_4(sc, RGE_TIMERINT2, 0);
1524*4bf8ce03SAdrian Chadd RGE_WRITE_4(sc, RGE_TIMERINT3, 0);
1525*4bf8ce03SAdrian Chadd
1526*4bf8ce03SAdrian Chadd rge_reset(sc);
1527*4bf8ce03SAdrian Chadd }
1528*4bf8ce03SAdrian Chadd
1529*4bf8ce03SAdrian Chadd static void
rge_disable_phy_ocp_pwrsave(struct rge_softc * sc)1530*4bf8ce03SAdrian Chadd rge_disable_phy_ocp_pwrsave(struct rge_softc *sc)
1531*4bf8ce03SAdrian Chadd {
1532*4bf8ce03SAdrian Chadd if (rge_read_phy_ocp(sc, 0xc416) != 0x0500) {
1533*4bf8ce03SAdrian Chadd rge_patch_phy_mcu(sc, 1);
1534*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xc416, 0);
1535*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, 0xc416, 0x0500);
1536*4bf8ce03SAdrian Chadd rge_patch_phy_mcu(sc, 0);
1537*4bf8ce03SAdrian Chadd }
1538*4bf8ce03SAdrian Chadd }
1539*4bf8ce03SAdrian Chadd
1540*4bf8ce03SAdrian Chadd static void
rge_patch_phy_mcu(struct rge_softc * sc,int set)1541*4bf8ce03SAdrian Chadd rge_patch_phy_mcu(struct rge_softc *sc, int set)
1542*4bf8ce03SAdrian Chadd {
1543*4bf8ce03SAdrian Chadd int i;
1544*4bf8ce03SAdrian Chadd
1545*4bf8ce03SAdrian Chadd if (set)
1546*4bf8ce03SAdrian Chadd RGE_PHY_SETBIT(sc, 0xb820, 0x0010);
1547*4bf8ce03SAdrian Chadd else
1548*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xb820, 0x0010);
1549*4bf8ce03SAdrian Chadd
1550*4bf8ce03SAdrian Chadd for (i = 0; i < 1000; i++) {
1551*4bf8ce03SAdrian Chadd if (set) {
1552*4bf8ce03SAdrian Chadd if ((rge_read_phy_ocp(sc, 0xb800) & 0x0040) != 0)
1553*4bf8ce03SAdrian Chadd break;
1554*4bf8ce03SAdrian Chadd } else {
1555*4bf8ce03SAdrian Chadd if (!(rge_read_phy_ocp(sc, 0xb800) & 0x0040))
1556*4bf8ce03SAdrian Chadd break;
1557*4bf8ce03SAdrian Chadd }
1558*4bf8ce03SAdrian Chadd DELAY(100);
1559*4bf8ce03SAdrian Chadd }
1560*4bf8ce03SAdrian Chadd if (i == 1000)
1561*4bf8ce03SAdrian Chadd RGE_PRINT_ERROR(sc, "timeout waiting to patch phy mcu\n");
1562*4bf8ce03SAdrian Chadd }
1563*4bf8ce03SAdrian Chadd
1564*4bf8ce03SAdrian Chadd void
rge_config_imtype(struct rge_softc * sc,int imtype)1565*4bf8ce03SAdrian Chadd rge_config_imtype(struct rge_softc *sc, int imtype)
1566*4bf8ce03SAdrian Chadd {
1567*4bf8ce03SAdrian Chadd switch (imtype) {
1568*4bf8ce03SAdrian Chadd case RGE_IMTYPE_NONE:
1569*4bf8ce03SAdrian Chadd sc->rge_intrs = RGE_INTRS;
1570*4bf8ce03SAdrian Chadd break;
1571*4bf8ce03SAdrian Chadd case RGE_IMTYPE_SIM:
1572*4bf8ce03SAdrian Chadd sc->rge_intrs = RGE_INTRS_TIMER;
1573*4bf8ce03SAdrian Chadd break;
1574*4bf8ce03SAdrian Chadd default:
1575*4bf8ce03SAdrian Chadd RGE_PRINT_ERROR(sc, "unknown imtype %d", imtype);
1576*4bf8ce03SAdrian Chadd }
1577*4bf8ce03SAdrian Chadd }
1578*4bf8ce03SAdrian Chadd
1579*4bf8ce03SAdrian Chadd void
rge_disable_aspm_clkreq(struct rge_softc * sc)1580*4bf8ce03SAdrian Chadd rge_disable_aspm_clkreq(struct rge_softc *sc)
1581*4bf8ce03SAdrian Chadd {
1582*4bf8ce03SAdrian Chadd int unlock = 1;
1583*4bf8ce03SAdrian Chadd
1584*4bf8ce03SAdrian Chadd if ((RGE_READ_1(sc, RGE_EECMD) & RGE_EECMD_WRITECFG) ==
1585*4bf8ce03SAdrian Chadd RGE_EECMD_WRITECFG)
1586*4bf8ce03SAdrian Chadd unlock = 0;
1587*4bf8ce03SAdrian Chadd
1588*4bf8ce03SAdrian Chadd if (unlock)
1589*4bf8ce03SAdrian Chadd RGE_SETBIT_1(sc, RGE_EECMD, RGE_EECMD_WRITECFG);
1590*4bf8ce03SAdrian Chadd
1591*4bf8ce03SAdrian Chadd if (sc->rge_type == MAC_R26 || sc->rge_type == MAC_R27)
1592*4bf8ce03SAdrian Chadd RGE_CLRBIT_1(sc, RGE_INT_CFG0, 0x08);
1593*4bf8ce03SAdrian Chadd else
1594*4bf8ce03SAdrian Chadd RGE_CLRBIT_1(sc, RGE_CFG2, RGE_CFG2_CLKREQ_EN);
1595*4bf8ce03SAdrian Chadd RGE_CLRBIT_1(sc, RGE_CFG5, RGE_CFG5_PME_STS);
1596*4bf8ce03SAdrian Chadd
1597*4bf8ce03SAdrian Chadd if (unlock)
1598*4bf8ce03SAdrian Chadd RGE_CLRBIT_1(sc, RGE_EECMD, RGE_EECMD_WRITECFG);
1599*4bf8ce03SAdrian Chadd }
1600*4bf8ce03SAdrian Chadd
1601*4bf8ce03SAdrian Chadd static void
rge_disable_hw_im(struct rge_softc * sc)1602*4bf8ce03SAdrian Chadd rge_disable_hw_im(struct rge_softc *sc)
1603*4bf8ce03SAdrian Chadd {
1604*4bf8ce03SAdrian Chadd RGE_WRITE_2(sc, RGE_IM, 0);
1605*4bf8ce03SAdrian Chadd }
1606*4bf8ce03SAdrian Chadd
1607*4bf8ce03SAdrian Chadd static void
rge_disable_sim_im(struct rge_softc * sc)1608*4bf8ce03SAdrian Chadd rge_disable_sim_im(struct rge_softc *sc)
1609*4bf8ce03SAdrian Chadd {
1610*4bf8ce03SAdrian Chadd RGE_WRITE_4(sc, RGE_TIMERINT0, 0);
1611*4bf8ce03SAdrian Chadd sc->rge_timerintr = 0;
1612*4bf8ce03SAdrian Chadd }
1613*4bf8ce03SAdrian Chadd
1614*4bf8ce03SAdrian Chadd static void
rge_setup_sim_im(struct rge_softc * sc)1615*4bf8ce03SAdrian Chadd rge_setup_sim_im(struct rge_softc *sc)
1616*4bf8ce03SAdrian Chadd {
1617*4bf8ce03SAdrian Chadd RGE_WRITE_4(sc, RGE_TIMERINT0, 0x2600);
1618*4bf8ce03SAdrian Chadd RGE_WRITE_4(sc, RGE_TIMERCNT, 1);
1619*4bf8ce03SAdrian Chadd sc->rge_timerintr = 1;
1620*4bf8ce03SAdrian Chadd }
1621*4bf8ce03SAdrian Chadd
1622*4bf8ce03SAdrian Chadd void
rge_setup_intr(struct rge_softc * sc,int imtype)1623*4bf8ce03SAdrian Chadd rge_setup_intr(struct rge_softc *sc, int imtype)
1624*4bf8ce03SAdrian Chadd {
1625*4bf8ce03SAdrian Chadd rge_config_imtype(sc, imtype);
1626*4bf8ce03SAdrian Chadd
1627*4bf8ce03SAdrian Chadd /* Enable interrupts. */
1628*4bf8ce03SAdrian Chadd RGE_WRITE_4(sc, RGE_IMR, sc->rge_intrs);
1629*4bf8ce03SAdrian Chadd
1630*4bf8ce03SAdrian Chadd switch (imtype) {
1631*4bf8ce03SAdrian Chadd case RGE_IMTYPE_NONE:
1632*4bf8ce03SAdrian Chadd rge_disable_sim_im(sc);
1633*4bf8ce03SAdrian Chadd rge_disable_hw_im(sc);
1634*4bf8ce03SAdrian Chadd break;
1635*4bf8ce03SAdrian Chadd case RGE_IMTYPE_SIM:
1636*4bf8ce03SAdrian Chadd rge_disable_hw_im(sc);
1637*4bf8ce03SAdrian Chadd rge_setup_sim_im(sc);
1638*4bf8ce03SAdrian Chadd break;
1639*4bf8ce03SAdrian Chadd default:
1640*4bf8ce03SAdrian Chadd RGE_PRINT_ERROR(sc, "unknown imtype %d", imtype);
1641*4bf8ce03SAdrian Chadd }
1642*4bf8ce03SAdrian Chadd }
1643*4bf8ce03SAdrian Chadd
1644*4bf8ce03SAdrian Chadd static void
rge_switch_mcu_ram_page(struct rge_softc * sc,int page)1645*4bf8ce03SAdrian Chadd rge_switch_mcu_ram_page(struct rge_softc *sc, int page)
1646*4bf8ce03SAdrian Chadd {
1647*4bf8ce03SAdrian Chadd uint16_t val;
1648*4bf8ce03SAdrian Chadd
1649*4bf8ce03SAdrian Chadd val = rge_read_mac_ocp(sc, 0xe446) & ~0x0003;
1650*4bf8ce03SAdrian Chadd val |= page;
1651*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xe446, val);
1652*4bf8ce03SAdrian Chadd }
1653*4bf8ce03SAdrian Chadd
1654*4bf8ce03SAdrian Chadd static int
rge_exit_oob(struct rge_softc * sc)1655*4bf8ce03SAdrian Chadd rge_exit_oob(struct rge_softc *sc)
1656*4bf8ce03SAdrian Chadd {
1657*4bf8ce03SAdrian Chadd int error, i;
1658*4bf8ce03SAdrian Chadd
1659*4bf8ce03SAdrian Chadd /* Disable RealWoW. */
1660*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xc0bc, 0x00ff);
1661*4bf8ce03SAdrian Chadd
1662*4bf8ce03SAdrian Chadd if ((error = rge_reset(sc)) != 0)
1663*4bf8ce03SAdrian Chadd return error;
1664*4bf8ce03SAdrian Chadd
1665*4bf8ce03SAdrian Chadd /* Disable OOB. */
1666*4bf8ce03SAdrian Chadd RGE_CLRBIT_1(sc, RGE_MCUCMD, RGE_MCUCMD_IS_OOB);
1667*4bf8ce03SAdrian Chadd
1668*4bf8ce03SAdrian Chadd RGE_MAC_CLRBIT(sc, 0xe8de, 0x4000);
1669*4bf8ce03SAdrian Chadd
1670*4bf8ce03SAdrian Chadd for (i = 0; i < 10; i++) {
1671*4bf8ce03SAdrian Chadd DELAY(100);
1672*4bf8ce03SAdrian Chadd if (RGE_READ_2(sc, RGE_TWICMD) & 0x0200)
1673*4bf8ce03SAdrian Chadd break;
1674*4bf8ce03SAdrian Chadd }
1675*4bf8ce03SAdrian Chadd
1676*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xc0aa, 0x07d0);
1677*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xc0a6, 0x01b5);
1678*4bf8ce03SAdrian Chadd rge_write_mac_ocp(sc, 0xc01e, 0x5555);
1679*4bf8ce03SAdrian Chadd
1680*4bf8ce03SAdrian Chadd for (i = 0; i < 10; i++) {
1681*4bf8ce03SAdrian Chadd DELAY(100);
1682*4bf8ce03SAdrian Chadd if (RGE_READ_2(sc, RGE_TWICMD) & 0x0200)
1683*4bf8ce03SAdrian Chadd break;
1684*4bf8ce03SAdrian Chadd }
1685*4bf8ce03SAdrian Chadd
1686*4bf8ce03SAdrian Chadd if (rge_read_mac_ocp(sc, 0xd42c) & 0x0100) {
1687*4bf8ce03SAdrian Chadd for (i = 0; i < RGE_TIMEOUT; i++) {
1688*4bf8ce03SAdrian Chadd if ((rge_read_phy_ocp(sc, 0xa420) & 0x0007) == 2)
1689*4bf8ce03SAdrian Chadd break;
1690*4bf8ce03SAdrian Chadd DELAY(1000);
1691*4bf8ce03SAdrian Chadd }
1692*4bf8ce03SAdrian Chadd RGE_MAC_CLRBIT(sc, 0xd42c, 0x0100);
1693*4bf8ce03SAdrian Chadd if (sc->rge_type != MAC_R25)
1694*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xa466, 0x0001);
1695*4bf8ce03SAdrian Chadd RGE_PHY_CLRBIT(sc, 0xa468, 0x000a);
1696*4bf8ce03SAdrian Chadd }
1697*4bf8ce03SAdrian Chadd
1698*4bf8ce03SAdrian Chadd return 0;
1699*4bf8ce03SAdrian Chadd }
1700*4bf8ce03SAdrian Chadd
1701*4bf8ce03SAdrian Chadd void
rge_write_csi(struct rge_softc * sc,uint32_t reg,uint32_t val)1702*4bf8ce03SAdrian Chadd rge_write_csi(struct rge_softc *sc, uint32_t reg, uint32_t val)
1703*4bf8ce03SAdrian Chadd {
1704*4bf8ce03SAdrian Chadd int i;
1705*4bf8ce03SAdrian Chadd
1706*4bf8ce03SAdrian Chadd RGE_WRITE_4(sc, RGE_CSIDR, val);
1707*4bf8ce03SAdrian Chadd RGE_WRITE_4(sc, RGE_CSIAR, (reg & RGE_CSIAR_ADDR_MASK) |
1708*4bf8ce03SAdrian Chadd (RGE_CSIAR_BYTE_EN << RGE_CSIAR_BYTE_EN_SHIFT) | RGE_CSIAR_BUSY);
1709*4bf8ce03SAdrian Chadd
1710*4bf8ce03SAdrian Chadd for (i = 0; i < 20000; i++) {
1711*4bf8ce03SAdrian Chadd DELAY(1);
1712*4bf8ce03SAdrian Chadd if (!(RGE_READ_4(sc, RGE_CSIAR) & RGE_CSIAR_BUSY))
1713*4bf8ce03SAdrian Chadd break;
1714*4bf8ce03SAdrian Chadd }
1715*4bf8ce03SAdrian Chadd
1716*4bf8ce03SAdrian Chadd DELAY(20);
1717*4bf8ce03SAdrian Chadd }
1718*4bf8ce03SAdrian Chadd
1719*4bf8ce03SAdrian Chadd uint32_t
rge_read_csi(struct rge_softc * sc,uint32_t reg)1720*4bf8ce03SAdrian Chadd rge_read_csi(struct rge_softc *sc, uint32_t reg)
1721*4bf8ce03SAdrian Chadd {
1722*4bf8ce03SAdrian Chadd int i;
1723*4bf8ce03SAdrian Chadd
1724*4bf8ce03SAdrian Chadd RGE_WRITE_4(sc, RGE_CSIAR, (reg & RGE_CSIAR_ADDR_MASK) |
1725*4bf8ce03SAdrian Chadd (RGE_CSIAR_BYTE_EN << RGE_CSIAR_BYTE_EN_SHIFT));
1726*4bf8ce03SAdrian Chadd
1727*4bf8ce03SAdrian Chadd for (i = 0; i < 20000; i++) {
1728*4bf8ce03SAdrian Chadd DELAY(1);
1729*4bf8ce03SAdrian Chadd if (RGE_READ_4(sc, RGE_CSIAR) & RGE_CSIAR_BUSY)
1730*4bf8ce03SAdrian Chadd break;
1731*4bf8ce03SAdrian Chadd }
1732*4bf8ce03SAdrian Chadd
1733*4bf8ce03SAdrian Chadd DELAY(20);
1734*4bf8ce03SAdrian Chadd
1735*4bf8ce03SAdrian Chadd return (RGE_READ_4(sc, RGE_CSIDR));
1736*4bf8ce03SAdrian Chadd }
1737*4bf8ce03SAdrian Chadd
1738*4bf8ce03SAdrian Chadd void
rge_write_mac_ocp(struct rge_softc * sc,uint16_t reg,uint16_t val)1739*4bf8ce03SAdrian Chadd rge_write_mac_ocp(struct rge_softc *sc, uint16_t reg, uint16_t val)
1740*4bf8ce03SAdrian Chadd {
1741*4bf8ce03SAdrian Chadd uint32_t tmp;
1742*4bf8ce03SAdrian Chadd
1743*4bf8ce03SAdrian Chadd tmp = (reg >> 1) << RGE_MACOCP_ADDR_SHIFT;
1744*4bf8ce03SAdrian Chadd tmp += val;
1745*4bf8ce03SAdrian Chadd tmp |= RGE_MACOCP_BUSY;
1746*4bf8ce03SAdrian Chadd RGE_WRITE_4(sc, RGE_MACOCP, tmp);
1747*4bf8ce03SAdrian Chadd }
1748*4bf8ce03SAdrian Chadd
1749*4bf8ce03SAdrian Chadd uint16_t
rge_read_mac_ocp(struct rge_softc * sc,uint16_t reg)1750*4bf8ce03SAdrian Chadd rge_read_mac_ocp(struct rge_softc *sc, uint16_t reg)
1751*4bf8ce03SAdrian Chadd {
1752*4bf8ce03SAdrian Chadd uint32_t val;
1753*4bf8ce03SAdrian Chadd
1754*4bf8ce03SAdrian Chadd val = (reg >> 1) << RGE_MACOCP_ADDR_SHIFT;
1755*4bf8ce03SAdrian Chadd RGE_WRITE_4(sc, RGE_MACOCP, val);
1756*4bf8ce03SAdrian Chadd
1757*4bf8ce03SAdrian Chadd return (RGE_READ_4(sc, RGE_MACOCP) & RGE_MACOCP_DATA_MASK);
1758*4bf8ce03SAdrian Chadd }
1759*4bf8ce03SAdrian Chadd
1760*4bf8ce03SAdrian Chadd static void
rge_write_ephy(struct rge_softc * sc,uint16_t reg,uint16_t val)1761*4bf8ce03SAdrian Chadd rge_write_ephy(struct rge_softc *sc, uint16_t reg, uint16_t val)
1762*4bf8ce03SAdrian Chadd {
1763*4bf8ce03SAdrian Chadd uint32_t tmp;
1764*4bf8ce03SAdrian Chadd int i;
1765*4bf8ce03SAdrian Chadd
1766*4bf8ce03SAdrian Chadd tmp = (reg & RGE_EPHYAR_ADDR_MASK) << RGE_EPHYAR_ADDR_SHIFT;
1767*4bf8ce03SAdrian Chadd tmp |= RGE_EPHYAR_BUSY | (val & RGE_EPHYAR_DATA_MASK);
1768*4bf8ce03SAdrian Chadd RGE_WRITE_4(sc, RGE_EPHYAR, tmp);
1769*4bf8ce03SAdrian Chadd
1770*4bf8ce03SAdrian Chadd for (i = 0; i < 20000; i++) {
1771*4bf8ce03SAdrian Chadd DELAY(1);
1772*4bf8ce03SAdrian Chadd if (!(RGE_READ_4(sc, RGE_EPHYAR) & RGE_EPHYAR_BUSY))
1773*4bf8ce03SAdrian Chadd break;
1774*4bf8ce03SAdrian Chadd }
1775*4bf8ce03SAdrian Chadd
1776*4bf8ce03SAdrian Chadd DELAY(20);
1777*4bf8ce03SAdrian Chadd }
1778*4bf8ce03SAdrian Chadd
1779*4bf8ce03SAdrian Chadd static uint16_t
rge_read_ephy(struct rge_softc * sc,uint16_t reg)1780*4bf8ce03SAdrian Chadd rge_read_ephy(struct rge_softc *sc, uint16_t reg)
1781*4bf8ce03SAdrian Chadd {
1782*4bf8ce03SAdrian Chadd uint32_t val;
1783*4bf8ce03SAdrian Chadd int i;
1784*4bf8ce03SAdrian Chadd
1785*4bf8ce03SAdrian Chadd val = (reg & RGE_EPHYAR_ADDR_MASK) << RGE_EPHYAR_ADDR_SHIFT;
1786*4bf8ce03SAdrian Chadd RGE_WRITE_4(sc, RGE_EPHYAR, val);
1787*4bf8ce03SAdrian Chadd
1788*4bf8ce03SAdrian Chadd for (i = 0; i < 20000; i++) {
1789*4bf8ce03SAdrian Chadd DELAY(1);
1790*4bf8ce03SAdrian Chadd val = RGE_READ_4(sc, RGE_EPHYAR);
1791*4bf8ce03SAdrian Chadd if (val & RGE_EPHYAR_BUSY)
1792*4bf8ce03SAdrian Chadd break;
1793*4bf8ce03SAdrian Chadd }
1794*4bf8ce03SAdrian Chadd
1795*4bf8ce03SAdrian Chadd DELAY(20);
1796*4bf8ce03SAdrian Chadd
1797*4bf8ce03SAdrian Chadd return (val & RGE_EPHYAR_DATA_MASK);
1798*4bf8ce03SAdrian Chadd }
1799*4bf8ce03SAdrian Chadd
1800*4bf8ce03SAdrian Chadd static uint16_t
rge_check_ephy_ext_add(struct rge_softc * sc,uint16_t reg)1801*4bf8ce03SAdrian Chadd rge_check_ephy_ext_add(struct rge_softc *sc, uint16_t reg)
1802*4bf8ce03SAdrian Chadd {
1803*4bf8ce03SAdrian Chadd uint16_t val;
1804*4bf8ce03SAdrian Chadd
1805*4bf8ce03SAdrian Chadd val = (reg >> 12);
1806*4bf8ce03SAdrian Chadd rge_write_ephy(sc, RGE_EPHYAR_EXT_ADDR, val);
1807*4bf8ce03SAdrian Chadd
1808*4bf8ce03SAdrian Chadd return reg & 0x0fff;
1809*4bf8ce03SAdrian Chadd }
1810*4bf8ce03SAdrian Chadd
1811*4bf8ce03SAdrian Chadd static void
rge_r27_write_ephy(struct rge_softc * sc,uint16_t reg,uint16_t val)1812*4bf8ce03SAdrian Chadd rge_r27_write_ephy(struct rge_softc *sc, uint16_t reg, uint16_t val)
1813*4bf8ce03SAdrian Chadd {
1814*4bf8ce03SAdrian Chadd rge_write_ephy(sc, rge_check_ephy_ext_add(sc, reg), val);
1815*4bf8ce03SAdrian Chadd }
1816*4bf8ce03SAdrian Chadd
1817*4bf8ce03SAdrian Chadd void
rge_write_phy(struct rge_softc * sc,uint16_t addr,uint16_t reg,uint16_t val)1818*4bf8ce03SAdrian Chadd rge_write_phy(struct rge_softc *sc, uint16_t addr, uint16_t reg, uint16_t val)
1819*4bf8ce03SAdrian Chadd {
1820*4bf8ce03SAdrian Chadd uint16_t off, phyaddr;
1821*4bf8ce03SAdrian Chadd
1822*4bf8ce03SAdrian Chadd phyaddr = addr ? addr : RGE_PHYBASE + (reg / 8);
1823*4bf8ce03SAdrian Chadd phyaddr <<= 4;
1824*4bf8ce03SAdrian Chadd
1825*4bf8ce03SAdrian Chadd off = addr ? reg : 0x10 + (reg % 8);
1826*4bf8ce03SAdrian Chadd
1827*4bf8ce03SAdrian Chadd phyaddr += (off - 16) << 1;
1828*4bf8ce03SAdrian Chadd
1829*4bf8ce03SAdrian Chadd rge_write_phy_ocp(sc, phyaddr, val);
1830*4bf8ce03SAdrian Chadd }
1831*4bf8ce03SAdrian Chadd
1832*4bf8ce03SAdrian Chadd uint16_t
rge_read_phy(struct rge_softc * sc,uint16_t addr,uint16_t reg)1833*4bf8ce03SAdrian Chadd rge_read_phy(struct rge_softc *sc, uint16_t addr, uint16_t reg)
1834*4bf8ce03SAdrian Chadd {
1835*4bf8ce03SAdrian Chadd uint16_t off, phyaddr;
1836*4bf8ce03SAdrian Chadd
1837*4bf8ce03SAdrian Chadd phyaddr = addr ? addr : RGE_PHYBASE + (reg / 8);
1838*4bf8ce03SAdrian Chadd phyaddr <<= 4;
1839*4bf8ce03SAdrian Chadd
1840*4bf8ce03SAdrian Chadd off = addr ? reg : 0x10 + (reg % 8);
1841*4bf8ce03SAdrian Chadd
1842*4bf8ce03SAdrian Chadd phyaddr += (off - 16) << 1;
1843*4bf8ce03SAdrian Chadd
1844*4bf8ce03SAdrian Chadd return (rge_read_phy_ocp(sc, phyaddr));
1845*4bf8ce03SAdrian Chadd }
1846*4bf8ce03SAdrian Chadd
1847*4bf8ce03SAdrian Chadd void
rge_write_phy_ocp(struct rge_softc * sc,uint16_t reg,uint16_t val)1848*4bf8ce03SAdrian Chadd rge_write_phy_ocp(struct rge_softc *sc, uint16_t reg, uint16_t val)
1849*4bf8ce03SAdrian Chadd {
1850*4bf8ce03SAdrian Chadd uint32_t tmp;
1851*4bf8ce03SAdrian Chadd int i;
1852*4bf8ce03SAdrian Chadd
1853*4bf8ce03SAdrian Chadd tmp = (reg >> 1) << RGE_PHYOCP_ADDR_SHIFT;
1854*4bf8ce03SAdrian Chadd tmp |= RGE_PHYOCP_BUSY | val;
1855*4bf8ce03SAdrian Chadd RGE_WRITE_4(sc, RGE_PHYOCP, tmp);
1856*4bf8ce03SAdrian Chadd
1857*4bf8ce03SAdrian Chadd for (i = 0; i < 20000; i++) {
1858*4bf8ce03SAdrian Chadd DELAY(1);
1859*4bf8ce03SAdrian Chadd if (!(RGE_READ_4(sc, RGE_PHYOCP) & RGE_PHYOCP_BUSY))
1860*4bf8ce03SAdrian Chadd break;
1861*4bf8ce03SAdrian Chadd }
1862*4bf8ce03SAdrian Chadd }
1863*4bf8ce03SAdrian Chadd
1864*4bf8ce03SAdrian Chadd uint16_t
rge_read_phy_ocp(struct rge_softc * sc,uint16_t reg)1865*4bf8ce03SAdrian Chadd rge_read_phy_ocp(struct rge_softc *sc, uint16_t reg)
1866*4bf8ce03SAdrian Chadd {
1867*4bf8ce03SAdrian Chadd uint32_t val;
1868*4bf8ce03SAdrian Chadd int i;
1869*4bf8ce03SAdrian Chadd
1870*4bf8ce03SAdrian Chadd val = (reg >> 1) << RGE_PHYOCP_ADDR_SHIFT;
1871*4bf8ce03SAdrian Chadd RGE_WRITE_4(sc, RGE_PHYOCP, val);
1872*4bf8ce03SAdrian Chadd
1873*4bf8ce03SAdrian Chadd for (i = 0; i < 20000; i++) {
1874*4bf8ce03SAdrian Chadd DELAY(1);
1875*4bf8ce03SAdrian Chadd val = RGE_READ_4(sc, RGE_PHYOCP);
1876*4bf8ce03SAdrian Chadd if (val & RGE_PHYOCP_BUSY)
1877*4bf8ce03SAdrian Chadd break;
1878*4bf8ce03SAdrian Chadd }
1879*4bf8ce03SAdrian Chadd
1880*4bf8ce03SAdrian Chadd return (val & RGE_PHYOCP_DATA_MASK);
1881*4bf8ce03SAdrian Chadd }
1882*4bf8ce03SAdrian Chadd
1883*4bf8ce03SAdrian Chadd int
rge_get_link_status(struct rge_softc * sc)1884*4bf8ce03SAdrian Chadd rge_get_link_status(struct rge_softc *sc)
1885*4bf8ce03SAdrian Chadd {
1886*4bf8ce03SAdrian Chadd return ((RGE_READ_2(sc, RGE_PHYSTAT) & RGE_PHYSTAT_LINK) ? 1 : 0);
1887*4bf8ce03SAdrian Chadd }
1888*4bf8ce03SAdrian Chadd
1889*4bf8ce03SAdrian Chadd #if 0
1890*4bf8ce03SAdrian Chadd #ifndef SMALL_KERNEL
1891*4bf8ce03SAdrian Chadd int
1892*4bf8ce03SAdrian Chadd rge_wol(struct ifnet *ifp, int enable)
1893*4bf8ce03SAdrian Chadd {
1894*4bf8ce03SAdrian Chadd struct rge_softc *sc = ifp->if_softc;
1895*4bf8ce03SAdrian Chadd
1896*4bf8ce03SAdrian Chadd if (enable) {
1897*4bf8ce03SAdrian Chadd if (!(RGE_READ_1(sc, RGE_CFG1) & RGE_CFG1_PM_EN)) {
1898*4bf8ce03SAdrian Chadd printf("%s: power management is disabled, "
1899*4bf8ce03SAdrian Chadd "cannot do WOL\n", sc->sc_dev.dv_xname);
1900*4bf8ce03SAdrian Chadd return (ENOTSUP);
1901*4bf8ce03SAdrian Chadd }
1902*4bf8ce03SAdrian Chadd
1903*4bf8ce03SAdrian Chadd }
1904*4bf8ce03SAdrian Chadd
1905*4bf8ce03SAdrian Chadd rge_iff(sc);
1906*4bf8ce03SAdrian Chadd
1907*4bf8ce03SAdrian Chadd if (enable)
1908*4bf8ce03SAdrian Chadd RGE_MAC_SETBIT(sc, 0xc0b6, 0x0001);
1909*4bf8ce03SAdrian Chadd else
1910*4bf8ce03SAdrian Chadd RGE_MAC_CLRBIT(sc, 0xc0b6, 0x0001);
1911*4bf8ce03SAdrian Chadd
1912*4bf8ce03SAdrian Chadd RGE_SETBIT_1(sc, RGE_EECMD, RGE_EECMD_WRITECFG);
1913*4bf8ce03SAdrian Chadd RGE_CLRBIT_1(sc, RGE_CFG5, RGE_CFG5_WOL_LANWAKE | RGE_CFG5_WOL_UCAST |
1914*4bf8ce03SAdrian Chadd RGE_CFG5_WOL_MCAST | RGE_CFG5_WOL_BCAST);
1915*4bf8ce03SAdrian Chadd RGE_CLRBIT_1(sc, RGE_CFG3, RGE_CFG3_WOL_LINK | RGE_CFG3_WOL_MAGIC);
1916*4bf8ce03SAdrian Chadd if (enable)
1917*4bf8ce03SAdrian Chadd RGE_SETBIT_1(sc, RGE_CFG5, RGE_CFG5_WOL_LANWAKE);
1918*4bf8ce03SAdrian Chadd RGE_CLRBIT_1(sc, RGE_EECMD, RGE_EECMD_WRITECFG);
1919*4bf8ce03SAdrian Chadd
1920*4bf8ce03SAdrian Chadd return (0);
1921*4bf8ce03SAdrian Chadd }
1922*4bf8ce03SAdrian Chadd
1923*4bf8ce03SAdrian Chadd void
1924*4bf8ce03SAdrian Chadd rge_wol_power(struct rge_softc *sc)
1925*4bf8ce03SAdrian Chadd {
1926*4bf8ce03SAdrian Chadd /* Disable RXDV gate. */
1927*4bf8ce03SAdrian Chadd RGE_CLRBIT_1(sc, RGE_PPSW, 0x08);
1928*4bf8ce03SAdrian Chadd DELAY(2000);
1929*4bf8ce03SAdrian Chadd
1930*4bf8ce03SAdrian Chadd RGE_SETBIT_1(sc, RGE_CFG1, RGE_CFG1_PM_EN);
1931*4bf8ce03SAdrian Chadd RGE_SETBIT_1(sc, RGE_CFG2, RGE_CFG2_PMSTS_EN);
1932*4bf8ce03SAdrian Chadd }
1933*4bf8ce03SAdrian Chadd #endif
1934*4bf8ce03SAdrian Chadd
1935*4bf8ce03SAdrian Chadd #endif
1936