Skip to content

Commit

Permalink
net: ethernet: Convert phydev advertize and supported from u32 to lin…
Browse files Browse the repository at this point in the history
…k mode

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>
  • Loading branch information
Andrew Lunn authored and David S. Miller committed Nov 11, 2018
1 parent 899a3cb commit 3c1bcc8
Show file tree
Hide file tree
Showing 39 changed files with 536 additions and 330 deletions.
3 changes: 2 additions & 1 deletion drivers/net/dsa/mt7530.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/aeroflex/greth.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
41 changes: 24 additions & 17 deletions drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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,
Expand All @@ -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;
Expand Down Expand Up @@ -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,
Expand All @@ -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 */
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand Down
22 changes: 12 additions & 10 deletions drivers/net/ethernet/apm/xgene-v2/mdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/ethernet/arc/emac_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
12 changes: 7 additions & 5 deletions drivers/net/ethernet/broadcom/b44.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
5 changes: 3 additions & 2 deletions drivers/net/ethernet/broadcom/genet/bcmmii.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
44 changes: 27 additions & 17 deletions drivers/net/ethernet/broadcom/tg3.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);

Expand All @@ -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;
Expand Down
7 changes: 5 additions & 2 deletions drivers/net/ethernet/cavium/octeon/octeon_mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 4 additions & 1 deletion drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/freescale/fman/mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
18 changes: 12 additions & 6 deletions drivers/net/ethernet/freescale/gianfar.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
7 changes: 1 addition & 6 deletions drivers/net/ethernet/freescale/ucc_geth.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
Loading

0 comments on commit 3c1bcc8

Please sign in to comment.