1 /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */ 2 /* Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved */ 3 4 #ifndef _MLXSW_SPECTRUM_ACL_TCAM_H 5 #define _MLXSW_SPECTRUM_ACL_TCAM_H 6 7 #include <linux/list.h> 8 #include <linux/parman.h> 9 10 #include "reg.h" 11 #include "spectrum.h" 12 #include "core_acl_flex_keys.h" 13 14 struct mlxsw_sp_acl_tcam { 15 unsigned long *used_regions; /* bit array */ 16 unsigned int max_regions; 17 unsigned long *used_groups; /* bit array */ 18 unsigned int max_groups; 19 unsigned int max_group_size; 20 unsigned long priv[0]; 21 /* priv has to be always the last item */ 22 }; 23 24 size_t mlxsw_sp_acl_tcam_priv_size(struct mlxsw_sp *mlxsw_sp); 25 int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp, 26 struct mlxsw_sp_acl_tcam *tcam); 27 void mlxsw_sp_acl_tcam_fini(struct mlxsw_sp *mlxsw_sp, 28 struct mlxsw_sp_acl_tcam *tcam); 29 int mlxsw_sp_acl_tcam_priority_get(struct mlxsw_sp *mlxsw_sp, 30 struct mlxsw_sp_acl_rule_info *rulei, 31 u32 *priority, bool fillup_priority); 32 33 struct mlxsw_sp_acl_profile_ops { 34 size_t ruleset_priv_size; 35 int (*ruleset_add)(struct mlxsw_sp *mlxsw_sp, 36 struct mlxsw_sp_acl_tcam *tcam, void *ruleset_priv, 37 struct mlxsw_afk_element_usage *tmplt_elusage); 38 void (*ruleset_del)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv); 39 int (*ruleset_bind)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv, 40 struct mlxsw_sp_port *mlxsw_sp_port, 41 bool ingress); 42 void (*ruleset_unbind)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv, 43 struct mlxsw_sp_port *mlxsw_sp_port, 44 bool ingress); 45 u16 (*ruleset_group_id)(void *ruleset_priv); 46 size_t (*rule_priv_size)(struct mlxsw_sp *mlxsw_sp); 47 int (*rule_add)(struct mlxsw_sp *mlxsw_sp, 48 void *ruleset_priv, void *rule_priv, 49 struct mlxsw_sp_acl_rule_info *rulei); 50 void (*rule_del)(struct mlxsw_sp *mlxsw_sp, void *rule_priv); 51 int (*rule_activity_get)(struct mlxsw_sp *mlxsw_sp, void *rule_priv, 52 bool *activity); 53 }; 54 55 const struct mlxsw_sp_acl_profile_ops * 56 mlxsw_sp_acl_tcam_profile_ops(struct mlxsw_sp *mlxsw_sp, 57 enum mlxsw_sp_acl_profile profile); 58 59 #define MLXSW_SP_ACL_TCAM_REGION_BASE_COUNT 16 60 #define MLXSW_SP_ACL_TCAM_REGION_RESIZE_STEP 16 61 62 #define MLXSW_SP_ACL_TCAM_CATCHALL_PRIO (~0U) 63 64 #define MLXSW_SP_ACL_TCAM_MASK_LEN \ 65 (MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN * BITS_PER_BYTE) 66 67 struct mlxsw_sp_acl_tcam_group; 68 69 struct mlxsw_sp_acl_tcam_region { 70 struct list_head list; /* Member of a TCAM group */ 71 struct list_head chunk_list; /* List of chunks under this region */ 72 struct mlxsw_sp_acl_tcam_group *group; 73 enum mlxsw_reg_ptar_key_type key_type; 74 u16 id; /* ACL ID and region ID - they are same */ 75 char tcam_region_info[MLXSW_REG_PXXX_TCAM_REGION_INFO_LEN]; 76 struct mlxsw_afk_key_info *key_info; 77 struct mlxsw_sp *mlxsw_sp; 78 unsigned long priv[0]; 79 /* priv has to be always the last item */ 80 }; 81 82 struct mlxsw_sp_acl_ctcam_region { 83 struct parman *parman; 84 const struct mlxsw_sp_acl_ctcam_region_ops *ops; 85 struct mlxsw_sp_acl_tcam_region *region; 86 }; 87 88 struct mlxsw_sp_acl_ctcam_chunk { 89 struct parman_prio parman_prio; 90 }; 91 92 struct mlxsw_sp_acl_ctcam_entry { 93 struct parman_item parman_item; 94 }; 95 96 struct mlxsw_sp_acl_ctcam_region_ops { 97 int (*entry_insert)(struct mlxsw_sp_acl_ctcam_region *cregion, 98 struct mlxsw_sp_acl_ctcam_entry *centry, 99 const char *mask); 100 void (*entry_remove)(struct mlxsw_sp_acl_ctcam_region *cregion, 101 struct mlxsw_sp_acl_ctcam_entry *centry); 102 }; 103 104 int 105 mlxsw_sp_acl_ctcam_region_init(struct mlxsw_sp *mlxsw_sp, 106 struct mlxsw_sp_acl_ctcam_region *cregion, 107 struct mlxsw_sp_acl_tcam_region *region, 108 const struct mlxsw_sp_acl_ctcam_region_ops *ops); 109 void mlxsw_sp_acl_ctcam_region_fini(struct mlxsw_sp_acl_ctcam_region *cregion); 110 void mlxsw_sp_acl_ctcam_chunk_init(struct mlxsw_sp_acl_ctcam_region *cregion, 111 struct mlxsw_sp_acl_ctcam_chunk *cchunk, 112 unsigned int priority); 113 void mlxsw_sp_acl_ctcam_chunk_fini(struct mlxsw_sp_acl_ctcam_chunk *cchunk); 114 int mlxsw_sp_acl_ctcam_entry_add(struct mlxsw_sp *mlxsw_sp, 115 struct mlxsw_sp_acl_ctcam_region *cregion, 116 struct mlxsw_sp_acl_ctcam_chunk *cchunk, 117 struct mlxsw_sp_acl_ctcam_entry *centry, 118 struct mlxsw_sp_acl_rule_info *rulei, 119 bool fillup_priority); 120 void mlxsw_sp_acl_ctcam_entry_del(struct mlxsw_sp *mlxsw_sp, 121 struct mlxsw_sp_acl_ctcam_region *cregion, 122 struct mlxsw_sp_acl_ctcam_chunk *cchunk, 123 struct mlxsw_sp_acl_ctcam_entry *centry); 124 static inline unsigned int 125 mlxsw_sp_acl_ctcam_entry_offset(struct mlxsw_sp_acl_ctcam_entry *centry) 126 { 127 return centry->parman_item.index; 128 } 129 130 enum mlxsw_sp_acl_atcam_region_type { 131 MLXSW_SP_ACL_ATCAM_REGION_TYPE_2KB, 132 MLXSW_SP_ACL_ATCAM_REGION_TYPE_4KB, 133 MLXSW_SP_ACL_ATCAM_REGION_TYPE_8KB, 134 MLXSW_SP_ACL_ATCAM_REGION_TYPE_12KB, 135 __MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX, 136 }; 137 138 #define MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX \ 139 (__MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX - 1) 140 141 struct mlxsw_sp_acl_atcam { 142 struct mlxsw_sp_acl_erp_core *erp_core; 143 }; 144 145 struct mlxsw_sp_acl_atcam_region { 146 struct rhashtable entries_ht; /* A-TCAM only */ 147 struct mlxsw_sp_acl_ctcam_region cregion; 148 const struct mlxsw_sp_acl_atcam_region_ops *ops; 149 struct mlxsw_sp_acl_tcam_region *region; 150 struct mlxsw_sp_acl_atcam *atcam; 151 enum mlxsw_sp_acl_atcam_region_type type; 152 struct mlxsw_sp_acl_erp_table *erp_table; 153 void *priv; 154 }; 155 156 struct mlxsw_sp_acl_atcam_entry_ht_key { 157 char enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN]; /* Encoded key */ 158 u8 erp_id; 159 }; 160 161 struct mlxsw_sp_acl_atcam_chunk { 162 struct mlxsw_sp_acl_ctcam_chunk cchunk; 163 }; 164 165 struct mlxsw_sp_acl_atcam_entry { 166 struct rhash_head ht_node; 167 struct mlxsw_sp_acl_atcam_entry_ht_key ht_key; 168 struct mlxsw_sp_acl_ctcam_entry centry; 169 struct mlxsw_sp_acl_atcam_lkey_id *lkey_id; 170 struct mlxsw_sp_acl_erp *erp; 171 }; 172 173 static inline struct mlxsw_sp_acl_atcam_region * 174 mlxsw_sp_acl_tcam_cregion_aregion(struct mlxsw_sp_acl_ctcam_region *cregion) 175 { 176 return container_of(cregion, struct mlxsw_sp_acl_atcam_region, cregion); 177 } 178 179 static inline struct mlxsw_sp_acl_atcam_entry * 180 mlxsw_sp_acl_tcam_centry_aentry(struct mlxsw_sp_acl_ctcam_entry *centry) 181 { 182 return container_of(centry, struct mlxsw_sp_acl_atcam_entry, centry); 183 } 184 185 int mlxsw_sp_acl_atcam_region_associate(struct mlxsw_sp *mlxsw_sp, 186 u16 region_id); 187 int 188 mlxsw_sp_acl_atcam_region_init(struct mlxsw_sp *mlxsw_sp, 189 struct mlxsw_sp_acl_atcam *atcam, 190 struct mlxsw_sp_acl_atcam_region *aregion, 191 struct mlxsw_sp_acl_tcam_region *region, 192 const struct mlxsw_sp_acl_ctcam_region_ops *ops); 193 void mlxsw_sp_acl_atcam_region_fini(struct mlxsw_sp_acl_atcam_region *aregion); 194 void mlxsw_sp_acl_atcam_chunk_init(struct mlxsw_sp_acl_atcam_region *aregion, 195 struct mlxsw_sp_acl_atcam_chunk *achunk, 196 unsigned int priority); 197 void mlxsw_sp_acl_atcam_chunk_fini(struct mlxsw_sp_acl_atcam_chunk *achunk); 198 int mlxsw_sp_acl_atcam_entry_add(struct mlxsw_sp *mlxsw_sp, 199 struct mlxsw_sp_acl_atcam_region *aregion, 200 struct mlxsw_sp_acl_atcam_chunk *achunk, 201 struct mlxsw_sp_acl_atcam_entry *aentry, 202 struct mlxsw_sp_acl_rule_info *rulei); 203 void mlxsw_sp_acl_atcam_entry_del(struct mlxsw_sp *mlxsw_sp, 204 struct mlxsw_sp_acl_atcam_region *aregion, 205 struct mlxsw_sp_acl_atcam_chunk *achunk, 206 struct mlxsw_sp_acl_atcam_entry *aentry); 207 int mlxsw_sp_acl_atcam_init(struct mlxsw_sp *mlxsw_sp, 208 struct mlxsw_sp_acl_atcam *atcam); 209 void mlxsw_sp_acl_atcam_fini(struct mlxsw_sp *mlxsw_sp, 210 struct mlxsw_sp_acl_atcam *atcam); 211 212 struct mlxsw_sp_acl_erp; 213 214 bool mlxsw_sp_acl_erp_is_ctcam_erp(const struct mlxsw_sp_acl_erp *erp); 215 u8 mlxsw_sp_acl_erp_id(const struct mlxsw_sp_acl_erp *erp); 216 struct mlxsw_sp_acl_erp * 217 mlxsw_sp_acl_erp_get(struct mlxsw_sp_acl_atcam_region *aregion, 218 const char *mask, bool ctcam); 219 void mlxsw_sp_acl_erp_put(struct mlxsw_sp_acl_atcam_region *aregion, 220 struct mlxsw_sp_acl_erp *erp); 221 int mlxsw_sp_acl_erp_region_init(struct mlxsw_sp_acl_atcam_region *aregion); 222 void mlxsw_sp_acl_erp_region_fini(struct mlxsw_sp_acl_atcam_region *aregion); 223 int mlxsw_sp_acl_erps_init(struct mlxsw_sp *mlxsw_sp, 224 struct mlxsw_sp_acl_atcam *atcam); 225 void mlxsw_sp_acl_erps_fini(struct mlxsw_sp *mlxsw_sp, 226 struct mlxsw_sp_acl_atcam *atcam); 227 228 #endif 229