Message ID | 20211126172739.329098-4-clement.leger@bootlin.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | Add FDMA support on ocelot switch driver | expand |
Context | Check | Description |
---|---|---|
netdev/tree_selection | success | Clearly marked for net-next |
netdev/apply | fail | Patch does not apply to net-next |
On Fri, Nov 26, 2021 at 06:27:38PM +0100, Clément Léger wrote: > IFH preparation can take quite some time on slow processors (up to 5% in > a iperf3 test for instance). In order to reduce the cost of this > preparation, pre-compute IFH since most of the parameters are fixed per > port. Only rew_op and vlan tag will be set when sending if different > than 0. This allows to remove entirely the calls to packing() with basic > usage. In the same time, export this function that will be used by FDMA. > > Signed-off-by: Clément Léger <clement.leger@bootlin.com> > --- If you would move this injection frame header template into struct ocelot_port_private instead of struct ocelot_port, I would not have anything against it. Because struct ocelot_port is common with DSA, whereas struct ocelot_port_private isn't. Also, as things stand, all switch drivers call ocelot_init_port, but not all supported switches have the same IFH format. See seville_xmit() -> seville_ifh_set_dest(). So even though DSA does not use this for anything, it wouldn't even contain valid information even if it wanted to. So maybe you can move this initialization to some place isolated to vsc7514.
Le Fri, 26 Nov 2021 17:54:55 +0000, Vladimir Oltean <vladimir.oltean@nxp.com> a écrit : > On Fri, Nov 26, 2021 at 06:27:38PM +0100, Clément Léger wrote: > > IFH preparation can take quite some time on slow processors (up to 5% in > > a iperf3 test for instance). In order to reduce the cost of this > > preparation, pre-compute IFH since most of the parameters are fixed per > > port. Only rew_op and vlan tag will be set when sending if different > > than 0. This allows to remove entirely the calls to packing() with basic > > usage. In the same time, export this function that will be used by FDMA. > > > > Signed-off-by: Clément Léger <clement.leger@bootlin.com> > > --- > > If you would move this injection frame header template into struct > ocelot_port_private instead of struct ocelot_port, I would not have > anything against it. Because struct ocelot_port is common with DSA, > whereas struct ocelot_port_private isn't. > > Also, as things stand, all switch drivers call ocelot_init_port, but not > all supported switches have the same IFH format. See seville_xmit() -> > seville_ifh_set_dest(). So even though DSA does not use this for > anything, it wouldn't even contain valid information even if it wanted > to. So maybe you can move this initialization to some place isolated to > vsc7514. Acked, this makes sense, I will do this.
diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c index e6c18b598d5c..1f7c9ff18ac5 100644 --- a/drivers/net/ethernet/mscc/ocelot.c +++ b/drivers/net/ethernet/mscc/ocelot.c @@ -1076,20 +1076,29 @@ bool ocelot_can_inject(struct ocelot *ocelot, int grp) } EXPORT_SYMBOL(ocelot_can_inject); +void ocelot_ifh_port_set(void *ifh, struct ocelot_port *ocelot_port, u32 rew_op, + u32 vlan_tag) +{ + memcpy(ifh, ocelot_port->ifh, OCELOT_TAG_LEN); + + if (vlan_tag) + ocelot_ifh_set_vlan_tci(ifh, vlan_tag); + if (rew_op) + ocelot_ifh_set_rew_op(ifh, rew_op); +} +EXPORT_SYMBOL(ocelot_ifh_port_set); + void ocelot_port_inject_frame(struct ocelot *ocelot, int port, int grp, u32 rew_op, struct sk_buff *skb) { + struct ocelot_port *ocelot_port = ocelot->ports[port]; u32 ifh[OCELOT_TAG_LEN / 4] = {0}; unsigned int i, count, last; ocelot_write_rix(ocelot, QS_INJ_CTRL_GAP_SIZE(1) | QS_INJ_CTRL_SOF, QS_INJ_CTRL, grp); - ocelot_ifh_set_bypass(ifh, 1); - ocelot_ifh_set_dest(ifh, BIT_ULL(port)); - ocelot_ifh_set_tag_type(ifh, IFH_TAG_TYPE_C); - ocelot_ifh_set_vlan_tci(ifh, skb_vlan_tag_get(skb)); - ocelot_ifh_set_rew_op(ifh, rew_op); + ocelot_ifh_port_set(ifh, ocelot_port, rew_op, skb_vlan_tag_get(skb)); for (i = 0; i < OCELOT_TAG_LEN / 4; i++) ocelot_write_rix(ocelot, ifh[i], QS_INJ_WR, grp); @@ -2128,6 +2137,10 @@ void ocelot_init_port(struct ocelot *ocelot, int port) skb_queue_head_init(&ocelot_port->tx_skbs); + ocelot_ifh_set_bypass(ocelot_port->ifh, 1); + ocelot_ifh_set_dest(ocelot_port->ifh, BIT_ULL(port)); + ocelot_ifh_set_tag_type(ocelot_port->ifh, IFH_TAG_TYPE_C); + /* Basic L2 initialization */ /* Set MAC IFG Gaps diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h index fef3a36b0210..b3381c90ff3e 100644 --- a/include/soc/mscc/ocelot.h +++ b/include/soc/mscc/ocelot.h @@ -6,6 +6,7 @@ #define _SOC_MSCC_OCELOT_H #include <linux/ptp_clock_kernel.h> +#include <linux/dsa/ocelot.h> #include <linux/net_tstamp.h> #include <linux/if_vlan.h> #include <linux/regmap.h> @@ -623,6 +624,8 @@ struct ocelot_port { struct net_device *bridge; u8 stp_state; + + u8 ifh[OCELOT_TAG_LEN]; }; struct ocelot { @@ -754,6 +757,8 @@ void __ocelot_target_write_ix(struct ocelot *ocelot, enum ocelot_target target, bool ocelot_can_inject(struct ocelot *ocelot, int grp); void ocelot_port_inject_frame(struct ocelot *ocelot, int port, int grp, u32 rew_op, struct sk_buff *skb); +void ocelot_ifh_port_set(void *ifh, struct ocelot_port *port, u32 rew_op, + u32 vlan_tag); int ocelot_xtr_poll_frame(struct ocelot *ocelot, int grp, struct sk_buff **skb); void ocelot_drain_cpu_queue(struct ocelot *ocelot, int grp);
IFH preparation can take quite some time on slow processors (up to 5% in a iperf3 test for instance). In order to reduce the cost of this preparation, pre-compute IFH since most of the parameters are fixed per port. Only rew_op and vlan tag will be set when sending if different than 0. This allows to remove entirely the calls to packing() with basic usage. In the same time, export this function that will be used by FDMA. Signed-off-by: Clément Léger <clement.leger@bootlin.com> --- drivers/net/ethernet/mscc/ocelot.c | 23 ++++++++++++++++++----- include/soc/mscc/ocelot.h | 5 +++++ 2 files changed, 23 insertions(+), 5 deletions(-)