1293901Sarybchik/*- 2301388Sarybchik * Copyright (c) 2009-2016 Solarflare Communications Inc. 3293901Sarybchik * All rights reserved. 4293901Sarybchik * 5293901Sarybchik * Redistribution and use in source and binary forms, with or without 6293901Sarybchik * modification, are permitted provided that the following conditions are met: 7293901Sarybchik * 8293901Sarybchik * 1. Redistributions of source code must retain the above copyright notice, 9293901Sarybchik * this list of conditions and the following disclaimer. 10293901Sarybchik * 2. Redistributions in binary form must reproduce the above copyright notice, 11293901Sarybchik * this list of conditions and the following disclaimer in the documentation 12293901Sarybchik * and/or other materials provided with the distribution. 13293901Sarybchik * 14293901Sarybchik * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15293901Sarybchik * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 16293901Sarybchik * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17293901Sarybchik * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 18293901Sarybchik * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19293901Sarybchik * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20293901Sarybchik * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21293901Sarybchik * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22293901Sarybchik * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23293901Sarybchik * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 24293901Sarybchik * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25293901Sarybchik * 26293901Sarybchik * The views and conclusions contained in the software and documentation are 27293901Sarybchik * those of the authors and should not be interpreted as representing official 28293901Sarybchik * policies, either expressed or implied, of the FreeBSD Project. 29293901Sarybchik */ 30293901Sarybchik 31293901Sarybchik#include <sys/cdefs.h> 32293901Sarybchik__FBSDID("$FreeBSD: stable/10/sys/dev/sfxge/common/efx_lic.c 342516 2018-12-26 10:25:01Z arybchik $"); 33293901Sarybchik 34293901Sarybchik#include "efx.h" 35293901Sarybchik#include "efx_impl.h" 36293901Sarybchik 37293901Sarybchik#if EFSYS_OPT_LICENSING 38293901Sarybchik 39301361Sarybchik#include "ef10_tlv_layout.h" 40301361Sarybchik 41301361Sarybchik#if EFSYS_OPT_SIENA | EFSYS_OPT_HUNTINGTON 42301361Sarybchik 43301361Sarybchik __checkReturn efx_rc_t 44301361Sarybchikefx_lic_v1v2_find_start( 45301361Sarybchik __in efx_nic_t *enp, 46301361Sarybchik __in_bcount(buffer_size) 47301361Sarybchik caddr_t bufferp, 48301361Sarybchik __in size_t buffer_size, 49301361Sarybchik __out uint32_t *startp 50301361Sarybchik ); 51301361Sarybchik 52301361Sarybchik __checkReturn efx_rc_t 53301361Sarybchikefx_lic_v1v2_find_end( 54301361Sarybchik __in efx_nic_t *enp, 55301361Sarybchik __in_bcount(buffer_size) 56301361Sarybchik caddr_t bufferp, 57301361Sarybchik __in size_t buffer_size, 58301361Sarybchik __in uint32_t offset, 59301361Sarybchik __out uint32_t *endp 60301361Sarybchik ); 61301361Sarybchik 62301361Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 63301361Sarybchikefx_lic_v1v2_find_key( 64301361Sarybchik __in efx_nic_t *enp, 65301361Sarybchik __in_bcount(buffer_size) 66301361Sarybchik caddr_t bufferp, 67301361Sarybchik __in size_t buffer_size, 68301361Sarybchik __in uint32_t offset, 69301361Sarybchik __out uint32_t *startp, 70301361Sarybchik __out uint32_t *lengthp 71301361Sarybchik ); 72301361Sarybchik 73301361Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 74301361Sarybchikefx_lic_v1v2_validate_key( 75301361Sarybchik __in efx_nic_t *enp, 76301361Sarybchik __in_bcount(length) caddr_t keyp, 77301361Sarybchik __in uint32_t length 78301361Sarybchik ); 79301361Sarybchik 80301361Sarybchik __checkReturn efx_rc_t 81301361Sarybchikefx_lic_v1v2_read_key( 82301361Sarybchik __in efx_nic_t *enp, 83301361Sarybchik __in_bcount(buffer_size) 84301361Sarybchik caddr_t bufferp, 85301361Sarybchik __in size_t buffer_size, 86301361Sarybchik __in uint32_t offset, 87301361Sarybchik __in uint32_t length, 88301361Sarybchik __out_bcount_part(key_max_size, *lengthp) 89301361Sarybchik caddr_t keyp, 90301361Sarybchik __in size_t key_max_size, 91301361Sarybchik __out uint32_t *lengthp 92301361Sarybchik ); 93301361Sarybchik 94301361Sarybchik __checkReturn efx_rc_t 95301361Sarybchikefx_lic_v1v2_write_key( 96301361Sarybchik __in efx_nic_t *enp, 97301361Sarybchik __in_bcount(buffer_size) 98301361Sarybchik caddr_t bufferp, 99301361Sarybchik __in size_t buffer_size, 100301361Sarybchik __in uint32_t offset, 101301361Sarybchik __in_bcount(length) caddr_t keyp, 102301361Sarybchik __in uint32_t length, 103301361Sarybchik __out uint32_t *lengthp 104301361Sarybchik ); 105301361Sarybchik 106301361Sarybchik __checkReturn efx_rc_t 107301361Sarybchikefx_lic_v1v2_delete_key( 108301361Sarybchik __in efx_nic_t *enp, 109301361Sarybchik __in_bcount(buffer_size) 110301361Sarybchik caddr_t bufferp, 111301361Sarybchik __in size_t buffer_size, 112301361Sarybchik __in uint32_t offset, 113301361Sarybchik __in uint32_t length, 114301361Sarybchik __in uint32_t end, 115301361Sarybchik __out uint32_t *deltap 116301361Sarybchik ); 117301361Sarybchik 118301361Sarybchik __checkReturn efx_rc_t 119301361Sarybchikefx_lic_v1v2_create_partition( 120301361Sarybchik __in efx_nic_t *enp, 121301361Sarybchik __in_bcount(buffer_size) 122301361Sarybchik caddr_t bufferp, 123301361Sarybchik __in size_t buffer_size 124301361Sarybchik ); 125301361Sarybchik 126301361Sarybchik __checkReturn efx_rc_t 127301361Sarybchikefx_lic_v1v2_finish_partition( 128301361Sarybchik __in efx_nic_t *enp, 129301361Sarybchik __in_bcount(buffer_size) 130301361Sarybchik caddr_t bufferp, 131301361Sarybchik __in size_t buffer_size 132301361Sarybchik ); 133301361Sarybchik 134301361Sarybchik#endif /* EFSYS_OPT_HUNTINGTON | EFSYS_OPT_SIENA */ 135301361Sarybchik 136301361Sarybchik 137293901Sarybchik#if EFSYS_OPT_SIENA 138293901Sarybchik 139293901Sarybchikstatic __checkReturn efx_rc_t 140293901Sarybchikefx_mcdi_fc_license_update_license( 141293901Sarybchik __in efx_nic_t *enp); 142293901Sarybchik 143293901Sarybchikstatic __checkReturn efx_rc_t 144293901Sarybchikefx_mcdi_fc_license_get_key_stats( 145293901Sarybchik __in efx_nic_t *enp, 146293901Sarybchik __out efx_key_stats_t *eksp); 147293901Sarybchik 148301340Sarybchikstatic const efx_lic_ops_t __efx_lic_v1_ops = { 149293901Sarybchik efx_mcdi_fc_license_update_license, /* elo_update_licenses */ 150293901Sarybchik efx_mcdi_fc_license_get_key_stats, /* elo_get_key_stats */ 151293901Sarybchik NULL, /* elo_app_state */ 152293901Sarybchik NULL, /* elo_get_id */ 153301361Sarybchik efx_lic_v1v2_find_start, /* elo_find_start */ 154301361Sarybchik efx_lic_v1v2_find_end, /* elo_find_end */ 155301361Sarybchik efx_lic_v1v2_find_key, /* elo_find_key */ 156301361Sarybchik efx_lic_v1v2_validate_key, /* elo_validate_key */ 157301361Sarybchik efx_lic_v1v2_read_key, /* elo_read_key */ 158301361Sarybchik efx_lic_v1v2_write_key, /* elo_write_key */ 159301361Sarybchik efx_lic_v1v2_delete_key, /* elo_delete_key */ 160301361Sarybchik efx_lic_v1v2_create_partition, /* elo_create_partition */ 161301361Sarybchik efx_lic_v1v2_finish_partition, /* elo_finish_partition */ 162293901Sarybchik}; 163293901Sarybchik 164293901Sarybchik#endif /* EFSYS_OPT_SIENA */ 165293901Sarybchik 166293901Sarybchik#if EFSYS_OPT_HUNTINGTON 167293901Sarybchik 168293901Sarybchikstatic __checkReturn efx_rc_t 169293901Sarybchikefx_mcdi_licensing_update_licenses( 170293901Sarybchik __in efx_nic_t *enp); 171293901Sarybchik 172293901Sarybchikstatic __checkReturn efx_rc_t 173293901Sarybchikefx_mcdi_licensing_get_key_stats( 174293901Sarybchik __in efx_nic_t *enp, 175293901Sarybchik __out efx_key_stats_t *eksp); 176293901Sarybchik 177293901Sarybchikstatic __checkReturn efx_rc_t 178293901Sarybchikefx_mcdi_licensed_app_state( 179293901Sarybchik __in efx_nic_t *enp, 180293901Sarybchik __in uint64_t app_id, 181293901Sarybchik __out boolean_t *licensedp); 182293901Sarybchik 183301340Sarybchikstatic const efx_lic_ops_t __efx_lic_v2_ops = { 184293901Sarybchik efx_mcdi_licensing_update_licenses, /* elo_update_licenses */ 185293901Sarybchik efx_mcdi_licensing_get_key_stats, /* elo_get_key_stats */ 186293901Sarybchik efx_mcdi_licensed_app_state, /* elo_app_state */ 187293901Sarybchik NULL, /* elo_get_id */ 188301361Sarybchik efx_lic_v1v2_find_start, /* elo_find_start */ 189301361Sarybchik efx_lic_v1v2_find_end, /* elo_find_end */ 190301361Sarybchik efx_lic_v1v2_find_key, /* elo_find_key */ 191301361Sarybchik efx_lic_v1v2_validate_key, /* elo_validate_key */ 192301361Sarybchik efx_lic_v1v2_read_key, /* elo_read_key */ 193301361Sarybchik efx_lic_v1v2_write_key, /* elo_write_key */ 194301361Sarybchik efx_lic_v1v2_delete_key, /* elo_delete_key */ 195301361Sarybchik efx_lic_v1v2_create_partition, /* elo_create_partition */ 196301361Sarybchik efx_lic_v1v2_finish_partition, /* elo_finish_partition */ 197293901Sarybchik}; 198293901Sarybchik 199293901Sarybchik#endif /* EFSYS_OPT_HUNTINGTON */ 200293901Sarybchik 201293901Sarybchik#if EFSYS_OPT_MEDFORD 202293901Sarybchik 203293901Sarybchikstatic __checkReturn efx_rc_t 204293901Sarybchikefx_mcdi_licensing_v3_update_licenses( 205293901Sarybchik __in efx_nic_t *enp); 206293901Sarybchik 207293901Sarybchikstatic __checkReturn efx_rc_t 208293901Sarybchikefx_mcdi_licensing_v3_report_license( 209293901Sarybchik __in efx_nic_t *enp, 210293901Sarybchik __out efx_key_stats_t *eksp); 211293901Sarybchik 212293901Sarybchikstatic __checkReturn efx_rc_t 213293901Sarybchikefx_mcdi_licensing_v3_app_state( 214293901Sarybchik __in efx_nic_t *enp, 215293901Sarybchik __in uint64_t app_id, 216293901Sarybchik __out boolean_t *licensedp); 217293901Sarybchik 218293901Sarybchikstatic __checkReturn efx_rc_t 219293901Sarybchikefx_mcdi_licensing_v3_get_id( 220293901Sarybchik __in efx_nic_t *enp, 221293901Sarybchik __in size_t buffer_size, 222293901Sarybchik __out uint32_t *typep, 223293901Sarybchik __out size_t *lengthp, 224293901Sarybchik __out_bcount_part_opt(buffer_size, *lengthp) 225293901Sarybchik uint8_t *bufferp); 226293901Sarybchik 227301361Sarybchik __checkReturn efx_rc_t 228301361Sarybchikefx_lic_v3_find_start( 229301361Sarybchik __in efx_nic_t *enp, 230301361Sarybchik __in_bcount(buffer_size) 231301361Sarybchik caddr_t bufferp, 232301361Sarybchik __in size_t buffer_size, 233301361Sarybchik __out uint32_t *startp 234301361Sarybchik ); 235301361Sarybchik 236301361Sarybchik __checkReturn efx_rc_t 237301361Sarybchikefx_lic_v3_find_end( 238301361Sarybchik __in efx_nic_t *enp, 239301361Sarybchik __in_bcount(buffer_size) 240301361Sarybchik caddr_t bufferp, 241301361Sarybchik __in size_t buffer_size, 242301361Sarybchik __in uint32_t offset, 243301361Sarybchik __out uint32_t *endp 244301361Sarybchik ); 245301361Sarybchik 246301361Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 247301361Sarybchikefx_lic_v3_find_key( 248301361Sarybchik __in efx_nic_t *enp, 249301361Sarybchik __in_bcount(buffer_size) 250301361Sarybchik caddr_t bufferp, 251301361Sarybchik __in size_t buffer_size, 252301361Sarybchik __in uint32_t offset, 253301361Sarybchik __out uint32_t *startp, 254301361Sarybchik __out uint32_t *lengthp 255301361Sarybchik ); 256301361Sarybchik 257301361Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 258301361Sarybchikefx_lic_v3_validate_key( 259301361Sarybchik __in efx_nic_t *enp, 260301361Sarybchik __in_bcount(length) caddr_t keyp, 261301361Sarybchik __in uint32_t length 262301361Sarybchik ); 263301361Sarybchik 264301361Sarybchik __checkReturn efx_rc_t 265301361Sarybchikefx_lic_v3_read_key( 266301361Sarybchik __in efx_nic_t *enp, 267301361Sarybchik __in_bcount(buffer_size) 268301361Sarybchik caddr_t bufferp, 269301361Sarybchik __in size_t buffer_size, 270301361Sarybchik __in uint32_t offset, 271301361Sarybchik __in uint32_t length, 272301361Sarybchik __out_bcount_part(key_max_size, *lengthp) 273301361Sarybchik caddr_t keyp, 274301361Sarybchik __in size_t key_max_size, 275301361Sarybchik __out uint32_t *lengthp 276301361Sarybchik ); 277301361Sarybchik 278301361Sarybchik __checkReturn efx_rc_t 279301361Sarybchikefx_lic_v3_write_key( 280301361Sarybchik __in efx_nic_t *enp, 281301361Sarybchik __in_bcount(buffer_size) 282301361Sarybchik caddr_t bufferp, 283301361Sarybchik __in size_t buffer_size, 284301361Sarybchik __in uint32_t offset, 285301361Sarybchik __in_bcount(length) caddr_t keyp, 286301361Sarybchik __in uint32_t length, 287301361Sarybchik __out uint32_t *lengthp 288301361Sarybchik ); 289301361Sarybchik 290301361Sarybchik __checkReturn efx_rc_t 291301361Sarybchikefx_lic_v3_delete_key( 292301361Sarybchik __in efx_nic_t *enp, 293301361Sarybchik __in_bcount(buffer_size) 294301361Sarybchik caddr_t bufferp, 295301361Sarybchik __in size_t buffer_size, 296301361Sarybchik __in uint32_t offset, 297301361Sarybchik __in uint32_t length, 298301361Sarybchik __in uint32_t end, 299301361Sarybchik __out uint32_t *deltap 300301361Sarybchik ); 301301361Sarybchik 302301361Sarybchik __checkReturn efx_rc_t 303301361Sarybchikefx_lic_v3_create_partition( 304301361Sarybchik __in efx_nic_t *enp, 305301361Sarybchik __in_bcount(buffer_size) 306301361Sarybchik caddr_t bufferp, 307301361Sarybchik __in size_t buffer_size 308301361Sarybchik ); 309301361Sarybchik 310301361Sarybchik __checkReturn efx_rc_t 311301361Sarybchikefx_lic_v3_finish_partition( 312301361Sarybchik __in efx_nic_t *enp, 313301361Sarybchik __in_bcount(buffer_size) 314301361Sarybchik caddr_t bufferp, 315301361Sarybchik __in size_t buffer_size 316301361Sarybchik ); 317301361Sarybchik 318301340Sarybchikstatic const efx_lic_ops_t __efx_lic_v3_ops = { 319293901Sarybchik efx_mcdi_licensing_v3_update_licenses, /* elo_update_licenses */ 320293901Sarybchik efx_mcdi_licensing_v3_report_license, /* elo_get_key_stats */ 321293901Sarybchik efx_mcdi_licensing_v3_app_state, /* elo_app_state */ 322293901Sarybchik efx_mcdi_licensing_v3_get_id, /* elo_get_id */ 323301361Sarybchik efx_lic_v3_find_start, /* elo_find_start*/ 324301361Sarybchik efx_lic_v3_find_end, /* elo_find_end */ 325301361Sarybchik efx_lic_v3_find_key, /* elo_find_key */ 326301361Sarybchik efx_lic_v3_validate_key, /* elo_validate_key */ 327301361Sarybchik efx_lic_v3_read_key, /* elo_read_key */ 328301361Sarybchik efx_lic_v3_write_key, /* elo_write_key */ 329301361Sarybchik efx_lic_v3_delete_key, /* elo_delete_key */ 330301361Sarybchik efx_lic_v3_create_partition, /* elo_create_partition */ 331301361Sarybchik efx_lic_v3_finish_partition, /* elo_finish_partition */ 332293901Sarybchik}; 333293901Sarybchik 334293901Sarybchik#endif /* EFSYS_OPT_MEDFORD */ 335293901Sarybchik 336293901Sarybchik 337293901Sarybchik/* V1 Licensing - used in Siena Modena only */ 338293901Sarybchik 339293901Sarybchik#if EFSYS_OPT_SIENA 340293901Sarybchik 341293901Sarybchikstatic __checkReturn efx_rc_t 342293901Sarybchikefx_mcdi_fc_license_update_license( 343293901Sarybchik __in efx_nic_t *enp) 344293901Sarybchik{ 345293901Sarybchik efx_mcdi_req_t req; 346342516Sarybchik EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FC_IN_LICENSE_LEN, 0); 347293901Sarybchik efx_rc_t rc; 348293901Sarybchik 349293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA); 350293901Sarybchik 351301366Sarybchik req.emr_cmd = MC_CMD_FC; 352293901Sarybchik req.emr_in_buf = payload; 353293901Sarybchik req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN; 354293901Sarybchik req.emr_out_buf = payload; 355293901Sarybchik req.emr_out_length = 0; 356293901Sarybchik 357301366Sarybchik MCDI_IN_SET_DWORD(req, FC_IN_CMD, 358301366Sarybchik MC_CMD_FC_OP_LICENSE); 359301366Sarybchik 360293901Sarybchik MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP, 361293901Sarybchik MC_CMD_FC_IN_LICENSE_UPDATE_LICENSE); 362293901Sarybchik 363293901Sarybchik efx_mcdi_execute(enp, &req); 364293901Sarybchik 365293901Sarybchik if (req.emr_rc != 0) { 366293901Sarybchik rc = req.emr_rc; 367293901Sarybchik goto fail1; 368293901Sarybchik } 369293901Sarybchik 370293901Sarybchik if (req.emr_out_length_used != 0) { 371293901Sarybchik rc = EIO; 372293901Sarybchik goto fail2; 373293901Sarybchik } 374293901Sarybchik 375293901Sarybchik return (0); 376293901Sarybchik 377293901Sarybchikfail2: 378293901Sarybchik EFSYS_PROBE(fail2); 379293901Sarybchikfail1: 380293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 381293901Sarybchik 382293901Sarybchik return (rc); 383293901Sarybchik} 384293901Sarybchik 385293901Sarybchikstatic __checkReturn efx_rc_t 386293901Sarybchikefx_mcdi_fc_license_get_key_stats( 387293901Sarybchik __in efx_nic_t *enp, 388293901Sarybchik __out efx_key_stats_t *eksp) 389293901Sarybchik{ 390293901Sarybchik efx_mcdi_req_t req; 391342516Sarybchik EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FC_IN_LICENSE_LEN, 392342516Sarybchik MC_CMD_FC_OUT_LICENSE_LEN); 393293901Sarybchik efx_rc_t rc; 394293901Sarybchik 395293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA); 396293901Sarybchik 397301366Sarybchik req.emr_cmd = MC_CMD_FC; 398293901Sarybchik req.emr_in_buf = payload; 399293901Sarybchik req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN; 400293901Sarybchik req.emr_out_buf = payload; 401293901Sarybchik req.emr_out_length = MC_CMD_FC_OUT_LICENSE_LEN; 402293901Sarybchik 403301366Sarybchik MCDI_IN_SET_DWORD(req, FC_IN_CMD, 404301366Sarybchik MC_CMD_FC_OP_LICENSE); 405301366Sarybchik 406293901Sarybchik MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP, 407293901Sarybchik MC_CMD_FC_IN_LICENSE_GET_KEY_STATS); 408293901Sarybchik 409301376Sarybchik efx_mcdi_execute_quiet(enp, &req); 410293901Sarybchik 411293901Sarybchik if (req.emr_rc != 0) { 412293901Sarybchik rc = req.emr_rc; 413293901Sarybchik goto fail1; 414293901Sarybchik } 415293901Sarybchik 416293901Sarybchik if (req.emr_out_length_used < MC_CMD_FC_OUT_LICENSE_LEN) { 417293901Sarybchik rc = EMSGSIZE; 418293901Sarybchik goto fail2; 419293901Sarybchik } 420293901Sarybchik 421293901Sarybchik eksp->eks_valid = 422293901Sarybchik MCDI_OUT_DWORD(req, FC_OUT_LICENSE_VALID_KEYS); 423293901Sarybchik eksp->eks_invalid = 424293901Sarybchik MCDI_OUT_DWORD(req, FC_OUT_LICENSE_INVALID_KEYS); 425293901Sarybchik eksp->eks_blacklisted = 426293901Sarybchik MCDI_OUT_DWORD(req, FC_OUT_LICENSE_BLACKLISTED_KEYS); 427293901Sarybchik eksp->eks_unverifiable = 0; 428293901Sarybchik eksp->eks_wrong_node = 0; 429293901Sarybchik eksp->eks_licensed_apps_lo = 0; 430293901Sarybchik eksp->eks_licensed_apps_hi = 0; 431293901Sarybchik eksp->eks_licensed_features_lo = 0; 432293901Sarybchik eksp->eks_licensed_features_hi = 0; 433293901Sarybchik 434293901Sarybchik return (0); 435293901Sarybchik 436293901Sarybchikfail2: 437293901Sarybchik EFSYS_PROBE(fail2); 438293901Sarybchikfail1: 439293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 440293901Sarybchik 441293901Sarybchik return (rc); 442293901Sarybchik} 443293901Sarybchik 444293901Sarybchik#endif /* EFSYS_OPT_SIENA */ 445293901Sarybchik 446301361Sarybchik/* V1 and V2 Partition format - based on a 16-bit TLV format */ 447301361Sarybchik 448301361Sarybchik#if EFSYS_OPT_SIENA | EFSYS_OPT_HUNTINGTON 449301361Sarybchik 450301361Sarybchik/* 451301361Sarybchik * V1/V2 format - defined in SF-108542-TC section 4.2: 452301361Sarybchik * Type (T): 16bit - revision/HMAC algorithm 453301361Sarybchik * Length (L): 16bit - value length in bytes 454301361Sarybchik * Value (V): L bytes - payload 455301361Sarybchik */ 456301361Sarybchik#define EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX (256) 457310839Sarybchik#define EFX_LICENSE_V1V2_HEADER_LENGTH (2 * sizeof(uint16_t)) 458301361Sarybchik 459301361Sarybchik __checkReturn efx_rc_t 460301361Sarybchikefx_lic_v1v2_find_start( 461301361Sarybchik __in efx_nic_t *enp, 462301361Sarybchik __in_bcount(buffer_size) 463301361Sarybchik caddr_t bufferp, 464301361Sarybchik __in size_t buffer_size, 465301361Sarybchik __out uint32_t *startp 466301361Sarybchik ) 467301361Sarybchik{ 468301361Sarybchik _NOTE(ARGUNUSED(enp, bufferp, buffer_size)) 469301361Sarybchik 470301361Sarybchik *startp = 0; 471301361Sarybchik return (0); 472301361Sarybchik} 473301361Sarybchik 474301361Sarybchik __checkReturn efx_rc_t 475301361Sarybchikefx_lic_v1v2_find_end( 476301361Sarybchik __in efx_nic_t *enp, 477301361Sarybchik __in_bcount(buffer_size) 478301361Sarybchik caddr_t bufferp, 479301361Sarybchik __in size_t buffer_size, 480301361Sarybchik __in uint32_t offset, 481301361Sarybchik __out uint32_t *endp 482301361Sarybchik ) 483301361Sarybchik{ 484301361Sarybchik _NOTE(ARGUNUSED(enp, bufferp, buffer_size)) 485301361Sarybchik 486301361Sarybchik *endp = offset + EFX_LICENSE_V1V2_HEADER_LENGTH; 487301361Sarybchik return (0); 488301361Sarybchik} 489301361Sarybchik 490301361Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 491301361Sarybchikefx_lic_v1v2_find_key( 492301361Sarybchik __in efx_nic_t *enp, 493301361Sarybchik __in_bcount(buffer_size) 494301361Sarybchik caddr_t bufferp, 495301361Sarybchik __in size_t buffer_size, 496301361Sarybchik __in uint32_t offset, 497301361Sarybchik __out uint32_t *startp, 498301361Sarybchik __out uint32_t *lengthp 499301361Sarybchik ) 500301361Sarybchik{ 501301361Sarybchik boolean_t found; 502301361Sarybchik uint16_t tlv_type; 503301361Sarybchik uint16_t tlv_length; 504301361Sarybchik 505301361Sarybchik _NOTE(ARGUNUSED(enp)) 506301361Sarybchik 507301981Sarybchik if ((size_t)buffer_size - offset < EFX_LICENSE_V1V2_HEADER_LENGTH) 508301361Sarybchik goto fail1; 509301361Sarybchik 510311054Sarybchik tlv_type = __LE_TO_CPU_16(((uint16_t *)&bufferp[offset])[0]); 511311054Sarybchik tlv_length = __LE_TO_CPU_16(((uint16_t *)&bufferp[offset])[1]); 512301361Sarybchik if ((tlv_length > EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX) || 513301361Sarybchik (tlv_type == 0 && tlv_length == 0)) { 514301361Sarybchik found = B_FALSE; 515301361Sarybchik } else { 516301361Sarybchik *startp = offset; 517301361Sarybchik *lengthp = tlv_length + EFX_LICENSE_V1V2_HEADER_LENGTH; 518301361Sarybchik found = B_TRUE; 519301361Sarybchik } 520301361Sarybchik return (found); 521301361Sarybchik 522301361Sarybchikfail1: 523342497Sarybchik EFSYS_PROBE1(fail1, boolean_t, B_FALSE); 524301361Sarybchik 525301361Sarybchik return (B_FALSE); 526301361Sarybchik} 527301361Sarybchik 528301361Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 529301361Sarybchikefx_lic_v1v2_validate_key( 530301361Sarybchik __in efx_nic_t *enp, 531301361Sarybchik __in_bcount(length) caddr_t keyp, 532301361Sarybchik __in uint32_t length 533301361Sarybchik ) 534301361Sarybchik{ 535301361Sarybchik uint16_t tlv_type; 536301361Sarybchik uint16_t tlv_length; 537301361Sarybchik 538301361Sarybchik _NOTE(ARGUNUSED(enp)) 539301361Sarybchik 540301361Sarybchik if (length < EFX_LICENSE_V1V2_HEADER_LENGTH) { 541301361Sarybchik goto fail1; 542301361Sarybchik } 543301361Sarybchik 544311054Sarybchik tlv_type = __LE_TO_CPU_16(((uint16_t *)keyp)[0]); 545311054Sarybchik tlv_length = __LE_TO_CPU_16(((uint16_t *)keyp)[1]); 546301361Sarybchik 547301981Sarybchik if (tlv_length > EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX) { 548301361Sarybchik goto fail2; 549301361Sarybchik } 550301361Sarybchik if (tlv_type == 0) { 551301361Sarybchik goto fail3; 552301361Sarybchik } 553301361Sarybchik if ((tlv_length + EFX_LICENSE_V1V2_HEADER_LENGTH) != length) { 554301361Sarybchik goto fail4; 555301361Sarybchik } 556301361Sarybchik 557301361Sarybchik return (B_TRUE); 558301361Sarybchik 559301361Sarybchikfail4: 560301361Sarybchik EFSYS_PROBE(fail4); 561301361Sarybchikfail3: 562301361Sarybchik EFSYS_PROBE(fail3); 563301361Sarybchikfail2: 564301361Sarybchik EFSYS_PROBE(fail2); 565301361Sarybchikfail1: 566342497Sarybchik EFSYS_PROBE1(fail1, boolean_t, B_FALSE); 567301361Sarybchik 568301361Sarybchik return (B_FALSE); 569301361Sarybchik} 570301361Sarybchik 571301361Sarybchik 572301361Sarybchik __checkReturn efx_rc_t 573301361Sarybchikefx_lic_v1v2_read_key( 574301361Sarybchik __in efx_nic_t *enp, 575301361Sarybchik __in_bcount(buffer_size) 576301361Sarybchik caddr_t bufferp, 577301361Sarybchik __in size_t buffer_size, 578301361Sarybchik __in uint32_t offset, 579301361Sarybchik __in uint32_t length, 580301361Sarybchik __out_bcount_part(key_max_size, *lengthp) 581301361Sarybchik caddr_t keyp, 582301361Sarybchik __in size_t key_max_size, 583301361Sarybchik __out uint32_t *lengthp 584301361Sarybchik ) 585301361Sarybchik{ 586301361Sarybchik efx_rc_t rc; 587301361Sarybchik 588342501Sarybchik _NOTE(ARGUNUSED(enp, buffer_size)) 589301361Sarybchik EFSYS_ASSERT(length <= (EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX + 590301361Sarybchik EFX_LICENSE_V1V2_HEADER_LENGTH)); 591301361Sarybchik 592301361Sarybchik if (key_max_size < length) { 593301361Sarybchik rc = ENOSPC; 594301361Sarybchik goto fail1; 595301361Sarybchik } 596301361Sarybchik memcpy(keyp, &bufferp[offset], length); 597301361Sarybchik 598301361Sarybchik *lengthp = length; 599301361Sarybchik 600301361Sarybchik return (0); 601301361Sarybchik 602301361Sarybchikfail1: 603301361Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 604301361Sarybchik 605301361Sarybchik return (rc); 606301361Sarybchik} 607301361Sarybchik 608301361Sarybchik __checkReturn efx_rc_t 609301361Sarybchikefx_lic_v1v2_write_key( 610301361Sarybchik __in efx_nic_t *enp, 611301361Sarybchik __in_bcount(buffer_size) 612301361Sarybchik caddr_t bufferp, 613301361Sarybchik __in size_t buffer_size, 614301361Sarybchik __in uint32_t offset, 615301361Sarybchik __in_bcount(length) caddr_t keyp, 616301361Sarybchik __in uint32_t length, 617301361Sarybchik __out uint32_t *lengthp 618301361Sarybchik ) 619301361Sarybchik{ 620301361Sarybchik efx_rc_t rc; 621301361Sarybchik 622301361Sarybchik _NOTE(ARGUNUSED(enp)) 623301361Sarybchik EFSYS_ASSERT(length <= (EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX + 624301361Sarybchik EFX_LICENSE_V1V2_HEADER_LENGTH)); 625301361Sarybchik 626311050Sarybchik /* Ensure space for terminator remains */ 627301361Sarybchik if ((offset + length) > 628310842Sarybchik (buffer_size - EFX_LICENSE_V1V2_HEADER_LENGTH)) { 629301361Sarybchik rc = ENOSPC; 630301361Sarybchik goto fail1; 631301361Sarybchik } 632301361Sarybchik 633301361Sarybchik memcpy(bufferp + offset, keyp, length); 634301361Sarybchik 635301361Sarybchik *lengthp = length; 636301361Sarybchik 637301361Sarybchik return (0); 638301361Sarybchik 639301361Sarybchikfail1: 640301361Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 641301361Sarybchik 642301361Sarybchik return (rc); 643301361Sarybchik} 644301361Sarybchik 645301361Sarybchik __checkReturn efx_rc_t 646301361Sarybchikefx_lic_v1v2_delete_key( 647301361Sarybchik __in efx_nic_t *enp, 648301361Sarybchik __in_bcount(buffer_size) 649301361Sarybchik caddr_t bufferp, 650301361Sarybchik __in size_t buffer_size, 651301361Sarybchik __in uint32_t offset, 652301361Sarybchik __in uint32_t length, 653301361Sarybchik __in uint32_t end, 654301361Sarybchik __out uint32_t *deltap 655301361Sarybchik ) 656301361Sarybchik{ 657301361Sarybchik uint32_t move_start = offset + length; 658301361Sarybchik uint32_t move_length = end - move_start; 659301361Sarybchik 660342501Sarybchik _NOTE(ARGUNUSED(enp, buffer_size)) 661301361Sarybchik EFSYS_ASSERT(end <= buffer_size); 662301361Sarybchik 663311050Sarybchik /* Shift everything after the key down */ 664301361Sarybchik memmove(bufferp + offset, bufferp + move_start, move_length); 665301361Sarybchik 666301361Sarybchik *deltap = length; 667301361Sarybchik 668301361Sarybchik return (0); 669301361Sarybchik} 670301361Sarybchik 671301361Sarybchik __checkReturn efx_rc_t 672301361Sarybchikefx_lic_v1v2_create_partition( 673301361Sarybchik __in efx_nic_t *enp, 674301361Sarybchik __in_bcount(buffer_size) 675301361Sarybchik caddr_t bufferp, 676301361Sarybchik __in size_t buffer_size 677301361Sarybchik ) 678301361Sarybchik{ 679342501Sarybchik _NOTE(ARGUNUSED(enp, buffer_size)) 680301361Sarybchik EFSYS_ASSERT(EFX_LICENSE_V1V2_HEADER_LENGTH <= buffer_size); 681301361Sarybchik 682311050Sarybchik /* Write terminator */ 683301361Sarybchik memset(bufferp, '\0', EFX_LICENSE_V1V2_HEADER_LENGTH); 684301361Sarybchik return (0); 685301361Sarybchik} 686301361Sarybchik 687301361Sarybchik 688301361Sarybchik __checkReturn efx_rc_t 689301361Sarybchikefx_lic_v1v2_finish_partition( 690301361Sarybchik __in efx_nic_t *enp, 691301361Sarybchik __in_bcount(buffer_size) 692301361Sarybchik caddr_t bufferp, 693301361Sarybchik __in size_t buffer_size 694301361Sarybchik ) 695301361Sarybchik{ 696301361Sarybchik _NOTE(ARGUNUSED(enp, bufferp, buffer_size)) 697301361Sarybchik 698301361Sarybchik return (0); 699301361Sarybchik} 700301361Sarybchik 701301361Sarybchik#endif /* EFSYS_OPT_HUNTINGTON | EFSYS_OPT_SIENA */ 702301361Sarybchik 703301361Sarybchik 704293901Sarybchik/* V2 Licensing - used by Huntington family only. See SF-113611-TC */ 705293901Sarybchik 706293901Sarybchik#if EFSYS_OPT_HUNTINGTON 707293901Sarybchik 708293901Sarybchikstatic __checkReturn efx_rc_t 709293901Sarybchikefx_mcdi_licensed_app_state( 710293901Sarybchik __in efx_nic_t *enp, 711293901Sarybchik __in uint64_t app_id, 712293901Sarybchik __out boolean_t *licensedp) 713293901Sarybchik{ 714293901Sarybchik efx_mcdi_req_t req; 715342516Sarybchik EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LICENSED_APP_STATE_IN_LEN, 716342516Sarybchik MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN); 717293901Sarybchik uint32_t app_state; 718293901Sarybchik efx_rc_t rc; 719293901Sarybchik 720293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON); 721293901Sarybchik 722293901Sarybchik /* V2 licensing supports 32bit app id only */ 723293901Sarybchik if ((app_id >> 32) != 0) { 724293901Sarybchik rc = EINVAL; 725293901Sarybchik goto fail1; 726293901Sarybchik } 727293901Sarybchik 728293901Sarybchik req.emr_cmd = MC_CMD_GET_LICENSED_APP_STATE; 729293901Sarybchik req.emr_in_buf = payload; 730293901Sarybchik req.emr_in_length = MC_CMD_GET_LICENSED_APP_STATE_IN_LEN; 731293901Sarybchik req.emr_out_buf = payload; 732293901Sarybchik req.emr_out_length = MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN; 733293901Sarybchik 734293901Sarybchik MCDI_IN_SET_DWORD(req, GET_LICENSED_APP_STATE_IN_APP_ID, 735293901Sarybchik app_id & 0xffffffff); 736293901Sarybchik 737293901Sarybchik efx_mcdi_execute(enp, &req); 738293901Sarybchik 739293901Sarybchik if (req.emr_rc != 0) { 740293901Sarybchik rc = req.emr_rc; 741293901Sarybchik goto fail2; 742293901Sarybchik } 743293901Sarybchik 744293901Sarybchik if (req.emr_out_length_used < MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN) { 745293901Sarybchik rc = EMSGSIZE; 746293901Sarybchik goto fail3; 747293901Sarybchik } 748293901Sarybchik 749293901Sarybchik app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_APP_STATE_OUT_STATE)); 750293901Sarybchik if (app_state != MC_CMD_GET_LICENSED_APP_STATE_OUT_NOT_LICENSED) { 751293901Sarybchik *licensedp = B_TRUE; 752293901Sarybchik } else { 753293901Sarybchik *licensedp = B_FALSE; 754293901Sarybchik } 755293901Sarybchik 756293901Sarybchik return (0); 757293901Sarybchik 758293901Sarybchikfail3: 759293901Sarybchik EFSYS_PROBE(fail3); 760293901Sarybchikfail2: 761293901Sarybchik EFSYS_PROBE(fail2); 762293901Sarybchikfail1: 763293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 764293901Sarybchik 765293901Sarybchik return (rc); 766293901Sarybchik} 767293901Sarybchik 768293901Sarybchikstatic __checkReturn efx_rc_t 769293901Sarybchikefx_mcdi_licensing_update_licenses( 770293901Sarybchik __in efx_nic_t *enp) 771293901Sarybchik{ 772293901Sarybchik efx_mcdi_req_t req; 773342516Sarybchik EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_IN_LEN, 0); 774293901Sarybchik efx_rc_t rc; 775293901Sarybchik 776293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON); 777293901Sarybchik 778293901Sarybchik req.emr_cmd = MC_CMD_LICENSING; 779293901Sarybchik req.emr_in_buf = payload; 780293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_IN_LEN; 781293901Sarybchik req.emr_out_buf = payload; 782293901Sarybchik req.emr_out_length = 0; 783293901Sarybchik 784293901Sarybchik MCDI_IN_SET_DWORD(req, LICENSING_IN_OP, 785293901Sarybchik MC_CMD_LICENSING_IN_OP_UPDATE_LICENSE); 786293901Sarybchik 787293901Sarybchik efx_mcdi_execute(enp, &req); 788293901Sarybchik 789293901Sarybchik if (req.emr_rc != 0) { 790293901Sarybchik rc = req.emr_rc; 791293901Sarybchik goto fail1; 792293901Sarybchik } 793293901Sarybchik 794293901Sarybchik if (req.emr_out_length_used != 0) { 795293901Sarybchik rc = EIO; 796293901Sarybchik goto fail2; 797293901Sarybchik } 798293901Sarybchik 799293901Sarybchik return (0); 800293901Sarybchik 801293901Sarybchikfail2: 802293901Sarybchik EFSYS_PROBE(fail2); 803293901Sarybchikfail1: 804293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 805293901Sarybchik 806293901Sarybchik return (rc); 807293901Sarybchik} 808293901Sarybchik 809293901Sarybchikstatic __checkReturn efx_rc_t 810293901Sarybchikefx_mcdi_licensing_get_key_stats( 811293901Sarybchik __in efx_nic_t *enp, 812293901Sarybchik __out efx_key_stats_t *eksp) 813293901Sarybchik{ 814293901Sarybchik efx_mcdi_req_t req; 815342516Sarybchik EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_IN_LEN, 816342516Sarybchik MC_CMD_LICENSING_OUT_LEN); 817293901Sarybchik efx_rc_t rc; 818293901Sarybchik 819293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON); 820293901Sarybchik 821293901Sarybchik req.emr_cmd = MC_CMD_LICENSING; 822293901Sarybchik req.emr_in_buf = payload; 823293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_IN_LEN; 824293901Sarybchik req.emr_out_buf = payload; 825293901Sarybchik req.emr_out_length = MC_CMD_LICENSING_OUT_LEN; 826293901Sarybchik 827293901Sarybchik MCDI_IN_SET_DWORD(req, LICENSING_IN_OP, 828293901Sarybchik MC_CMD_LICENSING_IN_OP_GET_KEY_STATS); 829293901Sarybchik 830293901Sarybchik efx_mcdi_execute(enp, &req); 831293901Sarybchik 832293901Sarybchik if (req.emr_rc != 0) { 833293901Sarybchik rc = req.emr_rc; 834293901Sarybchik goto fail1; 835293901Sarybchik } 836293901Sarybchik 837293901Sarybchik if (req.emr_out_length_used < MC_CMD_LICENSING_OUT_LEN) { 838293901Sarybchik rc = EMSGSIZE; 839293901Sarybchik goto fail2; 840293901Sarybchik } 841293901Sarybchik 842293901Sarybchik eksp->eks_valid = 843293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_OUT_VALID_APP_KEYS); 844293901Sarybchik eksp->eks_invalid = 845293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_OUT_INVALID_APP_KEYS); 846293901Sarybchik eksp->eks_blacklisted = 847293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_OUT_BLACKLISTED_APP_KEYS); 848293901Sarybchik eksp->eks_unverifiable = 849293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_OUT_UNVERIFIABLE_APP_KEYS); 850293901Sarybchik eksp->eks_wrong_node = 851293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_OUT_WRONG_NODE_APP_KEYS); 852293901Sarybchik eksp->eks_licensed_apps_lo = 0; 853293901Sarybchik eksp->eks_licensed_apps_hi = 0; 854293901Sarybchik eksp->eks_licensed_features_lo = 0; 855293901Sarybchik eksp->eks_licensed_features_hi = 0; 856293901Sarybchik 857293901Sarybchik return (0); 858293901Sarybchik 859293901Sarybchikfail2: 860293901Sarybchik EFSYS_PROBE(fail2); 861293901Sarybchikfail1: 862293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 863293901Sarybchik 864293901Sarybchik return (rc); 865293901Sarybchik} 866293901Sarybchik 867293901Sarybchik#endif /* EFSYS_OPT_HUNTINGTON */ 868293901Sarybchik 869293901Sarybchik/* V3 Licensing - used starting from Medford family. See SF-114884-SW */ 870293901Sarybchik 871293901Sarybchik#if EFSYS_OPT_MEDFORD 872293901Sarybchik 873293901Sarybchikstatic __checkReturn efx_rc_t 874293901Sarybchikefx_mcdi_licensing_v3_update_licenses( 875293901Sarybchik __in efx_nic_t *enp) 876293901Sarybchik{ 877293901Sarybchik efx_mcdi_req_t req; 878342516Sarybchik EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_V3_IN_LEN, 0); 879293901Sarybchik efx_rc_t rc; 880293901Sarybchik 881293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD); 882293901Sarybchik 883293901Sarybchik req.emr_cmd = MC_CMD_LICENSING_V3; 884293901Sarybchik req.emr_in_buf = payload; 885293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN; 886293901Sarybchik req.emr_out_buf = NULL; 887293901Sarybchik req.emr_out_length = 0; 888293901Sarybchik 889293901Sarybchik MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP, 890293901Sarybchik MC_CMD_LICENSING_V3_IN_OP_UPDATE_LICENSE); 891293901Sarybchik 892293901Sarybchik efx_mcdi_execute(enp, &req); 893293901Sarybchik 894293901Sarybchik if (req.emr_rc != 0) { 895293901Sarybchik rc = req.emr_rc; 896293901Sarybchik goto fail1; 897293901Sarybchik } 898293901Sarybchik 899293901Sarybchik return (0); 900293901Sarybchik 901293901Sarybchikfail1: 902293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 903293901Sarybchik 904293901Sarybchik return (rc); 905293901Sarybchik} 906293901Sarybchik 907293901Sarybchikstatic __checkReturn efx_rc_t 908293901Sarybchikefx_mcdi_licensing_v3_report_license( 909293901Sarybchik __in efx_nic_t *enp, 910293901Sarybchik __out efx_key_stats_t *eksp) 911293901Sarybchik{ 912293901Sarybchik efx_mcdi_req_t req; 913342516Sarybchik EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_V3_IN_LEN, 914342516Sarybchik MC_CMD_LICENSING_V3_OUT_LEN); 915293901Sarybchik efx_rc_t rc; 916293901Sarybchik 917293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD); 918293901Sarybchik 919293901Sarybchik req.emr_cmd = MC_CMD_LICENSING_V3; 920293901Sarybchik req.emr_in_buf = payload; 921293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN; 922293901Sarybchik req.emr_out_buf = payload; 923293901Sarybchik req.emr_out_length = MC_CMD_LICENSING_V3_OUT_LEN; 924293901Sarybchik 925293901Sarybchik MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP, 926293901Sarybchik MC_CMD_LICENSING_V3_IN_OP_REPORT_LICENSE); 927293901Sarybchik 928301376Sarybchik efx_mcdi_execute_quiet(enp, &req); 929293901Sarybchik 930293901Sarybchik if (req.emr_rc != 0) { 931293901Sarybchik rc = req.emr_rc; 932293901Sarybchik goto fail1; 933293901Sarybchik } 934293901Sarybchik 935293901Sarybchik if (req.emr_out_length_used < MC_CMD_LICENSING_V3_OUT_LEN) { 936293901Sarybchik rc = EMSGSIZE; 937293901Sarybchik goto fail2; 938293901Sarybchik } 939293901Sarybchik 940293901Sarybchik eksp->eks_valid = 941293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_VALID_KEYS); 942293901Sarybchik eksp->eks_invalid = 943293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_INVALID_KEYS); 944293901Sarybchik eksp->eks_blacklisted = 0; 945293901Sarybchik eksp->eks_unverifiable = 946293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_UNVERIFIABLE_KEYS); 947293901Sarybchik eksp->eks_wrong_node = 948293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_WRONG_NODE_KEYS); 949293901Sarybchik eksp->eks_licensed_apps_lo = 950293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_LO); 951293901Sarybchik eksp->eks_licensed_apps_hi = 952293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_HI); 953293901Sarybchik eksp->eks_licensed_features_lo = 954293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_LO); 955293901Sarybchik eksp->eks_licensed_features_hi = 956293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_HI); 957293901Sarybchik 958293901Sarybchik return (0); 959293901Sarybchik 960293901Sarybchikfail2: 961293901Sarybchik EFSYS_PROBE(fail2); 962293901Sarybchikfail1: 963293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 964293901Sarybchik 965293901Sarybchik return (rc); 966293901Sarybchik} 967293901Sarybchik 968293901Sarybchikstatic __checkReturn efx_rc_t 969293901Sarybchikefx_mcdi_licensing_v3_app_state( 970293901Sarybchik __in efx_nic_t *enp, 971293901Sarybchik __in uint64_t app_id, 972293901Sarybchik __out boolean_t *licensedp) 973293901Sarybchik{ 974293901Sarybchik efx_mcdi_req_t req; 975342516Sarybchik EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN, 976342516Sarybchik MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN); 977293901Sarybchik uint32_t app_state; 978293901Sarybchik efx_rc_t rc; 979293901Sarybchik 980293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD); 981293901Sarybchik 982293901Sarybchik req.emr_cmd = MC_CMD_GET_LICENSED_V3_APP_STATE; 983293901Sarybchik req.emr_in_buf = payload; 984293901Sarybchik req.emr_in_length = MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN; 985293901Sarybchik req.emr_out_buf = payload; 986293901Sarybchik req.emr_out_length = MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN; 987293901Sarybchik 988293901Sarybchik MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_LO, 989293901Sarybchik app_id & 0xffffffff); 990293901Sarybchik MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_HI, 991293901Sarybchik app_id >> 32); 992293901Sarybchik 993293901Sarybchik efx_mcdi_execute(enp, &req); 994293901Sarybchik 995293901Sarybchik if (req.emr_rc != 0) { 996293901Sarybchik rc = req.emr_rc; 997293901Sarybchik goto fail1; 998293901Sarybchik } 999293901Sarybchik 1000293901Sarybchik if (req.emr_out_length_used < MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN) { 1001293901Sarybchik rc = EMSGSIZE; 1002293901Sarybchik goto fail2; 1003293901Sarybchik } 1004293901Sarybchik 1005293901Sarybchik app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_V3_APP_STATE_OUT_STATE)); 1006293901Sarybchik if (app_state != MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_NOT_LICENSED) { 1007293901Sarybchik *licensedp = B_TRUE; 1008293901Sarybchik } else { 1009293901Sarybchik *licensedp = B_FALSE; 1010293901Sarybchik } 1011293901Sarybchik 1012293901Sarybchik return (0); 1013293901Sarybchik 1014293901Sarybchikfail2: 1015293901Sarybchik EFSYS_PROBE(fail2); 1016293901Sarybchikfail1: 1017293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1018293901Sarybchik 1019293901Sarybchik return (rc); 1020293901Sarybchik} 1021293901Sarybchik 1022293901Sarybchikstatic __checkReturn efx_rc_t 1023293901Sarybchikefx_mcdi_licensing_v3_get_id( 1024293901Sarybchik __in efx_nic_t *enp, 1025293901Sarybchik __in size_t buffer_size, 1026293901Sarybchik __out uint32_t *typep, 1027293901Sarybchik __out size_t *lengthp, 1028293901Sarybchik __out_bcount_part_opt(buffer_size, *lengthp) 1029293901Sarybchik uint8_t *bufferp) 1030293901Sarybchik{ 1031293901Sarybchik efx_mcdi_req_t req; 1032342516Sarybchik EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_GET_ID_V3_IN_LEN, 1033342516Sarybchik MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN); 1034293901Sarybchik efx_rc_t rc; 1035293901Sarybchik 1036293901Sarybchik req.emr_cmd = MC_CMD_LICENSING_GET_ID_V3; 1037293901Sarybchik 1038293901Sarybchik if (bufferp == NULL) { 1039293901Sarybchik /* Request id type and length only */ 1040293901Sarybchik req.emr_in_buf = bufferp; 1041293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN; 1042293901Sarybchik req.emr_out_buf = bufferp; 1043293901Sarybchik req.emr_out_length = MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN; 1044293901Sarybchik } else { 1045293901Sarybchik /* Request full buffer */ 1046293901Sarybchik req.emr_in_buf = bufferp; 1047293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN; 1048293901Sarybchik req.emr_out_buf = bufferp; 1049301361Sarybchik req.emr_out_length = MIN(buffer_size, MC_CMD_LICENSING_GET_ID_V3_OUT_LENMAX); 1050293901Sarybchik (void) memset(bufferp, 0, req.emr_out_length); 1051293901Sarybchik } 1052293901Sarybchik 1053301376Sarybchik efx_mcdi_execute_quiet(enp, &req); 1054293901Sarybchik 1055293901Sarybchik if (req.emr_rc != 0) { 1056293901Sarybchik rc = req.emr_rc; 1057293901Sarybchik goto fail1; 1058293901Sarybchik } 1059293901Sarybchik 1060293901Sarybchik if (req.emr_out_length_used < MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN) { 1061293901Sarybchik rc = EMSGSIZE; 1062293901Sarybchik goto fail2; 1063293901Sarybchik } 1064293901Sarybchik 1065293901Sarybchik *typep = MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_TYPE); 1066293901Sarybchik *lengthp = MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_ID_LENGTH); 1067293901Sarybchik 1068293901Sarybchik if (bufferp == NULL) { 1069293901Sarybchik /* modify length requirements to indicate to caller the extra buffering 1070293901Sarybchik ** needed to read the complete output. 1071293901Sarybchik */ 1072293901Sarybchik *lengthp += MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN; 1073293901Sarybchik } else { 1074293901Sarybchik /* Shift ID down to start of buffer */ 1075293901Sarybchik memmove(bufferp, 1076310839Sarybchik bufferp + MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST, 1077310839Sarybchik *lengthp); 1078310839Sarybchik memset(bufferp + (*lengthp), 0, 1079310839Sarybchik MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST); 1080293901Sarybchik } 1081293901Sarybchik 1082293901Sarybchik return (0); 1083293901Sarybchik 1084293901Sarybchikfail2: 1085293901Sarybchik EFSYS_PROBE(fail2); 1086293901Sarybchikfail1: 1087293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1088293901Sarybchik 1089293901Sarybchik return (rc); 1090293901Sarybchik} 1091293901Sarybchik 1092301361Sarybchik/* V3 format uses Huntington TLV format partition. See SF-108797-SW */ 1093301361Sarybchik#define EFX_LICENSE_V3_KEY_LENGTH_MIN (64) 1094301368Sarybchik#define EFX_LICENSE_V3_KEY_LENGTH_MAX (160) 1095293901Sarybchik 1096301361Sarybchik __checkReturn efx_rc_t 1097301361Sarybchikefx_lic_v3_find_start( 1098301361Sarybchik __in efx_nic_t *enp, 1099301361Sarybchik __in_bcount(buffer_size) 1100301361Sarybchik caddr_t bufferp, 1101301361Sarybchik __in size_t buffer_size, 1102301361Sarybchik __out uint32_t *startp 1103301361Sarybchik ) 1104301361Sarybchik{ 1105301361Sarybchik _NOTE(ARGUNUSED(enp)) 1106301361Sarybchik 1107301361Sarybchik return ef10_nvram_buffer_find_item_start(bufferp, buffer_size, startp); 1108301361Sarybchik} 1109301361Sarybchik 1110301361Sarybchik __checkReturn efx_rc_t 1111301361Sarybchikefx_lic_v3_find_end( 1112301361Sarybchik __in efx_nic_t *enp, 1113301361Sarybchik __in_bcount(buffer_size) 1114301361Sarybchik caddr_t bufferp, 1115301361Sarybchik __in size_t buffer_size, 1116301361Sarybchik __in uint32_t offset, 1117301361Sarybchik __out uint32_t *endp 1118301361Sarybchik ) 1119301361Sarybchik{ 1120301361Sarybchik _NOTE(ARGUNUSED(enp)) 1121301361Sarybchik 1122301361Sarybchik return ef10_nvram_buffer_find_end(bufferp, buffer_size, offset, endp); 1123301361Sarybchik} 1124301361Sarybchik 1125301361Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 1126301361Sarybchikefx_lic_v3_find_key( 1127301361Sarybchik __in efx_nic_t *enp, 1128301361Sarybchik __in_bcount(buffer_size) 1129301361Sarybchik caddr_t bufferp, 1130301361Sarybchik __in size_t buffer_size, 1131301361Sarybchik __in uint32_t offset, 1132301361Sarybchik __out uint32_t *startp, 1133301361Sarybchik __out uint32_t *lengthp 1134301361Sarybchik ) 1135301361Sarybchik{ 1136301361Sarybchik _NOTE(ARGUNUSED(enp)) 1137301361Sarybchik 1138301361Sarybchik return ef10_nvram_buffer_find_item(bufferp, buffer_size, 1139301361Sarybchik offset, startp, lengthp); 1140301361Sarybchik} 1141301361Sarybchik 1142301361Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 1143301361Sarybchikefx_lic_v3_validate_key( 1144301361Sarybchik __in efx_nic_t *enp, 1145301361Sarybchik __in_bcount(length) caddr_t keyp, 1146301361Sarybchik __in uint32_t length 1147301361Sarybchik ) 1148301361Sarybchik{ 1149311050Sarybchik /* Check key is a valid V3 key */ 1150301361Sarybchik uint8_t key_type; 1151301361Sarybchik uint8_t key_length; 1152301361Sarybchik 1153301361Sarybchik _NOTE(ARGUNUSED(enp)) 1154301361Sarybchik 1155301361Sarybchik if (length < EFX_LICENSE_V3_KEY_LENGTH_MIN) { 1156301361Sarybchik goto fail1; 1157301361Sarybchik } 1158301361Sarybchik 1159301370Sarybchik if (length > EFX_LICENSE_V3_KEY_LENGTH_MAX) { 1160301370Sarybchik goto fail2; 1161301370Sarybchik } 1162301370Sarybchik 1163311054Sarybchik key_type = ((uint8_t *)keyp)[0]; 1164311054Sarybchik key_length = ((uint8_t *)keyp)[1]; 1165301361Sarybchik 1166301361Sarybchik if (key_type < 3) { 1167301361Sarybchik goto fail3; 1168301361Sarybchik } 1169301370Sarybchik if (key_length > length) { 1170301361Sarybchik goto fail4; 1171301361Sarybchik } 1172301361Sarybchik return (B_TRUE); 1173301361Sarybchik 1174301361Sarybchikfail4: 1175301361Sarybchik EFSYS_PROBE(fail4); 1176301361Sarybchikfail3: 1177301361Sarybchik EFSYS_PROBE(fail3); 1178301361Sarybchikfail2: 1179301361Sarybchik EFSYS_PROBE(fail2); 1180301361Sarybchikfail1: 1181342497Sarybchik EFSYS_PROBE1(fail1, boolean_t, B_FALSE); 1182301361Sarybchik 1183301361Sarybchik return (B_FALSE); 1184301361Sarybchik} 1185301361Sarybchik 1186301361Sarybchik __checkReturn efx_rc_t 1187301361Sarybchikefx_lic_v3_read_key( 1188301361Sarybchik __in efx_nic_t *enp, 1189301361Sarybchik __in_bcount(buffer_size) 1190301361Sarybchik caddr_t bufferp, 1191301361Sarybchik __in size_t buffer_size, 1192301361Sarybchik __in uint32_t offset, 1193301361Sarybchik __in uint32_t length, 1194301361Sarybchik __out_bcount_part(key_max_size, *lengthp) 1195301361Sarybchik caddr_t keyp, 1196301361Sarybchik __in size_t key_max_size, 1197301361Sarybchik __out uint32_t *lengthp 1198301361Sarybchik ) 1199301361Sarybchik{ 1200301361Sarybchik _NOTE(ARGUNUSED(enp)) 1201301361Sarybchik 1202301361Sarybchik return ef10_nvram_buffer_get_item(bufferp, buffer_size, 1203301361Sarybchik offset, length, keyp, key_max_size, lengthp); 1204301361Sarybchik} 1205301361Sarybchik 1206301361Sarybchik __checkReturn efx_rc_t 1207301361Sarybchikefx_lic_v3_write_key( 1208301361Sarybchik __in efx_nic_t *enp, 1209301361Sarybchik __in_bcount(buffer_size) 1210301361Sarybchik caddr_t bufferp, 1211301361Sarybchik __in size_t buffer_size, 1212301361Sarybchik __in uint32_t offset, 1213301361Sarybchik __in_bcount(length) caddr_t keyp, 1214301361Sarybchik __in uint32_t length, 1215301361Sarybchik __out uint32_t *lengthp 1216301361Sarybchik ) 1217301361Sarybchik{ 1218301361Sarybchik _NOTE(ARGUNUSED(enp)) 1219301361Sarybchik EFSYS_ASSERT(length <= EFX_LICENSE_V3_KEY_LENGTH_MAX); 1220301361Sarybchik 1221301361Sarybchik return ef10_nvram_buffer_insert_item(bufferp, buffer_size, 1222301361Sarybchik offset, keyp, length, lengthp); 1223301361Sarybchik} 1224301361Sarybchik 1225301361Sarybchik __checkReturn efx_rc_t 1226301361Sarybchikefx_lic_v3_delete_key( 1227301361Sarybchik __in efx_nic_t *enp, 1228301361Sarybchik __in_bcount(buffer_size) 1229301361Sarybchik caddr_t bufferp, 1230301361Sarybchik __in size_t buffer_size, 1231301361Sarybchik __in uint32_t offset, 1232301361Sarybchik __in uint32_t length, 1233301361Sarybchik __in uint32_t end, 1234301361Sarybchik __out uint32_t *deltap 1235301361Sarybchik ) 1236301361Sarybchik{ 1237301361Sarybchik efx_rc_t rc; 1238301361Sarybchik 1239301361Sarybchik _NOTE(ARGUNUSED(enp)) 1240301361Sarybchik 1241301361Sarybchik if ((rc = ef10_nvram_buffer_delete_item(bufferp, 1242301361Sarybchik buffer_size, offset, length, end)) != 0) { 1243301361Sarybchik goto fail1; 1244301361Sarybchik } 1245301361Sarybchik 1246301361Sarybchik *deltap = length; 1247301361Sarybchik 1248301361Sarybchik return (0); 1249301361Sarybchik 1250301361Sarybchikfail1: 1251301361Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1252301361Sarybchik 1253301361Sarybchik return (rc); 1254301361Sarybchik} 1255301361Sarybchik 1256301361Sarybchik __checkReturn efx_rc_t 1257301361Sarybchikefx_lic_v3_create_partition( 1258301361Sarybchik __in efx_nic_t *enp, 1259301361Sarybchik __in_bcount(buffer_size) 1260301361Sarybchik caddr_t bufferp, 1261301361Sarybchik __in size_t buffer_size 1262301361Sarybchik ) 1263301361Sarybchik{ 1264301361Sarybchik efx_rc_t rc; 1265301361Sarybchik 1266311050Sarybchik /* Construct empty partition */ 1267301361Sarybchik if ((rc = ef10_nvram_buffer_create(enp, 1268301361Sarybchik NVRAM_PARTITION_TYPE_LICENSE, 1269301361Sarybchik bufferp, buffer_size)) != 0) { 1270301361Sarybchik rc = EFAULT; 1271301361Sarybchik goto fail1; 1272301361Sarybchik } 1273301361Sarybchik 1274301361Sarybchik return (0); 1275301361Sarybchik 1276301361Sarybchikfail1: 1277301361Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1278301361Sarybchik 1279301361Sarybchik return (rc); 1280301361Sarybchik} 1281301361Sarybchik 1282301361Sarybchik __checkReturn efx_rc_t 1283301361Sarybchikefx_lic_v3_finish_partition( 1284301361Sarybchik __in efx_nic_t *enp, 1285301361Sarybchik __in_bcount(buffer_size) 1286301361Sarybchik caddr_t bufferp, 1287301361Sarybchik __in size_t buffer_size 1288301361Sarybchik ) 1289301361Sarybchik{ 1290301361Sarybchik efx_rc_t rc; 1291301361Sarybchik 1292301361Sarybchik if ((rc = ef10_nvram_buffer_finish(bufferp, 1293301361Sarybchik buffer_size)) != 0) { 1294301361Sarybchik goto fail1; 1295301361Sarybchik } 1296301361Sarybchik 1297311050Sarybchik /* Validate completed partition */ 1298301361Sarybchik if ((rc = ef10_nvram_buffer_validate(enp, NVRAM_PARTITION_TYPE_LICENSE, 1299301361Sarybchik bufferp, buffer_size)) != 0) { 1300301361Sarybchik goto fail2; 1301301361Sarybchik } 1302301361Sarybchik 1303301361Sarybchik return (0); 1304301361Sarybchik 1305301361Sarybchikfail2: 1306301361Sarybchik EFSYS_PROBE(fail2); 1307301361Sarybchikfail1: 1308301361Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1309301361Sarybchik 1310301361Sarybchik return (rc); 1311301361Sarybchik} 1312301361Sarybchik 1313301361Sarybchik 1314293901Sarybchik#endif /* EFSYS_OPT_MEDFORD */ 1315293901Sarybchik 1316293901Sarybchik __checkReturn efx_rc_t 1317293901Sarybchikefx_lic_init( 1318293901Sarybchik __in efx_nic_t *enp) 1319293901Sarybchik{ 1320301340Sarybchik const efx_lic_ops_t *elop; 1321301379Sarybchik efx_key_stats_t eks; 1322293901Sarybchik efx_rc_t rc; 1323293901Sarybchik 1324293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1325293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 1326293901Sarybchik EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_LIC)); 1327293901Sarybchik 1328293901Sarybchik switch (enp->en_family) { 1329293901Sarybchik 1330293901Sarybchik#if EFSYS_OPT_SIENA 1331293901Sarybchik case EFX_FAMILY_SIENA: 1332301340Sarybchik elop = &__efx_lic_v1_ops; 1333293901Sarybchik break; 1334293901Sarybchik#endif /* EFSYS_OPT_SIENA */ 1335293901Sarybchik 1336293901Sarybchik#if EFSYS_OPT_HUNTINGTON 1337293901Sarybchik case EFX_FAMILY_HUNTINGTON: 1338301340Sarybchik elop = &__efx_lic_v2_ops; 1339293901Sarybchik break; 1340293901Sarybchik#endif /* EFSYS_OPT_HUNTINGTON */ 1341293901Sarybchik 1342293901Sarybchik#if EFSYS_OPT_MEDFORD 1343293901Sarybchik case EFX_FAMILY_MEDFORD: 1344301340Sarybchik elop = &__efx_lic_v3_ops; 1345293901Sarybchik break; 1346293901Sarybchik#endif /* EFSYS_OPT_MEDFORD */ 1347293901Sarybchik 1348293901Sarybchik default: 1349293901Sarybchik EFSYS_ASSERT(0); 1350293901Sarybchik rc = ENOTSUP; 1351293901Sarybchik goto fail1; 1352293901Sarybchik } 1353293901Sarybchik 1354293901Sarybchik enp->en_elop = elop; 1355293901Sarybchik enp->en_mod_flags |= EFX_MOD_LIC; 1356293901Sarybchik 1357301379Sarybchik /* Probe for support */ 1358301379Sarybchik if (efx_lic_get_key_stats(enp, &eks) == 0) { 1359301379Sarybchik enp->en_licensing_supported = B_TRUE; 1360301379Sarybchik } else { 1361301379Sarybchik enp->en_licensing_supported = B_FALSE; 1362301379Sarybchik } 1363301379Sarybchik 1364293901Sarybchik return (0); 1365293901Sarybchik 1366293901Sarybchikfail1: 1367293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1368293901Sarybchik 1369293901Sarybchik return (rc); 1370293901Sarybchik} 1371293901Sarybchik 1372301379Sarybchikextern __checkReturn boolean_t 1373301379Sarybchikefx_lic_check_support( 1374301379Sarybchik __in efx_nic_t *enp) 1375301379Sarybchik{ 1376301379Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1377301379Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 1378301379Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1379301379Sarybchik 1380301379Sarybchik return enp->en_licensing_supported; 1381301379Sarybchik} 1382301379Sarybchik 1383293901Sarybchik void 1384293901Sarybchikefx_lic_fini( 1385293901Sarybchik __in efx_nic_t *enp) 1386293901Sarybchik{ 1387293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1388293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 1389293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1390293901Sarybchik 1391293901Sarybchik enp->en_elop = NULL; 1392293901Sarybchik enp->en_mod_flags &= ~EFX_MOD_LIC; 1393293901Sarybchik} 1394293901Sarybchik 1395293901Sarybchik 1396293901Sarybchik __checkReturn efx_rc_t 1397293901Sarybchikefx_lic_update_licenses( 1398293901Sarybchik __in efx_nic_t *enp) 1399293901Sarybchik{ 1400301340Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1401293901Sarybchik efx_rc_t rc; 1402293901Sarybchik 1403293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1404293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1405293901Sarybchik 1406293901Sarybchik if ((rc = elop->elo_update_licenses(enp)) != 0) 1407293901Sarybchik goto fail1; 1408293901Sarybchik 1409293901Sarybchik return (0); 1410293901Sarybchik 1411293901Sarybchikfail1: 1412293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1413293901Sarybchik 1414293901Sarybchik return (rc); 1415293901Sarybchik} 1416293901Sarybchik 1417293901Sarybchik __checkReturn efx_rc_t 1418293901Sarybchikefx_lic_get_key_stats( 1419293901Sarybchik __in efx_nic_t *enp, 1420293901Sarybchik __out efx_key_stats_t *eksp) 1421293901Sarybchik{ 1422301340Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1423293901Sarybchik efx_rc_t rc; 1424293901Sarybchik 1425293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1426293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1427293901Sarybchik 1428293901Sarybchik if ((rc = elop->elo_get_key_stats(enp, eksp)) != 0) 1429293901Sarybchik goto fail1; 1430293901Sarybchik 1431293901Sarybchik return (0); 1432293901Sarybchik 1433293901Sarybchikfail1: 1434293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1435293901Sarybchik 1436293901Sarybchik return (rc); 1437293901Sarybchik} 1438293901Sarybchik 1439293901Sarybchik __checkReturn efx_rc_t 1440293901Sarybchikefx_lic_app_state( 1441293901Sarybchik __in efx_nic_t *enp, 1442293901Sarybchik __in uint64_t app_id, 1443293901Sarybchik __out boolean_t *licensedp) 1444293901Sarybchik{ 1445301340Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1446293901Sarybchik efx_rc_t rc; 1447293901Sarybchik 1448293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1449293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1450293901Sarybchik 1451301362Sarybchik if (elop->elo_app_state == NULL) 1452301362Sarybchik return (ENOTSUP); 1453301362Sarybchik 1454301362Sarybchik if ((rc = elop->elo_app_state(enp, app_id, licensedp)) != 0) 1455293901Sarybchik goto fail1; 1456293901Sarybchik 1457293901Sarybchik return (0); 1458293901Sarybchik 1459293901Sarybchikfail1: 1460293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1461293901Sarybchik 1462293901Sarybchik return (rc); 1463293901Sarybchik} 1464293901Sarybchik 1465293901Sarybchik __checkReturn efx_rc_t 1466293901Sarybchikefx_lic_get_id( 1467293901Sarybchik __in efx_nic_t *enp, 1468293901Sarybchik __in size_t buffer_size, 1469293901Sarybchik __out uint32_t *typep, 1470293901Sarybchik __out size_t *lengthp, 1471293901Sarybchik __out_opt uint8_t *bufferp 1472293901Sarybchik ) 1473293901Sarybchik{ 1474301340Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1475293901Sarybchik efx_rc_t rc; 1476293901Sarybchik 1477293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1478293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1479293901Sarybchik 1480301362Sarybchik if (elop->elo_get_id == NULL) 1481301362Sarybchik return (ENOTSUP); 1482293901Sarybchik 1483293901Sarybchik if ((rc = elop->elo_get_id(enp, buffer_size, typep, 1484293901Sarybchik lengthp, bufferp)) != 0) 1485301362Sarybchik goto fail1; 1486293901Sarybchik 1487293901Sarybchik return (0); 1488293901Sarybchik 1489293901Sarybchikfail1: 1490293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1491293901Sarybchik 1492293901Sarybchik return (rc); 1493293901Sarybchik} 1494293901Sarybchik 1495301361Sarybchik/* Buffer management API - abstracts varying TLV format used for License partition */ 1496301361Sarybchik 1497301361Sarybchik __checkReturn efx_rc_t 1498301361Sarybchikefx_lic_find_start( 1499301361Sarybchik __in efx_nic_t *enp, 1500301361Sarybchik __in_bcount(buffer_size) 1501301361Sarybchik caddr_t bufferp, 1502301361Sarybchik __in size_t buffer_size, 1503301361Sarybchik __out uint32_t *startp 1504301361Sarybchik ) 1505301361Sarybchik{ 1506301361Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1507301361Sarybchik efx_rc_t rc; 1508301361Sarybchik 1509301361Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1510301361Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1511301361Sarybchik 1512301361Sarybchik if ((rc = elop->elo_find_start(enp, bufferp, buffer_size, startp)) != 0) 1513301361Sarybchik goto fail1; 1514301361Sarybchik 1515301361Sarybchik return (0); 1516301361Sarybchik 1517301361Sarybchikfail1: 1518301361Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1519301361Sarybchik 1520301361Sarybchik return (rc); 1521301361Sarybchik} 1522301361Sarybchik 1523301361Sarybchik __checkReturn efx_rc_t 1524301361Sarybchikefx_lic_find_end( 1525301361Sarybchik __in efx_nic_t *enp, 1526301361Sarybchik __in_bcount(buffer_size) 1527301361Sarybchik caddr_t bufferp, 1528301361Sarybchik __in size_t buffer_size, 1529301361Sarybchik __in uint32_t offset, 1530301361Sarybchik __out uint32_t *endp 1531301361Sarybchik ) 1532301361Sarybchik{ 1533301361Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1534301361Sarybchik efx_rc_t rc; 1535301361Sarybchik 1536301361Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1537301361Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1538301361Sarybchik 1539301361Sarybchik if ((rc = elop->elo_find_end(enp, bufferp, buffer_size, offset, endp)) != 0) 1540301361Sarybchik goto fail1; 1541301361Sarybchik 1542301361Sarybchik return (0); 1543301361Sarybchik 1544301361Sarybchikfail1: 1545301361Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1546301361Sarybchik 1547301361Sarybchik return (rc); 1548301361Sarybchik} 1549301361Sarybchik 1550301361Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 1551301361Sarybchikefx_lic_find_key( 1552301361Sarybchik __in efx_nic_t *enp, 1553301361Sarybchik __in_bcount(buffer_size) 1554301361Sarybchik caddr_t bufferp, 1555301361Sarybchik __in size_t buffer_size, 1556301361Sarybchik __in uint32_t offset, 1557301361Sarybchik __out uint32_t *startp, 1558301361Sarybchik __out uint32_t *lengthp 1559301361Sarybchik ) 1560301361Sarybchik{ 1561301361Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1562301361Sarybchik 1563301361Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1564301361Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1565301361Sarybchik 1566301361Sarybchik EFSYS_ASSERT(bufferp); 1567301361Sarybchik EFSYS_ASSERT(startp); 1568301361Sarybchik EFSYS_ASSERT(lengthp); 1569301361Sarybchik 1570301361Sarybchik return (elop->elo_find_key(enp, bufferp, buffer_size, offset, 1571301361Sarybchik startp, lengthp)); 1572301361Sarybchik} 1573301361Sarybchik 1574301361Sarybchik 1575301361Sarybchik/* Validate that the buffer contains a single key in a recognised format. 1576301361Sarybchik** An empty or terminator buffer is not accepted as a valid key. 1577301361Sarybchik*/ 1578301361Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 1579301361Sarybchikefx_lic_validate_key( 1580301361Sarybchik __in efx_nic_t *enp, 1581301361Sarybchik __in_bcount(length) caddr_t keyp, 1582301361Sarybchik __in uint32_t length 1583301361Sarybchik ) 1584301361Sarybchik{ 1585301361Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1586301361Sarybchik boolean_t rc; 1587301361Sarybchik 1588301361Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1589301361Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1590301361Sarybchik 1591301361Sarybchik if ((rc = elop->elo_validate_key(enp, keyp, length)) == B_FALSE) 1592301361Sarybchik goto fail1; 1593301361Sarybchik 1594301361Sarybchik return (B_TRUE); 1595301361Sarybchik 1596301361Sarybchikfail1: 1597301361Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1598301361Sarybchik 1599301361Sarybchik return (rc); 1600301361Sarybchik} 1601301361Sarybchik 1602301361Sarybchik __checkReturn efx_rc_t 1603301361Sarybchikefx_lic_read_key( 1604301361Sarybchik __in efx_nic_t *enp, 1605301361Sarybchik __in_bcount(buffer_size) 1606301361Sarybchik caddr_t bufferp, 1607301361Sarybchik __in size_t buffer_size, 1608301361Sarybchik __in uint32_t offset, 1609301361Sarybchik __in uint32_t length, 1610301361Sarybchik __out_bcount_part(key_max_size, *lengthp) 1611301361Sarybchik caddr_t keyp, 1612301361Sarybchik __in size_t key_max_size, 1613301361Sarybchik __out uint32_t *lengthp 1614301361Sarybchik ) 1615301361Sarybchik{ 1616301361Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1617301361Sarybchik efx_rc_t rc; 1618301361Sarybchik 1619301361Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1620301361Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1621301361Sarybchik 1622301361Sarybchik if ((rc = elop->elo_read_key(enp, bufferp, buffer_size, offset, 1623301361Sarybchik length, keyp, key_max_size, lengthp)) != 0) 1624301361Sarybchik goto fail1; 1625301361Sarybchik 1626301361Sarybchik return (0); 1627301361Sarybchik 1628301361Sarybchikfail1: 1629301361Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1630301361Sarybchik 1631301361Sarybchik return (rc); 1632301361Sarybchik} 1633301361Sarybchik 1634301361Sarybchik __checkReturn efx_rc_t 1635301361Sarybchikefx_lic_write_key( 1636301361Sarybchik __in efx_nic_t *enp, 1637301361Sarybchik __in_bcount(buffer_size) 1638301361Sarybchik caddr_t bufferp, 1639301361Sarybchik __in size_t buffer_size, 1640301361Sarybchik __in uint32_t offset, 1641301361Sarybchik __in_bcount(length) caddr_t keyp, 1642301361Sarybchik __in uint32_t length, 1643301361Sarybchik __out uint32_t *lengthp 1644301361Sarybchik ) 1645301361Sarybchik{ 1646301361Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1647301361Sarybchik efx_rc_t rc; 1648301361Sarybchik 1649301361Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1650301361Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1651301361Sarybchik 1652301361Sarybchik if ((rc = elop->elo_write_key(enp, bufferp, buffer_size, offset, 1653301361Sarybchik keyp, length, lengthp)) != 0) 1654301361Sarybchik goto fail1; 1655301361Sarybchik 1656301361Sarybchik return (0); 1657301361Sarybchik 1658301361Sarybchikfail1: 1659301361Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1660301361Sarybchik 1661301361Sarybchik return (rc); 1662301361Sarybchik} 1663301361Sarybchik 1664301361Sarybchik __checkReturn efx_rc_t 1665301361Sarybchikefx_lic_delete_key( 1666301361Sarybchik __in efx_nic_t *enp, 1667301361Sarybchik __in_bcount(buffer_size) 1668301361Sarybchik caddr_t bufferp, 1669301361Sarybchik __in size_t buffer_size, 1670301361Sarybchik __in uint32_t offset, 1671301361Sarybchik __in uint32_t length, 1672301361Sarybchik __in uint32_t end, 1673301361Sarybchik __out uint32_t *deltap 1674301361Sarybchik ) 1675301361Sarybchik{ 1676301361Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1677301361Sarybchik efx_rc_t rc; 1678301361Sarybchik 1679301361Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1680301361Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1681301361Sarybchik 1682301361Sarybchik if ((rc = elop->elo_delete_key(enp, bufferp, buffer_size, offset, 1683301361Sarybchik length, end, deltap)) != 0) 1684301361Sarybchik goto fail1; 1685301361Sarybchik 1686301361Sarybchik return (0); 1687301361Sarybchik 1688301361Sarybchikfail1: 1689301361Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1690301361Sarybchik 1691301361Sarybchik return (rc); 1692301361Sarybchik} 1693301361Sarybchik 1694301361Sarybchik __checkReturn efx_rc_t 1695301361Sarybchikefx_lic_create_partition( 1696301361Sarybchik __in efx_nic_t *enp, 1697301361Sarybchik __in_bcount(buffer_size) 1698301361Sarybchik caddr_t bufferp, 1699301361Sarybchik __in size_t buffer_size 1700301361Sarybchik ) 1701301361Sarybchik{ 1702301361Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1703301361Sarybchik efx_rc_t rc; 1704301361Sarybchik 1705301361Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1706301361Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1707301361Sarybchik 1708301361Sarybchik if ((rc = elop->elo_create_partition(enp, bufferp, buffer_size)) != 0) 1709301361Sarybchik goto fail1; 1710301361Sarybchik 1711301361Sarybchik return (0); 1712301361Sarybchik 1713301361Sarybchikfail1: 1714301361Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1715301361Sarybchik 1716301361Sarybchik return (rc); 1717301361Sarybchik} 1718301361Sarybchik 1719301361Sarybchik 1720301361Sarybchik __checkReturn efx_rc_t 1721301361Sarybchikefx_lic_finish_partition( 1722301361Sarybchik __in efx_nic_t *enp, 1723301361Sarybchik __in_bcount(buffer_size) 1724301361Sarybchik caddr_t bufferp, 1725301361Sarybchik __in size_t buffer_size 1726301361Sarybchik ) 1727301361Sarybchik{ 1728301361Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1729301361Sarybchik efx_rc_t rc; 1730301361Sarybchik 1731301361Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1732301361Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1733301361Sarybchik 1734301361Sarybchik if ((rc = elop->elo_finish_partition(enp, bufferp, buffer_size)) != 0) 1735301361Sarybchik goto fail1; 1736301361Sarybchik 1737301361Sarybchik return (0); 1738301361Sarybchik 1739301361Sarybchikfail1: 1740301361Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1741301361Sarybchik 1742301361Sarybchik return (rc); 1743301361Sarybchik} 1744301361Sarybchik 1745293901Sarybchik#endif /* EFSYS_OPT_LICENSING */ 1746