mirror of https://gitee.com/openkylin/linux.git
net: phylink: in-band pause mode advertisement update for PCS
Re-code the pause in-band advertisement update in light of the addition of PCS support, so that we perform the minimum required; only the PCS configuration function needs to be called in this case, followed by the request to trigger a restart of negotiation if the programmed advertisement changed. We need to change the pcs_config() signature to pass whether resolved pause should be passed to the MAC for setups such as mvneta and mvpp2 where doing so overrides the MAC manual flow controls. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
1e1bf14a89
commit
1571e700fd
|
@ -441,7 +441,9 @@ static void phylink_pcs_config(struct phylink *pl, bool force_restart,
|
|||
if (pl->pcs_ops && pl->pcs_ops->pcs_config(pl->config,
|
||||
pl->cur_link_an_mode,
|
||||
state->interface,
|
||||
state->advertising))
|
||||
state->advertising,
|
||||
!!(pl->link_config.pause &
|
||||
MLO_PAUSE_AN)))
|
||||
restart = true;
|
||||
|
||||
phylink_mac_config(pl, state);
|
||||
|
@ -450,6 +452,49 @@ static void phylink_pcs_config(struct phylink *pl, bool force_restart,
|
|||
phylink_mac_pcs_an_restart(pl);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reconfigure for a change of inband advertisement.
|
||||
* If we have a separate PCS, we only need to call its pcs_config() method,
|
||||
* and then restart AN if it indicates something changed. Otherwise, we do
|
||||
* the full MAC reconfiguration.
|
||||
*/
|
||||
static int phylink_change_inband_advert(struct phylink *pl)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state))
|
||||
return 0;
|
||||
|
||||
if (!pl->pcs_ops) {
|
||||
/* Legacy method */
|
||||
phylink_mac_config(pl, &pl->link_config);
|
||||
phylink_mac_pcs_an_restart(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),
|
||||
phy_modes(pl->link_config.interface),
|
||||
__ETHTOOL_LINK_MODE_MASK_NBITS, pl->link_config.advertising,
|
||||
pl->link_config.pause);
|
||||
|
||||
/* Modern PCS-based method; update the advert at the PCS, and
|
||||
* restart negotiation if the pcs_config() helper indicates that
|
||||
* the programmed advertisement has changed.
|
||||
*/
|
||||
ret = pl->pcs_ops->pcs_config(pl->config, pl->cur_link_an_mode,
|
||||
pl->link_config.interface,
|
||||
pl->link_config.advertising,
|
||||
!!(pl->link_config.pause & MLO_PAUSE_AN));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (ret > 0)
|
||||
phylink_mac_pcs_an_restart(pl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void phylink_mac_pcs_get_state(struct phylink *pl,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
|
@ -1524,9 +1569,11 @@ int phylink_ethtool_set_pauseparam(struct phylink *pl,
|
|||
|
||||
config->pause = pause_state;
|
||||
|
||||
if (!pl->phydev && !test_bit(PHYLINK_DISABLE_STOPPED,
|
||||
&pl->phylink_disable_state))
|
||||
phylink_pcs_config(pl, true, &pl->link_config);
|
||||
/* Update our in-band advertisement, triggering a renegotiation if
|
||||
* the advertisement changed.
|
||||
*/
|
||||
if (!pl->phydev)
|
||||
phylink_change_inband_advert(pl);
|
||||
|
||||
mutex_unlock(&pl->state_mutex);
|
||||
|
||||
|
|
|
@ -286,7 +286,8 @@ struct phylink_pcs_ops {
|
|||
struct phylink_link_state *state);
|
||||
int (*pcs_config)(struct phylink_config *config, unsigned int mode,
|
||||
phy_interface_t interface,
|
||||
const unsigned long *advertising);
|
||||
const unsigned long *advertising,
|
||||
bool permit_pause_to_mac);
|
||||
void (*pcs_an_restart)(struct phylink_config *config);
|
||||
void (*pcs_link_up)(struct phylink_config *config, unsigned int mode,
|
||||
phy_interface_t interface, int speed, int duplex);
|
||||
|
@ -317,9 +318,11 @@ void pcs_get_state(struct phylink_config *config,
|
|||
* @mode: one of %MLO_AN_FIXED, %MLO_AN_PHY, %MLO_AN_INBAND.
|
||||
* @interface: interface mode to be used
|
||||
* @advertising: adertisement ethtool link mode mask
|
||||
* @permit_pause_to_mac: permit forwarding pause resolution to MAC
|
||||
*
|
||||
* Configure the PCS for the operating mode, the interface mode, and set
|
||||
* the advertisement mask.
|
||||
* the advertisement mask. @permit_pause_to_mac indicates whether the
|
||||
* hardware may forward the pause mode resolution to the MAC.
|
||||
*
|
||||
* When operating in %MLO_AN_INBAND, inband should always be enabled,
|
||||
* otherwise inband should be disabled.
|
||||
|
|
Loading…
Reference in New Issue