• Marek Behún's avatar
    net: dsa: mv88e6xxx: Fix inband AN for 2500base-x on 88E6393X family · 163000db
    Marek Behún authored
    Inband AN is broken on Amethyst in 2500base-x mode when set by standard
    mechanism (via cmode).
    
    (There probably is some weird setting done by default in the switch for
     this mode that make it cycle in some state or something, because when
     the peer is the mvneta controller, it receives link change interrupts
     every ~0.3ms, but the link is always down.)
    
    Get around this by configuring the PCS mode to 1000base-x (where inband
    AN works), and then changing the SerDes frequency while SerDes
    transmitter and receiver are disabled, before enabling SerDes PHY. After
    disabling SerDes PHY, change the PCS mode back to 2500base-x, to avoid
    confusing the device (if we leave it at 1000base-x PCS mode but with
    different frequency, and then change cmode to sgmii, the device won't
    change the frequency because it thinks it already has the correct one).
    
    The register which changes the frequency is undocumented. I discovered
    it by going through all registers in the ranges 4.f000-4.f100 and
    1e.8000-1e.8200 for all SerDes cmodes (sgmii, 1000base-x, 2500base-x,
    5gbase-r, 10gbase-r, usxgmii) and filtering out registers that didn't
    make sense (the value was the same for modes which have different
    frequency). The result of this was:
    
        reg   sgmii 1000base-x 2500base-x 5gbase-r 10gbase-r usxgmii
      04.f002  005b       0058       0059     005c      005d    005f
      04.f076  3000       0000       1000     4000      5000    7000
      04.f07c  0950       0950       1850     0550      0150    0150
      1e.8000  0059       0059       0058     0055      0051    0051
      1e.8140  0e20       0e20       0e28     0e21      0e42    0e42
    
    Register 04.f002 is the documented Port Operational Confiuration
    register, it's last 3 bits select PCS type, so changing this register
    also changes the frequency to the appropriate value.
    
    Registers 04.f076 and 04.f07c are not writable.
    
    Undocumented register 1e.8000 was the one: changing bits 3:0 from 9 to 8
    changed SerDes frequency to 3.125 GHz, while leaving the value of PCS
    mode in register 04.f002.2:0 at 1000base-x. Inband autonegotiation
    started working correctly.
    
    (I didn't try anything with register 1e.8140 since 1e.8000 solved the
     problem.)
    
    Since I don't have documentation for this register 1e.8000.3:0, I am
    using the constants without names, but my hypothesis is that this
    register selects PHY frequency. If in the future I have access to an
    oscilloscope able to handle these frequencies, I will try to test this
    hypothesis.
    
    Fixes: de776d0d ("net: dsa: mv88e6xxx: add support for mv88e6393x family")
    Signed-off-by: default avatarMarek Behún <kabel@kernel.org>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    163000db
serdes.h 9.27 KB