1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2017-2021 NXP 3 */ 4 5 /* System headers */ 6 #include <stdio.h> 7 #include <inttypes.h> 8 #include <unistd.h> 9 #include <sys/types.h> 10 11 #include <dpaa_ethdev.h> 12 #include <dpaa_flow.h> 13 #include <rte_dpaa_logs.h> 14 #include <fmlib/fm_port_ext.h> 15 #include <fmlib/fm_vsp_ext.h> 16 17 #define FMC_OUTPUT_FORMAT_VER 0x106 18 19 #define FMC_NAME_LEN 64 20 #define FMC_FMAN_NUM 2 21 #define FMC_PORTS_PER_FMAN 16 22 #define FMC_SCHEMES_NUM 32 23 #define FMC_SCHEME_PROTOCOLS_NUM 16 24 #define FMC_CC_NODES_NUM 512 25 #define FMC_REPLICATORS_NUM 16 26 #define FMC_PLC_NUM 64 27 #define MAX_SP_CODE_SIZE 0x7C0 28 #define FMC_MANIP_MAX 64 29 #define FMC_HMANIP_MAX 512 30 #define FMC_INSERT_MAX 56 31 #define FM_PCD_MAX_REPS 64 32 33 typedef struct fmc_port_t { 34 e_fm_port_type type; 35 unsigned int number; 36 struct fm_pcd_net_env_params_t distinction_units; 37 struct ioc_fm_port_pcd_params_t pcd_param; 38 struct ioc_fm_port_pcd_prs_params_t prs_param; 39 struct ioc_fm_port_pcd_kg_params_t kg_param; 40 struct ioc_fm_port_pcd_cc_params_t cc_param; 41 char name[FMC_NAME_LEN]; 42 char cctree_name[FMC_NAME_LEN]; 43 t_handle handle; 44 t_handle env_id_handle; 45 t_handle env_id_dev_id; 46 t_handle cctree_handle; 47 t_handle cctree_dev_id; 48 49 unsigned int schemes_count; 50 unsigned int schemes[FMC_SCHEMES_NUM]; 51 unsigned int ccnodes_count; 52 unsigned int ccnodes[FMC_CC_NODES_NUM]; 53 unsigned int htnodes_count; 54 unsigned int htnodes[FMC_CC_NODES_NUM]; 55 56 unsigned int replicators_count; 57 unsigned int replicators[FMC_REPLICATORS_NUM]; 58 ioc_fm_port_vsp_alloc_params_t vsp_param; 59 60 unsigned int ccroot_count; 61 unsigned int ccroot[FMC_CC_NODES_NUM]; 62 enum ioc_fm_pcd_engine ccroot_type[FMC_CC_NODES_NUM]; 63 unsigned int ccroot_manip[FMC_CC_NODES_NUM]; 64 65 unsigned int reasm_index; 66 } fmc_port; 67 68 typedef struct fmc_fman_t { 69 unsigned int number; 70 unsigned int port_count; 71 unsigned int ports[FMC_PORTS_PER_FMAN]; 72 char name[FMC_NAME_LEN]; 73 t_handle handle; 74 char pcd_name[FMC_NAME_LEN]; 75 t_handle pcd_handle; 76 unsigned int kg_payload_offset; 77 78 unsigned int offload_support; 79 80 unsigned int reasm_count; 81 struct fm_pcd_manip_params_t reasm[FMC_MANIP_MAX]; 82 char reasm_name[FMC_MANIP_MAX][FMC_NAME_LEN]; 83 t_handle reasm_handle[FMC_MANIP_MAX]; 84 t_handle reasm_dev_id[FMC_MANIP_MAX]; 85 86 unsigned int frag_count; 87 struct fm_pcd_manip_params_t frag[FMC_MANIP_MAX]; 88 char frag_name[FMC_MANIP_MAX][FMC_NAME_LEN]; 89 t_handle frag_handle[FMC_MANIP_MAX]; 90 t_handle frag_dev_id[FMC_MANIP_MAX]; 91 92 unsigned int hdr_count; 93 struct fm_pcd_manip_params_t hdr[FMC_HMANIP_MAX]; 94 uint8_t insert_data[FMC_HMANIP_MAX][FMC_INSERT_MAX]; 95 char hdr_name[FMC_HMANIP_MAX][FMC_NAME_LEN]; 96 t_handle hdr_handle[FMC_HMANIP_MAX]; 97 t_handle hdr_dev_id[FMC_HMANIP_MAX]; 98 unsigned int hdr_has_next[FMC_HMANIP_MAX]; 99 unsigned int hdr_next[FMC_HMANIP_MAX]; 100 } fmc_fman; 101 102 typedef enum fmc_apply_order_e { 103 fmcengine_start, 104 fmcengine_end, 105 fmcport_start, 106 fmcport_end, 107 fmcscheme, 108 fmcccnode, 109 fmchtnode, 110 fmccctree, 111 fmcpolicer, 112 fmcreplicator, 113 fmcmanipulation 114 } fmc_apply_order_e; 115 116 typedef struct fmc_apply_order_t { 117 fmc_apply_order_e type; 118 unsigned int index; 119 } fmc_apply_order; 120 121 struct fmc_model_t { 122 unsigned int format_version; 123 unsigned int sp_enable; 124 t_fm_pcd_prs_sw_params sp; 125 uint8_t spcode[MAX_SP_CODE_SIZE]; 126 127 unsigned int fman_count; 128 fmc_fman fman[FMC_FMAN_NUM]; 129 130 unsigned int port_count; 131 fmc_port port[FMC_FMAN_NUM * FMC_PORTS_PER_FMAN]; 132 133 unsigned int scheme_count; 134 char scheme_name[FMC_SCHEMES_NUM][FMC_NAME_LEN]; 135 t_handle scheme_handle[FMC_SCHEMES_NUM]; 136 t_handle scheme_dev_id[FMC_SCHEMES_NUM]; 137 struct fm_pcd_kg_scheme_params_t scheme[FMC_SCHEMES_NUM]; 138 139 unsigned int ccnode_count; 140 char ccnode_name[FMC_CC_NODES_NUM][FMC_NAME_LEN]; 141 t_handle ccnode_handle[FMC_CC_NODES_NUM]; 142 t_handle ccnode_dev_id[FMC_CC_NODES_NUM]; 143 struct fm_pcd_cc_node_params_t ccnode[FMC_CC_NODES_NUM]; 144 uint8_t cckeydata[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS] 145 [FM_PCD_MAX_SIZE_OF_KEY]; 146 unsigned char ccmask[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS] 147 [FM_PCD_MAX_SIZE_OF_KEY]; 148 unsigned int 149 ccentry_action_index[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS]; 150 enum ioc_fm_pcd_engine 151 ccentry_action_type[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS]; 152 unsigned char ccentry_frag[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS]; 153 unsigned int ccentry_manip[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS]; 154 unsigned int ccmiss_action_index[FMC_CC_NODES_NUM]; 155 enum ioc_fm_pcd_engine ccmiss_action_type[FMC_CC_NODES_NUM]; 156 unsigned char ccmiss_frag[FMC_CC_NODES_NUM]; 157 unsigned int ccmiss_manip[FMC_CC_NODES_NUM]; 158 159 unsigned int htnode_count; 160 char htnode_name[FMC_CC_NODES_NUM][FMC_NAME_LEN]; 161 t_handle htnode_handle[FMC_CC_NODES_NUM]; 162 t_handle htnode_dev_id[FMC_CC_NODES_NUM]; 163 struct fm_pcd_hash_table_params_t htnode[FMC_CC_NODES_NUM]; 164 165 unsigned int htentry_count[FMC_CC_NODES_NUM]; 166 struct ioc_fm_pcd_cc_key_params_t 167 htentry[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS]; 168 uint8_t htkeydata[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS] 169 [FM_PCD_MAX_SIZE_OF_KEY]; 170 unsigned int 171 htentry_action_index[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS]; 172 enum ioc_fm_pcd_engine 173 htentry_action_type[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS]; 174 unsigned char htentry_frag[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS]; 175 unsigned int htentry_manip[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS]; 176 177 unsigned int htmiss_action_index[FMC_CC_NODES_NUM]; 178 enum ioc_fm_pcd_engine htmiss_action_type[FMC_CC_NODES_NUM]; 179 unsigned char htmiss_frag[FMC_CC_NODES_NUM]; 180 unsigned int htmiss_manip[FMC_CC_NODES_NUM]; 181 182 unsigned int replicator_count; 183 char replicator_name[FMC_REPLICATORS_NUM][FMC_NAME_LEN]; 184 t_handle replicator_handle[FMC_REPLICATORS_NUM]; 185 t_handle replicator_dev_id[FMC_REPLICATORS_NUM]; 186 struct fm_pcd_frm_replic_group_params_t replicator[FMC_REPLICATORS_NUM]; 187 unsigned int 188 repentry_action_index[FMC_REPLICATORS_NUM][FM_PCD_MAX_REPS]; 189 unsigned char repentry_frag[FMC_REPLICATORS_NUM][FM_PCD_MAX_REPS]; 190 unsigned int repentry_manip[FMC_REPLICATORS_NUM][FM_PCD_MAX_REPS]; 191 192 unsigned int policer_count; 193 char policer_name[FMC_PLC_NUM][FMC_NAME_LEN]; 194 struct fm_pcd_plcr_profile_params_t policer[FMC_PLC_NUM]; 195 t_handle policer_handle[FMC_PLC_NUM]; 196 t_handle policer_dev_id[FMC_PLC_NUM]; 197 unsigned int policer_action_index[FMC_PLC_NUM][3]; 198 199 unsigned int apply_order_count; 200 fmc_apply_order apply_order[FMC_FMAN_NUM * 201 FMC_PORTS_PER_FMAN * 202 (FMC_SCHEMES_NUM + FMC_CC_NODES_NUM)]; 203 }; 204 205 struct fmc_model_t *g_fmc_model; 206 207 static int dpaa_port_fmc_port_parse(struct fman_if *fif, 208 const struct fmc_model_t *fmc_model, 209 int apply_idx) 210 { 211 int current_port = fmc_model->apply_order[apply_idx].index; 212 const fmc_port *pport = &fmc_model->port[current_port]; 213 const uint8_t mac_idx[] = {-1, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1}; 214 const uint8_t mac_type[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2}; 215 216 if (mac_idx[fif->mac_idx] != pport->number || 217 mac_type[fif->mac_idx] != pport->type) 218 return -1; 219 220 return current_port; 221 } 222 223 static int dpaa_port_fmc_scheme_parse(struct fman_if *fif, 224 const struct fmc_model_t *fmc, 225 int apply_idx, 226 uint16_t *rxq_idx, int max_nb_rxq, 227 uint32_t *fqids, int8_t *vspids) 228 { 229 int idx = fmc->apply_order[apply_idx].index; 230 uint32_t i; 231 232 if (!fmc->scheme[idx].override_storage_profile && 233 fif->is_shared_mac) { 234 DPAA_PMD_WARN("No VSP assigned to scheme %d for sharemac %d!", 235 idx, fif->mac_idx); 236 DPAA_PMD_WARN("Risk to receive pkts from skb pool to CRASH!"); 237 } 238 239 if (e_IOC_FM_PCD_DONE == 240 fmc->scheme[idx].next_engine) { 241 for (i = 0; i < fmc->scheme[idx] 242 .key_ext_and_hash.hash_dist_num_of_fqids; i++) { 243 uint32_t fqid = fmc->scheme[idx].base_fqid + i; 244 int k, found = 0; 245 246 if (fqid == fif->fqid_rx_def || 247 (fqid >= fif->fqid_rx_pcd && 248 fqid < (fif->fqid_rx_pcd + 249 fif->fqid_rx_pcd_count))) { 250 if (fif->is_shared_mac && 251 fmc->scheme[idx].override_storage_profile && 252 fmc->scheme[idx].storage_profile.direct && 253 fmc->scheme[idx].storage_profile 254 .profile_select.direct_relative_profile_id != 255 fif->base_profile_id) { 256 DPAA_PMD_ERR("Def RXQ must be associated with def VSP on sharemac!"); 257 258 return -1; 259 } 260 continue; 261 } 262 263 if (fif->is_shared_mac && 264 !fmc->scheme[idx].override_storage_profile) { 265 DPAA_PMD_ERR("RXQ to DPDK must be associated with VSP on sharemac!"); 266 return -1; 267 } 268 269 if (fif->is_shared_mac && 270 fmc->scheme[idx].override_storage_profile && 271 fmc->scheme[idx].storage_profile.direct && 272 fmc->scheme[idx].storage_profile 273 .profile_select.direct_relative_profile_id == 274 fif->base_profile_id) { 275 DPAA_PMD_ERR("RXQ can't be associated with default VSP on sharemac!"); 276 277 return -1; 278 } 279 280 if ((*rxq_idx) >= max_nb_rxq) { 281 DPAA_PMD_DEBUG("Too many queues in FMC policy" 282 "%d overflow %d", 283 (*rxq_idx), max_nb_rxq); 284 285 continue; 286 } 287 288 for (k = 0; k < (*rxq_idx); k++) { 289 if (fqids[k] == fqid) { 290 found = 1; 291 break; 292 } 293 } 294 295 if (found) 296 continue; 297 fqids[(*rxq_idx)] = fqid; 298 if (fmc->scheme[idx].override_storage_profile) { 299 if (fmc->scheme[idx].storage_profile.direct) { 300 vspids[(*rxq_idx)] = 301 fmc->scheme[idx].storage_profile 302 .profile_select 303 .direct_relative_profile_id; 304 } else { 305 vspids[(*rxq_idx)] = -1; 306 } 307 } else { 308 vspids[(*rxq_idx)] = -1; 309 } 310 (*rxq_idx)++; 311 } 312 } 313 314 return 0; 315 } 316 317 static int dpaa_port_fmc_ccnode_parse(struct fman_if *fif, 318 const struct fmc_model_t *fmc_model, 319 int apply_idx, 320 uint16_t *rxq_idx, int max_nb_rxq, 321 uint32_t *fqids, int8_t *vspids) 322 { 323 uint16_t j, k, found = 0; 324 const struct ioc_keys_params_t *keys_params; 325 uint32_t fqid, cc_idx = fmc_model->apply_order[apply_idx].index; 326 327 keys_params = &fmc_model->ccnode[cc_idx].keys_params; 328 329 if ((*rxq_idx) >= max_nb_rxq) { 330 DPAA_PMD_WARN("Too many queues in FMC policy %d overflow %d", 331 (*rxq_idx), max_nb_rxq); 332 333 return 0; 334 } 335 336 for (j = 0; j < keys_params->num_of_keys; ++j) { 337 found = 0; 338 fqid = keys_params->key_params[j].cc_next_engine_params 339 .params.enqueue_params.new_fqid; 340 341 /* We read DPDK queue from last classification rule present in 342 * FMC policy file. Hence, this check is required here. 343 * Also, the last classification rule in FMC policy file must 344 * have userspace queue so that it can be used by DPDK 345 * application. 346 */ 347 if (keys_params->key_params[j].cc_next_engine_params 348 .next_engine != e_IOC_FM_PCD_DONE) { 349 DPAA_PMD_WARN("FMC CC next engine not support"); 350 continue; 351 } 352 if (keys_params->key_params[j].cc_next_engine_params 353 .params.enqueue_params.action != 354 e_IOC_FM_PCD_ENQ_FRAME) 355 continue; 356 for (k = 0; k < (*rxq_idx); k++) { 357 if (fqids[k] == fqid) { 358 found = 1; 359 break; 360 } 361 } 362 if (found) 363 continue; 364 365 if ((*rxq_idx) >= max_nb_rxq) { 366 DPAA_PMD_WARN("Too many queues in FMC policy %d overflow %d", 367 (*rxq_idx), max_nb_rxq); 368 369 return 0; 370 } 371 372 fqids[(*rxq_idx)] = fqid; 373 vspids[(*rxq_idx)] = 374 keys_params->key_params[j].cc_next_engine_params 375 .params.enqueue_params 376 .new_relative_storage_profile_id; 377 378 if (vspids[(*rxq_idx)] == fif->base_profile_id && 379 fif->is_shared_mac) { 380 DPAA_PMD_ERR("VSP %d can NOT be used on DPDK.", 381 vspids[(*rxq_idx)]); 382 DPAA_PMD_ERR("It is associated to skb pool of shared interface."); 383 return -1; 384 } 385 (*rxq_idx)++; 386 } 387 388 return 0; 389 } 390 391 int dpaa_port_fmc_init(struct fman_if *fif, 392 uint32_t *fqids, int8_t *vspids, int max_nb_rxq) 393 { 394 int current_port = -1, ret; 395 uint16_t rxq_idx = 0; 396 const struct fmc_model_t *fmc_model; 397 uint32_t i; 398 399 if (!g_fmc_model) { 400 size_t bytes_read; 401 FILE *fp = fopen(FMC_FILE, "rb"); 402 403 if (!fp) { 404 DPAA_PMD_ERR("%s not exists", FMC_FILE); 405 return -1; 406 } 407 408 g_fmc_model = rte_malloc(NULL, sizeof(struct fmc_model_t), 64); 409 if (!g_fmc_model) { 410 DPAA_PMD_ERR("FMC memory alloc failed"); 411 fclose(fp); 412 return -1; 413 } 414 415 bytes_read = fread(g_fmc_model, 416 sizeof(struct fmc_model_t), 1, fp); 417 if (!bytes_read) { 418 DPAA_PMD_ERR("No bytes read"); 419 fclose(fp); 420 rte_free(g_fmc_model); 421 g_fmc_model = NULL; 422 return -1; 423 } 424 fclose(fp); 425 } 426 427 fmc_model = g_fmc_model; 428 429 if (fmc_model->format_version != FMC_OUTPUT_FORMAT_VER) 430 return -1; 431 432 for (i = 0; i < fmc_model->apply_order_count; i++) { 433 switch (fmc_model->apply_order[i].type) { 434 case fmcengine_start: 435 break; 436 case fmcengine_end: 437 break; 438 case fmcport_start: 439 current_port = dpaa_port_fmc_port_parse(fif, 440 fmc_model, i); 441 break; 442 case fmcport_end: 443 break; 444 case fmcscheme: 445 if (current_port < 0) 446 break; 447 448 ret = dpaa_port_fmc_scheme_parse(fif, fmc_model, 449 i, &rxq_idx, 450 max_nb_rxq, 451 fqids, vspids); 452 if (ret) 453 return ret; 454 455 break; 456 case fmcccnode: 457 if (current_port < 0) 458 break; 459 460 ret = dpaa_port_fmc_ccnode_parse(fif, fmc_model, 461 i, &rxq_idx, 462 max_nb_rxq, fqids, 463 vspids); 464 if (ret) 465 return ret; 466 467 break; 468 case fmchtnode: 469 break; 470 case fmcreplicator: 471 break; 472 case fmccctree: 473 break; 474 case fmcpolicer: 475 break; 476 case fmcmanipulation: 477 break; 478 default: 479 break; 480 } 481 } 482 483 return rxq_idx; 484 } 485