mlxsw: Add support for egress FID classification after decapsulation
authorAmit Cohen <amcohen@nvidia.com>
Sun, 19 Jun 2022 10:29:20 +0000 (13:29 +0300)
committerDavid S. Miller <davem@davemloft.net>
Mon, 20 Jun 2022 09:03:33 +0000 (10:03 +0100)
As preparation for unified bridge model, add support for VNI->FID mapping
via SVFA register.

When performing VXLAN encapsulation, the VXLAN header needs to contain a
VNI. This VNI is derived from the FID classification performed on
ingress, through which the ingress RIF is also determined.

Similarly, when performing VXLAN decapsulation, the FID of the packet
needs to be determined. This FID is derived from VNI classification
performed during decapsulation.

In the old model, both entries (i.e., FID->VNI and VNI->FID) were
configured via SFMR.vni.

In the new model, where ingress is separated from egress, ingress
configuration (VNI->FID) is performed via SVFA, while SFMR only
configures egress (FID->VNI).

Add 'vni' field to SVFA, add new mapping table - VNI to FID, add new
pack() function for VNI mapping and edit the comment in SFMR.

Signed-off-by: Amit Cohen <amcohen@nvidia.com>
Reviewed-by: Danielle Ratson <danieller@nvidia.com>
Reviewed-by: Petr Machata <petrm@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlxsw/reg.h
drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c

index 9992b64d041537c0f5d6d11164ed828c3277e395..33d460a60816cf3f1e651147e0e53e1d93ac9a4c 100644 (file)
@@ -1573,6 +1573,7 @@ MLXSW_ITEM32_LP(reg, svfa, 0x00, 16, 0x00, 12);
 enum mlxsw_reg_svfa_mt {
        MLXSW_REG_SVFA_MT_VID_TO_FID,
        MLXSW_REG_SVFA_MT_PORT_VID_TO_FID,
+       MLXSW_REG_SVFA_MT_VNI_TO_FID,
 };
 
 /* reg_svfa_mapping_table
@@ -1622,6 +1623,14 @@ MLXSW_ITEM32(reg, svfa, counter_set_type, 0x08, 24, 8);
  */
 MLXSW_ITEM32(reg, svfa, counter_index, 0x08, 0, 24);
 
+/* reg_svfa_vni
+ * Virtual Network Identifier.
+ * Access: Index
+ *
+ * Note: Reserved when mapping_table is not 2 (VNI mapping table).
+ */
+MLXSW_ITEM32(reg, svfa, vni, 0x10, 0, 24);
+
 /* reg_svfa_irif_v
  * Ingress RIF valid.
  * 0 - Ingress RIF is not valid, no ingress RIF assigned.
@@ -1642,20 +1651,45 @@ MLXSW_ITEM32(reg, svfa, irif_v, 0x14, 24, 1);
  */
 MLXSW_ITEM32(reg, svfa, irif, 0x14, 0, 16);
 
-static inline void mlxsw_reg_svfa_pack(char *payload, u16 local_port,
-                                      enum mlxsw_reg_svfa_mt mt, bool valid,
-                                      u16 fid, u16 vid)
+static inline void __mlxsw_reg_svfa_pack(char *payload,
+                                        enum mlxsw_reg_svfa_mt mt, bool valid,
+                                        u16 fid)
 {
        MLXSW_REG_ZERO(svfa, payload);
-       local_port = mt == MLXSW_REG_SVFA_MT_VID_TO_FID ? 0 : local_port;
        mlxsw_reg_svfa_swid_set(payload, 0);
-       mlxsw_reg_svfa_local_port_set(payload, local_port);
        mlxsw_reg_svfa_mapping_table_set(payload, mt);
        mlxsw_reg_svfa_v_set(payload, valid);
        mlxsw_reg_svfa_fid_set(payload, fid);
+}
+
+static inline void mlxsw_reg_svfa_port_vid_pack(char *payload, u16 local_port,
+                                               bool valid, u16 fid, u16 vid)
+{
+       enum mlxsw_reg_svfa_mt mt = MLXSW_REG_SVFA_MT_PORT_VID_TO_FID;
+
+       __mlxsw_reg_svfa_pack(payload, mt, valid, fid);
+       mlxsw_reg_svfa_local_port_set(payload, local_port);
        mlxsw_reg_svfa_vid_set(payload, vid);
 }
 
+static inline void mlxsw_reg_svfa_vid_pack(char *payload, bool valid, u16 fid,
+                                          u16 vid)
+{
+       enum mlxsw_reg_svfa_mt mt = MLXSW_REG_SVFA_MT_VID_TO_FID;
+
+       __mlxsw_reg_svfa_pack(payload, mt, valid, fid);
+       mlxsw_reg_svfa_vid_set(payload, vid);
+}
+
+static inline void mlxsw_reg_svfa_vni_pack(char *payload, bool valid, u16 fid,
+                                          u32 vni)
+{
+       enum mlxsw_reg_svfa_mt mt = MLXSW_REG_SVFA_MT_VNI_TO_FID;
+
+       __mlxsw_reg_svfa_pack(payload, mt, valid, fid);
+       mlxsw_reg_svfa_vni_set(payload, vni);
+}
+
 /*  SPVTR - Switch Port VLAN Stacking Register
  *  ------------------------------------------
  *  The Switch Port VLAN Stacking register configures the VLAN mode of the port
@@ -1878,9 +1912,10 @@ MLXSW_ITEM32(reg, sfmr, vv, 0x10, 31, 1);
 
 /* reg_sfmr_vni
  * Virtual Network Identifier.
+ * When legacy bridge model is used, a given VNI can only be assigned to one
+ * FID. When unified bridge model is used, it configures only the FID->VNI,
+ * the VNI->FID is done by SVFA.
  * Access: RW
- *
- * Note: A given VNI can only be assigned to one FID.
  */
 MLXSW_ITEM32(reg, sfmr, vni, 0x10, 0, 24);
 
index ce80931f0402adba861007db6923bd7a73f5f327..86b88e686fd3f825ac9a19c4810769979da87a3b 100644 (file)
@@ -441,10 +441,10 @@ static int mlxsw_sp_fid_vni_op(struct mlxsw_sp *mlxsw_sp, u16 fid_index,
 static int __mlxsw_sp_fid_port_vid_map(struct mlxsw_sp *mlxsw_sp, u16 fid_index,
                                       u16 local_port, u16 vid, bool valid)
 {
-       enum mlxsw_reg_svfa_mt mt = MLXSW_REG_SVFA_MT_PORT_VID_TO_FID;
        char svfa_pl[MLXSW_REG_SVFA_LEN];
 
-       mlxsw_reg_svfa_pack(svfa_pl, local_port, mt, valid, fid_index, vid);
+       mlxsw_reg_svfa_port_vid_pack(svfa_pl, local_port, valid, fid_index,
+                                    vid);
        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(svfa), svfa_pl);
 }