Re: [PATCH net-next v3 3/3] net: ti: icssg-prueth: Add support for ICSSG switch firmware

From: Andrew Davis
Date: Tue Apr 16 2024 - 13:20:40 EST


On 4/15/24 1:56 AM, Anwar, Md Danish wrote:
Hi Andrew,

On 4/13/2024 12:22 AM, Andrew Davis wrote:
On 3/27/24 6:40 AM, MD Danish Anwar wrote:
Add support for ICSSG switch firmware using existing Dual EMAC driver
with switchdev.

Limitations:
VLAN offloading is limited to 0-256 IDs.
MDB/FDB static entries are limited to 511 entries and different FDBs can
hash to same bucket and thus may not completely offloaded

Switch mode requires loading of new firmware into ICSSG cores. This
means interfaces have to taken down and then reconfigured to switch
mode.

Example assuming ETH1 and ETH2 as ICSSG2 interfaces:

Switch to ICSSG Switch mode:
  ip link set dev eth1 down
  ip link set dev eth2 down
  ip link add name br0 type bridge
  ip link set dev eth1 master br0
  ip link set dev eth2 master br0
  ip link set dev br0 up
  ip link set dev eth1 up
  ip link set dev eth2 up
  bridge vlan add dev br0 vid 1 pvid untagged self

Going back to Dual EMAC mode:

  ip link set dev br0 down
  ip link set dev eth1 nomaster
  ip link set dev eth2 nomaster
  ip link set dev eth1 down
  ip link set dev eth2 down
  ip link del name br0 type bridge
  ip link set dev eth1 up
  ip link set dev eth2 up

By default, Dual EMAC firmware is loaded, and can be changed to switch
mode by above steps


This was asked before, maybe I missed the answer, but why do we
default to Dual-EMAC firmware? I remember when I was working on
the original ICSS-ETH driver, we started with the Dual-EMAC
firmware as the switch firmware was not ready yet (and EMAC mode
was easier). Now that we have both available, if we just use Switch
firmwar by default, what would we lose? Seems that would solve
the issues with re-loading firmware at runtime (configuration loss
and dropping packets, etc..).


We can start the driver with either Dual-EMAC firmware or SWITCH
firmware. But the problem lies in switching between these two firmwares.
For switching to / from Dual-EMAC and switch firmwares we need to stop
the cores and that is where we previously used to bring down the
interfaces, switch firmware and bring it up again. But as discussed on
this thread, I can now do the same without bringing interfaces up /
down. We'll just need to stop the cores and change firmware this will
also result in preserving the configuration. There will be packet loss
but that will not be a big concern as Andrew L. pointed out.


Yes I saw that and understand all this, but that is not my question.

Currently we are starting in Dual-EMAC mode as by default the interfaces
are not needed to forward packets. They are supposed to act as
individual ports. Port to port forwarding is not needed. Only when user
adds a bridge and starts forwarding we switch to Switch mode and load
different firmware so that packet forwarding can happen in firmware.
That is why currently we are starting Dual-EMAC mode and then switching
to firmware.


Same, I see what we do here, this doesn't give me the "why".

If we use switch firmware by default, we will not be able to use
individual ports separately and any data sent to one port will be
forwarded to the second port.

So this seems to almost answer the question, but I still do not see
why we could not use the ports separately when using SWITCH firmware.

Why not have a filter/rule set by default to each port so that they
do not forward packets automatically but instead always forward
to the host port? That would result in the same functionality as
the Dual-EMAC firmware, but without all the mess of runtime firmware
switching based on usecase (simply update the forwarding rules when
in bridge mode).

Andrew


I will be posting v4 soon and I will describe all the details on how to
use and switch between different modes in the cover letter.

Andrew


[ ... ]

    static const struct prueth_pdata am64x_icssg_pdata = {
      .fdqring_mode = K3_RINGACC_RING_MODE_RING,
+    .switch_mode = 1,
  };
    static const struct of_device_id prueth_dt_match[] = {