| b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame] | 1 | From d1339d6956f0255b6ce2412328a98945be8cc3ca Mon Sep 17 00:00:00 2001 | 
 | 2 | From: Russell King <rmk+kernel@armlinux.org.uk> | 
 | 3 | Date: Sat, 16 Nov 2019 11:30:18 +0000 | 
 | 4 | Subject: [PATCH 651/660] net: phylink: split link_an_mode configured and | 
 | 5 |  current settings | 
 | 6 |  | 
 | 7 | Split link_an_mode between the configured setting and the current | 
 | 8 | operating setting.  This is an important distinction to make when we | 
 | 9 | need to configure PHY mode for a plugged SFP+ module that does not | 
 | 10 | use in-band signalling. | 
 | 11 |  | 
 | 12 | Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | 
 | 13 | --- | 
 | 14 |  drivers/net/phy/phylink.c | 59 ++++++++++++++++++++------------------- | 
 | 15 |  1 file changed, 31 insertions(+), 28 deletions(-) | 
 | 16 |  | 
 | 17 | --- a/drivers/net/phy/phylink.c | 
 | 18 | +++ b/drivers/net/phy/phylink.c | 
 | 19 | @@ -48,7 +48,8 @@ struct phylink { | 
 | 20 |  	unsigned long phylink_disable_state; /* bitmask of disables */ | 
 | 21 |  	struct phy_device *phydev; | 
 | 22 |  	phy_interface_t link_interface;	/* PHY_INTERFACE_xxx */ | 
 | 23 | -	u8 link_an_mode;		/* MLO_AN_xxx */ | 
 | 24 | +	u8 cfg_link_an_mode;		/* MLO_AN_xxx */ | 
 | 25 | +	u8 cur_link_an_mode; | 
 | 26 |  	u8 link_port;			/* The current non-phy ethtool port */ | 
 | 27 |  	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported); | 
 | 28 |   | 
 | 29 | @@ -258,12 +259,12 @@ static int phylink_parse_mode(struct phy | 
 | 30 |   | 
 | 31 |  	dn = fwnode_get_named_child_node(fwnode, "fixed-link"); | 
 | 32 |  	if (dn || fwnode_property_present(fwnode, "fixed-link")) | 
 | 33 | -		pl->link_an_mode = MLO_AN_FIXED; | 
 | 34 | +		pl->cfg_link_an_mode = MLO_AN_FIXED; | 
 | 35 |  	fwnode_handle_put(dn); | 
 | 36 |   | 
 | 37 |  	if (fwnode_property_read_string(fwnode, "managed", &managed) == 0 && | 
 | 38 |  	    strcmp(managed, "in-band-status") == 0) { | 
 | 39 | -		if (pl->link_an_mode == MLO_AN_FIXED) { | 
 | 40 | +		if (pl->cfg_link_an_mode == MLO_AN_FIXED) { | 
 | 41 |  			phylink_err(pl, | 
 | 42 |  				    "can't use both fixed-link and in-band-status\n"); | 
 | 43 |  			return -EINVAL; | 
 | 44 | @@ -275,7 +276,7 @@ static int phylink_parse_mode(struct phy | 
 | 45 |  		phylink_set(pl->supported, Asym_Pause); | 
 | 46 |  		phylink_set(pl->supported, Pause); | 
 | 47 |  		pl->link_config.an_enabled = true; | 
 | 48 | -		pl->link_an_mode = MLO_AN_INBAND; | 
 | 49 | +		pl->cfg_link_an_mode = MLO_AN_INBAND; | 
 | 50 |   | 
 | 51 |  		switch (pl->link_config.interface) { | 
 | 52 |  		case PHY_INTERFACE_MODE_SGMII: | 
 | 53 | @@ -335,14 +336,14 @@ static void phylink_mac_config(struct ph | 
 | 54 |  { | 
 | 55 |  	phylink_dbg(pl, | 
 | 56 |  		    "%s: mode=%s/%s/%s/%s adv=%*pb pause=%02x link=%u an=%u\n", | 
 | 57 | -		    __func__, phylink_an_mode_str(pl->link_an_mode), | 
 | 58 | +		    __func__, phylink_an_mode_str(pl->cur_link_an_mode), | 
 | 59 |  		    phy_modes(state->interface), | 
 | 60 |  		    phy_speed_to_str(state->speed), | 
 | 61 |  		    phy_duplex_to_str(state->duplex), | 
 | 62 |  		    __ETHTOOL_LINK_MODE_MASK_NBITS, state->advertising, | 
 | 63 |  		    state->pause, state->link, state->an_enabled); | 
 | 64 |   | 
 | 65 | -	pl->ops->mac_config(pl->config, pl->link_an_mode, state); | 
 | 66 | +	pl->ops->mac_config(pl->config, pl->cur_link_an_mode, state); | 
 | 67 |  } | 
 | 68 |   | 
 | 69 |  static void phylink_mac_config_up(struct phylink *pl, | 
 | 70 | @@ -443,7 +444,7 @@ static void phylink_mac_link_up(struct p | 
 | 71 |  	struct net_device *ndev = pl->netdev; | 
 | 72 |   | 
 | 73 |  	pl->cur_interface = link_state.interface; | 
 | 74 | -	pl->ops->mac_link_up(pl->config, pl->link_an_mode, | 
 | 75 | +	pl->ops->mac_link_up(pl->config, pl->cur_link_an_mode, | 
 | 76 |  			     pl->cur_interface, pl->phydev); | 
 | 77 |   | 
 | 78 |  	if (ndev) | 
 | 79 | @@ -462,7 +463,7 @@ static void phylink_mac_link_down(struct | 
 | 80 |   | 
 | 81 |  	if (ndev) | 
 | 82 |  		netif_carrier_off(ndev); | 
 | 83 | -	pl->ops->mac_link_down(pl->config, pl->link_an_mode, | 
 | 84 | +	pl->ops->mac_link_down(pl->config, pl->cur_link_an_mode, | 
 | 85 |  			       pl->cur_interface); | 
 | 86 |  	phylink_info(pl, "Link is Down\n"); | 
 | 87 |  } | 
 | 88 | @@ -481,7 +482,7 @@ static void phylink_resolve(struct work_ | 
 | 89 |  	} else if (pl->mac_link_dropped) { | 
 | 90 |  		link_state.link = false; | 
 | 91 |  	} else { | 
 | 92 | -		switch (pl->link_an_mode) { | 
 | 93 | +		switch (pl->cur_link_an_mode) { | 
 | 94 |  		case MLO_AN_PHY: | 
 | 95 |  			link_state = pl->phy_state; | 
 | 96 |  			phylink_resolve_flow(pl, &link_state); | 
 | 97 | @@ -649,7 +650,7 @@ struct phylink *phylink_create(struct ph | 
 | 98 |  		return ERR_PTR(ret); | 
 | 99 |  	} | 
 | 100 |   | 
 | 101 | -	if (pl->link_an_mode == MLO_AN_FIXED) { | 
 | 102 | +	if (pl->cfg_link_an_mode == MLO_AN_FIXED) { | 
 | 103 |  		ret = phylink_parse_fixedlink(pl, fwnode); | 
 | 104 |  		if (ret < 0) { | 
 | 105 |  			kfree(pl); | 
 | 106 | @@ -657,6 +658,8 @@ struct phylink *phylink_create(struct ph | 
 | 107 |  		} | 
 | 108 |  	} | 
 | 109 |   | 
 | 110 | +	pl->cur_link_an_mode = pl->cfg_link_an_mode; | 
 | 111 | + | 
 | 112 |  	ret = phylink_register_sfp(pl, fwnode); | 
 | 113 |  	if (ret < 0) { | 
 | 114 |  		kfree(pl); | 
 | 115 | @@ -770,8 +773,8 @@ static int phylink_bringup_phy(struct ph | 
 | 116 |  static int phylink_attach_phy(struct phylink *pl, struct phy_device *phy, | 
 | 117 |  			      phy_interface_t interface) | 
 | 118 |  { | 
 | 119 | -	if (WARN_ON(pl->link_an_mode == MLO_AN_FIXED || | 
 | 120 | -		    (pl->link_an_mode == MLO_AN_INBAND && | 
 | 121 | +	if (WARN_ON(pl->cfg_link_an_mode == MLO_AN_FIXED || | 
 | 122 | +		    (pl->cfg_link_an_mode == MLO_AN_INBAND && | 
 | 123 |  		     phy_interface_mode_is_8023z(interface)))) | 
 | 124 |  		return -EINVAL; | 
 | 125 |   | 
 | 126 | @@ -838,8 +841,8 @@ int phylink_of_phy_connect(struct phylin | 
 | 127 |  	int ret; | 
 | 128 |   | 
 | 129 |  	/* Fixed links and 802.3z are handled without needing a PHY */ | 
 | 130 | -	if (pl->link_an_mode == MLO_AN_FIXED || | 
 | 131 | -	    (pl->link_an_mode == MLO_AN_INBAND && | 
 | 132 | +	if (pl->cfg_link_an_mode == MLO_AN_FIXED || | 
 | 133 | +	    (pl->cfg_link_an_mode == MLO_AN_INBAND && | 
 | 134 |  	     phy_interface_mode_is_8023z(pl->link_interface))) | 
 | 135 |  		return 0; | 
 | 136 |   | 
 | 137 | @@ -850,7 +853,7 @@ int phylink_of_phy_connect(struct phylin | 
 | 138 |  		phy_node = of_parse_phandle(dn, "phy-device", 0); | 
 | 139 |   | 
 | 140 |  	if (!phy_node) { | 
 | 141 | -		if (pl->link_an_mode == MLO_AN_PHY) | 
 | 142 | +		if (pl->cfg_link_an_mode == MLO_AN_PHY) | 
 | 143 |  			return -ENODEV; | 
 | 144 |  		return 0; | 
 | 145 |  	} | 
 | 146 | @@ -913,7 +916,7 @@ int phylink_fixed_state_cb(struct phylin | 
 | 147 |  	/* It does not make sense to let the link be overriden unless we use | 
 | 148 |  	 * MLO_AN_FIXED | 
 | 149 |  	 */ | 
 | 150 | -	if (pl->link_an_mode != MLO_AN_FIXED) | 
 | 151 | +	if (pl->cfg_link_an_mode != MLO_AN_FIXED) | 
 | 152 |  		return -EINVAL; | 
 | 153 |   | 
 | 154 |  	mutex_lock(&pl->state_mutex); | 
 | 155 | @@ -963,7 +966,7 @@ void phylink_start(struct phylink *pl) | 
 | 156 |  	ASSERT_RTNL(); | 
 | 157 |   | 
 | 158 |  	phylink_info(pl, "configuring for %s/%s link mode\n", | 
 | 159 | -		     phylink_an_mode_str(pl->link_an_mode), | 
 | 160 | +		     phylink_an_mode_str(pl->cur_link_an_mode), | 
 | 161 |  		     phy_modes(pl->link_config.interface)); | 
 | 162 |   | 
 | 163 |  	/* Always set the carrier off */ | 
 | 164 | @@ -986,7 +989,7 @@ void phylink_start(struct phylink *pl) | 
 | 165 |  	clear_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state); | 
 | 166 |  	phylink_run_resolve(pl); | 
 | 167 |   | 
 | 168 | -	if (pl->link_an_mode == MLO_AN_FIXED && pl->link_gpio) { | 
 | 169 | +	if (pl->cfg_link_an_mode == MLO_AN_FIXED && pl->link_gpio) { | 
 | 170 |  		int irq = gpiod_to_irq(pl->link_gpio); | 
 | 171 |   | 
 | 172 |  		if (irq > 0) { | 
 | 173 | @@ -1001,7 +1004,7 @@ void phylink_start(struct phylink *pl) | 
 | 174 |  		if (irq <= 0) | 
 | 175 |  			mod_timer(&pl->link_poll, jiffies + HZ); | 
 | 176 |  	} | 
 | 177 | -	if (pl->link_an_mode == MLO_AN_FIXED && pl->get_fixed_state) | 
 | 178 | +	if (pl->cfg_link_an_mode == MLO_AN_FIXED && pl->get_fixed_state) | 
 | 179 |  		mod_timer(&pl->link_poll, jiffies + HZ); | 
 | 180 |  	if (pl->phydev) | 
 | 181 |  		phy_start(pl->phydev); | 
 | 182 | @@ -1128,7 +1131,7 @@ int phylink_ethtool_ksettings_get(struct | 
 | 183 |   | 
 | 184 |  	linkmode_copy(kset->link_modes.supported, pl->supported); | 
 | 185 |   | 
 | 186 | -	switch (pl->link_an_mode) { | 
 | 187 | +	switch (pl->cur_link_an_mode) { | 
 | 188 |  	case MLO_AN_FIXED: | 
 | 189 |  		/* We are using fixed settings. Report these as the | 
 | 190 |  		 * current link settings - and note that these also | 
 | 191 | @@ -1200,7 +1203,7 @@ int phylink_ethtool_ksettings_set(struct | 
 | 192 |  		/* If we have a fixed link (as specified by firmware), refuse | 
 | 193 |  		 * to change link parameters. | 
 | 194 |  		 */ | 
 | 195 | -		if (pl->link_an_mode == MLO_AN_FIXED && | 
 | 196 | +		if (pl->cur_link_an_mode == MLO_AN_FIXED && | 
 | 197 |  		    (s->speed != pl->link_config.speed || | 
 | 198 |  		     s->duplex != pl->link_config.duplex)) | 
 | 199 |  			return -EINVAL; | 
 | 200 | @@ -1212,7 +1215,7 @@ int phylink_ethtool_ksettings_set(struct | 
 | 201 |  		__clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, config.advertising); | 
 | 202 |  	} else { | 
 | 203 |  		/* If we have a fixed link, refuse to enable autonegotiation */ | 
 | 204 | -		if (pl->link_an_mode == MLO_AN_FIXED) | 
 | 205 | +		if (pl->cur_link_an_mode == MLO_AN_FIXED) | 
 | 206 |  			return -EINVAL; | 
 | 207 |   | 
 | 208 |  		config.speed = SPEED_UNKNOWN; | 
 | 209 | @@ -1254,7 +1257,7 @@ int phylink_ethtool_ksettings_set(struct | 
 | 210 |  	 * configuration. For a fixed link, this isn't able to change any | 
 | 211 |  	 * parameters, which just leaves inband mode. | 
 | 212 |  	 */ | 
 | 213 | -	if (pl->link_an_mode == MLO_AN_INBAND && | 
 | 214 | +	if (pl->cur_link_an_mode == MLO_AN_INBAND && | 
 | 215 |  	    !test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) { | 
 | 216 |  		phylink_mac_config(pl, &pl->link_config); | 
 | 217 |  		phylink_mac_an_restart(pl); | 
 | 218 | @@ -1344,7 +1347,7 @@ int phylink_ethtool_set_pauseparam(struc | 
 | 219 |  				   pause->tx_pause); | 
 | 220 |  	} else if (!test_bit(PHYLINK_DISABLE_STOPPED, | 
 | 221 |  			     &pl->phylink_disable_state)) { | 
 | 222 | -		switch (pl->link_an_mode) { | 
 | 223 | +		switch (pl->cur_link_an_mode) { | 
 | 224 |  		case MLO_AN_FIXED: | 
 | 225 |  			/* Should we allow fixed links to change against the config? */ | 
 | 226 |  			phylink_resolve_flow(pl, config); | 
 | 227 | @@ -1551,7 +1554,7 @@ static int phylink_mii_read(struct phyli | 
 | 228 |  	struct phylink_link_state state; | 
 | 229 |  	int val = 0xffff; | 
 | 230 |   | 
 | 231 | -	switch (pl->link_an_mode) { | 
 | 232 | +	switch (pl->cur_link_an_mode) { | 
 | 233 |  	case MLO_AN_FIXED: | 
 | 234 |  		if (phy_id == 0) { | 
 | 235 |  			phylink_get_fixed_state(pl, &state); | 
 | 236 | @@ -1579,7 +1582,7 @@ static int phylink_mii_read(struct phyli | 
 | 237 |  static int phylink_mii_write(struct phylink *pl, unsigned int phy_id, | 
 | 238 |  			     unsigned int reg, unsigned int val) | 
 | 239 |  { | 
 | 240 | -	switch (pl->link_an_mode) { | 
 | 241 | +	switch (pl->cur_link_an_mode) { | 
 | 242 |  	case MLO_AN_FIXED: | 
 | 243 |  		break; | 
 | 244 |   | 
 | 245 | @@ -1753,10 +1756,10 @@ static int phylink_sfp_module_insert(voi | 
 | 246 |  		linkmode_copy(pl->link_config.advertising, config.advertising); | 
 | 247 |  	} | 
 | 248 |   | 
 | 249 | -	if (pl->link_an_mode != MLO_AN_INBAND || | 
 | 250 | +	if (pl->cur_link_an_mode != MLO_AN_INBAND || | 
 | 251 |  	    pl->link_config.interface != config.interface) { | 
 | 252 |  		pl->link_config.interface = config.interface; | 
 | 253 | -		pl->link_an_mode = MLO_AN_INBAND; | 
 | 254 | +		pl->cur_link_an_mode = MLO_AN_INBAND; | 
 | 255 |   | 
 | 256 |  		changed = true; | 
 | 257 |   |