1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2017-2019,2021-2024 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 DPAA_MAX_NUM_ETH_DEV 8 18 19 static inline 20 ioc_fm_pcd_extract_entry_t * 21 SCH_EXT_ARR(ioc_fm_pcd_kg_scheme_params_t *scheme_params, int hdr_idx) 22 { 23 return &scheme_params->param.key_ext_and_hash.extract_array[hdr_idx]; 24 } 25 26 #define SCH_EXT_HDR(scheme_params, hdr_idx) \ 27 SCH_EXT_ARR(scheme_params, hdr_idx)->extract_params.extract_by_hdr 28 29 #define SCH_EXT_FULL_FLD(scheme_params, hdr_idx) \ 30 SCH_EXT_HDR(scheme_params, hdr_idx).extract_by_hdr_type.full_field 31 32 /* FMAN mac indexes mappings (0 is unused, first 8 are for 1G, next for 10G 33 * ports). 34 */ 35 const uint8_t mac_idx[] = {-1, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1}; 36 37 /* FM global info */ 38 struct dpaa_fm_info { 39 t_handle fman_handle; 40 t_handle pcd_handle; 41 }; 42 43 /*FM model to read and write from file */ 44 struct dpaa_fm_model { 45 uint32_t dev_count; 46 uint8_t device_order[DPAA_MAX_NUM_ETH_DEV]; 47 t_fm_port_params fm_port_params[DPAA_MAX_NUM_ETH_DEV]; 48 t_handle netenv_devid[DPAA_MAX_NUM_ETH_DEV]; 49 t_handle scheme_devid[DPAA_MAX_NUM_ETH_DEV][2]; 50 }; 51 52 static struct dpaa_fm_info fm_info; 53 static struct dpaa_fm_model fm_model; 54 static const char *fm_log = "/tmp/fmdpdk.bin"; 55 56 static void fm_prev_cleanup(void) 57 { 58 uint32_t fman_id = 0, i = 0, devid; 59 struct dpaa_if dpaa_intf = {0}; 60 t_fm_pcd_params fm_pcd_params = {0}; 61 PMD_INIT_FUNC_TRACE(); 62 63 fm_info.fman_handle = fm_open(fman_id); 64 if (!fm_info.fman_handle) { 65 DPAA_PMD_ERR("unable to open FMAN"); 66 return; 67 } 68 69 fm_pcd_params.h_fm = fm_info.fman_handle; 70 fm_pcd_params.prs_support = true; 71 fm_pcd_params.kg_support = true; 72 /* FM PCD Open */ 73 fm_info.pcd_handle = fm_pcd_open(&fm_pcd_params); 74 if (!fm_info.pcd_handle) { 75 DPAA_PMD_ERR("unable to open PCD"); 76 return; 77 } 78 79 while (i < fm_model.dev_count) { 80 devid = fm_model.device_order[i]; 81 /* FM Port Open */ 82 fm_model.fm_port_params[devid].h_fm = fm_info.fman_handle; 83 dpaa_intf.port_handle = 84 fm_port_open(&fm_model.fm_port_params[devid]); 85 dpaa_intf.scheme_handle[0] = create_device(fm_info.pcd_handle, 86 fm_model.scheme_devid[devid][0]); 87 dpaa_intf.scheme_count = 1; 88 if (fm_model.scheme_devid[devid][1]) { 89 dpaa_intf.scheme_handle[1] = 90 create_device(fm_info.pcd_handle, 91 fm_model.scheme_devid[devid][1]); 92 if (dpaa_intf.scheme_handle[1]) 93 dpaa_intf.scheme_count++; 94 } 95 96 dpaa_intf.netenv_handle = create_device(fm_info.pcd_handle, 97 fm_model.netenv_devid[devid]); 98 i++; 99 if (!dpaa_intf.netenv_handle || 100 !dpaa_intf.scheme_handle[0] || 101 !dpaa_intf.port_handle) 102 continue; 103 104 if (dpaa_fm_deconfig(&dpaa_intf, NULL)) 105 DPAA_PMD_ERR("DPAA FM deconfig failed"); 106 } 107 108 if (dpaa_fm_term()) 109 DPAA_PMD_ERR("DPAA FM term failed"); 110 111 memset(&fm_model, 0, sizeof(struct dpaa_fm_model)); 112 } 113 114 void dpaa_write_fm_config_to_file(void) 115 { 116 size_t bytes_write; 117 FILE *fp = fopen(fm_log, "wb"); 118 PMD_INIT_FUNC_TRACE(); 119 120 if (!fp) { 121 DPAA_PMD_ERR("File open failed"); 122 return; 123 } 124 bytes_write = fwrite(&fm_model, sizeof(struct dpaa_fm_model), 1, fp); 125 if (!bytes_write) { 126 DPAA_PMD_WARN("No bytes write"); 127 fclose(fp); 128 return; 129 } 130 fclose(fp); 131 } 132 133 static void dpaa_read_fm_config_from_file(void) 134 { 135 size_t bytes_read; 136 FILE *fp = fopen(fm_log, "rb"); 137 PMD_INIT_FUNC_TRACE(); 138 139 if (!fp) 140 return; 141 DPAA_PMD_INFO("Previous DPDK-FM config instance present, cleaning up."); 142 143 bytes_read = fread(&fm_model, sizeof(struct dpaa_fm_model), 1, fp); 144 if (!bytes_read) { 145 DPAA_PMD_WARN("No bytes read"); 146 fclose(fp); 147 return; 148 } 149 fclose(fp); 150 151 /*FM cleanup from previous configured app */ 152 fm_prev_cleanup(); 153 } 154 155 static inline int 156 set_hash_params_eth(ioc_fm_pcd_kg_scheme_params_t *scheme_params, int hdr_idx) 157 { 158 int k; 159 160 for (k = 0; k < 2; k++) { 161 SCH_EXT_ARR(scheme_params, hdr_idx)->type = 162 e_IOC_FM_PCD_EXTRACT_BY_HDR; 163 SCH_EXT_HDR(scheme_params, hdr_idx).hdr = 164 HEADER_TYPE_ETH; 165 SCH_EXT_HDR(scheme_params, hdr_idx).hdr_index = 166 e_IOC_FM_PCD_HDR_INDEX_NONE; 167 SCH_EXT_HDR(scheme_params, hdr_idx).type = 168 e_IOC_FM_PCD_EXTRACT_FULL_FIELD; 169 if (k == 0) 170 SCH_EXT_FULL_FLD(scheme_params, hdr_idx).eth = 171 IOC_NET_HF_ETH_SA; 172 else 173 SCH_EXT_FULL_FLD(scheme_params, hdr_idx).eth = 174 IOC_NET_HF_ETH_DA; 175 hdr_idx++; 176 } 177 return hdr_idx; 178 } 179 180 static inline int 181 set_hash_params_ipv4(ioc_fm_pcd_kg_scheme_params_t *scheme_params, int hdr_idx) 182 { 183 int k; 184 185 for (k = 0; k < 2; k++) { 186 SCH_EXT_ARR(scheme_params, hdr_idx)->type = 187 e_IOC_FM_PCD_EXTRACT_BY_HDR; 188 SCH_EXT_HDR(scheme_params, hdr_idx).hdr = 189 HEADER_TYPE_IPV4; 190 SCH_EXT_HDR(scheme_params, hdr_idx).hdr_index = 191 e_IOC_FM_PCD_HDR_INDEX_NONE; 192 SCH_EXT_HDR(scheme_params, hdr_idx).type = 193 e_IOC_FM_PCD_EXTRACT_FULL_FIELD; 194 if (k == 0) 195 SCH_EXT_FULL_FLD(scheme_params, hdr_idx).ipv4 = 196 ioc_net_hf_ipv_4_src_ip; 197 else 198 SCH_EXT_FULL_FLD(scheme_params, hdr_idx).ipv4 = 199 ioc_net_hf_ipv_4_dst_ip; 200 hdr_idx++; 201 } 202 return hdr_idx; 203 } 204 205 static inline int 206 set_hash_params_ipv6(ioc_fm_pcd_kg_scheme_params_t *scheme_params, int hdr_idx) 207 { 208 int k; 209 210 for (k = 0; k < 2; k++) { 211 SCH_EXT_ARR(scheme_params, hdr_idx)->type = 212 e_IOC_FM_PCD_EXTRACT_BY_HDR; 213 SCH_EXT_HDR(scheme_params, hdr_idx).hdr = 214 HEADER_TYPE_IPV6; 215 SCH_EXT_HDR(scheme_params, hdr_idx).hdr_index = 216 e_IOC_FM_PCD_HDR_INDEX_NONE; 217 SCH_EXT_HDR(scheme_params, hdr_idx).type = 218 e_IOC_FM_PCD_EXTRACT_FULL_FIELD; 219 if (k == 0) 220 SCH_EXT_FULL_FLD(scheme_params, hdr_idx).ipv6 = 221 ioc_net_hf_ipv_6_src_ip; 222 else 223 SCH_EXT_FULL_FLD(scheme_params, hdr_idx).ipv6 = 224 ioc_net_hf_ipv_6_dst_ip; 225 hdr_idx++; 226 } 227 return hdr_idx; 228 } 229 230 static inline int 231 set_hash_params_udp(ioc_fm_pcd_kg_scheme_params_t *scheme_params, int hdr_idx) 232 { 233 int k; 234 235 for (k = 0; k < 2; k++) { 236 SCH_EXT_ARR(scheme_params, hdr_idx)->type = 237 e_IOC_FM_PCD_EXTRACT_BY_HDR; 238 SCH_EXT_HDR(scheme_params, hdr_idx).hdr = 239 HEADER_TYPE_UDP; 240 SCH_EXT_HDR(scheme_params, hdr_idx).hdr_index = 241 e_IOC_FM_PCD_HDR_INDEX_NONE; 242 SCH_EXT_HDR(scheme_params, hdr_idx).type = 243 e_IOC_FM_PCD_EXTRACT_FULL_FIELD; 244 if (k == 0) 245 SCH_EXT_FULL_FLD(scheme_params, hdr_idx).udp = 246 IOC_NET_HF_UDP_PORT_SRC; 247 else 248 SCH_EXT_FULL_FLD(scheme_params, hdr_idx).udp = 249 IOC_NET_HF_UDP_PORT_DST; 250 hdr_idx++; 251 } 252 return hdr_idx; 253 } 254 255 static inline int 256 set_hash_params_tcp(ioc_fm_pcd_kg_scheme_params_t *scheme_params, int hdr_idx) 257 { 258 int k; 259 260 for (k = 0; k < 2; k++) { 261 SCH_EXT_ARR(scheme_params, hdr_idx)->type = 262 e_IOC_FM_PCD_EXTRACT_BY_HDR; 263 SCH_EXT_HDR(scheme_params, hdr_idx).hdr = 264 HEADER_TYPE_TCP; 265 SCH_EXT_HDR(scheme_params, hdr_idx).hdr_index = 266 e_IOC_FM_PCD_HDR_INDEX_NONE; 267 SCH_EXT_HDR(scheme_params, hdr_idx).type = 268 e_IOC_FM_PCD_EXTRACT_FULL_FIELD; 269 if (k == 0) 270 SCH_EXT_FULL_FLD(scheme_params, hdr_idx).tcp = 271 IOC_NET_HF_TCP_PORT_SRC; 272 else 273 SCH_EXT_FULL_FLD(scheme_params, hdr_idx).tcp = 274 IOC_NET_HF_TCP_PORT_DST; 275 hdr_idx++; 276 } 277 return hdr_idx; 278 } 279 280 static inline int 281 set_hash_params_sctp(ioc_fm_pcd_kg_scheme_params_t *scheme_params, int hdr_idx) 282 { 283 int k; 284 285 for (k = 0; k < 2; k++) { 286 SCH_EXT_ARR(scheme_params, hdr_idx)->type = 287 e_IOC_FM_PCD_EXTRACT_BY_HDR; 288 SCH_EXT_HDR(scheme_params, hdr_idx).hdr = 289 HEADER_TYPE_SCTP; 290 SCH_EXT_HDR(scheme_params, hdr_idx).hdr_index = 291 e_IOC_FM_PCD_HDR_INDEX_NONE; 292 SCH_EXT_HDR(scheme_params, hdr_idx).type = 293 e_IOC_FM_PCD_EXTRACT_FULL_FIELD; 294 if (k == 0) 295 SCH_EXT_FULL_FLD(scheme_params, hdr_idx).sctp = 296 IOC_NET_HF_SCTP_PORT_SRC; 297 else 298 SCH_EXT_FULL_FLD(scheme_params, hdr_idx).sctp = 299 IOC_NET_HF_SCTP_PORT_DST; 300 hdr_idx++; 301 } 302 return hdr_idx; 303 } 304 305 /* Set scheme params for hash distribution */ 306 static int set_scheme_params(ioc_fm_pcd_kg_scheme_params_t *scheme_params, 307 ioc_fm_pcd_net_env_params_t *dist_units, 308 struct dpaa_if *dpaa_intf, 309 struct fman_if *fif) 310 { 311 int dist_idx, hdr_idx = 0; 312 PMD_INIT_FUNC_TRACE(); 313 314 if (fif->num_profiles) { 315 scheme_params->param.override_storage_profile = true; 316 scheme_params->param.storage_profile.direct = true; 317 scheme_params->param.storage_profile.profile_select 318 .direct_relative_profile_id = fm_default_vsp_id(fif); 319 } 320 321 scheme_params->param.use_hash = 1; 322 scheme_params->param.modify = false; 323 scheme_params->param.always_direct = false; 324 scheme_params->param.scheme_counter.update = 1; 325 scheme_params->param.scheme_counter.value = 0; 326 scheme_params->param.next_engine = e_IOC_FM_PCD_DONE; 327 scheme_params->param.base_fqid = dpaa_intf->rx_queues[0].fqid; 328 scheme_params->param.net_env_params.net_env_id = 329 dpaa_intf->netenv_handle; 330 scheme_params->param.net_env_params.num_of_distinction_units = 331 dist_units->param.num_of_distinction_units; 332 333 scheme_params->param.key_ext_and_hash.hash_dist_num_of_fqids = 334 dpaa_intf->nb_rx_queues; 335 scheme_params->param.key_ext_and_hash.num_of_used_extracts = 336 2 * dist_units->param.num_of_distinction_units; 337 338 for (dist_idx = 0; dist_idx < 339 dist_units->param.num_of_distinction_units; 340 dist_idx++) { 341 switch (dist_units->param.units[dist_idx].hdrs[0].hdr) { 342 case HEADER_TYPE_ETH: 343 hdr_idx = set_hash_params_eth(scheme_params, hdr_idx); 344 break; 345 346 case HEADER_TYPE_IPV4: 347 hdr_idx = set_hash_params_ipv4(scheme_params, hdr_idx); 348 break; 349 350 case HEADER_TYPE_IPV6: 351 hdr_idx = set_hash_params_ipv6(scheme_params, hdr_idx); 352 break; 353 354 case HEADER_TYPE_UDP: 355 hdr_idx = set_hash_params_udp(scheme_params, hdr_idx); 356 break; 357 358 case HEADER_TYPE_TCP: 359 hdr_idx = set_hash_params_tcp(scheme_params, hdr_idx); 360 break; 361 362 case HEADER_TYPE_SCTP: 363 hdr_idx = set_hash_params_sctp(scheme_params, hdr_idx); 364 break; 365 366 default: 367 DPAA_PMD_ERR("Invalid Distinction Unit"); 368 return -1; 369 } 370 } 371 372 return 0; 373 } 374 375 static void set_dist_units(ioc_fm_pcd_net_env_params_t *dist_units, 376 uint64_t req_dist_set) 377 { 378 uint32_t loop = 0, dist_idx = 0, dist_field = 0; 379 int l2_configured = 0, ipv4_configured = 0, ipv6_configured = 0; 380 int udp_configured = 0, tcp_configured = 0, sctp_configured = 0; 381 PMD_INIT_FUNC_TRACE(); 382 383 if (!req_dist_set) 384 dist_units->param.units[dist_idx++].hdrs[0].hdr = 385 HEADER_TYPE_ETH; 386 387 while (req_dist_set) { 388 if (req_dist_set % 2 != 0) { 389 dist_field = 1U << loop; 390 switch (dist_field) { 391 case RTE_ETH_RSS_L2_PAYLOAD: 392 393 if (l2_configured) 394 break; 395 l2_configured = 1; 396 397 dist_units->param.units[dist_idx++].hdrs[0].hdr 398 = HEADER_TYPE_ETH; 399 break; 400 401 case RTE_ETH_RSS_IPV4: 402 case RTE_ETH_RSS_FRAG_IPV4: 403 case RTE_ETH_RSS_NONFRAG_IPV4_OTHER: 404 405 if (ipv4_configured) 406 break; 407 ipv4_configured = 1; 408 dist_units->param.units[dist_idx++].hdrs[0].hdr 409 = HEADER_TYPE_IPV4; 410 break; 411 412 case RTE_ETH_RSS_IPV6: 413 case RTE_ETH_RSS_FRAG_IPV6: 414 case RTE_ETH_RSS_NONFRAG_IPV6_OTHER: 415 case RTE_ETH_RSS_IPV6_EX: 416 417 if (ipv6_configured) 418 break; 419 ipv6_configured = 1; 420 dist_units->param.units[dist_idx++].hdrs[0].hdr 421 = HEADER_TYPE_IPV6; 422 break; 423 424 case RTE_ETH_RSS_NONFRAG_IPV4_TCP: 425 case RTE_ETH_RSS_NONFRAG_IPV6_TCP: 426 case RTE_ETH_RSS_IPV6_TCP_EX: 427 428 if (tcp_configured) 429 break; 430 tcp_configured = 1; 431 dist_units->param.units[dist_idx++].hdrs[0].hdr 432 = HEADER_TYPE_TCP; 433 break; 434 435 case RTE_ETH_RSS_NONFRAG_IPV4_UDP: 436 case RTE_ETH_RSS_NONFRAG_IPV6_UDP: 437 case RTE_ETH_RSS_IPV6_UDP_EX: 438 439 if (udp_configured) 440 break; 441 udp_configured = 1; 442 dist_units->param.units[dist_idx++].hdrs[0].hdr 443 = HEADER_TYPE_UDP; 444 break; 445 446 case RTE_ETH_RSS_NONFRAG_IPV4_SCTP: 447 case RTE_ETH_RSS_NONFRAG_IPV6_SCTP: 448 449 if (sctp_configured) 450 break; 451 sctp_configured = 1; 452 453 dist_units->param.units[dist_idx++].hdrs[0].hdr 454 = HEADER_TYPE_SCTP; 455 break; 456 457 default: 458 DPAA_PMD_ERR("Bad flow distribution option"); 459 } 460 } 461 req_dist_set = req_dist_set >> 1; 462 loop++; 463 } 464 465 /* Dist units is set to dist_idx */ 466 dist_units->param.num_of_distinction_units = dist_idx; 467 } 468 469 /* Apply PCD configuration on interface */ 470 static inline int set_port_pcd(struct dpaa_if *dpaa_intf) 471 { 472 int ret = 0; 473 unsigned int idx; 474 ioc_fm_port_pcd_params_t pcd_param; 475 ioc_fm_port_pcd_prs_params_t prs_param; 476 ioc_fm_port_pcd_kg_params_t kg_param; 477 478 PMD_INIT_FUNC_TRACE(); 479 480 /* PCD support for hash distribution */ 481 uint8_t pcd_support = e_FM_PORT_PCD_SUPPORT_PRS_AND_KG; 482 483 memset(&pcd_param, 0, sizeof(pcd_param)); 484 memset(&prs_param, 0, sizeof(prs_param)); 485 memset(&kg_param, 0, sizeof(kg_param)); 486 487 /* Set parse params */ 488 prs_param.first_prs_hdr = HEADER_TYPE_ETH; 489 490 /* Set kg params */ 491 for (idx = 0; idx < dpaa_intf->scheme_count; idx++) 492 kg_param.scheme_ids[idx] = dpaa_intf->scheme_handle[idx]; 493 kg_param.num_schemes = dpaa_intf->scheme_count; 494 495 /* Set pcd params */ 496 pcd_param.net_env_id = dpaa_intf->netenv_handle; 497 pcd_param.pcd_support = pcd_support; 498 pcd_param.p_kg_params = &kg_param; 499 pcd_param.p_prs_params = &prs_param; 500 501 /* FM PORT Disable */ 502 ret = fm_port_disable(dpaa_intf->port_handle); 503 if (ret != E_OK) { 504 DPAA_PMD_ERR("fm_port_disable: Failed"); 505 return ret; 506 } 507 508 /* FM PORT SetPCD */ 509 ret = fm_port_set_pcd(dpaa_intf->port_handle, &pcd_param); 510 if (ret != E_OK) { 511 DPAA_PMD_ERR("fm_port_set_pcd: Failed"); 512 return ret; 513 } 514 515 /* FM PORT Enable */ 516 ret = fm_port_enable(dpaa_intf->port_handle); 517 if (ret != E_OK) { 518 DPAA_PMD_ERR("fm_port_enable: Failed"); 519 goto fm_port_delete_pcd; 520 } 521 522 return 0; 523 524 fm_port_delete_pcd: 525 /* FM PORT DeletePCD */ 526 ret = fm_port_delete_pcd(dpaa_intf->port_handle); 527 if (ret != E_OK) { 528 DPAA_PMD_ERR("fm_port_delete_pcd: Failed"); 529 return ret; 530 } 531 return -1; 532 } 533 534 /* Unset PCD NerEnv and scheme */ 535 static inline void unset_pcd_netenv_scheme(struct dpaa_if *dpaa_intf) 536 { 537 int ret; 538 PMD_INIT_FUNC_TRACE(); 539 540 /* reduce scheme count */ 541 if (dpaa_intf->scheme_count) 542 dpaa_intf->scheme_count--; 543 544 DPAA_PMD_DEBUG("KG SCHEME DEL %d handle =%p", 545 dpaa_intf->scheme_count, 546 dpaa_intf->scheme_handle[dpaa_intf->scheme_count]); 547 548 ret = fm_pcd_kg_scheme_delete(dpaa_intf->scheme_handle 549 [dpaa_intf->scheme_count]); 550 if (ret != E_OK) 551 DPAA_PMD_ERR("fm_pcd_kg_scheme_delete: Failed"); 552 553 dpaa_intf->scheme_handle[dpaa_intf->scheme_count] = NULL; 554 } 555 556 /* Set PCD NetEnv and Scheme and default scheme */ 557 static inline int set_default_scheme(struct dpaa_if *dpaa_intf) 558 { 559 ioc_fm_pcd_kg_scheme_params_t scheme_params; 560 int idx = dpaa_intf->scheme_count; 561 PMD_INIT_FUNC_TRACE(); 562 563 /* Set PCD NetEnvCharacteristics */ 564 memset(&scheme_params, 0, sizeof(scheme_params)); 565 566 /* Adding 10 to default schemes as the number of interface would be 567 * lesser than 10 and the relative scheme ids should be unique for 568 * every scheme. 569 */ 570 scheme_params.param.scm_id.relative_scheme_id = 571 10 + dpaa_intf->ifid; 572 scheme_params.param.use_hash = 0; 573 scheme_params.param.next_engine = e_IOC_FM_PCD_DONE; 574 scheme_params.param.net_env_params.num_of_distinction_units = 0; 575 scheme_params.param.net_env_params.net_env_id = 576 dpaa_intf->netenv_handle; 577 scheme_params.param.base_fqid = dpaa_intf->rx_queues[0].fqid; 578 scheme_params.param.key_ext_and_hash.hash_dist_num_of_fqids = 1; 579 scheme_params.param.key_ext_and_hash.num_of_used_extracts = 0; 580 scheme_params.param.modify = false; 581 scheme_params.param.always_direct = false; 582 scheme_params.param.scheme_counter.update = 1; 583 scheme_params.param.scheme_counter.value = 0; 584 585 /* FM PCD KgSchemeSet */ 586 dpaa_intf->scheme_handle[idx] = 587 fm_pcd_kg_scheme_set(fm_info.pcd_handle, &scheme_params); 588 DPAA_PMD_DEBUG("KG SCHEME SET %d handle =%p", 589 idx, dpaa_intf->scheme_handle[idx]); 590 if (!dpaa_intf->scheme_handle[idx]) { 591 DPAA_PMD_ERR("fm_pcd_kg_scheme_set: Failed"); 592 return -1; 593 } 594 595 fm_model.scheme_devid[dpaa_intf->ifid][idx] = 596 get_device_id(dpaa_intf->scheme_handle[idx]); 597 dpaa_intf->scheme_count++; 598 return 0; 599 } 600 601 602 /* Set PCD NetEnv and Scheme and default scheme */ 603 static inline int set_pcd_netenv_scheme(struct dpaa_if *dpaa_intf, 604 uint64_t req_dist_set, 605 struct fman_if *fif) 606 { 607 int ret = -1; 608 ioc_fm_pcd_net_env_params_t dist_units; 609 ioc_fm_pcd_kg_scheme_params_t scheme_params; 610 int idx = dpaa_intf->scheme_count; 611 PMD_INIT_FUNC_TRACE(); 612 613 /* Set PCD NetEnvCharacteristics */ 614 memset(&dist_units, 0, sizeof(dist_units)); 615 memset(&scheme_params, 0, sizeof(scheme_params)); 616 617 /* Set dist unit header type */ 618 set_dist_units(&dist_units, req_dist_set); 619 620 scheme_params.param.scm_id.relative_scheme_id = dpaa_intf->ifid; 621 622 /* Set PCD Scheme params */ 623 ret = set_scheme_params(&scheme_params, &dist_units, dpaa_intf, fif); 624 if (ret) { 625 DPAA_PMD_ERR("Set scheme params: Failed"); 626 return -1; 627 } 628 629 /* FM PCD KgSchemeSet */ 630 dpaa_intf->scheme_handle[idx] = 631 fm_pcd_kg_scheme_set(fm_info.pcd_handle, &scheme_params); 632 DPAA_PMD_DEBUG("KG SCHEME SET %d handle =%p", 633 idx, dpaa_intf->scheme_handle[idx]); 634 if (!dpaa_intf->scheme_handle[idx]) { 635 DPAA_PMD_ERR("fm_pcd_kg_scheme_set: Failed"); 636 return -1; 637 } 638 639 fm_model.scheme_devid[dpaa_intf->ifid][idx] = 640 get_device_id(dpaa_intf->scheme_handle[idx]); 641 dpaa_intf->scheme_count++; 642 return 0; 643 } 644 645 646 static inline int get_rx_port_type(struct fman_if *fif) 647 { 648 if (fif->mac_type == fman_offline) 649 return e_FM_PORT_TYPE_OH_OFFLINE_PARSING; 650 /* For 1G fm-mac9 and fm-mac10 ports, configure the VSP as 10G 651 * ports so that kernel can configure correct port. 652 */ 653 else if (fif->mac_type == fman_mac_1g && 654 fif->mac_idx >= DPAA_10G_MAC_START_IDX) 655 return e_FM_PORT_TYPE_RX_10G; 656 else if (fif->mac_type == fman_mac_1g) 657 return e_FM_PORT_TYPE_RX; 658 else if (fif->mac_type == fman_mac_2_5g) 659 return e_FM_PORT_TYPE_RX_2_5G; 660 else if (fif->mac_type == fman_mac_10g) 661 return e_FM_PORT_TYPE_RX_10G; 662 663 DPAA_PMD_ERR("MAC type unsupported"); 664 return e_FM_PORT_TYPE_DUMMY; 665 } 666 667 static inline int set_fm_port_handle(struct dpaa_if *dpaa_intf, 668 uint64_t req_dist_set, 669 struct fman_if *fif) 670 { 671 t_fm_port_params fm_port_params; 672 ioc_fm_pcd_net_env_params_t dist_units; 673 PMD_INIT_FUNC_TRACE(); 674 675 /* Memset FM port params */ 676 memset(&fm_port_params, 0, sizeof(fm_port_params)); 677 678 /* Set FM port params */ 679 fm_port_params.h_fm = fm_info.fman_handle; 680 fm_port_params.port_type = get_rx_port_type(fif); 681 fm_port_params.port_id = mac_idx[fif->mac_idx]; 682 683 /* FM PORT Open */ 684 dpaa_intf->port_handle = fm_port_open(&fm_port_params); 685 if (!dpaa_intf->port_handle) { 686 DPAA_PMD_ERR("fm_port_open: Failed"); 687 return -1; 688 } 689 690 fm_model.fm_port_params[dpaa_intf->ifid] = fm_port_params; 691 692 /* Set PCD NetEnvCharacteristics */ 693 memset(&dist_units, 0, sizeof(dist_units)); 694 695 /* Set dist unit header type */ 696 set_dist_units(&dist_units, req_dist_set); 697 698 /* FM PCD NetEnvCharacteristicsSet */ 699 dpaa_intf->netenv_handle = 700 fm_pcd_net_env_characteristics_set(fm_info.pcd_handle, 701 &dist_units); 702 if (!dpaa_intf->netenv_handle) { 703 DPAA_PMD_ERR("fm_pcd_net_env_characteristics_set: Failed"); 704 return -1; 705 } 706 707 fm_model.netenv_devid[dpaa_intf->ifid] = 708 get_device_id(dpaa_intf->netenv_handle); 709 710 return 0; 711 } 712 713 /* De-Configure DPAA FM */ 714 int dpaa_fm_deconfig(struct dpaa_if *dpaa_intf, 715 struct fman_if *fif __rte_unused) 716 { 717 int ret; 718 unsigned int idx; 719 720 PMD_INIT_FUNC_TRACE(); 721 722 /* FM PORT Disable */ 723 ret = fm_port_disable(dpaa_intf->port_handle); 724 if (ret != E_OK) { 725 DPAA_PMD_ERR("fm_port_disable: Failed"); 726 return ret; 727 } 728 729 /* FM PORT DeletePCD */ 730 ret = fm_port_delete_pcd(dpaa_intf->port_handle); 731 if (ret != E_OK) { 732 DPAA_PMD_ERR("fm_port_delete_pcd: Failed"); 733 return ret; 734 } 735 736 for (idx = 0; idx < dpaa_intf->scheme_count; idx++) { 737 DPAA_PMD_DEBUG("KG SCHEME DEL %d, handle =%p", 738 idx, dpaa_intf->scheme_handle[idx]); 739 /* FM PCD KgSchemeDelete */ 740 ret = fm_pcd_kg_scheme_delete(dpaa_intf->scheme_handle[idx]); 741 if (ret != E_OK) { 742 DPAA_PMD_ERR("fm_pcd_kg_scheme_delete: Failed"); 743 return ret; 744 } 745 dpaa_intf->scheme_handle[idx] = NULL; 746 } 747 /* FM PCD NetEnvCharacteristicsDelete */ 748 ret = fm_pcd_net_env_characteristics_delete(dpaa_intf->netenv_handle); 749 if (ret != E_OK) { 750 DPAA_PMD_ERR("fm_pcd_net_env_characteristics_delete: Failed"); 751 return ret; 752 } 753 dpaa_intf->netenv_handle = NULL; 754 755 if (fif && fif->is_shared_mac) { 756 ret = fm_port_enable(dpaa_intf->port_handle); 757 if (ret != E_OK) { 758 DPAA_PMD_ERR("shared mac re-enable failed"); 759 return ret; 760 } 761 } 762 763 /* FM PORT Close */ 764 fm_port_close(dpaa_intf->port_handle); 765 dpaa_intf->port_handle = NULL; 766 767 /* Set scheme count to 0 */ 768 dpaa_intf->scheme_count = 0; 769 770 return 0; 771 } 772 773 int dpaa_fm_config(struct rte_eth_dev *dev, uint64_t req_dist_set) 774 { 775 struct dpaa_if *dpaa_intf = dev->data->dev_private; 776 struct fman_if *fif = dev->process_private; 777 int ret; 778 unsigned int i = 0; 779 PMD_INIT_FUNC_TRACE(); 780 781 if (dpaa_intf->port_handle) { 782 if (dpaa_fm_deconfig(dpaa_intf, fif)) 783 DPAA_PMD_ERR("DPAA FM deconfig failed"); 784 } 785 786 if (!dev->data->nb_rx_queues) 787 return 0; 788 789 if (dev->data->nb_rx_queues & (dev->data->nb_rx_queues - 1)) { 790 DPAA_PMD_ERR("No of queues should be power of 2"); 791 return -1; 792 } 793 794 dpaa_intf->nb_rx_queues = dev->data->nb_rx_queues; 795 796 /* Open FM Port and set it in port info */ 797 ret = set_fm_port_handle(dpaa_intf, req_dist_set, fif); 798 if (ret) { 799 DPAA_PMD_ERR("Set FM Port handle: Failed"); 800 return -1; 801 } 802 803 if (fif->num_profiles) { 804 for (i = 0; i < dpaa_intf->nb_rx_queues; i++) 805 dpaa_intf->rx_queues[i].vsp_id = 806 fm_default_vsp_id(fif); 807 808 i = 0; 809 } 810 811 /* Set PCD netenv and scheme */ 812 if (req_dist_set) { 813 ret = set_pcd_netenv_scheme(dpaa_intf, req_dist_set, fif); 814 if (ret) { 815 DPAA_PMD_ERR("Set PCD NetEnv and Scheme dist: Failed"); 816 goto unset_fm_port_handle; 817 } 818 } 819 /* Set default netenv and scheme */ 820 if (!fif->is_shared_mac) { 821 ret = set_default_scheme(dpaa_intf); 822 if (ret) { 823 DPAA_PMD_ERR("Set PCD NetEnv and Scheme: Failed"); 824 goto unset_pcd_netenv_scheme1; 825 } 826 } 827 828 /* Set Port PCD */ 829 ret = set_port_pcd(dpaa_intf); 830 if (ret) { 831 DPAA_PMD_ERR("Set Port PCD: Failed"); 832 goto unset_pcd_netenv_scheme; 833 } 834 835 for (; i < fm_model.dev_count; i++) 836 if (fm_model.device_order[i] == dpaa_intf->ifid) 837 return 0; 838 839 fm_model.device_order[fm_model.dev_count] = dpaa_intf->ifid; 840 fm_model.dev_count++; 841 842 return 0; 843 844 unset_pcd_netenv_scheme: 845 unset_pcd_netenv_scheme(dpaa_intf); 846 847 unset_pcd_netenv_scheme1: 848 unset_pcd_netenv_scheme(dpaa_intf); 849 850 unset_fm_port_handle: 851 /* FM PORT Close */ 852 fm_port_close(dpaa_intf->port_handle); 853 dpaa_intf->port_handle = NULL; 854 return -1; 855 } 856 857 int dpaa_fm_init(void) 858 { 859 t_handle fman_handle; 860 t_handle pcd_handle; 861 t_fm_pcd_params fm_pcd_params = {0}; 862 /* Hard-coded : fman id 0 since one fman is present in LS104x */ 863 int fman_id = 0, ret; 864 PMD_INIT_FUNC_TRACE(); 865 866 dpaa_read_fm_config_from_file(); 867 868 /* FM Open */ 869 fman_handle = fm_open(fman_id); 870 if (!fman_handle) { 871 DPAA_PMD_ERR("fm_open: Failed"); 872 return -1; 873 } 874 875 /* FM PCD Open */ 876 fm_pcd_params.h_fm = fman_handle; 877 fm_pcd_params.prs_support = true; 878 fm_pcd_params.kg_support = true; 879 pcd_handle = fm_pcd_open(&fm_pcd_params); 880 if (!pcd_handle) { 881 fm_close(fman_handle); 882 DPAA_PMD_ERR("fm_pcd_open: Failed"); 883 return -1; 884 } 885 886 /* FM PCD Enable */ 887 ret = fm_pcd_enable(pcd_handle); 888 if (ret) { 889 fm_close(fman_handle); 890 fm_pcd_close(pcd_handle); 891 DPAA_PMD_ERR("fm_pcd_enable: Failed"); 892 return -1; 893 } 894 895 /* Set fman and pcd handle in fm info */ 896 fm_info.fman_handle = fman_handle; 897 fm_info.pcd_handle = pcd_handle; 898 899 return 0; 900 } 901 902 903 /* De-initialization of FM */ 904 int dpaa_fm_term(void) 905 { 906 int ret; 907 908 PMD_INIT_FUNC_TRACE(); 909 910 if (fm_info.pcd_handle && fm_info.fman_handle) { 911 /* FM PCD Disable */ 912 ret = fm_pcd_disable(fm_info.pcd_handle); 913 if (ret) { 914 DPAA_PMD_ERR("fm_pcd_disable: Failed"); 915 return -1; 916 } 917 918 /* FM PCD Close */ 919 fm_pcd_close(fm_info.pcd_handle); 920 fm_info.pcd_handle = NULL; 921 } 922 923 if (fm_info.fman_handle) { 924 /* FM Close */ 925 fm_close(fm_info.fman_handle); 926 fm_info.fman_handle = NULL; 927 } 928 929 if (access(fm_log, F_OK) != -1) { 930 ret = remove(fm_log); 931 if (ret) 932 DPAA_PMD_ERR("File remove: Failed"); 933 } 934 return 0; 935 } 936 937 static int dpaa_port_vsp_configure(struct dpaa_if *dpaa_intf, 938 uint8_t vsp_id, t_handle fman_handle, 939 struct fman_if *fif, u32 mbuf_data_room_size) 940 { 941 t_fm_vsp_params vsp_params; 942 t_fm_buffer_prefix_content buf_prefix_cont; 943 uint8_t idx = mac_idx[fif->mac_idx]; 944 int ret; 945 946 if (vsp_id == fif->base_profile_id && fif->is_shared_mac) { 947 /* For shared interface, VSP of base 948 * profile is default pool located in kernel. 949 */ 950 dpaa_intf->vsp_bpid[vsp_id] = 0; 951 return 0; 952 } 953 954 if (vsp_id >= DPAA_VSP_PROFILE_MAX_NUM) { 955 DPAA_PMD_ERR("VSP ID %d exceeds MAX number %d", 956 vsp_id, DPAA_VSP_PROFILE_MAX_NUM); 957 return -1; 958 } 959 960 memset(&vsp_params, 0, sizeof(vsp_params)); 961 vsp_params.h_fm = fman_handle; 962 vsp_params.relative_profile_id = vsp_id; 963 if (fif->mac_type == fman_offline) 964 vsp_params.port_params.port_id = fif->mac_idx; 965 else 966 vsp_params.port_params.port_id = idx; 967 968 if (fif->mac_type == fman_mac_1g) { 969 vsp_params.port_params.port_type = e_FM_PORT_TYPE_RX; 970 } else if (fif->mac_type == fman_mac_2_5g) { 971 vsp_params.port_params.port_type = e_FM_PORT_TYPE_RX_2_5G; 972 } else if (fif->mac_type == fman_mac_10g) { 973 vsp_params.port_params.port_type = e_FM_PORT_TYPE_RX_10G; 974 } else if (fif->mac_type == fman_offline) { 975 vsp_params.port_params.port_type = 976 e_FM_PORT_TYPE_OH_OFFLINE_PARSING; 977 } else { 978 DPAA_PMD_ERR("Mac type %d error", fif->mac_type); 979 return -1; 980 } 981 982 vsp_params.port_params.port_type = get_rx_port_type(fif); 983 if (vsp_params.port_params.port_type == e_FM_PORT_TYPE_DUMMY) { 984 DPAA_PMD_ERR("Mac type %d error", fif->mac_type); 985 return -1; 986 } 987 988 vsp_params.ext_buf_pools.num_of_pools_used = 1; 989 vsp_params.ext_buf_pools.ext_buf_pool[0].id = dpaa_intf->vsp_bpid[vsp_id]; 990 vsp_params.ext_buf_pools.ext_buf_pool[0].size = mbuf_data_room_size; 991 992 dpaa_intf->vsp_handle[vsp_id] = fm_vsp_config(&vsp_params); 993 if (!dpaa_intf->vsp_handle[vsp_id]) { 994 DPAA_PMD_ERR("fm_vsp_config error for profile %d", vsp_id); 995 return -EINVAL; 996 } 997 998 /* configure the application buffer (structure, size and 999 * content) 1000 */ 1001 1002 memset(&buf_prefix_cont, 0, sizeof(buf_prefix_cont)); 1003 1004 buf_prefix_cont.priv_data_size = 16; 1005 buf_prefix_cont.data_align = 64; 1006 buf_prefix_cont.pass_prs_result = true; 1007 buf_prefix_cont.pass_time_stamp = true; 1008 buf_prefix_cont.pass_hash_result = false; 1009 buf_prefix_cont.pass_all_other_pcdinfo = false; 1010 buf_prefix_cont.manip_ext_space = 1011 RTE_PKTMBUF_HEADROOM - DPAA_MBUF_HW_ANNOTATION; 1012 1013 ret = fm_vsp_config_buffer_prefix_content(dpaa_intf->vsp_handle[vsp_id], 1014 &buf_prefix_cont); 1015 if (ret != E_OK) { 1016 DPAA_PMD_ERR("fm_vsp_config_buffer_prefix_content error for profile %d err: %d", 1017 vsp_id, ret); 1018 return ret; 1019 } 1020 1021 /* initialize the FM VSP module */ 1022 ret = fm_vsp_init(dpaa_intf->vsp_handle[vsp_id]); 1023 if (ret != E_OK) { 1024 DPAA_PMD_ERR("fm_vsp_init error for profile %d err:%d", 1025 vsp_id, ret); 1026 return ret; 1027 } 1028 1029 return 0; 1030 } 1031 1032 int dpaa_port_vsp_update(struct dpaa_if *dpaa_intf, 1033 bool fmc_mode, uint8_t vsp_id, uint32_t bpid, 1034 struct fman_if *fif, u32 mbuf_data_room_size) 1035 { 1036 int ret = 0; 1037 t_handle fman_handle; 1038 1039 if (!fif->num_profiles) 1040 return 0; 1041 1042 if (vsp_id >= fif->num_profiles) 1043 return 0; 1044 1045 if (dpaa_intf->vsp_bpid[vsp_id] == bpid) 1046 return 0; 1047 1048 if (dpaa_intf->vsp_handle[vsp_id]) { 1049 ret = fm_vsp_free(dpaa_intf->vsp_handle[vsp_id]); 1050 if (ret != E_OK) { 1051 DPAA_PMD_ERR("Error fm_vsp_free: err %d vsp_handle[%d]", 1052 ret, vsp_id); 1053 return ret; 1054 } 1055 dpaa_intf->vsp_handle[vsp_id] = 0; 1056 } 1057 1058 if (fmc_mode) 1059 fman_handle = fm_open(0); 1060 else 1061 fman_handle = fm_info.fman_handle; 1062 1063 dpaa_intf->vsp_bpid[vsp_id] = bpid; 1064 1065 return dpaa_port_vsp_configure(dpaa_intf, vsp_id, fman_handle, fif, 1066 mbuf_data_room_size); 1067 } 1068 1069 int dpaa_port_vsp_cleanup(struct dpaa_if *dpaa_intf, struct fman_if *fif) 1070 { 1071 int idx, ret; 1072 1073 for (idx = 0; idx < (uint8_t)fif->num_profiles; idx++) { 1074 if (dpaa_intf->vsp_handle[idx]) { 1075 ret = fm_vsp_free(dpaa_intf->vsp_handle[idx]); 1076 if (ret != E_OK) { 1077 DPAA_PMD_ERR("Error fm_vsp_free: err %d" 1078 " vsp_handle[%d]", ret, idx); 1079 return ret; 1080 } 1081 } 1082 } 1083 1084 return E_OK; 1085 } 1086