Skip to content

Commit

Permalink
net: pcs: rzn1-miic: update speed only if interface is changed
Browse files Browse the repository at this point in the history
As stated by Russel King, miic_config() can be called as a result of
ethtool setting the configuration while the link is already up. Since
the speed is also set in this function, it could potentially modify
the current speed that is set. This will only happen if there is
no PHY present and we aren't using fixed-link mode.

Handle that by storing the current interface mode in the miic_port
structure and update the speed only if the interface mode is going to
be changed.

Signed-off-by: Clément Léger <clement.leger@bootlin.com>
Link: https://lore.kernel.org/r/20220629122003.189397-1-clement.leger@bootlin.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Clément Léger authored and Jakub Kicinski committed Jul 2, 2022
1 parent b140569 commit 90c74f4
Showing 1 changed file with 16 additions and 5 deletions.
21 changes: 16 additions & 5 deletions drivers/net/pcs/pcs-rzn1-miic.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,13 @@ struct miic {
* @miic: backiling to MII converter structure
* @pcs: PCS structure associated to the port
* @port: port number
* @interface: interface mode of the port
*/
struct miic_port {
struct miic *miic;
struct phylink_pcs pcs;
int port;
phy_interface_t interface;
};

static struct miic_port *phylink_pcs_to_miic_port(struct phylink_pcs *pcs)
Expand Down Expand Up @@ -190,8 +192,8 @@ static int miic_config(struct phylink_pcs *pcs, unsigned int mode,
{
struct miic_port *miic_port = phylink_pcs_to_miic_port(pcs);
struct miic *miic = miic_port->miic;
u32 speed, conv_mode, val, mask;
int port = miic_port->port;
u32 speed, conv_mode, val;

switch (interface) {
case PHY_INTERFACE_MODE_RMII:
Expand All @@ -216,11 +218,20 @@ static int miic_config(struct phylink_pcs *pcs, unsigned int mode,
return -EOPNOTSUPP;
}

val = FIELD_PREP(MIIC_CONVCTRL_CONV_MODE, conv_mode) |
FIELD_PREP(MIIC_CONVCTRL_CONV_SPEED, speed);
val = FIELD_PREP(MIIC_CONVCTRL_CONV_MODE, conv_mode);
mask = MIIC_CONVCTRL_CONV_MODE;

miic_reg_rmw(miic, MIIC_CONVCTRL(port),
MIIC_CONVCTRL_CONV_MODE | MIIC_CONVCTRL_CONV_SPEED, val);
/* Update speed only if we are going to change the interface because
* the link might already be up and it would break it if the speed is
* changed.
*/
if (interface != miic_port->interface) {
val |= FIELD_PREP(MIIC_CONVCTRL_CONV_SPEED, speed);
mask |= MIIC_CONVCTRL_CONV_SPEED;
miic_port->interface = interface;
}

miic_reg_rmw(miic, MIIC_CONVCTRL(port), mask, val);
miic_converter_enable(miic_port->miic, miic_port->port, 1);

return 0;
Expand Down

0 comments on commit 90c74f4

Please sign in to comment.