sfxge: add accessors for license-related MCDI calls to common code

Add support for Huntington MCDI licensing interface to common code.
Ported from Linux net driver IOCTL functions with restructuring for
initial support for V3 licensing API.

Submitted by:   Richard Houldsworth <rhouldsworth at solarflare.com>
Reviewed by:    gnn
Sponsored by:   Solarflare Communications, Inc.
MFC after:      2 days
Differential Revision: https://reviews.freebsd.org/D4918
This commit is contained in:
Andrew Rybchenko 2016-01-14 09:19:28 +00:00
parent dc5427fc70
commit 0c848230f7
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=293901
8 changed files with 878 additions and 4 deletions

View File

@ -317,6 +317,7 @@ dev/sfxge/common/efx_ev.c optional sfxge pci
dev/sfxge/common/efx_filter.c optional sfxge pci
dev/sfxge/common/efx_hash.c optional sfxge pci
dev/sfxge/common/efx_intr.c optional sfxge pci
dev/sfxge/common/efx_lic.c optional sfxge pci
dev/sfxge/common/efx_mac.c optional sfxge pci
dev/sfxge/common/efx_mcdi.c optional sfxge pci
dev/sfxge/common/efx_mon.c optional sfxge pci

View File

@ -293,6 +293,8 @@ sfxge_map_mbuf_fast(bus_dma_tag_t tag, bus_dmamap_t map,
#define EFSYS_OPT_DECODE_INTR_FATAL 1
#define EFSYS_OPT_LICENSING 0
/* ID */
typedef struct __efsys_identifier_s efsys_identifier_t;

View File

@ -2310,6 +2310,57 @@ efx_hash_bytes(
__in size_t length,
__in uint32_t init);
#if EFSYS_OPT_LICENSING
/* LICENSING */
typedef struct efx_key_stats_s {
uint32_t eks_valid;
uint32_t eks_invalid;
uint32_t eks_blacklisted;
uint32_t eks_unverifiable;
uint32_t eks_wrong_node;
uint32_t eks_licensed_apps_lo;
uint32_t eks_licensed_apps_hi;
uint32_t eks_licensed_features_lo;
uint32_t eks_licensed_features_hi;
} efx_key_stats_t;
extern __checkReturn efx_rc_t
efx_lic_init(
__in efx_nic_t *enp);
extern void
efx_lic_fini(
__in efx_nic_t *enp);
extern __checkReturn efx_rc_t
efx_lic_update_licenses(
__in efx_nic_t *enp);
extern __checkReturn efx_rc_t
efx_lic_get_key_stats(
__in efx_nic_t *enp,
__out efx_key_stats_t *ksp);
extern __checkReturn efx_rc_t
efx_lic_app_state(
__in efx_nic_t *enp,
__in uint64_t app_id,
__out boolean_t *licensedp);
extern __checkReturn efx_rc_t
efx_lic_get_id(
__in efx_nic_t *enp,
__in size_t buffer_size,
__out uint32_t *typep,
__out size_t *lengthp,
__out_opt uint8_t *bufferp);
#endif /* EFSYS_OPT_LICENSING */
#ifdef __cplusplus
}

View File

@ -401,4 +401,15 @@
# endif
#endif /* EFSYS_OPT_BIST */
/* Support MCDI licensing API */
#if EFSYS_OPT_LICENSING
# if !EFSYS_OPT_MCDI
# error "LICENSING requires MCDI"
# endif
# if !EFSYS_HAS_UINT64
# error "LICENSING requires UINT64"
# endif
#endif /* EFSYS_OPT_LICENSING */
#endif /* _SYS_EFX_CHECK_H */

View File

