efx_lic.c revision 299923
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 299923 2016-05-16 08:27:20Z 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) 459299898Sarybchik#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 509299898Sarybchik if((size_t)buffer_size - offset < EFX_LICENSE_V1V2_HEADER_LENGTH) 510299898Sarybchik goto fail1; 511299898Sarybchik 512299898Sarybchik tlv_type = __LE_TO_CPU_16(((uint16_t*)&bufferp[offset])[0]); 513299898Sarybchik 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: 525299898Sarybchik EFSYS_PROBE(fail1); 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 const efx_lic_ops_t *elop = enp->en_elop; 538299898Sarybchik efx_rc_t rc; 539299898Sarybchik uint16_t tlv_type; 540299898Sarybchik uint16_t tlv_length; 541299898Sarybchik 542299898Sarybchik _NOTE(ARGUNUSED(enp)) 543299898Sarybchik 544299898Sarybchik if (length < EFX_LICENSE_V1V2_HEADER_LENGTH) { 545299898Sarybchik goto fail1; 546299898Sarybchik } 547299898Sarybchik 548299898Sarybchik tlv_type = __LE_TO_CPU_16(((uint16_t*)keyp)[0]); 549299898Sarybchik tlv_length = __LE_TO_CPU_16(((uint16_t*)keyp)[1]); 550299898Sarybchik 551299898Sarybchik if(tlv_length > EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX) { 552299898Sarybchik goto fail2; 553299898Sarybchik } 554299898Sarybchik if (tlv_type == 0) { 555299898Sarybchik goto fail3; 556299898Sarybchik } 557299898Sarybchik if ((tlv_length + EFX_LICENSE_V1V2_HEADER_LENGTH) != length) { 558299898Sarybchik goto fail4; 559299898Sarybchik } 560299898Sarybchik 561299898Sarybchik return (B_TRUE); 562299898Sarybchik 563299898Sarybchikfail4: 564299898Sarybchik EFSYS_PROBE(fail4); 565299898Sarybchikfail3: 566299898Sarybchik EFSYS_PROBE(fail3); 567299898Sarybchikfail2: 568299898Sarybchik EFSYS_PROBE(fail2); 569299898Sarybchikfail1: 570299898Sarybchik EFSYS_PROBE(fail1); 571299898Sarybchik 572299898Sarybchik return (B_FALSE); 573299898Sarybchik} 574299898Sarybchik 575299898Sarybchik 576299898Sarybchik __checkReturn efx_rc_t 577299898Sarybchikefx_lic_v1v2_read_key( 578299898Sarybchik __in efx_nic_t *enp, 579299898Sarybchik __in_bcount(buffer_size) 580299898Sarybchik caddr_t bufferp, 581299898Sarybchik __in size_t buffer_size, 582299898Sarybchik __in uint32_t offset, 583299898Sarybchik __in uint32_t length, 584299898Sarybchik __out_bcount_part(key_max_size, *lengthp) 585299898Sarybchik caddr_t keyp, 586299898Sarybchik __in size_t key_max_size, 587299898Sarybchik __out uint32_t *lengthp 588299898Sarybchik ) 589299898Sarybchik{ 590299898Sarybchik efx_rc_t rc; 591299898Sarybchik 592299898Sarybchik _NOTE(ARGUNUSED(enp)) 593299898Sarybchik EFSYS_ASSERT(length <= (EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX + 594299898Sarybchik EFX_LICENSE_V1V2_HEADER_LENGTH)); 595299898Sarybchik 596299898Sarybchik if (key_max_size < length) { 597299898Sarybchik rc = ENOSPC; 598299898Sarybchik goto fail1; 599299898Sarybchik } 600299898Sarybchik memcpy(keyp, &bufferp[offset], length); 601299898Sarybchik 602299898Sarybchik *lengthp = length; 603299898Sarybchik 604299898Sarybchik return (0); 605299898Sarybchik 606299898Sarybchikfail1: 607299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 608299898Sarybchik 609299898Sarybchik return (rc); 610299898Sarybchik} 611299898Sarybchik 612299898Sarybchik __checkReturn efx_rc_t 613299898Sarybchikefx_lic_v1v2_write_key( 614299898Sarybchik __in efx_nic_t *enp, 615299898Sarybchik __in_bcount(buffer_size) 616299898Sarybchik caddr_t bufferp, 617299898Sarybchik __in size_t buffer_size, 618299898Sarybchik __in uint32_t offset, 619299898Sarybchik __in_bcount(length) caddr_t keyp, 620299898Sarybchik __in uint32_t length, 621299898Sarybchik __out uint32_t *lengthp 622299898Sarybchik ) 623299898Sarybchik{ 624299898Sarybchik efx_rc_t rc; 625299898Sarybchik 626299898Sarybchik _NOTE(ARGUNUSED(enp)) 627299898Sarybchik EFSYS_ASSERT(length <= (EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX + 628299898Sarybchik EFX_LICENSE_V1V2_HEADER_LENGTH)); 629299898Sarybchik 630299898Sarybchik // Ensure space for terminator remains 631299898Sarybchik if ((offset + length) > 632299898Sarybchik (buffer_size - EFX_LICENSE_V1V2_HEADER_LENGTH) ) { 633299898Sarybchik rc = ENOSPC; 634299898Sarybchik goto fail1; 635299898Sarybchik } 636299898Sarybchik 637299898Sarybchik memcpy(bufferp + offset, keyp, length); 638299898Sarybchik 639299898Sarybchik *lengthp = length; 640299898Sarybchik 641299898Sarybchik return (0); 642299898Sarybchik 643299898Sarybchikfail1: 644299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 645299898Sarybchik 646299898Sarybchik return (rc); 647299898Sarybchik} 648299898Sarybchik 649299898Sarybchik __checkReturn efx_rc_t 650299898Sarybchikefx_lic_v1v2_delete_key( 651299898Sarybchik __in efx_nic_t *enp, 652299898Sarybchik __in_bcount(buffer_size) 653299898Sarybchik caddr_t bufferp, 654299898Sarybchik __in size_t buffer_size, 655299898Sarybchik __in uint32_t offset, 656299898Sarybchik __in uint32_t length, 657299898Sarybchik __in uint32_t end, 658299898Sarybchik __out uint32_t *deltap 659299898Sarybchik ) 660299898Sarybchik{ 661299898Sarybchik efx_rc_t rc; 662299898Sarybchik uint32_t move_start = offset + length; 663299898Sarybchik uint32_t move_length = end - move_start; 664299898Sarybchik 665299898Sarybchik _NOTE(ARGUNUSED(enp)) 666299898Sarybchik EFSYS_ASSERT(end <= buffer_size); 667299898Sarybchik 668299898Sarybchik // Shift everything after the key down 669299898Sarybchik memmove(bufferp + offset, bufferp + move_start, move_length); 670299898Sarybchik 671299898Sarybchik *deltap = length; 672299898Sarybchik 673299898Sarybchik return (0); 674299898Sarybchik} 675299898Sarybchik 676299898Sarybchik __checkReturn efx_rc_t 677299898Sarybchikefx_lic_v1v2_create_partition( 678299898Sarybchik __in efx_nic_t *enp, 679299898Sarybchik __in_bcount(buffer_size) 680299898Sarybchik caddr_t bufferp, 681299898Sarybchik __in size_t buffer_size 682299898Sarybchik ) 683299898Sarybchik{ 684299898Sarybchik _NOTE(ARGUNUSED(enp)) 685299898Sarybchik EFSYS_ASSERT(EFX_LICENSE_V1V2_HEADER_LENGTH <= buffer_size); 686299898Sarybchik 687299898Sarybchik // Write terminator 688299898Sarybchik memset(bufferp, '\0', EFX_LICENSE_V1V2_HEADER_LENGTH); 689299898Sarybchik return (0); 690299898Sarybchik} 691299898Sarybchik 692299898Sarybchik 693299898Sarybchik __checkReturn efx_rc_t 694299898Sarybchikefx_lic_v1v2_finish_partition( 695299898Sarybchik __in efx_nic_t *enp, 696299898Sarybchik __in_bcount(buffer_size) 697299898Sarybchik caddr_t bufferp, 698299898Sarybchik __in size_t buffer_size 699299898Sarybchik ) 700299898Sarybchik{ 701299898Sarybchik _NOTE(ARGUNUSED(enp, bufferp, buffer_size)) 702299898Sarybchik 703299898Sarybchik return (0); 704299898Sarybchik} 705299898Sarybchik 706299898Sarybchik#endif /* EFSYS_OPT_HUNTINGTON | EFSYS_OPT_SIENA */ 707299898Sarybchik 708299898Sarybchik 709293901Sarybchik/* V2 Licensing - used by Huntington family only. See SF-113611-TC */ 710293901Sarybchik 711293901Sarybchik#if EFSYS_OPT_HUNTINGTON 712293901Sarybchik 713293901Sarybchikstatic __checkReturn efx_rc_t 714293901Sarybchikefx_mcdi_licensed_app_state( 715293901Sarybchik __in efx_nic_t *enp, 716293901Sarybchik __in uint64_t app_id, 717293901Sarybchik __out boolean_t *licensedp) 718293901Sarybchik{ 719293901Sarybchik efx_mcdi_req_t req; 720293901Sarybchik uint8_t payload[MAX(MC_CMD_GET_LICENSED_APP_STATE_IN_LEN, 721293901Sarybchik MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN)]; 722293901Sarybchik uint32_t app_state; 723293901Sarybchik efx_rc_t rc; 724293901Sarybchik 725293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON); 726293901Sarybchik 727293901Sarybchik /* V2 licensing supports 32bit app id only */ 728293901Sarybchik if ((app_id >> 32) != 0) { 729293901Sarybchik rc = EINVAL; 730293901Sarybchik goto fail1; 731293901Sarybchik } 732293901Sarybchik 733293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 734293901Sarybchik req.emr_cmd = MC_CMD_GET_LICENSED_APP_STATE; 735293901Sarybchik req.emr_in_buf = payload; 736293901Sarybchik req.emr_in_length = MC_CMD_GET_LICENSED_APP_STATE_IN_LEN; 737293901Sarybchik req.emr_out_buf = payload; 738293901Sarybchik req.emr_out_length = MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN; 739293901Sarybchik 740293901Sarybchik MCDI_IN_SET_DWORD(req, GET_LICENSED_APP_STATE_IN_APP_ID, 741293901Sarybchik app_id & 0xffffffff); 742293901Sarybchik 743293901Sarybchik efx_mcdi_execute(enp, &req); 744293901Sarybchik 745293901Sarybchik if (req.emr_rc != 0) { 746293901Sarybchik rc = req.emr_rc; 747293901Sarybchik goto fail2; 748293901Sarybchik } 749293901Sarybchik 750293901Sarybchik if (req.emr_out_length_used < MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN) { 751293901Sarybchik rc = EMSGSIZE; 752293901Sarybchik goto fail3; 753293901Sarybchik } 754293901Sarybchik 755293901Sarybchik app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_APP_STATE_OUT_STATE)); 756293901Sarybchik if (app_state != MC_CMD_GET_LICENSED_APP_STATE_OUT_NOT_LICENSED) { 757293901Sarybchik *licensedp = B_TRUE; 758293901Sarybchik } else { 759293901Sarybchik *licensedp = B_FALSE; 760293901Sarybchik } 761293901Sarybchik 762293901Sarybchik return (0); 763293901Sarybchik 764293901Sarybchikfail3: 765293901Sarybchik EFSYS_PROBE(fail3); 766293901Sarybchikfail2: 767293901Sarybchik EFSYS_PROBE(fail2); 768293901Sarybchikfail1: 769293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 770293901Sarybchik 771293901Sarybchik return (rc); 772293901Sarybchik} 773293901Sarybchik 774293901Sarybchikstatic __checkReturn efx_rc_t 775293901Sarybchikefx_mcdi_licensing_update_licenses( 776293901Sarybchik __in efx_nic_t *enp) 777293901Sarybchik{ 778293901Sarybchik efx_mcdi_req_t req; 779293901Sarybchik uint8_t payload[MC_CMD_LICENSING_IN_LEN]; 780293901Sarybchik efx_rc_t rc; 781293901Sarybchik 782293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON); 783293901Sarybchik 784293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 785293901Sarybchik req.emr_cmd = MC_CMD_LICENSING; 786293901Sarybchik req.emr_in_buf = payload; 787293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_IN_LEN; 788293901Sarybchik req.emr_out_buf = payload; 789293901Sarybchik req.emr_out_length = 0; 790293901Sarybchik 791293901Sarybchik MCDI_IN_SET_DWORD(req, LICENSING_IN_OP, 792293901Sarybchik MC_CMD_LICENSING_IN_OP_UPDATE_LICENSE); 793293901Sarybchik 794293901Sarybchik efx_mcdi_execute(enp, &req); 795293901Sarybchik 796293901Sarybchik if (req.emr_rc != 0) { 797293901Sarybchik rc = req.emr_rc; 798293901Sarybchik goto fail1; 799293901Sarybchik } 800293901Sarybchik 801293901Sarybchik if (req.emr_out_length_used != 0) { 802293901Sarybchik rc = EIO; 803293901Sarybchik goto fail2; 804293901Sarybchik } 805293901Sarybchik 806293901Sarybchik return (0); 807293901Sarybchik 808293901Sarybchikfail2: 809293901Sarybchik EFSYS_PROBE(fail2); 810293901Sarybchikfail1: 811293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 812293901Sarybchik 813293901Sarybchik return (rc); 814293901Sarybchik} 815293901Sarybchik 816293901Sarybchikstatic __checkReturn efx_rc_t 817293901Sarybchikefx_mcdi_licensing_get_key_stats( 818293901Sarybchik __in efx_nic_t *enp, 819293901Sarybchik __out efx_key_stats_t *eksp) 820293901Sarybchik{ 821293901Sarybchik efx_mcdi_req_t req; 822293901Sarybchik uint8_t payload[MAX(MC_CMD_LICENSING_IN_LEN, 823293901Sarybchik MC_CMD_LICENSING_OUT_LEN)]; 824293901Sarybchik efx_rc_t rc; 825293901Sarybchik 826293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON); 827293901Sarybchik 828293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 829293901Sarybchik req.emr_cmd = MC_CMD_LICENSING; 830293901Sarybchik req.emr_in_buf = payload; 831293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_IN_LEN; 832293901Sarybchik req.emr_out_buf = payload; 833293901Sarybchik req.emr_out_length = MC_CMD_LICENSING_OUT_LEN; 834293901Sarybchik 835293901Sarybchik MCDI_IN_SET_DWORD(req, LICENSING_IN_OP, 836293901Sarybchik MC_CMD_LICENSING_IN_OP_GET_KEY_STATS); 837293901Sarybchik 838293901Sarybchik efx_mcdi_execute(enp, &req); 839293901Sarybchik 840293901Sarybchik if (req.emr_rc != 0) { 841293901Sarybchik rc = req.emr_rc; 842293901Sarybchik goto fail1; 843293901Sarybchik } 844293901Sarybchik 845293901Sarybchik if (req.emr_out_length_used < MC_CMD_LICENSING_OUT_LEN) { 846293901Sarybchik rc = EMSGSIZE; 847293901Sarybchik goto fail2; 848293901Sarybchik } 849293901Sarybchik 850293901Sarybchik eksp->eks_valid = 851293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_OUT_VALID_APP_KEYS); 852293901Sarybchik eksp->eks_invalid = 853293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_OUT_INVALID_APP_KEYS); 854293901Sarybchik eksp->eks_blacklisted = 855293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_OUT_BLACKLISTED_APP_KEYS); 856293901Sarybchik eksp->eks_unverifiable = 857293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_OUT_UNVERIFIABLE_APP_KEYS); 858293901Sarybchik eksp->eks_wrong_node = 859293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_OUT_WRONG_NODE_APP_KEYS); 860293901Sarybchik eksp->eks_licensed_apps_lo = 0; 861293901Sarybchik eksp->eks_licensed_apps_hi = 0; 862293901Sarybchik eksp->eks_licensed_features_lo = 0; 863293901Sarybchik eksp->eks_licensed_features_hi = 0; 864293901Sarybchik 865293901Sarybchik return (0); 866293901Sarybchik 867293901Sarybchikfail2: 868293901Sarybchik EFSYS_PROBE(fail2); 869293901Sarybchikfail1: 870293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 871293901Sarybchik 872293901Sarybchik return (rc); 873293901Sarybchik} 874293901Sarybchik 875293901Sarybchik#endif /* EFSYS_OPT_HUNTINGTON */ 876293901Sarybchik 877293901Sarybchik/* V3 Licensing - used starting from Medford family. See SF-114884-SW */ 878293901Sarybchik 879293901Sarybchik#if EFSYS_OPT_MEDFORD 880293901Sarybchik 881293901Sarybchikstatic __checkReturn efx_rc_t 882293901Sarybchikefx_mcdi_licensing_v3_update_licenses( 883293901Sarybchik __in efx_nic_t *enp) 884293901Sarybchik{ 885293901Sarybchik efx_mcdi_req_t req; 886293901Sarybchik uint8_t payload[MC_CMD_LICENSING_V3_IN_LEN]; 887293901Sarybchik efx_rc_t rc; 888293901Sarybchik 889293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD); 890293901Sarybchik 891293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 892293901Sarybchik req.emr_cmd = MC_CMD_LICENSING_V3; 893293901Sarybchik req.emr_in_buf = payload; 894293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN; 895293901Sarybchik req.emr_out_buf = NULL; 896293901Sarybchik req.emr_out_length = 0; 897293901Sarybchik 898293901Sarybchik MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP, 899293901Sarybchik MC_CMD_LICENSING_V3_IN_OP_UPDATE_LICENSE); 900293901Sarybchik 901293901Sarybchik efx_mcdi_execute(enp, &req); 902293901Sarybchik 903293901Sarybchik if (req.emr_rc != 0) { 904293901Sarybchik rc = req.emr_rc; 905293901Sarybchik goto fail1; 906293901Sarybchik } 907293901Sarybchik 908293901Sarybchik return (0); 909293901Sarybchik 910293901Sarybchikfail1: 911293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 912293901Sarybchik 913293901Sarybchik return (rc); 914293901Sarybchik} 915293901Sarybchik 916293901Sarybchikstatic __checkReturn efx_rc_t 917293901Sarybchikefx_mcdi_licensing_v3_report_license( 918293901Sarybchik __in efx_nic_t *enp, 919293901Sarybchik __out efx_key_stats_t *eksp) 920293901Sarybchik{ 921293901Sarybchik efx_mcdi_req_t req; 922293901Sarybchik uint8_t payload[MAX(MC_CMD_LICENSING_V3_IN_LEN, 923293901Sarybchik MC_CMD_LICENSING_V3_OUT_LEN)]; 924293901Sarybchik efx_rc_t rc; 925293901Sarybchik 926293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD); 927293901Sarybchik 928293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 929293901Sarybchik req.emr_cmd = MC_CMD_LICENSING_V3; 930293901Sarybchik req.emr_in_buf = payload; 931293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN; 932293901Sarybchik req.emr_out_buf = payload; 933293901Sarybchik req.emr_out_length = MC_CMD_LICENSING_V3_OUT_LEN; 934293901Sarybchik 935293901Sarybchik MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP, 936293901Sarybchik MC_CMD_LICENSING_V3_IN_OP_REPORT_LICENSE); 937293901Sarybchik 938299923Sarybchik efx_mcdi_execute_quiet(enp, &req); 939293901Sarybchik 940293901Sarybchik if (req.emr_rc != 0) { 941293901Sarybchik rc = req.emr_rc; 942293901Sarybchik goto fail1; 943293901Sarybchik } 944293901Sarybchik 945293901Sarybchik if (req.emr_out_length_used < MC_CMD_LICENSING_V3_OUT_LEN) { 946293901Sarybchik rc = EMSGSIZE; 947293901Sarybchik goto fail2; 948293901Sarybchik } 949293901Sarybchik 950293901Sarybchik eksp->eks_valid = 951293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_VALID_KEYS); 952293901Sarybchik eksp->eks_invalid = 953293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_INVALID_KEYS); 954293901Sarybchik eksp->eks_blacklisted = 0; 955293901Sarybchik eksp->eks_unverifiable = 956293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_UNVERIFIABLE_KEYS); 957293901Sarybchik eksp->eks_wrong_node = 958293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_WRONG_NODE_KEYS); 959293901Sarybchik eksp->eks_licensed_apps_lo = 960293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_LO); 961293901Sarybchik eksp->eks_licensed_apps_hi = 962293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_HI); 963293901Sarybchik eksp->eks_licensed_features_lo = 964293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_LO); 965293901Sarybchik eksp->eks_licensed_features_hi = 966293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_HI); 967293901Sarybchik 968293901Sarybchik return (0); 969293901Sarybchik 970293901Sarybchikfail2: 971293901Sarybchik EFSYS_PROBE(fail2); 972293901Sarybchikfail1: 973293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 974293901Sarybchik 975293901Sarybchik return (rc); 976293901Sarybchik} 977293901Sarybchik 978293901Sarybchikstatic __checkReturn efx_rc_t 979293901Sarybchikefx_mcdi_licensing_v3_app_state( 980293901Sarybchik __in efx_nic_t *enp, 981293901Sarybchik __in uint64_t app_id, 982293901Sarybchik __out boolean_t *licensedp) 983293901Sarybchik{ 984293901Sarybchik efx_mcdi_req_t req; 985293901Sarybchik uint8_t payload[MAX(MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN, 986293901Sarybchik MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN)]; 987293901Sarybchik uint32_t app_state; 988293901Sarybchik efx_rc_t rc; 989293901Sarybchik 990293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD); 991293901Sarybchik 992293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 993293901Sarybchik req.emr_cmd = MC_CMD_GET_LICENSED_V3_APP_STATE; 994293901Sarybchik req.emr_in_buf = payload; 995293901Sarybchik req.emr_in_length = MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN; 996293901Sarybchik req.emr_out_buf = payload; 997293901Sarybchik req.emr_out_length = MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN; 998293901Sarybchik 999293901Sarybchik MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_LO, 1000293901Sarybchik app_id & 0xffffffff); 1001293901Sarybchik MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_HI, 1002293901Sarybchik app_id >> 32); 1003293901Sarybchik 1004293901Sarybchik efx_mcdi_execute(enp, &req); 1005293901Sarybchik 1006293901Sarybchik if (req.emr_rc != 0) { 1007293901Sarybchik rc = req.emr_rc; 1008293901Sarybchik goto fail1; 1009293901Sarybchik } 1010293901Sarybchik 1011293901Sarybchik if (req.emr_out_length_used < MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN) { 1012293901Sarybchik rc = EMSGSIZE; 1013293901Sarybchik goto fail2; 1014293901Sarybchik } 1015293901Sarybchik 1016293901Sarybchik app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_V3_APP_STATE_OUT_STATE)); 1017293901Sarybchik if (app_state != MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_NOT_LICENSED) { 1018293901Sarybchik *licensedp = B_TRUE; 1019293901Sarybchik } else { 1020293901Sarybchik *licensedp = B_FALSE; 1021293901Sarybchik } 1022293901Sarybchik 1023293901Sarybchik return (0); 1024293901Sarybchik 1025293901Sarybchikfail2: 1026293901Sarybchik EFSYS_PROBE(fail2); 1027293901Sarybchikfail1: 1028293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1029293901Sarybchik 1030293901Sarybchik return (rc); 1031293901Sarybchik} 1032293901Sarybchik 1033293901Sarybchikstatic __checkReturn efx_rc_t 1034293901Sarybchikefx_mcdi_licensing_v3_get_id( 1035293901Sarybchik __in efx_nic_t *enp, 1036293901Sarybchik __in size_t buffer_size, 1037293901Sarybchik __out uint32_t *typep, 1038293901Sarybchik __out size_t *lengthp, 1039293901Sarybchik __out_bcount_part_opt(buffer_size, *lengthp) 1040293901Sarybchik uint8_t *bufferp) 1041293901Sarybchik{ 1042293901Sarybchik efx_mcdi_req_t req; 1043293901Sarybchik uint8_t payload[MAX(MC_CMD_LICENSING_GET_ID_V3_IN_LEN, 1044293901Sarybchik MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN)]; 1045293901Sarybchik efx_rc_t rc; 1046293901Sarybchik 1047293901Sarybchik req.emr_cmd = MC_CMD_LICENSING_GET_ID_V3; 1048293901Sarybchik 1049293901Sarybchik if (bufferp == NULL) { 1050293901Sarybchik /* Request id type and length only */ 1051293901Sarybchik req.emr_in_buf = bufferp; 1052293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN; 1053293901Sarybchik req.emr_out_buf = bufferp; 1054293901Sarybchik req.emr_out_length = MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN; 1055293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 1056293901Sarybchik } else { 1057293901Sarybchik /* Request full buffer */ 1058293901Sarybchik req.emr_in_buf = bufferp; 1059293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN; 1060293901Sarybchik req.emr_out_buf = bufferp; 1061299898Sarybchik req.emr_out_length = MIN(buffer_size, MC_CMD_LICENSING_GET_ID_V3_OUT_LENMAX); 1062293901Sarybchik (void) memset(bufferp, 0, req.emr_out_length); 1063293901Sarybchik } 1064293901Sarybchik 1065299923Sarybchik efx_mcdi_execute_quiet(enp, &req); 1066293901Sarybchik 1067293901Sarybchik if (req.emr_rc != 0) { 1068293901Sarybchik rc = req.emr_rc; 1069293901Sarybchik goto fail1; 1070293901Sarybchik } 1071293901Sarybchik 1072293901Sarybchik if (req.emr_out_length_used < MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN) { 1073293901Sarybchik rc = EMSGSIZE; 1074293901Sarybchik goto fail2; 1075293901Sarybchik } 1076293901Sarybchik 1077293901Sarybchik *typep = MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_TYPE); 1078293901Sarybchik *lengthp = MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_ID_LENGTH); 1079293901Sarybchik 1080293901Sarybchik if (bufferp == NULL) { 1081293901Sarybchik /* modify length requirements to indicate to caller the extra buffering 1082293901Sarybchik ** needed to read the complete output. 1083293901Sarybchik */ 1084293901Sarybchik *lengthp += MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN; 1085293901Sarybchik } else { 1086293901Sarybchik /* Shift ID down to start of buffer */ 1087293901Sarybchik memmove(bufferp, 1088293901Sarybchik bufferp+MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST, 1089293901Sarybchik *lengthp); 1090293901Sarybchik memset(bufferp+(*lengthp), 0, MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST); 1091293901Sarybchik } 1092293901Sarybchik 1093293901Sarybchik return (0); 1094293901Sarybchik 1095293901Sarybchikfail2: 1096293901Sarybchik EFSYS_PROBE(fail2); 1097293901Sarybchikfail1: 1098293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1099293901Sarybchik 1100293901Sarybchik return (rc); 1101293901Sarybchik} 1102293901Sarybchik 1103299898Sarybchik/* V3 format uses Huntington TLV format partition. See SF-108797-SW */ 1104299898Sarybchik#define EFX_LICENSE_V3_KEY_LENGTH_MIN (64) 1105299907Sarybchik#define EFX_LICENSE_V3_KEY_LENGTH_MAX (160) 1106293901Sarybchik 1107299898Sarybchik __checkReturn efx_rc_t 1108299898Sarybchikefx_lic_v3_find_start( 1109299898Sarybchik __in efx_nic_t *enp, 1110299898Sarybchik __in_bcount(buffer_size) 1111299898Sarybchik caddr_t bufferp, 1112299898Sarybchik __in size_t buffer_size, 1113299898Sarybchik __out uint32_t *startp 1114299898Sarybchik ) 1115299898Sarybchik{ 1116299898Sarybchik _NOTE(ARGUNUSED(enp)) 1117299898Sarybchik 1118299898Sarybchik return ef10_nvram_buffer_find_item_start(bufferp, buffer_size, startp); 1119299898Sarybchik} 1120299898Sarybchik 1121299898Sarybchik __checkReturn efx_rc_t 1122299898Sarybchikefx_lic_v3_find_end( 1123299898Sarybchik __in efx_nic_t *enp, 1124299898Sarybchik __in_bcount(buffer_size) 1125299898Sarybchik caddr_t bufferp, 1126299898Sarybchik __in size_t buffer_size, 1127299898Sarybchik __in uint32_t offset, 1128299898Sarybchik __out uint32_t *endp 1129299898Sarybchik ) 1130299898Sarybchik{ 1131299898Sarybchik _NOTE(ARGUNUSED(enp)) 1132299898Sarybchik 1133299898Sarybchik return ef10_nvram_buffer_find_end(bufferp, buffer_size, offset, endp); 1134299898Sarybchik} 1135299898Sarybchik 1136299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 1137299898Sarybchikefx_lic_v3_find_key( 1138299898Sarybchik __in efx_nic_t *enp, 1139299898Sarybchik __in_bcount(buffer_size) 1140299898Sarybchik caddr_t bufferp, 1141299898Sarybchik __in size_t buffer_size, 1142299898Sarybchik __in uint32_t offset, 1143299898Sarybchik __out uint32_t *startp, 1144299898Sarybchik __out uint32_t *lengthp 1145299898Sarybchik ) 1146299898Sarybchik{ 1147299898Sarybchik _NOTE(ARGUNUSED(enp)) 1148299898Sarybchik 1149299898Sarybchik return ef10_nvram_buffer_find_item(bufferp, buffer_size, 1150299898Sarybchik offset, startp, lengthp); 1151299898Sarybchik} 1152299898Sarybchik 1153299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 1154299898Sarybchikefx_lic_v3_validate_key( 1155299898Sarybchik __in efx_nic_t *enp, 1156299898Sarybchik __in_bcount(length) caddr_t keyp, 1157299898Sarybchik __in uint32_t length 1158299898Sarybchik ) 1159299898Sarybchik{ 1160299898Sarybchik // Check key is a valid V3 key 1161299898Sarybchik efx_rc_t rc; 1162299898Sarybchik uint8_t key_type; 1163299898Sarybchik uint8_t key_length; 1164299898Sarybchik 1165299898Sarybchik _NOTE(ARGUNUSED(enp)) 1166299898Sarybchik 1167299898Sarybchik if (length < EFX_LICENSE_V3_KEY_LENGTH_MIN) { 1168299898Sarybchik goto fail1; 1169299898Sarybchik } 1170299898Sarybchik 1171299911Sarybchik if (length > EFX_LICENSE_V3_KEY_LENGTH_MAX) { 1172299911Sarybchik goto fail2; 1173299911Sarybchik } 1174299911Sarybchik 1175299898Sarybchik key_type = ((uint8_t*)keyp)[0]; 1176299911Sarybchik key_length = ((uint8_t*)keyp)[1]; 1177299898Sarybchik 1178299898Sarybchik if (key_type < 3) { 1179299898Sarybchik goto fail3; 1180299898Sarybchik } 1181299911Sarybchik if (key_length > length) { 1182299898Sarybchik goto fail4; 1183299898Sarybchik } 1184299898Sarybchik return (B_TRUE); 1185299898Sarybchik 1186299898Sarybchikfail4: 1187299898Sarybchik EFSYS_PROBE(fail4); 1188299898Sarybchikfail3: 1189299898Sarybchik EFSYS_PROBE(fail3); 1190299898Sarybchikfail2: 1191299898Sarybchik EFSYS_PROBE(fail2); 1192299898Sarybchikfail1: 1193299898Sarybchik EFSYS_PROBE(fail1); 1194299898Sarybchik 1195299898Sarybchik return (B_FALSE); 1196299898Sarybchik} 1197299898Sarybchik 1198299898Sarybchik __checkReturn efx_rc_t 1199299898Sarybchikefx_lic_v3_read_key( 1200299898Sarybchik __in efx_nic_t *enp, 1201299898Sarybchik __in_bcount(buffer_size) 1202299898Sarybchik caddr_t bufferp, 1203299898Sarybchik __in size_t buffer_size, 1204299898Sarybchik __in uint32_t offset, 1205299898Sarybchik __in uint32_t length, 1206299898Sarybchik __out_bcount_part(key_max_size, *lengthp) 1207299898Sarybchik caddr_t keyp, 1208299898Sarybchik __in size_t key_max_size, 1209299898Sarybchik __out uint32_t *lengthp 1210299898Sarybchik ) 1211299898Sarybchik{ 1212299898Sarybchik _NOTE(ARGUNUSED(enp)) 1213299898Sarybchik 1214299898Sarybchik return ef10_nvram_buffer_get_item(bufferp, buffer_size, 1215299898Sarybchik offset, length, keyp, key_max_size, lengthp); 1216299898Sarybchik} 1217299898Sarybchik 1218299898Sarybchik __checkReturn efx_rc_t 1219299898Sarybchikefx_lic_v3_write_key( 1220299898Sarybchik __in efx_nic_t *enp, 1221299898Sarybchik __in_bcount(buffer_size) 1222299898Sarybchik caddr_t bufferp, 1223299898Sarybchik __in size_t buffer_size, 1224299898Sarybchik __in uint32_t offset, 1225299898Sarybchik __in_bcount(length) caddr_t keyp, 1226299898Sarybchik __in uint32_t length, 1227299898Sarybchik __out uint32_t *lengthp 1228299898Sarybchik ) 1229299898Sarybchik{ 1230299898Sarybchik _NOTE(ARGUNUSED(enp)) 1231299898Sarybchik EFSYS_ASSERT(length <= EFX_LICENSE_V3_KEY_LENGTH_MAX); 1232299898Sarybchik 1233299898Sarybchik return ef10_nvram_buffer_insert_item(bufferp, buffer_size, 1234299898Sarybchik offset, keyp, length, lengthp); 1235299898Sarybchik} 1236299898Sarybchik 1237299898Sarybchik __checkReturn efx_rc_t 1238299898Sarybchikefx_lic_v3_delete_key( 1239299898Sarybchik __in efx_nic_t *enp, 1240299898Sarybchik __in_bcount(buffer_size) 1241299898Sarybchik caddr_t bufferp, 1242299898Sarybchik __in size_t buffer_size, 1243299898Sarybchik __in uint32_t offset, 1244299898Sarybchik __in uint32_t length, 1245299898Sarybchik __in uint32_t end, 1246299898Sarybchik __out uint32_t *deltap 1247299898Sarybchik ) 1248299898Sarybchik{ 1249299898Sarybchik efx_rc_t rc; 1250299898Sarybchik 1251299898Sarybchik _NOTE(ARGUNUSED(enp)) 1252299898Sarybchik 1253299898Sarybchik if ((rc = ef10_nvram_buffer_delete_item(bufferp, 1254299898Sarybchik buffer_size, offset, length, end)) != 0) { 1255299898Sarybchik goto fail1; 1256299898Sarybchik } 1257299898Sarybchik 1258299898Sarybchik *deltap = length; 1259299898Sarybchik 1260299898Sarybchik return (0); 1261299898Sarybchik 1262299898Sarybchikfail1: 1263299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1264299898Sarybchik 1265299898Sarybchik return (rc); 1266299898Sarybchik} 1267299898Sarybchik 1268299898Sarybchik __checkReturn efx_rc_t 1269299898Sarybchikefx_lic_v3_create_partition( 1270299898Sarybchik __in efx_nic_t *enp, 1271299898Sarybchik __in_bcount(buffer_size) 1272299898Sarybchik caddr_t bufferp, 1273299898Sarybchik __in size_t buffer_size 1274299898Sarybchik ) 1275299898Sarybchik{ 1276299898Sarybchik efx_rc_t rc; 1277299898Sarybchik 1278299898Sarybchik // Construct empty partition 1279299898Sarybchik if ((rc = ef10_nvram_buffer_create(enp, 1280299898Sarybchik NVRAM_PARTITION_TYPE_LICENSE, 1281299898Sarybchik bufferp, buffer_size)) != 0) { 1282299898Sarybchik rc = EFAULT; 1283299898Sarybchik goto fail1; 1284299898Sarybchik } 1285299898Sarybchik 1286299898Sarybchik return (0); 1287299898Sarybchik 1288299898Sarybchikfail1: 1289299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1290299898Sarybchik 1291299898Sarybchik return (rc); 1292299898Sarybchik} 1293299898Sarybchik 1294299898Sarybchik __checkReturn efx_rc_t 1295299898Sarybchikefx_lic_v3_finish_partition( 1296299898Sarybchik __in efx_nic_t *enp, 1297299898Sarybchik __in_bcount(buffer_size) 1298299898Sarybchik caddr_t bufferp, 1299299898Sarybchik __in size_t buffer_size 1300299898Sarybchik ) 1301299898Sarybchik{ 1302299898Sarybchik efx_rc_t rc; 1303299898Sarybchik 1304299898Sarybchik if ((rc = ef10_nvram_buffer_finish(bufferp, 1305299898Sarybchik buffer_size)) != 0) { 1306299898Sarybchik goto fail1; 1307299898Sarybchik } 1308299898Sarybchik 1309299898Sarybchik // Validate completed partition 1310299898Sarybchik if ((rc = ef10_nvram_buffer_validate(enp, NVRAM_PARTITION_TYPE_LICENSE, 1311299898Sarybchik bufferp, buffer_size)) != 0) { 1312299898Sarybchik goto fail2; 1313299898Sarybchik } 1314299898Sarybchik 1315299898Sarybchik return (0); 1316299898Sarybchik 1317299898Sarybchikfail2: 1318299898Sarybchik EFSYS_PROBE(fail2); 1319299898Sarybchikfail1: 1320299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1321299898Sarybchik 1322299898Sarybchik return (rc); 1323299898Sarybchik} 1324299898Sarybchik 1325299898Sarybchik 1326293901Sarybchik#endif /* EFSYS_OPT_MEDFORD */ 1327293901Sarybchik 1328293901Sarybchik __checkReturn efx_rc_t 1329293901Sarybchikefx_lic_init( 1330293901Sarybchik __in efx_nic_t *enp) 1331293901Sarybchik{ 1332299517Sarybchik const efx_lic_ops_t *elop; 1333293901Sarybchik efx_rc_t rc; 1334293901Sarybchik 1335293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1336293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 1337293901Sarybchik EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_LIC)); 1338293901Sarybchik 1339293901Sarybchik switch (enp->en_family) { 1340293901Sarybchik 1341293901Sarybchik#if EFSYS_OPT_SIENA 1342293901Sarybchik case EFX_FAMILY_SIENA: 1343299517Sarybchik elop = &__efx_lic_v1_ops; 1344293901Sarybchik break; 1345293901Sarybchik#endif /* EFSYS_OPT_SIENA */ 1346293901Sarybchik 1347293901Sarybchik#if EFSYS_OPT_HUNTINGTON 1348293901Sarybchik case EFX_FAMILY_HUNTINGTON: 1349299517Sarybchik elop = &__efx_lic_v2_ops; 1350293901Sarybchik break; 1351293901Sarybchik#endif /* EFSYS_OPT_HUNTINGTON */ 1352293901Sarybchik 1353293901Sarybchik#if EFSYS_OPT_MEDFORD 1354293901Sarybchik case EFX_FAMILY_MEDFORD: 1355299517Sarybchik elop = &__efx_lic_v3_ops; 1356293901Sarybchik break; 1357293901Sarybchik#endif /* EFSYS_OPT_MEDFORD */ 1358293901Sarybchik 1359293901Sarybchik default: 1360293901Sarybchik EFSYS_ASSERT(0); 1361293901Sarybchik rc = ENOTSUP; 1362293901Sarybchik goto fail1; 1363293901Sarybchik } 1364293901Sarybchik 1365293901Sarybchik enp->en_elop = elop; 1366293901Sarybchik enp->en_mod_flags |= EFX_MOD_LIC; 1367293901Sarybchik 1368293901Sarybchik return (0); 1369293901Sarybchik 1370293901Sarybchikfail1: 1371293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1372293901Sarybchik 1373293901Sarybchik return (rc); 1374293901Sarybchik} 1375293901Sarybchik 1376293901Sarybchik void 1377293901Sarybchikefx_lic_fini( 1378293901Sarybchik __in efx_nic_t *enp) 1379293901Sarybchik{ 1380299517Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1381293901Sarybchik 1382293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1383293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 1384293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1385293901Sarybchik 1386293901Sarybchik enp->en_elop = NULL; 1387293901Sarybchik enp->en_mod_flags &= ~EFX_MOD_LIC; 1388293901Sarybchik} 1389293901Sarybchik 1390293901Sarybchik 1391293901Sarybchik __checkReturn efx_rc_t 1392293901Sarybchikefx_lic_update_licenses( 1393293901Sarybchik __in efx_nic_t *enp) 1394293901Sarybchik{ 1395299517Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1396293901Sarybchik efx_rc_t rc; 1397293901Sarybchik 1398293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1399293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1400293901Sarybchik 1401293901Sarybchik if ((rc = elop->elo_update_licenses(enp)) != 0) 1402293901Sarybchik goto fail1; 1403293901Sarybchik 1404293901Sarybchik return (0); 1405293901Sarybchik 1406293901Sarybchikfail1: 1407293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1408293901Sarybchik 1409293901Sarybchik return (rc); 1410293901Sarybchik} 1411293901Sarybchik 1412293901Sarybchik __checkReturn efx_rc_t 1413293901Sarybchikefx_lic_get_key_stats( 1414293901Sarybchik __in efx_nic_t *enp, 1415293901Sarybchik __out efx_key_stats_t *eksp) 1416293901Sarybchik{ 1417299517Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1418293901Sarybchik efx_rc_t rc; 1419293901Sarybchik 1420293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1421293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1422293901Sarybchik 1423293901Sarybchik if ((rc = elop->elo_get_key_stats(enp, eksp)) != 0) 1424293901Sarybchik goto fail1; 1425293901Sarybchik 1426293901Sarybchik return (0); 1427293901Sarybchik 1428293901Sarybchikfail1: 1429293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1430293901Sarybchik 1431293901Sarybchik return (rc); 1432293901Sarybchik} 1433293901Sarybchik 1434293901Sarybchik __checkReturn efx_rc_t 1435293901Sarybchikefx_lic_app_state( 1436293901Sarybchik __in efx_nic_t *enp, 1437293901Sarybchik __in uint64_t app_id, 1438293901Sarybchik __out boolean_t *licensedp) 1439293901Sarybchik{ 1440299517Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1441293901Sarybchik efx_rc_t rc; 1442293901Sarybchik 1443293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1444293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1445293901Sarybchik 1446299899Sarybchik if (elop->elo_app_state == NULL) 1447299899Sarybchik return (ENOTSUP); 1448299899Sarybchik 1449299899Sarybchik if ((rc = elop->elo_app_state(enp, app_id, licensedp)) != 0) 1450293901Sarybchik goto fail1; 1451293901Sarybchik 1452293901Sarybchik return (0); 1453293901Sarybchik 1454293901Sarybchikfail1: 1455293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1456293901Sarybchik 1457293901Sarybchik return (rc); 1458293901Sarybchik} 1459293901Sarybchik 1460293901Sarybchik __checkReturn efx_rc_t 1461293901Sarybchikefx_lic_get_id( 1462293901Sarybchik __in efx_nic_t *enp, 1463293901Sarybchik __in size_t buffer_size, 1464293901Sarybchik __out uint32_t *typep, 1465293901Sarybchik __out size_t *lengthp, 1466293901Sarybchik __out_opt uint8_t *bufferp 1467293901Sarybchik ) 1468293901Sarybchik{ 1469299517Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1470293901Sarybchik efx_rc_t rc; 1471293901Sarybchik 1472293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1473293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1474293901Sarybchik 1475299899Sarybchik if (elop->elo_get_id == NULL) 1476299899Sarybchik return (ENOTSUP); 1477293901Sarybchik 1478293901Sarybchik if ((rc = elop->elo_get_id(enp, buffer_size, typep, 1479293901Sarybchik lengthp, bufferp)) != 0) 1480299899Sarybchik goto fail1; 1481293901Sarybchik 1482293901Sarybchik return (0); 1483293901Sarybchik 1484293901Sarybchikfail1: 1485293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1486293901Sarybchik 1487293901Sarybchik return (rc); 1488293901Sarybchik} 1489293901Sarybchik 1490299898Sarybchik/* Buffer management API - abstracts varying TLV format used for License partition */ 1491299898Sarybchik 1492299898Sarybchik __checkReturn efx_rc_t 1493299898Sarybchikefx_lic_find_start( 1494299898Sarybchik __in efx_nic_t *enp, 1495299898Sarybchik __in_bcount(buffer_size) 1496299898Sarybchik caddr_t bufferp, 1497299898Sarybchik __in size_t buffer_size, 1498299898Sarybchik __out uint32_t *startp 1499299898Sarybchik ) 1500299898Sarybchik{ 1501299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1502299898Sarybchik efx_rc_t rc; 1503299898Sarybchik 1504299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1505299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1506299898Sarybchik 1507299898Sarybchik if ((rc = elop->elo_find_start(enp, bufferp, buffer_size, startp)) != 0) 1508299898Sarybchik goto fail1; 1509299898Sarybchik 1510299898Sarybchik return (0); 1511299898Sarybchik 1512299898Sarybchikfail1: 1513299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1514299898Sarybchik 1515299898Sarybchik return (rc); 1516299898Sarybchik} 1517299898Sarybchik 1518299898Sarybchik __checkReturn efx_rc_t 1519299898Sarybchikefx_lic_find_end( 1520299898Sarybchik __in efx_nic_t *enp, 1521299898Sarybchik __in_bcount(buffer_size) 1522299898Sarybchik caddr_t bufferp, 1523299898Sarybchik __in size_t buffer_size, 1524299898Sarybchik __in uint32_t offset, 1525299898Sarybchik __out uint32_t *endp 1526299898Sarybchik ) 1527299898Sarybchik{ 1528299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1529299898Sarybchik efx_rc_t rc; 1530299898Sarybchik 1531299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1532299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1533299898Sarybchik 1534299898Sarybchik if ((rc = elop->elo_find_end(enp, bufferp, buffer_size, offset, endp)) != 0) 1535299898Sarybchik goto fail1; 1536299898Sarybchik 1537299898Sarybchik return (0); 1538299898Sarybchik 1539299898Sarybchikfail1: 1540299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1541299898Sarybchik 1542299898Sarybchik return (rc); 1543299898Sarybchik} 1544299898Sarybchik 1545299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 1546299898Sarybchikefx_lic_find_key( 1547299898Sarybchik __in efx_nic_t *enp, 1548299898Sarybchik __in_bcount(buffer_size) 1549299898Sarybchik caddr_t bufferp, 1550299898Sarybchik __in size_t buffer_size, 1551299898Sarybchik __in uint32_t offset, 1552299898Sarybchik __out uint32_t *startp, 1553299898Sarybchik __out uint32_t *lengthp 1554299898Sarybchik ) 1555299898Sarybchik{ 1556299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1557299898Sarybchik boolean_t rc; 1558299898Sarybchik 1559299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1560299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1561299898Sarybchik 1562299898Sarybchik EFSYS_ASSERT(bufferp); 1563299898Sarybchik EFSYS_ASSERT(startp); 1564299898Sarybchik EFSYS_ASSERT(lengthp); 1565299898Sarybchik 1566299898Sarybchik return (elop->elo_find_key(enp, bufferp, buffer_size, offset, 1567299898Sarybchik startp, lengthp)); 1568299898Sarybchik} 1569299898Sarybchik 1570299898Sarybchik 1571299898Sarybchik/* Validate that the buffer contains a single key in a recognised format. 1572299898Sarybchik** An empty or terminator buffer is not accepted as a valid key. 1573299898Sarybchik*/ 1574299898Sarybchik __checkReturn __success(return != B_FALSE) boolean_t 1575299898Sarybchikefx_lic_validate_key( 1576299898Sarybchik __in efx_nic_t *enp, 1577299898Sarybchik __in_bcount(length) caddr_t keyp, 1578299898Sarybchik __in uint32_t length 1579299898Sarybchik ) 1580299898Sarybchik{ 1581299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1582299898Sarybchik boolean_t rc; 1583299898Sarybchik uint16_t tlv_type; 1584299898Sarybchik uint16_t tlv_length; 1585299898Sarybchik 1586299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1587299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1588299898Sarybchik 1589299898Sarybchik if ((rc = elop->elo_validate_key(enp, keyp, length)) == B_FALSE) 1590299898Sarybchik goto fail1; 1591299898Sarybchik 1592299898Sarybchik return (B_TRUE); 1593299898Sarybchik 1594299898Sarybchikfail1: 1595299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1596299898Sarybchik 1597299898Sarybchik return (rc); 1598299898Sarybchik} 1599299898Sarybchik 1600299898Sarybchik __checkReturn efx_rc_t 1601299898Sarybchikefx_lic_read_key( 1602299898Sarybchik __in efx_nic_t *enp, 1603299898Sarybchik __in_bcount(buffer_size) 1604299898Sarybchik caddr_t bufferp, 1605299898Sarybchik __in size_t buffer_size, 1606299898Sarybchik __in uint32_t offset, 1607299898Sarybchik __in uint32_t length, 1608299898Sarybchik __out_bcount_part(key_max_size, *lengthp) 1609299898Sarybchik caddr_t keyp, 1610299898Sarybchik __in size_t key_max_size, 1611299898Sarybchik __out uint32_t *lengthp 1612299898Sarybchik ) 1613299898Sarybchik{ 1614299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1615299898Sarybchik efx_rc_t rc; 1616299898Sarybchik 1617299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1618299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1619299898Sarybchik 1620299898Sarybchik if ((rc = elop->elo_read_key(enp, bufferp, buffer_size, offset, 1621299898Sarybchik length, keyp, key_max_size, lengthp)) != 0) 1622299898Sarybchik goto fail1; 1623299898Sarybchik 1624299898Sarybchik return (0); 1625299898Sarybchik 1626299898Sarybchikfail1: 1627299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1628299898Sarybchik 1629299898Sarybchik return (rc); 1630299898Sarybchik} 1631299898Sarybchik 1632299898Sarybchik __checkReturn efx_rc_t 1633299898Sarybchikefx_lic_write_key( 1634299898Sarybchik __in efx_nic_t *enp, 1635299898Sarybchik __in_bcount(buffer_size) 1636299898Sarybchik caddr_t bufferp, 1637299898Sarybchik __in size_t buffer_size, 1638299898Sarybchik __in uint32_t offset, 1639299898Sarybchik __in_bcount(length) caddr_t keyp, 1640299898Sarybchik __in uint32_t length, 1641299898Sarybchik __out uint32_t *lengthp 1642299898Sarybchik ) 1643299898Sarybchik{ 1644299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1645299898Sarybchik efx_rc_t rc; 1646299898Sarybchik 1647299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1648299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1649299898Sarybchik 1650299898Sarybchik if ((rc = elop->elo_write_key(enp, bufferp, buffer_size, offset, 1651299898Sarybchik keyp, length, lengthp)) != 0) 1652299898Sarybchik goto fail1; 1653299898Sarybchik 1654299898Sarybchik return (0); 1655299898Sarybchik 1656299898Sarybchikfail1: 1657299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1658299898Sarybchik 1659299898Sarybchik return (rc); 1660299898Sarybchik} 1661299898Sarybchik 1662299898Sarybchik __checkReturn efx_rc_t 1663299898Sarybchikefx_lic_delete_key( 1664299898Sarybchik __in efx_nic_t *enp, 1665299898Sarybchik __in_bcount(buffer_size) 1666299898Sarybchik caddr_t bufferp, 1667299898Sarybchik __in size_t buffer_size, 1668299898Sarybchik __in uint32_t offset, 1669299898Sarybchik __in uint32_t length, 1670299898Sarybchik __in uint32_t end, 1671299898Sarybchik __out uint32_t *deltap 1672299898Sarybchik ) 1673299898Sarybchik{ 1674299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1675299898Sarybchik efx_rc_t rc; 1676299898Sarybchik 1677299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1678299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1679299898Sarybchik 1680299898Sarybchik if ((rc = elop->elo_delete_key(enp, bufferp, buffer_size, offset, 1681299898Sarybchik length, end, deltap)) != 0) 1682299898Sarybchik goto fail1; 1683299898Sarybchik 1684299898Sarybchik return (0); 1685299898Sarybchik 1686299898Sarybchikfail1: 1687299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1688299898Sarybchik 1689299898Sarybchik return (rc); 1690299898Sarybchik} 1691299898Sarybchik 1692299898Sarybchik __checkReturn efx_rc_t 1693299898Sarybchikefx_lic_create_partition( 1694299898Sarybchik __in efx_nic_t *enp, 1695299898Sarybchik __in_bcount(buffer_size) 1696299898Sarybchik caddr_t bufferp, 1697299898Sarybchik __in size_t buffer_size 1698299898Sarybchik ) 1699299898Sarybchik{ 1700299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1701299898Sarybchik efx_rc_t rc; 1702299898Sarybchik 1703299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1704299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1705299898Sarybchik 1706299898Sarybchik if ((rc = elop->elo_create_partition(enp, bufferp, buffer_size)) != 0) 1707299898Sarybchik goto fail1; 1708299898Sarybchik 1709299898Sarybchik return (0); 1710299898Sarybchik 1711299898Sarybchikfail1: 1712299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1713299898Sarybchik 1714299898Sarybchik return (rc); 1715299898Sarybchik} 1716299898Sarybchik 1717299898Sarybchik 1718299898Sarybchik __checkReturn efx_rc_t 1719299898Sarybchikefx_lic_finish_partition( 1720299898Sarybchik __in efx_nic_t *enp, 1721299898Sarybchik __in_bcount(buffer_size) 1722299898Sarybchik caddr_t bufferp, 1723299898Sarybchik __in size_t buffer_size 1724299898Sarybchik ) 1725299898Sarybchik{ 1726299898Sarybchik const efx_lic_ops_t *elop = enp->en_elop; 1727299898Sarybchik efx_rc_t rc; 1728299898Sarybchik 1729299898Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1730299898Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 1731299898Sarybchik 1732299898Sarybchik if ((rc = elop->elo_finish_partition(enp, bufferp, buffer_size)) != 0) 1733299898Sarybchik goto fail1; 1734299898Sarybchik 1735299898Sarybchik return (0); 1736299898Sarybchik 1737299898Sarybchikfail1: 1738299898Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 1739299898Sarybchik 1740299898Sarybchik return (rc); 1741299898Sarybchik} 1742299898Sarybchik 1743293901Sarybchik#endif /* EFSYS_OPT_LICENSING */ 1744