kernel: update Broadcom PHY drivers
authorRafał Miłecki <rafal@milecki.pl>
Thu, 26 Jan 2017 10:27:50 +0000 (11:27 +0100)
committerRafał Miłecki <rafal@milecki.pl>
Thu, 26 Jan 2017 11:24:09 +0000 (12:24 +0100)
This commit adds 4 patches, one per kernel version that was used for
picking updates. This adds support for few new PHYs.

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
target/linux/generic/patches-4.4/078-0001-net-phy-update-Broadcom-drivers-to-v4.5.patch [new file with mode: 0644]
target/linux/generic/patches-4.4/078-0002-net-phy-update-Broadcom-drivers-to-v4.6.patch [new file with mode: 0644]
target/linux/generic/patches-4.4/078-0003-net-phy-cherry-pick-Broadcom-drivers-updates-from-v4.patch [new file with mode: 0644]
target/linux/generic/patches-4.4/078-0004-net-phy-pick-Broadcom-drivers-updates-from-net-next-.patch [new file with mode: 0644]

diff --git a/target/linux/generic/patches-4.4/078-0001-net-phy-update-Broadcom-drivers-to-v4.5.patch b/target/linux/generic/patches-4.4/078-0001-net-phy-update-Broadcom-drivers-to-v4.5.patch
new file mode 100644 (file)
index 0000000..222d126
--- /dev/null
@@ -0,0 +1,125 @@
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Subject: [PATCH 1/4] net: phy: update Broadcom drivers to v4.5
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+---
+
+--- a/drivers/net/phy/bcm7xxx.c
++++ b/drivers/net/phy/bcm7xxx.c
+@@ -250,10 +250,6 @@ static int bcm7xxx_config_init(struct ph
+       phy_write(phydev, MII_BCM7XXX_AUX_MODE, MII_BCM7XX_64CLK_MDIO);
+       phy_read(phydev, MII_BCM7XXX_AUX_MODE);
+-      /* Workaround only required for 100Mbits/sec capable PHYs */
+-      if (phydev->supported & PHY_GBIT_FEATURES)
+-              return 0;
+-
+       /* set shadow mode 2 */
+       ret = phy_set_clr_bits(phydev, MII_BCM7XXX_TEST,
+                       MII_BCM7XXX_SHD_MODE_2, MII_BCM7XXX_SHD_MODE_2);
+@@ -270,7 +266,7 @@ static int bcm7xxx_config_init(struct ph
+       phy_write(phydev, MII_BCM7XXX_100TX_FALSE_CAR, 0x7555);
+       /* reset shadow mode 2 */
+-      ret = phy_set_clr_bits(phydev, MII_BCM7XXX_TEST, MII_BCM7XXX_SHD_MODE_2, 0);
++      ret = phy_set_clr_bits(phydev, MII_BCM7XXX_TEST, 0, MII_BCM7XXX_SHD_MODE_2);
+       if (ret < 0)
+               return ret;
+@@ -307,11 +303,6 @@ static int bcm7xxx_suspend(struct phy_de
+       return 0;
+ }
+-static int bcm7xxx_dummy_config_init(struct phy_device *phydev)
+-{
+-      return 0;
+-}
+-
+ #define BCM7XXX_28NM_GPHY(_oui, _name)                                        \
+ {                                                                     \
+       .phy_id         = (_oui),                                       \
+@@ -338,7 +329,7 @@ static struct phy_driver bcm7xxx_driver[
+       .phy_id         = PHY_ID_BCM7425,
+       .phy_id_mask    = 0xfffffff0,
+       .name           = "Broadcom BCM7425",
+-      .features       = PHY_GBIT_FEATURES |
++      .features       = PHY_BASIC_FEATURES |
+                         SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+       .flags          = PHY_IS_INTERNAL,
+       .config_init    = bcm7xxx_config_init,
+@@ -351,7 +342,7 @@ static struct phy_driver bcm7xxx_driver[
+       .phy_id         = PHY_ID_BCM7429,
+       .phy_id_mask    = 0xfffffff0,
+       .name           = "Broadcom BCM7429",
+-      .features       = PHY_GBIT_FEATURES |
++      .features       = PHY_BASIC_FEATURES |
+                         SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+       .flags          = PHY_IS_INTERNAL,
+       .config_init    = bcm7xxx_config_init,
+@@ -361,31 +352,18 @@ static struct phy_driver bcm7xxx_driver[
+       .resume         = bcm7xxx_config_init,
+       .driver         = { .owner = THIS_MODULE },
+ }, {
+-      .phy_id         = PHY_BCM_OUI_4,
+-      .phy_id_mask    = 0xffff0000,
+-      .name           = "Broadcom BCM7XXX 40nm",
+-      .features       = PHY_GBIT_FEATURES |
+-                        SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+-      .flags          = PHY_IS_INTERNAL,
+-      .config_init    = bcm7xxx_config_init,
+-      .config_aneg    = genphy_config_aneg,
+-      .read_status    = genphy_read_status,
+-      .suspend        = bcm7xxx_suspend,
+-      .resume         = bcm7xxx_config_init,
+-      .driver         = { .owner = THIS_MODULE },
+-}, {
+-      .phy_id         = PHY_BCM_OUI_5,
+-      .phy_id_mask    = 0xffffff00,
+-      .name           = "Broadcom BCM7XXX 65nm",
+-      .features       = PHY_BASIC_FEATURES |
++      .phy_id         = PHY_ID_BCM7435,
++      .phy_id_mask    = 0xfffffff0,
++      .name           = "Broadcom BCM7435",
++      .features       = PHY_BASIC_FEATURES |
+                         SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+-      .flags          = PHY_IS_INTERNAL,
+-      .config_init    = bcm7xxx_dummy_config_init,
+-      .config_aneg    = genphy_config_aneg,
+-      .read_status    = genphy_read_status,
+-      .suspend        = bcm7xxx_suspend,
+-      .resume         = bcm7xxx_config_init,
+-      .driver         = { .owner = THIS_MODULE },
++      .flags          = PHY_IS_INTERNAL,
++      .config_init    = bcm7xxx_config_init,
++      .config_aneg    = genphy_config_aneg,
++      .read_status    = genphy_read_status,
++      .suspend        = bcm7xxx_suspend,
++      .resume         = bcm7xxx_config_init,
++      .driver         = { .owner = THIS_MODULE },
+ } };
+ static struct mdio_device_id __maybe_unused bcm7xxx_tbl[] = {
+@@ -395,9 +373,8 @@ static struct mdio_device_id __maybe_unu
+       { PHY_ID_BCM7425, 0xfffffff0, },
+       { PHY_ID_BCM7429, 0xfffffff0, },
+       { PHY_ID_BCM7439, 0xfffffff0, },
++      { PHY_ID_BCM7435, 0xfffffff0, },
+       { PHY_ID_BCM7445, 0xfffffff0, },
+-      { PHY_BCM_OUI_4, 0xffff0000 },
+-      { PHY_BCM_OUI_5, 0xffffff00 },
+       { }
+ };
+--- a/include/linux/brcmphy.h
++++ b/include/linux/brcmphy.h
+@@ -26,6 +26,7 @@
+ #define PHY_ID_BCM7366                        0x600d8490
+ #define PHY_ID_BCM7425                        0x600d86b0
+ #define PHY_ID_BCM7429                        0x600d8730
++#define PHY_ID_BCM7435                        0x600d8750
+ #define PHY_ID_BCM7439                        0x600d8480
+ #define PHY_ID_BCM7439_2              0xae025080
+ #define PHY_ID_BCM7445                        0x600d8510
diff --git a/target/linux/generic/patches-4.4/078-0002-net-phy-update-Broadcom-drivers-to-v4.6.patch b/target/linux/generic/patches-4.4/078-0002-net-phy-update-Broadcom-drivers-to-v4.6.patch
new file mode 100644 (file)
index 0000000..4be229b
--- /dev/null
@@ -0,0 +1,123 @@
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Subject: [PATCH 2/4] net: phy: update Broadcom drivers to v4.6
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+---
+
+--- a/drivers/net/phy/bcm7xxx.c
++++ b/drivers/net/phy/bcm7xxx.c
+@@ -24,7 +24,7 @@
+ #define MII_BCM7XXX_100TX_FALSE_CAR   0x13
+ #define MII_BCM7XXX_100TX_DISC                0x14
+ #define MII_BCM7XXX_AUX_MODE          0x1d
+-#define  MII_BCM7XX_64CLK_MDIO                BIT(12)
++#define  MII_BCM7XXX_64CLK_MDIO               BIT(12)
+ #define MII_BCM7XXX_TEST              0x1f
+ #define  MII_BCM7XXX_SHD_MODE_2               BIT(2)
+@@ -247,7 +247,7 @@ static int bcm7xxx_config_init(struct ph
+       int ret;
+       /* Enable 64 clock MDIO */
+-      phy_write(phydev, MII_BCM7XXX_AUX_MODE, MII_BCM7XX_64CLK_MDIO);
++      phy_write(phydev, MII_BCM7XXX_AUX_MODE, MII_BCM7XXX_64CLK_MDIO);
+       phy_read(phydev, MII_BCM7XXX_AUX_MODE);
+       /* set shadow mode 2 */
+@@ -318,6 +318,22 @@ static int bcm7xxx_suspend(struct phy_de
+       .driver         = { .owner = THIS_MODULE },                     \
+ }
++#define BCM7XXX_40NM_EPHY(_oui, _name)                                        \
++{                                                                     \
++      .phy_id         = (_oui),                                       \
++      .phy_id_mask    = 0xfffffff0,                                   \
++      .name           = _name,                                        \
++      .features       = PHY_BASIC_FEATURES |                          \
++                        SUPPORTED_Pause | SUPPORTED_Asym_Pause,       \
++      .flags          = PHY_IS_INTERNAL,                              \
++      .config_init    = bcm7xxx_config_init,                          \
++      .config_aneg    = genphy_config_aneg,                           \
++      .read_status    = genphy_read_status,                           \
++      .suspend        = bcm7xxx_suspend,                              \
++      .resume         = bcm7xxx_config_init,                          \
++      .driver         = { .owner = THIS_MODULE },                     \
++}
++
+ static struct phy_driver bcm7xxx_driver[] = {
+       BCM7XXX_28NM_GPHY(PHY_ID_BCM7250, "Broadcom BCM7250"),
+       BCM7XXX_28NM_GPHY(PHY_ID_BCM7364, "Broadcom BCM7364"),
+@@ -325,51 +341,19 @@ static struct phy_driver bcm7xxx_driver[
+       BCM7XXX_28NM_GPHY(PHY_ID_BCM7439, "Broadcom BCM7439"),
+       BCM7XXX_28NM_GPHY(PHY_ID_BCM7439_2, "Broadcom BCM7439 (2)"),
+       BCM7XXX_28NM_GPHY(PHY_ID_BCM7445, "Broadcom BCM7445"),
+-{
+-      .phy_id         = PHY_ID_BCM7425,
+-      .phy_id_mask    = 0xfffffff0,
+-      .name           = "Broadcom BCM7425",
+-      .features       = PHY_BASIC_FEATURES |
+-                        SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+-      .flags          = PHY_IS_INTERNAL,
+-      .config_init    = bcm7xxx_config_init,
+-      .config_aneg    = genphy_config_aneg,
+-      .read_status    = genphy_read_status,
+-      .suspend        = bcm7xxx_suspend,
+-      .resume         = bcm7xxx_config_init,
+-      .driver         = { .owner = THIS_MODULE },
+-}, {
+-      .phy_id         = PHY_ID_BCM7429,
+-      .phy_id_mask    = 0xfffffff0,
+-      .name           = "Broadcom BCM7429",
+-      .features       = PHY_BASIC_FEATURES |
+-                        SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+-      .flags          = PHY_IS_INTERNAL,
+-      .config_init    = bcm7xxx_config_init,
+-      .config_aneg    = genphy_config_aneg,
+-      .read_status    = genphy_read_status,
+-      .suspend        = bcm7xxx_suspend,
+-      .resume         = bcm7xxx_config_init,
+-      .driver         = { .owner = THIS_MODULE },
+-}, {
+-      .phy_id         = PHY_ID_BCM7435,
+-      .phy_id_mask    = 0xfffffff0,
+-      .name           = "Broadcom BCM7435",
+-      .features       = PHY_BASIC_FEATURES |
+-                        SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+-      .flags          = PHY_IS_INTERNAL,
+-      .config_init    = bcm7xxx_config_init,
+-      .config_aneg    = genphy_config_aneg,
+-      .read_status    = genphy_read_status,
+-      .suspend        = bcm7xxx_suspend,
+-      .resume         = bcm7xxx_config_init,
+-      .driver         = { .owner = THIS_MODULE },
+-} };
++      BCM7XXX_40NM_EPHY(PHY_ID_BCM7346, "Broadcom BCM7346"),
++      BCM7XXX_40NM_EPHY(PHY_ID_BCM7362, "Broadcom BCM7362"),
++      BCM7XXX_40NM_EPHY(PHY_ID_BCM7425, "Broadcom BCM7425"),
++      BCM7XXX_40NM_EPHY(PHY_ID_BCM7429, "Broadcom BCM7429"),
++      BCM7XXX_40NM_EPHY(PHY_ID_BCM7435, "Broadcom BCM7435"),
++};
+ static struct mdio_device_id __maybe_unused bcm7xxx_tbl[] = {
+       { PHY_ID_BCM7250, 0xfffffff0, },
+       { PHY_ID_BCM7364, 0xfffffff0, },
+       { PHY_ID_BCM7366, 0xfffffff0, },
++      { PHY_ID_BCM7346, 0xfffffff0, },
++      { PHY_ID_BCM7362, 0xfffffff0, },
+       { PHY_ID_BCM7425, 0xfffffff0, },
+       { PHY_ID_BCM7429, 0xfffffff0, },
+       { PHY_ID_BCM7439, 0xfffffff0, },
+--- a/include/linux/brcmphy.h
++++ b/include/linux/brcmphy.h
+@@ -24,6 +24,8 @@
+ #define PHY_ID_BCM7250                        0xae025280
+ #define PHY_ID_BCM7364                        0xae025260
+ #define PHY_ID_BCM7366                        0x600d8490
++#define PHY_ID_BCM7346                        0x600d8650
++#define PHY_ID_BCM7362                        0x600d84b0
+ #define PHY_ID_BCM7425                        0x600d86b0
+ #define PHY_ID_BCM7429                        0x600d8730
+ #define PHY_ID_BCM7435                        0x600d8750
diff --git a/target/linux/generic/patches-4.4/078-0003-net-phy-cherry-pick-Broadcom-drivers-updates-from-v4.patch b/target/linux/generic/patches-4.4/078-0003-net-phy-cherry-pick-Broadcom-drivers-updates-from-v4.patch
new file mode 100644 (file)
index 0000000..bf88189
--- /dev/null
@@ -0,0 +1,316 @@
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Subject: [PATCH 1/2] net: phy: cherry-pick Broadcom drivers updates from
+ v4.10-rc1
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This includes following upstream commits:
+5519da874ad0 net: phy: broadcom: Move bcm54xx_auxctl_{read, write} to common library
+b14995ac2527 net: phy: broadcom: Add BCM54810 PHY entry
+5b4e29005123 net: phy: broadcom: add bcm54xx_auxctl_read
+d92ead16be40 net: phy: broadcom: Add support for BCM54612E
+3cf25904fe46 net: phy: broadcom: Update Auxiliary Control Register macros
+
+Other commits were skipped as they depend on other changes like
+ETHTOOL_PHY_DOWNSHIFT & DOWNSHIFT_DEV_DISABLE and new APIs like
+get_sset_count.
+
+One exception was picking new regs from commit d06f78c4232d ("net: phy:
+broadcom: Add support code for downshift/Wirespeed").
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+---
+
+--- a/drivers/net/phy/Kconfig
++++ b/drivers/net/phy/Kconfig
+@@ -77,7 +77,7 @@ config BROADCOM_PHY
+       select BCM_NET_PHYLIB
+       ---help---
+         Currently supports the BCM5411, BCM5421, BCM5461, BCM54616S, BCM5464,
+-        BCM5481 and BCM5482 PHYs.
++        BCM5481, BCM54810 and BCM5482 PHYs.
+ config BCM_CYGNUS_PHY
+       tristate "Drivers for Broadcom Cygnus SoC internal PHY"
+--- a/drivers/net/phy/bcm-phy-lib.c
++++ b/drivers/net/phy/bcm-phy-lib.c
+@@ -50,6 +50,23 @@ int bcm_phy_read_exp(struct phy_device *
+ }
+ EXPORT_SYMBOL_GPL(bcm_phy_read_exp);
++int bcm54xx_auxctl_read(struct phy_device *phydev, u16 regnum)
++{
++      /* The register must be written to both the Shadow Register Select and
++       * the Shadow Read Register Selector
++       */
++      phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum |
++                regnum << MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT);
++      return phy_read(phydev, MII_BCM54XX_AUX_CTL);
++}
++EXPORT_SYMBOL_GPL(bcm54xx_auxctl_read);
++
++int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val)
++{
++      return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val);
++}
++EXPORT_SYMBOL(bcm54xx_auxctl_write);
++
+ int bcm_phy_write_misc(struct phy_device *phydev,
+                      u16 reg, u16 chl, u16 val)
+ {
+--- a/drivers/net/phy/bcm-phy-lib.h
++++ b/drivers/net/phy/bcm-phy-lib.h
+@@ -19,6 +19,9 @@
+ int bcm_phy_write_exp(struct phy_device *phydev, u16 reg, u16 val);
+ int bcm_phy_read_exp(struct phy_device *phydev, u16 reg);
++int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val);
++int bcm54xx_auxctl_read(struct phy_device *phydev, u16 regnum);
++
+ int bcm_phy_write_misc(struct phy_device *phydev,
+                      u16 reg, u16 chl, u16 value);
+ int bcm_phy_read_misc(struct phy_device *phydev,
+--- a/drivers/net/phy/broadcom.c
++++ b/drivers/net/phy/broadcom.c
+@@ -18,7 +18,7 @@
+ #include <linux/module.h>
+ #include <linux/phy.h>
+ #include <linux/brcmphy.h>
+-
++#include <linux/of.h>
+ #define BRCM_PHY_MODEL(phydev) \
+       ((phydev)->drv->phy_id & (phydev)->drv->phy_id_mask)
+@@ -30,9 +30,32 @@ MODULE_DESCRIPTION("Broadcom PHY driver"
+ MODULE_AUTHOR("Maciej W. Rozycki");
+ MODULE_LICENSE("GPL");
+-static int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val)
++static int bcm54810_config(struct phy_device *phydev)
+ {
+-      return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val);
++      int rc, val;
++
++      val = bcm_phy_read_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL);
++      val &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN;
++      rc = bcm_phy_write_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL,
++                             val);
++      if (rc < 0)
++              return rc;
++
++      val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC);
++      val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN;
++      val |= MII_BCM54XX_AUXCTL_MISC_WREN;
++      rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
++                                val);
++      if (rc < 0)
++              return rc;
++
++      val = bcm_phy_read_shadow(phydev, BCM54810_SHD_CLK_CTL);
++      val &= ~BCM54810_SHD_CLK_CTL_GTXCLK_EN;
++      rc = bcm_phy_write_shadow(phydev, BCM54810_SHD_CLK_CTL, val);
++      if (rc < 0)
++              return rc;
++
++      return 0;
+ }
+ /* Needs SMDSP clock enabled via bcm54xx_phydsp_config() */
+@@ -207,6 +230,12 @@ static int bcm54xx_config_init(struct ph
+           (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
+               bcm54xx_adjust_rxrefclk(phydev);
++      if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54810) {
++              err = bcm54810_config(phydev);
++              if (err)
++                      return err;
++      }
++
+       bcm54xx_phydsp_config(phydev);
+       return 0;
+@@ -304,6 +333,7 @@ static int bcm5482_read_status(struct ph
+ static int bcm5481_config_aneg(struct phy_device *phydev)
+ {
++      struct device_node *np = phydev->dev.of_node;
+       int ret;
+       /* Aneg firsly. */
+@@ -334,6 +364,49 @@ static int bcm5481_config_aneg(struct ph
+               phy_write(phydev, 0x18, reg);
+       }
++      if (of_property_read_bool(np, "enet-phy-lane-swap")) {
++              /* Lane Swap - Undocumented register...magic! */
++              ret = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_SEL_ER + 0x9,
++                                      0x11B);
++              if (ret < 0)
++                      return ret;
++      }
++
++      return ret;
++}
++
++static int bcm54612e_config_aneg(struct phy_device *phydev)
++{
++      int ret;
++
++      /* First, auto-negotiate. */
++      ret = genphy_config_aneg(phydev);
++
++      /* Clear TX internal delay unless requested. */
++      if ((phydev->interface != PHY_INTERFACE_MODE_RGMII_ID) &&
++          (phydev->interface != PHY_INTERFACE_MODE_RGMII_TXID)) {
++              /* Disable TXD to GTXCLK clock delay (default set) */
++              /* Bit 9 is the only field in shadow register 00011 */
++              bcm_phy_write_shadow(phydev, 0x03, 0);
++      }
++
++      /* Clear RX internal delay unless requested. */
++      if ((phydev->interface != PHY_INTERFACE_MODE_RGMII_ID) &&
++          (phydev->interface != PHY_INTERFACE_MODE_RGMII_RXID)) {
++              u16 reg;
++
++              /* Errata: reads require filling in the write selector field */
++              bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
++                                   MII_BCM54XX_AUXCTL_MISC_RDSEL_MISC);
++              reg = phy_read(phydev, MII_BCM54XX_AUX_CTL);
++              /* Disable RXD to RXC delay (default set) */
++              reg &= ~MII_BCM54XX_AUXCTL_MISC_RXD_RXC_SKEW;
++              /* Clear shadow selector field */
++              reg &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MASK;
++              bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
++                                   MII_BCM54XX_AUXCTL_MISC_WREN | reg);
++      }
++
+       return ret;
+ }
+@@ -488,6 +561,18 @@ static struct phy_driver broadcom_driver
+       .config_intr    = bcm_phy_config_intr,
+       .driver         = { .owner = THIS_MODULE },
+ }, {
++      .phy_id         = PHY_ID_BCM54612E,
++      .phy_id_mask    = 0xfffffff0,
++      .name           = "Broadcom BCM54612E",
++      .features       = PHY_GBIT_FEATURES |
++                        SUPPORTED_Pause | SUPPORTED_Asym_Pause,
++      .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
++      .config_init    = bcm54xx_config_init,
++      .config_aneg    = bcm54612e_config_aneg,
++      .read_status    = genphy_read_status,
++      .ack_interrupt  = bcm_phy_ack_intr,
++      .config_intr    = bcm_phy_config_intr,
++}, {
+       .phy_id         = PHY_ID_BCM54616S,
+       .phy_id_mask    = 0xfffffff0,
+       .name           = "Broadcom BCM54616S",
+@@ -527,6 +612,18 @@ static struct phy_driver broadcom_driver
+       .config_intr    = bcm_phy_config_intr,
+       .driver         = { .owner = THIS_MODULE },
+ }, {
++      .phy_id         = PHY_ID_BCM54810,
++      .phy_id_mask    = 0xfffffff0,
++      .name           = "Broadcom BCM54810",
++      .features       = PHY_GBIT_FEATURES |
++                        SUPPORTED_Pause | SUPPORTED_Asym_Pause,
++      .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
++      .config_init    = bcm54xx_config_init,
++      .config_aneg    = bcm5481_config_aneg,
++      .read_status    = genphy_read_status,
++      .ack_interrupt  = bcm_phy_ack_intr,
++      .config_intr    = bcm_phy_config_intr,
++}, {
+       .phy_id         = PHY_ID_BCM5482,
+       .phy_id_mask    = 0xfffffff0,
+       .name           = "Broadcom BCM5482",
+@@ -612,9 +709,11 @@ static struct mdio_device_id __maybe_unu
+       { PHY_ID_BCM5411, 0xfffffff0 },
+       { PHY_ID_BCM5421, 0xfffffff0 },
+       { PHY_ID_BCM5461, 0xfffffff0 },
++      { PHY_ID_BCM54612E, 0xfffffff0 },
+       { PHY_ID_BCM54616S, 0xfffffff0 },
+       { PHY_ID_BCM5464, 0xfffffff0 },
+       { PHY_ID_BCM5481, 0xfffffff0 },
++      { PHY_ID_BCM54810, 0xfffffff0 },
+       { PHY_ID_BCM5482, 0xfffffff0 },
+       { PHY_ID_BCM50610, 0xfffffff0 },
+       { PHY_ID_BCM50610M, 0xfffffff0 },
+--- a/include/linux/brcmphy.h
++++ b/include/linux/brcmphy.h
+@@ -13,11 +13,13 @@
+ #define PHY_ID_BCM5241                        0x0143bc30
+ #define PHY_ID_BCMAC131                       0x0143bc70
+ #define PHY_ID_BCM5481                        0x0143bca0
++#define PHY_ID_BCM54810                       0x03625d00
+ #define PHY_ID_BCM5482                        0x0143bcb0
+ #define PHY_ID_BCM5411                        0x00206070
+ #define PHY_ID_BCM5421                        0x002060e0
+ #define PHY_ID_BCM5464                        0x002060b0
+ #define PHY_ID_BCM5461                        0x002060c0
++#define PHY_ID_BCM54612E              0x03625e60
+ #define PHY_ID_BCM54616S              0x03625d10
+ #define PHY_ID_BCM57780                       0x03625d90
+@@ -55,6 +57,7 @@
+ #define PHY_BRCM_EXT_IBND_TX_ENABLE   0x00002000
+ #define PHY_BRCM_CLEAR_RGMII_MODE     0x00004000
+ #define PHY_BRCM_DIS_TXCRXC_NOENRGY   0x00008000
++
+ /* Broadcom BCM7xxx specific workarounds */
+ #define PHY_BRCM_7XXX_REV(x)          (((x) >> 8) & 0xff)
+ #define PHY_BRCM_7XXX_PATCH(x)                ((x) & 0xff)
+@@ -105,11 +108,14 @@
+ #define MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA     0x0800
+ #define MII_BCM54XX_AUXCTL_MISC_WREN  0x8000
++#define MII_BCM54XX_AUXCTL_MISC_RXD_RXC_SKEW  0x0100
+ #define MII_BCM54XX_AUXCTL_MISC_FORCE_AMDIX   0x0200
+ #define MII_BCM54XX_AUXCTL_MISC_RDSEL_MISC    0x7000
+ #define MII_BCM54XX_AUXCTL_SHDWSEL_MISC       0x0007
++#define MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT 12
++#define MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN (1 << 8)
+-#define MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL     0x0000
++#define MII_BCM54XX_AUXCTL_SHDWSEL_MASK       0x0007
+ /*
+  * Broadcom LED source encodings.  These are used in BCM5461, BCM5481,
+@@ -124,6 +130,7 @@
+ #define BCM_LED_SRC_INTR      0x6
+ #define BCM_LED_SRC_QUALITY   0x7
+ #define BCM_LED_SRC_RCVLED    0x8
++#define BCM_LED_SRC_WIRESPEED 0x9
+ #define BCM_LED_SRC_MULTICOLOR1       0xa
+ #define BCM_LED_SRC_OPENSHORT 0xb
+ #define BCM_LED_SRC_OFF               0xe     /* Tied high */
+@@ -135,6 +142,14 @@
+  * Shadow values go into bits [14:10] of register 0x1c to select a shadow
+  * register to access.
+  */
++
++/* 00100: Reserved control register 2 */
++#define BCM54XX_SHD_SCR2              0x04
++#define  BCM54XX_SHD_SCR2_WSPD_RTRY_DIS       0x100
++#define  BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_SHIFT 2
++#define  BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_OFFSET        2
++#define  BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_MASK  0x7
++
+ /* 00101: Spare Control Register 3 */
+ #define BCM54XX_SHD_SCR3              0x05
+ #define  BCM54XX_SHD_SCR3_DEF_CLK125  0x0001
+@@ -189,6 +204,12 @@
+ #define BCM5482_SSD_SGMII_SLAVE_EN    0x0002  /* Slave mode enable */
+ #define BCM5482_SSD_SGMII_SLAVE_AD    0x0001  /* Slave auto-detection */
++/* BCM54810 Registers */
++#define BCM54810_EXP_BROADREACH_LRE_MISC_CTL  (MII_BCM54XX_EXP_SEL_ER + 0x90)
++#define BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN       (1 << 0)
++#define BCM54810_SHD_CLK_CTL                  0x3
++#define BCM54810_SHD_CLK_CTL_GTXCLK_EN                (1 << 9)
++
+ /*****************************************************************************/
+ /* Fast Ethernet Transceiver definitions. */
diff --git a/target/linux/generic/patches-4.4/078-0004-net-phy-pick-Broadcom-drivers-updates-from-net-next-.patch b/target/linux/generic/patches-4.4/078-0004-net-phy-pick-Broadcom-drivers-updates-from-net-next-.patch
new file mode 100644 (file)
index 0000000..d0842df
--- /dev/null
@@ -0,0 +1,136 @@
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Subject: [PATCH 2/2] net: phy: pick Broadcom drivers updates from net-next for
+ 4.11
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+---
+
+--- a/drivers/net/phy/bcm7xxx.c
++++ b/drivers/net/phy/bcm7xxx.c
+@@ -163,12 +163,43 @@ static int bcm7xxx_28nm_e0_plus_afe_conf
+       return 0;
+ }
++static int bcm7xxx_28nm_a0_patch_afe_config_init(struct phy_device *phydev)
++{
++      /* +1 RC_CAL codes for RL centering for both LT and HT conditions */
++      bcm_phy_write_misc(phydev, AFE_RXCONFIG_2, 0xd003);
++
++      /* Cut master bias current by 2% to compensate for RC_CAL offset */
++      bcm_phy_write_misc(phydev, DSP_TAP10, 0x791b);
++
++      /* Improve hybrid leakage */
++      bcm_phy_write_misc(phydev, AFE_HPF_TRIM_OTHERS, 0x10e3);
++
++      /* Change rx_on_tune 8 to 0xf */
++      bcm_phy_write_misc(phydev, 0x21, 0x2, 0x87f6);
++
++      /* Change 100Tx EEE bandwidth */
++      bcm_phy_write_misc(phydev, 0x22, 0x2, 0x017d);
++
++      /* Enable ffe zero detection for Vitesse interoperability */
++      bcm_phy_write_misc(phydev, 0x26, 0x2, 0x0015);
++
++      r_rc_cal_reset(phydev);
++
++      return 0;
++}
++
+ static int bcm7xxx_28nm_config_init(struct phy_device *phydev)
+ {
+       u8 rev = PHY_BRCM_7XXX_REV(phydev->dev_flags);
+       u8 patch = PHY_BRCM_7XXX_PATCH(phydev->dev_flags);
+       int ret = 0;
++      /* Newer devices have moved the revision information back into a
++       * standard location in MII_PHYS_ID[23]
++       */
++      if (rev == 0)
++              rev = phydev->phy_id & ~phydev->drv->phy_id_mask;
++
+       pr_info_once("%s: %s PHY revision: 0x%02x, patch: %d\n",
+                    dev_name(&phydev->dev), phydev->drv->name, rev, patch);
+@@ -192,6 +223,9 @@ static int bcm7xxx_28nm_config_init(stru
+       case 0x10:
+               ret = bcm7xxx_28nm_e0_plus_afe_config_init(phydev);
+               break;
++      case 0x01:
++              ret = bcm7xxx_28nm_a0_patch_afe_config_init(phydev);
++              break;
+       default:
+               break;
+       }
+@@ -336,6 +370,7 @@ static int bcm7xxx_suspend(struct phy_de
+ static struct phy_driver bcm7xxx_driver[] = {
+       BCM7XXX_28NM_GPHY(PHY_ID_BCM7250, "Broadcom BCM7250"),
++      BCM7XXX_28NM_GPHY(PHY_ID_BCM7278, "Broadcom BCM7278"),
+       BCM7XXX_28NM_GPHY(PHY_ID_BCM7364, "Broadcom BCM7364"),
+       BCM7XXX_28NM_GPHY(PHY_ID_BCM7366, "Broadcom BCM7366"),
+       BCM7XXX_28NM_GPHY(PHY_ID_BCM7439, "Broadcom BCM7439"),
+@@ -350,6 +385,7 @@ static struct phy_driver bcm7xxx_driver[
+ static struct mdio_device_id __maybe_unused bcm7xxx_tbl[] = {
+       { PHY_ID_BCM7250, 0xfffffff0, },
++      { PHY_ID_BCM7278, 0xfffffff0, },
+       { PHY_ID_BCM7364, 0xfffffff0, },
+       { PHY_ID_BCM7366, 0xfffffff0, },
+       { PHY_ID_BCM7346, 0xfffffff0, },
+--- a/drivers/net/phy/broadcom.c
++++ b/drivers/net/phy/broadcom.c
+@@ -395,12 +395,10 @@ static int bcm54612e_config_aneg(struct
+           (phydev->interface != PHY_INTERFACE_MODE_RGMII_RXID)) {
+               u16 reg;
+-              /* Errata: reads require filling in the write selector field */
+-              bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
+-                                   MII_BCM54XX_AUXCTL_MISC_RDSEL_MISC);
+-              reg = phy_read(phydev, MII_BCM54XX_AUX_CTL);
++              reg = bcm54xx_auxctl_read(phydev,
++                                        MII_BCM54XX_AUXCTL_SHDWSEL_MISC);
+               /* Disable RXD to RXC delay (default set) */
+-              reg &= ~MII_BCM54XX_AUXCTL_MISC_RXD_RXC_SKEW;
++              reg &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN;
+               /* Clear shadow selector field */
+               reg &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MASK;
+               bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
+--- a/include/linux/brcmphy.h
++++ b/include/linux/brcmphy.h
+@@ -24,6 +24,7 @@
+ #define PHY_ID_BCM57780                       0x03625d90
+ #define PHY_ID_BCM7250                        0xae025280
++#define PHY_ID_BCM7278                        0xae0251a0
+ #define PHY_ID_BCM7364                        0xae025260
+ #define PHY_ID_BCM7366                        0x600d8490
+ #define PHY_ID_BCM7346                        0x600d8650
+@@ -103,18 +104,17 @@
+ /*
+  * AUXILIARY CONTROL SHADOW ACCESS REGISTERS.  (PHY REG 0x18)
+  */
+-#define MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL     0x0000
++#define MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL     0x00
+ #define MII_BCM54XX_AUXCTL_ACTL_TX_6DB                0x0400
+ #define MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA     0x0800
+-#define MII_BCM54XX_AUXCTL_MISC_WREN  0x8000
+-#define MII_BCM54XX_AUXCTL_MISC_RXD_RXC_SKEW  0x0100
+-#define MII_BCM54XX_AUXCTL_MISC_FORCE_AMDIX   0x0200
+-#define MII_BCM54XX_AUXCTL_MISC_RDSEL_MISC    0x7000
+-#define MII_BCM54XX_AUXCTL_SHDWSEL_MISC       0x0007
+-#define MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT 12
+-#define MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN (1 << 8)
++#define MII_BCM54XX_AUXCTL_SHDWSEL_MISC                       0x07
++#define MII_BCM54XX_AUXCTL_SHDWSEL_MISC_WIRESPEED_EN  0x0010
++#define MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN 0x0100
++#define MII_BCM54XX_AUXCTL_MISC_FORCE_AMDIX           0x0200
++#define MII_BCM54XX_AUXCTL_MISC_WREN                  0x8000
++#define MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT 12
+ #define MII_BCM54XX_AUXCTL_SHDWSEL_MASK       0x0007
+ /*