efx_lic.c revision 299899
1293901Sarybchik/*- 2293901Sarybchik * Copyright (c) 2009-2015 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: head/sys/dev/sfxge/common/efx_lic.c 299899 2016-05-16 06:19:17Z arybchik $"); 33293901Sarybchik 34293901Sarybchik#include "efx.h" 35293901Sarybchik#include "efx_impl.h" 36293901Sarybchik 37293901Sarybchik#if EFSYS_OPT_LICENSING 38293901Sarybchik 39299898Sarybchik#include "ef10_tlv_layout.h" 40299898Sarybchik 41299898Sarybchik#if EFSYS_OPT_SIENA | EFSYS_OPT_HUNTINGTON 42299898Sarybchik 43299898Sarybchik __checkReturn efx_rc_t 44299898Sarybchikefx_lic_v1v2_find_start( 45299898Sarybchik __in efx_nic_t *enp, 46299898Sarybchik __in_bcount(buffer_size) 47299898Sarybchik caddr_t bufferp, 48299898Sarybchik __in size_t buffer_size, 49299898Sarybchik __out uint32_t *startp 50299898Sarybchik ); 51299898Sarybchik 52299898Sarybchik __checkReturn efx_rc_t 53299898Sarybchikefx_lic_v1v2_find_end( 54299898Sarybchik __in efx_nic_t *enp, 55299898Sarybchik __in_bcount(buffer_size) 56299898Sarybchik caddr_t bufferp, 57299898Sarybchik __in size_t buffer_size, 58299898Sarybchik __in uint32_t offset, 59299898Sarybchik __out uint32_t *endp 60299898Sarybchik ); 61299898Sarybchik 62299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 63299898Sarybchikefx_lic_v1v2_find_key( 64299898Sarybchik __in efx_nic_t *enp, 65299898Sarybchik __in_bcount(buffer_size) 66299898Sarybchik caddr_t bufferp, 67299898Sarybchik __in size_t buffer_size, 68299898Sarybchik __in uint32_t offset, 69299898Sarybchik __out uint32_t *startp, 70299898Sarybchik __out uint32_t *lengthp 71299898Sarybchik ); 72299898Sarybchik 73299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 74299898Sarybchikefx_lic_v1v2_validate_key( 75299898Sarybchik __in efx_nic_t *enp, 76299898Sarybchik __in_bcount(length) caddr_t keyp, 77299898Sarybchik __in uint32_t length 78299898Sarybchik ); 79299898Sarybchik 80299898Sarybchik __checkReturn efx_rc_t 81299898Sarybchikefx_lic_v1v2_read_key( 82299898Sarybchik __in efx_nic_t *enp, 83299898Sarybchik __in_bcount(buffer_size) 84299898Sarybchik caddr_t bufferp, 85299898Sarybchik __in size_t buffer_size, 86299898Sarybchik __in uint32_t offset, 87299898Sarybchik __in uint32_t length, 88299898Sarybchik __out_bcount_part(key_max_size, *lengthp) 89299898Sarybchik caddr_t keyp, 90299898Sarybchik __in size_t key_max_size, 91299898Sarybchik __out uint32_t *lengthp 92299898Sarybchik ); 93299898Sarybchik 94299898Sarybchik __checkReturn efx_rc_t 95299898Sarybchikefx_lic_v1v2_write_key( 96299898Sarybchik __in efx_nic_t *enp, 97299898Sarybchik __in_bcount(buffer_size) 98299898Sarybchik caddr_t bufferp, 99299898Sarybchik __in size_t buffer_size, 100299898Sarybchik __in uint32_t offset, 101299898Sarybchik __in_bcount(length) caddr_t keyp, 102299898Sarybchik __in uint32_t length, 103299898Sarybchik __out uint32_t *lengthp 104299898Sarybchik ); 105299898Sarybchik 106299898Sarybchik __checkReturn efx_rc_t 107299898Sarybchikefx_lic_v1v2_delete_key( 108299898Sarybchik __in efx_nic_t *enp, 109299898Sarybchik __in_bcount(buffer_size) 110299898Sarybchik caddr_t bufferp, 111299898Sarybchik __in size_t buffer_size, 112299898Sarybchik __in uint32_t offset, 113299898Sarybchik __in uint32_t length, 114299898Sarybchik __in uint32_t end, 115299898Sarybchik __out uint32_t *deltap 116299898Sarybchik ); 117299898Sarybchik 118299898Sarybchik __checkReturn efx_rc_t 119299898Sarybchikefx_lic_v1v2_create_partition( 120299898Sarybchik __in efx_nic_t *enp, 121299898Sarybchik __in_bcount(buffer_size) 122299898Sarybchik caddr_t bufferp, 123299898Sarybchik __in size_t buffer_size 124299898Sarybchik ); 125299898Sarybchik 126299898Sarybchik __checkReturn efx_rc_t 127299898Sarybchikefx_lic_v1v2_finish_partition( 128299898Sarybchik __in efx_nic_t *enp, 129299898Sarybchik __in_bcount(buffer_size) 130299898Sarybchik caddr_t bufferp, 131299898Sarybchik __in size_t buffer_size 132299898Sarybchik ); 133299898Sarybchik 134299898Sarybchik#endif /* EFSYS_OPT_HUNTINGTON | EFSYS_OPT_SIENA */ 135299898Sarybchik 136299898Sarybchik 137293901Sarybchik#if EFSYS_OPT_SIENA 138293901Sarybchik 139293901Sarybchikstatic __checkReturn efx_rc_t 140293901Sarybchikefx_mcdi_fc_license_update_license( 141293901Sarybchik __in efx_nic_t *enp); 142293901Sarybchik 143293901Sarybchikstatic __checkReturn efx_rc_t 144293901Sarybchikefx_mcdi_fc_license_get_key_stats( 145293901Sarybchik __in efx_nic_t *enp, 146293901Sarybchik __out efx_key_stats_t *eksp); 147293901Sarybchik 148299517Sarybchikstatic const efx_lic_ops_t __efx_lic_v1_ops = { 149293901Sarybchik efx_mcdi_fc_license_update_license, /* elo_update_licenses */ 150293901Sarybchik efx_mcdi_fc_license_get_key_stats, /* elo_get_key_stats */ 151293901Sarybchik NULL, /* elo_app_state */ 152293901Sarybchik NULL, /* elo_get_id */ 153299898Sarybchik efx_lic_v1v2_find_start, /* elo_find_start */ 154299898Sarybchik efx_lic_v1v2_find_end, /* elo_find_end */ 155299898Sarybchik efx_lic_v1v2_find_key, /* elo_find_key */ 156299898Sarybchik efx_lic_v1v2_validate_key, /* elo_validate_key */ 157299898Sarybchik efx_lic_v1v2_read_key, /* elo_read_key */ 158299898Sarybchik efx_lic_v1v2_write_key, /* elo_write_key */ 159299898Sarybchik efx_lic_v1v2_delete_key, /* elo_delete_key */ 160299898Sarybchik efx_lic_v1v2_create_partition, /* elo_create_partition */ 161299898Sarybchik efx_lic_v1v2_finish_partition, /* elo_finish_partition */ 162293901Sarybchik}; 163293901Sarybchik 164293901Sarybchik#endif /* EFSYS_OPT_SIENA */ 165293901Sarybchik 166293901Sarybchik#if EFSYS_OPT_HUNTINGTON 167293901Sarybchik 168293901Sarybchikstatic __checkReturn efx_rc_t 169293901Sarybchikefx_mcdi_licensing_update_licenses( 170293901Sarybchik __in efx_nic_t *enp); 171293901Sarybchik 172293901Sarybchikstatic __checkReturn efx_rc_t 173293901Sarybchikefx_mcdi_licensing_get_key_stats( 174293901Sarybchik __in efx_nic_t *enp, 175293901Sarybchik __out efx_key_stats_t *eksp); 176293901Sarybchik 177293901Sarybchikstatic __checkReturn efx_rc_t 178293901Sarybchikefx_mcdi_licensed_app_state( 179293901Sarybchik __in efx_nic_t *enp, 180293901Sarybchik __in uint64_t app_id, 181293901Sarybchik __out boolean_t *licensedp); 182293901Sarybchik 183299517Sarybchikstatic const efx_lic_ops_t __efx_lic_v2_ops = { 184293901Sarybchik efx_mcdi_licensing_update_licenses, /* elo_update_licenses */ 185293901Sarybchik efx_mcdi_licensing_get_key_stats, /* elo_get_key_stats */ 186293901Sarybchik efx_mcdi_licensed_app_state, /* elo_app_state */ 187293901Sarybchik NULL, /* elo_get_id */ 188299898Sarybchik efx_lic_v1v2_find_start, /* elo_find_start */ 189299898Sarybchik efx_lic_v1v2_find_end, /* elo_find_end */ 190299898Sarybchik efx_lic_v1v2_find_key, /* elo_find_key */ 191299898Sarybchik efx_lic_v1v2_validate_key, /* elo_validate_key */ 192299898Sarybchik efx_lic_v1v2_read_key, /* elo_read_key */ 193299898Sarybchik efx_lic_v1v2_write_key, /* elo_write_key */ 194299898Sarybchik efx_lic_v1v2_delete_key, /* elo_delete_key */ 195299898Sarybchik efx_lic_v1v2_create_partition, /* elo_create_partition */ 196299898Sarybchik efx_lic_v1v2_finish_partition, /* elo_finish_partition */ 197293901Sarybchik}; 198293901Sarybchik 199293901Sarybchik#endif /* EFSYS_OPT_HUNTINGTON */ 200293901Sarybchik 201293901Sarybchik#if EFSYS_OPT_MEDFORD 202293901Sarybchik 203293901Sarybchikstatic __checkReturn efx_rc_t 204293901Sarybchikefx_mcdi_licensing_v3_update_licenses( 205293901Sarybchik __in efx_nic_t *enp); 206293901Sarybchik 207293901Sarybchikstatic __checkReturn efx_rc_t 208293901Sarybchikefx_mcdi_licensing_v3_report_license( 209293901Sarybchik __in efx_nic_t *enp, 210293901Sarybchik __out efx_key_stats_t *eksp); 211293901Sarybchik 212293901Sarybchikstatic __checkReturn efx_rc_t 213293901Sarybchikefx_mcdi_licensing_v3_app_state( 214293901Sarybchik __in efx_nic_t *enp, 215293901Sarybchik __in uint64_t app_id, 216293901Sarybchik __out boolean_t *licensedp); 217293901Sarybchik 218293901Sarybchikstatic __checkReturn efx_rc_t 219293901Sarybchikefx_mcdi_licensing_v3_get_id( 220293901Sarybchik __in efx_nic_t *enp, 221293901Sarybchik __in size_t buffer_size, 222293901Sarybchik __out uint32_t *typep, 223293901Sarybchik __out size_t *lengthp, 224293901Sarybchik __out_bcount_part_opt(buffer_size, *lengthp) 225293901Sarybchik uint8_t *bufferp); 226293901Sarybchik 227299898Sarybchik __checkReturn efx_rc_t 228299898Sarybchikefx_lic_v3_find_start( 229299898Sarybchik __in efx_nic_t *enp, 230299898Sarybchik __in_bcount(buffer_size) 231299898Sarybchik caddr_t bufferp, 232299898Sarybchik __in size_t buffer_size, 233299898Sarybchik __out uint32_t *startp 234299898Sarybchik ); 235299898Sarybchik 236299898Sarybchik __checkReturn efx_rc_t 237299898Sarybchikefx_lic_v3_find_end( 238299898Sarybchik __in efx_nic_t *enp, 239299898Sarybchik __in_bcount(buffer_size) 240299898Sarybchik caddr_t bufferp, 241299898Sarybchik __in size_t buffer_size, 242299898Sarybchik __in uint32_t offset, 243299898Sarybchik __out uint32_t *endp 244299898Sarybchik ); 245299898Sarybchik 246299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 247299898Sarybchikefx_lic_v3_find_key( 248299898Sarybchik __in efx_nic_t *enp, 249299898Sarybchik __in_bcount(buffer_size) 250299898Sarybchik caddr_t bufferp, 251299898Sarybchik __in size_t buffer_size, 252299898Sarybchik __in uint32_t offset, 253299898Sarybchik __out uint32_t *startp, 254299898Sarybchik __out uint32_t *lengthp 255299898Sarybchik ); 256299898Sarybchik 257299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 258299898Sarybchikefx_lic_v3_validate_key( 259299898Sarybchik __in efx_nic_t *enp, 260299898Sarybchik __in_bcount(length) caddr_t keyp, 261299898Sarybchik __in uint32_t length 262299898Sarybchik ); 263299898Sarybchik 264299898Sarybchik __checkReturn efx_rc_t 265299898Sarybchikefx_lic_v3_read_key( 266299898Sarybchik __in efx_nic_t *enp, 267299898Sarybchik __in_bcount(buffer_size) 268299898Sarybchik caddr_t bufferp, 269299898Sarybchik __in size_t buffer_size, 270299898Sarybchik __in uint32_t offset, 271299898Sarybchik __in uint32_t length, 272299898Sarybchik __out_bcount_part(key_max_size, *lengthp) 273299898Sarybchik caddr_t keyp, 274299898Sarybchik __in size_t key_max_size, 275299898Sarybchik __out uint32_t *lengthp 276299898Sarybchik ); 277299898Sarybchik 278299898Sarybchik __checkReturn efx_rc_t 279299898Sarybchikefx_lic_v3_write_key( 280299898Sarybchik __in efx_nic_t *enp, 281299898Sarybchik __in_bcount(buffer_size) 282299898Sarybchik caddr_t bufferp, 283299898Sarybchik __in size_t buffer_size, 284299898Sarybchik __in uint32_t offset, 285299898Sarybchik __in_bcount(length) caddr_t keyp, 286299898Sarybchik __in uint32_t length, 287299898Sarybchik __out uint32_t *lengthp 288299898Sarybchik ); 289299898Sarybchik 290299898Sarybchik __checkReturn efx_rc_t 291299898Sarybchikefx_lic_v3_delete_key( 292299898Sarybchik __in efx_nic_t *enp, 293299898Sarybchik __in_bcount(buffer_size) 294299898Sarybchik caddr_t bufferp, 295299898Sarybchik __in size_t buffer_size, 296299898Sarybchik __in uint32_t offset, 297299898Sarybchik __in uint32_t length, 298299898Sarybchik __in uint32_t end, 299299898Sarybchik __out uint32_t *deltap 300299898Sarybchik ); 301299898Sarybchik 302299898Sarybchik __checkReturn efx_rc_t 303299898Sarybchikefx_lic_v3_create_partition( 304299898Sarybchik __in efx_nic_t *enp, 305299898Sarybchik __in_bcount(buffer_size) 306299898Sarybchik caddr_t bufferp, 307299898Sarybchik __in size_t buffer_size 308299898Sarybchik ); 309299898Sarybchik 310299898Sarybchik __checkReturn efx_rc_t 311299898Sarybchikefx_lic_v3_finish_partition( 312299898Sarybchik __in efx_nic_t *enp, 313299898Sarybchik __in_bcount(buffer_size) 314299898Sarybchik caddr_t bufferp, 315299898Sarybchik __in size_t buffer_size 316299898Sarybchik ); 317299898Sarybchik 318299517Sarybchikstatic const efx_lic_ops_t __efx_lic_v3_ops = { 319293901Sarybchik efx_mcdi_licensing_v3_update_licenses, /* elo_update_licenses */ 320293901Sarybchik efx_mcdi_licensing_v3_report_license, /* elo_get_key_stats */ 321293901Sarybchik efx_mcdi_licensing_v3_app_state, /* elo_app_state */ 322293901Sarybchik efx_mcdi_licensing_v3_get_id, /* elo_get_id */ 323299898Sarybchik efx_lic_v3_find_start, /* elo_find_start*/ 324299898Sarybchik efx_lic_v3_find_end, /* elo_find_end */ 325299898Sarybchik efx_lic_v3_find_key, /* elo_find_key */ 326299898Sarybchik efx_lic_v3_validate_key, /* elo_validate_key */ 327299898Sarybchik efx_lic_v3_read_key, /* elo_read_key */ 328299898Sarybchik efx_lic_v3_write_key, /* elo_write_key */ 329299898Sarybchik efx_lic_v3_delete_key, /* elo_delete_key */ 330299898Sarybchik efx_lic_v3_create_partition, /* elo_create_partition */ 331299898Sarybchik efx_lic_v3_finish_partition, /* elo_finish_partition */ 332293901Sarybchik}; 333293901Sarybchik 334293901Sarybchik#endif /* EFSYS_OPT_MEDFORD */ 335293901Sarybchik 336293901Sarybchik 337293901Sarybchik/* V1 Licensing - used in Siena Modena only */ 338293901Sarybchik 339293901Sarybchik#if EFSYS_OPT_SIENA 340293901Sarybchik 341293901Sarybchikstatic __checkReturn efx_rc_t 342293901Sarybchikefx_mcdi_fc_license_update_license( 343293901Sarybchik __in efx_nic_t *enp) 344293901Sarybchik{ 345293901Sarybchik efx_mcdi_req_t req; 346293901Sarybchik uint8_t payload[MC_CMD_FC_IN_LICENSE_LEN]; 347293901Sarybchik efx_rc_t rc; 348293901Sarybchik 349293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA); 350293901Sarybchik 351293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 352293901Sarybchik req.emr_cmd = MC_CMD_FC_OP_LICENSE; 353293901Sarybchik req.emr_in_buf = payload; 354293901Sarybchik req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN; 355293901Sarybchik req.emr_out_buf = payload; 356293901Sarybchik req.emr_out_length = 0; 357293901Sarybchik 358293901Sarybchik MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP, 359293901Sarybchik MC_CMD_FC_IN_LICENSE_UPDATE_LICENSE); 360293901Sarybchik 361293901Sarybchik efx_mcdi_execute(enp, &req); 362293901Sarybchik 363293901Sarybchik if (req.emr_rc != 0) { 364293901Sarybchik rc = req.emr_rc; 365293901Sarybchik goto fail1; 366293901Sarybchik } 367293901Sarybchik 368293901Sarybchik if (req.emr_out_length_used != 0) { 369293901Sarybchik rc = EIO; 370293901Sarybchik goto fail2; 371293901Sarybchik } 372293901Sarybchik 373293901Sarybchik return (0); 374293901Sarybchik 375293901Sarybchikfail2: 376293901Sarybchik EFSYS_PROBE(fail2); 377293901Sarybchikfail1: 378293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 379293901Sarybchik 380293901Sarybchik return (rc); 381293901Sarybchik} 382293901Sarybchik 383293901Sarybchikstatic __checkReturn efx_rc_t 384293901Sarybchikefx_mcdi_fc_license_get_key_stats( 385293901Sarybchik __in efx_nic_t *enp, 386293901Sarybchik __out efx_key_stats_t *eksp) 387293901Sarybchik{ 388293901Sarybchik efx_mcdi_req_t req; 389293901Sarybchik uint8_t payload[MAX(MC_CMD_FC_IN_LICENSE_LEN, 390293901Sarybchik MC_CMD_FC_OUT_LICENSE_LEN)]; 391293901Sarybchik efx_rc_t rc; 392293901Sarybchik 393293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA); 394293901Sarybchik 395293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 396293901Sarybchik req.emr_cmd = MC_CMD_FC_OP_LICENSE; 397293901Sarybchik req.emr_in_buf = payload; 398293901Sarybchik req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN; 399293901Sarybchik req.emr_out_buf = payload; 400293901Sarybchik req.emr_out_length = MC_CMD_FC_OUT_LICENSE_LEN; 401293901Sarybchik 402293901Sarybchik MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP, 403293901Sarybchik MC_CMD_FC_IN_LICENSE_GET_KEY_STATS); 404293901Sarybchik 405293901Sarybchik efx_mcdi_execute(enp, &req); 406293901Sarybchik 407293901Sarybchik if (req.emr_rc != 0) { 408293901Sarybchik rc = req.emr_rc; 409293901Sarybchik goto fail1; 410293901Sarybchik } 411293901Sarybchik 412293901Sarybchik if (req.emr_out_length_used < MC_CMD_FC_OUT_LICENSE_LEN) { 413293901Sarybchik rc = EMSGSIZE; 414293901Sarybchik goto fail2; 415293901Sarybchik } 416293901Sarybchik 417293901Sarybchik eksp->eks_valid = 418293901Sarybchik MCDI_OUT_DWORD(req, FC_OUT_LICENSE_VALID_KEYS); 419293901Sarybchik eksp->eks_invalid = 420293901Sarybchik MCDI_OUT_DWORD(req, FC_OUT_LICENSE_INVALID_KEYS); 421293901Sarybchik eksp->eks_blacklisted = 422293901Sarybchik MCDI_OUT_DWORD(req, FC_OUT_LICENSE_BLACKLISTED_KEYS); 423293901Sarybchik eksp->eks_unverifiable = 0; 424293901Sarybchik eksp->eks_wrong_node = 0; 425293901Sarybchik eksp->eks_licensed_apps_lo = 0; 426293901Sarybchik eksp->eks_licensed_apps_hi = 0; 427293901Sarybchik eksp->eks_licensed_features_lo = 0; 428293901Sarybchik eksp->eks_licensed_features_hi = 0; 429293901Sarybchik 430293901Sarybchik return (0); 431293901Sarybchik 432293901Sarybchikfail2: 433293901Sarybchik EFSYS_PROBE(fail2); 434293901Sarybchikfail1: 435293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 436293901Sarybchik 437293901Sarybchik return (rc); 438293901Sarybchik} 439293901Sarybchik 440293901Sarybchik#endif /* EFSYS_OPT_SIENA */ 441293901Sarybchik 442299898Sarybchik/* V1 and V2 Partition format - based on a 16-bit TLV format */ 443299898Sarybchik 444299898Sarybchik#if EFSYS_OPT_SIENA | EFSYS_OPT_HUNTINGTON 445299898Sarybchik 446299898Sarybchik/* 447299898Sarybchik * V1/V2 format - defined in SF-108542-TC section 4.2: 448299898Sarybchik * Type (T): 16bit - revision/HMAC algorithm 449299898Sarybchik * Length (L): 16bit - value length in bytes 450299898Sarybchik * Value (V): L bytes - payload 451299898Sarybchik */ 452299898Sarybchik#define EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX (256) 453299898Sarybchik#define EFX_LICENSE_V1V2_HEADER_LENGTH (2*sizeof(uint16_t)) 454299898Sarybchik 455299898Sarybchik __checkReturn efx_rc_t 456299898Sarybchikefx_lic_v1v2_find_start( 457299898Sarybchik __in efx_nic_t *enp, 458299898Sarybchik __in_bcount(buffer_size) 459299898Sarybchik caddr_t bufferp, 460299898Sarybchik __in size_t buffer_size, 461299898Sarybchik __out uint32_t *startp 462299898Sarybchik ) 463299898Sarybchik{ 464299898Sarybchik _NOTE(ARGUNUSED(enp, bufferp, buffer_size)) 465299898Sarybchik 466299898Sarybchik *startp = 0; 467299898Sarybchik return (0); 468299898Sarybchik} 469299898Sarybchik 470299898Sarybchik __checkReturn efx_rc_t 471299898Sarybchikefx_lic_v1v2_find_end( 472299898Sarybchik __in efx_nic_t *enp, 473299898Sarybchik __in_bcount(buffer_size) 474299898Sarybchik caddr_t bufferp, 475299898Sarybchik __in size_t buffer_size, 476299898Sarybchik __in uint32_t offset, 477299898Sarybchik __out uint32_t *endp 478299898Sarybchik ) 479299898Sarybchik{ 480299898Sarybchik _NOTE(ARGUNUSED(enp, bufferp, buffer_size)) 481299898Sarybchik 482299898Sarybchik *endp = offset + EFX_LICENSE_V1V2_HEADER_LENGTH; 483299898Sarybchik return (0); 484299898Sarybchik} 485299898Sarybchik 486299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 487299898Sarybchikefx_lic_v1v2_find_key( 488299898Sarybchik __in efx_nic_t *enp, 489299898Sarybchik __in_bcount(buffer_size) 490299898Sarybchik caddr_t bufferp, 491299898Sarybchik __in size_t buffer_size, 492299898Sarybchik __in uint32_t offset, 493299898Sarybchik __out uint32_t *startp, 494299898Sarybchik __out uint32_t *lengthp 495299898Sarybchik ) 496299898Sarybchik{ 497299898Sarybchik boolean_t found; 498299898Sarybchik uint16_t tlv_type; 499299898Sarybchik uint16_t tlv_length; 500299898Sarybchik 501299898Sarybchik _NOTE(ARGUNUSED(enp)) 502299898Sarybchik 503299898Sarybchik if((size_t)buffer_size - offset < EFX_LICENSE_V1V2_HEADER_LENGTH) 504299898Sarybchik goto fail1; 505299898Sarybchik 506299898Sarybchik tlv_type = __LE_TO_CPU_16(((uint16_t*)&bufferp[offset])[0]); 507299898Sarybchik tlv_length = __LE_TO_CPU_16(((uint16_t*)&bufferp[offset])[1]); 508299898Sarybchik if ((tlv_length > EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX) || 509299898Sarybchik (tlv_type == 0 && tlv_length == 0)) { 510299898Sarybchik found = B_FALSE; 511299898Sarybchik } else { 512299898Sarybchik *startp = offset; 513299898Sarybchik *lengthp = tlv_length + EFX_LICENSE_V1V2_HEADER_LENGTH; 514299898Sarybchik found = B_TRUE; 515299898Sarybchik } 516299898Sarybchik return (found); 517299898Sarybchik 518299898Sarybchikfail1: 519299898Sarybchik EFSYS_PROBE(fail1); 520299898Sarybchik 521299898Sarybchik return (B_FALSE); 522299898Sarybchik} 523299898Sarybchik 524299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 525299898Sarybchikefx_lic_v1v2_validate_key( 526299898Sarybchik __in efx_nic_t *enp, 527299898Sarybchik __in_bcount(length) caddr_t keyp, 528299898Sarybchik __in uint32_t length 529299898Sarybchik ) 530299898Sarybchik{ 531299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 532299898Sarybchik efx_rc_t rc; 533299898Sarybchik uint16_t tlv_type; 534299898Sarybchik uint16_t tlv_length; 535299898Sarybchik 536299898Sarybchik _NOTE(ARGUNUSED(enp)) 537299898Sarybchik 538299898Sarybchik if (length < EFX_LICENSE_V1V2_HEADER_LENGTH) { 539299898Sarybchik goto fail1; 540299898Sarybchik } 541299898Sarybchik 542299898Sarybchik tlv_type = __LE_TO_CPU_16(((uint16_t*)keyp)[0]); 543299898Sarybchik tlv_length = __LE_TO_CPU_16(((uint16_t*)keyp)[1]); 544299898Sarybchik 545299898Sarybchik if(tlv_length > EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX) { 546299898Sarybchik goto fail2; 547299898Sarybchik } 548299898Sarybchik if (tlv_type == 0) { 549299898Sarybchik goto fail3; 550299898Sarybchik } 551299898Sarybchik if ((tlv_length + EFX_LICENSE_V1V2_HEADER_LENGTH) != length) { 552299898Sarybchik goto fail4; 553299898Sarybchik } 554299898Sarybchik 555299898Sarybchik return (B_TRUE); 556299898Sarybchik 557299898Sarybchikfail4: 558299898Sarybchik EFSYS_PROBE(fail4); 559299898Sarybchikfail3: 560299898Sarybchik EFSYS_PROBE(fail3); 561299898Sarybchikfail2: 562299898Sarybchik EFSYS_PROBE(fail2); 563299898Sarybchikfail1: 564299898Sarybchik EFSYS_PROBE(fail1); 565299898Sarybchik 566299898Sarybchik return (B_FALSE); 567299898Sarybchik} 568299898Sarybchik 569299898Sarybchik 570299898Sarybchik __checkReturn efx_rc_t 571299898Sarybchikefx_lic_v1v2_read_key( 572299898Sarybchik __in efx_nic_t *enp, 573299898Sarybchik __in_bcount(buffer_size) 574299898Sarybchik caddr_t bufferp, 575299898Sarybchik __in size_t buffer_size, 576299898Sarybchik __in uint32_t offset, 577299898Sarybchik __in uint32_t length, 578299898Sarybchik __out_bcount_part(key_max_size, *lengthp) 579299898Sarybchik caddr_t keyp, 580299898Sarybchik __in size_t key_max_size, 581299898Sarybchik __out uint32_t *lengthp 582299898Sarybchik ) 583299898Sarybchik{ 584299898Sarybchik efx_rc_t rc; 585299898Sarybchik 586299898Sarybchik _NOTE(ARGUNUSED(enp)) 587299898Sarybchik EFSYS_ASSERT(length <= (EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX + 588299898Sarybchik EFX_LICENSE_V1V2_HEADER_LENGTH)); 589299898Sarybchik 590299898Sarybchik if (key_max_size < length) { 591299898Sarybchik rc = ENOSPC; 592299898Sarybchik goto fail1; 593299898Sarybchik } 594299898Sarybchik memcpy(keyp, &bufferp[offset], length); 595299898Sarybchik 596299898Sarybchik *lengthp = length; 597299898Sarybchik 598299898Sarybchik return (0); 599299898Sarybchik 600299898Sarybchikfail1: 601299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 602299898Sarybchik 603299898Sarybchik return (rc); 604299898Sarybchik} 605299898Sarybchik 606299898Sarybchik __checkReturn efx_rc_t 607299898Sarybchikefx_lic_v1v2_write_key( 608299898Sarybchik __in efx_nic_t *enp, 609299898Sarybchik __in_bcount(buffer_size) 610299898Sarybchik caddr_t bufferp, 611299898Sarybchik __in size_t buffer_size, 612299898Sarybchik __in uint32_t offset, 613299898Sarybchik __in_bcount(length) caddr_t keyp, 614299898Sarybchik __in uint32_t length, 615299898Sarybchik __out uint32_t *lengthp 616299898Sarybchik ) 617299898Sarybchik{ 618299898Sarybchik efx_rc_t rc; 619299898Sarybchik 620299898Sarybchik _NOTE(ARGUNUSED(enp)) 621299898Sarybchik EFSYS_ASSERT(length <= (EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX + 622299898Sarybchik EFX_LICENSE_V1V2_HEADER_LENGTH)); 623299898Sarybchik 624299898Sarybchik // Ensure space for terminator remains 625299898Sarybchik if ((offset + length) > 626299898Sarybchik (buffer_size - EFX_LICENSE_V1V2_HEADER_LENGTH) ) { 627299898Sarybchik rc = ENOSPC; 628299898Sarybchik goto fail1; 629299898Sarybchik } 630299898Sarybchik 631299898Sarybchik memcpy(bufferp + offset, keyp, length); 632299898Sarybchik 633299898Sarybchik *lengthp = length; 634299898Sarybchik 635299898Sarybchik return (0); 636299898Sarybchik 637299898Sarybchikfail1: 638299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 639299898Sarybchik 640299898Sarybchik return (rc); 641299898Sarybchik} 642299898Sarybchik 643299898Sarybchik __checkReturn efx_rc_t 644299898Sarybchikefx_lic_v1v2_delete_key( 645299898Sarybchik __in efx_nic_t *enp, 646299898Sarybchik __in_bcount(buffer_size) 647299898Sarybchik caddr_t bufferp, 648299898Sarybchik __in size_t buffer_size, 649299898Sarybchik __in uint32_t offset, 650299898Sarybchik __in uint32_t length, 651299898Sarybchik __in uint32_t end, 652299898Sarybchik __out uint32_t *deltap 653299898Sarybchik ) 654299898Sarybchik{ 655299898Sarybchik efx_rc_t rc; 656299898Sarybchik uint32_t move_start = offset + length; 657299898Sarybchik uint32_t move_length = end - move_start; 658299898Sarybchik 659299898Sarybchik _NOTE(ARGUNUSED(enp)) 660299898Sarybchik EFSYS_ASSERT(end <= buffer_size); 661299898Sarybchik 662299898Sarybchik // Shift everything after the key down 663299898Sarybchik memmove(bufferp + offset, bufferp + move_start, move_length); 664299898Sarybchik 665299898Sarybchik *deltap = length; 666299898Sarybchik 667299898Sarybchik return (0); 668299898Sarybchik} 669299898Sarybchik 670299898Sarybchik __checkReturn efx_rc_t 671299898Sarybchikefx_lic_v1v2_create_partition( 672299898Sarybchik __in efx_nic_t *enp, 673299898Sarybchik __in_bcount(buffer_size) 674299898Sarybchik caddr_t bufferp, 675299898Sarybchik __in size_t buffer_size 676299898Sarybchik ) 677299898Sarybchik{ 678299898Sarybchik _NOTE(ARGUNUSED(enp)) 679299898Sarybchik EFSYS_ASSERT(EFX_LICENSE_V1V2_HEADER_LENGTH <= buffer_size); 680299898Sarybchik 681299898Sarybchik // Write terminator 682299898Sarybchik memset(bufferp, '\0', EFX_LICENSE_V1V2_HEADER_LENGTH); 683299898Sarybchik return (0); 684299898Sarybchik} 685299898Sarybchik 686299898Sarybchik 687299898Sarybchik __checkReturn efx_rc_t 688299898Sarybchikefx_lic_v1v2_finish_partition( 689299898Sarybchik __in efx_nic_t *enp, 690299898Sarybchik __in_bcount(buffer_size) 691299898Sarybchik caddr_t bufferp, 692299898Sarybchik __in size_t buffer_size 693299898Sarybchik ) 694299898Sarybchik{ 695299898Sarybchik _NOTE(ARGUNUSED(enp, bufferp, buffer_size)) 696299898Sarybchik 697299898Sarybchik return (0); 698299898Sarybchik} 699299898Sarybchik 700299898Sarybchik#endif /* EFSYS_OPT_HUNTINGTON | EFSYS_OPT_SIENA */ 701299898Sarybchik 702299898Sarybchik 703293901Sarybchik/* V2 Licensing - used by Huntington family only. See SF-113611-TC */ 704293901Sarybchik 705293901Sarybchik#if EFSYS_OPT_HUNTINGTON 706293901Sarybchik 707293901Sarybchikstatic __checkReturn efx_rc_t 708293901Sarybchikefx_mcdi_licensed_app_state( 709293901Sarybchik __in efx_nic_t *enp, 710293901Sarybchik __in uint64_t app_id, 711293901Sarybchik __out boolean_t *licensedp) 712293901Sarybchik{ 713293901Sarybchik efx_mcdi_req_t req; 714293901Sarybchik uint8_t payload[MAX(MC_CMD_GET_LICENSED_APP_STATE_IN_LEN, 715293901Sarybchik MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN)]; 716293901Sarybchik uint32_t app_state; 717293901Sarybchik efx_rc_t rc; 718293901Sarybchik 719293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON); 720293901Sarybchik 721293901Sarybchik /* V2 licensing supports 32bit app id only */ 722293901Sarybchik if ((app_id >> 32) != 0) { 723293901Sarybchik rc = EINVAL; 724293901Sarybchik goto fail1; 725293901Sarybchik } 726293901Sarybchik 727293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 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; 773293901Sarybchik uint8_t payload[MC_CMD_LICENSING_IN_LEN]; 774293901Sarybchik efx_rc_t rc; 775293901Sarybchik 776293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON); 777293901Sarybchik 778293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 779293901Sarybchik req.emr_cmd = MC_CMD_LICENSING; 780293901Sarybchik req.emr_in_buf = payload; 781293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_IN_LEN; 782293901Sarybchik req.emr_out_buf = payload; 783293901Sarybchik req.emr_out_length = 0; 784293901Sarybchik 785293901Sarybchik MCDI_IN_SET_DWORD(req, LICENSING_IN_OP, 786293901Sarybchik MC_CMD_LICENSING_IN_OP_UPDATE_LICENSE); 787293901Sarybchik 788293901Sarybchik efx_mcdi_execute(enp, &req); 789293901Sarybchik 790293901Sarybchik if (req.emr_rc != 0) { 791293901Sarybchik rc = req.emr_rc; 792293901Sarybchik goto fail1; 793293901Sarybchik } 794293901Sarybchik 795293901Sarybchik if (req.emr_out_length_used != 0) { 796293901Sarybchik rc = EIO; 797293901Sarybchik goto fail2; 798293901Sarybchik } 799293901Sarybchik 800293901Sarybchik return (0); 801293901Sarybchik 802293901Sarybchikfail2: 803293901Sarybchik EFSYS_PROBE(fail2); 804293901Sarybchikfail1: 805293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 806293901Sarybchik 807293901Sarybchik return (rc); 808293901Sarybchik} 809293901Sarybchik 810293901Sarybchikstatic __checkReturn efx_rc_t 811293901Sarybchikefx_mcdi_licensing_get_key_stats( 812293901Sarybchik __in efx_nic_t *enp, 813293901Sarybchik __out efx_key_stats_t *eksp) 814293901Sarybchik{ 815293901Sarybchik efx_mcdi_req_t req; 816293901Sarybchik uint8_t payload[MAX(MC_CMD_LICENSING_IN_LEN, 817293901Sarybchik MC_CMD_LICENSING_OUT_LEN)]; 818293901Sarybchik efx_rc_t rc; 819293901Sarybchik 820293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON); 821293901Sarybchik 822293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 823293901Sarybchik req.emr_cmd = MC_CMD_LICENSING; 824293901Sarybchik req.emr_in_buf = payload; 825293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_IN_LEN; 826293901Sarybchik req.emr_out_buf = payload; 827293901Sarybchik req.emr_out_length = MC_CMD_LICENSING_OUT_LEN; 828293901Sarybchik 829293901Sarybchik MCDI_IN_SET_DWORD(req, LICENSING_IN_OP, 830293901Sarybchik MC_CMD_LICENSING_IN_OP_GET_KEY_STATS); 831293901Sarybchik 832293901Sarybchik efx_mcdi_execute(enp, &req); 833293901Sarybchik 834293901Sarybchik if (req.emr_rc != 0) { 835293901Sarybchik rc = req.emr_rc; 836293901Sarybchik goto fail1; 837293901Sarybchik } 838293901Sarybchik 839293901Sarybchik if (req.emr_out_length_used < MC_CMD_LICENSING_OUT_LEN) { 840293901Sarybchik rc = EMSGSIZE; 841293901Sarybchik goto fail2; 842293901Sarybchik } 843293901Sarybchik 844293901Sarybchik eksp->eks_valid = 845293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_OUT_VALID_APP_KEYS); 846293901Sarybchik eksp->eks_invalid = 847293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_OUT_INVALID_APP_KEYS); 848293901Sarybchik eksp->eks_blacklisted = 849293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_OUT_BLACKLISTED_APP_KEYS); 850293901Sarybchik eksp->eks_unverifiable = 851293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_OUT_UNVERIFIABLE_APP_KEYS); 852293901Sarybchik eksp->eks_wrong_node = 853293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_OUT_WRONG_NODE_APP_KEYS); 854293901Sarybchik eksp->eks_licensed_apps_lo = 0; 855293901Sarybchik eksp->eks_licensed_apps_hi = 0; 856293901Sarybchik eksp->eks_licensed_features_lo = 0; 857293901Sarybchik eksp->eks_licensed_features_hi = 0; 858293901Sarybchik 859293901Sarybchik return (0); 860293901Sarybchik 861293901Sarybchikfail2: 862293901Sarybchik EFSYS_PROBE(fail2); 863293901Sarybchikfail1: 864293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 865293901Sarybchik 866293901Sarybchik return (rc); 867293901Sarybchik} 868293901Sarybchik 869293901Sarybchik#endif /* EFSYS_OPT_HUNTINGTON */ 870293901Sarybchik 871293901Sarybchik/* V3 Licensing - used starting from Medford family. See SF-114884-SW */ 872293901Sarybchik 873293901Sarybchik#if EFSYS_OPT_MEDFORD 874293901Sarybchik 875293901Sarybchikstatic __checkReturn efx_rc_t 876293901Sarybchikefx_mcdi_licensing_v3_update_licenses( 877293901Sarybchik __in efx_nic_t *enp) 878293901Sarybchik{ 879293901Sarybchik efx_mcdi_req_t req; 880293901Sarybchik uint8_t payload[MC_CMD_LICENSING_V3_IN_LEN]; 881293901Sarybchik efx_rc_t rc; 882293901Sarybchik 883293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD); 884293901Sarybchik 885293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 886293901Sarybchik req.emr_cmd = MC_CMD_LICENSING_V3; 887293901Sarybchik req.emr_in_buf = payload; 888293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN; 889293901Sarybchik req.emr_out_buf = NULL; 890293901Sarybchik req.emr_out_length = 0; 891293901Sarybchik 892293901Sarybchik MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP, 893293901Sarybchik MC_CMD_LICENSING_V3_IN_OP_UPDATE_LICENSE); 894293901Sarybchik 895293901Sarybchik efx_mcdi_execute(enp, &req); 896293901Sarybchik 897293901Sarybchik if (req.emr_rc != 0) { 898293901Sarybchik rc = req.emr_rc; 899293901Sarybchik goto fail1; 900293901Sarybchik } 901293901Sarybchik 902293901Sarybchik return (0); 903293901Sarybchik 904293901Sarybchikfail1: 905293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 906293901Sarybchik 907293901Sarybchik return (rc); 908293901Sarybchik} 909293901Sarybchik 910293901Sarybchikstatic __checkReturn efx_rc_t 911293901Sarybchikefx_mcdi_licensing_v3_report_license( 912293901Sarybchik __in efx_nic_t *enp, 913293901Sarybchik __out efx_key_stats_t *eksp) 914293901Sarybchik{ 915293901Sarybchik efx_mcdi_req_t req; 916293901Sarybchik uint8_t payload[MAX(MC_CMD_LICENSING_V3_IN_LEN, 917293901Sarybchik MC_CMD_LICENSING_V3_OUT_LEN)]; 918293901Sarybchik efx_rc_t rc; 919293901Sarybchik 920293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD); 921293901Sarybchik 922293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 923293901Sarybchik req.emr_cmd = MC_CMD_LICENSING_V3; 924293901Sarybchik req.emr_in_buf = payload; 925293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN; 926293901Sarybchik req.emr_out_buf = payload; 927293901Sarybchik req.emr_out_length = MC_CMD_LICENSING_V3_OUT_LEN; 928293901Sarybchik 929293901Sarybchik MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP, 930293901Sarybchik MC_CMD_LICENSING_V3_IN_OP_REPORT_LICENSE); 931293901Sarybchik 932293901Sarybchik efx_mcdi_execute(enp, &req); 933293901Sarybchik 934293901Sarybchik if (req.emr_rc != 0) { 935293901Sarybchik rc = req.emr_rc; 936293901Sarybchik goto fail1; 937293901Sarybchik } 938293901Sarybchik 939293901Sarybchik if (req.emr_out_length_used < MC_CMD_LICENSING_V3_OUT_LEN) { 940293901Sarybchik rc = EMSGSIZE; 941293901Sarybchik goto fail2; 942293901Sarybchik } 943293901Sarybchik 944293901Sarybchik eksp->eks_valid = 945293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_VALID_KEYS); 946293901Sarybchik eksp->eks_invalid = 947293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_INVALID_KEYS); 948293901Sarybchik eksp->eks_blacklisted = 0; 949293901Sarybchik eksp->eks_unverifiable = 950293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_UNVERIFIABLE_KEYS); 951293901Sarybchik eksp->eks_wrong_node = 952293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_WRONG_NODE_KEYS); 953293901Sarybchik eksp->eks_licensed_apps_lo = 954293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_LO); 955293901Sarybchik eksp->eks_licensed_apps_hi = 956293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_HI); 957293901Sarybchik eksp->eks_licensed_features_lo = 958293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_LO); 959293901Sarybchik eksp->eks_licensed_features_hi = 960293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_HI); 961293901Sarybchik 962293901Sarybchik return (0); 963293901Sarybchik 964293901Sarybchikfail2: 965293901Sarybchik EFSYS_PROBE(fail2); 966293901Sarybchikfail1: 967293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 968293901Sarybchik 969293901Sarybchik return (rc); 970293901Sarybchik} 971293901Sarybchik 972293901Sarybchikstatic __checkReturn efx_rc_t 973293901Sarybchikefx_mcdi_licensing_v3_app_state( 974293901Sarybchik __in efx_nic_t *enp, 975293901Sarybchik __in uint64_t app_id, 976293901Sarybchik __out boolean_t *licensedp) 977293901Sarybchik{ 978293901Sarybchik efx_mcdi_req_t req; 979293901Sarybchik uint8_t payload[MAX(MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN, 980293901Sarybchik MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN)]; 981293901Sarybchik uint32_t app_state; 982293901Sarybchik efx_rc_t rc; 983293901Sarybchik 984293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD); 985293901Sarybchik 986293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 987293901Sarybchik req.emr_cmd = MC_CMD_GET_LICENSED_V3_APP_STATE; 988293901Sarybchik req.emr_in_buf = payload; 989293901Sarybchik req.emr_in_length = MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN; 990293901Sarybchik req.emr_out_buf = payload; 991293901Sarybchik req.emr_out_length = MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN; 992293901Sarybchik 993293901Sarybchik MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_LO, 994293901Sarybchik app_id & 0xffffffff); 995293901Sarybchik MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_HI, 996293901Sarybchik app_id >> 32); 997293901Sarybchik 998293901Sarybchik efx_mcdi_execute(enp, &req); 999293901Sarybchik 1000293901Sarybchik if (req.emr_rc != 0) { 1001293901Sarybchik rc = req.emr_rc; 1002293901Sarybchik goto fail1; 1003293901Sarybchik } 1004293901Sarybchik 1005293901Sarybchik if (req.emr_out_length_used < MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN) { 1006293901Sarybchik rc = EMSGSIZE; 1007293901Sarybchik goto fail2; 1008293901Sarybchik } 1009293901Sarybchik 1010293901Sarybchik app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_V3_APP_STATE_OUT_STATE)); 1011293901Sarybchik if (app_state != MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_NOT_LICENSED) { 1012293901Sarybchik *licensedp = B_TRUE; 1013293901Sarybchik } else { 1014293901Sarybchik *licensedp = B_FALSE; 1015293901Sarybchik } 1016293901Sarybchik 1017293901Sarybchik return (0); 1018293901Sarybchik 1019293901Sarybchikfail2: 1020293901Sarybchik EFSYS_PROBE(fail2); 1021293901Sarybchikfail1: 1022293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1023293901Sarybchik 1024293901Sarybchik return (rc); 1025293901Sarybchik} 1026293901Sarybchik 1027293901Sarybchikstatic __checkReturn efx_rc_t 1028293901Sarybchikefx_mcdi_licensing_v3_get_id( 1029293901Sarybchik __in efx_nic_t *enp, 1030293901Sarybchik __in size_t buffer_size, 1031293901Sarybchik __out uint32_t *typep, 1032293901Sarybchik __out size_t *lengthp, 1033293901Sarybchik __out_bcount_part_opt(buffer_size, *lengthp) 1034293901Sarybchik uint8_t *bufferp) 1035293901Sarybchik{ 1036293901Sarybchik efx_mcdi_req_t req; 1037293901Sarybchik uint8_t payload[MAX(MC_CMD_LICENSING_GET_ID_V3_IN_LEN, 1038293901Sarybchik MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN)]; 1039293901Sarybchik efx_rc_t rc; 1040293901Sarybchik 1041293901Sarybchik req.emr_cmd = MC_CMD_LICENSING_GET_ID_V3; 1042293901Sarybchik 1043293901Sarybchik if (bufferp == NULL) { 1044293901Sarybchik /* Request id type and length only */ 1045293901Sarybchik req.emr_in_buf = bufferp; 1046293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN; 1047293901Sarybchik req.emr_out_buf = bufferp; 1048293901Sarybchik req.emr_out_length = MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN; 1049293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 1050293901Sarybchik } else { 1051293901Sarybchik /* Request full buffer */ 1052293901Sarybchik req.emr_in_buf = bufferp; 1053293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN; 1054293901Sarybchik req.emr_out_buf = bufferp; 1055299898Sarybchik req.emr_out_length = MIN(buffer_size, MC_CMD_LICENSING_GET_ID_V3_OUT_LENMAX); 1056293901Sarybchik (void) memset(bufferp, 0, req.emr_out_length); 1057293901Sarybchik } 1058293901Sarybchik 1059293901Sarybchik efx_mcdi_execute(enp, &req); 1060293901Sarybchik 1061293901Sarybchik if (req.emr_rc != 0) { 1062293901Sarybchik rc = req.emr_rc; 1063293901Sarybchik goto fail1; 1064293901Sarybchik } 1065293901Sarybchik 1066293901Sarybchik if (req.emr_out_length_used < MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN) { 1067293901Sarybchik rc = EMSGSIZE; 1068293901Sarybchik goto fail2; 1069293901Sarybchik } 1070293901Sarybchik 1071293901Sarybchik *typep = MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_TYPE); 1072293901Sarybchik *lengthp = MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_ID_LENGTH); 1073293901Sarybchik 1074293901Sarybchik if (bufferp == NULL) { 1075293901Sarybchik /* modify length requirements to indicate to caller the extra buffering 1076293901Sarybchik ** needed to read the complete output. 1077293901Sarybchik */ 1078293901Sarybchik *lengthp += MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN; 1079293901Sarybchik } else { 1080293901Sarybchik /* Shift ID down to start of buffer */ 1081293901Sarybchik memmove(bufferp, 1082293901Sarybchik bufferp+MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST, 1083293901Sarybchik *lengthp); 1084293901Sarybchik memset(bufferp+(*lengthp), 0, MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST); 1085293901Sarybchik } 1086293901Sarybchik 1087293901Sarybchik return (0); 1088293901Sarybchik 1089293901Sarybchikfail2: 1090293901Sarybchik EFSYS_PROBE(fail2); 1091293901Sarybchikfail1: 1092293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1093293901Sarybchik 1094293901Sarybchik return (rc); 1095293901Sarybchik} 1096293901Sarybchik 1097299898Sarybchik/* V3 format uses Huntington TLV format partition. See SF-108797-SW */ 1098299898Sarybchik#define EFX_LICENSE_V3_KEY_LENGTH_MIN (64) 1099299898Sarybchik#define EFX_LICENSE_V3_KEY_LENGTH_MAX (128) 1100299898Sarybchik#define EFX_LICENSE_V3_HASH_LENGTH (64) 1101293901Sarybchik 1102299898Sarybchik __checkReturn efx_rc_t 1103299898Sarybchikefx_lic_v3_find_start( 1104299898Sarybchik __in efx_nic_t *enp, 1105299898Sarybchik __in_bcount(buffer_size) 1106299898Sarybchik caddr_t bufferp, 1107299898Sarybchik __in size_t buffer_size, 1108299898Sarybchik __out uint32_t *startp 1109299898Sarybchik ) 1110299898Sarybchik{ 1111299898Sarybchik _NOTE(ARGUNUSED(enp)) 1112299898Sarybchik 1113299898Sarybchik return ef10_nvram_buffer_find_item_start(bufferp, buffer_size, startp); 1114299898Sarybchik} 1115299898Sarybchik 1116299898Sarybchik __checkReturn efx_rc_t 1117299898Sarybchikefx_lic_v3_find_end( 1118299898Sarybchik __in efx_nic_t *enp, 1119299898Sarybchik __in_bcount(buffer_size) 1120299898Sarybchik caddr_t bufferp, 1121299898Sarybchik __in size_t buffer_size, 1122299898Sarybchik __in uint32_t offset, 1123299898Sarybchik __out uint32_t *endp 1124299898Sarybchik ) 1125299898Sarybchik{ 1126299898Sarybchik _NOTE(ARGUNUSED(enp)) 1127299898Sarybchik 1128299898Sarybchik return ef10_nvram_buffer_find_end(bufferp, buffer_size, offset, endp); 1129299898Sarybchik} 1130299898Sarybchik 1131299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 1132299898Sarybchikefx_lic_v3_find_key( 1133299898Sarybchik __in efx_nic_t *enp, 1134299898Sarybchik __in_bcount(buffer_size) 1135299898Sarybchik caddr_t bufferp, 1136299898Sarybchik __in size_t buffer_size, 1137299898Sarybchik __in uint32_t offset, 1138299898Sarybchik __out uint32_t *startp, 1139299898Sarybchik __out uint32_t *lengthp 1140299898Sarybchik ) 1141299898Sarybchik{ 1142299898Sarybchik _NOTE(ARGUNUSED(enp)) 1143299898Sarybchik 1144299898Sarybchik return ef10_nvram_buffer_find_item(bufferp, buffer_size, 1145299898Sarybchik offset, startp, lengthp); 1146299898Sarybchik} 1147299898Sarybchik 1148299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 1149299898Sarybchikefx_lic_v3_validate_key( 1150299898Sarybchik __in efx_nic_t *enp, 1151299898Sarybchik __in_bcount(length) caddr_t keyp, 1152299898Sarybchik __in uint32_t length 1153299898Sarybchik ) 1154299898Sarybchik{ 1155299898Sarybchik // Check key is a valid V3 key 1156299898Sarybchik efx_rc_t rc; 1157299898Sarybchik uint8_t key_type; 1158299898Sarybchik uint8_t key_length; 1159299898Sarybchik 1160299898Sarybchik _NOTE(ARGUNUSED(enp)) 1161299898Sarybchik 1162299898Sarybchik if (length < EFX_LICENSE_V3_KEY_LENGTH_MIN) { 1163299898Sarybchik goto fail1; 1164299898Sarybchik } 1165299898Sarybchik 1166299898Sarybchik key_type = ((uint8_t*)keyp)[0]; 1167299898Sarybchik key_length = ((uint8_t*)keyp)[1] + EFX_LICENSE_V3_HASH_LENGTH; 1168299898Sarybchik 1169299898Sarybchik if(key_length > EFX_LICENSE_V3_KEY_LENGTH_MAX) { 1170299898Sarybchik goto fail2; 1171299898Sarybchik } 1172299898Sarybchik if (key_type < 3) { 1173299898Sarybchik goto fail3; 1174299898Sarybchik } 1175299898Sarybchik if (key_length != length) { 1176299898Sarybchik goto fail4; 1177299898Sarybchik } 1178299898Sarybchik return (B_TRUE); 1179299898Sarybchik 1180299898Sarybchikfail4: 1181299898Sarybchik EFSYS_PROBE(fail4); 1182299898Sarybchikfail3: 1183299898Sarybchik EFSYS_PROBE(fail3); 1184299898Sarybchikfail2: 1185299898Sarybchik EFSYS_PROBE(fail2); 1186299898Sarybchikfail1: 1187299898Sarybchik EFSYS_PROBE(fail1); 1188299898Sarybchik 1189299898Sarybchik return (B_FALSE); 1190299898Sarybchik} 1191299898Sarybchik 1192299898Sarybchik __checkReturn efx_rc_t 1193299898Sarybchikefx_lic_v3_read_key( 1194299898Sarybchik __in efx_nic_t *enp, 1195299898Sarybchik __in_bcount(buffer_size) 1196299898Sarybchik caddr_t bufferp, 1197299898Sarybchik __in size_t buffer_size, 1198299898Sarybchik __in uint32_t offset, 1199299898Sarybchik __in uint32_t length, 1200299898Sarybchik __out_bcount_part(key_max_size, *lengthp) 1201299898Sarybchik caddr_t keyp, 1202299898Sarybchik __in size_t key_max_size, 1203299898Sarybchik __out uint32_t *lengthp 1204299898Sarybchik ) 1205299898Sarybchik{ 1206299898Sarybchik _NOTE(ARGUNUSED(enp)) 1207299898Sarybchik 1208299898Sarybchik return ef10_nvram_buffer_get_item(bufferp, buffer_size, 1209299898Sarybchik offset, length, keyp, key_max_size, lengthp); 1210299898Sarybchik} 1211299898Sarybchik 1212299898Sarybchik __checkReturn efx_rc_t 1213299898Sarybchikefx_lic_v3_write_key( 1214299898Sarybchik __in efx_nic_t *enp, 1215299898Sarybchik __in_bcount(buffer_size) 1216299898Sarybchik caddr_t bufferp, 1217299898Sarybchik __in size_t buffer_size, 1218299898Sarybchik __in uint32_t offset, 1219299898Sarybchik __in_bcount(length) caddr_t keyp, 1220299898Sarybchik __in uint32_t length, 1221299898Sarybchik __out uint32_t *lengthp 1222299898Sarybchik ) 1223299898Sarybchik{ 1224299898Sarybchik _NOTE(ARGUNUSED(enp)) 1225299898Sarybchik EFSYS_ASSERT(length <= EFX_LICENSE_V3_KEY_LENGTH_MAX); 1226299898Sarybchik 1227299898Sarybchik return ef10_nvram_buffer_insert_item(bufferp, buffer_size, 1228299898Sarybchik offset, keyp, length, lengthp); 1229299898Sarybchik} 1230299898Sarybchik 1231299898Sarybchik __checkReturn efx_rc_t 1232299898Sarybchikefx_lic_v3_delete_key( 1233299898Sarybchik __in efx_nic_t *enp, 1234299898Sarybchik __in_bcount(buffer_size) 1235299898Sarybchik caddr_t bufferp, 1236299898Sarybchik __in size_t buffer_size, 1237299898Sarybchik __in uint32_t offset, 1238299898Sarybchik __in uint32_t length, 1239299898Sarybchik __in uint32_t end, 1240299898Sarybchik __out uint32_t *deltap 1241299898Sarybchik ) 1242299898Sarybchik{ 1243299898Sarybchik efx_rc_t rc; 1244299898Sarybchik 1245299898Sarybchik _NOTE(ARGUNUSED(enp)) 1246299898Sarybchik 1247299898Sarybchik if ((rc = ef10_nvram_buffer_delete_item(bufferp, 1248299898Sarybchik buffer_size, offset, length, end)) != 0) { 1249299898Sarybchik goto fail1; 1250299898Sarybchik } 1251299898Sarybchik 1252299898Sarybchik *deltap = length; 1253299898Sarybchik 1254299898Sarybchik return (0); 1255299898Sarybchik 1256299898Sarybchikfail1: 1257299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1258299898Sarybchik 1259299898Sarybchik return (rc); 1260299898Sarybchik} 1261299898Sarybchik 1262299898Sarybchik __checkReturn efx_rc_t 1263299898Sarybchikefx_lic_v3_create_partition( 1264299898Sarybchik __in efx_nic_t *enp, 1265299898Sarybchik __in_bcount(buffer_size) 1266299898Sarybchik caddr_t bufferp, 1267299898Sarybchik __in size_t buffer_size 1268299898Sarybchik ) 1269299898Sarybchik{ 1270299898Sarybchik efx_rc_t rc; 1271299898Sarybchik 1272299898Sarybchik // Construct empty partition 1273299898Sarybchik if ((rc = ef10_nvram_buffer_create(enp, 1274299898Sarybchik NVRAM_PARTITION_TYPE_LICENSE, 1275299898Sarybchik bufferp, buffer_size)) != 0) { 1276299898Sarybchik rc = EFAULT; 1277299898Sarybchik goto fail1; 1278299898Sarybchik } 1279299898Sarybchik 1280299898Sarybchik return (0); 1281299898Sarybchik 1282299898Sarybchikfail1: 1283299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1284299898Sarybchik 1285299898Sarybchik return (rc); 1286299898Sarybchik} 1287299898Sarybchik 1288299898Sarybchik __checkReturn efx_rc_t 1289299898Sarybchikefx_lic_v3_finish_partition( 1290299898Sarybchik __in efx_nic_t *enp, 1291299898Sarybchik __in_bcount(buffer_size) 1292299898Sarybchik caddr_t bufferp, 1293299898Sarybchik __in size_t buffer_size 1294299898Sarybchik ) 1295299898Sarybchik{ 1296299898Sarybchik efx_rc_t rc; 1297299898Sarybchik 1298299898Sarybchik if ((rc = ef10_nvram_buffer_finish(bufferp, 1299299898Sarybchik buffer_size)) != 0) { 1300299898Sarybchik goto fail1; 1301299898Sarybchik } 1302299898Sarybchik 1303299898Sarybchik // Validate completed partition 1304299898Sarybchik if ((rc = ef10_nvram_buffer_validate(enp, NVRAM_PARTITION_TYPE_LICENSE, 1305299898Sarybchik bufferp, buffer_size)) != 0) { 1306299898Sarybchik goto fail2; 1307299898Sarybchik } 1308299898Sarybchik 1309299898Sarybchik return (0); 1310299898Sarybchik 1311299898Sarybchikfail2: 1312299898Sarybchik EFSYS_PROBE(fail2); 1313299898Sarybchikfail1: 1314299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1315299898Sarybchik 1316299898Sarybchik return (rc); 1317299898Sarybchik} 1318299898Sarybchik 1319299898Sarybchik 1320293901Sarybchik#endif /* EFSYS_OPT_MEDFORD */ 1321293901Sarybchik 1322293901Sarybchik __checkReturn efx_rc_t 1323293901Sarybchikefx_lic_init( 1324293901Sarybchik __in efx_nic_t *enp) 1325293901Sarybchik{ 1326299517Sarybchik const efx_lic_ops_t *elop; 1327293901Sarybchik efx_rc_t rc; 1328293901Sarybchik 1329293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1330293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 1331293901Sarybchik EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_LIC)); 1332293901Sarybchik 1333293901Sarybchik switch (enp->en_family) { 1334293901Sarybchik 1335293901Sarybchik#if EFSYS_OPT_SIENA 1336293901Sarybchik case EFX_FAMILY_SIENA: 1337299517Sarybchik elop = &__efx_lic_v1_ops; 1338293901Sarybchik break; 1339293901Sarybchik#endif /* EFSYS_OPT_SIENA */ 1340293901Sarybchik 1341293901Sarybchik#if EFSYS_OPT_HUNTINGTON 1342293901Sarybchik case EFX_FAMILY_HUNTINGTON: 1343299517Sarybchik elop = &__efx_lic_v2_ops; 1344293901Sarybchik break; 1345293901Sarybchik#endif /* EFSYS_OPT_HUNTINGTON */ 1346293901Sarybchik 1347293901Sarybchik#if EFSYS_OPT_MEDFORD 1348293901Sarybchik case EFX_FAMILY_MEDFORD: 1349299517Sarybchik elop = &__efx_lic_v3_ops; 1350293901Sarybchik break; 1351293901Sarybchik#endif /* EFSYS_OPT_MEDFORD */ 1352293901Sarybchik 1353293901Sarybchik default: 1354293901Sarybchik EFSYS_ASSERT(0); 1355293901Sarybchik rc = ENOTSUP; 1356293901Sarybchik goto fail1; 1357293901Sarybchik } 1358293901Sarybchik 1359293901Sarybchik enp->en_elop = elop; 1360293901Sarybchik enp->en_mod_flags |= EFX_MOD_LIC; 1361293901Sarybchik 1362293901Sarybchik return (0); 1363293901Sarybchik 1364293901Sarybchikfail1: 1365293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1366293901Sarybchik 1367293901Sarybchik return (rc); 1368293901Sarybchik} 1369293901Sarybchik 1370293901Sarybchik void 1371293901Sarybchikefx_lic_fini( 1372293901Sarybchik __in efx_nic_t *enp) 1373293901Sarybchik{ 1374299517Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1375293901Sarybchik 1376293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1377293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 1378293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1379293901Sarybchik 1380293901Sarybchik enp->en_elop = NULL; 1381293901Sarybchik enp->en_mod_flags &= ~EFX_MOD_LIC; 1382293901Sarybchik} 1383293901Sarybchik 1384293901Sarybchik 1385293901Sarybchik __checkReturn efx_rc_t 1386293901Sarybchikefx_lic_update_licenses( 1387293901Sarybchik __in efx_nic_t *enp) 1388293901Sarybchik{ 1389299517Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1390293901Sarybchik efx_rc_t rc; 1391293901Sarybchik 1392293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1393293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1394293901Sarybchik 1395293901Sarybchik if ((rc = elop->elo_update_licenses(enp)) != 0) 1396293901Sarybchik goto fail1; 1397293901Sarybchik 1398293901Sarybchik return (0); 1399293901Sarybchik 1400293901Sarybchikfail1: 1401293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1402293901Sarybchik 1403293901Sarybchik return (rc); 1404293901Sarybchik} 1405293901Sarybchik 1406293901Sarybchik __checkReturn efx_rc_t 1407293901Sarybchikefx_lic_get_key_stats( 1408293901Sarybchik __in efx_nic_t *enp, 1409293901Sarybchik __out efx_key_stats_t *eksp) 1410293901Sarybchik{ 1411299517Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1412293901Sarybchik efx_rc_t rc; 1413293901Sarybchik 1414293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1415293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1416293901Sarybchik 1417293901Sarybchik if ((rc = elop->elo_get_key_stats(enp, eksp)) != 0) 1418293901Sarybchik goto fail1; 1419293901Sarybchik 1420293901Sarybchik return (0); 1421293901Sarybchik 1422293901Sarybchikfail1: 1423293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1424293901Sarybchik 1425293901Sarybchik return (rc); 1426293901Sarybchik} 1427293901Sarybchik 1428293901Sarybchik __checkReturn efx_rc_t 1429293901Sarybchikefx_lic_app_state( 1430293901Sarybchik __in efx_nic_t *enp, 1431293901Sarybchik __in uint64_t app_id, 1432293901Sarybchik __out boolean_t *licensedp) 1433293901Sarybchik{ 1434299517Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1435293901Sarybchik efx_rc_t rc; 1436293901Sarybchik 1437293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1438293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1439293901Sarybchik 1440299899Sarybchik if (elop->elo_app_state == NULL) 1441299899Sarybchik return (ENOTSUP); 1442299899Sarybchik 1443299899Sarybchik if ((rc = elop->elo_app_state(enp, app_id, licensedp)) != 0) 1444293901Sarybchik goto fail1; 1445293901Sarybchik 1446293901Sarybchik return (0); 1447293901Sarybchik 1448293901Sarybchikfail1: 1449293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1450293901Sarybchik 1451293901Sarybchik return (rc); 1452293901Sarybchik} 1453293901Sarybchik 1454293901Sarybchik __checkReturn efx_rc_t 1455293901Sarybchikefx_lic_get_id( 1456293901Sarybchik __in efx_nic_t *enp, 1457293901Sarybchik __in size_t buffer_size, 1458293901Sarybchik __out uint32_t *typep, 1459293901Sarybchik __out size_t *lengthp, 1460293901Sarybchik __out_opt uint8_t *bufferp 1461293901Sarybchik ) 1462293901Sarybchik{ 1463299517Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1464293901Sarybchik efx_rc_t rc; 1465293901Sarybchik 1466293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1467293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1468293901Sarybchik 1469299899Sarybchik if (elop->elo_get_id == NULL) 1470299899Sarybchik return (ENOTSUP); 1471293901Sarybchik 1472293901Sarybchik if ((rc = elop->elo_get_id(enp, buffer_size, typep, 1473293901Sarybchik lengthp, bufferp)) != 0) 1474299899Sarybchik goto fail1; 1475293901Sarybchik 1476293901Sarybchik return (0); 1477293901Sarybchik 1478293901Sarybchikfail1: 1479293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1480293901Sarybchik 1481293901Sarybchik return (rc); 1482293901Sarybchik} 1483293901Sarybchik 1484299898Sarybchik/* Buffer management API - abstracts varying TLV format used for License partition */ 1485299898Sarybchik 1486299898Sarybchik __checkReturn efx_rc_t 1487299898Sarybchikefx_lic_find_start( 1488299898Sarybchik __in efx_nic_t *enp, 1489299898Sarybchik __in_bcount(buffer_size) 1490299898Sarybchik caddr_t bufferp, 1491299898Sarybchik __in size_t buffer_size, 1492299898Sarybchik __out uint32_t *startp 1493299898Sarybchik ) 1494299898Sarybchik{ 1495299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1496299898Sarybchik efx_rc_t rc; 1497299898Sarybchik 1498299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1499299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1500299898Sarybchik 1501299898Sarybchik if ((rc = elop->elo_find_start(enp, bufferp, buffer_size, startp)) != 0) 1502299898Sarybchik goto fail1; 1503299898Sarybchik 1504299898Sarybchik return (0); 1505299898Sarybchik 1506299898Sarybchikfail1: 1507299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1508299898Sarybchik 1509299898Sarybchik return (rc); 1510299898Sarybchik} 1511299898Sarybchik 1512299898Sarybchik __checkReturn efx_rc_t 1513299898Sarybchikefx_lic_find_end( 1514299898Sarybchik __in efx_nic_t *enp, 1515299898Sarybchik __in_bcount(buffer_size) 1516299898Sarybchik caddr_t bufferp, 1517299898Sarybchik __in size_t buffer_size, 1518299898Sarybchik __in uint32_t offset, 1519299898Sarybchik __out uint32_t *endp 1520299898Sarybchik ) 1521299898Sarybchik{ 1522299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1523299898Sarybchik efx_rc_t rc; 1524299898Sarybchik 1525299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1526299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1527299898Sarybchik 1528299898Sarybchik if ((rc = elop->elo_find_end(enp, bufferp, buffer_size, offset, endp)) != 0) 1529299898Sarybchik goto fail1; 1530299898Sarybchik 1531299898Sarybchik return (0); 1532299898Sarybchik 1533299898Sarybchikfail1: 1534299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1535299898Sarybchik 1536299898Sarybchik return (rc); 1537299898Sarybchik} 1538299898Sarybchik 1539299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 1540299898Sarybchikefx_lic_find_key( 1541299898Sarybchik __in efx_nic_t *enp, 1542299898Sarybchik __in_bcount(buffer_size) 1543299898Sarybchik caddr_t bufferp, 1544299898Sarybchik __in size_t buffer_size, 1545299898Sarybchik __in uint32_t offset, 1546299898Sarybchik __out uint32_t *startp, 1547299898Sarybchik __out uint32_t *lengthp 1548299898Sarybchik ) 1549299898Sarybchik{ 1550299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1551299898Sarybchik boolean_t rc; 1552299898Sarybchik 1553299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1554299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1555299898Sarybchik 1556299898Sarybchik EFSYS_ASSERT(bufferp); 1557299898Sarybchik EFSYS_ASSERT(startp); 1558299898Sarybchik EFSYS_ASSERT(lengthp); 1559299898Sarybchik 1560299898Sarybchik return (elop->elo_find_key(enp, bufferp, buffer_size, offset, 1561299898Sarybchik startp, lengthp)); 1562299898Sarybchik} 1563299898Sarybchik 1564299898Sarybchik 1565299898Sarybchik/* Validate that the buffer contains a single key in a recognised format. 1566299898Sarybchik** An empty or terminator buffer is not accepted as a valid key. 1567299898Sarybchik*/ 1568299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 1569299898Sarybchikefx_lic_validate_key( 1570299898Sarybchik __in efx_nic_t *enp, 1571299898Sarybchik __in_bcount(length) caddr_t keyp, 1572299898Sarybchik __in uint32_t length 1573299898Sarybchik ) 1574299898Sarybchik{ 1575299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1576299898Sarybchik boolean_t rc; 1577299898Sarybchik uint16_t tlv_type; 1578299898Sarybchik uint16_t tlv_length; 1579299898Sarybchik 1580299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1581299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1582299898Sarybchik 1583299898Sarybchik if ((rc = elop->elo_validate_key(enp, keyp, length)) == B_FALSE) 1584299898Sarybchik goto fail1; 1585299898Sarybchik 1586299898Sarybchik return (B_TRUE); 1587299898Sarybchik 1588299898Sarybchikfail1: 1589299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1590299898Sarybchik 1591299898Sarybchik return (rc); 1592299898Sarybchik} 1593299898Sarybchik 1594299898Sarybchik __checkReturn efx_rc_t 1595299898Sarybchikefx_lic_read_key( 1596299898Sarybchik __in efx_nic_t *enp, 1597299898Sarybchik __in_bcount(buffer_size) 1598299898Sarybchik caddr_t bufferp, 1599299898Sarybchik __in size_t buffer_size, 1600299898Sarybchik __in uint32_t offset, 1601299898Sarybchik __in uint32_t length, 1602299898Sarybchik __out_bcount_part(key_max_size, *lengthp) 1603299898Sarybchik caddr_t keyp, 1604299898Sarybchik __in size_t key_max_size, 1605299898Sarybchik __out uint32_t *lengthp 1606299898Sarybchik ) 1607299898Sarybchik{ 1608299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1609299898Sarybchik efx_rc_t rc; 1610299898Sarybchik 1611299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1612299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1613299898Sarybchik 1614299898Sarybchik if ((rc = elop->elo_read_key(enp, bufferp, buffer_size, offset, 1615299898Sarybchik length, keyp, key_max_size, lengthp)) != 0) 1616299898Sarybchik goto fail1; 1617299898Sarybchik 1618299898Sarybchik return (0); 1619299898Sarybchik 1620299898Sarybchikfail1: 1621299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1622299898Sarybchik 1623299898Sarybchik return (rc); 1624299898Sarybchik} 1625299898Sarybchik 1626299898Sarybchik __checkReturn efx_rc_t 1627299898Sarybchikefx_lic_write_key( 1628299898Sarybchik __in efx_nic_t *enp, 1629299898Sarybchik __in_bcount(buffer_size) 1630299898Sarybchik caddr_t bufferp, 1631299898Sarybchik __in size_t buffer_size, 1632299898Sarybchik __in uint32_t offset, 1633299898Sarybchik __in_bcount(length) caddr_t keyp, 1634299898Sarybchik __in uint32_t length, 1635299898Sarybchik __out uint32_t *lengthp 1636299898Sarybchik ) 1637299898Sarybchik{ 1638299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1639299898Sarybchik efx_rc_t rc; 1640299898Sarybchik 1641299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1642299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1643299898Sarybchik 1644299898Sarybchik if ((rc = elop->elo_write_key(enp, bufferp, buffer_size, offset, 1645299898Sarybchik keyp, length, lengthp)) != 0) 1646299898Sarybchik goto fail1; 1647299898Sarybchik 1648299898Sarybchik return (0); 1649299898Sarybchik 1650299898Sarybchikfail1: 1651299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1652299898Sarybchik 1653299898Sarybchik return (rc); 1654299898Sarybchik} 1655299898Sarybchik 1656299898Sarybchik __checkReturn efx_rc_t 1657299898Sarybchikefx_lic_delete_key( 1658299898Sarybchik __in efx_nic_t *enp, 1659299898Sarybchik __in_bcount(buffer_size) 1660299898Sarybchik caddr_t bufferp, 1661299898Sarybchik __in size_t buffer_size, 1662299898Sarybchik __in uint32_t offset, 1663299898Sarybchik __in uint32_t length, 1664299898Sarybchik __in uint32_t end, 1665299898Sarybchik __out uint32_t *deltap 1666299898Sarybchik ) 1667299898Sarybchik{ 1668299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1669299898Sarybchik efx_rc_t rc; 1670299898Sarybchik 1671299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1672299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1673299898Sarybchik 1674299898Sarybchik if ((rc = elop->elo_delete_key(enp, bufferp, buffer_size, offset, 1675299898Sarybchik length, end, deltap)) != 0) 1676299898Sarybchik goto fail1; 1677299898Sarybchik 1678299898Sarybchik return (0); 1679299898Sarybchik 1680299898Sarybchikfail1: 1681299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1682299898Sarybchik 1683299898Sarybchik return (rc); 1684299898Sarybchik} 1685299898Sarybchik 1686299898Sarybchik __checkReturn efx_rc_t 1687299898Sarybchikefx_lic_create_partition( 1688299898Sarybchik __in efx_nic_t *enp, 1689299898Sarybchik __in_bcount(buffer_size) 1690299898Sarybchik caddr_t bufferp, 1691299898Sarybchik __in size_t buffer_size 1692299898Sarybchik ) 1693299898Sarybchik{ 1694299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1695299898Sarybchik efx_rc_t rc; 1696299898Sarybchik 1697299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1698299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1699299898Sarybchik 1700299898Sarybchik if ((rc = elop->elo_create_partition(enp, bufferp, buffer_size)) != 0) 1701299898Sarybchik goto fail1; 1702299898Sarybchik 1703299898Sarybchik return (0); 1704299898Sarybchik 1705299898Sarybchikfail1: 1706299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1707299898Sarybchik 1708299898Sarybchik return (rc); 1709299898Sarybchik} 1710299898Sarybchik 1711299898Sarybchik 1712299898Sarybchik __checkReturn efx_rc_t 1713299898Sarybchikefx_lic_finish_partition( 1714299898Sarybchik __in efx_nic_t *enp, 1715299898Sarybchik __in_bcount(buffer_size) 1716299898Sarybchik caddr_t bufferp, 1717299898Sarybchik __in size_t buffer_size 1718299898Sarybchik ) 1719299898Sarybchik{ 1720299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1721299898Sarybchik efx_rc_t rc; 1722299898Sarybchik 1723299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1724299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1725299898Sarybchik 1726299898Sarybchik if ((rc = elop->elo_finish_partition(enp, bufferp, buffer_size)) != 0) 1727299898Sarybchik goto fail1; 1728299898Sarybchik 1729299898Sarybchik return (0); 1730299898Sarybchik 1731299898Sarybchikfail1: 1732299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1733299898Sarybchik 1734299898Sarybchik return (rc); 1735299898Sarybchik} 1736299898Sarybchik 1737293901Sarybchik#endif /* EFSYS_OPT_LICENSING */ 1738