6505b680 | 19-Jan-2023 |
Vladimir Oltean <vladimir.oltean@nxp.com> |
net: mscc: ocelot: add MAC Merge layer support for VSC9959
Felix (VSC9959) has a DEV_GMII:MM_CONFIG block composed of 2 registers (ENABLE_CONFIG and VERIF_CONFIG). Because the MAC Merge statistics a
net: mscc: ocelot: add MAC Merge layer support for VSC9959
Felix (VSC9959) has a DEV_GMII:MM_CONFIG block composed of 2 registers (ENABLE_CONFIG and VERIF_CONFIG). Because the MAC Merge statistics and pMAC statistics are already in the Ocelot switch lib even if just Felix supports them, I'm adding support for the whole MAC Merge layer in the common Ocelot library too.
There is an interrupt (shared with the PTP interrupt) which signals changes to the MM verification state. This is done because the preemptible traffic classes should be committed to hardware only once the verification procedure has declared the link partner of being capable of receiving preemptible frames.
We implement ethtool getters and setters for the MAC Merge layer state. The "TX enabled" and "verify status" are taken from the IRQ handler, using a mutex to ensure serialized access.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
show more ...
|
a3bb8f52 | 20-Nov-2022 |
Colin Foster <colin.foster@in-advantage.com> |
net: mscc: ocelot: remove unnecessary exposure of stats structures
Since commit 4d1d157fb6a4 ("net: mscc: ocelot: share the common stat definitions between all drivers") there is no longer a need to
net: mscc: ocelot: remove unnecessary exposure of stats structures
Since commit 4d1d157fb6a4 ("net: mscc: ocelot: share the common stat definitions between all drivers") there is no longer a need to share the stats structures to the world. Relocate these definitions to inside ocelot_stats.c instead of a global include header.
Signed-off-by: Colin Foster <colin.foster@in-advantage.com> Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
show more ...
|
eca70102 | 11-Sep-2022 |
Vladimir Oltean <vladimir.oltean@nxp.com> |
net: dsa: felix: add support for changing DSA master
Changing the DSA master means different things depending on the tagging protocol in use.
For NPI mode ("ocelot" and "seville"), there is a singl
net: dsa: felix: add support for changing DSA master
Changing the DSA master means different things depending on the tagging protocol in use.
For NPI mode ("ocelot" and "seville"), there is a single port which can be configured as NPI, but DSA only permits changing the CPU port affinity of user ports one by one. So changing a user port to a different NPI port globally changes what the NPI port is, and breaks the user ports still using the old one.
To address this while still permitting the change of the NPI port, require that the user ports which are still affine to the old NPI port are down, and cannot be brought up until they are all affine to the same NPI port.
The tag_8021q mode ("ocelot-8021q") is more flexible, in that each user port can be freely assigned to one CPU port or to the other. This works by filtering host addresses towards both tag_8021q CPU ports, and then restricting the forwarding from a certain user port only to one of the two tag_8021q CPU ports.
Additionally, the 2 tag_8021q CPU ports can be placed in a LAG. This works by enabling forwarding via PGID_SRC from a certain user port towards the logical port ID containing both tag_8021q CPU ports, but then restricting forwarding per packet, via the LAG hash codes in PGID_AGGR, to either one or the other.
When we change the DSA master to a LAG device, DSA guarantees us that the LAG has at least one lower interface as a physical DSA master. But DSA masters can come and go as lowers of that LAG, and ds->ops->port_change_master() will not get called, because the DSA master is still the same (the LAG). So we need to hook into the ds->ops->port_lag_{join,leave} calls on the CPU ports and update the logical port ID of the LAG that user ports are assigned to.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
show more ...
|
4d1d157f | 08-Sep-2022 |
Vladimir Oltean <vladimir.oltean@nxp.com> |
net: mscc: ocelot: share the common stat definitions between all drivers
All switch families supported by the ocelot lib (ocelot, felix, seville) export the same registers so far. But for example fe
net: mscc: ocelot: share the common stat definitions between all drivers
All switch families supported by the ocelot lib (ocelot, felix, seville) export the same registers so far. But for example felix also has TSN counters, while the others don't.
To reduce the bloat even further, create an OCELOT_COMMON_STATS() macro which just lists all stats that are common between switches. The array elements are still replicated among all of vsc9959_stats_layout, vsc9953_stats_layout and ocelot_stats_layout.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
show more ...
|
b69cf1c6 | 08-Sep-2022 |
Vladimir Oltean <vladimir.oltean@nxp.com> |
net: mscc: ocelot: minimize definitions for stats
The current definition of struct ocelot_stat_layout is long-winded (4 lines per entry, and we have hundreds of entries), so we could make an effort
net: mscc: ocelot: minimize definitions for stats
The current definition of struct ocelot_stat_layout is long-winded (4 lines per entry, and we have hundreds of entries), so we could make an effort to use the C preprocessor and reduce the line count.
Create an implicit correspondence between enum ocelot_reg, which tells us the register address (SYS_COUNT_RX_OCTETS etc) and enum ocelot_stat which allows us to index the ocelot->stats array (OCELOT_STAT_RX_OCTETS etc), and don't require us to specify both when we define what stats each switch family has.
Create an OCELOT_STAT() macro that pairs only an enum ocelot_stat to an enum ocelot_reg, and an OCELOT_STAT_ETHTOOL() macro which also contains a name exported to the unstructured ethtool -S stringset API. For now, we define all counters as having the OCELOT_STAT_ETHTOOL() kind, but we will add more counters in the future which are not exported to the unstructured ethtool -S.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
show more ...
|
be5c13f2 | 08-Sep-2022 |
Vladimir Oltean <vladimir.oltean@nxp.com> |
net: mscc: ocelot: harmonize names of SYS_COUNT_TX_AGING and OCELOT_STAT_TX_AGED
The hardware counter is called C_TX_AGED, so rename SYS_COUNT_TX_AGING to SYS_COUNT_TX_AGED. This will become importa
net: mscc: ocelot: harmonize names of SYS_COUNT_TX_AGING and OCELOT_STAT_TX_AGED
The hardware counter is called C_TX_AGED, so rename SYS_COUNT_TX_AGING to SYS_COUNT_TX_AGED. This will become important since we want to minimize the way in which we declare struct ocelot_stat_layout elements, using the C preprocessor.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
show more ...
|
e32036e1 | 08-Sep-2022 |
Vladimir Oltean <vladimir.oltean@nxp.com> |
net: mscc: ocelot: add support for all sorts of standardized counters present in DSA
DSA is integrated with the new standardized ethtool -S --groups option, but the felix driver only exports unstruc
net: mscc: ocelot: add support for all sorts of standardized counters present in DSA
DSA is integrated with the new standardized ethtool -S --groups option, but the felix driver only exports unstructured statistics.
Reuse the array of 64-bit statistics collected by ocelot_check_stats_work(), but just export select values from it.
Since ocelot_check_stats_work() runs periodically to avoid 32-bit overflow, and the ethtool calling context is sleepable, we update the 64-bit stats one more time, to provide up-to-date values. The locking scheme with a mutex followed by a spinlock is a bit hard to digest, so we create and use a ocelot_port_stats_run() helper with a callback that populates the ethool stats group the caller is interested in.
The exported stats are: ethtool -S swp0 --groups eth-phy ethtool -S swp0 --groups eth-mac ethtool -S swp0 --groups eth-ctrl ethtool -S swp0 --groups rmon ethtool --include-statistics --show-pause swp0
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
show more ...
|
25027c84 | 08-Sep-2022 |
Vladimir Oltean <vladimir.oltean@nxp.com> |
net: dsa: felix: check the 32-bit PSFP stats against overflow
The Felix PSFP counters suffer from the same problem as the ocelot ndo_get_stats64 ones - they are 32-bit, so they can easily overflow a
net: dsa: felix: check the 32-bit PSFP stats against overflow
The Felix PSFP counters suffer from the same problem as the ocelot ndo_get_stats64 ones - they are 32-bit, so they can easily overflow and this can easily go undetected.
Add a custom hook in ocelot_check_stats_work() through which driver specific actions can be taken, and update the stats for the existing PSFP filters from that hook.
Previously, vsc9959_psfp_filter_add() and vsc9959_psfp_filter_del() were serialized with respect to each other via rtnl_lock(). However, with the new entry point into &psfp->sfi_list coming from the periodic worker, we now need an explicit mutex to serialize access to these lists.
We used to keep a struct felix_stream_filter_counters on stack, through which vsc9959_psfp_stats_get() - a FLOW_CLS_STATS callback - would retrieve data from vsc9959_psfp_counters_get(). We need to become smarter about that in 3 ways:
- we need to keep a persistent set of counters for each stream instead of keeping them on stack
- we need to promote those counters from u32 to u64, and create a procedure that properly keeps 64-bit counters. Since we clear the hardware counters anyway, and we poll every 2 seconds, a simple increment of a u64 counter with a u32 value will perfectly do the job.
- FLOW_CLS_STATS also expect incremental counters, so we also need to zeroize our u64 counters every time sch_flower calls us
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
show more ...
|
96980ff7 | 08-Sep-2022 |
Vladimir Oltean <vladimir.oltean@nxp.com> |
net: mscc: ocelot: make access to STAT_VIEW sleepable again
To support SPI-controlled switches in the future, access to SYS_STAT_CFG_STAT_VIEW needs to be done outside of any spinlock protected regi
net: mscc: ocelot: make access to STAT_VIEW sleepable again
To support SPI-controlled switches in the future, access to SYS_STAT_CFG_STAT_VIEW needs to be done outside of any spinlock protected region, but it still needs to be serialized (by a mutex).
Split the ocelot->stats_lock spinlock into a mutex that serializes indirect access to hardware registers (ocelot->stat_view_lock) and a spinlock that serializes access to the u64 ocelot->stats array.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
show more ...
|
d4c36765 | 16-Aug-2022 |
Vladimir Oltean <vladimir.oltean@nxp.com> |
net: mscc: ocelot: keep ocelot_stat_layout by reg address, not offset
With so many counter addresses recently discovered as being wrong, it is desirable to at least have a central database of inform
net: mscc: ocelot: keep ocelot_stat_layout by reg address, not offset
With so many counter addresses recently discovered as being wrong, it is desirable to at least have a central database of information, rather than two: one through the SYS_COUNT_* registers (used for ndo_get_stats64), and the other through the offset field of struct ocelot_stat_layout elements (used for ethtool -S).
The strategy will be to keep the SYS_COUNT_* definitions as the single source of truth, but for that we need to expand our current definitions to cover all registers. Then we need to convert the ocelot region creation logic, and stats worker, to the read semantics imposed by going through SYS_COUNT_* absolute register addresses, rather than offsets of 32-bit words relative to SYS_COUNT_RX_OCTETS (which should have been SYS_CNT, by the way).
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
show more ...
|
91904600 | 16-Aug-2022 |
Vladimir Oltean <vladimir.oltean@nxp.com> |
net: mscc: ocelot: make struct ocelot_stat_layout array indexable
The ocelot counters are 32-bit and require periodic reading, every 2 seconds, by ocelot_port_update_stats(), so that wraparounds are
net: mscc: ocelot: make struct ocelot_stat_layout array indexable
The ocelot counters are 32-bit and require periodic reading, every 2 seconds, by ocelot_port_update_stats(), so that wraparounds are detected.
Currently, the counters reported by ocelot_get_stats64() come from the 32-bit hardware counters directly, rather than from the 64-bit accumulated ocelot->stats, and this is a problem for their integrity.
The strategy is to make ocelot_get_stats64() able to cherry-pick individual stats from ocelot->stats the way in which it currently reads them out from SYS_COUNT_* registers. But currently it can't, because ocelot->stats is an opaque u64 array that's used only to feed data into ethtool -S.
To solve that problem, we need to make ocelot->stats indexable, and associate each element with an element of struct ocelot_stat_layout used by ethtool -S.
This makes ocelot_stat_layout a fat (and possibly sparse) array, so we need to change the way in which we access it. We no longer need OCELOT_STAT_END as a sentinel, because we know the array's size (OCELOT_NUM_STATS). We just need to skip the array elements that were left unpopulated for the switch revision (ocelot, felix, seville).
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
show more ...
|
22d842e3 | 16-Aug-2022 |
Vladimir Oltean <vladimir.oltean@nxp.com> |
net: mscc: ocelot: turn stats_lock into a spinlock
ocelot_get_stats64() currently runs unlocked and therefore may collide with ocelot_port_update_stats() which indirectly accesses the same counters.
net: mscc: ocelot: turn stats_lock into a spinlock
ocelot_get_stats64() currently runs unlocked and therefore may collide with ocelot_port_update_stats() which indirectly accesses the same counters. However, ocelot_get_stats64() runs in atomic context, and we cannot simply take the sleepable ocelot->stats_lock mutex. We need to convert it to an atomic spinlock first. Do that as a preparatory change.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
show more ...
|
a4e044dc | 21-May-2022 |
Vladimir Oltean <vladimir.oltean@nxp.com> |
net: dsa: felix: tag_8021q preparation for multiple CPU ports
Update the VCAP filters to support multiple tag_8021q CPU ports.
TX works using a filter for VLAN ID on the ingress of the CPU port, wi
net: dsa: felix: tag_8021q preparation for multiple CPU ports
Update the VCAP filters to support multiple tag_8021q CPU ports.
TX works using a filter for VLAN ID on the ingress of the CPU port, with a redirect and a VLAN pop action. This can be updated trivially by amending the ingress port mask of this rule to match on all tag_8021q CPU ports.
RX works using a filter for ingress port on the egress of the CPU port, with a VLAN push action. Here we need to replicate these filters for each tag_8021q CPU port, and let them all have the same action. This means that the OCELOT_VCAP_ES0_TAG_8021Q_RXVLAN() cookie needs to encode a unique value for every {user port, CPU port} pair it's given. Do this by encoding the CPU port in the upper 16 bits of the cookie, and the user port in the lower 16 bits.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
show more ...
|
c295f983 | 21-May-2022 |
Vladimir Oltean <vladimir.oltean@nxp.com> |
net: mscc: ocelot: switch from {,un}set to {,un}assign for tag_8021q CPU ports
There is a desire for the felix driver to gain support for multiple tag_8021q CPU ports, but the current model prevents
net: mscc: ocelot: switch from {,un}set to {,un}assign for tag_8021q CPU ports
There is a desire for the felix driver to gain support for multiple tag_8021q CPU ports, but the current model prevents it.
This is because ocelot_apply_bridge_fwd_mask() only takes into consideration whether a port is a tag_8021q CPU port, but not whose CPU port it is.
We need a model where we can have a direct affinity between an ocelot port and a tag_8021q CPU port. This serves as the basis for multiple CPU ports.
Declare a "dsa_8021q_cpu" backpointer in struct ocelot_port which encodes that affinity. Repurpose the "ocelot_set_dsa_8021q_cpu" API to "ocelot_assign_dsa_8021q_cpu" to express the change of paradigm.
Note that this change makes the first practical use of the new ocelot_port->index field in ocelot_port_unassign_dsa_8021q_cpu(), where we need to remove the old tag_8021q CPU port from the reserved VLAN range.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
show more ...
|