net: ethernet: Convert phydev advertize and supported from u32 to link mode
authorAndrew Lunn <andrew@lunn.ch>
Sat, 10 Nov 2018 22:43:33 +0000 (23:43 +0100)
committerDavid S. Miller <davem@davemloft.net>
Sun, 11 Nov 2018 18:10:01 +0000 (10:10 -0800)
There are a few MAC/PHYs combinations which now support > 1Gbps. These
may need to make use of link modes with bits > 31. Thus their
supported PHY features or advertised features cannot be implemented
using the current bitmap in a u32. Convert to using a linkmode bitmap,
which can support all the currently devices link modes, and is future
proof as more modes are added.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
39 files changed:
drivers/net/dsa/mt7530.c
drivers/net/ethernet/aeroflex/greth.c
drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
drivers/net/ethernet/apm/xgene-v2/mdio.c
drivers/net/ethernet/arc/emac_main.c
drivers/net/ethernet/broadcom/b44.c
drivers/net/ethernet/broadcom/genet/bcmmii.c
drivers/net/ethernet/broadcom/tg3.c
drivers/net/ethernet/cavium/octeon/octeon_mgmt.c
drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
drivers/net/ethernet/freescale/fman/mac.c
drivers/net/ethernet/freescale/gianfar.c
drivers/net/ethernet/freescale/ucc_geth.c
drivers/net/ethernet/hisilicon/hns/hns_enet.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c
drivers/net/ethernet/ibm/emac/core.c
drivers/net/ethernet/marvell/mv643xx_eth.c
drivers/net/ethernet/mediatek/mtk_eth_soc.c
drivers/net/ethernet/nxp/lpc_eth.c
drivers/net/ethernet/realtek/r8169.c
drivers/net/ethernet/socionext/sni_ave.c
drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
drivers/net/ethernet/toshiba/tc35815.c
drivers/net/phy/aquantia.c
drivers/net/phy/bcm63xx.c
drivers/net/phy/bcm87xx.c
drivers/net/phy/fixed_phy.c
drivers/net/phy/marvell.c
drivers/net/phy/marvell10g.c
drivers/net/phy/micrel.c
drivers/net/phy/phy-c45.c
drivers/net/phy/phy-core.c
drivers/net/phy/phy.c
drivers/net/phy/phy_device.c
drivers/net/phy/phylink.c
drivers/net/usb/lan78xx.c
include/linux/mii.h
include/linux/phy.h

index a5de9bffe5bec940a83186d731bfe77ac23f97d3..74547f43b938971ef401a2e1ff191c779f579e99 100644 (file)
@@ -658,7 +658,8 @@ static void mt7530_adjust_link(struct dsa_switch *ds, int port,
                        if (phydev->asym_pause)
                                rmt_adv |= LPA_PAUSE_ASYM;
 
-                       lcl_adv = ethtool_adv_to_lcl_adv_t(phydev->advertising);
+                       lcl_adv = linkmode_adv_to_lcl_adv_t(
+                               phydev->advertising);
                        flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
 
                        if (flowctrl & FLOW_CTRL_TX)
index 7c9348a26cbbea0ccea156a07197373ed76035ca..91fc64c1145edac1633dc1798c341f8bd66be3ec 100644 (file)
@@ -1283,7 +1283,7 @@ static int greth_mdio_probe(struct net_device *dev)
        else
                phy_set_max_speed(phy, SPEED_100);
 
-       phy->advertising = phy->supported;
+       linkmode_copy(phy->advertising, phy->supported);
 
        greth->link = 0;
        greth->speed = 0;
index 151bdb629e8a3b6d9fa53727eeba279e7c6e890d..128cd648ba99c0fbb753256f49781e2437ccc3d8 100644 (file)
@@ -857,6 +857,7 @@ static void xgbe_phy_free_phy_device(struct xgbe_prv_data *pdata)
 
 static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata)
 {
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, };
        struct xgbe_phy_data *phy_data = pdata->phy_data;
        unsigned int phy_id = phy_data->phydev->phy_id;
 
@@ -878,9 +879,15 @@ static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata)
        phy_write(phy_data->phydev, 0x04, 0x0d01);
        phy_write(phy_data->phydev, 0x00, 0x9140);
 
-       phy_data->phydev->supported = PHY_10BT_FEATURES |
-                                     PHY_100BT_FEATURES |
-                                     PHY_1000BT_FEATURES;
+       linkmode_set_bit_array(phy_10_100_features_array,
+                              ARRAY_SIZE(phy_10_100_features_array),
+                              supported);
+       linkmode_set_bit_array(phy_gbit_features_array,
+                              ARRAY_SIZE(phy_gbit_features_array),
+                              supported);
+
+       linkmode_copy(phy_data->phydev->supported, supported);
+
        phy_support_asym_pause(phy_data->phydev);
 
        netif_dbg(pdata, drv, pdata->netdev,
@@ -891,6 +898,7 @@ static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata)
 
 static bool xgbe_phy_belfuse_phy_quirks(struct xgbe_prv_data *pdata)
 {
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, };
        struct xgbe_phy_data *phy_data = pdata->phy_data;
        struct xgbe_sfp_eeprom *sfp_eeprom = &phy_data->sfp_eeprom;
        unsigned int phy_id = phy_data->phydev->phy_id;
@@ -951,9 +959,13 @@ static bool xgbe_phy_belfuse_phy_quirks(struct xgbe_prv_data *pdata)
        reg = phy_read(phy_data->phydev, 0x00);
        phy_write(phy_data->phydev, 0x00, reg & ~0x00800);
 
-       phy_data->phydev->supported = (PHY_10BT_FEATURES |
-                                      PHY_100BT_FEATURES |
-                                      PHY_1000BT_FEATURES);
+       linkmode_set_bit_array(phy_10_100_features_array,
+                              ARRAY_SIZE(phy_10_100_features_array),
+                              supported);
+       linkmode_set_bit_array(phy_gbit_features_array,
+                              ARRAY_SIZE(phy_gbit_features_array),
+                              supported);
+       linkmode_copy(phy_data->phydev->supported, supported);
        phy_support_asym_pause(phy_data->phydev);
 
        netif_dbg(pdata, drv, pdata->netdev,
@@ -976,7 +988,6 @@ static int xgbe_phy_find_phy_device(struct xgbe_prv_data *pdata)
        struct ethtool_link_ksettings *lks = &pdata->phy.lks;
        struct xgbe_phy_data *phy_data = pdata->phy_data;
        struct phy_device *phydev;
-       u32 advertising;
        int ret;
 
        /* If we already have a PHY, just return */
@@ -1036,9 +1047,8 @@ static int xgbe_phy_find_phy_device(struct xgbe_prv_data *pdata)
 
        xgbe_phy_external_phy_quirks(pdata);
 
-       ethtool_convert_link_mode_to_legacy_u32(&advertising,
-                                               lks->link_modes.advertising);
-       phydev->advertising &= advertising;
+       linkmode_and(phydev->advertising, phydev->advertising,
+                    lks->link_modes.advertising);
 
        phy_start_aneg(phy_data->phydev);
 
@@ -1497,7 +1507,7 @@ static void xgbe_phy_phydev_flowctrl(struct xgbe_prv_data *pdata)
        if (!phy_data->phydev)
                return;
 
-       lcl_adv = ethtool_adv_to_lcl_adv_t(phy_data->phydev->advertising);
+       lcl_adv = linkmode_adv_to_lcl_adv_t(phy_data->phydev->advertising);
 
        if (phy_data->phydev->pause) {
                XGBE_SET_LP_ADV(lks, Pause);
@@ -1815,7 +1825,6 @@ static int xgbe_phy_an_config(struct xgbe_prv_data *pdata)
 {
        struct ethtool_link_ksettings *lks = &pdata->phy.lks;
        struct xgbe_phy_data *phy_data = pdata->phy_data;
-       u32 advertising;
        int ret;
 
        ret = xgbe_phy_find_phy_device(pdata);
@@ -1825,12 +1834,10 @@ static int xgbe_phy_an_config(struct xgbe_prv_data *pdata)
        if (!phy_data->phydev)
                return 0;
 
-       ethtool_convert_link_mode_to_legacy_u32(&advertising,
-                                               lks->link_modes.advertising);
-
        phy_data->phydev->autoneg = pdata->phy.autoneg;
-       phy_data->phydev->advertising = phy_data->phydev->supported &
-                                       advertising;
+       linkmode_and(phy_data->phydev->advertising,
+                    phy_data->phydev->supported,
+                    lks->link_modes.advertising);
 
        if (pdata->phy.autoneg != AUTONEG_ENABLE) {
                phy_data->phydev->speed = pdata->phy.speed;
index f5fe3bb2e59d9a9eecfcfb358af0a15785d69cfa..53529cd851628c4de1f1f85ad9b60ce14d55ca70 100644 (file)
@@ -109,6 +109,7 @@ void xge_mdio_remove(struct net_device *ndev)
 
 int xge_mdio_config(struct net_device *ndev)
 {
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
        struct xge_pdata *pdata = netdev_priv(ndev);
        struct device *dev = &pdata->pdev->dev;
        struct mii_bus *mdio_bus;
@@ -148,16 +149,17 @@ int xge_mdio_config(struct net_device *ndev)
                goto err;
        }
 
-       phydev->supported &= ~(SUPPORTED_10baseT_Half |
-                              SUPPORTED_10baseT_Full |
-                              SUPPORTED_100baseT_Half |
-                              SUPPORTED_100baseT_Full |
-                              SUPPORTED_1000baseT_Half |
-                              SUPPORTED_AUI |
-                              SUPPORTED_MII |
-                              SUPPORTED_FIBRE |
-                              SUPPORTED_BNC);
-       phydev->advertising = phydev->supported;
+       linkmode_set_bit_array(phy_10_100_features_array,
+                              ARRAY_SIZE(phy_10_100_features_array),
+                              mask);
+       linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, mask);
+       linkmode_set_bit(ETHTOOL_LINK_MODE_AUI_BIT, mask);
+       linkmode_set_bit(ETHTOOL_LINK_MODE_MII_BIT, mask);
+       linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, mask);
+       linkmode_set_bit(ETHTOOL_LINK_MODE_BNC_BIT, mask);
+
+       linkmode_andnot(phydev->supported, phydev->supported, mask);
+       linkmode_copy(phydev->advertising, phydev->supported);
        pdata->phy_speed = SPEED_UNKNOWN;
 
        return 0;
index bd277b0dc615118a58b81dfba5b040e26fa667ba..4406325fdd9f697d914f3097ae8fc1ab85e6f129 100644 (file)
@@ -432,7 +432,8 @@ static int arc_emac_open(struct net_device *ndev)
        phy_dev->autoneg = AUTONEG_ENABLE;
        phy_dev->speed = 0;
        phy_dev->duplex = 0;
-       phy_dev->advertising &= phy_dev->supported;
+       linkmode_and(phy_dev->advertising, phy_dev->advertising,
+                    phy_dev->supported);
 
        priv->last_rx_bd = 0;
 
index e445ab724827f8d3c7c3770748902c08b76f8e13..f44808959ff38b475f1a492e565c216502b1d65f 100644 (file)
@@ -2248,6 +2248,7 @@ static void b44_adjust_link(struct net_device *dev)
 
 static int b44_register_phy_one(struct b44 *bp)
 {
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
        struct mii_bus *mii_bus;
        struct ssb_device *sdev = bp->sdev;
        struct phy_device *phydev;
@@ -2303,11 +2304,12 @@ static int b44_register_phy_one(struct b44 *bp)
        }
 
        /* mask with MAC supported features */
-       phydev->supported &= (SUPPORTED_100baseT_Half |
-                             SUPPORTED_100baseT_Full |
-                             SUPPORTED_Autoneg |
-                             SUPPORTED_MII);
-       phydev->advertising = phydev->supported;
+       linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, mask);
+       linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, mask);
+       linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, mask);
+       linkmode_set_bit(ETHTOOL_LINK_MODE_MII_BIT, mask);
+       linkmode_and(phydev->supported, phydev->supported, mask);
+       linkmode_copy(phydev->advertising, phydev->supported);
 
        bp->old_link = 0;
        bp->phy_addr = phydev->mdio.addr;
