]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 13 Oct 2021 09:12:23 +0000 (11:12 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 13 Oct 2021 09:12:23 +0000 (11:12 +0200)
added patches:
net-phy-bcm7xxx-fixed-indirect-mmd-operations.patch

queue-4.14/net-phy-bcm7xxx-fixed-indirect-mmd-operations.patch [new file with mode: 0644]
queue-4.14/series

diff --git a/queue-4.14/net-phy-bcm7xxx-fixed-indirect-mmd-operations.patch b/queue-4.14/net-phy-bcm7xxx-fixed-indirect-mmd-operations.patch
new file mode 100644 (file)
index 0000000..fd18160
--- /dev/null
@@ -0,0 +1,148 @@
+From d88fd1b546ff19c8040cfaea76bf16aed1c5a0bb Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Tue, 28 Sep 2021 13:32:33 -0700
+Subject: net: phy: bcm7xxx: Fixed indirect MMD operations
+
+From: Florian Fainelli <f.fainelli@gmail.com>
+
+commit d88fd1b546ff19c8040cfaea76bf16aed1c5a0bb upstream.
+
+When EEE support was added to the 28nm EPHY it was assumed that it would
+be able to support the standard clause 45 over clause 22 register access
+method. It turns out that the PHY does not support that, which is the
+very reason for using the indirect shadow mode 2 bank 3 access method.
+
+Implement {read,write}_mmd to allow the standard PHY library routines
+pertaining to EEE querying and configuration to work correctly on these
+PHYs. This forces us to implement a __phy_set_clr_bits() function that
+does not grab the MDIO bus lock since the PHY driver's {read,write}_mmd
+functions are always called with that lock held.
+
+Fixes: 83ee102a6998 ("net: phy: bcm7xxx: add support for 28nm EPHY")
+[florian: adjust locking since phy_{read,write}_mmd are called with no
+PHYLIB locks held]
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/phy/bcm7xxx.c |   94 ++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 94 insertions(+)
+
+--- a/drivers/net/phy/bcm7xxx.c
++++ b/drivers/net/phy/bcm7xxx.c
+@@ -30,7 +30,12 @@
+ #define MII_BCM7XXX_SHD_2_ADDR_CTRL   0xe
+ #define MII_BCM7XXX_SHD_2_CTRL_STAT   0xf
+ #define MII_BCM7XXX_SHD_2_BIAS_TRIM   0x1a
++#define MII_BCM7XXX_SHD_3_PCS_CTRL    0x0
++#define MII_BCM7XXX_SHD_3_PCS_STATUS  0x1
++#define MII_BCM7XXX_SHD_3_EEE_CAP     0x2
+ #define MII_BCM7XXX_SHD_3_AN_EEE_ADV  0x3
++#define MII_BCM7XXX_SHD_3_EEE_LP      0x4
++#define MII_BCM7XXX_SHD_3_EEE_WK_ERR  0x5
+ #define MII_BCM7XXX_SHD_3_PCS_CTRL_2  0x6
+ #define  MII_BCM7XXX_PCS_CTRL_2_DEF   0x4400
+ #define MII_BCM7XXX_SHD_3_AN_STAT     0xb
+@@ -462,6 +467,93 @@ static int bcm7xxx_28nm_ephy_config_init
+       return bcm7xxx_28nm_ephy_apd_enable(phydev);
+ }
++#define MII_BCM7XXX_REG_INVALID       0xff
++
++static u8 bcm7xxx_28nm_ephy_regnum_to_shd(u16 regnum)
++{
++      switch (regnum) {
++      case MDIO_CTRL1:
++              return MII_BCM7XXX_SHD_3_PCS_CTRL;
++      case MDIO_STAT1:
++              return MII_BCM7XXX_SHD_3_PCS_STATUS;
++      case MDIO_PCS_EEE_ABLE:
++              return MII_BCM7XXX_SHD_3_EEE_CAP;
++      case MDIO_AN_EEE_ADV:
++              return MII_BCM7XXX_SHD_3_AN_EEE_ADV;
++      case MDIO_AN_EEE_LPABLE:
++              return MII_BCM7XXX_SHD_3_EEE_LP;
++      case MDIO_PCS_EEE_WK_ERR:
++              return MII_BCM7XXX_SHD_3_EEE_WK_ERR;
++      default:
++              return MII_BCM7XXX_REG_INVALID;
++      }
++}
++
++static bool bcm7xxx_28nm_ephy_dev_valid(int devnum)
++{
++      return devnum == MDIO_MMD_AN || devnum == MDIO_MMD_PCS;
++}
++
++static int bcm7xxx_28nm_ephy_read_mmd(struct phy_device *phydev,
++                                    int devnum, u16 regnum)
++{
++      u8 shd = bcm7xxx_28nm_ephy_regnum_to_shd(regnum);
++      int ret;
++
++      if (!bcm7xxx_28nm_ephy_dev_valid(devnum) ||
++          shd == MII_BCM7XXX_REG_INVALID)
++              return -EOPNOTSUPP;
++
++      /* set shadow mode 2 */
++      ret = phy_set_clr_bits(phydev, MII_BCM7XXX_TEST,
++                             MII_BCM7XXX_SHD_MODE_2, 0);
++      if (ret < 0)
++              return ret;
++
++      /* Access the desired shadow register address */
++      ret = phy_write(phydev, MII_BCM7XXX_SHD_2_ADDR_CTRL, shd);
++      if (ret < 0)
++              goto reset_shadow_mode;
++
++      ret = phy_read(phydev, MII_BCM7XXX_SHD_2_CTRL_STAT);
++
++reset_shadow_mode:
++      /* reset shadow mode 2 */
++      phy_set_clr_bits(phydev, MII_BCM7XXX_TEST, 0,
++                       MII_BCM7XXX_SHD_MODE_2);
++      return ret;
++}
++
++static int bcm7xxx_28nm_ephy_write_mmd(struct phy_device *phydev,
++                                     int devnum, u16 regnum, u16 val)
++{
++      u8 shd = bcm7xxx_28nm_ephy_regnum_to_shd(regnum);
++      int ret;
++
++      if (!bcm7xxx_28nm_ephy_dev_valid(devnum) ||
++          shd == MII_BCM7XXX_REG_INVALID)
++              return -EOPNOTSUPP;
++
++      /* set shadow mode 2 */
++      ret = phy_set_clr_bits(phydev, MII_BCM7XXX_TEST,
++                             MII_BCM7XXX_SHD_MODE_2, 0);
++      if (ret < 0)
++              return ret;
++
++      /* Access the desired shadow register address */
++      ret = phy_write(phydev, MII_BCM7XXX_SHD_2_ADDR_CTRL, shd);
++      if (ret < 0)
++              goto reset_shadow_mode;
++
++      /* Write the desired value in the shadow register */
++      phy_write(phydev, MII_BCM7XXX_SHD_2_CTRL_STAT, val);
++
++reset_shadow_mode:
++      /* reset shadow mode 2 */
++      return phy_set_clr_bits(phydev, MII_BCM7XXX_TEST, 0,
++                              MII_BCM7XXX_SHD_MODE_2);
++}
++
+ static int bcm7xxx_28nm_ephy_resume(struct phy_device *phydev)
+ {
+       int ret;
+@@ -637,6 +729,8 @@ static int bcm7xxx_28nm_probe(struct phy
+       .get_strings    = bcm_phy_get_strings,                          \
+       .get_stats      = bcm7xxx_28nm_get_phy_stats,                   \
+       .probe          = bcm7xxx_28nm_probe,                           \
++      .read_mmd       = bcm7xxx_28nm_ephy_read_mmd,                   \
++      .write_mmd      = bcm7xxx_28nm_ephy_write_mmd,                  \
+ }
+ #define BCM7XXX_40NM_EPHY(_oui, _name)                                        \
index adb73df3797414594aebdfbd361d3c9d6e65c1fd..0592d0a727a7e365bb91df805a1e2c1f927cd322 100644 (file)
@@ -21,3 +21,4 @@ drm-nouveau-debugfs-fix-file-release-memory-leak.patch
 rtnetlink-fix-if_nlmsg_stats_size-under-estimation.patch
 i40e-fix-endless-loop-under-rtnl.patch
 i2c-acpi-fix-resource-leak-in-reconfiguration-device.patch
+net-phy-bcm7xxx-fixed-indirect-mmd-operations.patch