Deleted Added
full compact
rgephy.c (164827) rgephy.c (164830)
1/*-
2 * Copyright (c) 2003
3 * Bill Paul <wpaul@windriver.com>. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 17 unchanged lines hidden (view full) ---

26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2003
3 * Bill Paul <wpaul@windriver.com>. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 17 unchanged lines hidden (view full) ---

26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: head/sys/dev/mii/rgephy.c 164827 2006-12-02 15:32:34Z marius $");
34__FBSDID("$FreeBSD: head/sys/dev/mii/rgephy.c 164830 2006-12-02 19:36:25Z marius $");
35
36/*
37 * Driver for the RealTek 8169S/8110S internal 10/100/1000 PHY.
38 */
39
40#include <sys/param.h>
41#include <sys/systm.h>
42#include <sys/kernel.h>
43#include <sys/module.h>
44#include <sys/socket.h>
45#include <sys/bus.h>
46
35
36/*
37 * Driver for the RealTek 8169S/8110S internal 10/100/1000 PHY.
38 */
39
40#include <sys/param.h>
41#include <sys/systm.h>
42#include <sys/kernel.h>
43#include <sys/module.h>
44#include <sys/socket.h>
45#include <sys/bus.h>
46
47
48#include <net/if.h>
49#include <net/if_arp.h>
50#include <net/if_media.h>
51
52#include <dev/mii/mii.h>
53#include <dev/mii/miivar.h>
54#include "miidevs.h"
55

--- 27 unchanged lines hidden (view full) ---

83DRIVER_MODULE(rgephy, miibus, rgephy_driver, rgephy_devclass, 0, 0);
84
85static int rgephy_service(struct mii_softc *, struct mii_data *, int);
86static void rgephy_status(struct mii_softc *);
87static int rgephy_mii_phy_auto(struct mii_softc *);
88static void rgephy_reset(struct mii_softc *);
89static void rgephy_loop(struct mii_softc *);
90static void rgephy_load_dspcode(struct mii_softc *);
47#include <net/if.h>
48#include <net/if_arp.h>
49#include <net/if_media.h>
50
51#include <dev/mii/mii.h>
52#include <dev/mii/miivar.h>
53#include "miidevs.h"
54

--- 27 unchanged lines hidden (view full) ---

82DRIVER_MODULE(rgephy, miibus, rgephy_driver, rgephy_devclass, 0, 0);
83
84static int rgephy_service(struct mii_softc *, struct mii_data *, int);
85static void rgephy_status(struct mii_softc *);
86static int rgephy_mii_phy_auto(struct mii_softc *);
87static void rgephy_reset(struct mii_softc *);
88static void rgephy_loop(struct mii_softc *);
89static void rgephy_load_dspcode(struct mii_softc *);
91static int rgephy_mii_model;
92
93static const struct mii_phydesc rgephys[] = {
94 MII_PHY_DESC(xxREALTEK, RTL8169S),
95 MII_PHY_END
96};
97
98static int
99rgephy_probe(device_t dev)

--- 29 unchanged lines hidden (view full) ---

129
130 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst),
131 BMCR_ISO);
132#if 0
133 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst),
134 BMCR_LOOP|BMCR_S100);
135#endif
136
90
91static const struct mii_phydesc rgephys[] = {
92 MII_PHY_DESC(xxREALTEK, RTL8169S),
93 MII_PHY_END
94};
95
96static int
97rgephy_probe(device_t dev)

--- 29 unchanged lines hidden (view full) ---