index a6cbaca37e944ffc967b65b9eb3c963705fb73e7..aceb9b7b55bdf9c26d26f3bc9f44a4d7574c6a89 100644 (file)
@@ -226,7 +226,8 @@ int bcmgenet_mii_config(struct net_device *dev, bool init)
                 * capabilities, use that knowledge to also configure the
                 * Reverse MII interface correctly.
                 */
-               if (dev->phydev->supported & PHY_1000BT_FEATURES)
+               if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+                                     dev->phydev->supported))
                        port_ctrl = PORT_MODE_EXT_RVMII_50;
                else
                        port_ctrl = PORT_MODE_EXT_RVMII_25;
@@ -317,7 +318,7 @@ int bcmgenet_mii_probe(struct net_device *dev)
                return ret;
        }
 
-       phydev->advertising = phydev->supported;
+       linkmode_copy(phydev->advertising, phydev->supported);
 
        /* The internal PHY has its link interrupts routed to the
         * Ethernet MAC ISRs. On GENETv5 there is a hardware issue
index ce44d208e1372e21608ed5bdf8fed120381a7a79..79b881d9cdb073340da77338861b5a29865dc29d 100644 (file)
@@ -2157,7 +2157,8 @@ static void tg3_phy_start(struct tg3 *tp)
                phydev->speed = tp->link_config.speed;
                phydev->duplex = tp->link_config.duplex;
                phydev->autoneg = tp->link_config.autoneg;
-               phydev->advertising = tp->link_config.advertising;
+               ethtool_convert_legacy_u32_to_link_mode(
+                       phydev->advertising, tp->link_config.advertising);
        }
 
        phy_start(phydev);
@@ -4057,8 +4058,9 @@ static int tg3_power_down_prepare(struct tg3 *tp)
                do_low_power = false;
                if ((tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) &&
                    !(tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)) {
+                       __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising) = { 0, };
                        struct phy_device *phydev;
-                       u32 phyid, advertising;
+                       u32 phyid;
 
                        phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
 
@@ -4067,25 +4069,33 @@ static int tg3_power_down_prepare(struct tg3 *tp)
                        tp->link_config.speed = phydev->speed;
                        tp->link_config.duplex = phydev->duplex;
                        tp->link_config.autoneg = phydev->autoneg;
-                       tp->link_config.advertising = phydev->advertising;
-
-                       advertising = ADVERTISED_TP |
-                                     ADVERTISED_Pause |
-                                     ADVERTISED_Autoneg |
-                                     ADVERTISED_10baseT_Half;
+                       ethtool_convert_link_mode_to_legacy_u32(
+                               &tp->link_config.advertising,
+                               phydev->advertising);
+
+                       linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT, advertising);
+                       linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT,
+                                        advertising);
+                       linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
+                                        advertising);
+                       linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
+                                        advertising);
 
                        if (tg3_flag(tp, ENABLE_ASF) || device_should_wake) {
-                               if (tg3_flag(tp, WOL_SPEED_100MB))
-                                       advertising |=
-                                               ADVERTISED_100baseT_Half |
-                                               ADVERTISED_100baseT_Full |
-                                               ADVERTISED_10baseT_Full;
-                               else
-                                       advertising |= ADVERTISED_10baseT_Full;
+                               if (tg3_flag(tp, WOL_SPEED_100MB)) {
+                                       linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
+                                                        advertising);
+                                       linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+                                                        advertising);
+                                       linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
+                                                        advertising);
+                               } else {
+                                       linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
+                                                        advertising);
+                               }
                        }
 
-                       phydev->advertising = advertising;
-
+                       linkmode_copy(phydev->advertising, advertising);
                        phy_start_aneg(phydev);
 
                        phyid = phydev->drv->phy_id & phydev->drv->phy_id_mask;
index 4b3aecf98f2affc746a2833128815f71b3aae8dc..5359c1021f428b04bc13ad2de9cc437fc47596cb 100644 (file)
@@ -1080,8 +1080,11 @@ static int octeon_mgmt_open(struct net_device *netdev)
        /* Set the mode of the interface, RGMII/MII. */
        if (OCTEON_IS_MODEL(OCTEON_CN6XXX) && netdev->phydev) {
                union cvmx_agl_prtx_ctl agl_prtx_ctl;
-               int rgmii_mode = (netdev->phydev->supported &
-                                 (SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full)) != 0;
+               int rgmii_mode =
+                       (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
+                                          netdev->phydev->supported) |
+                        linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+                                          netdev->phydev->supported)) != 0;
 
                agl_prtx_ctl.u64 = cvmx_read_csr(p->agl_prt_ctl);
                agl_prtx_ctl.s.mode = rgmii_mode ? 0 : 1;
index 6e0f47f2c8a3754e7776dd3acef403f4848e1f1a..9510c9d78858d41cadf365bdec8423e5b23aaca9 100644 (file)
@@ -2475,6 +2475,7 @@ static void dpaa_adjust_link(struct net_device *net_dev)
 
 static int dpaa_phy_init(struct net_device *net_dev)
 {
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
        struct mac_device *mac_dev;
        struct phy_device *phy_dev;
        struct dpaa_priv *priv;
@@ -2491,7 +2492,9 @@ static int dpaa_phy_init(struct net_device *net_dev)
        }
 
        /* Remove any features not supported by the controller */
-       phy_dev->supported &= mac_dev->if_support;
+       ethtool_convert_legacy_u32_to_link_mode(mask, mac_dev->if_support);
+       linkmode_and(phy_dev->supported, phy_dev->supported, mask);
+
        phy_support_asym_pause(phy_dev);
 
        mac_dev->phy_dev = phy_dev;
index d79e4e009d637885271a1b7cdb29e9d24c7bbe02..71f4205f14e7d9fc1ce43728dbe50f89ecad4827 100644 (file)
@@ -393,7 +393,7 @@ void fman_get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause,
         */
 
        /* get local capabilities */
-       lcl_adv = ethtool_adv_to_lcl_adv_t(phy_dev->advertising);
+       lcl_adv = linkmode_adv_to_lcl_adv_t(phy_dev->advertising);
 
        /* get link partner capabilities */
        rmt_adv = 0;
index 3c8da1a18ba08cc7d266eff374363eaeb3faf47e..0e102c764b133da2420d8adefc098a6b39e168fb 100644 (file)
@@ -1784,14 +1784,20 @@ static phy_interface_t gfar_get_interface(struct net_device *dev)
  */
 static int init_phy(struct net_device *dev)
 {
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
        struct gfar_private *priv = netdev_priv(dev);
-       uint gigabit_support =
-               priv->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
-               GFAR_SUPPORTED_GBIT : 0;
        phy_interface_t interface;
        struct phy_device *phydev;
        struct ethtool_eee edata;
 
+       linkmode_set_bit_array(phy_10_100_features_array,
+                              ARRAY_SIZE(phy_10_100_features_array),
+                              mask);
+       linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, mask);
+       linkmode_set_bit(ETHTOOL_LINK_MODE_MII_BIT, mask);
+       if (priv->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT)
+               linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, mask);
+
        priv->oldlink = 0;
        priv->oldspeed = 0;
        priv->oldduplex = -1;
@@ -1809,8 +1815,8 @@ static int init_phy(struct net_device *dev)
                gfar_configure_serdes(dev);
 
        /* Remove any features not supported by the controller */
-       phydev->supported &= (GFAR_SUPPORTED | gigabit_support);
-       phydev->advertising = phydev->supported;
+       linkmode_and(phydev->supported, phydev->supported, mask);
+       linkmode_copy(phydev->advertising, phydev->supported);
 
        /* Add support for flow control */
        phy_support_asym_pause(phydev);
@@ -3656,7 +3662,7 @@ static u32 gfar_get_flowctrl_cfg(struct gfar_private *priv)
                if (phydev->asym_pause)
                        rmt_adv |= LPA_PAUSE_ASYM;
 
-               lcl_adv = ethtool_adv_to_lcl_adv_t(phydev->advertising);
+               lcl_adv = linkmode_adv_to_lcl_adv_t(phydev->advertising);
                flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
                if (flowctrl & FLOW_CTRL_TX)
                        val |= MACCFG1_TX_FLOW;
index 32e02700feaa1462b8d76ecee9303f8c9dbd4b50..2e978cb8b28c4e75588c37251a416406d7fec0d2 100644 (file)
@@ -1742,12 +1742,7 @@ static int init_phy(struct net_device *dev)
        if (priv->phy_interface == PHY_INTERFACE_MODE_SGMII)
                uec_configure_serdes(dev);
 
