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 e85bf04cf813..16fbb11d92ac 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) | |||
176 | * @npage_adv: Modes currently advertised on next pages | 176 | * @npage_adv: Modes currently advertised on next pages |
177 | * @npage_lpa: Modes advertised by link partner on next pages | 177 | * @npage_lpa: Modes advertised by link partner on next pages |
178 | * | 178 | * |
179 | * The @ecmd parameter is expected to have been cleared before calling | ||
180 | * mdio45_ethtool_gset_npage(). | ||
181 | * | ||
179 | * Since the CSRs for auto-negotiation using next pages are not fully | 182 | * Since the CSRs for auto-negotiation using next pages are not fully |
180 | * standardised, this function does not attempt to decode them. The | 183 | * standardised, this function does not attempt to decode them. The |
181 | * caller must pass them in. | 184 | * caller must pass them in. |
@@ -185,6 +188,7 @@ void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio, | |||
185 | u32 npage_adv, u32 npage_lpa) | 188 | u32 npage_adv, u32 npage_lpa) |
186 | { | 189 | { |
187 | int reg; | 190 | int reg; |
191 | u32 speed; | ||
188 | 192 | ||
189 | ecmd->transceiver = XCVR_INTERNAL; | 193 | ecmd->transceiver = XCVR_INTERNAL; |
190 | ecmd->phy_address = mdio->prtad; | 194 | ecmd->phy_address = mdio->prtad; |
@@ -287,33 +291,36 @@ void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio, | |||
287 | if (modes & (ADVERTISED_10000baseT_Full | | 291 | if (modes & (ADVERTISED_10000baseT_Full | |
288 | ADVERTISED_10000baseKX4_Full | | 292 | ADVERTISED_10000baseKX4_Full | |
289 | ADVERTISED_10000baseKR_Full)) { | 293 | ADVERTISED_10000baseKR_Full)) { |
290 | ecmd->speed = SPEED_10000; | 294 | speed = SPEED_10000; |
291 | ecmd->duplex = DUPLEX_FULL; | 295 | ecmd->duplex = DUPLEX_FULL; |
292 | } else if (modes & (ADVERTISED_1000baseT_Full | | 296 | } else if (modes & (ADVERTISED_1000baseT_Full | |
293 | ADVERTISED_1000baseT_Half | | 297 | ADVERTISED_1000baseT_Half | |
294 | ADVERTISED_1000baseKX_Full)) { | 298 | ADVERTISED_1000baseKX_Full)) { |
295 | ecmd->speed = SPEED_1000; | 299 | speed = SPEED_1000; |
296 | ecmd->duplex = !(modes & ADVERTISED_1000baseT_Half); | 300 | ecmd->duplex = !(modes & ADVERTISED_1000baseT_Half); |
297 | } else if (modes & (ADVERTISED_100baseT_Full | | 301 | } else if (modes & (ADVERTISED_100baseT_Full | |
298 | ADVERTISED_100baseT_Half)) { | 302 | ADVERTISED_100baseT_Half)) { |
299 | ecmd->speed = SPEED_100; | 303 | speed = SPEED_100; |
300 | ecmd->duplex = !!(modes & ADVERTISED_100baseT_Full); | 304 | ecmd->duplex = !!(modes & ADVERTISED_100baseT_Full); |
301 | } else { | 305 | } else { |
302 | ecmd->speed = SPEED_10; | 306 | speed = SPEED_10; |
303 | ecmd->duplex = !!(modes & ADVERTISED_10baseT_Full); | 307 | ecmd->duplex = !!(modes & ADVERTISED_10baseT_Full); |
304 | } | 308 | } |
305 | } else { | 309 | } else { |
306 | /* Report forced settings */ | 310 | /* Report forced settings */ |
307 | reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD, | 311 | reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD, |
308 | MDIO_CTRL1); | 312 | MDIO_CTRL1); |
309 | ecmd->speed = (((reg & MDIO_PMA_CTRL1_SPEED1000) ? 100 : 1) * | 313 | speed = (((reg & MDIO_PMA_CTRL1_SPEED1000) ? 100 : 1) |
310 | ((reg & MDIO_PMA_CTRL1_SPEED100) ? 100 : 10)); | 314 | * ((reg & MDIO_PMA_CTRL1_SPEED100) ? 100 : 10)); |
311 | ecmd->duplex = (reg & MDIO_CTRL1_FULLDPLX || | 315 | ecmd->duplex = (reg & MDIO_CTRL1_FULLDPLX || |
312 | ecmd->speed == SPEED_10000); | 316 | speed == SPEED_10000); |
313 | } | 317 | } |
314 | 318 | ||
319 | ethtool_cmd_speed_set(ecmd, speed); | ||
320 | |||
315 | /* 10GBASE-T MDI/MDI-X */ | 321 | /* 10GBASE-T MDI/MDI-X */ |
316 | if (ecmd->port == PORT_TP && ecmd->speed == SPEED_10000) { | 322 | if (ecmd->port == PORT_TP |
323 | && (ethtool_cmd_speed(ecmd) == SPEED_10000)) { | ||
317 | switch (mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD, | 324 | switch (mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD, |
318 | MDIO_PMA_10GBT_SWAPPOL)) { | 325 | MDIO_PMA_10GBT_SWAPPOL)) { |
319 | case MDIO_PMA_10GBT_SWAPPOL_ABNX | MDIO_PMA_10GBT_SWAPPOL_CDNX: | 326 | case MDIO_PMA_10GBT_SWAPPOL_ABNX | MDIO_PMA_10GBT_SWAPPOL_CDNX: |