1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(C) 2021 Marvell. 3 */ 4 5 #include <inttypes.h> 6 #include <math.h> 7 8 #include "cnxk_ethdev.h" 9 10 struct sdp_channel { 11 bool is_sdp_mask_set; 12 uint16_t channel; 13 uint16_t mask; 14 }; 15 16 struct flow_pre_l2_size_info { 17 uint8_t pre_l2_size_off; 18 uint8_t pre_l2_size_off_mask; 19 uint8_t pre_l2_size_shift_dir; 20 }; 21 22 static int 23 parse_outb_nb_desc(const char *key, const char *value, void *extra_args) 24 { 25 RTE_SET_USED(key); 26 uint32_t val; 27 28 val = atoi(value); 29 30 *(uint16_t *)extra_args = val; 31 32 return 0; 33 } 34 35 static int 36 parse_outb_nb_crypto_qs(const char *key, const char *value, void *extra_args) 37 { 38 RTE_SET_USED(key); 39 uint32_t val; 40 41 val = atoi(value); 42 43 if (val < 1 || val > 64) 44 return -EINVAL; 45 46 *(uint16_t *)extra_args = val; 47 48 return 0; 49 } 50 51 static int 52 parse_ipsec_in_spi_range(const char *key, const char *value, void *extra_args) 53 { 54 RTE_SET_USED(key); 55 uint32_t val; 56 57 errno = 0; 58 val = strtoul(value, NULL, 0); 59 if (errno) 60 val = 0; 61 62 *(uint32_t *)extra_args = val; 63 64 return 0; 65 } 66 67 static int 68 parse_ipsec_out_max_sa(const char *key, const char *value, void *extra_args) 69 { 70 RTE_SET_USED(key); 71 uint32_t val; 72 73 errno = 0; 74 val = strtoul(value, NULL, 0); 75 if (errno) 76 val = 0; 77 78 *(uint16_t *)extra_args = val; 79 80 return 0; 81 } 82 83 static int 84 parse_flow_max_priority(const char *key, const char *value, void *extra_args) 85 { 86 RTE_SET_USED(key); 87 uint16_t val; 88 89 val = atoi(value); 90 91 /* Limit the max priority to 32 */ 92 if (val < 1 || val > 32) 93 return -EINVAL; 94 95 *(uint16_t *)extra_args = val; 96 97 return 0; 98 } 99 100 static int 101 parse_flow_prealloc_size(const char *key, const char *value, void *extra_args) 102 { 103 RTE_SET_USED(key); 104 uint16_t val; 105 106 val = atoi(value); 107 108 /* Limit the prealloc size to 32 */ 109 if (val < 1 || val > 32) 110 return -EINVAL; 111 112 *(uint16_t *)extra_args = val; 113 114 return 0; 115 } 116 117 static int 118 parse_reta_size(const char *key, const char *value, void *extra_args) 119 { 120 RTE_SET_USED(key); 121 uint32_t val; 122 123 val = atoi(value); 124 125 if (val <= RTE_ETH_RSS_RETA_SIZE_64) 126 val = ROC_NIX_RSS_RETA_SZ_64; 127 else if (val > RTE_ETH_RSS_RETA_SIZE_64 && val <= RTE_ETH_RSS_RETA_SIZE_128) 128 val = ROC_NIX_RSS_RETA_SZ_128; 129 else if (val > RTE_ETH_RSS_RETA_SIZE_128 && val <= RTE_ETH_RSS_RETA_SIZE_256) 130 val = ROC_NIX_RSS_RETA_SZ_256; 131 else 132 val = ROC_NIX_RSS_RETA_SZ_64; 133 134 *(uint16_t *)extra_args = val; 135 136 return 0; 137 } 138 139 static int 140 parse_pre_l2_hdr_info(const char *key, const char *value, void *extra_args) 141 { 142 struct flow_pre_l2_size_info *info = 143 (struct flow_pre_l2_size_info *)extra_args; 144 char *tok1 = NULL, *tok2 = NULL; 145 uint16_t off, off_mask, dir; 146 147 RTE_SET_USED(key); 148 off = strtol(value, &tok1, 16); 149 tok1++; 150 off_mask = strtol(tok1, &tok2, 16); 151 tok2++; 152 dir = strtol(tok2, 0, 16); 153 if (off >= 256 || off_mask < 1 || off_mask >= 256 || dir > 1) 154 return -EINVAL; 155 info->pre_l2_size_off = off; 156 info->pre_l2_size_off_mask = off_mask; 157 info->pre_l2_size_shift_dir = dir; 158 159 return 0; 160 } 161 162 static int 163 parse_flag(const char *key, const char *value, void *extra_args) 164 { 165 RTE_SET_USED(key); 166 167 *(uint16_t *)extra_args = atoi(value); 168 169 return 0; 170 } 171 172 static int 173 parse_sqb_count(const char *key, const char *value, void *extra_args) 174 { 175 RTE_SET_USED(key); 176 uint32_t val; 177 178 val = atoi(value); 179 180 *(uint16_t *)extra_args = val; 181 182 return 0; 183 } 184 185 static int 186 parse_switch_header_type(const char *key, const char *value, void *extra_args) 187 { 188 RTE_SET_USED(key); 189 190 if (strcmp(value, "higig2") == 0) 191 *(uint16_t *)extra_args = ROC_PRIV_FLAGS_HIGIG; 192 193 if (strcmp(value, "dsa") == 0) 194 *(uint16_t *)extra_args = ROC_PRIV_FLAGS_EDSA; 195 196 if (strcmp(value, "chlen90b") == 0) 197 *(uint16_t *)extra_args = ROC_PRIV_FLAGS_LEN_90B; 198 199 if (strcmp(value, "exdsa") == 0) 200 *(uint16_t *)extra_args = ROC_PRIV_FLAGS_EXDSA; 201 202 if (strcmp(value, "vlan_exdsa") == 0) 203 *(uint16_t *)extra_args = ROC_PRIV_FLAGS_VLAN_EXDSA; 204 205 if (strcmp(value, "pre_l2") == 0) 206 *(uint16_t *)extra_args = ROC_PRIV_FLAGS_PRE_L2; 207 208 return 0; 209 } 210 211 static int 212 parse_sdp_channel_mask(const char *key, const char *value, void *extra_args) 213 { 214 RTE_SET_USED(key); 215 uint16_t chan = 0, mask = 0; 216 char *next = 0; 217 218 /* next will point to the separator '/' */ 219 chan = strtol(value, &next, 16); 220 mask = strtol(++next, 0, 16); 221 222 if (chan > GENMASK(11, 0) || mask > GENMASK(11, 0)) 223 return -EINVAL; 224 225 ((struct sdp_channel *)extra_args)->channel = chan; 226 ((struct sdp_channel *)extra_args)->mask = mask; 227 ((struct sdp_channel *)extra_args)->is_sdp_mask_set = true; 228 229 return 0; 230 } 231 232 #define CNXK_RSS_RETA_SIZE "reta_size" 233 #define CNXK_SCL_ENABLE "scalar_enable" 234 #define CNXK_MAX_SQB_COUNT "max_sqb_count" 235 #define CNXK_FLOW_PREALLOC_SIZE "flow_prealloc_size" 236 #define CNXK_FLOW_MAX_PRIORITY "flow_max_priority" 237 #define CNXK_SWITCH_HEADER_TYPE "switch_header" 238 #define CNXK_RSS_TAG_AS_XOR "tag_as_xor" 239 #define CNXK_LOCK_RX_CTX "lock_rx_ctx" 240 #define CNXK_IPSEC_IN_MIN_SPI "ipsec_in_min_spi" 241 #define CNXK_IPSEC_IN_MAX_SPI "ipsec_in_max_spi" 242 #define CNXK_IPSEC_OUT_MAX_SA "ipsec_out_max_sa" 243 #define CNXK_OUTB_NB_DESC "outb_nb_desc" 244 #define CNXK_NO_INL_DEV "no_inl_dev" 245 #define CNXK_OUTB_NB_CRYPTO_QS "outb_nb_crypto_qs" 246 #define CNXK_SDP_CHANNEL_MASK "sdp_channel_mask" 247 #define CNXK_FLOW_PRE_L2_INFO "flow_pre_l2_info" 248 249 int 250 cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev) 251 { 252 uint16_t reta_sz = ROC_NIX_RSS_RETA_SZ_64; 253 uint16_t sqb_count = CNXK_NIX_TX_MAX_SQB; 254 struct flow_pre_l2_size_info pre_l2_info; 255 uint32_t ipsec_in_max_spi = BIT(8) - 1; 256 uint32_t ipsec_out_max_sa = BIT(12); 257 uint16_t flow_prealloc_size = 1; 258 uint16_t switch_header_type = 0; 259 uint16_t flow_max_priority = 3; 260 uint16_t outb_nb_crypto_qs = 1; 261 uint32_t ipsec_in_min_spi = 0; 262 uint16_t outb_nb_desc = 8200; 263 struct sdp_channel sdp_chan; 264 uint16_t rss_tag_as_xor = 0; 265 uint16_t scalar_enable = 0; 266 uint8_t lock_rx_ctx = 0; 267 struct rte_kvargs *kvlist; 268 uint16_t no_inl_dev = 0; 269 270 memset(&sdp_chan, 0, sizeof(sdp_chan)); 271 memset(&pre_l2_info, 0, sizeof(struct flow_pre_l2_size_info)); 272 273 if (devargs == NULL) 274 goto null_devargs; 275 276 kvlist = rte_kvargs_parse(devargs->args, NULL); 277 if (kvlist == NULL) 278 goto exit; 279 280 rte_kvargs_process(kvlist, CNXK_RSS_RETA_SIZE, &parse_reta_size, 281 &reta_sz); 282 rte_kvargs_process(kvlist, CNXK_SCL_ENABLE, &parse_flag, 283 &scalar_enable); 284 rte_kvargs_process(kvlist, CNXK_MAX_SQB_COUNT, &parse_sqb_count, 285 &sqb_count); 286 rte_kvargs_process(kvlist, CNXK_FLOW_PREALLOC_SIZE, 287 &parse_flow_prealloc_size, &flow_prealloc_size); 288 rte_kvargs_process(kvlist, CNXK_FLOW_MAX_PRIORITY, 289 &parse_flow_max_priority, &flow_max_priority); 290 rte_kvargs_process(kvlist, CNXK_SWITCH_HEADER_TYPE, 291 &parse_switch_header_type, &switch_header_type); 292 rte_kvargs_process(kvlist, CNXK_RSS_TAG_AS_XOR, &parse_flag, 293 &rss_tag_as_xor); 294 rte_kvargs_process(kvlist, CNXK_LOCK_RX_CTX, &parse_flag, &lock_rx_ctx); 295 rte_kvargs_process(kvlist, CNXK_IPSEC_IN_MIN_SPI, 296 &parse_ipsec_in_spi_range, &ipsec_in_min_spi); 297 rte_kvargs_process(kvlist, CNXK_IPSEC_IN_MAX_SPI, 298 &parse_ipsec_in_spi_range, &ipsec_in_max_spi); 299 rte_kvargs_process(kvlist, CNXK_IPSEC_OUT_MAX_SA, 300 &parse_ipsec_out_max_sa, &ipsec_out_max_sa); 301 rte_kvargs_process(kvlist, CNXK_OUTB_NB_DESC, &parse_outb_nb_desc, 302 &outb_nb_desc); 303 rte_kvargs_process(kvlist, CNXK_OUTB_NB_CRYPTO_QS, 304 &parse_outb_nb_crypto_qs, &outb_nb_crypto_qs); 305 rte_kvargs_process(kvlist, CNXK_NO_INL_DEV, &parse_flag, &no_inl_dev); 306 rte_kvargs_process(kvlist, CNXK_SDP_CHANNEL_MASK, 307 &parse_sdp_channel_mask, &sdp_chan); 308 rte_kvargs_process(kvlist, CNXK_FLOW_PRE_L2_INFO, 309 &parse_pre_l2_hdr_info, &pre_l2_info); 310 rte_kvargs_free(kvlist); 311 312 null_devargs: 313 dev->scalar_ena = !!scalar_enable; 314 dev->inb.no_inl_dev = !!no_inl_dev; 315 dev->inb.max_spi = ipsec_in_max_spi; 316 dev->outb.max_sa = ipsec_out_max_sa; 317 dev->outb.nb_desc = outb_nb_desc; 318 dev->outb.nb_crypto_qs = outb_nb_crypto_qs; 319 dev->nix.ipsec_in_min_spi = ipsec_in_min_spi; 320 dev->nix.ipsec_in_max_spi = ipsec_in_max_spi; 321 dev->nix.ipsec_out_max_sa = ipsec_out_max_sa; 322 dev->nix.rss_tag_as_xor = !!rss_tag_as_xor; 323 dev->nix.max_sqb_count = sqb_count; 324 dev->nix.reta_sz = reta_sz; 325 dev->nix.lock_rx_ctx = lock_rx_ctx; 326 dev->npc.flow_prealloc_size = flow_prealloc_size; 327 dev->npc.flow_max_priority = flow_max_priority; 328 dev->npc.switch_header_type = switch_header_type; 329 dev->npc.sdp_channel = sdp_chan.channel; 330 dev->npc.sdp_channel_mask = sdp_chan.mask; 331 dev->npc.is_sdp_mask_set = sdp_chan.is_sdp_mask_set; 332 dev->npc.pre_l2_size_offset = pre_l2_info.pre_l2_size_off; 333 dev->npc.pre_l2_size_offset_mask = pre_l2_info.pre_l2_size_off_mask; 334 dev->npc.pre_l2_size_shift_dir = pre_l2_info.pre_l2_size_shift_dir; 335 return 0; 336 exit: 337 return -EINVAL; 338 } 339 340 RTE_PMD_REGISTER_PARAM_STRING(net_cnxk, 341 CNXK_RSS_RETA_SIZE "=<64|128|256>" 342 CNXK_SCL_ENABLE "=1" 343 CNXK_MAX_SQB_COUNT "=<8-512>" 344 CNXK_FLOW_PREALLOC_SIZE "=<1-32>" 345 CNXK_FLOW_MAX_PRIORITY "=<1-32>" 346 CNXK_SWITCH_HEADER_TYPE "=<higig2|dsa|chlen90b>" 347 CNXK_RSS_TAG_AS_XOR "=1" 348 CNXK_IPSEC_IN_MAX_SPI "=<1-65535>" 349 CNXK_OUTB_NB_DESC "=<1-65535>" 350 CNXK_FLOW_PRE_L2_INFO "=<0-255>/<1-255>/<0-1>" 351 CNXK_OUTB_NB_CRYPTO_QS "=<1-64>" 352 CNXK_NO_INL_DEV "=0" 353 CNXK_SDP_CHANNEL_MASK "=<1-4095>/<1-4095>"); 354