-       phy_set_max_speed(phydev, SPEED_100);
-
-       if (priv->max_speed == SPEED_1000)
-               phydev->supported |= ADVERTISED_1000baseT_Full;
-
-       phydev->advertising = phydev->supported;
+       phy_set_max_speed(phydev, priv->max_speed);
 
        priv->phydev = phydev;
 
index 28e907831b0eddbf760e0edb579ae7ae708520e0..c62378c07e70fcc14722146b943617468e43e57b 100644 (file)
@@ -1163,6 +1163,7 @@ static void hns_nic_adjust_link(struct net_device *ndev)
  */
 int hns_nic_init_phy(struct net_device *ndev, struct hnae_handle *h)
 {
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, };
        struct phy_device *phy_dev = h->phy_dev;
        int ret;
 
@@ -1180,8 +1181,9 @@ int hns_nic_init_phy(struct net_device *ndev, struct hnae_handle *h)
        if (unlikely(ret))
                return -ENODEV;
 
-       phy_dev->supported &= h->if_support;
-       phy_dev->advertising = phy_dev->supported;
+       ethtool_convert_legacy_u32_to_link_mode(supported, h->if_support);
+       linkmode_and(phy_dev->supported, phy_dev->supported, supported);
+       linkmode_copy(phy_dev->advertising, phy_dev->supported);
 
        if (h->phy_if == PHY_INTERFACE_MODE_XGMII)
                phy_dev->autoneg = false;
index ab90108db1c93e232630336c7da2841a480a5dc2..43bfc730a62da6c2fba7bb972f221af891664481 100644 (file)
@@ -6582,7 +6582,7 @@ int hclge_cfg_flowctrl(struct hclge_dev *hdev)
        if (!phydev->link || !phydev->autoneg)
                return 0;
 
-       local_advertising = ethtool_adv_to_lcl_adv_t(phydev->advertising);
+       local_advertising = linkmode_adv_to_lcl_adv_t(phydev->advertising);
 
        if (phydev->pause)
                remote_advertising = LPA_PAUSE_CAP;
index 03018638f701b3f2824bb153864e13cf929bd06c..741cb3b9519de677d8fd689546aa1d5587ae6f57 100644 (file)
@@ -195,12 +195,13 @@ int hclge_mac_connect_phy(struct hclge_dev *hdev)
 {
        struct net_device *netdev = hdev->vport[0].nic.netdev;
        struct phy_device *phydev = hdev->hw.mac.phydev;
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
        int ret;
 
        if (!phydev)
                return 0;
 
-       phydev->supported &= ~SUPPORTED_FIBRE;
+       linkmode_clear_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported);
 
        ret = phy_connect_direct(netdev, phydev,
                                 hclge_mac_adjust_link,
@@ -210,7 +211,15 @@ int hclge_mac_connect_phy(struct hclge_dev *hdev)
                return ret;
        }
 
-       phydev->supported &= HCLGE_PHY_SUPPORTED_FEATURES;
+       linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, mask);
+       linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT, mask);
+       linkmode_set_bit_array(phy_10_100_features_array,
+                              ARRAY_SIZE(phy_10_100_features_array),
+                              mask);
+       linkmode_set_bit_array(phy_gbit_features_array,
+                              ARRAY_SIZE(phy_gbit_features_array),
+                              mask);
+       linkmode_and(phydev->supported, phydev->supported, mask);
        phy_support_asym_pause(phydev);
 
        return 0;
index 760b2ad8e295769a21afe641edde6a57f6b4b851..209255495bc978e223f81700dc9cb7be1046f4cc 100644 (file)
@@ -2455,7 +2455,8 @@ static void emac_adjust_link(struct net_device *ndev)
        dev->phy.duplex = phy->duplex;
        dev->phy.pause = phy->pause;
        dev->phy.asym_pause = phy->asym_pause;
-       dev->phy.advertising = phy->advertising;
+       ethtool_convert_link_mode_to_legacy_u32(&dev->phy.advertising,
+                                               phy->advertising);
 }
 
 static int emac_mii_bus_read(struct mii_bus *bus, int addr, int regnum)
@@ -2490,7 +2491,8 @@ static int emac_mdio_phy_start_aneg(struct mii_phy *phy,
        phy_dev->autoneg = phy->autoneg;
        phy_dev->speed = phy->speed;
        phy_dev->duplex = phy->duplex;
-       phy_dev->advertising = phy->advertising;
+       ethtool_convert_legacy_u32_to_link_mode(phy_dev->advertising,
+                                               phy->advertising);
        return phy_start_aneg(phy_dev);
 }
 
@@ -2624,7 +2626,8 @@ static int emac_dt_phy_connect(struct emac_instance *dev,
        dev->phy.def->phy_id_mask = dev->phy_dev->drv->phy_id_mask;
        dev->phy.def->name = dev->phy_dev->drv->name;
        dev->phy.def->ops = &emac_dt_mdio_phy_ops;
-       dev->phy.features = dev->phy_dev->supported;
+       ethtool_convert_link_mode_to_legacy_u32(&dev->phy.features,
+                                               dev->phy_dev->supported);
        dev->phy.address = dev->phy_dev->mdio.addr;
        dev->phy.mode = dev->phy_dev->interface;
        return 0;
index 1e9bcbdc6a90b7f04bc07a136d80f3f7f55e929b..2f427271a793e4749f4a5f1d1163e738545ed173 100644 (file)
@@ -1499,23 +1499,16 @@ mv643xx_eth_get_link_ksettings_phy(struct mv643xx_eth_private *mp,
                                   struct ethtool_link_ksettings *cmd)
 {
        struct net_device *dev = mp->dev;
-       u32 supported, advertising;
 
        phy_ethtool_ksettings_get(dev->phydev, cmd);
 
        /*
         * The MAC does not support 1000baseT_Half.
         */
-       ethtool_convert_link_mode_to_legacy_u32(&supported,
-                                               cmd->link_modes.supported);
-       ethtool_convert_link_mode_to_legacy_u32(&advertising,
-                                               cmd->link_modes.advertising);
-       supported &= ~SUPPORTED_1000baseT_Half;
-       advertising &= ~ADVERTISED_1000baseT_Half;
-       ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
-                                               supported);
-       ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising,
-                                               advertising);
+       linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
+                          cmd->link_modes.supported);
+       linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
+                          cmd->link_modes.advertising);
 
        return 0;
 }
@@ -3031,10 +3024,12 @@ static void phy_init(struct mv643xx_eth_private *mp, int speed, int duplex)
                phy->autoneg = AUTONEG_ENABLE;
                phy->speed = 0;
                phy->duplex = 0;
-               phy->advertising = phy->supported | ADVERTISED_Autoneg;
+               linkmode_copy(phy->advertising, phy->supported);
+               linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
+                                phy->advertising);
        } else {
                phy->autoneg = AUTONEG_DISABLE;
-               phy->advertising = 0;
+               linkmode_zero(phy->advertising);
                phy->speed = speed;
                phy->duplex = duplex;
        }
index 7dbfdac4067ad0ebaf1f4034948e6972589dfeb2..399f565dd85a57c024dde28f62b9c678c562df0c 100644 (file)
@@ -243,7 +243,7 @@ static void mtk_phy_link_adjust(struct net_device *dev)
                if (dev->phydev->asym_pause)
                        rmt_adv |= LPA_PAUSE_ASYM;
 
-               lcl_adv = ethtool_adv_to_lcl_adv_t(dev->phydev->advertising);
+               lcl_adv = linkmode_adv_to_lcl_adv_t(dev->phydev->advertising);
                flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
 
                if (flowctrl & FLOW_CTRL_TX)
@@ -353,8 +353,9 @@ static int mtk_phy_connect(struct net_device *dev)
 
        phy_set_max_speed(dev->phydev, SPEED_1000);
        phy_support_asym_pause(dev->phydev);
-       dev->phydev->advertising = dev->phydev->supported |
-                                   ADVERTISED_Autoneg;
+       linkmode_copy(dev->phydev->advertising, dev->phydev->supported);
+       linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
+                        dev->phydev->advertising);
        phy_start_aneg(dev->phydev);
 
        of_node_put(np);
index 25382f8fbb70c2e19c0b862714eb4074cae2809f..bd8695a4faaa1d4c09ea9a3659b720b0260078ca 100644 (file)
@@ -783,8 +783,6 @@ static int lpc_mii_probe(struct net_device *ndev)
 
        phy_set_max_speed(phydev, SPEED_100);
 
-       phydev->advertising = phydev->supported;
-
        pldat->link = 0;
        pldat->speed = 0;
        pldat->duplex = -1;
index 1fd01688d37bdd9c7e09e2444034c0ccb286ea19..56de045268f8cf2bd6764bfb5682c5495aef5423 100644 (file)
@@ -6584,7 +6584,7 @@ static int r8169_phy_connect(struct rtl8169_private *tp)
                phy_set_max_speed(phydev, SPEED_100);
 
        /* Ensure to advertise everything, incl. pause */
-       phydev->advertising = phydev->supported;
+       linkmode_copy(phydev->advertising, phydev->supported);
 
        phy_attached_info(phydev);
 
index 6732f5cbde081052ce9e1c2417451118cadbff8f..9e7391faa1dcd4f4c79a1638e3e0f068c5d4e65f 100644 (file)
@@ -1117,7 +1117,7 @@ static void ave_phy_adjust_link(struct net_device *ndev)
                if (phydev->asym_pause)
                        rmt_adv |= LPA_PAUSE_ASYM;
 
-               lcl_adv = ethtool_adv_to_lcl_adv_t(phydev->advertising);
+               lcl_adv = linkmode_adv_to_lcl_adv_t(phydev->advertising);
                cap = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
                if (cap & FLOW_CTRL_TX)
                        txcr |= AVE_TXCR_FLOCTR;
index 5710864fa80903102a82115aaa2bec9ac6d31aba..d1f61c25d82bc8e25c1026bd20105614a73a1b05 100644 (file)
@@ -458,8 +458,10 @@ stmmac_get_pauseparam(struct net_device *netdev,
                if (!adv_lp.pause)
                        return;
        } else {
-               if (!(netdev->phydev->supported & SUPPORTED_Pause) ||
-                   !(netdev->phydev->supported & SUPPORTED_Asym_Pause))
+               if (!linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
+                                      netdev->phydev->supported) ||
+                   linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
+                                     netdev->phydev->supported))
                        return;
        }
 
