xref: /freebsd/sys/dev/sfxge/common/efx_lic.c (revision 685dc743dc3b5645e34836464128e1c0558b404b)
10c848230SAndrew Rybchenko /*-
2929c7febSAndrew Rybchenko  * Copyright (c) 2009-2016 Solarflare Communications Inc.
30c848230SAndrew Rybchenko  * All rights reserved.
40c848230SAndrew Rybchenko  *
50c848230SAndrew Rybchenko  * Redistribution and use in source and binary forms, with or without
60c848230SAndrew Rybchenko  * modification, are permitted provided that the following conditions are met:
70c848230SAndrew Rybchenko  *
80c848230SAndrew Rybchenko  * 1. Redistributions of source code must retain the above copyright notice,
90c848230SAndrew Rybchenko  *    this list of conditions and the following disclaimer.
100c848230SAndrew Rybchenko  * 2. Redistributions in binary form must reproduce the above copyright notice,
110c848230SAndrew Rybchenko  *    this list of conditions and the following disclaimer in the documentation
120c848230SAndrew Rybchenko  *    and/or other materials provided with the distribution.
130c848230SAndrew Rybchenko  *
140c848230SAndrew Rybchenko  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
150c848230SAndrew Rybchenko  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
160c848230SAndrew Rybchenko  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
170c848230SAndrew Rybchenko  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
180c848230SAndrew Rybchenko  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
190c848230SAndrew Rybchenko  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
200c848230SAndrew Rybchenko  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
210c848230SAndrew Rybchenko  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
220c848230SAndrew Rybchenko  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
230c848230SAndrew Rybchenko  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
240c848230SAndrew Rybchenko  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
250c848230SAndrew Rybchenko  *
260c848230SAndrew Rybchenko  * The views and conclusions contained in the software and documentation are
270c848230SAndrew Rybchenko  * those of the authors and should not be interpreted as representing official
280c848230SAndrew Rybchenko  * policies, either expressed or implied, of the FreeBSD Project.
290c848230SAndrew Rybchenko  */
300c848230SAndrew Rybchenko 
310c848230SAndrew Rybchenko #include <sys/cdefs.h>
320c848230SAndrew Rybchenko #include "efx.h"
330c848230SAndrew Rybchenko #include "efx_impl.h"
340c848230SAndrew Rybchenko 
350c848230SAndrew Rybchenko #if EFSYS_OPT_LICENSING
360c848230SAndrew Rybchenko 
37fc3a62cfSAndrew Rybchenko #include "ef10_tlv_layout.h"
389ed106d0SAndrew Rybchenko #if EFSYS_OPT_SIENA
399ed106d0SAndrew Rybchenko #include "efx_regs_mcdi_aoe.h"
409ed106d0SAndrew Rybchenko #endif
41fc3a62cfSAndrew Rybchenko 
42fc3a62cfSAndrew Rybchenko #if EFSYS_OPT_SIENA | EFSYS_OPT_HUNTINGTON
43fc3a62cfSAndrew Rybchenko 
44fc3a62cfSAndrew Rybchenko 	__checkReturn		efx_rc_t
45fc3a62cfSAndrew Rybchenko efx_lic_v1v2_find_start(
46fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
47fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
48fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
49fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
5095c45bd0SAndrew Rybchenko 	__out			uint32_t *startp);
51fc3a62cfSAndrew Rybchenko 
52fc3a62cfSAndrew Rybchenko 	__checkReturn		efx_rc_t
53fc3a62cfSAndrew Rybchenko efx_lic_v1v2_find_end(
54fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
55fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
56fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
57fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
58fc3a62cfSAndrew Rybchenko 	__in			uint32_t offset,
5995c45bd0SAndrew Rybchenko 	__out			uint32_t *endp);
60fc3a62cfSAndrew Rybchenko 
61fc3a62cfSAndrew Rybchenko 	__checkReturn	__success(return != B_FALSE)	boolean_t
62fc3a62cfSAndrew Rybchenko efx_lic_v1v2_find_key(
63fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
64fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
65fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
66fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
67fc3a62cfSAndrew Rybchenko 	__in			uint32_t offset,
68fc3a62cfSAndrew Rybchenko 	__out			uint32_t *startp,
6995c45bd0SAndrew Rybchenko 	__out			uint32_t *lengthp);
70fc3a62cfSAndrew Rybchenko 
71fc3a62cfSAndrew Rybchenko 	__checkReturn	__success(return != B_FALSE)	boolean_t
72fc3a62cfSAndrew Rybchenko efx_lic_v1v2_validate_key(
73fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
74fc3a62cfSAndrew Rybchenko 	__in_bcount(length)	caddr_t keyp,
7595c45bd0SAndrew Rybchenko 	__in			uint32_t length);
76fc3a62cfSAndrew Rybchenko 
77fc3a62cfSAndrew Rybchenko 	__checkReturn		efx_rc_t
78fc3a62cfSAndrew Rybchenko efx_lic_v1v2_read_key(
79fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
80fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
81fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
82fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
83fc3a62cfSAndrew Rybchenko 	__in			uint32_t offset,
84fc3a62cfSAndrew Rybchenko 	__in			uint32_t length,
85fc3a62cfSAndrew Rybchenko 	__out_bcount_part(key_max_size, *lengthp)
86fc3a62cfSAndrew Rybchenko 				caddr_t keyp,
87fc3a62cfSAndrew Rybchenko 	__in			size_t key_max_size,
8895c45bd0SAndrew Rybchenko 	__out			uint32_t *lengthp);
89fc3a62cfSAndrew Rybchenko 
90fc3a62cfSAndrew Rybchenko 	__checkReturn		efx_rc_t
91fc3a62cfSAndrew Rybchenko efx_lic_v1v2_write_key(
92fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
93fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
94fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
95fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
96fc3a62cfSAndrew Rybchenko 	__in			uint32_t offset,
97fc3a62cfSAndrew Rybchenko 	__in_bcount(length)	caddr_t keyp,
98fc3a62cfSAndrew Rybchenko 	__in			uint32_t length,
9995c45bd0SAndrew Rybchenko 	__out			uint32_t *lengthp);
100fc3a62cfSAndrew Rybchenko 
101fc3a62cfSAndrew Rybchenko 	__checkReturn		efx_rc_t
102fc3a62cfSAndrew Rybchenko efx_lic_v1v2_delete_key(
103fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
104fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
105fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
106fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
107fc3a62cfSAndrew Rybchenko 	__in			uint32_t offset,
108fc3a62cfSAndrew Rybchenko 	__in			uint32_t length,
109fc3a62cfSAndrew Rybchenko 	__in			uint32_t end,
11095c45bd0SAndrew Rybchenko 	__out			uint32_t *deltap);
111fc3a62cfSAndrew Rybchenko 
112fc3a62cfSAndrew Rybchenko 	__checkReturn		efx_rc_t
113fc3a62cfSAndrew Rybchenko efx_lic_v1v2_create_partition(
114fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
115fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
116fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
11795c45bd0SAndrew Rybchenko 	__in			size_t buffer_size);
118fc3a62cfSAndrew Rybchenko 
119fc3a62cfSAndrew Rybchenko 	__checkReturn		efx_rc_t
120fc3a62cfSAndrew Rybchenko efx_lic_v1v2_finish_partition(
121fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
122fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
123fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
12495c45bd0SAndrew Rybchenko 	__in			size_t buffer_size);
125fc3a62cfSAndrew Rybchenko 
126fc3a62cfSAndrew Rybchenko #endif	/* EFSYS_OPT_HUNTINGTON | EFSYS_OPT_SIENA */
127fc3a62cfSAndrew Rybchenko 
1280c848230SAndrew Rybchenko #if EFSYS_OPT_SIENA
1290c848230SAndrew Rybchenko 
1300c848230SAndrew Rybchenko static	__checkReturn	efx_rc_t
1310c848230SAndrew Rybchenko efx_mcdi_fc_license_update_license(
1320c848230SAndrew Rybchenko 	__in		efx_nic_t *enp);
1330c848230SAndrew Rybchenko 
1340c848230SAndrew Rybchenko static	__checkReturn	efx_rc_t
1350c848230SAndrew Rybchenko efx_mcdi_fc_license_get_key_stats(
1360c848230SAndrew Rybchenko 	__in		efx_nic_t *enp,
1370c848230SAndrew Rybchenko 	__out		efx_key_stats_t *eksp);
1380c848230SAndrew Rybchenko 
139ec831f7fSAndrew Rybchenko static const efx_lic_ops_t	__efx_lic_v1_ops = {
1400c848230SAndrew Rybchenko 	efx_mcdi_fc_license_update_license,	/* elo_update_licenses */
1410c848230SAndrew Rybchenko 	efx_mcdi_fc_license_get_key_stats,	/* elo_get_key_stats */
1420c848230SAndrew Rybchenko 	NULL,					/* elo_app_state */
1430c848230SAndrew Rybchenko 	NULL,					/* elo_get_id */
144fc3a62cfSAndrew Rybchenko 	efx_lic_v1v2_find_start,		/* elo_find_start */
145fc3a62cfSAndrew Rybchenko 	efx_lic_v1v2_find_end,			/* elo_find_end */
146fc3a62cfSAndrew Rybchenko 	efx_lic_v1v2_find_key,			/* elo_find_key */
147fc3a62cfSAndrew Rybchenko 	efx_lic_v1v2_validate_key,		/* elo_validate_key */
148fc3a62cfSAndrew Rybchenko 	efx_lic_v1v2_read_key,			/* elo_read_key */
149fc3a62cfSAndrew Rybchenko 	efx_lic_v1v2_write_key,			/* elo_write_key */
150fc3a62cfSAndrew Rybchenko 	efx_lic_v1v2_delete_key,		/* elo_delete_key */
151fc3a62cfSAndrew Rybchenko 	efx_lic_v1v2_create_partition,		/* elo_create_partition */
152fc3a62cfSAndrew Rybchenko 	efx_lic_v1v2_finish_partition,		/* elo_finish_partition */
1530c848230SAndrew Rybchenko };
1540c848230SAndrew Rybchenko 
1550c848230SAndrew Rybchenko #endif	/* EFSYS_OPT_SIENA */
1560c848230SAndrew Rybchenko 
1570c848230SAndrew Rybchenko #if EFSYS_OPT_HUNTINGTON
1580c848230SAndrew Rybchenko 
1590c848230SAndrew Rybchenko static	__checkReturn	efx_rc_t
1600c848230SAndrew Rybchenko efx_mcdi_licensing_update_licenses(
1610c848230SAndrew Rybchenko 	__in		efx_nic_t *enp);
1620c848230SAndrew Rybchenko 
1630c848230SAndrew Rybchenko static	__checkReturn	efx_rc_t
1640c848230SAndrew Rybchenko efx_mcdi_licensing_get_key_stats(
1650c848230SAndrew Rybchenko 	__in		efx_nic_t *enp,
1660c848230SAndrew Rybchenko 	__out		efx_key_stats_t *eksp);
1670c848230SAndrew Rybchenko 
1680c848230SAndrew Rybchenko static	__checkReturn	efx_rc_t
1690c848230SAndrew Rybchenko efx_mcdi_licensed_app_state(
1700c848230SAndrew Rybchenko 	__in		efx_nic_t *enp,
1710c848230SAndrew Rybchenko 	__in		uint64_t app_id,
1720c848230SAndrew Rybchenko 	__out		boolean_t *licensedp);
1730c848230SAndrew Rybchenko 
174ec831f7fSAndrew Rybchenko static const efx_lic_ops_t	__efx_lic_v2_ops = {
1750c848230SAndrew Rybchenko 	efx_mcdi_licensing_update_licenses,	/* elo_update_licenses */
1760c848230SAndrew Rybchenko 	efx_mcdi_licensing_get_key_stats,	/* elo_get_key_stats */
1770c848230SAndrew Rybchenko 	efx_mcdi_licensed_app_state,		/* elo_app_state */
1780c848230SAndrew Rybchenko 	NULL,					/* elo_get_id */
179fc3a62cfSAndrew Rybchenko 	efx_lic_v1v2_find_start,		/* elo_find_start */
180fc3a62cfSAndrew Rybchenko 	efx_lic_v1v2_find_end,			/* elo_find_end */
181fc3a62cfSAndrew Rybchenko 	efx_lic_v1v2_find_key,			/* elo_find_key */
182fc3a62cfSAndrew Rybchenko 	efx_lic_v1v2_validate_key,		/* elo_validate_key */
183fc3a62cfSAndrew Rybchenko 	efx_lic_v1v2_read_key,			/* elo_read_key */
184fc3a62cfSAndrew Rybchenko 	efx_lic_v1v2_write_key,			/* elo_write_key */
185fc3a62cfSAndrew Rybchenko 	efx_lic_v1v2_delete_key,		/* elo_delete_key */
186fc3a62cfSAndrew Rybchenko 	efx_lic_v1v2_create_partition,		/* elo_create_partition */
187fc3a62cfSAndrew Rybchenko 	efx_lic_v1v2_finish_partition,		/* elo_finish_partition */
1880c848230SAndrew Rybchenko };
1890c848230SAndrew Rybchenko 
1900c848230SAndrew Rybchenko #endif	/* EFSYS_OPT_HUNTINGTON */
1910c848230SAndrew Rybchenko 
192ef3b3edeSAndrew Rybchenko #if EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
1930c848230SAndrew Rybchenko 
1940c848230SAndrew Rybchenko static	__checkReturn	efx_rc_t
1950c848230SAndrew Rybchenko efx_mcdi_licensing_v3_update_licenses(
1960c848230SAndrew Rybchenko 	__in		efx_nic_t *enp);
1970c848230SAndrew Rybchenko 
1980c848230SAndrew Rybchenko static	__checkReturn	efx_rc_t
1990c848230SAndrew Rybchenko efx_mcdi_licensing_v3_report_license(
2000c848230SAndrew Rybchenko 	__in		efx_nic_t *enp,
2010c848230SAndrew Rybchenko 	__out		efx_key_stats_t *eksp);
2020c848230SAndrew Rybchenko 
2030c848230SAndrew Rybchenko static	__checkReturn	efx_rc_t
2040c848230SAndrew Rybchenko efx_mcdi_licensing_v3_app_state(
2050c848230SAndrew Rybchenko 	__in		efx_nic_t *enp,
2060c848230SAndrew Rybchenko 	__in		uint64_t app_id,
2070c848230SAndrew Rybchenko 	__out		boolean_t *licensedp);
2080c848230SAndrew Rybchenko 
2090c848230SAndrew Rybchenko static	__checkReturn	efx_rc_t
2100c848230SAndrew Rybchenko efx_mcdi_licensing_v3_get_id(
2110c848230SAndrew Rybchenko 	__in		efx_nic_t *enp,
2120c848230SAndrew Rybchenko 	__in		size_t buffer_size,
2130c848230SAndrew Rybchenko 	__out		uint32_t *typep,
2140c848230SAndrew Rybchenko 	__out		size_t *lengthp,
2150c848230SAndrew Rybchenko 	__out_bcount_part_opt(buffer_size, *lengthp)
2160c848230SAndrew Rybchenko 			uint8_t *bufferp);
2170c848230SAndrew Rybchenko 
218fc3a62cfSAndrew Rybchenko 	__checkReturn		efx_rc_t
219fc3a62cfSAndrew Rybchenko efx_lic_v3_find_start(
220fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
221fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
222fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
223fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
22495c45bd0SAndrew Rybchenko 	__out			uint32_t *startp);
225fc3a62cfSAndrew Rybchenko 
226fc3a62cfSAndrew Rybchenko 	__checkReturn		efx_rc_t
227fc3a62cfSAndrew Rybchenko efx_lic_v3_find_end(
228fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
229fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
230fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
231fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
232fc3a62cfSAndrew Rybchenko 	__in			uint32_t offset,
23395c45bd0SAndrew Rybchenko 	__out			uint32_t *endp);
234fc3a62cfSAndrew Rybchenko 
235fc3a62cfSAndrew Rybchenko 	__checkReturn	__success(return != B_FALSE)	boolean_t
236fc3a62cfSAndrew Rybchenko efx_lic_v3_find_key(
237fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
238fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
239fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
240fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
241fc3a62cfSAndrew Rybchenko 	__in			uint32_t offset,
242fc3a62cfSAndrew Rybchenko 	__out			uint32_t *startp,
24395c45bd0SAndrew Rybchenko 	__out			uint32_t *lengthp);
244fc3a62cfSAndrew Rybchenko 
245fc3a62cfSAndrew Rybchenko 	__checkReturn	__success(return != B_FALSE)	boolean_t
246fc3a62cfSAndrew Rybchenko efx_lic_v3_validate_key(
247fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
248fc3a62cfSAndrew Rybchenko 	__in_bcount(length)	caddr_t keyp,
24995c45bd0SAndrew Rybchenko 	__in			uint32_t length);
250fc3a62cfSAndrew Rybchenko 
251fc3a62cfSAndrew Rybchenko 	__checkReturn		efx_rc_t
252fc3a62cfSAndrew Rybchenko efx_lic_v3_read_key(
253fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
254fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
255fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
256fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
257fc3a62cfSAndrew Rybchenko 	__in			uint32_t offset,
258fc3a62cfSAndrew Rybchenko 	__in			uint32_t length,
259fc3a62cfSAndrew Rybchenko 	__out_bcount_part(key_max_size, *lengthp)
260fc3a62cfSAndrew Rybchenko 				caddr_t keyp,
261fc3a62cfSAndrew Rybchenko 	__in			size_t key_max_size,
26295c45bd0SAndrew Rybchenko 	__out			uint32_t *lengthp);
263fc3a62cfSAndrew Rybchenko 
264fc3a62cfSAndrew Rybchenko 	__checkReturn		efx_rc_t
265fc3a62cfSAndrew Rybchenko efx_lic_v3_write_key(
266fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
267fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
268fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
269fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
270fc3a62cfSAndrew Rybchenko 	__in			uint32_t offset,
271fc3a62cfSAndrew Rybchenko 	__in_bcount(length)	caddr_t keyp,
272fc3a62cfSAndrew Rybchenko 	__in			uint32_t length,
27395c45bd0SAndrew Rybchenko 	__out			uint32_t *lengthp);
274fc3a62cfSAndrew Rybchenko 
275fc3a62cfSAndrew Rybchenko 	__checkReturn		efx_rc_t
276fc3a62cfSAndrew Rybchenko efx_lic_v3_delete_key(
277fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
278fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
279fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
280fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
281fc3a62cfSAndrew Rybchenko 	__in			uint32_t offset,
282fc3a62cfSAndrew Rybchenko 	__in			uint32_t length,
283fc3a62cfSAndrew Rybchenko 	__in			uint32_t end,
28495c45bd0SAndrew Rybchenko 	__out			uint32_t *deltap);
285fc3a62cfSAndrew Rybchenko 
286fc3a62cfSAndrew Rybchenko 	__checkReturn		efx_rc_t
287fc3a62cfSAndrew Rybchenko efx_lic_v3_create_partition(
288fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
289fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
290fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
29195c45bd0SAndrew Rybchenko 	__in			size_t buffer_size);
292fc3a62cfSAndrew Rybchenko 
293fc3a62cfSAndrew Rybchenko 	__checkReturn		efx_rc_t
294fc3a62cfSAndrew Rybchenko efx_lic_v3_finish_partition(
295fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
296fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
297fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
29895c45bd0SAndrew Rybchenko 	__in			size_t buffer_size);
299fc3a62cfSAndrew Rybchenko 
300ec831f7fSAndrew Rybchenko static const efx_lic_ops_t	__efx_lic_v3_ops = {
3010c848230SAndrew Rybchenko 	efx_mcdi_licensing_v3_update_licenses,	/* elo_update_licenses */
3020c848230SAndrew Rybchenko 	efx_mcdi_licensing_v3_report_license,	/* elo_get_key_stats */
3030c848230SAndrew Rybchenko 	efx_mcdi_licensing_v3_app_state,	/* elo_app_state */
3040c848230SAndrew Rybchenko 	efx_mcdi_licensing_v3_get_id,		/* elo_get_id */
305fc3a62cfSAndrew Rybchenko 	efx_lic_v3_find_start,			/* elo_find_start */
306fc3a62cfSAndrew Rybchenko 	efx_lic_v3_find_end,			/* elo_find_end */
307fc3a62cfSAndrew Rybchenko 	efx_lic_v3_find_key,			/* elo_find_key */
308fc3a62cfSAndrew Rybchenko 	efx_lic_v3_validate_key,		/* elo_validate_key */
309fc3a62cfSAndrew Rybchenko 	efx_lic_v3_read_key,			/* elo_read_key */
310fc3a62cfSAndrew Rybchenko 	efx_lic_v3_write_key,			/* elo_write_key */
311fc3a62cfSAndrew Rybchenko 	efx_lic_v3_delete_key,			/* elo_delete_key */
312fc3a62cfSAndrew Rybchenko 	efx_lic_v3_create_partition,		/* elo_create_partition */
313fc3a62cfSAndrew Rybchenko 	efx_lic_v3_finish_partition,		/* elo_finish_partition */
3140c848230SAndrew Rybchenko };
3150c848230SAndrew Rybchenko 
316ef3b3edeSAndrew Rybchenko #endif	/* EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
3170c848230SAndrew Rybchenko 
3180c848230SAndrew Rybchenko /* V1 Licensing - used in Siena Modena only */
3190c848230SAndrew Rybchenko 
3200c848230SAndrew Rybchenko #if EFSYS_OPT_SIENA
3210c848230SAndrew Rybchenko 
3220c848230SAndrew Rybchenko static	__checkReturn	efx_rc_t
efx_mcdi_fc_license_update_license(__in efx_nic_t * enp)3230c848230SAndrew Rybchenko efx_mcdi_fc_license_update_license(
3240c848230SAndrew Rybchenko 	__in		efx_nic_t *enp)
3250c848230SAndrew Rybchenko {
3260c848230SAndrew Rybchenko 	efx_mcdi_req_t req;
327315bbbaaSAndrew Rybchenko 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FC_IN_LICENSE_LEN, 0);
3280c848230SAndrew Rybchenko 	efx_rc_t rc;
3290c848230SAndrew Rybchenko 
3300c848230SAndrew Rybchenko 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
3310c848230SAndrew Rybchenko 
332b59e9e4aSAndrew Rybchenko 	req.emr_cmd = MC_CMD_FC;
3330c848230SAndrew Rybchenko 	req.emr_in_buf = payload;
3340c848230SAndrew Rybchenko 	req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN;
3350c848230SAndrew Rybchenko 	req.emr_out_buf = payload;
3360c848230SAndrew Rybchenko 	req.emr_out_length = 0;
3370c848230SAndrew Rybchenko 
338b59e9e4aSAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, FC_IN_CMD,
339b59e9e4aSAndrew Rybchenko 	    MC_CMD_FC_OP_LICENSE);
340b59e9e4aSAndrew Rybchenko 
3410c848230SAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP,
3420c848230SAndrew Rybchenko 	    MC_CMD_FC_IN_LICENSE_UPDATE_LICENSE);
3430c848230SAndrew Rybchenko 
3440c848230SAndrew Rybchenko 	efx_mcdi_execute(enp, &req);
3450c848230SAndrew Rybchenko 
3460c848230SAndrew Rybchenko 	if (req.emr_rc != 0) {
3470c848230SAndrew Rybchenko 		rc = req.emr_rc;
3480c848230SAndrew Rybchenko 		goto fail1;
3490c848230SAndrew Rybchenko 	}
3500c848230SAndrew Rybchenko 
3510c848230SAndrew Rybchenko 	if (req.emr_out_length_used != 0) {
3520c848230SAndrew Rybchenko 		rc = EIO;
3530c848230SAndrew Rybchenko 		goto fail2;
3540c848230SAndrew Rybchenko 	}
3550c848230SAndrew Rybchenko 
3560c848230SAndrew Rybchenko 	return (0);
3570c848230SAndrew Rybchenko 
3580c848230SAndrew Rybchenko fail2:
3590c848230SAndrew Rybchenko 	EFSYS_PROBE(fail2);
3600c848230SAndrew Rybchenko fail1:
3610c848230SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
3620c848230SAndrew Rybchenko 
3630c848230SAndrew Rybchenko 	return (rc);
3640c848230SAndrew Rybchenko }
3650c848230SAndrew Rybchenko 
3660c848230SAndrew Rybchenko static	__checkReturn	efx_rc_t
efx_mcdi_fc_license_get_key_stats(__in efx_nic_t * enp,__out efx_key_stats_t * eksp)3670c848230SAndrew Rybchenko efx_mcdi_fc_license_get_key_stats(
3680c848230SAndrew Rybchenko 	__in		efx_nic_t *enp,
3690c848230SAndrew Rybchenko 	__out		efx_key_stats_t *eksp)
3700c848230SAndrew Rybchenko {
3710c848230SAndrew Rybchenko 	efx_mcdi_req_t req;
372315bbbaaSAndrew Rybchenko 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FC_IN_LICENSE_LEN,
373315bbbaaSAndrew Rybchenko 		MC_CMD_FC_OUT_LICENSE_LEN);
3740c848230SAndrew Rybchenko 	efx_rc_t rc;
3750c848230SAndrew Rybchenko 
3760c848230SAndrew Rybchenko 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
3770c848230SAndrew Rybchenko 
378b59e9e4aSAndrew Rybchenko 	req.emr_cmd = MC_CMD_FC;
3790c848230SAndrew Rybchenko 	req.emr_in_buf = payload;
3800c848230SAndrew Rybchenko 	req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN;
3810c848230SAndrew Rybchenko 	req.emr_out_buf = payload;
3820c848230SAndrew Rybchenko 	req.emr_out_length = MC_CMD_FC_OUT_LICENSE_LEN;
3830c848230SAndrew Rybchenko 
384b59e9e4aSAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, FC_IN_CMD,
385b59e9e4aSAndrew Rybchenko 	    MC_CMD_FC_OP_LICENSE);
386b59e9e4aSAndrew Rybchenko 
3870c848230SAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP,
3880c848230SAndrew Rybchenko 	    MC_CMD_FC_IN_LICENSE_GET_KEY_STATS);
3890c848230SAndrew Rybchenko 
390c6190b10SAndrew Rybchenko 	efx_mcdi_execute_quiet(enp, &req);
3910c848230SAndrew Rybchenko 
3920c848230SAndrew Rybchenko 	if (req.emr_rc != 0) {
3930c848230SAndrew Rybchenko 		rc = req.emr_rc;
3940c848230SAndrew Rybchenko 		goto fail1;
3950c848230SAndrew Rybchenko 	}
3960c848230SAndrew Rybchenko 
3970c848230SAndrew Rybchenko 	if (req.emr_out_length_used < MC_CMD_FC_OUT_LICENSE_LEN) {
3980c848230SAndrew Rybchenko 		rc = EMSGSIZE;
3990c848230SAndrew Rybchenko 		goto fail2;
4000c848230SAndrew Rybchenko 	}
4010c848230SAndrew Rybchenko 
4020c848230SAndrew Rybchenko 	eksp->eks_valid =
4030c848230SAndrew Rybchenko 		MCDI_OUT_DWORD(req, FC_OUT_LICENSE_VALID_KEYS);
4040c848230SAndrew Rybchenko 	eksp->eks_invalid =
4050c848230SAndrew Rybchenko 		MCDI_OUT_DWORD(req, FC_OUT_LICENSE_INVALID_KEYS);
4060c848230SAndrew Rybchenko 	eksp->eks_blacklisted =
4070c848230SAndrew Rybchenko 		MCDI_OUT_DWORD(req, FC_OUT_LICENSE_BLACKLISTED_KEYS);
4080c848230SAndrew Rybchenko 	eksp->eks_unverifiable = 0;
4090c848230SAndrew Rybchenko 	eksp->eks_wrong_node = 0;
4100c848230SAndrew Rybchenko 	eksp->eks_licensed_apps_lo = 0;
4110c848230SAndrew Rybchenko 	eksp->eks_licensed_apps_hi = 0;
4120c848230SAndrew Rybchenko 	eksp->eks_licensed_features_lo = 0;
4130c848230SAndrew Rybchenko 	eksp->eks_licensed_features_hi = 0;
4140c848230SAndrew Rybchenko 
4150c848230SAndrew Rybchenko 	return (0);
4160c848230SAndrew Rybchenko 
4170c848230SAndrew Rybchenko fail2:
4180c848230SAndrew Rybchenko 	EFSYS_PROBE(fail2);
4190c848230SAndrew Rybchenko fail1:
4200c848230SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
4210c848230SAndrew Rybchenko 
4220c848230SAndrew Rybchenko 	return (rc);
4230c848230SAndrew Rybchenko }
4240c848230SAndrew Rybchenko 
4250c848230SAndrew Rybchenko #endif	/* EFSYS_OPT_SIENA */
4260c848230SAndrew Rybchenko 
427fc3a62cfSAndrew Rybchenko /* V1 and V2 Partition format - based on a 16-bit TLV format */
428fc3a62cfSAndrew Rybchenko 
429fc3a62cfSAndrew Rybchenko #if EFSYS_OPT_SIENA | EFSYS_OPT_HUNTINGTON
430fc3a62cfSAndrew Rybchenko 
431fc3a62cfSAndrew Rybchenko /*
432fc3a62cfSAndrew Rybchenko  * V1/V2 format - defined in SF-108542-TC section 4.2:
433fc3a62cfSAndrew Rybchenko  *  Type (T):   16bit - revision/HMAC algorithm
434fc3a62cfSAndrew Rybchenko  *  Length (L): 16bit - value length in bytes
435fc3a62cfSAndrew Rybchenko  *  Value (V):  L bytes - payload
436fc3a62cfSAndrew Rybchenko  */
437fc3a62cfSAndrew Rybchenko #define	EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX	(256)
438fc3a62cfSAndrew Rybchenko #define	EFX_LICENSE_V1V2_HEADER_LENGTH		(2 * sizeof (uint16_t))
439fc3a62cfSAndrew Rybchenko 
440fc3a62cfSAndrew Rybchenko 	__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)441fc3a62cfSAndrew Rybchenko efx_lic_v1v2_find_start(
442fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
443fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
444fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
445fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
44695c45bd0SAndrew Rybchenko 	__out			uint32_t *startp)
447fc3a62cfSAndrew Rybchenko {
448fc3a62cfSAndrew Rybchenko 	_NOTE(ARGUNUSED(enp, bufferp, buffer_size))
449fc3a62cfSAndrew Rybchenko 
450fc3a62cfSAndrew Rybchenko 	*startp = 0;
451fc3a62cfSAndrew Rybchenko 	return (0);
452fc3a62cfSAndrew Rybchenko }
453fc3a62cfSAndrew Rybchenko 
454fc3a62cfSAndrew Rybchenko 	__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)455fc3a62cfSAndrew Rybchenko efx_lic_v1v2_find_end(
456fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
457fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
458fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
459fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
460fc3a62cfSAndrew Rybchenko 	__in			uint32_t offset,
46195c45bd0SAndrew Rybchenko 	__out			uint32_t *endp)
462fc3a62cfSAndrew Rybchenko {
463fc3a62cfSAndrew Rybchenko 	_NOTE(ARGUNUSED(enp, bufferp, buffer_size))
464fc3a62cfSAndrew Rybchenko 
465fc3a62cfSAndrew Rybchenko 	*endp = offset + EFX_LICENSE_V1V2_HEADER_LENGTH;
466fc3a62cfSAndrew Rybchenko 	return (0);
467fc3a62cfSAndrew Rybchenko }
468fc3a62cfSAndrew Rybchenko 
469fc3a62cfSAndrew Rybchenko 	__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)470fc3a62cfSAndrew Rybchenko efx_lic_v1v2_find_key(
471fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
472fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
473fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
474fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
475fc3a62cfSAndrew Rybchenko 	__in			uint32_t offset,
476fc3a62cfSAndrew Rybchenko 	__out			uint32_t *startp,
47795c45bd0SAndrew Rybchenko 	__out			uint32_t *lengthp)
478fc3a62cfSAndrew Rybchenko {
479fc3a62cfSAndrew Rybchenko 	boolean_t found;
480fc3a62cfSAndrew Rybchenko 	uint16_t tlv_type;
481fc3a62cfSAndrew Rybchenko 	uint16_t tlv_length;
482fc3a62cfSAndrew Rybchenko 
483fc3a62cfSAndrew Rybchenko 	_NOTE(ARGUNUSED(enp))
484fc3a62cfSAndrew Rybchenko 
485fc3a62cfSAndrew Rybchenko 	if ((size_t)buffer_size - offset < EFX_LICENSE_V1V2_HEADER_LENGTH)
486fc3a62cfSAndrew Rybchenko 		goto fail1;
487fc3a62cfSAndrew Rybchenko 
488fc3a62cfSAndrew Rybchenko 	tlv_type = __LE_TO_CPU_16(((uint16_t *)&bufferp[offset])[0]);
489fc3a62cfSAndrew Rybchenko 	tlv_length = __LE_TO_CPU_16(((uint16_t *)&bufferp[offset])[1]);
490fc3a62cfSAndrew Rybchenko 	if ((tlv_length > EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX) ||
491fc3a62cfSAndrew Rybchenko 	    (tlv_type == 0 && tlv_length == 0)) {
492fc3a62cfSAndrew Rybchenko 		found = B_FALSE;
493fc3a62cfSAndrew Rybchenko 	} else {
494fc3a62cfSAndrew Rybchenko 		*startp = offset;
495fc3a62cfSAndrew Rybchenko 		*lengthp = tlv_length + EFX_LICENSE_V1V2_HEADER_LENGTH;
496fc3a62cfSAndrew Rybchenko 		found = B_TRUE;
497fc3a62cfSAndrew Rybchenko 	}
498fc3a62cfSAndrew Rybchenko 	return (found);
499fc3a62cfSAndrew Rybchenko 
500fc3a62cfSAndrew Rybchenko fail1:
50179ddc224SAndrew Rybchenko 	EFSYS_PROBE1(fail1, boolean_t, B_FALSE);
502fc3a62cfSAndrew Rybchenko 
503fc3a62cfSAndrew Rybchenko 	return (B_FALSE);
504fc3a62cfSAndrew Rybchenko }
505fc3a62cfSAndrew Rybchenko 
506fc3a62cfSAndrew Rybchenko 	__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)507fc3a62cfSAndrew Rybchenko efx_lic_v1v2_validate_key(
508fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
509fc3a62cfSAndrew Rybchenko 	__in_bcount(length)	caddr_t keyp,
51095c45bd0SAndrew Rybchenko 	__in			uint32_t length)
511fc3a62cfSAndrew Rybchenko {
512fc3a62cfSAndrew Rybchenko 	uint16_t tlv_type;
513fc3a62cfSAndrew Rybchenko 	uint16_t tlv_length;
514fc3a62cfSAndrew Rybchenko 
515fc3a62cfSAndrew Rybchenko 	_NOTE(ARGUNUSED(enp))
516fc3a62cfSAndrew Rybchenko 
517fc3a62cfSAndrew Rybchenko 	if (length < EFX_LICENSE_V1V2_HEADER_LENGTH) {
518fc3a62cfSAndrew Rybchenko 		goto fail1;
519fc3a62cfSAndrew Rybchenko 	}
520fc3a62cfSAndrew Rybchenko 
521fc3a62cfSAndrew Rybchenko 	tlv_type = __LE_TO_CPU_16(((uint16_t *)keyp)[0]);
522fc3a62cfSAndrew Rybchenko 	tlv_length = __LE_TO_CPU_16(((uint16_t *)keyp)[1]);
523fc3a62cfSAndrew Rybchenko 
524fc3a62cfSAndrew Rybchenko 	if (tlv_length > EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX) {
525fc3a62cfSAndrew Rybchenko 		goto fail2;
526fc3a62cfSAndrew Rybchenko 	}
527fc3a62cfSAndrew Rybchenko 	if (tlv_type == 0) {
528fc3a62cfSAndrew Rybchenko 		goto fail3;
529fc3a62cfSAndrew Rybchenko 	}
530fc3a62cfSAndrew Rybchenko 	if ((tlv_length + EFX_LICENSE_V1V2_HEADER_LENGTH) != length) {
531fc3a62cfSAndrew Rybchenko 		goto fail4;
532fc3a62cfSAndrew Rybchenko 	}
533fc3a62cfSAndrew Rybchenko 
534fc3a62cfSAndrew Rybchenko 	return (B_TRUE);
535fc3a62cfSAndrew Rybchenko 
536fc3a62cfSAndrew Rybchenko fail4:
537fc3a62cfSAndrew Rybchenko 	EFSYS_PROBE(fail4);
538fc3a62cfSAndrew Rybchenko fail3:
539fc3a62cfSAndrew Rybchenko 	EFSYS_PROBE(fail3);
540fc3a62cfSAndrew Rybchenko fail2:
541fc3a62cfSAndrew Rybchenko 	EFSYS_PROBE(fail2);
542fc3a62cfSAndrew Rybchenko fail1:
54379ddc224SAndrew Rybchenko 	EFSYS_PROBE1(fail1, boolean_t, B_FALSE);
544fc3a62cfSAndrew Rybchenko 
545fc3a62cfSAndrew Rybchenko 	return (B_FALSE);
546fc3a62cfSAndrew Rybchenko }
547fc3a62cfSAndrew Rybchenko 
548fc3a62cfSAndrew Rybchenko 	__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)549fc3a62cfSAndrew Rybchenko efx_lic_v1v2_read_key(
550fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
551fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
552fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
553fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
554fc3a62cfSAndrew Rybchenko 	__in			uint32_t offset,
555fc3a62cfSAndrew Rybchenko 	__in			uint32_t length,
556fc3a62cfSAndrew Rybchenko 	__out_bcount_part(key_max_size, *lengthp)
557fc3a62cfSAndrew Rybchenko 				caddr_t keyp,
558fc3a62cfSAndrew Rybchenko 	__in			size_t key_max_size,
55995c45bd0SAndrew Rybchenko 	__out			uint32_t *lengthp)
560fc3a62cfSAndrew Rybchenko {
561fc3a62cfSAndrew Rybchenko 	efx_rc_t rc;
562fc3a62cfSAndrew Rybchenko 
563bbea9604SAndrew Rybchenko 	_NOTE(ARGUNUSED(enp, buffer_size))
564fc3a62cfSAndrew Rybchenko 	EFSYS_ASSERT(length <= (EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX +
565fc3a62cfSAndrew Rybchenko 	    EFX_LICENSE_V1V2_HEADER_LENGTH));
566fc3a62cfSAndrew Rybchenko 
567fc3a62cfSAndrew Rybchenko 	if (key_max_size < length) {
568fc3a62cfSAndrew Rybchenko 		rc = ENOSPC;
569fc3a62cfSAndrew Rybchenko 		goto fail1;
570fc3a62cfSAndrew Rybchenko 	}
571fc3a62cfSAndrew Rybchenko 	memcpy(keyp, &bufferp[offset], length);
572fc3a62cfSAndrew Rybchenko 
573fc3a62cfSAndrew Rybchenko 	*lengthp = length;
574fc3a62cfSAndrew Rybchenko 
575fc3a62cfSAndrew Rybchenko 	return (0);
576fc3a62cfSAndrew Rybchenko 
577fc3a62cfSAndrew Rybchenko fail1:
578fc3a62cfSAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
579fc3a62cfSAndrew Rybchenko 
580fc3a62cfSAndrew Rybchenko 	return (rc);
581fc3a62cfSAndrew Rybchenko }
582fc3a62cfSAndrew Rybchenko 
583fc3a62cfSAndrew Rybchenko 	__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)584fc3a62cfSAndrew Rybchenko efx_lic_v1v2_write_key(
585fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
586fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
587fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
588fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
589fc3a62cfSAndrew Rybchenko 	__in			uint32_t offset,
590fc3a62cfSAndrew Rybchenko 	__in_bcount(length)	caddr_t keyp,
591fc3a62cfSAndrew Rybchenko 	__in			uint32_t length,
59295c45bd0SAndrew Rybchenko 	__out			uint32_t *lengthp)
593fc3a62cfSAndrew Rybchenko {
594fc3a62cfSAndrew Rybchenko 	efx_rc_t rc;
595fc3a62cfSAndrew Rybchenko 
596fc3a62cfSAndrew Rybchenko 	_NOTE(ARGUNUSED(enp))
597fc3a62cfSAndrew Rybchenko 	EFSYS_ASSERT(length <= (EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX +
598fc3a62cfSAndrew Rybchenko 	    EFX_LICENSE_V1V2_HEADER_LENGTH));
599fc3a62cfSAndrew Rybchenko 
60075b16fa0SAndrew Rybchenko 	/* Ensure space for terminator remains */
601fc3a62cfSAndrew Rybchenko 	if ((offset + length) >
602fc3a62cfSAndrew Rybchenko 	    (buffer_size - EFX_LICENSE_V1V2_HEADER_LENGTH)) {
603fc3a62cfSAndrew Rybchenko 		rc = ENOSPC;
604fc3a62cfSAndrew Rybchenko 		goto fail1;
605fc3a62cfSAndrew Rybchenko 	}
606fc3a62cfSAndrew Rybchenko 
607fc3a62cfSAndrew Rybchenko 	memcpy(bufferp + offset, keyp, length);
608fc3a62cfSAndrew Rybchenko 
609fc3a62cfSAndrew Rybchenko 	*lengthp = length;
610fc3a62cfSAndrew Rybchenko 
611fc3a62cfSAndrew Rybchenko 	return (0);
612fc3a62cfSAndrew Rybchenko 
613fc3a62cfSAndrew Rybchenko fail1:
614fc3a62cfSAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
615fc3a62cfSAndrew Rybchenko 
616fc3a62cfSAndrew Rybchenko 	return (rc);
617fc3a62cfSAndrew Rybchenko }
618fc3a62cfSAndrew Rybchenko 
619fc3a62cfSAndrew Rybchenko 	__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)620fc3a62cfSAndrew Rybchenko efx_lic_v1v2_delete_key(
621fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
622fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
623fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
624fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
625fc3a62cfSAndrew Rybchenko 	__in			uint32_t offset,
626fc3a62cfSAndrew Rybchenko 	__in			uint32_t length,
627fc3a62cfSAndrew Rybchenko 	__in			uint32_t end,
62895c45bd0SAndrew Rybchenko 	__out			uint32_t *deltap)
629fc3a62cfSAndrew Rybchenko {
630fc3a62cfSAndrew Rybchenko 	uint32_t move_start = offset + length;
631fc3a62cfSAndrew Rybchenko 	uint32_t move_length = end - move_start;
632fc3a62cfSAndrew Rybchenko 
633bbea9604SAndrew Rybchenko 	_NOTE(ARGUNUSED(enp, buffer_size))
634fc3a62cfSAndrew Rybchenko 	EFSYS_ASSERT(end <= buffer_size);
635fc3a62cfSAndrew Rybchenko 
63675b16fa0SAndrew Rybchenko 	/* Shift everything after the key down */
637fc3a62cfSAndrew Rybchenko 	memmove(bufferp + offset, bufferp + move_start, move_length);
638fc3a62cfSAndrew Rybchenko 
639fc3a62cfSAndrew Rybchenko 	*deltap = length;
640fc3a62cfSAndrew Rybchenko 
641fc3a62cfSAndrew Rybchenko 	return (0);
642fc3a62cfSAndrew Rybchenko }
643fc3a62cfSAndrew Rybchenko 
644fc3a62cfSAndrew Rybchenko 	__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)645fc3a62cfSAndrew Rybchenko efx_lic_v1v2_create_partition(
646fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
647fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
648fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
64995c45bd0SAndrew Rybchenko 	__in			size_t buffer_size)
650fc3a62cfSAndrew Rybchenko {
651bbea9604SAndrew Rybchenko 	_NOTE(ARGUNUSED(enp, buffer_size))
652fc3a62cfSAndrew Rybchenko 	EFSYS_ASSERT(EFX_LICENSE_V1V2_HEADER_LENGTH <= buffer_size);
653fc3a62cfSAndrew Rybchenko 
65475b16fa0SAndrew Rybchenko 	/* Write terminator */
655fc3a62cfSAndrew Rybchenko 	memset(bufferp, '\0', EFX_LICENSE_V1V2_HEADER_LENGTH);
656fc3a62cfSAndrew Rybchenko 	return (0);
657fc3a62cfSAndrew Rybchenko }
658fc3a62cfSAndrew Rybchenko 
659fc3a62cfSAndrew Rybchenko 	__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)660fc3a62cfSAndrew Rybchenko efx_lic_v1v2_finish_partition(
661fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
662fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
663fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
66495c45bd0SAndrew Rybchenko 	__in			size_t buffer_size)
665fc3a62cfSAndrew Rybchenko {
666fc3a62cfSAndrew Rybchenko 	_NOTE(ARGUNUSED(enp, bufferp, buffer_size))
667fc3a62cfSAndrew Rybchenko 
668fc3a62cfSAndrew Rybchenko 	return (0);
669fc3a62cfSAndrew Rybchenko }
670fc3a62cfSAndrew Rybchenko 
671fc3a62cfSAndrew Rybchenko #endif	/* EFSYS_OPT_HUNTINGTON | EFSYS_OPT_SIENA */
672fc3a62cfSAndrew Rybchenko 
6730c848230SAndrew Rybchenko /* V2 Licensing - used by Huntington family only. See SF-113611-TC */
6740c848230SAndrew Rybchenko 
6750c848230SAndrew Rybchenko #if EFSYS_OPT_HUNTINGTON
6760c848230SAndrew Rybchenko 
6770c848230SAndrew Rybchenko static	__checkReturn	efx_rc_t
efx_mcdi_licensed_app_state(__in efx_nic_t * enp,__in uint64_t app_id,__out boolean_t * licensedp)6780c848230SAndrew Rybchenko efx_mcdi_licensed_app_state(
6790c848230SAndrew Rybchenko 	__in		efx_nic_t *enp,
6800c848230SAndrew Rybchenko 	__in		uint64_t app_id,
6810c848230SAndrew Rybchenko 	__out		boolean_t *licensedp)
6820c848230SAndrew Rybchenko {
6830c848230SAndrew Rybchenko 	efx_mcdi_req_t req;
684315bbbaaSAndrew Rybchenko 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LICENSED_APP_STATE_IN_LEN,
685315bbbaaSAndrew Rybchenko 		MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN);
6860c848230SAndrew Rybchenko 	uint32_t app_state;
6870c848230SAndrew Rybchenko 	efx_rc_t rc;
6880c848230SAndrew Rybchenko 
6890c848230SAndrew Rybchenko 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
6900c848230SAndrew Rybchenko 
6910c848230SAndrew Rybchenko 	/* V2 licensing supports 32bit app id only */
6920c848230SAndrew Rybchenko 	if ((app_id >> 32) != 0) {
6930c848230SAndrew Rybchenko 		rc = EINVAL;
6940c848230SAndrew Rybchenko 		goto fail1;
6950c848230SAndrew Rybchenko 	}
6960c848230SAndrew Rybchenko 
6970c848230SAndrew Rybchenko 	req.emr_cmd = MC_CMD_GET_LICENSED_APP_STATE;
6980c848230SAndrew Rybchenko 	req.emr_in_buf = payload;
6990c848230SAndrew Rybchenko 	req.emr_in_length = MC_CMD_GET_LICENSED_APP_STATE_IN_LEN;
7000c848230SAndrew Rybchenko 	req.emr_out_buf = payload;
7010c848230SAndrew Rybchenko 	req.emr_out_length = MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN;
7020c848230SAndrew Rybchenko 
7030c848230SAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, GET_LICENSED_APP_STATE_IN_APP_ID,
7040c848230SAndrew Rybchenko 		    app_id & 0xffffffff);
7050c848230SAndrew Rybchenko 
7060c848230SAndrew Rybchenko 	efx_mcdi_execute(enp, &req);
7070c848230SAndrew Rybchenko 
7080c848230SAndrew Rybchenko 	if (req.emr_rc != 0) {
7090c848230SAndrew Rybchenko 		rc = req.emr_rc;
7100c848230SAndrew Rybchenko 		goto fail2;
7110c848230SAndrew Rybchenko 	}
7120c848230SAndrew Rybchenko 
7130c848230SAndrew Rybchenko 	if (req.emr_out_length_used < MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN) {
7140c848230SAndrew Rybchenko 		rc = EMSGSIZE;
7150c848230SAndrew Rybchenko 		goto fail3;
7160c848230SAndrew Rybchenko 	}
7170c848230SAndrew Rybchenko 
7180c848230SAndrew Rybchenko 	app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_APP_STATE_OUT_STATE));
7190c848230SAndrew Rybchenko 	if (app_state != MC_CMD_GET_LICENSED_APP_STATE_OUT_NOT_LICENSED) {
7200c848230SAndrew Rybchenko 		*licensedp = B_TRUE;
7210c848230SAndrew Rybchenko 	} else {
7220c848230SAndrew Rybchenko 		*licensedp = B_FALSE;
7230c848230SAndrew Rybchenko 	}
7240c848230SAndrew Rybchenko 
7250c848230SAndrew Rybchenko 	return (0);
7260c848230SAndrew Rybchenko 
7270c848230SAndrew Rybchenko fail3:
7280c848230SAndrew Rybchenko 	EFSYS_PROBE(fail3);
7290c848230SAndrew Rybchenko fail2:
7300c848230SAndrew Rybchenko 	EFSYS_PROBE(fail2);
7310c848230SAndrew Rybchenko fail1:
7320c848230SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
7330c848230SAndrew Rybchenko 
7340c848230SAndrew Rybchenko 	return (rc);
7350c848230SAndrew Rybchenko }
7360c848230SAndrew Rybchenko 
7370c848230SAndrew Rybchenko static	__checkReturn	efx_rc_t
efx_mcdi_licensing_update_licenses(__in efx_nic_t * enp)7380c848230SAndrew Rybchenko efx_mcdi_licensing_update_licenses(
7390c848230SAndrew Rybchenko 	__in		efx_nic_t *enp)
7400c848230SAndrew Rybchenko {
7410c848230SAndrew Rybchenko 	efx_mcdi_req_t req;
742315bbbaaSAndrew Rybchenko 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_IN_LEN, 0);
7430c848230SAndrew Rybchenko 	efx_rc_t rc;
7440c848230SAndrew Rybchenko 
7450c848230SAndrew Rybchenko 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
7460c848230SAndrew Rybchenko 
7470c848230SAndrew Rybchenko 	req.emr_cmd = MC_CMD_LICENSING;
7480c848230SAndrew Rybchenko 	req.emr_in_buf = payload;
7490c848230SAndrew Rybchenko 	req.emr_in_length = MC_CMD_LICENSING_IN_LEN;
7500c848230SAndrew Rybchenko 	req.emr_out_buf = payload;
7510c848230SAndrew Rybchenko 	req.emr_out_length = 0;
7520c848230SAndrew Rybchenko 
7530c848230SAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, LICENSING_IN_OP,
7540c848230SAndrew Rybchenko 	    MC_CMD_LICENSING_IN_OP_UPDATE_LICENSE);
7550c848230SAndrew Rybchenko 
7560c848230SAndrew Rybchenko 	efx_mcdi_execute(enp, &req);
7570c848230SAndrew Rybchenko 
7580c848230SAndrew Rybchenko 	if (req.emr_rc != 0) {
7590c848230SAndrew Rybchenko 		rc = req.emr_rc;
7600c848230SAndrew Rybchenko 		goto fail1;
7610c848230SAndrew Rybchenko 	}
7620c848230SAndrew Rybchenko 
7630c848230SAndrew Rybchenko 	if (req.emr_out_length_used != 0) {
7640c848230SAndrew Rybchenko 		rc = EIO;
7650c848230SAndrew Rybchenko 		goto fail2;
7660c848230SAndrew Rybchenko 	}
7670c848230SAndrew Rybchenko 
7680c848230SAndrew Rybchenko 	return (0);
7690c848230SAndrew Rybchenko 
7700c848230SAndrew Rybchenko fail2:
7710c848230SAndrew Rybchenko 	EFSYS_PROBE(fail2);
7720c848230SAndrew Rybchenko fail1:
7730c848230SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
7740c848230SAndrew Rybchenko 
7750c848230SAndrew Rybchenko 	return (rc);
7760c848230SAndrew Rybchenko }
7770c848230SAndrew Rybchenko 
7780c848230SAndrew Rybchenko static	__checkReturn	efx_rc_t
efx_mcdi_licensing_get_key_stats(__in efx_nic_t * enp,__out efx_key_stats_t * eksp)7790c848230SAndrew Rybchenko efx_mcdi_licensing_get_key_stats(
7800c848230SAndrew Rybchenko 	__in		efx_nic_t *enp,
7810c848230SAndrew Rybchenko 	__out		efx_key_stats_t *eksp)
7820c848230SAndrew Rybchenko {
7830c848230SAndrew Rybchenko 	efx_mcdi_req_t req;
784315bbbaaSAndrew Rybchenko 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_IN_LEN,
785315bbbaaSAndrew Rybchenko 		MC_CMD_LICENSING_OUT_LEN);
7860c848230SAndrew Rybchenko 	efx_rc_t rc;
7870c848230SAndrew Rybchenko 
7880c848230SAndrew Rybchenko 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
7890c848230SAndrew Rybchenko 
7900c848230SAndrew Rybchenko 	req.emr_cmd = MC_CMD_LICENSING;
7910c848230SAndrew Rybchenko 	req.emr_in_buf = payload;
7920c848230SAndrew Rybchenko 	req.emr_in_length = MC_CMD_LICENSING_IN_LEN;
7930c848230SAndrew Rybchenko 	req.emr_out_buf = payload;
7940c848230SAndrew Rybchenko 	req.emr_out_length = MC_CMD_LICENSING_OUT_LEN;
7950c848230SAndrew Rybchenko 
7960c848230SAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, LICENSING_IN_OP,
7970c848230SAndrew Rybchenko 	    MC_CMD_LICENSING_IN_OP_GET_KEY_STATS);
7980c848230SAndrew Rybchenko 
7990c848230SAndrew Rybchenko 	efx_mcdi_execute(enp, &req);
8000c848230SAndrew Rybchenko 
8010c848230SAndrew Rybchenko 	if (req.emr_rc != 0) {
8020c848230SAndrew Rybchenko 		rc = req.emr_rc;
8030c848230SAndrew Rybchenko 		goto fail1;
8040c848230SAndrew Rybchenko 	}
8050c848230SAndrew Rybchenko 
8060c848230SAndrew Rybchenko 	if (req.emr_out_length_used < MC_CMD_LICENSING_OUT_LEN) {
8070c848230SAndrew Rybchenko 		rc = EMSGSIZE;
8080c848230SAndrew Rybchenko 		goto fail2;
8090c848230SAndrew Rybchenko 	}
8100c848230SAndrew Rybchenko 
8110c848230SAndrew Rybchenko 	eksp->eks_valid =
8120c848230SAndrew Rybchenko 		MCDI_OUT_DWORD(req, LICENSING_OUT_VALID_APP_KEYS);
8130c848230SAndrew Rybchenko 	eksp->eks_invalid =
8140c848230SAndrew Rybchenko 		MCDI_OUT_DWORD(req, LICENSING_OUT_INVALID_APP_KEYS);
8150c848230SAndrew Rybchenko 	eksp->eks_blacklisted =
8160c848230SAndrew Rybchenko 		MCDI_OUT_DWORD(req, LICENSING_OUT_BLACKLISTED_APP_KEYS);
8170c848230SAndrew Rybchenko 	eksp->eks_unverifiable =
8180c848230SAndrew Rybchenko 		MCDI_OUT_DWORD(req, LICENSING_OUT_UNVERIFIABLE_APP_KEYS);
8190c848230SAndrew Rybchenko 	eksp->eks_wrong_node =
8200c848230SAndrew Rybchenko 		MCDI_OUT_DWORD(req, LICENSING_OUT_WRONG_NODE_APP_KEYS);
8210c848230SAndrew Rybchenko 	eksp->eks_licensed_apps_lo = 0;
8220c848230SAndrew Rybchenko 	eksp->eks_licensed_apps_hi = 0;
8230c848230SAndrew Rybchenko 	eksp->eks_licensed_features_lo = 0;
8240c848230SAndrew Rybchenko 	eksp->eks_licensed_features_hi = 0;
8250c848230SAndrew Rybchenko 
8260c848230SAndrew Rybchenko 	return (0);
8270c848230SAndrew Rybchenko 
8280c848230SAndrew Rybchenko fail2:
8290c848230SAndrew Rybchenko 	EFSYS_PROBE(fail2);
8300c848230SAndrew Rybchenko fail1:
8310c848230SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
8320c848230SAndrew Rybchenko 
8330c848230SAndrew Rybchenko 	return (rc);
8340c848230SAndrew Rybchenko }
8350c848230SAndrew Rybchenko 
8360c848230SAndrew Rybchenko #endif	/* EFSYS_OPT_HUNTINGTON */
8370c848230SAndrew Rybchenko 
8380c848230SAndrew Rybchenko /* V3 Licensing - used starting from Medford family. See SF-114884-SW */
8390c848230SAndrew Rybchenko 
840ef3b3edeSAndrew Rybchenko #if EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
8410c848230SAndrew Rybchenko 
8420c848230SAndrew Rybchenko static	__checkReturn	efx_rc_t
efx_mcdi_licensing_v3_update_licenses(__in efx_nic_t * enp)8430c848230SAndrew Rybchenko efx_mcdi_licensing_v3_update_licenses(
8440c848230SAndrew Rybchenko 	__in		efx_nic_t *enp)
8450c848230SAndrew Rybchenko {
8460c848230SAndrew Rybchenko 	efx_mcdi_req_t req;
847315bbbaaSAndrew Rybchenko 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_V3_IN_LEN, 0);
8480c848230SAndrew Rybchenko 	efx_rc_t rc;
8490c848230SAndrew Rybchenko 
850ef3b3edeSAndrew Rybchenko 	EFSYS_ASSERT((enp->en_family == EFX_FAMILY_MEDFORD) ||
851ef3b3edeSAndrew Rybchenko 	    (enp->en_family == EFX_FAMILY_MEDFORD2));
8520c848230SAndrew Rybchenko 
8530c848230SAndrew Rybchenko 	req.emr_cmd = MC_CMD_LICENSING_V3;
8540c848230SAndrew Rybchenko 	req.emr_in_buf = payload;
8550c848230SAndrew Rybchenko 	req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN;
8560c848230SAndrew Rybchenko 	req.emr_out_buf = NULL;
8570c848230SAndrew Rybchenko 	req.emr_out_length = 0;
8580c848230SAndrew Rybchenko 
8590c848230SAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP,
8600c848230SAndrew Rybchenko 	    MC_CMD_LICENSING_V3_IN_OP_UPDATE_LICENSE);
8610c848230SAndrew Rybchenko 
8620c848230SAndrew Rybchenko 	efx_mcdi_execute(enp, &req);
8630c848230SAndrew Rybchenko 
8640c848230SAndrew Rybchenko 	if (req.emr_rc != 0) {
8650c848230SAndrew Rybchenko 		rc = req.emr_rc;
8660c848230SAndrew Rybchenko 		goto fail1;
8670c848230SAndrew Rybchenko 	}
8680c848230SAndrew Rybchenko 
8690c848230SAndrew Rybchenko 	return (0);
8700c848230SAndrew Rybchenko 
8710c848230SAndrew Rybchenko fail1:
8720c848230SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
8730c848230SAndrew Rybchenko 
8740c848230SAndrew Rybchenko 	return (rc);
8750c848230SAndrew Rybchenko }
8760c848230SAndrew Rybchenko 
8770c848230SAndrew Rybchenko static	__checkReturn	efx_rc_t
efx_mcdi_licensing_v3_report_license(__in efx_nic_t * enp,__out efx_key_stats_t * eksp)8780c848230SAndrew Rybchenko efx_mcdi_licensing_v3_report_license(
8790c848230SAndrew Rybchenko 	__in		efx_nic_t *enp,
8800c848230SAndrew Rybchenko 	__out		efx_key_stats_t *eksp)
8810c848230SAndrew Rybchenko {
8820c848230SAndrew Rybchenko 	efx_mcdi_req_t req;
883315bbbaaSAndrew Rybchenko 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_V3_IN_LEN,
884315bbbaaSAndrew Rybchenko 		MC_CMD_LICENSING_V3_OUT_LEN);
8850c848230SAndrew Rybchenko 	efx_rc_t rc;
8860c848230SAndrew Rybchenko 
887ef3b3edeSAndrew Rybchenko 	EFSYS_ASSERT((enp->en_family == EFX_FAMILY_MEDFORD) ||
888ef3b3edeSAndrew Rybchenko 	    (enp->en_family == EFX_FAMILY_MEDFORD2));
8890c848230SAndrew Rybchenko 
8900c848230SAndrew Rybchenko 	req.emr_cmd = MC_CMD_LICENSING_V3;
8910c848230SAndrew Rybchenko 	req.emr_in_buf = payload;
8920c848230SAndrew Rybchenko 	req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN;
8930c848230SAndrew Rybchenko 	req.emr_out_buf = payload;
8940c848230SAndrew Rybchenko 	req.emr_out_length = MC_CMD_LICENSING_V3_OUT_LEN;
8950c848230SAndrew Rybchenko 
8960c848230SAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP,
8970c848230SAndrew Rybchenko 	    MC_CMD_LICENSING_V3_IN_OP_REPORT_LICENSE);
8980c848230SAndrew Rybchenko 
899c6190b10SAndrew Rybchenko 	efx_mcdi_execute_quiet(enp, &req);
9000c848230SAndrew Rybchenko 
9010c848230SAndrew Rybchenko 	if (req.emr_rc != 0) {
9020c848230SAndrew Rybchenko 		rc = req.emr_rc;
9030c848230SAndrew Rybchenko 		goto fail1;
9040c848230SAndrew Rybchenko 	}
9050c848230SAndrew Rybchenko 
9060c848230SAndrew Rybchenko 	if (req.emr_out_length_used < MC_CMD_LICENSING_V3_OUT_LEN) {
9070c848230SAndrew Rybchenko 		rc = EMSGSIZE;
9080c848230SAndrew Rybchenko 		goto fail2;
9090c848230SAndrew Rybchenko 	}
9100c848230SAndrew Rybchenko 
9110c848230SAndrew Rybchenko 	eksp->eks_valid =
9120c848230SAndrew Rybchenko 		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_VALID_KEYS);
9130c848230SAndrew Rybchenko 	eksp->eks_invalid =
9140c848230SAndrew Rybchenko 		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_INVALID_KEYS);
9150c848230SAndrew Rybchenko 	eksp->eks_blacklisted = 0;
9160c848230SAndrew Rybchenko 	eksp->eks_unverifiable =
9170c848230SAndrew Rybchenko 		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_UNVERIFIABLE_KEYS);
9180c848230SAndrew Rybchenko 	eksp->eks_wrong_node =
9190c848230SAndrew Rybchenko 		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_WRONG_NODE_KEYS);
9200c848230SAndrew Rybchenko 	eksp->eks_licensed_apps_lo =
9210c848230SAndrew Rybchenko 		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_LO);
9220c848230SAndrew Rybchenko 	eksp->eks_licensed_apps_hi =
9230c848230SAndrew Rybchenko 		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_HI);
9240c848230SAndrew Rybchenko 	eksp->eks_licensed_features_lo =
9250c848230SAndrew Rybchenko 		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_LO);
9260c848230SAndrew Rybchenko 	eksp->eks_licensed_features_hi =
9270c848230SAndrew Rybchenko 		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_HI);
9280c848230SAndrew Rybchenko 
9290c848230SAndrew Rybchenko 	return (0);
9300c848230SAndrew Rybchenko 
9310c848230SAndrew Rybchenko fail2:
9320c848230SAndrew Rybchenko 	EFSYS_PROBE(fail2);
9330c848230SAndrew Rybchenko fail1:
9340c848230SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
9350c848230SAndrew Rybchenko 
9360c848230SAndrew Rybchenko 	return (rc);
9370c848230SAndrew Rybchenko }
9380c848230SAndrew Rybchenko 
9390c848230SAndrew Rybchenko 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)9400c848230SAndrew Rybchenko efx_mcdi_licensing_v3_app_state(
9410c848230SAndrew Rybchenko 	__in		efx_nic_t *enp,
9420c848230SAndrew Rybchenko 	__in		uint64_t app_id,
9430c848230SAndrew Rybchenko 	__out		boolean_t *licensedp)
9440c848230SAndrew Rybchenko {
9450c848230SAndrew Rybchenko 	efx_mcdi_req_t req;
946315bbbaaSAndrew Rybchenko 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN,
947315bbbaaSAndrew Rybchenko 		MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN);
9480c848230SAndrew Rybchenko 	uint32_t app_state;
9490c848230SAndrew Rybchenko 	efx_rc_t rc;
9500c848230SAndrew Rybchenko 
951ef3b3edeSAndrew Rybchenko 	EFSYS_ASSERT((enp->en_family == EFX_FAMILY_MEDFORD) ||
952ef3b3edeSAndrew Rybchenko 	    (enp->en_family == EFX_FAMILY_MEDFORD2));
9530c848230SAndrew Rybchenko 
9540c848230SAndrew Rybchenko 	req.emr_cmd = MC_CMD_GET_LICENSED_V3_APP_STATE;
9550c848230SAndrew Rybchenko 	req.emr_in_buf = payload;
9560c848230SAndrew Rybchenko 	req.emr_in_length = MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN;
9570c848230SAndrew Rybchenko 	req.emr_out_buf = payload;
9580c848230SAndrew Rybchenko 	req.emr_out_length = MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN;
9590c848230SAndrew Rybchenko 
9600c848230SAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_LO,
9610c848230SAndrew Rybchenko 		    app_id & 0xffffffff);
9620c848230SAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_HI,
9630c848230SAndrew Rybchenko 		    app_id >> 32);
9640c848230SAndrew Rybchenko 
9650c848230SAndrew Rybchenko 	efx_mcdi_execute(enp, &req);
9660c848230SAndrew Rybchenko 
9670c848230SAndrew Rybchenko 	if (req.emr_rc != 0) {
9680c848230SAndrew Rybchenko 		rc = req.emr_rc;
9690c848230SAndrew Rybchenko 		goto fail1;
9700c848230SAndrew Rybchenko 	}
9710c848230SAndrew Rybchenko 
97295c45bd0SAndrew Rybchenko 	if (req.emr_out_length_used <
97395c45bd0SAndrew Rybchenko 	    MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN) {
9740c848230SAndrew Rybchenko 		rc = EMSGSIZE;
9750c848230SAndrew Rybchenko 		goto fail2;
9760c848230SAndrew Rybchenko 	}
9770c848230SAndrew Rybchenko 
9780c848230SAndrew Rybchenko 	app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_V3_APP_STATE_OUT_STATE));
9790c848230SAndrew Rybchenko 	if (app_state != MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_NOT_LICENSED) {
9800c848230SAndrew Rybchenko 		*licensedp = B_TRUE;
9810c848230SAndrew Rybchenko 	} else {
9820c848230SAndrew Rybchenko 		*licensedp = B_FALSE;
9830c848230SAndrew Rybchenko 	}
9840c848230SAndrew Rybchenko 
9850c848230SAndrew Rybchenko 	return (0);
9860c848230SAndrew Rybchenko 
9870c848230SAndrew Rybchenko fail2:
9880c848230SAndrew Rybchenko 	EFSYS_PROBE(fail2);
9890c848230SAndrew Rybchenko fail1:
9900c848230SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
9910c848230SAndrew Rybchenko 
9920c848230SAndrew Rybchenko 	return (rc);
9930c848230SAndrew Rybchenko }
9940c848230SAndrew Rybchenko 
9950c848230SAndrew Rybchenko 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)9960c848230SAndrew Rybchenko efx_mcdi_licensing_v3_get_id(
9970c848230SAndrew Rybchenko 	__in		efx_nic_t *enp,
9980c848230SAndrew Rybchenko 	__in		size_t buffer_size,
9990c848230SAndrew Rybchenko 	__out		uint32_t *typep,
10000c848230SAndrew Rybchenko 	__out		size_t *lengthp,
10010c848230SAndrew Rybchenko 	__out_bcount_part_opt(buffer_size, *lengthp)
10020c848230SAndrew Rybchenko 			uint8_t *bufferp)
10030c848230SAndrew Rybchenko {
10040c848230SAndrew Rybchenko 	efx_mcdi_req_t req;
1005315bbbaaSAndrew Rybchenko 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_GET_ID_V3_IN_LEN,
1006*39e58a98SAndrew Rybchenko 		MC_CMD_LICENSING_GET_ID_V3_OUT_LENMAX);
10070c848230SAndrew Rybchenko 	efx_rc_t rc;
10080c848230SAndrew Rybchenko 
10090c848230SAndrew Rybchenko 	req.emr_cmd = MC_CMD_LICENSING_GET_ID_V3;
1010*39e58a98SAndrew Rybchenko 	req.emr_in_buf = payload;
10110c848230SAndrew Rybchenko 	req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN;
1012*39e58a98SAndrew Rybchenko 	req.emr_out_buf = payload;
1013*39e58a98SAndrew Rybchenko 	req.emr_out_length = MC_CMD_LICENSING_GET_ID_V3_OUT_LENMAX;
10140c848230SAndrew Rybchenko 
1015c6190b10SAndrew Rybchenko 	efx_mcdi_execute_quiet(enp, &req);
10160c848230SAndrew Rybchenko 
10170c848230SAndrew Rybchenko 	if (req.emr_rc != 0) {
10180c848230SAndrew Rybchenko 		rc = req.emr_rc;
10190c848230SAndrew Rybchenko 		goto fail1;
10200c848230SAndrew Rybchenko 	}
10210c848230SAndrew Rybchenko 
10220c848230SAndrew Rybchenko 	if (req.emr_out_length_used < MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN) {
10230c848230SAndrew Rybchenko 		rc = EMSGSIZE;
10240c848230SAndrew Rybchenko 		goto fail2;
10250c848230SAndrew Rybchenko 	}
10260c848230SAndrew Rybchenko 
10270c848230SAndrew Rybchenko 	*typep = MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_TYPE);
102895c45bd0SAndrew Rybchenko 	*lengthp =
102995c45bd0SAndrew Rybchenko 	    MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_ID_LENGTH);
10300c848230SAndrew Rybchenko 
1031*39e58a98SAndrew Rybchenko 	if (bufferp != NULL) {
1032*39e58a98SAndrew Rybchenko 		memcpy(bufferp,
1033*39e58a98SAndrew Rybchenko 		    payload + MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST,
1034*39e58a98SAndrew Rybchenko 		    MIN(buffer_size, *lengthp));
10350c848230SAndrew Rybchenko 	}
10360c848230SAndrew Rybchenko 
10370c848230SAndrew Rybchenko 	return (0);
10380c848230SAndrew Rybchenko 
10390c848230SAndrew Rybchenko fail2:
10400c848230SAndrew Rybchenko 	EFSYS_PROBE(fail2);
10410c848230SAndrew Rybchenko fail1:
10420c848230SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
10430c848230SAndrew Rybchenko 
10440c848230SAndrew Rybchenko 	return (rc);
10450c848230SAndrew Rybchenko }
10460c848230SAndrew Rybchenko 
1047fc3a62cfSAndrew Rybchenko /* V3 format uses Huntington TLV format partition. See SF-108797-SW */
1048fc3a62cfSAndrew Rybchenko #define	EFX_LICENSE_V3_KEY_LENGTH_MIN	(64)
1049ff2e27e5SAndrew Rybchenko #define	EFX_LICENSE_V3_KEY_LENGTH_MAX	(160)
1050fc3a62cfSAndrew Rybchenko 
1051fc3a62cfSAndrew Rybchenko 	__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)1052fc3a62cfSAndrew Rybchenko efx_lic_v3_find_start(
1053fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
1054fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
1055fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
1056fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
105795c45bd0SAndrew Rybchenko 	__out			uint32_t *startp)
1058fc3a62cfSAndrew Rybchenko {
1059fc3a62cfSAndrew Rybchenko 	_NOTE(ARGUNUSED(enp))
1060fc3a62cfSAndrew Rybchenko 
106195c45bd0SAndrew Rybchenko 	return (ef10_nvram_buffer_find_item_start(bufferp, buffer_size,
106295c45bd0SAndrew Rybchenko 	    startp));
1063fc3a62cfSAndrew Rybchenko }
1064fc3a62cfSAndrew Rybchenko 
1065fc3a62cfSAndrew Rybchenko 	__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)1066fc3a62cfSAndrew Rybchenko efx_lic_v3_find_end(
1067fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
1068fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
1069fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
1070fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
1071fc3a62cfSAndrew Rybchenko 	__in			uint32_t offset,
107295c45bd0SAndrew Rybchenko 	__out			uint32_t *endp)
1073fc3a62cfSAndrew Rybchenko {
1074fc3a62cfSAndrew Rybchenko 	_NOTE(ARGUNUSED(enp))
1075fc3a62cfSAndrew Rybchenko 
107695c45bd0SAndrew Rybchenko 	return (ef10_nvram_buffer_find_end(bufferp, buffer_size, offset, endp));
1077fc3a62cfSAndrew Rybchenko }
1078fc3a62cfSAndrew Rybchenko 
1079fc3a62cfSAndrew Rybchenko 	__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)1080fc3a62cfSAndrew Rybchenko efx_lic_v3_find_key(
1081fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
1082fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
1083fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
1084fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
1085fc3a62cfSAndrew Rybchenko 	__in			uint32_t offset,
1086fc3a62cfSAndrew Rybchenko 	__out			uint32_t *startp,
108795c45bd0SAndrew Rybchenko 	__out			uint32_t *lengthp)
1088fc3a62cfSAndrew Rybchenko {
1089fc3a62cfSAndrew Rybchenko 	_NOTE(ARGUNUSED(enp))
1090fc3a62cfSAndrew Rybchenko 
1091fc3a62cfSAndrew Rybchenko 	return ef10_nvram_buffer_find_item(bufferp, buffer_size,
1092fc3a62cfSAndrew Rybchenko 	    offset, startp, lengthp);
1093fc3a62cfSAndrew Rybchenko }
1094fc3a62cfSAndrew Rybchenko 
1095fc3a62cfSAndrew Rybchenko 	__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)1096fc3a62cfSAndrew Rybchenko efx_lic_v3_validate_key(
1097fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
1098fc3a62cfSAndrew Rybchenko 	__in_bcount(length)	caddr_t keyp,
109995c45bd0SAndrew Rybchenko 	__in			uint32_t length)
1100fc3a62cfSAndrew Rybchenko {
110175b16fa0SAndrew Rybchenko 	/* Check key is a valid V3 key */
1102fc3a62cfSAndrew Rybchenko 	uint8_t key_type;
1103fc3a62cfSAndrew Rybchenko 	uint8_t key_length;
1104fc3a62cfSAndrew Rybchenko 
1105fc3a62cfSAndrew Rybchenko 	_NOTE(ARGUNUSED(enp))
1106fc3a62cfSAndrew Rybchenko 
1107fc3a62cfSAndrew Rybchenko 	if (length < EFX_LICENSE_V3_KEY_LENGTH_MIN) {
1108fc3a62cfSAndrew Rybchenko 		goto fail1;
1109fc3a62cfSAndrew Rybchenko 	}
1110fc3a62cfSAndrew Rybchenko 
111195c6a821SAndrew Rybchenko 	if (length > EFX_LICENSE_V3_KEY_LENGTH_MAX) {
1112fc3a62cfSAndrew Rybchenko 		goto fail2;
1113fc3a62cfSAndrew Rybchenko 	}
111495c6a821SAndrew Rybchenko 
111595c6a821SAndrew Rybchenko 	key_type = ((uint8_t *)keyp)[0];
111695c6a821SAndrew Rybchenko 	key_length = ((uint8_t *)keyp)[1];
111795c6a821SAndrew Rybchenko 
1118fc3a62cfSAndrew Rybchenko 	if (key_type < 3) {
1119fc3a62cfSAndrew Rybchenko 		goto fail3;
1120fc3a62cfSAndrew Rybchenko 	}
112195c6a821SAndrew Rybchenko 	if (key_length > length) {
1122fc3a62cfSAndrew Rybchenko 		goto fail4;
1123fc3a62cfSAndrew Rybchenko 	}
1124fc3a62cfSAndrew Rybchenko 	return (B_TRUE);
1125fc3a62cfSAndrew Rybchenko 
1126fc3a62cfSAndrew Rybchenko fail4:
1127fc3a62cfSAndrew Rybchenko 	EFSYS_PROBE(fail4);
1128fc3a62cfSAndrew Rybchenko fail3:
1129fc3a62cfSAndrew Rybchenko 	EFSYS_PROBE(fail3);
1130fc3a62cfSAndrew Rybchenko fail2:
1131fc3a62cfSAndrew Rybchenko 	EFSYS_PROBE(fail2);
1132fc3a62cfSAndrew Rybchenko fail1:
113379ddc224SAndrew Rybchenko 	EFSYS_PROBE1(fail1, boolean_t, B_FALSE);
1134fc3a62cfSAndrew Rybchenko 
1135fc3a62cfSAndrew Rybchenko 	return (B_FALSE);
1136fc3a62cfSAndrew Rybchenko }
1137fc3a62cfSAndrew Rybchenko 
1138fc3a62cfSAndrew Rybchenko 	__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)1139fc3a62cfSAndrew Rybchenko efx_lic_v3_read_key(
1140fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
1141fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
1142fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
1143fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
1144fc3a62cfSAndrew Rybchenko 	__in			uint32_t offset,
1145fc3a62cfSAndrew Rybchenko 	__in			uint32_t length,
1146fc3a62cfSAndrew Rybchenko 	__out_bcount_part(key_max_size, *lengthp)
1147fc3a62cfSAndrew Rybchenko 				caddr_t keyp,
1148fc3a62cfSAndrew Rybchenko 	__in			size_t key_max_size,
114995c45bd0SAndrew Rybchenko 	__out			uint32_t *lengthp)
1150fc3a62cfSAndrew Rybchenko {
1151e919b7ecSAndrew Rybchenko 	uint32_t tag;
1152e919b7ecSAndrew Rybchenko 
1153fc3a62cfSAndrew Rybchenko 	_NOTE(ARGUNUSED(enp))
1154fc3a62cfSAndrew Rybchenko 
1155fc3a62cfSAndrew Rybchenko 	return ef10_nvram_buffer_get_item(bufferp, buffer_size,
1156e919b7ecSAndrew Rybchenko 		    offset, length, &tag, keyp, key_max_size, lengthp);
1157fc3a62cfSAndrew Rybchenko }
1158fc3a62cfSAndrew Rybchenko 
1159fc3a62cfSAndrew Rybchenko 	__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)1160fc3a62cfSAndrew Rybchenko efx_lic_v3_write_key(
1161fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
1162fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
1163fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
1164fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
1165fc3a62cfSAndrew Rybchenko 	__in			uint32_t offset,
1166fc3a62cfSAndrew Rybchenko 	__in_bcount(length)	caddr_t keyp,
1167fc3a62cfSAndrew Rybchenko 	__in			uint32_t length,
116895c45bd0SAndrew Rybchenko 	__out			uint32_t *lengthp)
1169fc3a62cfSAndrew Rybchenko {
1170fc3a62cfSAndrew Rybchenko 	_NOTE(ARGUNUSED(enp))
1171fc3a62cfSAndrew Rybchenko 	EFSYS_ASSERT(length <= EFX_LICENSE_V3_KEY_LENGTH_MAX);
1172fc3a62cfSAndrew Rybchenko 
1173fc3a62cfSAndrew Rybchenko 	return ef10_nvram_buffer_insert_item(bufferp, buffer_size,
1174e919b7ecSAndrew Rybchenko 		    offset, TLV_TAG_LICENSE, keyp, length, lengthp);
1175fc3a62cfSAndrew Rybchenko }
1176fc3a62cfSAndrew Rybchenko 
1177fc3a62cfSAndrew Rybchenko 	__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)1178fc3a62cfSAndrew Rybchenko efx_lic_v3_delete_key(
1179fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
1180fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
1181fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
1182fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
1183fc3a62cfSAndrew Rybchenko 	__in			uint32_t offset,
1184fc3a62cfSAndrew Rybchenko 	__in			uint32_t length,
1185fc3a62cfSAndrew Rybchenko 	__in			uint32_t end,
118695c45bd0SAndrew Rybchenko 	__out			uint32_t *deltap)
1187fc3a62cfSAndrew Rybchenko {
1188fc3a62cfSAndrew Rybchenko 	efx_rc_t rc;
1189fc3a62cfSAndrew Rybchenko 
1190fc3a62cfSAndrew Rybchenko 	_NOTE(ARGUNUSED(enp))
1191fc3a62cfSAndrew Rybchenko 
1192fc3a62cfSAndrew Rybchenko 	if ((rc = ef10_nvram_buffer_delete_item(bufferp,
1193fc3a62cfSAndrew Rybchenko 			buffer_size, offset, length, end)) != 0) {
1194fc3a62cfSAndrew Rybchenko 		goto fail1;
1195fc3a62cfSAndrew Rybchenko 	}
1196fc3a62cfSAndrew Rybchenko 
1197fc3a62cfSAndrew Rybchenko 	*deltap = length;
1198fc3a62cfSAndrew Rybchenko 
1199fc3a62cfSAndrew Rybchenko 	return (0);
1200fc3a62cfSAndrew Rybchenko 
1201fc3a62cfSAndrew Rybchenko fail1:
1202fc3a62cfSAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1203fc3a62cfSAndrew Rybchenko 
1204fc3a62cfSAndrew Rybchenko 	return (rc);
1205fc3a62cfSAndrew Rybchenko }
1206fc3a62cfSAndrew Rybchenko 
1207fc3a62cfSAndrew Rybchenko 	__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)1208fc3a62cfSAndrew Rybchenko efx_lic_v3_create_partition(
1209fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
1210fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
1211fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
121295c45bd0SAndrew Rybchenko 	__in			size_t buffer_size)
1213fc3a62cfSAndrew Rybchenko {
1214fc3a62cfSAndrew Rybchenko 	efx_rc_t rc;
1215fc3a62cfSAndrew Rybchenko 
1216e919b7ecSAndrew Rybchenko 	_NOTE(ARGUNUSED(enp))
1217e919b7ecSAndrew Rybchenko 
121875b16fa0SAndrew Rybchenko 	/* Construct empty partition */
1219e919b7ecSAndrew Rybchenko 	if ((rc = ef10_nvram_buffer_create(
1220fc3a62cfSAndrew Rybchenko 	    NVRAM_PARTITION_TYPE_LICENSE,
1221fc3a62cfSAndrew Rybchenko 	    bufferp, buffer_size)) != 0) {
1222fc3a62cfSAndrew Rybchenko 		rc = EFAULT;
1223fc3a62cfSAndrew Rybchenko 		goto fail1;
1224fc3a62cfSAndrew Rybchenko 	}
1225fc3a62cfSAndrew Rybchenko 
1226fc3a62cfSAndrew Rybchenko 	return (0);
1227fc3a62cfSAndrew Rybchenko 
1228fc3a62cfSAndrew Rybchenko fail1:
1229fc3a62cfSAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1230fc3a62cfSAndrew Rybchenko 
1231fc3a62cfSAndrew Rybchenko 	return (rc);
1232fc3a62cfSAndrew Rybchenko }
1233fc3a62cfSAndrew Rybchenko 
1234fc3a62cfSAndrew Rybchenko 	__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)1235fc3a62cfSAndrew Rybchenko efx_lic_v3_finish_partition(
1236fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
1237fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
1238fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
123995c45bd0SAndrew Rybchenko 	__in			size_t buffer_size)
1240fc3a62cfSAndrew Rybchenko {
1241fc3a62cfSAndrew Rybchenko 	efx_rc_t rc;
1242fc3a62cfSAndrew Rybchenko 
1243e919b7ecSAndrew Rybchenko 	_NOTE(ARGUNUSED(enp))
1244e919b7ecSAndrew Rybchenko 
1245fc3a62cfSAndrew Rybchenko 	if ((rc = ef10_nvram_buffer_finish(bufferp,
1246fc3a62cfSAndrew Rybchenko 			buffer_size)) != 0) {
1247fc3a62cfSAndrew Rybchenko 		goto fail1;
1248fc3a62cfSAndrew Rybchenko 	}
1249fc3a62cfSAndrew Rybchenko 
125075b16fa0SAndrew Rybchenko 	/* Validate completed partition */
1251e919b7ecSAndrew Rybchenko 	if ((rc = ef10_nvram_buffer_validate(
1252e919b7ecSAndrew Rybchenko 					NVRAM_PARTITION_TYPE_LICENSE,
1253fc3a62cfSAndrew Rybchenko 					bufferp, buffer_size)) != 0) {
1254fc3a62cfSAndrew Rybchenko 		goto fail2;
1255fc3a62cfSAndrew Rybchenko 	}
1256fc3a62cfSAndrew Rybchenko 
1257fc3a62cfSAndrew Rybchenko 	return (0);
1258fc3a62cfSAndrew Rybchenko 
1259fc3a62cfSAndrew Rybchenko fail2:
1260fc3a62cfSAndrew Rybchenko 	EFSYS_PROBE(fail2);
1261fc3a62cfSAndrew Rybchenko fail1:
1262fc3a62cfSAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1263fc3a62cfSAndrew Rybchenko 
1264fc3a62cfSAndrew Rybchenko 	return (rc);
1265fc3a62cfSAndrew Rybchenko }
1266fc3a62cfSAndrew Rybchenko 
1267ef3b3edeSAndrew Rybchenko #endif	/* EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
12680c848230SAndrew Rybchenko 
12690c848230SAndrew Rybchenko 	__checkReturn		efx_rc_t
efx_lic_init(__in efx_nic_t * enp)12700c848230SAndrew Rybchenko efx_lic_init(
12710c848230SAndrew Rybchenko 	__in			efx_nic_t *enp)
12720c848230SAndrew Rybchenko {
1273ec831f7fSAndrew Rybchenko 	const efx_lic_ops_t *elop;
12745df3232cSAndrew Rybchenko 	efx_key_stats_t eks;
12750c848230SAndrew Rybchenko 	efx_rc_t rc;
12760c848230SAndrew Rybchenko 
12770c848230SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
12780c848230SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
12790c848230SAndrew Rybchenko 	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_LIC));
12800c848230SAndrew Rybchenko 
12810c848230SAndrew Rybchenko 	switch (enp->en_family) {
12820c848230SAndrew Rybchenko #if EFSYS_OPT_SIENA
12830c848230SAndrew Rybchenko 	case EFX_FAMILY_SIENA:
1284ec831f7fSAndrew Rybchenko 		elop = &__efx_lic_v1_ops;
12850c848230SAndrew Rybchenko 		break;
12860c848230SAndrew Rybchenko #endif	/* EFSYS_OPT_SIENA */
12870c848230SAndrew Rybchenko 
12880c848230SAndrew Rybchenko #if EFSYS_OPT_HUNTINGTON
12890c848230SAndrew Rybchenko 	case EFX_FAMILY_HUNTINGTON:
1290ec831f7fSAndrew Rybchenko 		elop = &__efx_lic_v2_ops;
12910c848230SAndrew Rybchenko 		break;
12920c848230SAndrew Rybchenko #endif	/* EFSYS_OPT_HUNTINGTON */
12930c848230SAndrew Rybchenko 
12940c848230SAndrew Rybchenko #if EFSYS_OPT_MEDFORD
12950c848230SAndrew Rybchenko 	case EFX_FAMILY_MEDFORD:
1296ec831f7fSAndrew Rybchenko 		elop = &__efx_lic_v3_ops;
12970c848230SAndrew Rybchenko 		break;
12980c848230SAndrew Rybchenko #endif	/* EFSYS_OPT_MEDFORD */
12990c848230SAndrew Rybchenko 
1300ef3b3edeSAndrew Rybchenko #if EFSYS_OPT_MEDFORD2
1301ef3b3edeSAndrew Rybchenko 	case EFX_FAMILY_MEDFORD2:
1302ef3b3edeSAndrew Rybchenko 		elop = &__efx_lic_v3_ops;
1303ef3b3edeSAndrew Rybchenko 		break;
1304ef3b3edeSAndrew Rybchenko #endif	/* EFSYS_OPT_MEDFORD2 */
1305ef3b3edeSAndrew Rybchenko 
13060c848230SAndrew Rybchenko 	default:
13070c848230SAndrew Rybchenko 		EFSYS_ASSERT(0);
13080c848230SAndrew Rybchenko 		rc = ENOTSUP;
13090c848230SAndrew Rybchenko 		goto fail1;
13100c848230SAndrew Rybchenko 	}
13110c848230SAndrew Rybchenko 
13120c848230SAndrew Rybchenko 	enp->en_elop = elop;
13130c848230SAndrew Rybchenko 	enp->en_mod_flags |= EFX_MOD_LIC;
13140c848230SAndrew Rybchenko 
13155df3232cSAndrew Rybchenko 	/* Probe for support */
13165df3232cSAndrew Rybchenko 	if (efx_lic_get_key_stats(enp, &eks) == 0) {
13175df3232cSAndrew Rybchenko 		enp->en_licensing_supported = B_TRUE;
13185df3232cSAndrew Rybchenko 	} else {
13195df3232cSAndrew Rybchenko 		enp->en_licensing_supported = B_FALSE;
13205df3232cSAndrew Rybchenko 	}
13215df3232cSAndrew Rybchenko 
13220c848230SAndrew Rybchenko 	return (0);
13230c848230SAndrew Rybchenko 
13240c848230SAndrew Rybchenko fail1:
13250c848230SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
13260c848230SAndrew Rybchenko 
13270c848230SAndrew Rybchenko 	return (rc);
13280c848230SAndrew Rybchenko }
13290c848230SAndrew Rybchenko 
13305df3232cSAndrew Rybchenko extern	__checkReturn	boolean_t
efx_lic_check_support(__in efx_nic_t * enp)13315df3232cSAndrew Rybchenko efx_lic_check_support(
13325df3232cSAndrew Rybchenko 	__in			efx_nic_t *enp)
13335df3232cSAndrew Rybchenko {
13345df3232cSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
13355df3232cSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
13365df3232cSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
13375df3232cSAndrew Rybchenko 
133895c45bd0SAndrew Rybchenko 	return (enp->en_licensing_supported);
13395df3232cSAndrew Rybchenko }
13405df3232cSAndrew Rybchenko 
13410c848230SAndrew Rybchenko 				void
efx_lic_fini(__in efx_nic_t * enp)13420c848230SAndrew Rybchenko efx_lic_fini(
13430c848230SAndrew Rybchenko 	__in			efx_nic_t *enp)
13440c848230SAndrew Rybchenko {
13450c848230SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
13460c848230SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
13470c848230SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
13480c848230SAndrew Rybchenko 
13490c848230SAndrew Rybchenko 	enp->en_elop = NULL;
13500c848230SAndrew Rybchenko 	enp->en_mod_flags &= ~EFX_MOD_LIC;
13510c848230SAndrew Rybchenko }
13520c848230SAndrew Rybchenko 
13530c848230SAndrew Rybchenko 	__checkReturn	efx_rc_t
efx_lic_update_licenses(__in efx_nic_t * enp)13540c848230SAndrew Rybchenko efx_lic_update_licenses(
13550c848230SAndrew Rybchenko 	__in		efx_nic_t *enp)
13560c848230SAndrew Rybchenko {
1357ec831f7fSAndrew Rybchenko 	const efx_lic_ops_t *elop = enp->en_elop;
13580c848230SAndrew Rybchenko 	efx_rc_t rc;
13590c848230SAndrew Rybchenko 
13600c848230SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
13610c848230SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
13620c848230SAndrew Rybchenko 
13630c848230SAndrew Rybchenko 	if ((rc = elop->elo_update_licenses(enp)) != 0)
13640c848230SAndrew Rybchenko 		goto fail1;
13650c848230SAndrew Rybchenko 
13660c848230SAndrew Rybchenko 	return (0);
13670c848230SAndrew Rybchenko 
13680c848230SAndrew Rybchenko fail1:
13690c848230SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
13700c848230SAndrew Rybchenko 
13710c848230SAndrew Rybchenko 	return (rc);
13720c848230SAndrew Rybchenko }
13730c848230SAndrew Rybchenko 
13740c848230SAndrew Rybchenko 	__checkReturn	efx_rc_t
efx_lic_get_key_stats(__in efx_nic_t * enp,__out efx_key_stats_t * eksp)13750c848230SAndrew Rybchenko efx_lic_get_key_stats(
13760c848230SAndrew Rybchenko 	__in		efx_nic_t *enp,
13770c848230SAndrew Rybchenko 	__out		efx_key_stats_t *eksp)
13780c848230SAndrew Rybchenko {
1379ec831f7fSAndrew Rybchenko 	const efx_lic_ops_t *elop = enp->en_elop;
13800c848230SAndrew Rybchenko 	efx_rc_t rc;
13810c848230SAndrew Rybchenko 
13820c848230SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
13830c848230SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
13840c848230SAndrew Rybchenko 
13850c848230SAndrew Rybchenko 	if ((rc = elop->elo_get_key_stats(enp, eksp)) != 0)
13860c848230SAndrew Rybchenko 		goto fail1;
13870c848230SAndrew Rybchenko 
13880c848230SAndrew Rybchenko 	return (0);
13890c848230SAndrew Rybchenko 
13900c848230SAndrew Rybchenko fail1:
13910c848230SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
13920c848230SAndrew Rybchenko 
13930c848230SAndrew Rybchenko 	return (rc);
13940c848230SAndrew Rybchenko }
13950c848230SAndrew Rybchenko 
13960c848230SAndrew Rybchenko 	__checkReturn	efx_rc_t
efx_lic_app_state(__in efx_nic_t * enp,__in uint64_t app_id,__out boolean_t * licensedp)13970c848230SAndrew Rybchenko efx_lic_app_state(
13980c848230SAndrew Rybchenko 	__in		efx_nic_t *enp,
13990c848230SAndrew Rybchenko 	__in		uint64_t app_id,
14000c848230SAndrew Rybchenko 	__out		boolean_t *licensedp)
14010c848230SAndrew Rybchenko {
1402ec831f7fSAndrew Rybchenko 	const efx_lic_ops_t *elop = enp->en_elop;
14030c848230SAndrew Rybchenko 	efx_rc_t rc;
14040c848230SAndrew Rybchenko 
14050c848230SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
14060c848230SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
14070c848230SAndrew Rybchenko 
14087d4ce67aSAndrew Rybchenko 	if (elop->elo_app_state == NULL)
14097d4ce67aSAndrew Rybchenko 		return (ENOTSUP);
14107d4ce67aSAndrew Rybchenko 
14110c848230SAndrew Rybchenko 	if ((rc = elop->elo_app_state(enp, app_id, licensedp)) != 0)
14127d4ce67aSAndrew Rybchenko 		goto fail1;
14130c848230SAndrew Rybchenko 
14140c848230SAndrew Rybchenko 	return (0);
14150c848230SAndrew Rybchenko 
14160c848230SAndrew Rybchenko fail1:
14170c848230SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
14180c848230SAndrew Rybchenko 
14190c848230SAndrew Rybchenko 	return (rc);
14200c848230SAndrew Rybchenko }
14210c848230SAndrew Rybchenko 
14220c848230SAndrew Rybchenko 	__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)14230c848230SAndrew Rybchenko efx_lic_get_id(
14240c848230SAndrew Rybchenko 	__in		efx_nic_t *enp,
14250c848230SAndrew Rybchenko 	__in		size_t buffer_size,
14260c848230SAndrew Rybchenko 	__out		uint32_t *typep,
14270c848230SAndrew Rybchenko 	__out		size_t *lengthp,
142895c45bd0SAndrew Rybchenko 	__out_opt	uint8_t *bufferp)
14290c848230SAndrew Rybchenko {
1430ec831f7fSAndrew Rybchenko 	const efx_lic_ops_t *elop = enp->en_elop;
14310c848230SAndrew Rybchenko 	efx_rc_t rc;
14320c848230SAndrew Rybchenko 
14330c848230SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
14340c848230SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
14350c848230SAndrew Rybchenko 
14367d4ce67aSAndrew Rybchenko 	if (elop->elo_get_id == NULL)
14377d4ce67aSAndrew Rybchenko 		return (ENOTSUP);
14380c848230SAndrew Rybchenko 
14390c848230SAndrew Rybchenko 	if ((rc = elop->elo_get_id(enp, buffer_size, typep,
14400c848230SAndrew Rybchenko 				    lengthp, bufferp)) != 0)
14417d4ce67aSAndrew Rybchenko 		goto fail1;
14420c848230SAndrew Rybchenko 
14430c848230SAndrew Rybchenko 	return (0);
14440c848230SAndrew Rybchenko 
14450c848230SAndrew Rybchenko fail1:
14460c848230SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
14470c848230SAndrew Rybchenko 
14480c848230SAndrew Rybchenko 	return (rc);
14490c848230SAndrew Rybchenko }
14500c848230SAndrew Rybchenko 
145195c45bd0SAndrew Rybchenko /*
145295c45bd0SAndrew Rybchenko  * Buffer management API - abstracts varying TLV format used for License
145395c45bd0SAndrew Rybchenko  * partition.
145495c45bd0SAndrew Rybchenko  */
1455fc3a62cfSAndrew Rybchenko 
1456fc3a62cfSAndrew Rybchenko 	__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)1457fc3a62cfSAndrew Rybchenko efx_lic_find_start(
1458fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
1459fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
1460fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
1461fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
146295c45bd0SAndrew Rybchenko 	__out			uint32_t *startp)
1463fc3a62cfSAndrew Rybchenko {
1464fc3a62cfSAndrew Rybchenko 	const efx_lic_ops_t *elop = enp->en_elop;
1465fc3a62cfSAndrew Rybchenko 	efx_rc_t rc;
1466fc3a62cfSAndrew Rybchenko 
1467fc3a62cfSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1468fc3a62cfSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1469fc3a62cfSAndrew Rybchenko 
1470fc3a62cfSAndrew Rybchenko 	if ((rc = elop->elo_find_start(enp, bufferp, buffer_size, startp)) != 0)
1471fc3a62cfSAndrew Rybchenko 		goto fail1;
1472fc3a62cfSAndrew Rybchenko 
1473fc3a62cfSAndrew Rybchenko 	return (0);
1474fc3a62cfSAndrew Rybchenko 
1475fc3a62cfSAndrew Rybchenko fail1:
1476fc3a62cfSAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1477fc3a62cfSAndrew Rybchenko 
1478fc3a62cfSAndrew Rybchenko 	return (rc);
1479fc3a62cfSAndrew Rybchenko }
1480fc3a62cfSAndrew Rybchenko 
1481fc3a62cfSAndrew Rybchenko 	__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)1482fc3a62cfSAndrew Rybchenko efx_lic_find_end(
1483fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
1484fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
1485fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
1486fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
1487fc3a62cfSAndrew Rybchenko 	__in			uint32_t offset,
148895c45bd0SAndrew Rybchenko 	__out			uint32_t *endp)
1489fc3a62cfSAndrew Rybchenko {
1490fc3a62cfSAndrew Rybchenko 	const efx_lic_ops_t *elop = enp->en_elop;
1491fc3a62cfSAndrew Rybchenko 	efx_rc_t rc;
1492fc3a62cfSAndrew Rybchenko 
1493fc3a62cfSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1494fc3a62cfSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1495fc3a62cfSAndrew Rybchenko 
149695c45bd0SAndrew Rybchenko 	rc = elop->elo_find_end(enp, bufferp, buffer_size, offset, endp);
149795c45bd0SAndrew Rybchenko 	if (rc != 0)
1498fc3a62cfSAndrew Rybchenko 		goto fail1;
1499fc3a62cfSAndrew Rybchenko 
1500fc3a62cfSAndrew Rybchenko 	return (0);
1501fc3a62cfSAndrew Rybchenko 
1502fc3a62cfSAndrew Rybchenko fail1:
1503fc3a62cfSAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1504fc3a62cfSAndrew Rybchenko 
1505fc3a62cfSAndrew Rybchenko 	return (rc);
1506fc3a62cfSAndrew Rybchenko }
1507fc3a62cfSAndrew Rybchenko 
1508fc3a62cfSAndrew Rybchenko 	__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)1509fc3a62cfSAndrew Rybchenko efx_lic_find_key(
1510fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
1511fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
1512fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
1513fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
1514fc3a62cfSAndrew Rybchenko 	__in			uint32_t offset,
1515fc3a62cfSAndrew Rybchenko 	__out			uint32_t *startp,
151695c45bd0SAndrew Rybchenko 	__out			uint32_t *lengthp)
1517fc3a62cfSAndrew Rybchenko {
1518fc3a62cfSAndrew Rybchenko 	const efx_lic_ops_t *elop = enp->en_elop;
1519fc3a62cfSAndrew Rybchenko 
1520fc3a62cfSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1521fc3a62cfSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1522fc3a62cfSAndrew Rybchenko 
1523fc3a62cfSAndrew Rybchenko 	EFSYS_ASSERT(bufferp);
1524fc3a62cfSAndrew Rybchenko 	EFSYS_ASSERT(startp);
1525fc3a62cfSAndrew Rybchenko 	EFSYS_ASSERT(lengthp);
1526fc3a62cfSAndrew Rybchenko 
1527fc3a62cfSAndrew Rybchenko 	return (elop->elo_find_key(enp, bufferp, buffer_size, offset,
1528fc3a62cfSAndrew Rybchenko 				    startp, lengthp));
1529fc3a62cfSAndrew Rybchenko }
1530fc3a62cfSAndrew Rybchenko 
153195c45bd0SAndrew Rybchenko /*
153295c45bd0SAndrew Rybchenko  * Validate that the buffer contains a single key in a recognised format.
153395c45bd0SAndrew Rybchenko  * An empty or terminator buffer is not accepted as a valid key.
1534fc3a62cfSAndrew Rybchenko  */
1535fc3a62cfSAndrew Rybchenko 	__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)1536fc3a62cfSAndrew Rybchenko efx_lic_validate_key(
1537fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
1538fc3a62cfSAndrew Rybchenko 	__in_bcount(length)	caddr_t keyp,
153995c45bd0SAndrew Rybchenko 	__in			uint32_t length)
1540fc3a62cfSAndrew Rybchenko {
1541fc3a62cfSAndrew Rybchenko 	const efx_lic_ops_t *elop = enp->en_elop;
1542fc3a62cfSAndrew Rybchenko 	boolean_t rc;
1543fc3a62cfSAndrew Rybchenko 
1544fc3a62cfSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1545fc3a62cfSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1546fc3a62cfSAndrew Rybchenko 
1547fc3a62cfSAndrew Rybchenko 	if ((rc = elop->elo_validate_key(enp, keyp, length)) == B_FALSE)
1548fc3a62cfSAndrew Rybchenko 		goto fail1;
1549fc3a62cfSAndrew Rybchenko 
1550fc3a62cfSAndrew Rybchenko 	return (B_TRUE);
1551fc3a62cfSAndrew Rybchenko 
1552fc3a62cfSAndrew Rybchenko fail1:
1553fc3a62cfSAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1554fc3a62cfSAndrew Rybchenko 
1555fc3a62cfSAndrew Rybchenko 	return (rc);
1556fc3a62cfSAndrew Rybchenko }
1557fc3a62cfSAndrew Rybchenko 
1558fc3a62cfSAndrew Rybchenko 	__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)1559fc3a62cfSAndrew Rybchenko efx_lic_read_key(
1560fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
1561fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
1562fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
1563fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
1564fc3a62cfSAndrew Rybchenko 	__in			uint32_t offset,
1565fc3a62cfSAndrew Rybchenko 	__in			uint32_t length,
1566fc3a62cfSAndrew Rybchenko 	__out_bcount_part(key_max_size, *lengthp)
1567fc3a62cfSAndrew Rybchenko 				caddr_t keyp,
1568fc3a62cfSAndrew Rybchenko 	__in			size_t key_max_size,
156995c45bd0SAndrew Rybchenko 	__out			uint32_t *lengthp)
1570fc3a62cfSAndrew Rybchenko {
1571fc3a62cfSAndrew Rybchenko 	const efx_lic_ops_t *elop = enp->en_elop;
1572fc3a62cfSAndrew Rybchenko 	efx_rc_t rc;
1573fc3a62cfSAndrew Rybchenko 
1574fc3a62cfSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1575fc3a62cfSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1576fc3a62cfSAndrew Rybchenko 
1577fc3a62cfSAndrew Rybchenko 	if ((rc = elop->elo_read_key(enp, bufferp, buffer_size, offset,
1578fc3a62cfSAndrew Rybchenko 				    length, keyp, key_max_size, lengthp)) != 0)
1579fc3a62cfSAndrew Rybchenko 		goto fail1;
1580fc3a62cfSAndrew Rybchenko 
1581fc3a62cfSAndrew Rybchenko 	return (0);
1582fc3a62cfSAndrew Rybchenko 
1583fc3a62cfSAndrew Rybchenko fail1:
1584fc3a62cfSAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1585fc3a62cfSAndrew Rybchenko 
1586fc3a62cfSAndrew Rybchenko 	return (rc);
1587fc3a62cfSAndrew Rybchenko }
1588fc3a62cfSAndrew Rybchenko 
1589fc3a62cfSAndrew Rybchenko 	__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)1590fc3a62cfSAndrew Rybchenko efx_lic_write_key(
1591fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
1592fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
1593fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
1594fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
1595fc3a62cfSAndrew Rybchenko 	__in			uint32_t offset,
1596fc3a62cfSAndrew Rybchenko 	__in_bcount(length)	caddr_t keyp,
1597fc3a62cfSAndrew Rybchenko 	__in			uint32_t length,
159895c45bd0SAndrew Rybchenko 	__out			uint32_t *lengthp)
1599fc3a62cfSAndrew Rybchenko {
1600fc3a62cfSAndrew Rybchenko 	const efx_lic_ops_t *elop = enp->en_elop;
1601fc3a62cfSAndrew Rybchenko 	efx_rc_t rc;
1602fc3a62cfSAndrew Rybchenko 
1603fc3a62cfSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1604fc3a62cfSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1605fc3a62cfSAndrew Rybchenko 
1606fc3a62cfSAndrew Rybchenko 	if ((rc = elop->elo_write_key(enp, bufferp, buffer_size, offset,
1607fc3a62cfSAndrew Rybchenko 				    keyp, length, lengthp)) != 0)
1608fc3a62cfSAndrew Rybchenko 		goto fail1;
1609fc3a62cfSAndrew Rybchenko 
1610fc3a62cfSAndrew Rybchenko 	return (0);
1611fc3a62cfSAndrew Rybchenko 
1612fc3a62cfSAndrew Rybchenko fail1:
1613fc3a62cfSAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1614fc3a62cfSAndrew Rybchenko 
1615fc3a62cfSAndrew Rybchenko 	return (rc);
1616fc3a62cfSAndrew Rybchenko }
1617fc3a62cfSAndrew Rybchenko 
1618fc3a62cfSAndrew Rybchenko 	__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)1619fc3a62cfSAndrew Rybchenko efx_lic_delete_key(
1620fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
1621fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
1622fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
1623fc3a62cfSAndrew Rybchenko 	__in			size_t buffer_size,
1624fc3a62cfSAndrew Rybchenko 	__in			uint32_t offset,
1625fc3a62cfSAndrew Rybchenko 	__in			uint32_t length,
1626fc3a62cfSAndrew Rybchenko 	__in			uint32_t end,
162795c45bd0SAndrew Rybchenko 	__out			uint32_t *deltap)
1628fc3a62cfSAndrew Rybchenko {
1629fc3a62cfSAndrew Rybchenko 	const efx_lic_ops_t *elop = enp->en_elop;
1630fc3a62cfSAndrew Rybchenko 	efx_rc_t rc;
1631fc3a62cfSAndrew Rybchenko 
1632fc3a62cfSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1633fc3a62cfSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1634fc3a62cfSAndrew Rybchenko 
1635fc3a62cfSAndrew Rybchenko 	if ((rc = elop->elo_delete_key(enp, bufferp, buffer_size, offset,
1636fc3a62cfSAndrew Rybchenko 				    length, end, deltap)) != 0)
1637fc3a62cfSAndrew Rybchenko 		goto fail1;
1638fc3a62cfSAndrew Rybchenko 
1639fc3a62cfSAndrew Rybchenko 	return (0);
1640fc3a62cfSAndrew Rybchenko 
1641fc3a62cfSAndrew Rybchenko fail1:
1642fc3a62cfSAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1643fc3a62cfSAndrew Rybchenko 
1644fc3a62cfSAndrew Rybchenko 	return (rc);
1645fc3a62cfSAndrew Rybchenko }
1646fc3a62cfSAndrew Rybchenko 
1647fc3a62cfSAndrew Rybchenko 	__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)1648fc3a62cfSAndrew Rybchenko efx_lic_create_partition(
1649fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
1650fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
1651fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
165295c45bd0SAndrew Rybchenko 	__in			size_t buffer_size)
1653fc3a62cfSAndrew Rybchenko {
1654fc3a62cfSAndrew Rybchenko 	const efx_lic_ops_t *elop = enp->en_elop;
1655fc3a62cfSAndrew Rybchenko 	efx_rc_t rc;
1656fc3a62cfSAndrew Rybchenko 
1657fc3a62cfSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1658fc3a62cfSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1659fc3a62cfSAndrew Rybchenko 
1660fc3a62cfSAndrew Rybchenko 	if ((rc = elop->elo_create_partition(enp, bufferp, buffer_size)) != 0)
1661fc3a62cfSAndrew Rybchenko 		goto fail1;
1662fc3a62cfSAndrew Rybchenko 
1663fc3a62cfSAndrew Rybchenko 	return (0);
1664fc3a62cfSAndrew Rybchenko 
1665fc3a62cfSAndrew Rybchenko fail1:
1666fc3a62cfSAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1667fc3a62cfSAndrew Rybchenko 
1668fc3a62cfSAndrew Rybchenko 	return (rc);
1669fc3a62cfSAndrew Rybchenko }
1670fc3a62cfSAndrew Rybchenko 
1671fc3a62cfSAndrew Rybchenko 	__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)1672fc3a62cfSAndrew Rybchenko efx_lic_finish_partition(
1673fc3a62cfSAndrew Rybchenko 	__in			efx_nic_t *enp,
1674fc3a62cfSAndrew Rybchenko 	__in_bcount(buffer_size)
1675fc3a62cfSAndrew Rybchenko 				caddr_t bufferp,
167695c45bd0SAndrew Rybchenko 	__in			size_t buffer_size)
1677fc3a62cfSAndrew Rybchenko {
1678fc3a62cfSAndrew Rybchenko 	const efx_lic_ops_t *elop = enp->en_elop;
1679fc3a62cfSAndrew Rybchenko 	efx_rc_t rc;
1680fc3a62cfSAndrew Rybchenko 
1681fc3a62cfSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1682fc3a62cfSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1683fc3a62cfSAndrew Rybchenko 
1684fc3a62cfSAndrew Rybchenko 	if ((rc = elop->elo_finish_partition(enp, bufferp, buffer_size)) != 0)
1685fc3a62cfSAndrew Rybchenko 		goto fail1;
1686fc3a62cfSAndrew Rybchenko 
1687fc3a62cfSAndrew Rybchenko 	return (0);
1688fc3a62cfSAndrew Rybchenko 
1689fc3a62cfSAndrew Rybchenko fail1:
1690fc3a62cfSAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1691fc3a62cfSAndrew Rybchenko 
1692fc3a62cfSAndrew Rybchenko 	return (rc);
1693fc3a62cfSAndrew Rybchenko }
1694fc3a62cfSAndrew Rybchenko 
16950c848230SAndrew Rybchenko #endif	/* EFSYS_OPT_LICENSING */
1696