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