@@ -487,8 +489,10 @@ stmmac_set_pauseparam(struct net_device *netdev,
                if (!adv_lp.pause)
                        return -EOPNOTSUPP;
        } else {
-               if (!(phy->supported & SUPPORTED_Pause) ||
-                   !(phy->supported & SUPPORTED_Asym_Pause))
+               if (!linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
+                                      phy->supported) ||
+                   linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
+                                     phy->supported))
                        return -EOPNOTSUPP;
        }
 
index 6a71c2c0f17d1f9032787bb11c338fed6bf1bbd2..c50a9772f4affbdb4fc0683dc987f74766f22263 100644 (file)
@@ -607,9 +607,9 @@ static void tc_handle_link_change(struct net_device *dev)
 
 static int tc_mii_probe(struct net_device *dev)
 {
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
        struct tc35815_local *lp = netdev_priv(dev);
        struct phy_device *phydev;
-       u32 dropmask;
 
        phydev = phy_find_first(lp->mii_bus);
        if (!phydev) {
@@ -630,17 +630,22 @@ static int tc_mii_probe(struct net_device *dev)
 
        /* mask with MAC supported features */
        phy_set_max_speed(phydev, SPEED_100);
-       dropmask = 0;
-       if (options.speed == 10)
-               dropmask |= SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full;
-       else if (options.speed == 100)
-               dropmask |= SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full;
-       if (options.duplex == 1)
-               dropmask |= SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Full;
-       else if (options.duplex == 2)
-               dropmask |= SUPPORTED_10baseT_Half | SUPPORTED_100baseT_Half;
-       phydev->supported &= ~dropmask;
-       phydev->advertising = phydev->supported;
+       if (options.speed == 10) {
+               linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, mask);
+               linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, mask);
+       } else if (options.speed == 100) {
+               linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, mask);
+               linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, mask);
+       }
+       if (options.duplex == 1) {
+               linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, mask);
+               linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, mask);
+       } else if (options.duplex == 2) {
+               linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, mask);
+               linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, mask);
+       }
+       linkmode_and(phydev->supported, phydev->supported, mask);
+       linkmode_copy(phydev->advertising, phydev->supported);
 
        lp->link = 0;
        lp->speed = 0;
index efc0fbde97a1e794fe697df3361efae486d11585..beb3309bb0f0305679812ef2110208bfdfcae612 100644 (file)
 #define PHY_ID_AQR107  0x03a1b4e0
 #define PHY_ID_AQR405  0x03a1b4b0
 
-#define PHY_AQUANTIA_FEATURES  (SUPPORTED_10000baseT_Full | \
-                                SUPPORTED_1000baseT_Full | \
-                                SUPPORTED_100baseT_Full | \
-                                PHY_DEFAULT_FEATURES)
-
 static int aquantia_config_aneg(struct phy_device *phydev)
 {
-       phydev->supported = PHY_AQUANTIA_FEATURES;
-       phydev->advertising = phydev->supported;
+       linkmode_copy(phydev->supported, phy_10gbit_features);
+       linkmode_copy(phydev->advertising, phydev->supported);
 
        return 0;
 }
index 6a547b87ff0443eaa1af818630e96bc974a2ace7..a88dd14a25c0f01383dfc66335cb5ff356bb704d 100644 (file)
@@ -43,7 +43,7 @@ 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;
+       linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->supported);
 
        reg = phy_read(phydev, MII_BCM63XX_IR);
        if (reg < 0)
index 64d5ba7bf94f65cc8ebe609e6d83cb2356e4f041..1b350183bffbd20732f0b6a3495a5d16e3758aa3 100644 (file)
@@ -86,8 +86,12 @@ static int bcm87xx_of_reg_init(struct phy_device *phydev)
 
 static int bcm87xx_config_init(struct phy_device *phydev)
 {
-       phydev->supported = SUPPORTED_10000baseR_FEC;
-       phydev->advertising = ADVERTISED_10000baseR_FEC;
+       linkmode_zero(phydev->supported);
+       linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseR_FEC_BIT,
+                        phydev->supported);
+       linkmode_zero(phydev->advertising);
+       linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseR_FEC_BIT,
+                        phydev->advertising);
        phydev->state = PHY_NOLINK;
        phydev->autoneg = AUTONEG_DISABLE;
 
index 67b260877f305a33c8a8b4aa37d5862478fe7835..f7fb62712cd871c3a7d14597cbe1d68ac10e0b2d 100644 (file)
@@ -223,14 +223,23 @@ struct phy_device *fixed_phy_register(unsigned int irq,
 
        switch (status->speed) {
        case SPEED_1000:
-               phy->supported = PHY_1000BT_FEATURES;
-               break;
+               linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
+                                phy->supported);
+               linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+                                phy->supported);
+               /* fall through */
        case SPEED_100:
-               phy->supported = PHY_100BT_FEATURES;
-               break;
+               linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
+                                phy->supported);
+               linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+                                phy->supported);
+               /* fall through */
        case SPEED_10:
        default:
-               phy->supported = PHY_10BT_FEATURES;
+               linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
+                                phy->supported);
+               linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
+                                phy->supported);
        }
 
        ret = phy_device_register(phy);
index 463c616a7281132043567cefd600ce450af23d6e..96f33831ea990c76ecd497533526c357bc54df75 100644 (file)
@@ -491,25 +491,26 @@ static int m88e1318_config_aneg(struct phy_device *phydev)
 }
 
 /**
- * ethtool_adv_to_fiber_adv_t
- * @ethadv: the ethtool advertisement settings
+ * linkmode_adv_to_fiber_adv_t
+ * @advertise: the linkmode advertisement settings
  *
- * A small helper function that translates ethtool advertisement
- * settings to phy autonegotiation advertisements for the
- * MII_ADV register for fiber link.
+ * A small helper function that translates linkmode advertisement
+ * settings to phy autonegotiation advertisements for the MII_ADV
+ * register for fiber link.
  */
-static inline u32 ethtool_adv_to_fiber_adv_t(u32 ethadv)
+static inline u32 linkmode_adv_to_fiber_adv_t(unsigned long *advertise)
 {
        u32 result = 0;
 
-       if (ethadv & ADVERTISED_1000baseT_Half)
+       if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, advertise))
                result |= ADVERTISE_FIBER_1000HALF;
-       if (ethadv & ADVERTISED_1000baseT_Full)
+       if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, advertise))
                result |= ADVERTISE_FIBER_1000FULL;
 
-       if ((ethadv & ADVERTISE_PAUSE_ASYM) && (ethadv & ADVERTISE_PAUSE_CAP))
+       if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, advertise) &&
+           linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertise))
                result |= LPA_PAUSE_ASYM_FIBER;
-       else if (ethadv & ADVERTISE_PAUSE_CAP)
+       else if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertise))
                result |= (ADVERTISE_PAUSE_FIBER
                           & (~ADVERTISE_PAUSE_ASYM_FIBER));
 
@@ -530,14 +531,13 @@ static int marvell_config_aneg_fiber(struct phy_device *phydev)
        int changed = 0;
        int err;
        int adv, oldadv;
-       u32 advertise;
 
        if (phydev->autoneg != AUTONEG_ENABLE)
                return genphy_setup_forced(phydev);
 
        /* Only allow advertising what this PHY supports */
-       phydev->advertising &= phydev->supported;
-       advertise = phydev->advertising;
+       linkmode_and(phydev->advertising, phydev->advertising,
+                    phydev->supported);
 
        /* Setup fiber advertisement */
        adv = phy_read(phydev, MII_ADVERTISE);
@@ -547,7 +547,7 @@ static int marvell_config_aneg_fiber(struct phy_device *phydev)
        oldadv = adv;
        adv &= ~(ADVERTISE_FIBER_1000HALF | ADVERTISE_FIBER_1000FULL
                | LPA_PAUSE_FIBER);
-       adv |= ethtool_adv_to_fiber_adv_t(advertise);
+       adv |= linkmode_adv_to_fiber_adv_t(phydev->advertising);
 
        if (adv != oldadv) {
                err = phy_write(phydev, MII_ADVERTISE, adv);
@@ -879,8 +879,14 @@ static int m88e1510_config_init(struct phy_device *phydev)
                 * so disable Pause support.
                 */
                pause = SUPPORTED_Pause | SUPPORTED_Asym_Pause;
-               phydev->supported &= ~pause;
-               phydev->advertising &= ~pause;
+               linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
+                                  phydev->supported);
+               linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT,
+                                  phydev->supported);
+               linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
+                                  phydev->advertising);
+               linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT,
+                                  phydev->advertising);
        }
 
        return m88e1318_config_init(phydev);
@@ -1235,7 +1241,8 @@ static int marvell_read_status(struct phy_device *phydev)
        int err;
 
        /* Check the fiber mode first */
-       if (phydev->supported & SUPPORTED_FIBRE &&
+       if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
+                             phydev->supported) &&
            phydev->interface != PHY_INTERFACE_MODE_SGMII) {
                err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE);
                if (err < 0)
@@ -1278,7 +1285,8 @@ static int marvell_suspend(struct phy_device *phydev)
        int err;
 
        /* Suspend the fiber mode first */
-       if (!(phydev->supported & SUPPORTED_FIBRE)) {
+       if (!linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
+                              phydev->supported)) {
                err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE);
                if (err < 0)
                        goto error;
@@ -1312,7 +1320,8 @@ static int marvell_resume(struct phy_device *phydev)
        int err;
 
        /* Resume the fiber mode first */
-       if (!(phydev->supported & SUPPORTED_FIBRE)) {
+       if (!linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
+                              phydev->supported)) {
                err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE);
                if (err < 0)
                        goto error;
@@ -1463,7 +1472,8 @@ error:
 
 static int marvell_get_sset_count(struct phy_device *phydev)
 {
-       if (phydev->supported & SUPPORTED_FIBRE)
+       if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
+                             phydev->supported))
                return ARRAY_SIZE(marvell_hw_stats);
        else
                return ARRAY_SIZE(marvell_hw_stats) - NB_FIBER_STATS;
index 1c9d039eec63d97b9dc1bd05209e8d225703e166..d939dce16b35cce6182b5e33997978b06e46d9e1 100644 (file)
@@ -252,7 +252,6 @@ static int mv3310_resume(struct phy_device *phydev)
 static int mv3310_config_init(struct phy_device *phydev)
 {
        __ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, };
