igphy.c revision 1.3.2.3 1 1.3.2.3 skrll /* $NetBSD: igphy.c,v 1.3.2.3 2004/08/25 06:58:05 skrll Exp $ */
2 1.3.2.2 skrll
3 1.3.2.2 skrll /*
4 1.3.2.2 skrll * The Intel copyright applies to the analog register setup, and the
5 1.3.2.2 skrll * (currently disabled) SmartSpeed workaround code.
6 1.3.2.2 skrll */
7 1.3.2.2 skrll
8 1.3.2.2 skrll /*******************************************************************************
9 1.3.2.2 skrll
10 1.3.2.2 skrll Copyright (c) 2001-2003, Intel Corporation
11 1.3.2.2 skrll All rights reserved.
12 1.3.2.2 skrll
13 1.3.2.2 skrll Redistribution and use in source and binary forms, with or without
14 1.3.2.2 skrll modification, are permitted provided that the following conditions are met:
15 1.3.2.2 skrll
16 1.3.2.2 skrll 1. Redistributions of source code must retain the above copyright notice,
17 1.3.2.2 skrll this list of conditions and the following disclaimer.
18 1.3.2.2 skrll
19 1.3.2.2 skrll 2. Redistributions in binary form must reproduce the above copyright
20 1.3.2.2 skrll notice, this list of conditions and the following disclaimer in the
21 1.3.2.2 skrll documentation and/or other materials provided with the distribution.
22 1.3.2.2 skrll
23 1.3.2.2 skrll 3. Neither the name of the Intel Corporation nor the names of its
24 1.3.2.2 skrll contributors may be used to endorse or promote products derived from
25 1.3.2.2 skrll this software without specific prior written permission.
26 1.3.2.2 skrll
27 1.3.2.2 skrll THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28 1.3.2.2 skrll AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 1.3.2.2 skrll IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 1.3.2.2 skrll ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31 1.3.2.2 skrll LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 1.3.2.2 skrll CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 1.3.2.2 skrll SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 1.3.2.2 skrll INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 1.3.2.2 skrll CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 1.3.2.2 skrll ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 1.3.2.2 skrll POSSIBILITY OF SUCH DAMAGE.
38 1.3.2.2 skrll
39 1.3.2.2 skrll *******************************************************************************/
40 1.3.2.2 skrll
41 1.3.2.2 skrll
42 1.3.2.2 skrll /*-
43 1.3.2.2 skrll * Copyright (c) 1998, 1999, 2000, 2003 The NetBSD Foundation, Inc.
44 1.3.2.2 skrll * All rights reserved.
45 1.3.2.2 skrll *
46 1.3.2.2 skrll * This code is derived from software contributed to The NetBSD Foundation
47 1.3.2.2 skrll * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
48 1.3.2.2 skrll * NASA Ames Research Center, and by Frank van der Linden.
49 1.3.2.2 skrll *
50 1.3.2.2 skrll * Redistribution and use in source and binary forms, with or without
51 1.3.2.2 skrll * modification, are permitted provided that the following conditions
52 1.3.2.2 skrll * are met:
53 1.3.2.2 skrll * 1. Redistributions of source code must retain the above copyright
54 1.3.2.2 skrll * notice, this list of conditions and the following disclaimer.
55 1.3.2.2 skrll * 2. Redistributions in binary form must reproduce the above copyright
56 1.3.2.2 skrll * notice, this list of conditions and the following disclaimer in the
57 1.3.2.2 skrll * documentation and/or other materials provided with the distribution.
58 1.3.2.2 skrll * 3. All advertising materials mentioning features or use of this software
59 1.3.2.2 skrll * must display the following acknowledgement:
60 1.3.2.2 skrll * This product includes software developed by the NetBSD
61 1.3.2.2 skrll * Foundation, Inc. and its contributors.
62 1.3.2.2 skrll * 4. Neither the name of The NetBSD Foundation nor the names of its
63 1.3.2.2 skrll * contributors may be used to endorse or promote products derived
64 1.3.2.2 skrll * from this software without specific prior written permission.
65 1.3.2.2 skrll *
66 1.3.2.2 skrll * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
67 1.3.2.2 skrll * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
68 1.3.2.2 skrll * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
69 1.3.2.2 skrll * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
70 1.3.2.2 skrll * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
71 1.3.2.2 skrll * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
72 1.3.2.2 skrll * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
73 1.3.2.2 skrll * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
74 1.3.2.2 skrll * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
75 1.3.2.2 skrll * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
76 1.3.2.2 skrll * POSSIBILITY OF SUCH DAMAGE.
77 1.3.2.2 skrll */
78 1.3.2.2 skrll
79 1.3.2.2 skrll #include <sys/cdefs.h>
80 1.3.2.3 skrll __KERNEL_RCSID(0, "$NetBSD: igphy.c,v 1.3.2.3 2004/08/25 06:58:05 skrll Exp $");
81 1.3.2.2 skrll
82 1.3.2.2 skrll #include "opt_mii.h"
83 1.3.2.2 skrll
84 1.3.2.2 skrll #include <sys/param.h>
85 1.3.2.2 skrll #include <sys/systm.h>
86 1.3.2.2 skrll #include <sys/kernel.h>
87 1.3.2.2 skrll #include <sys/device.h>
88 1.3.2.2 skrll #include <sys/socket.h>
89 1.3.2.2 skrll #include <sys/errno.h>
90 1.3.2.2 skrll
91 1.3.2.2 skrll #include <net/if.h>
92 1.3.2.2 skrll #include <net/if_media.h>
93 1.3.2.2 skrll
94 1.3.2.2 skrll #include <dev/mii/mii.h>
95 1.3.2.2 skrll #include <dev/mii/miivar.h>
96 1.3.2.2 skrll #include <dev/mii/miidevs.h>
97 1.3.2.2 skrll
98 1.3.2.2 skrll #include <dev/mii/igphyreg.h>
99 1.3.2.2 skrll
100 1.3.2.2 skrll static void igphy_reset(struct mii_softc *);
101 1.3.2.2 skrll static void igphy_load_dspcode(struct mii_softc *);
102 1.3.2.2 skrll #if 0
103 1.3.2.2 skrll static void igphy_smartspeed_workaround(struct mii_softc *sc);
104 1.3.2.2 skrll #endif
105 1.3.2.2 skrll
106 1.3.2.3 skrll static int igphymatch(struct device *, struct cfdata *, void *);
107 1.3.2.3 skrll static void igphyattach(struct device *, struct device *, void *);
108 1.3.2.2 skrll
109 1.3.2.2 skrll CFATTACH_DECL(igphy, sizeof(struct mii_softc),
110 1.3.2.2 skrll igphymatch, igphyattach, mii_phy_detach, mii_phy_activate);
111 1.3.2.2 skrll
112 1.3.2.3 skrll static int igphy_service(struct mii_softc *, struct mii_data *, int);
113 1.3.2.3 skrll static void igphy_status(struct mii_softc *);
114 1.3.2.2 skrll
115 1.3.2.3 skrll static const struct mii_phy_funcs igphy_funcs = {
116 1.3.2.2 skrll igphy_service, igphy_status, igphy_reset,
117 1.3.2.2 skrll };
118 1.3.2.2 skrll
119 1.3.2.3 skrll static const struct mii_phydesc igphys[] = {
120 1.3.2.2 skrll { MII_OUI_yyINTEL, MII_MODEL_yyINTEL_IGP01E1000,
121 1.3.2.2 skrll MII_STR_yyINTEL_IGP01E1000 },
122 1.3.2.2 skrll
123 1.3.2.2 skrll {0, 0,
124 1.3.2.2 skrll NULL },
125 1.3.2.2 skrll };
126 1.3.2.2 skrll
127 1.3.2.3 skrll static int
128 1.3.2.2 skrll igphymatch(struct device *parent, struct cfdata *match, void *aux)
129 1.3.2.2 skrll {
130 1.3.2.2 skrll struct mii_attach_args *ma = aux;
131 1.3.2.2 skrll
132 1.3.2.2 skrll if (mii_phy_match(ma, igphys) != NULL)
133 1.3.2.2 skrll return 10;
134 1.3.2.2 skrll
135 1.3.2.2 skrll return 0;
136 1.3.2.2 skrll }
137 1.3.2.2 skrll
138 1.3.2.3 skrll static void
139 1.3.2.2 skrll igphyattach(struct device *parent, struct device *self, void *aux)
140 1.3.2.2 skrll {
141 1.3.2.2 skrll struct mii_softc *sc = (struct mii_softc *)self;
142 1.3.2.2 skrll struct mii_attach_args *ma = aux;
143 1.3.2.2 skrll struct mii_data *mii = ma->mii_data;
144 1.3.2.2 skrll const struct mii_phydesc *mpd;
145 1.3.2.2 skrll
146 1.3.2.2 skrll mpd = mii_phy_match(ma, igphys);
147 1.3.2.2 skrll aprint_naive(": Media interface\n");
148 1.3.2.2 skrll aprint_normal(": %s, rev. %d\n", mpd->mpd_name, MII_REV(ma->mii_id2));
149 1.3.2.2 skrll
150 1.3.2.2 skrll sc->mii_inst = mii->mii_instance;
151 1.3.2.2 skrll sc->mii_phy = ma->mii_phyno;
152 1.3.2.2 skrll sc->mii_funcs = &igphy_funcs;
153 1.3.2.2 skrll sc->mii_pdata = mii;
154 1.3.2.2 skrll sc->mii_flags = ma->mii_flags;
155 1.3.2.2 skrll sc->mii_anegticks = 10;
156 1.3.2.2 skrll
157 1.3.2.2 skrll PHY_RESET(sc);
158 1.3.2.2 skrll
159 1.3.2.2 skrll sc->mii_capabilities =
160 1.3.2.2 skrll PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
161 1.3.2.2 skrll if (sc->mii_capabilities & BMSR_EXTSTAT)
162 1.3.2.2 skrll sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR);
163 1.3.2.2 skrll aprint_normal("%s: ", sc->mii_dev.dv_xname);
164 1.3.2.2 skrll if ((sc->mii_capabilities & BMSR_MEDIAMASK) == 0 &&
165 1.3.2.2 skrll (sc->mii_extcapabilities & EXTSR_MEDIAMASK) == 0)
166 1.3.2.2 skrll aprint_error("no media present");
167 1.3.2.2 skrll else
168 1.3.2.2 skrll mii_phy_add_media(sc);
169 1.3.2.2 skrll aprint_normal("\n");
170 1.3.2.2 skrll }
171 1.3.2.2 skrll
172 1.3.2.2 skrll static void
173 1.3.2.2 skrll igphy_load_dspcode(struct mii_softc *sc)
174 1.3.2.2 skrll {
175 1.3.2.2 skrll static const struct {
176 1.3.2.2 skrll int reg;
177 1.3.2.2 skrll uint16_t val;
178 1.3.2.2 skrll } dspcode[] = {
179 1.3.2.2 skrll { 0x1f95, 0x0001 },
180 1.3.2.2 skrll { 0x1f71, 0xbd21 },
181 1.3.2.2 skrll { 0x1f79, 0x0018 },
182 1.3.2.2 skrll { 0x1f30, 0x1600 },
183 1.3.2.2 skrll { 0x1f31, 0x0014 },
184 1.3.2.2 skrll { 0x1f32, 0x161c },
185 1.3.2.2 skrll { 0x1f94, 0x0003 },
186 1.3.2.2 skrll { 0x1f96, 0x003f },
187 1.3.2.2 skrll { 0x2010, 0x0008 },
188 1.3.2.2 skrll { 0, 0 },
189 1.3.2.2 skrll };
190 1.3.2.2 skrll int i;
191 1.3.2.2 skrll
192 1.3.2.2 skrll delay(10);
193 1.3.2.2 skrll
194 1.3.2.2 skrll PHY_WRITE(sc, MII_IGPHY_PAGE_SELECT, 0x0000);
195 1.3.2.2 skrll PHY_WRITE(sc, 0x0000, 0x0140);
196 1.3.2.2 skrll
197 1.3.2.2 skrll delay(5);
198 1.3.2.2 skrll
199 1.3.2.2 skrll for (i = 0; dspcode[i].reg != 0; i++)
200 1.3.2.2 skrll IGPHY_WRITE(sc, dspcode[i].reg, dspcode[i].val);
201 1.3.2.2 skrll
202 1.3.2.2 skrll PHY_WRITE(sc, MII_IGPHY_PAGE_SELECT,0x0000);
203 1.3.2.2 skrll PHY_WRITE(sc, 0x0000, 0x3300);
204 1.3.2.2 skrll }
205 1.3.2.2 skrll
206 1.3.2.2 skrll static void
207 1.3.2.2 skrll igphy_reset(struct mii_softc *sc)
208 1.3.2.2 skrll {
209 1.3.2.2 skrll uint16_t fused, fine, coarse;
210 1.3.2.2 skrll
211 1.3.2.2 skrll mii_phy_reset(sc);
212 1.3.2.2 skrll igphy_load_dspcode(sc);
213 1.3.2.2 skrll
214 1.3.2.2 skrll fused = IGPHY_READ(sc, MII_IGPHY_ANALOG_SPARE_FUSE_STATUS);
215 1.3.2.2 skrll if ((fused & ANALOG_SPARE_FUSE_ENABLED) == 0) {
216 1.3.2.2 skrll fused = IGPHY_READ(sc, MII_IGPHY_ANALOG_FUSE_STATUS);
217 1.3.2.2 skrll
218 1.3.2.2 skrll fine = fused & ANALOG_FUSE_FINE_MASK;
219 1.3.2.2 skrll coarse = fused & ANALOG_FUSE_COARSE_MASK;
220 1.3.2.2 skrll
221 1.3.2.2 skrll if (coarse > ANALOG_FUSE_COARSE_THRESH) {
222 1.3.2.2 skrll coarse -= ANALOG_FUSE_COARSE_10;
223 1.3.2.2 skrll fine -= ANALOG_FUSE_FINE_1;
224 1.3.2.2 skrll } else if (coarse == ANALOG_FUSE_COARSE_THRESH)
225 1.3.2.2 skrll fine -= ANALOG_FUSE_FINE_10;
226 1.3.2.2 skrll
227 1.3.2.2 skrll fused = (fused & ANALOG_FUSE_POLY_MASK) |
228 1.3.2.2 skrll (fine & ANALOG_FUSE_FINE_MASK) |
229 1.3.2.2 skrll (coarse & ANALOG_FUSE_COARSE_MASK);
230 1.3.2.2 skrll
231 1.3.2.2 skrll IGPHY_WRITE(sc, MII_IGPHY_ANALOG_FUSE_CONTROL, fused);
232 1.3.2.2 skrll IGPHY_WRITE(sc, MII_IGPHY_ANALOG_FUSE_BYPASS,
233 1.3.2.2 skrll ANALOG_FUSE_ENABLE_SW_CONTROL);
234 1.3.2.2 skrll }
235 1.3.2.2 skrll PHY_WRITE(sc, MII_IGPHY_PAGE_SELECT,0x0000);
236 1.3.2.2 skrll }
237 1.3.2.2 skrll
238 1.3.2.2 skrll
239 1.3.2.3 skrll static int
240 1.3.2.2 skrll igphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
241 1.3.2.2 skrll {
242 1.3.2.2 skrll struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
243 1.3.2.2 skrll uint16_t reg;
244 1.3.2.2 skrll
245 1.3.2.2 skrll switch (cmd) {
246 1.3.2.2 skrll case MII_POLLSTAT:
247 1.3.2.2 skrll /*
248 1.3.2.2 skrll * If we're not polling our PHY instance, just return.
249 1.3.2.2 skrll */
250 1.3.2.2 skrll if (IFM_INST(ife->ifm_media) != sc->mii_inst)
251 1.3.2.2 skrll return (0);
252 1.3.2.2 skrll break;
253 1.3.2.2 skrll
254 1.3.2.2 skrll case MII_MEDIACHG:
255 1.3.2.2 skrll /*
256 1.3.2.2 skrll * If the media indicates a different PHY instance,
257 1.3.2.2 skrll * isolate ourselves.
258 1.3.2.2 skrll */
259 1.3.2.2 skrll if (IFM_INST(ife->ifm_media) != sc->mii_inst) {
260 1.3.2.2 skrll reg = PHY_READ(sc, MII_BMCR);
261 1.3.2.2 skrll PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO);
262 1.3.2.2 skrll return (0);
263 1.3.2.2 skrll }
264 1.3.2.2 skrll
265 1.3.2.2 skrll /*
266 1.3.2.2 skrll * If the interface is not up, don't do anything.
267 1.3.2.2 skrll */
268 1.3.2.2 skrll if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
269 1.3.2.2 skrll break;
270 1.3.2.2 skrll
271 1.3.2.2 skrll mii_phy_setmedia(sc);
272 1.3.2.2 skrll break;
273 1.3.2.2 skrll
274 1.3.2.2 skrll case MII_TICK:
275 1.3.2.2 skrll /*
276 1.3.2.2 skrll * If we're not currently selected, just return.
277 1.3.2.2 skrll */
278 1.3.2.2 skrll if (IFM_INST(ife->ifm_media) != sc->mii_inst)
279 1.3.2.2 skrll return (0);
280 1.3.2.2 skrll
281 1.3.2.2 skrll #if 0
282 1.3.2.2 skrll igphy_smartspeed_workaround(sc);
283 1.3.2.2 skrll #endif
284 1.3.2.2 skrll
285 1.3.2.2 skrll if (mii_phy_tick(sc) == EJUSTRETURN)
286 1.3.2.2 skrll return (0);
287 1.3.2.2 skrll break;
288 1.3.2.2 skrll
289 1.3.2.2 skrll case MII_DOWN:
290 1.3.2.2 skrll mii_phy_down(sc);
291 1.3.2.2 skrll return (0);
292 1.3.2.2 skrll }
293 1.3.2.2 skrll
294 1.3.2.2 skrll /* Update the media status. */
295 1.3.2.2 skrll mii_phy_status(sc);
296 1.3.2.2 skrll
297 1.3.2.2 skrll /* Callback if something changed. */
298 1.3.2.2 skrll mii_phy_update(sc, cmd);
299 1.3.2.2 skrll return (0);
300 1.3.2.2 skrll }
301 1.3.2.2 skrll
302 1.3.2.2 skrll
303 1.3.2.3 skrll static void
304 1.3.2.2 skrll igphy_status(struct mii_softc *sc)
305 1.3.2.2 skrll {
306 1.3.2.2 skrll struct mii_data *mii = sc->mii_pdata;
307 1.3.2.2 skrll struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
308 1.3.2.2 skrll uint16_t bmcr, pssr, gtsr, bmsr;
309 1.3.2.2 skrll
310 1.3.2.2 skrll mii->mii_media_status = IFM_AVALID;
311 1.3.2.2 skrll mii->mii_media_active = IFM_ETHER;
312 1.3.2.2 skrll
313 1.3.2.2 skrll pssr = PHY_READ(sc, MII_IGPHY_PORT_STATUS);
314 1.3.2.2 skrll
315 1.3.2.2 skrll if (pssr & PSSR_LINK_UP)
316 1.3.2.2 skrll mii->mii_media_status |= IFM_ACTIVE;
317 1.3.2.2 skrll
318 1.3.2.2 skrll bmcr = PHY_READ(sc, MII_BMCR);
319 1.3.2.2 skrll if (bmcr & BMCR_ISO) {
320 1.3.2.2 skrll mii->mii_media_active |= IFM_NONE;
321 1.3.2.2 skrll mii->mii_media_status = 0;
322 1.3.2.2 skrll return;
323 1.3.2.2 skrll }
324 1.3.2.2 skrll
325 1.3.2.2 skrll if (bmcr & BMCR_LOOP)
326 1.3.2.2 skrll mii->mii_media_active |= IFM_LOOP;
327 1.3.2.2 skrll
328 1.3.2.2 skrll bmsr = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR);
329 1.3.2.2 skrll
330 1.3.2.2 skrll /*
331 1.3.2.2 skrll * XXX can't check if the info is valid, no
332 1.3.2.2 skrll * 'negotiation done' bit?
333 1.3.2.2 skrll */
334 1.3.2.2 skrll if (bmcr & BMCR_AUTOEN) {
335 1.3.2.2 skrll if ((bmsr & BMSR_ACOMP) == 0) {
336 1.3.2.2 skrll mii->mii_media_active |= IFM_NONE;
337 1.3.2.2 skrll return;
338 1.3.2.2 skrll }
339 1.3.2.2 skrll switch (pssr & PSSR_SPEED_MASK) {
340 1.3.2.2 skrll case PSSR_SPEED_1000MBPS:
341 1.3.2.2 skrll mii->mii_media_active |= IFM_1000_T;
342 1.3.2.2 skrll gtsr = PHY_READ(sc, MII_100T2SR);
343 1.3.2.2 skrll if (gtsr & GTSR_MS_RES)
344 1.3.2.2 skrll mii->mii_media_active |= IFM_ETH_MASTER;
345 1.3.2.2 skrll break;
346 1.3.2.2 skrll
347 1.3.2.2 skrll case PSSR_SPEED_100MBPS:
348 1.3.2.2 skrll mii->mii_media_active |= IFM_100_TX;
349 1.3.2.2 skrll break;
350 1.3.2.2 skrll
351 1.3.2.2 skrll case PSSR_SPEED_10MBPS:
352 1.3.2.2 skrll mii->mii_media_active |= IFM_10_T;
353 1.3.2.2 skrll break;
354 1.3.2.2 skrll
355 1.3.2.2 skrll default:
356 1.3.2.2 skrll mii->mii_media_active |= IFM_NONE;
357 1.3.2.2 skrll mii->mii_media_status = 0;
358 1.3.2.2 skrll return;
359 1.3.2.2 skrll }
360 1.3.2.2 skrll
361 1.3.2.2 skrll if (pssr & PSSR_FULL_DUPLEX)
362 1.3.2.2 skrll mii->mii_media_active |=
363 1.3.2.2 skrll IFM_FDX | mii_phy_flowstatus(sc);
364 1.3.2.2 skrll } else
365 1.3.2.2 skrll mii->mii_media_active = ife->ifm_media;
366 1.3.2.2 skrll }
367 1.3.2.2 skrll
368 1.3.2.2 skrll #if 0
369 1.3.2.2 skrll static void
370 1.3.2.2 skrll igphy_smartspeed_workaround(struct mii_softc *sc)
371 1.3.2.2 skrll {
372 1.3.2.2 skrll uint16_t reg, gtsr, gctr;
373 1.3.2.2 skrll
374 1.3.2.2 skrll reg = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR);
375 1.3.2.2 skrll if (!(reg & BMSR_LINK)) {
376 1.3.2.2 skrll switch (sc->mii_ticks) {
377 1.3.2.2 skrll case 0:
378 1.3.2.2 skrll gtsr = PHY_READ(sc, MII_100T2SR);
379 1.3.2.2 skrll if (!(gtsr & GTSR_MAN_MS_FLT))
380 1.3.2.2 skrll break;
381 1.3.2.2 skrll gtsr = PHY_READ(sc, MII_100T2SR);
382 1.3.2.2 skrll if (gtsr & GTSR_MAN_MS_FLT) {
383 1.3.2.2 skrll gtcr = PHY_READ(sc, MII_100T2CR);
384 1.3.2.2 skrll if (gtcr & GTCR_MAN_MS) {
385 1.3.2.2 skrll gtcr &= ~GTCR_MAN_MS;
386 1.3.2.2 skrll PHY_WRITE(sc, MII_100T2CR,
387 1.3.2.2 skrll gtcr);
388 1.3.2.2 skrll }
389 1.3.2.2 skrll mii_phy_auto(sc, 0);
390 1.3.2.2 skrll sc->mii_ticks++;
391 1.3.2.2 skrll }
392 1.3.2.2 skrll break;
393 1.3.2.2 skrll case IGPHY_TICK_DOWNSHIFT:
394 1.3.2.2 skrll gtcr = PHY_READ(sc, MII_100T2CR);
395 1.3.2.2 skrll gtcr |= GTCR_MAN_MS;
396 1.3.2.2 skrll PHY_WRITE(sc, MII_100T2CR, gtcr);
397 1.3.2.2 skrll mii_phy_auto(sc, 0);
398 1.3.2.2 skrll break;
399 1.3.2.2 skrll default:
400 1.3.2.2 skrll break;
401 1.3.2.2 skrll }
402 1.3.2.2 skrll }
403 1.3.2.2 skrll }
404 1.3.2.2 skrll #endif
405