Debugging EcoNet's MT7530 PHYs

Caleb James DeLisle cjd at cjdns.fr
Wed Feb 11 02:13:26 PST 2026


On 10/02/2026 23:12, Benjamin Larsson wrote:
> If I understand correct, the ref SDK just sets up a transparent bridge 
> and lets the packets flow through? If that is correct is that an 
> option here?
When use_soc_lan is unset, this is what happens. When use_soc_lan is 
set, it does a bunch of highly awkward stuff to add support for one 
extra port on the internal switch. It's an option, probably to treat the 
internal switch as part of the eth driver - however this will not work 
on EN7526C which no external switch, internal is exposed.
>
> And IMO we should not stack stags. If it is possible to pass stags 
> through with the pass-through bit intact it should be possible to 
> address all ports on both switches with just one stag.
>
> I was hoping the PT_OPTION PVC bit would set the stag pass through bit 
> on incoming frames.

Stacking stags does potentially have a performance penalty in the tag 
parser - I say "potentially" because it's already walking a list which 
could be an array index, and even 2 array indexes is faster than what we 
have now.

But trying to use the PT bit as designed makes it impossible to 
differentiate between a packet that came from port N of the external 
switch and a packet that came from port N of the internal. Vendor code 
doesn't support having the same port number active on both internal and 
external, if you try it will quietly overwrite the switch_port_map entry 
in init_ethernet_port_map(), so I surmise this is a real silicon bug, 
not a misconfiguration on my end.

But (so far), stacking tags seems to work, so I would much prefer it to 
inter-switch rules, i.e. "you can't enable this port in the DT because 
you have one with the same number on the other switch".

BTW Vendor code (see: TCSUPPORT_MULTI_SWITCH_EXT) suggests there are 
boards with multiple external switches. Probably a board integrator hung 
another 7530 off of one of the RGMII interfaces. Per my reading, vendor 
code falls back on VLANs, giving up on the stag entirely. I haven't 
confirmed that transmit works yet, but assuming it does, stacked stags 
should Just Work in this use case whereas the PT bit clearly would not.


Thanks,

Caleb


