]> CyberLeo.Net >> Repos - FreeBSD/releng/10.3.git/blob - sys/dev/sfxge/common/efx_lic.c
- Copy stable/10@296371 to releng/10.3 in preparation for 10.3-RC1
[FreeBSD/releng/10.3.git] / sys / dev / sfxge / common / efx_lic.c
1 /*-
2  * Copyright (c) 2009-2015 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 #if EFSYS_OPT_SIENA
40
41 static  __checkReturn   efx_rc_t
42 efx_mcdi_fc_license_update_license(
43         __in            efx_nic_t *enp);
44
45 static  __checkReturn   efx_rc_t
46 efx_mcdi_fc_license_get_key_stats(
47         __in            efx_nic_t *enp,
48         __out           efx_key_stats_t *eksp);
49
50 static efx_lic_ops_t    __efx_lic_v1_ops = {
51         efx_mcdi_fc_license_update_license,     /* elo_update_licenses */
52         efx_mcdi_fc_license_get_key_stats,      /* elo_get_key_stats */
53         NULL,                                   /* elo_app_state */
54         NULL,                                   /* elo_get_id */
55 };
56
57 #endif  /* EFSYS_OPT_SIENA */
58
59 #if EFSYS_OPT_HUNTINGTON
60
61 static  __checkReturn   efx_rc_t
62 efx_mcdi_licensing_update_licenses(
63         __in            efx_nic_t *enp);
64
65 static  __checkReturn   efx_rc_t
66 efx_mcdi_licensing_get_key_stats(
67         __in            efx_nic_t *enp,
68         __out           efx_key_stats_t *eksp);
69
70 static  __checkReturn   efx_rc_t
71 efx_mcdi_licensed_app_state(
72         __in            efx_nic_t *enp,
73         __in            uint64_t app_id,
74         __out           boolean_t *licensedp);
75
76 static efx_lic_ops_t    __efx_lic_v2_ops = {
77         efx_mcdi_licensing_update_licenses,     /* elo_update_licenses */
78         efx_mcdi_licensing_get_key_stats,       /* elo_get_key_stats */
79         efx_mcdi_licensed_app_state,            /* elo_app_state */
80         NULL,                                   /* elo_get_id */
81 };
82
83 #endif  /* EFSYS_OPT_HUNTINGTON */
84
85 #if EFSYS_OPT_MEDFORD
86
87 static  __checkReturn   efx_rc_t
88 efx_mcdi_licensing_v3_update_licenses(
89         __in            efx_nic_t *enp);
90
91 static  __checkReturn   efx_rc_t
92 efx_mcdi_licensing_v3_report_license(
93         __in            efx_nic_t *enp,
94         __out           efx_key_stats_t *eksp);
95
96 static  __checkReturn   efx_rc_t
97 efx_mcdi_licensing_v3_app_state(
98         __in            efx_nic_t *enp,
99         __in            uint64_t app_id,
100         __out           boolean_t *licensedp);
101
102 static  __checkReturn   efx_rc_t
103 efx_mcdi_licensing_v3_get_id(
104         __in            efx_nic_t *enp,
105         __in            size_t buffer_size,
106         __out           uint32_t *typep,
107         __out           size_t *lengthp,
108         __out_bcount_part_opt(buffer_size, *lengthp)
109                         uint8_t *bufferp);
110
111 static efx_lic_ops_t    __efx_lic_v3_ops = {
112         efx_mcdi_licensing_v3_update_licenses,  /* elo_update_licenses */
113         efx_mcdi_licensing_v3_report_license,   /* elo_get_key_stats */
114         efx_mcdi_licensing_v3_app_state,        /* elo_app_state */
115         efx_mcdi_licensing_v3_get_id,           /* elo_get_id */
116 };
117
118 #endif  /* EFSYS_OPT_MEDFORD */
119
120
121 /* V1 Licensing - used in Siena Modena only */
122
123 #if EFSYS_OPT_SIENA
124
125 static  __checkReturn   efx_rc_t
126 efx_mcdi_fc_license_update_license(
127         __in            efx_nic_t *enp)
128 {
129         efx_mcdi_req_t req;
130         uint8_t payload[MC_CMD_FC_IN_LICENSE_LEN];
131         efx_rc_t rc;
132
133         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
134
135         (void) memset(payload, 0, sizeof (payload));
136         req.emr_cmd = MC_CMD_FC_OP_LICENSE;
137         req.emr_in_buf = payload;
138         req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN;
139         req.emr_out_buf = payload;
140         req.emr_out_length = 0;
141
142         MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP,
143             MC_CMD_FC_IN_LICENSE_UPDATE_LICENSE);
144
145         efx_mcdi_execute(enp, &req);
146
147         if (req.emr_rc != 0) {
148                 rc = req.emr_rc;
149                 goto fail1;
150         }
151
152         if (req.emr_out_length_used != 0) {
153                 rc = EIO;
154                 goto fail2;
155         }
156
157         return (0);
158
159 fail2:
160         EFSYS_PROBE(fail2);
161 fail1:
162         EFSYS_PROBE1(fail1, efx_rc_t, rc);
163
164         return (rc);
165 }
166
167 static  __checkReturn   efx_rc_t
168 efx_mcdi_fc_license_get_key_stats(
169         __in            efx_nic_t *enp,
170         __out           efx_key_stats_t *eksp)
171 {
172         efx_mcdi_req_t req;
173         uint8_t payload[MAX(MC_CMD_FC_IN_LICENSE_LEN,
174                             MC_CMD_FC_OUT_LICENSE_LEN)];
175         efx_rc_t rc;
176
177         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
178
179         (void) memset(payload, 0, sizeof (payload));
180         req.emr_cmd = MC_CMD_FC_OP_LICENSE;
181         req.emr_in_buf = payload;
182         req.emr_in_length = MC_CMD_FC_IN_LICENSE_LEN;
183         req.emr_out_buf = payload;
184         req.emr_out_length = MC_CMD_FC_OUT_LICENSE_LEN;
185
186         MCDI_IN_SET_DWORD(req, FC_IN_LICENSE_OP,
187             MC_CMD_FC_IN_LICENSE_GET_KEY_STATS);
188
189         efx_mcdi_execute(enp, &req);
190
191         if (req.emr_rc != 0) {
192                 rc = req.emr_rc;
193                 goto fail1;
194         }
195
196         if (req.emr_out_length_used < MC_CMD_FC_OUT_LICENSE_LEN) {
197                 rc = EMSGSIZE;
198                 goto fail2;
199         }
200
201         eksp->eks_valid =
202                 MCDI_OUT_DWORD(req, FC_OUT_LICENSE_VALID_KEYS);
203         eksp->eks_invalid =
204                 MCDI_OUT_DWORD(req, FC_OUT_LICENSE_INVALID_KEYS);
205         eksp->eks_blacklisted =
206                 MCDI_OUT_DWORD(req, FC_OUT_LICENSE_BLACKLISTED_KEYS);
207         eksp->eks_unverifiable = 0;
208         eksp->eks_wrong_node = 0;
209         eksp->eks_licensed_apps_lo = 0;
210         eksp->eks_licensed_apps_hi = 0;
211         eksp->eks_licensed_features_lo = 0;
212         eksp->eks_licensed_features_hi = 0;
213
214         return (0);
215
216 fail2:
217         EFSYS_PROBE(fail2);
218 fail1:
219         EFSYS_PROBE1(fail1, efx_rc_t, rc);
220
221         return (rc);
222 }
223
224 #endif  /* EFSYS_OPT_SIENA */
225
226 /* V2 Licensing - used by Huntington family only. See SF-113611-TC */
227
228 #if EFSYS_OPT_HUNTINGTON
229
230 static  __checkReturn   efx_rc_t
231 efx_mcdi_licensed_app_state(
232         __in            efx_nic_t *enp,
233         __in            uint64_t app_id,
234         __out           boolean_t *licensedp)
235 {
236         efx_mcdi_req_t req;
237         uint8_t payload[MAX(MC_CMD_GET_LICENSED_APP_STATE_IN_LEN,
238                             MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN)];
239         uint32_t app_state;
240         efx_rc_t rc;
241
242         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
243
244         /* V2 licensing supports 32bit app id only */
245         if ((app_id >> 32) != 0) {
246                 rc = EINVAL;
247                 goto fail1;
248         }
249
250         (void) memset(payload, 0, sizeof (payload));
251         req.emr_cmd = MC_CMD_GET_LICENSED_APP_STATE;
252         req.emr_in_buf = payload;
253         req.emr_in_length = MC_CMD_GET_LICENSED_APP_STATE_IN_LEN;
254         req.emr_out_buf = payload;
255         req.emr_out_length = MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN;
256
257         MCDI_IN_SET_DWORD(req, GET_LICENSED_APP_STATE_IN_APP_ID,
258                     app_id & 0xffffffff);
259
260         efx_mcdi_execute(enp, &req);
261
262         if (req.emr_rc != 0) {
263                 rc = req.emr_rc;
264                 goto fail2;
265         }
266
267         if (req.emr_out_length_used < MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN) {
268                 rc = EMSGSIZE;
269                 goto fail3;
270         }
271
272         app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_APP_STATE_OUT_STATE));
273         if (app_state != MC_CMD_GET_LICENSED_APP_STATE_OUT_NOT_LICENSED) {
274                 *licensedp = B_TRUE;
275         } else {
276                 *licensedp = B_FALSE;
277         }
278
279         return (0);
280
281 fail3:
282         EFSYS_PROBE(fail3);
283 fail2:
284         EFSYS_PROBE(fail2);
285 fail1:
286         EFSYS_PROBE1(fail1, efx_rc_t, rc);
287
288         return (rc);
289 }
290
291 static  __checkReturn   efx_rc_t
292 efx_mcdi_licensing_update_licenses(
293         __in            efx_nic_t *enp)
294 {
295         efx_mcdi_req_t req;
296         uint8_t payload[MC_CMD_LICENSING_IN_LEN];
297         efx_rc_t rc;
298
299         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
300
301         (void) memset(payload, 0, sizeof (payload));
302         req.emr_cmd = MC_CMD_LICENSING;
303         req.emr_in_buf = payload;
304         req.emr_in_length = MC_CMD_LICENSING_IN_LEN;
305         req.emr_out_buf = payload;
306         req.emr_out_length = 0;
307
308         MCDI_IN_SET_DWORD(req, LICENSING_IN_OP,
309             MC_CMD_LICENSING_IN_OP_UPDATE_LICENSE);
310
311         efx_mcdi_execute(enp, &req);
312
313         if (req.emr_rc != 0) {
314                 rc = req.emr_rc;
315                 goto fail1;
316         }
317
318         if (req.emr_out_length_used != 0) {
319                 rc = EIO;
320                 goto fail2;
321         }
322
323         return (0);
324
325 fail2:
326         EFSYS_PROBE(fail2);
327 fail1:
328         EFSYS_PROBE1(fail1, efx_rc_t, rc);
329
330         return (rc);
331 }
332
333 static  __checkReturn   efx_rc_t
334 efx_mcdi_licensing_get_key_stats(
335         __in            efx_nic_t *enp,
336         __out           efx_key_stats_t *eksp)
337 {
338         efx_mcdi_req_t req;
339         uint8_t payload[MAX(MC_CMD_LICENSING_IN_LEN,
340                             MC_CMD_LICENSING_OUT_LEN)];
341         efx_rc_t rc;
342
343         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
344
345         (void) memset(payload, 0, sizeof (payload));
346         req.emr_cmd = MC_CMD_LICENSING;
347         req.emr_in_buf = payload;
348         req.emr_in_length = MC_CMD_LICENSING_IN_LEN;
349         req.emr_out_buf = payload;
350         req.emr_out_length = MC_CMD_LICENSING_OUT_LEN;
351
352         MCDI_IN_SET_DWORD(req, LICENSING_IN_OP,
353             MC_CMD_LICENSING_IN_OP_GET_KEY_STATS);
354
355         efx_mcdi_execute(enp, &req);
356
357         if (req.emr_rc != 0) {
358                 rc = req.emr_rc;
359                 goto fail1;
360         }
361
362         if (req.emr_out_length_used < MC_CMD_LICENSING_OUT_LEN) {
363                 rc = EMSGSIZE;
364                 goto fail2;
365         }
366
367         eksp->eks_valid =
368                 MCDI_OUT_DWORD(req, LICENSING_OUT_VALID_APP_KEYS);
369         eksp->eks_invalid =
370                 MCDI_OUT_DWORD(req, LICENSING_OUT_INVALID_APP_KEYS);
371         eksp->eks_blacklisted =
372                 MCDI_OUT_DWORD(req, LICENSING_OUT_BLACKLISTED_APP_KEYS);
373         eksp->eks_unverifiable =
374                 MCDI_OUT_DWORD(req, LICENSING_OUT_UNVERIFIABLE_APP_KEYS);
375         eksp->eks_wrong_node =
376                 MCDI_OUT_DWORD(req, LICENSING_OUT_WRONG_NODE_APP_KEYS);
377         eksp->eks_licensed_apps_lo = 0;
378         eksp->eks_licensed_apps_hi = 0;
379         eksp->eks_licensed_features_lo = 0;
380         eksp->eks_licensed_features_hi = 0;
381
382         return (0);
383
384 fail2:
385         EFSYS_PROBE(fail2);
386 fail1:
387         EFSYS_PROBE1(fail1, efx_rc_t, rc);
388
389         return (rc);
390 }
391
392 #endif  /* EFSYS_OPT_HUNTINGTON */
393
394 /* V3 Licensing - used starting from Medford family. See SF-114884-SW */
395
396 #if EFSYS_OPT_MEDFORD
397
398 static  __checkReturn   efx_rc_t
399 efx_mcdi_licensing_v3_update_licenses(
400         __in            efx_nic_t *enp)
401 {
402         efx_mcdi_req_t req;
403         uint8_t payload[MC_CMD_LICENSING_V3_IN_LEN];
404         efx_rc_t rc;
405
406         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD);
407
408         (void) memset(payload, 0, sizeof (payload));
409         req.emr_cmd = MC_CMD_LICENSING_V3;
410         req.emr_in_buf = payload;
411         req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN;
412         req.emr_out_buf = NULL;
413         req.emr_out_length = 0;
414
415         MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP,
416             MC_CMD_LICENSING_V3_IN_OP_UPDATE_LICENSE);
417
418         efx_mcdi_execute(enp, &req);
419
420         if (req.emr_rc != 0) {
421                 rc = req.emr_rc;
422                 goto fail1;
423         }
424
425         return (0);
426
427 fail1:
428         EFSYS_PROBE1(fail1, efx_rc_t, rc);
429
430         return (rc);
431 }
432
433 static  __checkReturn   efx_rc_t
434 efx_mcdi_licensing_v3_report_license(
435         __in            efx_nic_t *enp,
436         __out           efx_key_stats_t *eksp)
437 {
438         efx_mcdi_req_t req;
439         uint8_t payload[MAX(MC_CMD_LICENSING_V3_IN_LEN,
440                             MC_CMD_LICENSING_V3_OUT_LEN)];
441         efx_rc_t rc;
442
443         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD);
444
445         (void) memset(payload, 0, sizeof (payload));
446         req.emr_cmd = MC_CMD_LICENSING_V3;
447         req.emr_in_buf = payload;
448         req.emr_in_length = MC_CMD_LICENSING_V3_IN_LEN;
449         req.emr_out_buf = payload;
450         req.emr_out_length = MC_CMD_LICENSING_V3_OUT_LEN;
451
452         MCDI_IN_SET_DWORD(req, LICENSING_V3_IN_OP,
453             MC_CMD_LICENSING_V3_IN_OP_REPORT_LICENSE);
454
455         efx_mcdi_execute(enp, &req);
456
457         if (req.emr_rc != 0) {
458                 rc = req.emr_rc;
459                 goto fail1;
460         }
461
462         if (req.emr_out_length_used < MC_CMD_LICENSING_V3_OUT_LEN) {
463                 rc = EMSGSIZE;
464                 goto fail2;
465         }
466
467         eksp->eks_valid =
468                 MCDI_OUT_DWORD(req, LICENSING_V3_OUT_VALID_KEYS);
469         eksp->eks_invalid =
470                 MCDI_OUT_DWORD(req, LICENSING_V3_OUT_INVALID_KEYS);
471         eksp->eks_blacklisted = 0;
472         eksp->eks_unverifiable =
473                 MCDI_OUT_DWORD(req, LICENSING_V3_OUT_UNVERIFIABLE_KEYS);
474         eksp->eks_wrong_node =
475                 MCDI_OUT_DWORD(req, LICENSING_V3_OUT_WRONG_NODE_KEYS);
476         eksp->eks_licensed_apps_lo =
477                 MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_LO);
478         eksp->eks_licensed_apps_hi =
479                 MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_APPS_HI);
480         eksp->eks_licensed_features_lo =
481                 MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_LO);
482         eksp->eks_licensed_features_hi =
483                 MCDI_OUT_DWORD(req, LICENSING_V3_OUT_LICENSED_FEATURES_HI);
484
485         return (0);
486
487 fail2:
488         EFSYS_PROBE(fail2);
489 fail1:
490         EFSYS_PROBE1(fail1, efx_rc_t, rc);
491
492         return (rc);
493 }
494
495 static  __checkReturn   efx_rc_t
496 efx_mcdi_licensing_v3_app_state(
497         __in            efx_nic_t *enp,
498         __in            uint64_t app_id,
499         __out           boolean_t *licensedp)
500 {
501         efx_mcdi_req_t req;
502         uint8_t payload[MAX(MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN,
503                             MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN)];
504         uint32_t app_state;
505         efx_rc_t rc;
506
507         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_MEDFORD);
508
509         (void) memset(payload, 0, sizeof (payload));
510         req.emr_cmd = MC_CMD_GET_LICENSED_V3_APP_STATE;
511         req.emr_in_buf = payload;
512         req.emr_in_length = MC_CMD_GET_LICENSED_V3_APP_STATE_IN_LEN;
513         req.emr_out_buf = payload;
514         req.emr_out_length = MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN;
515
516         MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_LO,
517                     app_id & 0xffffffff);
518         MCDI_IN_SET_DWORD(req, GET_LICENSED_V3_APP_STATE_IN_APP_ID_HI,
519                     app_id >> 32);
520
521         efx_mcdi_execute(enp, &req);
522
523         if (req.emr_rc != 0) {
524                 rc = req.emr_rc;
525                 goto fail1;
526         }
527
528         if (req.emr_out_length_used < MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_LEN) {
529                 rc = EMSGSIZE;
530                 goto fail2;
531         }
532
533         app_state = (MCDI_OUT_DWORD(req, GET_LICENSED_V3_APP_STATE_OUT_STATE));
534         if (app_state != MC_CMD_GET_LICENSED_V3_APP_STATE_OUT_NOT_LICENSED) {
535                 *licensedp = B_TRUE;
536         } else {
537                 *licensedp = B_FALSE;
538         }
539
540         return (0);
541
542 fail2:
543         EFSYS_PROBE(fail2);
544 fail1:
545         EFSYS_PROBE1(fail1, efx_rc_t, rc);
546
547         return (rc);
548 }
549
550 static  __checkReturn   efx_rc_t
551 efx_mcdi_licensing_v3_get_id(
552         __in            efx_nic_t *enp,
553         __in            size_t buffer_size,
554         __out           uint32_t *typep,
555         __out           size_t *lengthp,
556         __out_bcount_part_opt(buffer_size, *lengthp)
557                         uint8_t *bufferp)
558 {
559         efx_mcdi_req_t req;
560         uint8_t payload[MAX(MC_CMD_LICENSING_GET_ID_V3_IN_LEN,
561                             MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN)];
562         efx_rc_t rc;
563
564         req.emr_cmd = MC_CMD_LICENSING_GET_ID_V3;
565
566         if (bufferp == NULL) {
567                 /* Request id type and length only */
568                 req.emr_in_buf = bufferp;
569                 req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN;
570                 req.emr_out_buf = bufferp;
571                 req.emr_out_length = MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN;
572                 (void) memset(payload, 0, sizeof (payload));
573         } else {
574                 /* Request full buffer */
575                 req.emr_in_buf = bufferp;
576                 req.emr_in_length = MC_CMD_LICENSING_GET_ID_V3_IN_LEN;
577                 req.emr_out_buf = bufferp;
578                 req.emr_out_length = MIN(buffer_size, MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN);
579                 (void) memset(bufferp, 0, req.emr_out_length);
580         }
581
582         efx_mcdi_execute(enp, &req);
583
584         if (req.emr_rc != 0) {
585                 rc = req.emr_rc;
586                 goto fail1;
587         }
588
589         if (req.emr_out_length_used < MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN) {
590                 rc = EMSGSIZE;
591                 goto fail2;
592         }
593
594         *typep = MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_TYPE);
595         *lengthp = MCDI_OUT_DWORD(req, LICENSING_GET_ID_V3_OUT_LICENSE_ID_LENGTH);
596
597         if (bufferp == NULL) {
598                 /* modify length requirements to indicate to caller the extra buffering
599                 ** needed to read the complete output.
600                 */
601                 *lengthp += MC_CMD_LICENSING_GET_ID_V3_OUT_LENMIN;
602         } else {
603                 /* Shift ID down to start of buffer */
604                 memmove(bufferp,
605                   bufferp+MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST,
606                   *lengthp);
607                 memset(bufferp+(*lengthp), 0, MC_CMD_LICENSING_GET_ID_V3_OUT_LICENSE_ID_OFST);
608         }
609
610         return (0);
611
612 fail2:
613         EFSYS_PROBE(fail2);
614 fail1:
615         EFSYS_PROBE1(fail1, efx_rc_t, rc);
616
617         return (rc);
618 }
619
620
621 #endif  /* EFSYS_OPT_MEDFORD */
622
623         __checkReturn           efx_rc_t
624 efx_lic_init(
625         __in                    efx_nic_t *enp)
626 {
627         efx_lic_ops_t *elop;
628         efx_rc_t rc;
629
630         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
631         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
632         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_LIC));
633
634         switch (enp->en_family) {
635
636 #if EFSYS_OPT_SIENA
637         case EFX_FAMILY_SIENA:
638                 elop = (efx_lic_ops_t *)&__efx_lic_v1_ops;
639                 break;
640 #endif  /* EFSYS_OPT_SIENA */
641
642 #if EFSYS_OPT_HUNTINGTON
643         case EFX_FAMILY_HUNTINGTON:
644                 elop = (efx_lic_ops_t *)&__efx_lic_v2_ops;
645                 break;
646 #endif  /* EFSYS_OPT_HUNTINGTON */
647
648 #if EFSYS_OPT_MEDFORD
649         case EFX_FAMILY_MEDFORD:
650                 elop = (efx_lic_ops_t *)&__efx_lic_v3_ops;
651                 break;
652 #endif  /* EFSYS_OPT_MEDFORD */
653
654         default:
655                 EFSYS_ASSERT(0);
656                 rc = ENOTSUP;
657                 goto fail1;
658         }
659
660         enp->en_elop = elop;
661         enp->en_mod_flags |= EFX_MOD_LIC;
662
663         return (0);
664
665 fail1:
666         EFSYS_PROBE1(fail1, efx_rc_t, rc);
667
668         return (rc);
669 }
670
671                                 void
672 efx_lic_fini(
673         __in                    efx_nic_t *enp)
674 {
675         efx_lic_ops_t *elop = enp->en_elop;
676
677         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
678         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
679         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
680
681         enp->en_elop = NULL;
682         enp->en_mod_flags &= ~EFX_MOD_LIC;
683 }
684
685
686         __checkReturn   efx_rc_t
687 efx_lic_update_licenses(
688         __in            efx_nic_t *enp)
689 {
690         efx_lic_ops_t *elop = enp->en_elop;
691         efx_rc_t rc;
692
693         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
694         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
695
696         if ((rc = elop->elo_update_licenses(enp)) != 0)
697                 goto fail1;
698
699         return (0);
700
701 fail1:
702         EFSYS_PROBE1(fail1, efx_rc_t, rc);
703
704         return (rc);
705 }
706
707         __checkReturn   efx_rc_t
708 efx_lic_get_key_stats(
709         __in            efx_nic_t *enp,
710         __out           efx_key_stats_t *eksp)
711 {
712         efx_lic_ops_t *elop = enp->en_elop;
713         efx_rc_t rc;
714
715         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
716         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
717
718         if ((rc = elop->elo_get_key_stats(enp, eksp)) != 0)
719                 goto fail1;
720
721         return (0);
722
723 fail1:
724         EFSYS_PROBE1(fail1, efx_rc_t, rc);
725
726         return (rc);
727 }
728
729         __checkReturn   efx_rc_t
730 efx_lic_app_state(
731         __in            efx_nic_t *enp,
732         __in            uint64_t app_id,
733         __out           boolean_t *licensedp)
734 {
735         efx_lic_ops_t *elop = enp->en_elop;
736         efx_rc_t rc;
737
738         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
739         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
740
741         if (elop->elo_app_state == NULL) {
742                 rc = ENOTSUP;
743                 goto fail1;
744         }
745         if ((rc = elop->elo_app_state(enp, app_id, licensedp)) != 0)
746                 goto fail2;
747
748         return (0);
749
750 fail2:
751         EFSYS_PROBE(fail2);
752 fail1:
753         EFSYS_PROBE1(fail1, efx_rc_t, rc);
754
755         return (rc);
756 }
757
758         __checkReturn   efx_rc_t
759 efx_lic_get_id(
760         __in            efx_nic_t *enp,
761         __in            size_t buffer_size,
762         __out           uint32_t *typep,
763         __out           size_t *lengthp,
764         __out_opt       uint8_t *bufferp
765         )
766 {
767         efx_lic_ops_t *elop = enp->en_elop;
768         efx_rc_t rc;
769
770         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
771         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_LIC);
772
773         if (elop->elo_get_id == NULL) {
774                 rc = ENOTSUP;
775                 goto fail1;
776         }
777
778         if ((rc = elop->elo_get_id(enp, buffer_size, typep,
779                                     lengthp, bufferp)) != 0)
780                 goto fail2;
781
782         return (0);
783
784 fail2:
785         EFSYS_PROBE(fail2);
786 fail1:
787         EFSYS_PROBE1(fail1, efx_rc_t, rc);
788
789         return (rc);
790 }
791
792 #endif  /* EFSYS_OPT_LICENSING */