xref: /dpdk/drivers/common/sfc_efx/base/efx_lic.c (revision 672386c1e9e1f64f7aa3b1360ad22dc737ea8d72)
15e111ed8SAndrew Rybchenko /* SPDX-License-Identifier: BSD-3-Clause
25e111ed8SAndrew Rybchenko  *
3*672386c1SAndrew Rybchenko  * Copyright(c) 2019-2021 Xilinx, Inc.
45e111ed8SAndrew Rybchenko  * Copyright(c) 2009-2019 Solarflare Communications Inc.
55e111ed8SAndrew Rybchenko  */
65e111ed8SAndrew Rybchenko 
75e111ed8SAndrew Rybchenko #include "efx.h"
85e111ed8SAndrew Rybchenko #include "efx_impl.h"
95e111ed8SAndrew Rybchenko 
105e111ed8SAndrew Rybchenko #if EFSYS_OPT_LICENSING
115e111ed8SAndrew Rybchenko 
125e111ed8SAndrew Rybchenko #include "ef10_tlv_layout.h"
135e111ed8SAndrew Rybchenko #if EFSYS_OPT_SIENA
145e111ed8SAndrew Rybchenko #include "efx_regs_mcdi_aoe.h"
155e111ed8SAndrew Rybchenko #endif
165e111ed8SAndrew Rybchenko 
175e111ed8SAndrew Rybchenko #if EFSYS_OPT_SIENA | EFSYS_OPT_HUNTINGTON
185e111ed8SAndrew Rybchenko 
195e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
205e111ed8SAndrew Rybchenko efx_lic_v1v2_find_start(
215e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
225e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
235e111ed8SAndrew Rybchenko 				caddr_t bufferp,
245e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
255e111ed8SAndrew Rybchenko 	__out			uint32_t *startp);
265e111ed8SAndrew Rybchenko 
275e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
285e111ed8SAndrew Rybchenko efx_lic_v1v2_find_end(
295e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
305e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
315e111ed8SAndrew Rybchenko 				caddr_t bufferp,
325e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
335e111ed8SAndrew Rybchenko 	__in			uint32_t offset,
345e111ed8SAndrew Rybchenko 	__out			uint32_t *endp);
355e111ed8SAndrew Rybchenko 
365e111ed8SAndrew Rybchenko 	__checkReturn	__success(return != B_FALSE)	boolean_t
375e111ed8SAndrew Rybchenko efx_lic_v1v2_find_key(
385e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
395e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
405e111ed8SAndrew Rybchenko 				caddr_t bufferp,
415e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
425e111ed8SAndrew Rybchenko 	__in			uint32_t offset,
435e111ed8SAndrew Rybchenko 	__out			uint32_t *startp,
445e111ed8SAndrew Rybchenko 	__out			uint32_t *lengthp);
455e111ed8SAndrew Rybchenko 
465e111ed8SAndrew Rybchenko 	__checkReturn	__success(return != B_FALSE)	boolean_t
475e111ed8SAndrew Rybchenko efx_lic_v1v2_validate_key(
485e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
495e111ed8SAndrew Rybchenko 	__in_bcount(length)	caddr_t keyp,
505e111ed8SAndrew Rybchenko 	__in			uint32_t length);
515e111ed8SAndrew Rybchenko 
525e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
535e111ed8SAndrew Rybchenko efx_lic_v1v2_read_key(
545e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
555e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
565e111ed8SAndrew Rybchenko 				caddr_t bufferp,
575e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
585e111ed8SAndrew Rybchenko 	__in			uint32_t offset,
595e111ed8SAndrew Rybchenko 	__in			uint32_t length,
605e111ed8SAndrew Rybchenko 	__out_bcount_part(key_max_size, *lengthp)
615e111ed8SAndrew Rybchenko 				caddr_t keyp,
625e111ed8SAndrew Rybchenko 	__in			size_t key_max_size,
635e111ed8SAndrew Rybchenko 	__out			uint32_t *lengthp);
645e111ed8SAndrew Rybchenko 
655e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
665e111ed8SAndrew Rybchenko efx_lic_v1v2_write_key(
675e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
685e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
695e111ed8SAndrew Rybchenko 				caddr_t bufferp,
705e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
715e111ed8SAndrew Rybchenko 	__in			uint32_t offset,
725e111ed8SAndrew Rybchenko 	__in_bcount(length)	caddr_t keyp,
735e111ed8SAndrew Rybchenko 	__in			uint32_t length,
745e111ed8SAndrew Rybchenko 	__out			uint32_t *lengthp);
755e111ed8SAndrew Rybchenko 
765e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
775e111ed8SAndrew Rybchenko efx_lic_v1v2_delete_key(
785e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
795e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
805e111ed8SAndrew Rybchenko 				caddr_t bufferp,
815e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
825e111ed8SAndrew Rybchenko 	__in			uint32_t offset,
835e111ed8SAndrew Rybchenko 	__in			uint32_t length,
845e111ed8SAndrew Rybchenko 	__in			uint32_t end,
855e111ed8SAndrew Rybchenko 	__out			uint32_t *deltap);
865e111ed8SAndrew Rybchenko 
875e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
885e111ed8SAndrew Rybchenko efx_lic_v1v2_create_partition(
895e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
905e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
915e111ed8SAndrew Rybchenko 				caddr_t bufferp,
925e111ed8SAndrew Rybchenko 	__in			size_t buffer_size);
935e111ed8SAndrew Rybchenko 
945e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
955e111ed8SAndrew Rybchenko efx_lic_v1v2_finish_partition(
965e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
975e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
985e111ed8SAndrew Rybchenko 				caddr_t bufferp,
995e111ed8SAndrew Rybchenko 	__in			size_t buffer_size);
1005e111ed8SAndrew Rybchenko 
1015e111ed8SAndrew Rybchenko #endif	/* EFSYS_OPT_HUNTINGTON | EFSYS_OPT_SIENA */
1025e111ed8SAndrew Rybchenko 
1035e111ed8SAndrew Rybchenko 
1045e111ed8SAndrew Rybchenko #if EFSYS_OPT_SIENA
1055e111ed8SAndrew Rybchenko 
1065e111ed8SAndrew Rybchenko static	__checkReturn	efx_rc_t
1075e111ed8SAndrew Rybchenko efx_mcdi_fc_license_update_license(
1085e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp);
1095e111ed8SAndrew Rybchenko 
1105e111ed8SAndrew Rybchenko static	__checkReturn	efx_rc_t
1115e111ed8SAndrew Rybchenko efx_mcdi_fc_license_get_key_stats(
1125e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp,
1135e111ed8SAndrew Rybchenko 	__out		efx_key_stats_t *eksp);
1145e111ed8SAndrew Rybchenko 
1155e111ed8SAndrew Rybchenko static const efx_lic_ops_t	__efx_lic_v1_ops = {
1165e111ed8SAndrew Rybchenko 	efx_mcdi_fc_license_update_license,	/* elo_update_licenses */
1175e111ed8SAndrew Rybchenko 	efx_mcdi_fc_license_get_key_stats,	/* elo_get_key_stats */
1185e111ed8SAndrew Rybchenko 	NULL,					/* elo_app_state */
1195e111ed8SAndrew Rybchenko 	NULL,					/* elo_get_id */
1205e111ed8SAndrew Rybchenko 	efx_lic_v1v2_find_start,		/* elo_find_start */
1215e111ed8SAndrew Rybchenko 	efx_lic_v1v2_find_end,			/* elo_find_end */
1225e111ed8SAndrew Rybchenko 	efx_lic_v1v2_find_key,			/* elo_find_key */
1235e111ed8SAndrew Rybchenko 	efx_lic_v1v2_validate_key,		/* elo_validate_key */
1245e111ed8SAndrew Rybchenko 	efx_lic_v1v2_read_key,			/* elo_read_key */
1255e111ed8SAndrew Rybchenko 	efx_lic_v1v2_write_key,			/* elo_write_key */
1265e111ed8SAndrew Rybchenko 	efx_lic_v1v2_delete_key,		/* elo_delete_key */
1275e111ed8SAndrew Rybchenko 	efx_lic_v1v2_create_partition,		/* elo_create_partition */
1285e111ed8SAndrew Rybchenko 	efx_lic_v1v2_finish_partition,		/* elo_finish_partition */
1295e111ed8SAndrew Rybchenko };
1305e111ed8SAndrew Rybchenko 
1315e111ed8SAndrew Rybchenko #endif	/* EFSYS_OPT_SIENA */
1325e111ed8SAndrew Rybchenko 
1335e111ed8SAndrew Rybchenko #if EFSYS_OPT_HUNTINGTON
1345e111ed8SAndrew Rybchenko 
1355e111ed8SAndrew Rybchenko static	__checkReturn	efx_rc_t
1365e111ed8SAndrew Rybchenko efx_mcdi_licensing_update_licenses(
1375e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp);
1385e111ed8SAndrew Rybchenko 
1395e111ed8SAndrew Rybchenko static	__checkReturn	efx_rc_t
1405e111ed8SAndrew Rybchenko efx_mcdi_licensing_get_key_stats(
1415e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp,
1425e111ed8SAndrew Rybchenko 	__out		efx_key_stats_t *eksp);
1435e111ed8SAndrew Rybchenko 
1445e111ed8SAndrew Rybchenko static	__checkReturn	efx_rc_t
1455e111ed8SAndrew Rybchenko efx_mcdi_licensed_app_state(
1465e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp,
1475e111ed8SAndrew Rybchenko 	__in		uint64_t app_id,
1485e111ed8SAndrew Rybchenko 	__out		boolean_t *licensedp);
1495e111ed8SAndrew Rybchenko 
1505e111ed8SAndrew Rybchenko static const efx_lic_ops_t	__efx_lic_v2_ops = {
1515e111ed8SAndrew Rybchenko 	efx_mcdi_licensing_update_licenses,	/* elo_update_licenses */
1525e111ed8SAndrew Rybchenko 	efx_mcdi_licensing_get_key_stats,	/* elo_get_key_stats */
1535e111ed8SAndrew Rybchenko 	efx_mcdi_licensed_app_state,		/* elo_app_state */
1545e111ed8SAndrew Rybchenko 	NULL,					/* elo_get_id */
1555e111ed8SAndrew Rybchenko 	efx_lic_v1v2_find_start,		/* elo_find_start */
1565e111ed8SAndrew Rybchenko 	efx_lic_v1v2_find_end,			/* elo_find_end */
1575e111ed8SAndrew Rybchenko 	efx_lic_v1v2_find_key,			/* elo_find_key */
1585e111ed8SAndrew Rybchenko 	efx_lic_v1v2_validate_key,		/* elo_validate_key */
1595e111ed8SAndrew Rybchenko 	efx_lic_v1v2_read_key,			/* elo_read_key */
1605e111ed8SAndrew Rybchenko 	efx_lic_v1v2_write_key,			/* elo_write_key */
1615e111ed8SAndrew Rybchenko 	efx_lic_v1v2_delete_key,		/* elo_delete_key */
1625e111ed8SAndrew Rybchenko 	efx_lic_v1v2_create_partition,		/* elo_create_partition */
1635e111ed8SAndrew Rybchenko 	efx_lic_v1v2_finish_partition,		/* elo_finish_partition */
1645e111ed8SAndrew Rybchenko };
1655e111ed8SAndrew Rybchenko 
1665e111ed8SAndrew Rybchenko #endif	/* EFSYS_OPT_HUNTINGTON */
1675e111ed8SAndrew Rybchenko 
1685e111ed8SAndrew Rybchenko #if EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
1695e111ed8SAndrew Rybchenko 
1705e111ed8SAndrew Rybchenko static	__checkReturn	efx_rc_t
1715e111ed8SAndrew Rybchenko efx_mcdi_licensing_v3_update_licenses(
1725e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp);
1735e111ed8SAndrew Rybchenko 
1745e111ed8SAndrew Rybchenko static	__checkReturn	efx_rc_t
1755e111ed8SAndrew Rybchenko efx_mcdi_licensing_v3_report_license(
1765e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp,
1775e111ed8SAndrew Rybchenko 	__out		efx_key_stats_t *eksp);
1785e111ed8SAndrew Rybchenko 
1795e111ed8SAndrew Rybchenko static	__checkReturn	efx_rc_t
1805e111ed8SAndrew Rybchenko efx_mcdi_licensing_v3_app_state(
1815e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp,
1825e111ed8SAndrew Rybchenko 	__in		uint64_t app_id,
1835e111ed8SAndrew Rybchenko 	__out		boolean_t *licensedp);
1845e111ed8SAndrew Rybchenko 
1855e111ed8SAndrew Rybchenko static	__checkReturn	efx_rc_t
1865e111ed8SAndrew Rybchenko efx_mcdi_licensing_v3_get_id(
1875e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp,
1885e111ed8SAndrew Rybchenko 	__in		size_t buffer_size,
1895e111ed8SAndrew Rybchenko 	__out		uint32_t *typep,
1905e111ed8SAndrew Rybchenko 	__out		size_t *lengthp,
1915e111ed8SAndrew Rybchenko 	__out_bcount_part_opt(buffer_size, *lengthp)
1925e111ed8SAndrew Rybchenko 			uint8_t *bufferp);
1935e111ed8SAndrew Rybchenko 
1945e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
1955e111ed8SAndrew Rybchenko efx_lic_v3_find_start(
1965e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
1975e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
1985e111ed8SAndrew Rybchenko 				caddr_t bufferp,
1995e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
2005e111ed8SAndrew Rybchenko 	__out			uint32_t *startp);
2015e111ed8SAndrew Rybchenko 
2025e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
2035e111ed8SAndrew Rybchenko efx_lic_v3_find_end(
2045e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
2055e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
2065e111ed8SAndrew Rybchenko 				caddr_t bufferp,
2075e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
2085e111ed8SAndrew Rybchenko 	__in			uint32_t offset,
2095e111ed8SAndrew Rybchenko 	__out			uint32_t *endp);
2105e111ed8SAndrew Rybchenko 
2115e111ed8SAndrew Rybchenko 	__checkReturn	__success(return != B_FALSE)	boolean_t
2125e111ed8SAndrew Rybchenko efx_lic_v3_find_key(
2135e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
2145e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
2155e111ed8SAndrew Rybchenko 				caddr_t bufferp,
2165e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
2175e111ed8SAndrew Rybchenko 	__in			uint32_t offset,
2185e111ed8SAndrew Rybchenko 	__out			uint32_t *startp,
2195e111ed8SAndrew Rybchenko 	__out			uint32_t *lengthp);
2205e111ed8SAndrew Rybchenko 
2215e111ed8SAndrew Rybchenko 	__checkReturn	__success(return != B_FALSE)	boolean_t
2225e111ed8SAndrew Rybchenko efx_lic_v3_validate_key(
2235e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
2245e111ed8SAndrew Rybchenko 	__in_bcount(length)	caddr_t keyp,
2255e111ed8SAndrew Rybchenko 	__in			uint32_t length);
2265e111ed8SAndrew Rybchenko 
2275e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
2285e111ed8SAndrew Rybchenko efx_lic_v3_read_key(
2295e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
2305e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
2315e111ed8SAndrew Rybchenko 				caddr_t bufferp,
2325e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
2335e111ed8SAndrew Rybchenko 	__in			uint32_t offset,
2345e111ed8SAndrew Rybchenko 	__in			uint32_t length,
2355e111ed8SAndrew Rybchenko 	__out_bcount_part(key_max_size, *lengthp)
2365e111ed8SAndrew Rybchenko 				caddr_t keyp,
2375e111ed8SAndrew Rybchenko 	__in			size_t key_max_size,
2385e111ed8SAndrew Rybchenko 	__out			uint32_t *lengthp);
2395e111ed8SAndrew Rybchenko 
2405e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
2415e111ed8SAndrew Rybchenko efx_lic_v3_write_key(
2425e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
2435e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
2445e111ed8SAndrew Rybchenko 				caddr_t bufferp,
2455e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
2465e111ed8SAndrew Rybchenko 	__in			uint32_t offset,
2475e111ed8SAndrew Rybchenko 	__in_bcount(length)	caddr_t keyp,
2485e111ed8SAndrew Rybchenko 	__in			uint32_t length,
2495e111ed8SAndrew Rybchenko 	__out			uint32_t *lengthp);
2505e111ed8SAndrew Rybchenko 
2515e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
2525e111ed8SAndrew Rybchenko efx_lic_v3_delete_key(
2535e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
2545e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
2555e111ed8SAndrew Rybchenko 				caddr_t bufferp,
2565e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
2575e111ed8SAndrew Rybchenko 	__in			uint32_t offset,
2585e111ed8SAndrew Rybchenko 	__in			uint32_t length,
2595e111ed8SAndrew Rybchenko 	__in			uint32_t end,
2605e111ed8SAndrew Rybchenko 	__out			uint32_t *deltap);
2615e111ed8SAndrew Rybchenko 
2625e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
2635e111ed8SAndrew Rybchenko efx_lic_v3_create_partition(
2645e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
2655e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
2665e111ed8SAndrew Rybchenko 				caddr_t bufferp,
2675e111ed8SAndrew Rybchenko 	__in			size_t buffer_size);
2685e111ed8SAndrew Rybchenko 
2695e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
2705e111ed8SAndrew Rybchenko efx_lic_v3_finish_partition(
2715e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
2725e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
2735e111ed8SAndrew Rybchenko 				caddr_t bufferp,
2745e111ed8SAndrew Rybchenko 	__in			size_t buffer_size);
2755e111ed8SAndrew Rybchenko 
2765e111ed8SAndrew Rybchenko static const efx_lic_ops_t	__efx_lic_v3_ops = {
2775e111ed8SAndrew Rybchenko 	efx_mcdi_licensing_v3_update_licenses,	/* elo_update_licenses */
2785e111ed8SAndrew Rybchenko 	efx_mcdi_licensing_v3_report_license,	/* elo_get_key_stats */
2795e111ed8SAndrew Rybchenko 	efx_mcdi_licensing_v3_app_state,	/* elo_app_state */
2805e111ed8SAndrew Rybchenko 	efx_mcdi_licensing_v3_get_id,		/* elo_get_id */
2815e111ed8SAndrew Rybchenko 	efx_lic_v3_find_start,			/* elo_find_start */
2825e111ed8SAndrew Rybchenko 	efx_lic_v3_find_end,			/* elo_find_end */
2835e111ed8SAndrew Rybchenko 	efx_lic_v3_find_key,			/* elo_find_key */
2845e111ed8SAndrew Rybchenko 	efx_lic_v3_validate_key,		/* elo_validate_key */
2855e111ed8SAndrew Rybchenko 	efx_lic_v3_read_key,			/* elo_read_key */
2865e111ed8SAndrew Rybchenko 	efx_lic_v3_write_key,			/* elo_write_key */
2875e111ed8SAndrew Rybchenko 	efx_lic_v3_delete_key,			/* elo_delete_key */
2885e111ed8SAndrew Rybchenko 	efx_lic_v3_create_partition,		/* elo_create_partition */
2895e111ed8SAndrew Rybchenko 	efx_lic_v3_finish_partition,		/* elo_finish_partition */
2905e111ed8SAndrew Rybchenko };
2915e111ed8SAndrew Rybchenko 
2925e111ed8SAndrew Rybchenko #endif	/* EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
2935e111ed8SAndrew Rybchenko 
2945e111ed8SAndrew Rybchenko 
2955e111ed8SAndrew Rybchenko /* V1 Licensing - used in Siena Modena only */
2965e111ed8SAndrew Rybchenko 
2975e111ed8SAndrew Rybchenko #if EFSYS_OPT_SIENA
2985e111ed8SAndrew Rybchenko 
2995e111ed8SAndrew Rybchenko static	__checkReturn	efx_rc_t
efx_mcdi_fc_license_update_license(__in efx_nic_t * enp)3005e111ed8SAndrew Rybchenko efx_mcdi_fc_license_update_license(
3015e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp)
3025e111ed8SAndrew Rybchenko {
3035e111ed8SAndrew Rybchenko 	efx_mcdi_req_t req;
3045e111ed8SAndrew Rybchenko 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FC_IN_LICENSE_LEN, 0);
3055e111ed8SAndrew Rybchenko 	efx_rc_t rc;
3065e111ed8SAndrew Rybchenko 
3075e111ed8SAndrew Rybchenko 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
3085e111ed8SAndrew Rybchenko 
3095e111ed8SAndrew Rybchenko 	req.emr_cmd = MC_CMD_FC;
3105e111ed8SAndrew Rybchenko 	req.emr_in_buf = payload;
3115e111ed8SAndrew Rybchenko 	req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN;
3125e111ed8SAndrew Rybchenko 	req.emr_out_buf = payload;
3135e111ed8SAndrew Rybchenko 	req.emr_out_length = 0;
3145e111ed8SAndrew Rybchenko 
3155e111ed8SAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, FC_IN_CMD,
3165e111ed8SAndrew Rybchenko 	    MC_CMD_FC_OP_LICENSE);
3175e111ed8SAndrew Rybchenko 
3185e111ed8SAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP,
3195e111ed8SAndrew Rybchenko 	    MC_CMD_FC_IN_LICENSE_UPDATE_LICENSE);
3205e111ed8SAndrew Rybchenko 
3215e111ed8SAndrew Rybchenko 	efx_mcdi_execute(enp, &req);
3225e111ed8SAndrew Rybchenko 
3235e111ed8SAndrew Rybchenko 	if (req.emr_rc != 0) {
3245e111ed8SAndrew Rybchenko 		rc = req.emr_rc;
3255e111ed8SAndrew Rybchenko 		goto fail1;
3265e111ed8SAndrew Rybchenko 	}
3275e111ed8SAndrew Rybchenko 
3285e111ed8SAndrew Rybchenko 	if (req.emr_out_length_used != 0) {
3295e111ed8SAndrew Rybchenko 		rc = EIO;
3305e111ed8SAndrew Rybchenko 		goto fail2;
3315e111ed8SAndrew Rybchenko 	}
3325e111ed8SAndrew Rybchenko 
3335e111ed8SAndrew Rybchenko 	return (0);
3345e111ed8SAndrew Rybchenko 
3355e111ed8SAndrew Rybchenko fail2:
3365e111ed8SAndrew Rybchenko 	EFSYS_PROBE(fail2);
3375e111ed8SAndrew Rybchenko fail1:
3385e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
3395e111ed8SAndrew Rybchenko 
3405e111ed8SAndrew Rybchenko 	return (rc);
3415e111ed8SAndrew Rybchenko }
3425e111ed8SAndrew Rybchenko 
3435e111ed8SAndrew Rybchenko static	__checkReturn	efx_rc_t
efx_mcdi_fc_license_get_key_stats(__in efx_nic_t * enp,__out efx_key_stats_t * eksp)3445e111ed8SAndrew Rybchenko efx_mcdi_fc_license_get_key_stats(
3455e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp,
3465e111ed8SAndrew Rybchenko 	__out		efx_key_stats_t *eksp)
3475e111ed8SAndrew Rybchenko {
3485e111ed8SAndrew Rybchenko 	efx_mcdi_req_t req;
3495e111ed8SAndrew Rybchenko 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FC_IN_LICENSE_LEN,
3505e111ed8SAndrew Rybchenko 		MC_CMD_FC_OUT_LICENSE_LEN);
3515e111ed8SAndrew Rybchenko 	efx_rc_t rc;
3525e111ed8SAndrew Rybchenko 
3535e111ed8SAndrew Rybchenko 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
3545e111ed8SAndrew Rybchenko 
3555e111ed8SAndrew Rybchenko 	req.emr_cmd = MC_CMD_FC;
3565e111ed8SAndrew Rybchenko 	req.emr_in_buf = payload;
3575e111ed8SAndrew Rybchenko 	req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN;
3585e111ed8SAndrew Rybchenko 	req.emr_out_buf = payload;
3595e111ed8SAndrew Rybchenko 	req.emr_out_length = MC_CMD_FC_OUT_LICENSE_LEN;
3605e111ed8SAndrew Rybchenko 
3615e111ed8SAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, FC_IN_CMD,
3625e111ed8SAndrew Rybchenko 	    MC_CMD_FC_OP_LICENSE);
3635e111ed8SAndrew Rybchenko 
3645e111ed8SAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP,
3655e111ed8SAndrew Rybchenko 	    MC_CMD_FC_IN_LICENSE_GET_KEY_STATS);
3665e111ed8SAndrew Rybchenko 
3675e111ed8SAndrew Rybchenko 	efx_mcdi_execute_quiet(enp, &req);
3685e111ed8SAndrew Rybchenko 
3695e111ed8SAndrew Rybchenko 	if (req.emr_rc != 0) {
3705e111ed8SAndrew Rybchenko 		rc = req.emr_rc;
3715e111ed8SAndrew Rybchenko 		goto fail1;
3725e111ed8SAndrew Rybchenko 	}
3735e111ed8SAndrew Rybchenko 
3745e111ed8SAndrew Rybchenko 	if (req.emr_out_length_used < MC_CMD_FC_OUT_LICENSE_LEN) {
3755e111ed8SAndrew Rybchenko 		rc = EMSGSIZE;
3765e111ed8SAndrew Rybchenko 		goto fail2;
3775e111ed8SAndrew Rybchenko 	}
3785e111ed8SAndrew Rybchenko 
3795e111ed8SAndrew Rybchenko 	eksp->eks_valid =
3805e111ed8SAndrew Rybchenko 		MCDI_OUT_DWORD(req, FC_OUT_LICENSE_VALID_KEYS);
3815e111ed8SAndrew Rybchenko 	eksp->eks_invalid =
3825e111ed8SAndrew Rybchenko 		MCDI_OUT_DWORD(req, FC_OUT_LICENSE_INVALID_KEYS);
3835e111ed8SAndrew Rybchenko 	eksp->eks_blacklisted =
3845e111ed8SAndrew Rybchenko 		MCDI_OUT_DWORD(req, FC_OUT_LICENSE_BLACKLISTED_KEYS);
3855e111ed8SAndrew Rybchenko 	eksp->eks_unverifiable = 0;
3865e111ed8SAndrew Rybchenko 	eksp->eks_wrong_node = 0;
3875e111ed8SAndrew Rybchenko 	eksp->eks_licensed_apps_lo = 0;
3885e111ed8SAndrew Rybchenko 	eksp->eks_licensed_apps_hi = 0;
3895e111ed8SAndrew Rybchenko 	eksp->eks_licensed_features_lo = 0;
3905e111ed8SAndrew Rybchenko 	eksp->eks_licensed_features_hi = 0;
3915e111ed8SAndrew Rybchenko 
3925e111ed8SAndrew Rybchenko 	return (0);
3935e111ed8SAndrew Rybchenko 
3945e111ed8SAndrew Rybchenko fail2:
3955e111ed8SAndrew Rybchenko 	EFSYS_PROBE(fail2);
3965e111ed8SAndrew Rybchenko fail1:
3975e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
3985e111ed8SAndrew Rybchenko 
3995e111ed8SAndrew Rybchenko 	return (rc);
4005e111ed8SAndrew Rybchenko }
4015e111ed8SAndrew Rybchenko 
4025e111ed8SAndrew Rybchenko #endif	/* EFSYS_OPT_SIENA */
4035e111ed8SAndrew Rybchenko 
4045e111ed8SAndrew Rybchenko /* V1 and V2 Partition format - based on a 16-bit TLV format */
4055e111ed8SAndrew Rybchenko 
4065e111ed8SAndrew Rybchenko #if EFSYS_OPT_SIENA | EFSYS_OPT_HUNTINGTON
4075e111ed8SAndrew Rybchenko 
4085e111ed8SAndrew Rybchenko /*
4095e111ed8SAndrew Rybchenko  * V1/V2 format - defined in SF-108542-TC section 4.2:
4105e111ed8SAndrew Rybchenko  *  Type (T):   16bit - revision/HMAC algorithm
4115e111ed8SAndrew Rybchenko  *  Length (L): 16bit - value length in bytes
4125e111ed8SAndrew Rybchenko  *  Value (V):  L bytes - payload
4135e111ed8SAndrew Rybchenko  */
4145e111ed8SAndrew Rybchenko #define	EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX	(256)
4155e111ed8SAndrew Rybchenko #define	EFX_LICENSE_V1V2_HEADER_LENGTH		(2 * sizeof (uint16_t))
4165e111ed8SAndrew Rybchenko 
4175e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
efx_lic_v1v2_find_start(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__out uint32_t * startp)4185e111ed8SAndrew Rybchenko efx_lic_v1v2_find_start(
4195e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
4205e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
4215e111ed8SAndrew Rybchenko 				caddr_t bufferp,
4225e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
4235e111ed8SAndrew Rybchenko 	__out			uint32_t *startp)
4245e111ed8SAndrew Rybchenko {
4255e111ed8SAndrew Rybchenko 	_NOTE(ARGUNUSED(enp, bufferp, buffer_size))
4265e111ed8SAndrew Rybchenko 
4275e111ed8SAndrew Rybchenko 	*startp = 0;
4285e111ed8SAndrew Rybchenko 	return (0);
4295e111ed8SAndrew Rybchenko }
4305e111ed8SAndrew Rybchenko 
4315e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
efx_lic_v1v2_find_end(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__out uint32_t * endp)4325e111ed8SAndrew Rybchenko efx_lic_v1v2_find_end(
4335e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
4345e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
4355e111ed8SAndrew Rybchenko 				caddr_t bufferp,
4365e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
4375e111ed8SAndrew Rybchenko 	__in			uint32_t offset,
4385e111ed8SAndrew Rybchenko 	__out			uint32_t *endp)
4395e111ed8SAndrew Rybchenko {
4405e111ed8SAndrew Rybchenko 	_NOTE(ARGUNUSED(enp, bufferp, buffer_size))
4415e111ed8SAndrew Rybchenko 
4425e111ed8SAndrew Rybchenko 	*endp = offset + EFX_LICENSE_V1V2_HEADER_LENGTH;
4435e111ed8SAndrew Rybchenko 	return (0);
4445e111ed8SAndrew Rybchenko }
4455e111ed8SAndrew Rybchenko 
4465e111ed8SAndrew Rybchenko 	__checkReturn	__success(return != B_FALSE)	boolean_t
efx_lic_v1v2_find_key(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__out uint32_t * startp,__out uint32_t * lengthp)4475e111ed8SAndrew Rybchenko efx_lic_v1v2_find_key(
4485e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
4495e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
4505e111ed8SAndrew Rybchenko 				caddr_t bufferp,
4515e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
4525e111ed8SAndrew Rybchenko 	__in			uint32_t offset,
4535e111ed8SAndrew Rybchenko 	__out			uint32_t *startp,
4545e111ed8SAndrew Rybchenko 	__out			uint32_t *lengthp)
4555e111ed8SAndrew Rybchenko {
4565e111ed8SAndrew Rybchenko 	boolean_t found;
4575e111ed8SAndrew Rybchenko 	uint16_t tlv_type;
4585e111ed8SAndrew Rybchenko 	uint16_t tlv_length;
4595e111ed8SAndrew Rybchenko 
4605e111ed8SAndrew Rybchenko 	_NOTE(ARGUNUSED(enp))
4615e111ed8SAndrew Rybchenko 
4625e111ed8SAndrew Rybchenko 	if ((size_t)buffer_size - offset < EFX_LICENSE_V1V2_HEADER_LENGTH)
4635e111ed8SAndrew Rybchenko 		goto fail1;
4645e111ed8SAndrew Rybchenko 
4655e111ed8SAndrew Rybchenko 	tlv_type = __LE_TO_CPU_16(((uint16_t *)&bufferp[offset])[0]);
4665e111ed8SAndrew Rybchenko 	tlv_length = __LE_TO_CPU_16(((uint16_t *)&bufferp[offset])[1]);
4675e111ed8SAndrew Rybchenko 	if ((tlv_length > EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX) ||
4685e111ed8SAndrew Rybchenko 	    (tlv_type == 0 && tlv_length == 0)) {
4695e111ed8SAndrew Rybchenko 		found = B_FALSE;
4705e111ed8SAndrew Rybchenko 	} else {
4715e111ed8SAndrew Rybchenko 		*startp = offset;
4725e111ed8SAndrew Rybchenko 		*lengthp = tlv_length + EFX_LICENSE_V1V2_HEADER_LENGTH;
4735e111ed8SAndrew Rybchenko 		found = B_TRUE;
4745e111ed8SAndrew Rybchenko 	}
4755e111ed8SAndrew Rybchenko 	return (found);
4765e111ed8SAndrew Rybchenko 
4775e111ed8SAndrew Rybchenko fail1:
4785e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, boolean_t, B_FALSE);
4795e111ed8SAndrew Rybchenko 
4805e111ed8SAndrew Rybchenko 	return (B_FALSE);
4815e111ed8SAndrew Rybchenko }
4825e111ed8SAndrew Rybchenko 
4835e111ed8SAndrew Rybchenko 	__checkReturn	__success(return != B_FALSE)	boolean_t
efx_lic_v1v2_validate_key(__in efx_nic_t * enp,__in_bcount (length)caddr_t keyp,__in uint32_t length)4845e111ed8SAndrew Rybchenko efx_lic_v1v2_validate_key(
4855e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
4865e111ed8SAndrew Rybchenko 	__in_bcount(length)	caddr_t keyp,
4875e111ed8SAndrew Rybchenko 	__in			uint32_t length)
4885e111ed8SAndrew Rybchenko {
4895e111ed8SAndrew Rybchenko 	uint16_t tlv_type;
4905e111ed8SAndrew Rybchenko 	uint16_t tlv_length;
4915e111ed8SAndrew Rybchenko 
4925e111ed8SAndrew Rybchenko 	_NOTE(ARGUNUSED(enp))
4935e111ed8SAndrew Rybchenko 
4945e111ed8SAndrew Rybchenko 	if (length < EFX_LICENSE_V1V2_HEADER_LENGTH) {
4955e111ed8SAndrew Rybchenko 		goto fail1;
4965e111ed8SAndrew Rybchenko 	}
4975e111ed8SAndrew Rybchenko 
4985e111ed8SAndrew Rybchenko 	tlv_type = __LE_TO_CPU_16(((uint16_t *)keyp)[0]);
4995e111ed8SAndrew Rybchenko 	tlv_length = __LE_TO_CPU_16(((uint16_t *)keyp)[1]);
5005e111ed8SAndrew Rybchenko 
5015e111ed8SAndrew Rybchenko 	if (tlv_length > EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX) {
5025e111ed8SAndrew Rybchenko 		goto fail2;
5035e111ed8SAndrew Rybchenko 	}
5045e111ed8SAndrew Rybchenko 	if (tlv_type == 0) {
5055e111ed8SAndrew Rybchenko 		goto fail3;
5065e111ed8SAndrew Rybchenko 	}
5075e111ed8SAndrew Rybchenko 	if ((tlv_length + EFX_LICENSE_V1V2_HEADER_LENGTH) != length) {
5085e111ed8SAndrew Rybchenko 		goto fail4;
5095e111ed8SAndrew Rybchenko 	}
5105e111ed8SAndrew Rybchenko 
5115e111ed8SAndrew Rybchenko 	return (B_TRUE);
5125e111ed8SAndrew Rybchenko 
5135e111ed8SAndrew Rybchenko fail4:
5145e111ed8SAndrew Rybchenko 	EFSYS_PROBE(fail4);
5155e111ed8SAndrew Rybchenko fail3:
5165e111ed8SAndrew Rybchenko 	EFSYS_PROBE(fail3);
5175e111ed8SAndrew Rybchenko fail2:
5185e111ed8SAndrew Rybchenko 	EFSYS_PROBE(fail2);
5195e111ed8SAndrew Rybchenko fail1:
5205e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, boolean_t, B_FALSE);
5215e111ed8SAndrew Rybchenko 
5225e111ed8SAndrew Rybchenko 	return (B_FALSE);
5235e111ed8SAndrew Rybchenko }
5245e111ed8SAndrew Rybchenko 
5255e111ed8SAndrew Rybchenko 
5265e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
efx_lic_v1v2_read_key(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__in uint32_t length,__out_bcount_part (key_max_size,* lengthp)caddr_t keyp,__in size_t key_max_size,__out uint32_t * lengthp)5275e111ed8SAndrew Rybchenko efx_lic_v1v2_read_key(
5285e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
5295e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
5305e111ed8SAndrew Rybchenko 				caddr_t bufferp,
5315e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
5325e111ed8SAndrew Rybchenko 	__in			uint32_t offset,
5335e111ed8SAndrew Rybchenko 	__in			uint32_t length,
5345e111ed8SAndrew Rybchenko 	__out_bcount_part(key_max_size, *lengthp)
5355e111ed8SAndrew Rybchenko 				caddr_t keyp,
5365e111ed8SAndrew Rybchenko 	__in			size_t key_max_size,
5375e111ed8SAndrew Rybchenko 	__out			uint32_t *lengthp)
5385e111ed8SAndrew Rybchenko {
5395e111ed8SAndrew Rybchenko 	efx_rc_t rc;
5405e111ed8SAndrew Rybchenko 
5415e111ed8SAndrew Rybchenko 	_NOTE(ARGUNUSED(enp, buffer_size))
5425e111ed8SAndrew Rybchenko 	EFSYS_ASSERT(length <= (EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX +
5435e111ed8SAndrew Rybchenko 	    EFX_LICENSE_V1V2_HEADER_LENGTH));
5445e111ed8SAndrew Rybchenko 
5455e111ed8SAndrew Rybchenko 	if (key_max_size < length) {
5465e111ed8SAndrew Rybchenko 		rc = ENOSPC;
5475e111ed8SAndrew Rybchenko 		goto fail1;
5485e111ed8SAndrew Rybchenko 	}
5495e111ed8SAndrew Rybchenko 	memcpy(keyp, &bufferp[offset], length);
5505e111ed8SAndrew Rybchenko 
5515e111ed8SAndrew Rybchenko 	*lengthp = length;
5525e111ed8SAndrew Rybchenko 
5535e111ed8SAndrew Rybchenko 	return (0);
5545e111ed8SAndrew Rybchenko 
5555e111ed8SAndrew Rybchenko fail1:
5565e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
5575e111ed8SAndrew Rybchenko 
5585e111ed8SAndrew Rybchenko 	return (rc);
5595e111ed8SAndrew Rybchenko }
5605e111ed8SAndrew Rybchenko 
5615e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
efx_lic_v1v2_write_key(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__in_bcount (length)caddr_t keyp,__in uint32_t length,__out uint32_t * lengthp)5625e111ed8SAndrew Rybchenko efx_lic_v1v2_write_key(
5635e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
5645e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
5655e111ed8SAndrew Rybchenko 				caddr_t bufferp,
5665e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
5675e111ed8SAndrew Rybchenko 	__in			uint32_t offset,
5685e111ed8SAndrew Rybchenko 	__in_bcount(length)	caddr_t keyp,
5695e111ed8SAndrew Rybchenko 	__in			uint32_t length,
5705e111ed8SAndrew Rybchenko 	__out			uint32_t *lengthp)
5715e111ed8SAndrew Rybchenko {
5725e111ed8SAndrew Rybchenko 	efx_rc_t rc;
5735e111ed8SAndrew Rybchenko 
5745e111ed8SAndrew Rybchenko 	_NOTE(ARGUNUSED(enp))
5755e111ed8SAndrew Rybchenko 	EFSYS_ASSERT(length <= (EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX +
5765e111ed8SAndrew Rybchenko 	    EFX_LICENSE_V1V2_HEADER_LENGTH));
5775e111ed8SAndrew Rybchenko 
5785e111ed8SAndrew Rybchenko 	/* Ensure space for terminator remains */
5795e111ed8SAndrew Rybchenko 	if ((offset + length) >
5805e111ed8SAndrew Rybchenko 	    (buffer_size - EFX_LICENSE_V1V2_HEADER_LENGTH)) {
5815e111ed8SAndrew Rybchenko 		rc = ENOSPC;
5825e111ed8SAndrew Rybchenko 		goto fail1;
5835e111ed8SAndrew Rybchenko 	}
5845e111ed8SAndrew Rybchenko 
5855e111ed8SAndrew Rybchenko 	memcpy(bufferp + offset, keyp, length);
5865e111ed8SAndrew Rybchenko 
5875e111ed8SAndrew Rybchenko 	*lengthp = length;
5885e111ed8SAndrew Rybchenko 
5895e111ed8SAndrew Rybchenko 	return (0);
5905e111ed8SAndrew Rybchenko 
5915e111ed8SAndrew Rybchenko fail1:
5925e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
5935e111ed8SAndrew Rybchenko 
5945e111ed8SAndrew Rybchenko 	return (rc);
5955e111ed8SAndrew Rybchenko }
5965e111ed8SAndrew Rybchenko 
5975e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
efx_lic_v1v2_delete_key(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__in uint32_t length,__in uint32_t end,__out uint32_t * deltap)5985e111ed8SAndrew Rybchenko efx_lic_v1v2_delete_key(
5995e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
6005e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
6015e111ed8SAndrew Rybchenko 				caddr_t bufferp,
6025e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
6035e111ed8SAndrew Rybchenko 	__in			uint32_t offset,
6045e111ed8SAndrew Rybchenko 	__in			uint32_t length,
6055e111ed8SAndrew Rybchenko 	__in			uint32_t end,
6065e111ed8SAndrew Rybchenko 	__out			uint32_t *deltap)
6075e111ed8SAndrew Rybchenko {
6085e111ed8SAndrew Rybchenko 	uint32_t move_start = offset + length;
6095e111ed8SAndrew Rybchenko 	uint32_t move_length = end - move_start;
6105e111ed8SAndrew Rybchenko 
6115e111ed8SAndrew Rybchenko 	_NOTE(ARGUNUSED(enp, buffer_size))
6125e111ed8SAndrew Rybchenko 	EFSYS_ASSERT(end <= buffer_size);
6135e111ed8SAndrew Rybchenko 
6145e111ed8SAndrew Rybchenko 	/* Shift everything after the key down */
6155e111ed8SAndrew Rybchenko 	memmove(bufferp + offset, bufferp + move_start, move_length);
6165e111ed8SAndrew Rybchenko 
6175e111ed8SAndrew Rybchenko 	*deltap = length;
6185e111ed8SAndrew Rybchenko 
6195e111ed8SAndrew Rybchenko 	return (0);
6205e111ed8SAndrew Rybchenko }
6215e111ed8SAndrew Rybchenko 
6225e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
efx_lic_v1v2_create_partition(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size)6235e111ed8SAndrew Rybchenko efx_lic_v1v2_create_partition(
6245e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
6255e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
6265e111ed8SAndrew Rybchenko 				caddr_t bufferp,
6275e111ed8SAndrew Rybchenko 	__in			size_t buffer_size)
6285e111ed8SAndrew Rybchenko {
6295e111ed8SAndrew Rybchenko 	_NOTE(ARGUNUSED(enp, buffer_size))
6305e111ed8SAndrew Rybchenko 	EFSYS_ASSERT(EFX_LICENSE_V1V2_HEADER_LENGTH <= buffer_size);
6315e111ed8SAndrew Rybchenko 
6325e111ed8SAndrew Rybchenko 	/* Write terminator */
6335e111ed8SAndrew Rybchenko 	memset(bufferp, '\0', EFX_LICENSE_V1V2_HEADER_LENGTH);
6345e111ed8SAndrew Rybchenko 	return (0);
6355e111ed8SAndrew Rybchenko }
6365e111ed8SAndrew Rybchenko 
6375e111ed8SAndrew Rybchenko 
6385e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
efx_lic_v1v2_finish_partition(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size)6395e111ed8SAndrew Rybchenko efx_lic_v1v2_finish_partition(
6405e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
6415e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
6425e111ed8SAndrew Rybchenko 				caddr_t bufferp,
6435e111ed8SAndrew Rybchenko 	__in			size_t buffer_size)
6445e111ed8SAndrew Rybchenko {
6455e111ed8SAndrew Rybchenko 	_NOTE(ARGUNUSED(enp, bufferp, buffer_size))
6465e111ed8SAndrew Rybchenko 
6475e111ed8SAndrew Rybchenko 	return (0);
6485e111ed8SAndrew Rybchenko }
6495e111ed8SAndrew Rybchenko 
6505e111ed8SAndrew Rybchenko #endif	/* EFSYS_OPT_HUNTINGTON | EFSYS_OPT_SIENA */
6515e111ed8SAndrew Rybchenko 
6525e111ed8SAndrew Rybchenko 
6535e111ed8SAndrew Rybchenko /* V2 Licensing - used by Huntington family only. See SF-113611-TC */
6545e111ed8SAndrew Rybchenko 
6555e111ed8SAndrew Rybchenko #if EFSYS_OPT_HUNTINGTON
6565e111ed8SAndrew Rybchenko 
6575e111ed8SAndrew Rybchenko static	__checkReturn	efx_rc_t
efx_mcdi_licensed_app_state(__in efx_nic_t * enp,__in uint64_t app_id,__out boolean_t * licensedp)6585e111ed8SAndrew Rybchenko efx_mcdi_licensed_app_state(
6595e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp,
6605e111ed8SAndrew Rybchenko 	__in		uint64_t app_id,
6615e111ed8SAndrew Rybchenko 	__out		boolean_t *licensedp)
6625e111ed8SAndrew Rybchenko {
6635e111ed8SAndrew Rybchenko 	efx_mcdi_req_t req;
6645e111ed8SAndrew Rybchenko 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LICENSED_APP_STATE_IN_LEN,
6655e111ed8SAndrew Rybchenko 		MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN);
6665e111ed8SAndrew Rybchenko 	uint32_t app_state;
6675e111ed8SAndrew Rybchenko 	efx_rc_t rc;
6685e111ed8SAndrew Rybchenko 
6695e111ed8SAndrew Rybchenko 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
6705e111ed8SAndrew Rybchenko 
6715e111ed8SAndrew Rybchenko 	/* V2 licensing supports 32bit app id only */
6725e111ed8SAndrew Rybchenko 	if ((app_id >> 32) != 0) {
6735e111ed8SAndrew Rybchenko 		rc = EINVAL;
6745e111ed8SAndrew Rybchenko 		goto fail1;
6755e111ed8SAndrew Rybchenko 	}
6765e111ed8SAndrew Rybchenko 
6775e111ed8SAndrew Rybchenko 	req.emr_cmd = MC_CMD_GET_LICENSED_APP_STATE;
6785e111ed8SAndrew Rybchenko 	req.emr_in_buf = payload;
6795e111ed8SAndrew Rybchenko 	req.emr_in_length = MC_CMD_GET_LICENSED_APP_STATE_IN_LEN;
6805e111ed8SAndrew Rybchenko 	req.emr_out_buf = payload;
6815e111ed8SAndrew Rybchenko 	req.emr_out_length = MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN;
6825e111ed8SAndrew Rybchenko 
6835e111ed8SAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, GET_LICENSED_APP_STATE_IN_APP_ID,
6845e111ed8SAndrew Rybchenko 		    app_id & 0xffffffff);
6855e111ed8SAndrew Rybchenko 
6865e111ed8SAndrew Rybchenko 	efx_mcdi_execute(enp, &req);
6875e111ed8SAndrew Rybchenko 
6885e111ed8SAndrew Rybchenko 	if (req.emr_rc != 0) {
6895e111ed8SAndrew Rybchenko 		rc = req.emr_rc;
6905e111ed8SAndrew Rybchenko 		goto fail2;
6915e111ed8SAndrew Rybchenko 	}
6925e111ed8SAndrew Rybchenko 
6935e111ed8SAndrew Rybchenko 	if (req.emr_out_length_used < MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN) {
6945e111ed8SAndrew Rybchenko 		rc = EMSGSIZE;
6955e111ed8SAndrew Rybchenko 		goto fail3;
6965e111ed8SAndrew Rybchenko 	}
6975e111ed8SAndrew Rybchenko 
6985e111ed8SAndrew Rybchenko 	app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_APP_STATE_OUT_STATE));
6995e111ed8SAndrew Rybchenko 	if (app_state != MC_CMD_GET_LICENSED_APP_STATE_OUT_NOT_LICENSED) {
7005e111ed8SAndrew Rybchenko 		*licensedp = B_TRUE;
7015e111ed8SAndrew Rybchenko 	} else {
7025e111ed8SAndrew Rybchenko 		*licensedp = B_FALSE;
7035e111ed8SAndrew Rybchenko 	}
7045e111ed8SAndrew Rybchenko 
7055e111ed8SAndrew Rybchenko 	return (0);
7065e111ed8SAndrew Rybchenko 
7075e111ed8SAndrew Rybchenko fail3:
7085e111ed8SAndrew Rybchenko 	EFSYS_PROBE(fail3);
7095e111ed8SAndrew Rybchenko fail2:
7105e111ed8SAndrew Rybchenko 	EFSYS_PROBE(fail2);
7115e111ed8SAndrew Rybchenko fail1:
7125e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
7135e111ed8SAndrew Rybchenko 
7145e111ed8SAndrew Rybchenko 	return (rc);
7155e111ed8SAndrew Rybchenko }
7165e111ed8SAndrew Rybchenko 
7175e111ed8SAndrew Rybchenko static	__checkReturn	efx_rc_t
efx_mcdi_licensing_update_licenses(__in efx_nic_t * enp)7185e111ed8SAndrew Rybchenko efx_mcdi_licensing_update_licenses(
7195e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp)
7205e111ed8SAndrew Rybchenko {
7215e111ed8SAndrew Rybchenko 	efx_mcdi_req_t req;
7225e111ed8SAndrew Rybchenko 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_IN_LEN, 0);
7235e111ed8SAndrew Rybchenko 	efx_rc_t rc;
7245e111ed8SAndrew Rybchenko 
7255e111ed8SAndrew Rybchenko 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
7265e111ed8SAndrew Rybchenko 
7275e111ed8SAndrew Rybchenko 	req.emr_cmd = MC_CMD_LICENSING;
7285e111ed8SAndrew Rybchenko 	req.emr_in_buf = payload;
7295e111ed8SAndrew Rybchenko 	req.emr_in_length = MC_CMD_LICENSING_IN_LEN;
7305e111ed8SAndrew Rybchenko 	req.emr_out_buf = payload;
7315e111ed8SAndrew Rybchenko 	req.emr_out_length = 0;
7325e111ed8SAndrew Rybchenko 
7335e111ed8SAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, LICENSING_IN_OP,
7345e111ed8SAndrew Rybchenko 	    MC_CMD_LICENSING_IN_OP_UPDATE_LICENSE);
7355e111ed8SAndrew Rybchenko 
7365e111ed8SAndrew Rybchenko 	efx_mcdi_execute(enp, &req);
7375e111ed8SAndrew Rybchenko 
7385e111ed8SAndrew Rybchenko 	if (req.emr_rc != 0) {
7395e111ed8SAndrew Rybchenko 		rc = req.emr_rc;
7405e111ed8SAndrew Rybchenko 		goto fail1;
7415e111ed8SAndrew Rybchenko 	}
7425e111ed8SAndrew Rybchenko 
7435e111ed8SAndrew Rybchenko 	if (req.emr_out_length_used != 0) {
7445e111ed8SAndrew Rybchenko 		rc = EIO;
7455e111ed8SAndrew Rybchenko 		goto fail2;
7465e111ed8SAndrew Rybchenko 	}
7475e111ed8SAndrew Rybchenko 
7485e111ed8SAndrew Rybchenko 	return (0);
7495e111ed8SAndrew Rybchenko 
7505e111ed8SAndrew Rybchenko fail2:
7515e111ed8SAndrew Rybchenko 	EFSYS_PROBE(fail2);
7525e111ed8SAndrew Rybchenko fail1:
7535e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
7545e111ed8SAndrew Rybchenko 
7555e111ed8SAndrew Rybchenko 	return (rc);
7565e111ed8SAndrew Rybchenko }
7575e111ed8SAndrew Rybchenko 
7585e111ed8SAndrew Rybchenko static	__checkReturn	efx_rc_t
efx_mcdi_licensing_get_key_stats(__in efx_nic_t * enp,__out efx_key_stats_t * eksp)7595e111ed8SAndrew Rybchenko efx_mcdi_licensing_get_key_stats(
7605e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp,
7615e111ed8SAndrew Rybchenko 	__out		efx_key_stats_t *eksp)
7625e111ed8SAndrew Rybchenko {
7635e111ed8SAndrew Rybchenko 	efx_mcdi_req_t req;
7645e111ed8SAndrew Rybchenko 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_IN_LEN,
7655e111ed8SAndrew Rybchenko 		MC_CMD_LICENSING_OUT_LEN);
7665e111ed8SAndrew Rybchenko 	efx_rc_t rc;
7675e111ed8SAndrew Rybchenko 
7685e111ed8SAndrew Rybchenko 	EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
7695e111ed8SAndrew Rybchenko 
7705e111ed8SAndrew Rybchenko 	req.emr_cmd = MC_CMD_LICENSING;
7715e111ed8SAndrew Rybchenko 	req.emr_in_buf = payload;
7725e111ed8SAndrew Rybchenko 	req.emr_in_length = MC_CMD_LICENSING_IN_LEN;
7735e111ed8SAndrew Rybchenko 	req.emr_out_buf = payload;
7745e111ed8SAndrew Rybchenko 	req.emr_out_length = MC_CMD_LICENSING_OUT_LEN;
7755e111ed8SAndrew Rybchenko 
7765e111ed8SAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, LICENSING_IN_OP,
7775e111ed8SAndrew Rybchenko 	    MC_CMD_LICENSING_IN_OP_GET_KEY_STATS);
7785e111ed8SAndrew Rybchenko 
7795e111ed8SAndrew Rybchenko 	efx_mcdi_execute(enp, &req);
7805e111ed8SAndrew Rybchenko 
7815e111ed8SAndrew Rybchenko 	if (req.emr_rc != 0) {
7825e111ed8SAndrew Rybchenko 		rc = req.emr_rc;
7835e111ed8SAndrew Rybchenko 		goto fail1;
7845e111ed8SAndrew Rybchenko 	}
7855e111ed8SAndrew Rybchenko 
7865e111ed8SAndrew Rybchenko 	if (req.emr_out_length_used < MC_CMD_LICENSING_OUT_LEN) {
7875e111ed8SAndrew Rybchenko 		rc = EMSGSIZE;
7885e111ed8SAndrew Rybchenko 		goto fail2;
7895e111ed8SAndrew Rybchenko 	}
7905e111ed8SAndrew Rybchenko 
7915e111ed8SAndrew Rybchenko 	eksp->eks_valid =
7925e111ed8SAndrew Rybchenko 		MCDI_OUT_DWORD(req, LICENSING_OUT_VALID_APP_KEYS);
7935e111ed8SAndrew Rybchenko 	eksp->eks_invalid =
7945e111ed8SAndrew Rybchenko 		MCDI_OUT_DWORD(req, LICENSING_OUT_INVALID_APP_KEYS);
7955e111ed8SAndrew Rybchenko 	eksp->eks_blacklisted =
7965e111ed8SAndrew Rybchenko 		MCDI_OUT_DWORD(req, LICENSING_OUT_BLACKLISTED_APP_KEYS);
7975e111ed8SAndrew Rybchenko 	eksp->eks_unverifiable =
7985e111ed8SAndrew Rybchenko 		MCDI_OUT_DWORD(req, LICENSING_OUT_UNVERIFIABLE_APP_KEYS);
7995e111ed8SAndrew Rybchenko 	eksp->eks_wrong_node =
8005e111ed8SAndrew Rybchenko 		MCDI_OUT_DWORD(req, LICENSING_OUT_WRONG_NODE_APP_KEYS);
8015e111ed8SAndrew Rybchenko 	eksp->eks_licensed_apps_lo = 0;
8025e111ed8SAndrew Rybchenko 	eksp->eks_licensed_apps_hi = 0;
8035e111ed8SAndrew Rybchenko 	eksp->eks_licensed_features_lo = 0;
8045e111ed8SAndrew Rybchenko 	eksp->eks_licensed_features_hi = 0;
8055e111ed8SAndrew Rybchenko 
8065e111ed8SAndrew Rybchenko 	return (0);
8075e111ed8SAndrew Rybchenko 
8085e111ed8SAndrew Rybchenko fail2:
8095e111ed8SAndrew Rybchenko 	EFSYS_PROBE(fail2);
8105e111ed8SAndrew Rybchenko fail1:
8115e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
8125e111ed8SAndrew Rybchenko 
8135e111ed8SAndrew Rybchenko 	return (rc);
8145e111ed8SAndrew Rybchenko }
8155e111ed8SAndrew Rybchenko 
8165e111ed8SAndrew Rybchenko #endif	/* EFSYS_OPT_HUNTINGTON */
8175e111ed8SAndrew Rybchenko 
8185e111ed8SAndrew Rybchenko /* V3 Licensing - used starting from Medford family. See SF-114884-SW */
8195e111ed8SAndrew Rybchenko 
8205e111ed8SAndrew Rybchenko #if EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
8215e111ed8SAndrew Rybchenko 
8225e111ed8SAndrew Rybchenko static	__checkReturn	efx_rc_t
efx_mcdi_licensing_v3_update_licenses(__in efx_nic_t * enp)8235e111ed8SAndrew Rybchenko efx_mcdi_licensing_v3_update_licenses(
8245e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp)
8255e111ed8SAndrew Rybchenko {
8265e111ed8SAndrew Rybchenko 	efx_mcdi_req_t req;
8275e111ed8SAndrew Rybchenko 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_V3_IN_LEN, 0);
8285e111ed8SAndrew Rybchenko 	efx_rc_t rc;
8295e111ed8SAndrew Rybchenko 
8305e111ed8SAndrew Rybchenko 	EFSYS_ASSERT((enp->en_family == EFX_FAMILY_MEDFORD) ||
8315e111ed8SAndrew Rybchenko 	    (enp->en_family == EFX_FAMILY_MEDFORD2));
8325e111ed8SAndrew Rybchenko 
8335e111ed8SAndrew Rybchenko 	req.emr_cmd = MC_CMD_LICENSING_V3;
8345e111ed8SAndrew Rybchenko 	req.emr_in_buf = payload;
8355e111ed8SAndrew Rybchenko 	req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN;
8365e111ed8SAndrew Rybchenko 	req.emr_out_buf = NULL;
8375e111ed8SAndrew Rybchenko 	req.emr_out_length = 0;
8385e111ed8SAndrew Rybchenko 
8395e111ed8SAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP,
8405e111ed8SAndrew Rybchenko 	    MC_CMD_LICENSING_V3_IN_OP_UPDATE_LICENSE);
8415e111ed8SAndrew Rybchenko 
8425e111ed8SAndrew Rybchenko 	efx_mcdi_execute(enp, &req);
8435e111ed8SAndrew Rybchenko 
8445e111ed8SAndrew Rybchenko 	if (req.emr_rc != 0) {
8455e111ed8SAndrew Rybchenko 		rc = req.emr_rc;
8465e111ed8SAndrew Rybchenko 		goto fail1;
8475e111ed8SAndrew Rybchenko 	}
8485e111ed8SAndrew Rybchenko 
8495e111ed8SAndrew Rybchenko 	return (0);
8505e111ed8SAndrew Rybchenko 
8515e111ed8SAndrew Rybchenko fail1:
8525e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
8535e111ed8SAndrew Rybchenko 
8545e111ed8SAndrew Rybchenko 	return (rc);
8555e111ed8SAndrew Rybchenko }
8565e111ed8SAndrew Rybchenko 
8575e111ed8SAndrew Rybchenko static	__checkReturn	efx_rc_t
efx_mcdi_licensing_v3_report_license(__in efx_nic_t * enp,__out efx_key_stats_t * eksp)8585e111ed8SAndrew Rybchenko efx_mcdi_licensing_v3_report_license(
8595e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp,
8605e111ed8SAndrew Rybchenko 	__out		efx_key_stats_t *eksp)
8615e111ed8SAndrew Rybchenko {
8625e111ed8SAndrew Rybchenko 	efx_mcdi_req_t req;
8635e111ed8SAndrew Rybchenko 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_V3_IN_LEN,
8645e111ed8SAndrew Rybchenko 		MC_CMD_LICENSING_V3_OUT_LEN);
8655e111ed8SAndrew Rybchenko 	efx_rc_t rc;
8665e111ed8SAndrew Rybchenko 
8675e111ed8SAndrew Rybchenko 	EFSYS_ASSERT((enp->en_family == EFX_FAMILY_MEDFORD) ||
8685e111ed8SAndrew Rybchenko 	    (enp->en_family == EFX_FAMILY_MEDFORD2));
8695e111ed8SAndrew Rybchenko 
8705e111ed8SAndrew Rybchenko 	req.emr_cmd = MC_CMD_LICENSING_V3;
8715e111ed8SAndrew Rybchenko 	req.emr_in_buf = payload;
8725e111ed8SAndrew Rybchenko 	req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN;
8735e111ed8SAndrew Rybchenko 	req.emr_out_buf = payload;
8745e111ed8SAndrew Rybchenko 	req.emr_out_length = MC_CMD_LICENSING_V3_OUT_LEN;
8755e111ed8SAndrew Rybchenko 
8765e111ed8SAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP,
8775e111ed8SAndrew Rybchenko 	    MC_CMD_LICENSING_V3_IN_OP_REPORT_LICENSE);
8785e111ed8SAndrew Rybchenko 
8795e111ed8SAndrew Rybchenko 	efx_mcdi_execute_quiet(enp, &req);
8805e111ed8SAndrew Rybchenko 
8815e111ed8SAndrew Rybchenko 	if (req.emr_rc != 0) {
8825e111ed8SAndrew Rybchenko 		rc = req.emr_rc;
8835e111ed8SAndrew Rybchenko 		goto fail1;
8845e111ed8SAndrew Rybchenko 	}
8855e111ed8SAndrew Rybchenko 
8865e111ed8SAndrew Rybchenko 	if (req.emr_out_length_used < MC_CMD_LICENSING_V3_OUT_LEN) {
8875e111ed8SAndrew Rybchenko 		rc = EMSGSIZE;
8885e111ed8SAndrew Rybchenko 		goto fail2;
8895e111ed8SAndrew Rybchenko 	}
8905e111ed8SAndrew Rybchenko 
8915e111ed8SAndrew Rybchenko 	eksp->eks_valid =
8925e111ed8SAndrew Rybchenko 		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_VALID_KEYS);
8935e111ed8SAndrew Rybchenko 	eksp->eks_invalid =
8945e111ed8SAndrew Rybchenko 		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_INVALID_KEYS);
8955e111ed8SAndrew Rybchenko 	eksp->eks_blacklisted = 0;
8965e111ed8SAndrew Rybchenko 	eksp->eks_unverifiable =
8975e111ed8SAndrew Rybchenko 		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_UNVERIFIABLE_KEYS);
8985e111ed8SAndrew Rybchenko 	eksp->eks_wrong_node =
8995e111ed8SAndrew Rybchenko 		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_WRONG_NODE_KEYS);
9005e111ed8SAndrew Rybchenko 	eksp->eks_licensed_apps_lo =
9015e111ed8SAndrew Rybchenko 		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_LO);
9025e111ed8SAndrew Rybchenko 	eksp->eks_licensed_apps_hi =
9035e111ed8SAndrew Rybchenko 		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_HI);
9045e111ed8SAndrew Rybchenko 	eksp->eks_licensed_features_lo =
9055e111ed8SAndrew Rybchenko 		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_LO);
9065e111ed8SAndrew Rybchenko 	eksp->eks_licensed_features_hi =
9075e111ed8SAndrew Rybchenko 		MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_HI);
9085e111ed8SAndrew Rybchenko 
9095e111ed8SAndrew Rybchenko 	return (0);
9105e111ed8SAndrew Rybchenko 
9115e111ed8SAndrew Rybchenko fail2:
9125e111ed8SAndrew Rybchenko 	EFSYS_PROBE(fail2);
9135e111ed8SAndrew Rybchenko fail1:
9145e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
9155e111ed8SAndrew Rybchenko 
9165e111ed8SAndrew Rybchenko 	return (rc);
9175e111ed8SAndrew Rybchenko }
9185e111ed8SAndrew Rybchenko 
9195e111ed8SAndrew Rybchenko static	__checkReturn	efx_rc_t
efx_mcdi_licensing_v3_app_state(__in efx_nic_t * enp,__in uint64_t app_id,__out boolean_t * licensedp)9205e111ed8SAndrew Rybchenko efx_mcdi_licensing_v3_app_state(
9215e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp,
9225e111ed8SAndrew Rybchenko 	__in		uint64_t app_id,
9235e111ed8SAndrew Rybchenko 	__out		boolean_t *licensedp)
9245e111ed8SAndrew Rybchenko {
9255e111ed8SAndrew Rybchenko 	efx_mcdi_req_t req;
9265e111ed8SAndrew Rybchenko 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN,
9275e111ed8SAndrew Rybchenko 		MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN);
9285e111ed8SAndrew Rybchenko 	uint32_t app_state;
9295e111ed8SAndrew Rybchenko 	efx_rc_t rc;
9305e111ed8SAndrew Rybchenko 
9315e111ed8SAndrew Rybchenko 	EFSYS_ASSERT((enp->en_family == EFX_FAMILY_MEDFORD) ||
9325e111ed8SAndrew Rybchenko 	    (enp->en_family == EFX_FAMILY_MEDFORD2));
9335e111ed8SAndrew Rybchenko 
9345e111ed8SAndrew Rybchenko 	req.emr_cmd = MC_CMD_GET_LICENSED_V3_APP_STATE;
9355e111ed8SAndrew Rybchenko 	req.emr_in_buf = payload;
9365e111ed8SAndrew Rybchenko 	req.emr_in_length = MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN;
9375e111ed8SAndrew Rybchenko 	req.emr_out_buf = payload;
9385e111ed8SAndrew Rybchenko 	req.emr_out_length = MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN;
9395e111ed8SAndrew Rybchenko 
9405e111ed8SAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_LO,
9415e111ed8SAndrew Rybchenko 		    app_id & 0xffffffff);
9425e111ed8SAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_HI,
9435e111ed8SAndrew Rybchenko 		    app_id >> 32);
9445e111ed8SAndrew Rybchenko 
9455e111ed8SAndrew Rybchenko 	efx_mcdi_execute(enp, &req);
9465e111ed8SAndrew Rybchenko 
9475e111ed8SAndrew Rybchenko 	if (req.emr_rc != 0) {
9485e111ed8SAndrew Rybchenko 		rc = req.emr_rc;
9495e111ed8SAndrew Rybchenko 		goto fail1;
9505e111ed8SAndrew Rybchenko 	}
9515e111ed8SAndrew Rybchenko 
9525e111ed8SAndrew Rybchenko 	if (req.emr_out_length_used <
9535e111ed8SAndrew Rybchenko 	    MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN) {
9545e111ed8SAndrew Rybchenko 		rc = EMSGSIZE;
9555e111ed8SAndrew Rybchenko 		goto fail2;
9565e111ed8SAndrew Rybchenko 	}
9575e111ed8SAndrew Rybchenko 
9585e111ed8SAndrew Rybchenko 	app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_V3_APP_STATE_OUT_STATE));
9595e111ed8SAndrew Rybchenko 	if (app_state != MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_NOT_LICENSED) {
9605e111ed8SAndrew Rybchenko 		*licensedp = B_TRUE;
9615e111ed8SAndrew Rybchenko 	} else {
9625e111ed8SAndrew Rybchenko 		*licensedp = B_FALSE;
9635e111ed8SAndrew Rybchenko 	}
9645e111ed8SAndrew Rybchenko 
9655e111ed8SAndrew Rybchenko 	return (0);
9665e111ed8SAndrew Rybchenko 
9675e111ed8SAndrew Rybchenko fail2:
9685e111ed8SAndrew Rybchenko 	EFSYS_PROBE(fail2);
9695e111ed8SAndrew Rybchenko fail1:
9705e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
9715e111ed8SAndrew Rybchenko 
9725e111ed8SAndrew Rybchenko 	return (rc);
9735e111ed8SAndrew Rybchenko }
9745e111ed8SAndrew Rybchenko 
9755e111ed8SAndrew Rybchenko static	__checkReturn	efx_rc_t
efx_mcdi_licensing_v3_get_id(__in efx_nic_t * enp,__in size_t buffer_size,__out uint32_t * typep,__out size_t * lengthp,__out_bcount_part_opt (buffer_size,* lengthp)uint8_t * bufferp)9765e111ed8SAndrew Rybchenko efx_mcdi_licensing_v3_get_id(
9775e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp,
9785e111ed8SAndrew Rybchenko 	__in		size_t buffer_size,
9795e111ed8SAndrew Rybchenko 	__out		uint32_t *typep,
9805e111ed8SAndrew Rybchenko 	__out		size_t *lengthp,
9815e111ed8SAndrew Rybchenko 	__out_bcount_part_opt(buffer_size, *lengthp)
9825e111ed8SAndrew Rybchenko 			uint8_t *bufferp)
9835e111ed8SAndrew Rybchenko {
9845e111ed8SAndrew Rybchenko 	efx_mcdi_req_t req;
9855e111ed8SAndrew Rybchenko 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_GET_ID_V3_IN_LEN,
9865e111ed8SAndrew Rybchenko 		MC_CMD_LICENSING_GET_ID_V3_OUT_LENMAX);
9875e111ed8SAndrew Rybchenko 	efx_rc_t rc;
9885e111ed8SAndrew Rybchenko 
9895e111ed8SAndrew Rybchenko 	req.emr_cmd = MC_CMD_LICENSING_GET_ID_V3;
9905e111ed8SAndrew Rybchenko 	req.emr_in_buf = payload;
9915e111ed8SAndrew Rybchenko 	req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN;
9925e111ed8SAndrew Rybchenko 	req.emr_out_buf = payload;
9935e111ed8SAndrew Rybchenko 	req.emr_out_length = MC_CMD_LICENSING_GET_ID_V3_OUT_LENMAX;
9945e111ed8SAndrew Rybchenko 
9955e111ed8SAndrew Rybchenko 	efx_mcdi_execute_quiet(enp, &req);
9965e111ed8SAndrew Rybchenko 
9975e111ed8SAndrew Rybchenko 	if (req.emr_rc != 0) {
9985e111ed8SAndrew Rybchenko 		rc = req.emr_rc;
9995e111ed8SAndrew Rybchenko 		goto fail1;
10005e111ed8SAndrew Rybchenko 	}
10015e111ed8SAndrew Rybchenko 
10025e111ed8SAndrew Rybchenko 	if (req.emr_out_length_used < MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN) {
10035e111ed8SAndrew Rybchenko 		rc = EMSGSIZE;
10045e111ed8SAndrew Rybchenko 		goto fail2;
10055e111ed8SAndrew Rybchenko 	}
10065e111ed8SAndrew Rybchenko 
10075e111ed8SAndrew Rybchenko 	*typep = MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_TYPE);
10085e111ed8SAndrew Rybchenko 	*lengthp =
10095e111ed8SAndrew Rybchenko 	    MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_ID_LENGTH);
10105e111ed8SAndrew Rybchenko 
10115e111ed8SAndrew Rybchenko 	if (bufferp != NULL) {
10125e111ed8SAndrew Rybchenko 		memcpy(bufferp,
10135e111ed8SAndrew Rybchenko 		    payload + MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST,
10145e111ed8SAndrew Rybchenko 		    MIN(buffer_size, *lengthp));
10155e111ed8SAndrew Rybchenko 	}
10165e111ed8SAndrew Rybchenko 
10175e111ed8SAndrew Rybchenko 	return (0);
10185e111ed8SAndrew Rybchenko 
10195e111ed8SAndrew Rybchenko fail2:
10205e111ed8SAndrew Rybchenko 	EFSYS_PROBE(fail2);
10215e111ed8SAndrew Rybchenko fail1:
10225e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
10235e111ed8SAndrew Rybchenko 
10245e111ed8SAndrew Rybchenko 	return (rc);
10255e111ed8SAndrew Rybchenko }
10265e111ed8SAndrew Rybchenko 
10275e111ed8SAndrew Rybchenko /* V3 format uses Huntington TLV format partition. See SF-108797-SW */
10285e111ed8SAndrew Rybchenko #define	EFX_LICENSE_V3_KEY_LENGTH_MIN	(64)
10295e111ed8SAndrew Rybchenko #define	EFX_LICENSE_V3_KEY_LENGTH_MAX	(160)
10305e111ed8SAndrew Rybchenko 
10315e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
efx_lic_v3_find_start(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__out uint32_t * startp)10325e111ed8SAndrew Rybchenko efx_lic_v3_find_start(
10335e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
10345e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
10355e111ed8SAndrew Rybchenko 				caddr_t bufferp,
10365e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
10375e111ed8SAndrew Rybchenko 	__out			uint32_t *startp)
10385e111ed8SAndrew Rybchenko {
10395e111ed8SAndrew Rybchenko 	_NOTE(ARGUNUSED(enp))
10405e111ed8SAndrew Rybchenko 
10415e111ed8SAndrew Rybchenko 	return (ef10_nvram_buffer_find_item_start(bufferp, buffer_size,
10425e111ed8SAndrew Rybchenko 	    startp));
10435e111ed8SAndrew Rybchenko }
10445e111ed8SAndrew Rybchenko 
10455e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
efx_lic_v3_find_end(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__out uint32_t * endp)10465e111ed8SAndrew Rybchenko efx_lic_v3_find_end(
10475e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
10485e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
10495e111ed8SAndrew Rybchenko 				caddr_t bufferp,
10505e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
10515e111ed8SAndrew Rybchenko 	__in			uint32_t offset,
10525e111ed8SAndrew Rybchenko 	__out			uint32_t *endp)
10535e111ed8SAndrew Rybchenko {
10545e111ed8SAndrew Rybchenko 	_NOTE(ARGUNUSED(enp))
10555e111ed8SAndrew Rybchenko 
10565e111ed8SAndrew Rybchenko 	return (ef10_nvram_buffer_find_end(bufferp, buffer_size, offset, endp));
10575e111ed8SAndrew Rybchenko }
10585e111ed8SAndrew Rybchenko 
10595e111ed8SAndrew Rybchenko 	__checkReturn	__success(return != B_FALSE)	boolean_t
efx_lic_v3_find_key(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__out uint32_t * startp,__out uint32_t * lengthp)10605e111ed8SAndrew Rybchenko efx_lic_v3_find_key(
10615e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
10625e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
10635e111ed8SAndrew Rybchenko 				caddr_t bufferp,
10645e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
10655e111ed8SAndrew Rybchenko 	__in			uint32_t offset,
10665e111ed8SAndrew Rybchenko 	__out			uint32_t *startp,
10675e111ed8SAndrew Rybchenko 	__out			uint32_t *lengthp)
10685e111ed8SAndrew Rybchenko {
10695e111ed8SAndrew Rybchenko 	_NOTE(ARGUNUSED(enp))
10705e111ed8SAndrew Rybchenko 
10715e111ed8SAndrew Rybchenko 	return ef10_nvram_buffer_find_item(bufferp, buffer_size,
10725e111ed8SAndrew Rybchenko 	    offset, startp, lengthp);
10735e111ed8SAndrew Rybchenko }
10745e111ed8SAndrew Rybchenko 
10755e111ed8SAndrew Rybchenko 	__checkReturn	__success(return != B_FALSE)	boolean_t
efx_lic_v3_validate_key(__in efx_nic_t * enp,__in_bcount (length)caddr_t keyp,__in uint32_t length)10765e111ed8SAndrew Rybchenko efx_lic_v3_validate_key(
10775e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
10785e111ed8SAndrew Rybchenko 	__in_bcount(length)	caddr_t keyp,
10795e111ed8SAndrew Rybchenko 	__in			uint32_t length)
10805e111ed8SAndrew Rybchenko {
10815e111ed8SAndrew Rybchenko 	/* Check key is a valid V3 key */
10825e111ed8SAndrew Rybchenko 	uint8_t key_type;
10835e111ed8SAndrew Rybchenko 	uint8_t key_length;
10845e111ed8SAndrew Rybchenko 
10855e111ed8SAndrew Rybchenko 	_NOTE(ARGUNUSED(enp))
10865e111ed8SAndrew Rybchenko 
10875e111ed8SAndrew Rybchenko 	if (length < EFX_LICENSE_V3_KEY_LENGTH_MIN) {
10885e111ed8SAndrew Rybchenko 		goto fail1;
10895e111ed8SAndrew Rybchenko 	}
10905e111ed8SAndrew Rybchenko 
10915e111ed8SAndrew Rybchenko 	if (length > EFX_LICENSE_V3_KEY_LENGTH_MAX) {
10925e111ed8SAndrew Rybchenko 		goto fail2;
10935e111ed8SAndrew Rybchenko 	}
10945e111ed8SAndrew Rybchenko 
10955e111ed8SAndrew Rybchenko 	key_type = ((uint8_t *)keyp)[0];
10965e111ed8SAndrew Rybchenko 	key_length = ((uint8_t *)keyp)[1];
10975e111ed8SAndrew Rybchenko 
10985e111ed8SAndrew Rybchenko 	if (key_type < 3) {
10995e111ed8SAndrew Rybchenko 		goto fail3;
11005e111ed8SAndrew Rybchenko 	}
11015e111ed8SAndrew Rybchenko 	if (key_length > length) {
11025e111ed8SAndrew Rybchenko 		goto fail4;
11035e111ed8SAndrew Rybchenko 	}
11045e111ed8SAndrew Rybchenko 	return (B_TRUE);
11055e111ed8SAndrew Rybchenko 
11065e111ed8SAndrew Rybchenko fail4:
11075e111ed8SAndrew Rybchenko 	EFSYS_PROBE(fail4);
11085e111ed8SAndrew Rybchenko fail3:
11095e111ed8SAndrew Rybchenko 	EFSYS_PROBE(fail3);
11105e111ed8SAndrew Rybchenko fail2:
11115e111ed8SAndrew Rybchenko 	EFSYS_PROBE(fail2);
11125e111ed8SAndrew Rybchenko fail1:
11135e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, boolean_t, B_FALSE);
11145e111ed8SAndrew Rybchenko 
11155e111ed8SAndrew Rybchenko 	return (B_FALSE);
11165e111ed8SAndrew Rybchenko }
11175e111ed8SAndrew Rybchenko 
11185e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
efx_lic_v3_read_key(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__in uint32_t length,__out_bcount_part (key_max_size,* lengthp)caddr_t keyp,__in size_t key_max_size,__out uint32_t * lengthp)11195e111ed8SAndrew Rybchenko efx_lic_v3_read_key(
11205e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
11215e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
11225e111ed8SAndrew Rybchenko 				caddr_t bufferp,
11235e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
11245e111ed8SAndrew Rybchenko 	__in			uint32_t offset,
11255e111ed8SAndrew Rybchenko 	__in			uint32_t length,
11265e111ed8SAndrew Rybchenko 	__out_bcount_part(key_max_size, *lengthp)
11275e111ed8SAndrew Rybchenko 				caddr_t keyp,
11285e111ed8SAndrew Rybchenko 	__in			size_t key_max_size,
11295e111ed8SAndrew Rybchenko 	__out			uint32_t *lengthp)
11305e111ed8SAndrew Rybchenko {
11315e111ed8SAndrew Rybchenko 	uint32_t tag;
11325e111ed8SAndrew Rybchenko 
11335e111ed8SAndrew Rybchenko 	_NOTE(ARGUNUSED(enp))
11345e111ed8SAndrew Rybchenko 
11355e111ed8SAndrew Rybchenko 	return ef10_nvram_buffer_get_item(bufferp, buffer_size,
11365e111ed8SAndrew Rybchenko 		    offset, length, &tag, keyp, key_max_size, lengthp);
11375e111ed8SAndrew Rybchenko }
11385e111ed8SAndrew Rybchenko 
11395e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
efx_lic_v3_write_key(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__in_bcount (length)caddr_t keyp,__in uint32_t length,__out uint32_t * lengthp)11405e111ed8SAndrew Rybchenko efx_lic_v3_write_key(
11415e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
11425e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
11435e111ed8SAndrew Rybchenko 				caddr_t bufferp,
11445e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
11455e111ed8SAndrew Rybchenko 	__in			uint32_t offset,
11465e111ed8SAndrew Rybchenko 	__in_bcount(length)	caddr_t keyp,
11475e111ed8SAndrew Rybchenko 	__in			uint32_t length,
11485e111ed8SAndrew Rybchenko 	__out			uint32_t *lengthp)
11495e111ed8SAndrew Rybchenko {
11505e111ed8SAndrew Rybchenko 	_NOTE(ARGUNUSED(enp))
11515e111ed8SAndrew Rybchenko 	EFSYS_ASSERT(length <= EFX_LICENSE_V3_KEY_LENGTH_MAX);
11525e111ed8SAndrew Rybchenko 
11535e111ed8SAndrew Rybchenko 	return ef10_nvram_buffer_insert_item(bufferp, buffer_size,
11545e111ed8SAndrew Rybchenko 		    offset, TLV_TAG_LICENSE, keyp, length, lengthp);
11555e111ed8SAndrew Rybchenko }
11565e111ed8SAndrew Rybchenko 
11575e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
efx_lic_v3_delete_key(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__in uint32_t length,__in uint32_t end,__out uint32_t * deltap)11585e111ed8SAndrew Rybchenko efx_lic_v3_delete_key(
11595e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
11605e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
11615e111ed8SAndrew Rybchenko 				caddr_t bufferp,
11625e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
11635e111ed8SAndrew Rybchenko 	__in			uint32_t offset,
11645e111ed8SAndrew Rybchenko 	__in			uint32_t length,
11655e111ed8SAndrew Rybchenko 	__in			uint32_t end,
11665e111ed8SAndrew Rybchenko 	__out			uint32_t *deltap)
11675e111ed8SAndrew Rybchenko {
11685e111ed8SAndrew Rybchenko 	efx_rc_t rc;
11695e111ed8SAndrew Rybchenko 
11705e111ed8SAndrew Rybchenko 	_NOTE(ARGUNUSED(enp))
11715e111ed8SAndrew Rybchenko 
11725e111ed8SAndrew Rybchenko 	if ((rc = ef10_nvram_buffer_delete_item(bufferp,
11735e111ed8SAndrew Rybchenko 			buffer_size, offset, length, end)) != 0) {
11745e111ed8SAndrew Rybchenko 		goto fail1;
11755e111ed8SAndrew Rybchenko 	}
11765e111ed8SAndrew Rybchenko 
11775e111ed8SAndrew Rybchenko 	*deltap = length;
11785e111ed8SAndrew Rybchenko 
11795e111ed8SAndrew Rybchenko 	return (0);
11805e111ed8SAndrew Rybchenko 
11815e111ed8SAndrew Rybchenko fail1:
11825e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
11835e111ed8SAndrew Rybchenko 
11845e111ed8SAndrew Rybchenko 	return (rc);
11855e111ed8SAndrew Rybchenko }
11865e111ed8SAndrew Rybchenko 
11875e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
efx_lic_v3_create_partition(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size)11885e111ed8SAndrew Rybchenko efx_lic_v3_create_partition(
11895e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
11905e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
11915e111ed8SAndrew Rybchenko 				caddr_t bufferp,
11925e111ed8SAndrew Rybchenko 	__in			size_t buffer_size)
11935e111ed8SAndrew Rybchenko {
11945e111ed8SAndrew Rybchenko 	efx_rc_t rc;
11955e111ed8SAndrew Rybchenko 
11965e111ed8SAndrew Rybchenko 	_NOTE(ARGUNUSED(enp))
11975e111ed8SAndrew Rybchenko 
11985e111ed8SAndrew Rybchenko 	/* Construct empty partition */
11995e111ed8SAndrew Rybchenko 	if ((rc = ef10_nvram_buffer_create(
12005e111ed8SAndrew Rybchenko 	    NVRAM_PARTITION_TYPE_LICENSE,
12015e111ed8SAndrew Rybchenko 	    bufferp, buffer_size)) != 0) {
12025e111ed8SAndrew Rybchenko 		rc = EFAULT;
12035e111ed8SAndrew Rybchenko 		goto fail1;
12045e111ed8SAndrew Rybchenko 	}
12055e111ed8SAndrew Rybchenko 
12065e111ed8SAndrew Rybchenko 	return (0);
12075e111ed8SAndrew Rybchenko 
12085e111ed8SAndrew Rybchenko fail1:
12095e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
12105e111ed8SAndrew Rybchenko 
12115e111ed8SAndrew Rybchenko 	return (rc);
12125e111ed8SAndrew Rybchenko }
12135e111ed8SAndrew Rybchenko 
12145e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
efx_lic_v3_finish_partition(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size)12155e111ed8SAndrew Rybchenko efx_lic_v3_finish_partition(
12165e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
12175e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
12185e111ed8SAndrew Rybchenko 				caddr_t bufferp,
12195e111ed8SAndrew Rybchenko 	__in			size_t buffer_size)
12205e111ed8SAndrew Rybchenko {
12215e111ed8SAndrew Rybchenko 	efx_rc_t rc;
12225e111ed8SAndrew Rybchenko 
12235e111ed8SAndrew Rybchenko 	_NOTE(ARGUNUSED(enp))
12245e111ed8SAndrew Rybchenko 
12255e111ed8SAndrew Rybchenko 	if ((rc = ef10_nvram_buffer_finish(bufferp,
12265e111ed8SAndrew Rybchenko 			buffer_size)) != 0) {
12275e111ed8SAndrew Rybchenko 		goto fail1;
12285e111ed8SAndrew Rybchenko 	}
12295e111ed8SAndrew Rybchenko 
12305e111ed8SAndrew Rybchenko 	/* Validate completed partition */
12315e111ed8SAndrew Rybchenko 	if ((rc = ef10_nvram_buffer_validate(
12325e111ed8SAndrew Rybchenko 					NVRAM_PARTITION_TYPE_LICENSE,
12335e111ed8SAndrew Rybchenko 					bufferp, buffer_size)) != 0) {
12345e111ed8SAndrew Rybchenko 		goto fail2;
12355e111ed8SAndrew Rybchenko 	}
12365e111ed8SAndrew Rybchenko 
12375e111ed8SAndrew Rybchenko 	return (0);
12385e111ed8SAndrew Rybchenko 
12395e111ed8SAndrew Rybchenko fail2:
12405e111ed8SAndrew Rybchenko 	EFSYS_PROBE(fail2);
12415e111ed8SAndrew Rybchenko fail1:
12425e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
12435e111ed8SAndrew Rybchenko 
12445e111ed8SAndrew Rybchenko 	return (rc);
12455e111ed8SAndrew Rybchenko }
12465e111ed8SAndrew Rybchenko 
12475e111ed8SAndrew Rybchenko 
12485e111ed8SAndrew Rybchenko #endif	/* EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
12495e111ed8SAndrew Rybchenko 
12505e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
efx_lic_init(__in efx_nic_t * enp)12515e111ed8SAndrew Rybchenko efx_lic_init(
12525e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp)
12535e111ed8SAndrew Rybchenko {
12545e111ed8SAndrew Rybchenko 	const efx_lic_ops_t *elop;
12555e111ed8SAndrew Rybchenko 	efx_key_stats_t eks;
12565e111ed8SAndrew Rybchenko 	efx_rc_t rc;
12575e111ed8SAndrew Rybchenko 
12585e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
12595e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
12605e111ed8SAndrew Rybchenko 	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_LIC));
12615e111ed8SAndrew Rybchenko 
12625e111ed8SAndrew Rybchenko 	switch (enp->en_family) {
12635e111ed8SAndrew Rybchenko 
12645e111ed8SAndrew Rybchenko #if EFSYS_OPT_SIENA
12655e111ed8SAndrew Rybchenko 	case EFX_FAMILY_SIENA:
12665e111ed8SAndrew Rybchenko 		elop = &__efx_lic_v1_ops;
12675e111ed8SAndrew Rybchenko 		break;
12685e111ed8SAndrew Rybchenko #endif	/* EFSYS_OPT_SIENA */
12695e111ed8SAndrew Rybchenko 
12705e111ed8SAndrew Rybchenko #if EFSYS_OPT_HUNTINGTON
12715e111ed8SAndrew Rybchenko 	case EFX_FAMILY_HUNTINGTON:
12725e111ed8SAndrew Rybchenko 		elop = &__efx_lic_v2_ops;
12735e111ed8SAndrew Rybchenko 		break;
12745e111ed8SAndrew Rybchenko #endif	/* EFSYS_OPT_HUNTINGTON */
12755e111ed8SAndrew Rybchenko 
12765e111ed8SAndrew Rybchenko #if EFSYS_OPT_MEDFORD
12775e111ed8SAndrew Rybchenko 	case EFX_FAMILY_MEDFORD:
12785e111ed8SAndrew Rybchenko 		elop = &__efx_lic_v3_ops;
12795e111ed8SAndrew Rybchenko 		break;
12805e111ed8SAndrew Rybchenko #endif	/* EFSYS_OPT_MEDFORD */
12815e111ed8SAndrew Rybchenko 
12825e111ed8SAndrew Rybchenko #if EFSYS_OPT_MEDFORD2
12835e111ed8SAndrew Rybchenko 	case EFX_FAMILY_MEDFORD2:
12845e111ed8SAndrew Rybchenko 		elop = &__efx_lic_v3_ops;
12855e111ed8SAndrew Rybchenko 		break;
12865e111ed8SAndrew Rybchenko #endif	/* EFSYS_OPT_MEDFORD2 */
12875e111ed8SAndrew Rybchenko 
12885e111ed8SAndrew Rybchenko 	default:
12895e111ed8SAndrew Rybchenko 		EFSYS_ASSERT(0);
12905e111ed8SAndrew Rybchenko 		rc = ENOTSUP;
12915e111ed8SAndrew Rybchenko 		goto fail1;
12925e111ed8SAndrew Rybchenko 	}
12935e111ed8SAndrew Rybchenko 
12945e111ed8SAndrew Rybchenko 	enp->en_elop = elop;
12955e111ed8SAndrew Rybchenko 	enp->en_mod_flags |= EFX_MOD_LIC;
12965e111ed8SAndrew Rybchenko 
12975e111ed8SAndrew Rybchenko 	/* Probe for support */
12985e111ed8SAndrew Rybchenko 	if (efx_lic_get_key_stats(enp, &eks) == 0) {
12995e111ed8SAndrew Rybchenko 		enp->en_licensing_supported = B_TRUE;
13005e111ed8SAndrew Rybchenko 	} else {
13015e111ed8SAndrew Rybchenko 		enp->en_licensing_supported = B_FALSE;
13025e111ed8SAndrew Rybchenko 	}
13035e111ed8SAndrew Rybchenko 
13045e111ed8SAndrew Rybchenko 	return (0);
13055e111ed8SAndrew Rybchenko 
13065e111ed8SAndrew Rybchenko fail1:
13075e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
13085e111ed8SAndrew Rybchenko 
13095e111ed8SAndrew Rybchenko 	return (rc);
13105e111ed8SAndrew Rybchenko }
13115e111ed8SAndrew Rybchenko 
13125e111ed8SAndrew Rybchenko extern	__checkReturn	boolean_t
efx_lic_check_support(__in efx_nic_t * enp)13135e111ed8SAndrew Rybchenko efx_lic_check_support(
13145e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp)
13155e111ed8SAndrew Rybchenko {
13165e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
13175e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
13185e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
13195e111ed8SAndrew Rybchenko 
13205e111ed8SAndrew Rybchenko 	return (enp->en_licensing_supported);
13215e111ed8SAndrew Rybchenko }
13225e111ed8SAndrew Rybchenko 
13235e111ed8SAndrew Rybchenko 				void
efx_lic_fini(__in efx_nic_t * enp)13245e111ed8SAndrew Rybchenko efx_lic_fini(
13255e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp)
13265e111ed8SAndrew Rybchenko {
13275e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
13285e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
13295e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
13305e111ed8SAndrew Rybchenko 
13315e111ed8SAndrew Rybchenko 	enp->en_elop = NULL;
13325e111ed8SAndrew Rybchenko 	enp->en_mod_flags &= ~EFX_MOD_LIC;
13335e111ed8SAndrew Rybchenko }
13345e111ed8SAndrew Rybchenko 
13355e111ed8SAndrew Rybchenko 
13365e111ed8SAndrew Rybchenko 	__checkReturn	efx_rc_t
efx_lic_update_licenses(__in efx_nic_t * enp)13375e111ed8SAndrew Rybchenko efx_lic_update_licenses(
13385e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp)
13395e111ed8SAndrew Rybchenko {
13405e111ed8SAndrew Rybchenko 	const efx_lic_ops_t *elop = enp->en_elop;
13415e111ed8SAndrew Rybchenko 	efx_rc_t rc;
13425e111ed8SAndrew Rybchenko 
13435e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
13445e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
13455e111ed8SAndrew Rybchenko 
13465e111ed8SAndrew Rybchenko 	if ((rc = elop->elo_update_licenses(enp)) != 0)
13475e111ed8SAndrew Rybchenko 		goto fail1;
13485e111ed8SAndrew Rybchenko 
13495e111ed8SAndrew Rybchenko 	return (0);
13505e111ed8SAndrew Rybchenko 
13515e111ed8SAndrew Rybchenko fail1:
13525e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
13535e111ed8SAndrew Rybchenko 
13545e111ed8SAndrew Rybchenko 	return (rc);
13555e111ed8SAndrew Rybchenko }
13565e111ed8SAndrew Rybchenko 
13575e111ed8SAndrew Rybchenko 	__checkReturn	efx_rc_t
efx_lic_get_key_stats(__in efx_nic_t * enp,__out efx_key_stats_t * eksp)13585e111ed8SAndrew Rybchenko efx_lic_get_key_stats(
13595e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp,
13605e111ed8SAndrew Rybchenko 	__out		efx_key_stats_t *eksp)
13615e111ed8SAndrew Rybchenko {
13625e111ed8SAndrew Rybchenko 	const efx_lic_ops_t *elop = enp->en_elop;
13635e111ed8SAndrew Rybchenko 	efx_rc_t rc;
13645e111ed8SAndrew Rybchenko 
13655e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
13665e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
13675e111ed8SAndrew Rybchenko 
13685e111ed8SAndrew Rybchenko 	if ((rc = elop->elo_get_key_stats(enp, eksp)) != 0)
13695e111ed8SAndrew Rybchenko 		goto fail1;
13705e111ed8SAndrew Rybchenko 
13715e111ed8SAndrew Rybchenko 	return (0);
13725e111ed8SAndrew Rybchenko 
13735e111ed8SAndrew Rybchenko fail1:
13745e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
13755e111ed8SAndrew Rybchenko 
13765e111ed8SAndrew Rybchenko 	return (rc);
13775e111ed8SAndrew Rybchenko }
13785e111ed8SAndrew Rybchenko 
13795e111ed8SAndrew Rybchenko 	__checkReturn	efx_rc_t
efx_lic_app_state(__in efx_nic_t * enp,__in uint64_t app_id,__out boolean_t * licensedp)13805e111ed8SAndrew Rybchenko efx_lic_app_state(
13815e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp,
13825e111ed8SAndrew Rybchenko 	__in		uint64_t app_id,
13835e111ed8SAndrew Rybchenko 	__out		boolean_t *licensedp)
13845e111ed8SAndrew Rybchenko {
13855e111ed8SAndrew Rybchenko 	const efx_lic_ops_t *elop = enp->en_elop;
13865e111ed8SAndrew Rybchenko 	efx_rc_t rc;
13875e111ed8SAndrew Rybchenko 
13885e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
13895e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
13905e111ed8SAndrew Rybchenko 
13915e111ed8SAndrew Rybchenko 	if (elop->elo_app_state == NULL)
13925e111ed8SAndrew Rybchenko 		return (ENOTSUP);
13935e111ed8SAndrew Rybchenko 
13945e111ed8SAndrew Rybchenko 	if ((rc = elop->elo_app_state(enp, app_id, licensedp)) != 0)
13955e111ed8SAndrew Rybchenko 		goto fail1;
13965e111ed8SAndrew Rybchenko 
13975e111ed8SAndrew Rybchenko 	return (0);
13985e111ed8SAndrew Rybchenko 
13995e111ed8SAndrew Rybchenko fail1:
14005e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
14015e111ed8SAndrew Rybchenko 
14025e111ed8SAndrew Rybchenko 	return (rc);
14035e111ed8SAndrew Rybchenko }
14045e111ed8SAndrew Rybchenko 
14055e111ed8SAndrew Rybchenko 	__checkReturn	efx_rc_t
efx_lic_get_id(__in efx_nic_t * enp,__in size_t buffer_size,__out uint32_t * typep,__out size_t * lengthp,__out_opt uint8_t * bufferp)14065e111ed8SAndrew Rybchenko efx_lic_get_id(
14075e111ed8SAndrew Rybchenko 	__in		efx_nic_t *enp,
14085e111ed8SAndrew Rybchenko 	__in		size_t buffer_size,
14095e111ed8SAndrew Rybchenko 	__out		uint32_t *typep,
14105e111ed8SAndrew Rybchenko 	__out		size_t *lengthp,
14115e111ed8SAndrew Rybchenko 	__out_opt	uint8_t *bufferp)
14125e111ed8SAndrew Rybchenko {
14135e111ed8SAndrew Rybchenko 	const efx_lic_ops_t *elop = enp->en_elop;
14145e111ed8SAndrew Rybchenko 	efx_rc_t rc;
14155e111ed8SAndrew Rybchenko 
14165e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
14175e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
14185e111ed8SAndrew Rybchenko 
14195e111ed8SAndrew Rybchenko 	if (elop->elo_get_id == NULL)
14205e111ed8SAndrew Rybchenko 		return (ENOTSUP);
14215e111ed8SAndrew Rybchenko 
14225e111ed8SAndrew Rybchenko 	if ((rc = elop->elo_get_id(enp, buffer_size, typep,
14235e111ed8SAndrew Rybchenko 				    lengthp, bufferp)) != 0)
14245e111ed8SAndrew Rybchenko 		goto fail1;
14255e111ed8SAndrew Rybchenko 
14265e111ed8SAndrew Rybchenko 	return (0);
14275e111ed8SAndrew Rybchenko 
14285e111ed8SAndrew Rybchenko fail1:
14295e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
14305e111ed8SAndrew Rybchenko 
14315e111ed8SAndrew Rybchenko 	return (rc);
14325e111ed8SAndrew Rybchenko }
14335e111ed8SAndrew Rybchenko 
14345e111ed8SAndrew Rybchenko /*
14355e111ed8SAndrew Rybchenko  * Buffer management API - abstracts varying TLV format used for License
14365e111ed8SAndrew Rybchenko  * partition.
14375e111ed8SAndrew Rybchenko  */
14385e111ed8SAndrew Rybchenko 
14395e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
efx_lic_find_start(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__out uint32_t * startp)14405e111ed8SAndrew Rybchenko efx_lic_find_start(
14415e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
14425e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
14435e111ed8SAndrew Rybchenko 				caddr_t bufferp,
14445e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
14455e111ed8SAndrew Rybchenko 	__out			uint32_t *startp)
14465e111ed8SAndrew Rybchenko {
14475e111ed8SAndrew Rybchenko 	const efx_lic_ops_t *elop = enp->en_elop;
14485e111ed8SAndrew Rybchenko 	efx_rc_t rc;
14495e111ed8SAndrew Rybchenko 
14505e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
14515e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
14525e111ed8SAndrew Rybchenko 
14535e111ed8SAndrew Rybchenko 	if ((rc = elop->elo_find_start(enp, bufferp, buffer_size, startp)) != 0)
14545e111ed8SAndrew Rybchenko 		goto fail1;
14555e111ed8SAndrew Rybchenko 
14565e111ed8SAndrew Rybchenko 	return (0);
14575e111ed8SAndrew Rybchenko 
14585e111ed8SAndrew Rybchenko fail1:
14595e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
14605e111ed8SAndrew Rybchenko 
14615e111ed8SAndrew Rybchenko 	return (rc);
14625e111ed8SAndrew Rybchenko }
14635e111ed8SAndrew Rybchenko 
14645e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
efx_lic_find_end(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__out uint32_t * endp)14655e111ed8SAndrew Rybchenko efx_lic_find_end(
14665e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
14675e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
14685e111ed8SAndrew Rybchenko 				caddr_t bufferp,
14695e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
14705e111ed8SAndrew Rybchenko 	__in			uint32_t offset,
14715e111ed8SAndrew Rybchenko 	__out			uint32_t *endp)
14725e111ed8SAndrew Rybchenko {
14735e111ed8SAndrew Rybchenko 	const efx_lic_ops_t *elop = enp->en_elop;
14745e111ed8SAndrew Rybchenko 	efx_rc_t rc;
14755e111ed8SAndrew Rybchenko 
14765e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
14775e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
14785e111ed8SAndrew Rybchenko 
14795e111ed8SAndrew Rybchenko 	rc = elop->elo_find_end(enp, bufferp, buffer_size, offset, endp);
14805e111ed8SAndrew Rybchenko 	if (rc != 0)
14815e111ed8SAndrew Rybchenko 		goto fail1;
14825e111ed8SAndrew Rybchenko 
14835e111ed8SAndrew Rybchenko 	return (0);
14845e111ed8SAndrew Rybchenko 
14855e111ed8SAndrew Rybchenko fail1:
14865e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
14875e111ed8SAndrew Rybchenko 
14885e111ed8SAndrew Rybchenko 	return (rc);
14895e111ed8SAndrew Rybchenko }
14905e111ed8SAndrew Rybchenko 
14915e111ed8SAndrew Rybchenko 	__checkReturn	__success(return != B_FALSE)	boolean_t
efx_lic_find_key(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__out uint32_t * startp,__out uint32_t * lengthp)14925e111ed8SAndrew Rybchenko efx_lic_find_key(
14935e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
14945e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
14955e111ed8SAndrew Rybchenko 				caddr_t bufferp,
14965e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
14975e111ed8SAndrew Rybchenko 	__in			uint32_t offset,
14985e111ed8SAndrew Rybchenko 	__out			uint32_t *startp,
14995e111ed8SAndrew Rybchenko 	__out			uint32_t *lengthp)
15005e111ed8SAndrew Rybchenko {
15015e111ed8SAndrew Rybchenko 	const efx_lic_ops_t *elop = enp->en_elop;
15025e111ed8SAndrew Rybchenko 
15035e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
15045e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
15055e111ed8SAndrew Rybchenko 
15065e111ed8SAndrew Rybchenko 	EFSYS_ASSERT(bufferp);
15075e111ed8SAndrew Rybchenko 	EFSYS_ASSERT(startp);
15085e111ed8SAndrew Rybchenko 	EFSYS_ASSERT(lengthp);
15095e111ed8SAndrew Rybchenko 
15105e111ed8SAndrew Rybchenko 	return (elop->elo_find_key(enp, bufferp, buffer_size, offset,
15115e111ed8SAndrew Rybchenko 				    startp, lengthp));
15125e111ed8SAndrew Rybchenko }
15135e111ed8SAndrew Rybchenko 
15145e111ed8SAndrew Rybchenko 
15155e111ed8SAndrew Rybchenko /*
15165e111ed8SAndrew Rybchenko  * Validate that the buffer contains a single key in a recognised format.
15175e111ed8SAndrew Rybchenko  * An empty or terminator buffer is not accepted as a valid key.
15185e111ed8SAndrew Rybchenko  */
15195e111ed8SAndrew Rybchenko 	__checkReturn	__success(return != B_FALSE)	boolean_t
efx_lic_validate_key(__in efx_nic_t * enp,__in_bcount (length)caddr_t keyp,__in uint32_t length)15205e111ed8SAndrew Rybchenko efx_lic_validate_key(
15215e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
15225e111ed8SAndrew Rybchenko 	__in_bcount(length)	caddr_t keyp,
15235e111ed8SAndrew Rybchenko 	__in			uint32_t length)
15245e111ed8SAndrew Rybchenko {
15255e111ed8SAndrew Rybchenko 	const efx_lic_ops_t *elop = enp->en_elop;
15265e111ed8SAndrew Rybchenko 	boolean_t rc;
15275e111ed8SAndrew Rybchenko 
15285e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
15295e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
15305e111ed8SAndrew Rybchenko 
15315e111ed8SAndrew Rybchenko 	if ((rc = elop->elo_validate_key(enp, keyp, length)) == B_FALSE)
15325e111ed8SAndrew Rybchenko 		goto fail1;
15335e111ed8SAndrew Rybchenko 
15345e111ed8SAndrew Rybchenko 	return (B_TRUE);
15355e111ed8SAndrew Rybchenko 
15365e111ed8SAndrew Rybchenko fail1:
15375e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
15385e111ed8SAndrew Rybchenko 
15395e111ed8SAndrew Rybchenko 	return (rc);
15405e111ed8SAndrew Rybchenko }
15415e111ed8SAndrew Rybchenko 
15425e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
efx_lic_read_key(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__in uint32_t length,__out_bcount_part (key_max_size,* lengthp)caddr_t keyp,__in size_t key_max_size,__out uint32_t * lengthp)15435e111ed8SAndrew Rybchenko efx_lic_read_key(
15445e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
15455e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
15465e111ed8SAndrew Rybchenko 				caddr_t bufferp,
15475e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
15485e111ed8SAndrew Rybchenko 	__in			uint32_t offset,
15495e111ed8SAndrew Rybchenko 	__in			uint32_t length,
15505e111ed8SAndrew Rybchenko 	__out_bcount_part(key_max_size, *lengthp)
15515e111ed8SAndrew Rybchenko 				caddr_t keyp,
15525e111ed8SAndrew Rybchenko 	__in			size_t key_max_size,
15535e111ed8SAndrew Rybchenko 	__out			uint32_t *lengthp)
15545e111ed8SAndrew Rybchenko {
15555e111ed8SAndrew Rybchenko 	const efx_lic_ops_t *elop = enp->en_elop;
15565e111ed8SAndrew Rybchenko 	efx_rc_t rc;
15575e111ed8SAndrew Rybchenko 
15585e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
15595e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
15605e111ed8SAndrew Rybchenko 
15615e111ed8SAndrew Rybchenko 	if ((rc = elop->elo_read_key(enp, bufferp, buffer_size, offset,
15625e111ed8SAndrew Rybchenko 				    length, keyp, key_max_size, lengthp)) != 0)
15635e111ed8SAndrew Rybchenko 		goto fail1;
15645e111ed8SAndrew Rybchenko 
15655e111ed8SAndrew Rybchenko 	return (0);
15665e111ed8SAndrew Rybchenko 
15675e111ed8SAndrew Rybchenko fail1:
15685e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
15695e111ed8SAndrew Rybchenko 
15705e111ed8SAndrew Rybchenko 	return (rc);
15715e111ed8SAndrew Rybchenko }
15725e111ed8SAndrew Rybchenko 
15735e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
efx_lic_write_key(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__in_bcount (length)caddr_t keyp,__in uint32_t length,__out uint32_t * lengthp)15745e111ed8SAndrew Rybchenko efx_lic_write_key(
15755e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
15765e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
15775e111ed8SAndrew Rybchenko 				caddr_t bufferp,
15785e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
15795e111ed8SAndrew Rybchenko 	__in			uint32_t offset,
15805e111ed8SAndrew Rybchenko 	__in_bcount(length)	caddr_t keyp,
15815e111ed8SAndrew Rybchenko 	__in			uint32_t length,
15825e111ed8SAndrew Rybchenko 	__out			uint32_t *lengthp)
15835e111ed8SAndrew Rybchenko {
15845e111ed8SAndrew Rybchenko 	const efx_lic_ops_t *elop = enp->en_elop;
15855e111ed8SAndrew Rybchenko 	efx_rc_t rc;
15865e111ed8SAndrew Rybchenko 
15875e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
15885e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
15895e111ed8SAndrew Rybchenko 
15905e111ed8SAndrew Rybchenko 	if ((rc = elop->elo_write_key(enp, bufferp, buffer_size, offset,
15915e111ed8SAndrew Rybchenko 				    keyp, length, lengthp)) != 0)
15925e111ed8SAndrew Rybchenko 		goto fail1;
15935e111ed8SAndrew Rybchenko 
15945e111ed8SAndrew Rybchenko 	return (0);
15955e111ed8SAndrew Rybchenko 
15965e111ed8SAndrew Rybchenko fail1:
15975e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
15985e111ed8SAndrew Rybchenko 
15995e111ed8SAndrew Rybchenko 	return (rc);
16005e111ed8SAndrew Rybchenko }
16015e111ed8SAndrew Rybchenko 
16025e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
efx_lic_delete_key(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size,__in uint32_t offset,__in uint32_t length,__in uint32_t end,__out uint32_t * deltap)16035e111ed8SAndrew Rybchenko efx_lic_delete_key(
16045e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
16055e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
16065e111ed8SAndrew Rybchenko 				caddr_t bufferp,
16075e111ed8SAndrew Rybchenko 	__in			size_t buffer_size,
16085e111ed8SAndrew Rybchenko 	__in			uint32_t offset,
16095e111ed8SAndrew Rybchenko 	__in			uint32_t length,
16105e111ed8SAndrew Rybchenko 	__in			uint32_t end,
16115e111ed8SAndrew Rybchenko 	__out			uint32_t *deltap)
16125e111ed8SAndrew Rybchenko {
16135e111ed8SAndrew Rybchenko 	const efx_lic_ops_t *elop = enp->en_elop;
16145e111ed8SAndrew Rybchenko 	efx_rc_t rc;
16155e111ed8SAndrew Rybchenko 
16165e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
16175e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
16185e111ed8SAndrew Rybchenko 
16195e111ed8SAndrew Rybchenko 	if ((rc = elop->elo_delete_key(enp, bufferp, buffer_size, offset,
16205e111ed8SAndrew Rybchenko 				    length, end, deltap)) != 0)
16215e111ed8SAndrew Rybchenko 		goto fail1;
16225e111ed8SAndrew Rybchenko 
16235e111ed8SAndrew Rybchenko 	return (0);
16245e111ed8SAndrew Rybchenko 
16255e111ed8SAndrew Rybchenko fail1:
16265e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
16275e111ed8SAndrew Rybchenko 
16285e111ed8SAndrew Rybchenko 	return (rc);
16295e111ed8SAndrew Rybchenko }
16305e111ed8SAndrew Rybchenko 
16315e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
efx_lic_create_partition(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size)16325e111ed8SAndrew Rybchenko efx_lic_create_partition(
16335e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
16345e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
16355e111ed8SAndrew Rybchenko 				caddr_t bufferp,
16365e111ed8SAndrew Rybchenko 	__in			size_t buffer_size)
16375e111ed8SAndrew Rybchenko {
16385e111ed8SAndrew Rybchenko 	const efx_lic_ops_t *elop = enp->en_elop;
16395e111ed8SAndrew Rybchenko 	efx_rc_t rc;
16405e111ed8SAndrew Rybchenko 
16415e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
16425e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
16435e111ed8SAndrew Rybchenko 
16445e111ed8SAndrew Rybchenko 	if ((rc = elop->elo_create_partition(enp, bufferp, buffer_size)) != 0)
16455e111ed8SAndrew Rybchenko 		goto fail1;
16465e111ed8SAndrew Rybchenko 
16475e111ed8SAndrew Rybchenko 	return (0);
16485e111ed8SAndrew Rybchenko 
16495e111ed8SAndrew Rybchenko fail1:
16505e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
16515e111ed8SAndrew Rybchenko 
16525e111ed8SAndrew Rybchenko 	return (rc);
16535e111ed8SAndrew Rybchenko }
16545e111ed8SAndrew Rybchenko 
16555e111ed8SAndrew Rybchenko 
16565e111ed8SAndrew Rybchenko 	__checkReturn		efx_rc_t
efx_lic_finish_partition(__in efx_nic_t * enp,__in_bcount (buffer_size)caddr_t bufferp,__in size_t buffer_size)16575e111ed8SAndrew Rybchenko efx_lic_finish_partition(
16585e111ed8SAndrew Rybchenko 	__in			efx_nic_t *enp,
16595e111ed8SAndrew Rybchenko 	__in_bcount(buffer_size)
16605e111ed8SAndrew Rybchenko 				caddr_t bufferp,
16615e111ed8SAndrew Rybchenko 	__in			size_t buffer_size)
16625e111ed8SAndrew Rybchenko {
16635e111ed8SAndrew Rybchenko 	const efx_lic_ops_t *elop = enp->en_elop;
16645e111ed8SAndrew Rybchenko 	efx_rc_t rc;
16655e111ed8SAndrew Rybchenko 
16665e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
16675e111ed8SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
16685e111ed8SAndrew Rybchenko 
16695e111ed8SAndrew Rybchenko 	if ((rc = elop->elo_finish_partition(enp, bufferp, buffer_size)) != 0)
16705e111ed8SAndrew Rybchenko 		goto fail1;
16715e111ed8SAndrew Rybchenko 
16725e111ed8SAndrew Rybchenko 	return (0);
16735e111ed8SAndrew Rybchenko 
16745e111ed8SAndrew Rybchenko fail1:
16755e111ed8SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
16765e111ed8SAndrew Rybchenko 
16775e111ed8SAndrew Rybchenko 	return (rc);
16785e111ed8SAndrew Rybchenko }
16795e111ed8SAndrew Rybchenko 
16805e111ed8SAndrew Rybchenko #endif	/* EFSYS_OPT_LICENSING */
1681