source of highlighter
plain | download
    1 From 6bc360cf9aa17dcd07030eb06680cb5654eac20d Mon Sep 17 00:00:00 2001
    2 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
    3 Date: Tue, 11 Jan 2022 18:31:40 +0100
    4 Subject: [PATCH] net: dsa: mv88e6xxx: use BMSR_ANEGCOMPLETE bit for filling
    5  an_complete
    6 MIME-Version: 1.0
    7 Content-Type: text/plain; charset=UTF-8
    8 Content-Transfer-Encoding: 8bit
    9 
   10 Commit ede359d8843a ("net: dsa: mv88e6xxx: Link in pcs_get_state() if AN
   11 is bypassed") added the ability to link if AN was bypassed, and added
   12 filling of state->an_complete field, but set it to true if AN was
   13 enabled in BMCR, not when AN was reported complete in BMSR.
   14 
   15 This was done because for some reason, when I wanted to use BMSR value
   16 to infer an_complete, I was looking at BMSR_ANEGCAPABLE bit (which was
   17 always 1), instead of BMSR_ANEGCOMPLETE bit.
   18 
   19 Use BMSR_ANEGCOMPLETE for filling state->an_complete.
   20 
   21 Fixes: ede359d8843a ("net: dsa: mv88e6xxx: Link in pcs_get_state() if AN is bypassed")
   22 Signed-off-by: Marek BehĂșn <kabel@kernel.org>
   23 ---
   24  drivers/net/dsa/mv88e6xxx/serdes.c | 27 +++++++++++----------------
   25  1 file changed, 11 insertions(+), 16 deletions(-)
   26 
   27 diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c
   28 index 6a177bf654ee..bde2228b674d 100644
   29 --- a/drivers/net/dsa/mv88e6xxx/serdes.c
   30 +++ b/drivers/net/dsa/mv88e6xxx/serdes.c
   31 @@ -50,22 +50,17 @@ static int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip,
   32  }
   33  
   34  static int mv88e6xxx_serdes_pcs_get_state(struct mv88e6xxx_chip *chip,
   35 -                                         u16 ctrl, u16 status, u16 lpa,
   36 +                                         u16 bmsr, u16 lpa, u16 status,
   37                                           struct phylink_link_state *state)
   38  {
   39         state->link = !!(status & MV88E6390_SGMII_PHY_STATUS_LINK);
   40 +       state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);
   41  
   42         if (status & MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID) {
   43                 /* The Spped and Duplex Resolved register is 1 if AN is enabled
   44                  * and complete, or if AN is disabled. So with disabled AN we
   45 -                * still get here on link up. But we want to set an_complete
   46 -                * only if AN was enabled, thus we look at BMCR_ANENABLE.
   47 -                * (According to 802.3-2008 section 22.2.4.2.10, we should be
   48 -                *  able to get this same value from BMSR_ANEGCAPABLE, but tests
   49 -                *  show that these Marvell PHYs don't conform to this part of
   50 -                *  the specificaion - BMSR_ANEGCAPABLE is simply always 1.)
   51 +                * still get here on link up.
   52                  */
   53 -               state->an_complete = !!(ctrl & BMCR_ANENABLE);
   54                 state->duplex = status &
   55                                 MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL ?
   56                                                  DUPLEX_FULL : DUPLEX_HALF;
   57 @@ -191,12 +186,12 @@ int mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
   58  int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
   59                                    int lane, struct phylink_link_state *state)
   60  {
   61 -       u16 lpa, status, ctrl;
   62 +       u16 bmsr, lpa, status;
   63         int err;
   64  
   65 -       err = mv88e6352_serdes_read(chip, MII_BMCR, &ctrl);
   66 +       err = mv88e6352_serdes_read(chip, MII_BMSR, &bmsr);
   67         if (err) {
   68 -               dev_err(chip->dev, "can't read Serdes PHY control: %d\n", err);
   69 +               dev_err(chip->dev, "can't read Serdes BMSR: %d\n", err);
   70                 return err;
   71         }
   72  
   73 @@ -212,7 +207,7 @@ int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
   74                 return err;
   75         }
   76  
   77 -       return mv88e6xxx_serdes_pcs_get_state(chip, ctrl, status, lpa, state);
   78 +       return mv88e6xxx_serdes_pcs_get_state(chip, bmsr, lpa, status, state);
   79  }
   80  
   81  int mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
   82 @@ -918,13 +913,13 @@ int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
   83  static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip,
   84         int port, int lane, struct phylink_link_state *state)
   85  {
   86 -       u16 lpa, status, ctrl;
   87 +       u16 bmsr, lpa, status;
   88         int err;
   89  
   90         err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
   91 -                                   MV88E6390_SGMII_BMCR, &ctrl);
   92 +                                   MV88E6390_SGMII_BMSR, &bmsr);
   93         if (err) {
   94 -               dev_err(chip->dev, "can't read Serdes PHY control: %d\n", err);
   95 +               dev_err(chip->dev, "can't read Serdes PHY BMSR: %d\n", err);
   96                 return err;
   97         }
   98  
   99 @@ -942,7 +937,7 @@ static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip,
  100                 return err;
  101         }
  102  
  103 -       return mv88e6xxx_serdes_pcs_get_state(chip, ctrl, status, lpa, state);
  104 +       return mv88e6xxx_serdes_pcs_get_state(chip, bmsr, lpa, status, state);
  105  }
  106  
  107  static int mv88e6390_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip,
  108 -- 
  109 2.34.1
  110