efx_lic.c revision 342426
1293901Sarybchik/*-
2300607Sarybchik * Copyright (c) 2009-2016 Solarflare Communications Inc.
3293901Sarybchik * All rights reserved.
4293901Sarybchik *
5293901Sarybchik * Redistribution and use in source and binary forms, with or without
6293901Sarybchik * modification, are permitted provided that the following conditions are met:
7293901Sarybchik *
8293901Sarybchik * 1. Redistributions of source code must retain the above copyright notice,
9293901Sarybchik *    this list of conditions and the following disclaimer.
10293901Sarybchik * 2. Redistributions in binary form must reproduce the above copyright notice,
11293901Sarybchik *    this list of conditions and the following disclaimer in the documentation
12293901Sarybchik *    and/or other materials provided with the distribution.
13293901Sarybchik *
14293901Sarybchik * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15293901Sarybchik * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16293901Sarybchik * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17293901Sarybchik * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18293901Sarybchik * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19293901Sarybchik * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20293901Sarybchik * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21293901Sarybchik * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22293901Sarybchik * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23293901Sarybchik * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24293901Sarybchik * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25293901Sarybchik *
26293901Sarybchik * The views and conclusions contained in the software and documentation are
27293901Sarybchik * those of the authors and should not be interpreted as representing official
28293901Sarybchik * policies, either expressed or implied, of the FreeBSD Project.
29293901Sarybchik */
30293901Sarybchik
31293901Sarybchik#include <sys/cdefs.h>
32293901Sarybchik__FBSDID("$FreeBSD: stable/11/sys/dev/sfxge/common/efx_lic.c 342426 2018-12-25 07:02:08Z arybchik $");
33293901Sarybchik
34293901Sarybchik#include "efx.h"
35293901Sarybchik#include "efx_impl.h"
36293901Sarybchik
37293901Sarybchik#if EFSYS_OPT_LICENSING
38293901Sarybchik
39299898Sarybchik#include "ef10_tlv_layout.h"
40299898Sarybchik
41299898Sarybchik#if EFSYS_OPT_SIENA | EFSYS_OPT_HUNTINGTON
42299898Sarybchik
43299898Sarybchik	__checkReturn		efx_rc_t
44299898Sarybchikefx_lic_v1v2_find_start(
45299898Sarybchik	__in			efx_nic_t *enp,
46299898Sarybchik	__in_bcount(buffer_size)
47299898Sarybchik				caddr_t bufferp,
48299898Sarybchik	__in			size_t buffer_size,
49299898Sarybchik	__out			uint32_t *startp
50299898Sarybchik	);
51299898Sarybchik
52299898Sarybchik	__checkReturn		efx_rc_t
53299898Sarybchikefx_lic_v1v2_find_end(
54299898Sarybchik	__in			efx_nic_t *enp,
55299898Sarybchik	__in_bcount(buffer_size)
56299898Sarybchik				caddr_t bufferp,
57299898Sarybchik	__in			size_t buffer_size,
58299898Sarybchik	__in			uint32_t offset,
59299898Sarybchik	__out			uint32_t *endp
60299898Sarybchik	);
61299898Sarybchik
62299898Sarybchik	__checkReturn	__success(return != B_FALSE)	boolean_t
63299898Sarybchikefx_lic_v1v2_find_key(
64299898Sarybchik	__in			efx_nic_t *enp,
65299898Sarybchik	__in_bcount(buffer_size)
66299898Sarybchik				caddr_t bufferp,
67299898Sarybchik	__in			size_t buffer_size,
68299898Sarybchik	__in			uint32_t offset,
69299898Sarybchik	__out			uint32_t *startp,
70299898Sarybchik	__out			uint32_t *lengthp
71299898Sarybchik	);
72299898Sarybchik
73299898Sarybchik	__checkReturn	__success(return != B_FALSE)	boolean_t
74299898Sarybchikefx_lic_v1v2_validate_key(
75299898Sarybchik	__in			efx_nic_t *enp,
76299898Sarybchik	__in_bcount(length)	caddr_t keyp,
77299898Sarybchik	__in			uint32_t length
78299898Sarybchik	);
79299898Sarybchik
80299898Sarybchik	__checkReturn		efx_rc_t
81299898Sarybchikefx_lic_v1v2_read_key(
82299898Sarybchik	__in			efx_nic_t *enp,
83299898Sarybchik	__in_bcount(buffer_size)
84299898Sarybchik				caddr_t bufferp,
85299898Sarybchik	__in			size_t buffer_size,
86299898Sarybchik	__in			uint32_t offset,
87299898Sarybchik	__in			uint32_t length,
88299898Sarybchik	__out_bcount_part(key_max_size, *lengthp)
89299898Sarybchik				caddr_t keyp,
90299898Sarybchik	__in			size_t key_max_size,
91299898Sarybchik	__out			uint32_t *lengthp
92299898Sarybchik	);
93299898Sarybchik
94299898Sarybchik	__checkReturn		efx_rc_t
95299898Sarybchikefx_lic_v1v2_write_key(
96299898Sarybchik	__in			efx_nic_t *enp,
97299898Sarybchik	__in_bcount(buffer_size)
98299898Sarybchik				caddr_t bufferp,
99299898Sarybchik	__in			size_t buffer_size,
100299898Sarybchik	__in			uint32_t offset,
101299898Sarybchik	__in_bcount(length)	caddr_t keyp,
102299898Sarybchik	__in			uint32_t length,
103299898Sarybchik	__out			uint32_t *lengthp
104299898Sarybchik	);
105299898Sarybchik
106299898Sarybchik	__checkReturn		efx_rc_t
107299898Sarybchikefx_lic_v1v2_delete_key(
108299898Sarybchik	__in			efx_nic_t *enp,
109299898Sarybchik	__in_bcount(buffer_size)
110299898Sarybchik				caddr_t bufferp,
111299898Sarybchik	__in			size_t buffer_size,
112299898Sarybchik	__in			uint32_t offset,
113299898Sarybchik	__in			uint32_t length,
114299898Sarybchik	__in			uint32_t end,
115299898Sarybchik	__out			uint32_t *deltap
116299898Sarybchik	);
117299898Sarybchik
118299898Sarybchik	__checkReturn		efx_rc_t
119299898Sarybchikefx_lic_v1v2_create_partition(
120299898Sarybchik	__in			efx_nic_t *enp,
121299898Sarybchik	__in_bcount(buffer_size)
122299898Sarybchik				caddr_t bufferp,
123299898Sarybchik	__in			size_t buffer_size
124299898Sarybchik	);
125299898Sarybchik
126299898Sarybchik	__checkReturn		efx_rc_t
127299898Sarybchikefx_lic_v1v2_finish_partition(
128299898Sarybchik	__in			efx_nic_t *enp,
129299898Sarybchik	__in_bcount(buffer_size)
130299898Sarybchik				caddr_t bufferp,
131299898Sarybchik	__in			size_t buffer_size
132299898Sarybchik	);
133299898Sarybchik
134299898Sarybchik#endif	/* EFSYS_OPT_HUNTINGTON | EFSYS_OPT_SIENA */
135299898Sarybchik
136299898Sarybchik
137293901Sarybchik#if EFSYS_OPT_SIENA
138293901Sarybchik
139293901Sarybchikstatic	__checkReturn	efx_rc_t
140293901Sarybchikefx_mcdi_fc_license_update_license(
141293901Sarybchik	__in		efx_nic_t *enp);
142293901Sarybchik
143293901Sarybchikstatic	__checkReturn	efx_rc_t
144293901Sarybchikefx_mcdi_fc_license_get_key_stats(
145293901Sarybchik	__in		efx_nic_t *enp,
146293901Sarybchik	__out		efx_key_stats_t *eksp);
147293901Sarybchik
148299517Sarybchikstatic const efx_lic_ops_t	__efx_lic_v1_ops = {
149293901Sarybchik	efx_mcdi_fc_license_update_license,	/* elo_update_licenses */
150293901Sarybchik	efx_mcdi_fc_license_get_key_stats,	/* elo_get_key_stats */
151293901Sarybchik	NULL,					/* elo_app_state */
152293901Sarybchik	NULL,					/* elo_get_id */
153299898Sarybchik	efx_lic_v1v2_find_start,		/* elo_find_start */
154299898Sarybchik	efx_lic_v1v2_find_end,			/* elo_find_end */
155299898Sarybchik	efx_lic_v1v2_find_key,			/* elo_find_key */
156299898Sarybchik	efx_lic_v1v2_validate_key,		/* elo_validate_key */
157299898Sarybchik	efx_lic_v1v2_read_key,			/* elo_read_key */
158299898Sarybchik	efx_lic_v1v2_write_key,			/* elo_write_key */
159299898Sarybchik	efx_lic_v1v2_delete_key,		/* elo_delete_key */
160299898Sarybchik	efx_lic_v1v2_create_partition,		/* elo_create_partition */
161299898Sarybchik	efx_lic_v1v2_finish_partition,		/* elo_finish_partition */
162293901Sarybchik};
163293901Sarybchik
164293901Sarybchik#endif	/* EFSYS_OPT_SIENA */
165293901Sarybchik
166293901Sarybchik#if EFSYS_OPT_HUNTINGTON
167293901Sarybchik
168293901Sarybchikstatic	__checkReturn	efx_rc_t
169293901Sarybchikefx_mcdi_licensing_update_licenses(
170293901Sarybchik	__in		efx_nic_t *enp);
171293901Sarybchik
172293901Sarybchikstatic	__checkReturn	efx_rc_t
173293901Sarybchikefx_mcdi_licensing_get_key_stats(
174293901Sarybchik	__in		efx_nic_t *enp,
175293901Sarybchik	__out		efx_key_stats_t *eksp);
176293901Sarybchik
177293901Sarybchikstatic	__checkReturn	efx_rc_t
178293901Sarybchikefx_mcdi_licensed_app_state(
179293901Sarybchik	__in		efx_nic_t *enp,
180293901Sarybchik	__in		uint64_t app_id,
181293901Sarybchik	__out		boolean_t *licensedp);
182293901Sarybchik
183299517Sarybchikstatic const efx_lic_ops_t	__efx_lic_v2_ops = {
184293901Sarybchik	efx_mcdi_licensing_update_licenses,	/* elo_update_licenses */
185293901Sarybchik	efx_mcdi_licensing_get_key_stats,	/* elo_get_key_stats */
186293901Sarybchik	efx_mcdi_licensed_app_state,		/* elo_app_state */
187293901Sarybchik	NULL,					/* elo_get_id */
188299898Sarybchik	efx_lic_v1v2_find_start,		/* elo_find_start */
189299898Sarybchik	efx_lic_v1v2_find_end,			/* elo_find_end */
190299898Sarybchik	efx_lic_v1v2_find_key,			/* elo_find_key */
191299898Sarybchik	efx_lic_v1v2_validate_key,		/* elo_validate_key */
192299898Sarybchik	efx_lic_v1v2_read_key,			/* elo_read_key */
193299898Sarybchik	efx_lic_v1v2_write_key,			/* elo_write_key */
194299898Sarybchik	efx_lic_v1v2_delete_key,		/* elo_delete_key */
195299898Sarybchik	efx_lic_v1v2_create_partition,		/* elo_create_partition */
196299898Sarybchik	efx_lic_v1v2_finish_partition,		/* elo_finish_partition */
197293901Sarybchik};
198293901Sarybchik
199293901Sarybchik#endif	/* EFSYS_OPT_HUNTINGTON */
200293901Sarybchik
201293901Sarybchik#if EFSYS_OPT_MEDFORD
202293901Sarybchik
203293901Sarybchikstatic	__checkReturn	efx_rc_t
204293901Sarybchikefx_mcdi_licensing_v3_update_licenses(
205293901Sarybchik	__in		efx_nic_t *enp);
206293901Sarybchik
207293901Sarybchikstatic	__checkReturn	efx_rc_t
208293901Sarybchikefx_mcdi_licensing_v3_report_license(
209293901Sarybchik	__in		efx_nic_t *enp,
210293901Sarybchik	__out		efx_key_stats_t *eksp);
211293901Sarybchik
212293901Sarybchikstatic	__checkReturn	efx_rc_t
213293901Sarybchikefx_mcdi_licensing_v3_app_state(
214293901Sarybchik	__in		efx_nic_t *enp,
215293901Sarybchik	__in		uint64_t app_id,
216293901Sarybchik	__out		boolean_t *licensedp);
217293901Sarybchik
218293901Sarybchikstatic	__checkReturn	efx_rc_t
219293901Sarybchikefx_mcdi_licensing_v3_get_id(
220293901Sarybchik	__in		efx_nic_t *enp,
221293901Sarybchik	__in		size_t buffer_size,
222293901Sarybchik	__out		uint32_t *typep,
223293901Sarybchik	__out		size_t *lengthp,
224293901Sarybchik	__out_bcount_part_opt(buffer_size, *lengthp)
225293901Sarybchik			uint8_t *bufferp);
226293901Sarybchik
227299898Sarybchik	__checkReturn		efx_rc_t
228299898Sarybchikefx_lic_v3_find_start(
229299898Sarybchik	__in			efx_nic_t *enp,
230299898Sarybchik	__in_bcount(buffer_size)
231299898Sarybchik				caddr_t bufferp,
232299898Sarybchik	__in			size_t buffer_size,
233299898Sarybchik	__out			uint32_t *startp
234299898Sarybchik	);
235299898Sarybchik
236299898Sarybchik	__checkReturn		efx_rc_t
237299898Sarybchikefx_lic_v3_find_end(
238299898Sarybchik	__in			efx_nic_t *enp,
239299898Sarybchik	__in_bcount(buffer_size)
240299898Sarybchik				caddr_t bufferp,
241299898Sarybchik	__in			size_t buffer_size,
242299898Sarybchik	__in			uint32_t offset,
243299898Sarybchik	__out			uint32_t *endp
244299898Sarybchik	);
245299898Sarybchik
246299898Sarybchik	__checkReturn	__success(return != B_FALSE)	boolean_t
247299898Sarybchikefx_lic_v3_find_key(
248299898Sarybchik	__in			efx_nic_t *enp,
249299898Sarybchik	__in_bcount(buffer_size)
250299898Sarybchik				caddr_t bufferp,
251299898Sarybchik	__in			size_t buffer_size,
252299898Sarybchik	__in			uint32_t offset,
253299898Sarybchik	__out			uint32_t *startp,
254299898Sarybchik	__out			uint32_t *lengthp
255299898Sarybchik	);
256299898Sarybchik
257299898Sarybchik	__checkReturn	__success(return != B_FALSE)	boolean_t
258299898Sarybchikefx_lic_v3_validate_key(
259299898Sarybchik	__in			efx_nic_t *enp,
260299898Sarybchik	__in_bcount(length)	caddr_t keyp,
261299898Sarybchik	__in			uint32_t length
262299898Sarybchik	);
263299898Sarybchik
264299898Sarybchik	__checkReturn		efx_rc_t
265299898Sarybchikefx_lic_v3_read_key(
266299898Sarybchik	__in			efx_nic_t *enp,
267299898Sarybchik	__in_bcount(buffer_size)
268299898Sarybchik				caddr_t bufferp,
269299898Sarybchik	__in			size_t buffer_size,
270299898Sarybchik	__in			uint32_t offset,
271299898Sarybchik	__in			uint32_t length,
272299898Sarybchik	__out_bcount_part(key_max_size, *lengthp)
273299898Sarybchik				caddr_t keyp,
274299898Sarybchik	__in			size_t key_max_size,
275299898Sarybchik	__out			uint32_t *lengthp
276299898Sarybchik	);
277299898Sarybchik
278299898Sarybchik	__checkReturn		efx_rc_t
279299898Sarybchikefx_lic_v3_write_key(
280299898Sarybchik	__in			efx_nic_t *enp,
281299898Sarybchik	__in_bcount(buffer_size)
282299898Sarybchik				caddr_t bufferp,
283299898Sarybchik	__in			size_t buffer_size,
284299898Sarybchik	__in			uint32_t offset,
285299898Sarybchik	__in_bcount(length)	caddr_t keyp,
286299898Sarybchik	__in			uint32_t length,
287299898Sarybchik	__out			uint32_t *lengthp
288299898Sarybchik	);
289299898Sarybchik
290299898Sarybchik	__checkReturn		efx_rc_t
291299898Sarybchikefx_lic_v3_delete_key(
292299898Sarybchik	__in			efx_nic_t *enp,
293299898Sarybchik	__in_bcount(buffer_size)
294299898Sarybchik				caddr_t bufferp,
295299898Sarybchik	__in			size_t buffer_size,
296299898Sarybchik	__in			uint32_t offset,
297299898Sarybchik	__in			uint32_t length,
298299898Sarybchik	__in			uint32_t end,
299299898Sarybchik	__out			uint32_t *deltap
300299898Sarybchik	);
301299898Sarybchik
302299898Sarybchik	__checkReturn		efx_rc_t
303299898Sarybchikefx_lic_v3_create_partition(
304299898Sarybchik	__in			efx_nic_t *enp,
305299898Sarybchik	__in_bcount(buffer_size)
306299898Sarybchik				caddr_t bufferp,
307299898Sarybchik	__in			size_t buffer_size
308299898Sarybchik	);
309299898Sarybchik
310299898Sarybchik	__checkReturn		efx_rc_t
311299898Sarybchikefx_lic_v3_finish_partition(
312299898Sarybchik	__in			efx_nic_t *enp,
313299898Sarybchik	__in_bcount(buffer_size)
314299898Sarybchik				caddr_t bufferp,
315299898Sarybchik	__in			size_t buffer_size
316299898Sarybchik	);
317299898Sarybchik
318299517Sarybchikstatic const efx_lic_ops_t	__efx_lic_v3_ops = {
319293901Sarybchik	efx_mcdi_licensing_v3_update_licenses,	/* elo_update_licenses */
320293901Sarybchik	efx_mcdi_licensing_v3_report_license,	/* elo_get_key_stats */
321293901Sarybchik	efx_mcdi_licensing_v3_app_state,	/* elo_app_state */
322293901Sarybchik	efx_mcdi_licensing_v3_get_id,		/* elo_get_id */
323299898Sarybchik	efx_lic_v3_find_start,			/* elo_find_start*/
324299898Sarybchik	efx_lic_v3_find_end,			/* elo_find_end */
325299898Sarybchik	efx_lic_v3_find_key,			/* elo_find_key */
326299898Sarybchik	efx_lic_v3_validate_key,		/* elo_validate_key */
327299898Sarybchik	efx_lic_v3_read_key,			/* elo_read_key */
328299898Sarybchik	efx_lic_v3_write_key,			/* elo_write_key */
329299898Sarybchik	efx_lic_v3_delete_key,			/* elo_delete_key */
330299898Sarybchik	efx_lic_v3_create_partition,		/* elo_create_partition */
331299898Sarybchik	efx_lic_v3_finish_partition,		/* elo_finish_partition */
332293901Sarybchik};
333293901Sarybchik
334293901Sarybchik#endif	/* EFSYS_OPT_MEDFORD */
335293901Sarybchik
336293901Sarybchik
337293901Sarybchik/* V1 Licensing - used in Siena Modena only */
338293901Sarybchik
339293901Sarybchik#if EFSYS_OPT_SIENA
340293901Sarybchik
341293901Sarybchikstatic	__checkReturn	efx_rc_t
342293901Sarybchikefx_mcdi_fc_license_update_license(
343293901Sarybchik	__in		efx_nic_t *enp)
344293901Sarybchik{
345293901Sarybchik	efx_mcdi_req_t req;
346293901Sarybchik	uint8_t payload[MC_CMD_FC_IN_LICENSE_LEN];
347293901Sarybchik	efx_rc_t rc;
348293901Sarybchik
349293901Sarybchik	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
350293901Sarybchik
351293901Sarybchik	(void) memset(payload, 0, sizeof (payload));
352299905Sarybchik	req.emr_cmd = MC_CMD_FC;
353293901Sarybchik	req.emr_in_buf = payload;
354293901Sarybchik	req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN;
355293901Sarybchik	req.emr_out_buf = payload;
356293901Sarybchik	req.emr_out_length = 0;
357293901Sarybchik
358299905Sarybchik	MCDI_IN_SET_DWORD(req, FC_IN_CMD,
359299905Sarybchik	    MC_CMD_FC_OP_LICENSE);
360299905Sarybchik
361293901Sarybchik	MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP,
362293901Sarybchik	    MC_CMD_FC_IN_LICENSE_UPDATE_LICENSE);
363293901Sarybchik
364293901Sarybchik	efx_mcdi_execute(enp, &req);
365293901Sarybchik
366293901Sarybchik	if (req.emr_rc != 0) {
367293901Sarybchik		rc = req.emr_rc;
368293901Sarybchik		goto fail1;
369293901Sarybchik	}
370293901Sarybchik
371293901Sarybchik	if (req.emr_out_length_used != 0) {
372293901Sarybchik		rc = EIO;
373293901Sarybchik		goto fail2;
374293901Sarybchik	}
375293901Sarybchik
376293901Sarybchik	return (0);
377293901Sarybchik
378293901Sarybchikfail2:
379293901Sarybchik	EFSYS_PROBE(fail2);
380293901Sarybchikfail1:
381293901Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
382293901Sarybchik
383293901Sarybchik	return (rc);
384293901Sarybchik}
385293901Sarybchik
386293901Sarybchikstatic	__checkReturn	efx_rc_t
387293901Sarybchikefx_mcdi_fc_license_get_key_stats(
388293901Sarybchik	__in		efx_nic_t *enp,
389293901Sarybchik	__out		efx_key_stats_t *eksp)
390293901Sarybchik{
391293901Sarybchik	efx_mcdi_req_t req;
392293901Sarybchik	uint8_t payload[MAX(MC_CMD_FC_IN_LICENSE_LEN,
393293901Sarybchik			    MC_CMD_FC_OUT_LICENSE_LEN)];
394293901Sarybchik	efx_rc_t rc;
395293901Sarybchik
396293901Sarybchik	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
397293901Sarybchik
398293901Sarybchik	(void) memset(payload, 0, sizeof (payload));
399299905Sarybchik	req.emr_cmd = MC_CMD_FC;
400293901Sarybchik	req.emr_in_buf = payload;
401293901Sarybchik	req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN;
402293901Sarybchik	req.emr_out_buf = payload;
403293901Sarybchik	req.emr_out_length = MC_CMD_FC_OUT_LICENSE_LEN;
404293901Sarybchik
405299905Sarybchik	MCDI_IN_SET_DWORD(req, FC_IN_CMD,
406299905Sarybchik	    MC_CMD_FC_OP_LICENSE);
407299905Sarybchik
408293901Sarybchik	MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP,
409293901Sarybchik	    MC_CMD_FC_IN_LICENSE_GET_KEY_STATS);
410293901Sarybchik
411299923Sarybchik	efx_mcdi_execute_quiet(enp, &req);
412293901Sarybchik
413293901Sarybchik	if (req.emr_rc != 0) {
414293901Sarybchik		rc = req.emr_rc;
415293901Sarybchik		goto fail1;
416293901Sarybchik	}
417293901Sarybchik
418293901Sarybchik	if (req.emr_out_length_used < MC_CMD_FC_OUT_LICENSE_LEN) {
419293901Sarybchik		rc = EMSGSIZE;
420293901Sarybchik		goto fail2;
421293901Sarybchik	}
422293901Sarybchik
423293901Sarybchik	eksp->eks_valid =
424293901Sarybchik		MCDI_OUT_DWORD(req, FC_OUT_LICENSE_VALID_KEYS);
425293901Sarybchik	eksp->eks_invalid =
426293901Sarybchik		MCDI_OUT_DWORD(req, FC_OUT_LICENSE_INVALID_KEYS);
427293901Sarybchik	eksp->eks_blacklisted =
428293901Sarybchik		MCDI_OUT_DWORD(req, FC_OUT_LICENSE_BLACKLISTED_KEYS);
429293901Sarybchik	eksp->eks_unverifiable = 0;
430293901Sarybchik	eksp->eks_wrong_node = 0;
431293901Sarybchik	eksp->eks_licensed_apps_lo = 0;
432293901Sarybchik	eksp->eks_licensed_apps_hi = 0;
433293901Sarybchik	eksp->eks_licensed_features_lo = 0;
434293901Sarybchik	eksp->eks_licensed_features_hi = 0;
435293901Sarybchik
436293901Sarybchik	return (0);
437293901Sarybchik
438293901Sarybchikfail2:
439293901Sarybchik	EFSYS_PROBE(fail2);
440293901Sarybchikfail1:
441293901Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
442293901Sarybchik
443293901Sarybchik	return (rc);
444293901Sarybchik}
445293901Sarybchik
446293901Sarybchik#endif	/* EFSYS_OPT_SIENA */
447293901Sarybchik
448299898Sarybchik/* V1 and V2 Partition format - based on a 16-bit TLV format */
449299898Sarybchik
450299898Sarybchik#if EFSYS_OPT_SIENA | EFSYS_OPT_HUNTINGTON
451299898Sarybchik
452299898Sarybchik/*
453299898Sarybchik * V1/V2 format - defined in SF-108542-TC section 4.2:
454299898Sarybchik *  Type (T):   16bit - revision/HMAC algorithm
455299898Sarybchik *  Length (L): 16bit - value length in bytes
456299898Sarybchik *  Value (V):  L bytes - payload
457299898Sarybchik */
458299898Sarybchik#define EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX    (256)
459310841Sarybchik#define EFX_LICENSE_V1V2_HEADER_LENGTH         (2 * sizeof(uint16_t))
460299898Sarybchik
461299898Sarybchik	__checkReturn		efx_rc_t
462299898Sarybchikefx_lic_v1v2_find_start(
463299898Sarybchik	__in			efx_nic_t *enp,
464299898Sarybchik	__in_bcount(buffer_size)
465299898Sarybchik				caddr_t bufferp,
466299898Sarybchik	__in			size_t buffer_size,
467299898Sarybchik	__out			uint32_t *startp
468299898Sarybchik	)
469299898Sarybchik{
470299898Sarybchik	_NOTE(ARGUNUSED(enp, bufferp, buffer_size))
471299898Sarybchik
472299898Sarybchik	*startp = 0;
473299898Sarybchik	return (0);
474299898Sarybchik}
475299898Sarybchik
476299898Sarybchik	__checkReturn		efx_rc_t
477299898Sarybchikefx_lic_v1v2_find_end(
478299898Sarybchik	__in			efx_nic_t *enp,
479299898Sarybchik	__in_bcount(buffer_size)
480299898Sarybchik				caddr_t bufferp,
481299898Sarybchik	__in			size_t buffer_size,
482299898Sarybchik	__in			uint32_t offset,
483299898Sarybchik	__out			uint32_t *endp
484299898Sarybchik	)
485299898Sarybchik{
486299898Sarybchik	_NOTE(ARGUNUSED(enp, bufferp, buffer_size))
487299898Sarybchik
488299898Sarybchik	*endp = offset + EFX_LICENSE_V1V2_HEADER_LENGTH;
489299898Sarybchik	return (0);
490299898Sarybchik}
491299898Sarybchik
492299898Sarybchik	__checkReturn	__success(return != B_FALSE)	boolean_t
493299898Sarybchikefx_lic_v1v2_find_key(
494299898Sarybchik	__in			efx_nic_t *enp,
495299898Sarybchik	__in_bcount(buffer_size)
496299898Sarybchik				caddr_t bufferp,
497299898Sarybchik	__in			size_t buffer_size,
498299898Sarybchik	__in			uint32_t offset,
499299898Sarybchik	__out			uint32_t *startp,
500299898Sarybchik	__out			uint32_t *lengthp
501299898Sarybchik	)
502299898Sarybchik{
503299898Sarybchik	boolean_t found;
504299898Sarybchik	uint16_t tlv_type;
505299898Sarybchik	uint16_t tlv_length;
506299898Sarybchik
507299898Sarybchik	_NOTE(ARGUNUSED(enp))
508299898Sarybchik
509301125Sarybchik	if ((size_t)buffer_size - offset < EFX_LICENSE_V1V2_HEADER_LENGTH)
510299898Sarybchik		goto fail1;
511299898Sarybchik
512310922Sarybchik	tlv_type = __LE_TO_CPU_16(((uint16_t *)&bufferp[offset])[0]);
513310922Sarybchik	tlv_length = __LE_TO_CPU_16(((uint16_t *)&bufferp[offset])[1]);
514299898Sarybchik	if ((tlv_length > EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX) ||
515299898Sarybchik	    (tlv_type == 0 && tlv_length == 0)) {
516299898Sarybchik		found = B_FALSE;
517299898Sarybchik	} else {
518299898Sarybchik		*startp = offset;
519299898Sarybchik		*lengthp = tlv_length + EFX_LICENSE_V1V2_HEADER_LENGTH;
520299898Sarybchik		found = B_TRUE;
521299898Sarybchik	}
522299898Sarybchik	return (found);
523299898Sarybchik
524299898Sarybchikfail1:
525342426Sarybchik	EFSYS_PROBE1(fail1, boolean_t, B_FALSE);
526299898Sarybchik
527299898Sarybchik	return (B_FALSE);
528299898Sarybchik}
529299898Sarybchik
530299898Sarybchik	__checkReturn	__success(return != B_FALSE)	boolean_t
531299898Sarybchikefx_lic_v1v2_validate_key(
532299898Sarybchik	__in			efx_nic_t *enp,
533299898Sarybchik	__in_bcount(length)	caddr_t keyp,
534299898Sarybchik	__in			uint32_t length
535299898Sarybchik	)
536299898Sarybchik{
537299898Sarybchik	uint16_t tlv_type;
538299898Sarybchik	uint16_t tlv_length;
539299898Sarybchik
540299898Sarybchik	_NOTE(ARGUNUSED(enp))
541299898Sarybchik
542299898Sarybchik	if (length < EFX_LICENSE_V1V2_HEADER_LENGTH) {
543299898Sarybchik		goto fail1;
544299898Sarybchik	}
545299898Sarybchik
546310922Sarybchik	tlv_type = __LE_TO_CPU_16(((uint16_t *)keyp)[0]);
547310922Sarybchik	tlv_length = __LE_TO_CPU_16(((uint16_t *)keyp)[1]);
548299898Sarybchik
549301125Sarybchik	if (tlv_length > EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX) {
550299898Sarybchik		goto fail2;
551299898Sarybchik	}
552299898Sarybchik	if (tlv_type == 0) {
553299898Sarybchik		goto fail3;
554299898Sarybchik	}
555299898Sarybchik	if ((tlv_length + EFX_LICENSE_V1V2_HEADER_LENGTH) != length) {
556299898Sarybchik		goto fail4;
557299898Sarybchik	}
558299898Sarybchik
559299898Sarybchik	return (B_TRUE);
560299898Sarybchik
561299898Sarybchikfail4:
562299898Sarybchik	EFSYS_PROBE(fail4);
563299898Sarybchikfail3:
564299898Sarybchik	EFSYS_PROBE(fail3);
565299898Sarybchikfail2:
566299898Sarybchik	EFSYS_PROBE(fail2);
567299898Sarybchikfail1:
568342426Sarybchik	EFSYS_PROBE1(fail1, boolean_t, B_FALSE);
569299898Sarybchik
570299898Sarybchik	return (B_FALSE);
571299898Sarybchik}
572299898Sarybchik
573299898Sarybchik
574299898Sarybchik	__checkReturn		efx_rc_t
575299898Sarybchikefx_lic_v1v2_read_key(
576299898Sarybchik	__in			efx_nic_t *enp,
577299898Sarybchik	__in_bcount(buffer_size)
578299898Sarybchik				caddr_t bufferp,
579299898Sarybchik	__in			size_t buffer_size,
580299898Sarybchik	__in			uint32_t offset,
581299898Sarybchik	__in			uint32_t length,
582299898Sarybchik	__out_bcount_part(key_max_size, *lengthp)
583299898Sarybchik				caddr_t keyp,
584299898Sarybchik	__in			size_t key_max_size,
585299898Sarybchik	__out			uint32_t *lengthp
586299898Sarybchik	)
587299898Sarybchik{
588299898Sarybchik	efx_rc_t rc;
589299898Sarybchik
590299898Sarybchik	_NOTE(ARGUNUSED(enp))
591299898Sarybchik	EFSYS_ASSERT(length <= (EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX +
592299898Sarybchik	    EFX_LICENSE_V1V2_HEADER_LENGTH));
593299898Sarybchik
594299898Sarybchik	if (key_max_size < length) {
595299898Sarybchik		rc = ENOSPC;
596299898Sarybchik		goto fail1;
597299898Sarybchik	}
598299898Sarybchik	memcpy(keyp, &bufferp[offset], length);
599299898Sarybchik
600299898Sarybchik	*lengthp = length;
601299898Sarybchik
602299898Sarybchik	return (0);
603299898Sarybchik
604299898Sarybchikfail1:
605299898Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
606299898Sarybchik
607299898Sarybchik	return (rc);
608299898Sarybchik}
609299898Sarybchik
610299898Sarybchik	__checkReturn		efx_rc_t
611299898Sarybchikefx_lic_v1v2_write_key(
612299898Sarybchik	__in			efx_nic_t *enp,
613299898Sarybchik	__in_bcount(buffer_size)
614299898Sarybchik				caddr_t bufferp,
615299898Sarybchik	__in			size_t buffer_size,
616299898Sarybchik	__in			uint32_t offset,
617299898Sarybchik	__in_bcount(length)	caddr_t keyp,
618299898Sarybchik	__in			uint32_t length,
619299898Sarybchik	__out			uint32_t *lengthp
620299898Sarybchik	)
621299898Sarybchik{
622299898Sarybchik	efx_rc_t rc;
623299898Sarybchik
624299898Sarybchik	_NOTE(ARGUNUSED(enp))
625299898Sarybchik	EFSYS_ASSERT(length <= (EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX +
626299898Sarybchik	    EFX_LICENSE_V1V2_HEADER_LENGTH));
627299898Sarybchik
628310916Sarybchik	/* Ensure space for terminator remains */
629299898Sarybchik	if ((offset + length) >
630310919Sarybchik	    (buffer_size - EFX_LICENSE_V1V2_HEADER_LENGTH)) {
631299898Sarybchik		rc = ENOSPC;
632299898Sarybchik		goto fail1;
633299898Sarybchik	}
634299898Sarybchik
635299898Sarybchik	memcpy(bufferp + offset, keyp, length);
636299898Sarybchik
637299898Sarybchik	*lengthp = length;
638299898Sarybchik
639299898Sarybchik	return (0);
640299898Sarybchik
641299898Sarybchikfail1:
642299898Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
643299898Sarybchik
644299898Sarybchik	return (rc);
645299898Sarybchik}
646299898Sarybchik
647299898Sarybchik	__checkReturn		efx_rc_t
648299898Sarybchikefx_lic_v1v2_delete_key(
649299898Sarybchik	__in			efx_nic_t *enp,
650299898Sarybchik	__in_bcount(buffer_size)
651299898Sarybchik				caddr_t bufferp,
652299898Sarybchik	__in			size_t buffer_size,
653299898Sarybchik	__in			uint32_t offset,
654299898Sarybchik	__in			uint32_t length,
655299898Sarybchik	__in			uint32_t end,
656299898Sarybchik	__out			uint32_t *deltap
657299898Sarybchik	)
658299898Sarybchik{
659299898Sarybchik	uint32_t move_start = offset + length;
660299898Sarybchik	uint32_t move_length = end - move_start;
661299898Sarybchik
662299898Sarybchik	_NOTE(ARGUNUSED(enp))
663299898Sarybchik	EFSYS_ASSERT(end <= buffer_size);
664299898Sarybchik
665310916Sarybchik	/* Shift everything after the key down */
666299898Sarybchik	memmove(bufferp + offset, bufferp + move_start, move_length);
667299898Sarybchik
668299898Sarybchik	*deltap = length;
669299898Sarybchik
670299898Sarybchik	return (0);
671299898Sarybchik}
672299898Sarybchik
673299898Sarybchik	__checkReturn		efx_rc_t
674299898Sarybchikefx_lic_v1v2_create_partition(
675299898Sarybchik	__in			efx_nic_t *enp,
676299898Sarybchik	__in_bcount(buffer_size)
677299898Sarybchik				caddr_t bufferp,
678299898Sarybchik	__in			size_t buffer_size
679299898Sarybchik	)
680299898Sarybchik{
681299898Sarybchik	_NOTE(ARGUNUSED(enp))
682299898Sarybchik	EFSYS_ASSERT(EFX_LICENSE_V1V2_HEADER_LENGTH <= buffer_size);
683299898Sarybchik
684310916Sarybchik	/* Write terminator */
685299898Sarybchik	memset(bufferp, '\0', EFX_LICENSE_V1V2_HEADER_LENGTH);
686299898Sarybchik	return (0);
687299898Sarybchik}
688299898Sarybchik
689299898Sarybchik
690299898Sarybchik	__checkReturn		efx_rc_t
691299898Sarybchikefx_lic_v1v2_finish_partition(
692299898Sarybchik	__in			efx_nic_t *enp,
693299898Sarybchik	__in_bcount(buffer_size)
694299898Sarybchik				caddr_t bufferp,
695299898Sarybchik	__in			size_t buffer_size
696299898Sarybchik	)
697299898Sarybchik{
698299898Sarybchik	_NOTE(ARGUNUSED(enp, bufferp, buffer_size))
699299898Sarybchik
700299898Sarybchik	return (0);
701299898Sarybchik}
702299898Sarybchik
703299898Sarybchik#endif	/* EFSYS_OPT_HUNTINGTON | EFSYS_OPT_SIENA */
704299898Sarybchik
705299898Sarybchik
706293901Sarybchik/* V2 Licensing - used by Huntington family only. See SF-113611-TC */
707293901Sarybchik
708293901Sarybchik#if EFSYS_OPT_HUNTINGTON
709293901Sarybchik
710293901Sarybchikstatic	__checkReturn	efx_rc_t
711293901Sarybchikefx_mcdi_licensed_app_state(
712293901Sarybchik	__in		efx_nic_t *enp,
713293901Sarybchik	__in		uint64_t app_id,
714293901Sarybchik	__out		boolean_t *licensedp)
715293901Sarybchik{
716293901Sarybchik	efx_mcdi_req_t req;
717293901Sarybchik	uint8_t payload[MAX(MC_CMD_GET_LICENSED_APP_STATE_IN_LEN,
718293901Sarybchik			    MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN)];
719293901Sarybchik	uint32_t app_state;
720293901Sarybchik	efx_rc_t rc;
721293901Sarybchik
722293901Sarybchik	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
723293901Sarybchik
724293901Sarybchik	/* V2 licensing supports 32bit app id only */
725293901Sarybchik	if ((app_id >> 32) != 0) {
726293901Sarybchik		rc = EINVAL;
727293901Sarybchik		goto fail1;
728293901Sarybchik	}
729293901Sarybchik
730293901Sarybchik	(void) memset(payload, 0, sizeof (payload));
731293901Sarybchik	req.emr_cmd = MC_CMD_GET_LICENSED_APP_STATE;
732293901Sarybchik	req.emr_in_buf = payload;
733293901Sarybchik	req.emr_in_length = MC_CMD_GET_LICENSED_APP_STATE_IN_LEN;
734293901Sarybchik	req.emr_out_buf = payload;
735293901Sarybchik	req.emr_out_length = MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN;
736293901Sarybchik
737293901Sarybchik	MCDI_IN_SET_DWORD(req, GET_LICENSED_APP_STATE_IN_APP_ID,
738293901Sarybchik		    app_id & 0xffffffff);
739293901Sarybchik
740293901Sarybchik	efx_mcdi_execute(enp, &req);
741293901Sarybchik
742293901Sarybchik	if (req.emr_rc != 0) {
743293901Sarybchik		rc = req.emr_rc;
744293901Sarybchik		goto fail2;
745293901Sarybchik	}
746293901Sarybchik
747293901Sarybchik	if (req.emr_out_length_used < MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN) {
748293901Sarybchik		rc = EMSGSIZE;
749293901Sarybchik		goto fail3;
750293901Sarybchik	}
751293901Sarybchik
752293901Sarybchik	app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_APP_STATE_OUT_STATE));
753293901Sarybchik	if (app_state != MC_CMD_GET_LICENSED_APP_STATE_OUT_NOT_LICENSED) {
754293901Sarybchik		*licensedp = B_TRUE;
755293901Sarybchik	} else {
756293901Sarybchik		*licensedp = B_FALSE;
757293901Sarybchik	}
758293901Sarybchik
759293901Sarybchik	return (0);
760293901Sarybchik
761293901Sarybchikfail3:
762293901Sarybchik	EFSYS_PROBE(fail3);
763293901Sarybchikfail2:
764293901Sarybchik	EFSYS_PROBE(fail2);
765293901Sarybchikfail1:
766293901Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
767293901Sarybchik
768293901Sarybchik	return (rc);
769293901Sarybchik}
770293901Sarybchik
771293901Sarybchikstatic	__checkReturn	efx_rc_t
772293901Sarybchikefx_mcdi_licensing_update_licenses(
773293901Sarybchik	__in		efx_nic_t *enp)
774293901Sarybchik{
775293901Sarybchik	efx_mcdi_req_t req;
776293901Sarybchik	uint8_t payload[MC_CMD_LICENSING_IN_LEN];
777293901Sarybchik	efx_rc_t rc;
778293901Sarybchik
779293901Sarybchik	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
780293901Sarybchik
781293901Sarybchik	(void) memset(payload, 0, sizeof (payload));
782293901Sarybchik	req.emr_cmd = MC_CMD_LICENSING;
783293901Sarybchik	req.emr_in_buf = payload;
784293901Sarybchik	req.emr_in_length = MC_CMD_LICENSING_IN_LEN;
785293901Sarybchik	req.emr_out_buf = payload;
786293901Sarybchik	req.emr_out_length = 0;
787293901Sarybchik
788293901Sarybchik	MCDI_IN_SET_DWORD(req, LICENSING_IN_OP,
789293901Sarybchik	    MC_CMD_LICENSING_IN_OP_UPDATE_LICENSE);
790293901Sarybchik
791293901Sarybchik	efx_mcdi_execute(enp, &req);
792293901Sarybchik
793293901Sarybchik	if (req.emr_rc != 0) {
794293901Sarybchik		rc = req.emr_rc;
795293901Sarybchik		goto fail1;
796293901Sarybchik	}
797293901Sarybchik
798293901Sarybchik	if (req.emr_out_length_used != 0) {
799293901Sarybchik		rc = EIO;
800293901Sarybchik		goto fail2;
801293901Sarybchik	}
802293901Sarybchik
803293901Sarybchik	return (0);
804293901Sarybchik
805293901Sarybchikfail2:
806293901Sarybchik	EFSYS_PROBE(fail2);
807293901Sarybchikfail1:
808293901Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
809293901Sarybchik
810293901Sarybchik	return (rc);
811293901Sarybchik}
812293901Sarybchik
813293901Sarybchikstatic	__checkReturn	efx_rc_t
814293901Sarybchikefx_mcdi_licensing_get_key_stats(
815293901Sarybchik	__in		efx_nic_t *enp,
816293901Sarybchik	__out		efx_key_stats_t *eksp)
817293901Sarybchik{
818293901Sarybchik	efx_mcdi_req_t req;
819293901Sarybchik	uint8_t payload[MAX(MC_CMD_LICENSING_IN_LEN,
820293901Sarybchik			    MC_CMD_LICENSING_OUT_LEN)];
821293901Sarybchik	efx_rc_t rc;
822293901Sarybchik
823293901Sarybchik	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
824293901Sarybchik
825293901Sarybchik	(void) memset(payload, 0, sizeof (payload));
826293901Sarybchik	req.emr_cmd = MC_CMD_LICENSING;
827293901Sarybchik	req.emr_in_buf = payload;
828293901Sarybchik	req.emr_in_length = MC_CMD_LICENSING_IN_LEN;
829293901Sarybchik	req.emr_out_buf = payload;
830293901Sarybchik	req.emr_out_length = MC_CMD_LICENSING_OUT_LEN;
831293901Sarybchik
832293901Sarybchik	MCDI_IN_SET_DWORD(req, LICENSING_IN_OP,
833293901Sarybchik	    MC_CMD_LICENSING_IN_OP_GET_KEY_STATS);
834293901Sarybchik
835293901Sarybchik	efx_mcdi_execute(enp, &req);
836293901Sarybchik
837293901Sarybchik	if (req.emr_rc != 0) {
838293901Sarybchik		rc = req.emr_rc;
839293901Sarybchik		goto fail1;
840293901Sarybchik	}
841293901Sarybchik
842293901Sarybchik	if (req.emr_out_length_used < MC_CMD_LICENSING_OUT_LEN) {
843293901Sarybchik		rc = EMSGSIZE;
844293901Sarybchik		goto fail2;
845293901Sarybchik	}
846293901Sarybchik
847293901Sarybchik	eksp->eks_valid =
848293901Sarybchik		MCDI_OUT_DWORD(req, LICENSING_OUT_VALID_APP_KEYS);
849293901Sarybchik	eksp->eks_invalid =
850293901Sarybchik		MCDI_OUT_DWORD(req, LICENSING_OUT_INVALID_APP_KEYS);
851293901Sarybchik	eksp->eks_blacklisted =
852293901Sarybchik		MCDI_OUT_DWORD(req, LICENSING_OUT_BLACKLISTED_APP_KEYS);
853293901Sarybchik	eksp->eks_unverifiable =
854293901Sarybchik		MCDI_OUT_DWORD(req, LICENSING_OUT_UNVERIFIABLE_APP_KEYS);
855293901Sarybchik	eksp->eks_wrong_node =
856293901Sarybchik		MCDI_OUT_DWORD(req, LICENSING_OUT_WRONG_NODE_APP_KEYS);
857293901Sarybchik	eksp->eks_licensed_apps_lo = 0;
858293901Sarybchik	eksp->eks_licensed_apps_hi = 0;
859293901Sarybchik	eksp->eks_licensed_features_lo = 0;
860293901Sarybchik	eksp->eks_licensed_features_hi = 0;
861293901Sarybchik
862293901Sarybchik	return (0);
863293901Sarybchik
864293901Sarybchikfail2:
865293901Sarybchik	EFSYS_PROBE(fail2);
866293901Sarybchikfail1:
867293901Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
868293901Sarybchik
869293901Sarybchik	return (rc);
870293901Sarybchik}
871293901Sarybchik
872293901Sarybchik#endif	/* EFSYS_OPT_HUNTINGTON */
873293901Sarybchik
874293901Sarybchik/* V3 Licensing - used starting from Medford family. See SF-114884-SW */
875293901Sarybchik
876293901Sarybchik#if EFSYS_OPT_MEDFORD
877293901Sarybchik
878293901Sarybchikstatic	__checkReturn	efx_rc_t
879293901Sarybchikefx_mcdi_licensing_v3_update_licenses(
880293901Sarybchik	__in		efx_nic_t *enp)
881293901Sarybchik{
882293901Sarybchik	efx_mcdi_req_t req;
883293901Sarybchik	uint8_t payload[MC_CMD_LICENSING_V3_IN_LEN];
884293901Sarybchik	efx_rc_t rc;
885293901Sarybchik
886293901Sarybchik	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD);
887293901Sarybchik
888293901Sarybchik	(void) memset(payload, 0, sizeof (payload));
889293901Sarybchik	req.emr_cmd = MC_CMD_LICENSING_V3;
890293901Sarybchik	req.emr_in_buf = payload;
891293901Sarybchik	req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN;
892293901Sarybchik	req.emr_out_buf = NULL;
893293901Sarybchik	req.emr_out_length = 0;
894293901Sarybchik
895293901Sarybchik	MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP,
896293901Sarybchik	    MC_CMD_LICENSING_V3_IN_OP_UPDATE_LICENSE);
897293901Sarybchik
898293901Sarybchik	efx_mcdi_execute(enp, &req);
899293901Sarybchik
900293901Sarybchik	if (req.emr_rc != 0) {
901293901Sarybchik		rc = req.emr_rc;
902293901Sarybchik		goto fail1;
903293901Sarybchik	}
904293901Sarybchik
905293901Sarybchik	return (0);
906293901Sarybchik
907293901Sarybchikfail1:
908293901Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
909293901Sarybchik
910293901Sarybchik	return (rc);
911293901Sarybchik}
912293901Sarybchik
913293901Sarybchikstatic	__checkReturn	efx_rc_t
914293901Sarybchikefx_mcdi_licensing_v3_report_license(
915293901Sarybchik	__in		efx_nic_t *enp,
916293901Sarybchik	__out		efx_key_stats_t *eksp)
917293901Sarybchik{
918293901Sarybchik	efx_mcdi_req_t req;
919293901Sarybchik	uint8_t payload[MAX(MC_CMD_LICENSING_V3_IN_LEN,
920293901Sarybchik			    MC_CMD_LICENSING_V3_OUT_LEN)];
921293901Sarybchik	efx_rc_t rc;
922293901Sarybchik
923293901Sarybchik	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD);
924293901Sarybchik
925293901Sarybchik	(void) memset(payload, 0, sizeof (payload));
926293901Sarybchik	req.emr_cmd = MC_CMD_LICENSING_V3;
927293901Sarybchik	req.emr_in_buf = payload;
928293901Sarybchik	req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN;
929293901Sarybchik	req.emr_out_buf = payload;
930293901Sarybchik	req.emr_out_length = MC_CMD_LICENSING_V3_OUT_LEN;
931293901Sarybchik
932293901Sarybchik	MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP,
933293901Sarybchik	    MC_CMD_LICENSING_V3_IN_OP_REPORT_LICENSE);
934293901Sarybchik
935299923Sarybchik	efx_mcdi_execute_quiet(enp, &req);
936293901Sarybchik
937293901Sarybchik	if (req.emr_rc != 0) {
938293901Sarybchik		rc = req.emr_rc;
939293901Sarybchik		goto fail1;
940293901Sarybchik	}
941293901Sarybchik
942293901Sarybchik	if (req.emr_out_length_used < MC_CMD_LICENSING_V3_OUT_LEN) {
943293901Sarybchik		rc = EMSGSIZE;
944293901Sarybchik		goto fail2;
945293901Sarybchik	}
946293901Sarybchik
947293901Sarybchik	eksp->eks_valid =
948293901Sarybchik		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_VALID_KEYS);
949293901Sarybchik	eksp->eks_invalid =
950293901Sarybchik		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_INVALID_KEYS);
951293901Sarybchik	eksp->eks_blacklisted = 0;
952293901Sarybchik	eksp->eks_unverifiable =
953293901Sarybchik		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_UNVERIFIABLE_KEYS);
954293901Sarybchik	eksp->eks_wrong_node =
955293901Sarybchik		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_WRONG_NODE_KEYS);
956293901Sarybchik	eksp->eks_licensed_apps_lo =
957293901Sarybchik		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_LO);
958293901Sarybchik	eksp->eks_licensed_apps_hi =
959293901Sarybchik		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_HI);
960293901Sarybchik	eksp->eks_licensed_features_lo =
961293901Sarybchik		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_LO);
962293901Sarybchik	eksp->eks_licensed_features_hi =
963293901Sarybchik		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_HI);
964293901Sarybchik
965293901Sarybchik	return (0);
966293901Sarybchik
967293901Sarybchikfail2:
968293901Sarybchik	EFSYS_PROBE(fail2);
969293901Sarybchikfail1:
970293901Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
971293901Sarybchik
972293901Sarybchik	return (rc);
973293901Sarybchik}
974293901Sarybchik
975293901Sarybchikstatic	__checkReturn	efx_rc_t
976293901Sarybchikefx_mcdi_licensing_v3_app_state(
977293901Sarybchik	__in		efx_nic_t *enp,
978293901Sarybchik	__in		uint64_t app_id,
979293901Sarybchik	__out		boolean_t *licensedp)
980293901Sarybchik{
981293901Sarybchik	efx_mcdi_req_t req;
982293901Sarybchik	uint8_t payload[MAX(MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN,
983293901Sarybchik			    MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN)];
984293901Sarybchik	uint32_t app_state;
985293901Sarybchik	efx_rc_t rc;
986293901Sarybchik
987293901Sarybchik	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD);
988293901Sarybchik
989293901Sarybchik	(void) memset(payload, 0, sizeof (payload));
990293901Sarybchik	req.emr_cmd = MC_CMD_GET_LICENSED_V3_APP_STATE;
991293901Sarybchik	req.emr_in_buf = payload;
992293901Sarybchik	req.emr_in_length = MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN;
993293901Sarybchik	req.emr_out_buf = payload;
994293901Sarybchik	req.emr_out_length = MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN;
995293901Sarybchik
996293901Sarybchik	MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_LO,
997293901Sarybchik		    app_id & 0xffffffff);
998293901Sarybchik	MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_HI,
999293901Sarybchik		    app_id >> 32);
1000293901Sarybchik
1001293901Sarybchik	efx_mcdi_execute(enp, &req);
1002293901Sarybchik
1003293901Sarybchik	if (req.emr_rc != 0) {
1004293901Sarybchik		rc = req.emr_rc;
1005293901Sarybchik		goto fail1;
1006293901Sarybchik	}
1007293901Sarybchik
1008293901Sarybchik	if (req.emr_out_length_used < MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN) {
1009293901Sarybchik		rc = EMSGSIZE;
1010293901Sarybchik		goto fail2;
1011293901Sarybchik	}
1012293901Sarybchik
1013293901Sarybchik	app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_V3_APP_STATE_OUT_STATE));
1014293901Sarybchik	if (app_state != MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_NOT_LICENSED) {
1015293901Sarybchik		*licensedp = B_TRUE;
1016293901Sarybchik	} else {
1017293901Sarybchik		*licensedp = B_FALSE;
1018293901Sarybchik	}
1019293901Sarybchik
1020293901Sarybchik	return (0);
1021293901Sarybchik
1022293901Sarybchikfail2:
1023293901Sarybchik	EFSYS_PROBE(fail2);
1024293901Sarybchikfail1:
1025293901Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1026293901Sarybchik
1027293901Sarybchik	return (rc);
1028293901Sarybchik}
1029293901Sarybchik
1030293901Sarybchikstatic	__checkReturn	efx_rc_t
1031293901Sarybchikefx_mcdi_licensing_v3_get_id(
1032293901Sarybchik	__in		efx_nic_t *enp,
1033293901Sarybchik	__in		size_t buffer_size,
1034293901Sarybchik	__out		uint32_t *typep,
1035293901Sarybchik	__out		size_t *lengthp,
1036293901Sarybchik	__out_bcount_part_opt(buffer_size, *lengthp)
1037293901Sarybchik			uint8_t *bufferp)
1038293901Sarybchik{
1039293901Sarybchik	efx_mcdi_req_t req;
1040293901Sarybchik	uint8_t payload[MAX(MC_CMD_LICENSING_GET_ID_V3_IN_LEN,
1041293901Sarybchik			    MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN)];
1042293901Sarybchik	efx_rc_t rc;
1043293901Sarybchik
1044293901Sarybchik	req.emr_cmd = MC_CMD_LICENSING_GET_ID_V3;
1045293901Sarybchik
1046293901Sarybchik	if (bufferp == NULL) {
1047293901Sarybchik		/* Request id type and length only */
1048293901Sarybchik		req.emr_in_buf = bufferp;
1049293901Sarybchik		req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN;
1050293901Sarybchik		req.emr_out_buf = bufferp;
1051293901Sarybchik		req.emr_out_length = MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN;
1052293901Sarybchik		(void) memset(payload, 0, sizeof (payload));
1053293901Sarybchik	} else {
1054293901Sarybchik		/* Request full buffer */
1055293901Sarybchik		req.emr_in_buf = bufferp;
1056293901Sarybchik		req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN;
1057293901Sarybchik		req.emr_out_buf = bufferp;
1058299898Sarybchik		req.emr_out_length = MIN(buffer_size, MC_CMD_LICENSING_GET_ID_V3_OUT_LENMAX);
1059293901Sarybchik		(void) memset(bufferp, 0, req.emr_out_length);
1060293901Sarybchik	}
1061293901Sarybchik
1062299923Sarybchik	efx_mcdi_execute_quiet(enp, &req);
1063293901Sarybchik
1064293901Sarybchik	if (req.emr_rc != 0) {
1065293901Sarybchik		rc = req.emr_rc;
1066293901Sarybchik		goto fail1;
1067293901Sarybchik	}
1068293901Sarybchik
1069293901Sarybchik	if (req.emr_out_length_used < MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN) {
1070293901Sarybchik		rc = EMSGSIZE;
1071293901Sarybchik		goto fail2;
1072293901Sarybchik	}
1073293901Sarybchik
1074293901Sarybchik	*typep = MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_TYPE);
1075293901Sarybchik	*lengthp = MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_ID_LENGTH);
1076293901Sarybchik
1077293901Sarybchik	if (bufferp == NULL) {
1078293901Sarybchik		/* modify length requirements to indicate to caller the extra buffering
1079293901Sarybchik		** needed to read the complete output.
1080293901Sarybchik		*/
1081293901Sarybchik		*lengthp += MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN;
1082293901Sarybchik	} else {
1083293901Sarybchik		/* Shift ID down to start of buffer */
1084293901Sarybchik		memmove(bufferp,
1085310841Sarybchik		    bufferp + MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST,
1086310841Sarybchik		    *lengthp);
1087310841Sarybchik		memset(bufferp + (*lengthp), 0,
1088310841Sarybchik		    MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST);
1089293901Sarybchik	}
1090293901Sarybchik
1091293901Sarybchik	return (0);
1092293901Sarybchik
1093293901Sarybchikfail2:
1094293901Sarybchik	EFSYS_PROBE(fail2);
1095293901Sarybchikfail1:
1096293901Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1097293901Sarybchik
1098293901Sarybchik	return (rc);
1099293901Sarybchik}
1100293901Sarybchik
1101299898Sarybchik/* V3 format uses Huntington TLV format partition. See SF-108797-SW */
1102299898Sarybchik#define EFX_LICENSE_V3_KEY_LENGTH_MIN    (64)
1103299907Sarybchik#define EFX_LICENSE_V3_KEY_LENGTH_MAX    (160)
1104293901Sarybchik
1105299898Sarybchik	__checkReturn		efx_rc_t
1106299898Sarybchikefx_lic_v3_find_start(
1107299898Sarybchik	__in			efx_nic_t *enp,
1108299898Sarybchik	__in_bcount(buffer_size)
1109299898Sarybchik				caddr_t bufferp,
1110299898Sarybchik	__in			size_t buffer_size,
1111299898Sarybchik	__out			uint32_t *startp
1112299898Sarybchik	)
1113299898Sarybchik{
1114299898Sarybchik	_NOTE(ARGUNUSED(enp))
1115299898Sarybchik
1116299898Sarybchik	return ef10_nvram_buffer_find_item_start(bufferp, buffer_size, startp);
1117299898Sarybchik}
1118299898Sarybchik
1119299898Sarybchik	__checkReturn		efx_rc_t
1120299898Sarybchikefx_lic_v3_find_end(
1121299898Sarybchik	__in			efx_nic_t *enp,
1122299898Sarybchik	__in_bcount(buffer_size)
1123299898Sarybchik				caddr_t bufferp,
1124299898Sarybchik	__in			size_t buffer_size,
1125299898Sarybchik	__in			uint32_t offset,
1126299898Sarybchik	__out			uint32_t *endp
1127299898Sarybchik	)
1128299898Sarybchik{
1129299898Sarybchik	_NOTE(ARGUNUSED(enp))
1130299898Sarybchik
1131299898Sarybchik	return ef10_nvram_buffer_find_end(bufferp, buffer_size, offset, endp);
1132299898Sarybchik}
1133299898Sarybchik
1134299898Sarybchik	__checkReturn	__success(return != B_FALSE)	boolean_t
1135299898Sarybchikefx_lic_v3_find_key(
1136299898Sarybchik	__in			efx_nic_t *enp,
1137299898Sarybchik	__in_bcount(buffer_size)
1138299898Sarybchik				caddr_t bufferp,
1139299898Sarybchik	__in			size_t buffer_size,
1140299898Sarybchik	__in			uint32_t offset,
1141299898Sarybchik	__out			uint32_t *startp,
1142299898Sarybchik	__out			uint32_t *lengthp
1143299898Sarybchik	)
1144299898Sarybchik{
1145299898Sarybchik	_NOTE(ARGUNUSED(enp))
1146299898Sarybchik
1147299898Sarybchik	return ef10_nvram_buffer_find_item(bufferp, buffer_size,
1148299898Sarybchik	    offset, startp, lengthp);
1149299898Sarybchik}
1150299898Sarybchik
1151299898Sarybchik	__checkReturn	__success(return != B_FALSE)	boolean_t
1152299898Sarybchikefx_lic_v3_validate_key(
1153299898Sarybchik	__in			efx_nic_t *enp,
1154299898Sarybchik	__in_bcount(length)	caddr_t keyp,
1155299898Sarybchik	__in			uint32_t length
1156299898Sarybchik	)
1157299898Sarybchik{
1158310916Sarybchik	/* Check key is a valid V3 key */
1159299898Sarybchik	uint8_t key_type;
1160299898Sarybchik	uint8_t key_length;
1161299898Sarybchik
1162299898Sarybchik	_NOTE(ARGUNUSED(enp))
1163299898Sarybchik
1164299898Sarybchik	if (length < EFX_LICENSE_V3_KEY_LENGTH_MIN) {
1165299898Sarybchik		goto fail1;
1166299898Sarybchik	}
1167299898Sarybchik
1168299911Sarybchik	if (length > EFX_LICENSE_V3_KEY_LENGTH_MAX) {
1169299911Sarybchik		goto fail2;
1170299911Sarybchik	}
1171299911Sarybchik
1172310922Sarybchik	key_type = ((uint8_t *)keyp)[0];
1173310922Sarybchik	key_length = ((uint8_t *)keyp)[1];
1174299898Sarybchik
1175299898Sarybchik	if (key_type < 3) {
1176299898Sarybchik		goto fail3;
1177299898Sarybchik	}
1178299911Sarybchik	if (key_length > length) {
1179299898Sarybchik		goto fail4;
1180299898Sarybchik	}
1181299898Sarybchik	return (B_TRUE);
1182299898Sarybchik
1183299898Sarybchikfail4:
1184299898Sarybchik	EFSYS_PROBE(fail4);
1185299898Sarybchikfail3:
1186299898Sarybchik	EFSYS_PROBE(fail3);
1187299898Sarybchikfail2:
1188299898Sarybchik	EFSYS_PROBE(fail2);
1189299898Sarybchikfail1:
1190342426Sarybchik	EFSYS_PROBE1(fail1, boolean_t, B_FALSE);
1191299898Sarybchik
1192299898Sarybchik	return (B_FALSE);
1193299898Sarybchik}
1194299898Sarybchik
1195299898Sarybchik	__checkReturn		efx_rc_t
1196299898Sarybchikefx_lic_v3_read_key(
1197299898Sarybchik	__in			efx_nic_t *enp,
1198299898Sarybchik	__in_bcount(buffer_size)
1199299898Sarybchik				caddr_t bufferp,
1200299898Sarybchik	__in			size_t buffer_size,
1201299898Sarybchik	__in			uint32_t offset,
1202299898Sarybchik	__in			uint32_t length,
1203299898Sarybchik	__out_bcount_part(key_max_size, *lengthp)
1204299898Sarybchik				caddr_t keyp,
1205299898Sarybchik	__in			size_t key_max_size,
1206299898Sarybchik	__out			uint32_t *lengthp
1207299898Sarybchik	)
1208299898Sarybchik{
1209299898Sarybchik	_NOTE(ARGUNUSED(enp))
1210299898Sarybchik
1211299898Sarybchik	return ef10_nvram_buffer_get_item(bufferp, buffer_size,
1212299898Sarybchik		    offset, length, keyp, key_max_size, lengthp);
1213299898Sarybchik}
1214299898Sarybchik
1215299898Sarybchik	__checkReturn		efx_rc_t
1216299898Sarybchikefx_lic_v3_write_key(
1217299898Sarybchik	__in			efx_nic_t *enp,
1218299898Sarybchik	__in_bcount(buffer_size)
1219299898Sarybchik				caddr_t bufferp,
1220299898Sarybchik	__in			size_t buffer_size,
1221299898Sarybchik	__in			uint32_t offset,
1222299898Sarybchik	__in_bcount(length)	caddr_t keyp,
1223299898Sarybchik	__in			uint32_t length,
1224299898Sarybchik	__out			uint32_t *lengthp
1225299898Sarybchik	)
1226299898Sarybchik{
1227299898Sarybchik	_NOTE(ARGUNUSED(enp))
1228299898Sarybchik	EFSYS_ASSERT(length <= EFX_LICENSE_V3_KEY_LENGTH_MAX);
1229299898Sarybchik
1230299898Sarybchik	return ef10_nvram_buffer_insert_item(bufferp, buffer_size,
1231299898Sarybchik		    offset, keyp, length, lengthp);
1232299898Sarybchik}
1233299898Sarybchik
1234299898Sarybchik	__checkReturn		efx_rc_t
1235299898Sarybchikefx_lic_v3_delete_key(
1236299898Sarybchik	__in			efx_nic_t *enp,
1237299898Sarybchik	__in_bcount(buffer_size)
1238299898Sarybchik				caddr_t bufferp,
1239299898Sarybchik	__in			size_t buffer_size,
1240299898Sarybchik	__in			uint32_t offset,
1241299898Sarybchik	__in			uint32_t length,
1242299898Sarybchik	__in			uint32_t end,
1243299898Sarybchik	__out			uint32_t *deltap
1244299898Sarybchik	)
1245299898Sarybchik{
1246299898Sarybchik	efx_rc_t rc;
1247299898Sarybchik
1248299898Sarybchik	_NOTE(ARGUNUSED(enp))
1249299898Sarybchik
1250299898Sarybchik	if ((rc = ef10_nvram_buffer_delete_item(bufferp,
1251299898Sarybchik			buffer_size, offset, length, end)) != 0) {
1252299898Sarybchik		goto fail1;
1253299898Sarybchik	}
1254299898Sarybchik
1255299898Sarybchik	*deltap = length;
1256299898Sarybchik
1257299898Sarybchik	return (0);
1258299898Sarybchik
1259299898Sarybchikfail1:
1260299898Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1261299898Sarybchik
1262299898Sarybchik	return (rc);
1263299898Sarybchik}
1264299898Sarybchik
1265299898Sarybchik	__checkReturn		efx_rc_t
1266299898Sarybchikefx_lic_v3_create_partition(
1267299898Sarybchik	__in			efx_nic_t *enp,
1268299898Sarybchik	__in_bcount(buffer_size)
1269299898Sarybchik				caddr_t bufferp,
1270299898Sarybchik	__in			size_t buffer_size
1271299898Sarybchik	)
1272299898Sarybchik{
1273299898Sarybchik	efx_rc_t rc;
1274299898Sarybchik
1275310916Sarybchik	/* Construct empty partition */
1276299898Sarybchik	if ((rc = ef10_nvram_buffer_create(enp,
1277299898Sarybchik	    NVRAM_PARTITION_TYPE_LICENSE,
1278299898Sarybchik	    bufferp, buffer_size)) != 0) {
1279299898Sarybchik		rc = EFAULT;
1280299898Sarybchik		goto fail1;
1281299898Sarybchik	}
1282299898Sarybchik
1283299898Sarybchik	return (0);
1284299898Sarybchik
1285299898Sarybchikfail1:
1286299898Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1287299898Sarybchik
1288299898Sarybchik	return (rc);
1289299898Sarybchik}
1290299898Sarybchik
1291299898Sarybchik	__checkReturn		efx_rc_t
1292299898Sarybchikefx_lic_v3_finish_partition(
1293299898Sarybchik	__in			efx_nic_t *enp,
1294299898Sarybchik	__in_bcount(buffer_size)
1295299898Sarybchik				caddr_t bufferp,
1296299898Sarybchik	__in			size_t buffer_size
1297299898Sarybchik	)
1298299898Sarybchik{
1299299898Sarybchik	efx_rc_t rc;
1300299898Sarybchik
1301299898Sarybchik	if ((rc = ef10_nvram_buffer_finish(bufferp,
1302299898Sarybchik			buffer_size)) != 0) {
1303299898Sarybchik		goto fail1;
1304299898Sarybchik	}
1305299898Sarybchik
1306310916Sarybchik	/* Validate completed partition */
1307299898Sarybchik	if ((rc = ef10_nvram_buffer_validate(enp, NVRAM_PARTITION_TYPE_LICENSE,
1308299898Sarybchik					bufferp, buffer_size)) != 0) {
1309299898Sarybchik		goto fail2;
1310299898Sarybchik	}
1311299898Sarybchik
1312299898Sarybchik	return (0);
1313299898Sarybchik
1314299898Sarybchikfail2:
1315299898Sarybchik	EFSYS_PROBE(fail2);
1316299898Sarybchikfail1:
1317299898Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1318299898Sarybchik
1319299898Sarybchik	return (rc);
1320299898Sarybchik}
1321299898Sarybchik
1322299898Sarybchik
1323293901Sarybchik#endif	/* EFSYS_OPT_MEDFORD */
1324293901Sarybchik
1325293901Sarybchik	__checkReturn		efx_rc_t
1326293901Sarybchikefx_lic_init(
1327293901Sarybchik	__in			efx_nic_t *enp)
1328293901Sarybchik{
1329299517Sarybchik	const efx_lic_ops_t *elop;
1330300007Sarybchik	efx_key_stats_t eks;
1331293901Sarybchik	efx_rc_t rc;
1332293901Sarybchik
1333293901Sarybchik	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1334293901Sarybchik	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
1335293901Sarybchik	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_LIC));
1336293901Sarybchik
1337293901Sarybchik	switch (enp->en_family) {
1338293901Sarybchik
1339293901Sarybchik#if EFSYS_OPT_SIENA
1340293901Sarybchik	case EFX_FAMILY_SIENA:
1341299517Sarybchik		elop = &__efx_lic_v1_ops;
1342293901Sarybchik		break;
1343293901Sarybchik#endif	/* EFSYS_OPT_SIENA */
1344293901Sarybchik
1345293901Sarybchik#if EFSYS_OPT_HUNTINGTON
1346293901Sarybchik	case EFX_FAMILY_HUNTINGTON:
1347299517Sarybchik		elop = &__efx_lic_v2_ops;
1348293901Sarybchik		break;
1349293901Sarybchik#endif	/* EFSYS_OPT_HUNTINGTON */
1350293901Sarybchik
1351293901Sarybchik#if EFSYS_OPT_MEDFORD
1352293901Sarybchik	case EFX_FAMILY_MEDFORD:
1353299517Sarybchik		elop = &__efx_lic_v3_ops;
1354293901Sarybchik		break;
1355293901Sarybchik#endif	/* EFSYS_OPT_MEDFORD */
1356293901Sarybchik
1357293901Sarybchik	default:
1358293901Sarybchik		EFSYS_ASSERT(0);
1359293901Sarybchik		rc = ENOTSUP;
1360293901Sarybchik		goto fail1;
1361293901Sarybchik	}
1362293901Sarybchik
1363293901Sarybchik	enp->en_elop = elop;
1364293901Sarybchik	enp->en_mod_flags |= EFX_MOD_LIC;
1365293901Sarybchik
1366300007Sarybchik	/* Probe for support */
1367300007Sarybchik	if (efx_lic_get_key_stats(enp, &eks) == 0) {
1368300007Sarybchik		enp->en_licensing_supported = B_TRUE;
1369300007Sarybchik	} else {
1370300007Sarybchik		enp->en_licensing_supported = B_FALSE;
1371300007Sarybchik	}
1372300007Sarybchik
1373293901Sarybchik	return (0);
1374293901Sarybchik
1375293901Sarybchikfail1:
1376293901Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1377293901Sarybchik
1378293901Sarybchik	return (rc);
1379293901Sarybchik}
1380293901Sarybchik
1381300007Sarybchikextern	__checkReturn	boolean_t
1382300007Sarybchikefx_lic_check_support(
1383300007Sarybchik	__in			efx_nic_t *enp)
1384300007Sarybchik{
1385300007Sarybchik	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1386300007Sarybchik	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
1387300007Sarybchik	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1388300007Sarybchik
1389300007Sarybchik	return enp->en_licensing_supported;
1390300007Sarybchik}
1391300007Sarybchik
1392293901Sarybchik				void
1393293901Sarybchikefx_lic_fini(
1394293901Sarybchik	__in			efx_nic_t *enp)
1395293901Sarybchik{
1396293901Sarybchik	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1397293901Sarybchik	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
1398293901Sarybchik	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1399293901Sarybchik
1400293901Sarybchik	enp->en_elop = NULL;
1401293901Sarybchik	enp->en_mod_flags &= ~EFX_MOD_LIC;
1402293901Sarybchik}
1403293901Sarybchik
1404293901Sarybchik
1405293901Sarybchik	__checkReturn	efx_rc_t
1406293901Sarybchikefx_lic_update_licenses(
1407293901Sarybchik	__in		efx_nic_t *enp)
1408293901Sarybchik{
1409299517Sarybchik	const efx_lic_ops_t *elop = enp->en_elop;
1410293901Sarybchik	efx_rc_t rc;
1411293901Sarybchik
1412293901Sarybchik	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1413293901Sarybchik	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1414293901Sarybchik
1415293901Sarybchik	if ((rc = elop->elo_update_licenses(enp)) != 0)
1416293901Sarybchik		goto fail1;
1417293901Sarybchik
1418293901Sarybchik	return (0);
1419293901Sarybchik
1420293901Sarybchikfail1:
1421293901Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1422293901Sarybchik
1423293901Sarybchik	return (rc);
1424293901Sarybchik}
1425293901Sarybchik
1426293901Sarybchik	__checkReturn	efx_rc_t
1427293901Sarybchikefx_lic_get_key_stats(
1428293901Sarybchik	__in		efx_nic_t *enp,
1429293901Sarybchik	__out		efx_key_stats_t *eksp)
1430293901Sarybchik{
1431299517Sarybchik	const efx_lic_ops_t *elop = enp->en_elop;
1432293901Sarybchik	efx_rc_t rc;
1433293901Sarybchik
1434293901Sarybchik	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1435293901Sarybchik	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1436293901Sarybchik
1437293901Sarybchik	if ((rc = elop->elo_get_key_stats(enp, eksp)) != 0)
1438293901Sarybchik		goto fail1;
1439293901Sarybchik
1440293901Sarybchik	return (0);
1441293901Sarybchik
1442293901Sarybchikfail1:
1443293901Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1444293901Sarybchik
1445293901Sarybchik	return (rc);
1446293901Sarybchik}
1447293901Sarybchik
1448293901Sarybchik	__checkReturn	efx_rc_t
1449293901Sarybchikefx_lic_app_state(
1450293901Sarybchik	__in		efx_nic_t *enp,
1451293901Sarybchik	__in		uint64_t app_id,
1452293901Sarybchik	__out		boolean_t *licensedp)
1453293901Sarybchik{
1454299517Sarybchik	const efx_lic_ops_t *elop = enp->en_elop;
1455293901Sarybchik	efx_rc_t rc;
1456293901Sarybchik
1457293901Sarybchik	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1458293901Sarybchik	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1459293901Sarybchik
1460299899Sarybchik	if (elop->elo_app_state == NULL)
1461299899Sarybchik		return (ENOTSUP);
1462299899Sarybchik
1463299899Sarybchik	if ((rc = elop->elo_app_state(enp, app_id, licensedp)) != 0)
1464293901Sarybchik		goto fail1;
1465293901Sarybchik
1466293901Sarybchik	return (0);
1467293901Sarybchik
1468293901Sarybchikfail1:
1469293901Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1470293901Sarybchik
1471293901Sarybchik	return (rc);
1472293901Sarybchik}
1473293901Sarybchik
1474293901Sarybchik	__checkReturn	efx_rc_t
1475293901Sarybchikefx_lic_get_id(
1476293901Sarybchik	__in		efx_nic_t *enp,
1477293901Sarybchik	__in		size_t buffer_size,
1478293901Sarybchik	__out		uint32_t *typep,
1479293901Sarybchik	__out		size_t *lengthp,
1480293901Sarybchik	__out_opt	uint8_t *bufferp
1481293901Sarybchik	)
1482293901Sarybchik{
1483299517Sarybchik	const efx_lic_ops_t *elop = enp->en_elop;
1484293901Sarybchik	efx_rc_t rc;
1485293901Sarybchik
1486293901Sarybchik	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1487293901Sarybchik	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1488293901Sarybchik
1489299899Sarybchik	if (elop->elo_get_id == NULL)
1490299899Sarybchik		return (ENOTSUP);
1491293901Sarybchik
1492293901Sarybchik	if ((rc = elop->elo_get_id(enp, buffer_size, typep,
1493293901Sarybchik				    lengthp, bufferp)) != 0)
1494299899Sarybchik		goto fail1;
1495293901Sarybchik
1496293901Sarybchik	return (0);
1497293901Sarybchik
1498293901Sarybchikfail1:
1499293901Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1500293901Sarybchik
1501293901Sarybchik	return (rc);
1502293901Sarybchik}
1503293901Sarybchik
1504299898Sarybchik/* Buffer management API - abstracts varying TLV format used for License partition */
1505299898Sarybchik
1506299898Sarybchik	__checkReturn		efx_rc_t
1507299898Sarybchikefx_lic_find_start(
1508299898Sarybchik	__in			efx_nic_t *enp,
1509299898Sarybchik	__in_bcount(buffer_size)
1510299898Sarybchik				caddr_t bufferp,
1511299898Sarybchik	__in			size_t buffer_size,
1512299898Sarybchik	__out			uint32_t *startp
1513299898Sarybchik	)
1514299898Sarybchik{
1515299898Sarybchik	const efx_lic_ops_t *elop = enp->en_elop;
1516299898Sarybchik	efx_rc_t rc;
1517299898Sarybchik
1518299898Sarybchik	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1519299898Sarybchik	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1520299898Sarybchik
1521299898Sarybchik	if ((rc = elop->elo_find_start(enp, bufferp, buffer_size, startp)) != 0)
1522299898Sarybchik		goto fail1;
1523299898Sarybchik
1524299898Sarybchik	return (0);
1525299898Sarybchik
1526299898Sarybchikfail1:
1527299898Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1528299898Sarybchik
1529299898Sarybchik	return (rc);
1530299898Sarybchik}
1531299898Sarybchik
1532299898Sarybchik	__checkReturn		efx_rc_t
1533299898Sarybchikefx_lic_find_end(
1534299898Sarybchik	__in			efx_nic_t *enp,
1535299898Sarybchik	__in_bcount(buffer_size)
1536299898Sarybchik				caddr_t bufferp,
1537299898Sarybchik	__in			size_t buffer_size,
1538299898Sarybchik	__in			uint32_t offset,
1539299898Sarybchik	__out			uint32_t *endp
1540299898Sarybchik	)
1541299898Sarybchik{
1542299898Sarybchik	const efx_lic_ops_t *elop = enp->en_elop;
1543299898Sarybchik	efx_rc_t rc;
1544299898Sarybchik
1545299898Sarybchik	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1546299898Sarybchik	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1547299898Sarybchik
1548299898Sarybchik	if ((rc = elop->elo_find_end(enp, bufferp, buffer_size, offset, endp)) != 0)
1549299898Sarybchik		goto fail1;
1550299898Sarybchik
1551299898Sarybchik	return (0);
1552299898Sarybchik
1553299898Sarybchikfail1:
1554299898Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1555299898Sarybchik
1556299898Sarybchik	return (rc);
1557299898Sarybchik}
1558299898Sarybchik
1559299898Sarybchik	__checkReturn	__success(return != B_FALSE)	boolean_t
1560299898Sarybchikefx_lic_find_key(
1561299898Sarybchik	__in			efx_nic_t *enp,
1562299898Sarybchik	__in_bcount(buffer_size)
1563299898Sarybchik				caddr_t bufferp,
1564299898Sarybchik	__in			size_t buffer_size,
1565299898Sarybchik	__in			uint32_t offset,
1566299898Sarybchik	__out			uint32_t *startp,
1567299898Sarybchik	__out			uint32_t *lengthp
1568299898Sarybchik	)
1569299898Sarybchik{
1570299898Sarybchik	const efx_lic_ops_t *elop = enp->en_elop;
1571299898Sarybchik
1572299898Sarybchik	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1573299898Sarybchik	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1574299898Sarybchik
1575299898Sarybchik	EFSYS_ASSERT(bufferp);
1576299898Sarybchik	EFSYS_ASSERT(startp);
1577299898Sarybchik	EFSYS_ASSERT(lengthp);
1578299898Sarybchik
1579299898Sarybchik	return (elop->elo_find_key(enp, bufferp, buffer_size, offset,
1580299898Sarybchik				    startp, lengthp));
1581299898Sarybchik}
1582299898Sarybchik
1583299898Sarybchik
1584299898Sarybchik/* Validate that the buffer contains a single key in a recognised format.
1585299898Sarybchik** An empty or terminator buffer is not accepted as a valid key.
1586299898Sarybchik*/
1587299898Sarybchik	__checkReturn	__success(return != B_FALSE)	boolean_t
1588299898Sarybchikefx_lic_validate_key(
1589299898Sarybchik	__in			efx_nic_t *enp,
1590299898Sarybchik	__in_bcount(length)	caddr_t keyp,
1591299898Sarybchik	__in			uint32_t length
1592299898Sarybchik	)
1593299898Sarybchik{
1594299898Sarybchik	const efx_lic_ops_t *elop = enp->en_elop;
1595299898Sarybchik	boolean_t rc;
1596299898Sarybchik
1597299898Sarybchik	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1598299898Sarybchik	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1599299898Sarybchik
1600299898Sarybchik	if ((rc = elop->elo_validate_key(enp, keyp, length)) == B_FALSE)
1601299898Sarybchik		goto fail1;
1602299898Sarybchik
1603299898Sarybchik	return (B_TRUE);
1604299898Sarybchik
1605299898Sarybchikfail1:
1606299898Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1607299898Sarybchik
1608299898Sarybchik	return (rc);
1609299898Sarybchik}
1610299898Sarybchik
1611299898Sarybchik	__checkReturn		efx_rc_t
1612299898Sarybchikefx_lic_read_key(
1613299898Sarybchik	__in			efx_nic_t *enp,
1614299898Sarybchik	__in_bcount(buffer_size)
1615299898Sarybchik				caddr_t bufferp,
1616299898Sarybchik	__in			size_t buffer_size,
1617299898Sarybchik	__in			uint32_t offset,
1618299898Sarybchik	__in			uint32_t length,
1619299898Sarybchik	__out_bcount_part(key_max_size, *lengthp)
1620299898Sarybchik				caddr_t keyp,
1621299898Sarybchik	__in			size_t key_max_size,
1622299898Sarybchik	__out			uint32_t *lengthp
1623299898Sarybchik	)
1624299898Sarybchik{
1625299898Sarybchik	const efx_lic_ops_t *elop = enp->en_elop;
1626299898Sarybchik	efx_rc_t rc;
1627299898Sarybchik
1628299898Sarybchik	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1629299898Sarybchik	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1630299898Sarybchik
1631299898Sarybchik	if ((rc = elop->elo_read_key(enp, bufferp, buffer_size, offset,
1632299898Sarybchik				    length, keyp, key_max_size, lengthp)) != 0)
1633299898Sarybchik		goto fail1;
1634299898Sarybchik
1635299898Sarybchik	return (0);
1636299898Sarybchik
1637299898Sarybchikfail1:
1638299898Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1639299898Sarybchik
1640299898Sarybchik	return (rc);
1641299898Sarybchik}
1642299898Sarybchik
1643299898Sarybchik	__checkReturn		efx_rc_t
1644299898Sarybchikefx_lic_write_key(
1645299898Sarybchik	__in			efx_nic_t *enp,
1646299898Sarybchik	__in_bcount(buffer_size)
1647299898Sarybchik				caddr_t bufferp,
1648299898Sarybchik	__in			size_t buffer_size,
1649299898Sarybchik	__in			uint32_t offset,
1650299898Sarybchik	__in_bcount(length)	caddr_t keyp,
1651299898Sarybchik	__in			uint32_t length,
1652299898Sarybchik	__out			uint32_t *lengthp
1653299898Sarybchik	)
1654299898Sarybchik{
1655299898Sarybchik	const efx_lic_ops_t *elop = enp->en_elop;
1656299898Sarybchik	efx_rc_t rc;
1657299898Sarybchik
1658299898Sarybchik	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1659299898Sarybchik	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1660299898Sarybchik
1661299898Sarybchik	if ((rc = elop->elo_write_key(enp, bufferp, buffer_size, offset,
1662299898Sarybchik				    keyp, length, lengthp)) != 0)
1663299898Sarybchik		goto fail1;
1664299898Sarybchik
1665299898Sarybchik	return (0);
1666299898Sarybchik
1667299898Sarybchikfail1:
1668299898Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1669299898Sarybchik
1670299898Sarybchik	return (rc);
1671299898Sarybchik}
1672299898Sarybchik
1673299898Sarybchik	__checkReturn		efx_rc_t
1674299898Sarybchikefx_lic_delete_key(
1675299898Sarybchik	__in			efx_nic_t *enp,
1676299898Sarybchik	__in_bcount(buffer_size)
1677299898Sarybchik				caddr_t bufferp,
1678299898Sarybchik	__in			size_t buffer_size,
1679299898Sarybchik	__in			uint32_t offset,
1680299898Sarybchik	__in			uint32_t length,
1681299898Sarybchik	__in			uint32_t end,
1682299898Sarybchik	__out			uint32_t *deltap
1683299898Sarybchik	)
1684299898Sarybchik{
1685299898Sarybchik	const efx_lic_ops_t *elop = enp->en_elop;
1686299898Sarybchik	efx_rc_t rc;
1687299898Sarybchik
1688299898Sarybchik	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1689299898Sarybchik	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1690299898Sarybchik
1691299898Sarybchik	if ((rc = elop->elo_delete_key(enp, bufferp, buffer_size, offset,
1692299898Sarybchik				    length, end, deltap)) != 0)
1693299898Sarybchik		goto fail1;
1694299898Sarybchik
1695299898Sarybchik	return (0);
1696299898Sarybchik
1697299898Sarybchikfail1:
1698299898Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1699299898Sarybchik
1700299898Sarybchik	return (rc);
1701299898Sarybchik}
1702299898Sarybchik
1703299898Sarybchik	__checkReturn		efx_rc_t
1704299898Sarybchikefx_lic_create_partition(
1705299898Sarybchik	__in			efx_nic_t *enp,
1706299898Sarybchik	__in_bcount(buffer_size)
1707299898Sarybchik				caddr_t bufferp,
1708299898Sarybchik	__in			size_t buffer_size
1709299898Sarybchik	)
1710299898Sarybchik{
1711299898Sarybchik	const efx_lic_ops_t *elop = enp->en_elop;
1712299898Sarybchik	efx_rc_t rc;
1713299898Sarybchik
1714299898Sarybchik	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1715299898Sarybchik	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1716299898Sarybchik
1717299898Sarybchik	if ((rc = elop->elo_create_partition(enp, bufferp, buffer_size)) != 0)
1718299898Sarybchik		goto fail1;
1719299898Sarybchik
1720299898Sarybchik	return (0);
1721299898Sarybchik
1722299898Sarybchikfail1:
1723299898Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1724299898Sarybchik
1725299898Sarybchik	return (rc);
1726299898Sarybchik}
1727299898Sarybchik
1728299898Sarybchik
1729299898Sarybchik	__checkReturn		efx_rc_t
1730299898Sarybchikefx_lic_finish_partition(
1731299898Sarybchik	__in			efx_nic_t *enp,
1732299898Sarybchik	__in_bcount(buffer_size)
1733299898Sarybchik				caddr_t bufferp,
1734299898Sarybchik	__in			size_t buffer_size
1735299898Sarybchik	)
1736299898Sarybchik{
1737299898Sarybchik	const efx_lic_ops_t *elop = enp->en_elop;
1738299898Sarybchik	efx_rc_t rc;
1739299898Sarybchik
1740299898Sarybchik	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1741299898Sarybchik	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1742299898Sarybchik
1743299898Sarybchik	if ((rc = elop->elo_finish_partition(enp, bufferp, buffer_size)) != 0)
1744299898Sarybchik		goto fail1;
1745299898Sarybchik
1746299898Sarybchik	return (0);
1747299898Sarybchik
1748299898Sarybchikfail1:
1749299898Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1750299898Sarybchik
1751299898Sarybchik	return (rc);
1752299898Sarybchik}
1753299898Sarybchik
1754293901Sarybchik#endif	/* EFSYS_OPT_LICENSING */
1755