summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/dsa/microchip/ksz8.h6
-rw-r--r--drivers/net/dsa/microchip/ksz8795.c10
-rw-r--r--drivers/net/dsa/microchip/ksz_common.c121
-rw-r--r--drivers/net/dsa/microchip/ksz_common.h5
-rw-r--r--drivers/net/dsa/mt7530.c2
-rw-r--r--drivers/net/dsa/xrs700x/xrs700x.c1
-rw-r--r--drivers/net/ethernet/marvell/mvneta.c6
-rw-r--r--drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c25
-rw-r--r--drivers/net/pcs/pcs-rzn1-miic.c3
-rw-r--r--drivers/net/pcs/pcs-xpcs.c3
-rw-r--r--drivers/net/phy/bcm84881.c2
-rw-r--r--drivers/net/phy/marvell.c2
-rw-r--r--drivers/net/phy/phylink.c557
-rw-r--r--drivers/net/phy/sfp-bus.c5
-rw-r--r--include/linux/phy.h12
-rw-r--r--include/linux/phylink.h8
-rw-r--r--include/linux/sfp.h4
17 files changed, 442 insertions, 330 deletions
diff --git a/drivers/net/dsa/microchip/ksz8.h b/drivers/net/dsa/microchip/ksz8.h
index 1a5225264e6a..719692c8c858 100644
--- a/drivers/net/dsa/microchip/ksz8.h
+++ b/drivers/net/dsa/microchip/ksz8.h
@@ -56,9 +56,9 @@ int ksz8_reset_switch(struct ksz_device *dev);
int ksz8_switch_init(struct ksz_device *dev);
void ksz8_switch_exit(struct ksz_device *dev);
int ksz8_change_mtu(struct ksz_device *dev, int port, int mtu);
-void ksz8_phylink_mac_link_up(struct ksz_device *dev, int port,
- unsigned int mode, phy_interface_t interface,
- struct phy_device *phydev, int speed, int duplex,
+void ksz8_phylink_mac_link_up(struct phylink_config *config,
+ struct phy_device *phydev, unsigned int mode,
+ phy_interface_t interface, int speed, int duplex,
bool tx_pause, bool rx_pause);
#endif
diff --git a/drivers/net/dsa/microchip/ksz8795.c b/drivers/net/dsa/microchip/ksz8795.c
index c3da97abce20..0fd09b91b661 100644
--- a/drivers/net/dsa/microchip/ksz8795.c
+++ b/drivers/net/dsa/microchip/ksz8795.c
@@ -1563,11 +1563,15 @@ static void ksz8_cpu_port_link_up(struct ksz_device *dev, int speed, int duplex,
SW_10_MBIT, ctrl);
}
-void ksz8_phylink_mac_link_up(struct ksz_device *dev, int port,
- unsigned int mode, phy_interface_t interface,
- struct phy_device *phydev, int speed, int duplex,
+void ksz8_phylink_mac_link_up(struct phylink_config *config,
+ struct phy_device *phydev, unsigned int mode,
+ phy_interface_t interface, int speed, int duplex,
bool tx_pause, bool rx_pause)
{
+ struct dsa_port *dp = dsa_phylink_to_port(config);
+ struct ksz_device *dev = dp->ds->priv;
+ int port = dp->index;
+
/* If the port is the CPU port, apply special handling. Only the CPU
* port is configured via global registers.
*/
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 245dfb7a7a31..73a133c4f02d 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -253,6 +253,28 @@ static const struct ksz_drive_strength ksz8830_drive_strengths[] = {
{ KSZ8873_DRIVE_STRENGTH_16MA, 16000 },
};
+static void ksz8830_phylink_mac_config(struct phylink_config *config,
+ unsigned int mode,
+ const struct phylink_link_state *state);
+static void ksz_phylink_mac_config(struct phylink_config *config,
+ unsigned int mode,
+ const struct phylink_link_state *state);
+static void ksz_phylink_mac_link_down(struct phylink_config *config,
+ unsigned int mode,
+ phy_interface_t interface);
+
+static const struct phylink_mac_ops ksz8830_phylink_mac_ops = {
+ .mac_config = ksz8830_phylink_mac_config,
+ .mac_link_down = ksz_phylink_mac_link_down,
+ .mac_link_up = ksz8_phylink_mac_link_up,
+};
+
+static const struct phylink_mac_ops ksz8_phylink_mac_ops = {
+ .mac_config = ksz_phylink_mac_config,
+ .mac_link_down = ksz_phylink_mac_link_down,
+ .mac_link_up = ksz8_phylink_mac_link_up,
+};
+
static const struct ksz_dev_ops ksz8_dev_ops = {
.setup = ksz8_setup,
.get_port_addr = ksz8_get_port_addr,
@@ -277,7 +299,6 @@ static const struct ksz_dev_ops ksz8_dev_ops = {
.mirror_add = ksz8_port_mirror_add,
.mirror_del = ksz8_port_mirror_del,
.get_caps = ksz8_get_caps,
- .phylink_mac_link_up = ksz8_phylink_mac_link_up,
.config_cpu_port = ksz8_config_cpu_port,
.enable_stp_addr = ksz8_enable_stp_addr,
.reset = ksz8_reset_switch,
@@ -286,13 +307,19 @@ static const struct ksz_dev_ops ksz8_dev_ops = {
.change_mtu = ksz8_change_mtu,
};
-static void ksz9477_phylink_mac_link_up(struct ksz_device *dev, int port,
+static void ksz9477_phylink_mac_link_up(struct phylink_config *config,
+ struct phy_device *phydev,
unsigned int mode,
phy_interface_t interface,
- struct phy_device *phydev, int speed,
- int duplex, bool tx_pause,
+ int speed, int duplex, bool tx_pause,
bool rx_pause);
+static const struct phylink_mac_ops ksz9477_phylink_mac_ops = {
+ .mac_config = ksz_phylink_mac_config,
+ .mac_link_down = ksz_phylink_mac_link_down,
+ .mac_link_up = ksz9477_phylink_mac_link_up,
+};
+
static const struct ksz_dev_ops ksz9477_dev_ops = {
.setup = ksz9477_setup,
.get_port_addr = ksz9477_get_port_addr,
@@ -319,7 +346,6 @@ static const struct ksz_dev_ops ksz9477_dev_ops = {
.mdb_add = ksz9477_mdb_add,
.mdb_del = ksz9477_mdb_del,
.change_mtu = ksz9477_change_mtu,
- .phylink_mac_link_up = ksz9477_phylink_mac_link_up,
.get_wol = ksz9477_get_wol,
.set_wol = ksz9477_set_wol,
.wol_pre_shutdown = ksz9477_wol_pre_shutdown,
@@ -331,6 +357,12 @@ static const struct ksz_dev_ops ksz9477_dev_ops = {
.exit = ksz9477_switch_exit,
};
+static const struct phylink_mac_ops lan937x_phylink_mac_ops = {
+ .mac_config = ksz_phylink_mac_config,
+ .mac_link_down = ksz_phylink_mac_link_down,
+ .mac_link_up = ksz9477_phylink_mac_link_up,
+};
+
static const struct ksz_dev_ops lan937x_dev_ops = {
.setup = lan937x_setup,
.teardown = lan937x_teardown,
@@ -359,7 +391,6 @@ static const struct ksz_dev_ops lan937x_dev_ops = {
.mdb_add = ksz9477_mdb_add,
.mdb_del = ksz9477_mdb_del,
.change_mtu = lan937x_change_mtu,
- .phylink_mac_link_up = ksz9477_phylink_mac_link_up,
.config_cpu_port = lan937x_config_cpu_port,
.tc_cbs_set_cinc = lan937x_tc_cbs_set_cinc,
.enable_stp_addr = ksz9477_enable_stp_addr,
@@ -1197,6 +1228,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
.tc_cbs_supported = true,
.tc_ets_supported = true,
.ops = &ksz9477_dev_ops,
+ .phylink_mac_ops = &ksz9477_phylink_mac_ops,
.mib_names = ksz9477_mib_names,
.mib_cnt = ARRAY_SIZE(ksz9477_mib_names),
.reg_mib_cnt = MIB_COUNTER_NUM,
@@ -1224,6 +1256,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
.port_cnt = 5, /* total cpu and user ports */
.num_tx_queues = 4,
.ops = &ksz8_dev_ops,
+ .phylink_mac_ops = &ksz8_phylink_mac_ops,
.ksz87xx_eee_link_erratum = true,
.mib_names = ksz9477_mib_names,
.mib_cnt = ARRAY_SIZE(ksz9477_mib_names),
@@ -1263,6 +1296,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
.port_cnt = 5, /* total cpu and user ports */
.num_tx_queues = 4,
.ops = &ksz8_dev_ops,
+ .phylink_mac_ops = &ksz8_phylink_mac_ops,
.ksz87xx_eee_link_erratum = true,
.mib_names = ksz9477_mib_names,
.mib_cnt = ARRAY_SIZE(ksz9477_mib_names),
@@ -1288,6 +1322,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
.port_cnt = 5, /* total cpu and user ports */
.num_tx_queues = 4,
.ops = &ksz8_dev_ops,
+ .phylink_mac_ops = &ksz8_phylink_mac_ops,
.ksz87xx_eee_link_erratum = true,
.mib_names = ksz9477_mib_names,
.mib_cnt = ARRAY_SIZE(ksz9477_mib_names),
@@ -1313,6 +1348,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
.port_cnt = 3,
.num_tx_queues = 4,
.ops = &ksz8_dev_ops,
+ .phylink_mac_ops = &ksz8830_phylink_mac_ops,
.mib_names = ksz88xx_mib_names,
.mib_cnt = ARRAY_SIZE(ksz88xx_mib_names),
.reg_mib_cnt = MIB_COUNTER_NUM,
@@ -1339,6 +1375,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
.tc_cbs_supported = true,
.tc_ets_supported = true,
.ops = &ksz9477_dev_ops,
+ .phylink_mac_ops = &ksz9477_phylink_mac_ops,
.mib_names = ksz9477_mib_names,
.mib_cnt = ARRAY_SIZE(ksz9477_mib_names),
.reg_mib_cnt = MIB_COUNTER_NUM,
@@ -1371,6 +1408,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
.port_nirqs = 2,
.num_tx_queues = 4,
.ops = &ksz9477_dev_ops,
+ .phylink_mac_ops = &ksz9477_phylink_mac_ops,
.mib_names = ksz9477_mib_names,
.mib_cnt = ARRAY_SIZE(ksz9477_mib_names),
.reg_mib_cnt = MIB_COUNTER_NUM,
@@ -1403,6 +1441,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
.port_nirqs = 2,
.num_tx_queues = 4,
.ops = &ksz9477_dev_ops,
+ .phylink_mac_ops = &ksz9477_phylink_mac_ops,
.mib_names = ksz9477_mib_names,
.mib_cnt = ARRAY_SIZE(ksz9477_mib_names),
.reg_mib_cnt = MIB_COUNTER_NUM,
@@ -1433,6 +1472,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
.port_nirqs = 2,
.num_tx_queues = 4,
.ops = &ksz9477_dev_ops,
+ .phylink_mac_ops = &ksz9477_phylink_mac_ops,
.mib_names = ksz9477_mib_names,
.mib_cnt = ARRAY_SIZE(ksz9477_mib_names),
.reg_mib_cnt = MIB_COUNTER_NUM,
@@ -1461,6 +1501,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
.tc_cbs_supported = true,
.tc_ets_supported = true,
.ops = &ksz9477_dev_ops,
+ .phylink_mac_ops = &ksz9477_phylink_mac_ops,
.mib_names = ksz9477_mib_names,
.mib_cnt = ARRAY_SIZE(ksz9477_mib_names),
.reg_mib_cnt = MIB_COUNTER_NUM,
@@ -1489,6 +1530,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
.tc_cbs_supported = true,
.tc_ets_supported = true,
.ops = &ksz9477_dev_ops,
+ .phylink_mac_ops = &ksz9477_phylink_mac_ops,
.mib_names = ksz9477_mib_names,
.mib_cnt = ARRAY_SIZE(ksz9477_mib_names),
.reg_mib_cnt = MIB_COUNTER_NUM,
@@ -1521,6 +1563,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
.tc_cbs_supported = true,
.tc_ets_supported = true,
.ops = &lan937x_dev_ops,
+ .phylink_mac_ops = &lan937x_phylink_mac_ops,
.mib_names = ksz9477_mib_names,
.mib_cnt = ARRAY_SIZE(ksz9477_mib_names),
.reg_mib_cnt = MIB_COUNTER_NUM,
@@ -1548,6 +1591,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
.tc_cbs_supported = true,
.tc_ets_supported = true,
.ops = &lan937x_dev_ops,
+ .phylink_mac_ops = &lan937x_phylink_mac_ops,
.mib_names = ksz9477_mib_names,
.mib_cnt = ARRAY_SIZE(ksz9477_mib_names),
.reg_mib_cnt = MIB_COUNTER_NUM,
@@ -1575,6 +1619,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
.tc_cbs_supported = true,
.tc_ets_supported = true,
.ops = &lan937x_dev_ops,
+ .phylink_mac_ops = &lan937x_phylink_mac_ops,
.mib_names = ksz9477_mib_names,
.mib_cnt = ARRAY_SIZE(ksz9477_mib_names),
.reg_mib_cnt = MIB_COUNTER_NUM,
@@ -1606,6 +1651,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
.tc_cbs_supported = true,
.tc_ets_supported = true,
.ops = &lan937x_dev_ops,
+ .phylink_mac_ops = &lan937x_phylink_mac_ops,
.mib_names = ksz9477_mib_names,
.mib_cnt = ARRAY_SIZE(ksz9477_mib_names),
.reg_mib_cnt = MIB_COUNTER_NUM,
@@ -1637,6 +1683,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
.tc_cbs_supported = true,
.tc_ets_supported = true,
.ops = &lan937x_dev_ops,
+ .phylink_mac_ops = &lan937x_phylink_mac_ops,
.mib_names = ksz9477_mib_names,
.mib_cnt = ARRAY_SIZE(ksz9477_mib_names),
.reg_mib_cnt = MIB_COUNTER_NUM,
@@ -2443,14 +2490,15 @@ static u32 ksz_get_phy_flags(struct dsa_switch *ds, int port)
return 0;
}
-static void ksz_mac_link_down(struct dsa_switch *ds, int port,
- unsigned int mode, phy_interface_t interface)
+static void ksz_phylink_mac_link_down(struct phylink_config *config,
+ unsigned int mode,
+ phy_interface_t interface)
{
- struct ksz_device *dev = ds->priv;
- struct ksz_port *p = &dev->ports[port];
+ struct dsa_port *dp = dsa_phylink_to_port(config);
+ struct ksz_device *dev = dp->ds->priv;
/* Read all MIB counters when the link is going down. */
- p->read = true;
+ dev->ports[dp->index].read = true;
/* timer started */
if (dev->mib_read_interval)
schedule_delayed_work(&dev->mib_read, 0);
@@ -2977,16 +3025,23 @@ phy_interface_t ksz_get_xmii(struct ksz_device *dev, int port, bool gbit)
return interface;
}
-static void ksz_phylink_mac_config(struct dsa_switch *ds, int port,
+static void ksz8830_phylink_mac_config(struct phylink_config *config,
+ unsigned int mode,
+ const struct phylink_link_state *state)
+{
+ struct dsa_port *dp = dsa_phylink_to_port(config);
+ struct ksz_device *dev = dp->ds->priv;
+
+ dev->ports[dp->index].manual_flow = !(state->pause & MLO_PAUSE_AN);
+}
+
+static void ksz_phylink_mac_config(struct phylink_config *config,
unsigned int mode,
const struct phylink_link_state *state)
{
- struct ksz_device *dev = ds->priv;
-
- if (ksz_is_ksz88x3(dev)) {
- dev->ports[port].manual_flow = !(state->pause & MLO_PAUSE_AN);
- return;
- }
+ struct dsa_port *dp = dsa_phylink_to_port(config);
+ struct ksz_device *dev = dp->ds->priv;
+ int port = dp->index;
/* Internal PHYs */
if (dev->info->internal_phy[port])
@@ -2999,9 +3054,6 @@ static void ksz_phylink_mac_config(struct dsa_switch *ds, int port,
ksz_set_xmii(dev, port, state->interface);
- if (dev->dev_ops->phylink_mac_config)
- dev->dev_ops->phylink_mac_config(dev, port, mode, state);
-
if (dev->dev_ops->setup_rgmii_delay)
dev->dev_ops->setup_rgmii_delay(dev, port);
}
@@ -3099,13 +3151,16 @@ static void ksz_duplex_flowctrl(struct ksz_device *dev, int port, int duplex,
ksz_prmw8(dev, port, regs[P_XMII_CTRL_0], mask, val);
}
-static void ksz9477_phylink_mac_link_up(struct ksz_device *dev, int port,
+static void ksz9477_phylink_mac_link_up(struct phylink_config *config,
+ struct phy_device *phydev,
unsigned int mode,
phy_interface_t interface,
- struct phy_device *phydev, int speed,
- int duplex, bool tx_pause,
+ int speed, int duplex, bool tx_pause,
bool rx_pause)
{
+ struct dsa_port *dp = dsa_phylink_to_port(config);
+ struct ksz_device *dev = dp->ds->priv;
+ int port = dp->index;
struct ksz_port *p;
p = &dev->ports[port];
@@ -3121,18 +3176,6 @@ static void ksz9477_phylink_mac_link_up(struct ksz_device *dev, int port,
ksz_duplex_flowctrl(dev, port, duplex, tx_pause, rx_pause);
}
-static void ksz_phylink_mac_link_up(struct dsa_switch *ds, int port,
- unsigned int mode,
- phy_interface_t interface,
- struct phy_device *phydev, int speed,
- int duplex, bool tx_pause, bool rx_pause)
-{
- struct ksz_device *dev = ds->priv;
-
- dev->dev_ops->phylink_mac_link_up(dev, port, mode, interface, phydev,
- speed, duplex, tx_pause, rx_pause);
-}
-
static int ksz_switch_detect(struct ksz_device *dev)
{
u8 id1, id2, id4;
@@ -3790,9 +3833,6 @@ static const struct dsa_switch_ops ksz_switch_ops = {
.phy_read = ksz_phy_read16,
.phy_write = ksz_phy_write16,
.phylink_get_caps = ksz_phylink_get_caps,
- .phylink_mac_config = ksz_phylink_mac_config,
- .phylink_mac_link_up = ksz_phylink_mac_link_up,
- .phylink_mac_link_down = ksz_mac_link_down,
.port_setup = ksz_port_setup,
.set_ageing_time = ksz_set_ageing_time,
.get_strings = ksz_get_strings,
@@ -4236,6 +4276,9 @@ int ksz_switch_register(struct ksz_device *dev)
/* set the real number of ports */
dev->ds->num_ports = dev->info->port_cnt;
+ /* set the phylink ops */
+ dev->ds->phylink_mac_ops = dev->info->phylink_mac_ops;
+
/* Host port interface will be self detected, or specifically set in
* device tree.
*/
diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h
index 15612101a155..ec5caa7ffb81 100644
--- a/drivers/net/dsa/microchip/ksz_common.h
+++ b/drivers/net/dsa/microchip/ksz_common.h
@@ -22,6 +22,7 @@
struct ksz_device;
struct ksz_port;
+struct phylink_mac_ops;
enum ksz_regmap_width {
KSZ_REGMAP_8,
@@ -61,6 +62,7 @@ struct ksz_chip_data {
bool tc_cbs_supported;
bool tc_ets_supported;
const struct ksz_dev_ops *ops;
+ const struct phylink_mac_ops *phylink_mac_ops;
bool ksz87xx_eee_link_erratum;
const struct ksz_mib_names *mib_names;
int mib_cnt;
@@ -347,9 +349,6 @@ struct ksz_dev_ops {
int (*change_mtu)(struct ksz_device *dev, int port, int mtu);
void (*freeze_mib)(struct ksz_device *dev, int port, bool freeze);
void (*port_init_cnt)(struct ksz_device *dev, int port);
- void (*phylink_mac_config)(struct ksz_device *dev, int port,
- unsigned int mode,
- const struct phylink_link_state *state);
void (*phylink_mac_link_up)(struct ksz_device *dev, int port,
unsigned int mode,
phy_interface_t interface,
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 6985e1bf94f3..91523ace1a1c 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2980,7 +2980,7 @@ static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
priv->info->mac_port_get_caps(ds, port, config);
}
-static int mt753x_pcs_validate(struct phylink_pcs *pcs, unsigned int mode,
+static int mt753x_pcs_validate(struct phylink_pcs *pcs,
unsigned long *supported,
const struct phylink_link_state *state)
{
diff --git a/drivers/net/dsa/xrs700x/xrs700x.c b/drivers/net/dsa/xrs700x/xrs700x.c
index 6605fa44bcf0..de3b768f2ff9 100644
--- a/drivers/net/dsa/xrs700x/xrs700x.c
+++ b/drivers/net/dsa/xrs700x/xrs700x.c
@@ -780,6 +780,7 @@ struct xrs700x *xrs700x_switch_alloc(struct device *base, void *devpriv)
INIT_DELAYED_WORK(&priv->mib_work, xrs700x_mib_work);
ds->ops = &xrs700x_ops;
+ ds->phylink_mac_ops = &xrs700x_phylink_mac_ops;
ds->priv = priv;
priv->dev = base;
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 00402c252325..bf1f5151c203 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -3967,7 +3967,7 @@ static unsigned int mvneta_pcs_query_inband(struct phylink_pcs *pcs,
* Therefore, inband is "required".
*/
if (phy_interface_mode_is_8023z(interface))
- return LINK_INBAND_VALID | LINK_INBAND_REQUIRED;
+ return LINK_INBAND_ENABLE;
/* QSGMII, SGMII and RGMII can be configured to use inband
* signalling of the AN result. Indicate these as "possible".
@@ -3975,10 +3975,10 @@ static unsigned int mvneta_pcs_query_inband(struct phylink_pcs *pcs,
if (interface == PHY_INTERFACE_MODE_SGMII ||
interface == PHY_INTERFACE_MODE_QSGMII ||
phy_interface_mode_is_rgmii(interface))
- return LINK_INBAND_VALID | LINK_INBAND_POSSIBLE;
+ return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
/* For any other modes, indicate that inband is not supported. */
- return LINK_INBAND_VALID;
+ return LINK_INBAND_DISABLE;
}
static void mvneta_pcs_get_state(struct phylink_pcs *pcs,
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index 1baff3474c28..82c49095c045 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -6215,19 +6215,26 @@ static const struct phylink_pcs_ops mvpp2_phylink_xlg_pcs_ops = {
.pcs_config = mvpp2_xlg_pcs_config,
};
-static int mvpp2_gmac_pcs_validate(struct phylink_pcs *pcs, unsigned int mode,
- unsigned long *supported,
- const struct phylink_link_state *state)
+static unsigned int mvpp2_gmac_pcs_query_inband(struct phylink_pcs *pcs,
+ phy_interface_t interface)
{
- /* When in 802.3z mode, we must have AN enabled:
+ /* When operating in an 802.3z mode, we must have AN enabled:
* Bit 2 Field InBandAnEn In-band Auto-Negotiation enable. ...
* When <PortType> = 1 (1000BASE-X) this field must be set to 1.
+ * Therefore, inband is "required".
*/
- if (phy_interface_mode_is_8023z(state->interface) &&
- !phylink_test(state->advertising, Autoneg))
- return -EINVAL;
+ if (phy_interface_mode_is_8023z(interface))
+ return LINK_INBAND_ENABLE;
- return 0;
+ /* SGMII and RGMII can be configured to use inband signalling of the
+ * AN result. Indicate these as "possible".
+ */
+ if (interface == PHY_INTERFACE_MODE_SGMII ||
+ phy_interface_mode_is_rgmii(interface))
+ return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
+
+ /* For any other modes, indicate that inband is not supported. */
+ return LINK_INBAND_DISABLE;
}
static void mvpp2_gmac_pcs_get_state(struct phylink_pcs *pcs,
@@ -6334,7 +6341,7 @@ static void mvpp2_gmac_pcs_an_restart(struct phylink_pcs *pcs)
}
static const struct phylink_pcs_ops mvpp2_phylink_gmac_pcs_ops = {
- .pcs_validate = mvpp2_gmac_pcs_validate,
+ .pcs_query_inband = mvpp2_gmac_pcs_query_inband,
.pcs_get_state = mvpp2_gmac_pcs_get_state,
.pcs_config = mvpp2_gmac_pcs_config,
.pcs_an_restart = mvpp2_gmac_pcs_an_restart,
diff --git a/drivers/net/pcs/pcs-rzn1-miic.c b/drivers/net/pcs/pcs-rzn1-miic.c
index f2da79591119..4bd66fdde367 100644
--- a/drivers/net/pcs/pcs-rzn1-miic.c
+++ b/drivers/net/pcs/pcs-rzn1-miic.c
@@ -268,8 +268,7 @@ static void miic_link_up(struct phylink_pcs *pcs, unsigned int neg_mode,
(MIIC_CONVCTRL_CONV_SPEED | MIIC_CONVCTRL_FULLD), val);
}
-static int miic_validate(struct phylink_pcs *pcs, unsigned int mode,
- unsigned long *supported,
+static int miic_validate(struct phylink_pcs *pcs, unsigned long *supported,
const struct phylink_link_state *state)
{
if (phy_interface_mode_is_rgmii(state->interface) ||
diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
index f3cccb459ecb..31f0beba638a 100644
--- a/drivers/net/pcs/pcs-xpcs.c
+++ b/drivers/net/pcs/pcs-xpcs.c
@@ -604,8 +604,7 @@ static void xpcs_resolve_pma(struct dw_xpcs *xpcs,
}
}
-static int xpcs_validate(struct phylink_pcs *pcs, unsigned int mode,
- unsigned long *supported,
+static int xpcs_validate(struct phylink_pcs *pcs, unsigned long *supported,
const struct phylink_link_state *state)
{
__ETHTOOL_DECLARE_LINK_MODE_MASK(xpcs_supported) = { 0, };
diff --git a/drivers/net/phy/bcm84881.c b/drivers/net/phy/bcm84881.c
index a72b693be846..95c239474b43 100644
--- a/drivers/net/phy/bcm84881.c
+++ b/drivers/net/phy/bcm84881.c
@@ -245,7 +245,7 @@ static int bcm84881_read_status(struct phy_device *phydev)
static unsigned int bcm84881_query_inband(struct phy_device *phydev,
phy_interface_t interface)
{
- return LINK_INBAND_VALID;
+ return LINK_INBAND_DISABLE;
}
static struct phy_driver bcm84881_drivers[] = {
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 6a6bcda8796d..0c610fc1c67e 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -687,7 +687,7 @@ static unsigned int m88e1111_query_inband(struct phy_device *phydev,
*/
if (interface == PHY_INTERFACE_MODE_1000BASEX ||
interface == PHY_INTERFACE_MODE_SGMII)
- return LINK_INBAND_VALID | LINK_INBAND_POSSIBLE;
+ return LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
return 0;
}
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 8a3728d423e7..b905a6b93d80 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -56,7 +56,8 @@ struct phylink {
struct phy_device *phydev;
phy_interface_t link_interface; /* PHY_INTERFACE_xxx */
u8 cfg_link_an_mode; /* MLO_AN_xxx */
- u8 cur_link_an_mode;
+ u8 req_link_an_mode; /* Requested MLO_AN_xxx mode */
+ u8 act_link_an_mode; /* Active MLO_AN_xxx mode */
u8 link_port; /* The current non-phy ethtool port */
__ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
@@ -85,7 +86,6 @@ struct phylink {
bool sfp_may_have_phy;
DECLARE_PHY_INTERFACE_MASK(sfp_interfaces);
__ETHTOOL_DECLARE_LINK_MODE_MASK(sfp_support);
- u8 sfp_link_an_mode;
u8 sfp_port;
struct eee_config eee_cfg;
@@ -179,6 +179,24 @@ static const char *phylink_an_mode_str(unsigned int mode)
return mode < ARRAY_SIZE(modestr) ? modestr[mode] : "unknown";
}
+static const char *phylink_pcs_mode_str(unsigned int mode)
+{
+ if (!mode)
+ return "none";
+
+ if (mode & PHYLINK_PCS_NEG_OUTBAND)
+ return "outband";
+
+ if (mode & PHYLINK_PCS_NEG_INBAND) {
+ if (mode & PHYLINK_PCS_NEG_ENABLED)
+ return "inband/an-enabled";
+ else
+ return "inband/an-disabled";
+ }
+
+ return "unknown";
+}
+
static unsigned int phylink_interface_signal_rate(phy_interface_t interface)
{
switch (interface) {
@@ -651,7 +669,7 @@ static void phylink_validate_mask_caps(unsigned long *supported,
linkmode_and(state->advertising, state->advertising, mask);
}
-static int phylink_validate_mac_and_pcs(struct phylink *pl, unsigned int mode,
+static int phylink_validate_mac_and_pcs(struct phylink *pl,
unsigned long *supported,
struct phylink_link_state *state)
{
@@ -682,8 +700,7 @@ static int phylink_validate_mac_and_pcs(struct phylink *pl, unsigned int mode,
/* Validate the link parameters with the PCS */
if (pcs->ops->pcs_validate) {
- ret = pcs->ops->pcs_validate(pcs, mode, supported,
- state);
+ ret = pcs->ops->pcs_validate(pcs, supported, state);
if (ret < 0 || phylink_is_empty_linkmode(supported))
return -EINVAL;
@@ -708,7 +725,6 @@ static int phylink_validate_mac_and_pcs(struct phylink *pl, unsigned int mode,
}
static void phylink_validate_one(struct phylink *pl, struct phy_device *phy,
- unsigned int mode,
const unsigned long *supported,
const struct phylink_link_state *state,
phy_interface_t interface,
@@ -726,8 +742,7 @@ static void phylink_validate_one(struct phylink *pl, struct phy_device *phy,
if (phy)
tmp_state.rate_matching = phy_get_rate_matching(phy, interface);
- if (!phylink_validate_mac_and_pcs(pl, mode, tmp_supported,
- &tmp_state)) {
+ if (!phylink_validate_mac_and_pcs(pl, tmp_supported, &tmp_state)) {
phylink_dbg(pl, " interface %u (%s) rate match %s supports %*pbl\n",
interface, phy_modes(interface),
phy_rate_matching_to_str(tmp_state.rate_matching),
@@ -740,7 +755,6 @@ static void phylink_validate_one(struct phylink *pl, struct phy_device *phy,
}
static int phylink_validate_mask(struct phylink *pl, struct phy_device *phy,
- unsigned int mode,
unsigned long *supported,
struct phylink_link_state *state,
const unsigned long *interfaces)
@@ -750,7 +764,7 @@ static int phylink_validate_mask(struct phylink *pl, struct phy_device *phy,
int interface;
for_each_set_bit(interface, interfaces, PHY_INTERFACE_MODE_MAX)
- phylink_validate_one(pl, phy, mode, supported, state, interface,
+ phylink_validate_one(pl, phy, supported, state, interface,
all_s, all_adv);
linkmode_copy(supported, all_s);
@@ -759,20 +773,19 @@ static int phylink_validate_mask(struct phylink *pl, struct phy_device *phy,
return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
}
-static int phylink_validate(struct phylink *pl, unsigned int mode,
- unsigned long *supported,
+static int phylink_validate(struct phylink *pl, unsigned long *supported,
struct phylink_link_state *state)
{
const unsigned long *interfaces = pl->config->supported_interfaces;
if (state->interface == PHY_INTERFACE_MODE_NA)
- return phylink_validate_mask(pl, NULL, mode, supported, state,
+ return phylink_validate_mask(pl, NULL, supported, state,
interfaces);
if (!test_bit(state->interface, interfaces))
return -EINVAL;
- return phylink_validate_mac_and_pcs(pl, mode, supported, state);
+ return phylink_validate_mac_and_pcs(pl, supported, state);
}
static int phylink_parse_fixedlink(struct phylink *pl,
@@ -850,7 +863,7 @@ static int phylink_parse_fixedlink(struct phylink *pl,
linkmode_fill(pl->supported);
linkmode_copy(pl->link_config.advertising, pl->supported);
- phylink_validate(pl, MLO_AN_FIXED, pl->supported, &pl->link_config);
+ phylink_validate(pl, pl->supported, &pl->link_config);
pause = phylink_test(pl->supported, Pause);
asym_pause = phylink_test(pl->supported, Asym_Pause);
@@ -948,8 +961,7 @@ static int phylink_parse_mode(struct phylink *pl,
linkmode_copy(pl->link_config.advertising, pl->supported);
- if (phylink_validate(pl, pl->cfg_link_an_mode, pl->supported,
- &pl->link_config)) {
+ if (phylink_validate(pl, pl->supported, &pl->link_config)) {
phylink_err(pl,
"failed to validate link configuration for in-band status\n");
return -EINVAL;
@@ -1049,6 +1061,24 @@ static void phylink_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode,
pcs->ops->pcs_link_up(pcs, neg_mode, interface, speed, duplex);
}
+/* Query inband for a specific interface mode, asking the MAC for the
+ * PCS which will be used to handle the interface mode.
+ */
+static unsigned int phylink_query_inband(struct phylink *pl,
+ phy_interface_t interface)
+{
+ struct phylink_pcs *pcs;
+
+ if (!pl->using_mac_select_pcs)
+ return 0;
+
+ pcs = pl->mac_ops->mac_select_pcs(pl->config, interface);
+ if (!pcs)
+ return 0;
+
+ return phylink_pcs_query_inband(pcs, interface);
+}
+
static void phylink_pcs_poll_stop(struct phylink *pl)
{
if (phylink_mode_inband(pl->cfg_link_an_mode))
@@ -1076,13 +1106,13 @@ static void phylink_mac_config(struct phylink *pl,
phylink_dbg(pl,
"%s: mode=%s/%s/%s adv=%*pb pause=%02x\n",
- __func__, phylink_an_mode_str(pl->cur_link_an_mode),
+ __func__, phylink_an_mode_str(pl->act_link_an_mode),
phy_modes(st.interface),
phy_rate_matching_to_str(st.rate_matching),
__ETHTOOL_LINK_MODE_MASK_NBITS, st.advertising,
st.pause);
- pl->mac_ops->mac_config(pl->config, pl->cur_link_an_mode, &st);
+ pl->mac_ops->mac_config(pl->config, pl->act_link_an_mode, &st);
}
static void phylink_pcs_an_restart(struct phylink *pl)
@@ -1090,7 +1120,7 @@ static void phylink_pcs_an_restart(struct phylink *pl)
if (pl->pcs && linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
pl->link_config.advertising) &&
phy_interface_mode_is_8023z(pl->link_config.interface) &&
- phylink_autoneg_inband(pl->cur_link_an_mode))
+ phylink_autoneg_inband(pl->act_link_an_mode))
pl->pcs->ops->pcs_an_restart(pl->pcs);
}
@@ -1158,24 +1188,28 @@ static unsigned int phylink_pcs_neg_mode(struct phylink *pl,
}
pcs_link_mode = phylink_pcs_query_inband(pcs, interface);
- if (pl->phydev)
+ pcs_link_mode &= LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
+ if (pl->phydev) {
phy_link_mode = phy_query_inband(pl->phydev, interface);
+ phy_link_mode &= LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
+ }
if (!phylink_autoneg_inband(mode)) {
+ const char *s1, *s2, *s3, *empty = "";
+
+ s1 = s2 = s3 = empty;
+
+ if (pcs_link_mode == LINK_INBAND_ENABLE)
+ s1 = "PCS";
+
+ if (phy_link_mode == LINK_INBAND_ENABLE)
+ s3 = "PHY";
+
/* If either the PCS or PHY requires inband to be enabled,
* this is an invalid configuration. Provide a diagnostic
* message for this case, but don't try to force the issue.
*/
- if ((pcs_link_mode | phy_link_mode) & LINK_INBAND_REQUIRED) {
- const char *s1, *s2, *s3, *empty = "";
-
- s1 = s2 = s3 = empty;
- if (pcs_link_mode & LINK_INBAND_REQUIRED)
- s1 = "PCS";
-
- if (phy_link_mode & LINK_INBAND_REQUIRED)
- s3 = "PHY";
-
+ if (s1 != empty || s3 != empty) {
if (s1 != empty && s3 != empty)
s2 = " and ";
@@ -1188,24 +1222,44 @@ static unsigned int phylink_pcs_neg_mode(struct phylink *pl,
}
/* For SGMII modes, which are designed to be used with PHYs, we
- * try to use inband mode where-ever possible.
+ * try to use inband mode where-ever possible. However, there are
+ * some PHYs e.g. BCM84881 which do not support in-band.
*/
if (type == INBAND_CISCO_SGMII) {
- /* If the PCS or PHY can not provide inband, then use
- * out of band.
+ /* PCS PHY
+ * D E D E
+ * 0 0 0 0 no information inband enabled
+ * 1 0 0 0 pcs doesn't support outband
+ * 0 1 0 0 pcs required inband enabled
+ * 1 1 0 0 pcs optional inband enabled
+ * 0 0 1 0 phy doesn't support outband
+ * 1 0 1 0 pcs+phy doesn't support outband
+ * 0 1 1 0 pcs required, phy doesn't support, invalid
+ * 1 1 1 0 pcs optional, phy doesn't support, outband
+ * 0 0 0 1 phy required inband enabled
+ * 1 0 0 1 pcs doesn't support, phy required, invalid
+ * 0 1 0 1 pcs+phy required inband enabled
+ * 1 1 0 1 pcs optional, phy required inband enabled
+ * 0 0 1 1 phy optional inband enabled
+ * 1 0 1 1 pcs doesn't support, phy optional, outband
+ * 0 1 1 1 pcs required, phy optional inband enabled
+ * 1 1 1 1 pcs+phy optional inband enabled
*/
- if (pcs_link_mode == LINK_INBAND_VALID ||
- phy_link_mode == LINK_INBAND_VALID) {
- /* If either require inband, then we have a conflict. */
+ if (!pcs_link_mode)
+ pcs_link_mode = LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
+
+ if (!phy_link_mode)
+ phy_link_mode = LINK_INBAND_DISABLE | LINK_INBAND_ENABLE;
+
+ if (pcs_link_mode & phy_link_mode & LINK_INBAND_ENABLE) {
+ /* inband supported at both ends */
+ return PHYLINK_PCS_NEG_INBAND_ENABLED;
+ } else if (pcs_link_mode & phy_link_mode & LINK_INBAND_DISABLE) {
+ /* inband not supported at both ends */
return PHYLINK_PCS_NEG_OUTBAND;
+ } else {
+ /* invalid */
}
-
- /* Otherwise, use inband as this is what was requested.
- * This covers the case where the supported inband modes
- * have not been provided, or the PCS and PHY report that
- * they support inband.
- */
- return PHYLINK_PCS_NEG_INBAND_ENABLED;
}
/* For 802.3z, handle the PHY present vs absent cases separately */
@@ -1214,13 +1268,13 @@ static unsigned int phylink_pcs_neg_mode(struct phylink *pl,
/* If the PCS doesn't support inband, then inband must be
* disabled.
*/
- if (pcs_link_mode == LINK_INBAND_VALID)
+ if (pcs_link_mode == LINK_INBAND_DISABLE)
return PHYLINK_PCS_NEG_INBAND_DISABLED;
/* If the PCS requires inband, then inband must always be
* enabled.
*/
- if (pcs_link_mode & LINK_INBAND_REQUIRED)
+ if (pcs_link_mode == LINK_INBAND_ENABLE)
return PHYLINK_PCS_NEG_INBAND_ENABLED;
/* For the possible case, fall through to the "legacy" code. */
@@ -1239,6 +1293,15 @@ static unsigned int phylink_pcs_neg_mode(struct phylink *pl,
return neg_mode;
}
+static u8 phylink_choose_act_link_an_mode(struct phylink *pl)
+{
+ if (pl->req_link_an_mode == MLO_AN_INBAND && pl->phydev &&
+ pl->pcs_neg_mode == PHYLINK_PCS_NEG_OUTBAND)
+ return MLO_AN_PHY;
+
+ return pl->req_link_an_mode;
+}
+
static void phylink_major_config(struct phylink *pl, bool restart,
const struct phylink_link_state *state)
{
@@ -1248,7 +1311,9 @@ static void phylink_major_config(struct phylink *pl, bool restart,
unsigned int neg_mode;
int err;
- phylink_dbg(pl, "major config %s\n", phy_modes(state->interface));
+ phylink_dbg(pl, "major config, requested %s/%s\n",
+ phylink_an_mode_str(pl->req_link_an_mode),
+ phy_modes(state->interface));
if (pl->using_mac_select_pcs) {
pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface);
@@ -1263,14 +1328,24 @@ static void phylink_major_config(struct phylink *pl, bool restart,
}
pl->pcs_neg_mode = phylink_pcs_neg_mode(pl, pcs,
- pl->cur_link_an_mode,
+ pl->req_link_an_mode,
state->interface,
state->advertising);
+ /* set the active link AN mode, which may end up different from the
+ * current link AN mode depending on the PCS and PHY capabilities.
+ */
+ pl->act_link_an_mode = phylink_choose_act_link_an_mode(pl);
+
+ phylink_dbg(pl, "major config, active %s/%s/%s\n",
+ phylink_an_mode_str(pl->act_link_an_mode),
+ phylink_pcs_mode_str(pl->pcs_neg_mode),
+ phy_modes(state->interface));
+
phylink_pcs_poll_stop(pl);
if (pl->mac_ops->mac_prepare) {
- err = pl->mac_ops->mac_prepare(pl->config, pl->cur_link_an_mode,
+ err = pl->mac_ops->mac_prepare(pl->config, pl->act_link_an_mode,
state->interface);
if (err < 0) {
phylink_err(pl, "mac_prepare failed: %pe\n",
@@ -1304,7 +1379,7 @@ static void phylink_major_config(struct phylink *pl, bool restart,
if (pl->pcs_state == PCS_STATE_STARTING || pcs_changed)
phylink_pcs_enable(pl->pcs);
- neg_mode = pl->cur_link_an_mode;
+ neg_mode = pl->act_link_an_mode;
if (pl->pcs && pl->pcs->neg_mode)
neg_mode = pl->pcs_neg_mode;
@@ -1320,7 +1395,7 @@ static void phylink_major_config(struct phylink *pl, bool restart,
phylink_pcs_an_restart(pl);
if (pl->mac_ops->mac_finish) {
- err = pl->mac_ops->mac_finish(pl->config, pl->cur_link_an_mode,
+ err = pl->mac_ops->mac_finish(pl->config, pl->act_link_an_mode,
state->interface);
if (err < 0)
phylink_err(pl, "mac_finish failed: %pe\n",
@@ -1351,18 +1426,23 @@ static int phylink_change_inband_advert(struct phylink *pl)
return 0;
phylink_dbg(pl, "%s: mode=%s/%s adv=%*pb pause=%02x\n", __func__,
- phylink_an_mode_str(pl->cur_link_an_mode),
+ phylink_an_mode_str(pl->req_link_an_mode),
phy_modes(pl->link_config.interface),
__ETHTOOL_LINK_MODE_MASK_NBITS, pl->link_config.advertising,
pl->link_config.pause);
/* Recompute the PCS neg mode */
pl->pcs_neg_mode = phylink_pcs_neg_mode(pl, pl->pcs,
- pl->cur_link_an_mode,
+ pl->req_link_an_mode,
pl->link_config.interface,
pl->link_config.advertising);
- neg_mode = pl->cur_link_an_mode;
+ /* set the active link AN mode, which may end up different from the
+ * current link AN mode depending on the PCS and PHY capabilities.
+ */
+ pl->act_link_an_mode = phylink_choose_act_link_an_mode(pl);
+
+ neg_mode = pl->act_link_an_mode;
if (pl->pcs->neg_mode)
neg_mode = pl->pcs_neg_mode;
@@ -1427,7 +1507,7 @@ static void phylink_mac_initial_config(struct phylink *pl, bool force_restart)
{
struct phylink_link_state link_state;
- switch (pl->cur_link_an_mode) {
+ switch (pl->req_link_an_mode) {
case MLO_AN_PHY:
link_state = pl->phy_state;
break;
@@ -1570,14 +1650,14 @@ static void phylink_link_up(struct phylink *pl,
pl->cur_interface = link_state.interface;
- neg_mode = pl->cur_link_an_mode;
+ neg_mode = pl->act_link_an_mode;
if (pl->pcs && pl->pcs->neg_mode)
neg_mode = pl->pcs_neg_mode;
phylink_pcs_link_up(pl->pcs, neg_mode, pl->cur_interface, speed,
duplex);
- pl->mac_ops->mac_link_up(pl->config, pl->phydev, pl->cur_link_an_mode,
+ pl->mac_ops->mac_link_up(pl->config, pl->phydev, pl->act_link_an_mode,
pl->cur_interface, speed, duplex,
!!(link_state.pause & MLO_PAUSE_TX), rx_pause);
@@ -1603,7 +1683,7 @@ static void phylink_link_down(struct phylink *pl)
phylink_deactivate_eee(pl);
- pl->mac_ops->mac_link_down(pl->config, pl->cur_link_an_mode,
+ pl->mac_ops->mac_link_down(pl->config, pl->act_link_an_mode,
pl->cur_interface);
phylink_info(pl, "Link is Down\n");
}
@@ -1630,76 +1710,73 @@ static void phylink_resolve(struct work_struct *w)
} else if (pl->mac_link_dropped) {
link_state.link = false;
retrigger = true;
- } else {
- switch (pl->cur_link_an_mode) {
- case MLO_AN_PHY:
+ } else if (pl->act_link_an_mode == MLO_AN_FIXED) {
+ phylink_get_fixed_state(pl, &link_state);
+ mac_config = link_state.link;
+ } else if (pl->act_link_an_mode == MLO_AN_PHY) {
+ /* PHY mode, or PCS configured for outband mode */
+ if (pl->phydev) {
link_state = pl->phy_state;
- phylink_apply_manual_flow(pl, &link_state);
- mac_config = link_state.link;
- break;
+ } else {
+ /* No PHY - assume link is down */
+ link_state.link = false;
+ }
+ mac_config = link_state.link;
+ } else {
+ /* Inband mode */
+ phylink_mac_pcs_get_state(pl, &link_state);
- case MLO_AN_FIXED:
- phylink_get_fixed_state(pl, &link_state);
- mac_config = link_state.link;
- break;
+ /* The PCS may have a latching link-fail indicator.
+ * If the link was up, bring the link down and
+ * re-trigger the resolve. Otherwise, re-read the
+ * PCS state to get the current status of the link.
+ */
+ if (!link_state.link) {
+ if (cur_link_state)
+ retrigger = true;
+ else
+ phylink_mac_pcs_get_state(pl, &link_state);
+ }
- case MLO_AN_INBAND:
- phylink_mac_pcs_get_state(pl, &link_state);
+ /* If we have a phy, the "up" state is the union of
+ * both the PHY and the MAC
+ */
+ if (pl->phydev)
+ link_state.link &= pl->phy_state.link;
- /* The PCS may have a latching link-fail indicator.
- * If the link was up, bring the link down and
- * re-trigger the resolve. Otherwise, re-read the
- * PCS state to get the current status of the link.
+ /* Only update if the PHY link is up */
+ if (pl->phydev && pl->phy_state.link) {
+ /* If the interface has changed, force a
+ * link down event if the link isn't already
+ * down, and re-resolve.
*/
- if (!link_state.link) {
- if (cur_link_state)
- retrigger = true;
- else
- phylink_mac_pcs_get_state(pl,
- &link_state);
+ if (link_state.interface != pl->phy_state.interface) {
+ retrigger = true;
+ link_state.link = false;
}
+ link_state.interface = pl->phy_state.interface;
- /* If we have a phy, the "up" state is the union of
- * both the PHY and the MAC
+ /* If we are doing rate matching, then the
+ * link speed/duplex comes from the PHY
*/
- if (pl->phydev)
- link_state.link &= pl->phy_state.link;
-
- /* Only update if the PHY link is up */
- if (pl->phydev && pl->phy_state.link) {
- /* If the interface has changed, force a
- * link down event if the link isn't already
- * down, and re-resolve.
- */
- if (link_state.interface !=
- pl->phy_state.interface) {
- retrigger = true;
- link_state.link = false;
- }
- link_state.interface = pl->phy_state.interface;
-
- /* If we are doing rate matching, then the
- * link speed/duplex comes from the PHY
- */
- if (pl->phy_state.rate_matching) {
- link_state.rate_matching =
- pl->phy_state.rate_matching;
- link_state.speed = pl->phy_state.speed;
- link_state.duplex =
- pl->phy_state.duplex;
- }
-
- /* If we have a PHY, we need to update with
- * the PHY flow control bits.
- */
- link_state.pause = pl->phy_state.pause;
- mac_config = true;
+ if (pl->phy_state.rate_matching) {
+ link_state.rate_matching =
+ pl->phy_state.rate_matching;
+ link_state.speed = pl->phy_state.speed;
+ link_state.duplex = pl->phy_state.duplex;
}
- phylink_apply_manual_flow(pl, &link_state);
- break;
+
+ /* If we have a PHY, we need to update with
+ * the PHY flow control bits.
+ */
+ link_state.pause = pl->phy_state.pause;
+ mac_config = true;
}
}
+ if (pl->act_link_an_mode != MLO_AN_FIXED)
+ phylink_apply_manual_flow(pl, &link_state);
+
if (mac_config) {
if (link_state.interface != pl->link_config.interface) {
/* The interface has changed, force the link down and
@@ -1858,7 +1935,7 @@ struct phylink *phylink_create(struct phylink_config *config,
linkmode_fill(pl->supported);
linkmode_copy(pl->link_config.advertising, pl->supported);
- phylink_validate(pl, MLO_AN_FIXED, pl->supported, &pl->link_config);
+ phylink_validate(pl, pl->supported, &pl->link_config);
/* Set the default EEE configuration */
pl->eee_cfg = pl->config->eee;
@@ -1877,7 +1954,8 @@ struct phylink *phylink_create(struct phylink_config *config,
}
}
- pl->cur_link_an_mode = pl->cfg_link_an_mode;
+ pl->req_link_an_mode = pl->cfg_link_an_mode;
+ pl->act_link_an_mode = pl->req_link_an_mode;
ret = phylink_register_sfp(pl, fwnode);
if (ret < 0) {
@@ -1963,9 +2041,6 @@ static int phylink_validate_phy(struct phylink *pl, struct phy_device *phy,
struct phylink_link_state *state)
{
DECLARE_PHY_INTERFACE_MASK(interfaces);
- unsigned int mode;
-
- mode = pl->cfg_link_an_mode;
/* If the PHY provides a bitmap of the interfaces it will be using
* depending on the negotiated media speeds, use this to validate
@@ -2002,7 +2077,7 @@ static int phylink_validate_phy(struct phylink *pl, struct phy_device *phy,
phy->possible_interfaces,
(int)PHY_INTERFACE_MODE_MAX, interfaces);
- return phylink_validate_mask(pl, phy, mode, supported, state,
+ return phylink_validate_mask(pl, phy, supported, state,
interfaces);
}
@@ -2031,7 +2106,7 @@ static int phylink_validate_phy(struct phylink *pl, struct phy_device *phy,
state->interface != PHY_INTERFACE_MODE_USXGMII)
state->interface = PHY_INTERFACE_MODE_NA;
- return phylink_validate(pl, mode, supported, state);
+ return phylink_validate(pl, supported, state);
}
static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy,
@@ -2334,7 +2409,7 @@ void phylink_start(struct phylink *pl)
ASSERT_RTNL();
phylink_info(pl, "configuring for %s/%s link mode\n",
- phylink_an_mode_str(pl->cur_link_an_mode),
+ phylink_an_mode_str(pl->req_link_an_mode),
phy_modes(pl->link_config.interface));
/* Always set the carrier off */
@@ -2545,6 +2620,32 @@ int phylink_ethtool_set_wol(struct phylink *pl, struct ethtool_wolinfo *wol)
}
EXPORT_SYMBOL_GPL(phylink_ethtool_set_wol);
+static phy_interface_t phylink_sfp_select_interface(struct phylink *pl,
+ const unsigned long *link_modes)
+{
+ phy_interface_t interface;
+
+ interface = sfp_select_interface(pl->sfp_bus, link_modes);
+ if (interface == PHY_INTERFACE_MODE_NA) {
+ phylink_err(pl,
+ "selection of interface failed, advertisement %*pb\n",
+ __ETHTOOL_LINK_MODE_MASK_NBITS,
+ link_modes);
+ return interface;
+ }
+
+ if (!test_bit(interface, pl->config->supported_interfaces)) {
+ phylink_err(pl,
+ "selection of interface failed - SFP selected %s (%u) but MAC supports %*pbl\n",
+ phy_modes(interface), interface,
+ (int)PHY_INTERFACE_MODE_MAX,
+ pl->config->supported_interfaces);
+ return PHY_INTERFACE_MODE_NA;
+ }
+
+ return interface;
+}
+
static void phylink_merge_link_mode(unsigned long *dst, const unsigned long *b)
{
__ETHTOOL_DECLARE_LINK_MODE_MASK(mask);
@@ -2593,7 +2694,7 @@ int phylink_ethtool_ksettings_get(struct phylink *pl,
linkmode_copy(kset->link_modes.supported, pl->supported);
- switch (pl->cur_link_an_mode) {
+ switch (pl->act_link_an_mode) {
case MLO_AN_FIXED:
/* We are using fixed settings. Report these as the
* current link settings - and note that these also
@@ -2624,37 +2725,24 @@ int phylink_ethtool_ksettings_get(struct phylink *pl,
}
EXPORT_SYMBOL_GPL(phylink_ethtool_ksettings_get);
-static int phylink_query_inband(struct phylink *pl, phy_interface_t interface)
+static bool phylink_validate_pcs_inband_autoneg(struct phylink *pl,
+ phy_interface_t interface,
+ unsigned long *adv)
{
- struct phylink_pcs *pcs;
-
- if (!pl->using_mac_select_pcs)
- return 0;
-
- pcs = pl->mac_ops->mac_select_pcs(pl->config, interface);
- if (!pcs)
- return 0;
-
- return phylink_pcs_query_inband(pcs, interface);
-}
-
-static bool phylink_validate_pcs_an(struct phylink *pl,
- phy_interface_t interface, bool an_state)
-{
- int link_inband = phylink_query_inband(pl, interface);
+ unsigned int inband = phylink_query_inband(pl, interface);
+ unsigned int mask;
/* If the PCS doesn't implement inband support, be permissive. */
- if (!(link_inband & LINK_INBAND_VALID))
+ if (!inband)
return true;
- /* If the PCS can configure the use of inband, allow either state */
- if (link_inband & LINK_INBAND_POSSIBLE)
- return true;
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, adv))
+ mask = LINK_INBAND_ENABLE;
+ else
+ mask = LINK_INBAND_DISABLE;
- /* Otherwise, require the AN state to be fixed according to the
- * required flag.
- */
- return an_state == !!(link_inband & LINK_INBAND_REQUIRED);
+ /* Check whether the PCS implements the required mode */
+ return !!(inband & mask);
}
/**
@@ -2718,7 +2806,7 @@ int phylink_ethtool_ksettings_set(struct phylink *pl,
/* If we have a fixed link, refuse to change link parameters.
* If the link parameters match, accept them but do nothing.
*/
- if (phylink_mode_fixed(pl->cur_link_an_mode)) {
+ if (phylink_mode_fixed(pl->req_link_an_mode)) {
if (s->speed != pl->link_config.speed ||
s->duplex != pl->link_config.duplex)
return -EINVAL;
@@ -2734,7 +2822,7 @@ int phylink_ethtool_ksettings_set(struct phylink *pl,
* is our default case) but do not allow the advertisement to
* be changed. If the advertisement matches, simply return.
*/
- if (phylink_mode_fixed(pl->cur_link_an_mode)) {
+ if (phylink_mode_fixed(pl->req_link_an_mode)) {
if (!linkmode_equal(config.advertising,
pl->link_config.advertising))
return -EINVAL;
@@ -2760,22 +2848,16 @@ int phylink_ethtool_ksettings_set(struct phylink *pl,
* link can be configured correctly.
*/
if (pl->sfp_bus) {
- config.interface = sfp_select_interface(pl->sfp_bus,
+ config.interface = phylink_sfp_select_interface(pl,
config.advertising);
- if (config.interface == PHY_INTERFACE_MODE_NA) {
- phylink_err(pl,
- "selection of interface failed, advertisement %*pb\n",
- __ETHTOOL_LINK_MODE_MASK_NBITS,
- config.advertising);
+ if (config.interface == PHY_INTERFACE_MODE_NA)
return -EINVAL;
- }
/* Revalidate with the selected interface */
linkmode_copy(support, pl->supported);
- if (phylink_validate(pl, pl->cur_link_an_mode, support,
- &config)) {
+ if (phylink_validate(pl, support, &config)) {
phylink_err(pl, "validation of %s/%s with support %*pb failed\n",
- phylink_an_mode_str(pl->cur_link_an_mode),
+ phylink_an_mode_str(pl->req_link_an_mode),
phy_modes(config.interface),
__ETHTOOL_LINK_MODE_MASK_NBITS, support);
return -EINVAL;
@@ -2783,8 +2865,7 @@ int phylink_ethtool_ksettings_set(struct phylink *pl,
} else {
/* Validate without changing the current supported mask. */
linkmode_copy(support, pl->supported);
- if (phylink_validate(pl, pl->cur_link_an_mode, support,
- &config))
+ if (phylink_validate(pl, support, &config))
return -EINVAL;
}
@@ -2797,9 +2878,8 @@ int phylink_ethtool_ksettings_set(struct phylink *pl,
/* Validate the autonegotiation state. We don't have a PHY in this
* situation, so the PCS is the media-facing entity.
*/
- if (!phylink_validate_pcs_an(pl, config.interface,
- linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
- config.advertising)))
+ if (!phylink_validate_pcs_inband_autoneg(pl, config.interface,
+ config.advertising))
return -EINVAL;
mutex_lock(&pl->state_mutex);
@@ -2884,7 +2964,7 @@ int phylink_ethtool_set_pauseparam(struct phylink *pl,
ASSERT_RTNL();
- if (phylink_mode_fixed(pl->cur_link_an_mode))
+ if (phylink_mode_fixed(pl->req_link_an_mode))
return -EOPNOTSUPP;
if (!phylink_test(pl->supported, Pause) &&
@@ -3202,7 +3282,7 @@ static int phylink_mii_read(struct phylink *pl, unsigned int phy_id,
struct phylink_link_state state;
int val = 0xffff;
- switch (pl->cur_link_an_mode) {
+ switch (pl->act_link_an_mode) {
case MLO_AN_FIXED:
if (phy_id == 0) {
phylink_get_fixed_state(pl, &state);
@@ -3227,7 +3307,7 @@ static int phylink_mii_read(struct phylink *pl, unsigned int phy_id,
static int phylink_mii_write(struct phylink *pl, unsigned int phy_id,
unsigned int reg, unsigned int val)
{
- switch (pl->cur_link_an_mode) {
+ switch (pl->act_link_an_mode) {
case MLO_AN_FIXED:
break;
@@ -3397,10 +3477,11 @@ static phy_interface_t phylink_choose_sfp_interface(struct phylink *pl,
return interface;
}
-static void phylink_sfp_set_config(struct phylink *pl, u8 mode,
+static void phylink_sfp_set_config(struct phylink *pl,
unsigned long *supported,
struct phylink_link_state *state)
{
+ u8 mode = MLO_AN_INBAND;
bool changed = false;
phylink_dbg(pl, "requesting link mode %s/%s with support %*pb\n",
@@ -3417,9 +3498,9 @@ static void phylink_sfp_set_config(struct phylink *pl, u8 mode,
changed = true;
}
- if (pl->cur_link_an_mode != mode ||
+ if (pl->req_link_an_mode != mode ||
pl->link_config.interface != state->interface) {
- pl->cur_link_an_mode = mode;
+ pl->req_link_an_mode = mode;
pl->link_config.interface = state->interface;
changed = true;
@@ -3436,10 +3517,8 @@ static void phylink_sfp_set_config(struct phylink *pl, u8 mode,
static int phylink_sfp_config_phy(struct phylink *pl, struct phy_device *phy)
{
- __ETHTOOL_DECLARE_LINK_MODE_MASK(support1);
__ETHTOOL_DECLARE_LINK_MODE_MASK(support);
struct phylink_link_state config;
- phy_interface_t iface;
int ret;
linkmode_copy(support, phy->supported);
@@ -3452,7 +3531,7 @@ static int phylink_sfp_config_phy(struct phylink *pl, struct phy_device *phy)
config.pause = MLO_PAUSE_AN;
/* Ignore errors if we're expecting a PHY to attach later */
- ret = phylink_validate(pl, pl->sfp_link_an_mode, support, &config);
+ ret = phylink_validate(pl, support, &config);
if (ret) {
phylink_err(pl, "validation with support %*pb failed: %pe\n",
__ETHTOOL_LINK_MODE_MASK_NBITS, support,
@@ -3460,30 +3539,27 @@ static int phylink_sfp_config_phy(struct phylink *pl, struct phy_device *phy)
return ret;
}
- iface = sfp_select_interface(pl->sfp_bus, config.advertising);
- if (iface == PHY_INTERFACE_MODE_NA) {
- phylink_err(pl,
- "selection of interface failed, advertisement %*pb\n",
- __ETHTOOL_LINK_MODE_MASK_NBITS, config.advertising);
+ config.interface = phylink_sfp_select_interface(pl, config.advertising);
+ if (config.interface == PHY_INTERFACE_MODE_NA)
return -EINVAL;
- }
- config.interface = iface;
- linkmode_copy(support1, support);
- ret = phylink_validate(pl, pl->sfp_link_an_mode, support1, &config);
- if (ret) {
- phylink_err(pl,
- "validation of %s/%s with support %*pb failed: %pe\n",
- phylink_an_mode_str(pl->sfp_link_an_mode),
- phy_modes(config.interface),
- __ETHTOOL_LINK_MODE_MASK_NBITS, support,
- ERR_PTR(ret));
+ /* Attach the PHY so that the PHY is present when we do the major
+ * configuration step.
+ */
+ ret = phylink_attach_phy(pl, phy, config.interface);
+ if (ret < 0)
+ return ret;
+
+ /* This will validate the configuration for us. */
+ ret = phylink_bringup_phy(pl, phy, config.interface);
+ if (ret < 0) {
+ phy_detach(phy);
return ret;
}
pl->link_port = pl->sfp_port;
- phylink_sfp_set_config(pl, pl->sfp_link_an_mode, support, &config);
+ phylink_sfp_set_config(pl, support, &config);
return 0;
}
@@ -3522,8 +3598,8 @@ static int phylink_sfp_config_optical(struct phylink *pl)
/* For all the interfaces that are supported, reduce the sfp_support
* mask to only those link modes that can be supported.
*/
- ret = phylink_validate_mask(pl, NULL, MLO_AN_INBAND, pl->sfp_support,
- &config, interfaces);
+ ret = phylink_validate_mask(pl, NULL, pl->sfp_support, &config,
+ interfaces);
if (ret) {
phylink_err(pl, "unsupported SFP module: validation with support %*pb failed\n",
__ETHTOOL_LINK_MODE_MASK_NBITS, support);
@@ -3539,9 +3615,8 @@ static int phylink_sfp_config_optical(struct phylink *pl)
phylink_dbg(pl, "optical SFP: chosen %s interface\n",
phy_modes(interface));
- if (!phylink_validate_pcs_an(pl, interface,
- linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
- config.advertising))) {
+ if (!phylink_validate_pcs_inband_autoneg(pl, interface,
+ config.advertising)) {
phylink_err(pl, "autoneg setting not compatible with PCS");
return -EINVAL;
}
@@ -3549,7 +3624,7 @@ static int phylink_sfp_config_optical(struct phylink *pl)
config.interface = interface;
/* Ignore errors if we're expecting a PHY to attach later */
- ret = phylink_validate(pl, MLO_AN_INBAND, support, &config);
+ ret = phylink_validate(pl, support, &config);
if (ret) {
phylink_err(pl, "validation with support %*pb failed: %pe\n",
__ETHTOOL_LINK_MODE_MASK_NBITS, support,
@@ -3559,7 +3634,7 @@ static int phylink_sfp_config_optical(struct phylink *pl)
pl->link_port = pl->sfp_port;
- phylink_sfp_set_config(pl, MLO_AN_INBAND, pl->sfp_support, &config);
+ phylink_sfp_set_config(pl, pl->sfp_support, &config);
return 0;
}
@@ -3575,7 +3650,6 @@ static int phylink_sfp_module_insert(void *upstream,
phy_interface_zero(pl->sfp_interfaces);
sfp_parse_support(pl->sfp_bus, id, pl->sfp_support, pl->sfp_interfaces);
pl->sfp_port = sfp_parse_port(pl->sfp_bus, id, pl->sfp_support);
- pl->sfp_link_an_mode = MLO_AN_INBAND;
/* If this module may have a PHY connecting later, defer until later */
pl->sfp_may_have_phy = sfp_may_have_phy(pl->sfp_bus, id);
@@ -3636,7 +3710,7 @@ static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy)
DECLARE_PHY_INTERFACE_MASK(interfaces);
struct phylink *pl = upstream;
phy_interface_t interface;
- int link_inband, ret;
+ int ret;
/*
* This is the new way of dealing with flow control for PHYs,
@@ -3655,64 +3729,51 @@ static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy)
phylink_dbg(pl, "copper SFP: PHY provides empty supported_interfaces\n");
/* Do the initial configuration */
- ret = phylink_sfp_config_phy(pl, phy);
- if (ret < 0)
- return ret;
- } else {
- phylink_dbg(pl, "copper SFP: interfaces=[mac=%*pbl, sfp=%*pbl]\n",
- (int)PHY_INTERFACE_MODE_MAX,
- pl->config->supported_interfaces,
- (int)PHY_INTERFACE_MODE_MAX,
- phy->supported_interfaces);
-
- phy_interface_and(interfaces, phy->supported_interfaces,
- pl->config->supported_interfaces);
- interface = phylink_choose_sfp_interface(pl, interfaces);
- if (interface == PHY_INTERFACE_MODE_NA) {
- phylink_err(pl,
- "selection of interface for PHY failed\n");
- return -EINVAL;
- }
-
- phylink_dbg(pl, "copper SFP: chosen %s interface\n",
- phy_modes(interface));
-
- link_inband = phy_query_inband(phy, interface);
- phylink_dbg(pl, "copper SFP: PHY link in-band modes 0x%x\n",
- link_inband);
-
- /* If the link inband is valid but the PHY doesn't support
- * inband, then we have to use PHY mode. E.g. BCM84881.
- */
- if (link_inband == LINK_INBAND_VALID)
- pl->sfp_link_an_mode = MLO_AN_PHY;
-
- if (pl->cur_link_an_mode != pl->sfp_link_an_mode ||
- pl->link_config.interface != interface) {
- pl->link_config.interface = interface;
- pl->cur_link_an_mode = pl->sfp_link_an_mode;
+ return phylink_sfp_config_phy(pl, phy);
+ }
- phylink_info(pl, "switched to %s/%s link mode\n",
- phylink_an_mode_str(pl->sfp_link_an_mode),
- phy_modes(interface));
- }
+ phylink_dbg(pl, "copper SFP: interfaces=[mac=%*pbl, sfp=%*pbl]\n",
+ (int)PHY_INTERFACE_MODE_MAX,
+ pl->config->supported_interfaces,
+ (int)PHY_INTERFACE_MODE_MAX,
+ phy->supported_interfaces);
- if (!test_bit(PHYLINK_DISABLE_STOPPED,
- &pl->phylink_disable_state))
- phylink_mac_initial_config(pl, false);
+ phy_interface_and(interfaces, phy->supported_interfaces,
+ pl->config->supported_interfaces);
+ interface = phylink_choose_sfp_interface(pl, interfaces);
+ if (interface == PHY_INTERFACE_MODE_NA) {
+ phylink_err(pl,
+ "selection of interface for PHY failed\n");
+ return -EINVAL;
}
- interface = pl->link_config.interface;
+ phylink_dbg(pl, "copper SFP: chosen %s interface\n",
+ phy_modes(interface));
ret = phylink_attach_phy(pl, phy, interface);
if (ret < 0)
return ret;
ret = phylink_bringup_phy(pl, phy, interface);
- if (ret)
+ if (ret) {
phy_detach(phy);
+ return ret;
+ }
- return ret;
+ if (pl->req_link_an_mode != MLO_AN_INBAND ||
+ pl->link_config.interface != interface) {
+ pl->link_config.interface = interface;
+ pl->req_link_an_mode = MLO_AN_INBAND;
+
+ phylink_info(pl, "switched to %s/%s link mode\n",
+ phylink_an_mode_str(pl->req_link_an_mode),
+ phy_modes(pl->link_config.interface));
+ }
+
+ if (!test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state))
+ phylink_mac_initial_config(pl, false);
+
+ return 0;
}
static void phylink_sfp_disconnect_phy(void *upstream)
diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c
index db39dec7f247..2f44fc51848f 100644
--- a/drivers/net/phy/sfp-bus.c
+++ b/drivers/net/phy/sfp-bus.c
@@ -355,7 +355,7 @@ EXPORT_SYMBOL_GPL(sfp_parse_support);
* modes mask.
*/
phy_interface_t sfp_select_interface(struct sfp_bus *bus,
- unsigned long *link_modes)
+ const unsigned long *link_modes)
{
if (phylink_test(link_modes, 25000baseCR_Full) ||
phylink_test(link_modes, 25000baseKR_Full) ||
@@ -373,7 +373,8 @@ phy_interface_t sfp_select_interface(struct sfp_bus *bus,
if (phylink_test(link_modes, 5000baseT_Full))
return PHY_INTERFACE_MODE_5GBASER;
- if (phylink_test(link_modes, 2500baseX_Full))
+ if (phylink_test(link_modes, 2500baseX_Full) ||
+ phylink_test(link_modes, 2500baseT_Full))
return PHY_INTERFACE_MODE_2500BASEX;
if (phylink_test(link_modes, 1000baseT_Half) ||
diff --git a/include/linux/phy.h b/include/linux/phy.h
index ded6ce314710..547098e9a98c 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -810,9 +810,9 @@ struct phy_tdr_config {
/**
* enum link_inband_signalling - inband signalling modes that are supported
*
- * @LINK_INBAND_VALID: inband signalling report is valid
- * @LINK_INBAND_POSSIBLE: inband signalling can be used
- * @LINK_INBAND_REQUIRED: inband signalling is required
+ * @LINK_INBAND_DISABLE: inband signalling can be disabled
+ * @LINK_INBAND_ENABLE: inband signalling can be enabled
+ * @LINK_INBAND_BYPASS: only valid with LINK_INBAND_ENABLE and supports bypass
*
* The possible and required bits can only be used if the valid bit is set.
* If possible is clear, that means inband signalling can not be used.
@@ -820,9 +820,9 @@ struct phy_tdr_config {
* signalling must be used.
*/
enum link_inband_signalling {
- LINK_INBAND_VALID = BIT(0),
- LINK_INBAND_POSSIBLE = BIT(1),
- LINK_INBAND_REQUIRED = BIT(2),
+ LINK_INBAND_DISABLE = BIT(0),
+ LINK_INBAND_ENABLE = BIT(1),
+ LINK_INBAND_BYPASS = BIT(2),
};
/**
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index 8664b3442a3a..40324cdb4353 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -472,8 +472,7 @@ struct phylink_pcs {
* (where necessary).
*/
struct phylink_pcs_ops {
- int (*pcs_validate)(struct phylink_pcs *pcs, unsigned int mode,
- unsigned long *supported,
+ int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported,
const struct phylink_link_state *state);
unsigned int (*pcs_query_inband)(struct phylink_pcs *pcs,
phy_interface_t interface);
@@ -498,7 +497,6 @@ struct phylink_pcs_ops {
/**
* pcs_validate() - validate the link configuration.
* @pcs: a pointer to a &struct phylink_pcs.
- * @mode: link autonegotiation mode
* @supported: ethtool bitmask for supported link modes.
* @state: a const pointer to a &struct phylink_link_state.
*
@@ -510,8 +508,8 @@ struct phylink_pcs_ops {
* Returns -EINVAL if the interface mode/autoneg mode is not supported.
* Returns non-zero positive if the link state can be supported.
*/
-int pcs_validate(struct phylink_pcs *pcs, unsigned int mode,
- unsigned long *supported, struct phylink_link_state *state);
+int pcs_validate(struct phylink_pcs *pcs, unsigned long *supported,
+ const struct phylink_link_state *state);
/**
* pcs_query_inband - query inband support for interface mode.
diff --git a/include/linux/sfp.h b/include/linux/sfp.h
index 9346cd44814d..a45da7eef9a2 100644
--- a/include/linux/sfp.h
+++ b/include/linux/sfp.h
@@ -554,7 +554,7 @@ bool sfp_may_have_phy(struct sfp_bus *bus, const struct sfp_eeprom_id *id);
void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
unsigned long *support, unsigned long *interfaces);
phy_interface_t sfp_select_interface(struct sfp_bus *bus,
- unsigned long *link_modes);
+ const unsigned long *link_modes);
int sfp_get_module_info(struct sfp_bus *bus, struct ethtool_modinfo *modinfo);
int sfp_get_module_eeprom(struct sfp_bus *bus, struct ethtool_eeprom *ee,
@@ -592,7 +592,7 @@ static inline void sfp_parse_support(struct sfp_bus *bus,
}
static inline phy_interface_t sfp_select_interface(struct sfp_bus *bus,
- unsigned long *link_modes)
+ const unsigned long *link_modes)
{
return PHY_INTERFACE_MODE_NA;
}