1293901Sarybchik/*- 2300607Sarybchik * Copyright (c) 2009-2016 Solarflare Communications Inc. 3293901Sarybchik * All rights reserved. 4293901Sarybchik * 5293901Sarybchik * Redistribution and use in source and binary forms, with or without 6293901Sarybchik * modification, are permitted provided that the following conditions are met: 7293901Sarybchik * 8293901Sarybchik * 1. Redistributions of source code must retain the above copyright notice, 9293901Sarybchik * this list of conditions and the following disclaimer. 10293901Sarybchik * 2. Redistributions in binary form must reproduce the above copyright notice, 11293901Sarybchik * this list of conditions and the following disclaimer in the documentation 12293901Sarybchik * and/or other materials provided with the distribution. 13293901Sarybchik * 14293901Sarybchik * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15293901Sarybchik * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 16293901Sarybchik * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17293901Sarybchik * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 18293901Sarybchik * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19293901Sarybchik * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20293901Sarybchik * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21293901Sarybchik * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22293901Sarybchik * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23293901Sarybchik * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 24293901Sarybchik * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25293901Sarybchik * 26293901Sarybchik * The views and conclusions contained in the software and documentation are 27293901Sarybchik * those of the authors and should not be interpreted as representing official 28293901Sarybchik * policies, either expressed or implied, of the FreeBSD Project. 29293901Sarybchik */ 30293901Sarybchik 31293901Sarybchik#include <sys/cdefs.h> 32293901Sarybchik__FBSDID("$FreeBSD: stable/11/sys/dev/sfxge/common/efx_lic.c 342445 2018-12-25 07:27:45Z arybchik $"); 33293901Sarybchik 34293901Sarybchik#include "efx.h" 35293901Sarybchik#include "efx_impl.h" 36293901Sarybchik 37293901Sarybchik#if EFSYS_OPT_LICENSING 38293901Sarybchik 39299898Sarybchik#include "ef10_tlv_layout.h" 40299898Sarybchik 41299898Sarybchik#if EFSYS_OPT_SIENA | EFSYS_OPT_HUNTINGTON 42299898Sarybchik 43299898Sarybchik __checkReturn efx_rc_t 44299898Sarybchikefx_lic_v1v2_find_start( 45299898Sarybchik __in efx_nic_t *enp, 46299898Sarybchik __in_bcount(buffer_size) 47299898Sarybchik caddr_t bufferp, 48299898Sarybchik __in size_t buffer_size, 49299898Sarybchik __out uint32_t *startp 50299898Sarybchik ); 51299898Sarybchik 52299898Sarybchik __checkReturn efx_rc_t 53299898Sarybchikefx_lic_v1v2_find_end( 54299898Sarybchik __in efx_nic_t *enp, 55299898Sarybchik __in_bcount(buffer_size) 56299898Sarybchik caddr_t bufferp, 57299898Sarybchik __in size_t buffer_size, 58299898Sarybchik __in uint32_t offset, 59299898Sarybchik __out uint32_t *endp 60299898Sarybchik ); 61299898Sarybchik 62299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 63299898Sarybchikefx_lic_v1v2_find_key( 64299898Sarybchik __in efx_nic_t *enp, 65299898Sarybchik __in_bcount(buffer_size) 66299898Sarybchik caddr_t bufferp, 67299898Sarybchik __in size_t buffer_size, 68299898Sarybchik __in uint32_t offset, 69299898Sarybchik __out uint32_t *startp, 70299898Sarybchik __out uint32_t *lengthp 71299898Sarybchik ); 72299898Sarybchik 73299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 74299898Sarybchikefx_lic_v1v2_validate_key( 75299898Sarybchik __in efx_nic_t *enp, 76299898Sarybchik __in_bcount(length) caddr_t keyp, 77299898Sarybchik __in uint32_t length 78299898Sarybchik ); 79299898Sarybchik 80299898Sarybchik __checkReturn efx_rc_t 81299898Sarybchikefx_lic_v1v2_read_key( 82299898Sarybchik __in efx_nic_t *enp, 83299898Sarybchik __in_bcount(buffer_size) 84299898Sarybchik caddr_t bufferp, 85299898Sarybchik __in size_t buffer_size, 86299898Sarybchik __in uint32_t offset, 87299898Sarybchik __in uint32_t length, 88299898Sarybchik __out_bcount_part(key_max_size, *lengthp) 89299898Sarybchik caddr_t keyp, 90299898Sarybchik __in size_t key_max_size, 91299898Sarybchik __out uint32_t *lengthp 92299898Sarybchik ); 93299898Sarybchik 94299898Sarybchik __checkReturn efx_rc_t 95299898Sarybchikefx_lic_v1v2_write_key( 96299898Sarybchik __in efx_nic_t *enp, 97299898Sarybchik __in_bcount(buffer_size) 98299898Sarybchik caddr_t bufferp, 99299898Sarybchik __in size_t buffer_size, 100299898Sarybchik __in uint32_t offset, 101299898Sarybchik __in_bcount(length) caddr_t keyp, 102299898Sarybchik __in uint32_t length, 103299898Sarybchik __out uint32_t *lengthp 104299898Sarybchik ); 105299898Sarybchik 106299898Sarybchik __checkReturn efx_rc_t 107299898Sarybchikefx_lic_v1v2_delete_key( 108299898Sarybchik __in efx_nic_t *enp, 109299898Sarybchik __in_bcount(buffer_size) 110299898Sarybchik caddr_t bufferp, 111299898Sarybchik __in size_t buffer_size, 112299898Sarybchik __in uint32_t offset, 113299898Sarybchik __in uint32_t length, 114299898Sarybchik __in uint32_t end, 115299898Sarybchik __out uint32_t *deltap 116299898Sarybchik ); 117299898Sarybchik 118299898Sarybchik __checkReturn efx_rc_t 119299898Sarybchikefx_lic_v1v2_create_partition( 120299898Sarybchik __in efx_nic_t *enp, 121299898Sarybchik __in_bcount(buffer_size) 122299898Sarybchik caddr_t bufferp, 123299898Sarybchik __in size_t buffer_size 124299898Sarybchik ); 125299898Sarybchik 126299898Sarybchik __checkReturn efx_rc_t 127299898Sarybchikefx_lic_v1v2_finish_partition( 128299898Sarybchik __in efx_nic_t *enp, 129299898Sarybchik __in_bcount(buffer_size) 130299898Sarybchik caddr_t bufferp, 131299898Sarybchik __in size_t buffer_size 132299898Sarybchik ); 133299898Sarybchik 134299898Sarybchik#endif /* EFSYS_OPT_HUNTINGTON | EFSYS_OPT_SIENA */ 135299898Sarybchik 136299898Sarybchik 137293901Sarybchik#if EFSYS_OPT_SIENA 138293901Sarybchik 139293901Sarybchikstatic __checkReturn efx_rc_t 140293901Sarybchikefx_mcdi_fc_license_update_license( 141293901Sarybchik __in efx_nic_t *enp); 142293901Sarybchik 143293901Sarybchikstatic __checkReturn efx_rc_t 144293901Sarybchikefx_mcdi_fc_license_get_key_stats( 145293901Sarybchik __in efx_nic_t *enp, 146293901Sarybchik __out efx_key_stats_t *eksp); 147293901Sarybchik 148299517Sarybchikstatic const efx_lic_ops_t __efx_lic_v1_ops = { 149293901Sarybchik efx_mcdi_fc_license_update_license, /* elo_update_licenses */ 150293901Sarybchik efx_mcdi_fc_license_get_key_stats, /* elo_get_key_stats */ 151293901Sarybchik NULL, /* elo_app_state */ 152293901Sarybchik NULL, /* elo_get_id */ 153299898Sarybchik efx_lic_v1v2_find_start, /* elo_find_start */ 154299898Sarybchik efx_lic_v1v2_find_end, /* elo_find_end */ 155299898Sarybchik efx_lic_v1v2_find_key, /* elo_find_key */ 156299898Sarybchik efx_lic_v1v2_validate_key, /* elo_validate_key */ 157299898Sarybchik efx_lic_v1v2_read_key, /* elo_read_key */ 158299898Sarybchik efx_lic_v1v2_write_key, /* elo_write_key */ 159299898Sarybchik efx_lic_v1v2_delete_key, /* elo_delete_key */ 160299898Sarybchik efx_lic_v1v2_create_partition, /* elo_create_partition */ 161299898Sarybchik efx_lic_v1v2_finish_partition, /* elo_finish_partition */ 162293901Sarybchik}; 163293901Sarybchik 164293901Sarybchik#endif /* EFSYS_OPT_SIENA */ 165293901Sarybchik 166293901Sarybchik#if EFSYS_OPT_HUNTINGTON 167293901Sarybchik 168293901Sarybchikstatic __checkReturn efx_rc_t 169293901Sarybchikefx_mcdi_licensing_update_licenses( 170293901Sarybchik __in efx_nic_t *enp); 171293901Sarybchik 172293901Sarybchikstatic __checkReturn efx_rc_t 173293901Sarybchikefx_mcdi_licensing_get_key_stats( 174293901Sarybchik __in efx_nic_t *enp, 175293901Sarybchik __out efx_key_stats_t *eksp); 176293901Sarybchik 177293901Sarybchikstatic __checkReturn efx_rc_t 178293901Sarybchikefx_mcdi_licensed_app_state( 179293901Sarybchik __in efx_nic_t *enp, 180293901Sarybchik __in uint64_t app_id, 181293901Sarybchik __out boolean_t *licensedp); 182293901Sarybchik 183299517Sarybchikstatic const efx_lic_ops_t __efx_lic_v2_ops = { 184293901Sarybchik efx_mcdi_licensing_update_licenses, /* elo_update_licenses */ 185293901Sarybchik efx_mcdi_licensing_get_key_stats, /* elo_get_key_stats */ 186293901Sarybchik efx_mcdi_licensed_app_state, /* elo_app_state */ 187293901Sarybchik NULL, /* elo_get_id */ 188299898Sarybchik efx_lic_v1v2_find_start, /* elo_find_start */ 189299898Sarybchik efx_lic_v1v2_find_end, /* elo_find_end */ 190299898Sarybchik efx_lic_v1v2_find_key, /* elo_find_key */ 191299898Sarybchik efx_lic_v1v2_validate_key, /* elo_validate_key */ 192299898Sarybchik efx_lic_v1v2_read_key, /* elo_read_key */ 193299898Sarybchik efx_lic_v1v2_write_key, /* elo_write_key */ 194299898Sarybchik efx_lic_v1v2_delete_key, /* elo_delete_key */ 195299898Sarybchik efx_lic_v1v2_create_partition, /* elo_create_partition */ 196299898Sarybchik efx_lic_v1v2_finish_partition, /* elo_finish_partition */ 197293901Sarybchik}; 198293901Sarybchik 199293901Sarybchik#endif /* EFSYS_OPT_HUNTINGTON */ 200293901Sarybchik 201293901Sarybchik#if EFSYS_OPT_MEDFORD 202293901Sarybchik 203293901Sarybchikstatic __checkReturn efx_rc_t 204293901Sarybchikefx_mcdi_licensing_v3_update_licenses( 205293901Sarybchik __in efx_nic_t *enp); 206293901Sarybchik 207293901Sarybchikstatic __checkReturn efx_rc_t 208293901Sarybchikefx_mcdi_licensing_v3_report_license( 209293901Sarybchik __in efx_nic_t *enp, 210293901Sarybchik __out efx_key_stats_t *eksp); 211293901Sarybchik 212293901Sarybchikstatic __checkReturn efx_rc_t 213293901Sarybchikefx_mcdi_licensing_v3_app_state( 214293901Sarybchik __in efx_nic_t *enp, 215293901Sarybchik __in uint64_t app_id, 216293901Sarybchik __out boolean_t *licensedp); 217293901Sarybchik 218293901Sarybchikstatic __checkReturn efx_rc_t 219293901Sarybchikefx_mcdi_licensing_v3_get_id( 220293901Sarybchik __in efx_nic_t *enp, 221293901Sarybchik __in size_t buffer_size, 222293901Sarybchik __out uint32_t *typep, 223293901Sarybchik __out size_t *lengthp, 224293901Sarybchik __out_bcount_part_opt(buffer_size, *lengthp) 225293901Sarybchik uint8_t *bufferp); 226293901Sarybchik 227299898Sarybchik __checkReturn efx_rc_t 228299898Sarybchikefx_lic_v3_find_start( 229299898Sarybchik __in efx_nic_t *enp, 230299898Sarybchik __in_bcount(buffer_size) 231299898Sarybchik caddr_t bufferp, 232299898Sarybchik __in size_t buffer_size, 233299898Sarybchik __out uint32_t *startp 234299898Sarybchik ); 235299898Sarybchik 236299898Sarybchik __checkReturn efx_rc_t 237299898Sarybchikefx_lic_v3_find_end( 238299898Sarybchik __in efx_nic_t *enp, 239299898Sarybchik __in_bcount(buffer_size) 240299898Sarybchik caddr_t bufferp, 241299898Sarybchik __in size_t buffer_size, 242299898Sarybchik __in uint32_t offset, 243299898Sarybchik __out uint32_t *endp 244299898Sarybchik ); 245299898Sarybchik 246299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 247299898Sarybchikefx_lic_v3_find_key( 248299898Sarybchik __in efx_nic_t *enp, 249299898Sarybchik __in_bcount(buffer_size) 250299898Sarybchik caddr_t bufferp, 251299898Sarybchik __in size_t buffer_size, 252299898Sarybchik __in uint32_t offset, 253299898Sarybchik __out uint32_t *startp, 254299898Sarybchik __out uint32_t *lengthp 255299898Sarybchik ); 256299898Sarybchik 257299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 258299898Sarybchikefx_lic_v3_validate_key( 259299898Sarybchik __in efx_nic_t *enp, 260299898Sarybchik __in_bcount(length) caddr_t keyp, 261299898Sarybchik __in uint32_t length 262299898Sarybchik ); 263299898Sarybchik 264299898Sarybchik __checkReturn efx_rc_t 265299898Sarybchikefx_lic_v3_read_key( 266299898Sarybchik __in efx_nic_t *enp, 267299898Sarybchik __in_bcount(buffer_size) 268299898Sarybchik caddr_t bufferp, 269299898Sarybchik __in size_t buffer_size, 270299898Sarybchik __in uint32_t offset, 271299898Sarybchik __in uint32_t length, 272299898Sarybchik __out_bcount_part(key_max_size, *lengthp) 273299898Sarybchik caddr_t keyp, 274299898Sarybchik __in size_t key_max_size, 275299898Sarybchik __out uint32_t *lengthp 276299898Sarybchik ); 277299898Sarybchik 278299898Sarybchik __checkReturn efx_rc_t 279299898Sarybchikefx_lic_v3_write_key( 280299898Sarybchik __in efx_nic_t *enp, 281299898Sarybchik __in_bcount(buffer_size) 282299898Sarybchik caddr_t bufferp, 283299898Sarybchik __in size_t buffer_size, 284299898Sarybchik __in uint32_t offset, 285299898Sarybchik __in_bcount(length) caddr_t keyp, 286299898Sarybchik __in uint32_t length, 287299898Sarybchik __out uint32_t *lengthp 288299898Sarybchik ); 289299898Sarybchik 290299898Sarybchik __checkReturn efx_rc_t 291299898Sarybchikefx_lic_v3_delete_key( 292299898Sarybchik __in efx_nic_t *enp, 293299898Sarybchik __in_bcount(buffer_size) 294299898Sarybchik caddr_t bufferp, 295299898Sarybchik __in size_t buffer_size, 296299898Sarybchik __in uint32_t offset, 297299898Sarybchik __in uint32_t length, 298299898Sarybchik __in uint32_t end, 299299898Sarybchik __out uint32_t *deltap 300299898Sarybchik ); 301299898Sarybchik 302299898Sarybchik __checkReturn efx_rc_t 303299898Sarybchikefx_lic_v3_create_partition( 304299898Sarybchik __in efx_nic_t *enp, 305299898Sarybchik __in_bcount(buffer_size) 306299898Sarybchik caddr_t bufferp, 307299898Sarybchik __in size_t buffer_size 308299898Sarybchik ); 309299898Sarybchik 310299898Sarybchik __checkReturn efx_rc_t 311299898Sarybchikefx_lic_v3_finish_partition( 312299898Sarybchik __in efx_nic_t *enp, 313299898Sarybchik __in_bcount(buffer_size) 314299898Sarybchik caddr_t bufferp, 315299898Sarybchik __in size_t buffer_size 316299898Sarybchik ); 317299898Sarybchik 318299517Sarybchikstatic const efx_lic_ops_t __efx_lic_v3_ops = { 319293901Sarybchik efx_mcdi_licensing_v3_update_licenses, /* elo_update_licenses */ 320293901Sarybchik efx_mcdi_licensing_v3_report_license, /* elo_get_key_stats */ 321293901Sarybchik efx_mcdi_licensing_v3_app_state, /* elo_app_state */ 322293901Sarybchik efx_mcdi_licensing_v3_get_id, /* elo_get_id */ 323299898Sarybchik efx_lic_v3_find_start, /* elo_find_start*/ 324299898Sarybchik efx_lic_v3_find_end, /* elo_find_end */ 325299898Sarybchik efx_lic_v3_find_key, /* elo_find_key */ 326299898Sarybchik efx_lic_v3_validate_key, /* elo_validate_key */ 327299898Sarybchik efx_lic_v3_read_key, /* elo_read_key */ 328299898Sarybchik efx_lic_v3_write_key, /* elo_write_key */ 329299898Sarybchik efx_lic_v3_delete_key, /* elo_delete_key */ 330299898Sarybchik efx_lic_v3_create_partition, /* elo_create_partition */ 331299898Sarybchik efx_lic_v3_finish_partition, /* elo_finish_partition */ 332293901Sarybchik}; 333293901Sarybchik 334293901Sarybchik#endif /* EFSYS_OPT_MEDFORD */ 335293901Sarybchik 336293901Sarybchik 337293901Sarybchik/* V1 Licensing - used in Siena Modena only */ 338293901Sarybchik 339293901Sarybchik#if EFSYS_OPT_SIENA 340293901Sarybchik 341293901Sarybchikstatic __checkReturn efx_rc_t 342293901Sarybchikefx_mcdi_fc_license_update_license( 343293901Sarybchik __in efx_nic_t *enp) 344293901Sarybchik{ 345293901Sarybchik efx_mcdi_req_t req; 346342445Sarybchik 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 351299905Sarybchik 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 357299905Sarybchik MCDI_IN_SET_DWORD(req, FC_IN_CMD, 358299905Sarybchik MC_CMD_FC_OP_LICENSE); 359299905Sarybchik 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; 391342445Sarybchik EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FC_IN_LICENSE_LEN, 392342445Sarybchik MC_CMD_FC_OUT_LICENSE_LEN); 393293901Sarybchik efx_rc_t rc; 394293901Sarybchik 395293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA); 396293901Sarybchik 397299905Sarybchik 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 403299905Sarybchik MCDI_IN_SET_DWORD(req, FC_IN_CMD, 404299905Sarybchik MC_CMD_FC_OP_LICENSE); 405299905Sarybchik 406293901Sarybchik MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP, 407293901Sarybchik MC_CMD_FC_IN_LICENSE_GET_KEY_STATS); 408293901Sarybchik 409299923Sarybchik 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 446299898Sarybchik/* V1 and V2 Partition format - based on a 16-bit TLV format */ 447299898Sarybchik 448299898Sarybchik#if EFSYS_OPT_SIENA | EFSYS_OPT_HUNTINGTON 449299898Sarybchik 450299898Sarybchik/* 451299898Sarybchik * V1/V2 format - defined in SF-108542-TC section 4.2: 452299898Sarybchik * Type (T): 16bit - revision/HMAC algorithm 453299898Sarybchik * Length (L): 16bit - value length in bytes 454299898Sarybchik * Value (V): L bytes - payload 455299898Sarybchik */ 456299898Sarybchik#define EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX (256) 457310841Sarybchik#define EFX_LICENSE_V1V2_HEADER_LENGTH (2 * sizeof(uint16_t)) 458299898Sarybchik 459299898Sarybchik __checkReturn efx_rc_t 460299898Sarybchikefx_lic_v1v2_find_start( 461299898Sarybchik __in efx_nic_t *enp, 462299898Sarybchik __in_bcount(buffer_size) 463299898Sarybchik caddr_t bufferp, 464299898Sarybchik __in size_t buffer_size, 465299898Sarybchik __out uint32_t *startp 466299898Sarybchik ) 467299898Sarybchik{ 468299898Sarybchik _NOTE(ARGUNUSED(enp, bufferp, buffer_size)) 469299898Sarybchik 470299898Sarybchik *startp = 0; 471299898Sarybchik return (0); 472299898Sarybchik} 473299898Sarybchik 474299898Sarybchik __checkReturn efx_rc_t 475299898Sarybchikefx_lic_v1v2_find_end( 476299898Sarybchik __in efx_nic_t *enp, 477299898Sarybchik __in_bcount(buffer_size) 478299898Sarybchik caddr_t bufferp, 479299898Sarybchik __in size_t buffer_size, 480299898Sarybchik __in uint32_t offset, 481299898Sarybchik __out uint32_t *endp 482299898Sarybchik ) 483299898Sarybchik{ 484299898Sarybchik _NOTE(ARGUNUSED(enp, bufferp, buffer_size)) 485299898Sarybchik 486299898Sarybchik *endp = offset + EFX_LICENSE_V1V2_HEADER_LENGTH; 487299898Sarybchik return (0); 488299898Sarybchik} 489299898Sarybchik 490299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 491299898Sarybchikefx_lic_v1v2_find_key( 492299898Sarybchik __in efx_nic_t *enp, 493299898Sarybchik __in_bcount(buffer_size) 494299898Sarybchik caddr_t bufferp, 495299898Sarybchik __in size_t buffer_size, 496299898Sarybchik __in uint32_t offset, 497299898Sarybchik __out uint32_t *startp, 498299898Sarybchik __out uint32_t *lengthp 499299898Sarybchik ) 500299898Sarybchik{ 501299898Sarybchik boolean_t found; 502299898Sarybchik uint16_t tlv_type; 503299898Sarybchik uint16_t tlv_length; 504299898Sarybchik 505299898Sarybchik _NOTE(ARGUNUSED(enp)) 506299898Sarybchik 507301125Sarybchik if ((size_t)buffer_size - offset < EFX_LICENSE_V1V2_HEADER_LENGTH) 508299898Sarybchik goto fail1; 509299898Sarybchik 510310922Sarybchik tlv_type = __LE_TO_CPU_16(((uint16_t *)&bufferp[offset])[0]); 511310922Sarybchik tlv_length = __LE_TO_CPU_16(((uint16_t *)&bufferp[offset])[1]); 512299898Sarybchik if ((tlv_length > EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX) || 513299898Sarybchik (tlv_type == 0 && tlv_length == 0)) { 514299898Sarybchik found = B_FALSE; 515299898Sarybchik } else { 516299898Sarybchik *startp = offset; 517299898Sarybchik *lengthp = tlv_length + EFX_LICENSE_V1V2_HEADER_LENGTH; 518299898Sarybchik found = B_TRUE; 519299898Sarybchik } 520299898Sarybchik return (found); 521299898Sarybchik 522299898Sarybchikfail1: 523342426Sarybchik EFSYS_PROBE1(fail1, boolean_t, B_FALSE); 524299898Sarybchik 525299898Sarybchik return (B_FALSE); 526299898Sarybchik} 527299898Sarybchik 528299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 529299898Sarybchikefx_lic_v1v2_validate_key( 530299898Sarybchik __in efx_nic_t *enp, 531299898Sarybchik __in_bcount(length) caddr_t keyp, 532299898Sarybchik __in uint32_t length 533299898Sarybchik ) 534299898Sarybchik{ 535299898Sarybchik uint16_t tlv_type; 536299898Sarybchik uint16_t tlv_length; 537299898Sarybchik 538299898Sarybchik _NOTE(ARGUNUSED(enp)) 539299898Sarybchik 540299898Sarybchik if (length < EFX_LICENSE_V1V2_HEADER_LENGTH) { 541299898Sarybchik goto fail1; 542299898Sarybchik } 543299898Sarybchik 544310922Sarybchik tlv_type = __LE_TO_CPU_16(((uint16_t *)keyp)[0]); 545310922Sarybchik tlv_length = __LE_TO_CPU_16(((uint16_t *)keyp)[1]); 546299898Sarybchik 547301125Sarybchik if (tlv_length > EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX) { 548299898Sarybchik goto fail2; 549299898Sarybchik } 550299898Sarybchik if (tlv_type == 0) { 551299898Sarybchik goto fail3; 552299898Sarybchik } 553299898Sarybchik if ((tlv_length + EFX_LICENSE_V1V2_HEADER_LENGTH) != length) { 554299898Sarybchik goto fail4; 555299898Sarybchik } 556299898Sarybchik 557299898Sarybchik return (B_TRUE); 558299898Sarybchik 559299898Sarybchikfail4: 560299898Sarybchik EFSYS_PROBE(fail4); 561299898Sarybchikfail3: 562299898Sarybchik EFSYS_PROBE(fail3); 563299898Sarybchikfail2: 564299898Sarybchik EFSYS_PROBE(fail2); 565299898Sarybchikfail1: 566342426Sarybchik EFSYS_PROBE1(fail1, boolean_t, B_FALSE); 567299898Sarybchik 568299898Sarybchik return (B_FALSE); 569299898Sarybchik} 570299898Sarybchik 571299898Sarybchik 572299898Sarybchik __checkReturn efx_rc_t 573299898Sarybchikefx_lic_v1v2_read_key( 574299898Sarybchik __in efx_nic_t *enp, 575299898Sarybchik __in_bcount(buffer_size) 576299898Sarybchik caddr_t bufferp, 577299898Sarybchik __in size_t buffer_size, 578299898Sarybchik __in uint32_t offset, 579299898Sarybchik __in uint32_t length, 580299898Sarybchik __out_bcount_part(key_max_size, *lengthp) 581299898Sarybchik caddr_t keyp, 582299898Sarybchik __in size_t key_max_size, 583299898Sarybchik __out uint32_t *lengthp 584299898Sarybchik ) 585299898Sarybchik{ 586299898Sarybchik efx_rc_t rc; 587299898Sarybchik 588342430Sarybchik _NOTE(ARGUNUSED(enp, buffer_size)) 589299898Sarybchik EFSYS_ASSERT(length <= (EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX + 590299898Sarybchik EFX_LICENSE_V1V2_HEADER_LENGTH)); 591299898Sarybchik 592299898Sarybchik if (key_max_size < length) { 593299898Sarybchik rc = ENOSPC; 594299898Sarybchik goto fail1; 595299898Sarybchik } 596299898Sarybchik memcpy(keyp, &bufferp[offset], length); 597299898Sarybchik 598299898Sarybchik *lengthp = length; 599299898Sarybchik 600299898Sarybchik return (0); 601299898Sarybchik 602299898Sarybchikfail1: 603299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 604299898Sarybchik 605299898Sarybchik return (rc); 606299898Sarybchik} 607299898Sarybchik 608299898Sarybchik __checkReturn efx_rc_t 609299898Sarybchikefx_lic_v1v2_write_key( 610299898Sarybchik __in efx_nic_t *enp, 611299898Sarybchik __in_bcount(buffer_size) 612299898Sarybchik caddr_t bufferp, 613299898Sarybchik __in size_t buffer_size, 614299898Sarybchik __in uint32_t offset, 615299898Sarybchik __in_bcount(length) caddr_t keyp, 616299898Sarybchik __in uint32_t length, 617299898Sarybchik __out uint32_t *lengthp 618299898Sarybchik ) 619299898Sarybchik{ 620299898Sarybchik efx_rc_t rc; 621299898Sarybchik 622299898Sarybchik _NOTE(ARGUNUSED(enp)) 623299898Sarybchik EFSYS_ASSERT(length <= (EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX + 624299898Sarybchik EFX_LICENSE_V1V2_HEADER_LENGTH)); 625299898Sarybchik 626310916Sarybchik /* Ensure space for terminator remains */ 627299898Sarybchik if ((offset + length) > 628310919Sarybchik (buffer_size - EFX_LICENSE_V1V2_HEADER_LENGTH)) { 629299898Sarybchik rc = ENOSPC; 630299898Sarybchik goto fail1; 631299898Sarybchik } 632299898Sarybchik 633299898Sarybchik memcpy(bufferp + offset, keyp, length); 634299898Sarybchik 635299898Sarybchik *lengthp = length; 636299898Sarybchik 637299898Sarybchik return (0); 638299898Sarybchik 639299898Sarybchikfail1: 640299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 641299898Sarybchik 642299898Sarybchik return (rc); 643299898Sarybchik} 644299898Sarybchik 645299898Sarybchik __checkReturn efx_rc_t 646299898Sarybchikefx_lic_v1v2_delete_key( 647299898Sarybchik __in efx_nic_t *enp, 648299898Sarybchik __in_bcount(buffer_size) 649299898Sarybchik caddr_t bufferp, 650299898Sarybchik __in size_t buffer_size, 651299898Sarybchik __in uint32_t offset, 652299898Sarybchik __in uint32_t length, 653299898Sarybchik __in uint32_t end, 654299898Sarybchik __out uint32_t *deltap 655299898Sarybchik ) 656299898Sarybchik{ 657299898Sarybchik uint32_t move_start = offset + length; 658299898Sarybchik uint32_t move_length = end - move_start; 659299898Sarybchik 660342430Sarybchik _NOTE(ARGUNUSED(enp, buffer_size)) 661299898Sarybchik EFSYS_ASSERT(end <= buffer_size); 662299898Sarybchik 663310916Sarybchik /* Shift everything after the key down */ 664299898Sarybchik memmove(bufferp + offset, bufferp + move_start, move_length); 665299898Sarybchik 666299898Sarybchik *deltap = length; 667299898Sarybchik 668299898Sarybchik return (0); 669299898Sarybchik} 670299898Sarybchik 671299898Sarybchik __checkReturn efx_rc_t 672299898Sarybchikefx_lic_v1v2_create_partition( 673299898Sarybchik __in efx_nic_t *enp, 674299898Sarybchik __in_bcount(buffer_size) 675299898Sarybchik caddr_t bufferp, 676299898Sarybchik __in size_t buffer_size 677299898Sarybchik ) 678299898Sarybchik{ 679342430Sarybchik _NOTE(ARGUNUSED(enp, buffer_size)) 680299898Sarybchik EFSYS_ASSERT(EFX_LICENSE_V1V2_HEADER_LENGTH <= buffer_size); 681299898Sarybchik 682310916Sarybchik /* Write terminator */ 683299898Sarybchik memset(bufferp, '\0', EFX_LICENSE_V1V2_HEADER_LENGTH); 684299898Sarybchik return (0); 685299898Sarybchik} 686299898Sarybchik 687299898Sarybchik 688299898Sarybchik __checkReturn efx_rc_t 689299898Sarybchikefx_lic_v1v2_finish_partition( 690299898Sarybchik __in efx_nic_t *enp, 691299898Sarybchik __in_bcount(buffer_size) 692299898Sarybchik caddr_t bufferp, 693299898Sarybchik __in size_t buffer_size 694299898Sarybchik ) 695299898Sarybchik{ 696299898Sarybchik _NOTE(ARGUNUSED(enp, bufferp, buffer_size)) 697299898Sarybchik 698299898Sarybchik return (0); 699299898Sarybchik} 700299898Sarybchik 701299898Sarybchik#endif /* EFSYS_OPT_HUNTINGTON | EFSYS_OPT_SIENA */ 702299898Sarybchik 703299898Sarybchik 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; 715342445Sarybchik EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LICENSED_APP_STATE_IN_LEN, 716342445Sarybchik 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; 773342445Sarybchik 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; 815342445Sarybchik EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_IN_LEN, 816342445Sarybchik 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; 878342445Sarybchik 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; 913342445Sarybchik EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_V3_IN_LEN, 914342445Sarybchik 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 928299923Sarybchik 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; 975342445Sarybchik EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN, 976342445Sarybchik 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; 1032342445Sarybchik EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_GET_ID_V3_IN_LEN, 1033342445Sarybchik 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; 1049299898Sarybchik 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 1053299923Sarybchik 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, 1076310841Sarybchik bufferp + MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST, 1077310841Sarybchik *lengthp); 1078310841Sarybchik memset(bufferp + (*lengthp), 0, 1079310841Sarybchik 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 1092299898Sarybchik/* V3 format uses Huntington TLV format partition. See SF-108797-SW */ 1093299898Sarybchik#define EFX_LICENSE_V3_KEY_LENGTH_MIN (64) 1094299907Sarybchik#define EFX_LICENSE_V3_KEY_LENGTH_MAX (160) 1095293901Sarybchik 1096299898Sarybchik __checkReturn efx_rc_t 1097299898Sarybchikefx_lic_v3_find_start( 1098299898Sarybchik __in efx_nic_t *enp, 1099299898Sarybchik __in_bcount(buffer_size) 1100299898Sarybchik caddr_t bufferp, 1101299898Sarybchik __in size_t buffer_size, 1102299898Sarybchik __out uint32_t *startp 1103299898Sarybchik ) 1104299898Sarybchik{ 1105299898Sarybchik _NOTE(ARGUNUSED(enp)) 1106299898Sarybchik 1107299898Sarybchik return ef10_nvram_buffer_find_item_start(bufferp, buffer_size, startp); 1108299898Sarybchik} 1109299898Sarybchik 1110299898Sarybchik __checkReturn efx_rc_t 1111299898Sarybchikefx_lic_v3_find_end( 1112299898Sarybchik __in efx_nic_t *enp, 1113299898Sarybchik __in_bcount(buffer_size) 1114299898Sarybchik caddr_t bufferp, 1115299898Sarybchik __in size_t buffer_size, 1116299898Sarybchik __in uint32_t offset, 1117299898Sarybchik __out uint32_t *endp 1118299898Sarybchik ) 1119299898Sarybchik{ 1120299898Sarybchik _NOTE(ARGUNUSED(enp)) 1121299898Sarybchik 1122299898Sarybchik return ef10_nvram_buffer_find_end(bufferp, buffer_size, offset, endp); 1123299898Sarybchik} 1124299898Sarybchik 1125299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 1126299898Sarybchikefx_lic_v3_find_key( 1127299898Sarybchik __in efx_nic_t *enp, 1128299898Sarybchik __in_bcount(buffer_size) 1129299898Sarybchik caddr_t bufferp, 1130299898Sarybchik __in size_t buffer_size, 1131299898Sarybchik __in uint32_t offset, 1132299898Sarybchik __out uint32_t *startp, 1133299898Sarybchik __out uint32_t *lengthp 1134299898Sarybchik ) 1135299898Sarybchik{ 1136299898Sarybchik _NOTE(ARGUNUSED(enp)) 1137299898Sarybchik 1138299898Sarybchik return ef10_nvram_buffer_find_item(bufferp, buffer_size, 1139299898Sarybchik offset, startp, lengthp); 1140299898Sarybchik} 1141299898Sarybchik 1142299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 1143299898Sarybchikefx_lic_v3_validate_key( 1144299898Sarybchik __in efx_nic_t *enp, 1145299898Sarybchik __in_bcount(length) caddr_t keyp, 1146299898Sarybchik __in uint32_t length 1147299898Sarybchik ) 1148299898Sarybchik{ 1149310916Sarybchik /* Check key is a valid V3 key */ 1150299898Sarybchik uint8_t key_type; 1151299898Sarybchik uint8_t key_length; 1152299898Sarybchik 1153299898Sarybchik _NOTE(ARGUNUSED(enp)) 1154299898Sarybchik 1155299898Sarybchik if (length < EFX_LICENSE_V3_KEY_LENGTH_MIN) { 1156299898Sarybchik goto fail1; 1157299898Sarybchik } 1158299898Sarybchik 1159299911Sarybchik if (length > EFX_LICENSE_V3_KEY_LENGTH_MAX) { 1160299911Sarybchik goto fail2; 1161299911Sarybchik } 1162299911Sarybchik 1163310922Sarybchik key_type = ((uint8_t *)keyp)[0]; 1164310922Sarybchik key_length = ((uint8_t *)keyp)[1]; 1165299898Sarybchik 1166299898Sarybchik if (key_type < 3) { 1167299898Sarybchik goto fail3; 1168299898Sarybchik } 1169299911Sarybchik if (key_length > length) { 1170299898Sarybchik goto fail4; 1171299898Sarybchik } 1172299898Sarybchik return (B_TRUE); 1173299898Sarybchik 1174299898Sarybchikfail4: 1175299898Sarybchik EFSYS_PROBE(fail4); 1176299898Sarybchikfail3: 1177299898Sarybchik EFSYS_PROBE(fail3); 1178299898Sarybchikfail2: 1179299898Sarybchik EFSYS_PROBE(fail2); 1180299898Sarybchikfail1: 1181342426Sarybchik EFSYS_PROBE1(fail1, boolean_t, B_FALSE); 1182299898Sarybchik 1183299898Sarybchik return (B_FALSE); 1184299898Sarybchik} 1185299898Sarybchik 1186299898Sarybchik __checkReturn efx_rc_t 1187299898Sarybchikefx_lic_v3_read_key( 1188299898Sarybchik __in efx_nic_t *enp, 1189299898Sarybchik __in_bcount(buffer_size) 1190299898Sarybchik caddr_t bufferp, 1191299898Sarybchik __in size_t buffer_size, 1192299898Sarybchik __in uint32_t offset, 1193299898Sarybchik __in uint32_t length, 1194299898Sarybchik __out_bcount_part(key_max_size, *lengthp) 1195299898Sarybchik caddr_t keyp, 1196299898Sarybchik __in size_t key_max_size, 1197299898Sarybchik __out uint32_t *lengthp 1198299898Sarybchik ) 1199299898Sarybchik{ 1200299898Sarybchik _NOTE(ARGUNUSED(enp)) 1201299898Sarybchik 1202299898Sarybchik return ef10_nvram_buffer_get_item(bufferp, buffer_size, 1203299898Sarybchik offset, length, keyp, key_max_size, lengthp); 1204299898Sarybchik} 1205299898Sarybchik 1206299898Sarybchik __checkReturn efx_rc_t 1207299898Sarybchikefx_lic_v3_write_key( 1208299898Sarybchik __in efx_nic_t *enp, 1209299898Sarybchik __in_bcount(buffer_size) 1210299898Sarybchik caddr_t bufferp, 1211299898Sarybchik __in size_t buffer_size, 1212299898Sarybchik __in uint32_t offset, 1213299898Sarybchik __in_bcount(length) caddr_t keyp, 1214299898Sarybchik __in uint32_t length, 1215299898Sarybchik __out uint32_t *lengthp 1216299898Sarybchik ) 1217299898Sarybchik{ 1218299898Sarybchik _NOTE(ARGUNUSED(enp)) 1219299898Sarybchik EFSYS_ASSERT(length <= EFX_LICENSE_V3_KEY_LENGTH_MAX); 1220299898Sarybchik 1221299898Sarybchik return ef10_nvram_buffer_insert_item(bufferp, buffer_size, 1222299898Sarybchik offset, keyp, length, lengthp); 1223299898Sarybchik} 1224299898Sarybchik 1225299898Sarybchik __checkReturn efx_rc_t 1226299898Sarybchikefx_lic_v3_delete_key( 1227299898Sarybchik __in efx_nic_t *enp, 1228299898Sarybchik __in_bcount(buffer_size) 1229299898Sarybchik caddr_t bufferp, 1230299898Sarybchik __in size_t buffer_size, 1231299898Sarybchik __in uint32_t offset, 1232299898Sarybchik __in uint32_t length, 1233299898Sarybchik __in uint32_t end, 1234299898Sarybchik __out uint32_t *deltap 1235299898Sarybchik ) 1236299898Sarybchik{ 1237299898Sarybchik efx_rc_t rc; 1238299898Sarybchik 1239299898Sarybchik _NOTE(ARGUNUSED(enp)) 1240299898Sarybchik 1241299898Sarybchik if ((rc = ef10_nvram_buffer_delete_item(bufferp, 1242299898Sarybchik buffer_size, offset, length, end)) != 0) { 1243299898Sarybchik goto fail1; 1244299898Sarybchik } 1245299898Sarybchik 1246299898Sarybchik *deltap = length; 1247299898Sarybchik 1248299898Sarybchik return (0); 1249299898Sarybchik 1250299898Sarybchikfail1: 1251299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1252299898Sarybchik 1253299898Sarybchik return (rc); 1254299898Sarybchik} 1255299898Sarybchik 1256299898Sarybchik __checkReturn efx_rc_t 1257299898Sarybchikefx_lic_v3_create_partition( 1258299898Sarybchik __in efx_nic_t *enp, 1259299898Sarybchik __in_bcount(buffer_size) 1260299898Sarybchik caddr_t bufferp, 1261299898Sarybchik __in size_t buffer_size 1262299898Sarybchik ) 1263299898Sarybchik{ 1264299898Sarybchik efx_rc_t rc; 1265299898Sarybchik 1266310916Sarybchik /* Construct empty partition */ 1267299898Sarybchik if ((rc = ef10_nvram_buffer_create(enp, 1268299898Sarybchik NVRAM_PARTITION_TYPE_LICENSE, 1269299898Sarybchik bufferp, buffer_size)) != 0) { 1270299898Sarybchik rc = EFAULT; 1271299898Sarybchik goto fail1; 1272299898Sarybchik } 1273299898Sarybchik 1274299898Sarybchik return (0); 1275299898Sarybchik 1276299898Sarybchikfail1: 1277299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1278299898Sarybchik 1279299898Sarybchik return (rc); 1280299898Sarybchik} 1281299898Sarybchik 1282299898Sarybchik __checkReturn efx_rc_t 1283299898Sarybchikefx_lic_v3_finish_partition( 1284299898Sarybchik __in efx_nic_t *enp, 1285299898Sarybchik __in_bcount(buffer_size) 1286299898Sarybchik caddr_t bufferp, 1287299898Sarybchik __in size_t buffer_size 1288299898Sarybchik ) 1289299898Sarybchik{ 1290299898Sarybchik efx_rc_t rc; 1291299898Sarybchik 1292299898Sarybchik if ((rc = ef10_nvram_buffer_finish(bufferp, 1293299898Sarybchik buffer_size)) != 0) { 1294299898Sarybchik goto fail1; 1295299898Sarybchik } 1296299898Sarybchik 1297310916Sarybchik /* Validate completed partition */ 1298299898Sarybchik if ((rc = ef10_nvram_buffer_validate(enp, NVRAM_PARTITION_TYPE_LICENSE, 1299299898Sarybchik bufferp, buffer_size)) != 0) { 1300299898Sarybchik goto fail2; 1301299898Sarybchik } 1302299898Sarybchik 1303299898Sarybchik return (0); 1304299898Sarybchik 1305299898Sarybchikfail2: 1306299898Sarybchik EFSYS_PROBE(fail2); 1307299898Sarybchikfail1: 1308299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1309299898Sarybchik 1310299898Sarybchik return (rc); 1311299898Sarybchik} 1312299898Sarybchik 1313299898Sarybchik 1314293901Sarybchik#endif /* EFSYS_OPT_MEDFORD */ 1315293901Sarybchik 1316293901Sarybchik __checkReturn efx_rc_t 1317293901Sarybchikefx_lic_init( 1318293901Sarybchik __in efx_nic_t *enp) 1319293901Sarybchik{ 1320299517Sarybchik const efx_lic_ops_t *elop; 1321300007Sarybchik 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: 1332299517Sarybchik elop = &__efx_lic_v1_ops; 1333293901Sarybchik break; 1334293901Sarybchik#endif /* EFSYS_OPT_SIENA */ 1335293901Sarybchik 1336293901Sarybchik#if EFSYS_OPT_HUNTINGTON 1337293901Sarybchik case EFX_FAMILY_HUNTINGTON: 1338299517Sarybchik elop = &__efx_lic_v2_ops; 1339293901Sarybchik break; 1340293901Sarybchik#endif /* EFSYS_OPT_HUNTINGTON */ 1341293901Sarybchik 1342293901Sarybchik#if EFSYS_OPT_MEDFORD 1343293901Sarybchik case EFX_FAMILY_MEDFORD: 1344299517Sarybchik 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 1357300007Sarybchik /* Probe for support */ 1358300007Sarybchik if (efx_lic_get_key_stats(enp, &eks) == 0) { 1359300007Sarybchik enp->en_licensing_supported = B_TRUE; 1360300007Sarybchik } else { 1361300007Sarybchik enp->en_licensing_supported = B_FALSE; 1362300007Sarybchik } 1363300007Sarybchik 1364293901Sarybchik return (0); 1365293901Sarybchik 1366293901Sarybchikfail1: 1367293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1368293901Sarybchik 1369293901Sarybchik return (rc); 1370293901Sarybchik} 1371293901Sarybchik 1372300007Sarybchikextern __checkReturn boolean_t 1373300007Sarybchikefx_lic_check_support( 1374300007Sarybchik __in efx_nic_t *enp) 1375300007Sarybchik{ 1376300007Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1377300007Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 1378300007Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1379300007Sarybchik 1380300007Sarybchik return enp->en_licensing_supported; 1381300007Sarybchik} 1382300007Sarybchik 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{ 1400299517Sarybchik 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{ 1422299517Sarybchik 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{ 1445299517Sarybchik 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 1451299899Sarybchik if (elop->elo_app_state == NULL) 1452299899Sarybchik return (ENOTSUP); 1453299899Sarybchik 1454299899Sarybchik 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{ 1474299517Sarybchik 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 1480299899Sarybchik if (elop->elo_get_id == NULL) 1481299899Sarybchik return (ENOTSUP); 1482293901Sarybchik 1483293901Sarybchik if ((rc = elop->elo_get_id(enp, buffer_size, typep, 1484293901Sarybchik lengthp, bufferp)) != 0) 1485299899Sarybchik goto fail1; 1486293901Sarybchik 1487293901Sarybchik return (0); 1488293901Sarybchik 1489293901Sarybchikfail1: 1490293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1491293901Sarybchik 1492293901Sarybchik return (rc); 1493293901Sarybchik} 1494293901Sarybchik 1495299898Sarybchik/* Buffer management API - abstracts varying TLV format used for License partition */ 1496299898Sarybchik 1497299898Sarybchik __checkReturn efx_rc_t 1498299898Sarybchikefx_lic_find_start( 1499299898Sarybchik __in efx_nic_t *enp, 1500299898Sarybchik __in_bcount(buffer_size) 1501299898Sarybchik caddr_t bufferp, 1502299898Sarybchik __in size_t buffer_size, 1503299898Sarybchik __out uint32_t *startp 1504299898Sarybchik ) 1505299898Sarybchik{ 1506299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1507299898Sarybchik efx_rc_t rc; 1508299898Sarybchik 1509299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1510299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1511299898Sarybchik 1512299898Sarybchik if ((rc = elop->elo_find_start(enp, bufferp, buffer_size, startp)) != 0) 1513299898Sarybchik goto fail1; 1514299898Sarybchik 1515299898Sarybchik return (0); 1516299898Sarybchik 1517299898Sarybchikfail1: 1518299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1519299898Sarybchik 1520299898Sarybchik return (rc); 1521299898Sarybchik} 1522299898Sarybchik 1523299898Sarybchik __checkReturn efx_rc_t 1524299898Sarybchikefx_lic_find_end( 1525299898Sarybchik __in efx_nic_t *enp, 1526299898Sarybchik __in_bcount(buffer_size) 1527299898Sarybchik caddr_t bufferp, 1528299898Sarybchik __in size_t buffer_size, 1529299898Sarybchik __in uint32_t offset, 1530299898Sarybchik __out uint32_t *endp 1531299898Sarybchik ) 1532299898Sarybchik{ 1533299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1534299898Sarybchik efx_rc_t rc; 1535299898Sarybchik 1536299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1537299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1538299898Sarybchik 1539299898Sarybchik if ((rc = elop->elo_find_end(enp, bufferp, buffer_size, offset, endp)) != 0) 1540299898Sarybchik goto fail1; 1541299898Sarybchik 1542299898Sarybchik return (0); 1543299898Sarybchik 1544299898Sarybchikfail1: 1545299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1546299898Sarybchik 1547299898Sarybchik return (rc); 1548299898Sarybchik} 1549299898Sarybchik 1550299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 1551299898Sarybchikefx_lic_find_key( 1552299898Sarybchik __in efx_nic_t *enp, 1553299898Sarybchik __in_bcount(buffer_size) 1554299898Sarybchik caddr_t bufferp, 1555299898Sarybchik __in size_t buffer_size, 1556299898Sarybchik __in uint32_t offset, 1557299898Sarybchik __out uint32_t *startp, 1558299898Sarybchik __out uint32_t *lengthp 1559299898Sarybchik ) 1560299898Sarybchik{ 1561299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1562299898Sarybchik 1563299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1564299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1565299898Sarybchik 1566299898Sarybchik EFSYS_ASSERT(bufferp); 1567299898Sarybchik EFSYS_ASSERT(startp); 1568299898Sarybchik EFSYS_ASSERT(lengthp); 1569299898Sarybchik 1570299898Sarybchik return (elop->elo_find_key(enp, bufferp, buffer_size, offset, 1571299898Sarybchik startp, lengthp)); 1572299898Sarybchik} 1573299898Sarybchik 1574299898Sarybchik 1575299898Sarybchik/* Validate that the buffer contains a single key in a recognised format. 1576299898Sarybchik** An empty or terminator buffer is not accepted as a valid key. 1577299898Sarybchik*/ 1578299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 1579299898Sarybchikefx_lic_validate_key( 1580299898Sarybchik __in efx_nic_t *enp, 1581299898Sarybchik __in_bcount(length) caddr_t keyp, 1582299898Sarybchik __in uint32_t length 1583299898Sarybchik ) 1584299898Sarybchik{ 1585299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1586299898Sarybchik boolean_t rc; 1587299898Sarybchik 1588299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1589299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1590299898Sarybchik 1591299898Sarybchik if ((rc = elop->elo_validate_key(enp, keyp, length)) == B_FALSE) 1592299898Sarybchik goto fail1; 1593299898Sarybchik 1594299898Sarybchik return (B_TRUE); 1595299898Sarybchik 1596299898Sarybchikfail1: 1597299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1598299898Sarybchik 1599299898Sarybchik return (rc); 1600299898Sarybchik} 1601299898Sarybchik 1602299898Sarybchik __checkReturn efx_rc_t 1603299898Sarybchikefx_lic_read_key( 1604299898Sarybchik __in efx_nic_t *enp, 1605299898Sarybchik __in_bcount(buffer_size) 1606299898Sarybchik caddr_t bufferp, 1607299898Sarybchik __in size_t buffer_size, 1608299898Sarybchik __in uint32_t offset, 1609299898Sarybchik __in uint32_t length, 1610299898Sarybchik __out_bcount_part(key_max_size, *lengthp) 1611299898Sarybchik caddr_t keyp, 1612299898Sarybchik __in size_t key_max_size, 1613299898Sarybchik __out uint32_t *lengthp 1614299898Sarybchik ) 1615299898Sarybchik{ 1616299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1617299898Sarybchik efx_rc_t rc; 1618299898Sarybchik 1619299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1620299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1621299898Sarybchik 1622299898Sarybchik if ((rc = elop->elo_read_key(enp, bufferp, buffer_size, offset, 1623299898Sarybchik length, keyp, key_max_size, lengthp)) != 0) 1624299898Sarybchik goto fail1; 1625299898Sarybchik 1626299898Sarybchik return (0); 1627299898Sarybchik 1628299898Sarybchikfail1: 1629299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1630299898Sarybchik 1631299898Sarybchik return (rc); 1632299898Sarybchik} 1633299898Sarybchik 1634299898Sarybchik __checkReturn efx_rc_t 1635299898Sarybchikefx_lic_write_key( 1636299898Sarybchik __in efx_nic_t *enp, 1637299898Sarybchik __in_bcount(buffer_size) 1638299898Sarybchik caddr_t bufferp, 1639299898Sarybchik __in size_t buffer_size, 1640299898Sarybchik __in uint32_t offset, 1641299898Sarybchik __in_bcount(length) caddr_t keyp, 1642299898Sarybchik __in uint32_t length, 1643299898Sarybchik __out uint32_t *lengthp 1644299898Sarybchik ) 1645299898Sarybchik{ 1646299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1647299898Sarybchik efx_rc_t rc; 1648299898Sarybchik 1649299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1650299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1651299898Sarybchik 1652299898Sarybchik if ((rc = elop->elo_write_key(enp, bufferp, buffer_size, offset, 1653299898Sarybchik keyp, length, lengthp)) != 0) 1654299898Sarybchik goto fail1; 1655299898Sarybchik 1656299898Sarybchik return (0); 1657299898Sarybchik 1658299898Sarybchikfail1: 1659299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1660299898Sarybchik 1661299898Sarybchik return (rc); 1662299898Sarybchik} 1663299898Sarybchik 1664299898Sarybchik __checkReturn efx_rc_t 1665299898Sarybchikefx_lic_delete_key( 1666299898Sarybchik __in efx_nic_t *enp, 1667299898Sarybchik __in_bcount(buffer_size) 1668299898Sarybchik caddr_t bufferp, 1669299898Sarybchik __in size_t buffer_size, 1670299898Sarybchik __in uint32_t offset, 1671299898Sarybchik __in uint32_t length, 1672299898Sarybchik __in uint32_t end, 1673299898Sarybchik __out uint32_t *deltap 1674299898Sarybchik ) 1675299898Sarybchik{ 1676299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1677299898Sarybchik efx_rc_t rc; 1678299898Sarybchik 1679299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1680299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1681299898Sarybchik 1682299898Sarybchik if ((rc = elop->elo_delete_key(enp, bufferp, buffer_size, offset, 1683299898Sarybchik length, end, deltap)) != 0) 1684299898Sarybchik goto fail1; 1685299898Sarybchik 1686299898Sarybchik return (0); 1687299898Sarybchik 1688299898Sarybchikfail1: 1689299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1690299898Sarybchik 1691299898Sarybchik return (rc); 1692299898Sarybchik} 1693299898Sarybchik 1694299898Sarybchik __checkReturn efx_rc_t 1695299898Sarybchikefx_lic_create_partition( 1696299898Sarybchik __in efx_nic_t *enp, 1697299898Sarybchik __in_bcount(buffer_size) 1698299898Sarybchik caddr_t bufferp, 1699299898Sarybchik __in size_t buffer_size 1700299898Sarybchik ) 1701299898Sarybchik{ 1702299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1703299898Sarybchik efx_rc_t rc; 1704299898Sarybchik 1705299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1706299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1707299898Sarybchik 1708299898Sarybchik if ((rc = elop->elo_create_partition(enp, bufferp, buffer_size)) != 0) 1709299898Sarybchik goto fail1; 1710299898Sarybchik 1711299898Sarybchik return (0); 1712299898Sarybchik 1713299898Sarybchikfail1: 1714299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1715299898Sarybchik 1716299898Sarybchik return (rc); 1717299898Sarybchik} 1718299898Sarybchik 1719299898Sarybchik 1720299898Sarybchik __checkReturn efx_rc_t 1721299898Sarybchikefx_lic_finish_partition( 1722299898Sarybchik __in efx_nic_t *enp, 1723299898Sarybchik __in_bcount(buffer_size) 1724299898Sarybchik caddr_t bufferp, 1725299898Sarybchik __in size_t buffer_size 1726299898Sarybchik ) 1727299898Sarybchik{ 1728299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1729299898Sarybchik efx_rc_t rc; 1730299898Sarybchik 1731299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1732299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1733299898Sarybchik 1734299898Sarybchik if ((rc = elop->elo_finish_partition(enp, bufferp, buffer_size)) != 0) 1735299898Sarybchik goto fail1; 1736299898Sarybchik 1737299898Sarybchik return (0); 1738299898Sarybchik 1739299898Sarybchikfail1: 1740299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1741299898Sarybchik 1742299898Sarybchik return (rc); 1743299898Sarybchik} 1744299898Sarybchik 1745293901Sarybchik#endif /* EFSYS_OPT_LICENSING */ 1746