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