net: phylink: improve initial mac configuration
Improve the initial MAC configuration so we get a configuration which more represents the final operating mode, in particular with respect to the flow control settings. We do this by: 1) more fully initialising our phy state, so we can use this as the initial state for PHY based connections. 2) reading the fixed link state. 3) ensuring that in-band mode has sane pause settings for SGMII vs 802.3z negotiation modes. In all three cases, we ensure that state->link is false, just in case any MAC drivers have other ideas by mis-using this member, and we also take account of manual pause mode configuration at this point. This avoids MLO_PAUSE_AN being seen in mac_config() when operating in PHY, fixed mode or inband SGMII mode, thereby giving cleaner semantics to the pause flags. As a result of this, the pause flags now indicate in a mode-independent way what is required from a mac_config() implementation. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: hongrongxuan <hongrongxuan@huawei.com> Conflicts: drivers/net/phy/phylink.c
This commit is contained in:
parent
cca40c4a30
commit
202442fe4e
|
@ -421,6 +421,35 @@ static void phylink_get_fixed_state(struct phylink *pl,
|
||||||
phylink_resolve_flow(state);
|
phylink_resolve_flow(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void phylink_mac_initial_config(struct phylink *pl)
|
||||||
|
{
|
||||||
|
struct phylink_link_state link_state;
|
||||||
|
|
||||||
|
switch (pl->cur_link_an_mode) {
|
||||||
|
case MLO_AN_PHY:
|
||||||
|
link_state = pl->phy_state;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MLO_AN_FIXED:
|
||||||
|
phylink_get_fixed_state(pl, &link_state);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MLO_AN_INBAND:
|
||||||
|
link_state = pl->link_config;
|
||||||
|
if (link_state.interface == PHY_INTERFACE_MODE_SGMII)
|
||||||
|
link_state.pause = MLO_PAUSE_NONE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: /* can't happen */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
link_state.link = false;
|
||||||
|
|
||||||
|
phylink_apply_manual_flow(pl, &link_state);
|
||||||
|
phylink_mac_config(pl, &link_state);
|
||||||
|
}
|
||||||
|
|
||||||
static const char *phylink_pause_to_str(int pause)
|
static const char *phylink_pause_to_str(int pause)
|
||||||
{
|
{
|
||||||
switch (pause & MLO_PAUSE_TXRX_MASK) {
|
switch (pause & MLO_PAUSE_TXRX_MASK) {
|
||||||
|
@ -764,6 +793,9 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy)
|
||||||
mutex_lock(&phy->lock);
|
mutex_lock(&phy->lock);
|
||||||
mutex_lock(&pl->state_mutex);
|
mutex_lock(&pl->state_mutex);
|
||||||
pl->phydev = phy;
|
pl->phydev = phy;
|
||||||
|
pl->phy_state.pause = MLO_PAUSE_NONE;
|
||||||
|
pl->phy_state.speed = SPEED_UNKNOWN;
|
||||||
|
pl->phy_state.duplex = DUPLEX_UNKNOWN;
|
||||||
linkmode_copy(pl->supported, supported);
|
linkmode_copy(pl->supported, supported);
|
||||||
linkmode_copy(pl->link_config.advertising, config.advertising);
|
linkmode_copy(pl->link_config.advertising, config.advertising);
|
||||||
|
|
||||||
|
@ -990,7 +1022,7 @@ void phylink_start(struct phylink *pl)
|
||||||
* a fixed-link to start with the correct parameters, and also
|
* a fixed-link to start with the correct parameters, and also
|
||||||
* ensures that we set the appropriate advertisement for Serdes links.
|
* ensures that we set the appropriate advertisement for Serdes links.
|
||||||
*/
|
*/
|
||||||
phylink_mac_config(pl, &pl->link_config);
|
phylink_mac_initial_config(pl);
|
||||||
|
|
||||||
/* Restart autonegotiation if using 802.3z to ensure that the link
|
/* Restart autonegotiation if using 802.3z to ensure that the link
|
||||||
* parameters are properly negotiated. This is necessary for DSA
|
* parameters are properly negotiated. This is necessary for DSA
|
||||||
|
@ -1794,7 +1826,7 @@ static int phylink_sfp_module_insert(void *upstream,
|
||||||
|
|
||||||
if (changed && !test_bit(PHYLINK_DISABLE_STOPPED,
|
if (changed && !test_bit(PHYLINK_DISABLE_STOPPED,
|
||||||
&pl->phylink_disable_state))
|
&pl->phylink_disable_state))
|
||||||
phylink_mac_config(pl, &pl->link_config);
|
phylink_mac_initial_config(pl);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue