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.

[FAQ]: AM26x: Enabling InterVLAN in CPSW

Part Number: AM2612


Hi TI experts,

Can you please help me understand CPSW's InterVLAN feature and provide steps to enable the same.

  • InterVLAN is a packet routing feature of CPSW which does not involve CPU for manipulating certain fields of the packet, making it very quicker than traditional CPU packet modification in software. The CPSW module supports wire rate InterVLAN routing for a small number of routes, that is the host will setup an ALE classifier with an associated egress operation that will cause the CPSW to perform particular egress operations. The ALE uses the classifier along with an egress opcode, destination port mask and TTL check field to tell the CPSW how to manipulate the packet on the egress. The CPSW will use the opcode along with a per port operation table to process the packet. The following egress operations are supported:

    1. Replace source MAC address with a different MAC address.
    2. Replace destination MAC address with a different MAC address.
    3. Swap source and destination MAC address of the incoming packet.
    4. Replace the VLAN tag of the packet.
    5. Update Time-to-live field in the packet header.

    The egress operations are performed only on the packets which match the input packet classifier criteria. The packet can be matched on a combination of the following criteria:

    1. Source MAC address
    2. Destination MAC address
    3. VLAN ID
    4. Source IP address
    5. Destination IP address
    6. EtherType
    7. Port Number

    This allows the CPSW to perform the routing function for a small set of routes without getting the local host/CPU involved. This way, the packet which should've been sent to the host port and modified by the CPU application, will now be re-configured by CPSW itself. In the event that the time-to-live check feature is enabled and the time-to-live is either 0 or 1, the packet will not get the egress opcode and instead be sent to the host as if the route is not setup. This allows the host to deal with invalid TTL fields.

    Do note that the appropriate ALE table entries for Unicast, Multicast and Broadcast packets will still be required. If not configured, the packet will be dropped by ALE even before it is matched for InterVLAN input packet classifier config.

    Sample Implementation:

    Lets understand the sample implementation by using an example scenario. 

    Consider a daisy chained ethernet topology, in which the external host sends packets to each node in the network. Each node in the chain responds back with the packet with modified VLAN Tag. The node-1 is connected to the external PC, but all the other nodes in the network require node-1 to forward the packets to the respective nodes. The responses from other nodes will also be forwarded back to host PC via node-1. In such a scenario, relying on Software for manipulating the packet fields for packet forwarding and switching will consume a lot of CPU resources. InterVLAN can be configured here for:

    1. Matching a packet based on the Destination MAC address and VLAN ID of the packet. This way, we can decide if the packet is to be forwarded to other nodes, or to be modified on this node and looped back to the host PC.
    2. If a packet matches the config, the packet sent out on Mac Port-1 will have the source and destination MAC address swapped, while retaining the VLAN ID. This emulates a case of CPSW Hardware packet loopback.
    3. If packet is to be forwarded to other nodes in the network via Mac Port-2, the packet fields are not manipulated and the packet is sent out as it is for other nodes.
    4. If the packet does not match any criteria, it can be dropped.

    To enable InterVLAN, the application essentially calls the ENET IOCTL: CPSW_PER_IOCTL_SET_INTERVLAN_ROUTE_MULTI_EGRESS. We populate the InterVLAN config here in Cpsw_SetInterVlanRouteMultiEgressInArgs. If setting up a Policer Entry, that can be configured in the Cpsw_SetInterVlanRouteMultiEgressOutArgs. The Cpsw_SetInterVlanRouteMultiEgressInArgs requires 3 fields: number of egress ports, input packet match config, egress config. The below code snippets show how to configure each of the three fields.

    1. In this case, we have CPSW3G with two egress ports:
      .numEgressPorts = 2,
    2. The below code snippet shows how the packet match config can be setup for interVlanInargs. Here we check for VLAN ID == 255 and a particular MAC address to be destination MAC address in the incoming packet. The packetMatchEnMask can have the following values (use bit-wise OR for a combination):
      CPSW_INTERVLAN_INGRESSPKT_MATCH_PORT, CPSW_INTERVLAN_INGRESSPKT_MATCH_MACDST, CPSW_INTERVLAN_INGRESSPKT_MATCH_MACSRC, CPSW_INTERVLAN_INGRESSPKT_MATCH_IPDST, CPSW_INTERVLAN_INGRESSPKT_MATCH_IPSRC, CPSW_INTERVLAN_INGRESSPKT_MATCH_ETHERTYPE
      .inPktMatchCfg =
      {
          /* By default vlanId is matched, to match any other field
              * use the below packetMatchEnMask and fill the corresponding field*/
          .vlanId              = 255,
          .ttlCheckEn          = false,
          .packetMatchEnMask   = CPSW_INTERVLAN_INGRESSPKT_MATCH_MACDST,
      },

    3. The below code snippet shows how to configure the Egress operations per port:
      .egressCfg =
      {
          {
          .egressPort = ENET_MAC_PORT_1,
          .outPktModCfg =
                  {
                      .replaceDASA         = true,
                      .forceUntaggedEgress = false,
                      .decrementTTL        = false,
                      .vlanId              = 255,
                  },
          },
          {
              .egressPort = ENET_MAC_PORT_2,
              .outPktModCfg =
                  {
                      .replaceDASA         = false,
                      .forceUntaggedEgress = false,
                      .decrementTTL        = false,
                      .vlanId              = 255,
                  },
          },
      },

    The MAC address details can be copied into the CpswAle_MacAddrClassifierInfo fields as shown below.

    int32_t EnetApp_configureIntervlan(Enet_Handle hEnet) {
            Enet_IoctlPrms prms;
            int32_t status = ENET_SOK;
         
        /* Add InterVlan configuration to match vlanId, Dst Mac port */
        Cpsw_SetInterVlanRouteMultiEgressOutArgs interVlanOutargs;
            Cpsw_SetInterVlanRouteMultiEgressInArgs interVlanInargs = {
            .numEgressPorts = 2,
            .egressCfg =
                {
                    {
                        .egressPort = ENET_MAC_PORT_1,
                        .outPktModCfg =
                            {
                                .replaceDASA         = true,
                                .forceUntaggedEgress = false,
                                .decrementTTL        = false,
                                .vlanId              = 255,
                            },
                    },
                    {
                        .egressPort = ENET_MAC_PORT_2,
                        .outPktModCfg =
                            {
                                .replaceDASA         = false,
                                .forceUntaggedEgress = false,
                                .decrementTTL        = false,
                                .vlanId              = 255,
                            },
                    },
                },
            .inPktMatchCfg =
            {
                /* By default vlanId is matched, to match any other field
                 * use the below packetMatchEnMask and fill the corresponding field*/
                .vlanId             = 255,
                .ttlCheckEn        = false,
                .packetMatchEnMask = CPSW_INTERVLAN_INGRESSPKT_MATCH_MACDST,
            },
        };
         
        /* check if source address for input packet is host PC */
        memcpy(interVlanInargs.inPktMatchCfg.srcMacAddrInfo.addr.addr,
                TEST_HOST_PC_MAC_ADDR, ENET_MAC_ADDR_LEN);
            /* check if destination address for input packet is this node */
        memcpy(interVlanInargs.inPktMatchCfg.dstMacAddrInfo.addr.addr,
                NODE_MAC_ADDR, ENET_MAC_ADDR_LEN);
            /* Make the destination address of output packet as host PC */
        memcpy(interVlanInargs.egressCfg[ENET_MAC_PORT_1].outPktModCfg.dstAddr,
                TEST_HOST_PC_MAC_ADDR, ENET_MAC_ADDR_LEN);
            /* Make the source address of output packet as this node */
        memcpy(interVlanInargs.egressCfg[ENET_MAC_PORT_1].outPktModCfg.srcAddr,
                NODE_MAC_ADDR, ENET_MAC_ADDR_LEN);
            /* When forwarding packet to other ports, make sure the SRC MAC is HOST
               PC mac */
        memcpy(interVlanInargs.egressCfg[ENET_MAC_PORT_2].outPktModCfg.srcAddr,
                NODE_MAC_ADDR, ENET_MAC_ADDR_LEN);
         
        ENET_IOCTL_SET_INOUT_ARGS(&prms, &interVlanInargs, &interVlanOutargs);
         
        ENET_IOCTL(hEnet, gEnetApp.coreId,
                    CPSW_PER_IOCTL_SET_INTERVLAN_ROUTE_MULTI_EGRESS,
                            & prms, status);
         
        return status;
    }

    The above function EnetApp_configureInterVLAN() consolidates all the above discussed steps and calls the IOCTL to enable InterVLAN. This function can be called after the EnetApp_open() function, once the MAC ports are up.

    Regards,
    Shaunak Deshpande

    Checkout other FAQs for AM263x/AM263Px

    Checkout other FAQs for AM261x