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