Commit b9274abe authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-phy-bcm54811-phy-initialization'

 says:

====================
net: phy: bcm54811: PHY initialization

Proper bcm54811 PHY driver initialization for MII-Lite.

The bcm54811 PHY in MLP package must be setup for MII-Lite interface
mode by software. Normally, the PHY to MAC interface is selected in
hardware by setting the bootstrap pins of the PHY. However, MII and
MII-Lite share the same hardware setup and must be distinguished by
software, setting appropriate bit in a configuration register.
The MII-Lite interface mode is non-standard one, defined by Broadcom
for some of their PHYs. The MII-Lite lightness consist in omitting
RXER, TXER, CRS and COL signals of the standard MII interface.
Absence of COL them makes half-duplex links modes impossible but
does not interfere with Broadcom's BroadR-Reach link modes, because
they are full-duplex only.
To do it in a clean way, MII-Lite must be introduced first, including
its limitation to link modes (no half-duplex), because it is a
prerequisite for the patch #3 of this series. The patch #4 does not
depend on MII-Lite directly but both #3 and #4 are necessary for
bcm54811 to work properly without additional configuration steps to be
done - for example in the bootloader, before the kernel starts.

PATCH 1 - Add MII-Lite PHY interface mode as defined by Broadcom for
   their two-wire PHYs. It can be used with most Ethernet controllers
   under certain limitations (no half-duplex link modes etc.).

PATCH 2 - Add MII-Lite PHY interface type

PATCH 3 - Activation of MII-Lite interface mode on Broadcom bcm5481x
   PHYs

PATCH 4 - Initialize the BCM54811 PHY properly so that it conforms
   to the datasheet regarding a reserved bit in the LRE Control
   register, which must be written to zero after every device reset.
   Ignore the LDS capability bit in LRE Status register on bcm54811.
====================

Link: https://patch.msgid.link/20250708090140.61355-1-kamilh@axis.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 6dfcbd7d 3117a11f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ properties:
      # MAC.
      - internal
      - mii
      - mii-lite
      - gmii
      - sgmii
      - psgmii
+7 −0
Original line number Diff line number Diff line
@@ -333,6 +333,13 @@ Some of the interface modes are described below:
    SerDes lane, each port having speeds of 2.5G / 1G / 100M / 10M achieved
    through symbol replication. The PCS expects the standard USXGMII code word.

``PHY_INTERFACE_MODE_MIILITE``
    Non-standard, simplified MII mode, without TXER, RXER, CRS and COL signals
    as defined for the MII. The absence of COL signal makes half-duplex link
    modes impossible but does not interfere with BroadR-Reach link modes on
    Broadcom (and other two-wire Ethernet) PHYs, because they are full-duplex
    only.

Pause frames / flow control
===========================

+34 −5
Original line number Diff line number Diff line
@@ -407,7 +407,7 @@ static int bcm5481x_set_brrmode(struct phy_device *phydev, bool on)
static int bcm54811_config_init(struct phy_device *phydev)
{
	struct bcm54xx_phy_priv *priv = phydev->priv;
	int err, reg;
	int err, reg, exp_sync_ethernet;

	/* Enable CLK125 MUX on LED4 if ref clock is enabled. */
	if (!(phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED)) {
@@ -424,6 +424,18 @@ static int bcm54811_config_init(struct phy_device *phydev)
	if (priv->brr_mode)
		phydev->autoneg = 0;

	/* Enable MII Lite (No TXER, RXER, CRS, COL) if configured */
	if (phydev->interface == PHY_INTERFACE_MODE_MIILITE)
		exp_sync_ethernet = BCM_EXP_SYNC_ETHERNET_MII_LITE;
	else
		exp_sync_ethernet = 0;

	err = bcm_phy_modify_exp(phydev, BCM_EXP_SYNC_ETHERNET,
				 BCM_EXP_SYNC_ETHERNET_MII_LITE,
				 exp_sync_ethernet);
	if (err < 0)
		return err;

	return bcm5481x_set_brrmode(phydev, priv->brr_mode);
}

@@ -655,7 +667,7 @@ static int bcm5481x_read_abilities(struct phy_device *phydev)
{
	struct device_node *np = phydev->mdio.dev.of_node;
	struct bcm54xx_phy_priv *priv = phydev->priv;
	int i, val, err;
	int i, val, err, aneg;

	for (i = 0; i < ARRAY_SIZE(bcm54811_linkmodes); i++)
		linkmode_clear_bit(bcm54811_linkmodes[i], phydev->supported);
@@ -676,9 +688,19 @@ static int bcm5481x_read_abilities(struct phy_device *phydev)
		if (val < 0)
			return val;

		/* BCM54811 is not capable of LDS but the corresponding bit
		 * in LRESR is set to 1 and marked "Ignore" in the datasheet.
		 * So we must read the bcm54811 as unable to auto-negotiate
		 * in BroadR-Reach mode.
		 */
		if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54811)
			aneg = 0;
		else
			aneg = val & LRESR_LDSABILITY;

		linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
				 phydev->supported,
				 val & LRESR_LDSABILITY);
				 aneg);
		linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT1_Full_BIT,
				 phydev->supported,
				 val & LRESR_100_1PAIR);
@@ -735,8 +757,15 @@ static int bcm54811_config_aneg(struct phy_device *phydev)

	/* Aneg firstly. */
	if (priv->brr_mode) {
		/* BCM54811 is only capable of autonegotiation in IEEE mode */
		phydev->autoneg = 0;
		/* BCM54811 is only capable of autonegotiation in IEEE mode.
		 * In BroadR-Reach mode, disable the Long Distance Signaling,
		 * the BRR mode autoneg as supported in other Broadcom PHYs.
		 * This bit is marked as "Reserved" and "Default 1, must be
		 *  written to 0 after every device reset" in the datasheet.
		 */
		ret = phy_modify(phydev, MII_BCM54XX_LRECR, LRECR_LDSEN, 0);
		if (ret < 0)
			return ret;
		ret = bcm_config_lre_aneg(phydev, false);
	} else {
		ret = genphy_config_aneg(phydev);
+1 −0
Original line number Diff line number Diff line
@@ -115,6 +115,7 @@ int phy_interface_num_ports(phy_interface_t interface)
		return 0;
	case PHY_INTERFACE_MODE_INTERNAL:
	case PHY_INTERFACE_MODE_MII:
	case PHY_INTERFACE_MODE_MIILITE:
	case PHY_INTERFACE_MODE_GMII:
	case PHY_INTERFACE_MODE_TBI:
	case PHY_INTERFACE_MODE_REVMII:
+4 −0
Original line number Diff line number Diff line
@@ -316,6 +316,10 @@ unsigned long phy_caps_from_interface(phy_interface_t interface)
		link_caps |= BIT(LINK_CAPA_100HD) | BIT(LINK_CAPA_100FD);
		break;

	case PHY_INTERFACE_MODE_MIILITE:
		link_caps |= BIT(LINK_CAPA_10FD) | BIT(LINK_CAPA_100FD);
		break;

	case PHY_INTERFACE_MODE_TBI:
	case PHY_INTERFACE_MODE_MOCA:
	case PHY_INTERFACE_MODE_RTBI:
Loading