1 /*-
2  * Copyright (c) 2009-2016 Solarflare Communications Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  *    this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  *    this list of conditions and the following disclaimer in the documentation
12  *    and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  * The views and conclusions contained in the software and documentation are
27  * those of the authors and should not be interpreted as representing official
28  * policies, either expressed or implied, of the FreeBSD Project.
29  */
30 
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD: stable/10/sys/dev/sfxge/common/efx_lic.c 342516 2018-12-26 10:25:01Z arybchik $");
33 
34 #include "efx.h"
35 #include "efx_impl.h"
36 
37 #if EFSYS_OPT_LICENSING
38 
39 #include "ef10_tlv_layout.h"
40 
41 #if EFSYS_OPT_SIENA | EFSYS_OPT_HUNTINGTON
42 
43 	__checkReturn		efx_rc_t
44 efx_lic_v1v2_find_start(
45 	__in			efx_nic_t *enp,
46 	__in_bcount(buffer_size)
47 				caddr_t bufferp,
48 	__in			size_t buffer_size,
49 	__out			uint32_t *startp
50 	);
51 
52 	__checkReturn		efx_rc_t
53 efx_lic_v1v2_find_end(
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 	__out			uint32_t *endp
60 	);
61 
62 	__checkReturn	__success(return != B_FALSE)	boolean_t
63 efx_lic_v1v2_find_key(
64 	__in			efx_nic_t *enp,
65 	__in_bcount(buffer_size)
66 				caddr_t bufferp,
67 	__in			size_t buffer_size,
68 	__in			uint32_t offset,
69 	__out			uint32_t *startp,
70 	__out			uint32_t *lengthp
71 	);
72 
73 	__checkReturn	__success(return != B_FALSE)	boolean_t
74 efx_lic_v1v2_validate_key(
75 	__in			efx_nic_t *enp,
76 	__in_bcount(length)	caddr_t keyp,
77 	__in			uint32_t length
78 	);
79 
80 	__checkReturn		efx_rc_t
81 efx_lic_v1v2_read_key(
82 	__in			efx_nic_t *enp,
83 	__in_bcount(buffer_size)
84 				caddr_t bufferp,
85 	__in			size_t buffer_size,
86 	__in			uint32_t offset,
87 	__in			uint32_t length,
88 	__out_bcount_part(key_max_size, *lengthp)
89 				caddr_t keyp,
90 	__in			size_t key_max_size,
91 	__out			uint32_t *lengthp
92 	);
93 
94 	__checkReturn		efx_rc_t
95 efx_lic_v1v2_write_key(
96 	__in			efx_nic_t *enp,
97 	__in_bcount(buffer_size)
98 				caddr_t bufferp,
99 	__in			size_t buffer_size,
100 	__in			uint32_t offset,
101 	__in_bcount(length)	caddr_t keyp,
102 	__in			uint32_t length,
103 	__out			uint32_t *lengthp
104 	);
105 
106 	__checkReturn		efx_rc_t
107 efx_lic_v1v2_delete_key(
108 	__in			efx_nic_t *enp,
109 	__in_bcount(buffer_size)
110 				caddr_t bufferp,
111 	__in			size_t buffer_size,
112 	__in			uint32_t offset,
113 	__in			uint32_t length,
114 	__in			uint32_t end,
115 	__out			uint32_t *deltap
116 	);
117 
118 	__checkReturn		efx_rc_t
119 efx_lic_v1v2_create_partition(
120 	__in			efx_nic_t *enp,
121 	__in_bcount(buffer_size)
122 				caddr_t bufferp,
123 	__in			size_t buffer_size
124 	);
125 
126 	__checkReturn		efx_rc_t
127 efx_lic_v1v2_finish_partition(
128 	__in			efx_nic_t *enp,
129 	__in_bcount(buffer_size)
130 				caddr_t bufferp,
131 	__in			size_t buffer_size
132 	);
133 
134 #endif	/* EFSYS_OPT_HUNTINGTON | EFSYS_OPT_SIENA */
135 
136 
137 #if EFSYS_OPT_SIENA
138 
139 static	__checkReturn	efx_rc_t
140 efx_mcdi_fc_license_update_license(
141 	__in		efx_nic_t *enp);
142 
143 static	__checkReturn	efx_rc_t
144 efx_mcdi_fc_license_get_key_stats(
145 	__in		efx_nic_t *enp,
146 	__out		efx_key_stats_t *eksp);
147 
148 static const efx_lic_ops_t	__efx_lic_v1_ops = {
149 	efx_mcdi_fc_license_update_license,	/* elo_update_licenses */
150 	efx_mcdi_fc_license_get_key_stats,	/* elo_get_key_stats */
151 	NULL,					/* elo_app_state */
152 	NULL,					/* elo_get_id */
153 	efx_lic_v1v2_find_start,		/* elo_find_start */
154 	efx_lic_v1v2_find_end,			/* elo_find_end */
155 	efx_lic_v1v2_find_key,			/* elo_find_key */
156 	efx_lic_v1v2_validate_key,		/* elo_validate_key */
157 	efx_lic_v1v2_read_key,			/* elo_read_key */
158 	efx_lic_v1v2_write_key,			/* elo_write_key */
159 	efx_lic_v1v2_delete_key,		/* elo_delete_key */
160 	efx_lic_v1v2_create_partition,		/* elo_create_partition */
161 	efx_lic_v1v2_finish_partition,		/* elo_finish_partition */
162 };
163 
164 #endif	/* EFSYS_OPT_SIENA */
165 
166 #if EFSYS_OPT_HUNTINGTON
167 
168 static	__checkReturn	efx_rc_t
169 efx_mcdi_licensing_update_licenses(
170 	__in		efx_nic_t *enp);
171 
172 static	__checkReturn	efx_rc_t
173 efx_mcdi_licensing_get_key_stats(
174 	__in		efx_nic_t *enp,
175 	__out		efx_key_stats_t *eksp);
176 
177 static	__checkReturn	efx_rc_t
178 efx_mcdi_licensed_app_state(
179 	__in		efx_nic_t *enp,
180 	__in		uint64_t app_id,
181 	__out		boolean_t *licensedp);
182 
183 static const efx_lic_ops_t	__efx_lic_v2_ops = {
184 	efx_mcdi_licensing_update_licenses,	/* elo_update_licenses */
185 	efx_mcdi_licensing_get_key_stats,	/* elo_get_key_stats */
186 	efx_mcdi_licensed_app_state,		/* elo_app_state */
187 	NULL,					/* elo_get_id */
188 	efx_lic_v1v2_find_start,		/* elo_find_start */
189 	efx_lic_v1v2_find_end,			/* elo_find_end */
190 	efx_lic_v1v2_find_key,			/* elo_find_key */
191 	efx_lic_v1v2_validate_key,		/* elo_validate_key */
192 	efx_lic_v1v2_read_key,			/* elo_read_key */
193 	efx_lic_v1v2_write_key,			/* elo_write_key */
194 	efx_lic_v1v2_delete_key,		/* elo_delete_key */
195 	efx_lic_v1v2_create_partition,		/* elo_create_partition */
196 	efx_lic_v1v2_finish_partition,		/* elo_finish_partition */
197 };
198 
199 #endif	/* EFSYS_OPT_HUNTINGTON */
200 
201 #if EFSYS_OPT_MEDFORD
202 
203 static	__checkReturn	efx_rc_t
204 efx_mcdi_licensing_v3_update_licenses(
205 	__in		efx_nic_t *enp);
206 
207 static	__checkReturn	efx_rc_t
208 efx_mcdi_licensing_v3_report_license(
209 	__in		efx_nic_t *enp,
210 	__out		efx_key_stats_t *eksp);
211 
212 static	__checkReturn	efx_rc_t
213 efx_mcdi_licensing_v3_app_state(
214 	__in		efx_nic_t *enp,
215 	__in		uint64_t app_id,
216 	__out		boolean_t *licensedp);
217 
218 static	__checkReturn	efx_rc_t
219 efx_mcdi_licensing_v3_get_id(
220 	__in		efx_nic_t *enp,
221 	__in		size_t buffer_size,
222 	__out		uint32_t *typep,
223 	__out		size_t *lengthp,
224 	__out_bcount_part_opt(buffer_size, *lengthp)
225 			uint8_t *bufferp);
226 
227 	__checkReturn		efx_rc_t
228 efx_lic_v3_find_start(
229 	__in			efx_nic_t *enp,
230 	__in_bcount(buffer_size)
231 				caddr_t bufferp,
232 	__in			size_t buffer_size,
233 	__out			uint32_t *startp
234 	);
235 
236 	__checkReturn		efx_rc_t
237 efx_lic_v3_find_end(
238 	__in			efx_nic_t *enp,
239 	__in_bcount(buffer_size)
240 				caddr_t bufferp,
241 	__in			size_t buffer_size,
242 	__in			uint32_t offset,
243 	__out			uint32_t *endp
244 	);
245 
246 	__checkReturn	__success(return != B_FALSE)	boolean_t
247 efx_lic_v3_find_key(
248 	__in			efx_nic_t *enp,
249 	__in_bcount(buffer_size)
250 				caddr_t bufferp,
251 	__in			size_t buffer_size,
252 	__in			uint32_t offset,
253 	__out			uint32_t *startp,
254 	__out			uint32_t *lengthp
255 	);
256 
257 	__checkReturn	__success(return != B_FALSE)	boolean_t
258 efx_lic_v3_validate_key(
259 	__in			efx_nic_t *enp,
260 	__in_bcount(length)	caddr_t keyp,
261 	__in			uint32_t length
262 	);
263 
264 	__checkReturn		efx_rc_t
265 efx_lic_v3_read_key(
266 	__in			efx_nic_t *enp,
267 	__in_bcount(buffer_size)
268 				caddr_t bufferp,
269 	__in			size_t buffer_size,
270 	__in			uint32_t offset,
271 	__in			uint32_t length,
272 	__out_bcount_part(key_max_size, *lengthp)
273 				caddr_t keyp,
274 	__in			size_t key_max_size,
275 	__out			uint32_t *lengthp
276 	);
277 
278 	__checkReturn		efx_rc_t
279 efx_lic_v3_write_key(
280 	__in			efx_nic_t *enp,
281 	__in_bcount(buffer_size)
282 				caddr_t bufferp,
283 	__in			size_t buffer_size,
284 	__in			uint32_t offset,
285 	__in_bcount(length)	caddr_t keyp,
286 	__in			uint32_t length,
287 	__out			uint32_t *lengthp
288 	);
289 
290 	__checkReturn		efx_rc_t
291 efx_lic_v3_delete_key(
292 	__in			efx_nic_t *enp,
293 	__in_bcount(buffer_size)
294 				caddr_t bufferp,
295 	__in			size_t buffer_size,
296 	__in			uint32_t offset,
297 	__in			uint32_t length,
298 	__in			uint32_t end,
299 	__out			uint32_t *deltap
300 	);
301 
302 	__checkReturn		efx_rc_t
303 efx_lic_v3_create_partition(
304 	__in			efx_nic_t *enp,
305 	__in_bcount(buffer_size)
306 				caddr_t bufferp,
307 	__in			size_t buffer_size
308 	);
309 
310 	__checkReturn		efx_rc_t
311 efx_lic_v3_finish_partition(
312 	__in			efx_nic_t *enp,
313 	__in_bcount(buffer_size)
314 				caddr_t bufferp,
315 	__in			size_t buffer_size
316 	);
317 
318 static const efx_lic_ops_t	__efx_lic_v3_ops = {
319 	efx_mcdi_licensing_v3_update_licenses,	/* elo_update_licenses */
320 	efx_mcdi_licensing_v3_report_license,	/* elo_get_key_stats */
321 	efx_mcdi_licensing_v3_app_state,	/* elo_app_state */
322 	efx_mcdi_licensing_v3_get_id,		/* elo_get_id */
323 	efx_lic_v3_find_start,			/* elo_find_start*/
324 	efx_lic_v3_find_end,			/* elo_find_end */
325 	efx_lic_v3_find_key,			/* elo_find_key */
326 	efx_lic_v3_validate_key,		/* elo_validate_key */
327 	efx_lic_v3_read_key,			/* elo_read_key */
328 	efx_lic_v3_write_key,			/* elo_write_key */
329 	efx_lic_v3_delete_key,			/* elo_delete_key */
330 	efx_lic_v3_create_partition,		/* elo_create_partition */
331 	efx_lic_v3_finish_partition,		/* elo_finish_partition */
332 };
333 
334 #endif	/* EFSYS_OPT_MEDFORD */
335 
336 
337 /* V1 Licensing - used in Siena Modena only */
338 
339 #if EFSYS_OPT_SIENA
340 
341 static	__checkReturn	efx_rc_t
efx_mcdi_fc_license_update_license(__in efx_nic_t * enp)342 efx_mcdi_fc_license_update_license(
343 	__in		efx_nic_t *enp)
344 {
345 	efx_mcdi_req_t req;
346 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FC_IN_LICENSE_LEN, 0);
347 	efx_rc_t rc;
348 
349 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
350 
351 	req.emr_cmd = MC_CMD_FC;
352 	req.emr_in_buf = payload;
353 	req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN;
354 	req.emr_out_buf = payload;
355 	req.emr_out_length = 0;
356 
357 	MCDI_IN_SET_DWORD(req, FC_IN_CMD,
358 	    MC_CMD_FC_OP_LICENSE);
359 
360 	MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP,
361 	    MC_CMD_FC_IN_LICENSE_UPDATE_LICENSE);
362 
363 	efx_mcdi_execute(enp, &req);
364 
365 	if (req.emr_rc != 0) {
366 		rc = req.emr_rc;
367 		goto fail1;
368 	}
369 
370 	if (req.emr_out_length_used != 0) {
371 		rc = EIO;
372 		goto fail2;
373 	}
374 
375 	return (0);
376 
377 fail2:
378 	EFSYS_PROBE(fail2);
379 fail1:
380 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
381 
382 	return (rc);
383 }
384 
385 static	__checkReturn	efx_rc_t
efx_mcdi_fc_license_get_key_stats(__in efx_nic_t * enp,__out efx_key_stats_t * eksp)386 efx_mcdi_fc_license_get_key_stats(
387 	__in		efx_nic_t *enp,
388 	__out		efx_key_stats_t *eksp)
389 {
390 	efx_mcdi_req_t req;
391 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FC_IN_LICENSE_LEN,
392 		MC_CMD_FC_OUT_LICENSE_LEN);
393 	efx_rc_t rc;
394 
395 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
396 
397 	req.emr_cmd = MC_CMD_FC;
398 	req.emr_in_buf = payload;
399 	req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN;
400 	req.emr_out_buf = payload;
401 	req.emr_out_length = MC_CMD_FC_OUT_LICENSE_LEN;
402 
403 	MCDI_IN_SET_DWORD(req, FC_IN_CMD,
404 	    MC_CMD_FC_OP_LICENSE);
405 
406 	MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP,
407 	    MC_CMD_FC_IN_LICENSE_GET_KEY_STATS);
408 
409 	efx_mcdi_execute_quiet(enp, &req);
410 
411 	if (req.emr_rc != 0) {
412 		rc = req.emr_rc;
413 		goto fail1;
414 	}
415 
416 	if (req.emr_out_length_used < MC_CMD_FC_OUT_LICENSE_LEN) {
417 		rc = EMSGSIZE;
418 		goto fail2;
419 	}
420 
421 	eksp->eks_valid =
422 		MCDI_OUT_DWORD(req, FC_OUT_LICENSE_VALID_KEYS);
423 	eksp->eks_invalid =
424 		MCDI_OUT_DWORD(req, FC_OUT_LICENSE_INVALID_KEYS);
425 	eksp->eks_blacklisted =
426 		MCDI_OUT_DWORD(req, FC_OUT_LICENSE_BLACKLISTED_KEYS);
427 	eksp->eks_unverifiable = 0;
428 	eksp->eks_wrong_node = 0;
429 	eksp->eks_licensed_apps_lo = 0;
430 	eksp->eks_licensed_apps_hi = 0;
431 	eksp->eks_licensed_features_lo = 0;
432 	eksp->eks_licensed_features_hi = 0;
433 
434 	return (0);
435 
436 fail2:
437 	EFSYS_PROBE(fail2);
438 fail1:
439 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
440 
441 	return (rc);
442 }
443 
444 #endif	/* EFSYS_OPT_SIENA */
445 
446 /* V1 and V2 Partition format - based on a 16-bit TLV format */
447 
448 #if EFSYS_OPT_SIENA | EFSYS_OPT_HUNTINGTON
449 
450 /*
451  * V1/V2 format - defined in SF-108542-TC section 4.2:
452  *  Type (T):   16bit - revision/HMAC algorithm
453  *  Length (L): 16bit - value length in bytes
454  *  Value (V):  L bytes - payload
455  */
456 #define EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX    (256)
457 #define EFX_LICENSE_V1V2_HEADER_LENGTH         (2 * sizeof(uint16_t))
458 
459 	__checkReturn		efx_rc_t
efx_lic_v1v2_find_start(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__out uint32_t * startp)460 efx_lic_v1v2_find_start(
461 	__in			efx_nic_t *enp,
462 	__in_bcount(buffer_size)
463 				caddr_t bufferp,
464 	__in			size_t buffer_size,
465 	__out			uint32_t *startp
466 	)
467 {
468 	_NOTE(ARGUNUSED(enp, bufferp, buffer_size))
469 
470 	*startp = 0;
471 	return (0);
472 }
473 
474 	__checkReturn		efx_rc_t
efx_lic_v1v2_find_end(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__out uint32_t * endp)475 efx_lic_v1v2_find_end(
476 	__in			efx_nic_t *enp,
477 	__in_bcount(buffer_size)
478 				caddr_t bufferp,
479 	__in			size_t buffer_size,
480 	__in			uint32_t offset,
481 	__out			uint32_t *endp
482 	)
483 {
484 	_NOTE(ARGUNUSED(enp, bufferp, buffer_size))
485 
486 	*endp = offset + EFX_LICENSE_V1V2_HEADER_LENGTH;
487 	return (0);
488 }
489 
490 	__checkReturn	__success(return != B_FALSE)	boolean_t
efx_lic_v1v2_find_key(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__out uint32_t * startp,__out uint32_t * lengthp)491 efx_lic_v1v2_find_key(
492 	__in			efx_nic_t *enp,
493 	__in_bcount(buffer_size)
494 				caddr_t bufferp,
495 	__in			size_t buffer_size,
496 	__in			uint32_t offset,
497 	__out			uint32_t *startp,
498 	__out			uint32_t *lengthp
499 	)
500 {
501 	boolean_t found;
502 	uint16_t tlv_type;
503 	uint16_t tlv_length;
504 
505 	_NOTE(ARGUNUSED(enp))
506 
507 	if ((size_t)buffer_size - offset < EFX_LICENSE_V1V2_HEADER_LENGTH)
508 		goto fail1;
509 
510 	tlv_type = __LE_TO_CPU_16(((uint16_t *)&bufferp[offset])[0]);
511 	tlv_length = __LE_TO_CPU_16(((uint16_t *)&bufferp[offset])[1]);
512 	if ((tlv_length > EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX) ||
513 	    (tlv_type == 0 && tlv_length == 0)) {
514 		found = B_FALSE;
515 	} else {
516 		*startp = offset;
517 		*lengthp = tlv_length + EFX_LICENSE_V1V2_HEADER_LENGTH;
518 		found = B_TRUE;
519 	}
520 	return (found);
521 
522 fail1:
523 	EFSYS_PROBE1(fail1, boolean_t, B_FALSE);
524 
525 	return (B_FALSE);
526 }
527 
528 	__checkReturn	__success(return != B_FALSE)	boolean_t
efx_lic_v1v2_validate_key(__in efx_nic_t * enp,__in_bcount (length)caddr_t keyp,__in uint32_t length)529 efx_lic_v1v2_validate_key(
530 	__in			efx_nic_t *enp,
531 	__in_bcount(length)	caddr_t keyp,
532 	__in			uint32_t length
533 	)
534 {
535 	uint16_t tlv_type;
536 	uint16_t tlv_length;
537 
538 	_NOTE(ARGUNUSED(enp))
539 
540 	if (length < EFX_LICENSE_V1V2_HEADER_LENGTH) {
541 		goto fail1;
542 	}
543 
544 	tlv_type = __LE_TO_CPU_16(((uint16_t *)keyp)[0]);
545 	tlv_length = __LE_TO_CPU_16(((uint16_t *)keyp)[1]);
546 
547 	if (tlv_length > EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX) {
548 		goto fail2;
549 	}
550 	if (tlv_type == 0) {
551 		goto fail3;
552 	}
553 	if ((tlv_length + EFX_LICENSE_V1V2_HEADER_LENGTH) != length) {
554 		goto fail4;
555 	}
556 
557 	return (B_TRUE);
558 
559 fail4:
560 	EFSYS_PROBE(fail4);
561 fail3:
562 	EFSYS_PROBE(fail3);
563 fail2:
564 	EFSYS_PROBE(fail2);
565 fail1:
566 	EFSYS_PROBE1(fail1, boolean_t, B_FALSE);
567 
568 	return (B_FALSE);
569 }
570 
571 
572 	__checkReturn		efx_rc_t
efx_lic_v1v2_read_key(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__in uint32_t length,__out_bcount_part (key_max_size,* lengthp)caddr_t keyp,__in size_t key_max_size,__out uint32_t * lengthp)573 efx_lic_v1v2_read_key(
574 	__in			efx_nic_t *enp,
575 	__in_bcount(buffer_size)
576 				caddr_t bufferp,
577 	__in			size_t buffer_size,
578 	__in			uint32_t offset,
579 	__in			uint32_t length,
580 	__out_bcount_part(key_max_size, *lengthp)
581 				caddr_t keyp,
582 	__in			size_t key_max_size,
583 	__out			uint32_t *lengthp
584 	)
585 {
586 	efx_rc_t rc;
587 
588 	_NOTE(ARGUNUSED(enp, buffer_size))
589 	EFSYS_ASSERT(length <= (EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX +
590 	    EFX_LICENSE_V1V2_HEADER_LENGTH));
591 
592 	if (key_max_size < length) {
593 		rc = ENOSPC;
594 		goto fail1;
595 	}
596 	memcpy(keyp, &bufferp[offset], length);
597 
598 	*lengthp = length;
599 
600 	return (0);
601 
602 fail1:
603 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
604 
605 	return (rc);
606 }
607 
608 	__checkReturn		efx_rc_t
efx_lic_v1v2_write_key(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__in_bcount (length)caddr_t keyp,__in uint32_t length,__out uint32_t * lengthp)609 efx_lic_v1v2_write_key(
610 	__in			efx_nic_t *enp,
611 	__in_bcount(buffer_size)
612 				caddr_t bufferp,
613 	__in			size_t buffer_size,
614 	__in			uint32_t offset,
615 	__in_bcount(length)	caddr_t keyp,
616 	__in			uint32_t length,
617 	__out			uint32_t *lengthp
618 	)
619 {
620 	efx_rc_t rc;
621 
622 	_NOTE(ARGUNUSED(enp))
623 	EFSYS_ASSERT(length <= (EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX +
624 	    EFX_LICENSE_V1V2_HEADER_LENGTH));
625 
626 	/* Ensure space for terminator remains */
627 	if ((offset + length) >
628 	    (buffer_size - EFX_LICENSE_V1V2_HEADER_LENGTH)) {
629 		rc = ENOSPC;
630 		goto fail1;
631 	}
632 
633 	memcpy(bufferp + offset, keyp, length);
634 
635 	*lengthp = length;
636 
637 	return (0);
638 
639 fail1:
640 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
641 
642 	return (rc);
643 }
644 
645 	__checkReturn		efx_rc_t
efx_lic_v1v2_delete_key(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__in uint32_t length,__in uint32_t end,__out uint32_t * deltap)646 efx_lic_v1v2_delete_key(
647 	__in			efx_nic_t *enp,
648 	__in_bcount(buffer_size)
649 				caddr_t bufferp,
650 	__in			size_t buffer_size,
651 	__in			uint32_t offset,
652 	__in			uint32_t length,
653 	__in			uint32_t end,
654 	__out			uint32_t *deltap
655 	)
656 {
657 	uint32_t move_start = offset + length;
658 	uint32_t move_length = end - move_start;
659 
660 	_NOTE(ARGUNUSED(enp, buffer_size))
661 	EFSYS_ASSERT(end <= buffer_size);
662 
663 	/* Shift everything after the key down */
664 	memmove(bufferp + offset, bufferp + move_start, move_length);
665 
666 	*deltap = length;
667 
668 	return (0);
669 }
670 
671 	__checkReturn		efx_rc_t
efx_lic_v1v2_create_partition(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size)672 efx_lic_v1v2_create_partition(
673 	__in			efx_nic_t *enp,
674 	__in_bcount(buffer_size)
675 				caddr_t bufferp,
676 	__in			size_t buffer_size
677 	)
678 {
679 	_NOTE(ARGUNUSED(enp, buffer_size))
680 	EFSYS_ASSERT(EFX_LICENSE_V1V2_HEADER_LENGTH <= buffer_size);
681 
682 	/* Write terminator */
683 	memset(bufferp, '\0', EFX_LICENSE_V1V2_HEADER_LENGTH);
684 	return (0);
685 }
686 
687 
688 	__checkReturn		efx_rc_t
efx_lic_v1v2_finish_partition(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size)689 efx_lic_v1v2_finish_partition(
690 	__in			efx_nic_t *enp,
691 	__in_bcount(buffer_size)
692 				caddr_t bufferp,
693 	__in			size_t buffer_size
694 	)
695 {
696 	_NOTE(ARGUNUSED(enp, bufferp, buffer_size))
697 
698 	return (0);
699 }
700 
701 #endif	/* EFSYS_OPT_HUNTINGTON | EFSYS_OPT_SIENA */
702 
703 
704 /* V2 Licensing - used by Huntington family only. See SF-113611-TC */
705 
706 #if EFSYS_OPT_HUNTINGTON
707 
708 static	__checkReturn	efx_rc_t
efx_mcdi_licensed_app_state(__in efx_nic_t * enp,__in uint64_t app_id,__out boolean_t * licensedp)709 efx_mcdi_licensed_app_state(
710 	__in		efx_nic_t *enp,
711 	__in		uint64_t app_id,
712 	__out		boolean_t *licensedp)
713 {
714 	efx_mcdi_req_t req;
715 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LICENSED_APP_STATE_IN_LEN,
716 		MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN);
717 	uint32_t app_state;
718 	efx_rc_t rc;
719 
720 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
721 
722 	/* V2 licensing supports 32bit app id only */
723 	if ((app_id >> 32) != 0) {
724 		rc = EINVAL;
725 		goto fail1;
726 	}
727 
728 	req.emr_cmd = MC_CMD_GET_LICENSED_APP_STATE;
729 	req.emr_in_buf = payload;
730 	req.emr_in_length = MC_CMD_GET_LICENSED_APP_STATE_IN_LEN;
731 	req.emr_out_buf = payload;
732 	req.emr_out_length = MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN;
733 
734 	MCDI_IN_SET_DWORD(req, GET_LICENSED_APP_STATE_IN_APP_ID,
735 		    app_id & 0xffffffff);
736 
737 	efx_mcdi_execute(enp, &req);
738 
739 	if (req.emr_rc != 0) {
740 		rc = req.emr_rc;
741 		goto fail2;
742 	}
743 
744 	if (req.emr_out_length_used < MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN) {
745 		rc = EMSGSIZE;
746 		goto fail3;
747 	}
748 
749 	app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_APP_STATE_OUT_STATE));
750 	if (app_state != MC_CMD_GET_LICENSED_APP_STATE_OUT_NOT_LICENSED) {
751 		*licensedp = B_TRUE;
752 	} else {
753 		*licensedp = B_FALSE;
754 	}
755 
756 	return (0);
757 
758 fail3:
759 	EFSYS_PROBE(fail3);
760 fail2:
761 	EFSYS_PROBE(fail2);
762 fail1:
763 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
764 
765 	return (rc);
766 }
767 
768 static	__checkReturn	efx_rc_t
efx_mcdi_licensing_update_licenses(__in efx_nic_t * enp)769 efx_mcdi_licensing_update_licenses(
770 	__in		efx_nic_t *enp)
771 {
772 	efx_mcdi_req_t req;
773 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_IN_LEN, 0);
774 	efx_rc_t rc;
775 
776 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
777 
778 	req.emr_cmd = MC_CMD_LICENSING;
779 	req.emr_in_buf = payload;
780 	req.emr_in_length = MC_CMD_LICENSING_IN_LEN;
781 	req.emr_out_buf = payload;
782 	req.emr_out_length = 0;
783 
784 	MCDI_IN_SET_DWORD(req, LICENSING_IN_OP,
785 	    MC_CMD_LICENSING_IN_OP_UPDATE_LICENSE);
786 
787 	efx_mcdi_execute(enp, &req);
788 
789 	if (req.emr_rc != 0) {
790 		rc = req.emr_rc;
791 		goto fail1;
792 	}
793 
794 	if (req.emr_out_length_used != 0) {
795 		rc = EIO;
796 		goto fail2;
797 	}
798 
799 	return (0);
800 
801 fail2:
802 	EFSYS_PROBE(fail2);
803 fail1:
804 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
805 
806 	return (rc);
807 }
808 
809 static	__checkReturn	efx_rc_t
efx_mcdi_licensing_get_key_stats(__in efx_nic_t * enp,__out efx_key_stats_t * eksp)810 efx_mcdi_licensing_get_key_stats(
811 	__in		efx_nic_t *enp,
812 	__out		efx_key_stats_t *eksp)
813 {
814 	efx_mcdi_req_t req;
815 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_IN_LEN,
816 		MC_CMD_LICENSING_OUT_LEN);
817 	efx_rc_t rc;
818 
819 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
820 
821 	req.emr_cmd = MC_CMD_LICENSING;
822 	req.emr_in_buf = payload;
823 	req.emr_in_length = MC_CMD_LICENSING_IN_LEN;
824 	req.emr_out_buf = payload;
825 	req.emr_out_length = MC_CMD_LICENSING_OUT_LEN;
826 
827 	MCDI_IN_SET_DWORD(req, LICENSING_IN_OP,
828 	    MC_CMD_LICENSING_IN_OP_GET_KEY_STATS);
829 
830 	efx_mcdi_execute(enp, &req);
831 
832 	if (req.emr_rc != 0) {
833 		rc = req.emr_rc;
834 		goto fail1;
835 	}
836 
837 	if (req.emr_out_length_used < MC_CMD_LICENSING_OUT_LEN) {
838 		rc = EMSGSIZE;
839 		goto fail2;
840 	}
841 
842 	eksp->eks_valid =
843 		MCDI_OUT_DWORD(req, LICENSING_OUT_VALID_APP_KEYS);
844 	eksp->eks_invalid =
845 		MCDI_OUT_DWORD(req, LICENSING_OUT_INVALID_APP_KEYS);
846 	eksp->eks_blacklisted =
847 		MCDI_OUT_DWORD(req, LICENSING_OUT_BLACKLISTED_APP_KEYS);
848 	eksp->eks_unverifiable =
849 		MCDI_OUT_DWORD(req, LICENSING_OUT_UNVERIFIABLE_APP_KEYS);
850 	eksp->eks_wrong_node =
851 		MCDI_OUT_DWORD(req, LICENSING_OUT_WRONG_NODE_APP_KEYS);
852 	eksp->eks_licensed_apps_lo = 0;
853 	eksp->eks_licensed_apps_hi = 0;
854 	eksp->eks_licensed_features_lo = 0;
855 	eksp->eks_licensed_features_hi = 0;
856 
857 	return (0);
858 
859 fail2:
860 	EFSYS_PROBE(fail2);
861 fail1:
862 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
863 
864 	return (rc);
865 }
866 
867 #endif	/* EFSYS_OPT_HUNTINGTON */
868 
869 /* V3 Licensing - used starting from Medford family. See SF-114884-SW */
870 
871 #if EFSYS_OPT_MEDFORD
872 
873 static	__checkReturn	efx_rc_t
efx_mcdi_licensing_v3_update_licenses(__in efx_nic_t * enp)874 efx_mcdi_licensing_v3_update_licenses(
875 	__in		efx_nic_t *enp)
876 {
877 	efx_mcdi_req_t req;
878 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_V3_IN_LEN, 0);
879 	efx_rc_t rc;
880 
881 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD);
882 
883 	req.emr_cmd = MC_CMD_LICENSING_V3;
884 	req.emr_in_buf = payload;
885 	req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN;
886 	req.emr_out_buf = NULL;
887 	req.emr_out_length = 0;
888 
889 	MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP,
890 	    MC_CMD_LICENSING_V3_IN_OP_UPDATE_LICENSE);
891 
892 	efx_mcdi_execute(enp, &req);
893 
894 	if (req.emr_rc != 0) {
895 		rc = req.emr_rc;
896 		goto fail1;
897 	}
898 
899 	return (0);
900 
901 fail1:
902 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
903 
904 	return (rc);
905 }
906 
907 static	__checkReturn	efx_rc_t
efx_mcdi_licensing_v3_report_license(__in efx_nic_t * enp,__out efx_key_stats_t * eksp)908 efx_mcdi_licensing_v3_report_license(
909 	__in		efx_nic_t *enp,
910 	__out		efx_key_stats_t *eksp)
911 {
912 	efx_mcdi_req_t req;
913 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_V3_IN_LEN,
914 		MC_CMD_LICENSING_V3_OUT_LEN);
915 	efx_rc_t rc;
916 
917 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD);
918 
919 	req.emr_cmd = MC_CMD_LICENSING_V3;
920 	req.emr_in_buf = payload;
921 	req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN;
922 	req.emr_out_buf = payload;
923 	req.emr_out_length = MC_CMD_LICENSING_V3_OUT_LEN;
924 
925 	MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP,
926 	    MC_CMD_LICENSING_V3_IN_OP_REPORT_LICENSE);
927 
928 	efx_mcdi_execute_quiet(enp, &req);
929 
930 	if (req.emr_rc != 0) {
931 		rc = req.emr_rc;
932 		goto fail1;
933 	}
934 
935 	if (req.emr_out_length_used < MC_CMD_LICENSING_V3_OUT_LEN) {
936 		rc = EMSGSIZE;
937 		goto fail2;
938 	}
939 
940 	eksp->eks_valid =
941 		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_VALID_KEYS);
942 	eksp->eks_invalid =
943 		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_INVALID_KEYS);
944 	eksp->eks_blacklisted = 0;
945 	eksp->eks_unverifiable =
946 		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_UNVERIFIABLE_KEYS);
947 	eksp->eks_wrong_node =
948 		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_WRONG_NODE_KEYS);
949 	eksp->eks_licensed_apps_lo =
950 		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_LO);
951 	eksp->eks_licensed_apps_hi =
952 		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_HI);
953 	eksp->eks_licensed_features_lo =
954 		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_LO);
955 	eksp->eks_licensed_features_hi =
956 		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_HI);
957 
958 	return (0);
959 
960 fail2:
961 	EFSYS_PROBE(fail2);
962 fail1:
963 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
964 
965 	return (rc);
966 }
967 
968 static	__checkReturn	efx_rc_t
efx_mcdi_licensing_v3_app_state(__in efx_nic_t * enp,__in uint64_t app_id,__out boolean_t * licensedp)969 efx_mcdi_licensing_v3_app_state(
970 	__in		efx_nic_t *enp,
971 	__in		uint64_t app_id,
972 	__out		boolean_t *licensedp)
973 {
974 	efx_mcdi_req_t req;
975 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN,
976 		MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN);
977 	uint32_t app_state;
978 	efx_rc_t rc;
979 
980 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD);
981 
982 	req.emr_cmd = MC_CMD_GET_LICENSED_V3_APP_STATE;
983 	req.emr_in_buf = payload;
984 	req.emr_in_length = MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN;
985 	req.emr_out_buf = payload;
986 	req.emr_out_length = MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN;
987 
988 	MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_LO,
989 		    app_id & 0xffffffff);
990 	MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_HI,
991 		    app_id >> 32);
992 
993 	efx_mcdi_execute(enp, &req);
994 
995 	if (req.emr_rc != 0) {
996 		rc = req.emr_rc;
997 		goto fail1;
998 	}
999 
1000 	if (req.emr_out_length_used < MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN) {
1001 		rc = EMSGSIZE;
1002 		goto fail2;
1003 	}
1004 
1005 	app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_V3_APP_STATE_OUT_STATE));
1006 	if (app_state != MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_NOT_LICENSED) {
1007 		*licensedp = B_TRUE;
1008 	} else {
1009 		*licensedp = B_FALSE;
1010 	}
1011 
1012 	return (0);
1013 
1014 fail2:
1015 	EFSYS_PROBE(fail2);
1016 fail1:
1017 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1018 
1019 	return (rc);
1020 }
1021 
1022 static	__checkReturn	efx_rc_t
efx_mcdi_licensing_v3_get_id(__in efx_nic_t * enp,__in size_t buffer_size,__out uint32_t * typep,__out size_t * lengthp,__out_bcount_part_opt (buffer_size,* lengthp)uint8_t * bufferp)1023 efx_mcdi_licensing_v3_get_id(
1024 	__in		efx_nic_t *enp,
1025 	__in		size_t buffer_size,
1026 	__out		uint32_t *typep,
1027 	__out		size_t *lengthp,
1028 	__out_bcount_part_opt(buffer_size, *lengthp)
1029 			uint8_t *bufferp)
1030 {
1031 	efx_mcdi_req_t req;
1032 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_GET_ID_V3_IN_LEN,
1033 		MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN);
1034 	efx_rc_t rc;
1035 
1036 	req.emr_cmd = MC_CMD_LICENSING_GET_ID_V3;
1037 
1038 	if (bufferp == NULL) {
1039 		/* Request id type and length only */
1040 		req.emr_in_buf = bufferp;
1041 		req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN;
1042 		req.emr_out_buf = bufferp;
1043 		req.emr_out_length = MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN;
1044 	} else {
1045 		/* Request full buffer */
1046 		req.emr_in_buf = bufferp;
1047 		req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN;
1048 		req.emr_out_buf = bufferp;
1049 		req.emr_out_length = MIN(buffer_size, MC_CMD_LICENSING_GET_ID_V3_OUT_LENMAX);
1050 		(void) memset(bufferp, 0, req.emr_out_length);
1051 	}
1052 
1053 	efx_mcdi_execute_quiet(enp, &req);
1054 
1055 	if (req.emr_rc != 0) {
1056 		rc = req.emr_rc;
1057 		goto fail1;
1058 	}
1059 
1060 	if (req.emr_out_length_used < MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN) {
1061 		rc = EMSGSIZE;
1062 		goto fail2;
1063 	}
1064 
1065 	*typep = MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_TYPE);
1066 	*lengthp = MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_ID_LENGTH);
1067 
1068 	if (bufferp == NULL) {
1069 		/* modify length requirements to indicate to caller the extra buffering
1070 		** needed to read the complete output.
1071 		*/
1072 		*lengthp += MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN;
1073 	} else {
1074 		/* Shift ID down to start of buffer */
1075 		memmove(bufferp,
1076 		    bufferp + MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST,
1077 		    *lengthp);
1078 		memset(bufferp + (*lengthp), 0,
1079 		    MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST);
1080 	}
1081 
1082 	return (0);
1083 
1084 fail2:
1085 	EFSYS_PROBE(fail2);
1086 fail1:
1087 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1088 
1089 	return (rc);
1090 }
1091 
1092 /* V3 format uses Huntington TLV format partition. See SF-108797-SW */
1093 #define EFX_LICENSE_V3_KEY_LENGTH_MIN    (64)
1094 #define EFX_LICENSE_V3_KEY_LENGTH_MAX    (160)
1095 
1096 	__checkReturn		efx_rc_t
efx_lic_v3_find_start(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__out uint32_t * startp)1097 efx_lic_v3_find_start(
1098 	__in			efx_nic_t *enp,
1099 	__in_bcount(buffer_size)
1100 				caddr_t bufferp,
1101 	__in			size_t buffer_size,
1102 	__out			uint32_t *startp
1103 	)
1104 {
1105 	_NOTE(ARGUNUSED(enp))
1106 
1107 	return ef10_nvram_buffer_find_item_start(bufferp, buffer_size, startp);
1108 }
1109 
1110 	__checkReturn		efx_rc_t
efx_lic_v3_find_end(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__out uint32_t * endp)1111 efx_lic_v3_find_end(
1112 	__in			efx_nic_t *enp,
1113 	__in_bcount(buffer_size)
1114 				caddr_t bufferp,
1115 	__in			size_t buffer_size,
1116 	__in			uint32_t offset,
1117 	__out			uint32_t *endp
1118 	)
1119 {
1120 	_NOTE(ARGUNUSED(enp))
1121 
1122 	return ef10_nvram_buffer_find_end(bufferp, buffer_size, offset, endp);
1123 }
1124 
1125 	__checkReturn	__success(return != B_FALSE)	boolean_t
efx_lic_v3_find_key(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__out uint32_t * startp,__out uint32_t * lengthp)1126 efx_lic_v3_find_key(
1127 	__in			efx_nic_t *enp,
1128 	__in_bcount(buffer_size)
1129 				caddr_t bufferp,
1130 	__in			size_t buffer_size,
1131 	__in			uint32_t offset,
1132 	__out			uint32_t *startp,
1133 	__out			uint32_t *lengthp
1134 	)
1135 {
1136 	_NOTE(ARGUNUSED(enp))
1137 
1138 	return ef10_nvram_buffer_find_item(bufferp, buffer_size,
1139 	    offset, startp, lengthp);
1140 }
1141 
1142 	__checkReturn	__success(return != B_FALSE)	boolean_t
efx_lic_v3_validate_key(__in efx_nic_t * enp,__in_bcount (length)caddr_t keyp,__in uint32_t length)1143 efx_lic_v3_validate_key(
1144 	__in			efx_nic_t *enp,
1145 	__in_bcount(length)	caddr_t keyp,
1146 	__in			uint32_t length
1147 	)
1148 {
1149 	/* Check key is a valid V3 key */
1150 	uint8_t key_type;
1151 	uint8_t key_length;
1152 
1153 	_NOTE(ARGUNUSED(enp))
1154 
1155 	if (length < EFX_LICENSE_V3_KEY_LENGTH_MIN) {
1156 		goto fail1;
1157 	}
1158 
1159 	if (length > EFX_LICENSE_V3_KEY_LENGTH_MAX) {
1160 		goto fail2;
1161 	}
1162 
1163 	key_type = ((uint8_t *)keyp)[0];
1164 	key_length = ((uint8_t *)keyp)[1];
1165 
1166 	if (key_type < 3) {
1167 		goto fail3;
1168 	}
1169 	if (key_length > length) {
1170 		goto fail4;
1171 	}
1172 	return (B_TRUE);
1173 
1174 fail4:
1175 	EFSYS_PROBE(fail4);
1176 fail3:
1177 	EFSYS_PROBE(fail3);
1178 fail2:
1179 	EFSYS_PROBE(fail2);
1180 fail1:
1181 	EFSYS_PROBE1(fail1, boolean_t, B_FALSE);
1182 
1183 	return (B_FALSE);
1184 }
1185 
1186 	__checkReturn		efx_rc_t
efx_lic_v3_read_key(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__in uint32_t length,__out_bcount_part (key_max_size,* lengthp)caddr_t keyp,__in size_t key_max_size,__out uint32_t * lengthp)1187 efx_lic_v3_read_key(
1188 	__in			efx_nic_t *enp,
1189 	__in_bcount(buffer_size)
1190 				caddr_t bufferp,
1191 	__in			size_t buffer_size,
1192 	__in			uint32_t offset,
1193 	__in			uint32_t length,
1194 	__out_bcount_part(key_max_size, *lengthp)
1195 				caddr_t keyp,
1196 	__in			size_t key_max_size,
1197 	__out			uint32_t *lengthp
1198 	)
1199 {
1200 	_NOTE(ARGUNUSED(enp))
1201 
1202 	return ef10_nvram_buffer_get_item(bufferp, buffer_size,
1203 		    offset, length, keyp, key_max_size, lengthp);
1204 }
1205 
1206 	__checkReturn		efx_rc_t
efx_lic_v3_write_key(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__in_bcount (length)caddr_t keyp,__in uint32_t length,__out uint32_t * lengthp)1207 efx_lic_v3_write_key(
1208 	__in			efx_nic_t *enp,
1209 	__in_bcount(buffer_size)
1210 				caddr_t bufferp,
1211 	__in			size_t buffer_size,
1212 	__in			uint32_t offset,
1213 	__in_bcount(length)	caddr_t keyp,
1214 	__in			uint32_t length,
1215 	__out			uint32_t *lengthp
1216 	)
1217 {
1218 	_NOTE(ARGUNUSED(enp))
1219 	EFSYS_ASSERT(length <= EFX_LICENSE_V3_KEY_LENGTH_MAX);
1220 
1221 	return ef10_nvram_buffer_insert_item(bufferp, buffer_size,
1222 		    offset, keyp, length, lengthp);
1223 }
1224 
1225 	__checkReturn		efx_rc_t
efx_lic_v3_delete_key(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__in uint32_t length,__in uint32_t end,__out uint32_t * deltap)1226 efx_lic_v3_delete_key(
1227 	__in			efx_nic_t *enp,
1228 	__in_bcount(buffer_size)
1229 				caddr_t bufferp,
1230 	__in			size_t buffer_size,
1231 	__in			uint32_t offset,
1232 	__in			uint32_t length,
1233 	__in			uint32_t end,
1234 	__out			uint32_t *deltap
1235 	)
1236 {
1237 	efx_rc_t rc;
1238 
1239 	_NOTE(ARGUNUSED(enp))
1240 
1241 	if ((rc = ef10_nvram_buffer_delete_item(bufferp,
1242 			buffer_size, offset, length, end)) != 0) {
1243 		goto fail1;
1244 	}
1245 
1246 	*deltap = length;
1247 
1248 	return (0);
1249 
1250 fail1:
1251 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1252 
1253 	return (rc);
1254 }
1255 
1256 	__checkReturn		efx_rc_t
efx_lic_v3_create_partition(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size)1257 efx_lic_v3_create_partition(
1258 	__in			efx_nic_t *enp,
1259 	__in_bcount(buffer_size)
1260 				caddr_t bufferp,
1261 	__in			size_t buffer_size
1262 	)
1263 {
1264 	efx_rc_t rc;
1265 
1266 	/* Construct empty partition */
1267 	if ((rc = ef10_nvram_buffer_create(enp,
1268 	    NVRAM_PARTITION_TYPE_LICENSE,
1269 	    bufferp, buffer_size)) != 0) {
1270 		rc = EFAULT;
1271 		goto fail1;
1272 	}
1273 
1274 	return (0);
1275 
1276 fail1:
1277 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1278 
1279 	return (rc);
1280 }
1281 
1282 	__checkReturn		efx_rc_t
efx_lic_v3_finish_partition(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size)1283 efx_lic_v3_finish_partition(
1284 	__in			efx_nic_t *enp,
1285 	__in_bcount(buffer_size)
1286 				caddr_t bufferp,
1287 	__in			size_t buffer_size
1288 	)
1289 {
1290 	efx_rc_t rc;
1291 
1292 	if ((rc = ef10_nvram_buffer_finish(bufferp,
1293 			buffer_size)) != 0) {
1294 		goto fail1;
1295 	}
1296 
1297 	/* Validate completed partition */
1298 	if ((rc = ef10_nvram_buffer_validate(enp, NVRAM_PARTITION_TYPE_LICENSE,
1299 					bufferp, buffer_size)) != 0) {
1300 		goto fail2;
1301 	}
1302 
1303 	return (0);
1304 
1305 fail2:
1306 	EFSYS_PROBE(fail2);
1307 fail1:
1308 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1309 
1310 	return (rc);
1311 }
1312 
1313 
1314 #endif	/* EFSYS_OPT_MEDFORD */
1315 
1316 	__checkReturn		efx_rc_t
efx_lic_init(__in efx_nic_t * enp)1317 efx_lic_init(
1318 	__in			efx_nic_t *enp)
1319 {
1320 	const efx_lic_ops_t *elop;
1321 	efx_key_stats_t eks;
1322 	efx_rc_t rc;
1323 
1324 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1325 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
1326 	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_LIC));
1327 
1328 	switch (enp->en_family) {
1329 
1330 #if EFSYS_OPT_SIENA
1331 	case EFX_FAMILY_SIENA:
1332 		elop = &__efx_lic_v1_ops;
1333 		break;
1334 #endif	/* EFSYS_OPT_SIENA */
1335 
1336 #if EFSYS_OPT_HUNTINGTON
1337 	case EFX_FAMILY_HUNTINGTON:
1338 		elop = &__efx_lic_v2_ops;
1339 		break;
1340 #endif	/* EFSYS_OPT_HUNTINGTON */
1341 
1342 #if EFSYS_OPT_MEDFORD
1343 	case EFX_FAMILY_MEDFORD:
1344 		elop = &__efx_lic_v3_ops;
1345 		break;
1346 #endif	/* EFSYS_OPT_MEDFORD */
1347 
1348 	default:
1349 		EFSYS_ASSERT(0);
1350 		rc = ENOTSUP;
1351 		goto fail1;
1352 	}
1353 
1354 	enp->en_elop = elop;
1355 	enp->en_mod_flags |= EFX_MOD_LIC;
1356 
1357 	/* Probe for support */
1358 	if (efx_lic_get_key_stats(enp, &eks) == 0) {
1359 		enp->en_licensing_supported = B_TRUE;
1360 	} else {
1361 		enp->en_licensing_supported = B_FALSE;
1362 	}
1363 
1364 	return (0);
1365 
1366 fail1:
1367 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1368 
1369 	return (rc);
1370 }
1371 
1372 extern	__checkReturn	boolean_t
efx_lic_check_support(__in efx_nic_t * enp)1373 efx_lic_check_support(
1374 	__in			efx_nic_t *enp)
1375 {
1376 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1377 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
1378 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1379 
1380 	return enp->en_licensing_supported;
1381 }
1382 
1383 				void
efx_lic_fini(__in efx_nic_t * enp)1384 efx_lic_fini(
1385 	__in			efx_nic_t *enp)
1386 {
1387 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1388 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
1389 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1390 
1391 	enp->en_elop = NULL;
1392 	enp->en_mod_flags &= ~EFX_MOD_LIC;
1393 }
1394 
1395 
1396 	__checkReturn	efx_rc_t
efx_lic_update_licenses(__in efx_nic_t * enp)1397 efx_lic_update_licenses(
1398 	__in		efx_nic_t *enp)
1399 {
1400 	const efx_lic_ops_t *elop = enp->en_elop;
1401 	efx_rc_t rc;
1402 
1403 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1404 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1405 
1406 	if ((rc = elop->elo_update_licenses(enp)) != 0)
1407 		goto fail1;
1408 
1409 	return (0);
1410 
1411 fail1:
1412 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1413 
1414 	return (rc);
1415 }
1416 
1417 	__checkReturn	efx_rc_t
efx_lic_get_key_stats(__in efx_nic_t * enp,__out efx_key_stats_t * eksp)1418 efx_lic_get_key_stats(
1419 	__in		efx_nic_t *enp,
1420 	__out		efx_key_stats_t *eksp)
1421 {
1422 	const efx_lic_ops_t *elop = enp->en_elop;
1423 	efx_rc_t rc;
1424 
1425 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1426 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1427 
1428 	if ((rc = elop->elo_get_key_stats(enp, eksp)) != 0)
1429 		goto fail1;
1430 
1431 	return (0);
1432 
1433 fail1:
1434 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1435 
1436 	return (rc);
1437 }
1438 
1439 	__checkReturn	efx_rc_t
efx_lic_app_state(__in efx_nic_t * enp,__in uint64_t app_id,__out boolean_t * licensedp)1440 efx_lic_app_state(
1441 	__in		efx_nic_t *enp,
1442 	__in		uint64_t app_id,
1443 	__out		boolean_t *licensedp)
1444 {
1445 	const efx_lic_ops_t *elop = enp->en_elop;
1446 	efx_rc_t rc;
1447 
1448 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1449 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1450 
1451 	if (elop->elo_app_state == NULL)
1452 		return (ENOTSUP);
1453 
1454 	if ((rc = elop->elo_app_state(enp, app_id, licensedp)) != 0)
1455 		goto fail1;
1456 
1457 	return (0);
1458 
1459 fail1:
1460 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1461 
1462 	return (rc);
1463 }
1464 
1465 	__checkReturn	efx_rc_t
efx_lic_get_id(__in efx_nic_t * enp,__in size_t buffer_size,__out uint32_t * typep,__out size_t * lengthp,__out_opt uint8_t * bufferp)1466 efx_lic_get_id(
1467 	__in		efx_nic_t *enp,
1468 	__in		size_t buffer_size,
1469 	__out		uint32_t *typep,
1470 	__out		size_t *lengthp,
1471 	__out_opt	uint8_t *bufferp
1472 	)
1473 {
1474 	const efx_lic_ops_t *elop = enp->en_elop;
1475 	efx_rc_t rc;
1476 
1477 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1478 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1479 
1480 	if (elop->elo_get_id == NULL)
1481 		return (ENOTSUP);
1482 
1483 	if ((rc = elop->elo_get_id(enp, buffer_size, typep,
1484 				    lengthp, bufferp)) != 0)
1485 		goto fail1;
1486 
1487 	return (0);
1488 
1489 fail1:
1490 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1491 
1492 	return (rc);
1493 }
1494 
1495 /* Buffer management API - abstracts varying TLV format used for License partition */
1496 
1497 	__checkReturn		efx_rc_t
efx_lic_find_start(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__out uint32_t * startp)1498 efx_lic_find_start(
1499 	__in			efx_nic_t *enp,
1500 	__in_bcount(buffer_size)
1501 				caddr_t bufferp,
1502 	__in			size_t buffer_size,
1503 	__out			uint32_t *startp
1504 	)
1505 {
1506 	const efx_lic_ops_t *elop = enp->en_elop;
1507 	efx_rc_t rc;
1508 
1509 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1510 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1511 
1512 	if ((rc = elop->elo_find_start(enp, bufferp, buffer_size, startp)) != 0)
1513 		goto fail1;
1514 
1515 	return (0);
1516 
1517 fail1:
1518 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1519 
1520 	return (rc);
1521 }
1522 
1523 	__checkReturn		efx_rc_t
efx_lic_find_end(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__out uint32_t * endp)1524 efx_lic_find_end(
1525 	__in			efx_nic_t *enp,
1526 	__in_bcount(buffer_size)
1527 				caddr_t bufferp,
1528 	__in			size_t buffer_size,
1529 	__in			uint32_t offset,
1530 	__out			uint32_t *endp
1531 	)
1532 {
1533 	const efx_lic_ops_t *elop = enp->en_elop;
1534 	efx_rc_t rc;
1535 
1536 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1537 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1538 
1539 	if ((rc = elop->elo_find_end(enp, bufferp, buffer_size, offset, endp)) != 0)
1540 		goto fail1;
1541 
1542 	return (0);
1543 
1544 fail1:
1545 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1546 
1547 	return (rc);
1548 }
1549 
1550 	__checkReturn	__success(return != B_FALSE)	boolean_t
efx_lic_find_key(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__out uint32_t * startp,__out uint32_t * lengthp)1551 efx_lic_find_key(
1552 	__in			efx_nic_t *enp,
1553 	__in_bcount(buffer_size)
1554 				caddr_t bufferp,
1555 	__in			size_t buffer_size,
1556 	__in			uint32_t offset,
1557 	__out			uint32_t *startp,
1558 	__out			uint32_t *lengthp
1559 	)
1560 {
1561 	const efx_lic_ops_t *elop = enp->en_elop;
1562 
1563 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1564 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1565 
1566 	EFSYS_ASSERT(bufferp);
1567 	EFSYS_ASSERT(startp);
1568 	EFSYS_ASSERT(lengthp);
1569 
1570 	return (elop->elo_find_key(enp, bufferp, buffer_size, offset,
1571 				    startp, lengthp));
1572 }
1573 
1574 
1575 /* Validate that the buffer contains a single key in a recognised format.
1576 ** An empty or terminator buffer is not accepted as a valid key.
1577 */
1578 	__checkReturn	__success(return != B_FALSE)	boolean_t
efx_lic_validate_key(__in efx_nic_t * enp,__in_bcount (length)caddr_t keyp,__in uint32_t length)1579 efx_lic_validate_key(
1580 	__in			efx_nic_t *enp,
1581 	__in_bcount(length)	caddr_t keyp,
1582 	__in			uint32_t length
1583 	)
1584 {
1585 	const efx_lic_ops_t *elop = enp->en_elop;
1586 	boolean_t rc;
1587 
1588 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1589 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1590 
1591 	if ((rc = elop->elo_validate_key(enp, keyp, length)) == B_FALSE)
1592 		goto fail1;
1593 
1594 	return (B_TRUE);
1595 
1596 fail1:
1597 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1598 
1599 	return (rc);
1600 }
1601 
1602 	__checkReturn		efx_rc_t
efx_lic_read_key(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__in uint32_t length,__out_bcount_part (key_max_size,* lengthp)caddr_t keyp,__in size_t key_max_size,__out uint32_t * lengthp)1603 efx_lic_read_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 	__out_bcount_part(key_max_size, *lengthp)
1611 				caddr_t keyp,
1612 	__in			size_t key_max_size,
1613 	__out			uint32_t *lengthp
1614 	)
1615 {
1616 	const efx_lic_ops_t *elop = enp->en_elop;
1617 	efx_rc_t rc;
1618 
1619 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1620 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1621 
1622 	if ((rc = elop->elo_read_key(enp, bufferp, buffer_size, offset,
1623 				    length, keyp, key_max_size, lengthp)) != 0)
1624 		goto fail1;
1625 
1626 	return (0);
1627 
1628 fail1:
1629 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1630 
1631 	return (rc);
1632 }
1633 
1634 	__checkReturn		efx_rc_t
efx_lic_write_key(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__in_bcount (length)caddr_t keyp,__in uint32_t length,__out uint32_t * lengthp)1635 efx_lic_write_key(
1636 	__in			efx_nic_t *enp,
1637 	__in_bcount(buffer_size)
1638 				caddr_t bufferp,
1639 	__in			size_t buffer_size,
1640 	__in			uint32_t offset,
1641 	__in_bcount(length)	caddr_t keyp,
1642 	__in			uint32_t length,
1643 	__out			uint32_t *lengthp
1644 	)
1645 {
1646 	const efx_lic_ops_t *elop = enp->en_elop;
1647 	efx_rc_t rc;
1648 
1649 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1650 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1651 
1652 	if ((rc = elop->elo_write_key(enp, bufferp, buffer_size, offset,
1653 				    keyp, length, lengthp)) != 0)
1654 		goto fail1;
1655 
1656 	return (0);
1657 
1658 fail1:
1659 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1660 
1661 	return (rc);
1662 }
1663 
1664 	__checkReturn		efx_rc_t
efx_lic_delete_key(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__in uint32_t length,__in uint32_t end,__out uint32_t * deltap)1665 efx_lic_delete_key(
1666 	__in			efx_nic_t *enp,
1667 	__in_bcount(buffer_size)
1668 				caddr_t bufferp,
1669 	__in			size_t buffer_size,
1670 	__in			uint32_t offset,
1671 	__in			uint32_t length,
1672 	__in			uint32_t end,
1673 	__out			uint32_t *deltap
1674 	)
1675 {
1676 	const efx_lic_ops_t *elop = enp->en_elop;
1677 	efx_rc_t rc;
1678 
1679 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1680 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1681 
1682 	if ((rc = elop->elo_delete_key(enp, bufferp, buffer_size, offset,
1683 				    length, end, deltap)) != 0)
1684 		goto fail1;
1685 
1686 	return (0);
1687 
1688 fail1:
1689 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1690 
1691 	return (rc);
1692 }
1693 
1694 	__checkReturn		efx_rc_t
efx_lic_create_partition(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size)1695 efx_lic_create_partition(
1696 	__in			efx_nic_t *enp,
1697 	__in_bcount(buffer_size)
1698 				caddr_t bufferp,
1699 	__in			size_t buffer_size
1700 	)
1701 {
1702 	const efx_lic_ops_t *elop = enp->en_elop;
1703 	efx_rc_t rc;
1704 
1705 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1706 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1707 
1708 	if ((rc = elop->elo_create_partition(enp, bufferp, buffer_size)) != 0)
1709 		goto fail1;
1710 
1711 	return (0);
1712 
1713 fail1:
1714 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1715 
1716 	return (rc);
1717 }
1718 
1719 
1720 	__checkReturn		efx_rc_t
efx_lic_finish_partition(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size)1721 efx_lic_finish_partition(
1722 	__in			efx_nic_t *enp,
1723 	__in_bcount(buffer_size)
1724 				caddr_t bufferp,
1725 	__in			size_t buffer_size
1726 	)
1727 {
1728 	const efx_lic_ops_t *elop = enp->en_elop;
1729 	efx_rc_t rc;
1730 
1731 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1732 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1733 
1734 	if ((rc = elop->elo_finish_partition(enp, bufferp, buffer_size)) != 0)
1735 		goto fail1;
1736 
1737 	return (0);
1738 
1739 fail1:
1740 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1741 
1742 	return (rc);
1743 }
1744 
1745 #endif	/* EFSYS_OPT_LICENSING */
1746