Part Number: AM6422
Clarification on VLAN ID 0 TX/RX behavior on AM64x CPSW3G
Purpose
We would like TI FAE to clarify whether the default VLAN ID 0 handling on TI AM64x CPSW3G may cause the following behavior:
- Packets sent through
eth1.0are observed on the wire without an explicit VLAN tag - Reception of externally injected VLAN ID 0 packets may also be affected
- What is the recommended way to handle this scenario in software or configuration
Hardware and Software Environment
Hardware platform
- SoC: TI AM64x
- Switch IP: CPSW3G
- Network/PTP interface under investigation:
eth1 - PTP device:
/dev/ptp1
Software environment
- OS: Linux, built in a Yocto/KAS environment
- CPSW driver:
am65-cpsw-nuss - Kernel-side files involved in our analysis:
am65-cpsw-nuss.ccpsw_ale.c
- Application-side scenario:
- VLAN sub-interface
eth1.0is used to send/receive VLAN ID 0 traffic eth1.100is used as a comparison point and transmits frames with VLAN 100 as expected- ptp4l work in IEEE C37.238-2011 as slave. GM work in IEEE C37.238-2011 with VLAN ID 0 by default .
- VLAN sub-interface
Diagnostic tool
- We used TI's official
switch-configutility to dump the ALE table - Tool source: https://git.ti.com/cgit/switch-config/switch-config/
- The tool was cross-compiled for the target using the same Yocto toolchain as the PTP application
Observed Behavior
Observation 1: VLAN 100 behaves normally, VLAN 0 does not
- Frames sent from
eth1.100are captured externally with VLAN tag 100 - Frames sent from
eth1.0are captured externally without an explicit VLAN tag 0 - From the Linux side,
eth1.0is configured correctly and we already verified:- VLAN ID = 0
reorder_hdr offegress-qos-map 4:4
Observation 2: External equipment can send VLAN 0 frames toward this device
- The peer clock is able to transmit VLAN ID 0 PTP packets
- Our application logs indicate that the receive path can enter VLAN mode, so at least part of the RX path appears VLAN-aware
Observation 3: ALE dump shows VLAN 0 is force-untagged
We executed the following command on the target:
./switch-config -I eth1 -d
Relevant output is shown below:
K3 cpsw dump version (1) len(11704)
ALE table dump ents(512):
0 : type: vlan , vid = 0, untag_force = 0x7, reg_mcast = 0x0, unreg_mcast = 0x0, member_list = 0x7
1 : type: ucast, addr = 98:03:8a:84:88:15, ucast_type = persistant, port_num = 0x0, Secure
2 : type: mcast, vid = 0, addr = ff:ff:ff:ff:ff:ff, mcast_state = f, no super, port_mask = 0x7
3 : type: mcast, addr = 33:33:00:00:00:01, mcast_state = f, no super, port_mask = 0x7
4 : type: mcast, addr = 01:00:5e:00:00:01, mcast_state = f, no super, port_mask = 0x7
5 : type: ucast, addr = 00:00:54:68:00:00, ucast_type = persistant, port_num = 0x0, Secure
6 : type: mcast, addr = 33:33:ff:84:88:15, mcast_state = f, no super, port_mask = 0x3
7 : type: mcast, addr = 01:00:5e:00:00:fc, mcast_state = f, no super, port_mask = 0x3
8 : type: mcast, addr = 01:00:5e:00:00:fb, mcast_state = f, no super, port_mask = 0x3
9 : type: mcast, addr = 33:33:00:01:00:03, mcast_state = f, no super, port_mask = 0x3
10 : type: mcast, addr = 33:33:00:00:00:fb, mcast_state = f, no super, port_mask = 0x3
11 : type: mcast, addr = 01:80:c2:00:00:21, mcast_state = f, no super, port_mask = 0x3
12 : type: vlan , vid = 100, untag_force = 0x0, reg_mcast = 0x0, unreg_mcast = 0x0, member_list = 0x3
The most important ALE entry for us is:
vid = 0, untag_force = 0x7, member_list = 0x7
Compared with VLAN 100:
vid = 100, untag_force = 0x0, member_list = 0x3
This suggests that VLAN 100 is not force-untagged, while VLAN 0 is force-untagged.
Our Current Understanding
Based on source code review, our current understanding is as follows.
1. No explicit VLAN 0 stripping logic was found in the TX netdev path
In the ndo_start_xmit path of am65-cpsw-nuss.c, we did not find an obvious special-case branch that strips VLAN tags only when VLAN ID equals 0.
2. Default VLAN 0 initialization may program ALE to force untag egress
In am65-cpsw-nuss.c, we found logic similar to:
port_mask = GENMASK(common->port_num, 0) &
~common->disabled_ports_mask;
cpsw_ale_add_vlan(common->ale, 0, port_mask,
port_mask, port_mask,
port_mask & ~ALE_PORT_HOST);
Our interpretation is:
member_list = port_maskuntag_force = port_mask
If port_mask = 0x7, this matches the ALE dump exactly.
3. This may explain why eth1.0 traffic appears untagged on the wire
Even if Linux constructs a VLAN ID 0 packet on eth1.0, once the packet enters CPSW/ALE, it may be converted to an untagged egress frame because of the default VLAN 0 untag_force policy.
However, we are not sure whether this is only an egress behavior or whether it also affects ingress delivery to eth1.0.
Questions for TI FAE
Question 1
For AM64x CPSW3G, does the ALE entry vid = 0, untag_force = 0x7 cause the following behavior?
- The application sends packets through
eth1.0 - Internally, Linux treats them as VLAN ID 0 packets
- But externally, the wire capture shows packets without an explicit VLAN tag
In other words:
Is this ALE configuration sufficient to explain the observed behavior that packets sent via
eth1.0appear untagged on the wire?
Question 2
Does this VLAN 0 / untag_force configuration also affect reception of externally injected VLAN ID 0 frames?
Specifically, we want to understand whether priority-tagged VLAN 0 frames entering the switch port:
- Are treated as untagged frames on the CPSW/ALE/host path
- Can still be delivered correctly to
eth1.0 - Or are actually delivered to
eth1instead ofeth1.0
Question 3
For applications that must preserve explicit VLAN ID 0 tagging on both TX and RX, what is TI's recommended solution?
For example, should we:
- Modify the default VLAN 0 ALE initialization so that
untag_force != port_mask - Change VLAN 0
untag_forceto0 - Manage VLAN 0 through switchdev / VLAN APIs in a different way
- Or is explicit preservation of VLAN ID 0 tags fundamentally unsupported/limited on CPSW in this mode?
If TI has a recommended driver patch, reference configuration, kernel version, or design note for this case, please share it.
What We Need Confirmed
We would appreciate a clear answer to the following:
- Does
vid = 0, untag_force = 0x7cause packets sent frometh1.0to appear as untagged frames on the wire? - Does this configuration also affect reception/classification of external VLAN ID 0 packets toward
eth1.0? - If the application requires true transmission/reception of explicitly tagged VLAN ID 0 frames, what is the recommended driver/configuration change?
Additional Notes
eth1.100currently behaves as expected and external captures show VLAN 100- The issue is specific to
eth1.0 - The current
switch-configversion can only dump ALE state; it cannot modify the VLAN 0 ALE entry online - Therefore, at this stage we can only infer the root cause from observations and source code, and we need TI to confirm the intended CPSW/ALE behavior