3 mii.c: MII interface library
5 Maintained by Jeff Garzik <jgarzik@pobox.com>
6 Copyright 2001,2002 Jeff Garzik
8 Various code came from myson803.c and other files by
9 Donald Becker. Copyright:
11 Written 1998-2002 by Donald Becker.
13 This software may be used and distributed according
14 to the terms of the GNU General Public License (GPL),
15 incorporated herein by reference. Drivers based on
16 or derived from this code fall under the GPL and must
17 retain the authorship, copyright and license notice.
18 This file is not a complete program and may only be
19 used when the entire operating system is licensed
22 The author may be reached as becker@scyld.com, or C/O
23 Scyld Computing Corporation
24 410 Severn Ave., Suite 210
30 #include <linux/kernel.h>
31 #include <linux/module.h>
32 #include <linux/netdevice.h>
33 #include <linux/ethtool.h>
34 #include <linux/mii.h>
36 static u32
mii_get_an(struct mii_if_info
*mii
, u16 addr
)
40 advert
= mii
->mdio_read(mii
->dev
, mii
->phy_id
, addr
);
42 return mii_lpa_to_ethtool_lpa_t(advert
);
46 * mii_ethtool_gset - get settings that are specified in @ecmd
48 * @ecmd: requested ethtool_cmd
50 * The @ecmd parameter is expected to have been cleared before calling
53 * Returns 0 for success, negative on error.
55 int mii_ethtool_gset(struct mii_if_info
*mii
, struct ethtool_cmd
*ecmd
)
57 struct net_device
*dev
= mii
->dev
;
58 u16 bmcr
, bmsr
, ctrl1000
= 0, stat1000
= 0;
62 (SUPPORTED_10baseT_Half
| SUPPORTED_10baseT_Full
|
63 SUPPORTED_100baseT_Half
| SUPPORTED_100baseT_Full
|
64 SUPPORTED_Autoneg
| SUPPORTED_TP
| SUPPORTED_MII
);
65 if (mii
->supports_gmii
)
66 ecmd
->supported
|= SUPPORTED_1000baseT_Half
|
67 SUPPORTED_1000baseT_Full
;
69 /* only supports twisted-pair */
70 ecmd
->port
= PORT_MII
;
72 /* only supports internal transceiver */
73 ecmd
->transceiver
= XCVR_INTERNAL
;
75 /* this isn't fully supported at higher layers */
76 ecmd
->phy_address
= mii
->phy_id
;
77 ecmd
->mdio_support
= ETH_MDIO_SUPPORTS_C22
;
79 ecmd
->advertising
= ADVERTISED_TP
| ADVERTISED_MII
;
81 bmcr
= mii
->mdio_read(dev
, mii
->phy_id
, MII_BMCR
);
82 bmsr
= mii
->mdio_read(dev
, mii
->phy_id
, MII_BMSR
);
83 if (mii
->supports_gmii
) {
84 ctrl1000
= mii
->mdio_read(dev
, mii
->phy_id
, MII_CTRL1000
);
85 stat1000
= mii
->mdio_read(dev
, mii
->phy_id
, MII_STAT1000
);
87 if (bmcr
& BMCR_ANENABLE
) {
88 ecmd
->advertising
|= ADVERTISED_Autoneg
;
89 ecmd
->autoneg
= AUTONEG_ENABLE
;
91 ecmd
->advertising
|= mii_get_an(mii
, MII_ADVERTISE
);
92 if (mii
->supports_gmii
)
94 mii_ctrl1000_to_ethtool_adv_t(ctrl1000
);
96 if (bmsr
& BMSR_ANEGCOMPLETE
) {
97 ecmd
->lp_advertising
= mii_get_an(mii
, MII_LPA
);
98 ecmd
->lp_advertising
|=
99 mii_stat1000_to_ethtool_lpa_t(stat1000
);
101 ecmd
->lp_advertising
= 0;
104 nego
= ecmd
->advertising
& ecmd
->lp_advertising
;
106 if (nego
& (ADVERTISED_1000baseT_Full
|
107 ADVERTISED_1000baseT_Half
)) {
108 ethtool_cmd_speed_set(ecmd
, SPEED_1000
);
109 ecmd
->duplex
= !!(nego
& ADVERTISED_1000baseT_Full
);
110 } else if (nego
& (ADVERTISED_100baseT_Full
|
111 ADVERTISED_100baseT_Half
)) {
112 ethtool_cmd_speed_set(ecmd
, SPEED_100
);
113 ecmd
->duplex
= !!(nego
& ADVERTISED_100baseT_Full
);
115 ethtool_cmd_speed_set(ecmd
, SPEED_10
);
116 ecmd
->duplex
= !!(nego
& ADVERTISED_10baseT_Full
);
119 ecmd
->autoneg
= AUTONEG_DISABLE
;
121 ethtool_cmd_speed_set(ecmd
,
122 ((bmcr
& BMCR_SPEED1000
&&
123 (bmcr
& BMCR_SPEED100
) == 0) ?
125 ((bmcr
& BMCR_SPEED100
) ?
126 SPEED_100
: SPEED_10
)));
127 ecmd
->duplex
= (bmcr
& BMCR_FULLDPLX
) ? DUPLEX_FULL
: DUPLEX_HALF
;
130 mii
->full_duplex
= ecmd
->duplex
;
132 /* ignore maxtxpkt, maxrxpkt for now */
138 * mii_ethtool_get_link_ksettings - get settings that are specified in @cmd
139 * @mii: MII interface
140 * @cmd: requested ethtool_link_ksettings
142 * The @cmd parameter is expected to have been cleared before calling
143 * mii_ethtool_get_link_ksettings().
145 * Returns 0 for success, negative on error.
147 int mii_ethtool_get_link_ksettings(struct mii_if_info
*mii
,
148 struct ethtool_link_ksettings
*cmd
)
150 struct net_device
*dev
= mii
->dev
;
151 u16 bmcr
, bmsr
, ctrl1000
= 0, stat1000
= 0;
152 u32 nego
, supported
, advertising
, lp_advertising
;
154 supported
= (SUPPORTED_10baseT_Half
| SUPPORTED_10baseT_Full
|
155 SUPPORTED_100baseT_Half
| SUPPORTED_100baseT_Full
|
156 SUPPORTED_Autoneg
| SUPPORTED_TP
| SUPPORTED_MII
);
157 if (mii
->supports_gmii
)
158 supported
|= SUPPORTED_1000baseT_Half
|
159 SUPPORTED_1000baseT_Full
;
161 /* only supports twisted-pair */
162 cmd
->base
.port
= PORT_MII
;
164 /* this isn't fully supported at higher layers */
165 cmd
->base
.phy_address
= mii
->phy_id
;
166 cmd
->base
.mdio_support
= ETH_MDIO_SUPPORTS_C22
;
168 advertising
= ADVERTISED_TP
| ADVERTISED_MII
;
170 bmcr
= mii
->mdio_read(dev
, mii
->phy_id
, MII_BMCR
);
171 bmsr
= mii
->mdio_read(dev
, mii
->phy_id
, MII_BMSR
);
172 if (mii
->supports_gmii
) {
173 ctrl1000
= mii
->mdio_read(dev
, mii
->phy_id
, MII_CTRL1000
);
174 stat1000
= mii
->mdio_read(dev
, mii
->phy_id
, MII_STAT1000
);
176 if (bmcr
& BMCR_ANENABLE
) {
177 advertising
|= ADVERTISED_Autoneg
;
178 cmd
->base
.autoneg
= AUTONEG_ENABLE
;
180 advertising
|= mii_get_an(mii
, MII_ADVERTISE
);
181 if (mii
->supports_gmii
)
182 advertising
|= mii_ctrl1000_to_ethtool_adv_t(ctrl1000
);
184 if (bmsr
& BMSR_ANEGCOMPLETE
) {
185 lp_advertising
= mii_get_an(mii
, MII_LPA
);
187 mii_stat1000_to_ethtool_lpa_t(stat1000
);
192 nego
= advertising
& lp_advertising
;
194 if (nego
& (ADVERTISED_1000baseT_Full
|
195 ADVERTISED_1000baseT_Half
)) {
196 cmd
->base
.speed
= SPEED_1000
;
197 cmd
->base
.duplex
= !!(nego
& ADVERTISED_1000baseT_Full
);
198 } else if (nego
& (ADVERTISED_100baseT_Full
|
199 ADVERTISED_100baseT_Half
)) {
200 cmd
->base
.speed
= SPEED_100
;
201 cmd
->base
.duplex
= !!(nego
& ADVERTISED_100baseT_Full
);
203 cmd
->base
.speed
= SPEED_10
;
204 cmd
->base
.duplex
= !!(nego
& ADVERTISED_10baseT_Full
);
207 cmd
->base
.autoneg
= AUTONEG_DISABLE
;
209 cmd
->base
.speed
= ((bmcr
& BMCR_SPEED1000
&&
210 (bmcr
& BMCR_SPEED100
) == 0) ?
212 ((bmcr
& BMCR_SPEED100
) ?
213 SPEED_100
: SPEED_10
));
214 cmd
->base
.duplex
= (bmcr
& BMCR_FULLDPLX
) ?
215 DUPLEX_FULL
: DUPLEX_HALF
;
220 mii
->full_duplex
= cmd
->base
.duplex
;
222 ethtool_convert_legacy_u32_to_link_mode(cmd
->link_modes
.supported
,
224 ethtool_convert_legacy_u32_to_link_mode(cmd
->link_modes
.advertising
,
226 ethtool_convert_legacy_u32_to_link_mode(cmd
->link_modes
.lp_advertising
,
229 /* ignore maxtxpkt, maxrxpkt for now */
235 * mii_ethtool_sset - set settings that are specified in @ecmd
236 * @mii: MII interface
237 * @ecmd: requested ethtool_cmd
239 * Returns 0 for success, negative on error.
241 int mii_ethtool_sset(struct mii_if_info
*mii
, struct ethtool_cmd
*ecmd
)
243 struct net_device
*dev
= mii
->dev
;
244 u32 speed
= ethtool_cmd_speed(ecmd
);
246 if (speed
!= SPEED_10
&&
247 speed
!= SPEED_100
&&
250 if (ecmd
->duplex
!= DUPLEX_HALF
&& ecmd
->duplex
!= DUPLEX_FULL
)
252 if (ecmd
->port
!= PORT_MII
)
254 if (ecmd
->transceiver
!= XCVR_INTERNAL
)
256 if (ecmd
->phy_address
!= mii
->phy_id
)
258 if (ecmd
->autoneg
!= AUTONEG_DISABLE
&& ecmd
->autoneg
!= AUTONEG_ENABLE
)
260 if ((speed
== SPEED_1000
) && (!mii
->supports_gmii
))
263 /* ignore supported, maxtxpkt, maxrxpkt */
265 if (ecmd
->autoneg
== AUTONEG_ENABLE
) {
266 u32 bmcr
, advert
, tmp
;
267 u32 advert2
= 0, tmp2
= 0;
269 if ((ecmd
->advertising
& (ADVERTISED_10baseT_Half
|
270 ADVERTISED_10baseT_Full
|
271 ADVERTISED_100baseT_Half
|
272 ADVERTISED_100baseT_Full
|
273 ADVERTISED_1000baseT_Half
|
274 ADVERTISED_1000baseT_Full
)) == 0)
277 /* advertise only what has been requested */
278 advert
= mii
->mdio_read(dev
, mii
->phy_id
, MII_ADVERTISE
);
279 tmp
= advert
& ~(ADVERTISE_ALL
| ADVERTISE_100BASE4
);
280 if (mii
->supports_gmii
) {
281 advert2
= mii
->mdio_read(dev
, mii
->phy_id
, MII_CTRL1000
);
282 tmp2
= advert2
& ~(ADVERTISE_1000HALF
| ADVERTISE_1000FULL
);
284 tmp
|= ethtool_adv_to_mii_adv_t(ecmd
->advertising
);
286 if (mii
->supports_gmii
)
288 ethtool_adv_to_mii_ctrl1000_t(ecmd
->advertising
);
290 mii
->mdio_write(dev
, mii
->phy_id
, MII_ADVERTISE
, tmp
);
291 mii
->advertising
= tmp
;
293 if ((mii
->supports_gmii
) && (advert2
!= tmp2
))
294 mii
->mdio_write(dev
, mii
->phy_id
, MII_CTRL1000
, tmp2
);
296 /* turn on autonegotiation, and force a renegotiate */
297 bmcr
= mii
->mdio_read(dev
, mii
->phy_id
, MII_BMCR
);
298 bmcr
|= (BMCR_ANENABLE
| BMCR_ANRESTART
);
299 mii
->mdio_write(dev
, mii
->phy_id
, MII_BMCR
, bmcr
);
301 mii
->force_media
= 0;
305 /* turn off auto negotiation, set speed and duplexity */
306 bmcr
= mii
->mdio_read(dev
, mii
->phy_id
, MII_BMCR
);
307 tmp
= bmcr
& ~(BMCR_ANENABLE
| BMCR_SPEED100
|
308 BMCR_SPEED1000
| BMCR_FULLDPLX
);
309 if (speed
== SPEED_1000
)
310 tmp
|= BMCR_SPEED1000
;
311 else if (speed
== SPEED_100
)
312 tmp
|= BMCR_SPEED100
;
313 if (ecmd
->duplex
== DUPLEX_FULL
) {
314 tmp
|= BMCR_FULLDPLX
;
315 mii
->full_duplex
= 1;
317 mii
->full_duplex
= 0;
319 mii
->mdio_write(dev
, mii
->phy_id
, MII_BMCR
, tmp
);
321 mii
->force_media
= 1;
327 * mii_ethtool_set_link_ksettings - set settings that are specified in @cmd
328 * @mii: MII interfaces
329 * @cmd: requested ethtool_link_ksettings
331 * Returns 0 for success, negative on error.
333 int mii_ethtool_set_link_ksettings(struct mii_if_info
*mii
,
334 const struct ethtool_link_ksettings
*cmd
)
336 struct net_device
*dev
= mii
->dev
;
337 u32 speed
= cmd
->base
.speed
;
339 if (speed
!= SPEED_10
&&
340 speed
!= SPEED_100
&&
343 if (cmd
->base
.duplex
!= DUPLEX_HALF
&& cmd
->base
.duplex
!= DUPLEX_FULL
)
345 if (cmd
->base
.port
!= PORT_MII
)
347 if (cmd
->base
.phy_address
!= mii
->phy_id
)
349 if (cmd
->base
.autoneg
!= AUTONEG_DISABLE
&&
350 cmd
->base
.autoneg
!= AUTONEG_ENABLE
)
352 if ((speed
== SPEED_1000
) && (!mii
->supports_gmii
))
355 /* ignore supported, maxtxpkt, maxrxpkt */
357 if (cmd
->base
.autoneg
== AUTONEG_ENABLE
) {
358 u32 bmcr
, advert
, tmp
;
359 u32 advert2
= 0, tmp2
= 0;
362 ethtool_convert_link_mode_to_legacy_u32(
363 &advertising
, cmd
->link_modes
.advertising
);
365 if ((advertising
& (ADVERTISED_10baseT_Half
|
366 ADVERTISED_10baseT_Full
|
367 ADVERTISED_100baseT_Half
|
368 ADVERTISED_100baseT_Full
|
369 ADVERTISED_1000baseT_Half
|
370 ADVERTISED_1000baseT_Full
)) == 0)
373 /* advertise only what has been requested */
374 advert
= mii
->mdio_read(dev
, mii
->phy_id
, MII_ADVERTISE
);
375 tmp
= advert
& ~(ADVERTISE_ALL
| ADVERTISE_100BASE4
);
376 if (mii
->supports_gmii
) {
377 advert2
= mii
->mdio_read(dev
, mii
->phy_id
,
380 ~(ADVERTISE_1000HALF
| ADVERTISE_1000FULL
);
382 tmp
|= ethtool_adv_to_mii_adv_t(advertising
);
384 if (mii
->supports_gmii
)
385 tmp2
|= ethtool_adv_to_mii_ctrl1000_t(advertising
);
387 mii
->mdio_write(dev
, mii
->phy_id
, MII_ADVERTISE
, tmp
);
388 mii
->advertising
= tmp
;
390 if ((mii
->supports_gmii
) && (advert2
!= tmp2
))
391 mii
->mdio_write(dev
, mii
->phy_id
, MII_CTRL1000
, tmp2
);
393 /* turn on autonegotiation, and force a renegotiate */
394 bmcr
= mii
->mdio_read(dev
, mii
->phy_id
, MII_BMCR
);
395 bmcr
|= (BMCR_ANENABLE
| BMCR_ANRESTART
);
396 mii
->mdio_write(dev
, mii
->phy_id
, MII_BMCR
, bmcr
);
398 mii
->force_media
= 0;
402 /* turn off auto negotiation, set speed and duplexity */
403 bmcr
= mii
->mdio_read(dev
, mii
->phy_id
, MII_BMCR
);
404 tmp
= bmcr
& ~(BMCR_ANENABLE
| BMCR_SPEED100
|
405 BMCR_SPEED1000
| BMCR_FULLDPLX
);
406 if (speed
== SPEED_1000
)
407 tmp
|= BMCR_SPEED1000
;
408 else if (speed
== SPEED_100
)
409 tmp
|= BMCR_SPEED100
;
410 if (cmd
->base
.duplex
== DUPLEX_FULL
) {
411 tmp
|= BMCR_FULLDPLX
;
412 mii
->full_duplex
= 1;
414 mii
->full_duplex
= 0;
417 mii
->mdio_write(dev
, mii
->phy_id
, MII_BMCR
, tmp
);
419 mii
->force_media
= 1;
425 * mii_check_gmii_support - check if the MII supports Gb interfaces
426 * @mii: the MII interface
428 int mii_check_gmii_support(struct mii_if_info
*mii
)
432 reg
= mii
->mdio_read(mii
->dev
, mii
->phy_id
, MII_BMSR
);
433 if (reg
& BMSR_ESTATEN
) {
434 reg
= mii
->mdio_read(mii
->dev
, mii
->phy_id
, MII_ESTATUS
);
435 if (reg
& (ESTATUS_1000_TFULL
| ESTATUS_1000_THALF
))
443 * mii_link_ok - is link status up/ok
444 * @mii: the MII interface
446 * Returns 1 if the MII reports link status up/ok, 0 otherwise.
448 int mii_link_ok (struct mii_if_info
*mii
)
450 /* first, a dummy read, needed to latch some MII phys */
451 mii
->mdio_read(mii
->dev
, mii
->phy_id
, MII_BMSR
);
452 if (mii
->mdio_read(mii
->dev
, mii
->phy_id
, MII_BMSR
) & BMSR_LSTATUS
)
458 * mii_nway_restart - restart NWay (autonegotiation) for this interface
459 * @mii: the MII interface
461 * Returns 0 on success, negative on error.
463 int mii_nway_restart (struct mii_if_info
*mii
)
468 /* if autoneg is off, it's an error */
469 bmcr
= mii
->mdio_read(mii
->dev
, mii
->phy_id
, MII_BMCR
);
471 if (bmcr
& BMCR_ANENABLE
) {
472 bmcr
|= BMCR_ANRESTART
;
473 mii
->mdio_write(mii
->dev
, mii
->phy_id
, MII_BMCR
, bmcr
);
481 * mii_check_link - check MII link status
482 * @mii: MII interface
484 * If the link status changed (previous != current), call
485 * netif_carrier_on() if current link status is Up or call
486 * netif_carrier_off() if current link status is Down.
488 void mii_check_link (struct mii_if_info
*mii
)
490 int cur_link
= mii_link_ok(mii
);
491 int prev_link
= netif_carrier_ok(mii
->dev
);
493 if (cur_link
&& !prev_link
)
494 netif_carrier_on(mii
->dev
);
495 else if (prev_link
&& !cur_link
)
496 netif_carrier_off(mii
->dev
);
500 * mii_check_media - check the MII interface for a carrier/speed/duplex change
501 * @mii: the MII interface
502 * @ok_to_print: OK to print link up/down messages
503 * @init_media: OK to save duplex mode in @mii
505 * Returns 1 if the duplex mode changed, 0 if not.
506 * If the media type is forced, always returns 0.
508 unsigned int mii_check_media (struct mii_if_info
*mii
,
509 unsigned int ok_to_print
,
510 unsigned int init_media
)
512 unsigned int old_carrier
, new_carrier
;
513 int advertise
, lpa
, media
, duplex
;
516 /* check current and old link status */
517 old_carrier
= netif_carrier_ok(mii
->dev
) ? 1 : 0;
518 new_carrier
= (unsigned int) mii_link_ok(mii
);
520 /* if carrier state did not change, this is a "bounce",
521 * just exit as everything is already set correctly
523 if ((!init_media
) && (old_carrier
== new_carrier
))
524 return 0; /* duplex did not change */
526 /* no carrier, nothing much to do */
528 netif_carrier_off(mii
->dev
);
530 netdev_info(mii
->dev
, "link down\n");
531 return 0; /* duplex did not change */
535 * we have carrier, see who's on the other end
537 netif_carrier_on(mii
->dev
);
539 if (mii
->force_media
) {
541 netdev_info(mii
->dev
, "link up\n");
542 return 0; /* duplex did not change */
545 /* get MII advertise and LPA values */
546 if ((!init_media
) && (mii
->advertising
))
547 advertise
= mii
->advertising
;
549 advertise
= mii
->mdio_read(mii
->dev
, mii
->phy_id
, MII_ADVERTISE
);
550 mii
->advertising
= advertise
;
552 lpa
= mii
->mdio_read(mii
->dev
, mii
->phy_id
, MII_LPA
);
553 if (mii
->supports_gmii
)
554 lpa2
= mii
->mdio_read(mii
->dev
, mii
->phy_id
, MII_STAT1000
);
556 /* figure out media and duplex from advertise and LPA values */
557 media
= mii_nway_result(lpa
& advertise
);
558 duplex
= (media
& ADVERTISE_FULL
) ? 1 : 0;
559 if (lpa2
& LPA_1000FULL
)
563 netdev_info(mii
->dev
, "link up, %uMbps, %s-duplex, lpa 0x%04X\n",
564 lpa2
& (LPA_1000FULL
| LPA_1000HALF
) ? 1000 :
565 media
& (ADVERTISE_100FULL
| ADVERTISE_100HALF
) ?
567 duplex
? "full" : "half",
570 if ((init_media
) || (mii
->full_duplex
!= duplex
)) {
571 mii
->full_duplex
= duplex
;
572 return 1; /* duplex changed */
575 return 0; /* duplex did not change */
579 * generic_mii_ioctl - main MII ioctl interface
580 * @mii_if: the MII interface
581 * @mii_data: MII ioctl data structure
582 * @cmd: MII ioctl command
583 * @duplex_chg_out: pointer to @duplex_changed status if there was no
586 * Returns 0 on success, negative on error.
588 int generic_mii_ioctl(struct mii_if_info
*mii_if
,
589 struct mii_ioctl_data
*mii_data
, int cmd
,
590 unsigned int *duplex_chg_out
)
593 unsigned int duplex_changed
= 0;
598 mii_data
->phy_id
&= mii_if
->phy_id_mask
;
599 mii_data
->reg_num
&= mii_if
->reg_num_mask
;
603 mii_data
->phy_id
= mii_if
->phy_id
;
608 mii_if
->mdio_read(mii_if
->dev
, mii_data
->phy_id
,
613 u16 val
= mii_data
->val_in
;
615 if (mii_data
->phy_id
== mii_if
->phy_id
) {
616 switch(mii_data
->reg_num
) {
618 unsigned int new_duplex
= 0;
619 if (val
& (BMCR_RESET
|BMCR_ANENABLE
))
620 mii_if
->force_media
= 0;
622 mii_if
->force_media
= 1;
623 if (mii_if
->force_media
&&
624 (val
& BMCR_FULLDPLX
))
626 if (mii_if
->full_duplex
!= new_duplex
) {
628 mii_if
->full_duplex
= new_duplex
;
633 mii_if
->advertising
= val
;
641 mii_if
->mdio_write(mii_if
->dev
, mii_data
->phy_id
,
642 mii_data
->reg_num
, val
);
651 if ((rc
== 0) && (duplex_chg_out
) && (duplex_changed
))
657 MODULE_AUTHOR ("Jeff Garzik <jgarzik@pobox.com>");
658 MODULE_DESCRIPTION ("MII hardware support library");
659 MODULE_LICENSE("GPL");
661 EXPORT_SYMBOL(mii_link_ok
);
662 EXPORT_SYMBOL(mii_nway_restart
);
663 EXPORT_SYMBOL(mii_ethtool_gset
);
664 EXPORT_SYMBOL(mii_ethtool_get_link_ksettings
);
665 EXPORT_SYMBOL(mii_ethtool_sset
);
666 EXPORT_SYMBOL(mii_ethtool_set_link_ksettings
);
667 EXPORT_SYMBOL(mii_check_link
);
668 EXPORT_SYMBOL(mii_check_media
);
669 EXPORT_SYMBOL(mii_check_gmii_support
);
670 EXPORT_SYMBOL(generic_mii_ioctl
);