[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <87lfgj997g.fsf@kurt>
Date: Tue, 06 Oct 2020 08:09:39 +0200
From: Kurt Kanzenbach <kurt@...utronix.de>
To: Vladimir Oltean <olteanv@...il.com>
Cc: Andrew Lunn <andrew@...n.ch>,
Vivien Didelot <vivien.didelot@...il.com>,
Florian Fainelli <f.fainelli@...il.com>,
"David S. Miller" <davem@...emloft.net>,
Jakub Kicinski <kuba@...nel.org>, netdev@...r.kernel.org,
Rob Herring <robh+dt@...nel.org>, devicetree@...r.kernel.org,
Sebastian Andrzej Siewior <bigeasy@...utronix.de>,
Richard Cochran <richardcochran@...il.com>,
Kamil Alkhouri <kamil.alkhouri@...offenburg.de>,
ilias.apalodimas@...aro.org
Subject: Re: [PATCH net-next v6 2/7] net: dsa: Add DSA driver for Hirschmann Hellcreek switches
Hi Vladimir,
thanks for the review.
On Sun Oct 04 2020, Vladimir Oltean wrote:
> On Sun, Oct 04, 2020 at 01:29:06PM +0200, Kurt Kanzenbach wrote:
>> +static int hellcreek_vlan_del(struct dsa_switch *ds, int port,
>> + const struct switchdev_obj_port_vlan *vlan)
>> +{
>> + struct hellcreek *hellcreek = ds->priv;
>> + u16 vid;
>> +
>> + dev_dbg(hellcreek->dev, "Remove VLANs (%d -- %d) on port %d\n",
>> + vlan->vid_begin, vlan->vid_end, port);
>> +
>> + for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid) {
>> + mutex_lock(&hellcreek->ports[port].vlan_lock);
>> + if (hellcreek->ports[port].vlan_filtering)
>> + hellcreek_unapply_vlan(hellcreek, port, vid);
>
> I don't think this works.
>
> ip link add br0 type bridge vlan_filtering 1
> ip link set swp0 master br0
> bridge vlan add dev swp0 vid 100
> ip link set br0 type bridge vlan_filtering 0
> bridge vlan del dev swp0 vid 100
> ip link set br0 type bridge vlan_filtering 1
>
> The expectation would be that swp0 blocks vid 100 now, but with your
> scheme it doesn't (it is not unapplied, and not unqueued either, because
> it was never queued in the first place).
Yes, that's correct. So, I think we have to queue not only the addition
of VLANs, but rather the "action" itself such as add or del. And then
apply all pending actions whenever vlan_filtering is set.
>> +static int hellcreek_port_bridge_join(struct dsa_switch *ds, int port,
>> + struct net_device *br)
>> +{
>> + struct hellcreek *hellcreek = ds->priv;
>> + int i;
>> +
>> + dev_dbg(hellcreek->dev, "Port %d joins a bridge\n", port);
>> +
>> + /* Configure port's vid to all other ports as egress untagged */
>> + for (i = 0; i < ds->num_ports; ++i) {
>> + if (!dsa_is_user_port(ds, i))
>> + continue;
>> +
>> + if (i == port)
>> + continue;
>> +
>> + hellcreek_apply_vlan(hellcreek, i, port, false, true);
>> + }
>
> I think this is buggy when joining a VLAN filtering bridge. Your ports
> will pass frames with VID=2 with no problem, even without the user
> specifying 'bridge vlan add dev swp0 vid 2', and that's an issue. My
> understanding is that VLANs 1, 2, 3 stop having any sort of special
> meaning when the upper bridge has vlan_filtering=1.
Yes, that understanding is correct. So, what happens is when a port is
joining a VLAN filtering bridge is:
|root@tsn:~# ip link add name br0 type bridge
|root@tsn:~# ip link set dev br0 type bridge vlan_filtering 1
|root@tsn:~# ip link set dev lan0 master br0
|[ 209.375055] br0: port 1(lan0) entered blocking state
|[ 209.380073] br0: port 1(lan0) entered disabled state
|[ 209.385340] hellcreek ff240000.switch: Port 2 joins a bridge
|[ 209.391584] hellcreek ff240000.switch: Apply VLAN: port=3 vid=2 pvid=0 untagged=1
|[ 209.399439] device lan0 entered promiscuous mode
|[ 209.404043] device eth0 entered promiscuous mode
|[ 209.409204] hellcreek ff240000.switch: Enable VLAN filtering on port 2
|[ 209.415716] hellcreek ff240000.switch: Unapply VLAN: port=2 vid=2
|[ 209.421840] hellcreek ff240000.switch: Unapply VLAN: port=0 vid=2
|[ 209.428170] hellcreek ff240000.switch: Apply queued VLANs: port2
|[ 209.434158] hellcreek ff240000.switch: Apply VLAN: port=2 vid=0 pvid=0 untagged=0
|[ 209.441649] hellcreek ff240000.switch: Clear queued VLANs: port2
|[ 209.447920] hellcreek ff240000.switch: Apply queued VLANs: port0
|[ 209.453910] hellcreek ff240000.switch: Apply VLAN: port=0 vid=0 pvid=0 untagged=0
|[ 209.461402] hellcreek ff240000.switch: Clear queued VLANs: port0
|[ 209.467620] hellcreek ff240000.switch: VLAN prepare for port 2
|[ 209.473476] hellcreek ff240000.switch: VLAN prepare for port 0
|[ 209.479534] hellcreek ff240000.switch: Add VLANs (1 -- 1) on port 2, untagged, PVID
|[ 209.487164] hellcreek ff240000.switch: Apply VLAN: port=2 vid=1 pvid=1 untagged=1
|[ 209.494659] hellcreek ff240000.switch: Add VLANs (1 -- 1) on port 0, untagged, no PVID
|[ 209.502794] hellcreek ff240000.switch: Apply VLAN: port=0 vid=1 pvid=0 untagged=1
|root@tsn:~# bridge vlan show
|port vlan ids
|lan0 1 PVID Egress Untagged
|
|br0 1 PVID Egress Untagged
... which looks correct to me. The VLAN 2 is unapplied as expected. Or?
>
> And how do you deal with the case where swp1 and swp2 are bridged and
> have the VLAN 3 installed via 'bridge vlan', but swp3 isn't bridged?
> Will swp1/swp2 communicate with swp3? If yes, that's a problem.
There is no swp3. Currently there are only two ports and either they are
bridged or not.
>> +static int __hellcreek_fdb_del(struct hellcreek *hellcreek,
>> + const struct hellcreek_fdb_entry *entry)
>> +{
>> + dev_dbg(hellcreek->dev, "Delete FDB entry: MAC=%pM!\n", entry->mac);
>> +
>
> Do these dev_dbg statements bring much value at all, even to you?
Yes, they do. See the log snippet above.
>> +/* Default setup for DSA: VLAN <X>: CPU and Port <X> egress untagged. */
>> +static int hellcreek_setup_vlan_membership(struct dsa_switch *ds, int port,
>> + bool enabled)
>
> This function always returns zero, so it should be void.
Yes. I noticed that as well and wanted to fix it before sending. Sorry, my bad.
>> +static int hellcreek_vlan_filtering(struct dsa_switch *ds, int port,
>> + bool vlan_filtering)
>> +{
>> + struct hellcreek *hellcreek = ds->priv;
>> +
>> + dev_dbg(hellcreek->dev, "%s VLAN filtering on port %d\n",
>> + vlan_filtering ? "Enable" : "Disable", port);
>> +
>> + /* Configure port to drop packages with not known vids */
>> + hellcreek_setup_ingressflt(hellcreek, port, vlan_filtering);
>> +
>> + /* Drop DSA vlan membership config. The user can now do it. */
>> + hellcreek_setup_vlan_membership(ds, port, !vlan_filtering);
>> +
>> + /* Apply saved vlan configurations while not filtering for port <X>. */
>> + hellcreek_apply_vlan_filtering(hellcreek, port, vlan_filtering);
>> +
>> + /* Do the same for the cpu port. */
>> + hellcreek_apply_vlan_filtering(hellcreek, CPU_PORT, vlan_filtering);
>
> I think we should create a DSA_NOTIFIER_VLAN_FILTERING so you wouldn't
> have to do this, but not now.
OK.
>> +static int hellcreek_probe(struct platform_device *pdev)
>> +{
>> + struct device *dev = &pdev->dev;
>> + struct hellcreek *hellcreek;
>> + struct resource *res;
>> + int ret, i;
>> +
>> + hellcreek = devm_kzalloc(dev, sizeof(*hellcreek), GFP_KERNEL);
>> + if (!hellcreek)
>> + return -ENOMEM;
>> +
>> + hellcreek->vidmbrcfg = devm_kcalloc(dev, 4096,
>
> VLAN_N_VID
Thanks!
>> +static const struct hellcreek_platform_data de1soc_r1_pdata = {
>> + .num_ports = 4,
>> + .is_100_mbits = 1,
>> + .qbv_support = 1,
>> + .qbv_on_cpu_port = 1,
>
> Why does this matter?
Because Qbv on the CPU port is a feature and not all switch variants
have that. It will matter as soon as TAPRIO is implemented.
>> +#include <linux/bitops.h>
>> +#include <linux/kernel.h>
>> +#include <linux/device.h>
>> +#include <linux/ptp_clock_kernel.h>
>> +#include <linux/timecounter.h>
>> +#include <linux/mutex.h>
>
> Could you sort alphabetically?
Sure.
>
>> +#include <linux/platform_data/hirschmann-hellcreek.h>
>> +#include <net/dsa.h>
>> +
>> +/* Ports:
>> + * - 0: CPU
>> + * - 1: Tunnel
>> + * - 2: TSN front port 1
>> + * - 3: TSN front port 2
>> + * - ...
>> + */
>> +#define CPU_PORT 0
>> +#define TUNNEL_PORT 1
>
> What's a tunnel port exactly?
AFAIK it's a debugging port for mirroring or looping traffic. Anyhow,
that is not a regular port and cannot be treated as such.
Thanks,
Kurt
Download attachment "signature.asc" of type "application/pgp-signature" (833 bytes)
Powered by blists - more mailing lists