127
128 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst),
129 BMCR_ISO);
130#if 0
131 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst),
132 BMCR_LOOP|BMCR_S100);
133#endif
134
137 rgephy_mii_model = MII_MODEL(ma->mii_id2);
138
139 sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
140 sc->mii_capabilities &= ~BMSR_ANEG;
141
142 device_printf(dev, " ");
143 mii_add_media(sc);
144 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, 0, sc->mii_inst),
145 RGEPHY_BMCR_FDX);
146 PRINT(", 1000baseTX");
147 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, IFM_FDX, sc->mii_inst), 0);
148 PRINT("1000baseTX-FDX");
149 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), 0);
150 PRINT("auto");
151
152 printf("\n");
153#undef ADD
154#undef PRINT
155
156 rgephy_reset(sc);
157 MIIBUS_MEDIAINIT(sc->mii_dev);
135 sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
136 sc->mii_capabilities &= ~BMSR_ANEG;
137
138 device_printf(dev, " ");
139 mii_add_media(sc);
140 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, 0, sc->mii_inst),
141 RGEPHY_BMCR_FDX);
142 PRINT(", 1000baseTX");
143 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, IFM_FDX, sc->mii_inst), 0);
144 PRINT("1000baseTX-FDX");
145 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), 0);
146 PRINT("auto");
147
148 printf("\n");
149#undef ADD
150#undef PRINT
151
152 rgephy_reset(sc);
153 MIIBUS_MEDIAINIT(sc->mii_dev);
158 return(0);
154 return (0);
159}
160
161static int
162rgephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
163{
164 struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
165 int reg, speed, gig, anar;
166

--- 66 unchanged lines hidden (view full) ---

233 PHY_WRITE(sc, RGEPHY_MII_1000CTL, 0);
234 PHY_WRITE(sc, RGEPHY_MII_ANAR, anar);
235 PHY_WRITE(sc, RGEPHY_MII_BMCR, speed |
236 RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG);
237 break;
238 }
239
240 /*
155}
156
157static int
158rgephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
159{
160 struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
161 int reg, speed, gig, anar;
162

--- 66 unchanged lines hidden (view full) ---

229 PHY_WRITE(sc, RGEPHY_MII_1000CTL, 0);
230 PHY_WRITE(sc, RGEPHY_MII_ANAR, anar);
231 PHY_WRITE(sc, RGEPHY_MII_BMCR, speed |
232 RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG);
233 break;
234 }
235
236 /*
241 * When settning the link manually, one side must
237 * When setting the link manually, one side must
242 * be the master and the other the slave. However
243 * ifmedia doesn't give us a good way to specify
244 * this, so we fake it by using one of the LINK
245 * flags. If LINK0 is set, we program the PHY to
246 * be a master, otherwise it's a slave.
247 */
248 if ((mii->mii_ifp->if_flags & IFF_LINK0)) {
249 PHY_WRITE(sc, RGEPHY_MII_1000CTL,

--- 42 unchanged lines hidden (view full) ---

292 */
293 reg = PHY_READ(sc, RL_GMEDIASTAT);
294 if (reg & RL_GMEDIASTAT_LINK)
295 break;
296
297 /*
298 * Only retry autonegotiation every 5 seconds.
299 */
238 * be the master and the other the slave. However
239 * ifmedia doesn't give us a good way to specify
240 * this, so we fake it by using one of the LINK
241 * flags. If LINK0 is set, we program the PHY to
242 * be a master, otherwise it's a slave.
243 */
244 if ((mii->mii_ifp->if_flags & IFF_LINK0)) {
245 PHY_WRITE(sc, RGEPHY_MII_1000CTL,

--- 42 unchanged lines hidden (view full) ---

288 */
289 reg = PHY_READ(sc, RL_GMEDIASTAT);
290 if (reg & RL_GMEDIASTAT_LINK)
291 break;
292
293 /*
294 * Only retry autonegotiation every 5 seconds.
295 */
300 if (++sc->mii_ticks <= 5/*10*/)
296 if (++sc->mii_ticks <= MII_ANEGTICKS)
301 break;
297 break;
302
298
303 sc->mii_ticks = 0;
304 rgephy_mii_phy_auto(sc);
305 return (0);
306 }
307
308 /* Update the media status. */
309 rgephy_status(sc);
310
311 /*
312 * Callback if something changed. Note that we need to poke
313 * the DSP on the RealTek PHYs if the media changes.
314 *
315 */
299 sc->mii_ticks = 0;
300 rgephy_mii_phy_auto(sc);
301 return (0);
302 }
303
304 /* Update the media status. */
305 rgephy_status(sc);
306
307 /*
308 * Callback if something changed. Note that we need to poke
309 * the DSP on the RealTek PHYs if the media changes.
310 *
311 */
316 if (sc->mii_media_active != mii->mii_media_active ||
312 if (sc->mii_media_active != mii->mii_media_active ||
317 sc->mii_media_status != mii->mii_media_status ||
318 cmd == MII_MEDIACHG) {
319 rgephy_load_dspcode(sc);
320 }
321 mii_phy_update(sc, cmd);
322 return (0);
323}
324

--- 31 unchanged lines hidden (view full) ---

356 else if (bmsr & RL_GMEDIASTAT_100MBPS)
357 mii->mii_media_active |= IFM_100_TX;
358 else if (bmsr & RL_GMEDIASTAT_10MBPS)
359 mii->mii_media_active |= IFM_10_T;
360 else
361 mii->mii_media_active |= IFM_NONE;
362 if (bmsr & RL_GMEDIASTAT_FDX)
363 mii->mii_media_active |= IFM_FDX;
313 sc->mii_media_status != mii->mii_media_status ||
314 cmd == MII_MEDIACHG) {
315 rgephy_load_dspcode(sc);
316 }
317 mii_phy_update(sc, cmd);
318 return (0);
319}
320

--- 31 unchanged lines hidden (view full) ---

