aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sfc')
-rw-r--r--drivers/net/sfc/ethtool.c3
-rw-r--r--drivers/net/sfc/mdio_10g.c177
-rw-r--r--drivers/net/sfc/mdio_10g.h3
-rw-r--r--drivers/net/sfc/net_driver.h4
-rw-r--r--drivers/net/sfc/tenxpress.c151
-rw-r--r--drivers/net/sfc/workarounds.h4
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
269static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr, u32 xnp) 269static 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 */
314void mdio_clause45_get_settings_ext(struct efx_nic *efx, 311void 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
744static u32 tenxpress_get_xnp_lpa(struct efx_nic *efx) 746static void
747tenxpress_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
764static 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
772static 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
810static int sft9001_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) 788static 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; 796static 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
827static bool sft9001_set_xnp_advertise(struct efx_nic *efx, u32 advertising) 804static 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
854struct efx_phy_operations falcon_sfx7101_phy_ops = { 818struct 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