mlxsw: spectrum_acl: Implement priority setting for rules inserted to TCAM
authorJiri Pirko <jiri@mellanox.com>
Sun, 8 Jul 2018 20:51:25 +0000 (23:51 +0300)
committerDavid S. Miller <davem@davemloft.net>
Mon, 9 Jul 2018 23:24:17 +0000 (16:24 -0700)
For Spectrum-2, we need to insert priority to C-TCAM because HW
needs that info in order to correctly process scenarios where rules
are in both C-TCAM and A-TCAM.

So extend the mlxsw_sp_acl_ctcam_entry_add() args to accept indication
if priority needs to be filled up and implement the priority
computation and fill-up.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlxsw/spectrum1_acl_tcam.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_ctcam.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h

index 752c2ecd7a02f98d24ec2fa84c019458d698a1f4..04f0c9cfae244378f53988d699232c52aa768121 100644 (file)
@@ -91,7 +91,8 @@ mlxsw_sp1_acl_ctcam_region_catchall_add(struct mlxsw_sp *mlxsw_sp,
                goto err_rulei_commit;
        err = mlxsw_sp_acl_ctcam_entry_add(mlxsw_sp, &region->cregion,
                                           &region->catchall.cchunk,
-                                          &region->catchall.centry, rulei);
+                                          &region->catchall.centry,
+                                          rulei, false);
        if (err)
                goto err_entry_add;
        region->catchall.rulei = rulei;
@@ -178,7 +179,7 @@ static int mlxsw_sp1_acl_tcam_entry_add(struct mlxsw_sp *mlxsw_sp,
 
        return mlxsw_sp_acl_ctcam_entry_add(mlxsw_sp, &region->cregion,
                                            &chunk->cchunk, &entry->centry,
-                                           rulei);
+                                           rulei, false);
 }
 
 static void mlxsw_sp1_acl_tcam_entry_del(struct mlxsw_sp *mlxsw_sp,
index 34546abb3fe589b6d902a39d905bfef632f4b8cc..ef0d4c0a5a1f9b492f2936064f668c28b50d0871 100644 (file)
@@ -71,16 +71,24 @@ static int
 mlxsw_sp_acl_ctcam_region_entry_insert(struct mlxsw_sp *mlxsw_sp,
                                       struct mlxsw_sp_acl_tcam_region *region,
                                       unsigned int offset,
-                                      struct mlxsw_sp_acl_rule_info *rulei)
+                                      struct mlxsw_sp_acl_rule_info *rulei,
+                                      bool fillup_priority)
 {
        struct mlxsw_afk *afk = mlxsw_sp_acl_afk(mlxsw_sp->acl);
        char ptce2_pl[MLXSW_REG_PTCE2_LEN];
        char *act_set;
+       u32 priority;
        char *mask;
        char *key;
+       int err;
+
+       err = mlxsw_sp_acl_tcam_priority_get(mlxsw_sp, rulei, &priority,
+                                            fillup_priority);
+       if (err)
+               return err;
 
        mlxsw_reg_ptce2_pack(ptce2_pl, true, MLXSW_REG_PTCE2_OP_WRITE_WRITE,
-                            region->tcam_region_info, offset, 0);
+                            region->tcam_region_info, offset, priority);
        key = mlxsw_reg_ptce2_flex_key_blocks_data(ptce2_pl);
        mask = mlxsw_reg_ptce2_mask_data(ptce2_pl);
        mlxsw_afk_encode(afk, region->key_info, &rulei->values, key, mask);
@@ -172,7 +180,8 @@ int mlxsw_sp_acl_ctcam_entry_add(struct mlxsw_sp *mlxsw_sp,
                                 struct mlxsw_sp_acl_ctcam_region *cregion,
                                 struct mlxsw_sp_acl_ctcam_chunk *cchunk,
                                 struct mlxsw_sp_acl_ctcam_entry *centry,
-                                struct mlxsw_sp_acl_rule_info *rulei)
+                                struct mlxsw_sp_acl_rule_info *rulei,
+                                bool fillup_priority)
 {
        int err;
 
@@ -183,7 +192,7 @@ int mlxsw_sp_acl_ctcam_entry_add(struct mlxsw_sp *mlxsw_sp,
 
        err = mlxsw_sp_acl_ctcam_region_entry_insert(mlxsw_sp, cregion->region,
                                                     centry->parman_item.index,
-                                                    rulei);
+                                                    rulei, fillup_priority);
        if (err)
                goto err_rule_insert;
        return 0;
index f5015a787964381c06faa60e6b186fbd851ed8c0..53fe51a8d720891389a4e9493bafab8a98b139b8 100644 (file)
@@ -112,6 +112,29 @@ void mlxsw_sp_acl_tcam_fini(struct mlxsw_sp *mlxsw_sp,
        kfree(tcam->used_regions);
 }
 
+int mlxsw_sp_acl_tcam_priority_get(struct mlxsw_sp *mlxsw_sp,
+                                  struct mlxsw_sp_acl_rule_info *rulei,
+                                  u32 *priority, bool fillup_priority)
+{
+       u64 max_priority;
+
+       if (!fillup_priority) {
+               *priority = 0;
+               return 0;
+       }
+
+       if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, KVD_SIZE))
+               return -EIO;
+
+       max_priority = MLXSW_CORE_RES_GET(mlxsw_sp->core, KVD_SIZE);
+       if (rulei->priority > max_priority)
+               return -EINVAL;
+
+       /* Unlike in TC, in HW, higher number means higher priority. */
+       *priority = max_priority - rulei->priority;
+       return 0;
+}
+
 static int mlxsw_sp_acl_tcam_region_id_get(struct mlxsw_sp_acl_tcam *tcam,
                                           u16 *p_id)
 {
index e01b75bcf009b63c3404e66ced8d8d81ae9d84f7..cef769764505b62b1f45b7580bd1af0414608ff4 100644 (file)
@@ -57,6 +57,9 @@ int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp,
                           struct mlxsw_sp_acl_tcam *tcam);
 void mlxsw_sp_acl_tcam_fini(struct mlxsw_sp *mlxsw_sp,
                            struct mlxsw_sp_acl_tcam *tcam);
+int mlxsw_sp_acl_tcam_priority_get(struct mlxsw_sp *mlxsw_sp,
+                                  struct mlxsw_sp_acl_rule_info *rulei,
+                                  u32 *priority, bool fillup_priority);
 
 struct mlxsw_sp_acl_profile_ops {
        size_t ruleset_priv_size;
@@ -128,7 +131,8 @@ int mlxsw_sp_acl_ctcam_entry_add(struct mlxsw_sp *mlxsw_sp,
                                 struct mlxsw_sp_acl_ctcam_region *cregion,
                                 struct mlxsw_sp_acl_ctcam_chunk *cchunk,
                                 struct mlxsw_sp_acl_ctcam_entry *centry,
-                                struct mlxsw_sp_acl_rule_info *rulei);
+                                struct mlxsw_sp_acl_rule_info *rulei,
+                                bool fillup_priority);
 void mlxsw_sp_acl_ctcam_entry_del(struct mlxsw_sp *mlxsw_sp,
                                  struct mlxsw_sp_acl_ctcam_region *cregion,
                                  struct mlxsw_sp_acl_ctcam_chunk *cchunk,