-       u32 mask;
        int val;
 
        /* Check that the PHY interface type is compatible */
@@ -336,13 +335,9 @@ static int mv3310_config_init(struct phy_device *phydev)
                }
        }
 
-       if (!ethtool_convert_link_mode_to_legacy_u32(&mask, supported))
-               phydev_warn(phydev,
-                           "PHY supports (%*pb) more modes than phylib supports, some modes not supported.\n",
-                           __ETHTOOL_LINK_MODE_MASK_NBITS, supported);
-
-       phydev->supported &= mask;
-       phydev->advertising &= phydev->supported;
+       linkmode_copy(phydev->supported, supported);
+       linkmode_and(phydev->advertising, phydev->advertising,
+                    phydev->supported);
 
        return 0;
 }
@@ -350,7 +345,7 @@ static int mv3310_config_init(struct phy_device *phydev)
 static int mv3310_config_aneg(struct phy_device *phydev)
 {
        bool changed = false;
-       u32 advertising;
+       u16 reg;
        int ret;
 
        /* We don't support manual MDI control */
@@ -364,31 +359,35 @@ static int mv3310_config_aneg(struct phy_device *phydev)
                return genphy_c45_an_disable_aneg(phydev);
        }
 
-       phydev->advertising &= phydev->supported;
-       advertising = phydev->advertising;
+       linkmode_and(phydev->advertising, phydev->advertising,
+                    phydev->supported);
 
        ret = mv3310_modify(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE,
                            ADVERTISE_ALL | ADVERTISE_100BASE4 |
                            ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM,
-                           ethtool_adv_to_mii_adv_t(advertising));
+                           linkmode_adv_to_mii_adv_t(phydev->advertising));
        if (ret < 0)
                return ret;
        if (ret > 0)
                changed = true;
 
+       reg = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising);
        ret = mv3310_modify(phydev, MDIO_MMD_AN, MV_AN_CTRL1000,
-                           ADVERTISE_1000FULL | ADVERTISE_1000HALF,
-                           ethtool_adv_to_mii_ctrl1000_t(advertising));
+                           ADVERTISE_1000FULL | ADVERTISE_1000HALF, reg);
        if (ret < 0)
                return ret;
        if (ret > 0)
                changed = true;
 
        /* 10G control register */
+       if (linkmode_test_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
+                             phydev->advertising))
+               reg = MDIO_AN_10GBT_CTRL_ADV10G;
+       else
+               reg = 0;
+
        ret = mv3310_modify(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
-                           MDIO_AN_10GBT_CTRL_ADV10G,
-                           advertising & ADVERTISED_10000baseT_Full ?
-                               MDIO_AN_10GBT_CTRL_ADV10G : 0);
+                           MDIO_AN_10GBT_CTRL_ADV10G, reg);
        if (ret < 0)
                return ret;
        if (ret > 0)
index cb5783905a2500760ce61c52fd0d939debb3af54..c33384710d26e03230562d1b0754b490dc0a45fc 100644 (file)
@@ -311,17 +311,22 @@ static int kszphy_config_init(struct phy_device *phydev)
 
 static int ksz8041_config_init(struct phy_device *phydev)
 {
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
+
        struct device_node *of_node = phydev->mdio.dev.of_node;
 
        /* Limit supported and advertised modes in fiber mode */
        if (of_property_read_bool(of_node, "micrel,fiber-mode")) {
                phydev->dev_flags |= MICREL_PHY_FXEN;
-               phydev->supported &= SUPPORTED_100baseT_Full |
-                                    SUPPORTED_100baseT_Half;
-               phydev->supported |= SUPPORTED_FIBRE;
-               phydev->advertising &= ADVERTISED_100baseT_Full |
-                                      ADVERTISED_100baseT_Half;
-               phydev->advertising |= ADVERTISED_FIBRE;
+               linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, mask);
+               linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, mask);
+
+               linkmode_and(phydev->supported, phydev->supported, mask);
+               linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
+                                phydev->supported);
+               linkmode_and(phydev->advertising, phydev->advertising, mask);
+               linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
+                                phydev->advertising);
                phydev->autoneg = AUTONEG_DISABLE;
        }
 
index d7636ff03bc72f28dc3c5f234b5f6e818445271e..a19f4dfa74709a4673fdda262b34cad2f0119cce 100644 (file)
@@ -304,8 +304,11 @@ EXPORT_SYMBOL_GPL(gen10g_no_soft_reset);
 int gen10g_config_init(struct phy_device *phydev)
 {
        /* Temporarily just say we support everything */
-       phydev->supported = SUPPORTED_10000baseT_Full;
-       phydev->advertising = SUPPORTED_10000baseT_Full;
+       linkmode_zero(phydev->supported);
+
+       linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
+                        phydev->supported);
+       linkmode_copy(phydev->advertising, phydev->supported);
 
        return 0;
 }
index c7da4cbb11032d7883371cc50b93f956b7e7f0d2..9d192b660b07a2ecbe01d4bc7f5a723ddff876c6 100644 (file)
@@ -129,7 +129,6 @@ static const struct phy_setting settings[] = {
  * @speed: speed to match
  * @duplex: duplex to match
  * @mask: allowed link modes
- * @maxbit: bit size of link modes
  * @exact: an exact match is required
  *
  * Search the settings array for a setting that matches the speed and
@@ -143,14 +142,14 @@ static const struct phy_setting settings[] = {
  * they all fail, %NULL will be returned.
  */
 const struct phy_setting *
-phy_lookup_setting(int speed, int duplex, const unsigned long *mask,
-                  size_t maxbit, bool exact)
+phy_lookup_setting(int speed, int duplex, const unsigned long *mask, bool exact)
 {
        const struct phy_setting *p, *match = NULL, *last = NULL;
        int i;
 
        for (i = 0, p = settings; i < ARRAY_SIZE(settings); i++, p++) {
-               if (p->bit < maxbit && test_bit(p->bit, mask)) {
+               if (p->bit < __ETHTOOL_LINK_MODE_MASK_NBITS &&
+                   test_bit(p->bit, mask)) {
                        last = p;
                        if (p->speed == speed && p->duplex == duplex) {
                                /* Exact match for speed and duplex */
@@ -175,13 +174,13 @@ phy_lookup_setting(int speed, int duplex, const unsigned long *mask,
 EXPORT_SYMBOL_GPL(phy_lookup_setting);
 
 size_t phy_speeds(unsigned int *speeds, size_t size,
-                 unsigned long *mask, size_t maxbit)
+                 unsigned long *mask)
 {
        size_t count;
        int i;
 
        for (i = 0, count = 0; i < ARRAY_SIZE(settings) && count < size; i++)
-               if (settings[i].bit < maxbit &&
+               if (settings[i].bit < __ETHTOOL_LINK_MODE_MASK_NBITS &&
                    test_bit(settings[i].bit, mask) &&
                    (count == 0 || speeds[count - 1] != settings[i].speed))
                        speeds[count++] = settings[i].speed;
@@ -199,27 +198,38 @@ size_t phy_speeds(unsigned int *speeds, size_t size,
  */
 void phy_resolve_aneg_linkmode(struct phy_device *phydev)
 {
-       u32 common = phydev->lp_advertising & phydev->advertising;
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(common);
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(lp);
 
-       if (common & ADVERTISED_10000baseT_Full) {
+       ethtool_convert_legacy_u32_to_link_mode(lp, phydev->lp_advertising);
+
+       linkmode_and(common, lp, phydev->advertising);
+
+       if (linkmode_test_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, common)) {
                phydev->speed = SPEED_10000;
                phydev->duplex = DUPLEX_FULL;
-       } else if (common & ADVERTISED_1000baseT_Full) {
+       } else if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+                                    common)) {
                phydev->speed = SPEED_1000;
                phydev->duplex = DUPLEX_FULL;
-       } else if (common & ADVERTISED_1000baseT_Half) {
+       } else if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
+                                    common)) {
                phydev->speed = SPEED_1000;
                phydev->duplex = DUPLEX_HALF;
-       } else if (common & ADVERTISED_100baseT_Full) {
+       } else if (linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+                                    common)) {
                phydev->speed = SPEED_100;
                phydev->duplex = DUPLEX_FULL;
-       } else if (common & ADVERTISED_100baseT_Half) {
+       } else if (linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
+                                    common)) {
                phydev->speed = SPEED_100;
                phydev->duplex = DUPLEX_HALF;
-       } else if (common & ADVERTISED_10baseT_Full) {
+       } else if (linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
+                                    common)) {
                phydev->speed = SPEED_10;
                phydev->duplex = DUPLEX_FULL;
-       } else if (common & ADVERTISED_10baseT_Half) {
+       } else if (linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
+                                    common)) {
                phydev->speed = SPEED_10;
                phydev->duplex = DUPLEX_HALF;
        }
index 627e66ab60ebf67d9a4cb037b79aec94ea5b2388..ecc8a7d5306c52d2539a850096d3c37ea62ac6d1 100644 (file)
@@ -179,11 +179,9 @@ EXPORT_SYMBOL(phy_aneg_done);
  * settings were found.
  */
 static const struct phy_setting *
-phy_find_valid(int speed, int duplex, u32 supported)
+phy_find_valid(int speed, int duplex, unsigned long *supported)
 {
-       unsigned long mask = supported;
-
-       return phy_lookup_setting(speed, duplex, &mask, BITS_PER_LONG, false);
+       return phy_lookup_setting(speed, duplex, supported, false);
 }
 
 /**
@@ -200,9 +198,7 @@ unsigned int phy_supported_speeds(struct phy_device *phy,
                                  unsigned int *speeds,
                                  unsigned int size)
 {
-       unsigned long supported = phy->supported;
-
-       return phy_speeds(speeds, size, &supported, BITS_PER_LONG);
+       return phy_speeds(speeds, size, phy->supported);
 }
 
 /**
@@ -214,11 +210,10 @@ unsigned int phy_supported_speeds(struct phy_device *phy,
  *
  * Description: Returns true if there is a valid setting, false otherwise.
  */
-static inline bool phy_check_valid(int speed, int duplex, u32 features)
+static inline bool phy_check_valid(int speed, int duplex,
+                                  unsigned long *features)
 {
-       unsigned long mask = features;
-
-       return !!phy_lookup_setting(speed, duplex, &mask, BITS_PER_LONG, true);
+       return !!phy_lookup_setting(speed, duplex, features, true);
 }
 
 /**
@@ -232,13 +227,13 @@ static inline bool phy_check_valid(int speed, int duplex, u32 features)
 static void phy_sanitize_settings(struct phy_device *phydev)
 {
        const struct phy_setting *setting;
-       u32 features = phydev->supported;
 
        /* Sanitize settings based on PHY capabilities */
-       if ((features & SUPPORTED_Autoneg) == 0)
+       if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported))
                phydev->autoneg = AUTONEG_DISABLE;
 
-       setting = phy_find_valid(phydev->speed, phydev->duplex, features);
+       setting = phy_find_valid(phydev->speed, phydev->duplex,
+                                phydev->supported);
        if (setting) {
                phydev->speed = setting->speed;
                phydev->duplex = setting->duplex;
@@ -264,13 +259,15 @@ static void phy_sanitize_settings(struct phy_device *phydev)
  */
 int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd)
 {
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising);
        u32 speed = ethtool_cmd_speed(cmd);
 
        if (cmd->phy_address != phydev->mdio.addr)
                return -EINVAL;
 
        /* We make sure that we don't pass unsupported values in to the PHY */
-       cmd->advertising &= phydev->supported;
+       ethtool_convert_legacy_u32_to_link_mode(advertising, cmd->advertising);
+       linkmode_and(advertising, advertising, phydev->supported);
 
        /* Verify the settings we care about. */
        if (cmd->autoneg != AUTONEG_ENABLE && cmd->autoneg != AUTONEG_DISABLE)
@@ -291,12 +288,14 @@ int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd)
 
        phydev->speed = speed;
 
