Re: [PATCH RFC net-next 1/2] net: pcs: xpcs: Add special code to operate in Microchip KSZ9477 switch

From: Vladimir Oltean
Date: Tue Jan 28 2025 - 10:23:51 EST


On Tue, Jan 28, 2025 at 12:33:11PM +0000, Russell King (Oracle) wrote:
> I wonder what the original Synopsys documentation says about the AN
> control register.

My private XPCS databook 2017-12.pdf, the applicability of which I cannot
vouch for, has a section with programming guidelines for SGMII
Auto-Negotiation. I quote:

| Clause 37 auto-negotiation can be performed in the SGMII mode by
| programming various registers as follows:
|
| 1. In configurations with both 10G and 1G mode speed mode, switch
| DWC_xpcs to 1G speed mode by following the steps described in
| "Switching to 1G or KX Mode and 10 or 100 Mbps SGMII Speed".
|
| 2. In Backplane Ethernet PCS configurations, program bit[12] (AN_EN) of
| SR_AN_CTRL Register to 0 and bit[12] (CL37_BP) of VR_XS_PCS_DIG_CTRL1
| Register to 1.
|
| 3. Disable Clause 37 auto-negotiation by programming bit [12]
| (AN_ENABLE) of SR_MII_CTRL Register to 0 (in case it is already
| enabled).
|
| 4. Program various fields of VR_MII_AN_CTRL Register appropriately as
| follows:
| - Program PCS_MODE to 2’b10
| - Program TX_CONFIG to 1 (PHY side SGMII) or 0 (MAC side SGMII) based
| on your requirement
| - Program MII_AN_INTR_EN to 1, to enable auto-negotiation complete
| interrupt
| - If TX_CONFIG is set to 1 and bit[0] of VR_MII_DIG_CTRL1 Register is
| set to 0, program SGMII_LINK_STS to indicate the link status to the
| MAC side SGMII.
| - Program MII_CTRL to 0 or 1, as per your requirement.
|
| 5. If DWC_xpcs is configured as PHY-side SGMII in the above step, you
| can program bit [0] of VR_MII_DIG_CTRL1 Register to 1, if you wish to
| use the values of the xpcs_sgmii_link_sts_i input ports.
| xpcs_sgmii_full_duplex_i and xpcs_sgmii_link_speed_i as the
| transmitted configuration word.
|
| 6. If DWC_xpcs is configured as PHY-side SGMII and if bit[0] of
| VR_MII_DIG_CTRL1 Register is set to 0,
| - Program SS13 and SS6 bits of SR_MII_CTRL Register to the required
| SGMII Speed
| - Program bit [5] (FD) of SR_MII_AN_ADV to the desired mode. This
| step is mandatory even if you wish to leave the FD register bit to
| its default value.
|
| 7. If DWC_xpcs is configured as MAC-side SGMII in step 4, program bit[9]
| of VR_MII_DIG_CTRL1 Register to 1, for DWC_xpcs to automatically
| switch to the negotiated link-speed, after the completion of
| auto-negotiation.
|
| 8. Enable CL37 Auto-negotiation, by programming bit[12] of the
| SR_MII_CTRL Register to 1.

In my reading of these steps, writing to DW_VR_MII_AN_CTRL does not
depend on a subsequent write to SR_MII_AN_ADV to take effect.
But there is this additional note in the databook:

| If TX_CONFIG=1 and Bit[0] (SGMII_PHY_MODE_CTRL) of VR_MII_DIG_CTRL1 = 0,
| program the SR_MII_AN_ADV only after programming 'SGMII_LINK_STS' bit
| (of VR_MII_AN_CTRL) and SS13 and SS6 bits (of SR_MII_CTRL)

So my understanding is that SR_MII_AN_ADV needs to be written only if
TX_CONFIG=1 (SJA1105 calls this AUTONEG_CONTROL[PHY_MODE]). That's quite
different, and that will make sense when you consider that there's also
a table with the places the autoneg code word gets its info from:

Config_Reg Bits in the 1000BASE-X and SGMII Mode

+----------------+-------------------+--------------------+--------------------------------------------+
| Config_Reg bit | 1000Base-X mode | SGMII mode value | SGMII mode value |
| | | when TX_CONFIG = 0 | when TX_CONFIG = 1 |
+----------------+-------------------+--------------------+--------------------------------------------+
| 15 | Next page support | 0 | Link up or down. |
| | | | If DW_VR_MII_DIG_CTRL1_PHY_MODE_CTRL == 0, |
| | | | this bit is derived from Bit 4 |
| | | | (SGMII_LINK_STS) of the VR_MII_AN_CTRL. |
| | | | If DW_VR_MII_DIG_CTRL1_PHY_MODE_CTRL == 1, |
| | | | this bit is derived from the input port |
| | | | 'xpcs_sgmii_link_sts_i' |
+----------------+-------------------+--------------------+--------------------------------------------+
| 14 | ACK | 1 | 1 |
+----------------+-------------------+--------------------+--------------------------------------------+
| 13 | RF[1] | 0 | 0 |
+----------------+-------------------+--------------------+--------------------------------------------+
| 12 | RF[0] | 0 | FULL_DUPLEX |
| | | | If DW_VR_MII_DIG_CTRL1_PHY_MODE_CTRL == 0, |
| | | | this bit is derived from Bit 5 (FD) of |
| | | | the SR_MII_AN_ADV. |
| | | | If DW_VR_MII_DIG_CTRL1_PHY_MODE_CTRL == 1, |
| | | | this bit is derived from the input port |
| | | | 'xpcs_sgmii_full_duplex_i' |
+----------------+-------------------+--------------------+--------------------------------------------+
| 11:10 | Reserved | 0 | SPEED |
| | | | If DW_VR_MII_DIG_CTRL1_PHY_MODE_CTRL == 0, |
| | | | these bits are derived from Bit 13 (SS13) |
| | | | and Bit 6 (SS6) of the SR_MII_CTRL. |
| | | | If DW_VR_MII_DIG_CTRL1_PHY_MODE_CTRL == 1, |
| | | | this bit is derived from the input port |
| | | | 'xpcs_sgmii_link_speed_i[1:0]' |
+----------------+-------------------+--------------------+--------------------------------------------+
| 9 | Reserved | 0 | 0 |
+----------------+-------------------+--------------------+--------------------------------------------+
| 8:7 | PAUSE[1:0] | 0 | 0 |
+----------------+-------------------+--------------------+--------------------------------------------+
| 6 | HALF_DUPLEX | 0 | 0 |
+----------------+-------------------+--------------------+--------------------------------------------+
| 5 | FULL_DUPLEX | 0 | 0 |
+----------------+-------------------+--------------------+--------------------------------------------+
| 4:1 | Reserved | 0 | 0 |
+----------------+-------------------+--------------------+--------------------------------------------+
| 0 | Reserved | 1 | 1 |
+----------------+-------------------+--------------------+--------------------------------------------+

I haven't figured out either what might be going on with the KSZ9477
integration, I just made a quick refresher and I thought this might be
useful for you as well, Russell. I do notice Tristram does force
TX_CONFIG=1 (DW_VR_MII_TX_CONFIG_PHY_SIDE_SGMII), but I don't understand
what's truly behind that. Hopefully just a misunderstanding.

Tristram, why do you set this field to 1? Linux only supports the
configuration where a MAC behaves like a MAC. There needs to be an
entire discussion if you want to configure a MAC to be a SGMII autoneg
master (like a PHY), how to model that.

Could you confirm that the requirement to program the SGMII
Auto-Negotiation Advertisement Register only exists if the Transmit
Configuration Master field is programmed to 1, like you are doing?