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 */ 793