-       phydev->advertising = cmd->advertising;
+       linkmode_copy(phydev->advertising, advertising);
 
        if (AUTONEG_ENABLE == cmd->autoneg)
-               phydev->advertising |= ADVERTISED_Autoneg;
+               linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
+                                phydev->advertising);
        else
-               phydev->advertising &= ~ADVERTISED_Autoneg;
+               linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
+                                  phydev->advertising);
 
        phydev->duplex = cmd->duplex;
 
@@ -312,19 +311,18 @@ EXPORT_SYMBOL(phy_ethtool_sset);
 int phy_ethtool_ksettings_set(struct phy_device *phydev,
                              const struct ethtool_link_ksettings *cmd)
 {
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising);
        u8 autoneg = cmd->base.autoneg;
        u8 duplex = cmd->base.duplex;
        u32 speed = cmd->base.speed;
-       u32 advertising;
 
        if (cmd->base.phy_address != phydev->mdio.addr)
                return -EINVAL;
 
-       ethtool_convert_link_mode_to_legacy_u32(&advertising,
-                                               cmd->link_modes.advertising);
+       linkmode_copy(advertising, cmd->link_modes.advertising);
 
        /* We make sure that we don't pass unsupported values in to the PHY */
-       advertising &= phydev->supported;
+       linkmode_and(advertising, advertising, phydev->supported);
 
        /* Verify the settings we care about. */
        if (autoneg != AUTONEG_ENABLE && autoneg != AUTONEG_DISABLE)
@@ -345,12 +343,14 @@ int phy_ethtool_ksettings_set(struct phy_device *phydev,
 
        phydev->speed = speed;
 
-       phydev->advertising = advertising;
+       linkmode_copy(phydev->advertising, advertising);
 
        if (autoneg == AUTONEG_ENABLE)
-               phydev->advertising |= ADVERTISED_Autoneg;
+               linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
+                                phydev->advertising);
        else
-               phydev->advertising &= ~ADVERTISED_Autoneg;
+               linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
+                                  phydev->advertising);
 
        phydev->duplex = duplex;
 
@@ -366,11 +366,8 @@ EXPORT_SYMBOL(phy_ethtool_ksettings_set);
 void phy_ethtool_ksettings_get(struct phy_device *phydev,
                               struct ethtool_link_ksettings *cmd)
 {
-       ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
-                                               phydev->supported);
-
-       ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising,
-                                               phydev->advertising);
+       linkmode_copy(cmd->link_modes.supported, phydev->supported);
+       linkmode_copy(cmd->link_modes.advertising, phydev->advertising);
 
        ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.lp_advertising,
                                                phydev->lp_advertising);
@@ -442,7 +439,8 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd)
                                }
                                break;
                        case MII_ADVERTISE:
-                               phydev->advertising = mii_adv_to_ethtool_adv_t(val);
+                               mii_adv_to_linkmode_adv_t(phydev->advertising,
+                                                         val);
                                change_autoneg = true;
                                break;
                        default:
@@ -604,20 +602,38 @@ static int phy_poll_aneg_done(struct phy_device *phydev)
  */
 int phy_speed_down(struct phy_device *phydev, bool sync)
 {
-       u32 adv = phydev->lp_advertising & phydev->supported;
-       u32 adv_old = phydev->advertising;
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(adv_old);
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(adv);
        int ret;
 
        if (phydev->autoneg != AUTONEG_ENABLE)
                return 0;
 
-       if (adv & PHY_10BT_FEATURES)
-               phydev->advertising &= ~(PHY_100BT_FEATURES |
-                                        PHY_1000BT_FEATURES);
-       else if (adv & PHY_100BT_FEATURES)
-               phydev->advertising &= ~PHY_1000BT_FEATURES;
+       linkmode_copy(adv_old, phydev->advertising);
+       ethtool_convert_legacy_u32_to_link_mode(adv, phydev->lp_advertising);
+       linkmode_and(adv, adv, phydev->supported);
+
+       if (linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, adv) ||
+           linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, adv)) {
+               linkmode_clear_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
+                                  phydev->advertising);
+               linkmode_clear_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+                                  phydev->advertising);
+               linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
+                                  phydev->advertising);
+               linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+                                  phydev->advertising);
+       } else if (linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
+                                    adv) ||
+                  linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+                                    adv)) {
+               linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
+                                  phydev->advertising);
+               linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+                                  phydev->advertising);
+       }
 
-       if (phydev->advertising == adv_old)
+       if (linkmode_equal(phydev->advertising, adv_old))
                return 0;
 
        ret = phy_config_aneg(phydev);
@@ -636,15 +652,30 @@ EXPORT_SYMBOL_GPL(phy_speed_down);
  */
 int phy_speed_up(struct phy_device *phydev)
 {
-       u32 mask = PHY_10BT_FEATURES | PHY_100BT_FEATURES | PHY_1000BT_FEATURES;
-       u32 adv_old = phydev->advertising;
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(all_speeds) = { 0, };
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(not_speeds);
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(adv_old);
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(speeds);
+
+       linkmode_copy(adv_old, phydev->advertising);
 
        if (phydev->autoneg != AUTONEG_ENABLE)
                return 0;
 
-       phydev->advertising = (adv_old & ~mask) | (phydev->supported & mask);
+       linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, all_speeds);
+       linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, all_speeds);
+       linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, all_speeds);
+       linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, all_speeds);
+       linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, all_speeds);
+       linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, all_speeds);
 
-       if (phydev->advertising == adv_old)
+       linkmode_andnot(not_speeds, adv_old, all_speeds);
+       linkmode_copy(supported, phydev->supported);
+       linkmode_and(speeds, supported, all_speeds);
+       linkmode_or(phydev->advertising, not_speeds, speeds);
+
+       if (linkmode_equal(phydev->advertising, adv_old))
                return 0;
 
        return phy_config_aneg(phydev);
@@ -973,6 +1004,30 @@ void phy_mac_interrupt(struct phy_device *phydev)
 }
 EXPORT_SYMBOL(phy_mac_interrupt);
 
