|
60 | 60 | #define NFP_FW_LOAD_RET_MAJOR GENMASK_ULL(15, 8) |
61 | 61 | #define NFP_FW_LOAD_RET_MINOR GENMASK_ULL(23, 16) |
62 | 62 |
|
| 63 | +#define NFP_HWINFO_LOOKUP_SIZE GENMASK_ULL(11, 0) |
| 64 | + |
63 | 65 | enum nfp_nsp_cmd { |
64 | 66 | SPCODE_NOOP = 0, /* No operation */ |
65 | 67 | SPCODE_SOFT_RESET = 1, /* Soft reset the NFP */ |
@@ -477,7 +479,9 @@ nfp_nsp_command_buf_def(struct nfp_nsp *nsp, |
477 | 479 | FIELD_PREP(NSP_BUFFER_ADDRESS, cpp_buf); |
478 | 480 | ret = nfp_nsp_command_real(nsp, &arg->arg); |
479 | 481 | if (ret < 0) { |
480 | | - PMD_DRV_LOG(ERR, "NSP command failed"); |
| 482 | + if (!arg->arg.error_quiet) |
| 483 | + PMD_DRV_LOG(ERR, "NSP command failed"); |
| 484 | + |
481 | 485 | return ret; |
482 | 486 | } |
483 | 487 |
|
@@ -755,3 +759,83 @@ nfp_nsp_read_media(struct nfp_nsp *state, |
755 | 759 |
|
756 | 760 | return nfp_nsp_command_buf(state, &media); |
757 | 761 | } |
| 762 | + |
| 763 | +int |
| 764 | +nfp_nsp_load_stored_fw(struct nfp_nsp *state) |
| 765 | +{ |
| 766 | + int ret; |
| 767 | + struct nfp_nsp_command_buf_arg fw_stored = { |
| 768 | + { |
| 769 | + .code = SPCODE_FW_STORED, |
| 770 | + .error_cb = nfp_nsp_load_fw_extended_msg, |
| 771 | + }, |
| 772 | + }; |
| 773 | + |
| 774 | + ret = nfp_nsp_command_buf(state, &fw_stored); |
| 775 | + if (ret < 0) |
| 776 | + return ret; |
| 777 | + |
| 778 | + nfp_nsp_load_fw_extended_msg(state, ret); |
| 779 | + |
| 780 | + return 0; |
| 781 | +} |
| 782 | + |
| 783 | +static int |
| 784 | +nfp_nsp_hwinfo_lookup_real(struct nfp_nsp *state, |
| 785 | + void *buf, |
| 786 | + size_t size, |
| 787 | + bool optional) |
| 788 | +{ |
| 789 | + struct nfp_nsp_command_buf_arg hwinfo_lookup = { |
| 790 | + { |
| 791 | + .code = SPCODE_HWINFO_LOOKUP, |
| 792 | + .option = size, |
| 793 | + .error_quiet = optional, |
| 794 | + }, |
| 795 | + .in_buf = buf, |
| 796 | + .in_size = size, |
| 797 | + .out_buf = buf, |
| 798 | + .out_size = size, |
| 799 | + }; |
| 800 | + |
| 801 | + return nfp_nsp_command_buf(state, &hwinfo_lookup); |
| 802 | +} |
| 803 | + |
| 804 | +int |
| 805 | +nfp_nsp_hwinfo_lookup_optional(struct nfp_nsp *state, |
| 806 | + void *buf, |
| 807 | + size_t size, |
| 808 | + const char *default_val) |
| 809 | +{ |
| 810 | + int ret; |
| 811 | + size_t min_size; |
| 812 | + |
| 813 | + if (strnlen(default_val, size) == size) { |
| 814 | + PMD_DRV_LOG(ERR, "NSP HWinfo default value not NULL terminated"); |
| 815 | + return -EINVAL; |
| 816 | + } |
| 817 | + |
| 818 | + if (!nfp_nsp_has_hwinfo_lookup(state)) |
| 819 | + goto default_return; |
| 820 | + |
| 821 | + min_size = RTE_MIN(size, NFP_HWINFO_LOOKUP_SIZE); |
| 822 | + ret = nfp_nsp_hwinfo_lookup_real(state, buf, min_size, true); |
| 823 | + if (ret != 0) { |
| 824 | + if (ret == -ENOENT) |
| 825 | + goto default_return; |
| 826 | + |
| 827 | + PMD_DRV_LOG(ERR, "NSP HWinfo lookup failed: %d", ret); |
| 828 | + return ret; |
| 829 | + } |
| 830 | + |
| 831 | + if (strnlen(buf, min_size) == min_size) { |
| 832 | + PMD_DRV_LOG(ERR, "NSP HWinfo value not NULL terminated"); |
| 833 | + return -EINVAL; |
| 834 | + } |
| 835 | + |
| 836 | + return 0; |
| 837 | + |
| 838 | +default_return: |
| 839 | + strlcpy(buf, default_val, size); |
| 840 | + return 0; |
| 841 | +} |
0 commit comments