@@ -1310,7 +1310,8 @@ void b53_port_event(struct dsa_switch *ds, int port)
EXPORT_SYMBOL(b53_port_event);
static void b53_phylink_get_caps(struct dsa_switch *ds, int port,
- struct phylink_config *config)
+ struct phylink_config *config,
+ phy_interface_t *default_interface)
{
struct b53_device *dev = ds->priv;
@@ -713,7 +713,8 @@ static u32 bcm_sf2_sw_get_phy_flags(struct dsa_switch *ds, int port)
}
static void bcm_sf2_sw_get_caps(struct dsa_switch *ds, int port,
- struct phylink_config *config)
+ struct phylink_config *config,
+ phy_interface_t *default_interface)
{
unsigned long *interfaces = config->supported_interfaces;
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
@@ -1462,7 +1462,8 @@ static void hellcreek_teardown(struct dsa_switch *ds)
}
static void hellcreek_phylink_get_caps(struct dsa_switch *ds, int port,
- struct phylink_config *config)
+ struct phylink_config *config,
+ phy_interface_t *default_interface)
{
struct hellcreek *hellcreek = ds->priv;
@@ -1492,7 +1492,8 @@ static int gswip_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
}
static void gswip_xrx200_phylink_get_caps(struct dsa_switch *ds, int port,
- struct phylink_config *config)
+ struct phylink_config *config,
+ phy_interface_t *default_interface)
{
switch (port) {
case 0:
@@ -1525,7 +1526,8 @@ static void gswip_xrx200_phylink_get_caps(struct dsa_switch *ds, int port,
}
static void gswip_xrx300_phylink_get_caps(struct dsa_switch *ds, int port,
- struct phylink_config *config)
+ struct phylink_config *config,
+ phy_interface_t *default_interface)
{
switch (port) {
case 0:
@@ -560,7 +560,8 @@ static int ksz_check_device_id(struct ksz_device *dev)
}
static void ksz_phylink_get_caps(struct dsa_switch *ds, int port,
- struct phylink_config *config)
+ struct phylink_config *config,
+ phy_interface_t *default_interface)
{
struct ksz_device *dev = ds->priv;
@@ -2914,7 +2914,8 @@ mt7531_cpu_port_config(struct dsa_switch *ds, int port)
}
static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
- struct phylink_config *config)
+ struct phylink_config *config,
+ phy_interface_t *default_interface)
{
struct mt7530_priv *priv = ds->priv;
@@ -819,7 +819,8 @@ static void mv88e6393x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
}
static void mv88e6xxx_get_caps(struct dsa_switch *ds, int port,
- struct phylink_config *config)
+ struct phylink_config *config,
+ phy_interface_t *default_interface)
{
struct mv88e6xxx_chip *chip = ds->priv;
@@ -937,7 +937,8 @@ static int felix_vlan_del(struct dsa_switch *ds, int port,
}
static void felix_phylink_get_caps(struct dsa_switch *ds, int port,
- struct phylink_config *config)
+ struct phylink_config *config,
+ phy_interface_t *default_interface)
{
struct ocelot *ocelot = ds->priv;
@@ -500,7 +500,8 @@ static enum dsa_tag_protocol ar9331_sw_get_tag_protocol(struct dsa_switch *ds,
}
static void ar9331_sw_phylink_get_caps(struct dsa_switch *ds, int port,
- struct phylink_config *config)
+ struct phylink_config *config,
+ phy_interface_t *default_interface)
{
config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
MAC_10 | MAC_100;
@@ -1749,7 +1749,8 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
}
static void qca8k_phylink_get_caps(struct dsa_switch *ds, int port,
- struct phylink_config *config)
+ struct phylink_config *config,
+ phy_interface_t *default_interface)
{
switch (port) {
case 0: /* 1st CPU port */
@@ -1024,7 +1024,8 @@ static int rtl8365mb_ext_config_forcemode(struct realtek_priv *priv, int port,
}
static void rtl8365mb_phylink_get_caps(struct dsa_switch *ds, int port,
- struct phylink_config *config)
+ struct phylink_config *config,
+ phy_interface_t *default_interface)
{
const struct rtl8365mb_extint *extint =
rtl8365mb_get_port_extint(ds->priv, port);
@@ -1390,7 +1390,8 @@ static void sja1105_mac_link_up(struct dsa_switch *ds, int port,
}
static void sja1105_phylink_get_caps(struct dsa_switch *ds, int port,
- struct phylink_config *config)
+ struct phylink_config *config,
+ phy_interface_t *default_interface)
{
struct sja1105_private *priv = ds->priv;
struct sja1105_xmii_params_entry *mii;
@@ -443,7 +443,8 @@ static void xrs700x_teardown(struct dsa_switch *ds)
}
static void xrs700x_phylink_get_caps(struct dsa_switch *ds, int port,
- struct phylink_config *config)
+ struct phylink_config *config,
+ phy_interface_t *default_interface)
{
switch (port) {
case 0:
@@ -848,7 +848,8 @@ struct dsa_switch_ops {
* PHYLINK integration
*/
void (*phylink_get_caps)(struct dsa_switch *ds, int port,
- struct phylink_config *config);
+ struct phylink_config *config,
+ phy_interface_t *default_interface);
void (*phylink_validate)(struct dsa_switch *ds, int port,
unsigned long *supported,
struct phylink_link_state *state);
@@ -1524,13 +1524,9 @@ static const struct phylink_mac_ops dsa_port_phylink_mac_ops = {
int dsa_port_phylink_create(struct dsa_port *dp)
{
struct dsa_switch *ds = dp->ds;
- phy_interface_t mode;
+ phy_interface_t mode, def_mode;
int err;
- err = of_get_phy_mode(dp->dn, &mode);
- if (err)
- mode = PHY_INTERFACE_MODE_NA;
-
/* Presence of phylink_mac_link_state or phylink_mac_an_restart is
* an indicator of a legacy phylink driver.
*/
@@ -1538,8 +1534,23 @@ int dsa_port_phylink_create(struct dsa_port *dp)
ds->ops->phylink_mac_an_restart)
dp->pl_config.legacy_pre_march2020 = true;
+ def_mode = PHY_INTERFACE_MODE_NA;
if (ds->ops->phylink_get_caps)
- ds->ops->phylink_get_caps(ds, dp->index, &dp->pl_config);
+ ds->ops->phylink_get_caps(ds, dp->index, &dp->pl_config,
+ &def_mode);
+
+ err = of_get_phy_mode(dp->dn, &mode);
+ if (err) {
+ /* We must not set the default mode for user ports as a PHY
+ * overrides the NA mode in phylink. Setting it here would
+ * prevent the interface mode being updated.
+ */
+ if (dp->type == DSA_PORT_TYPE_CPU ||
+ dp->type == DSA_PORT_TYPE_DSA)
+ mode = def_mode;
+ else
+ mode = PHY_INTERFACE_MODE_NA;
+ }
dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn),
mode, &dsa_port_phylink_mac_ops);
DSA port bindings allow for an optional phy interface mode. When an interface mode is not specified, DSA uses the NA interface mode type. However, phylink needs to know the parameters of the link, and this will become especially important when using phylink for ports that are devoid of all properties except the required "reg" property, so that phylink can select the maximum supported link settings. Without knowing the interface mode, phylink can't truely know the maximum link speed. Update the prototype for the phylink_get_caps method to allow drivers to report this information back to DSA, and update all DSA implementations function declarations to cater for this change. No code is added to the implementations. Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> --- drivers/net/dsa/b53/b53_common.c | 3 ++- drivers/net/dsa/bcm_sf2.c | 3 ++- drivers/net/dsa/hirschmann/hellcreek.c | 3 ++- drivers/net/dsa/lantiq_gswip.c | 6 ++++-- drivers/net/dsa/microchip/ksz_common.c | 3 ++- drivers/net/dsa/mt7530.c | 3 ++- drivers/net/dsa/mv88e6xxx/chip.c | 3 ++- drivers/net/dsa/ocelot/felix.c | 3 ++- drivers/net/dsa/qca/ar9331.c | 3 ++- drivers/net/dsa/qca8k.c | 3 ++- drivers/net/dsa/realtek/rtl8365mb.c | 3 ++- drivers/net/dsa/sja1105/sja1105_main.c | 3 ++- drivers/net/dsa/xrs700x/xrs700x.c | 3 ++- include/net/dsa.h | 3 ++- net/dsa/port.c | 23 +++++++++++++++++------ 15 files changed, 47 insertions(+), 21 deletions(-)