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

net: phy: dp83867: Fix initialization of PHYCR register

When initializing the PHY control register, the FIFO depth bits are
written without reading the previous register value, i.e. all other
bits are overwritten with zero. This disables automatic MDI-X
configuration, which is enabled by default. Fix initialization by doing
a read/modify/write operation.

Signed-off-by: Stefan Hauser <stefan@shauser.net>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Stefan Hauser and committed by
David S. Miller
b291c418 373819ec

+9 -4
+9 -4
drivers/net/phy/dp83867.c
··· 57 57 58 58 /* PHY CTRL bits */ 59 59 #define DP83867_PHYCR_FIFO_DEPTH_SHIFT 14 60 + #define DP83867_PHYCR_FIFO_DEPTH_MASK (3 << 14) 60 61 61 62 /* RGMIIDCTL bits */ 62 63 #define DP83867_RGMII_TX_CLK_DELAY_SHIFT 4 ··· 134 133 static int dp83867_config_init(struct phy_device *phydev) 135 134 { 136 135 struct dp83867_private *dp83867; 137 - int ret; 138 - u16 val, delay; 136 + int ret, val; 137 + u16 delay; 139 138 140 139 if (!phydev->priv) { 141 140 dp83867 = devm_kzalloc(&phydev->mdio.dev, sizeof(*dp83867), ··· 152 151 } 153 152 154 153 if (phy_interface_is_rgmii(phydev)) { 155 - ret = phy_write(phydev, MII_DP83867_PHYCTRL, 156 - (dp83867->fifo_depth << DP83867_PHYCR_FIFO_DEPTH_SHIFT)); 154 + val = phy_read(phydev, MII_DP83867_PHYCTRL); 155 + if (val < 0) 156 + return val; 157 + val &= ~DP83867_PHYCR_FIFO_DEPTH_MASK; 158 + val |= (dp83867->fifo_depth << DP83867_PHYCR_FIFO_DEPTH_SHIFT); 159 + ret = phy_write(phydev, MII_DP83867_PHYCTRL, val); 157 160 if (ret) 158 161 return ret; 159 162 }