PCS driver registers each SerDes as an fwnode_pcs provider in probe;
the resolver returns the cached or freshly-allocated rtpcs_link for
the requested (sds, link_idx) cell. DSA glue stops calling
rtpcs_create directly, drops .mac_select_pcs, and instead populates
phylink_config.num_available_pcs / fill_available_pcs from each
port's pcs-handle in phylink_get_caps. The rtl838x_port.pcs pointer
becomes a has_pcs bool populated at port probe via fwnode_property_
present, since nothing assigns the actual phylink_pcs anymore but the
"does this port use a PCS?" checks elsewhere still need a presence
flag.
Without .mac_select_pcs, phylink_major_config only searches the
pcs_list when state->interface is set in phylink_config.pcs_interfaces
(drivers/net/phy/phylink.c:1378). Populate it per port whenever the
port has a pcs-handle, listing the SerDes-routable interface modes for
each SoC variant -- without this, pcs_config / pcs_link_up are never
called and the SerDes is left unconfigured.
pcs_get_state still needs the MAC port number to index per-port link
status registers. Recover it at probe via rtpcs_map_links: walk the
sibling switch's ethernet-ports subtree (same backwards topology
lookup the sibling MDIO driver does for phy-handle), and for every
port whose pcs-handle resolves to one of our SerDes, store the port's
reg in sds->link_port[]. The resolver consults link_port[] when
allocating rtpcs_link and fails with -ENODEV if a consumer requested
a link the map step didn't record. Avoids a driver-side port_base
table that would have to encode per-SoC SerDes-to-port wiring (and
would silently break on non-contiguous variants); the DT is the
single source of truth.
Kconfig selects FWNODE_PCS.
Assisted-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Link: https://github.com/openwrt/openwrt/pull/23539
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
The rtldsa_port_xstp_state_set() function offers a generic interface
to its callers to set the bridge state of one port. While it calls
device specific helpers in the background it runs the data mapping
for each architecture with a family_id check on its own. So the
hardware abstraction is done in two places
- rtldsa_port_xstp_state_set() translates one half
- its helper translate the other half
Convert the signature of the device specific helpers so that this
function does not need to know any hardware details. Instead move
the table/offset/bit calculations into the helpers. This way the
code path uses a consistent hardware abstraction.
- rtldsa_port_xstp_state_set() calls the helpers
- helpers do the hardware translation
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/23080
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
The rtl838x.h header is needed for all targets and not only RTL838x
specific. Rename it to rtl-otto.h to make clear that this is a
generic include.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/22931
Signed-off-by: Robert Marko <robimarko@gmail.com>
There are currently two header files for the dsa driver. rtl83xx.h
and rtl838x.h. It is unclear for what reason they are separated.
Especially as one always includes the other. Merge those two files
into one.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/22931
Signed-off-by: Robert Marko <robimarko@gmail.com>
There is only one check left for that attribute in rtldsa_port_mdb_add().
Split the consumer into device specific implementations and remove the
attribute from the private structure.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/22794
Signed-off-by: Robert Marko <robimarko@gmail.com>
For a long time the dsa driver has been providing a builtin mdio bus
via dsa default attribute user_mii_bus. This simply uses read/write
commands from the standard realtek otto bus (aka parent). The reason
has always been unclear.
Looking around the kernel 6.18 codebase there is only one case where
this is really needed. The only consumer is dsa_user_phy_setup().
ret = phylink_of_phy_connect(dp->pl, port_dn, phy_flags);
if (ret == -ENODEV && ds->user_mii_bus) {
/* We could not connect to a designated PHY or SFP, so try to
* use the switch internal MDIO bus instead
*/
ret = dsa_user_phy_connect(user_dev, dp->index, phy_flags);
}
Luckily the phylink_of_phy_connect() works fine and the internal bus
access is not needed at all. No need to keep the bus alive. Drop it.
While we are here fix the error handling issue of this code
if (!of_device_is_available(dn))
ret = -ENODEV;
Returncode was set to error but never handed back to the caller.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/22799
Signed-off-by: Robert Marko <robimarko@gmail.com>
Another two variables that are not part of the runtime but the
configuration structure. Move them around.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/22749
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
The fib_entries attribute is a device specific constant.
Therefore move it into the configuration structure. Add
a comment why someone used 16K fib_entries for RTL931x
instead of the possible 32K.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/22438
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
The port_width attribute is only used once and can be derived
from the cpu_port. Drop it. Add a comment for better readability.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/22438
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
The cpu_port is a per-device constant. Thus move it from the
instance structure to the config structure.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/22438
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
The dsa driver currently has different attributes to denote what
hardware is around a port:
- phy_is_integrated: true if phy is not driven by a serdes
- phy: the type of the attached phy (e.g. 0=NONE, 2=RTL8218B, ....)
- pcs: link to a serdes pcs instance
This is somehow redundant and especially the phy type should be only
part of the phy driver and is not needed by the dsa driver at all.
Remove the redundancy by simply keeping a boolean attribute "phy" that
flags a phy driven port and can be used similar to the pcs (pointer)
attribute. With that the driver can check phy/pcs as follows:
- if (ports[i].pcs) -> port has a dedicated serdes
- if (ports[i].phy) -> port has a dedicated phy
That implemented, the "phy-is-integrated" attribute of a phy can be
removed from the dts. This will be a separate commit. As a side effect
the following (annoying) boot message for kernel 6.18 gets fixed.
OF: /switchcore@1b000000/mdio-controller/mdio-bus@0/ethernet-phy@24:
Read of boolean property 'sfp' with a value.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/22698
Signed-off-by: Robert Marko <robimarko@gmail.com>
Between 6.12 and 6.18, several DSA switch ops have changed.
phylink_mac_* ops were moved out of dsa_switch_ops into dsa_switch using
phylink_mac_ops. Add new definitions for that and adjust the callbacks
accordingly to work with the different signatures.
get_mac_eee() has been dropped and support_eee() was added.
remove_new() has been dropped completely, allowing us to use remove()
again.
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/21181
Signed-off-by: Robert Marko <robimarko@gmail.com>
This is an automatically generated commit.
When doing `git bisect`, consider `git bisect --skip`.
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/21181
Signed-off-by: Robert Marko <robimarko@gmail.com>