This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM335x Ether subsystem use as LAN Hub

Other Parts Discussed in Thread: AM3352

Hi,

I want to achieve the LAN hub function with 2 ethernet ports on the AM3352 Ethernet Subsystem.
I think possible because the 3PSW supports a Layer 2 switching, Can I use the 3PSW as follows?


When the packet data come into ether port 1, this packet data is moving through to ether port2 without CPU and/or DMA intervention.


Best regards,
H.U

  • That is exactly the purpose of the ethernet switch subsystem.

    Minimal initialization is the same as for a single ethernet port, except with port-specific steps repeated for both ports. I described it in somewhat more detail for the dm814x in this post (the am335x is essentially the same except for its clock config).

  • Hi, Matthijs van Duin

    Thank you for your reply.

    Can you provide a sample driver?
    or do you know the Linux driver for LAN Hub function?
    I want them to reference.

    Best regards,
  • The linux driver for the ethernet subsystem is contained in the sources drivers/net/ethernet/ti/cpsw*. It operates in switch mode by default. (Alternatively you can set the "dual_emac" property in device tree to request the two ethernet ports to appear as separate network interfaces.)

    Note however that for basic (unmanaged, vlan-unaware) switch functionality no driver would be required to look after the switch and PHYs after initialization. I have a baremetal codebase which just performs the initialization during early startup and pays no further attention to the switch, and it works fine. An ethernet driver for the host (involving only the CPDMA and CPSW_WR registers) can be started (and restarted) at any time after that without affecting the switch. There is a minor issue that switch table entries would never age out, so the switch table might fill up over time, but this would only become a problem if the switch encounters 1024 distinct network devices since it was last reset, which is not very likely on most networks. I'm also not sure whether anything bad would actually happen.

    Note that the linux driver isn't structured this way: the switch initialization/driver and host ethernet driver are interwoven there. (In particular, with the current state of the linux driver you can't reboot the host without also resetting the switch.)

    FYI, the term "hub" refers to a somewhat different kind of device which operates purely at the physical layer and is unaware of network addressing. It is mostly obsolete, having been displaced by switches.

  • Hi Matthijy van Duin,

    I followed your recommendations (using cpsw3g driver for Win EC7 on AM3352) and got the switch running except broadcasts. Broadcasts (d.h. arp, dhcp) do not pass the switch in any combination (p0-p1, p1-p2, p0-p2). The limit control setting has no influence.
    Which setting could prohibit broadcasts across the switch?
  • Strange, it should forward broadcasts and multicasts to all ports by default. I actually had to extra steps because I didn't want broadcasts to be forwarded to port 0, to avoid burdening my extremely simplistic IPv6-only stack with irrelevant packets (IPv6 never uses broadcasts). This required adding an ALE table entry for the broadcast address ff:ff:ff:ff:ff:ff to limit the set of forwarding ports.

    The am335x has a slightly newer version of the ethernet switch subsystem than the dm814x, but it seems unlikely to me they'd differ on such a fundamental matter. (I don't have any am335x device with two ethernet ports to test with.)

    My guess would be either the Win EC7 cpsw driver somehow misconfigures the subsystem, or possibly u-boot does and the winec driver fails to undo it (assuming u-boot is also used to boot windows ec?). Looking at the u-boot cpsw code (driver/net/cpsw.c) now, I see it does some fairly silly things. I'll study it a bit more and see if I can produce suggestions to make it correctly initialize the subsystem. (I know nothing whatsoever about Win EC so I can't help you there...)

  • Ah, the u-boot code did make me realize that my earlier statement about the switch entirely looking after itself is in fact only true when using RGMII, which has in-band link state communication. When using (G)MII or RMII, software must (preferably on notification from a phy irq) check the link state and get speed/duplex via mdio, and configure it into the corresponding mii controller ("mac sliver"). (Or alternatively program fixed settings into both phy and mii controller and hope the link partner will accept it.)

    Annoyingly, it looks like fixing u-boot's initialization would require significant restructuring because the assumption of a single phy is pointlessly hardcoded in various places and, similar to the linux driver, switch initialization and host ethernet initialization is interwoven. The latter is particularly troublesome in u-boot since host ethernet isn't initialized until you actually execute some network command, and is killed again immediately after (along with the switch, currently).

    Since you have ethernet mostly working, maybe the issue is easier to fix in the Win EC driver... make sure the ALE is cleared by writing 1 << 30 to ALE_CONTROL and then enable it by writing 1 << 31 to ALE_CONTROL. Since this implicitly disables "VLAN aware" mode, the default vlan config (ALE_UNKNOWN_VLAN) should be ignored, but set it to 0x070707 just to be safe. If this doesn't solve the problem, you can try adding a multicast entry for ff:ff:ff:ff:ff:ff specifying forwarding to all ports. In case the driver doesn't have a utility function for creating ALE entries, the manual steps are: set the entry data (ALE_TBLW* in memory order) to (u32[3]){ 0x1c, 0x1000ffff, 0xffffffff }, then write (index | 1 << 31) to ALE_TBLCTL to store the entry. If you do this immediately after clearing the ALE table, you can safely hardcode index 0.

    Addendum: And you'll want to add a unicast entry for the host MAC address (do this before enabling the ALE to avoid a race condition), or set EN_P0_UNI_FLOOD in ALE_CONTROL (this may cause unnecessary traffic to host, but probably not much), or make sure the host sends a packet (e.g. DHCP) after enabling the ALE. One of these three things need to be done before the host will receive any unicast traffic.

  • Hi Matthijy van Duin,

    I was able to confirm that it works as LAN Hub using the StarterWare(enet_lwip) with EVM-SK.
    Thank you for your advice.

    Best regards,
    H.U

  • Hi Matthijs,

    thank you for your help. I inserted some additional logs with cpsw3g register dumps and I found incorrect ale table entries. They are caused by wrong #defines in cpsw3g_ale.c from the AM335-BSP of WinEC7:

    /* ALE Table Definitions and Bitfields */
    #define CPSW_ALE_ENTRY_BITS                      68       should be 72
    #define CPSW_ALE_ENTRY_WORDS \
        ((CPSW_ALE_ENTRY_BITS + 31) / 32)
    #define CPSW_ALE_ENTRY_TYPE_SHIFT        60
    #define CPSW_ALE_ENTRY_TYPE_BITS            2
    #define CPSW_ALE_VLAN_ID_SHIFT                48
    #define CPSW_ALE_VLAN_ID_BITS                  12
    #define CPSW_ALE_ADDR_SHIFT                      0
    #define CPSW_ALE_ADDR_BITS                      48
    #define CPSW_ALE_MCAST_STATE_SHIFT    62
    #define CPSW_ALE_MCAST_STATE_BITS       2
    #define CPSW_ALE_PORT_MASK_SHIFT        64     should be 66
    #define CPSW_ALE_PORT_MASK_BITS            3
    #define CPSW_ALE_SUPER_SHIFT                  67    should be 65
    #define CPSW_ALE_SUPER_BITS                      1
    #define CPSW_ALE_MCAST_SHIFT                 40     should be 62
    #define CPSW_ALE_MCAST_BITS                     1
    #define CPSW_ALE_UCAST_TYPE_SHIFT     66      should be 62
    #define CPSW_ALE_UCAST_TYPE_BITS         2
    #define CPSW_ALE_PORT_NUM_SHIFT         64      should be 66
    #define CPSW_ALE_PORT_NUM_BITS             2
    #define CPSW_ALE_BLOCKED_SHIFT           63       should be 65
    #define CPSW_ALE_BLOCKED_BITS                1
    #define CPSW_ALE_SECURE_SHIFT             62       should be 64
    #define CPSW_ALE_SECURE_BITS                 1
    #define CPSW_ALE_UCAST_TYPE_SHIFT     66
    #define CPSW_ALE_UCAST_TYPE_BITS         2

    With this modifications everything works fine.

    -- Best regards

  • Ah, well those were the right offsets... for an ancient version of the ALE (used e.g. in some older DaVinci chips).

  • Hi H.U,

    Sorry for interrupting.
    I want to make LAN Hub with EVM-SK.
    Can you give me an advice how to make LAN Hub using Starterware(enet_lwip)?
    If possible, can you share the program?

    best regards,
    g.f.