+static void mmd_eee_adv_to_linkmode(unsigned long *advertising, u16 eee_adv)
+{
+       linkmode_zero(advertising);
+
+       if (eee_adv & MDIO_EEE_100TX)
+               linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+                                advertising);
+       if (eee_adv & MDIO_EEE_1000T)
+               linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+                                advertising);
+       if (eee_adv & MDIO_EEE_10GT)
+               linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
+                                advertising);
+       if (eee_adv & MDIO_EEE_1000KX)
+               linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
+                                advertising);
+       if (eee_adv & MDIO_EEE_10GKX4)
+               linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
+                                advertising);
+       if (eee_adv & MDIO_EEE_10GKR)
+               linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
+                                advertising);
+}
+
 /**
  * phy_init_eee - init and check the EEE feature
  * @phydev: target phy_device struct
@@ -991,9 +1046,12 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
        /* According to 802.3az,the EEE is supported only in full duplex-mode.
         */
        if (phydev->duplex == DUPLEX_FULL) {
+               __ETHTOOL_DECLARE_LINK_MODE_MASK(common);
+               __ETHTOOL_DECLARE_LINK_MODE_MASK(lp);
+               __ETHTOOL_DECLARE_LINK_MODE_MASK(adv);
                int eee_lp, eee_cap, eee_adv;
-               u32 lp, cap, adv;
                int status;
+               u32 cap;
 
                /* Read phy status to properly get the right settings */
                status = phy_read_status(phydev);
@@ -1020,9 +1078,11 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
                if (eee_adv <= 0)
                        goto eee_exit_err;
 
-               adv = mmd_eee_adv_to_ethtool_adv_t(eee_adv);
-               lp = mmd_eee_adv_to_ethtool_adv_t(eee_lp);
-               if (!phy_check_valid(phydev->speed, phydev->duplex, lp & adv))
+               mmd_eee_adv_to_linkmode(adv, eee_adv);
+               mmd_eee_adv_to_linkmode(lp, eee_lp);
+               linkmode_and(common, adv, lp);
+
+               if (!phy_check_valid(phydev->speed, phydev->duplex, common))
                        goto eee_exit_err;
 
                if (clk_stop_enable) {
index 0f56d408b0332595bed1cfd7291e053c0e4f2f38..09a1c2d835b2ac0989e083517d10670f411565aa 100644 (file)
@@ -66,10 +66,12 @@ static const int phy_basic_ports_array[] = {
        ETHTOOL_LINK_MODE_TP_BIT,
        ETHTOOL_LINK_MODE_MII_BIT,
 };
+EXPORT_SYMBOL_GPL(phy_basic_ports_array);
 
 static const int phy_fibre_port_array[] = {
        ETHTOOL_LINK_MODE_FIBRE_BIT,
 };
+EXPORT_SYMBOL_GPL(phy_fibre_port_array);
 
 static const int phy_all_ports_features_array[] = {
        ETHTOOL_LINK_MODE_Autoneg_BIT,
@@ -80,27 +82,32 @@ static const int phy_all_ports_features_array[] = {
        ETHTOOL_LINK_MODE_BNC_BIT,
        ETHTOOL_LINK_MODE_Backplane_BIT,
 };
+EXPORT_SYMBOL_GPL(phy_all_ports_features_array);
 
-static const int phy_10_100_features_array[] = {
+const int phy_10_100_features_array[4] = {
        ETHTOOL_LINK_MODE_10baseT_Half_BIT,
        ETHTOOL_LINK_MODE_10baseT_Full_BIT,
        ETHTOOL_LINK_MODE_100baseT_Half_BIT,
        ETHTOOL_LINK_MODE_100baseT_Full_BIT,
 };
+EXPORT_SYMBOL_GPL(phy_10_100_features_array);
 
-static const int phy_basic_t1_features_array[] = {
+const int phy_basic_t1_features_array[2] = {
        ETHTOOL_LINK_MODE_TP_BIT,
        ETHTOOL_LINK_MODE_100baseT_Full_BIT,
 };
+EXPORT_SYMBOL_GPL(phy_basic_t1_features_array);
 
-static const int phy_gbit_features_array[] = {
+const int phy_gbit_features_array[2] = {
        ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
        ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
 };
+EXPORT_SYMBOL_GPL(phy_gbit_features_array);
 
-static const int phy_10gbit_features_array[] = {
+const int phy_10gbit_features_array[1] = {
        ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
 };
+EXPORT_SYMBOL_GPL(phy_10gbit_features_array);
 
 __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_full_features) __ro_after_init;
 EXPORT_SYMBOL_GPL(phy_10gbit_full_features);
@@ -1441,8 +1448,13 @@ static int genphy_config_advert(struct phy_device *phydev)
        int err, changed = 0;
 
        /* Only allow advertising what this PHY supports */
-       phydev->advertising &= phydev->supported;
-       advertise = phydev->advertising;
+       linkmode_and(phydev->advertising, phydev->advertising,
+                    phydev->supported);
+       if (!ethtool_convert_link_mode_to_legacy_u32(&advertise,
+                                                    phydev->advertising))
+               phydev_warn(phydev, "PHY advertising (%*pb) more modes than genphy supports, some modes not advertised.\n",
+                           __ETHTOOL_LINK_MODE_MASK_NBITS,
+                           phydev->advertising);
 
        /* Setup standard advertisement */
        adv = phy_read(phydev, MII_ADVERTISE);
@@ -1481,10 +1493,11 @@ static int genphy_config_advert(struct phy_device *phydev)
        oldadv = adv;
        adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
 
-       if (phydev->supported & (SUPPORTED_1000baseT_Half |
-                                SUPPORTED_1000baseT_Full)) {
+       if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
+                             phydev->supported) ||
+           linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+                             phydev->supported))
                adv |= ethtool_adv_to_mii_ctrl1000_t(advertise);
-       }
 
        if (adv != oldadv)
                changed = 1;
@@ -1692,8 +1705,10 @@ int genphy_read_status(struct phy_device *phydev)
        phydev->lp_advertising = 0;
 
        if (AUTONEG_ENABLE == phydev->autoneg) {
-               if (phydev->supported & (SUPPORTED_1000baseT_Half
-                                       | SUPPORTED_1000baseT_Full)) {
+               if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
+                                     phydev->supported) ||
+                   linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+                                     phydev->supported)) {
                        lpagb = phy_read(phydev, MII_STAT1000);
                        if (lpagb < 0)
                                return lpagb;
@@ -1800,11 +1815,13 @@ EXPORT_SYMBOL(genphy_soft_reset);
 int genphy_config_init(struct phy_device *phydev)
 {
        int val;
-       u32 features;
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(features) = { 0, };
 
-       features = (SUPPORTED_TP | SUPPORTED_MII
-                       | SUPPORTED_AUI | SUPPORTED_FIBRE |
-                       SUPPORTED_BNC | SUPPORTED_Pause | SUPPORTED_Asym_Pause);
+       linkmode_set_bit_array(phy_basic_ports_array,
+                              ARRAY_SIZE(phy_basic_ports_array),
+                              features);
+       linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, features);
+       linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, features);
 
        /* Do we support autonegotiation? */
        val = phy_read(phydev, MII_BMSR);
@@ -1812,16 +1829,16 @@ int genphy_config_init(struct phy_device *phydev)
                return val;
 
        if (val & BMSR_ANEGCAPABLE)
-               features |= SUPPORTED_Autoneg;
+               linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, features);
 
        if (val & BMSR_100FULL)
-               features |= SUPPORTED_100baseT_Full;
+               linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, features);
        if (val & BMSR_100HALF)
-               features |= SUPPORTED_100baseT_Half;
+               linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, features);
        if (val & BMSR_10FULL)
-               features |= SUPPORTED_10baseT_Full;
+               linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, features);
        if (val & BMSR_10HALF)
-               features |= SUPPORTED_10baseT_Half;
+               linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, features);
 
        if (val & BMSR_ESTATEN) {
                val = phy_read(phydev, MII_ESTATUS);
@@ -1829,13 +1846,15 @@ int genphy_config_init(struct phy_device *phydev)
                        return val;
 
                if (val & ESTATUS_1000_TFULL)
-                       features |= SUPPORTED_1000baseT_Full;
+                       linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+                                        features);
                if (val & ESTATUS_1000_THALF)
-                       features |= SUPPORTED_1000baseT_Half;
+                       linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
+                                        features);
        }
 
-       phydev->supported &= features;
-       phydev->advertising &= features;
+       linkmode_and(phydev->supported, phydev->supported, features);
+       linkmode_and(phydev->advertising, phydev->advertising, features);
 
        return 0;
 }
@@ -1879,20 +1898,37 @@ EXPORT_SYMBOL(genphy_loopback);
 
 static int __set_phy_supported(struct phy_device *phydev, u32 max_speed)
 {
-       phydev->supported &= ~(PHY_1000BT_FEATURES | PHY_100BT_FEATURES |
-                              PHY_10BT_FEATURES);
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(speeds) = { 0, };
+
+       linkmode_set_bit_array(phy_10_100_features_array,
+                              ARRAY_SIZE(phy_10_100_features_array),
+                              speeds);
+       linkmode_set_bit_array(phy_gbit_features_array,
+                              ARRAY_SIZE(phy_gbit_features_array),
+                              speeds);
+
+       linkmode_andnot(phydev->supported, phydev->supported, speeds);
 
        switch (max_speed) {
        default:
                return -ENOTSUPP;
        case SPEED_1000:
-               phydev->supported |= PHY_1000BT_FEATURES;
+               linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
+                                phydev->supported);
+               linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+                                phydev->supported);
                /* fall through */
        case SPEED_100:
-               phydev->supported |= PHY_100BT_FEATURES;
+               linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
+                                phydev->supported);
+               linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+                                phydev->supported);
                /* fall through */
        case SPEED_10:
-               phydev->supported |= PHY_10BT_FEATURES;
+               linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
+                                phydev->supported);
+               linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
+                                phydev->supported);
        }
 
        return 0;
@@ -1906,7 +1942,7 @@ int phy_set_max_speed(struct phy_device *phydev, u32 max_speed)
        if (err)
                return err;
 
-       phydev->advertising = phydev->supported;
+       linkmode_copy(phydev->advertising, phydev->supported);
 
        return 0;
 }
@@ -1923,10 +1959,8 @@ EXPORT_SYMBOL(phy_set_max_speed);
  */
 void phy_remove_link_mode(struct phy_device *phydev, u32 link_mode)
 {
-       WARN_ON(link_mode > 31);
-
-       phydev->supported &= ~BIT(link_mode);
-       phydev->advertising = phydev->supported;
+       linkmode_clear_bit(link_mode, phydev->supported);
+       linkmode_copy(phydev->advertising, phydev->supported);
 }
 EXPORT_SYMBOL(phy_remove_link_mode);
 
@@ -1939,9 +1973,9 @@ EXPORT_SYMBOL(phy_remove_link_mode);
  */
 void phy_support_sym_pause(struct phy_device *phydev)
 {
-       phydev->supported &= ~SUPPORTED_Asym_Pause;
-       phydev->supported |= SUPPORTED_Pause;
-       phydev->advertising = phydev->supported;
+       linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydev->supported);
+       linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->supported);
+       linkmode_copy(phydev->advertising, phydev->supported);
 }
 EXPORT_SYMBOL(phy_support_sym_pause);
 
@@ -1953,8 +1987,9 @@ EXPORT_SYMBOL(phy_support_sym_pause);
  */
 void phy_support_asym_pause(struct phy_device *phydev)
 {
-       phydev->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
-       phydev->advertising = phydev->supported;
+       linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->supported);
+       linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydev->supported);
+       linkmode_copy(phydev->advertising, phydev->supported);
 }
 EXPORT_SYMBOL(phy_support_asym_pause);
 
@@ -1972,12 +2007,13 @@ EXPORT_SYMBOL(phy_support_asym_pause);
 void phy_set_sym_pause(struct phy_device *phydev, bool rx, bool tx,
                       bool autoneg)
 {
-       phydev->supported &= ~SUPPORTED_Pause;
+       linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->supported);
 
        if (rx && tx && autoneg)
-               phydev->supported |= SUPPORTED_Pause;
+               linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT,
+                                phydev->supported);
 
-       phydev->advertising = phydev->supported;
+       linkmode_copy(phydev->advertising, phydev->supported);
 }
 EXPORT_SYMBOL(phy_set_sym_pause);
 
@@ -1994,20 +2030,29 @@ EXPORT_SYMBOL(phy_set_sym_pause);
  */
 void phy_set_asym_pause(struct phy_device *phydev, bool rx, bool tx)
 {
-       u16 oldadv = phydev->advertising;
-       u16 newadv = oldadv &= ~(SUPPORTED_Pause | SUPPORTED_Asym_Pause);
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(oldadv);
 
-       if (rx)
-               newadv |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
-       if (tx)
-               newadv ^= SUPPORTED_Asym_Pause;
+       linkmode_copy(oldadv, phydev->advertising);
 
-       if (oldadv != newadv) {
-               phydev->advertising = newadv;
+       linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT,
+                          phydev->advertising);
+       linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
+                          phydev->advertising);
 
