The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/sfxge/common/efx_lic.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2009-2016 Solarflare Communications Inc.
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions are met:
    7  *
    8  * 1. Redistributions of source code must retain the above copyright notice,
    9  *    this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright notice,
   11  *    this list of conditions and the following disclaimer in the documentation
   12  *    and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
   16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
   18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   21  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   22  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   23  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
   24  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   25  *
   26  * The views and conclusions contained in the software and documentation are
   27  * those of the authors and should not be interpreted as representing official
   28  * policies, either expressed or implied, of the FreeBSD Project.
   29  */
   30 
   31 #include <sys/cdefs.h>
   32 __FBSDID("$FreeBSD$");
   33 
   34 #include "efx.h"
   35 #include "efx_impl.h"
   36 
   37 #if EFSYS_OPT_LICENSING
   38 
   39 #include "ef10_tlv_layout.h"
   40 #if EFSYS_OPT_SIENA
   41 #include "efx_regs_mcdi_aoe.h"
   42 #endif
   43 
   44 #if EFSYS_OPT_SIENA | EFSYS_OPT_HUNTINGTON
   45 
   46         __checkReturn           efx_rc_t
   47 efx_lic_v1v2_find_start(
   48         __in                    efx_nic_t *enp,
   49         __in_bcount(buffer_size)
   50                                 caddr_t bufferp,
   51         __in                    size_t buffer_size,
   52         __out                   uint32_t *startp);
   53 
   54         __checkReturn           efx_rc_t
   55 efx_lic_v1v2_find_end(
   56         __in                    efx_nic_t *enp,
   57         __in_bcount(buffer_size)
   58                                 caddr_t bufferp,
   59         __in                    size_t buffer_size,
   60         __in                    uint32_t offset,
   61         __out                   uint32_t *endp);
   62 
   63         __checkReturn   __success(return != B_FALSE)    boolean_t
   64 efx_lic_v1v2_find_key(
   65         __in                    efx_nic_t *enp,
   66         __in_bcount(buffer_size)
   67                                 caddr_t bufferp,
   68         __in                    size_t buffer_size,
   69         __in                    uint32_t offset,
   70         __out                   uint32_t *startp,
   71         __out                   uint32_t *lengthp);
   72 
   73         __checkReturn   __success(return != B_FALSE)    boolean_t
   74 efx_lic_v1v2_validate_key(
   75         __in                    efx_nic_t *enp,
   76         __in_bcount(length)     caddr_t keyp,
   77         __in                    uint32_t length);
   78 
   79         __checkReturn           efx_rc_t
   80 efx_lic_v1v2_read_key(
   81         __in                    efx_nic_t *enp,
   82         __in_bcount(buffer_size)
   83                                 caddr_t bufferp,
   84         __in                    size_t buffer_size,
   85         __in                    uint32_t offset,
   86         __in                    uint32_t length,
   87         __out_bcount_part(key_max_size, *lengthp)
   88                                 caddr_t keyp,
   89         __in                    size_t key_max_size,
   90         __out                   uint32_t *lengthp);
   91 
   92         __checkReturn           efx_rc_t
   93 efx_lic_v1v2_write_key(
   94         __in                    efx_nic_t *enp,
   95         __in_bcount(buffer_size)
   96                                 caddr_t bufferp,
   97         __in                    size_t buffer_size,
   98         __in                    uint32_t offset,
   99         __in_bcount(length)     caddr_t keyp,
  100         __in                    uint32_t length,
  101         __out                   uint32_t *lengthp);
  102 
  103         __checkReturn           efx_rc_t
  104 efx_lic_v1v2_delete_key(
  105         __in                    efx_nic_t *enp,
  106         __in_bcount(buffer_size)
  107                                 caddr_t bufferp,
  108         __in                    size_t buffer_size,
  109         __in                    uint32_t offset,
  110         __in                    uint32_t length,
  111         __in                    uint32_t end,
  112         __out                   uint32_t *deltap);
  113 
  114         __checkReturn           efx_rc_t
  115 efx_lic_v1v2_create_partition(
  116         __in                    efx_nic_t *enp,
  117         __in_bcount(buffer_size)
  118                                 caddr_t bufferp,
  119         __in                    size_t buffer_size);
  120 
  121         __checkReturn           efx_rc_t
  122 efx_lic_v1v2_finish_partition(
  123         __in                    efx_nic_t *enp,
  124         __in_bcount(buffer_size)
  125                                 caddr_t bufferp,
  126         __in                    size_t buffer_size);
  127 
  128 #endif  /* EFSYS_OPT_HUNTINGTON | EFSYS_OPT_SIENA */
  129 
  130 #if EFSYS_OPT_SIENA
  131 
  132 static  __checkReturn   efx_rc_t
  133 efx_mcdi_fc_license_update_license(
  134         __in            efx_nic_t *enp);
  135 
  136 static  __checkReturn   efx_rc_t
  137 efx_mcdi_fc_license_get_key_stats(
  138         __in            efx_nic_t *enp,
  139         __out           efx_key_stats_t *eksp);
  140 
  141 static const efx_lic_ops_t      __efx_lic_v1_ops = {
  142         efx_mcdi_fc_license_update_license,     /* elo_update_licenses */
  143         efx_mcdi_fc_license_get_key_stats,      /* elo_get_key_stats */
  144         NULL,                                   /* elo_app_state */
  145         NULL,                                   /* elo_get_id */
  146         efx_lic_v1v2_find_start,                /* elo_find_start */
  147         efx_lic_v1v2_find_end,                  /* elo_find_end */
  148         efx_lic_v1v2_find_key,                  /* elo_find_key */
  149         efx_lic_v1v2_validate_key,              /* elo_validate_key */
  150         efx_lic_v1v2_read_key,                  /* elo_read_key */
  151         efx_lic_v1v2_write_key,                 /* elo_write_key */
  152         efx_lic_v1v2_delete_key,                /* elo_delete_key */
  153         efx_lic_v1v2_create_partition,          /* elo_create_partition */
  154         efx_lic_v1v2_finish_partition,          /* elo_finish_partition */
  155 };
  156 
  157 #endif  /* EFSYS_OPT_SIENA */
  158 
  159 #if EFSYS_OPT_HUNTINGTON
  160 
  161 static  __checkReturn   efx_rc_t
  162 efx_mcdi_licensing_update_licenses(
  163         __in            efx_nic_t *enp);
  164 
  165 static  __checkReturn   efx_rc_t
  166 efx_mcdi_licensing_get_key_stats(
  167         __in            efx_nic_t *enp,
  168         __out           efx_key_stats_t *eksp);
  169 
  170 static  __checkReturn   efx_rc_t
  171 efx_mcdi_licensed_app_state(
  172         __in            efx_nic_t *enp,
  173         __in            uint64_t app_id,
  174         __out           boolean_t *licensedp);
  175 
  176 static const efx_lic_ops_t      __efx_lic_v2_ops = {
  177         efx_mcdi_licensing_update_licenses,     /* elo_update_licenses */
  178         efx_mcdi_licensing_get_key_stats,       /* elo_get_key_stats */
  179         efx_mcdi_licensed_app_state,            /* elo_app_state */
  180         NULL,                                   /* elo_get_id */
  181         efx_lic_v1v2_find_start,                /* elo_find_start */
  182         efx_lic_v1v2_find_end,                  /* elo_find_end */
  183         efx_lic_v1v2_find_key,                  /* elo_find_key */
  184         efx_lic_v1v2_validate_key,              /* elo_validate_key */
  185         efx_lic_v1v2_read_key,                  /* elo_read_key */
  186         efx_lic_v1v2_write_key,                 /* elo_write_key */
  187         efx_lic_v1v2_delete_key,                /* elo_delete_key */
  188         efx_lic_v1v2_create_partition,          /* elo_create_partition */
  189         efx_lic_v1v2_finish_partition,          /* elo_finish_partition */
  190 };
  191 
  192 #endif  /* EFSYS_OPT_HUNTINGTON */
  193 
  194 #if EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
  195 
  196 static  __checkReturn   efx_rc_t
  197 efx_mcdi_licensing_v3_update_licenses(
  198         __in            efx_nic_t *enp);
  199 
  200 static  __checkReturn   efx_rc_t
  201 efx_mcdi_licensing_v3_report_license(
  202         __in            efx_nic_t *enp,
  203         __out           efx_key_stats_t *eksp);
  204 
  205 static  __checkReturn   efx_rc_t
  206 efx_mcdi_licensing_v3_app_state(
  207         __in            efx_nic_t *enp,
  208         __in            uint64_t app_id,
  209         __out           boolean_t *licensedp);
  210 
  211 static  __checkReturn   efx_rc_t
  212 efx_mcdi_licensing_v3_get_id(
  213         __in            efx_nic_t *enp,
  214         __in            size_t buffer_size,
  215         __out           uint32_t *typep,
  216         __out           size_t *lengthp,
  217         __out_bcount_part_opt(buffer_size, *lengthp)
  218                         uint8_t *bufferp);
  219 
  220         __checkReturn           efx_rc_t
  221 efx_lic_v3_find_start(
  222         __in                    efx_nic_t *enp,
  223         __in_bcount(buffer_size)
  224                                 caddr_t bufferp,
  225         __in                    size_t buffer_size,
  226         __out                   uint32_t *startp);
  227 
  228         __checkReturn           efx_rc_t
  229 efx_lic_v3_find_end(
  230         __in                    efx_nic_t *enp,
  231         __in_bcount(buffer_size)
  232                                 caddr_t bufferp,
  233         __in                    size_t buffer_size,
  234         __in                    uint32_t offset,
  235         __out                   uint32_t *endp);
  236 
  237         __checkReturn   __success(return != B_FALSE)    boolean_t
  238 efx_lic_v3_find_key(
  239         __in                    efx_nic_t *enp,
  240         __in_bcount(buffer_size)
  241                                 caddr_t bufferp,
  242         __in                    size_t buffer_size,
  243         __in                    uint32_t offset,
  244         __out                   uint32_t *startp,
  245         __out                   uint32_t *lengthp);
  246 
  247         __checkReturn   __success(return != B_FALSE)    boolean_t
  248 efx_lic_v3_validate_key(
  249         __in                    efx_nic_t *enp,
  250         __in_bcount(length)     caddr_t keyp,
  251         __in                    uint32_t length);
  252 
  253         __checkReturn           efx_rc_t
  254 efx_lic_v3_read_key(
  255         __in                    efx_nic_t *enp,
  256         __in_bcount(buffer_size)
  257                                 caddr_t bufferp,
  258         __in                    size_t buffer_size,
  259         __in                    uint32_t offset,
  260         __in                    uint32_t length,
  261         __out_bcount_part(key_max_size, *lengthp)
  262                                 caddr_t keyp,
  263         __in                    size_t key_max_size,
  264         __out                   uint32_t *lengthp);
  265 
  266         __checkReturn           efx_rc_t
  267 efx_lic_v3_write_key(
  268         __in                    efx_nic_t *enp,
  269         __in_bcount(buffer_size)
  270                                 caddr_t bufferp,
  271         __in                    size_t buffer_size,
  272         __in                    uint32_t offset,
  273         __in_bcount(length)     caddr_t keyp,
  274         __in                    uint32_t length,
  275         __out                   uint32_t *lengthp);
  276 
  277         __checkReturn           efx_rc_t
  278 efx_lic_v3_delete_key(
  279         __in                    efx_nic_t *enp,
  280         __in_bcount(buffer_size)
  281                                 caddr_t bufferp,
  282         __in                    size_t buffer_size,
  283         __in                    uint32_t offset,
  284         __in                    uint32_t length,
  285         __in                    uint32_t end,
  286         __out                   uint32_t *deltap);
  287 
  288         __checkReturn           efx_rc_t
  289 efx_lic_v3_create_partition(
  290         __in                    efx_nic_t *enp,
  291         __in_bcount(buffer_size)
  292                                 caddr_t bufferp,
  293         __in                    size_t buffer_size);
  294 
  295         __checkReturn           efx_rc_t
  296 efx_lic_v3_finish_partition(
  297         __in                    efx_nic_t *enp,
  298         __in_bcount(buffer_size)
  299                                 caddr_t bufferp,
  300         __in                    size_t buffer_size);
  301 
  302 static const efx_lic_ops_t      __efx_lic_v3_ops = {
  303         efx_mcdi_licensing_v3_update_licenses,  /* elo_update_licenses */
  304         efx_mcdi_licensing_v3_report_license,   /* elo_get_key_stats */
  305         efx_mcdi_licensing_v3_app_state,        /* elo_app_state */
  306         efx_mcdi_licensing_v3_get_id,           /* elo_get_id */
  307         efx_lic_v3_find_start,                  /* elo_find_start */
  308         efx_lic_v3_find_end,                    /* elo_find_end */
  309         efx_lic_v3_find_key,                    /* elo_find_key */
  310         efx_lic_v3_validate_key,                /* elo_validate_key */
  311         efx_lic_v3_read_key,                    /* elo_read_key */
  312         efx_lic_v3_write_key,                   /* elo_write_key */
  313         efx_lic_v3_delete_key,                  /* elo_delete_key */
  314         efx_lic_v3_create_partition,            /* elo_create_partition */
  315         efx_lic_v3_finish_partition,            /* elo_finish_partition */
  316 };
  317 
  318 #endif  /* EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
  319 
  320 /* V1 Licensing - used in Siena Modena only */
  321 
  322 #if EFSYS_OPT_SIENA
  323 
  324 static  __checkReturn   efx_rc_t
  325 efx_mcdi_fc_license_update_license(
  326         __in            efx_nic_t *enp)
  327 {
  328         efx_mcdi_req_t req;
  329         EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FC_IN_LICENSE_LEN, 0);
  330         efx_rc_t rc;
  331 
  332         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
  333 
  334         req.emr_cmd = MC_CMD_FC;
  335         req.emr_in_buf = payload;
  336         req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN;
  337         req.emr_out_buf = payload;
  338         req.emr_out_length = 0;
  339 
  340         MCDI_IN_SET_DWORD(req, FC_IN_CMD,
  341             MC_CMD_FC_OP_LICENSE);
  342 
  343         MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP,
  344             MC_CMD_FC_IN_LICENSE_UPDATE_LICENSE);
  345 
  346         efx_mcdi_execute(enp, &req);
  347 
  348         if (req.emr_rc != 0) {
  349                 rc = req.emr_rc;
  350                 goto fail1;
  351         }
  352 
  353         if (req.emr_out_length_used != 0) {
  354                 rc = EIO;
  355                 goto fail2;
  356         }
  357 
  358         return (0);
  359 
  360 fail2:
  361         EFSYS_PROBE(fail2);
  362 fail1:
  363         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  364 
  365         return (rc);
  366 }
  367 
  368 static  __checkReturn   efx_rc_t
  369 efx_mcdi_fc_license_get_key_stats(
  370         __in            efx_nic_t *enp,
  371         __out           efx_key_stats_t *eksp)
  372 {
  373         efx_mcdi_req_t req;
  374         EFX_MCDI_DECLARE_BUF(payload, MC_CMD_FC_IN_LICENSE_LEN,
  375                 MC_CMD_FC_OUT_LICENSE_LEN);
  376         efx_rc_t rc;
  377 
  378         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
  379 
  380         req.emr_cmd = MC_CMD_FC;
  381         req.emr_in_buf = payload;
  382         req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN;
  383         req.emr_out_buf = payload;
  384         req.emr_out_length = MC_CMD_FC_OUT_LICENSE_LEN;
  385 
  386         MCDI_IN_SET_DWORD(req, FC_IN_CMD,
  387             MC_CMD_FC_OP_LICENSE);
  388 
  389         MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP,
  390             MC_CMD_FC_IN_LICENSE_GET_KEY_STATS);
  391 
  392         efx_mcdi_execute_quiet(enp, &req);
  393 
  394         if (req.emr_rc != 0) {
  395                 rc = req.emr_rc;
  396                 goto fail1;
  397         }
  398 
  399         if (req.emr_out_length_used < MC_CMD_FC_OUT_LICENSE_LEN) {
  400                 rc = EMSGSIZE;
  401                 goto fail2;
  402         }
  403 
  404         eksp->eks_valid =
  405                 MCDI_OUT_DWORD(req, FC_OUT_LICENSE_VALID_KEYS);
  406         eksp->eks_invalid =
  407                 MCDI_OUT_DWORD(req, FC_OUT_LICENSE_INVALID_KEYS);
  408         eksp->eks_blacklisted =
  409                 MCDI_OUT_DWORD(req, FC_OUT_LICENSE_BLACKLISTED_KEYS);
  410         eksp->eks_unverifiable = 0;
  411         eksp->eks_wrong_node = 0;
  412         eksp->eks_licensed_apps_lo = 0;
  413         eksp->eks_licensed_apps_hi = 0;
  414         eksp->eks_licensed_features_lo = 0;
  415         eksp->eks_licensed_features_hi = 0;
  416 
  417         return (0);
  418 
  419 fail2:
  420         EFSYS_PROBE(fail2);
  421 fail1:
  422         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  423 
  424         return (rc);
  425 }
  426 
  427 #endif  /* EFSYS_OPT_SIENA */
  428 
  429 /* V1 and V2 Partition format - based on a 16-bit TLV format */
  430 
  431 #if EFSYS_OPT_SIENA | EFSYS_OPT_HUNTINGTON
  432 
  433 /*
  434  * V1/V2 format - defined in SF-108542-TC section 4.2:
  435  *  Type (T):   16bit - revision/HMAC algorithm
  436  *  Length (L): 16bit - value length in bytes
  437  *  Value (V):  L bytes - payload
  438  */
  439 #define EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX     (256)
  440 #define EFX_LICENSE_V1V2_HEADER_LENGTH          (2 * sizeof (uint16_t))
  441 
  442         __checkReturn           efx_rc_t
  443 efx_lic_v1v2_find_start(
  444         __in                    efx_nic_t *enp,
  445         __in_bcount(buffer_size)
  446                                 caddr_t bufferp,
  447         __in                    size_t buffer_size,
  448         __out                   uint32_t *startp)
  449 {
  450         _NOTE(ARGUNUSED(enp, bufferp, buffer_size))
  451 
  452         *startp = 0;
  453         return (0);
  454 }
  455 
  456         __checkReturn           efx_rc_t
  457 efx_lic_v1v2_find_end(
  458         __in                    efx_nic_t *enp,
  459         __in_bcount(buffer_size)
  460                                 caddr_t bufferp,
  461         __in                    size_t buffer_size,
  462         __in                    uint32_t offset,
  463         __out                   uint32_t *endp)
  464 {
  465         _NOTE(ARGUNUSED(enp, bufferp, buffer_size))
  466 
  467         *endp = offset + EFX_LICENSE_V1V2_HEADER_LENGTH;
  468         return (0);
  469 }
  470 
  471         __checkReturn   __success(return != B_FALSE)    boolean_t
  472 efx_lic_v1v2_find_key(
  473         __in                    efx_nic_t *enp,
  474         __in_bcount(buffer_size)
  475                                 caddr_t bufferp,
  476         __in                    size_t buffer_size,
  477         __in                    uint32_t offset,
  478         __out                   uint32_t *startp,
  479         __out                   uint32_t *lengthp)
  480 {
  481         boolean_t found;
  482         uint16_t tlv_type;
  483         uint16_t tlv_length;
  484 
  485         _NOTE(ARGUNUSED(enp))
  486 
  487         if ((size_t)buffer_size - offset < EFX_LICENSE_V1V2_HEADER_LENGTH)
  488                 goto fail1;
  489 
  490         tlv_type = __LE_TO_CPU_16(((uint16_t *)&bufferp[offset])[0]);
  491         tlv_length = __LE_TO_CPU_16(((uint16_t *)&bufferp[offset])[1]);
  492         if ((tlv_length > EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX) ||
  493             (tlv_type == 0 && tlv_length == 0)) {
  494                 found = B_FALSE;
  495         } else {
  496                 *startp = offset;
  497                 *lengthp = tlv_length + EFX_LICENSE_V1V2_HEADER_LENGTH;
  498                 found = B_TRUE;
  499         }
  500         return (found);
  501 
  502 fail1:
  503         EFSYS_PROBE1(fail1, boolean_t, B_FALSE);
  504 
  505         return (B_FALSE);
  506 }
  507 
  508         __checkReturn   __success(return != B_FALSE)    boolean_t
  509 efx_lic_v1v2_validate_key(
  510         __in                    efx_nic_t *enp,
  511         __in_bcount(length)     caddr_t keyp,
  512         __in                    uint32_t length)
  513 {
  514         uint16_t tlv_type;
  515         uint16_t tlv_length;
  516 
  517         _NOTE(ARGUNUSED(enp))
  518 
  519         if (length < EFX_LICENSE_V1V2_HEADER_LENGTH) {
  520                 goto fail1;
  521         }
  522 
  523         tlv_type = __LE_TO_CPU_16(((uint16_t *)keyp)[0]);
  524         tlv_length = __LE_TO_CPU_16(((uint16_t *)keyp)[1]);
  525 
  526         if (tlv_length > EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX) {
  527                 goto fail2;
  528         }
  529         if (tlv_type == 0) {
  530                 goto fail3;
  531         }
  532         if ((tlv_length + EFX_LICENSE_V1V2_HEADER_LENGTH) != length) {
  533                 goto fail4;
  534         }
  535 
  536         return (B_TRUE);
  537 
  538 fail4:
  539         EFSYS_PROBE(fail4);
  540 fail3:
  541         EFSYS_PROBE(fail3);
  542 fail2:
  543         EFSYS_PROBE(fail2);
  544 fail1:
  545         EFSYS_PROBE1(fail1, boolean_t, B_FALSE);
  546 
  547         return (B_FALSE);
  548 }
  549 
  550         __checkReturn           efx_rc_t
  551 efx_lic_v1v2_read_key(
  552         __in                    efx_nic_t *enp,
  553         __in_bcount(buffer_size)
  554                                 caddr_t bufferp,
  555         __in                    size_t buffer_size,
  556         __in                    uint32_t offset,
  557         __in                    uint32_t length,
  558         __out_bcount_part(key_max_size, *lengthp)
  559                                 caddr_t keyp,
  560         __in                    size_t key_max_size,
  561         __out                   uint32_t *lengthp)
  562 {
  563         efx_rc_t rc;
  564 
  565         _NOTE(ARGUNUSED(enp, buffer_size))
  566         EFSYS_ASSERT(length <= (EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX +
  567             EFX_LICENSE_V1V2_HEADER_LENGTH));
  568 
  569         if (key_max_size < length) {
  570                 rc = ENOSPC;
  571                 goto fail1;
  572         }
  573         memcpy(keyp, &bufferp[offset], length);
  574 
  575         *lengthp = length;
  576 
  577         return (0);
  578 
  579 fail1:
  580         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  581 
  582         return (rc);
  583 }
  584 
  585         __checkReturn           efx_rc_t
  586 efx_lic_v1v2_write_key(
  587         __in                    efx_nic_t *enp,
  588         __in_bcount(buffer_size)
  589                                 caddr_t bufferp,
  590         __in                    size_t buffer_size,
  591         __in                    uint32_t offset,
  592         __in_bcount(length)     caddr_t keyp,
  593         __in                    uint32_t length,
  594         __out                   uint32_t *lengthp)
  595 {
  596         efx_rc_t rc;
  597 
  598         _NOTE(ARGUNUSED(enp))
  599         EFSYS_ASSERT(length <= (EFX_LICENSE_V1V2_PAYLOAD_LENGTH_MAX +
  600             EFX_LICENSE_V1V2_HEADER_LENGTH));
  601 
  602         /* Ensure space for terminator remains */
  603         if ((offset + length) >
  604             (buffer_size - EFX_LICENSE_V1V2_HEADER_LENGTH)) {
  605                 rc = ENOSPC;
  606                 goto fail1;
  607         }
  608 
  609         memcpy(bufferp + offset, keyp, length);
  610 
  611         *lengthp = length;
  612 
  613         return (0);
  614 
  615 fail1:
  616         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  617 
  618         return (rc);
  619 }
  620 
  621         __checkReturn           efx_rc_t
  622 efx_lic_v1v2_delete_key(
  623         __in                    efx_nic_t *enp,
  624         __in_bcount(buffer_size)
  625                                 caddr_t bufferp,
  626         __in                    size_t buffer_size,
  627         __in                    uint32_t offset,
  628         __in                    uint32_t length,
  629         __in                    uint32_t end,
  630         __out                   uint32_t *deltap)
  631 {
  632         uint32_t move_start = offset + length;
  633         uint32_t move_length = end - move_start;
  634 
  635         _NOTE(ARGUNUSED(enp, buffer_size))
  636         EFSYS_ASSERT(end <= buffer_size);
  637 
  638         /* Shift everything after the key down */
  639         memmove(bufferp + offset, bufferp + move_start, move_length);
  640 
  641         *deltap = length;
  642 
  643         return (0);
  644 }
  645 
  646         __checkReturn           efx_rc_t
  647 efx_lic_v1v2_create_partition(
  648         __in                    efx_nic_t *enp,
  649         __in_bcount(buffer_size)
  650                                 caddr_t bufferp,
  651         __in                    size_t buffer_size)
  652 {
  653         _NOTE(ARGUNUSED(enp, buffer_size))
  654         EFSYS_ASSERT(EFX_LICENSE_V1V2_HEADER_LENGTH <= buffer_size);
  655 
  656         /* Write terminator */
  657         memset(bufferp, '\0', EFX_LICENSE_V1V2_HEADER_LENGTH);
  658         return (0);
  659 }
  660 
  661         __checkReturn           efx_rc_t
  662 efx_lic_v1v2_finish_partition(
  663         __in                    efx_nic_t *enp,
  664         __in_bcount(buffer_size)
  665                                 caddr_t bufferp,
  666         __in                    size_t buffer_size)
  667 {
  668         _NOTE(ARGUNUSED(enp, bufferp, buffer_size))
  669 
  670         return (0);
  671 }
  672 
  673 #endif  /* EFSYS_OPT_HUNTINGTON | EFSYS_OPT_SIENA */
  674 
  675 /* V2 Licensing - used by Huntington family only. See SF-113611-TC */
  676 
  677 #if EFSYS_OPT_HUNTINGTON
  678 
  679 static  __checkReturn   efx_rc_t
  680 efx_mcdi_licensed_app_state(
  681         __in            efx_nic_t *enp,
  682         __in            uint64_t app_id,
  683         __out           boolean_t *licensedp)
  684 {
  685         efx_mcdi_req_t req;
  686         EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LICENSED_APP_STATE_IN_LEN,
  687                 MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN);
  688         uint32_t app_state;
  689         efx_rc_t rc;
  690 
  691         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
  692 
  693         /* V2 licensing supports 32bit app id only */
  694         if ((app_id >> 32) != 0) {
  695                 rc = EINVAL;
  696                 goto fail1;
  697         }
  698 
  699         req.emr_cmd = MC_CMD_GET_LICENSED_APP_STATE;
  700         req.emr_in_buf = payload;
  701         req.emr_in_length = MC_CMD_GET_LICENSED_APP_STATE_IN_LEN;
  702         req.emr_out_buf = payload;
  703         req.emr_out_length = MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN;
  704 
  705         MCDI_IN_SET_DWORD(req, GET_LICENSED_APP_STATE_IN_APP_ID,
  706                     app_id & 0xffffffff);
  707 
  708         efx_mcdi_execute(enp, &req);
  709 
  710         if (req.emr_rc != 0) {
  711                 rc = req.emr_rc;
  712                 goto fail2;
  713         }
  714 
  715         if (req.emr_out_length_used < MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN) {
  716                 rc = EMSGSIZE;
  717                 goto fail3;
  718         }
  719 
  720         app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_APP_STATE_OUT_STATE));
  721         if (app_state != MC_CMD_GET_LICENSED_APP_STATE_OUT_NOT_LICENSED) {
  722                 *licensedp = B_TRUE;
  723         } else {
  724                 *licensedp = B_FALSE;
  725         }
  726 
  727         return (0);
  728 
  729 fail3:
  730         EFSYS_PROBE(fail3);
  731 fail2:
  732         EFSYS_PROBE(fail2);
  733 fail1:
  734         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  735 
  736         return (rc);
  737 }
  738 
  739 static  __checkReturn   efx_rc_t
  740 efx_mcdi_licensing_update_licenses(
  741         __in            efx_nic_t *enp)
  742 {
  743         efx_mcdi_req_t req;
  744         EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_IN_LEN, 0);
  745         efx_rc_t rc;
  746 
  747         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
  748 
  749         req.emr_cmd = MC_CMD_LICENSING;
  750         req.emr_in_buf = payload;
  751         req.emr_in_length = MC_CMD_LICENSING_IN_LEN;
  752         req.emr_out_buf = payload;
  753         req.emr_out_length = 0;
  754 
  755         MCDI_IN_SET_DWORD(req, LICENSING_IN_OP,
  756             MC_CMD_LICENSING_IN_OP_UPDATE_LICENSE);
  757 
  758         efx_mcdi_execute(enp, &req);
  759 
  760         if (req.emr_rc != 0) {
  761                 rc = req.emr_rc;
  762                 goto fail1;
  763         }
  764 
  765         if (req.emr_out_length_used != 0) {
  766                 rc = EIO;
  767                 goto fail2;
  768         }
  769 
  770         return (0);
  771 
  772 fail2:
  773         EFSYS_PROBE(fail2);
  774 fail1:
  775         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  776 
  777         return (rc);
  778 }
  779 
  780 static  __checkReturn   efx_rc_t
  781 efx_mcdi_licensing_get_key_stats(
  782         __in            efx_nic_t *enp,
  783         __out           efx_key_stats_t *eksp)
  784 {
  785         efx_mcdi_req_t req;
  786         EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_IN_LEN,
  787                 MC_CMD_LICENSING_OUT_LEN);
  788         efx_rc_t rc;
  789 
  790         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
  791 
  792         req.emr_cmd = MC_CMD_LICENSING;
  793         req.emr_in_buf = payload;
  794         req.emr_in_length = MC_CMD_LICENSING_IN_LEN;
  795         req.emr_out_buf = payload;
  796         req.emr_out_length = MC_CMD_LICENSING_OUT_LEN;
  797 
  798         MCDI_IN_SET_DWORD(req, LICENSING_IN_OP,
  799             MC_CMD_LICENSING_IN_OP_GET_KEY_STATS);
  800 
  801         efx_mcdi_execute(enp, &req);
  802 
  803         if (req.emr_rc != 0) {
  804                 rc = req.emr_rc;
  805                 goto fail1;
  806         }
  807 
  808         if (req.emr_out_length_used < MC_CMD_LICENSING_OUT_LEN) {
  809                 rc = EMSGSIZE;
  810                 goto fail2;
  811         }
  812 
  813         eksp->eks_valid =
  814                 MCDI_OUT_DWORD(req, LICENSING_OUT_VALID_APP_KEYS);
  815         eksp->eks_invalid =
  816                 MCDI_OUT_DWORD(req, LICENSING_OUT_INVALID_APP_KEYS);
  817         eksp->eks_blacklisted =
  818                 MCDI_OUT_DWORD(req, LICENSING_OUT_BLACKLISTED_APP_KEYS);
  819         eksp->eks_unverifiable =
  820                 MCDI_OUT_DWORD(req, LICENSING_OUT_UNVERIFIABLE_APP_KEYS);
  821         eksp->eks_wrong_node =
  822                 MCDI_OUT_DWORD(req, LICENSING_OUT_WRONG_NODE_APP_KEYS);
  823         eksp->eks_licensed_apps_lo = 0;
  824         eksp->eks_licensed_apps_hi = 0;
  825         eksp->eks_licensed_features_lo = 0;
  826         eksp->eks_licensed_features_hi = 0;
  827 
  828         return (0);
  829 
  830 fail2:
  831         EFSYS_PROBE(fail2);
  832 fail1:
  833         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  834 
  835         return (rc);
  836 }
  837 
  838 #endif  /* EFSYS_OPT_HUNTINGTON */
  839 
  840 /* V3 Licensing - used starting from Medford family. See SF-114884-SW */
  841 
  842 #if EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
  843 
  844 static  __checkReturn   efx_rc_t
  845 efx_mcdi_licensing_v3_update_licenses(
  846         __in            efx_nic_t *enp)
  847 {
  848         efx_mcdi_req_t req;
  849         EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_V3_IN_LEN, 0);
  850         efx_rc_t rc;
  851 
  852         EFSYS_ASSERT((enp->en_family == EFX_FAMILY_MEDFORD) ||
  853             (enp->en_family == EFX_FAMILY_MEDFORD2));
  854 
  855         req.emr_cmd = MC_CMD_LICENSING_V3;
  856         req.emr_in_buf = payload;
  857         req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN;
  858         req.emr_out_buf = NULL;
  859         req.emr_out_length = 0;
  860 
  861         MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP,
  862             MC_CMD_LICENSING_V3_IN_OP_UPDATE_LICENSE);
  863 
  864         efx_mcdi_execute(enp, &req);
  865 
  866         if (req.emr_rc != 0) {
  867                 rc = req.emr_rc;
  868                 goto fail1;
  869         }
  870 
  871         return (0);
  872 
  873 fail1:
  874         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  875 
  876         return (rc);
  877 }
  878 
  879 static  __checkReturn   efx_rc_t
  880 efx_mcdi_licensing_v3_report_license(
  881         __in            efx_nic_t *enp,
  882         __out           efx_key_stats_t *eksp)
  883 {
  884         efx_mcdi_req_t req;
  885         EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_V3_IN_LEN,
  886                 MC_CMD_LICENSING_V3_OUT_LEN);
  887         efx_rc_t rc;
  888 
  889         EFSYS_ASSERT((enp->en_family == EFX_FAMILY_MEDFORD) ||
  890             (enp->en_family == EFX_FAMILY_MEDFORD2));
  891 
  892         req.emr_cmd = MC_CMD_LICENSING_V3;
  893         req.emr_in_buf = payload;
  894         req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN;
  895         req.emr_out_buf = payload;
  896         req.emr_out_length = MC_CMD_LICENSING_V3_OUT_LEN;
  897 
  898         MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP,
  899             MC_CMD_LICENSING_V3_IN_OP_REPORT_LICENSE);
  900 
  901         efx_mcdi_execute_quiet(enp, &req);
  902 
  903         if (req.emr_rc != 0) {
  904                 rc = req.emr_rc;
  905                 goto fail1;
  906         }
  907 
  908         if (req.emr_out_length_used < MC_CMD_LICENSING_V3_OUT_LEN) {
  909                 rc = EMSGSIZE;
  910                 goto fail2;
  911         }
  912 
  913         eksp->eks_valid =
  914                 MCDI_OUT_DWORD(req, LICENSING_V3_OUT_VALID_KEYS);
  915         eksp->eks_invalid =
  916                 MCDI_OUT_DWORD(req, LICENSING_V3_OUT_INVALID_KEYS);
  917         eksp->eks_blacklisted = 0;
  918         eksp->eks_unverifiable =
  919                 MCDI_OUT_DWORD(req, LICENSING_V3_OUT_UNVERIFIABLE_KEYS);
  920         eksp->eks_wrong_node =
  921                 MCDI_OUT_DWORD(req, LICENSING_V3_OUT_WRONG_NODE_KEYS);
  922         eksp->eks_licensed_apps_lo =
  923                 MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_LO);
  924         eksp->eks_licensed_apps_hi =
  925                 MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_HI);
  926         eksp->eks_licensed_features_lo =
  927                 MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_LO);
  928         eksp->eks_licensed_features_hi =
  929                 MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_HI);
  930 
  931         return (0);
  932 
  933 fail2:
  934         EFSYS_PROBE(fail2);
  935 fail1:
  936         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  937 
  938         return (rc);
  939 }
  940 
  941 static  __checkReturn   efx_rc_t
  942 efx_mcdi_licensing_v3_app_state(
  943         __in            efx_nic_t *enp,
  944         __in            uint64_t app_id,
  945         __out           boolean_t *licensedp)
  946 {
  947         efx_mcdi_req_t req;
  948         EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN,
  949                 MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN);
  950         uint32_t app_state;
  951         efx_rc_t rc;
  952 
  953         EFSYS_ASSERT((enp->en_family == EFX_FAMILY_MEDFORD) ||
  954             (enp->en_family == EFX_FAMILY_MEDFORD2));
  955 
  956         req.emr_cmd = MC_CMD_GET_LICENSED_V3_APP_STATE;
  957         req.emr_in_buf = payload;
  958         req.emr_in_length = MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN;
  959         req.emr_out_buf = payload;
  960         req.emr_out_length = MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN;
  961 
  962         MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_LO,
  963                     app_id & 0xffffffff);
  964         MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_HI,
  965                     app_id >> 32);
  966 
  967         efx_mcdi_execute(enp, &req);
  968 
  969         if (req.emr_rc != 0) {
  970                 rc = req.emr_rc;
  971                 goto fail1;
  972         }
  973 
  974         if (req.emr_out_length_used <
  975             MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN) {
  976                 rc = EMSGSIZE;
  977                 goto fail2;
  978         }
  979 
  980         app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_V3_APP_STATE_OUT_STATE));
  981         if (app_state != MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_NOT_LICENSED) {
  982                 *licensedp = B_TRUE;
  983         } else {
  984                 *licensedp = B_FALSE;
  985         }
  986 
  987         return (0);
  988 
  989 fail2:
  990         EFSYS_PROBE(fail2);
  991 fail1:
  992         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  993 
  994         return (rc);
  995 }
  996 
  997 static  __checkReturn   efx_rc_t
  998 efx_mcdi_licensing_v3_get_id(
  999         __in            efx_nic_t *enp,
 1000         __in            size_t buffer_size,
 1001         __out           uint32_t *typep,
 1002         __out           size_t *lengthp,
 1003         __out_bcount_part_opt(buffer_size, *lengthp)
 1004                         uint8_t *bufferp)
 1005 {
 1006         efx_mcdi_req_t req;
 1007         EFX_MCDI_DECLARE_BUF(payload, MC_CMD_LICENSING_GET_ID_V3_IN_LEN,
 1008                 MC_CMD_LICENSING_GET_ID_V3_OUT_LENMAX);
 1009         efx_rc_t rc;
 1010 
 1011         req.emr_cmd = MC_CMD_LICENSING_GET_ID_V3;
 1012         req.emr_in_buf = payload;
 1013         req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN;
 1014         req.emr_out_buf = payload;
 1015         req.emr_out_length = MC_CMD_LICENSING_GET_ID_V3_OUT_LENMAX;
 1016 
 1017         efx_mcdi_execute_quiet(enp, &req);
 1018 
 1019         if (req.emr_rc != 0) {
 1020                 rc = req.emr_rc;
 1021                 goto fail1;
 1022         }
 1023 
 1024         if (req.emr_out_length_used < MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN) {
 1025                 rc = EMSGSIZE;
 1026                 goto fail2;
 1027         }
 1028 
 1029         *typep = MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_TYPE);
 1030         *lengthp =
 1031             MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_ID_LENGTH);
 1032 
 1033         if (bufferp != NULL) {
 1034                 memcpy(bufferp,
 1035                     payload + MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST,
 1036                     MIN(buffer_size, *lengthp));
 1037         }
 1038 
 1039         return (0);
 1040 
 1041 fail2:
 1042         EFSYS_PROBE(fail2);
 1043 fail1:
 1044         EFSYS_PROBE1(fail1, efx_rc_t, rc);
 1045 
 1046         return (rc);
 1047 }
 1048 
 1049 /* V3 format uses Huntington TLV format partition. See SF-108797-SW */
 1050 #define EFX_LICENSE_V3_KEY_LENGTH_MIN   (64)
 1051 #define EFX_LICENSE_V3_KEY_LENGTH_MAX   (160)
 1052 
 1053         __checkReturn           efx_rc_t
 1054 efx_lic_v3_find_start(
 1055         __in                    efx_nic_t *enp,
 1056         __in_bcount(buffer_size)
 1057                                 caddr_t bufferp,
 1058         __in                    size_t buffer_size,
 1059         __out                   uint32_t *startp)
 1060 {
 1061         _NOTE(ARGUNUSED(enp))
 1062 
 1063         return (ef10_nvram_buffer_find_item_start(bufferp, buffer_size,
 1064             startp));
 1065 }
 1066 
 1067         __checkReturn           efx_rc_t
 1068 efx_lic_v3_find_end(
 1069         __in                    efx_nic_t *enp,
 1070         __in_bcount(buffer_size)
 1071                                 caddr_t bufferp,
 1072         __in                    size_t buffer_size,
 1073         __in                    uint32_t offset,
 1074         __out                   uint32_t *endp)
 1075 {
 1076         _NOTE(ARGUNUSED(enp))
 1077 
 1078         return (ef10_nvram_buffer_find_end(bufferp, buffer_size, offset, endp));
 1079 }
 1080 
 1081         __checkReturn   __success(return != B_FALSE)    boolean_t
 1082 efx_lic_v3_find_key(
 1083         __in                    efx_nic_t *enp,
 1084         __in_bcount(buffer_size)
 1085                                 caddr_t bufferp,
 1086         __in                    size_t buffer_size,
 1087         __in                    uint32_t offset,
 1088         __out                   uint32_t *startp,
 1089         __out                   uint32_t *lengthp)
 1090 {
 1091         _NOTE(ARGUNUSED(enp))
 1092 
 1093         return ef10_nvram_buffer_find_item(bufferp, buffer_size,
 1094             offset, startp, lengthp);
 1095 }
 1096 
 1097         __checkReturn   __success(return != B_FALSE)    boolean_t
 1098 efx_lic_v3_validate_key(
 1099         __in                    efx_nic_t *enp,
 1100         __in_bcount(length)     caddr_t keyp,
 1101         __in                    uint32_t length)
 1102 {
 1103         /* Check key is a valid V3 key */
 1104         uint8_t key_type;
 1105         uint8_t key_length;
 1106 
 1107         _NOTE(ARGUNUSED(enp))
 1108 
 1109         if (length < EFX_LICENSE_V3_KEY_LENGTH_MIN) {
 1110                 goto fail1;
 1111         }
 1112 
 1113         if (length > EFX_LICENSE_V3_KEY_LENGTH_MAX) {
 1114                 goto fail2;
 1115         }
 1116 
 1117         key_type = ((uint8_t *)keyp)[0];
 1118         key_length = ((uint8_t *)keyp)[1];
 1119 
 1120         if (key_type < 3) {
 1121                 goto fail3;
 1122         }
 1123         if (key_length > length) {
 1124                 goto fail4;
 1125         }
 1126         return (B_TRUE);
 1127 
 1128 fail4:
 1129         EFSYS_PROBE(fail4);
 1130 fail3:
 1131         EFSYS_PROBE(fail3);
 1132 fail2:
 1133         EFSYS_PROBE(fail2);
 1134 fail1:
 1135         EFSYS_PROBE1(fail1, boolean_t, B_FALSE);
 1136 
 1137         return (B_FALSE);
 1138 }
 1139 
 1140         __checkReturn           efx_rc_t
 1141 efx_lic_v3_read_key(
 1142         __in                    efx_nic_t *enp,
 1143         __in_bcount(buffer_size)
 1144                                 caddr_t bufferp,
 1145         __in                    size_t buffer_size,
 1146         __in                    uint32_t offset,
 1147         __in                    uint32_t length,
 1148         __out_bcount_part(key_max_size, *lengthp)
 1149                                 caddr_t keyp,
 1150         __in                    size_t key_max_size,
 1151         __out                   uint32_t *lengthp)
 1152 {
 1153         uint32_t tag;
 1154 
 1155         _NOTE(ARGUNUSED(enp))
 1156 
 1157         return ef10_nvram_buffer_get_item(bufferp, buffer_size,
 1158                     offset, length, &tag, keyp, key_max_size, lengthp);
 1159 }
 1160 
 1161         __checkReturn           efx_rc_t
 1162 efx_lic_v3_write_key(
 1163         __in                    efx_nic_t *enp,
 1164         __in_bcount(buffer_size)
 1165                                 caddr_t bufferp,
 1166         __in                    size_t buffer_size,
 1167         __in                    uint32_t offset,
 1168         __in_bcount(length)     caddr_t keyp,
 1169         __in                    uint32_t length,
 1170         __out                   uint32_t *lengthp)
 1171 {
 1172         _NOTE(ARGUNUSED(enp))
 1173         EFSYS_ASSERT(length <= EFX_LICENSE_V3_KEY_LENGTH_MAX);
 1174 
 1175         return ef10_nvram_buffer_insert_item(bufferp, buffer_size,
 1176                     offset, TLV_TAG_LICENSE, keyp, length, lengthp);
 1177 }
 1178 
 1179         __checkReturn           efx_rc_t
 1180 efx_lic_v3_delete_key(
 1181         __in                    efx_nic_t *enp,
 1182         __in_bcount(buffer_size)
 1183                                 caddr_t bufferp,
 1184         __in                    size_t buffer_size,
 1185         __in                    uint32_t offset,
 1186         __in                    uint32_t length,
 1187         __in                    uint32_t end,
 1188         __out                   uint32_t *deltap)
 1189 {
 1190         efx_rc_t rc;
 1191 
 1192         _NOTE(ARGUNUSED(enp))
 1193 
 1194         if ((rc = ef10_nvram_buffer_delete_item(bufferp,
 1195                         buffer_size, offset, length, end)) != 0) {
 1196                 goto fail1;
 1197         }
 1198 
 1199         *deltap = length;
 1200 
 1201         return (0);
 1202 
 1203 fail1:
 1204         EFSYS_PROBE1(fail1, efx_rc_t, rc);
 1205 
 1206         return (rc);
 1207 }
 1208 
 1209         __checkReturn           efx_rc_t
 1210 efx_lic_v3_create_partition(
 1211         __in                    efx_nic_t *enp,
 1212         __in_bcount(buffer_size)
 1213                                 caddr_t bufferp,
 1214         __in                    size_t buffer_size)
 1215 {
 1216         efx_rc_t rc;
 1217 
 1218         _NOTE(ARGUNUSED(enp))
 1219 
 1220         /* Construct empty partition */
 1221         if ((rc = ef10_nvram_buffer_create(
 1222             NVRAM_PARTITION_TYPE_LICENSE,
 1223             bufferp, buffer_size)) != 0) {
 1224                 rc = EFAULT;
 1225                 goto fail1;
 1226         }
 1227 
 1228         return (0);
 1229 
 1230 fail1:
 1231         EFSYS_PROBE1(fail1, efx_rc_t, rc);
 1232 
 1233         return (rc);
 1234 }
 1235 
 1236         __checkReturn           efx_rc_t
 1237 efx_lic_v3_finish_partition(
 1238         __in                    efx_nic_t *enp,
 1239         __in_bcount(buffer_size)
 1240                                 caddr_t bufferp,
 1241         __in                    size_t buffer_size)
 1242 {
 1243         efx_rc_t rc;
 1244 
 1245         _NOTE(ARGUNUSED(enp))
 1246 
 1247         if ((rc = ef10_nvram_buffer_finish(bufferp,
 1248                         buffer_size)) != 0) {
 1249                 goto fail1;
 1250         }
 1251 
 1252         /* Validate completed partition */
 1253         if ((rc = ef10_nvram_buffer_validate(
 1254                                         NVRAM_PARTITION_TYPE_LICENSE,
 1255                                         bufferp, buffer_size)) != 0) {
 1256                 goto fail2;
 1257         }
 1258 
 1259         return (0);
 1260 
 1261 fail2:
 1262         EFSYS_PROBE(fail2);
 1263 fail1:
 1264         EFSYS_PROBE1(fail1, efx_rc_t, rc);
 1265 
 1266         return (rc);
 1267 }
 1268 
 1269 #endif  /* EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
 1270 
 1271         __checkReturn           efx_rc_t
 1272 efx_lic_init(
 1273         __in                    efx_nic_t *enp)
 1274 {
 1275         const efx_lic_ops_t *elop;
 1276         efx_key_stats_t eks;
 1277         efx_rc_t rc;
 1278 
 1279         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 1280         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
 1281         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_LIC));
 1282 
 1283         switch (enp->en_family) {
 1284 #if EFSYS_OPT_SIENA
 1285         case EFX_FAMILY_SIENA:
 1286                 elop = &__efx_lic_v1_ops;
 1287                 break;
 1288 #endif  /* EFSYS_OPT_SIENA */
 1289 
 1290 #if EFSYS_OPT_HUNTINGTON
 1291         case EFX_FAMILY_HUNTINGTON:
 1292                 elop = &__efx_lic_v2_ops;
 1293                 break;
 1294 #endif  /* EFSYS_OPT_HUNTINGTON */
 1295 
 1296 #if EFSYS_OPT_MEDFORD
 1297         case EFX_FAMILY_MEDFORD:
 1298                 elop = &__efx_lic_v3_ops;
 1299                 break;
 1300 #endif  /* EFSYS_OPT_MEDFORD */
 1301 
 1302 #if EFSYS_OPT_MEDFORD2
 1303         case EFX_FAMILY_MEDFORD2:
 1304                 elop = &__efx_lic_v3_ops;
 1305                 break;
 1306 #endif  /* EFSYS_OPT_MEDFORD2 */
 1307 
 1308         default:
 1309                 EFSYS_ASSERT(0);
 1310                 rc = ENOTSUP;
 1311                 goto fail1;
 1312         }
 1313 
 1314         enp->en_elop = elop;
 1315         enp->en_mod_flags |= EFX_MOD_LIC;
 1316 
 1317         /* Probe for support */
 1318         if (efx_lic_get_key_stats(enp, &eks) == 0) {
 1319                 enp->en_licensing_supported = B_TRUE;
 1320         } else {
 1321                 enp->en_licensing_supported = B_FALSE;
 1322         }
 1323 
 1324         return (0);
 1325 
 1326 fail1:
 1327         EFSYS_PROBE1(fail1, efx_rc_t, rc);
 1328 
 1329         return (rc);
 1330 }
 1331 
 1332 extern  __checkReturn   boolean_t
 1333 efx_lic_check_support(
 1334         __in                    efx_nic_t *enp)
 1335 {
 1336         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 1337         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
 1338         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
 1339 
 1340         return (enp->en_licensing_supported);
 1341 }
 1342 
 1343                                 void
 1344 efx_lic_fini(
 1345         __in                    efx_nic_t *enp)
 1346 {
 1347         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 1348         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
 1349         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
 1350 
 1351         enp->en_elop = NULL;
 1352         enp->en_mod_flags &= ~EFX_MOD_LIC;
 1353 }
 1354 
 1355         __checkReturn   efx_rc_t
 1356 efx_lic_update_licenses(
 1357         __in            efx_nic_t *enp)
 1358 {
 1359         const efx_lic_ops_t *elop = enp->en_elop;
 1360         efx_rc_t rc;
 1361 
 1362         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 1363         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
 1364 
 1365         if ((rc = elop->elo_update_licenses(enp)) != 0)
 1366                 goto fail1;
 1367 
 1368         return (0);
 1369 
 1370 fail1:
 1371         EFSYS_PROBE1(fail1, efx_rc_t, rc);
 1372 
 1373         return (rc);
 1374 }
 1375 
 1376         __checkReturn   efx_rc_t
 1377 efx_lic_get_key_stats(
 1378         __in            efx_nic_t *enp,
 1379         __out           efx_key_stats_t *eksp)
 1380 {
 1381         const efx_lic_ops_t *elop = enp->en_elop;
 1382         efx_rc_t rc;
 1383 
 1384         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 1385         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
 1386 
 1387         if ((rc = elop->elo_get_key_stats(enp, eksp)) != 0)
 1388                 goto fail1;
 1389 
 1390         return (0);
 1391 
 1392 fail1:
 1393         EFSYS_PROBE1(fail1, efx_rc_t, rc);
 1394 
 1395         return (rc);
 1396 }
 1397 
 1398         __checkReturn   efx_rc_t
 1399 efx_lic_app_state(
 1400         __in            efx_nic_t *enp,
 1401         __in            uint64_t app_id,
 1402         __out           boolean_t *licensedp)
 1403 {
 1404         const efx_lic_ops_t *elop = enp->en_elop;
 1405         efx_rc_t rc;
 1406 
 1407         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 1408         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
 1409 
 1410         if (elop->elo_app_state == NULL)
 1411                 return (ENOTSUP);
 1412 
 1413         if ((rc = elop->elo_app_state(enp, app_id, licensedp)) != 0)
 1414                 goto fail1;
 1415 
 1416         return (0);
 1417 
 1418 fail1:
 1419         EFSYS_PROBE1(fail1, efx_rc_t, rc);
 1420 
 1421         return (rc);
 1422 }
 1423 
 1424         __checkReturn   efx_rc_t
 1425 efx_lic_get_id(
 1426         __in            efx_nic_t *enp,
 1427         __in            size_t buffer_size,
 1428         __out           uint32_t *typep,
 1429         __out           size_t *lengthp,
 1430         __out_opt       uint8_t *bufferp)
 1431 {
 1432         const efx_lic_ops_t *elop = enp->en_elop;
 1433         efx_rc_t rc;
 1434 
 1435         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 1436         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
 1437 
 1438         if (elop->elo_get_id == NULL)
 1439                 return (ENOTSUP);
 1440 
 1441         if ((rc = elop->elo_get_id(enp, buffer_size, typep,
 1442                                     lengthp, bufferp)) != 0)
 1443                 goto fail1;
 1444 
 1445         return (0);
 1446 
 1447 fail1:
 1448         EFSYS_PROBE1(fail1, efx_rc_t, rc);
 1449 
 1450         return (rc);
 1451 }
 1452 
 1453 /*
 1454  * Buffer management API - abstracts varying TLV format used for License
 1455  * partition.
 1456  */
 1457 
 1458         __checkReturn           efx_rc_t
 1459 efx_lic_find_start(
 1460         __in                    efx_nic_t *enp,
 1461         __in_bcount(buffer_size)
 1462                                 caddr_t bufferp,
 1463         __in                    size_t buffer_size,
 1464         __out                   uint32_t *startp)
 1465 {
 1466         const efx_lic_ops_t *elop = enp->en_elop;
 1467         efx_rc_t rc;
 1468 
 1469         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 1470         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
 1471 
 1472         if ((rc = elop->elo_find_start(enp, bufferp, buffer_size, startp)) != 0)
 1473                 goto fail1;
 1474 
 1475         return (0);
 1476 
 1477 fail1:
 1478         EFSYS_PROBE1(fail1, efx_rc_t, rc);
 1479 
 1480         return (rc);
 1481 }
 1482 
 1483         __checkReturn           efx_rc_t
 1484 efx_lic_find_end(
 1485         __in                    efx_nic_t *enp,
 1486         __in_bcount(buffer_size)
 1487                                 caddr_t bufferp,
 1488         __in                    size_t buffer_size,
 1489         __in                    uint32_t offset,
 1490         __out                   uint32_t *endp)
 1491 {
 1492         const efx_lic_ops_t *elop = enp->en_elop;
 1493         efx_rc_t rc;
 1494 
 1495         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 1496         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
 1497 
 1498         rc = elop->elo_find_end(enp, bufferp, buffer_size, offset, endp);
 1499         if (rc != 0)
 1500                 goto fail1;
 1501 
 1502         return (0);
 1503 
 1504 fail1:
 1505         EFSYS_PROBE1(fail1, efx_rc_t, rc);
 1506 
 1507         return (rc);
 1508 }
 1509 
 1510         __checkReturn   __success(return != B_FALSE)    boolean_t
 1511 efx_lic_find_key(
 1512         __in                    efx_nic_t *enp,
 1513         __in_bcount(buffer_size)
 1514                                 caddr_t bufferp,
 1515         __in                    size_t buffer_size,
 1516         __in                    uint32_t offset,
 1517         __out                   uint32_t *startp,
 1518         __out                   uint32_t *lengthp)
 1519 {
 1520         const efx_lic_ops_t *elop = enp->en_elop;
 1521 
 1522         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 1523         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
 1524 
 1525         EFSYS_ASSERT(bufferp);
 1526         EFSYS_ASSERT(startp);
 1527         EFSYS_ASSERT(lengthp);
 1528 
 1529         return (elop->elo_find_key(enp, bufferp, buffer_size, offset,
 1530                                     startp, lengthp));
 1531 }
 1532 
 1533 /*
 1534  * Validate that the buffer contains a single key in a recognised format.
 1535  * An empty or terminator buffer is not accepted as a valid key.
 1536  */
 1537         __checkReturn   __success(return != B_FALSE)    boolean_t
 1538 efx_lic_validate_key(
 1539         __in                    efx_nic_t *enp,
 1540         __in_bcount(length)     caddr_t keyp,
 1541         __in                    uint32_t length)
 1542 {
 1543         const efx_lic_ops_t *elop = enp->en_elop;
 1544         boolean_t rc;
 1545 
 1546         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 1547         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
 1548 
 1549         if ((rc = elop->elo_validate_key(enp, keyp, length)) == B_FALSE)
 1550                 goto fail1;
 1551 
 1552         return (B_TRUE);
 1553 
 1554 fail1:
 1555         EFSYS_PROBE1(fail1, efx_rc_t, rc);
 1556 
 1557         return (rc);
 1558 }
 1559 
 1560         __checkReturn           efx_rc_t
 1561 efx_lic_read_key(
 1562         __in                    efx_nic_t *enp,
 1563         __in_bcount(buffer_size)
 1564                                 caddr_t bufferp,
 1565         __in                    size_t buffer_size,
 1566         __in                    uint32_t offset,
 1567         __in                    uint32_t length,
 1568         __out_bcount_part(key_max_size, *lengthp)
 1569                                 caddr_t keyp,
 1570         __in                    size_t key_max_size,
 1571         __out                   uint32_t *lengthp)
 1572 {
 1573         const efx_lic_ops_t *elop = enp->en_elop;
 1574         efx_rc_t rc;
 1575 
 1576         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 1577         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
 1578 
 1579         if ((rc = elop->elo_read_key(enp, bufferp, buffer_size, offset,
 1580                                     length, keyp, key_max_size, lengthp)) != 0)
 1581                 goto fail1;
 1582 
 1583         return (0);
 1584 
 1585 fail1:
 1586         EFSYS_PROBE1(fail1, efx_rc_t, rc);
 1587 
 1588         return (rc);
 1589 }
 1590 
 1591         __checkReturn           efx_rc_t
 1592 efx_lic_write_key(
 1593         __in                    efx_nic_t *enp,
 1594         __in_bcount(buffer_size)
 1595                                 caddr_t bufferp,
 1596         __in                    size_t buffer_size,
 1597         __in                    uint32_t offset,
 1598         __in_bcount(length)     caddr_t keyp,
 1599         __in                    uint32_t length,
 1600         __out                   uint32_t *lengthp)
 1601 {
 1602         const efx_lic_ops_t *elop = enp->en_elop;
 1603         efx_rc_t rc;
 1604 
 1605         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 1606         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
 1607 
 1608         if ((rc = elop->elo_write_key(enp, bufferp, buffer_size, offset,
 1609                                     keyp, length, lengthp)) != 0)
 1610                 goto fail1;
 1611 
 1612         return (0);
 1613 
 1614 fail1:
 1615         EFSYS_PROBE1(fail1, efx_rc_t, rc);
 1616 
 1617         return (rc);
 1618 }
 1619 
 1620         __checkReturn           efx_rc_t
 1621 efx_lic_delete_key(
 1622         __in                    efx_nic_t *enp,
 1623         __in_bcount(buffer_size)
 1624                                 caddr_t bufferp,
 1625         __in                    size_t buffer_size,
 1626         __in                    uint32_t offset,
 1627         __in                    uint32_t length,
 1628         __in                    uint32_t end,
 1629         __out                   uint32_t *deltap)
 1630 {
 1631         const efx_lic_ops_t *elop = enp->en_elop;
 1632         efx_rc_t rc;
 1633 
 1634         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 1635         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
 1636 
 1637         if ((rc = elop->elo_delete_key(enp, bufferp, buffer_size, offset,
 1638                                     length, end, deltap)) != 0)
 1639                 goto fail1;
 1640 
 1641         return (0);
 1642 
 1643 fail1:
 1644         EFSYS_PROBE1(fail1, efx_rc_t, rc);
 1645 
 1646         return (rc);
 1647 }
 1648 
 1649         __checkReturn           efx_rc_t
 1650 efx_lic_create_partition(
 1651         __in                    efx_nic_t *enp,
 1652         __in_bcount(buffer_size)
 1653                                 caddr_t bufferp,
 1654         __in                    size_t buffer_size)
 1655 {
 1656         const efx_lic_ops_t *elop = enp->en_elop;
 1657         efx_rc_t rc;
 1658 
 1659         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 1660         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
 1661 
 1662         if ((rc = elop->elo_create_partition(enp, bufferp, buffer_size)) != 0)
 1663                 goto fail1;
 1664 
 1665         return (0);
 1666 
 1667 fail1:
 1668         EFSYS_PROBE1(fail1, efx_rc_t, rc);
 1669 
 1670         return (rc);
 1671 }
 1672 
 1673         __checkReturn           efx_rc_t
 1674 efx_lic_finish_partition(
 1675         __in                    efx_nic_t *enp,
 1676         __in_bcount(buffer_size)
 1677                                 caddr_t bufferp,
 1678         __in                    size_t buffer_size)
 1679 {
 1680         const efx_lic_ops_t *elop = enp->en_elop;
 1681         efx_rc_t rc;
 1682 
 1683         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 1684         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
 1685 
 1686         if ((rc = elop->elo_finish_partition(enp, bufferp, buffer_size)) != 0)
 1687                 goto fail1;
 1688 
 1689         return (0);
 1690 
 1691 fail1:
 1692         EFSYS_PROBE1(fail1, efx_rc_t, rc);
 1693 
 1694         return (rc);
 1695 }
 1696 
 1697 #endif  /* EFSYS_OPT_LICENSING */

Cache object: fc69b3a79b96246f76219f46919180f0


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.