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