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