efx_lic.c revision 342445
1247835Skib/*-
2247835Skib * Copyright (c) 2009-2016 Solarflare Communications Inc.
3247835Skib * All rights reserved.
4247835Skib *
5247835Skib * Redistribution and use in source and binary forms, with or without
6247835Skib * modification, are permitted provided that the following conditions are met:
7247835Skib *
8247835Skib * 1. Redistributions of source code must retain the above copyright notice,
9247835Skib *    this list of conditions and the following disclaimer.
10247835Skib * 2. Redistributions in binary form must reproduce the above copyright notice,
11247835Skib *    this list of conditions and the following disclaimer in the documentation
12247835Skib *    and/or other materials provided with the distribution.
13247835Skib *
14247835Skib * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15247835Skib * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16247835Skib * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17247835Skib * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18247835Skib * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19247835Skib * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20247835Skib * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21247835Skib * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22247835Skib * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23247835Skib * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24247835Skib * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25247835Skib *
26247835Skib * The views and conclusions contained in the software and documentation are
27247835Skib * those of the authors and should not be interpreted as representing official
28247835Skib * policies, either expressed or implied, of the FreeBSD Project.
29247835Skib */
30247835Skib
31247835Skib#include <sys/cdefs.h>
32247835Skib__FBSDID("$FreeBSD: stable/11/sys/dev/sfxge/common/efx_lic.c 342445 2018-12-25 07:27:45Z arybchik $");
33247835Skib
34247835Skib#include "efx.h"
35247835Skib#include "efx_impl.h"
36247835Skib
37247835Skib#if EFSYS_OPT_LICENSING
38247835Skib
39247835Skib#include "ef10_tlv_layout.h"
40247835Skib
41247835Skib#if EFSYS_OPT_SIENA | EFSYS_OPT_HUNTINGTON
42247835Skib
43247835Skib	__checkReturn		efx_rc_t
44247835Skibefx_lic_v1v2_find_start(
45247835Skib	__in			efx_nic_t *enp,
46247835Skib	__in_bcount(buffer_size)
47247835Skib				caddr_t bufferp,
48247835Skib	__in			size_t buffer_size,
49247835Skib	__out			uint32_t *startp
50247835Skib	);
51247835Skib
52247835Skib	__checkReturn		efx_rc_t
53247835Skibefx_lic_v1v2_find_end(
54247835Skib	__in			efx_nic_t *enp,
55247835Skib	__in_bcount(buffer_size)
56247835Skib				caddr_t bufferp,
57247835Skib	__in			size_t buffer_size,
58247835Skib	__in			uint32_t offset,
59247835Skib	__out			uint32_t *endp
60247835Skib	);
61247835Skib
62247835Skib	__checkReturn	__success(return != B_FALSE)	boolean_t
63247835Skibefx_lic_v1v2_find_key(
64247835Skib	__in			efx_nic_t *enp,
65247835Skib	__in_bcount(buffer_size)
66247835Skib				caddr_t bufferp,
67247835Skib	__in			size_t buffer_size,
68247835Skib	__in			uint32_t offset,
69247835Skib	__out			uint32_t *startp,
70247835Skib	__out			uint32_t *lengthp
71247835Skib	);
72247835Skib
73247835Skib	__checkReturn	__success(return != B_FALSE)	boolean_t
74247835Skibefx_lic_v1v2_validate_key(
75247835Skib	__in			efx_nic_t *enp,
76247835Skib	__in_bcount(length)	caddr_t keyp,
77247835Skib	__in			uint32_t length
78247835Skib	);
79247835Skib
80247835Skib	__checkReturn		efx_rc_t
81247835Skibefx_lic_v1v2_read_key(
82247835Skib	__in			efx_nic_t *enp,
83247835Skib	__in_bcount(buffer_size)
84247835Skib				caddr_t bufferp,
85247835Skib	__in			size_t buffer_size,
86247835Skib	__in			uint32_t offset,
87247835Skib	__in			uint32_t length,
88247835Skib	__out_bcount_part(key_max_size, *lengthp)
89247835Skib				caddr_t keyp,
90247835Skib	__in			size_t key_max_size,
91247835Skib	__out			uint32_t *lengthp
92247835Skib	);
93247835Skib
94247835Skib	__checkReturn		efx_rc_t
95247835Skibefx_lic_v1v2_write_key(
96247835Skib	__in			efx_nic_t *enp,
97247835Skib	__in_bcount(buffer_size)
98247835Skib				caddr_t bufferp,
99247835Skib	__in			size_t buffer_size,
100247835Skib	__in			uint32_t offset,
101247835Skib	__in_bcount(length)	caddr_t keyp,
102247835Skib	__in			uint32_t length,
103247835Skib	__out			uint32_t *lengthp
104247835Skib	);
105247835Skib
106247835Skib	__checkReturn		efx_rc_t
107247835Skibefx_lic_v1v2_delete_key(
108247835Skib	__in			efx_nic_t *enp,
109247835Skib	__in_bcount(buffer_size)
110247849Skib				caddr_t bufferp,
111247849Skib	__in			size_t buffer_size,
112247849Skib	__in			uint32_t offset,
113247849Skib	__in			uint32_t length,
114247849Skib	__in			uint32_t end,
115247849Skib	__out			uint32_t *deltap
116247849Skib	);
117247849Skib
118247835Skib	__checkReturn		efx_rc_t
119247835Skibefx_lic_v1v2_create_partition(
120247849Skib	__in			efx_nic_t *enp,
121247849Skib	__in_bcount(buffer_size)
122247849Skib				caddr_t bufferp,
123247849Skib	__in			size_t buffer_size
124247849Skib	);
125247849Skib
126247835Skib	__checkReturn		efx_rc_t
127247835Skibefx_lic_v1v2_finish_partition(
128247835Skib	__in			efx_nic_t *enp,
129247835Skib	__in_bcount(buffer_size)
130247835Skib				caddr_t bufferp,
131247835Skib	__in			size_t buffer_size
132247835Skib	);
133247835Skib
134247835Skib#endif	/* EFSYS_OPT_HUNTINGTON | EFSYS_OPT_SIENA */
135247835Skib
136247835Skib
137247835Skib#if EFSYS_OPT_SIENA
138267548Sattilio
139247835Skibstatic	__checkReturn	efx_rc_t
140247835Skibefx_mcdi_fc_license_update_license(
141247835Skib	__in		efx_nic_t *enp);
142247835Skib
143247835Skibstatic	__checkReturn	efx_rc_t
144247835Skibefx_mcdi_fc_license_get_key_stats(
145247835Skib	__in		efx_nic_t *enp,
146247835Skib	__out		efx_key_stats_t *eksp);
147247835Skib
148247835Skibstatic const efx_lic_ops_t	__efx_lic_v1_ops = {
149247835Skib	efx_mcdi_fc_license_update_license,	/* elo_update_licenses */
150247835Skib	efx_mcdi_fc_license_get_key_stats,	/* elo_get_key_stats */
151247835Skib	NULL,					/* elo_app_state */
152247835Skib	NULL,					/* elo_get_id */
153247835Skib	efx_lic_v1v2_find_start,		/* elo_find_start */
154247835Skib	efx_lic_v1v2_find_end,			/* elo_find_end */
155247835Skib	efx_lic_v1v2_find_key,			/* elo_find_key */
156247835Skib	efx_lic_v1v2_validate_key,		/* elo_validate_key */
157247835Skib	efx_lic_v1v2_read_key,			/* elo_read_key */
158247835Skib	efx_lic_v1v2_write_key,			/* elo_write_key */
159247835Skib	efx_lic_v1v2_delete_key,		/* elo_delete_key */
160247835Skib	efx_lic_v1v2_create_partition,		/* elo_create_partition */
161247835Skib	efx_lic_v1v2_finish_partition,		/* elo_finish_partition */
162247835Skib};
163247835Skib
164247835Skib#endif	/* EFSYS_OPT_SIENA */
165247835Skib
166247835Skib#if EFSYS_OPT_HUNTINGTON
167247835Skib
168247835Skibstatic	__checkReturn	efx_rc_t
169247835Skibefx_mcdi_licensing_update_licenses(
170247835Skib	__in		efx_nic_t *enp);
171247835Skib
172247835Skibstatic	__checkReturn	efx_rc_t
173247835Skibefx_mcdi_licensing_get_key_stats(
174247835Skib	__in		efx_nic_t *enp,
175247835Skib	__out		efx_key_stats_t *eksp);
176247835Skib
177247835Skibstatic	__checkReturn	efx_rc_t
178247835Skibefx_mcdi_licensed_app_state(
179247835Skib	__in		efx_nic_t *enp,
180247835Skib	__in		uint64_t app_id,
181247835Skib	__out		boolean_t *licensedp);
182247835Skib
183247835Skibstatic const efx_lic_ops_t	__efx_lic_v2_ops = {
184247835Skib	efx_mcdi_licensing_update_licenses,	/* elo_update_licenses */
185247835Skib	efx_mcdi_licensing_get_key_stats,	/* elo_get_key_stats */
186247835Skib	efx_mcdi_licensed_app_state,		/* elo_app_state */
187247835Skib	NULL,					/* elo_get_id */
188247835Skib	efx_lic_v1v2_find_start,		/* elo_find_start */
189247835Skib	efx_lic_v1v2_find_end,			/* elo_find_end */
190247835Skib	efx_lic_v1v2_find_key,			/* elo_find_key */
191247835Skib	efx_lic_v1v2_validate_key,		/* elo_validate_key */
192247835Skib	efx_lic_v1v2_read_key,			/* elo_read_key */
193247835Skib	efx_lic_v1v2_write_key,			/* elo_write_key */
194247835Skib	efx_lic_v1v2_delete_key,		/* elo_delete_key */
195247835Skib	efx_lic_v1v2_create_partition,		/* elo_create_partition */
196247835Skib	efx_lic_v1v2_finish_partition,		/* elo_finish_partition */
197247835Skib};
198247835Skib
199247835Skib#endif	/* EFSYS_OPT_HUNTINGTON */
200247835Skib
201247835Skib#if EFSYS_OPT_MEDFORD
202247835Skib
203247835Skibstatic	__checkReturn	efx_rc_t
204247835Skibefx_mcdi_licensing_v3_update_licenses(
205247835Skib	__in		efx_nic_t *enp);
206247835Skib
207247835Skibstatic	__checkReturn	efx_rc_t
208247835Skibefx_mcdi_licensing_v3_report_license(
209247835Skib	__in		efx_nic_t *enp,
210247835Skib	__out		efx_key_stats_t *eksp);
211247835Skib
212247835Skibstatic	__checkReturn	efx_rc_t
213247835Skibefx_mcdi_licensing_v3_app_state(
214247835Skib	__in		efx_nic_t *enp,
215247835Skib	__in		uint64_t app_id,
216247835Skib	__out		boolean_t *licensedp);
217247835Skib
218247835Skibstatic	__checkReturn	efx_rc_t
219273862Stijlefx_mcdi_licensing_v3_get_id(
220247835Skib	__in		efx_nic_t *enp,
221247835Skib	__in		size_t buffer_size,
222273862Stijl	__out		uint32_t *typep,
223273862Stijl	__out		size_t *lengthp,
224247835Skib	__out_bcount_part_opt(buffer_size, *lengthp)
225247835Skib			uint8_t *bufferp);
226247835Skib
227247835Skib	__checkReturn		efx_rc_t
228247835Skibefx_lic_v3_find_start(
229247835Skib	__in			efx_nic_t *enp,
230273862Stijl	__in_bcount(buffer_size)
231247835Skib				caddr_t bufferp,
232247835Skib	__in			size_t buffer_size,
233273862Stijl	__out			uint32_t *startp
234273862Stijl	);
235247835Skib
236247835Skib	__checkReturn		efx_rc_t
237247835Skibefx_lic_v3_find_end(
238247835Skib	__in			efx_nic_t *enp,
239247835Skib	__in_bcount(buffer_size)
240247835Skib				caddr_t bufferp,
241273862Stijl	__in			size_t buffer_size,
242247835Skib	__in			uint32_t offset,
243247835Skib	__out			uint32_t *endp
244273862Stijl	);
245273862Stijl
246247835Skib	__checkReturn	__success(return != B_FALSE)	boolean_t
247247835Skibefx_lic_v3_find_key(
248247835Skib	__in			efx_nic_t *enp,
249247835Skib	__in_bcount(buffer_size)
250247835Skib				caddr_t bufferp,
251247835Skib	__in			size_t buffer_size,
252247835Skib	__in			uint32_t offset,
253247835Skib	__out			uint32_t *startp,
254247835Skib	__out			uint32_t *lengthp
255247835Skib	);
256247835Skib
257247835Skib	__checkReturn	__success(return != B_FALSE)	boolean_t
258247835Skibefx_lic_v3_validate_key(
259247835Skib	__in			efx_nic_t *enp,
260247835Skib	__in_bcount(length)	caddr_t keyp,
261247835Skib	__in			uint32_t length
262247835Skib	);
263247835Skib
264247835Skib	__checkReturn		efx_rc_t
265247835Skibefx_lic_v3_read_key(
266247835Skib	__in			efx_nic_t *enp,
267247835Skib	__in_bcount(buffer_size)
268247835Skib				caddr_t bufferp,
269247835Skib	__in			size_t buffer_size,
270247835Skib	__in			uint32_t offset,
271247835Skib	__in			uint32_t length,
272247835Skib	__out_bcount_part(key_max_size, *lengthp)
273247835Skib				caddr_t keyp,
274247835Skib	__in			size_t key_max_size,
275247835Skib	__out			uint32_t *lengthp
276247835Skib	);
277247835Skib
278247835Skib	__checkReturn		efx_rc_t
279247835Skibefx_lic_v3_write_key(
280247835Skib	__in			efx_nic_t *enp,
281247835Skib	__in_bcount(buffer_size)
282247835Skib				caddr_t bufferp,
283247835Skib	__in			size_t buffer_size,
284247835Skib	__in			uint32_t offset,
285247835Skib	__in_bcount(length)	caddr_t keyp,
286247835Skib	__in			uint32_t length,
287247835Skib	__out			uint32_t *lengthp
288247835Skib	);
289247835Skib
290247835Skib	__checkReturn		efx_rc_t
291247835Skibefx_lic_v3_delete_key(
292247835Skib	__in			efx_nic_t *enp,
293247835Skib	__in_bcount(buffer_size)
294247835Skib				caddr_t bufferp,
295247835Skib	__in			size_t buffer_size,
296247835Skib	__in			uint32_t offset,
297247835Skib	__in			uint32_t length,
298247835Skib	__in			uint32_t end,
299247835Skib	__out			uint32_t *deltap
300247835Skib	);
301247835Skib
302247835Skib	__checkReturn		efx_rc_t
303247835Skibefx_lic_v3_create_partition(
304247835Skib	__in			efx_nic_t *enp,
305254873Sdumbbell	__in_bcount(buffer_size)
306247835Skib				caddr_t bufferp,
307247835Skib	__in			size_t buffer_size
308247835Skib	);
309247835Skib
310247835Skib	__checkReturn		efx_rc_t
311247835Skibefx_lic_v3_finish_partition(
312247835Skib	__in			efx_nic_t *enp,
313247835Skib	__in_bcount(buffer_size)
314247835Skib				caddr_t bufferp,
315247835Skib	__in			size_t buffer_size
316254182Skib	);
317247835Skib
318247835Skibstatic const efx_lic_ops_t	__efx_lic_v3_ops = {
319247835Skib	efx_mcdi_licensing_v3_update_licenses,	/* elo_update_licenses */
320247835Skib	efx_mcdi_licensing_v3_report_license,	/* elo_get_key_stats */
321247835Skib	efx_mcdi_licensing_v3_app_state,	/* elo_app_state */
322247835Skib	efx_mcdi_licensing_v3_get_id,		/* elo_get_id */
323247835Skib	efx_lic_v3_find_start,			/* elo_find_start*/
324254873Sdumbbell	efx_lic_v3_find_end,			/* elo_find_end */
325254873Sdumbbell	efx_lic_v3_find_key,			/* elo_find_key */
326247835Skib	efx_lic_v3_validate_key,		/* elo_validate_key */
327247835Skib	efx_lic_v3_read_key,			/* elo_read_key */
328247835Skib	efx_lic_v3_write_key,			/* elo_write_key */
329247835Skib	efx_lic_v3_delete_key,			/* elo_delete_key */
330247835Skib	efx_lic_v3_create_partition,		/* elo_create_partition */
331247835Skib	efx_lic_v3_finish_partition,		/* elo_finish_partition */
332247835Skib};
333247835Skib
334247835Skib#endif	/* EFSYS_OPT_MEDFORD */
335247835Skib
336247835Skib
337247835Skib/* V1 Licensing - used in Siena Modena only */
338247835Skib
339247835Skib#if EFSYS_OPT_SIENA
340247835Skib
341247835Skibstatic	__checkReturn	efx_rc_t
342247835Skibefx_mcdi_fc_license_update_license(
343247835Skib	__in		efx_nic_t *enp)
344247835Skib{
345247835Skib	efx_mcdi_req_t req;
346247835Skib	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FC_IN_LICENSE_LEN, 0);
347247835Skib	efx_rc_t rc;
348247835Skib
349247835Skib	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
350247835Skib
351247835Skib	req.emr_cmd = MC_CMD_FC;
352247835Skib	req.emr_in_buf = payload;
353247835Skib	req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN;
354247835Skib	req.emr_out_buf = payload;
355247835Skib	req.emr_out_length = 0;
356247835Skib
357247835Skib	MCDI_IN_SET_DWORD(req, FC_IN_CMD,
358247835Skib	    MC_CMD_FC_OP_LICENSE);
359247835Skib
360254873Sdumbbell	MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP,
361254873Sdumbbell	    MC_CMD_FC_IN_LICENSE_UPDATE_LICENSE);
362247835Skib
363247835Skib	efx_mcdi_execute(enp, &req);
364247835Skib
365247835Skib	if (req.emr_rc != 0) {
366247835Skib		rc = req.emr_rc;
367247835Skib		goto fail1;
368247835Skib	}
369247835Skib
370247835Skib	if (req.emr_out_length_used != 0) {
371247835Skib		rc = EIO;
372247835Skib		goto fail2;
373247835Skib	}
374247835Skib
375247835Skib	return (0);
376247835Skib
377247835Skibfail2:
378247835Skib	EFSYS_PROBE(fail2);
379247835Skibfail1:
380247835Skib	EFSYS_PROBE1(fail1, efx_rc_t, rc);
381247835Skib
382247835Skib	return (rc);
383247835Skib}
384247835Skib
385247835Skibstatic	__checkReturn	efx_rc_t
386247835Skibefx_mcdi_fc_license_get_key_stats(
387247835Skib	__in		efx_nic_t *enp,
388247835Skib	__out		efx_key_stats_t *eksp)
389247835Skib{
390247835Skib	efx_mcdi_req_t req;
391247835Skib	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FC_IN_LICENSE_LEN,
392247835Skib		MC_CMD_FC_OUT_LICENSE_LEN);
393247835Skib	efx_rc_t rc;
394247835Skib
395247835Skib	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
396247835Skib
397247835Skib	req.emr_cmd = MC_CMD_FC;
398247835Skib	req.emr_in_buf = payload;
399247835Skib	req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN;
400247835Skib	req.emr_out_buf = payload;
401247835Skib	req.emr_out_length = MC_CMD_FC_OUT_LICENSE_LEN;
402247835Skib
403247835Skib	MCDI_IN_SET_DWORD(req, FC_IN_CMD,
404247835Skib	    MC_CMD_FC_OP_LICENSE);
405247835Skib
406247835Skib	MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP,
407247835Skib	    MC_CMD_FC_IN_LICENSE_GET_KEY_STATS);
408247835Skib
409247835Skib	efx_mcdi_execute_quiet(enp, &req);
410247835Skib
411247835Skib	if (req.emr_rc != 0) {
412247835Skib		rc = req.emr_rc;
413247835Skib		goto fail1;
414247835Skib	}
415247835Skib
416247835Skib	if (req.emr_out_length_used < MC_CMD_FC_OUT_LICENSE_LEN) {
417247835Skib		rc = EMSGSIZE;
418247835Skib		goto fail2;
419247835Skib	}
420247835Skib
421247835Skib	eksp->eks_valid =
422247835Skib		MCDI_OUT_DWORD(req, FC_OUT_LICENSE_VALID_KEYS);
423247835Skib	eksp->eks_invalid =
424247835Skib		MCDI_OUT_DWORD(req, FC_OUT_LICENSE_INVALID_KEYS);
425247835Skib	eksp->eks_blacklisted =
426247835Skib		MCDI_OUT_DWORD(req, FC_OUT_LICENSE_BLACKLISTED_KEYS);
427247835Skib	eksp->eks_unverifiable = 0;
428247835Skib	eksp->eks_wrong_node = 0;
429247835Skib	eksp->eks_licensed_apps_lo = 0;
430247835Skib	eksp->eks_licensed_apps_hi = 0;
431247835Skib	eksp->eks_licensed_features_lo = 0;
432247835Skib	eksp->eks_licensed_features_hi = 0;
433247835Skib
434247835Skib	return (0);
435247835Skib
436247835Skibfail2:
437247835Skib	EFSYS_PROBE(fail2);
438247835Skibfail1:
439247835Skib	EFSYS_PROBE1(fail1, efx_rc_t, rc);
440247835Skib
441247835Skib	return (rc);
442247835Skib}
443247835Skib
444247835Skib#endif	/* EFSYS_OPT_SIENA */
445247835Skib
446247835Skib/* V1 and V2 Partition format - based on a 16-bit TLV format */
447247835Skib
448247835Skib#if EFSYS_OPT_SIENA | EFSYS_OPT_HUNTINGTON
449247835Skib
450247835Skib/*
451247835Skib * V1/V2 format - defined in SF-108542-TC section 4.2:
452247835Skib *  Type (T):   16bit - revision/HMAC algorithm
453247835Skib *  Length (L): 16bit - value length in bytes
454247835Skib *  Value (V):  L bytes - payload
455247835Skib */
456247835Skib#define EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX    (256)
457247835Skib#define EFX_LICENSE_V1V2_HEADER_LENGTH         (2 * sizeof(uint16_t))
458254182Skib
459247835Skib	__checkReturn		efx_rc_t
460247835Skibefx_lic_v1v2_find_start(
461247835Skib	__in			efx_nic_t *enp,
462247835Skib	__in_bcount(buffer_size)
463247835Skib				caddr_t bufferp,
464247835Skib	__in			size_t buffer_size,
465247835Skib	__out			uint32_t *startp
466247835Skib	)
467247835Skib{
468247835Skib	_NOTE(ARGUNUSED(enp, bufferp, buffer_size))
469247835Skib
470247835Skib	*startp = 0;
471247835Skib	return (0);
472247835Skib}
473247835Skib
474247835Skib	__checkReturn		efx_rc_t
475247835Skibefx_lic_v1v2_find_end(
476247835Skib	__in			efx_nic_t *enp,
477247835Skib	__in_bcount(buffer_size)
478247835Skib				caddr_t bufferp,
479247835Skib	__in			size_t buffer_size,
480247835Skib	__in			uint32_t offset,
481247835Skib	__out			uint32_t *endp
482247835Skib	)
483247835Skib{
484247835Skib	_NOTE(ARGUNUSED(enp, bufferp, buffer_size))
485247835Skib
486247835Skib	*endp = offset + EFX_LICENSE_V1V2_HEADER_LENGTH;
487247835Skib	return (0);
488247835Skib}
489247835Skib
490247835Skib	__checkReturn	__success(return != B_FALSE)	boolean_t
491247835Skibefx_lic_v1v2_find_key(
492247835Skib	__in			efx_nic_t *enp,
493247835Skib	__in_bcount(buffer_size)
494247835Skib				caddr_t bufferp,
495247835Skib	__in			size_t buffer_size,
496247835Skib	__in			uint32_t offset,
497247835Skib	__out			uint32_t *startp,
498247835Skib	__out			uint32_t *lengthp
499247835Skib	)
500247835Skib{
501247835Skib	boolean_t found;
502247835Skib	uint16_t tlv_type;
503247835Skib	uint16_t tlv_length;
504247835Skib
505247835Skib	_NOTE(ARGUNUSED(enp))
506247835Skib
507247835Skib	if ((size_t)buffer_size - offset < EFX_LICENSE_V1V2_HEADER_LENGTH)
508247835Skib		goto fail1;
509247835Skib
510247835Skib	tlv_type = __LE_TO_CPU_16(((uint16_t *)&bufferp[offset])[0]);
511247835Skib	tlv_length = __LE_TO_CPU_16(((uint16_t *)&bufferp[offset])[1]);
512247835Skib	if ((tlv_length > EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX) ||
513247835Skib	    (tlv_type == 0 && tlv_length == 0)) {
514247835Skib		found = B_FALSE;
515247835Skib	} else {
516247835Skib		*startp = offset;
517247835Skib		*lengthp = tlv_length + EFX_LICENSE_V1V2_HEADER_LENGTH;
518247835Skib		found = B_TRUE;
519247835Skib	}
520247835Skib	return (found);
521247835Skib
522247835Skibfail1:
523247835Skib	EFSYS_PROBE1(fail1, boolean_t, B_FALSE);
524247835Skib
525247835Skib	return (B_FALSE);
526247835Skib}
527247835Skib
528247835Skib	__checkReturn	__success(return != B_FALSE)	boolean_t
529247835Skibefx_lic_v1v2_validate_key(
530247835Skib	__in			efx_nic_t *enp,
531247835Skib	__in_bcount(length)	caddr_t keyp,
532247835Skib	__in			uint32_t length
533254182Skib	)
534247835Skib{
535247835Skib	uint16_t tlv_type;
536247835Skib	uint16_t tlv_length;
537247835Skib
538247835Skib	_NOTE(ARGUNUSED(enp))
539247835Skib
540247835Skib	if (length < EFX_LICENSE_V1V2_HEADER_LENGTH) {
541247835Skib		goto fail1;
542247835Skib	}
543247835Skib
544247835Skib	tlv_type = __LE_TO_CPU_16(((uint16_t *)keyp)[0]);
545247835Skib	tlv_length = __LE_TO_CPU_16(((uint16_t *)keyp)[1]);
546247835Skib
547247835Skib	if (tlv_length > EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX) {
548247835Skib		goto fail2;
549247835Skib	}
550247835Skib	if (tlv_type == 0) {
551247835Skib		goto fail3;
552247835Skib	}
553247835Skib	if ((tlv_length + EFX_LICENSE_V1V2_HEADER_LENGTH) != length) {
554247835Skib		goto fail4;
555247835Skib	}
556247835Skib
557247835Skib	return (B_TRUE);
558247835Skib
559247835Skibfail4:
560247835Skib	EFSYS_PROBE(fail4);
561247835Skibfail3:
562247835Skib	EFSYS_PROBE(fail3);
563247835Skibfail2:
564247835Skib	EFSYS_PROBE(fail2);
565247835Skibfail1:
566247835Skib	EFSYS_PROBE1(fail1, boolean_t, B_FALSE);
567247835Skib
568247835Skib	return (B_FALSE);
569247835Skib}
570247835Skib
571247835Skib
572247835Skib	__checkReturn		efx_rc_t
573247835Skibefx_lic_v1v2_read_key(
574247835Skib	__in			efx_nic_t *enp,
575247835Skib	__in_bcount(buffer_size)
576247835Skib				caddr_t bufferp,
577247835Skib	__in			size_t buffer_size,
578247835Skib	__in			uint32_t offset,
579247835Skib	__in			uint32_t length,
580247835Skib	__out_bcount_part(key_max_size, *lengthp)
581247835Skib				caddr_t keyp,
582247835Skib	__in			size_t key_max_size,
583247835Skib	__out			uint32_t *lengthp
584247835Skib	)
585247835Skib{
586247835Skib	efx_rc_t rc;
587247835Skib
588254182Skib	_NOTE(ARGUNUSED(enp, buffer_size))
589247835Skib	EFSYS_ASSERT(length <= (EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX +
590247835Skib	    EFX_LICENSE_V1V2_HEADER_LENGTH));
591247835Skib
592247835Skib	if (key_max_size < length) {
593247835Skib		rc = ENOSPC;
594254182Skib		goto fail1;
595247835Skib	}
596247835Skib	memcpy(keyp, &bufferp[offset], length);
597254182Skib
598247835Skib	*lengthp = length;
599247835Skib
600247835Skib	return (0);
601247835Skib
602247835Skibfail1:
603247835Skib	EFSYS_PROBE1(fail1, efx_rc_t, rc);
604247835Skib
605247835Skib	return (rc);
606247835Skib}
607247835Skib
608247835Skib	__checkReturn		efx_rc_t
609247835Skibefx_lic_v1v2_write_key(
610247835Skib	__in			efx_nic_t *enp,
611247835Skib	__in_bcount(buffer_size)
612247835Skib				caddr_t bufferp,
613247835Skib	__in			size_t buffer_size,
614247835Skib	__in			uint32_t offset,
615247835Skib	__in_bcount(length)	caddr_t keyp,
616247835Skib	__in			uint32_t length,
617247835Skib	__out			uint32_t *lengthp
618247835Skib	)
619247835Skib{
620247835Skib	efx_rc_t rc;
621247835Skib
622247835Skib	_NOTE(ARGUNUSED(enp))
623247835Skib	EFSYS_ASSERT(length <= (EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX +
624254182Skib	    EFX_LICENSE_V1V2_HEADER_LENGTH));
625247835Skib
626247835Skib	/* Ensure space for terminator remains */
627247835Skib	if ((offset + length) >
628247835Skib	    (buffer_size - EFX_LICENSE_V1V2_HEADER_LENGTH)) {
629247835Skib		rc = ENOSPC;
630247835Skib		goto fail1;
631254182Skib	}
632254182Skib
633247835Skib	memcpy(bufferp + offset, keyp, length);
634247835Skib
635247835Skib	*lengthp = length;
636247835Skib
637247835Skib	return (0);
638247835Skib
639247835Skibfail1:
640247835Skib	EFSYS_PROBE1(fail1, efx_rc_t, rc);
641247835Skib
642247835Skib	return (rc);
643247835Skib}
644247835Skib
645247835Skib	__checkReturn		efx_rc_t
646247835Skibefx_lic_v1v2_delete_key(
647247835Skib	__in			efx_nic_t *enp,
648247835Skib	__in_bcount(buffer_size)
649247835Skib				caddr_t bufferp,
650247835Skib	__in			size_t buffer_size,
651247835Skib	__in			uint32_t offset,
652247835Skib	__in			uint32_t length,
653247835Skib	__in			uint32_t end,
654247835Skib	__out			uint32_t *deltap
655247835Skib	)
656247835Skib{
657247835Skib	uint32_t move_start = offset + length;
658247835Skib	uint32_t move_length = end - move_start;
659247835Skib
660247835Skib	_NOTE(ARGUNUSED(enp, buffer_size))
661247835Skib	EFSYS_ASSERT(end <= buffer_size);
662254182Skib
663247835Skib	/* Shift everything after the key down */
664247835Skib	memmove(bufferp + offset, bufferp + move_start, move_length);
665247835Skib
666247835Skib	*deltap = length;
667247835Skib
668247835Skib	return (0);
669247835Skib}
670247835Skib
671247835Skib	__checkReturn		efx_rc_t
672247835Skibefx_lic_v1v2_create_partition(
673247835Skib	__in			efx_nic_t *enp,
674247835Skib	__in_bcount(buffer_size)
675247835Skib				caddr_t bufferp,
676247835Skib	__in			size_t buffer_size
677247835Skib	)
678247835Skib{
679247835Skib	_NOTE(ARGUNUSED(enp, buffer_size))
680247835Skib	EFSYS_ASSERT(EFX_LICENSE_V1V2_HEADER_LENGTH <= buffer_size);
681247835Skib
682247835Skib	/* Write terminator */
683247835Skib	memset(bufferp, '\0', EFX_LICENSE_V1V2_HEADER_LENGTH);
684247835Skib	return (0);
685247835Skib}
686247835Skib
687247835Skib
688247835Skib	__checkReturn		efx_rc_t
689247835Skibefx_lic_v1v2_finish_partition(
690247835Skib	__in			efx_nic_t *enp,
691247835Skib	__in_bcount(buffer_size)
692247835Skib				caddr_t bufferp,
693247835Skib	__in			size_t buffer_size
694247835Skib	)
695247835Skib{
696247835Skib	_NOTE(ARGUNUSED(enp, bufferp, buffer_size))
697247835Skib
698247835Skib	return (0);
699247835Skib}
700247835Skib
701247835Skib#endif	/* EFSYS_OPT_HUNTINGTON | EFSYS_OPT_SIENA */
702247835Skib
703247835Skib
704247835Skib/* V2 Licensing - used by Huntington family only. See SF-113611-TC */
705247835Skib
706247835Skib#if EFSYS_OPT_HUNTINGTON
707247835Skib
708247835Skibstatic	__checkReturn	efx_rc_t
709247835Skibefx_mcdi_licensed_app_state(
710247835Skib	__in		efx_nic_t *enp,
711247835Skib	__in		uint64_t app_id,
712247835Skib	__out		boolean_t *licensedp)
713247835Skib{
714247835Skib	efx_mcdi_req_t req;
715247835Skib	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LICENSED_APP_STATE_IN_LEN,
716247835Skib		MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN);
717247835Skib	uint32_t app_state;
718247835Skib	efx_rc_t rc;
719247835Skib
720247835Skib	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
721247835Skib
722247835Skib	/* V2 licensing supports 32bit app id only */
723254182Skib	if ((app_id >> 32) != 0) {
724247835Skib		rc = EINVAL;
725247835Skib		goto fail1;
726247835Skib	}
727247835Skib
728247835Skib	req.emr_cmd = MC_CMD_GET_LICENSED_APP_STATE;
729254182Skib	req.emr_in_buf = payload;
730247835Skib	req.emr_in_length = MC_CMD_GET_LICENSED_APP_STATE_IN_LEN;
731247835Skib	req.emr_out_buf = payload;
732247835Skib	req.emr_out_length = MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN;
733247835Skib
734247835Skib	MCDI_IN_SET_DWORD(req, GET_LICENSED_APP_STATE_IN_APP_ID,
735247835Skib		    app_id & 0xffffffff);
736247835Skib
737247835Skib	efx_mcdi_execute(enp, &req);
738247835Skib
739247835Skib	if (req.emr_rc != 0) {
740247835Skib		rc = req.emr_rc;
741247835Skib		goto fail2;
742254182Skib	}
743247835Skib
744247835Skib	if (req.emr_out_length_used < MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN) {
745247835Skib		rc = EMSGSIZE;
746247835Skib		goto fail3;
747247835Skib	}
748247835Skib
749247835Skib	app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_APP_STATE_OUT_STATE));
750247835Skib	if (app_state != MC_CMD_GET_LICENSED_APP_STATE_OUT_NOT_LICENSED) {
751247835Skib		*licensedp = B_TRUE;
752247835Skib	} else {
753247835Skib		*licensedp = B_FALSE;
754247835Skib	}
755247835Skib
756247835Skib	return (0);
757247835Skib
758247835Skibfail3:
759247835Skib	EFSYS_PROBE(fail3);
760247835Skibfail2:
761247835Skib	EFSYS_PROBE(fail2);
762247835Skibfail1:
763247835Skib	EFSYS_PROBE1(fail1, efx_rc_t, rc);
764247835Skib
765247835Skib	return (rc);
766247835Skib}
767247835Skib
768247835Skibstatic	__checkReturn	efx_rc_t
769247835Skibefx_mcdi_licensing_update_licenses(
770247835Skib	__in		efx_nic_t *enp)
771247835Skib{
772247835Skib	efx_mcdi_req_t req;
773247835Skib	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_IN_LEN, 0);
774247835Skib	efx_rc_t rc;
775247835Skib
776247835Skib	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
777247835Skib
778247835Skib	req.emr_cmd = MC_CMD_LICENSING;
779247835Skib	req.emr_in_buf = payload;
780247835Skib	req.emr_in_length = MC_CMD_LICENSING_IN_LEN;
781247835Skib	req.emr_out_buf = payload;
782247835Skib	req.emr_out_length = 0;
783247835Skib
784247835Skib	MCDI_IN_SET_DWORD(req, LICENSING_IN_OP,
785247835Skib	    MC_CMD_LICENSING_IN_OP_UPDATE_LICENSE);
786247835Skib
787247835Skib	efx_mcdi_execute(enp, &req);
788247835Skib
789247835Skib	if (req.emr_rc != 0) {
790247835Skib		rc = req.emr_rc;
791247835Skib		goto fail1;
792247835Skib	}
793247835Skib
794247835Skib	if (req.emr_out_length_used != 0) {
795247835Skib		rc = EIO;
796247835Skib		goto fail2;
797247835Skib	}
798247835Skib
799247835Skib	return (0);
800247835Skib
801247835Skibfail2:
802247835Skib	EFSYS_PROBE(fail2);
803247835Skibfail1:
804247835Skib	EFSYS_PROBE1(fail1, efx_rc_t, rc);
805247835Skib
806247835Skib	return (rc);
807247835Skib}
808247835Skib
809247835Skibstatic	__checkReturn	efx_rc_t
810247835Skibefx_mcdi_licensing_get_key_stats(
811247835Skib	__in		efx_nic_t *enp,
812247835Skib	__out		efx_key_stats_t *eksp)
813247835Skib{
814247835Skib	efx_mcdi_req_t req;
815247835Skib	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_IN_LEN,
816247835Skib		MC_CMD_LICENSING_OUT_LEN);
817247835Skib	efx_rc_t rc;
818247835Skib
819247835Skib	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
820247835Skib
821247835Skib	req.emr_cmd = MC_CMD_LICENSING;
822247835Skib	req.emr_in_buf = payload;
823247835Skib	req.emr_in_length = MC_CMD_LICENSING_IN_LEN;
824247835Skib	req.emr_out_buf = payload;
825247835Skib	req.emr_out_length = MC_CMD_LICENSING_OUT_LEN;
826247835Skib
827247835Skib	MCDI_IN_SET_DWORD(req, LICENSING_IN_OP,
828247835Skib	    MC_CMD_LICENSING_IN_OP_GET_KEY_STATS);
829247835Skib
830247835Skib	efx_mcdi_execute(enp, &req);
831247835Skib
832247835Skib	if (req.emr_rc != 0) {
833247835Skib		rc = req.emr_rc;
834247835Skib		goto fail1;
835247835Skib	}
836247835Skib
837247835Skib	if (req.emr_out_length_used < MC_CMD_LICENSING_OUT_LEN) {
838247835Skib		rc = EMSGSIZE;
839247835Skib		goto fail2;
840247835Skib	}
841247835Skib
842247835Skib	eksp->eks_valid =
843247835Skib		MCDI_OUT_DWORD(req, LICENSING_OUT_VALID_APP_KEYS);
844247835Skib	eksp->eks_invalid =
845247835Skib		MCDI_OUT_DWORD(req, LICENSING_OUT_INVALID_APP_KEYS);
846247835Skib	eksp->eks_blacklisted =
847247835Skib		MCDI_OUT_DWORD(req, LICENSING_OUT_BLACKLISTED_APP_KEYS);
848247835Skib	eksp->eks_unverifiable =
849247835Skib		MCDI_OUT_DWORD(req, LICENSING_OUT_UNVERIFIABLE_APP_KEYS);
850247835Skib	eksp->eks_wrong_node =
851247835Skib		MCDI_OUT_DWORD(req, LICENSING_OUT_WRONG_NODE_APP_KEYS);
852247835Skib	eksp->eks_licensed_apps_lo = 0;
853247835Skib	eksp->eks_licensed_apps_hi = 0;
854247835Skib	eksp->eks_licensed_features_lo = 0;
855247835Skib	eksp->eks_licensed_features_hi = 0;
856247835Skib
857247835Skib	return (0);
858247835Skib
859247835Skibfail2:
860247835Skib	EFSYS_PROBE(fail2);
861247835Skibfail1:
862247835Skib	EFSYS_PROBE1(fail1, efx_rc_t, rc);
863247835Skib
864247835Skib	return (rc);
865247835Skib}
866247835Skib
867247835Skib#endif	/* EFSYS_OPT_HUNTINGTON */
868247835Skib
869247835Skib/* V3 Licensing - used starting from Medford family. See SF-114884-SW */
870247835Skib
871247835Skib#if EFSYS_OPT_MEDFORD
872247835Skib
873247835Skibstatic	__checkReturn	efx_rc_t
874247835Skibefx_mcdi_licensing_v3_update_licenses(
875247835Skib	__in		efx_nic_t *enp)
876247835Skib{
877247835Skib	efx_mcdi_req_t req;
878247835Skib	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_V3_IN_LEN, 0);
879247835Skib	efx_rc_t rc;
880247835Skib
881247835Skib	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD);
882247835Skib
883247835Skib	req.emr_cmd = MC_CMD_LICENSING_V3;
884247835Skib	req.emr_in_buf = payload;
885247835Skib	req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN;
886	req.emr_out_buf = NULL;
887	req.emr_out_length = 0;
888
889	MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP,
890	    MC_CMD_LICENSING_V3_IN_OP_UPDATE_LICENSE);
891
892	efx_mcdi_execute(enp, &req);
893
894	if (req.emr_rc != 0) {
895		rc = req.emr_rc;
896		goto fail1;
897	}
898
899	return (0);
900
901fail1:
902	EFSYS_PROBE1(fail1, efx_rc_t, rc);
903
904	return (rc);
905}
906
907static	__checkReturn	efx_rc_t
908efx_mcdi_licensing_v3_report_license(
909	__in		efx_nic_t *enp,
910	__out		efx_key_stats_t *eksp)
911{
912	efx_mcdi_req_t req;
913	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_V3_IN_LEN,
914		MC_CMD_LICENSING_V3_OUT_LEN);
915	efx_rc_t rc;
916
917	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD);
918
919	req.emr_cmd = MC_CMD_LICENSING_V3;
920	req.emr_in_buf = payload;
921	req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN;
922	req.emr_out_buf = payload;
923	req.emr_out_length = MC_CMD_LICENSING_V3_OUT_LEN;
924
925	MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP,
926	    MC_CMD_LICENSING_V3_IN_OP_REPORT_LICENSE);
927
928	efx_mcdi_execute_quiet(enp, &req);
929
930	if (req.emr_rc != 0) {
931		rc = req.emr_rc;
932		goto fail1;
933	}
934
935	if (req.emr_out_length_used < MC_CMD_LICENSING_V3_OUT_LEN) {
936		rc = EMSGSIZE;
937		goto fail2;
938	}
939
940	eksp->eks_valid =
941		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_VALID_KEYS);
942	eksp->eks_invalid =
943		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_INVALID_KEYS);
944	eksp->eks_blacklisted = 0;
945	eksp->eks_unverifiable =
946		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_UNVERIFIABLE_KEYS);
947	eksp->eks_wrong_node =
948		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_WRONG_NODE_KEYS);
949	eksp->eks_licensed_apps_lo =
950		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_LO);
951	eksp->eks_licensed_apps_hi =
952		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_HI);
953	eksp->eks_licensed_features_lo =
954		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_LO);
955	eksp->eks_licensed_features_hi =
956		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_HI);
957
958	return (0);
959
960fail2:
961	EFSYS_PROBE(fail2);
962fail1:
963	EFSYS_PROBE1(fail1, efx_rc_t, rc);
964
965	return (rc);
966}
967
968static	__checkReturn	efx_rc_t
969efx_mcdi_licensing_v3_app_state(
970	__in		efx_nic_t *enp,
971	__in		uint64_t app_id,
972	__out		boolean_t *licensedp)
973{
974	efx_mcdi_req_t req;
975	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN,
976		MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN);
977	uint32_t app_state;
978	efx_rc_t rc;
979
980	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD);
981
982	req.emr_cmd = MC_CMD_GET_LICENSED_V3_APP_STATE;
983	req.emr_in_buf = payload;
984	req.emr_in_length = MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN;
985	req.emr_out_buf = payload;
986	req.emr_out_length = MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN;
987
988	MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_LO,
989		    app_id & 0xffffffff);
990	MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_HI,
991		    app_id >> 32);
992
993	efx_mcdi_execute(enp, &req);
994
995	if (req.emr_rc != 0) {
996		rc = req.emr_rc;
997		goto fail1;
998	}
999
1000	if (req.emr_out_length_used < MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN) {
1001		rc = EMSGSIZE;
1002		goto fail2;
1003	}
1004
1005	app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_V3_APP_STATE_OUT_STATE));
1006	if (app_state != MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_NOT_LICENSED) {
1007		*licensedp = B_TRUE;
1008	} else {
1009		*licensedp = B_FALSE;
1010	}
1011
1012	return (0);
1013
1014fail2:
1015	EFSYS_PROBE(fail2);
1016fail1:
1017	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1018
1019	return (rc);
1020}
1021
1022static	__checkReturn	efx_rc_t
1023efx_mcdi_licensing_v3_get_id(
1024	__in		efx_nic_t *enp,
1025	__in		size_t buffer_size,
1026	__out		uint32_t *typep,
1027	__out		size_t *lengthp,
1028	__out_bcount_part_opt(buffer_size, *lengthp)
1029			uint8_t *bufferp)
1030{
1031	efx_mcdi_req_t req;
1032	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_GET_ID_V3_IN_LEN,
1033		MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN);
1034	efx_rc_t rc;
1035
1036	req.emr_cmd = MC_CMD_LICENSING_GET_ID_V3;
1037
1038	if (bufferp == NULL) {
1039		/* Request id type and length only */
1040		req.emr_in_buf = bufferp;
1041		req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN;
1042		req.emr_out_buf = bufferp;
1043		req.emr_out_length = MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN;
1044	} else {
1045		/* Request full buffer */
1046		req.emr_in_buf = bufferp;
1047		req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN;
1048		req.emr_out_buf = bufferp;
1049		req.emr_out_length = MIN(buffer_size, MC_CMD_LICENSING_GET_ID_V3_OUT_LENMAX);
1050		(void) memset(bufferp, 0, req.emr_out_length);
1051	}
1052
1053	efx_mcdi_execute_quiet(enp, &req);
1054
1055	if (req.emr_rc != 0) {
1056		rc = req.emr_rc;
1057		goto fail1;
1058	}
1059
1060	if (req.emr_out_length_used < MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN) {
1061		rc = EMSGSIZE;
1062		goto fail2;
1063	}
1064
1065	*typep = MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_TYPE);
1066	*lengthp = MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_ID_LENGTH);
1067
1068	if (bufferp == NULL) {
1069		/* modify length requirements to indicate to caller the extra buffering
1070		** needed to read the complete output.
1071		*/
1072		*lengthp += MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN;
1073	} else {
1074		/* Shift ID down to start of buffer */
1075		memmove(bufferp,
1076		    bufferp + MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST,
1077		    *lengthp);
1078		memset(bufferp + (*lengthp), 0,
1079		    MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST);
1080	}
1081
1082	return (0);
1083
1084fail2:
1085	EFSYS_PROBE(fail2);
1086fail1:
1087	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1088
1089	return (rc);
1090}
1091
1092/* V3 format uses Huntington TLV format partition. See SF-108797-SW */
1093#define EFX_LICENSE_V3_KEY_LENGTH_MIN    (64)
1094#define EFX_LICENSE_V3_KEY_LENGTH_MAX    (160)
1095
1096	__checkReturn		efx_rc_t
1097efx_lic_v3_find_start(
1098	__in			efx_nic_t *enp,
1099	__in_bcount(buffer_size)
1100				caddr_t bufferp,
1101	__in			size_t buffer_size,
1102	__out			uint32_t *startp
1103	)
1104{
1105	_NOTE(ARGUNUSED(enp))
1106
1107	return ef10_nvram_buffer_find_item_start(bufferp, buffer_size, startp);
1108}
1109
1110	__checkReturn		efx_rc_t
1111efx_lic_v3_find_end(
1112	__in			efx_nic_t *enp,
1113	__in_bcount(buffer_size)
1114				caddr_t bufferp,
1115	__in			size_t buffer_size,
1116	__in			uint32_t offset,
1117	__out			uint32_t *endp
1118	)
1119{
1120	_NOTE(ARGUNUSED(enp))
1121
1122	return ef10_nvram_buffer_find_end(bufferp, buffer_size, offset, endp);
1123}
1124
1125	__checkReturn	__success(return != B_FALSE)	boolean_t
1126efx_lic_v3_find_key(
1127	__in			efx_nic_t *enp,
1128	__in_bcount(buffer_size)
1129				caddr_t bufferp,
1130	__in			size_t buffer_size,
1131	__in			uint32_t offset,
1132	__out			uint32_t *startp,
1133	__out			uint32_t *lengthp
1134	)
1135{
1136	_NOTE(ARGUNUSED(enp))
1137
1138	return ef10_nvram_buffer_find_item(bufferp, buffer_size,
1139	    offset, startp, lengthp);
1140}
1141
1142	__checkReturn	__success(return != B_FALSE)	boolean_t
1143efx_lic_v3_validate_key(
1144	__in			efx_nic_t *enp,
1145	__in_bcount(length)	caddr_t keyp,
1146	__in			uint32_t length
1147	)
1148{
1149	/* Check key is a valid V3 key */
1150	uint8_t key_type;
1151	uint8_t key_length;
1152
1153	_NOTE(ARGUNUSED(enp))
1154
1155	if (length < EFX_LICENSE_V3_KEY_LENGTH_MIN) {
1156		goto fail1;
1157	}
1158
1159	if (length > EFX_LICENSE_V3_KEY_LENGTH_MAX) {
1160		goto fail2;
1161	}
1162
1163	key_type = ((uint8_t *)keyp)[0];
1164	key_length = ((uint8_t *)keyp)[1];
1165
1166	if (key_type < 3) {
1167		goto fail3;
1168	}
1169	if (key_length > length) {
1170		goto fail4;
1171	}
1172	return (B_TRUE);
1173
1174fail4:
1175	EFSYS_PROBE(fail4);
1176fail3:
1177	EFSYS_PROBE(fail3);
1178fail2:
1179	EFSYS_PROBE(fail2);
1180fail1:
1181	EFSYS_PROBE1(fail1, boolean_t, B_FALSE);
1182
1183	return (B_FALSE);
1184}
1185
1186	__checkReturn		efx_rc_t
1187efx_lic_v3_read_key(
1188	__in			efx_nic_t *enp,
1189	__in_bcount(buffer_size)
1190				caddr_t bufferp,
1191	__in			size_t buffer_size,
1192	__in			uint32_t offset,
1193	__in			uint32_t length,
1194	__out_bcount_part(key_max_size, *lengthp)
1195				caddr_t keyp,
1196	__in			size_t key_max_size,
1197	__out			uint32_t *lengthp
1198	)
1199{
1200	_NOTE(ARGUNUSED(enp))
1201
1202	return ef10_nvram_buffer_get_item(bufferp, buffer_size,
1203		    offset, length, keyp, key_max_size, lengthp);
1204}
1205
1206	__checkReturn		efx_rc_t
1207efx_lic_v3_write_key(
1208	__in			efx_nic_t *enp,
1209	__in_bcount(buffer_size)
1210				caddr_t bufferp,
1211	__in			size_t buffer_size,
1212	__in			uint32_t offset,
1213	__in_bcount(length)	caddr_t keyp,
1214	__in			uint32_t length,
1215	__out			uint32_t *lengthp
1216	)
1217{
1218	_NOTE(ARGUNUSED(enp))
1219	EFSYS_ASSERT(length <= EFX_LICENSE_V3_KEY_LENGTH_MAX);
1220
1221	return ef10_nvram_buffer_insert_item(bufferp, buffer_size,
1222		    offset, keyp, length, lengthp);
1223}
1224
1225	__checkReturn		efx_rc_t
1226efx_lic_v3_delete_key(
1227	__in			efx_nic_t *enp,
1228	__in_bcount(buffer_size)
1229				caddr_t bufferp,
1230	__in			size_t buffer_size,
1231	__in			uint32_t offset,
1232	__in			uint32_t length,
1233	__in			uint32_t end,
1234	__out			uint32_t *deltap
1235	)
1236{
1237	efx_rc_t rc;
1238
1239	_NOTE(ARGUNUSED(enp))
1240
1241	if ((rc = ef10_nvram_buffer_delete_item(bufferp,
1242			buffer_size, offset, length, end)) != 0) {
1243		goto fail1;
1244	}
1245
1246	*deltap = length;
1247
1248	return (0);
1249
1250fail1:
1251	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1252
1253	return (rc);
1254}
1255
1256	__checkReturn		efx_rc_t
1257efx_lic_v3_create_partition(
1258	__in			efx_nic_t *enp,
1259	__in_bcount(buffer_size)
1260				caddr_t bufferp,
1261	__in			size_t buffer_size
1262	)
1263{
1264	efx_rc_t rc;
1265
1266	/* Construct empty partition */
1267	if ((rc = ef10_nvram_buffer_create(enp,
1268	    NVRAM_PARTITION_TYPE_LICENSE,
1269	    bufferp, buffer_size)) != 0) {
1270		rc = EFAULT;
1271		goto fail1;
1272	}
1273
1274	return (0);
1275
1276fail1:
1277	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1278
1279	return (rc);
1280}
1281
1282	__checkReturn		efx_rc_t
1283efx_lic_v3_finish_partition(
1284	__in			efx_nic_t *enp,
1285	__in_bcount(buffer_size)
1286				caddr_t bufferp,
1287	__in			size_t buffer_size
1288	)
1289{
1290	efx_rc_t rc;
1291
1292	if ((rc = ef10_nvram_buffer_finish(bufferp,
1293			buffer_size)) != 0) {
1294		goto fail1;
1295	}
1296
1297	/* Validate completed partition */
1298	if ((rc = ef10_nvram_buffer_validate(enp, NVRAM_PARTITION_TYPE_LICENSE,
1299					bufferp, buffer_size)) != 0) {
1300		goto fail2;
1301	}
1302
1303	return (0);
1304
1305fail2:
1306	EFSYS_PROBE(fail2);
1307fail1:
1308	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1309
1310	return (rc);
1311}
1312
1313
1314#endif	/* EFSYS_OPT_MEDFORD */
1315
1316	__checkReturn		efx_rc_t
1317efx_lic_init(
1318	__in			efx_nic_t *enp)
1319{
1320	const efx_lic_ops_t *elop;
1321	efx_key_stats_t eks;
1322	efx_rc_t rc;
1323
1324	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1325	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
1326	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_LIC));
1327
1328	switch (enp->en_family) {
1329
1330#if EFSYS_OPT_SIENA
1331	case EFX_FAMILY_SIENA:
1332		elop = &__efx_lic_v1_ops;
1333		break;
1334#endif	/* EFSYS_OPT_SIENA */
1335
1336#if EFSYS_OPT_HUNTINGTON
1337	case EFX_FAMILY_HUNTINGTON:
1338		elop = &__efx_lic_v2_ops;
1339		break;
1340#endif	/* EFSYS_OPT_HUNTINGTON */
1341
1342#if EFSYS_OPT_MEDFORD
1343	case EFX_FAMILY_MEDFORD:
1344		elop = &__efx_lic_v3_ops;
1345		break;
1346#endif	/* EFSYS_OPT_MEDFORD */
1347
1348	default:
1349		EFSYS_ASSERT(0);
1350		rc = ENOTSUP;
1351		goto fail1;
1352	}
1353
1354	enp->en_elop = elop;
1355	enp->en_mod_flags |= EFX_MOD_LIC;
1356
1357	/* Probe for support */
1358	if (efx_lic_get_key_stats(enp, &eks) == 0) {
1359		enp->en_licensing_supported = B_TRUE;
1360	} else {
1361		enp->en_licensing_supported = B_FALSE;
1362	}
1363
1364	return (0);
1365
1366fail1:
1367	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1368
1369	return (rc);
1370}
1371
1372extern	__checkReturn	boolean_t
1373efx_lic_check_support(
1374	__in			efx_nic_t *enp)
1375{
1376	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1377	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
1378	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1379
1380	return enp->en_licensing_supported;
1381}
1382
1383				void
1384efx_lic_fini(
1385	__in			efx_nic_t *enp)
1386{
1387	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1388	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
1389	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1390
1391	enp->en_elop = NULL;
1392	enp->en_mod_flags &= ~EFX_MOD_LIC;
1393}
1394
1395
1396	__checkReturn	efx_rc_t
1397efx_lic_update_licenses(
1398	__in		efx_nic_t *enp)
1399{
1400	const efx_lic_ops_t *elop = enp->en_elop;
1401	efx_rc_t rc;
1402
1403	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1404	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1405
1406	if ((rc = elop->elo_update_licenses(enp)) != 0)
1407		goto fail1;
1408
1409	return (0);
1410
1411fail1:
1412	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1413
1414	return (rc);
1415}
1416
1417	__checkReturn	efx_rc_t
1418efx_lic_get_key_stats(
1419	__in		efx_nic_t *enp,
1420	__out		efx_key_stats_t *eksp)
1421{
1422	const efx_lic_ops_t *elop = enp->en_elop;
1423	efx_rc_t rc;
1424
1425	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1426	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1427
1428	if ((rc = elop->elo_get_key_stats(enp, eksp)) != 0)
1429		goto fail1;
1430
1431	return (0);
1432
1433fail1:
1434	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1435
1436	return (rc);
1437}
1438
1439	__checkReturn	efx_rc_t
1440efx_lic_app_state(
1441	__in		efx_nic_t *enp,
1442	__in		uint64_t app_id,
1443	__out		boolean_t *licensedp)
1444{
1445	const efx_lic_ops_t *elop = enp->en_elop;
1446	efx_rc_t rc;
1447
1448	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1449	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1450
1451	if (elop->elo_app_state == NULL)
1452		return (ENOTSUP);
1453
1454	if ((rc = elop->elo_app_state(enp, app_id, licensedp)) != 0)
1455		goto fail1;
1456
1457	return (0);
1458
1459fail1:
1460	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1461
1462	return (rc);
1463}
1464
1465	__checkReturn	efx_rc_t
1466efx_lic_get_id(
1467	__in		efx_nic_t *enp,
1468	__in		size_t buffer_size,
1469	__out		uint32_t *typep,
1470	__out		size_t *lengthp,
1471	__out_opt	uint8_t *bufferp
1472	)
1473{
1474	const efx_lic_ops_t *elop = enp->en_elop;
1475	efx_rc_t rc;
1476
1477	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1478	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1479
1480	if (elop->elo_get_id == NULL)
1481		return (ENOTSUP);
1482
1483	if ((rc = elop->elo_get_id(enp, buffer_size, typep,
1484				    lengthp, bufferp)) != 0)
1485		goto fail1;
1486
1487	return (0);
1488
1489fail1:
1490	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1491
1492	return (rc);
1493}
1494
1495/* Buffer management API - abstracts varying TLV format used for License partition */
1496
1497	__checkReturn		efx_rc_t
1498efx_lic_find_start(
1499	__in			efx_nic_t *enp,
1500	__in_bcount(buffer_size)
1501				caddr_t bufferp,
1502	__in			size_t buffer_size,
1503	__out			uint32_t *startp
1504	)
1505{
1506	const efx_lic_ops_t *elop = enp->en_elop;
1507	efx_rc_t rc;
1508
1509	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1510	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1511
1512	if ((rc = elop->elo_find_start(enp, bufferp, buffer_size, startp)) != 0)
1513		goto fail1;
1514
1515	return (0);
1516
1517fail1:
1518	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1519
1520	return (rc);
1521}
1522
1523	__checkReturn		efx_rc_t
1524efx_lic_find_end(
1525	__in			efx_nic_t *enp,
1526	__in_bcount(buffer_size)
1527				caddr_t bufferp,
1528	__in			size_t buffer_size,
1529	__in			uint32_t offset,
1530	__out			uint32_t *endp
1531	)
1532{
1533	const efx_lic_ops_t *elop = enp->en_elop;
1534	efx_rc_t rc;
1535
1536	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1537	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1538
1539	if ((rc = elop->elo_find_end(enp, bufferp, buffer_size, offset, endp)) != 0)
1540		goto fail1;
1541
1542	return (0);
1543
1544fail1:
1545	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1546
1547	return (rc);
1548}
1549
1550	__checkReturn	__success(return != B_FALSE)	boolean_t
1551efx_lic_find_key(
1552	__in			efx_nic_t *enp,
1553	__in_bcount(buffer_size)
1554				caddr_t bufferp,
1555	__in			size_t buffer_size,
1556	__in			uint32_t offset,
1557	__out			uint32_t *startp,
1558	__out			uint32_t *lengthp
1559	)
1560{
1561	const efx_lic_ops_t *elop = enp->en_elop;
1562
1563	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1564	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1565
1566	EFSYS_ASSERT(bufferp);
1567	EFSYS_ASSERT(startp);
1568	EFSYS_ASSERT(lengthp);
1569
1570	return (elop->elo_find_key(enp, bufferp, buffer_size, offset,
1571				    startp, lengthp));
1572}
1573
1574
1575/* Validate that the buffer contains a single key in a recognised format.
1576** An empty or terminator buffer is not accepted as a valid key.
1577*/
1578	__checkReturn	__success(return != B_FALSE)	boolean_t
1579efx_lic_validate_key(
1580	__in			efx_nic_t *enp,
1581	__in_bcount(length)	caddr_t keyp,
1582	__in			uint32_t length
1583	)
1584{
1585	const efx_lic_ops_t *elop = enp->en_elop;
1586	boolean_t rc;
1587
1588	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1589	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1590
1591	if ((rc = elop->elo_validate_key(enp, keyp, length)) == B_FALSE)
1592		goto fail1;
1593
1594	return (B_TRUE);
1595
1596fail1:
1597	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1598
1599	return (rc);
1600}
1601
1602	__checkReturn		efx_rc_t
1603efx_lic_read_key(
1604	__in			efx_nic_t *enp,
1605	__in_bcount(buffer_size)
1606				caddr_t bufferp,
1607	__in			size_t buffer_size,
1608	__in			uint32_t offset,
1609	__in			uint32_t length,
1610	__out_bcount_part(key_max_size, *lengthp)
1611				caddr_t keyp,
1612	__in			size_t key_max_size,
1613	__out			uint32_t *lengthp
1614	)
1615{
1616	const efx_lic_ops_t *elop = enp->en_elop;
1617	efx_rc_t rc;
1618
1619	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1620	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1621
1622	if ((rc = elop->elo_read_key(enp, bufferp, buffer_size, offset,
1623				    length, keyp, key_max_size, lengthp)) != 0)
1624		goto fail1;
1625
1626	return (0);
1627
1628fail1:
1629	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1630
1631	return (rc);
1632}
1633
1634	__checkReturn		efx_rc_t
1635efx_lic_write_key(
1636	__in			efx_nic_t *enp,
1637	__in_bcount(buffer_size)
1638				caddr_t bufferp,
1639	__in			size_t buffer_size,
1640	__in			uint32_t offset,
1641	__in_bcount(length)	caddr_t keyp,
1642	__in			uint32_t length,
1643	__out			uint32_t *lengthp
1644	)
1645{
1646	const efx_lic_ops_t *elop = enp->en_elop;
1647	efx_rc_t rc;
1648
1649	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1650	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1651
1652	if ((rc = elop->elo_write_key(enp, bufferp, buffer_size, offset,
1653				    keyp, length, lengthp)) != 0)
1654		goto fail1;
1655
1656	return (0);
1657
1658fail1:
1659	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1660
1661	return (rc);
1662}
1663
1664	__checkReturn		efx_rc_t
1665efx_lic_delete_key(
1666	__in			efx_nic_t *enp,
1667	__in_bcount(buffer_size)
1668				caddr_t bufferp,
1669	__in			size_t buffer_size,
1670	__in			uint32_t offset,
1671	__in			uint32_t length,
1672	__in			uint32_t end,
1673	__out			uint32_t *deltap
1674	)
1675{
1676	const efx_lic_ops_t *elop = enp->en_elop;
1677	efx_rc_t rc;
1678
1679	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1680	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1681
1682	if ((rc = elop->elo_delete_key(enp, bufferp, buffer_size, offset,
1683				    length, end, deltap)) != 0)
1684		goto fail1;
1685
1686	return (0);
1687
1688fail1:
1689	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1690
1691	return (rc);
1692}
1693
1694	__checkReturn		efx_rc_t
1695efx_lic_create_partition(
1696	__in			efx_nic_t *enp,
1697	__in_bcount(buffer_size)
1698				caddr_t bufferp,
1699	__in			size_t buffer_size
1700	)
1701{
1702	const efx_lic_ops_t *elop = enp->en_elop;
1703	efx_rc_t rc;
1704
1705	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1706	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1707
1708	if ((rc = elop->elo_create_partition(enp, bufferp, buffer_size)) != 0)
1709		goto fail1;
1710
1711	return (0);
1712
1713fail1:
1714	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1715
1716	return (rc);
1717}
1718
1719
1720	__checkReturn		efx_rc_t
1721efx_lic_finish_partition(
1722	__in			efx_nic_t *enp,
1723	__in_bcount(buffer_size)
1724				caddr_t bufferp,
1725	__in			size_t buffer_size
1726	)
1727{
1728	const efx_lic_ops_t *elop = enp->en_elop;
1729	efx_rc_t rc;
1730
1731	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
1732	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
1733
1734	if ((rc = elop->elo_finish_partition(enp, bufferp, buffer_size)) != 0)
1735		goto fail1;
1736
1737	return (0);
1738
1739fail1:
1740	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1741
1742	return (rc);
1743}
1744
1745#endif	/* EFSYS_OPT_LICENSING */
1746