1 /* SPDX-License-Identifier: BSD-3-Clause
3 * Copyright(c) 2019-2021 Xilinx, Inc.
4 * Copyright(c) 2009-2019 Solarflare Communications Inc.
10 #if EFSYS_OPT_LICENSING
12 #include "ef10_tlv_layout.h"
14 #include "efx_regs_mcdi_aoe.h"
17 #if EFSYS_OPT_SIENA | EFSYS_OPT_HUNTINGTON
19 __checkReturn efx_rc_t
20 efx_lic_v1v2_find_start(
22 __in_bcount(buffer_size)
24 __in size_t buffer_size,
25 __out uint32_t *startp);
27 __checkReturn efx_rc_t
28 efx_lic_v1v2_find_end(
30 __in_bcount(buffer_size)
32 __in size_t buffer_size,
34 __out uint32_t *endp);
36 __checkReturn __success(return != B_FALSE) boolean_t
37 efx_lic_v1v2_find_key(
39 __in_bcount(buffer_size)
41 __in size_t buffer_size,
43 __out uint32_t *startp,
44 __out uint32_t *lengthp);
46 __checkReturn __success(return != B_FALSE) boolean_t
47 efx_lic_v1v2_validate_key(
49 __in_bcount(length) caddr_t keyp,
50 __in uint32_t length);
52 __checkReturn efx_rc_t
53 efx_lic_v1v2_read_key(
55 __in_bcount(buffer_size)
57 __in size_t buffer_size,
60 __out_bcount_part(key_max_size, *lengthp)
62 __in size_t key_max_size,
63 __out uint32_t *lengthp);
65 __checkReturn efx_rc_t
66 efx_lic_v1v2_write_key(
68 __in_bcount(buffer_size)
70 __in size_t buffer_size,
72 __in_bcount(length) caddr_t keyp,
74 __out uint32_t *lengthp);
76 __checkReturn efx_rc_t
77 efx_lic_v1v2_delete_key(
79 __in_bcount(buffer_size)
81 __in size_t buffer_size,
85 __out uint32_t *deltap);
87 __checkReturn efx_rc_t
88 efx_lic_v1v2_create_partition(
90 __in_bcount(buffer_size)
92 __in size_t buffer_size);
94 __checkReturn efx_rc_t
95 efx_lic_v1v2_finish_partition(
97 __in_bcount(buffer_size)
99 __in size_t buffer_size);
101 #endif /* EFSYS_OPT_HUNTINGTON | EFSYS_OPT_SIENA */
106 static __checkReturn efx_rc_t
107 efx_mcdi_fc_license_update_license(
108 __in efx_nic_t *enp);
110 static __checkReturn efx_rc_t
111 efx_mcdi_fc_license_get_key_stats(
113 __out efx_key_stats_t *eksp);
115 static const efx_lic_ops_t __efx_lic_v1_ops = {
116 efx_mcdi_fc_license_update_license, /* elo_update_licenses */
117 efx_mcdi_fc_license_get_key_stats, /* elo_get_key_stats */
118 NULL, /* elo_app_state */
119 NULL, /* elo_get_id */
120 efx_lic_v1v2_find_start, /* elo_find_start */
121 efx_lic_v1v2_find_end, /* elo_find_end */
122 efx_lic_v1v2_find_key, /* elo_find_key */
123 efx_lic_v1v2_validate_key, /* elo_validate_key */
124 efx_lic_v1v2_read_key, /* elo_read_key */
125 efx_lic_v1v2_write_key, /* elo_write_key */
126 efx_lic_v1v2_delete_key, /* elo_delete_key */
127 efx_lic_v1v2_create_partition, /* elo_create_partition */
128 efx_lic_v1v2_finish_partition, /* elo_finish_partition */
131 #endif /* EFSYS_OPT_SIENA */
133 #if EFSYS_OPT_HUNTINGTON
135 static __checkReturn efx_rc_t
136 efx_mcdi_licensing_update_licenses(
137 __in efx_nic_t *enp);
139 static __checkReturn efx_rc_t
140 efx_mcdi_licensing_get_key_stats(
142 __out efx_key_stats_t *eksp);
144 static __checkReturn efx_rc_t
145 efx_mcdi_licensed_app_state(
147 __in uint64_t app_id,
148 __out boolean_t *licensedp);
150 static const efx_lic_ops_t __efx_lic_v2_ops = {
151 efx_mcdi_licensing_update_licenses, /* elo_update_licenses */
152 efx_mcdi_licensing_get_key_stats, /* elo_get_key_stats */
153 efx_mcdi_licensed_app_state, /* elo_app_state */
154 NULL, /* elo_get_id */
155 efx_lic_v1v2_find_start, /* elo_find_start */
156 efx_lic_v1v2_find_end, /* elo_find_end */
157 efx_lic_v1v2_find_key, /* elo_find_key */
158 efx_lic_v1v2_validate_key, /* elo_validate_key */
159 efx_lic_v1v2_read_key, /* elo_read_key */
160 efx_lic_v1v2_write_key, /* elo_write_key */
161 efx_lic_v1v2_delete_key, /* elo_delete_key */
162 efx_lic_v1v2_create_partition, /* elo_create_partition */
163 efx_lic_v1v2_finish_partition, /* elo_finish_partition */
166 #endif /* EFSYS_OPT_HUNTINGTON */
168 #if EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
170 static __checkReturn efx_rc_t
171 efx_mcdi_licensing_v3_update_licenses(
172 __in efx_nic_t *enp);
174 static __checkReturn efx_rc_t
175 efx_mcdi_licensing_v3_report_license(
177 __out efx_key_stats_t *eksp);
179 static __checkReturn efx_rc_t
180 efx_mcdi_licensing_v3_app_state(
182 __in uint64_t app_id,
183 __out boolean_t *licensedp);
185 static __checkReturn efx_rc_t
186 efx_mcdi_licensing_v3_get_id(
188 __in size_t buffer_size,
189 __out uint32_t *typep,
190 __out size_t *lengthp,
191 __out_bcount_part_opt(buffer_size, *lengthp)
194 __checkReturn efx_rc_t
195 efx_lic_v3_find_start(
197 __in_bcount(buffer_size)
199 __in size_t buffer_size,
200 __out uint32_t *startp);
202 __checkReturn efx_rc_t
205 __in_bcount(buffer_size)
207 __in size_t buffer_size,
208 __in uint32_t offset,
209 __out uint32_t *endp);
211 __checkReturn __success(return != B_FALSE) boolean_t
214 __in_bcount(buffer_size)
216 __in size_t buffer_size,
217 __in uint32_t offset,
218 __out uint32_t *startp,
219 __out uint32_t *lengthp);
221 __checkReturn __success(return != B_FALSE) boolean_t
222 efx_lic_v3_validate_key(
224 __in_bcount(length) caddr_t keyp,
225 __in uint32_t length);
227 __checkReturn efx_rc_t
230 __in_bcount(buffer_size)
232 __in size_t buffer_size,
233 __in uint32_t offset,
234 __in uint32_t length,
235 __out_bcount_part(key_max_size, *lengthp)
237 __in size_t key_max_size,
238 __out uint32_t *lengthp);
240 __checkReturn efx_rc_t
241 efx_lic_v3_write_key(
243 __in_bcount(buffer_size)
245 __in size_t buffer_size,
246 __in uint32_t offset,
247 __in_bcount(length) caddr_t keyp,
248 __in uint32_t length,
249 __out uint32_t *lengthp);
251 __checkReturn efx_rc_t
252 efx_lic_v3_delete_key(
254 __in_bcount(buffer_size)
256 __in size_t buffer_size,
257 __in uint32_t offset,
258 __in uint32_t length,
260 __out uint32_t *deltap);
262 __checkReturn efx_rc_t
263 efx_lic_v3_create_partition(
265 __in_bcount(buffer_size)
267 __in size_t buffer_size);
269 __checkReturn efx_rc_t
270 efx_lic_v3_finish_partition(
272 __in_bcount(buffer_size)
274 __in size_t buffer_size);
276 static const efx_lic_ops_t __efx_lic_v3_ops = {
277 efx_mcdi_licensing_v3_update_licenses, /* elo_update_licenses */
278 efx_mcdi_licensing_v3_report_license, /* elo_get_key_stats */
279 efx_mcdi_licensing_v3_app_state, /* elo_app_state */
280 efx_mcdi_licensing_v3_get_id, /* elo_get_id */
281 efx_lic_v3_find_start, /* elo_find_start */
282 efx_lic_v3_find_end, /* elo_find_end */
283 efx_lic_v3_find_key, /* elo_find_key */
284 efx_lic_v3_validate_key, /* elo_validate_key */
285 efx_lic_v3_read_key, /* elo_read_key */
286 efx_lic_v3_write_key, /* elo_write_key */
287 efx_lic_v3_delete_key, /* elo_delete_key */
288 efx_lic_v3_create_partition, /* elo_create_partition */
289 efx_lic_v3_finish_partition, /* elo_finish_partition */
292 #endif /* EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
295 /* V1 Licensing - used in Siena Modena only */
299 static __checkReturn efx_rc_t
300 efx_mcdi_fc_license_update_license(
304 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FC_IN_LICENSE_LEN, 0);
307 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
309 req.emr_cmd = MC_CMD_FC;
310 req.emr_in_buf = payload;
311 req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN;
312 req.emr_out_buf = payload;
313 req.emr_out_length = 0;
315 MCDI_IN_SET_DWORD(req, FC_IN_CMD,
316 MC_CMD_FC_OP_LICENSE);
318 MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP,
319 MC_CMD_FC_IN_LICENSE_UPDATE_LICENSE);
321 efx_mcdi_execute(enp, &req);
323 if (req.emr_rc != 0) {
328 if (req.emr_out_length_used != 0) {
338 EFSYS_PROBE1(fail1, efx_rc_t, rc);
343 static __checkReturn efx_rc_t
344 efx_mcdi_fc_license_get_key_stats(
346 __out efx_key_stats_t *eksp)
349 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FC_IN_LICENSE_LEN,
350 MC_CMD_FC_OUT_LICENSE_LEN);
353 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
355 req.emr_cmd = MC_CMD_FC;
356 req.emr_in_buf = payload;
357 req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN;
358 req.emr_out_buf = payload;
359 req.emr_out_length = MC_CMD_FC_OUT_LICENSE_LEN;
361 MCDI_IN_SET_DWORD(req, FC_IN_CMD,
362 MC_CMD_FC_OP_LICENSE);
364 MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP,
365 MC_CMD_FC_IN_LICENSE_GET_KEY_STATS);
367 efx_mcdi_execute_quiet(enp, &req);
369 if (req.emr_rc != 0) {
374 if (req.emr_out_length_used < MC_CMD_FC_OUT_LICENSE_LEN) {
380 MCDI_OUT_DWORD(req, FC_OUT_LICENSE_VALID_KEYS);
382 MCDI_OUT_DWORD(req, FC_OUT_LICENSE_INVALID_KEYS);
383 eksp->eks_blacklisted =
384 MCDI_OUT_DWORD(req, FC_OUT_LICENSE_BLACKLISTED_KEYS);
385 eksp->eks_unverifiable = 0;
386 eksp->eks_wrong_node = 0;
387 eksp->eks_licensed_apps_lo = 0;
388 eksp->eks_licensed_apps_hi = 0;
389 eksp->eks_licensed_features_lo = 0;
390 eksp->eks_licensed_features_hi = 0;
397 EFSYS_PROBE1(fail1, efx_rc_t, rc);
402 #endif /* EFSYS_OPT_SIENA */
404 /* V1 and V2 Partition format - based on a 16-bit TLV format */
406 #if EFSYS_OPT_SIENA | EFSYS_OPT_HUNTINGTON
409 * V1/V2 format - defined in SF-108542-TC section 4.2:
410 * Type (T): 16bit - revision/HMAC algorithm
411 * Length (L): 16bit - value length in bytes
412 * Value (V): L bytes - payload
414 #define EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX (256)
415 #define EFX_LICENSE_V1V2_HEADER_LENGTH (2 * sizeof (uint16_t))
417 __checkReturn efx_rc_t
418 efx_lic_v1v2_find_start(
420 __in_bcount(buffer_size)
422 __in size_t buffer_size,
423 __out uint32_t *startp)
425 _NOTE(ARGUNUSED(enp, bufferp, buffer_size))
431 __checkReturn efx_rc_t
432 efx_lic_v1v2_find_end(
434 __in_bcount(buffer_size)
436 __in size_t buffer_size,
437 __in uint32_t offset,
438 __out uint32_t *endp)
440 _NOTE(ARGUNUSED(enp, bufferp, buffer_size))
442 *endp = offset + EFX_LICENSE_V1V2_HEADER_LENGTH;
446 __checkReturn __success(return != B_FALSE) boolean_t
447 efx_lic_v1v2_find_key(
449 __in_bcount(buffer_size)
451 __in size_t buffer_size,
452 __in uint32_t offset,
453 __out uint32_t *startp,
454 __out uint32_t *lengthp)
460 _NOTE(ARGUNUSED(enp))
462 if ((size_t)buffer_size - offset < EFX_LICENSE_V1V2_HEADER_LENGTH)
465 tlv_type = __LE_TO_CPU_16(((uint16_t *)&bufferp[offset])[0]);
466 tlv_length = __LE_TO_CPU_16(((uint16_t *)&bufferp[offset])[1]);
467 if ((tlv_length > EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX) ||
468 (tlv_type == 0 && tlv_length == 0)) {
472 *lengthp = tlv_length + EFX_LICENSE_V1V2_HEADER_LENGTH;
478 EFSYS_PROBE1(fail1, boolean_t, B_FALSE);
483 __checkReturn __success(return != B_FALSE) boolean_t
484 efx_lic_v1v2_validate_key(
486 __in_bcount(length) caddr_t keyp,
487 __in uint32_t length)
492 _NOTE(ARGUNUSED(enp))
494 if (length < EFX_LICENSE_V1V2_HEADER_LENGTH) {
498 tlv_type = __LE_TO_CPU_16(((uint16_t *)keyp)[0]);
499 tlv_length = __LE_TO_CPU_16(((uint16_t *)keyp)[1]);
501 if (tlv_length > EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX) {
507 if ((tlv_length + EFX_LICENSE_V1V2_HEADER_LENGTH) != length) {
520 EFSYS_PROBE1(fail1, boolean_t, B_FALSE);
526 __checkReturn efx_rc_t
527 efx_lic_v1v2_read_key(
529 __in_bcount(buffer_size)
531 __in size_t buffer_size,
532 __in uint32_t offset,
533 __in uint32_t length,
534 __out_bcount_part(key_max_size, *lengthp)
536 __in size_t key_max_size,
537 __out uint32_t *lengthp)
541 _NOTE(ARGUNUSED(enp, buffer_size))
542 EFSYS_ASSERT(length <= (EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX +
543 EFX_LICENSE_V1V2_HEADER_LENGTH));
545 if (key_max_size < length) {
549 memcpy(keyp, &bufferp[offset], length);
556 EFSYS_PROBE1(fail1, efx_rc_t, rc);
561 __checkReturn efx_rc_t
562 efx_lic_v1v2_write_key(
564 __in_bcount(buffer_size)
566 __in size_t buffer_size,
567 __in uint32_t offset,
568 __in_bcount(length) caddr_t keyp,
569 __in uint32_t length,
570 __out uint32_t *lengthp)
574 _NOTE(ARGUNUSED(enp))
575 EFSYS_ASSERT(length <= (EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX +
576 EFX_LICENSE_V1V2_HEADER_LENGTH));
578 /* Ensure space for terminator remains */
579 if ((offset + length) >
580 (buffer_size - EFX_LICENSE_V1V2_HEADER_LENGTH)) {
585 memcpy(bufferp + offset, keyp, length);
592 EFSYS_PROBE1(fail1, efx_rc_t, rc);
597 __checkReturn efx_rc_t
598 efx_lic_v1v2_delete_key(
600 __in_bcount(buffer_size)
602 __in size_t buffer_size,
603 __in uint32_t offset,
604 __in uint32_t length,
606 __out uint32_t *deltap)
608 uint32_t move_start = offset + length;
609 uint32_t move_length = end - move_start;
611 _NOTE(ARGUNUSED(enp, buffer_size))
612 EFSYS_ASSERT(end <= buffer_size);
614 /* Shift everything after the key down */
615 memmove(bufferp + offset, bufferp + move_start, move_length);
622 __checkReturn efx_rc_t
623 efx_lic_v1v2_create_partition(
625 __in_bcount(buffer_size)
627 __in size_t buffer_size)
629 _NOTE(ARGUNUSED(enp, buffer_size))
630 EFSYS_ASSERT(EFX_LICENSE_V1V2_HEADER_LENGTH <= buffer_size);
632 /* Write terminator */
633 memset(bufferp, '\0', EFX_LICENSE_V1V2_HEADER_LENGTH);
638 __checkReturn efx_rc_t
639 efx_lic_v1v2_finish_partition(
641 __in_bcount(buffer_size)
643 __in size_t buffer_size)
645 _NOTE(ARGUNUSED(enp, bufferp, buffer_size))
650 #endif /* EFSYS_OPT_HUNTINGTON | EFSYS_OPT_SIENA */
653 /* V2 Licensing - used by Huntington family only. See SF-113611-TC */
655 #if EFSYS_OPT_HUNTINGTON
657 static __checkReturn efx_rc_t
658 efx_mcdi_licensed_app_state(
660 __in uint64_t app_id,
661 __out boolean_t *licensedp)
664 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LICENSED_APP_STATE_IN_LEN,
665 MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN);
669 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
671 /* V2 licensing supports 32bit app id only */
672 if ((app_id >> 32) != 0) {
677 req.emr_cmd = MC_CMD_GET_LICENSED_APP_STATE;
678 req.emr_in_buf = payload;
679 req.emr_in_length = MC_CMD_GET_LICENSED_APP_STATE_IN_LEN;
680 req.emr_out_buf = payload;
681 req.emr_out_length = MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN;
683 MCDI_IN_SET_DWORD(req, GET_LICENSED_APP_STATE_IN_APP_ID,
684 app_id & 0xffffffff);
686 efx_mcdi_execute(enp, &req);
688 if (req.emr_rc != 0) {
693 if (req.emr_out_length_used < MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN) {
698 app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_APP_STATE_OUT_STATE));
699 if (app_state != MC_CMD_GET_LICENSED_APP_STATE_OUT_NOT_LICENSED) {
702 *licensedp = B_FALSE;
712 EFSYS_PROBE1(fail1, efx_rc_t, rc);
717 static __checkReturn efx_rc_t
718 efx_mcdi_licensing_update_licenses(
722 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_IN_LEN, 0);
725 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
727 req.emr_cmd = MC_CMD_LICENSING;
728 req.emr_in_buf = payload;
729 req.emr_in_length = MC_CMD_LICENSING_IN_LEN;
730 req.emr_out_buf = payload;
731 req.emr_out_length = 0;
733 MCDI_IN_SET_DWORD(req, LICENSING_IN_OP,
734 MC_CMD_LICENSING_IN_OP_UPDATE_LICENSE);
736 efx_mcdi_execute(enp, &req);
738 if (req.emr_rc != 0) {
743 if (req.emr_out_length_used != 0) {
753 EFSYS_PROBE1(fail1, efx_rc_t, rc);
758 static __checkReturn efx_rc_t
759 efx_mcdi_licensing_get_key_stats(
761 __out efx_key_stats_t *eksp)
764 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_IN_LEN,
765 MC_CMD_LICENSING_OUT_LEN);
768 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
770 req.emr_cmd = MC_CMD_LICENSING;
771 req.emr_in_buf = payload;
772 req.emr_in_length = MC_CMD_LICENSING_IN_LEN;
773 req.emr_out_buf = payload;
774 req.emr_out_length = MC_CMD_LICENSING_OUT_LEN;
776 MCDI_IN_SET_DWORD(req, LICENSING_IN_OP,
777 MC_CMD_LICENSING_IN_OP_GET_KEY_STATS);
779 efx_mcdi_execute(enp, &req);
781 if (req.emr_rc != 0) {
786 if (req.emr_out_length_used < MC_CMD_LICENSING_OUT_LEN) {
792 MCDI_OUT_DWORD(req, LICENSING_OUT_VALID_APP_KEYS);
794 MCDI_OUT_DWORD(req, LICENSING_OUT_INVALID_APP_KEYS);
795 eksp->eks_blacklisted =
796 MCDI_OUT_DWORD(req, LICENSING_OUT_BLACKLISTED_APP_KEYS);
797 eksp->eks_unverifiable =
798 MCDI_OUT_DWORD(req, LICENSING_OUT_UNVERIFIABLE_APP_KEYS);
799 eksp->eks_wrong_node =
800 MCDI_OUT_DWORD(req, LICENSING_OUT_WRONG_NODE_APP_KEYS);
801 eksp->eks_licensed_apps_lo = 0;
802 eksp->eks_licensed_apps_hi = 0;
803 eksp->eks_licensed_features_lo = 0;
804 eksp->eks_licensed_features_hi = 0;
811 EFSYS_PROBE1(fail1, efx_rc_t, rc);
816 #endif /* EFSYS_OPT_HUNTINGTON */
818 /* V3 Licensing - used starting from Medford family. See SF-114884-SW */
820 #if EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
822 static __checkReturn efx_rc_t
823 efx_mcdi_licensing_v3_update_licenses(
827 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_V3_IN_LEN, 0);
830 EFSYS_ASSERT((enp->en_family == EFX_FAMILY_MEDFORD) ||
831 (enp->en_family == EFX_FAMILY_MEDFORD2));
833 req.emr_cmd = MC_CMD_LICENSING_V3;
834 req.emr_in_buf = payload;
835 req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN;
836 req.emr_out_buf = NULL;
837 req.emr_out_length = 0;
839 MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP,
840 MC_CMD_LICENSING_V3_IN_OP_UPDATE_LICENSE);
842 efx_mcdi_execute(enp, &req);
844 if (req.emr_rc != 0) {
852 EFSYS_PROBE1(fail1, efx_rc_t, rc);
857 static __checkReturn efx_rc_t
858 efx_mcdi_licensing_v3_report_license(
860 __out efx_key_stats_t *eksp)
863 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_V3_IN_LEN,
864 MC_CMD_LICENSING_V3_OUT_LEN);
867 EFSYS_ASSERT((enp->en_family == EFX_FAMILY_MEDFORD) ||
868 (enp->en_family == EFX_FAMILY_MEDFORD2));
870 req.emr_cmd = MC_CMD_LICENSING_V3;
871 req.emr_in_buf = payload;
872 req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN;
873 req.emr_out_buf = payload;
874 req.emr_out_length = MC_CMD_LICENSING_V3_OUT_LEN;
876 MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP,
877 MC_CMD_LICENSING_V3_IN_OP_REPORT_LICENSE);
879 efx_mcdi_execute_quiet(enp, &req);
881 if (req.emr_rc != 0) {
886 if (req.emr_out_length_used < MC_CMD_LICENSING_V3_OUT_LEN) {
892 MCDI_OUT_DWORD(req, LICENSING_V3_OUT_VALID_KEYS);
894 MCDI_OUT_DWORD(req, LICENSING_V3_OUT_INVALID_KEYS);
895 eksp->eks_blacklisted = 0;
896 eksp->eks_unverifiable =
897 MCDI_OUT_DWORD(req, LICENSING_V3_OUT_UNVERIFIABLE_KEYS);
898 eksp->eks_wrong_node =
899 MCDI_OUT_DWORD(req, LICENSING_V3_OUT_WRONG_NODE_KEYS);
900 eksp->eks_licensed_apps_lo =
901 MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_LO);
902 eksp->eks_licensed_apps_hi =
903 MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_HI);
904 eksp->eks_licensed_features_lo =
905 MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_LO);
906 eksp->eks_licensed_features_hi =
907 MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_HI);
914 EFSYS_PROBE1(fail1, efx_rc_t, rc);
919 static __checkReturn efx_rc_t
920 efx_mcdi_licensing_v3_app_state(
922 __in uint64_t app_id,
923 __out boolean_t *licensedp)
926 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN,
927 MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN);
931 EFSYS_ASSERT((enp->en_family == EFX_FAMILY_MEDFORD) ||
932 (enp->en_family == EFX_FAMILY_MEDFORD2));
934 req.emr_cmd = MC_CMD_GET_LICENSED_V3_APP_STATE;
935 req.emr_in_buf = payload;
936 req.emr_in_length = MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN;
937 req.emr_out_buf = payload;
938 req.emr_out_length = MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN;
940 MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_LO,
941 app_id & 0xffffffff);
942 MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_HI,
945 efx_mcdi_execute(enp, &req);
947 if (req.emr_rc != 0) {
952 if (req.emr_out_length_used <
953 MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN) {
958 app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_V3_APP_STATE_OUT_STATE));
959 if (app_state != MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_NOT_LICENSED) {
962 *licensedp = B_FALSE;
970 EFSYS_PROBE1(fail1, efx_rc_t, rc);
975 static __checkReturn efx_rc_t
976 efx_mcdi_licensing_v3_get_id(
978 __in size_t buffer_size,
979 __out uint32_t *typep,
980 __out size_t *lengthp,
981 __out_bcount_part_opt(buffer_size, *lengthp)
985 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_GET_ID_V3_IN_LEN,
986 MC_CMD_LICENSING_GET_ID_V3_OUT_LENMAX);
989 req.emr_cmd = MC_CMD_LICENSING_GET_ID_V3;
990 req.emr_in_buf = payload;
991 req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN;
992 req.emr_out_buf = payload;
993 req.emr_out_length = MC_CMD_LICENSING_GET_ID_V3_OUT_LENMAX;
995 efx_mcdi_execute_quiet(enp, &req);
997 if (req.emr_rc != 0) {
1002 if (req.emr_out_length_used < MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN) {
1007 *typep = MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_TYPE);
1009 MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_ID_LENGTH);
1011 if (bufferp != NULL) {
1013 payload + MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST,
1014 MIN(buffer_size, *lengthp));
1022 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1027 /* V3 format uses Huntington TLV format partition. See SF-108797-SW */
1028 #define EFX_LICENSE_V3_KEY_LENGTH_MIN (64)
1029 #define EFX_LICENSE_V3_KEY_LENGTH_MAX (160)
1031 __checkReturn efx_rc_t
1032 efx_lic_v3_find_start(
1033 __in efx_nic_t *enp,
1034 __in_bcount(buffer_size)
1036 __in size_t buffer_size,
1037 __out uint32_t *startp)
1039 _NOTE(ARGUNUSED(enp))
1041 return (ef10_nvram_buffer_find_item_start(bufferp, buffer_size,
1045 __checkReturn efx_rc_t
1046 efx_lic_v3_find_end(
1047 __in efx_nic_t *enp,
1048 __in_bcount(buffer_size)
1050 __in size_t buffer_size,
1051 __in uint32_t offset,
1052 __out uint32_t *endp)
1054 _NOTE(ARGUNUSED(enp))
1056 return (ef10_nvram_buffer_find_end(bufferp, buffer_size, offset, endp));
1059 __checkReturn __success(return != B_FALSE) boolean_t
1060 efx_lic_v3_find_key(
1061 __in efx_nic_t *enp,
1062 __in_bcount(buffer_size)
1064 __in size_t buffer_size,
1065 __in uint32_t offset,
1066 __out uint32_t *startp,
1067 __out uint32_t *lengthp)
1069 _NOTE(ARGUNUSED(enp))
1071 return ef10_nvram_buffer_find_item(bufferp, buffer_size,
1072 offset, startp, lengthp);
1075 __checkReturn __success(return != B_FALSE) boolean_t
1076 efx_lic_v3_validate_key(
1077 __in efx_nic_t *enp,
1078 __in_bcount(length) caddr_t keyp,
1079 __in uint32_t length)
1081 /* Check key is a valid V3 key */
1085 _NOTE(ARGUNUSED(enp))
1087 if (length < EFX_LICENSE_V3_KEY_LENGTH_MIN) {
1091 if (length > EFX_LICENSE_V3_KEY_LENGTH_MAX) {
1095 key_type = ((uint8_t *)keyp)[0];
1096 key_length = ((uint8_t *)keyp)[1];
1101 if (key_length > length) {
1113 EFSYS_PROBE1(fail1, boolean_t, B_FALSE);
1118 __checkReturn efx_rc_t
1119 efx_lic_v3_read_key(
1120 __in efx_nic_t *enp,
1121 __in_bcount(buffer_size)
1123 __in size_t buffer_size,
1124 __in uint32_t offset,
1125 __in uint32_t length,
1126 __out_bcount_part(key_max_size, *lengthp)
1128 __in size_t key_max_size,
1129 __out uint32_t *lengthp)
1133 _NOTE(ARGUNUSED(enp))
1135 return ef10_nvram_buffer_get_item(bufferp, buffer_size,
1136 offset, length, &tag, keyp, key_max_size, lengthp);
1139 __checkReturn efx_rc_t
1140 efx_lic_v3_write_key(
1141 __in efx_nic_t *enp,
1142 __in_bcount(buffer_size)
1144 __in size_t buffer_size,
1145 __in uint32_t offset,
1146 __in_bcount(length) caddr_t keyp,
1147 __in uint32_t length,
1148 __out uint32_t *lengthp)
1150 _NOTE(ARGUNUSED(enp))
1151 EFSYS_ASSERT(length <= EFX_LICENSE_V3_KEY_LENGTH_MAX);
1153 return ef10_nvram_buffer_insert_item(bufferp, buffer_size,
1154 offset, TLV_TAG_LICENSE, keyp, length, lengthp);
1157 __checkReturn efx_rc_t
1158 efx_lic_v3_delete_key(
1159 __in efx_nic_t *enp,
1160 __in_bcount(buffer_size)
1162 __in size_t buffer_size,
1163 __in uint32_t offset,
1164 __in uint32_t length,
1166 __out uint32_t *deltap)
1170 _NOTE(ARGUNUSED(enp))
1172 if ((rc = ef10_nvram_buffer_delete_item(bufferp,
1173 buffer_size, offset, length, end)) != 0) {
1182 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1187 __checkReturn efx_rc_t
1188 efx_lic_v3_create_partition(
1189 __in efx_nic_t *enp,
1190 __in_bcount(buffer_size)
1192 __in size_t buffer_size)
1196 _NOTE(ARGUNUSED(enp))
1198 /* Construct empty partition */
1199 if ((rc = ef10_nvram_buffer_create(
1200 NVRAM_PARTITION_TYPE_LICENSE,
1201 bufferp, buffer_size)) != 0) {
1209 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1214 __checkReturn efx_rc_t
1215 efx_lic_v3_finish_partition(
1216 __in efx_nic_t *enp,
1217 __in_bcount(buffer_size)
1219 __in size_t buffer_size)
1223 _NOTE(ARGUNUSED(enp))
1225 if ((rc = ef10_nvram_buffer_finish(bufferp,
1226 buffer_size)) != 0) {
1230 /* Validate completed partition */
1231 if ((rc = ef10_nvram_buffer_validate(
1232 NVRAM_PARTITION_TYPE_LICENSE,
1233 bufferp, buffer_size)) != 0) {
1242 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1248 #endif /* EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
1250 __checkReturn efx_rc_t
1252 __in efx_nic_t *enp)
1254 const efx_lic_ops_t *elop;
1255 efx_key_stats_t eks;
1258 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1259 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
1260 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_LIC));
1262 switch (enp->en_family) {
1265 case EFX_FAMILY_SIENA:
1266 elop = &__efx_lic_v1_ops;
1268 #endif /* EFSYS_OPT_SIENA */
1270 #if EFSYS_OPT_HUNTINGTON
1271 case EFX_FAMILY_HUNTINGTON:
1272 elop = &__efx_lic_v2_ops;
1274 #endif /* EFSYS_OPT_HUNTINGTON */
1276 #if EFSYS_OPT_MEDFORD
1277 case EFX_FAMILY_MEDFORD:
1278 elop = &__efx_lic_v3_ops;
1280 #endif /* EFSYS_OPT_MEDFORD */
1282 #if EFSYS_OPT_MEDFORD2
1283 case EFX_FAMILY_MEDFORD2:
1284 elop = &__efx_lic_v3_ops;
1286 #endif /* EFSYS_OPT_MEDFORD2 */
1294 enp->en_elop = elop;
1295 enp->en_mod_flags |= EFX_MOD_LIC;
1297 /* Probe for support */
1298 if (efx_lic_get_key_stats(enp, &eks) == 0) {
1299 enp->en_licensing_supported = B_TRUE;
1301 enp->en_licensing_supported = B_FALSE;
1307 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1312 extern __checkReturn boolean_t
1313 efx_lic_check_support(
1314 __in efx_nic_t *enp)
1316 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1317 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
1318 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1320 return (enp->en_licensing_supported);
1325 __in efx_nic_t *enp)
1327 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1328 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
1329 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1331 enp->en_elop = NULL;
1332 enp->en_mod_flags &= ~EFX_MOD_LIC;
1336 __checkReturn efx_rc_t
1337 efx_lic_update_licenses(
1338 __in efx_nic_t *enp)
1340 const efx_lic_ops_t *elop = enp->en_elop;
1343 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1344 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1346 if ((rc = elop->elo_update_licenses(enp)) != 0)
1352 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1357 __checkReturn efx_rc_t
1358 efx_lic_get_key_stats(
1359 __in efx_nic_t *enp,
1360 __out efx_key_stats_t *eksp)
1362 const efx_lic_ops_t *elop = enp->en_elop;
1365 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1366 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1368 if ((rc = elop->elo_get_key_stats(enp, eksp)) != 0)
1374 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1379 __checkReturn efx_rc_t
1381 __in efx_nic_t *enp,
1382 __in uint64_t app_id,
1383 __out boolean_t *licensedp)
1385 const efx_lic_ops_t *elop = enp->en_elop;
1388 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1389 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1391 if (elop->elo_app_state == NULL)
1394 if ((rc = elop->elo_app_state(enp, app_id, licensedp)) != 0)
1400 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1405 __checkReturn efx_rc_t
1407 __in efx_nic_t *enp,
1408 __in size_t buffer_size,
1409 __out uint32_t *typep,
1410 __out size_t *lengthp,
1411 __out_opt uint8_t *bufferp)
1413 const efx_lic_ops_t *elop = enp->en_elop;
1416 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1417 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1419 if (elop->elo_get_id == NULL)
1422 if ((rc = elop->elo_get_id(enp, buffer_size, typep,
1423 lengthp, bufferp)) != 0)
1429 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1435 * Buffer management API - abstracts varying TLV format used for License
1439 __checkReturn efx_rc_t
1441 __in efx_nic_t *enp,
1442 __in_bcount(buffer_size)
1444 __in size_t buffer_size,
1445 __out uint32_t *startp)
1447 const efx_lic_ops_t *elop = enp->en_elop;
1450 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1451 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1453 if ((rc = elop->elo_find_start(enp, bufferp, buffer_size, startp)) != 0)
1459 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1464 __checkReturn efx_rc_t
1466 __in efx_nic_t *enp,
1467 __in_bcount(buffer_size)
1469 __in size_t buffer_size,
1470 __in uint32_t offset,
1471 __out uint32_t *endp)
1473 const efx_lic_ops_t *elop = enp->en_elop;
1476 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1477 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1479 rc = elop->elo_find_end(enp, bufferp, buffer_size, offset, endp);
1486 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1491 __checkReturn __success(return != B_FALSE) boolean_t
1493 __in efx_nic_t *enp,
1494 __in_bcount(buffer_size)
1496 __in size_t buffer_size,
1497 __in uint32_t offset,
1498 __out uint32_t *startp,
1499 __out uint32_t *lengthp)
1501 const efx_lic_ops_t *elop = enp->en_elop;
1503 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1504 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1506 EFSYS_ASSERT(bufferp);
1507 EFSYS_ASSERT(startp);
1508 EFSYS_ASSERT(lengthp);
1510 return (elop->elo_find_key(enp, bufferp, buffer_size, offset,
1516 * Validate that the buffer contains a single key in a recognised format.
1517 * An empty or terminator buffer is not accepted as a valid key.
1519 __checkReturn __success(return != B_FALSE) boolean_t
1520 efx_lic_validate_key(
1521 __in efx_nic_t *enp,
1522 __in_bcount(length) caddr_t keyp,
1523 __in uint32_t length)
1525 const efx_lic_ops_t *elop = enp->en_elop;
1528 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1529 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1531 if ((rc = elop->elo_validate_key(enp, keyp, length)) == B_FALSE)
1537 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1542 __checkReturn efx_rc_t
1544 __in efx_nic_t *enp,
1545 __in_bcount(buffer_size)
1547 __in size_t buffer_size,
1548 __in uint32_t offset,
1549 __in uint32_t length,
1550 __out_bcount_part(key_max_size, *lengthp)
1552 __in size_t key_max_size,
1553 __out uint32_t *lengthp)
1555 const efx_lic_ops_t *elop = enp->en_elop;
1558 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1559 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1561 if ((rc = elop->elo_read_key(enp, bufferp, buffer_size, offset,
1562 length, keyp, key_max_size, lengthp)) != 0)
1568 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1573 __checkReturn efx_rc_t
1575 __in efx_nic_t *enp,
1576 __in_bcount(buffer_size)
1578 __in size_t buffer_size,
1579 __in uint32_t offset,
1580 __in_bcount(length) caddr_t keyp,
1581 __in uint32_t length,
1582 __out uint32_t *lengthp)
1584 const efx_lic_ops_t *elop = enp->en_elop;
1587 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1588 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1590 if ((rc = elop->elo_write_key(enp, bufferp, buffer_size, offset,
1591 keyp, length, lengthp)) != 0)
1597 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1602 __checkReturn efx_rc_t
1604 __in efx_nic_t *enp,
1605 __in_bcount(buffer_size)
1607 __in size_t buffer_size,
1608 __in uint32_t offset,
1609 __in uint32_t length,
1611 __out uint32_t *deltap)
1613 const efx_lic_ops_t *elop = enp->en_elop;
1616 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1617 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1619 if ((rc = elop->elo_delete_key(enp, bufferp, buffer_size, offset,
1620 length, end, deltap)) != 0)
1626 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1631 __checkReturn efx_rc_t
1632 efx_lic_create_partition(
1633 __in efx_nic_t *enp,
1634 __in_bcount(buffer_size)
1636 __in size_t buffer_size)
1638 const efx_lic_ops_t *elop = enp->en_elop;
1641 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1642 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1644 if ((rc = elop->elo_create_partition(enp, bufferp, buffer_size)) != 0)
1650 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1656 __checkReturn efx_rc_t
1657 efx_lic_finish_partition(
1658 __in efx_nic_t *enp,
1659 __in_bcount(buffer_size)
1661 __in size_t buffer_size)
1663 const efx_lic_ops_t *elop = enp->en_elop;
1666 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1667 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1669 if ((rc = elop->elo_finish_partition(enp, bufferp, buffer_size)) != 0)
1675 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1680 #endif /* EFSYS_OPT_LICENSING */