Author: arybchik
Date: Wed Jan 20 08:01:21 2016
New Revision: 294386
URL: https://svnweb.freebsd.org/changeset/base/294386

Log:
  MFC r293901,r294371
  
  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.

Added:
  stable/10/sys/dev/sfxge/common/efx_lic.c
     - copied unchanged from r293901, head/sys/dev/sfxge/common/efx_lic.c
Modified:
  stable/10/sys/conf/files.amd64
  stable/10/sys/dev/sfxge/common/efsys.h
  stable/10/sys/dev/sfxge/common/efx.h
  stable/10/sys/dev/sfxge/common/efx_check.h
  stable/10/sys/dev/sfxge/common/efx_impl.h
  stable/10/sys/dev/sfxge/common/efx_nic.c
  stable/10/sys/modules/sfxge/Makefile
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/conf/files.amd64
==============================================================================
--- stable/10/sys/conf/files.amd64      Wed Jan 20 07:59:04 2016        
(r294385)
+++ stable/10/sys/conf/files.amd64      Wed Jan 20 08:01:21 2016        
(r294386)
@@ -317,6 +317,7 @@ dev/sfxge/common/efx_ev.c   optional        sfxge
 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

Modified: stable/10/sys/dev/sfxge/common/efsys.h
==============================================================================
--- stable/10/sys/dev/sfxge/common/efsys.h      Wed Jan 20 07:59:04 2016        
(r294385)
+++ stable/10/sys/dev/sfxge/common/efsys.h      Wed Jan 20 08:01:21 2016        
(r294386)
@@ -211,6 +211,8 @@ sfxge_map_mbuf_fast(bus_dma_tag_t tag, b
 #define        __out_ecount_opt(_n)
 #define        __out_bcount(_n)
 #define        __out_bcount_opt(_n)
+#define        __out_bcount_part(_n, _l)
+#define        __out_bcount_part_opt(_n, _l)
 
 #define        __deref_out
 
@@ -293,6 +295,8 @@ sfxge_map_mbuf_fast(bus_dma_tag_t tag, b
 
 #define        EFSYS_OPT_DECODE_INTR_FATAL 1
 
+#define        EFSYS_OPT_LICENSING 0
+
 /* ID */
 
 typedef struct __efsys_identifier_s    efsys_identifier_t;

Modified: stable/10/sys/dev/sfxge/common/efx.h
==============================================================================
--- stable/10/sys/dev/sfxge/common/efx.h        Wed Jan 20 07:59:04 2016        
(r294385)
+++ stable/10/sys/dev/sfxge/common/efx.h        Wed Jan 20 08:01:21 2016        
(r294386)
@@ -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
 }

Modified: stable/10/sys/dev/sfxge/common/efx_check.h
==============================================================================
--- stable/10/sys/dev/sfxge/common/efx_check.h  Wed Jan 20 07:59:04 2016        
(r294385)
+++ stable/10/sys/dev/sfxge/common/efx_check.h  Wed Jan 20 08:01:21 2016        
(r294386)
@@ -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 */

Modified: stable/10/sys/dev/sfxge/common/efx_impl.h
==============================================================================
--- stable/10/sys/dev/sfxge/common/efx_impl.h   Wed Jan 20 07:59:04 2016        
(r294385)
+++ stable/10/sys/dev/sfxge/common/efx_impl.h   Wed Jan 20 08:01:21 2016        
(r294386)
@@ -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 {

Copied: stable/10/sys/dev/sfxge/common/efx_lic.c (from r293901, 
head/sys/dev/sfxge/common/efx_lic.c)
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ stable/10/sys/dev/sfxge/common/efx_lic.c    Wed Jan 20 08:01:21 2016        
(r294386, copy of r293901, head/sys/dev/sfxge/common/efx_lic.c)
@@ -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 */

Modified: stable/10/sys/dev/sfxge/common/efx_nic.c
==============================================================================
--- stable/10/sys/dev/sfxge/common/efx_nic.c    Wed Jan 20 07:59:04 2016        
(r294385)
+++ stable/10/sys/dev/sfxge/common/efx_nic.c    Wed Jan 20 08:01:21 2016        
(r294386)
@@ -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;

Modified: stable/10/sys/modules/sfxge/Makefile
==============================================================================
--- stable/10/sys/modules/sfxge/Makefile        Wed Jan 20 07:59:04 2016        
(r294385)
+++ stable/10/sys/modules/sfxge/Makefile        Wed Jan 20 08:01:21 2016        
(r294386)
@@ -16,7 +16,7 @@ SRCS+=        sfxge_port.c sfxge_rx.c sfxge_tx.
 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
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to