Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'phylink-link-callback-replay-helpers-for-sja1105-and-xpcs'

Vladimir Oltean says:

====================
Phylink link callback replay helpers for SJA1105 and XPCS

The sja1105 is reducing its direct interaction with the XPCS.

The changes presented here are an older simplification idea, broken out
of a previous patch set to allow for more thorough review.
====================

Link: https://patch.msgid.link/20260119121954.1624535-1-vladimir.oltean@nxp.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+80 -84
+11 -73
drivers/net/dsa/sja1105/sja1105_main.c
··· 1260 1260 int speed_mbps) 1261 1261 { 1262 1262 struct sja1105_mac_config_entry *mac; 1263 + struct device *dev = priv->ds->dev; 1263 1264 u64 speed; 1265 + int rc; 1264 1266 1265 1267 /* On P/Q/R/S, one can read from the device via the MAC reconfiguration 1266 1268 * tables. On E/T, MAC reconfig tables are not readable, only writable. ··· 1306 1304 * we want auto during upload phase). 1307 1305 */ 1308 1306 mac[port].speed = speed; 1309 - 1310 - return 0; 1311 - } 1312 - 1313 - /* Write the MAC Configuration Table entry and, if necessary, the CGU settings, 1314 - * after a link speedchange for this port. 1315 - */ 1316 - static int sja1105_set_port_config(struct sja1105_private *priv, int port) 1317 - { 1318 - struct sja1105_mac_config_entry *mac; 1319 - struct device *dev = priv->ds->dev; 1320 - int rc; 1321 - 1322 - /* On P/Q/R/S, one can read from the device via the MAC reconfiguration 1323 - * tables. On E/T, MAC reconfig tables are not readable, only writable. 1324 - * We have to *know* what the MAC looks like. For the sake of keeping 1325 - * the code common, we'll use the static configuration tables as a 1326 - * reasonable approximation for both E/T and P/Q/R/S. 1327 - */ 1328 - mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries; 1329 1307 1330 1308 /* Write to the dynamic reconfiguration tables */ 1331 1309 rc = sja1105_dynamic_config_write(priv, BLK_IDX_MAC_CONFIG, port, ··· 1362 1380 struct sja1105_private *priv = dp->ds->priv; 1363 1381 int port = dp->index; 1364 1382 1365 - if (!sja1105_set_port_speed(priv, port, speed)) 1366 - sja1105_set_port_config(priv, port); 1367 - 1383 + sja1105_set_port_speed(priv, port, speed); 1368 1384 sja1105_inhibit_tx(priv, BIT(port), false); 1369 1385 } 1370 1386 ··· 2260 2280 { 2261 2281 struct ptp_system_timestamp ptp_sts_before; 2262 2282 struct ptp_system_timestamp ptp_sts_after; 2263 - u16 bmcr[SJA1105_MAX_NUM_PORTS] = {0}; 2264 - u64 mac_speed[SJA1105_MAX_NUM_PORTS]; 2265 2283 struct sja1105_mac_config_entry *mac; 2266 2284 struct dsa_switch *ds = priv->ds; 2285 + struct dsa_port *dp; 2267 2286 s64 t1, t2, t3, t4; 2268 - s64 t12, t34; 2269 - int rc, i; 2270 - s64 now; 2287 + s64 t12, t34, now; 2288 + int rc; 2271 2289 2272 2290 mutex_lock(&priv->fdb_lock); 2273 2291 mutex_lock(&priv->mgmt_lock); ··· 2277 2299 * switch wants to see in the static config in order to allow us to 2278 2300 * change it through the dynamic interface later. 2279 2301 */ 2280 - for (i = 0; i < ds->num_ports; i++) { 2281 - mac_speed[i] = mac[i].speed; 2282 - mac[i].speed = priv->info->port_speed[SJA1105_SPEED_AUTO]; 2283 - 2284 - if (priv->pcs[i]) 2285 - bmcr[i] = mdiobus_c45_read(priv->mdio_pcs, i, 2286 - MDIO_MMD_VEND2, MDIO_CTRL1); 2302 + dsa_switch_for_each_available_port(dp, ds) { 2303 + phylink_replay_link_begin(dp->pl); 2304 + mac[dp->index].speed = priv->info->port_speed[SJA1105_SPEED_AUTO]; 2287 2305 } 2288 2306 2289 2307 /* No PTP operations can run right now */ ··· 2333 2359 goto out; 2334 2360 } 2335 2361 2336 - for (i = 0; i < ds->num_ports; i++) { 2337 - struct phylink_pcs *pcs = priv->pcs[i]; 2338 - unsigned int neg_mode; 2339 - 2340 - mac[i].speed = mac_speed[i]; 2341 - rc = sja1105_set_port_config(priv, i); 2342 - if (rc < 0) 2343 - goto out; 2344 - 2345 - if (!pcs) 2346 - continue; 2347 - 2348 - if (bmcr[i] & BMCR_ANENABLE) 2349 - neg_mode = PHYLINK_PCS_NEG_INBAND_ENABLED; 2350 - else 2351 - neg_mode = PHYLINK_PCS_NEG_OUTBAND; 2352 - 2353 - rc = pcs->ops->pcs_config(pcs, neg_mode, priv->phy_mode[i], 2354 - NULL, true); 2355 - if (rc < 0) 2356 - goto out; 2357 - 2358 - if (neg_mode == PHYLINK_PCS_NEG_OUTBAND) { 2359 - int speed = SPEED_UNKNOWN; 2360 - 2361 - if (priv->phy_mode[i] == PHY_INTERFACE_MODE_2500BASEX) 2362 - speed = SPEED_2500; 2363 - else if (bmcr[i] & BMCR_SPEED1000) 2364 - speed = SPEED_1000; 2365 - else if (bmcr[i] & BMCR_SPEED100) 2366 - speed = SPEED_100; 2367 - else 2368 - speed = SPEED_10; 2369 - 2370 - pcs->ops->pcs_link_up(pcs, neg_mode, priv->phy_mode[i], 2371 - speed, DUPLEX_FULL); 2372 - } 2373 - } 2362 + dsa_switch_for_each_available_port(dp, ds) 2363 + phylink_replay_link_end(dp->pl); 2374 2364 2375 2365 rc = sja1105_reload_cbs(priv); 2376 2366 if (rc < 0)
+64 -11
drivers/net/phy/phylink.c
··· 28 28 PHYLINK_DISABLE_STOPPED, 29 29 PHYLINK_DISABLE_LINK, 30 30 PHYLINK_DISABLE_MAC_WOL, 31 + PHYLINK_DISABLE_REPLAY, 31 32 32 33 PCS_STATE_DOWN = 0, 33 34 PCS_STATE_STARTING, ··· 78 77 79 78 bool link_failed; 80 79 bool suspend_link_up; 80 + bool force_major_config; 81 81 bool major_config_failed; 82 82 bool mac_supports_eee_ops; 83 83 bool mac_supports_eee; ··· 1686 1684 if (pl->act_link_an_mode != MLO_AN_FIXED) 1687 1685 phylink_apply_manual_flow(pl, &link_state); 1688 1686 1689 - if (mac_config) { 1690 - if (link_state.interface != pl->link_config.interface) { 1691 - /* The interface has changed, force the link down and 1692 - * then reconfigure. 1693 - */ 1694 - if (cur_link_state) { 1695 - phylink_link_down(pl); 1696 - cur_link_state = false; 1697 - } 1698 - phylink_major_config(pl, false, &link_state); 1699 - pl->link_config.interface = link_state.interface; 1687 + if ((mac_config && link_state.interface != pl->link_config.interface) || 1688 + pl->force_major_config) { 1689 + /* The interface has changed or a forced major configuration 1690 + * was requested, so force the link down and then reconfigure. 1691 + */ 1692 + if (cur_link_state) { 1693 + phylink_link_down(pl); 1694 + cur_link_state = false; 1700 1695 } 1696 + phylink_major_config(pl, false, &link_state); 1697 + pl->link_config.interface = link_state.interface; 1698 + pl->force_major_config = false; 1701 1699 } 1702 1700 1703 1701 /* If configuration of the interface failed, force the link down ··· 4360 4358 } 4361 4359 } 4362 4360 EXPORT_SYMBOL_GPL(phylink_mii_c45_pcs_get_state); 4361 + 4362 + /** 4363 + * phylink_replay_link_begin() - begin replay of link callbacks for driver 4364 + * which loses state 4365 + * @pl: a pointer to a &struct phylink returned from phylink_create() 4366 + * 4367 + * Helper for MAC drivers which may perform a destructive reset at runtime. 4368 + * Both the own driver's mac_link_down() method is called, as well as the 4369 + * pcs_link_down() method of the split PCS (if any). 4370 + * 4371 + * This is similar to phylink_stop(), except it does not alter the state of 4372 + * the phylib PHY (it is assumed that it is not affected by the MAC destructive 4373 + * reset). 4374 + */ 4375 + void phylink_replay_link_begin(struct phylink *pl) 4376 + { 4377 + ASSERT_RTNL(); 4378 + 4379 + phylink_run_resolve_and_disable(pl, PHYLINK_DISABLE_REPLAY); 4380 + } 4381 + EXPORT_SYMBOL_GPL(phylink_replay_link_begin); 4382 + 4383 + /** 4384 + * phylink_replay_link_end() - end replay of link callbacks for driver 4385 + * which lost state 4386 + * @pl: a pointer to a &struct phylink returned from phylink_create() 4387 + * 4388 + * Helper for MAC drivers which may perform a destructive reset at runtime. 4389 + * Both the own driver's mac_config() and mac_link_up() methods, as well as the 4390 + * pcs_config() and pcs_link_up() method of the split PCS (if any), are called. 4391 + * 4392 + * This is similar to phylink_start(), except it does not alter the state of 4393 + * the phylib PHY. 4394 + * 4395 + * One must call this method only within the same rtnl_lock() critical section 4396 + * as a previous phylink_replay_link_start(). 4397 + */ 4398 + void phylink_replay_link_end(struct phylink *pl) 4399 + { 4400 + ASSERT_RTNL(); 4401 + 4402 + if (WARN(!test_bit(PHYLINK_DISABLE_REPLAY, 4403 + &pl->phylink_disable_state), 4404 + "phylink_replay_link_end() called without a prior phylink_replay_link_begin()\n")) 4405 + return; 4406 + 4407 + pl->force_major_config = true; 4408 + phylink_enable_and_run_resolve(pl, PHYLINK_DISABLE_REPLAY); 4409 + flush_work(&pl->resolve); 4410 + } 4411 + EXPORT_SYMBOL_GPL(phylink_replay_link_end); 4363 4412 4364 4413 static int __init phylink_init(void) 4365 4414 {
+5
include/linux/phylink.h
··· 837 837 838 838 void phylink_decode_usxgmii_word(struct phylink_link_state *state, 839 839 uint16_t lpa); 840 + 841 + void phylink_replay_link_begin(struct phylink *pl); 842 + 843 + void phylink_replay_link_end(struct phylink *pl); 844 + 840 845 #endif