352 else if (bmsr & RL_GMEDIASTAT_100MBPS)
353 mii->mii_media_active |= IFM_100_TX;
354 else if (bmsr & RL_GMEDIASTAT_10MBPS)
355 mii->mii_media_active |= IFM_10_T;
356 else
357 mii->mii_media_active |= IFM_NONE;
358 if (bmsr & RL_GMEDIASTAT_FDX)
359 mii->mii_media_active |= IFM_FDX;
364
365 return;
366}
367
360}
361
368
369static int
370rgephy_mii_phy_auto(struct mii_softc *mii)
371{
362static int
363rgephy_mii_phy_auto(struct mii_softc *mii)
364{
365
372 rgephy_loop(mii);
373 rgephy_reset(mii);
374
375 PHY_WRITE(mii, RGEPHY_MII_ANAR,
376 BMSR_MEDIA_TO_ANAR(mii->mii_capabilities) | ANAR_CSMA);
377 DELAY(1000);
378 PHY_WRITE(mii, RGEPHY_MII_1000CTL,
379 RGEPHY_1000CTL_AHD|RGEPHY_1000CTL_AFD);
380 DELAY(1000);
381 PHY_WRITE(mii, RGEPHY_MII_BMCR,
382 RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG);
383 DELAY(100);
384
385 return (EJUSTRETURN);
386}
387
388static void
389rgephy_loop(struct mii_softc *sc)
390{
366 rgephy_loop(mii);
367 rgephy_reset(mii);
368
369 PHY_WRITE(mii, RGEPHY_MII_ANAR,
370 BMSR_MEDIA_TO_ANAR(mii->mii_capabilities) | ANAR_CSMA);
371 DELAY(1000);
372 PHY_WRITE(mii, RGEPHY_MII_1000CTL,
373 RGEPHY_1000CTL_AHD|RGEPHY_1000CTL_AFD);
374 DELAY(1000);
375 PHY_WRITE(mii, RGEPHY_MII_BMCR,
376 RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG);
377 DELAY(100);
378
379 return (EJUSTRETURN);
380}
381
382static void
383rgephy_loop(struct mii_softc *sc)
384{
391 u_int32_t bmsr;
392 int i;
393
394 PHY_WRITE(sc, RGEPHY_MII_BMCR, RGEPHY_BMCR_PDOWN);
395 DELAY(1000);
396
397 for (i = 0; i < 15000; i++) {
385 int i;
386
387 PHY_WRITE(sc, RGEPHY_MII_BMCR, RGEPHY_BMCR_PDOWN);
388 DELAY(1000);
389
390 for (i = 0; i < 15000; i++) {
398 bmsr = PHY_READ(sc, RGEPHY_MII_BMSR);
399 if (!(bmsr & RGEPHY_BMSR_LINK)) {
391 if (!(PHY_READ(sc, RGEPHY_MII_BMSR) & RGEPHY_BMSR_LINK)) {
400#if 0
401 device_printf(sc->mii_dev, "looped %d\n", i);
402#endif
403 break;
404 }
405 DELAY(10);
406 }
407}

--- 55 unchanged lines hidden (view full) ---

463 PHY_WRITE(sc, 4, val);
464 PHY_WRITE(sc, 3, 0xDF01);
465 PHY_WRITE(sc, 2, 0xDF20);
466 PHY_WRITE(sc, 1, 0xFF95);
467 PHY_WRITE(sc, 0, 0xBF00);
468 PHY_SETBIT(sc, 4, 0x0800);
469 PHY_CLRBIT(sc, 4, 0x0800);
470 PHY_WRITE(sc, 31, 0x0000);
392#if 0
393 device_printf(sc->mii_dev, "looped %d\n", i);
394#endif
395 break;
396 }
397 DELAY(10);
398 }
399}

--- 55 unchanged lines hidden (view full) ---

455 PHY_WRITE(sc, 4, val);
456 PHY_WRITE(sc, 3, 0xDF01);
457 PHY_WRITE(sc, 2, 0xDF20);
458 PHY_WRITE(sc, 1, 0xFF95);
459 PHY_WRITE(sc, 0, 0xBF00);
460 PHY_SETBIT(sc, 4, 0x0800);
461 PHY_CLRBIT(sc, 4, 0x0800);
462 PHY_WRITE(sc, 31, 0x0000);
471
463
472 DELAY(40);
473}
474
475static void
476rgephy_reset(struct mii_softc *sc)
477{
464 DELAY(40);
465}
466
467static void
468rgephy_reset(struct mii_softc *sc)
469{
470
478 mii_phy_reset(sc);
479 DELAY(1000);
480 rgephy_load_dspcode(sc);
471 mii_phy_reset(sc);
472 DELAY(1000);
473 rgephy_load_dspcode(sc);
481
482 return;
483}
474}