-               if (phydev->autoneg)
-                       phy_start_aneg(phydev);
+       if (rx) {
+               linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT,
+                                phydev->advertising);
+               linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
+                                phydev->advertising);
        }
+
+       if (tx)
+               linkmode_change_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
+                                   phydev->advertising);
+
+       if (!linkmode_equal(oldadv, phydev->advertising) &&
+           phydev->autoneg)
+               phy_start_aneg(phydev);
 }
 EXPORT_SYMBOL(phy_set_asym_pause);
 
@@ -2023,8 +2068,10 @@ EXPORT_SYMBOL(phy_set_asym_pause);
 bool phy_validate_pause(struct phy_device *phydev,
                        struct ethtool_pauseparam *pp)
 {
-       if (!(phydev->supported & SUPPORTED_Pause) ||
-           (!(phydev->supported & SUPPORTED_Asym_Pause) &&
+       if (!linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
+                              phydev->supported) ||
+           (!linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
+                               phydev->supported) &&
             pp->rx_pause != pp->tx_pause))
                return false;
        return true;
@@ -2112,9 +2159,9 @@ static int phy_probe(struct device *dev)
         * or both of these values
         */
        ethtool_convert_link_mode_to_legacy_u32(&features, phydrv->features);
-       phydev->supported = features;
+       linkmode_copy(phydev->supported, phydrv->features);
        of_set_phy_supported(phydev);
-       phydev->advertising = phydev->supported;
+       linkmode_copy(phydev->advertising, phydev->supported);
 
        /* Get the EEE modes we want to prohibit. We will ask
         * the PHY stop advertising these mode later on
@@ -2134,14 +2181,22 @@ static int phy_probe(struct device *dev)
         */
        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);
+               linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT,
+                                  phydev->supported);
+               linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
+                                  phydev->supported);
                if (test_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydrv->features))
-                       phydev->supported |= SUPPORTED_Pause;
+                       linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT,
+                                        phydev->supported);
                if (test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
                             phydrv->features))
-                       phydev->supported |= SUPPORTED_Asym_Pause;
+                       linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
+                                        phydev->supported);
        } else {
-               phydev->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
+               linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT,
+                                phydev->supported);
+               linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
+                                phydev->supported);
        }
 
        /* Set the state to READY by default */
index 9b8dd0d0ee42ce0ec35ba6a0add122bc6aadb8a4..e7becc7379d74899c5d007bc0e7789aeb953fc6e 100644 (file)
@@ -191,8 +191,7 @@ static int phylink_parse_fixedlink(struct phylink *pl,
        phylink_validate(pl, pl->supported, &pl->link_config);
 
        s = phy_lookup_setting(pl->link_config.speed, pl->link_config.duplex,
-                              pl->supported,
-                              __ETHTOOL_LINK_MODE_MASK_NBITS, true);
+                              pl->supported, true);
        linkmode_zero(pl->supported);
        phylink_set(pl->supported, MII);
        if (s) {
@@ -634,13 +633,11 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy)
 {
        struct phylink_link_state config;
        __ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
-       u32 advertising;
        int ret;
 
        memset(&config, 0, sizeof(config));
-       ethtool_convert_legacy_u32_to_link_mode(supported, phy->supported);
-       ethtool_convert_legacy_u32_to_link_mode(config.advertising,
-                                               phy->advertising);
+       linkmode_copy(supported, phy->supported);
+       linkmode_copy(config.advertising, phy->advertising);
        config.interface = pl->link_config.interface;
 
        /*
@@ -673,15 +670,14 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy)
        linkmode_copy(pl->link_config.advertising, config.advertising);
 
        /* Restrict the phy advertisement according to the MAC support. */
-       ethtool_convert_link_mode_to_legacy_u32(&advertising, config.advertising);
-       phy->advertising = advertising;
+       linkmode_copy(phy->advertising, config.advertising);
        mutex_unlock(&pl->state_mutex);
        mutex_unlock(&phy->lock);
 
        netdev_dbg(pl->netdev,
-                  "phy: setting supported %*pb advertising 0x%08x\n",
+                  "phy: setting supported %*pb advertising %*pb\n",
                   __ETHTOOL_LINK_MODE_MASK_NBITS, pl->supported,
-                  phy->advertising);
+                  __ETHTOOL_LINK_MODE_MASK_NBITS, phy->advertising);
 
        phy_start_machine(phy);
        if (phy->irq > 0)
@@ -1088,8 +1084,7 @@ int phylink_ethtool_ksettings_set(struct phylink *pl,
                 * duplex.
                 */
                s = phy_lookup_setting(kset->base.speed, kset->base.duplex,
-                                      pl->supported,
-                                      __ETHTOOL_LINK_MODE_MASK_NBITS, false);
+                                      pl->supported, false);
                if (!s)
                        return -EINVAL;
 
index be1917be28f2d457c561a117ea92dd49c7f62d50..3c8bdac78866c08b2185ec62ae56ce9057ab0baa 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/slab.h>
 #include <linux/if_vlan.h>
 #include <linux/uaccess.h>
+#include <linux/linkmode.h>
 #include <linux/list.h>
 #include <linux/ip.h>
 #include <linux/ipv6.h>
@@ -1586,18 +1587,17 @@ static int lan78xx_set_pause(struct net_device *net,
                dev->fc_request_control |= FLOW_CTRL_TX;
 
        if (ecmd.base.autoneg) {
+               __ETHTOOL_DECLARE_LINK_MODE_MASK(fc) = { 0, };
                u32 mii_adv;
-               u32 advertising;
 
-               ethtool_convert_link_mode_to_legacy_u32(
-                       &advertising, ecmd.link_modes.advertising);
-
-               advertising &= ~(ADVERTISED_Pause | ADVERTISED_Asym_Pause);
+               linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT,
+                                  ecmd.link_modes.advertising);
+               linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
+                                  ecmd.link_modes.advertising);
                mii_adv = (u32)mii_advertise_flowctrl(dev->fc_request_control);
-               advertising |= mii_adv_to_ethtool_adv_t(mii_adv);
-
-               ethtool_convert_legacy_u32_to_link_mode(
-                       ecmd.link_modes.advertising, advertising);
+               mii_adv_to_linkmode_adv_t(fc, mii_adv);
+               linkmode_or(ecmd.link_modes.advertising, fc,
+                           ecmd.link_modes.advertising);
 
                phy_ethtool_ksettings_set(phydev, &ecmd);
        }
@@ -2095,6 +2095,7 @@ static struct phy_device *lan7801_phy_init(struct lan78xx_net *dev)
 
 static int lan78xx_phy_init(struct lan78xx_net *dev)
 {
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(fc) = { 0, };
        int ret;
        u32 mii_adv;
        struct phy_device *phydev;
@@ -2158,9 +2159,13 @@ static int lan78xx_phy_init(struct lan78xx_net *dev)
 
        /* support both flow controls */
        dev->fc_request_control = (FLOW_CTRL_RX | FLOW_CTRL_TX);
-       phydev->advertising &= ~(ADVERTISED_Pause | ADVERTISED_Asym_Pause);
+       linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT,
+                          phydev->advertising);
+       linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
+                          phydev->advertising);
        mii_adv = (u32)mii_advertise_flowctrl(dev->fc_request_control);
-       phydev->advertising |= mii_adv_to_ethtool_adv_t(mii_adv);
+       mii_adv_to_linkmode_adv_t(fc, mii_adv);
+       linkmode_or(phydev->advertising, fc, phydev->advertising);
 
        if (phydev->mdio.dev.of_node) {
                u32 reg;
index 2da85b02e1c0655cc7e45e4feb9687bd2127c21b..aaa458bbef2a7415a004357eea1d931f14413c84 100644 (file)
@@ -385,19 +385,21 @@ static inline void mii_adv_to_linkmode_adv_t(unsigned long *advertising,
 }
 
 /**
- * ethtool_adv_to_lcl_adv_t
- * @advertising:pointer to ethtool advertising
+ * linkmode_adv_to_lcl_adv_t
+ * @advertising:pointer to linkmode advertising
  *
- * A small helper function that translates ethtool advertising to LVL
+ * A small helper function that translates linkmode advertising to LVL
  * pause capabilities.
  */
-static inline u32 ethtool_adv_to_lcl_adv_t(u32 advertising)
+static inline u32 linkmode_adv_to_lcl_adv_t(unsigned long *advertising)
 {
        u32 lcl_adv = 0;
 
-       if (advertising & ADVERTISED_Pause)
+       if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
+                             advertising))
                lcl_adv |= ADVERTISE_PAUSE_CAP;
-       if (advertising & ADVERTISED_Asym_Pause)
+       if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
+                             advertising))
                lcl_adv |= ADVERTISE_PAUSE_ASYM;
 
        return lcl_adv;
index a5bcb4aaa48ea07d761715229c153127c680f1da..cbc66ac3b560944e0fc6b4622be0c9be51e13259 100644 (file)
@@ -58,6 +58,11 @@ extern __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_full_features) __ro_after_ini
 #define PHY_10GBIT_FEATURES ((unsigned long *)&phy_10gbit_features)
 #define PHY_10GBIT_FULL_FEATURES ((unsigned long *)&phy_10gbit_full_features)
 
+extern const int phy_10_100_features_array[4];
+extern const int phy_basic_t1_features_array[2];
+extern const int phy_gbit_features_array[2];
+extern const int phy_10gbit_features_array[1];
+
 /*
  * Set phydev->irq to PHY_POLL if interrupts are not supported,
  * or not desired for this PHY.  Set to PHY_IGNORE_INTERRUPT if
@@ -405,10 +410,11 @@ struct phy_device {
        int pause;
        int asym_pause;
 
-       /* Union of PHY and Attached devices' supported modes */
-       /* See mii.h for more info */
-       u32 supported;
-       u32 advertising;
+       /* Union of PHY and Attached devices' supported link modes */
+       /* See ethtool.h for more info */
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising);
+
        u32 lp_advertising;
 
        /* Energy efficient ethernet modes which should be prohibited */
@@ -660,9 +666,9 @@ struct phy_setting {
 
 const struct phy_setting *
 phy_lookup_setting(int speed, int duplex, const unsigned long *mask,
-                  size_t maxbit, bool exact);
+                  bool exact);
 size_t phy_speeds(unsigned int *speeds, size_t size,
-                 unsigned long *mask, size_t maxbit);
+                 unsigned long *mask);
 
 void phy_resolve_aneg_linkmode(struct phy_device *phydev);