efx_lic.c revision 342426
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 342426 2018-12-25 07:02:08Z 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)); 352299905Sarybchik req.emr_cmd = MC_CMD_FC; 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 358299905Sarybchik MCDI_IN_SET_DWORD(req, FC_IN_CMD, 359299905Sarybchik MC_CMD_FC_OP_LICENSE); 360299905Sarybchik 361293901Sarybchik MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP, 362293901Sarybchik MC_CMD_FC_IN_LICENSE_UPDATE_LICENSE); 363293901Sarybchik 364293901Sarybchik efx_mcdi_execute(enp, &req); 365293901Sarybchik 366293901Sarybchik if (req.emr_rc != 0) { 367293901Sarybchik rc = req.emr_rc; 368293901Sarybchik goto fail1; 369293901Sarybchik } 370293901Sarybchik 371293901Sarybchik if (req.emr_out_length_used != 0) { 372293901Sarybchik rc = EIO; 373293901Sarybchik goto fail2; 374293901Sarybchik } 375293901Sarybchik 376293901Sarybchik return (0); 377293901Sarybchik 378293901Sarybchikfail2: 379293901Sarybchik EFSYS_PROBE(fail2); 380293901Sarybchikfail1: 381293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 382293901Sarybchik 383293901Sarybchik return (rc); 384293901Sarybchik} 385293901Sarybchik 386293901Sarybchikstatic __checkReturn efx_rc_t 387293901Sarybchikefx_mcdi_fc_license_get_key_stats( 388293901Sarybchik __in efx_nic_t *enp, 389293901Sarybchik __out efx_key_stats_t *eksp) 390293901Sarybchik{ 391293901Sarybchik efx_mcdi_req_t req; 392293901Sarybchik uint8_t payload[MAX(MC_CMD_FC_IN_LICENSE_LEN, 393293901Sarybchik MC_CMD_FC_OUT_LICENSE_LEN)]; 394293901Sarybchik efx_rc_t rc; 395293901Sarybchik 396293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA); 397293901Sarybchik 398293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 399299905Sarybchik req.emr_cmd = MC_CMD_FC; 400293901Sarybchik req.emr_in_buf = payload; 401293901Sarybchik req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN; 402293901Sarybchik req.emr_out_buf = payload; 403293901Sarybchik req.emr_out_length = MC_CMD_FC_OUT_LICENSE_LEN; 404293901Sarybchik 405299905Sarybchik MCDI_IN_SET_DWORD(req, FC_IN_CMD, 406299905Sarybchik MC_CMD_FC_OP_LICENSE); 407299905Sarybchik 408293901Sarybchik MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP, 409293901Sarybchik MC_CMD_FC_IN_LICENSE_GET_KEY_STATS); 410293901Sarybchik 411299923Sarybchik efx_mcdi_execute_quiet(enp, &req); 412293901Sarybchik 413293901Sarybchik if (req.emr_rc != 0) { 414293901Sarybchik rc = req.emr_rc; 415293901Sarybchik goto fail1; 416293901Sarybchik } 417293901Sarybchik 418293901Sarybchik if (req.emr_out_length_used < MC_CMD_FC_OUT_LICENSE_LEN) { 419293901Sarybchik rc = EMSGSIZE; 420293901Sarybchik goto fail2; 421293901Sarybchik } 422293901Sarybchik 423293901Sarybchik eksp->eks_valid = 424293901Sarybchik MCDI_OUT_DWORD(req, FC_OUT_LICENSE_VALID_KEYS); 425293901Sarybchik eksp->eks_invalid = 426293901Sarybchik MCDI_OUT_DWORD(req, FC_OUT_LICENSE_INVALID_KEYS); 427293901Sarybchik eksp->eks_blacklisted = 428293901Sarybchik MCDI_OUT_DWORD(req, FC_OUT_LICENSE_BLACKLISTED_KEYS); 429293901Sarybchik eksp->eks_unverifiable = 0; 430293901Sarybchik eksp->eks_wrong_node = 0; 431293901Sarybchik eksp->eks_licensed_apps_lo = 0; 432293901Sarybchik eksp->eks_licensed_apps_hi = 0; 433293901Sarybchik eksp->eks_licensed_features_lo = 0; 434293901Sarybchik eksp->eks_licensed_features_hi = 0; 435293901Sarybchik 436293901Sarybchik return (0); 437293901Sarybchik 438293901Sarybchikfail2: 439293901Sarybchik EFSYS_PROBE(fail2); 440293901Sarybchikfail1: 441293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 442293901Sarybchik 443293901Sarybchik return (rc); 444293901Sarybchik} 445293901Sarybchik 446293901Sarybchik#endif /* EFSYS_OPT_SIENA */ 447293901Sarybchik 448299898Sarybchik/* V1 and V2 Partition format - based on a 16-bit TLV format */ 449299898Sarybchik 450299898Sarybchik#if EFSYS_OPT_SIENA | EFSYS_OPT_HUNTINGTON 451299898Sarybchik 452299898Sarybchik/* 453299898Sarybchik * V1/V2 format - defined in SF-108542-TC section 4.2: 454299898Sarybchik * Type (T): 16bit - revision/HMAC algorithm 455299898Sarybchik * Length (L): 16bit - value length in bytes 456299898Sarybchik * Value (V): L bytes - payload 457299898Sarybchik */ 458299898Sarybchik#define EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX (256) 459310841Sarybchik#define EFX_LICENSE_V1V2_HEADER_LENGTH (2 * sizeof(uint16_t)) 460299898Sarybchik 461299898Sarybchik __checkReturn efx_rc_t 462299898Sarybchikefx_lic_v1v2_find_start( 463299898Sarybchik __in efx_nic_t *enp, 464299898Sarybchik __in_bcount(buffer_size) 465299898Sarybchik caddr_t bufferp, 466299898Sarybchik __in size_t buffer_size, 467299898Sarybchik __out uint32_t *startp 468299898Sarybchik ) 469299898Sarybchik{ 470299898Sarybchik _NOTE(ARGUNUSED(enp, bufferp, buffer_size)) 471299898Sarybchik 472299898Sarybchik *startp = 0; 473299898Sarybchik return (0); 474299898Sarybchik} 475299898Sarybchik 476299898Sarybchik __checkReturn efx_rc_t 477299898Sarybchikefx_lic_v1v2_find_end( 478299898Sarybchik __in efx_nic_t *enp, 479299898Sarybchik __in_bcount(buffer_size) 480299898Sarybchik caddr_t bufferp, 481299898Sarybchik __in size_t buffer_size, 482299898Sarybchik __in uint32_t offset, 483299898Sarybchik __out uint32_t *endp 484299898Sarybchik ) 485299898Sarybchik{ 486299898Sarybchik _NOTE(ARGUNUSED(enp, bufferp, buffer_size)) 487299898Sarybchik 488299898Sarybchik *endp = offset + EFX_LICENSE_V1V2_HEADER_LENGTH; 489299898Sarybchik return (0); 490299898Sarybchik} 491299898Sarybchik 492299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 493299898Sarybchikefx_lic_v1v2_find_key( 494299898Sarybchik __in efx_nic_t *enp, 495299898Sarybchik __in_bcount(buffer_size) 496299898Sarybchik caddr_t bufferp, 497299898Sarybchik __in size_t buffer_size, 498299898Sarybchik __in uint32_t offset, 499299898Sarybchik __out uint32_t *startp, 500299898Sarybchik __out uint32_t *lengthp 501299898Sarybchik ) 502299898Sarybchik{ 503299898Sarybchik boolean_t found; 504299898Sarybchik uint16_t tlv_type; 505299898Sarybchik uint16_t tlv_length; 506299898Sarybchik 507299898Sarybchik _NOTE(ARGUNUSED(enp)) 508299898Sarybchik 509301125Sarybchik if ((size_t)buffer_size - offset < EFX_LICENSE_V1V2_HEADER_LENGTH) 510299898Sarybchik goto fail1; 511299898Sarybchik 512310922Sarybchik tlv_type = __LE_TO_CPU_16(((uint16_t *)&bufferp[offset])[0]); 513310922Sarybchik tlv_length = __LE_TO_CPU_16(((uint16_t *)&bufferp[offset])[1]); 514299898Sarybchik if ((tlv_length > EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX) || 515299898Sarybchik (tlv_type == 0 && tlv_length == 0)) { 516299898Sarybchik found = B_FALSE; 517299898Sarybchik } else { 518299898Sarybchik *startp = offset; 519299898Sarybchik *lengthp = tlv_length + EFX_LICENSE_V1V2_HEADER_LENGTH; 520299898Sarybchik found = B_TRUE; 521299898Sarybchik } 522299898Sarybchik return (found); 523299898Sarybchik 524299898Sarybchikfail1: 525342426Sarybchik EFSYS_PROBE1(fail1, boolean_t, B_FALSE); 526299898Sarybchik 527299898Sarybchik return (B_FALSE); 528299898Sarybchik} 529299898Sarybchik 530299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 531299898Sarybchikefx_lic_v1v2_validate_key( 532299898Sarybchik __in efx_nic_t *enp, 533299898Sarybchik __in_bcount(length) caddr_t keyp, 534299898Sarybchik __in uint32_t length 535299898Sarybchik ) 536299898Sarybchik{ 537299898Sarybchik uint16_t tlv_type; 538299898Sarybchik uint16_t tlv_length; 539299898Sarybchik 540299898Sarybchik _NOTE(ARGUNUSED(enp)) 541299898Sarybchik 542299898Sarybchik if (length < EFX_LICENSE_V1V2_HEADER_LENGTH) { 543299898Sarybchik goto fail1; 544299898Sarybchik } 545299898Sarybchik 546310922Sarybchik tlv_type = __LE_TO_CPU_16(((uint16_t *)keyp)[0]); 547310922Sarybchik tlv_length = __LE_TO_CPU_16(((uint16_t *)keyp)[1]); 548299898Sarybchik 549301125Sarybchik if (tlv_length > EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX) { 550299898Sarybchik goto fail2; 551299898Sarybchik } 552299898Sarybchik if (tlv_type == 0) { 553299898Sarybchik goto fail3; 554299898Sarybchik } 555299898Sarybchik if ((tlv_length + EFX_LICENSE_V1V2_HEADER_LENGTH) != length) { 556299898Sarybchik goto fail4; 557299898Sarybchik } 558299898Sarybchik 559299898Sarybchik return (B_TRUE); 560299898Sarybchik 561299898Sarybchikfail4: 562299898Sarybchik EFSYS_PROBE(fail4); 563299898Sarybchikfail3: 564299898Sarybchik EFSYS_PROBE(fail3); 565299898Sarybchikfail2: 566299898Sarybchik EFSYS_PROBE(fail2); 567299898Sarybchikfail1: 568342426Sarybchik EFSYS_PROBE1(fail1, boolean_t, B_FALSE); 569299898Sarybchik 570299898Sarybchik return (B_FALSE); 571299898Sarybchik} 572299898Sarybchik 573299898Sarybchik 574299898Sarybchik __checkReturn efx_rc_t 575299898Sarybchikefx_lic_v1v2_read_key( 576299898Sarybchik __in efx_nic_t *enp, 577299898Sarybchik __in_bcount(buffer_size) 578299898Sarybchik caddr_t bufferp, 579299898Sarybchik __in size_t buffer_size, 580299898Sarybchik __in uint32_t offset, 581299898Sarybchik __in uint32_t length, 582299898Sarybchik __out_bcount_part(key_max_size, *lengthp) 583299898Sarybchik caddr_t keyp, 584299898Sarybchik __in size_t key_max_size, 585299898Sarybchik __out uint32_t *lengthp 586299898Sarybchik ) 587299898Sarybchik{ 588299898Sarybchik efx_rc_t rc; 589299898Sarybchik 590299898Sarybchik _NOTE(ARGUNUSED(enp)) 591299898Sarybchik EFSYS_ASSERT(length <= (EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX + 592299898Sarybchik EFX_LICENSE_V1V2_HEADER_LENGTH)); 593299898Sarybchik 594299898Sarybchik if (key_max_size < length) { 595299898Sarybchik rc = ENOSPC; 596299898Sarybchik goto fail1; 597299898Sarybchik } 598299898Sarybchik memcpy(keyp, &bufferp[offset], length); 599299898Sarybchik 600299898Sarybchik *lengthp = length; 601299898Sarybchik 602299898Sarybchik return (0); 603299898Sarybchik 604299898Sarybchikfail1: 605299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 606299898Sarybchik 607299898Sarybchik return (rc); 608299898Sarybchik} 609299898Sarybchik 610299898Sarybchik __checkReturn efx_rc_t 611299898Sarybchikefx_lic_v1v2_write_key( 612299898Sarybchik __in efx_nic_t *enp, 613299898Sarybchik __in_bcount(buffer_size) 614299898Sarybchik caddr_t bufferp, 615299898Sarybchik __in size_t buffer_size, 616299898Sarybchik __in uint32_t offset, 617299898Sarybchik __in_bcount(length) caddr_t keyp, 618299898Sarybchik __in uint32_t length, 619299898Sarybchik __out uint32_t *lengthp 620299898Sarybchik ) 621299898Sarybchik{ 622299898Sarybchik efx_rc_t rc; 623299898Sarybchik 624299898Sarybchik _NOTE(ARGUNUSED(enp)) 625299898Sarybchik EFSYS_ASSERT(length <= (EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX + 626299898Sarybchik EFX_LICENSE_V1V2_HEADER_LENGTH)); 627299898Sarybchik 628310916Sarybchik /* Ensure space for terminator remains */ 629299898Sarybchik if ((offset + length) > 630310919Sarybchik (buffer_size - EFX_LICENSE_V1V2_HEADER_LENGTH)) { 631299898Sarybchik rc = ENOSPC; 632299898Sarybchik goto fail1; 633299898Sarybchik } 634299898Sarybchik 635299898Sarybchik memcpy(bufferp + offset, keyp, length); 636299898Sarybchik 637299898Sarybchik *lengthp = length; 638299898Sarybchik 639299898Sarybchik return (0); 640299898Sarybchik 641299898Sarybchikfail1: 642299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 643299898Sarybchik 644299898Sarybchik return (rc); 645299898Sarybchik} 646299898Sarybchik 647299898Sarybchik __checkReturn efx_rc_t 648299898Sarybchikefx_lic_v1v2_delete_key( 649299898Sarybchik __in efx_nic_t *enp, 650299898Sarybchik __in_bcount(buffer_size) 651299898Sarybchik caddr_t bufferp, 652299898Sarybchik __in size_t buffer_size, 653299898Sarybchik __in uint32_t offset, 654299898Sarybchik __in uint32_t length, 655299898Sarybchik __in uint32_t end, 656299898Sarybchik __out uint32_t *deltap 657299898Sarybchik ) 658299898Sarybchik{ 659299898Sarybchik uint32_t move_start = offset + length; 660299898Sarybchik uint32_t move_length = end - move_start; 661299898Sarybchik 662299898Sarybchik _NOTE(ARGUNUSED(enp)) 663299898Sarybchik EFSYS_ASSERT(end <= buffer_size); 664299898Sarybchik 665310916Sarybchik /* Shift everything after the key down */ 666299898Sarybchik memmove(bufferp + offset, bufferp + move_start, move_length); 667299898Sarybchik 668299898Sarybchik *deltap = length; 669299898Sarybchik 670299898Sarybchik return (0); 671299898Sarybchik} 672299898Sarybchik 673299898Sarybchik __checkReturn efx_rc_t 674299898Sarybchikefx_lic_v1v2_create_partition( 675299898Sarybchik __in efx_nic_t *enp, 676299898Sarybchik __in_bcount(buffer_size) 677299898Sarybchik caddr_t bufferp, 678299898Sarybchik __in size_t buffer_size 679299898Sarybchik ) 680299898Sarybchik{ 681299898Sarybchik _NOTE(ARGUNUSED(enp)) 682299898Sarybchik EFSYS_ASSERT(EFX_LICENSE_V1V2_HEADER_LENGTH <= buffer_size); 683299898Sarybchik 684310916Sarybchik /* Write terminator */ 685299898Sarybchik memset(bufferp, '\0', EFX_LICENSE_V1V2_HEADER_LENGTH); 686299898Sarybchik return (0); 687299898Sarybchik} 688299898Sarybchik 689299898Sarybchik 690299898Sarybchik __checkReturn efx_rc_t 691299898Sarybchikefx_lic_v1v2_finish_partition( 692299898Sarybchik __in efx_nic_t *enp, 693299898Sarybchik __in_bcount(buffer_size) 694299898Sarybchik caddr_t bufferp, 695299898Sarybchik __in size_t buffer_size 696299898Sarybchik ) 697299898Sarybchik{ 698299898Sarybchik _NOTE(ARGUNUSED(enp, bufferp, buffer_size)) 699299898Sarybchik 700299898Sarybchik return (0); 701299898Sarybchik} 702299898Sarybchik 703299898Sarybchik#endif /* EFSYS_OPT_HUNTINGTON | EFSYS_OPT_SIENA */ 704299898Sarybchik 705299898Sarybchik 706293901Sarybchik/* V2 Licensing - used by Huntington family only. See SF-113611-TC */ 707293901Sarybchik 708293901Sarybchik#if EFSYS_OPT_HUNTINGTON 709293901Sarybchik 710293901Sarybchikstatic __checkReturn efx_rc_t 711293901Sarybchikefx_mcdi_licensed_app_state( 712293901Sarybchik __in efx_nic_t *enp, 713293901Sarybchik __in uint64_t app_id, 714293901Sarybchik __out boolean_t *licensedp) 715293901Sarybchik{ 716293901Sarybchik efx_mcdi_req_t req; 717293901Sarybchik uint8_t payload[MAX(MC_CMD_GET_LICENSED_APP_STATE_IN_LEN, 718293901Sarybchik MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN)]; 719293901Sarybchik uint32_t app_state; 720293901Sarybchik efx_rc_t rc; 721293901Sarybchik 722293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON); 723293901Sarybchik 724293901Sarybchik /* V2 licensing supports 32bit app id only */ 725293901Sarybchik if ((app_id >> 32) != 0) { 726293901Sarybchik rc = EINVAL; 727293901Sarybchik goto fail1; 728293901Sarybchik } 729293901Sarybchik 730293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 731293901Sarybchik req.emr_cmd = MC_CMD_GET_LICENSED_APP_STATE; 732293901Sarybchik req.emr_in_buf = payload; 733293901Sarybchik req.emr_in_length = MC_CMD_GET_LICENSED_APP_STATE_IN_LEN; 734293901Sarybchik req.emr_out_buf = payload; 735293901Sarybchik req.emr_out_length = MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN; 736293901Sarybchik 737293901Sarybchik MCDI_IN_SET_DWORD(req, GET_LICENSED_APP_STATE_IN_APP_ID, 738293901Sarybchik app_id & 0xffffffff); 739293901Sarybchik 740293901Sarybchik efx_mcdi_execute(enp, &req); 741293901Sarybchik 742293901Sarybchik if (req.emr_rc != 0) { 743293901Sarybchik rc = req.emr_rc; 744293901Sarybchik goto fail2; 745293901Sarybchik } 746293901Sarybchik 747293901Sarybchik if (req.emr_out_length_used < MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN) { 748293901Sarybchik rc = EMSGSIZE; 749293901Sarybchik goto fail3; 750293901Sarybchik } 751293901Sarybchik 752293901Sarybchik app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_APP_STATE_OUT_STATE)); 753293901Sarybchik if (app_state != MC_CMD_GET_LICENSED_APP_STATE_OUT_NOT_LICENSED) { 754293901Sarybchik *licensedp = B_TRUE; 755293901Sarybchik } else { 756293901Sarybchik *licensedp = B_FALSE; 757293901Sarybchik } 758293901Sarybchik 759293901Sarybchik return (0); 760293901Sarybchik 761293901Sarybchikfail3: 762293901Sarybchik EFSYS_PROBE(fail3); 763293901Sarybchikfail2: 764293901Sarybchik EFSYS_PROBE(fail2); 765293901Sarybchikfail1: 766293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 767293901Sarybchik 768293901Sarybchik return (rc); 769293901Sarybchik} 770293901Sarybchik 771293901Sarybchikstatic __checkReturn efx_rc_t 772293901Sarybchikefx_mcdi_licensing_update_licenses( 773293901Sarybchik __in efx_nic_t *enp) 774293901Sarybchik{ 775293901Sarybchik efx_mcdi_req_t req; 776293901Sarybchik uint8_t payload[MC_CMD_LICENSING_IN_LEN]; 777293901Sarybchik efx_rc_t rc; 778293901Sarybchik 779293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON); 780293901Sarybchik 781293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 782293901Sarybchik req.emr_cmd = MC_CMD_LICENSING; 783293901Sarybchik req.emr_in_buf = payload; 784293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_IN_LEN; 785293901Sarybchik req.emr_out_buf = payload; 786293901Sarybchik req.emr_out_length = 0; 787293901Sarybchik 788293901Sarybchik MCDI_IN_SET_DWORD(req, LICENSING_IN_OP, 789293901Sarybchik MC_CMD_LICENSING_IN_OP_UPDATE_LICENSE); 790293901Sarybchik 791293901Sarybchik efx_mcdi_execute(enp, &req); 792293901Sarybchik 793293901Sarybchik if (req.emr_rc != 0) { 794293901Sarybchik rc = req.emr_rc; 795293901Sarybchik goto fail1; 796293901Sarybchik } 797293901Sarybchik 798293901Sarybchik if (req.emr_out_length_used != 0) { 799293901Sarybchik rc = EIO; 800293901Sarybchik goto fail2; 801293901Sarybchik } 802293901Sarybchik 803293901Sarybchik return (0); 804293901Sarybchik 805293901Sarybchikfail2: 806293901Sarybchik EFSYS_PROBE(fail2); 807293901Sarybchikfail1: 808293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 809293901Sarybchik 810293901Sarybchik return (rc); 811293901Sarybchik} 812293901Sarybchik 813293901Sarybchikstatic __checkReturn efx_rc_t 814293901Sarybchikefx_mcdi_licensing_get_key_stats( 815293901Sarybchik __in efx_nic_t *enp, 816293901Sarybchik __out efx_key_stats_t *eksp) 817293901Sarybchik{ 818293901Sarybchik efx_mcdi_req_t req; 819293901Sarybchik uint8_t payload[MAX(MC_CMD_LICENSING_IN_LEN, 820293901Sarybchik MC_CMD_LICENSING_OUT_LEN)]; 821293901Sarybchik efx_rc_t rc; 822293901Sarybchik 823293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON); 824293901Sarybchik 825293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 826293901Sarybchik req.emr_cmd = MC_CMD_LICENSING; 827293901Sarybchik req.emr_in_buf = payload; 828293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_IN_LEN; 829293901Sarybchik req.emr_out_buf = payload; 830293901Sarybchik req.emr_out_length = MC_CMD_LICENSING_OUT_LEN; 831293901Sarybchik 832293901Sarybchik MCDI_IN_SET_DWORD(req, LICENSING_IN_OP, 833293901Sarybchik MC_CMD_LICENSING_IN_OP_GET_KEY_STATS); 834293901Sarybchik 835293901Sarybchik efx_mcdi_execute(enp, &req); 836293901Sarybchik 837293901Sarybchik if (req.emr_rc != 0) { 838293901Sarybchik rc = req.emr_rc; 839293901Sarybchik goto fail1; 840293901Sarybchik } 841293901Sarybchik 842293901Sarybchik if (req.emr_out_length_used < MC_CMD_LICENSING_OUT_LEN) { 843293901Sarybchik rc = EMSGSIZE; 844293901Sarybchik goto fail2; 845293901Sarybchik } 846293901Sarybchik 847293901Sarybchik eksp->eks_valid = 848293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_OUT_VALID_APP_KEYS); 849293901Sarybchik eksp->eks_invalid = 850293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_OUT_INVALID_APP_KEYS); 851293901Sarybchik eksp->eks_blacklisted = 852293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_OUT_BLACKLISTED_APP_KEYS); 853293901Sarybchik eksp->eks_unverifiable = 854293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_OUT_UNVERIFIABLE_APP_KEYS); 855293901Sarybchik eksp->eks_wrong_node = 856293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_OUT_WRONG_NODE_APP_KEYS); 857293901Sarybchik eksp->eks_licensed_apps_lo = 0; 858293901Sarybchik eksp->eks_licensed_apps_hi = 0; 859293901Sarybchik eksp->eks_licensed_features_lo = 0; 860293901Sarybchik eksp->eks_licensed_features_hi = 0; 861293901Sarybchik 862293901Sarybchik return (0); 863293901Sarybchik 864293901Sarybchikfail2: 865293901Sarybchik EFSYS_PROBE(fail2); 866293901Sarybchikfail1: 867293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 868293901Sarybchik 869293901Sarybchik return (rc); 870293901Sarybchik} 871293901Sarybchik 872293901Sarybchik#endif /* EFSYS_OPT_HUNTINGTON */ 873293901Sarybchik 874293901Sarybchik/* V3 Licensing - used starting from Medford family. See SF-114884-SW */ 875293901Sarybchik 876293901Sarybchik#if EFSYS_OPT_MEDFORD 877293901Sarybchik 878293901Sarybchikstatic __checkReturn efx_rc_t 879293901Sarybchikefx_mcdi_licensing_v3_update_licenses( 880293901Sarybchik __in efx_nic_t *enp) 881293901Sarybchik{ 882293901Sarybchik efx_mcdi_req_t req; 883293901Sarybchik uint8_t payload[MC_CMD_LICENSING_V3_IN_LEN]; 884293901Sarybchik efx_rc_t rc; 885293901Sarybchik 886293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD); 887293901Sarybchik 888293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 889293901Sarybchik req.emr_cmd = MC_CMD_LICENSING_V3; 890293901Sarybchik req.emr_in_buf = payload; 891293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN; 892293901Sarybchik req.emr_out_buf = NULL; 893293901Sarybchik req.emr_out_length = 0; 894293901Sarybchik 895293901Sarybchik MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP, 896293901Sarybchik MC_CMD_LICENSING_V3_IN_OP_UPDATE_LICENSE); 897293901Sarybchik 898293901Sarybchik efx_mcdi_execute(enp, &req); 899293901Sarybchik 900293901Sarybchik if (req.emr_rc != 0) { 901293901Sarybchik rc = req.emr_rc; 902293901Sarybchik goto fail1; 903293901Sarybchik } 904293901Sarybchik 905293901Sarybchik return (0); 906293901Sarybchik 907293901Sarybchikfail1: 908293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 909293901Sarybchik 910293901Sarybchik return (rc); 911293901Sarybchik} 912293901Sarybchik 913293901Sarybchikstatic __checkReturn efx_rc_t 914293901Sarybchikefx_mcdi_licensing_v3_report_license( 915293901Sarybchik __in efx_nic_t *enp, 916293901Sarybchik __out efx_key_stats_t *eksp) 917293901Sarybchik{ 918293901Sarybchik efx_mcdi_req_t req; 919293901Sarybchik uint8_t payload[MAX(MC_CMD_LICENSING_V3_IN_LEN, 920293901Sarybchik MC_CMD_LICENSING_V3_OUT_LEN)]; 921293901Sarybchik efx_rc_t rc; 922293901Sarybchik 923293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD); 924293901Sarybchik 925293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 926293901Sarybchik req.emr_cmd = MC_CMD_LICENSING_V3; 927293901Sarybchik req.emr_in_buf = payload; 928293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN; 929293901Sarybchik req.emr_out_buf = payload; 930293901Sarybchik req.emr_out_length = MC_CMD_LICENSING_V3_OUT_LEN; 931293901Sarybchik 932293901Sarybchik MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP, 933293901Sarybchik MC_CMD_LICENSING_V3_IN_OP_REPORT_LICENSE); 934293901Sarybchik 935299923Sarybchik efx_mcdi_execute_quiet(enp, &req); 936293901Sarybchik 937293901Sarybchik if (req.emr_rc != 0) { 938293901Sarybchik rc = req.emr_rc; 939293901Sarybchik goto fail1; 940293901Sarybchik } 941293901Sarybchik 942293901Sarybchik if (req.emr_out_length_used < MC_CMD_LICENSING_V3_OUT_LEN) { 943293901Sarybchik rc = EMSGSIZE; 944293901Sarybchik goto fail2; 945293901Sarybchik } 946293901Sarybchik 947293901Sarybchik eksp->eks_valid = 948293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_VALID_KEYS); 949293901Sarybchik eksp->eks_invalid = 950293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_INVALID_KEYS); 951293901Sarybchik eksp->eks_blacklisted = 0; 952293901Sarybchik eksp->eks_unverifiable = 953293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_UNVERIFIABLE_KEYS); 954293901Sarybchik eksp->eks_wrong_node = 955293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_WRONG_NODE_KEYS); 956293901Sarybchik eksp->eks_licensed_apps_lo = 957293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_LO); 958293901Sarybchik eksp->eks_licensed_apps_hi = 959293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_HI); 960293901Sarybchik eksp->eks_licensed_features_lo = 961293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_LO); 962293901Sarybchik eksp->eks_licensed_features_hi = 963293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_HI); 964293901Sarybchik 965293901Sarybchik return (0); 966293901Sarybchik 967293901Sarybchikfail2: 968293901Sarybchik EFSYS_PROBE(fail2); 969293901Sarybchikfail1: 970293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 971293901Sarybchik 972293901Sarybchik return (rc); 973293901Sarybchik} 974293901Sarybchik 975293901Sarybchikstatic __checkReturn efx_rc_t 976293901Sarybchikefx_mcdi_licensing_v3_app_state( 977293901Sarybchik __in efx_nic_t *enp, 978293901Sarybchik __in uint64_t app_id, 979293901Sarybchik __out boolean_t *licensedp) 980293901Sarybchik{ 981293901Sarybchik efx_mcdi_req_t req; 982293901Sarybchik uint8_t payload[MAX(MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN, 983293901Sarybchik MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN)]; 984293901Sarybchik uint32_t app_state; 985293901Sarybchik efx_rc_t rc; 986293901Sarybchik 987293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD); 988293901Sarybchik 989293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 990293901Sarybchik req.emr_cmd = MC_CMD_GET_LICENSED_V3_APP_STATE; 991293901Sarybchik req.emr_in_buf = payload; 992293901Sarybchik req.emr_in_length = MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN; 993293901Sarybchik req.emr_out_buf = payload; 994293901Sarybchik req.emr_out_length = MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN; 995293901Sarybchik 996293901Sarybchik MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_LO, 997293901Sarybchik app_id & 0xffffffff); 998293901Sarybchik MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_HI, 999293901Sarybchik app_id >> 32); 1000293901Sarybchik 1001293901Sarybchik efx_mcdi_execute(enp, &req); 1002293901Sarybchik 1003293901Sarybchik if (req.emr_rc != 0) { 1004293901Sarybchik rc = req.emr_rc; 1005293901Sarybchik goto fail1; 1006293901Sarybchik } 1007293901Sarybchik 1008293901Sarybchik if (req.emr_out_length_used < MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN) { 1009293901Sarybchik rc = EMSGSIZE; 1010293901Sarybchik goto fail2; 1011293901Sarybchik } 1012293901Sarybchik 1013293901Sarybchik app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_V3_APP_STATE_OUT_STATE)); 1014293901Sarybchik if (app_state != MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_NOT_LICENSED) { 1015293901Sarybchik *licensedp = B_TRUE; 1016293901Sarybchik } else { 1017293901Sarybchik *licensedp = B_FALSE; 1018293901Sarybchik } 1019293901Sarybchik 1020293901Sarybchik return (0); 1021293901Sarybchik 1022293901Sarybchikfail2: 1023293901Sarybchik EFSYS_PROBE(fail2); 1024293901Sarybchikfail1: 1025293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1026293901Sarybchik 1027293901Sarybchik return (rc); 1028293901Sarybchik} 1029293901Sarybchik 1030293901Sarybchikstatic __checkReturn efx_rc_t 1031293901Sarybchikefx_mcdi_licensing_v3_get_id( 1032293901Sarybchik __in efx_nic_t *enp, 1033293901Sarybchik __in size_t buffer_size, 1034293901Sarybchik __out uint32_t *typep, 1035293901Sarybchik __out size_t *lengthp, 1036293901Sarybchik __out_bcount_part_opt(buffer_size, *lengthp) 1037293901Sarybchik uint8_t *bufferp) 1038293901Sarybchik{ 1039293901Sarybchik efx_mcdi_req_t req; 1040293901Sarybchik uint8_t payload[MAX(MC_CMD_LICENSING_GET_ID_V3_IN_LEN, 1041293901Sarybchik MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN)]; 1042293901Sarybchik efx_rc_t rc; 1043293901Sarybchik 1044293901Sarybchik req.emr_cmd = MC_CMD_LICENSING_GET_ID_V3; 1045293901Sarybchik 1046293901Sarybchik if (bufferp == NULL) { 1047293901Sarybchik /* Request id type and length only */ 1048293901Sarybchik req.emr_in_buf = bufferp; 1049293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN; 1050293901Sarybchik req.emr_out_buf = bufferp; 1051293901Sarybchik req.emr_out_length = MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN; 1052293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 1053293901Sarybchik } else { 1054293901Sarybchik /* Request full buffer */ 1055293901Sarybchik req.emr_in_buf = bufferp; 1056293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN; 1057293901Sarybchik req.emr_out_buf = bufferp; 1058299898Sarybchik req.emr_out_length = MIN(buffer_size, MC_CMD_LICENSING_GET_ID_V3_OUT_LENMAX); 1059293901Sarybchik (void) memset(bufferp, 0, req.emr_out_length); 1060293901Sarybchik } 1061293901Sarybchik 1062299923Sarybchik efx_mcdi_execute_quiet(enp, &req); 1063293901Sarybchik 1064293901Sarybchik if (req.emr_rc != 0) { 1065293901Sarybchik rc = req.emr_rc; 1066293901Sarybchik goto fail1; 1067293901Sarybchik } 1068293901Sarybchik 1069293901Sarybchik if (req.emr_out_length_used < MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN) { 1070293901Sarybchik rc = EMSGSIZE; 1071293901Sarybchik goto fail2; 1072293901Sarybchik } 1073293901Sarybchik 1074293901Sarybchik *typep = MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_TYPE); 1075293901Sarybchik *lengthp = MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_ID_LENGTH); 1076293901Sarybchik 1077293901Sarybchik if (bufferp == NULL) { 1078293901Sarybchik /* modify length requirements to indicate to caller the extra buffering 1079293901Sarybchik ** needed to read the complete output. 1080293901Sarybchik */ 1081293901Sarybchik *lengthp += MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN; 1082293901Sarybchik } else { 1083293901Sarybchik /* Shift ID down to start of buffer */ 1084293901Sarybchik memmove(bufferp, 1085310841Sarybchik bufferp + MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST, 1086310841Sarybchik *lengthp); 1087310841Sarybchik memset(bufferp + (*lengthp), 0, 1088310841Sarybchik MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST); 1089293901Sarybchik } 1090293901Sarybchik 1091293901Sarybchik return (0); 1092293901Sarybchik 1093293901Sarybchikfail2: 1094293901Sarybchik EFSYS_PROBE(fail2); 1095293901Sarybchikfail1: 1096293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1097293901Sarybchik 1098293901Sarybchik return (rc); 1099293901Sarybchik} 1100293901Sarybchik 1101299898Sarybchik/* V3 format uses Huntington TLV format partition. See SF-108797-SW */ 1102299898Sarybchik#define EFX_LICENSE_V3_KEY_LENGTH_MIN (64) 1103299907Sarybchik#define EFX_LICENSE_V3_KEY_LENGTH_MAX (160) 1104293901Sarybchik 1105299898Sarybchik __checkReturn efx_rc_t 1106299898Sarybchikefx_lic_v3_find_start( 1107299898Sarybchik __in efx_nic_t *enp, 1108299898Sarybchik __in_bcount(buffer_size) 1109299898Sarybchik caddr_t bufferp, 1110299898Sarybchik __in size_t buffer_size, 1111299898Sarybchik __out uint32_t *startp 1112299898Sarybchik ) 1113299898Sarybchik{ 1114299898Sarybchik _NOTE(ARGUNUSED(enp)) 1115299898Sarybchik 1116299898Sarybchik return ef10_nvram_buffer_find_item_start(bufferp, buffer_size, startp); 1117299898Sarybchik} 1118299898Sarybchik 1119299898Sarybchik __checkReturn efx_rc_t 1120299898Sarybchikefx_lic_v3_find_end( 1121299898Sarybchik __in efx_nic_t *enp, 1122299898Sarybchik __in_bcount(buffer_size) 1123299898Sarybchik caddr_t bufferp, 1124299898Sarybchik __in size_t buffer_size, 1125299898Sarybchik __in uint32_t offset, 1126299898Sarybchik __out uint32_t *endp 1127299898Sarybchik ) 1128299898Sarybchik{ 1129299898Sarybchik _NOTE(ARGUNUSED(enp)) 1130299898Sarybchik 1131299898Sarybchik return ef10_nvram_buffer_find_end(bufferp, buffer_size, offset, endp); 1132299898Sarybchik} 1133299898Sarybchik 1134299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 1135299898Sarybchikefx_lic_v3_find_key( 1136299898Sarybchik __in efx_nic_t *enp, 1137299898Sarybchik __in_bcount(buffer_size) 1138299898Sarybchik caddr_t bufferp, 1139299898Sarybchik __in size_t buffer_size, 1140299898Sarybchik __in uint32_t offset, 1141299898Sarybchik __out uint32_t *startp, 1142299898Sarybchik __out uint32_t *lengthp 1143299898Sarybchik ) 1144299898Sarybchik{ 1145299898Sarybchik _NOTE(ARGUNUSED(enp)) 1146299898Sarybchik 1147299898Sarybchik return ef10_nvram_buffer_find_item(bufferp, buffer_size, 1148299898Sarybchik offset, startp, lengthp); 1149299898Sarybchik} 1150299898Sarybchik 1151299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 1152299898Sarybchikefx_lic_v3_validate_key( 1153299898Sarybchik __in efx_nic_t *enp, 1154299898Sarybchik __in_bcount(length) caddr_t keyp, 1155299898Sarybchik __in uint32_t length 1156299898Sarybchik ) 1157299898Sarybchik{ 1158310916Sarybchik /* Check key is a valid V3 key */ 1159299898Sarybchik uint8_t key_type; 1160299898Sarybchik uint8_t key_length; 1161299898Sarybchik 1162299898Sarybchik _NOTE(ARGUNUSED(enp)) 1163299898Sarybchik 1164299898Sarybchik if (length < EFX_LICENSE_V3_KEY_LENGTH_MIN) { 1165299898Sarybchik goto fail1; 1166299898Sarybchik } 1167299898Sarybchik 1168299911Sarybchik if (length > EFX_LICENSE_V3_KEY_LENGTH_MAX) { 1169299911Sarybchik goto fail2; 1170299911Sarybchik } 1171299911Sarybchik 1172310922Sarybchik key_type = ((uint8_t *)keyp)[0]; 1173310922Sarybchik key_length = ((uint8_t *)keyp)[1]; 1174299898Sarybchik 1175299898Sarybchik if (key_type < 3) { 1176299898Sarybchik goto fail3; 1177299898Sarybchik } 1178299911Sarybchik if (key_length > length) { 1179299898Sarybchik goto fail4; 1180299898Sarybchik } 1181299898Sarybchik return (B_TRUE); 1182299898Sarybchik 1183299898Sarybchikfail4: 1184299898Sarybchik EFSYS_PROBE(fail4); 1185299898Sarybchikfail3: 1186299898Sarybchik EFSYS_PROBE(fail3); 1187299898Sarybchikfail2: 1188299898Sarybchik EFSYS_PROBE(fail2); 1189299898Sarybchikfail1: 1190342426Sarybchik EFSYS_PROBE1(fail1, boolean_t, B_FALSE); 1191299898Sarybchik 1192299898Sarybchik return (B_FALSE); 1193299898Sarybchik} 1194299898Sarybchik 1195299898Sarybchik __checkReturn efx_rc_t 1196299898Sarybchikefx_lic_v3_read_key( 1197299898Sarybchik __in efx_nic_t *enp, 1198299898Sarybchik __in_bcount(buffer_size) 1199299898Sarybchik caddr_t bufferp, 1200299898Sarybchik __in size_t buffer_size, 1201299898Sarybchik __in uint32_t offset, 1202299898Sarybchik __in uint32_t length, 1203299898Sarybchik __out_bcount_part(key_max_size, *lengthp) 1204299898Sarybchik caddr_t keyp, 1205299898Sarybchik __in size_t key_max_size, 1206299898Sarybchik __out uint32_t *lengthp 1207299898Sarybchik ) 1208299898Sarybchik{ 1209299898Sarybchik _NOTE(ARGUNUSED(enp)) 1210299898Sarybchik 1211299898Sarybchik return ef10_nvram_buffer_get_item(bufferp, buffer_size, 1212299898Sarybchik offset, length, keyp, key_max_size, lengthp); 1213299898Sarybchik} 1214299898Sarybchik 1215299898Sarybchik __checkReturn efx_rc_t 1216299898Sarybchikefx_lic_v3_write_key( 1217299898Sarybchik __in efx_nic_t *enp, 1218299898Sarybchik __in_bcount(buffer_size) 1219299898Sarybchik caddr_t bufferp, 1220299898Sarybchik __in size_t buffer_size, 1221299898Sarybchik __in uint32_t offset, 1222299898Sarybchik __in_bcount(length) caddr_t keyp, 1223299898Sarybchik __in uint32_t length, 1224299898Sarybchik __out uint32_t *lengthp 1225299898Sarybchik ) 1226299898Sarybchik{ 1227299898Sarybchik _NOTE(ARGUNUSED(enp)) 1228299898Sarybchik EFSYS_ASSERT(length <= EFX_LICENSE_V3_KEY_LENGTH_MAX); 1229299898Sarybchik 1230299898Sarybchik return ef10_nvram_buffer_insert_item(bufferp, buffer_size, 1231299898Sarybchik offset, keyp, length, lengthp); 1232299898Sarybchik} 1233299898Sarybchik 1234299898Sarybchik __checkReturn efx_rc_t 1235299898Sarybchikefx_lic_v3_delete_key( 1236299898Sarybchik __in efx_nic_t *enp, 1237299898Sarybchik __in_bcount(buffer_size) 1238299898Sarybchik caddr_t bufferp, 1239299898Sarybchik __in size_t buffer_size, 1240299898Sarybchik __in uint32_t offset, 1241299898Sarybchik __in uint32_t length, 1242299898Sarybchik __in uint32_t end, 1243299898Sarybchik __out uint32_t *deltap 1244299898Sarybchik ) 1245299898Sarybchik{ 1246299898Sarybchik efx_rc_t rc; 1247299898Sarybchik 1248299898Sarybchik _NOTE(ARGUNUSED(enp)) 1249299898Sarybchik 1250299898Sarybchik if ((rc = ef10_nvram_buffer_delete_item(bufferp, 1251299898Sarybchik buffer_size, offset, length, end)) != 0) { 1252299898Sarybchik goto fail1; 1253299898Sarybchik } 1254299898Sarybchik 1255299898Sarybchik *deltap = length; 1256299898Sarybchik 1257299898Sarybchik return (0); 1258299898Sarybchik 1259299898Sarybchikfail1: 1260299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1261299898Sarybchik 1262299898Sarybchik return (rc); 1263299898Sarybchik} 1264299898Sarybchik 1265299898Sarybchik __checkReturn efx_rc_t 1266299898Sarybchikefx_lic_v3_create_partition( 1267299898Sarybchik __in efx_nic_t *enp, 1268299898Sarybchik __in_bcount(buffer_size) 1269299898Sarybchik caddr_t bufferp, 1270299898Sarybchik __in size_t buffer_size 1271299898Sarybchik ) 1272299898Sarybchik{ 1273299898Sarybchik efx_rc_t rc; 1274299898Sarybchik 1275310916Sarybchik /* Construct empty partition */ 1276299898Sarybchik if ((rc = ef10_nvram_buffer_create(enp, 1277299898Sarybchik NVRAM_PARTITION_TYPE_LICENSE, 1278299898Sarybchik bufferp, buffer_size)) != 0) { 1279299898Sarybchik rc = EFAULT; 1280299898Sarybchik goto fail1; 1281299898Sarybchik } 1282299898Sarybchik 1283299898Sarybchik return (0); 1284299898Sarybchik 1285299898Sarybchikfail1: 1286299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1287299898Sarybchik 1288299898Sarybchik return (rc); 1289299898Sarybchik} 1290299898Sarybchik 1291299898Sarybchik __checkReturn efx_rc_t 1292299898Sarybchikefx_lic_v3_finish_partition( 1293299898Sarybchik __in efx_nic_t *enp, 1294299898Sarybchik __in_bcount(buffer_size) 1295299898Sarybchik caddr_t bufferp, 1296299898Sarybchik __in size_t buffer_size 1297299898Sarybchik ) 1298299898Sarybchik{ 1299299898Sarybchik efx_rc_t rc; 1300299898Sarybchik 1301299898Sarybchik if ((rc = ef10_nvram_buffer_finish(bufferp, 1302299898Sarybchik buffer_size)) != 0) { 1303299898Sarybchik goto fail1; 1304299898Sarybchik } 1305299898Sarybchik 1306310916Sarybchik /* Validate completed partition */ 1307299898Sarybchik if ((rc = ef10_nvram_buffer_validate(enp, NVRAM_PARTITION_TYPE_LICENSE, 1308299898Sarybchik bufferp, buffer_size)) != 0) { 1309299898Sarybchik goto fail2; 1310299898Sarybchik } 1311299898Sarybchik 1312299898Sarybchik return (0); 1313299898Sarybchik 1314299898Sarybchikfail2: 1315299898Sarybchik EFSYS_PROBE(fail2); 1316299898Sarybchikfail1: 1317299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1318299898Sarybchik 1319299898Sarybchik return (rc); 1320299898Sarybchik} 1321299898Sarybchik 1322299898Sarybchik 1323293901Sarybchik#endif /* EFSYS_OPT_MEDFORD */ 1324293901Sarybchik 1325293901Sarybchik __checkReturn efx_rc_t 1326293901Sarybchikefx_lic_init( 1327293901Sarybchik __in efx_nic_t *enp) 1328293901Sarybchik{ 1329299517Sarybchik const efx_lic_ops_t *elop; 1330300007Sarybchik efx_key_stats_t eks; 1331293901Sarybchik efx_rc_t rc; 1332293901Sarybchik 1333293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1334293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 1335293901Sarybchik EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_LIC)); 1336293901Sarybchik 1337293901Sarybchik switch (enp->en_family) { 1338293901Sarybchik 1339293901Sarybchik#if EFSYS_OPT_SIENA 1340293901Sarybchik case EFX_FAMILY_SIENA: 1341299517Sarybchik elop = &__efx_lic_v1_ops; 1342293901Sarybchik break; 1343293901Sarybchik#endif /* EFSYS_OPT_SIENA */ 1344293901Sarybchik 1345293901Sarybchik#if EFSYS_OPT_HUNTINGTON 1346293901Sarybchik case EFX_FAMILY_HUNTINGTON: 1347299517Sarybchik elop = &__efx_lic_v2_ops; 1348293901Sarybchik break; 1349293901Sarybchik#endif /* EFSYS_OPT_HUNTINGTON */ 1350293901Sarybchik 1351293901Sarybchik#if EFSYS_OPT_MEDFORD 1352293901Sarybchik case EFX_FAMILY_MEDFORD: 1353299517Sarybchik elop = &__efx_lic_v3_ops; 1354293901Sarybchik break; 1355293901Sarybchik#endif /* EFSYS_OPT_MEDFORD */ 1356293901Sarybchik 1357293901Sarybchik default: 1358293901Sarybchik EFSYS_ASSERT(0); 1359293901Sarybchik rc = ENOTSUP; 1360293901Sarybchik goto fail1; 1361293901Sarybchik } 1362293901Sarybchik 1363293901Sarybchik enp->en_elop = elop; 1364293901Sarybchik enp->en_mod_flags |= EFX_MOD_LIC; 1365293901Sarybchik 1366300007Sarybchik /* Probe for support */ 1367300007Sarybchik if (efx_lic_get_key_stats(enp, &eks) == 0) { 1368300007Sarybchik enp->en_licensing_supported = B_TRUE; 1369300007Sarybchik } else { 1370300007Sarybchik enp->en_licensing_supported = B_FALSE; 1371300007Sarybchik } 1372300007Sarybchik 1373293901Sarybchik return (0); 1374293901Sarybchik 1375293901Sarybchikfail1: 1376293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1377293901Sarybchik 1378293901Sarybchik return (rc); 1379293901Sarybchik} 1380293901Sarybchik 1381300007Sarybchikextern __checkReturn boolean_t 1382300007Sarybchikefx_lic_check_support( 1383300007Sarybchik __in efx_nic_t *enp) 1384300007Sarybchik{ 1385300007Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1386300007Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 1387300007Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1388300007Sarybchik 1389300007Sarybchik return enp->en_licensing_supported; 1390300007Sarybchik} 1391300007Sarybchik 1392293901Sarybchik void 1393293901Sarybchikefx_lic_fini( 1394293901Sarybchik __in efx_nic_t *enp) 1395293901Sarybchik{ 1396293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1397293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 1398293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1399293901Sarybchik 1400293901Sarybchik enp->en_elop = NULL; 1401293901Sarybchik enp->en_mod_flags &= ~EFX_MOD_LIC; 1402293901Sarybchik} 1403293901Sarybchik 1404293901Sarybchik 1405293901Sarybchik __checkReturn efx_rc_t 1406293901Sarybchikefx_lic_update_licenses( 1407293901Sarybchik __in efx_nic_t *enp) 1408293901Sarybchik{ 1409299517Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1410293901Sarybchik efx_rc_t rc; 1411293901Sarybchik 1412293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1413293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1414293901Sarybchik 1415293901Sarybchik if ((rc = elop->elo_update_licenses(enp)) != 0) 1416293901Sarybchik goto fail1; 1417293901Sarybchik 1418293901Sarybchik return (0); 1419293901Sarybchik 1420293901Sarybchikfail1: 1421293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1422293901Sarybchik 1423293901Sarybchik return (rc); 1424293901Sarybchik} 1425293901Sarybchik 1426293901Sarybchik __checkReturn efx_rc_t 1427293901Sarybchikefx_lic_get_key_stats( 1428293901Sarybchik __in efx_nic_t *enp, 1429293901Sarybchik __out efx_key_stats_t *eksp) 1430293901Sarybchik{ 1431299517Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1432293901Sarybchik efx_rc_t rc; 1433293901Sarybchik 1434293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1435293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1436293901Sarybchik 1437293901Sarybchik if ((rc = elop->elo_get_key_stats(enp, eksp)) != 0) 1438293901Sarybchik goto fail1; 1439293901Sarybchik 1440293901Sarybchik return (0); 1441293901Sarybchik 1442293901Sarybchikfail1: 1443293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1444293901Sarybchik 1445293901Sarybchik return (rc); 1446293901Sarybchik} 1447293901Sarybchik 1448293901Sarybchik __checkReturn efx_rc_t 1449293901Sarybchikefx_lic_app_state( 1450293901Sarybchik __in efx_nic_t *enp, 1451293901Sarybchik __in uint64_t app_id, 1452293901Sarybchik __out boolean_t *licensedp) 1453293901Sarybchik{ 1454299517Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1455293901Sarybchik efx_rc_t rc; 1456293901Sarybchik 1457293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1458293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1459293901Sarybchik 1460299899Sarybchik if (elop->elo_app_state == NULL) 1461299899Sarybchik return (ENOTSUP); 1462299899Sarybchik 1463299899Sarybchik if ((rc = elop->elo_app_state(enp, app_id, licensedp)) != 0) 1464293901Sarybchik goto fail1; 1465293901Sarybchik 1466293901Sarybchik return (0); 1467293901Sarybchik 1468293901Sarybchikfail1: 1469293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1470293901Sarybchik 1471293901Sarybchik return (rc); 1472293901Sarybchik} 1473293901Sarybchik 1474293901Sarybchik __checkReturn efx_rc_t 1475293901Sarybchikefx_lic_get_id( 1476293901Sarybchik __in efx_nic_t *enp, 1477293901Sarybchik __in size_t buffer_size, 1478293901Sarybchik __out uint32_t *typep, 1479293901Sarybchik __out size_t *lengthp, 1480293901Sarybchik __out_opt uint8_t *bufferp 1481293901Sarybchik ) 1482293901Sarybchik{ 1483299517Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1484293901Sarybchik efx_rc_t rc; 1485293901Sarybchik 1486293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1487293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1488293901Sarybchik 1489299899Sarybchik if (elop->elo_get_id == NULL) 1490299899Sarybchik return (ENOTSUP); 1491293901Sarybchik 1492293901Sarybchik if ((rc = elop->elo_get_id(enp, buffer_size, typep, 1493293901Sarybchik lengthp, bufferp)) != 0) 1494299899Sarybchik goto fail1; 1495293901Sarybchik 1496293901Sarybchik return (0); 1497293901Sarybchik 1498293901Sarybchikfail1: 1499293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1500293901Sarybchik 1501293901Sarybchik return (rc); 1502293901Sarybchik} 1503293901Sarybchik 1504299898Sarybchik/* Buffer management API - abstracts varying TLV format used for License partition */ 1505299898Sarybchik 1506299898Sarybchik __checkReturn efx_rc_t 1507299898Sarybchikefx_lic_find_start( 1508299898Sarybchik __in efx_nic_t *enp, 1509299898Sarybchik __in_bcount(buffer_size) 1510299898Sarybchik caddr_t bufferp, 1511299898Sarybchik __in size_t buffer_size, 1512299898Sarybchik __out uint32_t *startp 1513299898Sarybchik ) 1514299898Sarybchik{ 1515299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1516299898Sarybchik efx_rc_t rc; 1517299898Sarybchik 1518299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1519299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1520299898Sarybchik 1521299898Sarybchik if ((rc = elop->elo_find_start(enp, bufferp, buffer_size, startp)) != 0) 1522299898Sarybchik goto fail1; 1523299898Sarybchik 1524299898Sarybchik return (0); 1525299898Sarybchik 1526299898Sarybchikfail1: 1527299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1528299898Sarybchik 1529299898Sarybchik return (rc); 1530299898Sarybchik} 1531299898Sarybchik 1532299898Sarybchik __checkReturn efx_rc_t 1533299898Sarybchikefx_lic_find_end( 1534299898Sarybchik __in efx_nic_t *enp, 1535299898Sarybchik __in_bcount(buffer_size) 1536299898Sarybchik caddr_t bufferp, 1537299898Sarybchik __in size_t buffer_size, 1538299898Sarybchik __in uint32_t offset, 1539299898Sarybchik __out uint32_t *endp 1540299898Sarybchik ) 1541299898Sarybchik{ 1542299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1543299898Sarybchik efx_rc_t rc; 1544299898Sarybchik 1545299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1546299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1547299898Sarybchik 1548299898Sarybchik if ((rc = elop->elo_find_end(enp, bufferp, buffer_size, offset, endp)) != 0) 1549299898Sarybchik goto fail1; 1550299898Sarybchik 1551299898Sarybchik return (0); 1552299898Sarybchik 1553299898Sarybchikfail1: 1554299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1555299898Sarybchik 1556299898Sarybchik return (rc); 1557299898Sarybchik} 1558299898Sarybchik 1559299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 1560299898Sarybchikefx_lic_find_key( 1561299898Sarybchik __in efx_nic_t *enp, 1562299898Sarybchik __in_bcount(buffer_size) 1563299898Sarybchik caddr_t bufferp, 1564299898Sarybchik __in size_t buffer_size, 1565299898Sarybchik __in uint32_t offset, 1566299898Sarybchik __out uint32_t *startp, 1567299898Sarybchik __out uint32_t *lengthp 1568299898Sarybchik ) 1569299898Sarybchik{ 1570299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1571299898Sarybchik 1572299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1573299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1574299898Sarybchik 1575299898Sarybchik EFSYS_ASSERT(bufferp); 1576299898Sarybchik EFSYS_ASSERT(startp); 1577299898Sarybchik EFSYS_ASSERT(lengthp); 1578299898Sarybchik 1579299898Sarybchik return (elop->elo_find_key(enp, bufferp, buffer_size, offset, 1580299898Sarybchik startp, lengthp)); 1581299898Sarybchik} 1582299898Sarybchik 1583299898Sarybchik 1584299898Sarybchik/* Validate that the buffer contains a single key in a recognised format. 1585299898Sarybchik** An empty or terminator buffer is not accepted as a valid key. 1586299898Sarybchik*/ 1587299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 1588299898Sarybchikefx_lic_validate_key( 1589299898Sarybchik __in efx_nic_t *enp, 1590299898Sarybchik __in_bcount(length) caddr_t keyp, 1591299898Sarybchik __in uint32_t length 1592299898Sarybchik ) 1593299898Sarybchik{ 1594299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1595299898Sarybchik boolean_t rc; 1596299898Sarybchik 1597299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1598299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1599299898Sarybchik 1600299898Sarybchik if ((rc = elop->elo_validate_key(enp, keyp, length)) == B_FALSE) 1601299898Sarybchik goto fail1; 1602299898Sarybchik 1603299898Sarybchik return (B_TRUE); 1604299898Sarybchik 1605299898Sarybchikfail1: 1606299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1607299898Sarybchik 1608299898Sarybchik return (rc); 1609299898Sarybchik} 1610299898Sarybchik 1611299898Sarybchik __checkReturn efx_rc_t 1612299898Sarybchikefx_lic_read_key( 1613299898Sarybchik __in efx_nic_t *enp, 1614299898Sarybchik __in_bcount(buffer_size) 1615299898Sarybchik caddr_t bufferp, 1616299898Sarybchik __in size_t buffer_size, 1617299898Sarybchik __in uint32_t offset, 1618299898Sarybchik __in uint32_t length, 1619299898Sarybchik __out_bcount_part(key_max_size, *lengthp) 1620299898Sarybchik caddr_t keyp, 1621299898Sarybchik __in size_t key_max_size, 1622299898Sarybchik __out uint32_t *lengthp 1623299898Sarybchik ) 1624299898Sarybchik{ 1625299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1626299898Sarybchik efx_rc_t rc; 1627299898Sarybchik 1628299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1629299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1630299898Sarybchik 1631299898Sarybchik if ((rc = elop->elo_read_key(enp, bufferp, buffer_size, offset, 1632299898Sarybchik length, keyp, key_max_size, lengthp)) != 0) 1633299898Sarybchik goto fail1; 1634299898Sarybchik 1635299898Sarybchik return (0); 1636299898Sarybchik 1637299898Sarybchikfail1: 1638299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1639299898Sarybchik 1640299898Sarybchik return (rc); 1641299898Sarybchik} 1642299898Sarybchik 1643299898Sarybchik __checkReturn efx_rc_t 1644299898Sarybchikefx_lic_write_key( 1645299898Sarybchik __in efx_nic_t *enp, 1646299898Sarybchik __in_bcount(buffer_size) 1647299898Sarybchik caddr_t bufferp, 1648299898Sarybchik __in size_t buffer_size, 1649299898Sarybchik __in uint32_t offset, 1650299898Sarybchik __in_bcount(length) caddr_t keyp, 1651299898Sarybchik __in uint32_t length, 1652299898Sarybchik __out uint32_t *lengthp 1653299898Sarybchik ) 1654299898Sarybchik{ 1655299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1656299898Sarybchik efx_rc_t rc; 1657299898Sarybchik 1658299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1659299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1660299898Sarybchik 1661299898Sarybchik if ((rc = elop->elo_write_key(enp, bufferp, buffer_size, offset, 1662299898Sarybchik keyp, length, lengthp)) != 0) 1663299898Sarybchik goto fail1; 1664299898Sarybchik 1665299898Sarybchik return (0); 1666299898Sarybchik 1667299898Sarybchikfail1: 1668299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1669299898Sarybchik 1670299898Sarybchik return (rc); 1671299898Sarybchik} 1672299898Sarybchik 1673299898Sarybchik __checkReturn efx_rc_t 1674299898Sarybchikefx_lic_delete_key( 1675299898Sarybchik __in efx_nic_t *enp, 1676299898Sarybchik __in_bcount(buffer_size) 1677299898Sarybchik caddr_t bufferp, 1678299898Sarybchik __in size_t buffer_size, 1679299898Sarybchik __in uint32_t offset, 1680299898Sarybchik __in uint32_t length, 1681299898Sarybchik __in uint32_t end, 1682299898Sarybchik __out uint32_t *deltap 1683299898Sarybchik ) 1684299898Sarybchik{ 1685299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1686299898Sarybchik efx_rc_t rc; 1687299898Sarybchik 1688299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1689299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1690299898Sarybchik 1691299898Sarybchik if ((rc = elop->elo_delete_key(enp, bufferp, buffer_size, offset, 1692299898Sarybchik length, end, deltap)) != 0) 1693299898Sarybchik goto fail1; 1694299898Sarybchik 1695299898Sarybchik return (0); 1696299898Sarybchik 1697299898Sarybchikfail1: 1698299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1699299898Sarybchik 1700299898Sarybchik return (rc); 1701299898Sarybchik} 1702299898Sarybchik 1703299898Sarybchik __checkReturn efx_rc_t 1704299898Sarybchikefx_lic_create_partition( 1705299898Sarybchik __in efx_nic_t *enp, 1706299898Sarybchik __in_bcount(buffer_size) 1707299898Sarybchik caddr_t bufferp, 1708299898Sarybchik __in size_t buffer_size 1709299898Sarybchik ) 1710299898Sarybchik{ 1711299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1712299898Sarybchik efx_rc_t rc; 1713299898Sarybchik 1714299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1715299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1716299898Sarybchik 1717299898Sarybchik if ((rc = elop->elo_create_partition(enp, bufferp, buffer_size)) != 0) 1718299898Sarybchik goto fail1; 1719299898Sarybchik 1720299898Sarybchik return (0); 1721299898Sarybchik 1722299898Sarybchikfail1: 1723299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1724299898Sarybchik 1725299898Sarybchik return (rc); 1726299898Sarybchik} 1727299898Sarybchik 1728299898Sarybchik 1729299898Sarybchik __checkReturn efx_rc_t 1730299898Sarybchikefx_lic_finish_partition( 1731299898Sarybchik __in efx_nic_t *enp, 1732299898Sarybchik __in_bcount(buffer_size) 1733299898Sarybchik caddr_t bufferp, 1734299898Sarybchik __in size_t buffer_size 1735299898Sarybchik ) 1736299898Sarybchik{ 1737299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1738299898Sarybchik efx_rc_t rc; 1739299898Sarybchik 1740299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1741299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1742299898Sarybchik 1743299898Sarybchik if ((rc = elop->elo_finish_partition(enp, bufferp, buffer_size)) != 0) 1744299898Sarybchik goto fail1; 1745299898Sarybchik 1746299898Sarybchik return (0); 1747299898Sarybchik 1748299898Sarybchikfail1: 1749299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1750299898Sarybchik 1751299898Sarybchik return (rc); 1752299898Sarybchik} 1753299898Sarybchik 1754293901Sarybchik#endif /* EFSYS_OPT_LICENSING */ 1755