linux/drivers/net/ethernet/pensando/ionic/ionic_main.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright(c) 2017 - 2019 Pensando Systems, Inc */
   3
   4#include <linux/printk.h>
   5#include <linux/dynamic_debug.h>
   6#include <linux/module.h>
   7#include <linux/netdevice.h>
   8#include <linux/utsname.h>
   9#include <generated/utsrelease.h>
  10#include <linux/ctype.h>
  11
  12#include "ionic.h"
  13#include "ionic_bus.h"
  14#include "ionic_lif.h"
  15#include "ionic_debugfs.h"
  16
  17MODULE_DESCRIPTION(IONIC_DRV_DESCRIPTION);
  18MODULE_AUTHOR("Pensando Systems, Inc");
  19MODULE_LICENSE("GPL");
  20
  21static const char *ionic_error_to_str(enum ionic_status_code code)
  22{
  23        switch (code) {
  24        case IONIC_RC_SUCCESS:
  25                return "IONIC_RC_SUCCESS";
  26        case IONIC_RC_EVERSION:
  27                return "IONIC_RC_EVERSION";
  28        case IONIC_RC_EOPCODE:
  29                return "IONIC_RC_EOPCODE";
  30        case IONIC_RC_EIO:
  31                return "IONIC_RC_EIO";
  32        case IONIC_RC_EPERM:
  33                return "IONIC_RC_EPERM";
  34        case IONIC_RC_EQID:
  35                return "IONIC_RC_EQID";
  36        case IONIC_RC_EQTYPE:
  37                return "IONIC_RC_EQTYPE";
  38        case IONIC_RC_ENOENT:
  39                return "IONIC_RC_ENOENT";
  40        case IONIC_RC_EINTR:
  41                return "IONIC_RC_EINTR";
  42        case IONIC_RC_EAGAIN:
  43                return "IONIC_RC_EAGAIN";
  44        case IONIC_RC_ENOMEM:
  45                return "IONIC_RC_ENOMEM";
  46        case IONIC_RC_EFAULT:
  47                return "IONIC_RC_EFAULT";
  48        case IONIC_RC_EBUSY:
  49                return "IONIC_RC_EBUSY";
  50        case IONIC_RC_EEXIST:
  51                return "IONIC_RC_EEXIST";
  52        case IONIC_RC_EINVAL:
  53                return "IONIC_RC_EINVAL";
  54        case IONIC_RC_ENOSPC:
  55                return "IONIC_RC_ENOSPC";
  56        case IONIC_RC_ERANGE:
  57                return "IONIC_RC_ERANGE";
  58        case IONIC_RC_BAD_ADDR:
  59                return "IONIC_RC_BAD_ADDR";
  60        case IONIC_RC_DEV_CMD:
  61                return "IONIC_RC_DEV_CMD";
  62        case IONIC_RC_ENOSUPP:
  63                return "IONIC_RC_ENOSUPP";
  64        case IONIC_RC_ERROR:
  65                return "IONIC_RC_ERROR";
  66        case IONIC_RC_ERDMA:
  67                return "IONIC_RC_ERDMA";
  68        case IONIC_RC_EBAD_FW:
  69                return "IONIC_RC_EBAD_FW";
  70        default:
  71                return "IONIC_RC_UNKNOWN";
  72        }
  73}
  74
  75static int ionic_error_to_errno(enum ionic_status_code code)
  76{
  77        switch (code) {
  78        case IONIC_RC_SUCCESS:
  79                return 0;
  80        case IONIC_RC_EVERSION:
  81        case IONIC_RC_EQTYPE:
  82        case IONIC_RC_EQID:
  83        case IONIC_RC_EINVAL:
  84        case IONIC_RC_ENOSUPP:
  85                return -EINVAL;
  86        case IONIC_RC_EPERM:
  87                return -EPERM;
  88        case IONIC_RC_ENOENT:
  89                return -ENOENT;
  90        case IONIC_RC_EAGAIN:
  91                return -EAGAIN;
  92        case IONIC_RC_ENOMEM:
  93                return -ENOMEM;
  94        case IONIC_RC_EFAULT:
  95                return -EFAULT;
  96        case IONIC_RC_EBUSY:
  97                return -EBUSY;
  98        case IONIC_RC_EEXIST:
  99                return -EEXIST;
 100        case IONIC_RC_ENOSPC:
 101                return -ENOSPC;
 102        case IONIC_RC_ERANGE:
 103                return -ERANGE;
 104        case IONIC_RC_BAD_ADDR:
 105                return -EFAULT;
 106        case IONIC_RC_EOPCODE:
 107        case IONIC_RC_EINTR:
 108        case IONIC_RC_DEV_CMD:
 109        case IONIC_RC_ERROR:
 110        case IONIC_RC_ERDMA:
 111        case IONIC_RC_EIO:
 112        default:
 113                return -EIO;
 114        }
 115}
 116
 117static const char *ionic_opcode_to_str(enum ionic_cmd_opcode opcode)
 118{
 119        switch (opcode) {
 120        case IONIC_CMD_NOP:
 121                return "IONIC_CMD_NOP";
 122        case IONIC_CMD_INIT:
 123                return "IONIC_CMD_INIT";
 124        case IONIC_CMD_RESET:
 125                return "IONIC_CMD_RESET";
 126        case IONIC_CMD_IDENTIFY:
 127                return "IONIC_CMD_IDENTIFY";
 128        case IONIC_CMD_GETATTR:
 129                return "IONIC_CMD_GETATTR";
 130        case IONIC_CMD_SETATTR:
 131                return "IONIC_CMD_SETATTR";
 132        case IONIC_CMD_PORT_IDENTIFY:
 133                return "IONIC_CMD_PORT_IDENTIFY";
 134        case IONIC_CMD_PORT_INIT:
 135                return "IONIC_CMD_PORT_INIT";
 136        case IONIC_CMD_PORT_RESET:
 137                return "IONIC_CMD_PORT_RESET";
 138        case IONIC_CMD_PORT_GETATTR:
 139                return "IONIC_CMD_PORT_GETATTR";
 140        case IONIC_CMD_PORT_SETATTR:
 141                return "IONIC_CMD_PORT_SETATTR";
 142        case IONIC_CMD_LIF_INIT:
 143                return "IONIC_CMD_LIF_INIT";
 144        case IONIC_CMD_LIF_RESET:
 145                return "IONIC_CMD_LIF_RESET";
 146        case IONIC_CMD_LIF_IDENTIFY:
 147                return "IONIC_CMD_LIF_IDENTIFY";
 148        case IONIC_CMD_LIF_SETATTR:
 149                return "IONIC_CMD_LIF_SETATTR";
 150        case IONIC_CMD_LIF_GETATTR:
 151                return "IONIC_CMD_LIF_GETATTR";
 152        case IONIC_CMD_LIF_SETPHC:
 153                return "IONIC_CMD_LIF_SETPHC";
 154        case IONIC_CMD_RX_MODE_SET:
 155                return "IONIC_CMD_RX_MODE_SET";
 156        case IONIC_CMD_RX_FILTER_ADD:
 157                return "IONIC_CMD_RX_FILTER_ADD";
 158        case IONIC_CMD_RX_FILTER_DEL:
 159                return "IONIC_CMD_RX_FILTER_DEL";
 160        case IONIC_CMD_Q_IDENTIFY:
 161                return "IONIC_CMD_Q_IDENTIFY";
 162        case IONIC_CMD_Q_INIT:
 163                return "IONIC_CMD_Q_INIT";
 164        case IONIC_CMD_Q_CONTROL:
 165                return "IONIC_CMD_Q_CONTROL";
 166        case IONIC_CMD_RDMA_RESET_LIF:
 167                return "IONIC_CMD_RDMA_RESET_LIF";
 168        case IONIC_CMD_RDMA_CREATE_EQ:
 169                return "IONIC_CMD_RDMA_CREATE_EQ";
 170        case IONIC_CMD_RDMA_CREATE_CQ:
 171                return "IONIC_CMD_RDMA_CREATE_CQ";
 172        case IONIC_CMD_RDMA_CREATE_ADMINQ:
 173                return "IONIC_CMD_RDMA_CREATE_ADMINQ";
 174        case IONIC_CMD_FW_DOWNLOAD:
 175                return "IONIC_CMD_FW_DOWNLOAD";
 176        case IONIC_CMD_FW_CONTROL:
 177                return "IONIC_CMD_FW_CONTROL";
 178        case IONIC_CMD_FW_DOWNLOAD_V1:
 179                return "IONIC_CMD_FW_DOWNLOAD_V1";
 180        case IONIC_CMD_FW_CONTROL_V1:
 181                return "IONIC_CMD_FW_CONTROL_V1";
 182        case IONIC_CMD_VF_GETATTR:
 183                return "IONIC_CMD_VF_GETATTR";
 184        case IONIC_CMD_VF_SETATTR:
 185                return "IONIC_CMD_VF_SETATTR";
 186        default:
 187                return "DEVCMD_UNKNOWN";
 188        }
 189}
 190
 191const char *ionic_vf_attr_to_str(enum ionic_vf_attr attr)
 192{
 193        switch (attr) {
 194        case IONIC_VF_ATTR_SPOOFCHK:
 195                return "IONIC_VF_ATTR_SPOOFCHK";
 196        case IONIC_VF_ATTR_TRUST:
 197                return "IONIC_VF_ATTR_TRUST";
 198        case IONIC_VF_ATTR_LINKSTATE:
 199                return "IONIC_VF_ATTR_LINKSTATE";
 200        case IONIC_VF_ATTR_MAC:
 201                return "IONIC_VF_ATTR_MAC";
 202        case IONIC_VF_ATTR_VLAN:
 203                return "IONIC_VF_ATTR_VLAN";
 204        case IONIC_VF_ATTR_RATE:
 205                return "IONIC_VF_ATTR_RATE";
 206        case IONIC_VF_ATTR_STATSADDR:
 207                return "IONIC_VF_ATTR_STATSADDR";
 208        default:
 209                return "IONIC_VF_ATTR_UNKNOWN";
 210        }
 211}
 212
 213static void ionic_adminq_flush(struct ionic_lif *lif)
 214{
 215        struct ionic_desc_info *desc_info;
 216        unsigned long irqflags;
 217        struct ionic_queue *q;
 218
 219        spin_lock_irqsave(&lif->adminq_lock, irqflags);
 220        if (!lif->adminqcq) {
 221                spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
 222                return;
 223        }
 224
 225        q = &lif->adminqcq->q;
 226
 227        while (q->tail_idx != q->head_idx) {
 228                desc_info = &q->info[q->tail_idx];
 229                memset(desc_info->desc, 0, sizeof(union ionic_adminq_cmd));
 230                desc_info->cb = NULL;
 231                desc_info->cb_arg = NULL;
 232                q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
 233        }
 234        spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
 235}
 236
 237void ionic_adminq_netdev_err_print(struct ionic_lif *lif, u8 opcode,
 238                                   u8 status, int err)
 239{
 240        const char *stat_str;
 241
 242        stat_str = (err == -ETIMEDOUT) ? "TIMEOUT" :
 243                                         ionic_error_to_str(status);
 244
 245        netdev_err(lif->netdev, "%s (%d) failed: %s (%d)\n",
 246                   ionic_opcode_to_str(opcode), opcode, stat_str, err);
 247}
 248
 249static int ionic_adminq_check_err(struct ionic_lif *lif,
 250                                  struct ionic_admin_ctx *ctx,
 251                                  const bool timeout,
 252                                  const bool do_msg)
 253{
 254        int err = 0;
 255
 256        if (ctx->comp.comp.status || timeout) {
 257                err = timeout ? -ETIMEDOUT :
 258                                ionic_error_to_errno(ctx->comp.comp.status);
 259
 260                if (do_msg)
 261                        ionic_adminq_netdev_err_print(lif, ctx->cmd.cmd.opcode,
 262                                                      ctx->comp.comp.status, err);
 263
 264                if (timeout)
 265                        ionic_adminq_flush(lif);
 266        }
 267
 268        return err;
 269}
 270
 271static void ionic_adminq_cb(struct ionic_queue *q,
 272                            struct ionic_desc_info *desc_info,
 273                            struct ionic_cq_info *cq_info, void *cb_arg)
 274{
 275        struct ionic_admin_ctx *ctx = cb_arg;
 276        struct ionic_admin_comp *comp;
 277
 278        if (!ctx)
 279                return;
 280
 281        comp = cq_info->cq_desc;
 282
 283        memcpy(&ctx->comp, comp, sizeof(*comp));
 284
 285        dev_dbg(q->dev, "comp admin queue command:\n");
 286        dynamic_hex_dump("comp ", DUMP_PREFIX_OFFSET, 16, 1,
 287                         &ctx->comp, sizeof(ctx->comp), true);
 288
 289        complete_all(&ctx->work);
 290}
 291
 292int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
 293{
 294        struct ionic_desc_info *desc_info;
 295        unsigned long irqflags;
 296        struct ionic_queue *q;
 297        int err = 0;
 298
 299        spin_lock_irqsave(&lif->adminq_lock, irqflags);
 300        if (!lif->adminqcq) {
 301                spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
 302                return -EIO;
 303        }
 304
 305        q = &lif->adminqcq->q;
 306
 307        if (!ionic_q_has_space(q, 1)) {
 308                err = -ENOSPC;
 309                goto err_out;
 310        }
 311
 312        err = ionic_heartbeat_check(lif->ionic);
 313        if (err)
 314                goto err_out;
 315
 316        desc_info = &q->info[q->head_idx];
 317        memcpy(desc_info->desc, &ctx->cmd, sizeof(ctx->cmd));
 318
 319        dev_dbg(&lif->netdev->dev, "post admin queue command:\n");
 320        dynamic_hex_dump("cmd ", DUMP_PREFIX_OFFSET, 16, 1,
 321                         &ctx->cmd, sizeof(ctx->cmd), true);
 322
 323        ionic_q_post(q, true, ionic_adminq_cb, ctx);
 324
 325err_out:
 326        spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
 327
 328        return err;
 329}
 330
 331int ionic_adminq_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx,
 332                      const int err, const bool do_msg)
 333{
 334        struct net_device *netdev = lif->netdev;
 335        unsigned long time_limit;
 336        unsigned long time_start;
 337        unsigned long time_done;
 338        unsigned long remaining;
 339        const char *name;
 340
 341        name = ionic_opcode_to_str(ctx->cmd.cmd.opcode);
 342
 343        if (err) {
 344                if (do_msg && !test_bit(IONIC_LIF_F_FW_RESET, lif->state))
 345                        netdev_err(netdev, "Posting of %s (%d) failed: %d\n",
 346                                   name, ctx->cmd.cmd.opcode, err);
 347                ctx->comp.comp.status = IONIC_RC_ERROR;
 348                return err;
 349        }
 350
 351        time_start = jiffies;
 352        time_limit = time_start + HZ * (ulong)DEVCMD_TIMEOUT;
 353        do {
 354                remaining = wait_for_completion_timeout(&ctx->work,
 355                                                        IONIC_ADMINQ_TIME_SLICE);
 356
 357                /* check for done */
 358                if (remaining)
 359                        break;
 360
 361                /* force a check of FW status and break out if FW reset */
 362                (void)ionic_heartbeat_check(lif->ionic);
 363                if ((test_bit(IONIC_LIF_F_FW_RESET, lif->state) &&
 364                     !lif->ionic->idev.fw_status_ready) ||
 365                    test_bit(IONIC_LIF_F_FW_STOPPING, lif->state)) {
 366                        if (do_msg)
 367                                netdev_warn(netdev, "%s (%d) interrupted, FW in reset\n",
 368                                            name, ctx->cmd.cmd.opcode);
 369                        ctx->comp.comp.status = IONIC_RC_ERROR;
 370                        return -ENXIO;
 371                }
 372
 373        } while (time_before(jiffies, time_limit));
 374        time_done = jiffies;
 375
 376        dev_dbg(lif->ionic->dev, "%s: elapsed %d msecs\n",
 377                __func__, jiffies_to_msecs(time_done - time_start));
 378
 379        return ionic_adminq_check_err(lif, ctx,
 380                                      time_after_eq(time_done, time_limit),
 381                                      do_msg);
 382}
 383
 384int ionic_adminq_post_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
 385{
 386        int err;
 387
 388        err = ionic_adminq_post(lif, ctx);
 389
 390        return ionic_adminq_wait(lif, ctx, err, true);
 391}
 392
 393int ionic_adminq_post_wait_nomsg(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
 394{
 395        int err;
 396
 397        err = ionic_adminq_post(lif, ctx);
 398
 399        return ionic_adminq_wait(lif, ctx, err, false);
 400}
 401
 402static void ionic_dev_cmd_clean(struct ionic *ionic)
 403{
 404        struct ionic_dev *idev = &ionic->idev;
 405
 406        iowrite32(0, &idev->dev_cmd_regs->doorbell);
 407        memset_io(&idev->dev_cmd_regs->cmd, 0, sizeof(idev->dev_cmd_regs->cmd));
 408}
 409
 410void ionic_dev_cmd_dev_err_print(struct ionic *ionic, u8 opcode, u8 status,
 411                                 int err)
 412{
 413        const char *stat_str;
 414
 415        stat_str = (err == -ETIMEDOUT) ? "TIMEOUT" :
 416                                         ionic_error_to_str(status);
 417
 418        dev_err(ionic->dev, "DEV_CMD %s (%d) error, %s (%d) failed\n",
 419                ionic_opcode_to_str(opcode), opcode, stat_str, err);
 420}
 421
 422static int __ionic_dev_cmd_wait(struct ionic *ionic, unsigned long max_seconds,
 423                                const bool do_msg)
 424{
 425        struct ionic_dev *idev = &ionic->idev;
 426        unsigned long start_time;
 427        unsigned long max_wait;
 428        unsigned long duration;
 429        int done = 0;
 430        bool fw_up;
 431        int opcode;
 432        int err;
 433
 434        /* Wait for dev cmd to complete, retrying if we get EAGAIN,
 435         * but don't wait any longer than max_seconds.
 436         */
 437        max_wait = jiffies + (max_seconds * HZ);
 438try_again:
 439        opcode = readb(&idev->dev_cmd_regs->cmd.cmd.opcode);
 440        start_time = jiffies;
 441        for (fw_up = ionic_is_fw_running(idev);
 442             !done && fw_up && time_before(jiffies, max_wait);
 443             fw_up = ionic_is_fw_running(idev)) {
 444                done = ionic_dev_cmd_done(idev);
 445                if (done)
 446                        break;
 447                usleep_range(100, 200);
 448        }
 449        duration = jiffies - start_time;
 450
 451        dev_dbg(ionic->dev, "DEVCMD %s (%d) done=%d took %ld secs (%ld jiffies)\n",
 452                ionic_opcode_to_str(opcode), opcode,
 453                done, duration / HZ, duration);
 454
 455        if (!done && !fw_up) {
 456                ionic_dev_cmd_clean(ionic);
 457                dev_warn(ionic->dev, "DEVCMD %s (%d) interrupted - FW is down\n",
 458                         ionic_opcode_to_str(opcode), opcode);
 459                return -ENXIO;
 460        }
 461
 462        if (!done && !time_before(jiffies, max_wait)) {
 463                ionic_dev_cmd_clean(ionic);
 464                dev_warn(ionic->dev, "DEVCMD %s (%d) timeout after %ld secs\n",
 465                         ionic_opcode_to_str(opcode), opcode, max_seconds);
 466                return -ETIMEDOUT;
 467        }
 468
 469        err = ionic_dev_cmd_status(&ionic->idev);
 470        if (err) {
 471                if (err == IONIC_RC_EAGAIN &&
 472                    time_before(jiffies, (max_wait - HZ))) {
 473                        dev_dbg(ionic->dev, "DEV_CMD %s (%d), %s (%d) retrying...\n",
 474                                ionic_opcode_to_str(opcode), opcode,
 475                                ionic_error_to_str(err), err);
 476
 477                        msleep(1000);
 478                        iowrite32(0, &idev->dev_cmd_regs->done);
 479                        iowrite32(1, &idev->dev_cmd_regs->doorbell);
 480                        goto try_again;
 481                }
 482
 483                if (!(opcode == IONIC_CMD_FW_CONTROL && err == IONIC_RC_EAGAIN))
 484                        if (do_msg)
 485                                ionic_dev_cmd_dev_err_print(ionic, opcode, err,
 486                                                            ionic_error_to_errno(err));
 487
 488                return ionic_error_to_errno(err);
 489        }
 490
 491        return 0;
 492}
 493
 494int ionic_dev_cmd_wait(struct ionic *ionic, unsigned long max_seconds)
 495{
 496        return __ionic_dev_cmd_wait(ionic, max_seconds, true);
 497}
 498
 499int ionic_dev_cmd_wait_nomsg(struct ionic *ionic, unsigned long max_seconds)
 500{
 501        return __ionic_dev_cmd_wait(ionic, max_seconds, false);
 502}
 503
 504int ionic_setup(struct ionic *ionic)
 505{
 506        int err;
 507
 508        err = ionic_dev_setup(ionic);
 509        if (err)
 510                return err;
 511        ionic_reset(ionic);
 512
 513        return 0;
 514}
 515
 516int ionic_identify(struct ionic *ionic)
 517{
 518        struct ionic_identity *ident = &ionic->ident;
 519        struct ionic_dev *idev = &ionic->idev;
 520        size_t sz;
 521        int err;
 522
 523        memset(ident, 0, sizeof(*ident));
 524
 525        ident->drv.os_type = cpu_to_le32(IONIC_OS_TYPE_LINUX);
 526        strncpy(ident->drv.driver_ver_str, UTS_RELEASE,
 527                sizeof(ident->drv.driver_ver_str) - 1);
 528
 529        mutex_lock(&ionic->dev_cmd_lock);
 530
 531        sz = min(sizeof(ident->drv), sizeof(idev->dev_cmd_regs->data));
 532        memcpy_toio(&idev->dev_cmd_regs->data, &ident->drv, sz);
 533
 534        ionic_dev_cmd_identify(idev, IONIC_IDENTITY_VERSION_1);
 535        err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
 536        if (!err) {
 537                sz = min(sizeof(ident->dev), sizeof(idev->dev_cmd_regs->data));
 538                memcpy_fromio(&ident->dev, &idev->dev_cmd_regs->data, sz);
 539        }
 540        mutex_unlock(&ionic->dev_cmd_lock);
 541
 542        if (err) {
 543                dev_err(ionic->dev, "Cannot identify ionic: %d\n", err);
 544                goto err_out;
 545        }
 546
 547        if (isprint(idev->dev_info.fw_version[0]) &&
 548            isascii(idev->dev_info.fw_version[0]))
 549                dev_info(ionic->dev, "FW: %.*s\n",
 550                         (int)(sizeof(idev->dev_info.fw_version) - 1),
 551                         idev->dev_info.fw_version);
 552        else
 553                dev_info(ionic->dev, "FW: (invalid string) 0x%02x 0x%02x 0x%02x 0x%02x ...\n",
 554                         (u8)idev->dev_info.fw_version[0],
 555                         (u8)idev->dev_info.fw_version[1],
 556                         (u8)idev->dev_info.fw_version[2],
 557                         (u8)idev->dev_info.fw_version[3]);
 558
 559        err = ionic_lif_identify(ionic, IONIC_LIF_TYPE_CLASSIC,
 560                                 &ionic->ident.lif);
 561        if (err) {
 562                dev_err(ionic->dev, "Cannot identify LIFs: %d\n", err);
 563                goto err_out;
 564        }
 565
 566        return 0;
 567
 568err_out:
 569        return err;
 570}
 571
 572int ionic_init(struct ionic *ionic)
 573{
 574        struct ionic_dev *idev = &ionic->idev;
 575        int err;
 576
 577        mutex_lock(&ionic->dev_cmd_lock);
 578        ionic_dev_cmd_init(idev);
 579        err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
 580        mutex_unlock(&ionic->dev_cmd_lock);
 581
 582        return err;
 583}
 584
 585int ionic_reset(struct ionic *ionic)
 586{
 587        struct ionic_dev *idev = &ionic->idev;
 588        int err;
 589
 590        if (!ionic_is_fw_running(idev))
 591                return 0;
 592
 593        mutex_lock(&ionic->dev_cmd_lock);
 594        ionic_dev_cmd_reset(idev);
 595        err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
 596        mutex_unlock(&ionic->dev_cmd_lock);
 597
 598        return err;
 599}
 600
 601int ionic_port_identify(struct ionic *ionic)
 602{
 603        struct ionic_identity *ident = &ionic->ident;
 604        struct ionic_dev *idev = &ionic->idev;
 605        size_t sz;
 606        int err;
 607
 608        mutex_lock(&ionic->dev_cmd_lock);
 609
 610        ionic_dev_cmd_port_identify(idev);
 611        err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
 612        if (!err) {
 613                sz = min(sizeof(ident->port), sizeof(idev->dev_cmd_regs->data));
 614                memcpy_fromio(&ident->port, &idev->dev_cmd_regs->data, sz);
 615        }
 616
 617        mutex_unlock(&ionic->dev_cmd_lock);
 618
 619        return err;
 620}
 621
 622int ionic_port_init(struct ionic *ionic)
 623{
 624        struct ionic_identity *ident = &ionic->ident;
 625        struct ionic_dev *idev = &ionic->idev;
 626        size_t sz;
 627        int err;
 628
 629        if (!idev->port_info) {
 630                idev->port_info_sz = ALIGN(sizeof(*idev->port_info), PAGE_SIZE);
 631                idev->port_info = dma_alloc_coherent(ionic->dev,
 632                                                     idev->port_info_sz,
 633                                                     &idev->port_info_pa,
 634                                                     GFP_KERNEL);
 635                if (!idev->port_info)
 636                        return -ENOMEM;
 637        }
 638
 639        sz = min(sizeof(ident->port.config), sizeof(idev->dev_cmd_regs->data));
 640
 641        mutex_lock(&ionic->dev_cmd_lock);
 642
 643        memcpy_toio(&idev->dev_cmd_regs->data, &ident->port.config, sz);
 644        ionic_dev_cmd_port_init(idev);
 645        err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
 646
 647        ionic_dev_cmd_port_state(&ionic->idev, IONIC_PORT_ADMIN_STATE_UP);
 648        (void)ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
 649
 650        mutex_unlock(&ionic->dev_cmd_lock);
 651        if (err) {
 652                dev_err(ionic->dev, "Failed to init port\n");
 653                dma_free_coherent(ionic->dev, idev->port_info_sz,
 654                                  idev->port_info, idev->port_info_pa);
 655                idev->port_info = NULL;
 656                idev->port_info_pa = 0;
 657        }
 658
 659        return err;
 660}
 661
 662int ionic_port_reset(struct ionic *ionic)
 663{
 664        struct ionic_dev *idev = &ionic->idev;
 665        int err = 0;
 666
 667        if (!idev->port_info)
 668                return 0;
 669
 670        if (ionic_is_fw_running(idev)) {
 671                mutex_lock(&ionic->dev_cmd_lock);
 672                ionic_dev_cmd_port_reset(idev);
 673                err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
 674                mutex_unlock(&ionic->dev_cmd_lock);
 675        }
 676
 677        dma_free_coherent(ionic->dev, idev->port_info_sz,
 678                          idev->port_info, idev->port_info_pa);
 679
 680        idev->port_info = NULL;
 681        idev->port_info_pa = 0;
 682
 683        return err;
 684}
 685
 686static int __init ionic_init_module(void)
 687{
 688        ionic_debugfs_create();
 689        return ionic_bus_register_driver();
 690}
 691
 692static void __exit ionic_cleanup_module(void)
 693{
 694        ionic_bus_unregister_driver();
 695        ionic_debugfs_destroy();
 696
 697        pr_info("%s removed\n", IONIC_DRV_NAME);
 698}
 699
 700module_init(ionic_init_module);
 701module_exit(ionic_cleanup_module);
 702