@ -84,6 +84,7 @@ extern "C" {
#define EFX_MOD_WOL 0x00000800
#define EFX_MOD_FILTER 0x00001000
#define EFX_MOD_PKTFILTER 0x00002000
#define EFX_MOD_LIC 0x00004000
#define EFX_RESET_MAC 0x00000001
#define EFX_RESET_PHY 0x00000002
@ -591,6 +592,18 @@ efx_mcdi_nvram_test(
#endif /* EFSYS_OPT_VPD || EFSYS_OPT_NVRAM */
#if EFSYS_OPT_LICENSING
typedef struct efx_lic_ops_s {
efx_rc_t (*elo_update_licenses)(efx_nic_t *);
efx_rc_t (*elo_get_key_stats)(efx_nic_t *, efx_key_stats_t *);
efx_rc_t (*elo_app_state)(efx_nic_t *, uint64_t, boolean_t *);
efx_rc_t (*elo_get_id)(efx_nic_t *, size_t, uint32_t *,
size_t *, uint8_t *);
} efx_lic_ops_t;
#endif
typedef struct efx_drv_cfg_s {
uint32_t edc_min_vi_count;
uint32_t edc_max_vi_count;
@ -640,6 +653,9 @@ struct efx_nic_s {
uint32_t en_rss_context;
#endif /* EFSYS_OPT_RX_SCALE */
uint32_t en_vport_id;
#if EFSYS_OPT_LICENSING
efx_lic_ops_t *en_elop;
#endif
union {
#if EFSYS_OPT_FALCON
struct {

View File

@ -0,0 +1,792 @@
/*-
* Copyright (c) 2009-2015 Solarflare Communications Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are
* those of the authors and should not be interpreted as representing official
* policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "efx.h"
#include "efx_impl.h"
#if EFSYS_OPT_LICENSING
#if EFSYS_OPT_SIENA
static __checkReturn efx_rc_t
efx_mcdi_fc_license_update_license(
__in efx_nic_t *enp);
static __checkReturn efx_rc_t
efx_mcdi_fc_license_get_key_stats(
__in efx_nic_t *enp,
__out efx_key_stats_t *eksp);
static efx_lic_ops_t __efx_lic_v1_ops = {
efx_mcdi_fc_license_update_license, /* elo_update_licenses */
efx_mcdi_fc_license_get_key_stats, /* elo_get_key_stats */
NULL, /* elo_app_state */
NULL, /* elo_get_id */
};
#endif /* EFSYS_OPT_SIENA */
#if EFSYS_OPT_HUNTINGTON
static __checkReturn efx_rc_t
efx_mcdi_licensing_update_licenses(
__in efx_nic_t *enp);
static __checkReturn efx_rc_t
efx_mcdi_licensing_get_key_stats(
__in efx_nic_t *enp,
__out efx_key_stats_t *eksp);
static __checkReturn efx_rc_t
efx_mcdi_licensed_app_state(
__in efx_nic_t *enp,
__in uint64_t app_id,
__out boolean_t *licensedp);
static efx_lic_ops_t __efx_lic_v2_ops = {
efx_mcdi_licensing_update_licenses, /* elo_update_licenses */
efx_mcdi_licensing_get_key_stats, /* elo_get_key_stats */
efx_mcdi_licensed_app_state, /* elo_app_state */
NULL, /* elo_get_id */
};
#endif /* EFSYS_OPT_HUNTINGTON */
#if EFSYS_OPT_MEDFORD
static __checkReturn efx_rc_t
efx_mcdi_licensing_v3_update_licenses(
__in efx_nic_t *enp);
static __checkReturn efx_rc_t
efx_mcdi_licensing_v3_report_license(
__in efx_nic_t *enp,
__out efx_key_stats_t *eksp);
static __checkReturn efx_rc_t
efx_mcdi_licensing_v3_app_state(
__in efx_nic_t *enp,
__in uint64_t app_id,
__out boolean_t *licensedp);
static __checkReturn efx_rc_t
efx_mcdi_licensing_v3_get_id(
__in efx_nic_t *enp,
__in size_t buffer_size,
__out uint32_t *typep,
__out size_t *lengthp,
__out_bcount_part_opt(buffer_size, *lengthp)
uint8_t *bufferp);
static efx_lic_ops_t __efx_lic_v3_ops = {
efx_mcdi_licensing_v3_update_licenses, /* elo_update_licenses */
efx_mcdi_licensing_v3_report_license, /* elo_get_key_stats */
efx_mcdi_licensing_v3_app_state, /* elo_app_state */
efx_mcdi_licensing_v3_get_id, /* elo_get_id */
};
#endif /* EFSYS_OPT_MEDFORD */
/* V1 Licensing - used in Siena Modena only */
#if EFSYS_OPT_SIENA
static __checkReturn efx_rc_t
efx_mcdi_fc_license_update_license(
__in efx_nic_t *enp)
{
efx_mcdi_req_t req;
uint8_t payload[MC_CMD_FC_IN_LICENSE_LEN];
efx_rc_t rc;
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
(void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_FC_OP_LICENSE;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN;
req.emr_out_buf = payload;
req.emr_out_length = 0;
MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP,
MC_CMD_FC_IN_LICENSE_UPDATE_LICENSE);
efx_mcdi_execute(enp, &req);
if (req.emr_rc != 0) {
rc = req.emr_rc;
goto fail1;
}
if (req.emr_out_length_used != 0) {
rc = EIO;
goto fail2;
}
return (0);
fail2:
EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
static __checkReturn efx_rc_t
efx_mcdi_fc_license_get_key_stats(
__in efx_nic_t *enp,
__out efx_key_stats_t *eksp)
{
efx_mcdi_req_t req;
uint8_t payload[MAX(MC_CMD_FC_IN_LICENSE_LEN,
MC_CMD_FC_OUT_LICENSE_LEN)];
efx_rc_t rc;
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
(void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_FC_OP_LICENSE;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN;
req.emr_out_buf = payload;
req.emr_out_length = MC_CMD_FC_OUT_LICENSE_LEN;
MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP,
MC_CMD_FC_IN_LICENSE_GET_KEY_STATS);
efx_mcdi_execute(enp, &req);
if (req.emr_rc != 0) {
rc = req.emr_rc;
goto fail1;
}
if (req.emr_out_length_used < MC_CMD_FC_OUT_LICENSE_LEN) {
rc = EMSGSIZE;
goto fail2;
}
eksp->eks_valid =
MCDI_OUT_DWORD(req, FC_OUT_LICENSE_VALID_KEYS);
eksp->eks_invalid =
MCDI_OUT_DWORD(req, FC_OUT_LICENSE_INVALID_KEYS);
eksp->eks_blacklisted =
MCDI_OUT_DWORD(req, FC_OUT_LICENSE_BLACKLISTED_KEYS);
eksp->eks_unverifiable = 0;
eksp->eks_wrong_node = 0;
eksp->eks_licensed_apps_lo = 0;
eksp->eks_licensed_apps_hi = 0;
eksp->eks_licensed_features_lo = 0;
eksp->eks_licensed_features_hi = 0;
return (0);
fail2:
EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
#endif /* EFSYS_OPT_SIENA */
/* V2 Licensing - used by Huntington family only. See SF-113611-TC */
#if EFSYS_OPT_HUNTINGTON
static __checkReturn efx_rc_t
efx_mcdi_licensed_app_state(
__in efx_nic_t *enp,
__in uint64_t app_id,
__out boolean_t *licensedp)
{
efx_mcdi_req_t req;
uint8_t payload[MAX(MC_CMD_GET_LICENSED_APP_STATE_IN_LEN,
MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN)];
uint32_t app_state;
efx_rc_t rc;
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
/* V2 licensing supports 32bit app id only */
if ((app_id >> 32) != 0) {
rc = EINVAL;
goto fail1;
}
(void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_LICENSED_APP_STATE;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_LICENSED_APP_STATE_IN_LEN;
req.emr_out_buf = payload;
req.emr_out_length = MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN;
MCDI_IN_SET_DWORD(req, GET_LICENSED_APP_STATE_IN_APP_ID,
app_id & 0xffffffff);
efx_mcdi_execute(enp, &req);
if (req.emr_rc != 0) {
rc = req.emr_rc;
goto fail2;
}
if (req.emr_out_length_used < MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN) {
rc = EMSGSIZE;
goto fail3;
}
app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_APP_STATE_OUT_STATE));
if (app_state != MC_CMD_GET_LICENSED_APP_STATE_OUT_NOT_LICENSED) {
*licensedp = B_TRUE;
} else {
*licensedp = B_FALSE;
}
return (0);
fail3:
EFSYS_PROBE(fail3);
fail2:
EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
static __checkReturn efx_rc_t
efx_mcdi_licensing_update_licenses(
__in efx_nic_t *enp)
{
efx_mcdi_req_t req;
uint8_t payload[MC_CMD_LICENSING_IN_LEN];
efx_rc_t rc;
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
(void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_LICENSING;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_LICENSING_IN_LEN;
req.emr_out_buf = payload;
req.emr_out_length = 0;
MCDI_IN_SET_DWORD(req, LICENSING_IN_OP,
MC_CMD_LICENSING_IN_OP_UPDATE_LICENSE);
efx_mcdi_execute(enp, &req);
if (req.emr_rc != 0) {
rc = req.emr_rc;
goto fail1;
}
if (req.emr_out_length_used != 0) {
rc = EIO;
goto fail2;
}
return (0);
fail2:
EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
static __checkReturn efx_rc_t
efx_mcdi_licensing_get_key_stats(
__in efx_nic_t *enp,
__out efx_key_stats_t *eksp)
{
efx_mcdi_req_t req;
uint8_t payload[MAX(MC_CMD_LICENSING_IN_LEN,
MC_CMD_LICENSING_OUT_LEN)];
efx_rc_t rc;
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
(void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_LICENSING;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_LICENSING_IN_LEN;
req.emr_out_buf = payload;
req.emr_out_length = MC_CMD_LICENSING_OUT_LEN;
MCDI_IN_SET_DWORD(req, LICENSING_IN_OP,
MC_CMD_LICENSING_IN_OP_GET_KEY_STATS);
efx_mcdi_execute(enp, &req);
if (req.emr_rc != 0) {
rc = req.emr_rc;
goto fail1;
}
if (req.emr_out_length_used < MC_CMD_LICENSING_OUT_LEN) {
rc = EMSGSIZE;
goto fail2;
}
eksp->eks_valid =
MCDI_OUT_DWORD(req, LICENSING_OUT_VALID_APP_KEYS);
eksp->eks_invalid =
MCDI_OUT_DWORD(req, LICENSING_OUT_INVALID_APP_KEYS);
eksp->eks_blacklisted =
MCDI_OUT_DWORD(req, LICENSING_OUT_BLACKLISTED_APP_KEYS);
eksp->eks_unverifiable =
MCDI_OUT_DWORD(req, LICENSING_OUT_UNVERIFIABLE_APP_KEYS);
eksp->eks_wrong_node =
MCDI_OUT_DWORD(req, LICENSING_OUT_WRONG_NODE_APP_KEYS);
eksp->eks_licensed_apps_lo = 0;
eksp->eks_licensed_apps_hi = 0;
eksp->eks_licensed_features_lo = 0;
eksp->eks_licensed_features_hi = 0;
return (0);
fail2:
EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
#endif /* EFSYS_OPT_HUNTINGTON */
/* V3 Licensing - used starting from Medford family. See SF-114884-SW */
#if EFSYS_OPT_MEDFORD
static __checkReturn efx_rc_t
efx_mcdi_licensing_v3_update_licenses(
__in efx_nic_t *enp)
{
efx_mcdi_req_t req;
uint8_t payload[MC_CMD_LICENSING_V3_IN_LEN];
efx_rc_t rc;
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD);
(void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_LICENSING_V3;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN;
req.emr_out_buf = NULL;
req.emr_out_length = 0;
MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP,
MC_CMD_LICENSING_V3_IN_OP_UPDATE_LICENSE);
efx_mcdi_execute(enp, &req);
if (req.emr_rc != 0) {
rc = req.emr_rc;
goto fail1;
}
return (0);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
static __checkReturn efx_rc_t
efx_mcdi_licensing_v3_report_license(
__in efx_nic_t *enp,
__out efx_key_stats_t *eksp)
{
efx_mcdi_req_t req;
uint8_t payload[MAX(MC_CMD_LICENSING_V3_IN_LEN,
MC_CMD_LICENSING_V3_OUT_LEN)];
efx_rc_t rc;
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD);
(void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_LICENSING_V3;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN;
req.emr_out_buf = payload;
req.emr_out_length = MC_CMD_LICENSING_V3_OUT_LEN;
MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP,
MC_CMD_LICENSING_V3_IN_OP_REPORT_LICENSE);
efx_mcdi_execute(enp, &req);
if (req.emr_rc != 0) {
rc = req.emr_rc;
goto fail1;
}
if (req.emr_out_length_used < MC_CMD_LICENSING_V3_OUT_LEN) {
rc = EMSGSIZE;
goto fail2;
}
eksp->eks_valid =
MCDI_OUT_DWORD(req, LICENSING_V3_OUT_VALID_KEYS);
eksp->eks_invalid =
MCDI_OUT_DWORD(req, LICENSING_V3_OUT_INVALID_KEYS);
eksp->eks_blacklisted = 0;
eksp->eks_unverifiable =
MCDI_OUT_DWORD(req, LICENSING_V3_OUT_UNVERIFIABLE_KEYS);
eksp->eks_wrong_node =
MCDI_OUT_DWORD(req, LICENSING_V3_OUT_WRONG_NODE_KEYS);
eksp->eks_licensed_apps_lo =
MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_LO);
eksp->eks_licensed_apps_hi =
MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_HI);
eksp->eks_licensed_features_lo =
MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_LO);
eksp->eks_licensed_features_hi =
MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_HI);
return (0);
fail2:
EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
static __checkReturn efx_rc_t
efx_mcdi_licensing_v3_app_state(
__in efx_nic_t *enp,
__in uint64_t app_id,
__out boolean_t *licensedp)
{
efx_mcdi_req_t req;
uint8_t payload[MAX(MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN,
MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN)];
uint32_t app_state;
efx_rc_t rc;
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD);
(void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_LICENSED_V3_APP_STATE;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN;
req.emr_out_buf = payload;
req.emr_out_length = MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN;
MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_LO,
app_id & 0xffffffff);
MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_HI,
app_id >> 32);
efx_mcdi_execute(enp, &req);
if (req.emr_rc != 0) {
rc = req.emr_rc;
goto fail1;
}
if (req.emr_out_length_used < MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN) {
rc = EMSGSIZE;
goto fail2;
}
app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_V3_APP_STATE_OUT_STATE));
if (app_state != MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_NOT_LICENSED) {
*licensedp = B_TRUE;
} else {
*licensedp = B_FALSE;
}
return (0);
fail2:
EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
static __checkReturn efx_rc_t
efx_mcdi_licensing_v3_get_id(
__in efx_nic_t *enp,
__in size_t buffer_size,
__out uint32_t *typep,
__out size_t *lengthp,
__out_bcount_part_opt(buffer_size, *lengthp)
uint8_t *bufferp)
{
efx_mcdi_req_t req;
uint8_t payload[MAX(MC_CMD_LICENSING_GET_ID_V3_IN_LEN,
MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN)];
efx_rc_t rc;
req.emr_cmd = MC_CMD_LICENSING_GET_ID_V3;
if (bufferp == NULL) {
/* Request id type and length only */
req.emr_in_buf = bufferp;
req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN;
req.emr_out_buf = bufferp;
req.emr_out_length = MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN;
(void) memset(payload, 0, sizeof (payload));
} else {
/* Request full buffer */
req.emr_in_buf = bufferp;
req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN;
req.emr_out_buf = bufferp;
req.emr_out_length = MIN(buffer_size, MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN);
(void) memset(bufferp, 0, req.emr_out_length);
}
efx_mcdi_execute(enp, &req);
if (req.emr_rc != 0) {
rc = req.emr_rc;
goto fail1;
}
if (req.emr_out_length_used < MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN) {
rc = EMSGSIZE;
goto fail2;
}
*typep = MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_TYPE);
*lengthp = MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_ID_LENGTH);
if (bufferp == NULL) {
/* modify length requirements to indicate to caller the extra buffering
** needed to read the complete output.
*/
*lengthp += MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN;
} else {
/* Shift ID down to start of buffer */
memmove(bufferp,
bufferp+MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST,
*lengthp);
memset(bufferp+(*lengthp), 0, MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST);
}
return (0);
fail2:
EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
#endif /* EFSYS_OPT_MEDFORD */
__checkReturn efx_rc_t
efx_lic_init(
__in efx_nic_t *enp)
{
efx_lic_ops_t *elop;
efx_rc_t rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_LIC));
switch (enp->en_family) {
#if EFSYS_OPT_SIENA
case EFX_FAMILY_SIENA:
elop = (efx_lic_ops_t *)&__efx_lic_v1_ops;
break;
#endif /* EFSYS_OPT_SIENA */
#if EFSYS_OPT_HUNTINGTON
case EFX_FAMILY_HUNTINGTON:
elop = (efx_lic_ops_t *)&__efx_lic_v2_ops;
break;
#endif /* EFSYS_OPT_HUNTINGTON */
#if EFSYS_OPT_MEDFORD
case EFX_FAMILY_MEDFORD:
elop = (efx_lic_ops_t *)&__efx_lic_v3_ops;
break;
#endif /* EFSYS_OPT_MEDFORD */
default:
EFSYS_ASSERT(0);
rc = ENOTSUP;
goto fail1;
}
enp->en_elop = elop;
enp->en_mod_flags |= EFX_MOD_LIC;
return (0);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
void
efx_lic_fini(
__in efx_nic_t *enp)
{
efx_lic_ops_t *elop = enp->en_elop;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
enp->en_elop = NULL;
enp->en_mod_flags &= ~EFX_MOD_LIC;
}
__checkReturn efx_rc_t
efx_lic_update_licenses(
__in efx_nic_t *enp)
{
efx_lic_ops_t *elop = enp->en_elop;
efx_rc_t rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
if ((rc = elop->elo_update_licenses(enp)) != 0)
goto fail1;
return (0);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
__checkReturn efx_rc_t
efx_lic_get_key_stats(
__in efx_nic_t *enp,
__out efx_key_stats_t *eksp)
{
efx_lic_ops_t *elop = enp->en_elop;
efx_rc_t rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
if ((rc = elop->elo_get_key_stats(enp, eksp)) != 0)
goto fail1;
return (0);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
__checkReturn efx_rc_t
efx_lic_app_state(
__in efx_nic_t *enp,
__in uint64_t app_id,
__out boolean_t *licensedp)
{
efx_lic_ops_t *elop = enp->en_elop;
efx_rc_t rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
if (elop->elo_app_state == NULL) {
rc = ENOTSUP;
goto fail1;
}
if ((rc = elop->elo_app_state(enp, app_id, licensedp)) != 0)
goto fail2;
return (0);
fail2:
EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
__checkReturn efx_rc_t
efx_lic_get_id(
__in efx_nic_t *enp,
__in size_t buffer_size,
__out uint32_t *typep,
__out size_t *lengthp,
__out_opt uint8_t *bufferp
)
{
efx_lic_ops_t *elop = enp->en_elop;
efx_rc_t rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
if (elop->elo_get_id == NULL) {
rc = ENOTSUP;
goto fail1;
}
if ((rc = elop->elo_get_id(enp, buffer_size, typep,
lengthp, bufferp)) != 0)
goto fail2;
return (0);
fail2:
EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
return (rc);
}
#endif /* EFSYS_OPT_LICENSING */

View File

@ -708,8 +708,9 @@ efx_nic_reset(
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
/*
* All modules except the MCDI, PROBE, NVRAM, VPD, MON (which we
* do not reset here) must have been shut down or never initialized.
* All modules except the MCDI, PROBE, NVRAM, VPD, MON, LIC
* (which we do not reset here) must have been shut down or never
* initialized.
*
* A rule of thumb here is: If the controller or MC reboots, is *any*
* state lost. If it's lost and needs reapplying, then the module
@ -717,7 +718,7 @@ efx_nic_reset(
*/
mod_flags = enp->en_mod_flags;
mod_flags &= ~(EFX_MOD_MCDI | EFX_MOD_PROBE | EFX_MOD_NVRAM |
EFX_MOD_VPD | EFX_MOD_MON);
EFX_MOD_VPD | EFX_MOD_MON | EFX_MOD_LIC);
EFSYS_ASSERT3U(mod_flags, ==, 0);
if (mod_flags != 0) {
rc = EINVAL;

View File

@ -14,7 +14,7 @@ SRCS+= sfxge_port.c sfxge_rx.c sfxge_tx.c
SRCS+= sfxge.h sfxge_rx.h sfxge_tx.h sfxge_version.h
.PATH: ${.CURDIR}/../../dev/sfxge/common
SRCS+= efx_bootcfg.c efx_crc32.c efx_ev.c efx_intr.c efx_mac.c
SRCS+= efx_bootcfg.c efx_crc32.c efx_ev.c efx_intr.c efx_lic.c efx_mac.c
SRCS+= efx_mcdi.c efx_mon.c efx_nic.c
SRCS+= efx_nvram.c efx_phy.c efx_port.c efx_rx.c efx_sram.c efx_tx.c
SRCS+= efx_vpd.c efx_wol.c efx_filter.c efx_hash.c