dpdk/drivers/raw/ifpga/base/ifpga_sec_mgr.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright(c) 2020 Intel Corporation
   3 */
   4
   5#include <fcntl.h>
   6#include <signal.h>
   7#include <unistd.h>
   8#include "ifpga_sec_mgr.h"
   9
  10
  11static const char * const rsu_prog[] = {"IDLE", "PREPARING", "SLEEPING",
  12        "READY", "AUTHENTICATING", "COPYING", "CANCELLATION", "PROGRAMMING_KEY",
  13        "DONE", "PKVL_DONE"};
  14static const char * const rsu_statl[] = {"NORMAL", "TIMEOUT", "AUTH_FAIL",
  15        "COPY_FAIL", "FATAL", "PKVL_REJECT", "NON_INCR", "ERASE_FAIL",
  16        "WEAROUT"};
  17static const char * const rsu_stath[] = {"NIOS_OK", "USER_OK", "FACTORY_OK",
  18        "USER_FAIL", "FACTORY_FAIL", "NIOS_FLASH_ERR", "FPGA_FLASH_ERR"};
  19
  20static const char *rsu_progress_name(uint32_t prog)
  21{
  22        if (prog > SEC_PROGRESS_PKVL_PROM_DONE)
  23                return "UNKNOWN";
  24        else
  25                return rsu_prog[prog];
  26}
  27
  28static const char *rsu_status_name(uint32_t stat)
  29{
  30        if (stat >= SEC_STATUS_NIOS_OK) {
  31                if (stat > SEC_STATUS_FPGA_FLASH_ERR)
  32                        return "UNKNOWN";
  33                else
  34                        return rsu_stath[stat-SEC_STATUS_NIOS_OK];
  35        } else {
  36                if (stat > SEC_STATUS_WEAROUT)
  37                        return "UNKNOWN";
  38                else
  39                        return rsu_statl[stat];
  40        }
  41}
  42
  43static bool secure_start_done(uint32_t doorbell)
  44{
  45        return (SEC_STATUS_G(doorbell) == SEC_STATUS_ERASE_FAIL ||
  46                SEC_STATUS_G(doorbell) == SEC_STATUS_WEAROUT ||
  47                (SEC_PROGRESS_G(doorbell) != SEC_PROGRESS_IDLE &&
  48                SEC_PROGRESS_G(doorbell) != SEC_PROGRESS_RSU_DONE));
  49}
  50
  51static bool secure_prog_ready(uint32_t doorbell)
  52{
  53        return (SEC_PROGRESS_G(doorbell) != SEC_PROGRESS_READY);
  54}
  55
  56static int poll_timeout(struct intel_max10_device *dev, uint32_t offset,
  57        bool (*cond)(uint32_t), uint32_t interval_ms, uint32_t timeout_ms)
  58{
  59        uint32_t val = 0;
  60        int ret = 0;
  61
  62        for (;;) {
  63                ret = max10_sys_read(dev, offset, &val);
  64                if (ret < 0) {
  65                        dev_err(dev,
  66                                "Failed to read max10 register 0x%x [e:%d]\n",
  67                                offset, ret);
  68                        break;
  69                }
  70
  71                if (cond(val)) {
  72                        dev_debug(dev,
  73                                "Read 0x%08x from max10 register 0x%x "
  74                                "[poll success]\n", val, offset);
  75                        ret = 0;
  76                        break;
  77                }
  78                if (timeout_ms > interval_ms)
  79                        timeout_ms -= interval_ms;
  80                else
  81                        timeout_ms = 0;
  82                if (timeout_ms == 0) {
  83                        dev_debug(dev,
  84                                "Read 0x%08x from max10 register 0x%x "
  85                                "[poll timeout]\n", val, offset);
  86                        ret = -ETIMEDOUT;
  87                        break;
  88                }
  89                msleep(interval_ms);
  90        }
  91
  92        return ret;
  93}
  94
  95static int n3000_secure_update_start(struct intel_max10_device *dev)
  96{
  97        uint32_t doorbell = 0;
  98        uint32_t prog = 0;
  99        uint32_t status = 0;
 100        int ret = 0;
 101
 102        ret = max10_sys_read(dev, MAX10_DOORBELL, &doorbell);
 103        if (ret < 0) {
 104                dev_err(dev,
 105                        "Failed to read max10 doorbell register [e:%d]\n",
 106                        ret);
 107                return ret;
 108        }
 109
 110        prog = SEC_PROGRESS_G(doorbell);
 111        if ((prog != SEC_PROGRESS_IDLE) && (prog != SEC_PROGRESS_RSU_DONE)) {
 112                dev_debug(dev, "Current RSU progress is %s\n",
 113                        rsu_progress_name(prog));
 114                return -EBUSY;
 115        }
 116
 117        ret = max10_sys_update_bits(dev, MAX10_DOORBELL,
 118                RSU_REQUEST | HOST_STATUS, RSU_REQUEST);
 119        if (ret < 0) {
 120                dev_err(dev,
 121                        "Failed to updt max10 doorbell register [e:%d]\n",
 122                        ret);
 123                return ret;
 124        }
 125
 126        ret = poll_timeout(dev, MAX10_DOORBELL, secure_start_done,
 127                IFPGA_SEC_START_INTERVAL_MS, IFPGA_SEC_START_TIMEOUT_MS);
 128        if (ret < 0) {
 129                dev_err(dev,
 130                        "Failed to poll max10 doorbell register [e:%d]\n",
 131                        ret);
 132                return ret;
 133        }
 134
 135        ret = max10_sys_read(dev, MAX10_DOORBELL, &doorbell);
 136        if (ret < 0) {
 137                dev_err(dev,
 138                        "Failed to read max10 doorbell register [e:%d]\n",
 139                        ret);
 140                return ret;
 141        }
 142
 143        status = SEC_STATUS_G(doorbell);
 144        if (status == SEC_STATUS_WEAROUT)
 145                return -EAGAIN;
 146
 147        if (status == SEC_STATUS_ERASE_FAIL)
 148                return -EIO;
 149
 150        return 0;
 151}
 152
 153static int n3000_cancel(struct ifpga_sec_mgr *smgr)
 154{
 155        struct intel_max10_device *dev = NULL;
 156        uint32_t doorbell = 0;
 157        uint32_t prog = 0;
 158        int ret = 0;
 159
 160        if (!smgr || !smgr->max10_dev)
 161                return -ENODEV;
 162        dev = (struct intel_max10_device *)smgr->max10_dev;
 163
 164        ret = max10_sys_read(dev, MAX10_DOORBELL, &doorbell);
 165        if (ret < 0) {
 166                dev_err(dev,
 167                        "Failed to read max10 doorbell register [e:%d]\n",
 168                        ret);
 169                return ret;
 170        }
 171
 172        prog = SEC_PROGRESS_G(doorbell);
 173        if (prog == SEC_PROGRESS_IDLE)
 174                return 0;
 175        if (prog != SEC_PROGRESS_READY)
 176                return -EBUSY;
 177
 178        return max10_sys_update_bits(dev, MAX10_DOORBELL, HOST_STATUS,
 179                HOST_STATUS_S(HOST_STATUS_ABORT_RSU));
 180}
 181
 182static int n3000_prepare(struct ifpga_sec_mgr *smgr)
 183{
 184        struct intel_max10_device *dev = NULL;
 185        int retry = 0;
 186        int ret = 0;
 187
 188        if (!smgr || !smgr->max10_dev)
 189                return -ENODEV;
 190        dev = (struct intel_max10_device *)smgr->max10_dev;
 191
 192        ret = n3000_secure_update_start(dev);
 193        if (ret == -EBUSY)
 194                n3000_cancel(smgr);
 195
 196        while (ret) {
 197                if (++retry > IFPGA_RSU_START_RETRY)
 198                        break;
 199                msleep(1000);
 200                ret = n3000_secure_update_start(dev);
 201        }
 202        if (retry > IFPGA_RSU_START_RETRY) {
 203                dev_err(dev, "Failed to start secure flash update\n");
 204                ret = -EAGAIN;
 205        }
 206
 207        return ret;
 208}
 209
 210static int n3000_bulk_write(struct intel_max10_device *dev, uint32_t addr,
 211        char *buf, uint32_t len)
 212{
 213        uint32_t i = 0;
 214        uint32_t n = 0;
 215        uint32_t v = 0;
 216        uint32_t p = 0;
 217        int ret = 0;
 218
 219        if (len & 0x3) {
 220                dev_err(dev,
 221                        "Length of data block is not 4 bytes aligned [e:%u]\n",
 222                        len);
 223                return -EINVAL;
 224        }
 225
 226        n = len >> 2;
 227        for (i = 0; i < n; i++) {
 228                p = i << 2;
 229                v = *(uint32_t *)(buf + p);
 230                ret = max10_reg_write(dev, addr + p, v);
 231                if (ret < 0) {
 232                        dev_err(dev,
 233                                "Failed to write to staging area 0x%08x [e:%d]\n",
 234                                addr + p, ret);
 235                        return ret;
 236                }
 237                usleep(1);
 238        }
 239
 240        return 0;
 241}
 242
 243static int n3000_write_blk(struct ifpga_sec_mgr *smgr, char *buf,
 244        uint32_t offset, uint32_t len)
 245{
 246        struct intel_max10_device *dev = NULL;
 247        uint32_t doorbell = 0;
 248        uint32_t prog = 0;
 249        uint32_t m = 0;
 250        int ret = 0;
 251
 252        if (!smgr || !smgr->max10_dev)
 253                return -ENODEV;
 254        dev = (struct intel_max10_device *)smgr->max10_dev;
 255
 256        if (offset + len > dev->staging_area_size) {
 257                dev_err(dev,
 258                        "Write position would be out of staging area [e:%u]\n",
 259                        dev->staging_area_size);
 260                return -ENOMEM;
 261        }
 262
 263        ret = max10_sys_read(dev, MAX10_DOORBELL, &doorbell);
 264        if (ret < 0) {
 265                dev_err(dev,
 266                        "Failed to read max10 doorbell register [e:%d]\n",
 267                        ret);
 268                return ret;
 269        }
 270
 271        prog = SEC_PROGRESS_G(doorbell);
 272        if (prog == SEC_PROGRESS_PREPARE)
 273                return -EAGAIN;
 274        else if (prog != SEC_PROGRESS_READY)
 275                return -EBUSY;
 276
 277        m = len & 0x3;
 278        if (m != 0)
 279                len += 4 - m;   /* make length to 4 bytes align */
 280
 281        return n3000_bulk_write(dev, dev->staging_area_base + offset, buf, len);
 282}
 283
 284static int n3000_write_done(struct ifpga_sec_mgr *smgr)
 285{
 286        struct intel_max10_device *dev = NULL;
 287        uint32_t doorbell = 0;
 288        uint32_t prog = 0;
 289        uint32_t status = 0;
 290        int ret = 0;
 291
 292        if (!smgr || !smgr->max10_dev)
 293                return -ENODEV;
 294        dev = (struct intel_max10_device *)smgr->max10_dev;
 295
 296        ret = max10_sys_read(dev, MAX10_DOORBELL, &doorbell);
 297        if (ret < 0) {
 298                dev_err(dev,
 299                        "Failed to read max10 doorbell register [e:%d]\n",
 300                        ret);
 301                return ret;
 302        }
 303
 304        prog = SEC_PROGRESS_G(doorbell);
 305        if (prog != SEC_PROGRESS_READY)
 306                return -EBUSY;
 307
 308        ret = max10_sys_update_bits(dev, MAX10_DOORBELL, HOST_STATUS,
 309                HOST_STATUS_S(HOST_STATUS_WRITE_DONE));
 310        if (ret < 0) {
 311                dev_err(dev,
 312                        "Failed to update max10 doorbell register [e:%d]\n",
 313                        ret);
 314                return ret;
 315        }
 316
 317        ret = poll_timeout(dev, MAX10_DOORBELL, secure_prog_ready,
 318                IFPGA_NIOS_HANDSHAKE_INTERVAL_MS,
 319                IFPGA_NIOS_HANDSHAKE_TIMEOUT_MS);
 320        if (ret < 0) {
 321                dev_err(dev,
 322                        "Failed to poll max10 doorbell register [e:%d]\n",
 323                        ret);
 324                return ret;
 325        }
 326
 327        ret = max10_sys_read(dev, MAX10_DOORBELL, &doorbell);
 328        if (ret < 0) {
 329                dev_err(dev,
 330                        "Failed to read max10 doorbell register [e:%d]\n",
 331                        ret);
 332                return ret;
 333        }
 334
 335        status = SEC_STATUS_G(doorbell);
 336        switch (status) {
 337        case SEC_STATUS_NORMAL:
 338        case SEC_STATUS_NIOS_OK:
 339        case SEC_STATUS_USER_OK:
 340        case SEC_STATUS_FACTORY_OK:
 341                ret = 0;
 342                break;
 343        default:
 344                ret = -EIO;
 345                break;
 346        }
 347
 348        return ret;
 349}
 350
 351static int n3000_check_complete(struct ifpga_sec_mgr *smgr)
 352{
 353        struct intel_max10_device *dev = NULL;
 354        uint32_t doorbell = 0;
 355        uint32_t status = 0;
 356        uint32_t prog = 0;
 357        int ret = 0;
 358
 359        if (!smgr || !smgr->max10_dev)
 360                return -ENODEV;
 361        dev = (struct intel_max10_device *)smgr->max10_dev;
 362
 363        ret = max10_sys_read(dev, MAX10_DOORBELL, &doorbell);
 364        if (ret < 0) {
 365                dev_err(dev,
 366                        "Failed to read max10 doorbell register [e:%d]\n",
 367                        ret);
 368                return ret;
 369        }
 370
 371        status = SEC_STATUS_G(doorbell);
 372        switch (status) {
 373        case SEC_STATUS_NORMAL:
 374        case SEC_STATUS_NIOS_OK:
 375        case SEC_STATUS_USER_OK:
 376        case SEC_STATUS_FACTORY_OK:
 377        case SEC_STATUS_WEAROUT:
 378                break;
 379        default:
 380                return -EIO;
 381        }
 382
 383        prog = SEC_PROGRESS_G(doorbell);
 384        switch (prog) {
 385        case SEC_PROGRESS_IDLE:
 386        case SEC_PROGRESS_RSU_DONE:
 387                return 0;
 388        case SEC_PROGRESS_AUTHENTICATING:
 389        case SEC_PROGRESS_COPYING:
 390        case SEC_PROGRESS_UPDATE_CANCEL:
 391        case SEC_PROGRESS_PROGRAM_KEY_HASH:
 392                return -EAGAIN;
 393        case SEC_PROGRESS_PREPARE:
 394        case SEC_PROGRESS_READY:
 395                return -EBUSY;
 396        default:
 397                return -EIO;
 398        }
 399
 400        return 0;
 401}
 402
 403static int n3000_reload_fpga(struct intel_max10_device *dev, int page)
 404{
 405        int ret = 0;
 406
 407        dev_info(dev, "Reload FPGA\n");
 408
 409        if (!dev || ((page != 0) && (page != 1))) {
 410                dev_err(dev, "Input parameter of %s is invalid\n", __func__);
 411                ret = -EINVAL;
 412                goto end;
 413        }
 414
 415        if (dev->flags & MAX10_FLAGS_SECURE) {
 416                ret = max10_sys_update_bits(dev, FPGA_RECONF_REG,
 417                        SFPGA_RP_LOAD, 0);
 418                if (ret < 0) {
 419                        dev_err(dev,
 420                                "Failed to update max10 reconfig register [e:%d]\n",
 421                                ret);
 422                        goto end;
 423                }
 424                ret = max10_sys_update_bits(dev, FPGA_RECONF_REG,
 425                        SFPGA_RP_LOAD | SFPGA_RECONF_PAGE,
 426                        SFPGA_RP_LOAD | SFPGA_PAGE(page));
 427                if (ret < 0) {
 428                        dev_err(dev,
 429                                "Failed to update max10 reconfig register [e:%d]\n",
 430                                ret);
 431                        goto end;
 432                }
 433        } else {
 434                ret = max10_sys_update_bits(dev, RSU_REG, FPGA_RP_LOAD, 0);
 435                if (ret < 0) {
 436                        dev_err(dev,
 437                                "Failed to update max10 rsu register [e:%d]\n",
 438                                ret);
 439                        goto end;
 440                }
 441                ret = max10_sys_update_bits(dev, RSU_REG,
 442                        FPGA_RP_LOAD | FPGA_RECONF_PAGE,
 443                        FPGA_RP_LOAD | FPGA_PAGE(page));
 444                if (ret < 0) {
 445                        dev_err(dev,
 446                                "Failed to update max10 rsu register [e:%d]\n",
 447                                ret);
 448                        goto end;
 449                }
 450        }
 451
 452        ret = max10_sys_update_bits(dev, FPGA_RECONF_REG, COUNTDOWN_START, 0);
 453        if (ret < 0) {
 454                dev_err(dev,
 455                        "Failed to update max10 reconfig register [e:%d]\n",
 456                        ret);
 457                goto end;
 458        }
 459
 460        ret = max10_sys_update_bits(dev, FPGA_RECONF_REG, COUNTDOWN_START,
 461                COUNTDOWN_START);
 462        if (ret < 0) {
 463                dev_err(dev,
 464                        "Failed to update max10 reconfig register [e:%d]\n",
 465                        ret);
 466        }
 467end:
 468        if (ret < 0)
 469                dev_err(dev, "Failed to reload FPGA\n");
 470
 471        return ret;
 472}
 473
 474static int n3000_reload_bmc(struct intel_max10_device *dev, int page)
 475{
 476        uint32_t val = 0;
 477        int ret = 0;
 478
 479        dev_info(dev, "Reload BMC\n");
 480
 481        if (!dev || ((page != 0) && (page != 1))) {
 482                dev_err(dev, "Input parameter of %s is invalid\n", __func__);
 483                ret = -EINVAL;
 484                goto end;
 485        }
 486
 487        if (dev->flags & MAX10_FLAGS_SECURE) {
 488                ret = max10_sys_update_bits(dev, MAX10_DOORBELL,
 489                        CONFIG_SEL | REBOOT_REQ,
 490                        CONFIG_SEL_S(page) | REBOOT_REQ);
 491        } else {
 492                val = (page == 0) ? 0x1 : 0x3;
 493                ret = max10_reg_write(dev, IFPGA_DUAL_CFG_CTRL1, val);
 494                if (ret < 0) {
 495                        dev_err(dev,
 496                                "Failed to write to dual config1 register [e:%d]\n",
 497                                ret);
 498                        goto end;
 499                }
 500
 501                ret = max10_reg_write(dev, IFPGA_DUAL_CFG_CTRL0, 0x1);
 502                if (ret < 0) {
 503                        if (ret == -EIO) {
 504                                ret = 0;
 505                                goto end;
 506                        }
 507                        dev_err(dev,
 508                                "Failed to write to dual config0 register [e:%d]\n",
 509                                ret);
 510                }
 511        }
 512
 513end:
 514        if (ret < 0)
 515                dev_err(dev, "Failed to reload BMC\n");
 516
 517        return ret;
 518}
 519
 520static int n3000_reload(struct ifpga_sec_mgr *smgr, int type, int page)
 521{
 522        int psel = 0;
 523        int ret = 0;
 524
 525        if (!smgr || !smgr->max10_dev)
 526                return -ENODEV;
 527
 528        if (type == IFPGA_BOOT_TYPE_FPGA) {
 529                psel = (page == IFPGA_BOOT_PAGE_FACTORY ? 0 : 1);
 530                ret = n3000_reload_fpga(smgr->max10_dev, psel);
 531        } else if (type == IFPGA_BOOT_TYPE_BMC) {
 532                psel = (page == IFPGA_BOOT_PAGE_FACTORY ? 1 : 0);
 533                ret = n3000_reload_bmc(smgr->max10_dev, psel);
 534        } else {
 535                ret = -EINVAL;
 536        }
 537
 538        return ret;
 539}
 540
 541static uint64_t n3000_get_hw_errinfo(struct ifpga_sec_mgr *smgr)
 542{
 543        struct intel_max10_device *dev = NULL;
 544        uint32_t doorbell = 0;
 545        uint32_t stat = 0;
 546        uint32_t prog = 0;
 547        uint32_t auth_result = 0;
 548        int ret = 0;
 549
 550        if (!smgr || !smgr->max10_dev)
 551                return -ENODEV;
 552        dev = (struct intel_max10_device *)smgr->max10_dev;
 553
 554        ret = max10_sys_read(dev, MAX10_DOORBELL, &doorbell);
 555        if (ret < 0) {
 556                dev_err(dev, "Failed to read max10 doorbell register [e:%d]\n",
 557                        ret);
 558                return -1;
 559        }
 560        stat = SEC_STATUS_G(doorbell);
 561        prog = SEC_PROGRESS_G(doorbell);
 562        dev_debug(dev, "Current RSU status is %s, progress is %s\n",
 563                rsu_status_name(stat), rsu_progress_name(prog));
 564
 565        ret = max10_sys_read(dev, MAX10_AUTH_RESULT, &auth_result);
 566        if (ret < 0) {
 567                dev_err(dev,
 568                        "Failed to read authenticate result register [e:%d]\n",
 569                        ret);
 570                return -1;
 571        }
 572
 573        return (uint64_t)doorbell << 32 | (uint64_t)auth_result;
 574}
 575
 576static const struct ifpga_sec_ops n3000_sec_ops = {
 577        .prepare = n3000_prepare,
 578        .write_blk = n3000_write_blk,
 579        .write_done = n3000_write_done,
 580        .check_complete = n3000_check_complete,
 581        .reload = n3000_reload,
 582        .cancel = n3000_cancel,
 583        .cleanup = NULL,
 584        .get_hw_errinfo = n3000_get_hw_errinfo,
 585};
 586
 587int init_sec_mgr(struct ifpga_fme_hw *fme)
 588{
 589        struct ifpga_hw *hw = NULL;
 590        opae_share_data *sd = NULL;
 591        struct ifpga_sec_mgr *smgr = NULL;
 592
 593        if (!fme || !fme->max10_dev)
 594                return -ENODEV;
 595
 596        smgr = (struct ifpga_sec_mgr *)malloc(sizeof(*smgr));
 597        if (!smgr) {
 598                dev_err(NULL, "Failed to allocate memory for security manager\n");
 599                return -ENOMEM;
 600        }
 601        fme->sec_mgr = smgr;
 602
 603        hw = (struct ifpga_hw *)fme->parent;
 604        if (hw && hw->adapter && hw->adapter->shm.ptr) {
 605                sd = (opae_share_data *)hw->adapter->shm.ptr;
 606                smgr->rsu_control = &sd->rsu_ctrl;
 607                smgr->rsu_status = &sd->rsu_stat;
 608        } else {
 609                smgr->rsu_control = NULL;
 610                smgr->rsu_status = NULL;
 611        }
 612
 613        if (hw && (hw->pci_data->device_id == IFPGA_N3000_DID) &&
 614                (hw->pci_data->vendor_id == IFPGA_N3000_VID)) {
 615                smgr->ops = &n3000_sec_ops;
 616                smgr->copy_speed = IFPGA_N3000_COPY_SPEED;
 617        } else {
 618                dev_err(NULL, "No operation for security manager\n");
 619                smgr->ops = NULL;
 620        }
 621
 622        smgr->fme = fme;
 623        smgr->max10_dev = fme->max10_dev;
 624
 625        return 0;
 626}
 627
 628void release_sec_mgr(struct ifpga_fme_hw *fme)
 629{
 630        struct ifpga_sec_mgr *smgr = NULL;
 631
 632        if (fme) {
 633                smgr = (struct ifpga_sec_mgr *)fme->sec_mgr;
 634                if (smgr) {
 635                        fme->sec_mgr = NULL;
 636                        free(smgr);
 637                }
 638        }
 639}
 640