diff options
Diffstat (limited to 'drivers/net/mdio.c')
| -rw-r--r-- | drivers/net/mdio.c | 23 | 
1 files changed, 15 insertions, 8 deletions
diff --git a/drivers/net/mdio.c b/drivers/net/mdio.c index e85bf04cf81..16fbb11d92a 100644 --- a/drivers/net/mdio.c +++ b/drivers/net/mdio.c @@ -176,6 +176,9 @@ static u32 mdio45_get_an(const struct mdio_if_info *mdio, u16 addr)   * @npage_adv: Modes currently advertised on next pages   * @npage_lpa: Modes advertised by link partner on next pages   * + * The @ecmd parameter is expected to have been cleared before calling + * mdio45_ethtool_gset_npage(). + *   * Since the CSRs for auto-negotiation using next pages are not fully   * standardised, this function does not attempt to decode them.  The   * caller must pass them in. @@ -185,6 +188,7 @@ void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio,  			       u32 npage_adv, u32 npage_lpa)  {  	int reg; +	u32 speed;  	ecmd->transceiver = XCVR_INTERNAL;  	ecmd->phy_address = mdio->prtad; @@ -287,33 +291,36 @@ void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio,  		if (modes & (ADVERTISED_10000baseT_Full |  			     ADVERTISED_10000baseKX4_Full |  			     ADVERTISED_10000baseKR_Full)) { -			ecmd->speed = SPEED_10000; +			speed = SPEED_10000;  			ecmd->duplex = DUPLEX_FULL;  		} else if (modes & (ADVERTISED_1000baseT_Full |  				    ADVERTISED_1000baseT_Half |  				    ADVERTISED_1000baseKX_Full)) { -			ecmd->speed = SPEED_1000; +			speed = SPEED_1000;  			ecmd->duplex = !(modes & ADVERTISED_1000baseT_Half);  		} else if (modes & (ADVERTISED_100baseT_Full |  				    ADVERTISED_100baseT_Half)) { -			ecmd->speed = SPEED_100; +			speed = SPEED_100;  			ecmd->duplex = !!(modes & ADVERTISED_100baseT_Full);  		} else { -			ecmd->speed = SPEED_10; +			speed = SPEED_10;  			ecmd->duplex = !!(modes & ADVERTISED_10baseT_Full);  		}  	} else {  		/* Report forced settings */  		reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD,  				      MDIO_CTRL1); -		ecmd->speed = (((reg & MDIO_PMA_CTRL1_SPEED1000) ? 100 : 1) * -			       ((reg & MDIO_PMA_CTRL1_SPEED100) ? 100 : 10)); +		speed = (((reg & MDIO_PMA_CTRL1_SPEED1000) ? 100 : 1) +			 * ((reg & MDIO_PMA_CTRL1_SPEED100) ? 100 : 10));  		ecmd->duplex = (reg & MDIO_CTRL1_FULLDPLX || -				ecmd->speed == SPEED_10000); +				speed == SPEED_10000);  	} +	ethtool_cmd_speed_set(ecmd, speed); +  	/* 10GBASE-T MDI/MDI-X */ -	if (ecmd->port == PORT_TP && ecmd->speed == SPEED_10000) { +	if (ecmd->port == PORT_TP +	    && (ethtool_cmd_speed(ecmd) == SPEED_10000)) {  		switch (mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD,  					MDIO_PMA_10GBT_SWAPPOL)) {  		case MDIO_PMA_10GBT_SWAPPOL_ABNX | MDIO_PMA_10GBT_SWAPPOL_CDNX:  |