Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

phy: lynx-28g: distinguish between 10GBASE-R and USXGMII

The driver does not handle well protocol switching to or from USXGMII,
because it conflates it with 10GBase-R.

In the expected USXGMII use case, that isn't a problem, because SerDes
protocol switching performed by the lynx-28g driver is not necessary,
because USXGMII natively supports multiple speeds, as opposed to SFP
modules using 1000Base-X or 10GBase-R which require switching between
the 2.

That being said, let's be explicit, and in case someone requests a
protocol change which involves USXGMII, let's do the right thing.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Link: https://patch.msgid.link/20251125114847.804961-13-vladimir.oltean@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Vladimir Oltean and committed by
Vinod Koul
55ce1d64 6a1ae518

+74 -13
+74 -13
drivers/phy/freescale/phy-fsl-lynx-28g.c
··· 246 246 enum lynx_lane_mode { 247 247 LANE_MODE_UNKNOWN, 248 248 LANE_MODE_1000BASEX_SGMII, 249 - LANE_MODE_10GBASER_USXGMII, 249 + LANE_MODE_10GBASER, 250 + LANE_MODE_USXGMII, 250 251 LANE_MODE_MAX, 251 252 }; 252 253 ··· 317 316 .smp_autoz_d1r = 0, 318 317 .smp_autoz_eg1r = 0, 319 318 }, 320 - [LANE_MODE_10GBASER_USXGMII] = { 319 + [LANE_MODE_USXGMII] = { 320 + .proto_sel = LNaGCR0_PROTO_SEL_XFI, 321 + .if_width = LNaGCR0_IF_WIDTH_20_BIT, 322 + .teq_type = EQ_TYPE_2TAP, 323 + .sgn_preq = 1, 324 + .ratio_preq = 0, 325 + .sgn_post1q = 1, 326 + .ratio_post1q = 3, 327 + .amp_red = 7, 328 + .adpt_eq = 48, 329 + .enter_idle_flt_sel = 0, 330 + .exit_idle_flt_sel = 0, 331 + .data_lost_th_sel = 0, 332 + .gk2ovd = 0, 333 + .gk3ovd = 0, 334 + .gk4ovd = 0, 335 + .gk2ovd_en = 0, 336 + .gk3ovd_en = 0, 337 + .gk4ovd_en = 0, 338 + .eq_offset_ovd = 0x1f, 339 + .eq_offset_ovd_en = 0, 340 + .eq_offset_rng_dbl = 1, 341 + .eq_blw_sel = 1, 342 + .eq_boost = 0, 343 + .spare_in = 0, 344 + .smp_autoz_d1r = 2, 345 + .smp_autoz_eg1r = 0, 346 + }, 347 + [LANE_MODE_10GBASER] = { 321 348 .proto_sel = LNaGCR0_PROTO_SEL_XFI, 322 349 .if_width = LNaGCR0_IF_WIDTH_20_BIT, 323 350 .teq_type = EQ_TYPE_2TAP, ··· 442 413 switch (lane_mode) { 443 414 case LANE_MODE_1000BASEX_SGMII: 444 415 return "1000Base-X/SGMII"; 445 - case LANE_MODE_10GBASER_USXGMII: 446 - return "10GBase-R/USXGMII"; 416 + case LANE_MODE_10GBASER: 417 + return "10GBase-R"; 418 + case LANE_MODE_USXGMII: 419 + return "USXGMII"; 447 420 default: 448 421 return "unknown"; 449 422 } ··· 458 427 case PHY_INTERFACE_MODE_1000BASEX: 459 428 return LANE_MODE_1000BASEX_SGMII; 460 429 case PHY_INTERFACE_MODE_10GBASER: 430 + return LANE_MODE_10GBASER; 461 431 case PHY_INTERFACE_MODE_USXGMII: 462 - return LANE_MODE_10GBASER_USXGMII; 432 + return LANE_MODE_USXGMII; 463 433 default: 464 434 return LANE_MODE_UNKNOWN; 465 435 } ··· 528 496 break; 529 497 case PLLnCR1_FRATE_10G_20GVCO: 530 498 switch (lane_mode) { 531 - case LANE_MODE_10GBASER_USXGMII: 499 + case LANE_MODE_10GBASER: 500 + case LANE_MODE_USXGMII: 532 501 lynx_28g_lane_rmw(lane, LNaTGCR0, 533 502 FIELD_PREP(LNaTGCR0_N_RATE, LNaTGCR0_N_RATE_FULL), 534 503 LNaTGCR0_N_RATE); ··· 627 594 pccr->width = 4; 628 595 pccr->shift = SGMII_CFG(lane); 629 596 break; 630 - case LANE_MODE_10GBASER_USXGMII: 597 + case LANE_MODE_USXGMII: 598 + case LANE_MODE_10GBASER: 631 599 pccr->offset = PCCC; 632 600 pccr->width = 4; 633 601 pccr->shift = SXGMII_CFG(lane); ··· 645 611 switch (lane_mode) { 646 612 case LANE_MODE_1000BASEX_SGMII: 647 613 return SGMIIaCR0(lane); 648 - case LANE_MODE_10GBASER_USXGMII: 614 + case LANE_MODE_USXGMII: 615 + case LANE_MODE_10GBASER: 649 616 return SXGMIIaCR0(lane); 650 617 default: 651 618 return -EOPNOTSUPP; 652 619 } 620 + } 621 + 622 + static int lynx_pccr_read(struct lynx_28g_lane *lane, enum lynx_lane_mode mode, 623 + u32 *val) 624 + { 625 + struct lynx_28g_priv *priv = lane->priv; 626 + struct lynx_pccr pccr; 627 + u32 tmp; 628 + int err; 629 + 630 + err = lynx_28g_get_pccr(mode, lane->id, &pccr); 631 + if (err) 632 + return err; 633 + 634 + tmp = lynx_28g_read(priv, pccr.offset); 635 + *val = (tmp >> pccr.shift) & GENMASK(pccr.width - 1, 0); 636 + 637 + return 0; 653 638 } 654 639 655 640 static int lynx_pccr_write(struct lynx_28g_lane *lane, ··· 882 829 case LANE_MODE_1000BASEX_SGMII: 883 830 val |= PCC8_SGMIIa_CFG; 884 831 break; 885 - case LANE_MODE_10GBASER_USXGMII: 886 - val |= PCCC_SXGMIIn_CFG | PCCC_SXGMIIn_XFI; 832 + case LANE_MODE_10GBASER: 833 + val |= PCCC_SXGMIIn_XFI; 834 + fallthrough; 835 + case LANE_MODE_USXGMII: 836 + val |= PCCC_SXGMIIn_CFG; 887 837 break; 888 838 default: 889 839 break; ··· 1011 955 break; 1012 956 case PLLnCR1_FRATE_10G_20GVCO: 1013 957 /* 10.3125GHz clock net */ 1014 - __set_bit(LANE_MODE_10GBASER_USXGMII, pll->supported); 958 + __set_bit(LANE_MODE_10GBASER, pll->supported); 959 + __set_bit(LANE_MODE_USXGMII, pll->supported); 1015 960 break; 1016 961 default: 1017 962 /* 6GHz, 12.890625GHz, 8GHz */ ··· 1057 1000 1058 1001 static void lynx_28g_lane_read_configuration(struct lynx_28g_lane *lane) 1059 1002 { 1060 - u32 pss, protocol; 1003 + u32 pccr, pss, protocol; 1061 1004 1062 1005 pss = lynx_28g_lane_read(lane, LNaPSS); 1063 1006 protocol = FIELD_GET(LNaPSS_TYPE, pss); ··· 1066 1009 lane->mode = LANE_MODE_1000BASEX_SGMII; 1067 1010 break; 1068 1011 case LNaPSS_TYPE_XFI: 1069 - lane->mode = LANE_MODE_10GBASER_USXGMII; 1012 + lynx_pccr_read(lane, LANE_MODE_10GBASER, &pccr); 1013 + if (pccr & PCCC_SXGMIIn_XFI) 1014 + lane->mode = LANE_MODE_10GBASER; 1015 + else 1016 + lane->mode = LANE_MODE_USXGMII; 1070 1017 break; 1071 1018 default: 1072 1019 lane->mode = LANE_MODE_UNKNOWN;