1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2018 Netronome Systems, Inc. 3 * All rights reserved. 4 */ 5 6 #include <assert.h> 7 #include <stdint.h> 8 #include <stdio.h> 9 #include <string.h> 10 #include <stdlib.h> 11 #include <errno.h> 12 #include <sys/types.h> 13 14 #include <rte_byteorder.h> 15 #include <ethdev_pci.h> 16 17 #include "nfp_cpp.h" 18 #include "nfp_target.h" 19 #include "nfp6000/nfp6000.h" 20 #include "nfp6000/nfp_xpb.h" 21 #include "nfp_nffw.h" 22 23 #define NFP_PL_DEVICE_ID 0x00000004 24 #define NFP_PL_DEVICE_ID_MASK 0xff 25 #define NFP_PL_DEVICE_PART_MASK 0xffff0000 26 #define NFP_PL_DEVICE_MODEL_MASK (NFP_PL_DEVICE_PART_MASK | \ 27 NFP_PL_DEVICE_ID_MASK) 28 29 void 30 nfp_cpp_priv_set(struct nfp_cpp *cpp, void *priv) 31 { 32 cpp->priv = priv; 33 } 34 35 void * 36 nfp_cpp_priv(struct nfp_cpp *cpp) 37 { 38 return cpp->priv; 39 } 40 41 void 42 nfp_cpp_model_set(struct nfp_cpp *cpp, uint32_t model) 43 { 44 cpp->model = model; 45 } 46 47 uint32_t 48 nfp_cpp_model(struct nfp_cpp *cpp) 49 { 50 int err; 51 uint32_t model; 52 53 if (!cpp) 54 return NFP_CPP_MODEL_INVALID; 55 56 err = __nfp_cpp_model_autodetect(cpp, &model); 57 58 if (err < 0) 59 return err; 60 61 return model; 62 } 63 64 void 65 nfp_cpp_interface_set(struct nfp_cpp *cpp, uint32_t interface) 66 { 67 cpp->interface = interface; 68 } 69 70 int 71 nfp_cpp_serial(struct nfp_cpp *cpp, const uint8_t **serial) 72 { 73 *serial = cpp->serial; 74 return cpp->serial_len; 75 } 76 77 int 78 nfp_cpp_serial_set(struct nfp_cpp *cpp, const uint8_t *serial, 79 size_t serial_len) 80 { 81 if (cpp->serial_len) 82 free(cpp->serial); 83 84 cpp->serial = malloc(serial_len); 85 if (!cpp->serial) 86 return -1; 87 88 memcpy(cpp->serial, serial, serial_len); 89 cpp->serial_len = serial_len; 90 91 return 0; 92 } 93 94 uint16_t 95 nfp_cpp_interface(struct nfp_cpp *cpp) 96 { 97 if (!cpp) 98 return NFP_CPP_INTERFACE(NFP_CPP_INTERFACE_TYPE_INVALID, 0, 0); 99 100 return cpp->interface; 101 } 102 103 void * 104 nfp_cpp_area_priv(struct nfp_cpp_area *cpp_area) 105 { 106 return &cpp_area[1]; 107 } 108 109 struct nfp_cpp * 110 nfp_cpp_area_cpp(struct nfp_cpp_area *cpp_area) 111 { 112 return cpp_area->cpp; 113 } 114 115 const char * 116 nfp_cpp_area_name(struct nfp_cpp_area *cpp_area) 117 { 118 return cpp_area->name; 119 } 120 121 /* 122 * nfp_cpp_area_alloc - allocate a new CPP area 123 * @cpp: CPP handle 124 * @dest: CPP id 125 * @address: start address on CPP target 126 * @size: size of area in bytes 127 * 128 * Allocate and initialize a CPP area structure. The area must later 129 * be locked down with an 'acquire' before it can be safely accessed. 130 * 131 * NOTE: @address and @size must be 32-bit aligned values. 132 */ 133 struct nfp_cpp_area * 134 nfp_cpp_area_alloc_with_name(struct nfp_cpp *cpp, uint32_t dest, 135 const char *name, unsigned long long address, 136 unsigned long size) 137 { 138 struct nfp_cpp_area *area; 139 uint64_t tmp64 = (uint64_t)address; 140 int tmp, err; 141 142 if (!cpp) 143 return NULL; 144 145 /* CPP bus uses only a 40-bit address */ 146 if ((address + size) > (1ULL << 40)) 147 return NFP_ERRPTR(EFAULT); 148 149 /* Remap from cpp_island to cpp_target */ 150 err = nfp_target_cpp(dest, tmp64, &dest, &tmp64, cpp->imb_cat_table); 151 if (err < 0) 152 return NULL; 153 154 address = (unsigned long long)tmp64; 155 156 if (!name) 157 name = ""; 158 159 area = calloc(1, sizeof(*area) + cpp->op->area_priv_size + 160 strlen(name) + 1); 161 if (!area) 162 return NULL; 163 164 area->cpp = cpp; 165 area->name = ((char *)area) + sizeof(*area) + cpp->op->area_priv_size; 166 memcpy(area->name, name, strlen(name) + 1); 167 168 /* 169 * Preserve errno around the call to area_init, since most 170 * implementations will blindly call nfp_target_action_width()for both 171 * read or write modes, and that will set errno to EINVAL. 172 */ 173 tmp = errno; 174 175 err = cpp->op->area_init(area, dest, address, size); 176 if (err < 0) { 177 free(area); 178 return NULL; 179 } 180 181 /* Restore errno */ 182 errno = tmp; 183 184 area->offset = address; 185 area->size = size; 186 187 return area; 188 } 189 190 struct nfp_cpp_area * 191 nfp_cpp_area_alloc(struct nfp_cpp *cpp, uint32_t dest, 192 unsigned long long address, unsigned long size) 193 { 194 return nfp_cpp_area_alloc_with_name(cpp, dest, NULL, address, size); 195 } 196 197 /* 198 * nfp_cpp_area_alloc_acquire - allocate a new CPP area and lock it down 199 * 200 * @cpp: CPP handle 201 * @dest: CPP id 202 * @address: start address on CPP target 203 * @size: size of area 204 * 205 * Allocate and initilizae a CPP area structure, and lock it down so 206 * that it can be accessed directly. 207 * 208 * NOTE: @address and @size must be 32-bit aligned values. 209 * 210 * NOTE: The area must also be 'released' when the structure is freed. 211 */ 212 struct nfp_cpp_area * 213 nfp_cpp_area_alloc_acquire(struct nfp_cpp *cpp, uint32_t destination, 214 unsigned long long address, unsigned long size) 215 { 216 struct nfp_cpp_area *area; 217 218 area = nfp_cpp_area_alloc(cpp, destination, address, size); 219 if (!area) 220 return NULL; 221 222 if (nfp_cpp_area_acquire(area)) { 223 nfp_cpp_area_free(area); 224 return NULL; 225 } 226 227 return area; 228 } 229 230 /* 231 * nfp_cpp_area_free - free up the CPP area 232 * area: CPP area handle 233 * 234 * Frees up memory resources held by the CPP area. 235 */ 236 void 237 nfp_cpp_area_free(struct nfp_cpp_area *area) 238 { 239 if (area->cpp->op->area_cleanup) 240 area->cpp->op->area_cleanup(area); 241 free(area); 242 } 243 244 /* 245 * nfp_cpp_area_release_free - release CPP area and free it 246 * area: CPP area handle 247 * 248 * Releases CPP area and frees up memory resources held by the it. 249 */ 250 void 251 nfp_cpp_area_release_free(struct nfp_cpp_area *area) 252 { 253 nfp_cpp_area_release(area); 254 nfp_cpp_area_free(area); 255 } 256 257 /* 258 * nfp_cpp_area_acquire - lock down a CPP area for access 259 * @area: CPP area handle 260 * 261 * Locks down the CPP area for a potential long term activity. Area 262 * must always be locked down before being accessed. 263 */ 264 int 265 nfp_cpp_area_acquire(struct nfp_cpp_area *area) 266 { 267 if (area->cpp->op->area_acquire) { 268 int err = area->cpp->op->area_acquire(area); 269 270 if (err < 0) 271 return -1; 272 } 273 274 return 0; 275 } 276 277 /* 278 * nfp_cpp_area_release - release a locked down CPP area 279 * @area: CPP area handle 280 * 281 * Releases a previously locked down CPP area. 282 */ 283 void 284 nfp_cpp_area_release(struct nfp_cpp_area *area) 285 { 286 if (area->cpp->op->area_release) 287 area->cpp->op->area_release(area); 288 } 289 290 /* 291 * nfp_cpp_area_iomem() - get IOMEM region for CPP area 292 * 293 * @area: CPP area handle 294 * 295 * Returns an iomem pointer for use with readl()/writel() style operations. 296 * 297 * NOTE: Area must have been locked down with an 'acquire'. 298 * 299 * Return: pointer to the area, or NULL 300 */ 301 void * 302 nfp_cpp_area_iomem(struct nfp_cpp_area *area) 303 { 304 void *iomem = NULL; 305 306 if (area->cpp->op->area_iomem) 307 iomem = area->cpp->op->area_iomem(area); 308 309 return iomem; 310 } 311 312 /* 313 * nfp_cpp_area_read - read data from CPP area 314 * 315 * @area: CPP area handle 316 * @offset: offset into CPP area 317 * @kernel_vaddr: kernel address to put data into 318 * @length: number of bytes to read 319 * 320 * Read data from indicated CPP region. 321 * 322 * NOTE: @offset and @length must be 32-bit aligned values. 323 * 324 * NOTE: Area must have been locked down with an 'acquire'. 325 */ 326 int 327 nfp_cpp_area_read(struct nfp_cpp_area *area, unsigned long offset, 328 void *kernel_vaddr, size_t length) 329 { 330 if ((offset + length) > area->size) 331 return NFP_ERRNO(EFAULT); 332 333 return area->cpp->op->area_read(area, kernel_vaddr, offset, length); 334 } 335 336 /* 337 * nfp_cpp_area_write - write data to CPP area 338 * 339 * @area: CPP area handle 340 * @offset: offset into CPP area 341 * @kernel_vaddr: kernel address to read data from 342 * @length: number of bytes to write 343 * 344 * Write data to indicated CPP region. 345 * 346 * NOTE: @offset and @length must be 32-bit aligned values. 347 * 348 * NOTE: Area must have been locked down with an 'acquire'. 349 */ 350 int 351 nfp_cpp_area_write(struct nfp_cpp_area *area, unsigned long offset, 352 const void *kernel_vaddr, size_t length) 353 { 354 if ((offset + length) > area->size) 355 return NFP_ERRNO(EFAULT); 356 357 return area->cpp->op->area_write(area, kernel_vaddr, offset, length); 358 } 359 360 void * 361 nfp_cpp_area_mapped(struct nfp_cpp_area *area) 362 { 363 if (area->cpp->op->area_mapped) 364 return area->cpp->op->area_mapped(area); 365 return NULL; 366 } 367 368 /* 369 * nfp_cpp_area_check_range - check if address range fits in CPP area 370 * 371 * @area: CPP area handle 372 * @offset: offset into CPP area 373 * @length: size of address range in bytes 374 * 375 * Check if address range fits within CPP area. Return 0 if area fits 376 * or -1 on error. 377 */ 378 int 379 nfp_cpp_area_check_range(struct nfp_cpp_area *area, unsigned long long offset, 380 unsigned long length) 381 { 382 if (((offset + length) > area->size)) 383 return NFP_ERRNO(EFAULT); 384 385 return 0; 386 } 387 388 /* 389 * Return the correct CPP address, and fixup xpb_addr as needed, 390 * based upon NFP model. 391 */ 392 static uint32_t 393 nfp_xpb_to_cpp(struct nfp_cpp *cpp, uint32_t *xpb_addr) 394 { 395 uint32_t xpb; 396 int island; 397 398 xpb = NFP_CPP_ID(14, NFP_CPP_ACTION_RW, 0); 399 400 /* 401 * Ensure that non-local XPB accesses go out through the 402 * global XPBM bus. 403 */ 404 island = ((*xpb_addr) >> 24) & 0x3f; 405 406 if (!island) 407 return xpb; 408 409 if (island == 1) { 410 /* 411 * Accesses to the ARM Island overlay uses Island 0 412 * Global Bit 413 */ 414 (*xpb_addr) &= ~0x7f000000; 415 if (*xpb_addr < 0x60000) 416 *xpb_addr |= (1 << 30); 417 else 418 /* And only non-ARM interfaces use island id = 1 */ 419 if (NFP_CPP_INTERFACE_TYPE_of(nfp_cpp_interface(cpp)) != 420 NFP_CPP_INTERFACE_TYPE_ARM) 421 *xpb_addr |= (1 << 24); 422 } else { 423 (*xpb_addr) |= (1 << 30); 424 } 425 426 return xpb; 427 } 428 429 int 430 nfp_cpp_area_readl(struct nfp_cpp_area *area, unsigned long offset, 431 uint32_t *value) 432 { 433 int sz; 434 uint32_t tmp = 0; 435 436 sz = nfp_cpp_area_read(area, offset, &tmp, sizeof(tmp)); 437 *value = rte_le_to_cpu_32(tmp); 438 439 return (sz == sizeof(*value)) ? 0 : -1; 440 } 441 442 int 443 nfp_cpp_area_writel(struct nfp_cpp_area *area, unsigned long offset, 444 uint32_t value) 445 { 446 int sz; 447 448 value = rte_cpu_to_le_32(value); 449 sz = nfp_cpp_area_write(area, offset, &value, sizeof(value)); 450 return (sz == sizeof(value)) ? 0 : -1; 451 } 452 453 int 454 nfp_cpp_area_readq(struct nfp_cpp_area *area, unsigned long offset, 455 uint64_t *value) 456 { 457 int sz; 458 uint64_t tmp = 0; 459 460 sz = nfp_cpp_area_read(area, offset, &tmp, sizeof(tmp)); 461 *value = rte_le_to_cpu_64(tmp); 462 463 return (sz == sizeof(*value)) ? 0 : -1; 464 } 465 466 int 467 nfp_cpp_area_writeq(struct nfp_cpp_area *area, unsigned long offset, 468 uint64_t value) 469 { 470 int sz; 471 472 value = rte_cpu_to_le_64(value); 473 sz = nfp_cpp_area_write(area, offset, &value, sizeof(value)); 474 475 return (sz == sizeof(value)) ? 0 : -1; 476 } 477 478 int 479 nfp_cpp_readl(struct nfp_cpp *cpp, uint32_t cpp_id, unsigned long long address, 480 uint32_t *value) 481 { 482 int sz; 483 uint32_t tmp; 484 485 sz = nfp_cpp_read(cpp, cpp_id, address, &tmp, sizeof(tmp)); 486 *value = rte_le_to_cpu_32(tmp); 487 488 return (sz == sizeof(*value)) ? 0 : -1; 489 } 490 491 int 492 nfp_cpp_writel(struct nfp_cpp *cpp, uint32_t cpp_id, unsigned long long address, 493 uint32_t value) 494 { 495 int sz; 496 497 value = rte_cpu_to_le_32(value); 498 sz = nfp_cpp_write(cpp, cpp_id, address, &value, sizeof(value)); 499 500 return (sz == sizeof(value)) ? 0 : -1; 501 } 502 503 int 504 nfp_cpp_readq(struct nfp_cpp *cpp, uint32_t cpp_id, unsigned long long address, 505 uint64_t *value) 506 { 507 int sz; 508 uint64_t tmp; 509 510 sz = nfp_cpp_read(cpp, cpp_id, address, &tmp, sizeof(tmp)); 511 *value = rte_le_to_cpu_64(tmp); 512 513 return (sz == sizeof(*value)) ? 0 : -1; 514 } 515 516 int 517 nfp_cpp_writeq(struct nfp_cpp *cpp, uint32_t cpp_id, unsigned long long address, 518 uint64_t value) 519 { 520 int sz; 521 522 value = rte_cpu_to_le_64(value); 523 sz = nfp_cpp_write(cpp, cpp_id, address, &value, sizeof(value)); 524 525 return (sz == sizeof(value)) ? 0 : -1; 526 } 527 528 int 529 nfp_xpb_writel(struct nfp_cpp *cpp, uint32_t xpb_addr, uint32_t value) 530 { 531 uint32_t cpp_dest; 532 533 cpp_dest = nfp_xpb_to_cpp(cpp, &xpb_addr); 534 535 return nfp_cpp_writel(cpp, cpp_dest, xpb_addr, value); 536 } 537 538 int 539 nfp_xpb_readl(struct nfp_cpp *cpp, uint32_t xpb_addr, uint32_t *value) 540 { 541 uint32_t cpp_dest; 542 543 cpp_dest = nfp_xpb_to_cpp(cpp, &xpb_addr); 544 545 return nfp_cpp_readl(cpp, cpp_dest, xpb_addr, value); 546 } 547 548 static struct nfp_cpp * 549 nfp_cpp_alloc(struct rte_pci_device *dev, int driver_lock_needed) 550 { 551 const struct nfp_cpp_operations *ops; 552 struct nfp_cpp *cpp; 553 int err; 554 555 ops = nfp_cpp_transport_operations(); 556 557 if (!ops || !ops->init) 558 return NFP_ERRPTR(EINVAL); 559 560 cpp = calloc(1, sizeof(*cpp)); 561 if (!cpp) 562 return NULL; 563 564 cpp->op = ops; 565 cpp->driver_lock_needed = driver_lock_needed; 566 567 if (cpp->op->init) { 568 err = cpp->op->init(cpp, dev); 569 if (err < 0) { 570 free(cpp); 571 return NULL; 572 } 573 } 574 575 if (NFP_CPP_MODEL_IS_6000(nfp_cpp_model(cpp))) { 576 uint32_t xpbaddr; 577 size_t tgt; 578 579 for (tgt = 0; tgt < ARRAY_SIZE(cpp->imb_cat_table); tgt++) { 580 /* Hardcoded XPB IMB Base, island 0 */ 581 xpbaddr = 0x000a0000 + (tgt * 4); 582 err = nfp_xpb_readl(cpp, xpbaddr, 583 (uint32_t *)&cpp->imb_cat_table[tgt]); 584 if (err < 0) { 585 free(cpp); 586 return NULL; 587 } 588 } 589 } 590 591 return cpp; 592 } 593 594 /* 595 * nfp_cpp_free - free the CPP handle 596 * @cpp: CPP handle 597 */ 598 void 599 nfp_cpp_free(struct nfp_cpp *cpp) 600 { 601 if (cpp->op && cpp->op->free) 602 cpp->op->free(cpp); 603 604 if (cpp->serial_len) 605 free(cpp->serial); 606 607 free(cpp); 608 } 609 610 struct nfp_cpp * 611 nfp_cpp_from_device_name(struct rte_pci_device *dev, int driver_lock_needed) 612 { 613 return nfp_cpp_alloc(dev, driver_lock_needed); 614 } 615 616 /* 617 * Modify bits of a 32-bit value from the XPB bus 618 * 619 * @param cpp NFP CPP device handle 620 * @param xpb_tgt XPB target and address 621 * @param mask mask of bits to alter 622 * @param value value to modify 623 * 624 * @return 0 on success, or -1 on failure (and set errno accordingly). 625 */ 626 int 627 nfp_xpb_writelm(struct nfp_cpp *cpp, uint32_t xpb_tgt, uint32_t mask, 628 uint32_t value) 629 { 630 int err; 631 uint32_t tmp; 632 633 err = nfp_xpb_readl(cpp, xpb_tgt, &tmp); 634 if (err < 0) 635 return err; 636 637 tmp &= ~mask; 638 tmp |= (mask & value); 639 return nfp_xpb_writel(cpp, xpb_tgt, tmp); 640 } 641 642 /* 643 * Modify bits of a 32-bit value from the XPB bus 644 * 645 * @param cpp NFP CPP device handle 646 * @param xpb_tgt XPB target and address 647 * @param mask mask of bits to alter 648 * @param value value to monitor for 649 * @param timeout_us maximum number of us to wait (-1 for forever) 650 * 651 * @return >= 0 on success, or -1 on failure (and set errno accordingly). 652 */ 653 int 654 nfp_xpb_waitlm(struct nfp_cpp *cpp, uint32_t xpb_tgt, uint32_t mask, 655 uint32_t value, int timeout_us) 656 { 657 uint32_t tmp; 658 int err; 659 660 do { 661 err = nfp_xpb_readl(cpp, xpb_tgt, &tmp); 662 if (err < 0) 663 goto exit; 664 665 if ((tmp & mask) == (value & mask)) { 666 if (timeout_us < 0) 667 timeout_us = 0; 668 break; 669 } 670 671 if (timeout_us < 0) 672 continue; 673 674 timeout_us -= 100; 675 usleep(100); 676 } while (timeout_us >= 0); 677 678 if (timeout_us < 0) 679 err = NFP_ERRNO(ETIMEDOUT); 680 else 681 err = timeout_us; 682 683 exit: 684 return err; 685 } 686 687 /* 688 * nfp_cpp_read - read from CPP target 689 * @cpp: CPP handle 690 * @destination: CPP id 691 * @address: offset into CPP target 692 * @kernel_vaddr: kernel buffer for result 693 * @length: number of bytes to read 694 */ 695 int 696 nfp_cpp_read(struct nfp_cpp *cpp, uint32_t destination, 697 unsigned long long address, void *kernel_vaddr, size_t length) 698 { 699 struct nfp_cpp_area *area; 700 int err; 701 702 area = nfp_cpp_area_alloc_acquire(cpp, destination, address, length); 703 if (!area) { 704 printf("Area allocation/acquire failed\n"); 705 return -1; 706 } 707 708 err = nfp_cpp_area_read(area, 0, kernel_vaddr, length); 709 710 nfp_cpp_area_release_free(area); 711 return err; 712 } 713 714 /* 715 * nfp_cpp_write - write to CPP target 716 * @cpp: CPP handle 717 * @destination: CPP id 718 * @address: offset into CPP target 719 * @kernel_vaddr: kernel buffer to read from 720 * @length: number of bytes to write 721 */ 722 int 723 nfp_cpp_write(struct nfp_cpp *cpp, uint32_t destination, 724 unsigned long long address, const void *kernel_vaddr, 725 size_t length) 726 { 727 struct nfp_cpp_area *area; 728 int err; 729 730 area = nfp_cpp_area_alloc_acquire(cpp, destination, address, length); 731 if (!area) 732 return -1; 733 734 err = nfp_cpp_area_write(area, 0, kernel_vaddr, length); 735 736 nfp_cpp_area_release_free(area); 737 return err; 738 } 739 740 /* 741 * nfp_cpp_area_fill - fill a CPP area with a value 742 * @area: CPP area 743 * @offset: offset into CPP area 744 * @value: value to fill with 745 * @length: length of area to fill 746 */ 747 int 748 nfp_cpp_area_fill(struct nfp_cpp_area *area, unsigned long offset, 749 uint32_t value, size_t length) 750 { 751 int err; 752 size_t i; 753 uint64_t value64; 754 755 value = rte_cpu_to_le_32(value); 756 value64 = ((uint64_t)value << 32) | value; 757 758 if ((offset + length) > area->size) 759 return NFP_ERRNO(EINVAL); 760 761 if ((area->offset + offset) & 3) 762 return NFP_ERRNO(EINVAL); 763 764 if (((area->offset + offset) & 7) == 4 && length >= 4) { 765 err = nfp_cpp_area_write(area, offset, &value, sizeof(value)); 766 if (err < 0) 767 return err; 768 if (err != sizeof(value)) 769 return NFP_ERRNO(ENOSPC); 770 offset += sizeof(value); 771 length -= sizeof(value); 772 } 773 774 for (i = 0; (i + sizeof(value)) < length; i += sizeof(value64)) { 775 err = 776 nfp_cpp_area_write(area, offset + i, &value64, 777 sizeof(value64)); 778 if (err < 0) 779 return err; 780 if (err != sizeof(value64)) 781 return NFP_ERRNO(ENOSPC); 782 } 783 784 if ((i + sizeof(value)) <= length) { 785 err = 786 nfp_cpp_area_write(area, offset + i, &value, sizeof(value)); 787 if (err < 0) 788 return err; 789 if (err != sizeof(value)) 790 return NFP_ERRNO(ENOSPC); 791 i += sizeof(value); 792 } 793 794 return (int)i; 795 } 796 797 /* 798 * NOTE: This code should not use nfp_xpb_* functions, 799 * as those are model-specific 800 */ 801 uint32_t 802 __nfp_cpp_model_autodetect(struct nfp_cpp *cpp, uint32_t *model) 803 { 804 uint32_t reg; 805 int err; 806 807 err = nfp_xpb_readl(cpp, NFP_XPB_DEVICE(1, 1, 16) + NFP_PL_DEVICE_ID, 808 ®); 809 if (err < 0) 810 return err; 811 812 *model = reg & NFP_PL_DEVICE_MODEL_MASK; 813 if (*model & NFP_PL_DEVICE_ID_MASK) 814 *model -= 0x10; 815 816 return 0; 817 } 818 819 /* 820 * nfp_cpp_map_area() - Helper function to map an area 821 * @cpp: NFP CPP handler 822 * @domain: CPP domain 823 * @target: CPP target 824 * @addr: CPP address 825 * @size: Size of the area 826 * @area: Area handle (output) 827 * 828 * Map an area of IOMEM access. To undo the effect of this function call 829 * @nfp_cpp_area_release_free(*area). 830 * 831 * Return: Pointer to memory mapped area or ERR_PTR 832 */ 833 uint8_t * 834 nfp_cpp_map_area(struct nfp_cpp *cpp, int domain, int target, uint64_t addr, 835 unsigned long size, struct nfp_cpp_area **area) 836 { 837 uint8_t *res; 838 uint32_t dest; 839 840 dest = NFP_CPP_ISLAND_ID(target, NFP_CPP_ACTION_RW, 0, domain); 841 842 *area = nfp_cpp_area_alloc_acquire(cpp, dest, addr, size); 843 if (!*area) 844 goto err_eio; 845 846 res = nfp_cpp_area_iomem(*area); 847 if (!res) 848 goto err_release_free; 849 850 return res; 851 852 err_release_free: 853 nfp_cpp_area_release_free(*area); 854 err_eio: 855 return NULL; 856 } 857