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: releng/10.3/sys/dev/sfxge/common/efx_lic.c 294386 2016-01-20 08:01:21Z arybchik $"); 33293901Sarybchik 34293901Sarybchik#include "efx.h" 35293901Sarybchik#include "efx_impl.h" 36293901Sarybchik 37293901Sarybchik#if EFSYS_OPT_LICENSING 38293901Sarybchik 39293901Sarybchik#if EFSYS_OPT_SIENA 40293901Sarybchik 41293901Sarybchikstatic __checkReturn efx_rc_t 42293901Sarybchikefx_mcdi_fc_license_update_license( 43293901Sarybchik __in efx_nic_t *enp); 44293901Sarybchik 45293901Sarybchikstatic __checkReturn efx_rc_t 46293901Sarybchikefx_mcdi_fc_license_get_key_stats( 47293901Sarybchik __in efx_nic_t *enp, 48293901Sarybchik __out efx_key_stats_t *eksp); 49293901Sarybchik 50293901Sarybchikstatic efx_lic_ops_t __efx_lic_v1_ops = { 51293901Sarybchik efx_mcdi_fc_license_update_license, /* elo_update_licenses */ 52293901Sarybchik efx_mcdi_fc_license_get_key_stats, /* elo_get_key_stats */ 53293901Sarybchik NULL, /* elo_app_state */ 54293901Sarybchik NULL, /* elo_get_id */ 55293901Sarybchik}; 56293901Sarybchik 57293901Sarybchik#endif /* EFSYS_OPT_SIENA */ 58293901Sarybchik 59293901Sarybchik#if EFSYS_OPT_HUNTINGTON 60293901Sarybchik 61293901Sarybchikstatic __checkReturn efx_rc_t 62293901Sarybchikefx_mcdi_licensing_update_licenses( 63293901Sarybchik __in efx_nic_t *enp); 64293901Sarybchik 65293901Sarybchikstatic __checkReturn efx_rc_t 66293901Sarybchikefx_mcdi_licensing_get_key_stats( 67293901Sarybchik __in efx_nic_t *enp, 68293901Sarybchik __out efx_key_stats_t *eksp); 69293901Sarybchik 70293901Sarybchikstatic __checkReturn efx_rc_t 71293901Sarybchikefx_mcdi_licensed_app_state( 72293901Sarybchik __in efx_nic_t *enp, 73293901Sarybchik __in uint64_t app_id, 74293901Sarybchik __out boolean_t *licensedp); 75293901Sarybchik 76293901Sarybchikstatic efx_lic_ops_t __efx_lic_v2_ops = { 77293901Sarybchik efx_mcdi_licensing_update_licenses, /* elo_update_licenses */ 78293901Sarybchik efx_mcdi_licensing_get_key_stats, /* elo_get_key_stats */ 79293901Sarybchik efx_mcdi_licensed_app_state, /* elo_app_state */ 80293901Sarybchik NULL, /* elo_get_id */ 81293901Sarybchik}; 82293901Sarybchik 83293901Sarybchik#endif /* EFSYS_OPT_HUNTINGTON */ 84293901Sarybchik 85293901Sarybchik#if EFSYS_OPT_MEDFORD 86293901Sarybchik 87293901Sarybchikstatic __checkReturn efx_rc_t 88293901Sarybchikefx_mcdi_licensing_v3_update_licenses( 89293901Sarybchik __in efx_nic_t *enp); 90293901Sarybchik 91293901Sarybchikstatic __checkReturn efx_rc_t 92293901Sarybchikefx_mcdi_licensing_v3_report_license( 93293901Sarybchik __in efx_nic_t *enp, 94293901Sarybchik __out efx_key_stats_t *eksp); 95293901Sarybchik 96293901Sarybchikstatic __checkReturn efx_rc_t 97293901Sarybchikefx_mcdi_licensing_v3_app_state( 98293901Sarybchik __in efx_nic_t *enp, 99293901Sarybchik __in uint64_t app_id, 100293901Sarybchik __out boolean_t *licensedp); 101293901Sarybchik 102293901Sarybchikstatic __checkReturn efx_rc_t 103293901Sarybchikefx_mcdi_licensing_v3_get_id( 104293901Sarybchik __in efx_nic_t *enp, 105293901Sarybchik __in size_t buffer_size, 106293901Sarybchik __out uint32_t *typep, 107293901Sarybchik __out size_t *lengthp, 108293901Sarybchik __out_bcount_part_opt(buffer_size, *lengthp) 109293901Sarybchik uint8_t *bufferp); 110293901Sarybchik 111293901Sarybchikstatic efx_lic_ops_t __efx_lic_v3_ops = { 112293901Sarybchik efx_mcdi_licensing_v3_update_licenses, /* elo_update_licenses */ 113293901Sarybchik efx_mcdi_licensing_v3_report_license, /* elo_get_key_stats */ 114293901Sarybchik efx_mcdi_licensing_v3_app_state, /* elo_app_state */ 115293901Sarybchik efx_mcdi_licensing_v3_get_id, /* elo_get_id */ 116293901Sarybchik}; 117293901Sarybchik 118293901Sarybchik#endif /* EFSYS_OPT_MEDFORD */ 119293901Sarybchik 120293901Sarybchik 121293901Sarybchik/* V1 Licensing - used in Siena Modena only */ 122293901Sarybchik 123293901Sarybchik#if EFSYS_OPT_SIENA 124293901Sarybchik 125293901Sarybchikstatic __checkReturn efx_rc_t 126293901Sarybchikefx_mcdi_fc_license_update_license( 127293901Sarybchik __in efx_nic_t *enp) 128293901Sarybchik{ 129293901Sarybchik efx_mcdi_req_t req; 130293901Sarybchik uint8_t payload[MC_CMD_FC_IN_LICENSE_LEN]; 131293901Sarybchik efx_rc_t rc; 132293901Sarybchik 133293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA); 134293901Sarybchik 135293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 136293901Sarybchik req.emr_cmd = MC_CMD_FC_OP_LICENSE; 137293901Sarybchik req.emr_in_buf = payload; 138293901Sarybchik req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN; 139293901Sarybchik req.emr_out_buf = payload; 140293901Sarybchik req.emr_out_length = 0; 141293901Sarybchik 142293901Sarybchik MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP, 143293901Sarybchik MC_CMD_FC_IN_LICENSE_UPDATE_LICENSE); 144293901Sarybchik 145293901Sarybchik efx_mcdi_execute(enp, &req); 146293901Sarybchik 147293901Sarybchik if (req.emr_rc != 0) { 148293901Sarybchik rc = req.emr_rc; 149293901Sarybchik goto fail1; 150293901Sarybchik } 151293901Sarybchik 152293901Sarybchik if (req.emr_out_length_used != 0) { 153293901Sarybchik rc = EIO; 154293901Sarybchik goto fail2; 155293901Sarybchik } 156293901Sarybchik 157293901Sarybchik return (0); 158293901Sarybchik 159293901Sarybchikfail2: 160293901Sarybchik EFSYS_PROBE(fail2); 161293901Sarybchikfail1: 162293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 163293901Sarybchik 164293901Sarybchik return (rc); 165293901Sarybchik} 166293901Sarybchik 167293901Sarybchikstatic __checkReturn efx_rc_t 168293901Sarybchikefx_mcdi_fc_license_get_key_stats( 169293901Sarybchik __in efx_nic_t *enp, 170293901Sarybchik __out efx_key_stats_t *eksp) 171293901Sarybchik{ 172293901Sarybchik efx_mcdi_req_t req; 173293901Sarybchik uint8_t payload[MAX(MC_CMD_FC_IN_LICENSE_LEN, 174293901Sarybchik MC_CMD_FC_OUT_LICENSE_LEN)]; 175293901Sarybchik efx_rc_t rc; 176293901Sarybchik 177293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA); 178293901Sarybchik 179293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 180293901Sarybchik req.emr_cmd = MC_CMD_FC_OP_LICENSE; 181293901Sarybchik req.emr_in_buf = payload; 182293901Sarybchik req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN; 183293901Sarybchik req.emr_out_buf = payload; 184293901Sarybchik req.emr_out_length = MC_CMD_FC_OUT_LICENSE_LEN; 185293901Sarybchik 186293901Sarybchik MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP, 187293901Sarybchik MC_CMD_FC_IN_LICENSE_GET_KEY_STATS); 188293901Sarybchik 189293901Sarybchik efx_mcdi_execute(enp, &req); 190293901Sarybchik 191293901Sarybchik if (req.emr_rc != 0) { 192293901Sarybchik rc = req.emr_rc; 193293901Sarybchik goto fail1; 194293901Sarybchik } 195293901Sarybchik 196293901Sarybchik if (req.emr_out_length_used < MC_CMD_FC_OUT_LICENSE_LEN) { 197293901Sarybchik rc = EMSGSIZE; 198293901Sarybchik goto fail2; 199293901Sarybchik } 200293901Sarybchik 201293901Sarybchik eksp->eks_valid = 202293901Sarybchik MCDI_OUT_DWORD(req, FC_OUT_LICENSE_VALID_KEYS); 203293901Sarybchik eksp->eks_invalid = 204293901Sarybchik MCDI_OUT_DWORD(req, FC_OUT_LICENSE_INVALID_KEYS); 205293901Sarybchik eksp->eks_blacklisted = 206293901Sarybchik MCDI_OUT_DWORD(req, FC_OUT_LICENSE_BLACKLISTED_KEYS); 207293901Sarybchik eksp->eks_unverifiable = 0; 208293901Sarybchik eksp->eks_wrong_node = 0; 209293901Sarybchik eksp->eks_licensed_apps_lo = 0; 210293901Sarybchik eksp->eks_licensed_apps_hi = 0; 211293901Sarybchik eksp->eks_licensed_features_lo = 0; 212293901Sarybchik eksp->eks_licensed_features_hi = 0; 213293901Sarybchik 214293901Sarybchik return (0); 215293901Sarybchik 216293901Sarybchikfail2: 217293901Sarybchik EFSYS_PROBE(fail2); 218293901Sarybchikfail1: 219293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 220293901Sarybchik 221293901Sarybchik return (rc); 222293901Sarybchik} 223293901Sarybchik 224293901Sarybchik#endif /* EFSYS_OPT_SIENA */ 225293901Sarybchik 226293901Sarybchik/* V2 Licensing - used by Huntington family only. See SF-113611-TC */ 227293901Sarybchik 228293901Sarybchik#if EFSYS_OPT_HUNTINGTON 229293901Sarybchik 230293901Sarybchikstatic __checkReturn efx_rc_t 231293901Sarybchikefx_mcdi_licensed_app_state( 232293901Sarybchik __in efx_nic_t *enp, 233293901Sarybchik __in uint64_t app_id, 234293901Sarybchik __out boolean_t *licensedp) 235293901Sarybchik{ 236293901Sarybchik efx_mcdi_req_t req; 237293901Sarybchik uint8_t payload[MAX(MC_CMD_GET_LICENSED_APP_STATE_IN_LEN, 238293901Sarybchik MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN)]; 239293901Sarybchik uint32_t app_state; 240293901Sarybchik efx_rc_t rc; 241293901Sarybchik 242293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON); 243293901Sarybchik 244293901Sarybchik /* V2 licensing supports 32bit app id only */ 245293901Sarybchik if ((app_id >> 32) != 0) { 246293901Sarybchik rc = EINVAL; 247293901Sarybchik goto fail1; 248293901Sarybchik } 249293901Sarybchik 250293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 251293901Sarybchik req.emr_cmd = MC_CMD_GET_LICENSED_APP_STATE; 252293901Sarybchik req.emr_in_buf = payload; 253293901Sarybchik req.emr_in_length = MC_CMD_GET_LICENSED_APP_STATE_IN_LEN; 254293901Sarybchik req.emr_out_buf = payload; 255293901Sarybchik req.emr_out_length = MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN; 256293901Sarybchik 257293901Sarybchik MCDI_IN_SET_DWORD(req, GET_LICENSED_APP_STATE_IN_APP_ID, 258293901Sarybchik app_id & 0xffffffff); 259293901Sarybchik 260293901Sarybchik efx_mcdi_execute(enp, &req); 261293901Sarybchik 262293901Sarybchik if (req.emr_rc != 0) { 263293901Sarybchik rc = req.emr_rc; 264293901Sarybchik goto fail2; 265293901Sarybchik } 266293901Sarybchik 267293901Sarybchik if (req.emr_out_length_used < MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN) { 268293901Sarybchik rc = EMSGSIZE; 269293901Sarybchik goto fail3; 270293901Sarybchik } 271293901Sarybchik 272293901Sarybchik app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_APP_STATE_OUT_STATE)); 273293901Sarybchik if (app_state != MC_CMD_GET_LICENSED_APP_STATE_OUT_NOT_LICENSED) { 274293901Sarybchik *licensedp = B_TRUE; 275293901Sarybchik } else { 276293901Sarybchik *licensedp = B_FALSE; 277293901Sarybchik } 278293901Sarybchik 279293901Sarybchik return (0); 280293901Sarybchik 281293901Sarybchikfail3: 282293901Sarybchik EFSYS_PROBE(fail3); 283293901Sarybchikfail2: 284293901Sarybchik EFSYS_PROBE(fail2); 285293901Sarybchikfail1: 286293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 287293901Sarybchik 288293901Sarybchik return (rc); 289293901Sarybchik} 290293901Sarybchik 291293901Sarybchikstatic __checkReturn efx_rc_t 292293901Sarybchikefx_mcdi_licensing_update_licenses( 293293901Sarybchik __in efx_nic_t *enp) 294293901Sarybchik{ 295293901Sarybchik efx_mcdi_req_t req; 296293901Sarybchik uint8_t payload[MC_CMD_LICENSING_IN_LEN]; 297293901Sarybchik efx_rc_t rc; 298293901Sarybchik 299293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON); 300293901Sarybchik 301293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 302293901Sarybchik req.emr_cmd = MC_CMD_LICENSING; 303293901Sarybchik req.emr_in_buf = payload; 304293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_IN_LEN; 305293901Sarybchik req.emr_out_buf = payload; 306293901Sarybchik req.emr_out_length = 0; 307293901Sarybchik 308293901Sarybchik MCDI_IN_SET_DWORD(req, LICENSING_IN_OP, 309293901Sarybchik MC_CMD_LICENSING_IN_OP_UPDATE_LICENSE); 310293901Sarybchik 311293901Sarybchik efx_mcdi_execute(enp, &req); 312293901Sarybchik 313293901Sarybchik if (req.emr_rc != 0) { 314293901Sarybchik rc = req.emr_rc; 315293901Sarybchik goto fail1; 316293901Sarybchik } 317293901Sarybchik 318293901Sarybchik if (req.emr_out_length_used != 0) { 319293901Sarybchik rc = EIO; 320293901Sarybchik goto fail2; 321293901Sarybchik } 322293901Sarybchik 323293901Sarybchik return (0); 324293901Sarybchik 325293901Sarybchikfail2: 326293901Sarybchik EFSYS_PROBE(fail2); 327293901Sarybchikfail1: 328293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 329293901Sarybchik 330293901Sarybchik return (rc); 331293901Sarybchik} 332293901Sarybchik 333293901Sarybchikstatic __checkReturn efx_rc_t 334293901Sarybchikefx_mcdi_licensing_get_key_stats( 335293901Sarybchik __in efx_nic_t *enp, 336293901Sarybchik __out efx_key_stats_t *eksp) 337293901Sarybchik{ 338293901Sarybchik efx_mcdi_req_t req; 339293901Sarybchik uint8_t payload[MAX(MC_CMD_LICENSING_IN_LEN, 340293901Sarybchik MC_CMD_LICENSING_OUT_LEN)]; 341293901Sarybchik efx_rc_t rc; 342293901Sarybchik 343293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON); 344293901Sarybchik 345293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 346293901Sarybchik req.emr_cmd = MC_CMD_LICENSING; 347293901Sarybchik req.emr_in_buf = payload; 348293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_IN_LEN; 349293901Sarybchik req.emr_out_buf = payload; 350293901Sarybchik req.emr_out_length = MC_CMD_LICENSING_OUT_LEN; 351293901Sarybchik 352293901Sarybchik MCDI_IN_SET_DWORD(req, LICENSING_IN_OP, 353293901Sarybchik MC_CMD_LICENSING_IN_OP_GET_KEY_STATS); 354293901Sarybchik 355293901Sarybchik efx_mcdi_execute(enp, &req); 356293901Sarybchik 357293901Sarybchik if (req.emr_rc != 0) { 358293901Sarybchik rc = req.emr_rc; 359293901Sarybchik goto fail1; 360293901Sarybchik } 361293901Sarybchik 362293901Sarybchik if (req.emr_out_length_used < MC_CMD_LICENSING_OUT_LEN) { 363293901Sarybchik rc = EMSGSIZE; 364293901Sarybchik goto fail2; 365293901Sarybchik } 366293901Sarybchik 367293901Sarybchik eksp->eks_valid = 368293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_OUT_VALID_APP_KEYS); 369293901Sarybchik eksp->eks_invalid = 370293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_OUT_INVALID_APP_KEYS); 371293901Sarybchik eksp->eks_blacklisted = 372293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_OUT_BLACKLISTED_APP_KEYS); 373293901Sarybchik eksp->eks_unverifiable = 374293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_OUT_UNVERIFIABLE_APP_KEYS); 375293901Sarybchik eksp->eks_wrong_node = 376293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_OUT_WRONG_NODE_APP_KEYS); 377293901Sarybchik eksp->eks_licensed_apps_lo = 0; 378293901Sarybchik eksp->eks_licensed_apps_hi = 0; 379293901Sarybchik eksp->eks_licensed_features_lo = 0; 380293901Sarybchik eksp->eks_licensed_features_hi = 0; 381293901Sarybchik 382293901Sarybchik return (0); 383293901Sarybchik 384293901Sarybchikfail2: 385293901Sarybchik EFSYS_PROBE(fail2); 386293901Sarybchikfail1: 387293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 388293901Sarybchik 389293901Sarybchik return (rc); 390293901Sarybchik} 391293901Sarybchik 392293901Sarybchik#endif /* EFSYS_OPT_HUNTINGTON */ 393293901Sarybchik 394293901Sarybchik/* V3 Licensing - used starting from Medford family. See SF-114884-SW */ 395293901Sarybchik 396293901Sarybchik#if EFSYS_OPT_MEDFORD 397293901Sarybchik 398293901Sarybchikstatic __checkReturn efx_rc_t 399293901Sarybchikefx_mcdi_licensing_v3_update_licenses( 400293901Sarybchik __in efx_nic_t *enp) 401293901Sarybchik{ 402293901Sarybchik efx_mcdi_req_t req; 403293901Sarybchik uint8_t payload[MC_CMD_LICENSING_V3_IN_LEN]; 404293901Sarybchik efx_rc_t rc; 405293901Sarybchik 406293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD); 407293901Sarybchik 408293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 409293901Sarybchik req.emr_cmd = MC_CMD_LICENSING_V3; 410293901Sarybchik req.emr_in_buf = payload; 411293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN; 412293901Sarybchik req.emr_out_buf = NULL; 413293901Sarybchik req.emr_out_length = 0; 414293901Sarybchik 415293901Sarybchik MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP, 416293901Sarybchik MC_CMD_LICENSING_V3_IN_OP_UPDATE_LICENSE); 417293901Sarybchik 418293901Sarybchik efx_mcdi_execute(enp, &req); 419293901Sarybchik 420293901Sarybchik if (req.emr_rc != 0) { 421293901Sarybchik rc = req.emr_rc; 422293901Sarybchik goto fail1; 423293901Sarybchik } 424293901Sarybchik 425293901Sarybchik return (0); 426293901Sarybchik 427293901Sarybchikfail1: 428293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 429293901Sarybchik 430293901Sarybchik return (rc); 431293901Sarybchik} 432293901Sarybchik 433293901Sarybchikstatic __checkReturn efx_rc_t 434293901Sarybchikefx_mcdi_licensing_v3_report_license( 435293901Sarybchik __in efx_nic_t *enp, 436293901Sarybchik __out efx_key_stats_t *eksp) 437293901Sarybchik{ 438293901Sarybchik efx_mcdi_req_t req; 439293901Sarybchik uint8_t payload[MAX(MC_CMD_LICENSING_V3_IN_LEN, 440293901Sarybchik MC_CMD_LICENSING_V3_OUT_LEN)]; 441293901Sarybchik efx_rc_t rc; 442293901Sarybchik 443293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD); 444293901Sarybchik 445293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 446293901Sarybchik req.emr_cmd = MC_CMD_LICENSING_V3; 447293901Sarybchik req.emr_in_buf = payload; 448293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN; 449293901Sarybchik req.emr_out_buf = payload; 450293901Sarybchik req.emr_out_length = MC_CMD_LICENSING_V3_OUT_LEN; 451293901Sarybchik 452293901Sarybchik MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP, 453293901Sarybchik MC_CMD_LICENSING_V3_IN_OP_REPORT_LICENSE); 454293901Sarybchik 455293901Sarybchik efx_mcdi_execute(enp, &req); 456293901Sarybchik 457293901Sarybchik if (req.emr_rc != 0) { 458293901Sarybchik rc = req.emr_rc; 459293901Sarybchik goto fail1; 460293901Sarybchik } 461293901Sarybchik 462293901Sarybchik if (req.emr_out_length_used < MC_CMD_LICENSING_V3_OUT_LEN) { 463293901Sarybchik rc = EMSGSIZE; 464293901Sarybchik goto fail2; 465293901Sarybchik } 466293901Sarybchik 467293901Sarybchik eksp->eks_valid = 468293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_VALID_KEYS); 469293901Sarybchik eksp->eks_invalid = 470293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_INVALID_KEYS); 471293901Sarybchik eksp->eks_blacklisted = 0; 472293901Sarybchik eksp->eks_unverifiable = 473293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_UNVERIFIABLE_KEYS); 474293901Sarybchik eksp->eks_wrong_node = 475293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_WRONG_NODE_KEYS); 476293901Sarybchik eksp->eks_licensed_apps_lo = 477293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_LO); 478293901Sarybchik eksp->eks_licensed_apps_hi = 479293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_HI); 480293901Sarybchik eksp->eks_licensed_features_lo = 481293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_LO); 482293901Sarybchik eksp->eks_licensed_features_hi = 483293901Sarybchik MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_HI); 484293901Sarybchik 485293901Sarybchik return (0); 486293901Sarybchik 487293901Sarybchikfail2: 488293901Sarybchik EFSYS_PROBE(fail2); 489293901Sarybchikfail1: 490293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 491293901Sarybchik 492293901Sarybchik return (rc); 493293901Sarybchik} 494293901Sarybchik 495293901Sarybchikstatic __checkReturn efx_rc_t 496293901Sarybchikefx_mcdi_licensing_v3_app_state( 497293901Sarybchik __in efx_nic_t *enp, 498293901Sarybchik __in uint64_t app_id, 499293901Sarybchik __out boolean_t *licensedp) 500293901Sarybchik{ 501293901Sarybchik efx_mcdi_req_t req; 502293901Sarybchik uint8_t payload[MAX(MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN, 503293901Sarybchik MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN)]; 504293901Sarybchik uint32_t app_state; 505293901Sarybchik efx_rc_t rc; 506293901Sarybchik 507293901Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD); 508293901Sarybchik 509293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 510293901Sarybchik req.emr_cmd = MC_CMD_GET_LICENSED_V3_APP_STATE; 511293901Sarybchik req.emr_in_buf = payload; 512293901Sarybchik req.emr_in_length = MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN; 513293901Sarybchik req.emr_out_buf = payload; 514293901Sarybchik req.emr_out_length = MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN; 515293901Sarybchik 516293901Sarybchik MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_LO, 517293901Sarybchik app_id & 0xffffffff); 518293901Sarybchik MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_HI, 519293901Sarybchik app_id >> 32); 520293901Sarybchik 521293901Sarybchik efx_mcdi_execute(enp, &req); 522293901Sarybchik 523293901Sarybchik if (req.emr_rc != 0) { 524293901Sarybchik rc = req.emr_rc; 525293901Sarybchik goto fail1; 526293901Sarybchik } 527293901Sarybchik 528293901Sarybchik if (req.emr_out_length_used < MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN) { 529293901Sarybchik rc = EMSGSIZE; 530293901Sarybchik goto fail2; 531293901Sarybchik } 532293901Sarybchik 533293901Sarybchik app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_V3_APP_STATE_OUT_STATE)); 534293901Sarybchik if (app_state != MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_NOT_LICENSED) { 535293901Sarybchik *licensedp = B_TRUE; 536293901Sarybchik } else { 537293901Sarybchik *licensedp = B_FALSE; 538293901Sarybchik } 539293901Sarybchik 540293901Sarybchik return (0); 541293901Sarybchik 542293901Sarybchikfail2: 543293901Sarybchik EFSYS_PROBE(fail2); 544293901Sarybchikfail1: 545293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 546293901Sarybchik 547293901Sarybchik return (rc); 548293901Sarybchik} 549293901Sarybchik 550293901Sarybchikstatic __checkReturn efx_rc_t 551293901Sarybchikefx_mcdi_licensing_v3_get_id( 552293901Sarybchik __in efx_nic_t *enp, 553293901Sarybchik __in size_t buffer_size, 554293901Sarybchik __out uint32_t *typep, 555293901Sarybchik __out size_t *lengthp, 556293901Sarybchik __out_bcount_part_opt(buffer_size, *lengthp) 557293901Sarybchik uint8_t *bufferp) 558293901Sarybchik{ 559293901Sarybchik efx_mcdi_req_t req; 560293901Sarybchik uint8_t payload[MAX(MC_CMD_LICENSING_GET_ID_V3_IN_LEN, 561293901Sarybchik MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN)]; 562293901Sarybchik efx_rc_t rc; 563293901Sarybchik 564293901Sarybchik req.emr_cmd = MC_CMD_LICENSING_GET_ID_V3; 565293901Sarybchik 566293901Sarybchik if (bufferp == NULL) { 567293901Sarybchik /* Request id type and length only */ 568293901Sarybchik req.emr_in_buf = bufferp; 569293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN; 570293901Sarybchik req.emr_out_buf = bufferp; 571293901Sarybchik req.emr_out_length = MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN; 572293901Sarybchik (void) memset(payload, 0, sizeof (payload)); 573293901Sarybchik } else { 574293901Sarybchik /* Request full buffer */ 575293901Sarybchik req.emr_in_buf = bufferp; 576293901Sarybchik req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN; 577293901Sarybchik req.emr_out_buf = bufferp; 578293901Sarybchik req.emr_out_length = MIN(buffer_size, MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN); 579293901Sarybchik (void) memset(bufferp, 0, req.emr_out_length); 580293901Sarybchik } 581293901Sarybchik 582293901Sarybchik efx_mcdi_execute(enp, &req); 583293901Sarybchik 584293901Sarybchik if (req.emr_rc != 0) { 585293901Sarybchik rc = req.emr_rc; 586293901Sarybchik goto fail1; 587293901Sarybchik } 588293901Sarybchik 589293901Sarybchik if (req.emr_out_length_used < MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN) { 590293901Sarybchik rc = EMSGSIZE; 591293901Sarybchik goto fail2; 592293901Sarybchik } 593293901Sarybchik 594293901Sarybchik *typep = MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_TYPE); 595293901Sarybchik *lengthp = MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_ID_LENGTH); 596293901Sarybchik 597293901Sarybchik if (bufferp == NULL) { 598293901Sarybchik /* modify length requirements to indicate to caller the extra buffering 599293901Sarybchik ** needed to read the complete output. 600293901Sarybchik */ 601293901Sarybchik *lengthp += MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN; 602293901Sarybchik } else { 603293901Sarybchik /* Shift ID down to start of buffer */ 604293901Sarybchik memmove(bufferp, 605293901Sarybchik bufferp+MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST, 606293901Sarybchik *lengthp); 607293901Sarybchik memset(bufferp+(*lengthp), 0, MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST); 608293901Sarybchik } 609293901Sarybchik 610293901Sarybchik return (0); 611293901Sarybchik 612293901Sarybchikfail2: 613293901Sarybchik EFSYS_PROBE(fail2); 614293901Sarybchikfail1: 615293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 616293901Sarybchik 617293901Sarybchik return (rc); 618293901Sarybchik} 619293901Sarybchik 620293901Sarybchik 621293901Sarybchik#endif /* EFSYS_OPT_MEDFORD */ 622293901Sarybchik 623293901Sarybchik __checkReturn efx_rc_t 624293901Sarybchikefx_lic_init( 625293901Sarybchik __in efx_nic_t *enp) 626293901Sarybchik{ 627293901Sarybchik efx_lic_ops_t *elop; 628293901Sarybchik efx_rc_t rc; 629293901Sarybchik 630293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 631293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 632293901Sarybchik EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_LIC)); 633293901Sarybchik 634293901Sarybchik switch (enp->en_family) { 635293901Sarybchik 636293901Sarybchik#if EFSYS_OPT_SIENA 637293901Sarybchik case EFX_FAMILY_SIENA: 638293901Sarybchik elop = (efx_lic_ops_t *)&__efx_lic_v1_ops; 639293901Sarybchik break; 640293901Sarybchik#endif /* EFSYS_OPT_SIENA */ 641293901Sarybchik 642293901Sarybchik#if EFSYS_OPT_HUNTINGTON 643293901Sarybchik case EFX_FAMILY_HUNTINGTON: 644293901Sarybchik elop = (efx_lic_ops_t *)&__efx_lic_v2_ops; 645293901Sarybchik break; 646293901Sarybchik#endif /* EFSYS_OPT_HUNTINGTON */ 647293901Sarybchik 648293901Sarybchik#if EFSYS_OPT_MEDFORD 649293901Sarybchik case EFX_FAMILY_MEDFORD: 650293901Sarybchik elop = (efx_lic_ops_t *)&__efx_lic_v3_ops; 651293901Sarybchik break; 652293901Sarybchik#endif /* EFSYS_OPT_MEDFORD */ 653293901Sarybchik 654293901Sarybchik default: 655293901Sarybchik EFSYS_ASSERT(0); 656293901Sarybchik rc = ENOTSUP; 657293901Sarybchik goto fail1; 658293901Sarybchik } 659293901Sarybchik 660293901Sarybchik enp->en_elop = elop; 661293901Sarybchik enp->en_mod_flags |= EFX_MOD_LIC; 662293901Sarybchik 663293901Sarybchik return (0); 664293901Sarybchik 665293901Sarybchikfail1: 666293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 667293901Sarybchik 668293901Sarybchik return (rc); 669293901Sarybchik} 670293901Sarybchik 671293901Sarybchik void 672293901Sarybchikefx_lic_fini( 673293901Sarybchik __in efx_nic_t *enp) 674293901Sarybchik{ 675293901Sarybchik efx_lic_ops_t *elop = enp->en_elop; 676293901Sarybchik 677293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 678293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 679293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 680293901Sarybchik 681293901Sarybchik enp->en_elop = NULL; 682293901Sarybchik enp->en_mod_flags &= ~EFX_MOD_LIC; 683293901Sarybchik} 684293901Sarybchik 685293901Sarybchik 686293901Sarybchik __checkReturn efx_rc_t 687293901Sarybchikefx_lic_update_licenses( 688293901Sarybchik __in efx_nic_t *enp) 689293901Sarybchik{ 690293901Sarybchik efx_lic_ops_t *elop = enp->en_elop; 691293901Sarybchik efx_rc_t rc; 692293901Sarybchik 693293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 694293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 695293901Sarybchik 696293901Sarybchik if ((rc = elop->elo_update_licenses(enp)) != 0) 697293901Sarybchik goto fail1; 698293901Sarybchik 699293901Sarybchik return (0); 700293901Sarybchik 701293901Sarybchikfail1: 702293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 703293901Sarybchik 704293901Sarybchik return (rc); 705293901Sarybchik} 706293901Sarybchik 707293901Sarybchik __checkReturn efx_rc_t 708293901Sarybchikefx_lic_get_key_stats( 709293901Sarybchik __in efx_nic_t *enp, 710293901Sarybchik __out efx_key_stats_t *eksp) 711293901Sarybchik{ 712293901Sarybchik efx_lic_ops_t *elop = enp->en_elop; 713293901Sarybchik efx_rc_t rc; 714293901Sarybchik 715293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 716293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 717293901Sarybchik 718293901Sarybchik if ((rc = elop->elo_get_key_stats(enp, eksp)) != 0) 719293901Sarybchik goto fail1; 720293901Sarybchik 721293901Sarybchik return (0); 722293901Sarybchik 723293901Sarybchikfail1: 724293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 725293901Sarybchik 726293901Sarybchik return (rc); 727293901Sarybchik} 728293901Sarybchik 729293901Sarybchik __checkReturn efx_rc_t 730293901Sarybchikefx_lic_app_state( 731293901Sarybchik __in efx_nic_t *enp, 732293901Sarybchik __in uint64_t app_id, 733293901Sarybchik __out boolean_t *licensedp) 734293901Sarybchik{ 735293901Sarybchik efx_lic_ops_t *elop = enp->en_elop; 736293901Sarybchik efx_rc_t rc; 737293901Sarybchik 738293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 739293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 740293901Sarybchik 741293901Sarybchik if (elop->elo_app_state == NULL) { 742293901Sarybchik rc = ENOTSUP; 743293901Sarybchik goto fail1; 744293901Sarybchik } 745293901Sarybchik if ((rc = elop->elo_app_state(enp, app_id, licensedp)) != 0) 746293901Sarybchik goto fail2; 747293901Sarybchik 748293901Sarybchik return (0); 749293901Sarybchik 750293901Sarybchikfail2: 751293901Sarybchik EFSYS_PROBE(fail2); 752293901Sarybchikfail1: 753293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 754293901Sarybchik 755293901Sarybchik return (rc); 756293901Sarybchik} 757293901Sarybchik 758293901Sarybchik __checkReturn efx_rc_t 759293901Sarybchikefx_lic_get_id( 760293901Sarybchik __in efx_nic_t *enp, 761293901Sarybchik __in size_t buffer_size, 762293901Sarybchik __out uint32_t *typep, 763293901Sarybchik __out size_t *lengthp, 764293901Sarybchik __out_opt uint8_t *bufferp 765293901Sarybchik ) 766293901Sarybchik{ 767293901Sarybchik efx_lic_ops_t *elop = enp->en_elop; 768293901Sarybchik efx_rc_t rc; 769293901Sarybchik 770293901Sarybchik EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 771293901Sarybchik EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC); 772293901Sarybchik 773293901Sarybchik if (elop->elo_get_id == NULL) { 774293901Sarybchik rc = ENOTSUP; 775293901Sarybchik goto fail1; 776293901Sarybchik } 777293901Sarybchik 778293901Sarybchik if ((rc = elop->elo_get_id(enp, buffer_size, typep, 779293901Sarybchik lengthp, bufferp)) != 0) 780293901Sarybchik goto fail2; 781293901Sarybchik 782293901Sarybchik return (0); 783293901Sarybchik 784293901Sarybchikfail2: 785293901Sarybchik EFSYS_PROBE(fail2); 786293901Sarybchikfail1: 787293901Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 788293901Sarybchik 789293901Sarybchik return (rc); 790293901Sarybchik} 791293901Sarybchik 792293901Sarybchik#endif /* EFSYS_OPT_LICENSING */ 793