>
> MvH
> Benjamin Larsson
>
> On 10/02/2026 22:07, Caleb James DeLisle wrote:
>> Welp, that didn't take long.
>>
>> It turns out when I remove PORT_STAG on the receiving side (internal 
>> port 5), the switch mistakes the first 2 bytes of the stag for a 
>> length, and if the packet is actually shorter than that length, it 
>> drops. So 0004 worked fine, but 0104 didn't until I sent a longer 
>> packet.
>>
>> Clearing L2LEN_CHK on the AGC register works around the issue and 
>> packets are received in full with correctly stacked stags.
>>
>> If I can make the passthrough bit copy, or stop it from copying the 
>> port number when I have PORT_STAG set, that would be of course 
>> superior, but if I have to use the hack to get the feature then I'll 
>> send the patchset like that.
>>
>> Thanks,
>>
>> Caleb
>>
>>
>> On 10/02/2026 20:25, Caleb James DeLisle wrote:
>>> Hello guys,
>>>
>>> I have an update on this MT7530. As I mentioned in my initial email 
>>> there are two switches that are stacked, so I'm needing to do quite 
>>> a bit of patching to mt7530.c to create anything that is going to work.
>>>
>>> I'm trying to handle incoming traffic from the MCM ("external") 
>>> switch to the on-die switch. It comes in port 4 of the external, 
>>> where I have a cable attached, then goes to port 6 which the 
>>> external is treating as a CPU port. Then it comes in port 5 of the 
>>> internal. Here's my values for the PVC register:
>>>
>>> ext 4 0x810001c0 ACC_FRM=all VLAN_ATTR=transparent EG_TAG=consistent 
>>> STAG_VPID=0x8100
>>> ext 6 0x00000920 ACC_FRM=all PORT_STAG VLAN_ATTR=user 
>>> EG_TAG=consistent PT_OPTION STAG_VPID=0x0
>>> int 5 0x810001e0 ACC_FRM=all PORT_STAG VLAN_ATTR=transparent 
>>> EG_TAG=consistent STAG_VPID=0x8100
>>> int 6 0x00000120 ACC_FRM=all PORT_STAG VLAN_ATTR=user 
>>> EG_TAG=consistent STAG_VPID=0x0
>>>
>>> When PT_OPTION is set on port 6 of the external, it sets the 
>>> Passthrough bit on the Special Tag before sending it to the internal 
>>> switch. When int 5 has PORT_STAG set, the Passthrough bit is 
>>> required otherwise it will drop STAG'd packets. However, when it's 
>>> set the switch does a weird stupid thing and it copies the port 
>>> number from what was received from the external switch - but it 
>>> DOESN'T copy the passthrough bit. So you end up with this:
>>>
>>> [ port 4 ][ port 4 +PT ][ packet header ]
>>>
>>> And the obvious problem is this is indistinguishable from a packet 
>>> that comes from port 4 of the internal switch and has an stag 
>>> directly under the eth header.
>>>
>>> ---
>>>
>>> Another angle is to remove the PORT_STAG from internal port 5, and 
>>> then you get this:
>>>
>>> [ port 5 ][ port 4 +PT ][ packet header ]
>>>
>>> In that case you can also remove PT_OPTION from external port 6, but 
>>> sending ANY kind of VLAN packet from the outside gets it filtered 
>>> and RxFiltering gets incremented. No matter what I do, I can't 
>>> figure out how to stop VLAN packets from getting dropped except by 
>>> putting PORT_STAG on the receiving port (internal port 5). No 
>>> configuration of internal port6 prevents it, even if it's a dumb 
>>> switch, is still drops them.
>>>
>>>
>>> Anyone have any ideas?
>>>
>>>
>>> Thanks,
>>>
>>> Caleb
>>>
>>>
>>>
>>>
>>> On 28/01/2026 14:26, Caleb James DeLisle wrote:
>>>> Update: It turns out the reset controller I was using only reset 
>>>> the on-die switch, Benjamin found the reset register for the 
>>>> external switch and now everything is behaving MUCH more like 
>>>> normal. I'd say at this point I'm no longer stuck.
>>>>
>>>> Thanks,
>>>>
>>>> Caleb
>>>>
>>>>
>>>> On 27/01/2026 18:26, Caleb James DeLisle wrote:
>>>>>>
>>>>>> Would there be any reason not to set BMCR_PDOWN in 
>>>>>> mt7530_phy_config_init() so we know they're in a consistent state?
>>>>>>
>>>>>> Also if you happen to have an MT7621 sitting there running, would 
>>>>>> you mind setting BMCR_ANENABLE | BMCR_ANRESTART with mdio on a 
>>>>>> running port to see if it's the same behavior? The port should 
>>>>>> immediately die and then go into a loop trying to connect every 
>>>>>> few seconds / minutes depending on what it's connected to.
>>>>>>
>>>>> Whoops, spoke too soon. dsa_register_switch() (indirectly) calls 
>>>>> phy_resume() so the phy is up while the port is down. However, 
>>>>> adding this to mt7530_port_enable() does make it work:
>>>>>
>>>>>     if (priv->id == ID_EN751221_EXT && phy)
>>>>>         genphy_soft_reset(phy);
>>>>>
>>>>> I note that if the port is brought up within seconds of having 
>>>>> been reset, then it seems to work (at least sporadically) despite 
>>>>> the BMCR_ANENABLE bug. I imagine this is something that can be 
>>>>> tuned out, but given it's happening in the bootloader, I don't 
>>>>> have much confidence that I'm going to find the knob to fix it. 
>>>>> I've got a problem with my vendor OS image, but when I get that 
>>>>> fixed I'll check that as well.
>>>>>
>>>>> In the mean time, if any likely culprits come to mind, do let me 
>>>>> know.
>>>>>
>>>>> Thanks,
>>>>>
>>>>> Caleb
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> openwrt-devel mailing list
>>>>> openwrt-devel at lists.openwrt.org
>>>>> https://lists.openwrt.org/mailman/listinfo/openwrt-devel
>
>



More information about the openwrt-devel mailing list