diff options
Diffstat (limited to 'drivers/net/sfc')
-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) | 453 | if (required & ~prev.supported) |
482 | return -EINVAL; | 454 | return -EINVAL; |
483 | 455 | ||
484 | /* Set the basic control bits */ | 456 | if (ecmd->autoneg) { |
485 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, | 457 | bool xnp = (ecmd->advertising & ADVERTISED_10000baseT_Full |
486 | MDIO_MMDREG_CTRL1); | 458 | || EFX_WORKAROUND_13204(efx)); |
487 | reg &= ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX | 0x003c); | 459 | |
488 | reg |= ctrl1_bits; | 460 | /* Set up the base page */ |
489 | mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, MDIO_MMDREG_CTRL1, | 461 | reg = ADVERTISE_CSMA; |
490 | reg); | 462 | if (ecmd->advertising & ADVERTISED_10baseT_Half) |
491 | 463 | reg |= ADVERTISE_10HALF; | |
492 | /* Set the AN registers */ | 464 | if (ecmd->advertising & ADVERTISED_10baseT_Full) |
493 | if (ecmd->autoneg != prev.autoneg || | 465 | reg |= ADVERTISE_10FULL; |
494 | ecmd->advertising != prev.advertising) { | 466 | if (ecmd->advertising & ADVERTISED_100baseT_Half) |
495 | bool xnp = false; | 467 | reg |= ADVERTISE_100HALF; |
496 | 468 | if (ecmd->advertising & ADVERTISED_100baseT_Full) | |
497 | if (efx->phy_op->set_xnp_advertise) | 469 | reg |= ADVERTISE_100FULL; |
498 | xnp = efx->phy_op->set_xnp_advertise(efx, | 470 | if (xnp) |
499 | ecmd->advertising); | 471 | reg |= ADVERTISE_RESV; |
500 | 472 | else if (ecmd->advertising & (ADVERTISED_1000baseT_Half | | |
501 | if (ecmd->autoneg) { | 473 | ADVERTISED_1000baseT_Full)) |
502 | reg = 0; | 474 | reg |= ADVERTISE_NPAGE; |
503 | if (ecmd->advertising & ADVERTISED_10baseT_Half) | 475 | reg |= efx_fc_advertise(efx->wanted_fc); |
504 | reg |= ADVERTISE_10HALF; | 476 | mdio_clause45_write(efx, phy_id, MDIO_MMD_AN, |
505 | if (ecmd->advertising & ADVERTISED_10baseT_Full) | 477 | MDIO_AN_ADVERTISE, reg); |
506 | reg |= ADVERTISE_10FULL; | 478 | |
507 | if (ecmd->advertising & ADVERTISED_100baseT_Half) | 479 | /* Set up the (extended) next page if necessary */ |
508 | reg |= ADVERTISE_100HALF; | 480 | if (efx->phy_op->set_npage_adv) |
509 | if (ecmd->advertising & ADVERTISED_100baseT_Full) | 481 | efx->phy_op->set_npage_adv(efx, ecmd->advertising); |
510 | reg |= ADVERTISE_100FULL; | ||
511 | if (xnp) | ||
512 | reg |= ADVERTISE_RESV; | ||
513 | mdio_clause45_write(efx, phy_id, MDIO_MMD_AN, | ||
514 | MDIO_AN_ADVERTISE, reg); | ||
515 | } | ||
516 | 482 | ||
483 | /* Enable and restart AN */ | ||
517 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, | 484 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, |
518 | MDIO_MMDREG_CTRL1); | 485 | MDIO_MMDREG_CTRL1); |
519 | if (ecmd->autoneg) | 486 | reg |= BMCR_ANENABLE; |
520 | reg |= BMCR_ANENABLE | BMCR_ANRESTART; | 487 | if (!(EFX_WORKAROUND_15195(efx) && |
521 | else | 488 | LOOPBACK_MASK(efx) & efx->phy_op->loopbacks)) |
522 | reg &= ~BMCR_ANENABLE; | 489 | reg |= BMCR_ANRESTART; |
523 | if (EFX_WORKAROUND_15195(efx) | ||
524 | && LOOPBACK_MASK(efx) & efx->phy_op->loopbacks) | ||
525 | reg &= ~BMCR_ANRESTART; | ||
526 | if (xnp) | 490 | if (xnp) |
527 | reg |= 1 << MDIO_AN_CTRL_XNP_LBN; | 491 | reg |= 1 << MDIO_AN_CTRL_XNP_LBN; |
528 | else | 492 | else |
529 | reg &= ~(1 << MDIO_AN_CTRL_XNP_LBN); | 493 | reg &= ~(1 << MDIO_AN_CTRL_XNP_LBN); |
530 | mdio_clause45_write(efx, phy_id, MDIO_MMD_AN, | 494 | mdio_clause45_write(efx, phy_id, MDIO_MMD_AN, |
531 | MDIO_MMDREG_CTRL1, reg); | 495 | MDIO_MMDREG_CTRL1, reg); |
496 | } else { | ||
497 | /* Disable AN */ | ||
498 | mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN, | ||
499 | MDIO_MMDREG_CTRL1, | ||
500 | __ffs(BMCR_ANENABLE), false); | ||
501 | |||
502 | /* Set the basic control bits */ | ||
503 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, | ||
504 | MDIO_MMDREG_CTRL1); | ||
505 | reg &= ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX | | ||
506 | 0x003c); | ||
507 | if (ecmd->speed == SPEED_100) | ||
508 | reg |= BMCR_SPEED100; | ||
509 | if (ecmd->duplex) | ||
510 | reg |= BMCR_FULLDPLX; | ||
511 | mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, | ||
512 | MDIO_MMDREG_CTRL1, reg); | ||
532 | } | 513 | } |
533 | 514 | ||
534 | return 0; | 515 | return 0; |
diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h index 09bf801d0569..8ba49773ce7e 100644 --- a/drivers/net/sfc/mdio_10g.h +++ b/drivers/net/sfc/mdio_10g.h | |||
@@ -155,7 +155,8 @@ | |||
155 | #define MDIO_AN_XNP 22 | 155 | #define MDIO_AN_XNP 22 |
156 | #define MDIO_AN_LPA_XNP 25 | 156 | #define MDIO_AN_LPA_XNP 25 |
157 | 157 | ||
158 | #define MDIO_AN_10GBT_ADVERTISE 32 | 158 | #define MDIO_AN_10GBT_CTRL 32 |
159 | #define MDIO_AN_10GBT_CTRL_ADV_10G_LBN 12 | ||
159 | #define MDIO_AN_10GBT_STATUS (33) | 160 | #define MDIO_AN_10GBT_STATUS (33) |
160 | #define MDIO_AN_10GBT_STATUS_MS_FLT_LBN (15) /* MASTER/SLAVE config fault */ | 161 | #define MDIO_AN_10GBT_STATUS_MS_FLT_LBN (15) /* MASTER/SLAVE config fault */ |
161 | #define MDIO_AN_10GBT_STATUS_MS_LBN (14) /* MASTER/SLAVE config */ | 162 | #define MDIO_AN_10GBT_STATUS_MS_LBN (14) /* MASTER/SLAVE config */ |
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 5f255f75754e..8eb411a1c82e 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h | |||
@@ -566,7 +566,7 @@ struct efx_mac_operations { | |||
566 | * @poll: Poll for hardware state. Serialised by the mac_lock. | 566 | * @poll: Poll for hardware state. Serialised by the mac_lock. |
567 | * @get_settings: Get ethtool settings. Serialised by the mac_lock. | 567 | * @get_settings: Get ethtool settings. Serialised by the mac_lock. |
568 | * @set_settings: Set ethtool settings. Serialised by the mac_lock. | 568 | * @set_settings: Set ethtool settings. Serialised by the mac_lock. |
569 | * @set_xnp_advertise: Set abilities advertised in Extended Next Page | 569 | * @set_npage_adv: Set abilities advertised in (Extended) Next Page |
570 | * (only needed where AN bit is set in mmds) | 570 | * (only needed where AN bit is set in mmds) |
571 | * @num_tests: Number of PHY-specific tests/results | 571 | * @num_tests: Number of PHY-specific tests/results |
572 | * @test_names: Names of the tests/results | 572 | * @test_names: Names of the tests/results |
@@ -586,7 +586,7 @@ struct efx_phy_operations { | |||
586 | struct ethtool_cmd *ecmd); | 586 | struct ethtool_cmd *ecmd); |
587 | int (*set_settings) (struct efx_nic *efx, | 587 | int (*set_settings) (struct efx_nic *efx, |
588 | struct ethtool_cmd *ecmd); | 588 | struct ethtool_cmd *ecmd); |
589 | bool (*set_xnp_advertise) (struct efx_nic *efx, u32); | 589 | void (*set_npage_adv) (struct efx_nic *efx, u32); |
590 | u32 num_tests; | 590 | u32 num_tests; |
591 | const char *const *test_names; | 591 | const char *const *test_names; |
592 | int (*run_tests) (struct efx_nic *efx, int *results, unsigned flags); | 592 | int (*run_tests) (struct efx_nic *efx, int *results, unsigned flags); |
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index c9584619322a..412d209d8313 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c | |||
@@ -179,11 +179,13 @@ | |||
179 | #define C22EXT_STATUS_LINK_LBN 2 | 179 | #define C22EXT_STATUS_LINK_LBN 2 |
180 | #define C22EXT_STATUS_LINK_WIDTH 1 | 180 | #define C22EXT_STATUS_LINK_WIDTH 1 |
181 | 181 | ||
182 | #define C22EXT_MSTSLV_REG 49162 | 182 | #define C22EXT_MSTSLV_CTRL 49161 |
183 | #define C22EXT_MSTSLV_1000_HD_LBN 10 | 183 | #define C22EXT_MSTSLV_CTRL_ADV_1000_HD_LBN 8 |
184 | #define C22EXT_MSTSLV_1000_HD_WIDTH 1 | 184 | #define C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN 9 |
185 | #define C22EXT_MSTSLV_1000_FD_LBN 11 | 185 | |
186 | #define C22EXT_MSTSLV_1000_FD_WIDTH 1 | 186 | #define C22EXT_MSTSLV_STATUS 49162 |
187 | #define C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN 10 | ||
188 | #define C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN 11 | ||
187 | 189 | ||
188 | /* Time to wait between powering down the LNPGA and turning off the power | 190 | /* Time to wait between powering down the LNPGA and turning off the power |
189 | * rails */ | 191 | * rails */ |
@@ -741,114 +743,76 @@ reset: | |||
741 | return rc; | 743 | return rc; |
742 | } | 744 | } |
743 | 745 | ||
744 | static u32 tenxpress_get_xnp_lpa(struct efx_nic *efx) | 746 | static void |
747 | tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) | ||
745 | { | 748 | { |
746 | int phy = efx->mii.phy_id; | 749 | int phy_id = efx->mii.phy_id; |
747 | u32 lpa = 0; | 750 | u32 adv = 0, lpa = 0; |
748 | int reg; | 751 | int reg; |
749 | 752 | ||
750 | if (efx->phy_type != PHY_TYPE_SFX7101) { | 753 | if (efx->phy_type != PHY_TYPE_SFX7101) { |
751 | reg = mdio_clause45_read(efx, phy, MDIO_MMD_C22EXT, | 754 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT, |
752 | C22EXT_MSTSLV_REG); | 755 | C22EXT_MSTSLV_CTRL); |
753 | if (reg & (1 << C22EXT_MSTSLV_1000_HD_LBN)) | 756 | if (reg & (1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN)) |
757 | adv |= ADVERTISED_1000baseT_Full; | ||
758 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT, | ||
759 | C22EXT_MSTSLV_STATUS); | ||
760 | if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN)) | ||
754 | lpa |= ADVERTISED_1000baseT_Half; | 761 | lpa |= ADVERTISED_1000baseT_Half; |
755 | if (reg & (1 << C22EXT_MSTSLV_1000_FD_LBN)) | 762 | if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN)) |
756 | lpa |= ADVERTISED_1000baseT_Full; | 763 | lpa |= ADVERTISED_1000baseT_Full; |
757 | } | 764 | } |
758 | reg = mdio_clause45_read(efx, phy, MDIO_MMD_AN, MDIO_AN_10GBT_STATUS); | 765 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, |
766 | MDIO_AN_10GBT_CTRL); | ||
767 | if (reg & (1 << MDIO_AN_10GBT_CTRL_ADV_10G_LBN)) | ||
768 | adv |= ADVERTISED_10000baseT_Full; | ||
769 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, | ||
770 | MDIO_AN_10GBT_STATUS); | ||
759 | if (reg & (1 << MDIO_AN_10GBT_STATUS_LP_10G_LBN)) | 771 | if (reg & (1 << MDIO_AN_10GBT_STATUS_LP_10G_LBN)) |
760 | lpa |= ADVERTISED_10000baseT_Full; | 772 | lpa |= ADVERTISED_10000baseT_Full; |
761 | return lpa; | ||
762 | } | ||
763 | |||
764 | static void sfx7101_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) | ||
765 | { | ||
766 | mdio_clause45_get_settings_ext(efx, ecmd, ADVERTISED_10000baseT_Full, | ||
767 | tenxpress_get_xnp_lpa(efx)); | ||
768 | ecmd->supported |= SUPPORTED_10000baseT_Full; | ||
769 | ecmd->advertising |= ADVERTISED_10000baseT_Full; | ||
770 | } | ||
771 | |||
772 | static void sft9001_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) | ||
773 | { | ||
774 | int phy_id = efx->mii.phy_id; | ||
775 | u32 xnp_adv = 0; | ||
776 | int reg; | ||
777 | |||
778 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, | ||
779 | PMA_PMD_SPEED_ENABLE_REG); | ||
780 | if (EFX_WORKAROUND_13204(efx) && (reg & (1 << PMA_PMD_100TX_ADV_LBN))) | ||
781 | xnp_adv |= ADVERTISED_100baseT_Full; | ||
782 | if (reg & (1 << PMA_PMD_1000T_ADV_LBN)) | ||
783 | xnp_adv |= ADVERTISED_1000baseT_Full; | ||
784 | if (reg & (1 << PMA_PMD_10000T_ADV_LBN)) | ||
785 | xnp_adv |= ADVERTISED_10000baseT_Full; | ||
786 | |||
787 | mdio_clause45_get_settings_ext(efx, ecmd, xnp_adv, | ||
788 | tenxpress_get_xnp_lpa(efx)); | ||
789 | 773 | ||
790 | ecmd->supported |= (SUPPORTED_100baseT_Half | | 774 | mdio_clause45_get_settings_ext(efx, ecmd, adv, lpa); |
791 | SUPPORTED_100baseT_Full | | ||
792 | SUPPORTED_1000baseT_Full); | ||
793 | 775 | ||
794 | /* Use the vendor defined C22ext register for duplex settings */ | 776 | if (efx->phy_type != PHY_TYPE_SFX7101) |
795 | if (ecmd->speed != SPEED_10000 && !ecmd->autoneg) { | 777 | ecmd->supported |= (SUPPORTED_100baseT_Full | |
796 | reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT, | 778 | SUPPORTED_1000baseT_Full); |
797 | GPHY_XCONTROL_REG); | ||
798 | ecmd->duplex = (reg & (1 << GPHY_DUPLEX_LBN) ? | ||
799 | DUPLEX_FULL : DUPLEX_HALF); | ||
800 | } | ||
801 | 779 | ||
802 | /* In loopback, the PHY automatically brings up the correct interface, | 780 | /* In loopback, the PHY automatically brings up the correct interface, |
803 | * but doesn't advertise the correct speed. So override it */ | 781 | * but doesn't advertise the correct speed. So override it */ |
804 | if (efx->loopback_mode == LOOPBACK_GPHY) | 782 | if (efx->loopback_mode == LOOPBACK_GPHY) |
805 | ecmd->speed = SPEED_1000; | 783 | ecmd->speed = SPEED_1000; |
806 | else if (LOOPBACK_MASK(efx) & SFT9001_LOOPBACKS) | 784 | else if (LOOPBACK_MASK(efx) & efx->phy_op->loopbacks) |
807 | ecmd->speed = SPEED_10000; | 785 | ecmd->speed = SPEED_10000; |
808 | } | 786 | } |
809 | 787 | ||
810 | static int sft9001_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) | 788 | static int tenxpress_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) |
811 | { | 789 | { |
812 | int phy_id = efx->mii.phy_id; | 790 | if (!ecmd->autoneg) |
813 | int rc; | 791 | return -EINVAL; |
814 | |||
815 | rc = mdio_clause45_set_settings(efx, ecmd); | ||
816 | if (rc) | ||
817 | return rc; | ||
818 | 792 | ||
819 | if (ecmd->speed != SPEED_10000 && !ecmd->autoneg) | 793 | return mdio_clause45_set_settings(efx, ecmd); |
820 | mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT, | 794 | } |
821 | GPHY_XCONTROL_REG, GPHY_DUPLEX_LBN, | ||
822 | ecmd->duplex == DUPLEX_FULL); | ||
823 | 795 | ||
824 | return rc; | 796 | static void sfx7101_set_npage_adv(struct efx_nic *efx, u32 advertising) |
797 | { | ||
798 | mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_AN, | ||
799 | MDIO_AN_10GBT_CTRL, | ||
800 | MDIO_AN_10GBT_CTRL_ADV_10G_LBN, | ||
801 | advertising & ADVERTISED_10000baseT_Full); | ||
825 | } | 802 | } |
826 | 803 | ||
827 | static bool sft9001_set_xnp_advertise(struct efx_nic *efx, u32 advertising) | 804 | static void sft9001_set_npage_adv(struct efx_nic *efx, u32 advertising) |
828 | { | 805 | { |
829 | int phy = efx->mii.phy_id; | 806 | int phy_id = efx->mii.phy_id; |
830 | int reg = mdio_clause45_read(efx, phy, MDIO_MMD_PMAPMD, | 807 | |
831 | PMA_PMD_SPEED_ENABLE_REG); | 808 | mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT, |
832 | bool enabled; | 809 | C22EXT_MSTSLV_CTRL, |
833 | 810 | C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN, | |
834 | reg &= ~((1 << 2) | (1 << 3)); | 811 | advertising & ADVERTISED_1000baseT_Full); |
835 | if (EFX_WORKAROUND_13204(efx) && | 812 | mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN, |
836 | (advertising & ADVERTISED_100baseT_Full)) | 813 | MDIO_AN_10GBT_CTRL, |
837 | reg |= 1 << PMA_PMD_100TX_ADV_LBN; | 814 | MDIO_AN_10GBT_CTRL_ADV_10G_LBN, |
838 | if (advertising & ADVERTISED_1000baseT_Full) | 815 | advertising & ADVERTISED_10000baseT_Full); |
839 | reg |= 1 << PMA_PMD_1000T_ADV_LBN; | ||
840 | if (advertising & ADVERTISED_10000baseT_Full) | ||
841 | reg |= 1 << PMA_PMD_10000T_ADV_LBN; | ||
842 | mdio_clause45_write(efx, phy, MDIO_MMD_PMAPMD, | ||
843 | PMA_PMD_SPEED_ENABLE_REG, reg); | ||
844 | |||
845 | enabled = (advertising & | ||
846 | (ADVERTISED_1000baseT_Half | | ||
847 | ADVERTISED_1000baseT_Full | | ||
848 | ADVERTISED_10000baseT_Full)); | ||
849 | if (EFX_WORKAROUND_13204(efx)) | ||
850 | enabled |= (advertising & ADVERTISED_100baseT_Full); | ||
851 | return enabled; | ||
852 | } | 816 | } |
853 | 817 | ||
854 | struct efx_phy_operations falcon_sfx7101_phy_ops = { | 818 | struct efx_phy_operations falcon_sfx7101_phy_ops = { |
@@ -858,8 +822,9 @@ struct efx_phy_operations falcon_sfx7101_phy_ops = { | |||
858 | .poll = tenxpress_phy_poll, | 822 | .poll = tenxpress_phy_poll, |
859 | .fini = tenxpress_phy_fini, | 823 | .fini = tenxpress_phy_fini, |
860 | .clear_interrupt = efx_port_dummy_op_void, | 824 | .clear_interrupt = efx_port_dummy_op_void, |
861 | .get_settings = sfx7101_get_settings, | 825 | .get_settings = tenxpress_get_settings, |
862 | .set_settings = mdio_clause45_set_settings, | 826 | .set_settings = tenxpress_set_settings, |
827 | .set_npage_adv = sfx7101_set_npage_adv, | ||
863 | .num_tests = ARRAY_SIZE(sfx7101_test_names), | 828 | .num_tests = ARRAY_SIZE(sfx7101_test_names), |
864 | .test_names = sfx7101_test_names, | 829 | .test_names = sfx7101_test_names, |
865 | .run_tests = sfx7101_run_tests, | 830 | .run_tests = sfx7101_run_tests, |
@@ -874,9 +839,9 @@ struct efx_phy_operations falcon_sft9001_phy_ops = { | |||
874 | .poll = tenxpress_phy_poll, | 839 | .poll = tenxpress_phy_poll, |
875 | .fini = tenxpress_phy_fini, | 840 | .fini = tenxpress_phy_fini, |
876 | .clear_interrupt = efx_port_dummy_op_void, | 841 | .clear_interrupt = efx_port_dummy_op_void, |
877 | .get_settings = sft9001_get_settings, | 842 | .get_settings = tenxpress_get_settings, |
878 | .set_settings = sft9001_set_settings, | 843 | .set_settings = tenxpress_set_settings, |
879 | .set_xnp_advertise = sft9001_set_xnp_advertise, | 844 | .set_npage_adv = sft9001_set_npage_adv, |
880 | .num_tests = ARRAY_SIZE(sft9001_test_names), | 845 | .num_tests = ARRAY_SIZE(sft9001_test_names), |
881 | .test_names = sft9001_test_names, | 846 | .test_names = sft9001_test_names, |
882 | .run_tests = sft9001_run_tests, | 847 | .run_tests = sft9001_run_tests, |
diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h index b810dcdf4681..78de68f4a95b 100644 --- a/drivers/net/sfc/workarounds.h +++ b/drivers/net/sfc/workarounds.h | |||
@@ -18,7 +18,6 @@ | |||
18 | #define EFX_WORKAROUND_ALWAYS(efx) 1 | 18 | #define EFX_WORKAROUND_ALWAYS(efx) 1 |
19 | #define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1) | 19 | #define EFX_WORKAROUND_FALCON_A(efx) (falcon_rev(efx) <= FALCON_REV_A1) |
20 | #define EFX_WORKAROUND_10G(efx) EFX_IS10G(efx) | 20 | #define EFX_WORKAROUND_10G(efx) EFX_IS10G(efx) |
21 | #define EFX_WORKAROUND_SFT9001A(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A) | ||
22 | #define EFX_WORKAROUND_SFT9001(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A || \ | 21 | #define EFX_WORKAROUND_SFT9001(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A || \ |
23 | (efx)->phy_type == PHY_TYPE_SFT9001B) | 22 | (efx)->phy_type == PHY_TYPE_SFT9001B) |
24 | 23 | ||
@@ -55,9 +54,6 @@ | |||
55 | 54 | ||
56 | /* Need to send XNP pages for 100BaseT */ | 55 | /* Need to send XNP pages for 100BaseT */ |
57 | #define EFX_WORKAROUND_13204 EFX_WORKAROUND_SFT9001 | 56 | #define EFX_WORKAROUND_13204 EFX_WORKAROUND_SFT9001 |
58 | /* Need to keep AN enabled */ | ||
59 | #define EFX_WORKAROUND_13963 EFX_WORKAROUND_SFT9001A | ||
60 | |||
61 | /* Don't restart AN in near-side loopback */ | 57 | /* Don't restart AN in near-side loopback */ |
62 | #define EFX_WORKAROUND_15195 EFX_WORKAROUND_SFT9001 | 58 | #define EFX_WORKAROUND_15195 EFX_WORKAROUND_SFT9001 |
63 | 59 | ||