aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.19.8/0605-net-phy-Replace-phy-driver-features-u32-with-link_mo.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/0605-net-phy-Replace-phy-driver-features-u32-with-link_mo.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.19.8/0605-net-phy-Replace-phy-driver-features-u32-with-link_mo.patch514
1 files changed, 514 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/0605-net-phy-Replace-phy-driver-features-u32-with-link_mo.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/0605-net-phy-Replace-phy-driver-features-u32-with-link_mo.patch
new file mode 100644
index 00000000..7704bd82
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/0605-net-phy-Replace-phy-driver-features-u32-with-link_mo.patch
@@ -0,0 +1,514 @@
+From f2c5c618c9427ef14a9de25cb58d88d1b138e6b9 Mon Sep 17 00:00:00 2001
+From: Andrew Lunn <andrew@lunn.ch>
+Date: Sat, 29 Sep 2018 23:04:16 +0200
+Subject: [PATCH 0605/2940] net: phy: Replace phy driver features u32 with
+ link_mode bitmap
+
+This is one step in allowing phylib to make use of link_mode bitmaps,
+instead of u32 for supported and advertised features. Convert the phy
+drivers to use bitmaps to indicates the features they support.
+
+Build bitmap equivalents of the u32 values at runtime, and have the
+drivers point to the appropriate bitmap. These bitmaps are shared, and
+we don't want a driver to modify them. So mark them __ro_after_init.
+
+Within phylib, the features bitmap is currently turned back into a
+u32. This will be removed once the whole of phylib, and the drivers
+are converted to use bitmaps.
+
+Signed-off-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sudheesh Mavila <sudheesh.mavila@amd.com>
+---
+ drivers/net/ethernet/marvell/pxa168_eth.c | 4 +-
+ drivers/net/phy/aquantia.c | 12 +-
+ drivers/net/phy/bcm63xx.c | 9 +-
+ drivers/net/phy/et1011c.c | 2 +-
+ drivers/net/phy/marvell.c | 2 +-
+ drivers/net/phy/marvell10g.c | 11 +-
+ drivers/net/phy/microchip_t1.c | 2 +-
+ drivers/net/phy/phy_device.c | 164 +++++++++++++++++++++-
+ drivers/net/phy/ste10Xp.c | 4 +-
+ include/linux/linkmode.h | 9 ++
+ include/linux/phy.h | 24 ++--
+ 11 files changed, 201 insertions(+), 42 deletions(-)
+ mode change 100644 => 100755 drivers/net/phy/et1011c.c
+ mode change 100644 => 100755 drivers/net/phy/ste10Xp.c
+
+diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c
+index 3a9730612a70..b406395bbb37 100644
+--- a/drivers/net/ethernet/marvell/pxa168_eth.c
++++ b/drivers/net/ethernet/marvell/pxa168_eth.c
+@@ -988,8 +988,8 @@ static int pxa168_init_phy(struct net_device *dev)
+ cmd.base.phy_address = pep->phy_addr;
+ cmd.base.speed = pep->phy_speed;
+ cmd.base.duplex = pep->phy_duplex;
+- ethtool_convert_legacy_u32_to_link_mode(cmd.link_modes.advertising,
+- PHY_BASIC_FEATURES);
++ bitmap_copy(cmd.link_modes.advertising, PHY_BASIC_FEATURES,
++ __ETHTOOL_LINK_MODE_MASK_NBITS);
+ cmd.base.autoneg = AUTONEG_ENABLE;
+
+ if (cmd.base.speed != 0)
+diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia.c
+index 319edc9c8ec7..632472cab3bb 100644
+--- a/drivers/net/phy/aquantia.c
++++ b/drivers/net/phy/aquantia.c
+@@ -115,7 +115,7 @@ static struct phy_driver aquantia_driver[] = {
+ .phy_id = PHY_ID_AQ1202,
+ .phy_id_mask = 0xfffffff0,
+ .name = "Aquantia AQ1202",
+- .features = PHY_AQUANTIA_FEATURES,
++ .features = PHY_10GBIT_FULL_FEATURES,
+ .flags = PHY_HAS_INTERRUPT,
+ .aneg_done = genphy_c45_aneg_done,
+ .config_aneg = aquantia_config_aneg,
+@@ -127,7 +127,7 @@ static struct phy_driver aquantia_driver[] = {
+ .phy_id = PHY_ID_AQ2104,
+ .phy_id_mask = 0xfffffff0,
+ .name = "Aquantia AQ2104",
+- .features = PHY_AQUANTIA_FEATURES,
++ .features = PHY_10GBIT_FULL_FEATURES,
+ .flags = PHY_HAS_INTERRUPT,
+ .aneg_done = genphy_c45_aneg_done,
+ .config_aneg = aquantia_config_aneg,
+@@ -139,7 +139,7 @@ static struct phy_driver aquantia_driver[] = {
+ .phy_id = PHY_ID_AQR105,
+ .phy_id_mask = 0xfffffff0,
+ .name = "Aquantia AQR105",
+- .features = PHY_AQUANTIA_FEATURES,
++ .features = PHY_10GBIT_FULL_FEATURES,
+ .flags = PHY_HAS_INTERRUPT,
+ .aneg_done = genphy_c45_aneg_done,
+ .config_aneg = aquantia_config_aneg,
+@@ -151,7 +151,7 @@ static struct phy_driver aquantia_driver[] = {
+ .phy_id = PHY_ID_AQR106,
+ .phy_id_mask = 0xfffffff0,
+ .name = "Aquantia AQR106",
+- .features = PHY_AQUANTIA_FEATURES,
++ .features = PHY_10GBIT_FULL_FEATURES,
+ .flags = PHY_HAS_INTERRUPT,
+ .aneg_done = genphy_c45_aneg_done,
+ .config_aneg = aquantia_config_aneg,
+@@ -163,7 +163,7 @@ static struct phy_driver aquantia_driver[] = {
+ .phy_id = PHY_ID_AQR107,
+ .phy_id_mask = 0xfffffff0,
+ .name = "Aquantia AQR107",
+- .features = PHY_AQUANTIA_FEATURES,
++ .features = PHY_10GBIT_FULL_FEATURES,
+ .flags = PHY_HAS_INTERRUPT,
+ .aneg_done = genphy_c45_aneg_done,
+ .config_aneg = aquantia_config_aneg,
+@@ -175,7 +175,7 @@ static struct phy_driver aquantia_driver[] = {
+ .phy_id = PHY_ID_AQR405,
+ .phy_id_mask = 0xfffffff0,
+ .name = "Aquantia AQR405",
+- .features = PHY_AQUANTIA_FEATURES,
++ .features = PHY_10GBIT_FULL_FEATURES,
+ .flags = PHY_HAS_INTERRUPT,
+ .aneg_done = genphy_c45_aneg_done,
+ .config_aneg = aquantia_config_aneg,
+diff --git a/drivers/net/phy/bcm63xx.c b/drivers/net/phy/bcm63xx.c
+index cf14613745c9..d95bffdec4c1 100644
+--- a/drivers/net/phy/bcm63xx.c
++++ b/drivers/net/phy/bcm63xx.c
+@@ -42,6 +42,9 @@ static int bcm63xx_config_init(struct phy_device *phydev)
+ {
+ int reg, err;
+
++ /* ASYM_PAUSE bit is marked RO in datasheet, so don't cheat */
++ phydev->supported |= SUPPORTED_Pause;
++
+ reg = phy_read(phydev, MII_BCM63XX_IR);
+ if (reg < 0)
+ return reg;
+@@ -65,8 +68,7 @@ static struct phy_driver bcm63xx_driver[] = {
+ .phy_id = 0x00406000,
+ .phy_id_mask = 0xfffffc00,
+ .name = "Broadcom BCM63XX (1)",
+- /* ASYM_PAUSE bit is marked RO in datasheet, so don't cheat */
+- .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
++ .features = PHY_BASIC_FEATURES,
+ .flags = PHY_HAS_INTERRUPT | PHY_IS_INTERNAL,
+ .config_init = bcm63xx_config_init,
+ .ack_interrupt = bcm_phy_ack_intr,
+@@ -75,8 +77,7 @@ static struct phy_driver bcm63xx_driver[] = {
+ /* same phy as above, with just a different OUI */
+ .phy_id = 0x002bdc00,
+ .phy_id_mask = 0xfffffc00,
+- .name = "Broadcom BCM63XX (2)",
+- .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
++ .features = PHY_BASIC_FEATURES,
+ .flags = PHY_HAS_INTERRUPT | PHY_IS_INTERNAL,
+ .config_init = bcm63xx_config_init,
+ .ack_interrupt = bcm_phy_ack_intr,
+diff --git a/drivers/net/phy/et1011c.c b/drivers/net/phy/et1011c.c
+old mode 100644
+new mode 100755
+index a9a4edfa23c8..ab541c9c56fb
+--- a/drivers/net/phy/et1011c.c
++++ b/drivers/net/phy/et1011c.c
+@@ -91,7 +91,7 @@ static struct phy_driver et1011c_driver[] = { {
+ .phy_id = 0x0282f014,
+ .name = "ET1011C",
+ .phy_id_mask = 0xfffffff0,
+- .features = (PHY_BASIC_FEATURES | SUPPORTED_1000baseT_Full),
++ .features = PHY_GBIT_FEATURES,
+ .flags = PHY_POLL,
+ .config_aneg = et1011c_config_aneg,
+ .read_status = et1011c_read_status,
+diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
+index f7c69ca34056..de1e900f7253 100644
+--- a/drivers/net/phy/marvell.c
++++ b/drivers/net/phy/marvell.c
+@@ -2222,7 +2222,7 @@ static struct phy_driver marvell_drivers[] = {
+ .phy_id = MARVELL_PHY_ID_88E1510,
+ .phy_id_mask = MARVELL_PHY_ID_MASK,
+ .name = "Marvell 88E1510",
+- .features = PHY_GBIT_FEATURES | SUPPORTED_FIBRE,
++ .features = PHY_GBIT_FIBRE_FEATURES,
+ .flags = PHY_HAS_INTERRUPT,
+ .probe = &m88e1510_probe,
+ .config_init = &m88e1510_config_init,
+diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c
+index f77a2d9e7f9d..7f4a43c65da6 100644
+--- a/drivers/net/phy/marvell10g.c
++++ b/drivers/net/phy/marvell10g.c
+@@ -535,16 +535,7 @@ static struct phy_driver mv3310_drivers[] = {
+ .phy_id = 0x002b09aa,
+ .phy_id_mask = MARVELL_PHY_ID_MASK,
+ .name = "mv88x3310",
+- .features = SUPPORTED_10baseT_Full |
+- SUPPORTED_10baseT_Half |
+- SUPPORTED_100baseT_Full |
+- SUPPORTED_100baseT_Half |
+- SUPPORTED_1000baseT_Full |
+- SUPPORTED_Autoneg |
+- SUPPORTED_TP |
+- SUPPORTED_FIBRE |
+- SUPPORTED_10000baseT_Full |
+- SUPPORTED_Backplane,
++ .features = PHY_10GBIT_FEATURES,
+ .soft_reset = gen10g_no_soft_reset,
+ .config_init = mv3310_config_init,
+ .probe = mv3310_probe,
+diff --git a/drivers/net/phy/microchip_t1.c b/drivers/net/phy/microchip_t1.c
+index b1917dd1978a..c600a8509d60 100644
+--- a/drivers/net/phy/microchip_t1.c
++++ b/drivers/net/phy/microchip_t1.c
+@@ -46,7 +46,7 @@ static struct phy_driver microchip_t1_phy_driver[] = {
+ .phy_id_mask = 0xfffffff0,
+ .name = "Microchip LAN87xx T1",
+
+- .features = SUPPORTED_100baseT_Full,
++ .features = PHY_BASIC_T1_FEATURES,
+ .flags = PHY_HAS_INTERRUPT,
+
+ .config_init = genphy_config_init,
+diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
+index 733e35b7c4bb..9ce93eb66fb0 100644
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -29,6 +29,7 @@
+ #include <linux/module.h>
+ #include <linux/mii.h>
+ #include <linux/ethtool.h>
++#include <linux/bitmap.h>
+ #include <linux/phy.h>
+ #include <linux/phy_led_triggers.h>
+ #include <linux/mdio.h>
+@@ -42,6 +43,149 @@ MODULE_DESCRIPTION("PHY library");
+ MODULE_AUTHOR("Andy Fleming");
+ MODULE_LICENSE("GPL");
+
++__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_basic_features) __ro_after_init;
++EXPORT_SYMBOL_GPL(phy_basic_features);
++
++__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_basic_t1_features) __ro_after_init;
++EXPORT_SYMBOL_GPL(phy_basic_t1_features);
++
++__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_features) __ro_after_init;
++EXPORT_SYMBOL_GPL(phy_gbit_features);
++
++__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_fibre_features) __ro_after_init;
++EXPORT_SYMBOL_GPL(phy_gbit_fibre_features);
++
++__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_all_ports_features) __ro_after_init;
++EXPORT_SYMBOL_GPL(phy_gbit_all_ports_features);
++
++__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_features) __ro_after_init;
++EXPORT_SYMBOL_GPL(phy_10gbit_features);
++
++static const int phy_basic_ports_array[] = {
++ ETHTOOL_LINK_MODE_Autoneg_BIT,
++ ETHTOOL_LINK_MODE_TP_BIT,
++ ETHTOOL_LINK_MODE_MII_BIT,
++};
++
++static const int phy_fibre_port_array[] = {
++ ETHTOOL_LINK_MODE_FIBRE_BIT,
++};
++
++static const int phy_all_ports_features_array[] = {
++ ETHTOOL_LINK_MODE_Autoneg_BIT,
++ ETHTOOL_LINK_MODE_TP_BIT,
++ ETHTOOL_LINK_MODE_MII_BIT,
++ ETHTOOL_LINK_MODE_FIBRE_BIT,
++ ETHTOOL_LINK_MODE_AUI_BIT,
++ ETHTOOL_LINK_MODE_BNC_BIT,
++ ETHTOOL_LINK_MODE_Backplane_BIT,
++};
++
++static const int phy_10_100_features_array[] = {
++ ETHTOOL_LINK_MODE_10baseT_Half_BIT,
++ ETHTOOL_LINK_MODE_10baseT_Full_BIT,
++ ETHTOOL_LINK_MODE_100baseT_Half_BIT,
++ ETHTOOL_LINK_MODE_100baseT_Full_BIT,
++};
++
++static const int phy_basic_t1_features_array[] = {
++ ETHTOOL_LINK_MODE_TP_BIT,
++ ETHTOOL_LINK_MODE_100baseT_Full_BIT,
++};
++
++static const int phy_gbit_features_array[] = {
++ ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
++ ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
++};
++
++static const int phy_10gbit_features_array[] = {
++ ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
++};
++
++__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_full_features) __ro_after_init;
++EXPORT_SYMBOL_GPL(phy_10gbit_full_features);
++
++static const int phy_10gbit_full_features_array[] = {
++ ETHTOOL_LINK_MODE_10baseT_Full_BIT,
++ ETHTOOL_LINK_MODE_100baseT_Full_BIT,
++ ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
++ ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
++};
++
++static void features_init(void)
++{
++ /* 10/100 half/full*/
++ linkmode_set_bit_array(phy_basic_ports_array,
++ ARRAY_SIZE(phy_basic_ports_array),
++ phy_basic_features);
++ linkmode_set_bit_array(phy_10_100_features_array,
++ ARRAY_SIZE(phy_10_100_features_array),
++ phy_basic_features);
++
++ /* 100 full, TP */
++ linkmode_set_bit_array(phy_basic_t1_features_array,
++ ARRAY_SIZE(phy_basic_t1_features_array),
++ phy_basic_t1_features);
++
++ /* 10/100 half/full + 1000 half/full */
++ linkmode_set_bit_array(phy_basic_ports_array,
++ ARRAY_SIZE(phy_basic_ports_array),
++ phy_gbit_features);
++ linkmode_set_bit_array(phy_10_100_features_array,
++ ARRAY_SIZE(phy_10_100_features_array),
++ phy_gbit_features);
++ linkmode_set_bit_array(phy_gbit_features_array,
++ ARRAY_SIZE(phy_gbit_features_array),
++ phy_gbit_features);
++
++ /* 10/100 half/full + 1000 half/full + fibre*/
++ linkmode_set_bit_array(phy_basic_ports_array,
++ ARRAY_SIZE(phy_basic_ports_array),
++ phy_gbit_fibre_features);
++ linkmode_set_bit_array(phy_10_100_features_array,
++ ARRAY_SIZE(phy_10_100_features_array),
++ phy_gbit_fibre_features);
++ linkmode_set_bit_array(phy_gbit_features_array,
++ ARRAY_SIZE(phy_gbit_features_array),
++ phy_gbit_fibre_features);
++ linkmode_set_bit_array(phy_fibre_port_array,
++ ARRAY_SIZE(phy_fibre_port_array),
++ phy_gbit_fibre_features);
++
++ /* 10/100 half/full + 1000 half/full + TP/MII/FIBRE/AUI/BNC/Backplane*/
++ linkmode_set_bit_array(phy_all_ports_features_array,
++ ARRAY_SIZE(phy_all_ports_features_array),
++ phy_gbit_all_ports_features);
++ linkmode_set_bit_array(phy_10_100_features_array,
++ ARRAY_SIZE(phy_10_100_features_array),
++ phy_gbit_all_ports_features);
++ linkmode_set_bit_array(phy_gbit_features_array,
++ ARRAY_SIZE(phy_gbit_features_array),
++ phy_gbit_all_ports_features);
++
++ /* 10/100 half/full + 1000 half/full + 10G full*/
++ linkmode_set_bit_array(phy_all_ports_features_array,
++ ARRAY_SIZE(phy_all_ports_features_array),
++ phy_10gbit_features);
++ linkmode_set_bit_array(phy_10_100_features_array,
++ ARRAY_SIZE(phy_10_100_features_array),
++ phy_10gbit_features);
++ linkmode_set_bit_array(phy_gbit_features_array,
++ ARRAY_SIZE(phy_gbit_features_array),
++ phy_10gbit_features);
++ linkmode_set_bit_array(phy_10gbit_features_array,
++ ARRAY_SIZE(phy_10gbit_features_array),
++ phy_10gbit_features);
++
++ /* 10/100/1000/10G full */
++ linkmode_set_bit_array(phy_all_ports_features_array,
++ ARRAY_SIZE(phy_all_ports_features_array),
++ phy_10gbit_full_features);
++ linkmode_set_bit_array(phy_10gbit_full_features_array,
++ ARRAY_SIZE(phy_10gbit_full_features_array),
++ phy_10gbit_full_features);
++}
++
+ void phy_device_free(struct phy_device *phydev)
+ {
+ put_device(&phydev->mdio.dev);
+@@ -1826,6 +1970,7 @@ static int phy_probe(struct device *dev)
+ struct phy_device *phydev = to_phy_device(dev);
+ struct device_driver *drv = phydev->mdio.dev.driver;
+ struct phy_driver *phydrv = to_phy_driver(drv);
++ u32 features;
+ int err = 0;
+
+ phydev->drv = phydrv;
+@@ -1846,7 +1991,8 @@ static int phy_probe(struct device *dev)
+ * a controller will attach, and may modify one
+ * or both of these values
+ */
+- phydev->supported = phydrv->features;
++ ethtool_convert_link_mode_to_legacy_u32(&features, phydrv->features);
++ phydev->supported = features;
+ of_set_phy_supported(phydev);
+ phydev->advertising = phydev->supported;
+
+@@ -1866,10 +2012,14 @@ static int phy_probe(struct device *dev)
+ * (e.g. hardware erratum) where the driver wants to set only one
+ * of these bits.
+ */
+- if (phydrv->features & (SUPPORTED_Pause | SUPPORTED_Asym_Pause)) {
++ if (test_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydrv->features) ||
++ test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydrv->features)) {
+ phydev->supported &= ~(SUPPORTED_Pause | SUPPORTED_Asym_Pause);
+- phydev->supported |= phydrv->features &
+- (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
++ if (test_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydrv->features))
++ phydev->supported |= SUPPORTED_Pause;
++ if (test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
++ phydrv->features))
++ phydev->supported |= SUPPORTED_Asym_Pause;
+ } else {
+ phydev->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
+ }
+@@ -1990,9 +2140,7 @@ static struct phy_driver genphy_driver = {
+ .name = "Generic PHY",
+ .soft_reset = genphy_no_soft_reset,
+ .config_init = genphy_config_init,
+- .features = PHY_GBIT_FEATURES | SUPPORTED_MII |
+- SUPPORTED_AUI | SUPPORTED_FIBRE |
+- SUPPORTED_BNC,
++ .features = PHY_GBIT_ALL_PORTS_FEATURES,
+ .aneg_done = genphy_aneg_done,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+@@ -2007,6 +2155,8 @@ static int __init phy_init(void)
+ if (rc)
+ return rc;
+
++ features_init();
++
+ rc = phy_driver_register(&genphy_10g_driver, THIS_MODULE);
+ if (rc)
+ goto err_10g;
+diff --git a/drivers/net/phy/ste10Xp.c b/drivers/net/phy/ste10Xp.c
+old mode 100644
+new mode 100755
+index fbd548a1ad84..2fe9a87b55b5
+--- a/drivers/net/phy/ste10Xp.c
++++ b/drivers/net/phy/ste10Xp.c
+@@ -86,7 +86,7 @@ static struct phy_driver ste10xp_pdriver[] = {
+ .phy_id = STE101P_PHY_ID,
+ .phy_id_mask = 0xfffffff0,
+ .name = "STe101p",
+- .features = PHY_BASIC_FEATURES | SUPPORTED_Pause,
++ .features = PHY_BASIC_FEATURES,
+ .flags = PHY_HAS_INTERRUPT,
+ .config_init = ste10Xp_config_init,
+ .ack_interrupt = ste10Xp_ack_interrupt,
+@@ -97,7 +97,7 @@ static struct phy_driver ste10xp_pdriver[] = {
+ .phy_id = STE100P_PHY_ID,
+ .phy_id_mask = 0xffffffff,
+ .name = "STe100p",
+- .features = PHY_BASIC_FEATURES | SUPPORTED_Pause,
++ .features = PHY_BASIC_FEATURES,
+ .flags = PHY_HAS_INTERRUPT,
+ .config_init = ste10Xp_config_init,
+ .ack_interrupt = ste10Xp_ack_interrupt,
+diff --git a/include/linux/linkmode.h b/include/linux/linkmode.h
+index 014fb86c7114..22443d7fb5cd 100644
+--- a/include/linux/linkmode.h
++++ b/include/linux/linkmode.h
+@@ -43,6 +43,15 @@ static inline void linkmode_set_bit(int nr, volatile unsigned long *addr)
+ __set_bit(nr, addr);
+ }
+
++static inline void linkmode_set_bit_array(const int *array, int array_size,
++ unsigned long *addr)
++{
++ int i;
++
++ for (i = 0; i < array_size; i++)
++ linkmode_set_bit(array[i], addr);
++}
++
+ static inline void linkmode_clear_bit(int nr, volatile unsigned long *addr)
+ {
+ __clear_bit(nr, addr);
+diff --git a/include/linux/phy.h b/include/linux/phy.h
+index 81532a61e995..7086051820f9 100644
+--- a/include/linux/phy.h
++++ b/include/linux/phy.h
+@@ -42,13 +42,21 @@
+ #define PHY_1000BT_FEATURES (SUPPORTED_1000baseT_Half | \
+ SUPPORTED_1000baseT_Full)
+
+-#define PHY_BASIC_FEATURES (PHY_10BT_FEATURES | \
+- PHY_100BT_FEATURES | \
+- PHY_DEFAULT_FEATURES)
+-
+-#define PHY_GBIT_FEATURES (PHY_BASIC_FEATURES | \
+- PHY_1000BT_FEATURES)
+-
++extern __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_basic_features) __ro_after_init;
++extern __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_basic_t1_features) __ro_after_init;
++extern __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_features) __ro_after_init;
++extern __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_fibre_features) __ro_after_init;
++extern __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_all_ports_features) __ro_after_init;
++extern __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_features) __ro_after_init;
++extern __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_full_features) __ro_after_init;
++
++#define PHY_BASIC_FEATURES ((unsigned long *)&phy_basic_features)
++#define PHY_BASIC_T1_FEATURES ((unsigned long *)&phy_basic_t1_features)
++#define PHY_GBIT_FEATURES ((unsigned long *)&phy_gbit_features)
++#define PHY_GBIT_FIBRE_FEATURES ((unsigned long *)&phy_gbit_fibre_features)
++#define PHY_GBIT_ALL_PORTS_FEATURES ((unsigned long *)&phy_gbit_all_ports_features)
++#define PHY_10GBIT_FEATURES ((unsigned long *)&phy_10gbit_features)
++#define PHY_10GBIT_FULL_FEATURES ((unsigned long *)&phy_10gbit_full_features)
+
+ /*
+ * Set phydev->irq to PHY_POLL if interrupts are not supported,
+@@ -510,7 +518,7 @@ struct phy_driver {
+ u32 phy_id;
+ char *name;
+ u32 phy_id_mask;
+- u32 features;
++ const unsigned long * const features;
+ u32 flags;
+ const void *driver_data;
+
+--
+2.17.1
+