Debugging EcoNet's MT7530 PHYs

Caleb James DeLisle cjd at cjdns.fr
Tue Feb 10 13:07:55 PST 2026


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