diff options
| -rw-r--r-- | drivers/net/sfc/ethtool.c | 3 | ||||
| -rw-r--r-- | drivers/net/sfc/mdio_10g.c | 177 | ||||
| -rw-r--r-- | drivers/net/sfc/mdio_10g.h | 3 | ||||
| -rw-r--r-- | drivers/net/sfc/net_driver.h | 4 | ||||
| -rw-r--r-- | drivers/net/sfc/tenxpress.c | 151 | ||||
| -rw-r--r-- | drivers/net/sfc/workarounds.h | 4 |
6 files changed, 141 insertions, 201 deletions
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index 53d259e90187..7b5924c039b3 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c | |||
| @@ -219,9 +219,6 @@ int efx_ethtool_set_settings(struct net_device *net_dev, | |||
| 219 | struct efx_nic *efx = netdev_priv(net_dev); | 219 | struct efx_nic *efx = netdev_priv(net_dev); |
| 220 | int rc; | 220 | int rc; |
| 221 | 221 | ||
| 222 | if (EFX_WORKAROUND_13963(efx) && !ecmd->autoneg) | ||
| 223 | return -EINVAL; | ||
| 224 | |||
| 225 | /* Falcon GMAC does not support 1000Mbps HD */ | 222 | /* Falcon GMAC does not support 1000Mbps HD */ |
| 226 | if (ecmd->speed == SPEED_1000 && ecmd->duplex != DUPLEX_FULL) { | 223 | if (ecmd->speed == SPEED_1000 && ecmd->duplex != DUPLEX_FULL) { |
| 227 | EFX_LOG(efx, "rejecting unsupported 1000Mbps HD" | 224 | EFX_LOG(efx, "rejecting unsupported 1000Mbps HD" |
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c index 16bc5853d0ea..f9e2f95c3b48 100644 --- a/drivers/net/sfc/mdio_10g.c +++ b/drivers/net/sfc/mdio_10g.c | |||
| @@ -266,7 +266,7 @@ void mdio_clause45_set_mmds_lpower(struct efx_nic *efx, | |||
| 266 | } | 266 | } |
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr, u32 xnp) | 269 | static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr) |
| 270 | { | 270 | { |
| 271 | int phy_id = efx->mii.phy_id; | 271 | int phy_id = efx->mii.phy_id; |
| 272 | u32 result = 0; | 272 | u32 result = 0; |
| @@ -281,9 +281,6 @@ static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr, u32 xnp) | |||
| 281 | result |= ADVERTISED_100baseT_Half; | 281 | result |= ADVERTISED_100baseT_Half; |
| 282 | if (reg & ADVERTISE_100FULL) | 282 | if (reg & ADVERTISE_100FULL) |
| 283 | result |= ADVERTISED_100baseT_Full; | 283 | result |= ADVERTISED_100baseT_Full; |
| 284 | if (reg & LPA_RESV) | ||
| 285 | result |= xnp; | ||
| 286 | |||
| 287 | return result; | 284 | return result; |
| 288 | } | 285 | } |
| 289 | 286 | ||
| @@ -313,7 +310,7 @@ void mdio_clause45_get_settings(struct efx_nic *efx, | |||
| 313 | */ | 310 | */ |
| 314 | void mdio_clause45_get_settings_ext(struct efx_nic *efx, | 311 | void mdio_clause45_get_settings_ext(struct efx_nic *efx, |
| 315 | struct ethtool_cmd *ecmd, | 312 | struct ethtool_cmd *ecmd, |
| 316 | u32 xnp, u32 xnp_lpa) | 313 | u32 npage_adv, u32 npage_lpa) |
| 317 | { | 314 | { |
| 318 | int phy_id = efx->mii.phy_id; | 315 | int phy_id = efx->mii.phy_id; |
| 319 | int reg; | 316 | int reg; |
| @@ -364,8 +361,8 @@ void mdio_clause45_get_settings_ext(struct efx_nic *efx, | |||
| 364 | ecmd->autoneg = AUTONEG_ENABLE; | 361 | ecmd->autoneg = AUTONEG_ENABLE; |
| 365 | ecmd->advertising |= | 362 | ecmd->advertising |= |
| 366 | ADVERTISED_Autoneg | | 363 | ADVERTISED_Autoneg | |
| 367 | mdio_clause45_get_an(efx, | 364 | mdio_clause45_get_an(efx, MDIO_AN_ADVERTISE) | |
| 368 | MDIO_AN_ADVERTISE, xnp); | 365 | npage_adv; |
| 369 | } else | 366 | } else |
| 370 | ecmd->autoneg = AUTONEG_DISABLE; | 367 | ecmd->autoneg = AUTONEG_DISABLE; |
| 371 | } else | 368 | } else |
| @@ -374,27 +371,30 @@ void mdio_clause45_get_settings_ext(struct efx_nic *efx, | |||
| 374 | if (ecmd->autoneg) { | 371 | if (ecmd->autoneg) { |
| 375 | /* If AN is complete, report best common mode, | 372 | /* If AN is complete, report best common mode, |
| 376 | * otherwise report best advertised mode. */ | 373 | * otherwise report best advertised mode. */ |
| 377 | u32 common = ecmd->advertising; | 374 | u32 modes = 0; |
| 378 | if (mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, | 375 | if (mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, |
| 379 | MDIO_MMDREG_STAT1) & | 376 | MDIO_MMDREG_STAT1) & |
| 380 | (1 << MDIO_AN_STATUS_AN_DONE_LBN)) { | 377 | (1 << MDIO_AN_STATUS_AN_DONE_LBN)) |
| 381 | common &= mdio_clause45_get_an(efx, MDIO_AN_LPA, | 378 | modes = (ecmd->advertising & |
| 382 | xnp_lpa); | 379 | (mdio_clause45_get_an(efx, MDIO_AN_LPA) | |
| 383 | } | 380 | npage_lpa)); |
| 384 | if (common & ADVERTISED_10000baseT_Full) { | 381 | if (modes == 0) |
| 382 | modes = ecmd->advertising; | ||
| 383 | |||
| 384 | if (modes & ADVERTISED_10000baseT_Full) { | ||
| 385 | ecmd->speed = SPEED_10000; | 385 | ecmd->speed = SPEED_10000; |
| 386 | ecmd->duplex = DUPLEX_FULL; | 386 | ecmd->duplex = DUPLEX_FULL; |
| 387 | } else if (common & (ADVERTISED_1000baseT_Full | | 387 | } else if (modes & (ADVERTISED_1000baseT_Full | |
| 388 | ADVERTISED_1000baseT_Half)) { | 388 | ADVERTISED_1000baseT_Half)) { |
| 389 | ecmd->speed = SPEED_1000; | 389 | ecmd->speed = SPEED_1000; |
| 390 | ecmd->duplex = !!(common & ADVERTISED_1000baseT_Full); | 390 | ecmd->duplex = !!(modes & ADVERTISED_1000baseT_Full); |
| 391 | } else if (common & (ADVERTISED_100baseT_Full | | 391 | } else if (modes & (ADVERTISED_100baseT_Full | |
| 392 | ADVERTISED_100baseT_Half)) { | 392 | ADVERTISED_100baseT_Half)) { |
| 393 | ecmd->speed = SPEED_100; | 393 | ecmd->speed = SPEED_100; |
| 394 | ecmd->duplex = !!(common & ADVERTISED_100baseT_Full); | 394 | ecmd->duplex = !!(modes & ADVERTISED_100baseT_Full); |
| 395 | } else { | 395 | } else { |
| 396 | ecmd->speed = SPEED_10; | 396 | ecmd->speed = SPEED_10; |
| 397 | ecmd->duplex = !!(common & ADVERTISED_10baseT_Full); | 397 | ecmd->duplex = !!(modes & ADVERTISED_10baseT_Full); |
| 398 | } | 398 | } |
| 399 | } else { | 399 | } else { |
| 400 | /* Report forced settings */ | 400 | /* Report forced settings */ |
| @@ -418,7 +418,7 @@ int mdio_clause45_set_settings(struct efx_nic *efx, | |||
| 418 | int phy_id = efx->mii.phy_id; | 418 | int phy_id = efx->mii.phy_id; |
| 419 | struct ethtool_cmd prev; | 419 | struct ethtool_cmd prev; |
| 420 | u32 required; | 420 | u32 required; |
| 421 | int ctrl1_bits, reg; | 421 | int reg; |
| 422 | 422 | ||
| 423 | efx->phy_op->get_settings(efx, &prev); | 423 | efx->phy_op->get_settings(efx, &prev); |
| 424 | 424 | ||
| @@ -433,102 +433,83 @@ int mdio_clause45_set_settings(struct efx_nic *efx, | |||
| 433 | if (prev.port != PORT_TP || ecmd->port != PORT_TP) | 433 | if (prev.port != PORT_TP || ecmd->port != PORT_TP) |
| 434 | return -EINVAL; | 434 | return -EINVAL; |
| 435 | 435 | ||
| 436 | /* Check that PHY supports these settings and work out the | 436 | /* Check that PHY supports these settings */ |
| 437 | * basic control bits */ | 437 | if (ecmd->autoneg) { |
| 438 | if (ecmd->duplex) { | 438 | required = SUPPORTED_Autoneg; |
| 439 | } else if (ecmd->duplex) { | ||
| 439 | switch (ecmd->speed) { | 440 | switch (ecmd->speed) { |
| 440 | case SPEED_10: | 441 | case SPEED_10: required = SUPPORTED_10baseT_Full; break; |
| 441 | ctrl1_bits = BMCR_FULLDPLX; | 442 | case SPEED_100: required = SUPPORTED_100baseT_Full; break; |
| 442 | required = SUPPORTED_10baseT_Full; | 443 | default: return -EINVAL; |
| 443 | break; | ||
| 444 | case SPEED_100: | ||
| 445 | ctrl1_bits = BMCR_SPEED100 | BMCR_FULLDPLX; | ||
| 446 | required = SUPPORTED_100baseT_Full; | ||
| 447 | break; | ||
| 448 | case SPEED_1000: | ||
| 449 | ctrl1_bits = BMCR_SPEED1000 | BMCR_FULLDPLX; | ||
| 450 | required = SUPPORTED_1000baseT_Full; | ||
| 451 | break; | ||
| 452 | case SPEED_10000: | ||
| 453 | ctrl1_bits = (BMCR_SPEED1000 | BMCR_SPEED100 | | ||
| 454 | BMCR_FULLDPLX); | ||
| 455 | required = SUPPORTED_10000baseT_Full; | ||
| 456 | break; | ||
| 457 | default: | ||
| 458 | return -EINVAL; | ||
| 459 | } | 444 | } |
| 460 | } else { | 445 | } else { |
| 461 | switch (ecmd->speed) { | 446 | switch (ecmd->speed) { |
| 462 | case SPEED_10: | 447 | case SPEED_10: required = SUPPORTED_10baseT_Half; break; |
| 463 | ctrl1_bits = 0; | 448 | case SPEED_100: required = SUPPORTED_100baseT_Half; break; |
| 464 | required = SUPPORTED_10baseT_Half; | 449 | default: return -EINVAL; |
| 465 | break; | ||
| 466 | case SPEED_100: | ||
| 467 | ctrl1_bits = BMCR_SPEED100; | ||
| 468 | required = SUPPORTED_100baseT_Half; | ||
| 469 | break; | ||
| 470 | case SPEED_1000: | ||
| 471 | ctrl1_bits = BMCR_SPEED1000; | ||
| 472 | required = SUPPORTED_1000baseT_Half; | ||
| 473 | break; | ||
| 474 | default: | ||
| 475 | return -EINVAL; | ||
| 476 | } | 450 | } |
| 477 | } | 451 | } |
| 478 | if (ecmd->autoneg) | ||
| 479 | required |= SUPPORTED_Autoneg; | ||
| 480 | required |= ecmd->advertising; | 452 | required |= ecmd->advertising; |
| 481 | if (required & ~prev.supported) | ||
