On 11/30/18 8:21 AM, Andrew Lunn wrote:
> Hi Steve
> 
> Cool to see another interface being made DSA capable.
> 
>> +/**
>> + *  ixgbe_msca - Write the command register and poll for completion/timeout
>> + *  @hw: pointer to hardware structure
>> + *  @cmd: command register value to write
>> + **/
>> +static s32 ixgbe_msca_cmd(struct ixgbe_hw *hw, u32 cmd)
>> +{
>> +    u32 i;
>> +
>> +    IXGBE_WRITE_REG(hw, IXGBE_MSCA, cmd);
>> +
>> +    for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
>> +            udelay(10);
>> +            cmd = IXGBE_READ_REG(hw, IXGBE_MSCA);
>> +            if (!(cmd & IXGBE_MSCA_MDI_COMMAND))
>> +                    return 0;
>> +    }
>> +
>> +    return -ETIMEDOUT;
> 
> Please consider using readx_poll_timeout()

OK

>> +}
>> +
>> +/**
>> + *  ixgbe_msca - Use device_id to figure out if MDIO bus is shared between 
>> MACs.
>> + *  The embedded x550(s) in the C3000 line of SoCs only have a single 
>> mii_bus
>> + *  shared between all MACs, and that introduces some new mask flags that 
>> need
>> + *  to be passed to the *_swfw_sync callbacks.
>> + *  @hw: pointer to hardware structure
>> + **/
>> +static bool ixgbe_is_shared_mii(struct ixgbe_hw *hw)
>> +{
>> +    switch (hw->device_id) {
>> +    case IXGBE_DEV_ID_X550EM_A_KR:
>> +    case IXGBE_DEV_ID_X550EM_A_KR_L:
>> +    case IXGBE_DEV_ID_X550EM_A_SFP_N:
>> +    case IXGBE_DEV_ID_X550EM_A_SGMII:
>> +    case IXGBE_DEV_ID_X550EM_A_SGMII_L:
>> +    case IXGBE_DEV_ID_X550EM_A_10G_T:
>> +    case IXGBE_DEV_ID_X550EM_A_SFP:
>> +    case IXGBE_DEV_ID_X550EM_A_1G_T:
>> +    case IXGBE_DEV_ID_X550EM_A_1G_T_L:
>> +            return true;
>> +    }
>> +
>> +    return false;
>> +}
>> +
>> +/**
>> + *  ixgbe_mii_bus_read - Read a clause 22/45 register
>> + *  @hw: pointer to hardware structure
>> + *  @addr: address
>> + *  @regnum: register number
>> + **/
>> +static s32 ixgbe_mii_bus_read(struct mii_bus *bus, int addr, int regnum)
>> +{
>> +    struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)bus->priv;
>> +    struct ixgbe_hw *hw = &adapter->hw;
>> +    u32 hwaddr, cmd, gssr = hw->phy.phy_semaphore_mask;
>> +    s32 data;
>> +
>> +    if (ixgbe_is_shared_mii(hw)) {
>> +            gssr |= IXGBE_GSSR_TOKEN_SM;
>> +            if (hw->bus.lan_id)
>> +                    gssr |= IXGBE_GSSR_PHY1_SM;
>> +            else
>> +                    gssr |= IXGBE_GSSR_PHY0_SM;
>> +    }
> 
> Could you explain this shared bus a bit more.  If there is only one
> physical MDIO bus, you should only register one bus with Linux. So i
> would not normally expect to see ixgbe_is_shared_mii() sort of
> statements into the read/write functions. That tends to happen at the
> point you are registering the MDIO bus, and when looking for the MACs
> PHY on the bus.

Yep, registering multiple interfaces is wrong.  The first board I tested
against only had a single MAC enabled (they can be disabled/hidden via
straps) so it just happened to work.  Then I moved to a board with all
four interfaces enabled and found this.

The Intel C3xxx family of SoCs have up to four ixgbe MACs.  These are
structured as two devices of two functions each on fixed internal root
ports.

from lspci:
<snip>
            +-16.0-[05]--+-00.0
            |            \-00.1
            +-17.0-[06]--+-00.0
            |            \-00.1
<snip>

Each of those MACs exposes the same set of MDIO control registers as if
there are four interface, but there's really only a single bus in the
hardware for these SoCs.

How about I change:
1) ixgbe_is_shared_mii() -> ixgbe_is_x550em_a()
2) ixgbe_mii_bus_(read|write) -> ixgbe_x550em_a_mii_bus_(read|write) and
    update the phy_semaphore_mask unconditionally
3) Only have ixgbe_mii_bus_init() register something for the x550em_a
    devices for now, and leave handling other platforms for the future.
4) Have ixgbe_mii_bus_init() register only a single mdiobus for func 0
    of the device downstream of the 00:16.0 root port, or if that's been
    disabled then func 0 downstream of the 00:17.0 root port.  All of the
    devices on bus 0 of the SoC are at fixed device/function locations.

Would that be acceptable?

Reply via email to