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

net: phy: dp83822: Fix RGMII TX delay configuration

The logic for enabling the TX clock shift is inverse of enabling the RX
clock shift. The TX clock shift is disabled when DP83822_TX_CLK_SHIFT is
set. Correct the current behavior and always write the delay configuration
to ensure consistent delay settings regardless of bootloader configuration.

Reference: https://www.ti.com/lit/ds/symlink/dp83822i.pdf p. 69

Fixes: 8095295292b5 ("net: phy: DP83822: Add setting the fixed internal delay")
Signed-off-by: Tim Pambor <tp@osasysteme.de>
Link: https://lore.kernel.org/r/20240305110608.104072-1-tp@osasysteme.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Tim Pambor and committed by
Jakub Kicinski
c8a5c731 9831e35e

+20 -17
+20 -17
drivers/net/phy/dp83822.c
··· 380 380 { 381 381 struct dp83822_private *dp83822 = phydev->priv; 382 382 struct device *dev = &phydev->mdio.dev; 383 - int rgmii_delay; 383 + int rgmii_delay = 0; 384 384 s32 rx_int_delay; 385 385 s32 tx_int_delay; 386 386 int err = 0; ··· 390 390 rx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0, 391 391 true); 392 392 393 - if (rx_int_delay <= 0) 394 - rgmii_delay = 0; 395 - else 396 - rgmii_delay = DP83822_RX_CLK_SHIFT; 393 + /* Set DP83822_RX_CLK_SHIFT to enable rx clk internal delay */ 394 + if (rx_int_delay > 0) 395 + rgmii_delay |= DP83822_RX_CLK_SHIFT; 397 396 398 397 tx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0, 399 398 false); 399 + 400 + /* Set DP83822_TX_CLK_SHIFT to disable tx clk internal delay */ 400 401 if (tx_int_delay <= 0) 401 - rgmii_delay &= ~DP83822_TX_CLK_SHIFT; 402 - else 403 402 rgmii_delay |= DP83822_TX_CLK_SHIFT; 404 403 405 - if (rgmii_delay) { 406 - err = phy_set_bits_mmd(phydev, DP83822_DEVADDR, 407 - MII_DP83822_RCSR, rgmii_delay); 408 - if (err) 409 - return err; 410 - } 404 + err = phy_modify_mmd(phydev, DP83822_DEVADDR, MII_DP83822_RCSR, 405 + DP83822_RX_CLK_SHIFT | DP83822_TX_CLK_SHIFT, rgmii_delay); 406 + if (err) 407 + return err; 411 408 412 - phy_set_bits_mmd(phydev, DP83822_DEVADDR, 413 - MII_DP83822_RCSR, DP83822_RGMII_MODE_EN); 409 + err = phy_set_bits_mmd(phydev, DP83822_DEVADDR, 410 + MII_DP83822_RCSR, DP83822_RGMII_MODE_EN); 411 + 412 + if (err) 413 + return err; 414 414 } else { 415 - phy_clear_bits_mmd(phydev, DP83822_DEVADDR, 416 - MII_DP83822_RCSR, DP83822_RGMII_MODE_EN); 415 + err = phy_clear_bits_mmd(phydev, DP83822_DEVADDR, 416 + MII_DP83822_RCSR, DP83822_RGMII_MODE_EN); 417 + 418 + if (err) 419 + return err; 417 420 } 418 421 419 422 if (dp83822->fx_enabled) {