1
2
3
4
5
6
7#include "efx.h"
8#include "efx_impl.h"
9
10#if EFSYS_OPT_LICENSING
11
12#include "ef10_tlv_layout.h"
13#if EFSYS_OPT_SIENA
14#include "efx_regs_mcdi_aoe.h"
15#endif
16
17#if EFSYS_OPT_SIENA | EFSYS_OPT_HUNTINGTON
18
19 __checkReturn efx_rc_t
20efx_lic_v1v2_find_start(
21 __in efx_nic_t *enp,
22 __in_bcount(buffer_size)
23 caddr_t bufferp,
24 __in size_t buffer_size,
25 __out uint32_t *startp);
26
27 __checkReturn efx_rc_t
28efx_lic_v1v2_find_end(
29 __in efx_nic_t *enp,
30 __in_bcount(buffer_size)
31 caddr_t bufferp,
32 __in size_t buffer_size,
33 __in uint32_t offset,
34 __out uint32_t *endp);
35
36 __checkReturn __success(return != B_FALSE) boolean_t
37efx_lic_v1v2_find_key(
38 __in efx_nic_t *enp,
39 __in_bcount(buffer_size)
40 caddr_t bufferp,
41 __in size_t buffer_size,
42 __in uint32_t offset,
43 __out uint32_t *startp,
44 __out uint32_t *lengthp);
45
46 __checkReturn __success(return != B_FALSE) boolean_t
47efx_lic_v1v2_validate_key(
48 __in efx_nic_t *enp,
49 __in_bcount(length) caddr_t keyp,
50 __in uint32_t length);
51
52 __checkReturn efx_rc_t
53efx_lic_v1v2_read_key(
54 __in efx_nic_t *enp,
55 __in_bcount(buffer_size)
56 caddr_t bufferp,
57 __in size_t buffer_size,
58 __in uint32_t offset,
59 __in uint32_t length,
60 __out_bcount_part(key_max_size, *lengthp)
61 caddr_t keyp,
62 __in size_t key_max_size,
63 __out uint32_t *lengthp);
64
65 __checkReturn efx_rc_t
66efx_lic_v1v2_write_key(
67 __in efx_nic_t *enp,
68 __in_bcount(buffer_size)
69 caddr_t bufferp,
70 __in size_t buffer_size,
71 __in uint32_t offset,
72 __in_bcount(length) caddr_t keyp,
73 __in uint32_t length,
74 __out uint32_t *lengthp);
75
76 __checkReturn efx_rc_t
77efx_lic_v1v2_delete_key(
78 __in efx_nic_t *enp,
79 __in_bcount(buffer_size)
80 caddr_t bufferp,
81 __in size_t buffer_size,
82 __in uint32_t offset,
83 __in uint32_t length,
84 __in uint32_t end,
85 __out uint32_t *deltap);
86
87 __checkReturn efx_rc_t
88efx_lic_v1v2_create_partition(
89 __in efx_nic_t *enp,
90 __in_bcount(buffer_size)
91 caddr_t bufferp,
92 __in size_t buffer_size);
93
94 __checkReturn efx_rc_t
95efx_lic_v1v2_finish_partition(
96 __in efx_nic_t *enp,
97 __in_bcount(buffer_size)
98 caddr_t bufferp,
99 __in size_t buffer_size);
100
101#endif
102
103
104#if EFSYS_OPT_SIENA
105
106static __checkReturn efx_rc_t
107efx_mcdi_fc_license_update_license(
108 __in efx_nic_t *enp);
109
110static __checkReturn efx_rc_t
111efx_mcdi_fc_license_get_key_stats(
112 __in efx_nic_t *enp,
113 __out efx_key_stats_t *eksp);
114
115static const efx_lic_ops_t __efx_lic_v1_ops = {
116 efx_mcdi_fc_license_update_license,
117 efx_mcdi_fc_license_get_key_stats,
118 NULL,
119 NULL,
120 efx_lic_v1v2_find_start,
121 efx_lic_v1v2_find_end,
122 efx_lic_v1v2_find_key,
123 efx_lic_v1v2_validate_key,
124 efx_lic_v1v2_read_key,
125 efx_lic_v1v2_write_key,
126 efx_lic_v1v2_delete_key,
127 efx_lic_v1v2_create_partition,
128 efx_lic_v1v2_finish_partition,
129};
130
131#endif
132
133#if EFSYS_OPT_HUNTINGTON
134
135static __checkReturn efx_rc_t
136efx_mcdi_licensing_update_licenses(
137 __in efx_nic_t *enp);
138
139static __checkReturn efx_rc_t
140efx_mcdi_licensing_get_key_stats(
141 __in efx_nic_t *enp,
142 __out efx_key_stats_t *eksp);
143
144static __checkReturn efx_rc_t
145efx_mcdi_licensed_app_state(
146 __in efx_nic_t *enp,
147 __in uint64_t app_id,
148 __out boolean_t *licensedp);
149
150static const efx_lic_ops_t __efx_lic_v2_ops = {
151 efx_mcdi_licensing_update_licenses,
152 efx_mcdi_licensing_get_key_stats,
153 efx_mcdi_licensed_app_state,
154 NULL,
155 efx_lic_v1v2_find_start,
156 efx_lic_v1v2_find_end,
157 efx_lic_v1v2_find_key,
158 efx_lic_v1v2_validate_key,
159 efx_lic_v1v2_read_key,
160 efx_lic_v1v2_write_key,
161 efx_lic_v1v2_delete_key,
162 efx_lic_v1v2_create_partition,
163 efx_lic_v1v2_finish_partition,
164};
165
166#endif
167
168#if EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
169
170static __checkReturn efx_rc_t
171efx_mcdi_licensing_v3_update_licenses(
172 __in efx_nic_t *enp);
173
174static __checkReturn efx_rc_t
175efx_mcdi_licensing_v3_report_license(
176 __in efx_nic_t *enp,
177 __out efx_key_stats_t *eksp);
178
179static __checkReturn efx_rc_t
180efx_mcdi_licensing_v3_app_state(
181 __in efx_nic_t *enp,
182 __in uint64_t app_id,
183 __out boolean_t *licensedp);
184
185static __checkReturn efx_rc_t
186efx_mcdi_licensing_v3_get_id(
187 __in efx_nic_t *enp,
188 __in size_t buffer_size,
189 __out uint32_t *typep,
190 __out size_t *lengthp,
191 __out_bcount_part_opt(buffer_size, *lengthp)
192 uint8_t *bufferp);
193
194 __checkReturn efx_rc_t
195efx_lic_v3_find_start(
196 __in efx_nic_t *enp,
197 __in_bcount(buffer_size)
198 caddr_t bufferp,
199 __in size_t buffer_size,
200 __out uint32_t *startp);
201
202 __checkReturn efx_rc_t
203efx_lic_v3_find_end(
204 __in efx_nic_t *enp,
205 __in_bcount(buffer_size)
206 caddr_t bufferp,
207 __in size_t buffer_size,
208 __in uint32_t offset,
209 __out uint32_t *endp);
210
211 __checkReturn __success(return != B_FALSE) boolean_t
212efx_lic_v3_find_key(
213 __in efx_nic_t *enp,
214 __in_bcount(buffer_size)
215 caddr_t bufferp,
216 __in size_t buffer_size,
217 __in uint32_t offset,
218 __out uint32_t *startp,
219 __out uint32_t *lengthp);
220
221 __checkReturn __success(return != B_FALSE) boolean_t
222efx_lic_v3_validate_key(
223 __in efx_nic_t *enp,
224 __in_bcount(length) caddr_t keyp,
225 __in uint32_t length);
226
227 __checkReturn efx_rc_t
228efx_lic_v3_read_key(
229 __in efx_nic_t *enp,
230 __in_bcount(buffer_size)
231 caddr_t bufferp,
232 __in size_t buffer_size,
233 __in uint32_t offset,
234 __in uint32_t length,
235 __out_bcount_part(key_max_size, *lengthp)
236 caddr_t keyp,
237 __in size_t key_max_size,
238 __out uint32_t *lengthp);
239
240 __checkReturn efx_rc_t
241efx_lic_v3_write_key(
242 __in efx_nic_t *enp,
243 __in_bcount(buffer_size)
244 caddr_t bufferp,
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);
250
251 __checkReturn efx_rc_t
252efx_lic_v3_delete_key(
253 __in efx_nic_t *enp,
254 __in_bcount(buffer_size)
255 caddr_t bufferp,
256 __in size_t buffer_size,
257 __in uint32_t offset,
258 __in uint32_t length,
259 __in uint32_t end,
260 __out uint32_t *deltap);
261
262 __checkReturn efx_rc_t
263efx_lic_v3_create_partition(
264 __in efx_nic_t *enp,
265 __in_bcount(buffer_size)
266 caddr_t bufferp,
267 __in size_t buffer_size);
268
269 __checkReturn efx_rc_t
270efx_lic_v3_finish_partition(
271 __in efx_nic_t *enp,
272 __in_bcount(buffer_size)
273 caddr_t bufferp,
274 __in size_t buffer_size);
275
276static const efx_lic_ops_t __efx_lic_v3_ops = {
277 efx_mcdi_licensing_v3_update_licenses,
278 efx_mcdi_licensing_v3_report_license,
279 efx_mcdi_licensing_v3_app_state,
280 efx_mcdi_licensing_v3_get_id,
281 efx_lic_v3_find_start,
282 efx_lic_v3_find_end,
283 efx_lic_v3_find_key,
284 efx_lic_v3_validate_key,
285 efx_lic_v3_read_key,
286 efx_lic_v3_write_key,
287 efx_lic_v3_delete_key,
288 efx_lic_v3_create_partition,
289 efx_lic_v3_finish_partition,
290};
291
292#endif
293
294
295
296
297#if EFSYS_OPT_SIENA
298
299static __checkReturn efx_rc_t
300efx_mcdi_fc_license_update_license(
301 __in efx_nic_t *enp)
302{
303 efx_mcdi_req_t req;
304 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FC_IN_LICENSE_LEN, 0);
305 efx_rc_t rc;
306
307 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
308
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;
314
315 MCDI_IN_SET_DWORD(req, FC_IN_CMD,
316 MC_CMD_FC_OP_LICENSE);
317
318 MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP,
319 MC_CMD_FC_IN_LICENSE_UPDATE_LICENSE);
320
321 efx_mcdi_execute(enp, &req);
322
323 if (req.emr_rc != 0) {
324 rc = req.emr_rc;
325 goto fail1;
326 }
327
328 if (req.emr_out_length_used != 0) {
329 rc = EIO;
330 goto fail2;
331 }
332
333 return (0);
334
335fail2:
336 EFSYS_PROBE(fail2);
337fail1:
338 EFSYS_PROBE1(fail1, efx_rc_t, rc);
339
340 return (rc);
341}
342
343static __checkReturn efx_rc_t
344efx_mcdi_fc_license_get_key_stats(
345 __in efx_nic_t *enp,
346 __out efx_key_stats_t *eksp)
347{
348 efx_mcdi_req_t req;
349 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FC_IN_LICENSE_LEN,
350 MC_CMD_FC_OUT_LICENSE_LEN);
351 efx_rc_t rc;
352
353 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
354
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;
360
361 MCDI_IN_SET_DWORD(req, FC_IN_CMD,
362 MC_CMD_FC_OP_LICENSE);
363
364 MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP,
365 MC_CMD_FC_IN_LICENSE_GET_KEY_STATS);
366
367 efx_mcdi_execute_quiet(enp, &req);
368
369 if (req.emr_rc != 0) {
370 rc = req.emr_rc;
371 goto fail1;
372 }
373
374 if (req.emr_out_length_used < MC_CMD_FC_OUT_LICENSE_LEN) {
375 rc = EMSGSIZE;
376 goto fail2;
377 }
378
379 eksp->eks_valid =
380 MCDI_OUT_DWORD(req, FC_OUT_LICENSE_VALID_KEYS);
381 eksp->eks_invalid =
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;
391
392 return (0);
393
394fail2:
395 EFSYS_PROBE(fail2);
396fail1:
397 EFSYS_PROBE1(fail1, efx_rc_t, rc);
398
399 return (rc);
400}
401
402#endif
403
404
405
406#if EFSYS_OPT_SIENA | EFSYS_OPT_HUNTINGTON
407
408
409
410
411
412
413
414#define EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX (256)
415#define EFX_LICENSE_V1V2_HEADER_LENGTH (2 * sizeof (uint16_t))
416
417 __checkReturn efx_rc_t
418efx_lic_v1v2_find_start(
419 __in efx_nic_t *enp,
420 __in_bcount(buffer_size)
421 caddr_t bufferp,
422 __in size_t buffer_size,
423 __out uint32_t *startp)
424{
425 _NOTE(ARGUNUSED(enp, bufferp, buffer_size))
426
427 *startp = 0;
428 return (0);
429}
430
431 __checkReturn efx_rc_t
432efx_lic_v1v2_find_end(
433 __in efx_nic_t *enp,
434 __in_bcount(buffer_size)
435 caddr_t bufferp,
436 __in size_t buffer_size,
437 __in uint32_t offset,
438 __out uint32_t *endp)
439{
440 _NOTE(ARGUNUSED(enp, bufferp, buffer_size))
441
442 *endp = offset + EFX_LICENSE_V1V2_HEADER_LENGTH;
443 return (0);
444}
445
446 __checkReturn __success(return != B_FALSE) boolean_t
447efx_lic_v1v2_find_key(
448 __in efx_nic_t *enp,
449 __in_bcount(buffer_size)
450 caddr_t bufferp,
451 __in size_t buffer_size,
452 __in uint32_t offset,
453 __out uint32_t *startp,
454 __out uint32_t *lengthp)
455{
456 boolean_t found;
457 uint16_t tlv_type;
458 uint16_t tlv_length;
459
460 _NOTE(ARGUNUSED(enp))
461
462 if ((size_t)buffer_size - offset < EFX_LICENSE_V1V2_HEADER_LENGTH)
463 goto fail1;
464
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)) {
469 found = B_FALSE;
470 } else {
471 *startp = offset;
472 *lengthp = tlv_length + EFX_LICENSE_V1V2_HEADER_LENGTH;
473 found = B_TRUE;
474 }
475 return (found);
476
477fail1:
478 EFSYS_PROBE1(fail1, boolean_t, B_FALSE);
479
480 return (B_FALSE);
481}
482
483 __checkReturn __success(return != B_FALSE) boolean_t
484efx_lic_v1v2_validate_key(
485 __in efx_nic_t *enp,
486 __in_bcount(length) caddr_t keyp,
487 __in uint32_t length)
488{
489 uint16_t tlv_type;
490 uint16_t tlv_length;
491
492 _NOTE(ARGUNUSED(enp))
493
494 if (length < EFX_LICENSE_V1V2_HEADER_LENGTH) {
495 goto fail1;
496 }
497
498 tlv_type = __LE_TO_CPU_16(((uint16_t *)keyp)[0]);
499 tlv_length = __LE_TO_CPU_16(((uint16_t *)keyp)[1]);
500
501 if (tlv_length > EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX) {
502 goto fail2;
503 }
504 if (tlv_type == 0) {
505 goto fail3;
506 }
507 if ((tlv_length + EFX_LICENSE_V1V2_HEADER_LENGTH) != length) {
508 goto fail4;
509 }
510
511 return (B_TRUE);
512
513fail4:
514 EFSYS_PROBE(fail4);
515fail3:
516 EFSYS_PROBE(fail3);
517fail2:
518 EFSYS_PROBE(fail2);
519fail1:
520 EFSYS_PROBE1(fail1, boolean_t, B_FALSE);
521
522 return (B_FALSE);
523}
524
525
526 __checkReturn efx_rc_t
527efx_lic_v1v2_read_key(
528 __in efx_nic_t *enp,
529 __in_bcount(buffer_size)
530 caddr_t bufferp,
531 __in size_t buffer_size,
532 __in uint32_t offset,
533 __in uint32_t length,
534 __out_bcount_part(key_max_size, *lengthp)
535 caddr_t keyp,
536 __in size_t key_max_size,
537 __out uint32_t *lengthp)
538{
539 efx_rc_t rc;
540
541 _NOTE(ARGUNUSED(enp, buffer_size))
542 EFSYS_ASSERT(length <= (EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX +
543 EFX_LICENSE_V1V2_HEADER_LENGTH));
544
545 if (key_max_size < length) {
546 rc = ENOSPC;
547 goto fail1;
548 }
549 memcpy(keyp, &bufferp[offset], length);
550
551 *lengthp = length;
552
553 return (0);
554
555fail1:
556 EFSYS_PROBE1(fail1, efx_rc_t, rc);
557
558 return (rc);
559}
560
561 __checkReturn efx_rc_t
562efx_lic_v1v2_write_key(
563 __in efx_nic_t *enp,
564 __in_bcount(buffer_size)
565 caddr_t bufferp,
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)
571{
572 efx_rc_t rc;
573
574 _NOTE(ARGUNUSED(enp))
575 EFSYS_ASSERT(length <= (EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX +
576 EFX_LICENSE_V1V2_HEADER_LENGTH));
577
578
579 if ((offset + length) >
580 (buffer_size - EFX_LICENSE_V1V2_HEADER_LENGTH)) {
581 rc = ENOSPC;
582 goto fail1;
583 }
584
585 memcpy(bufferp + offset, keyp, length);
586
587 *lengthp = length;
588
589 return (0);
590
591fail1:
592 EFSYS_PROBE1(fail1, efx_rc_t, rc);
593
594 return (rc);
595}
596
597 __checkReturn efx_rc_t
598efx_lic_v1v2_delete_key(
599 __in efx_nic_t *enp,
600 __in_bcount(buffer_size)
601 caddr_t bufferp,
602 __in size_t buffer_size,
603 __in uint32_t offset,
604 __in uint32_t length,
605 __in uint32_t end,
606 __out uint32_t *deltap)
607{
608 uint32_t move_start = offset + length;
609 uint32_t move_length = end - move_start;
610
611 _NOTE(ARGUNUSED(enp, buffer_size))
612 EFSYS_ASSERT(end <= buffer_size);
613
614
615 memmove(bufferp + offset, bufferp + move_start, move_length);
616
617 *deltap = length;
618
619 return (0);
620}
621
622 __checkReturn efx_rc_t
623efx_lic_v1v2_create_partition(
624 __in efx_nic_t *enp,
625 __in_bcount(buffer_size)
626 caddr_t bufferp,
627 __in size_t buffer_size)
628{
629 _NOTE(ARGUNUSED(enp, buffer_size))
630 EFSYS_ASSERT(EFX_LICENSE_V1V2_HEADER_LENGTH <= buffer_size);
631
632
633 memset(bufferp, '\0', EFX_LICENSE_V1V2_HEADER_LENGTH);
634 return (0);
635}
636
637
638 __checkReturn efx_rc_t
639efx_lic_v1v2_finish_partition(
640 __in efx_nic_t *enp,
641 __in_bcount(buffer_size)
642 caddr_t bufferp,
643 __in size_t buffer_size)
644{
645 _NOTE(ARGUNUSED(enp, bufferp, buffer_size))
646
647 return (0);
648}
649
650#endif
651
652
653
654
655#if EFSYS_OPT_HUNTINGTON
656
657static __checkReturn efx_rc_t
658efx_mcdi_licensed_app_state(
659 __in efx_nic_t *enp,
660 __in uint64_t app_id,
661 __out boolean_t *licensedp)
662{
663 efx_mcdi_req_t req;
664 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LICENSED_APP_STATE_IN_LEN,
665 MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN);
666 uint32_t app_state;
667 efx_rc_t rc;
668
669 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
670
671
672 if ((app_id >> 32) != 0) {
673 rc = EINVAL;
674 goto fail1;
675 }
676
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;
682
683 MCDI_IN_SET_DWORD(req, GET_LICENSED_APP_STATE_IN_APP_ID,
684 app_id & 0xffffffff);
685
686 efx_mcdi_execute(enp, &req);
687
688 if (req.emr_rc != 0) {
689 rc = req.emr_rc;
690 goto fail2;
691 }
692
693 if (req.emr_out_length_used < MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN) {
694 rc = EMSGSIZE;
695 goto fail3;
696 }
697
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) {
700 *licensedp = B_TRUE;
701 } else {
702 *licensedp = B_FALSE;
703 }
704
705 return (0);
706
707fail3:
708 EFSYS_PROBE(fail3);
709fail2:
710 EFSYS_PROBE(fail2);
711fail1:
712 EFSYS_PROBE1(fail1, efx_rc_t, rc);
713
714 return (rc);
715}
716
717static __checkReturn efx_rc_t
718efx_mcdi_licensing_update_licenses(
719 __in efx_nic_t *enp)
720{
721 efx_mcdi_req_t req;
722 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_IN_LEN, 0);
723 efx_rc_t rc;
724
725 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
726
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;
732
733 MCDI_IN_SET_DWORD(req, LICENSING_IN_OP,
734 MC_CMD_LICENSING_IN_OP_UPDATE_LICENSE);
735
736 efx_mcdi_execute(enp, &req);
737
738 if (req.emr_rc != 0) {
739 rc = req.emr_rc;
740 goto fail1;
741 }
742
743 if (req.emr_out_length_used != 0) {
744 rc = EIO;
745 goto fail2;
746 }
747
748 return (0);
749
750fail2:
751 EFSYS_PROBE(fail2);
752fail1:
753 EFSYS_PROBE1(fail1, efx_rc_t, rc);
754
755 return (rc);
756}
757
758static __checkReturn efx_rc_t
759efx_mcdi_licensing_get_key_stats(
760 __in efx_nic_t *enp,
761 __out efx_key_stats_t *eksp)
762{
763 efx_mcdi_req_t req;
764 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_IN_LEN,
765 MC_CMD_LICENSING_OUT_LEN);
766 efx_rc_t rc;
767
768 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
769
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;
775
776 MCDI_IN_SET_DWORD(req, LICENSING_IN_OP,
777 MC_CMD_LICENSING_IN_OP_GET_KEY_STATS);
778
779 efx_mcdi_execute(enp, &req);
780
781 if (req.emr_rc != 0) {
782 rc = req.emr_rc;
783 goto fail1;
784 }
785
786 if (req.emr_out_length_used < MC_CMD_LICENSING_OUT_LEN) {
787 rc = EMSGSIZE;
788 goto fail2;
789 }
790
791 eksp->eks_valid =
792 MCDI_OUT_DWORD(req, LICENSING_OUT_VALID_APP_KEYS);
793 eksp->eks_invalid =
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;
805
806 return (0);
807
808fail2:
809 EFSYS_PROBE(fail2);
810fail1:
811 EFSYS_PROBE1(fail1, efx_rc_t, rc);
812
813 return (rc);
814}
815
816#endif
817
818
819
820#if EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
821
822static __checkReturn efx_rc_t
823efx_mcdi_licensing_v3_update_licenses(
824 __in efx_nic_t *enp)
825{
826 efx_mcdi_req_t req;
827 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_V3_IN_LEN, 0);
828 efx_rc_t rc;
829
830 EFSYS_ASSERT((enp->en_family == EFX_FAMILY_MEDFORD) ||
831 (enp->en_family == EFX_FAMILY_MEDFORD2));
832
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;
838
839 MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP,
840 MC_CMD_LICENSING_V3_IN_OP_UPDATE_LICENSE);
841
842 efx_mcdi_execute(enp, &req);
843
844 if (req.emr_rc != 0) {
845 rc = req.emr_rc;
846 goto fail1;
847 }
848
849 return (0);
850
851fail1:
852 EFSYS_PROBE1(fail1, efx_rc_t, rc);
853
854 return (rc);
855}
856
857static __checkReturn efx_rc_t
858efx_mcdi_licensing_v3_report_license(
859 __in efx_nic_t *enp,
860 __out efx_key_stats_t *eksp)
861{
862 efx_mcdi_req_t req;
863 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_V3_IN_LEN,
864 MC_CMD_LICENSING_V3_OUT_LEN);
865 efx_rc_t rc;
866
867 EFSYS_ASSERT((enp->en_family == EFX_FAMILY_MEDFORD) ||
868 (enp->en_family == EFX_FAMILY_MEDFORD2));
869
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;
875
876 MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP,
877 MC_CMD_LICENSING_V3_IN_OP_REPORT_LICENSE);
878
879 efx_mcdi_execute_quiet(enp, &req);
880
881 if (req.emr_rc != 0) {
882 rc = req.emr_rc;
883 goto fail1;
884 }
885
886 if (req.emr_out_length_used < MC_CMD_LICENSING_V3_OUT_LEN) {
887 rc = EMSGSIZE;
888 goto fail2;
889 }
890
891 eksp->eks_valid =
892 MCDI_OUT_DWORD(req, LICENSING_V3_OUT_VALID_KEYS);
893 eksp->eks_invalid =
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);
908
909 return (0);
910
911fail2:
912 EFSYS_PROBE(fail2);
913fail1:
914 EFSYS_PROBE1(fail1, efx_rc_t, rc);
915
916 return (rc);
917}
918
919static __checkReturn efx_rc_t
920efx_mcdi_licensing_v3_app_state(
921 __in efx_nic_t *enp,
922 __in uint64_t app_id,
923 __out boolean_t *licensedp)
924{
925 efx_mcdi_req_t req;
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);
928 uint32_t app_state;
929 efx_rc_t rc;
930
931 EFSYS_ASSERT((enp->en_family == EFX_FAMILY_MEDFORD) ||
932 (enp->en_family == EFX_FAMILY_MEDFORD2));
933
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;
939
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,
943 app_id >> 32);
944
945 efx_mcdi_execute(enp, &req);
946
947 if (req.emr_rc != 0) {
948 rc = req.emr_rc;
949 goto fail1;
950 }
951
952 if (req.emr_out_length_used <
953 MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN) {
954 rc = EMSGSIZE;
955 goto fail2;
956 }
957
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) {
960 *licensedp = B_TRUE;
961 } else {
962 *licensedp = B_FALSE;
963 }
964
965 return (0);
966
967fail2:
968 EFSYS_PROBE(fail2);
969fail1:
970 EFSYS_PROBE1(fail1, efx_rc_t, rc);
971
972 return (rc);
973}
974
975static __checkReturn efx_rc_t
976efx_mcdi_licensing_v3_get_id(
977 __in efx_nic_t *enp,
978 __in size_t buffer_size,
979 __out uint32_t *typep,
980 __out size_t *lengthp,
981 __out_bcount_part_opt(buffer_size, *lengthp)
982 uint8_t *bufferp)
983{
984 efx_mcdi_req_t req;
985 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_GET_ID_V3_IN_LEN,
986 MC_CMD_LICENSING_GET_ID_V3_OUT_LENMAX);
987 efx_rc_t rc;
988
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;
994
995 efx_mcdi_execute_quiet(enp, &req);
996
997 if (req.emr_rc != 0) {
998 rc = req.emr_rc;
999 goto fail1;
1000 }
1001
1002 if (req.emr_out_length_used < MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN) {
1003 rc = EMSGSIZE;
1004 goto fail2;
1005 }
1006
1007 *typep = MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_TYPE);
1008 *lengthp =
1009 MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_ID_LENGTH);
1010
1011 if (bufferp != NULL) {
1012 memcpy(bufferp,
1013 payload + MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST,
1014 MIN(buffer_size, *lengthp));
1015 }
1016
1017 return (0);
1018
1019fail2:
1020 EFSYS_PROBE(fail2);
1021fail1:
1022 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1023
1024 return (rc);
1025}
1026
1027
1028#define EFX_LICENSE_V3_KEY_LENGTH_MIN (64)
1029#define EFX_LICENSE_V3_KEY_LENGTH_MAX (160)
1030
1031 __checkReturn efx_rc_t
1032efx_lic_v3_find_start(
1033 __in efx_nic_t *enp,
1034 __in_bcount(buffer_size)
1035 caddr_t bufferp,
1036 __in size_t buffer_size,
1037 __out uint32_t *startp)
1038{
1039 _NOTE(ARGUNUSED(enp))
1040
1041 return (ef10_nvram_buffer_find_item_start(bufferp, buffer_size,
1042 startp));
1043}
1044
1045 __checkReturn efx_rc_t
1046efx_lic_v3_find_end(
1047 __in efx_nic_t *enp,
1048 __in_bcount(buffer_size)
1049 caddr_t bufferp,
1050 __in size_t buffer_size,
1051 __in uint32_t offset,
1052 __out uint32_t *endp)
1053{
1054 _NOTE(ARGUNUSED(enp))
1055
1056 return (ef10_nvram_buffer_find_end(bufferp, buffer_size, offset, endp));
1057}
1058
1059 __checkReturn __success(return != B_FALSE) boolean_t
1060efx_lic_v3_find_key(
1061 __in efx_nic_t *enp,
1062 __in_bcount(buffer_size)
1063 caddr_t bufferp,
1064 __in size_t buffer_size,
1065 __in uint32_t offset,
1066 __out uint32_t *startp,
1067 __out uint32_t *lengthp)
1068{
1069 _NOTE(ARGUNUSED(enp))
1070
1071 return ef10_nvram_buffer_find_item(bufferp, buffer_size,
1072 offset, startp, lengthp);
1073}
1074
1075 __checkReturn __success(return != B_FALSE) boolean_t
1076efx_lic_v3_validate_key(
1077 __in efx_nic_t *enp,
1078 __in_bcount(length) caddr_t keyp,
1079 __in uint32_t length)
1080{
1081
1082 uint8_t key_type;
1083 uint8_t key_length;
1084
1085 _NOTE(ARGUNUSED(enp))
1086
1087 if (length < EFX_LICENSE_V3_KEY_LENGTH_MIN) {
1088 goto fail1;
1089 }
1090
1091 if (length > EFX_LICENSE_V3_KEY_LENGTH_MAX) {
1092 goto fail2;
1093 }
1094
1095 key_type = ((uint8_t *)keyp)[0];
1096 key_length = ((uint8_t *)keyp)[1];
1097
1098 if (key_type < 3) {
1099 goto fail3;
1100 }
1101 if (key_length > length) {
1102 goto fail4;
1103 }
1104 return (B_TRUE);
1105
1106fail4:
1107 EFSYS_PROBE(fail4);
1108fail3:
1109 EFSYS_PROBE(fail3);
1110fail2:
1111 EFSYS_PROBE(fail2);
1112fail1:
1113 EFSYS_PROBE1(fail1, boolean_t, B_FALSE);
1114
1115 return (B_FALSE);
1116}
1117
1118 __checkReturn efx_rc_t
1119efx_lic_v3_read_key(
1120 __in efx_nic_t *enp,
1121 __in_bcount(buffer_size)
1122 caddr_t bufferp,
1123 __in size_t buffer_size,
1124 __in uint32_t offset,
1125 __in uint32_t length,
1126 __out_bcount_part(key_max_size, *lengthp)
1127 caddr_t keyp,
1128 __in size_t key_max_size,
1129 __out uint32_t *lengthp)
1130{
1131 uint32_t tag;
1132
1133 _NOTE(ARGUNUSED(enp))
1134
1135 return ef10_nvram_buffer_get_item(bufferp, buffer_size,
1136 offset, length, &tag, keyp, key_max_size, lengthp);
1137}
1138
1139 __checkReturn efx_rc_t
1140efx_lic_v3_write_key(
1141 __in efx_nic_t *enp,
1142 __in_bcount(buffer_size)
1143 caddr_t bufferp,
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)
1149{
1150 _NOTE(ARGUNUSED(enp))
1151 EFSYS_ASSERT(length <= EFX_LICENSE_V3_KEY_LENGTH_MAX);
1152
1153 return ef10_nvram_buffer_insert_item(bufferp, buffer_size,
1154 offset, TLV_TAG_LICENSE, keyp, length, lengthp);
1155}
1156
1157 __checkReturn efx_rc_t
1158efx_lic_v3_delete_key(
1159 __in efx_nic_t *enp,
1160 __in_bcount(buffer_size)
1161 caddr_t bufferp,
1162 __in size_t buffer_size,
1163 __in uint32_t offset,
1164 __in uint32_t length,
1165 __in uint32_t end,
1166 __out uint32_t *deltap)
1167{
1168 efx_rc_t rc;
1169
1170 _NOTE(ARGUNUSED(enp))
1171
1172 if ((rc = ef10_nvram_buffer_delete_item(bufferp,
1173 buffer_size, offset, length, end)) != 0) {
1174 goto fail1;
1175 }
1176
1177 *deltap = length;
1178
1179 return (0);
1180
1181fail1:
1182 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1183
1184 return (rc);
1185}
1186
1187 __checkReturn efx_rc_t
1188efx_lic_v3_create_partition(
1189 __in efx_nic_t *enp,
1190 __in_bcount(buffer_size)
1191 caddr_t bufferp,
1192 __in size_t buffer_size)
1193{
1194 efx_rc_t rc;
1195
1196 _NOTE(ARGUNUSED(enp))
1197
1198
1199 if ((rc = ef10_nvram_buffer_create(
1200 NVRAM_PARTITION_TYPE_LICENSE,
1201 bufferp, buffer_size)) != 0) {
1202 rc = EFAULT;
1203 goto fail1;
1204 }
1205
1206 return (0);
1207
1208fail1:
1209 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1210
1211 return (rc);
1212}
1213
1214 __checkReturn efx_rc_t
1215efx_lic_v3_finish_partition(
1216 __in efx_nic_t *enp,
1217 __in_bcount(buffer_size)
1218 caddr_t bufferp,
1219 __in size_t buffer_size)
1220{
1221 efx_rc_t rc;
1222
1223 _NOTE(ARGUNUSED(enp))
1224
1225 if ((rc = ef10_nvram_buffer_finish(bufferp,
1226 buffer_size)) != 0) {
1227 goto fail1;
1228 }
1229
1230
1231 if ((rc = ef10_nvram_buffer_validate(
1232 NVRAM_PARTITION_TYPE_LICENSE,
1233 bufferp, buffer_size)) != 0) {
1234 goto fail2;
1235 }
1236
1237 return (0);
1238
1239fail2:
1240 EFSYS_PROBE(fail2);
1241fail1:
1242 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1243
1244 return (rc);
1245}
1246
1247
1248#endif
1249
1250 __checkReturn efx_rc_t
1251efx_lic_init(
1252 __in efx_nic_t *enp)
1253{
1254 const efx_lic_ops_t *elop;
1255 efx_key_stats_t eks;
1256 efx_rc_t rc;
1257
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));
1261
1262 switch (enp->en_family) {
1263
1264#if EFSYS_OPT_SIENA
1265 case EFX_FAMILY_SIENA:
1266 elop = &__efx_lic_v1_ops;
1267 break;
1268#endif
1269
1270#if EFSYS_OPT_HUNTINGTON
1271 case EFX_FAMILY_HUNTINGTON:
1272 elop = &__efx_lic_v2_ops;
1273 break;
1274#endif
1275
1276#if EFSYS_OPT_MEDFORD
1277 case EFX_FAMILY_MEDFORD:
1278 elop = &__efx_lic_v3_ops;
1279 break;
1280#endif
1281
1282#if EFSYS_OPT_MEDFORD2
1283 case EFX_FAMILY_MEDFORD2:
1284 elop = &__efx_lic_v3_ops;
1285 break;
1286#endif
1287
1288 default:
1289 EFSYS_ASSERT(0);
1290 rc = ENOTSUP;
1291 goto fail1;
1292 }
1293
1294 enp->en_elop = elop;
1295 enp->en_mod_flags |= EFX_MOD_LIC;
1296
1297
1298 if (efx_lic_get_key_stats(enp, &eks) == 0) {
1299 enp->en_licensing_supported = B_TRUE;
1300 } else {
1301 enp->en_licensing_supported = B_FALSE;
1302 }
1303
1304 return (0);
1305
1306fail1:
1307 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1308
1309 return (rc);
1310}
1311
1312extern __checkReturn boolean_t
1313efx_lic_check_support(
1314 __in efx_nic_t *enp)
1315{
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);
1319
1320 return (enp->en_licensing_supported);
1321}
1322
1323 void
1324efx_lic_fini(
1325 __in efx_nic_t *enp)
1326{
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);
1330
1331 enp->en_elop = NULL;
1332 enp->en_mod_flags &= ~EFX_MOD_LIC;
1333}
1334
1335
1336 __checkReturn efx_rc_t
1337efx_lic_update_licenses(
1338 __in efx_nic_t *enp)
1339{
1340 const efx_lic_ops_t *elop = enp->en_elop;
1341 efx_rc_t rc;
1342
1343 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1344 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1345
1346 if ((rc = elop->elo_update_licenses(enp)) != 0)
1347 goto fail1;
1348
1349 return (0);
1350
1351fail1:
1352 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1353
1354 return (rc);
1355}
1356
1357 __checkReturn efx_rc_t
1358efx_lic_get_key_stats(
1359 __in efx_nic_t *enp,
1360 __out efx_key_stats_t *eksp)
1361{
1362 const efx_lic_ops_t *elop = enp->en_elop;
1363 efx_rc_t rc;
1364
1365 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1366 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1367
1368 if ((rc = elop->elo_get_key_stats(enp, eksp)) != 0)
1369 goto fail1;
1370
1371 return (0);
1372
1373fail1:
1374 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1375
1376 return (rc);
1377}
1378
1379 __checkReturn efx_rc_t
1380efx_lic_app_state(
1381 __in efx_nic_t *enp,
1382 __in uint64_t app_id,
1383 __out boolean_t *licensedp)
1384{
1385 const efx_lic_ops_t *elop = enp->en_elop;
1386 efx_rc_t rc;
1387
1388 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1389 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1390
1391 if (elop->elo_app_state == NULL)
1392 return (ENOTSUP);
1393
1394 if ((rc = elop->elo_app_state(enp, app_id, licensedp)) != 0)
1395 goto fail1;
1396
1397 return (0);
1398
1399fail1:
1400 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1401
1402 return (rc);
1403}
1404
1405 __checkReturn efx_rc_t
1406efx_lic_get_id(
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)
1412{
1413 const efx_lic_ops_t *elop = enp->en_elop;
1414 efx_rc_t rc;
1415
1416 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1417 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1418
1419 if (elop->elo_get_id == NULL)
1420 return (ENOTSUP);
1421
1422 if ((rc = elop->elo_get_id(enp, buffer_size, typep,
1423 lengthp, bufferp)) != 0)
1424 goto fail1;
1425
1426 return (0);
1427
1428fail1:
1429 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1430
1431 return (rc);
1432}
1433
1434
1435
1436
1437
1438
1439 __checkReturn efx_rc_t
1440efx_lic_find_start(
1441 __in efx_nic_t *enp,
1442 __in_bcount(buffer_size)
1443 caddr_t bufferp,
1444 __in size_t buffer_size,
1445 __out uint32_t *startp)
1446{
1447 const efx_lic_ops_t *elop = enp->en_elop;
1448 efx_rc_t rc;
1449
1450 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1451 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1452
1453 if ((rc = elop->elo_find_start(enp, bufferp, buffer_size, startp)) != 0)
1454 goto fail1;
1455
1456 return (0);
1457
1458fail1:
1459 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1460
1461 return (rc);
1462}
1463
1464 __checkReturn efx_rc_t
1465efx_lic_find_end(
1466 __in efx_nic_t *enp,
1467 __in_bcount(buffer_size)
1468 caddr_t bufferp,
1469 __in size_t buffer_size,
1470 __in uint32_t offset,
1471 __out uint32_t *endp)
1472{
1473 const efx_lic_ops_t *elop = enp->en_elop;
1474 efx_rc_t rc;
1475
1476 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1477 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1478
1479 rc = elop->elo_find_end(enp, bufferp, buffer_size, offset, endp);
1480 if (rc != 0)
1481 goto fail1;
1482
1483 return (0);
1484
1485fail1:
1486 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1487
1488 return (rc);
1489}
1490
1491 __checkReturn __success(return != B_FALSE) boolean_t
1492efx_lic_find_key(
1493 __in efx_nic_t *enp,
1494 __in_bcount(buffer_size)
1495 caddr_t bufferp,
1496 __in size_t buffer_size,
1497 __in uint32_t offset,
1498 __out uint32_t *startp,
1499 __out uint32_t *lengthp)
1500{
1501 const efx_lic_ops_t *elop = enp->en_elop;
1502
1503 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1504 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1505
1506 EFSYS_ASSERT(bufferp);
1507 EFSYS_ASSERT(startp);
1508 EFSYS_ASSERT(lengthp);
1509
1510 return (elop->elo_find_key(enp, bufferp, buffer_size, offset,
1511 startp, lengthp));
1512}
1513
1514
1515
1516
1517
1518
1519 __checkReturn __success(return != B_FALSE) boolean_t
1520efx_lic_validate_key(
1521 __in efx_nic_t *enp,
1522 __in_bcount(length) caddr_t keyp,
1523 __in uint32_t length)
1524{
1525 const efx_lic_ops_t *elop = enp->en_elop;
1526 boolean_t rc;
1527
1528 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1529 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1530
1531 if ((rc = elop->elo_validate_key(enp, keyp, length)) == B_FALSE)
1532 goto fail1;
1533
1534 return (B_TRUE);
1535
1536fail1:
1537 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1538
1539 return (rc);
1540}
1541
1542 __checkReturn efx_rc_t
1543efx_lic_read_key(
1544 __in efx_nic_t *enp,
1545 __in_bcount(buffer_size)
1546 caddr_t bufferp,
1547 __in size_t buffer_size,
1548 __in uint32_t offset,
1549 __in uint32_t length,
1550 __out_bcount_part(key_max_size, *lengthp)
1551 caddr_t keyp,
1552 __in size_t key_max_size,
1553 __out uint32_t *lengthp)
1554{
1555 const efx_lic_ops_t *elop = enp->en_elop;
1556 efx_rc_t rc;
1557
1558 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1559 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1560
1561 if ((rc = elop->elo_read_key(enp, bufferp, buffer_size, offset,
1562 length, keyp, key_max_size, lengthp)) != 0)
1563 goto fail1;
1564
1565 return (0);
1566
1567fail1:
1568 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1569
1570 return (rc);
1571}
1572
1573 __checkReturn efx_rc_t
1574efx_lic_write_key(
1575 __in efx_nic_t *enp,
1576 __in_bcount(buffer_size)
1577 caddr_t bufferp,
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)
1583{
1584 const efx_lic_ops_t *elop = enp->en_elop;
1585 efx_rc_t rc;
1586
1587 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1588 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1589
1590 if ((rc = elop->elo_write_key(enp, bufferp, buffer_size, offset,
1591 keyp, length, lengthp)) != 0)
1592 goto fail1;
1593
1594 return (0);
1595
1596fail1:
1597 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1598
1599 return (rc);
1600}
1601
1602 __checkReturn efx_rc_t
1603efx_lic_delete_key(
1604 __in efx_nic_t *enp,
1605 __in_bcount(buffer_size)
1606 caddr_t bufferp,
1607 __in size_t buffer_size,
1608 __in uint32_t offset,
1609 __in uint32_t length,
1610 __in uint32_t end,
1611 __out uint32_t *deltap)
1612{
1613 const efx_lic_ops_t *elop = enp->en_elop;
1614 efx_rc_t rc;
1615
1616 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1617 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1618
1619 if ((rc = elop->elo_delete_key(enp, bufferp, buffer_size, offset,
1620 length, end, deltap)) != 0)
1621 goto fail1;
1622
1623 return (0);
1624
1625fail1:
1626 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1627
1628 return (rc);
1629}
1630
1631 __checkReturn efx_rc_t
1632efx_lic_create_partition(
1633 __in efx_nic_t *enp,
1634 __in_bcount(buffer_size)
1635 caddr_t bufferp,
1636 __in size_t buffer_size)
1637{
1638 const efx_lic_ops_t *elop = enp->en_elop;
1639 efx_rc_t rc;
1640
1641 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1642 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1643
1644 if ((rc = elop->elo_create_partition(enp, bufferp, buffer_size)) != 0)
1645 goto fail1;
1646
1647 return (0);
1648
1649fail1:
1650 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1651
1652 return (rc);
1653}
1654
1655
1656 __checkReturn efx_rc_t
1657efx_lic_finish_partition(
1658 __in efx_nic_t *enp,
1659 __in_bcount(buffer_size)
1660 caddr_t bufferp,
1661 __in size_t buffer_size)
1662{
1663 const efx_lic_ops_t *elop = enp->en_elop;
1664 efx_rc_t rc;
1665
1666 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1667 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1668
1669 if ((rc = elop->elo_finish_partition(enp, bufferp, buffer_size)) != 0)
1670 goto fail1;
1671
1672 return (0);
1673
1674fail1:
1675 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1676
1677 return (rc);
1678}
1679
1680#endif
1681