linux/drivers/net/ethernet/pensando/ionic/ionic_dev.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright(c) 2017 - 2019 Pensando Systems, Inc */
   3
   4#include <linux/kernel.h>
   5#include <linux/types.h>
   6#include <linux/errno.h>
   7#include <linux/io.h>
   8#include <linux/slab.h>
   9#include <linux/etherdevice.h>
  10#include "ionic.h"
  11#include "ionic_dev.h"
  12#include "ionic_lif.h"
  13
  14static void ionic_watchdog_cb(struct timer_list *t)
  15{
  16        struct ionic *ionic = from_timer(ionic, t, watchdog_timer);
  17        struct ionic_lif *lif = ionic->lif;
  18        struct ionic_deferred_work *work;
  19        int hb;
  20
  21        mod_timer(&ionic->watchdog_timer,
  22                  round_jiffies(jiffies + ionic->watchdog_period));
  23
  24        if (!lif)
  25                return;
  26
  27        hb = ionic_heartbeat_check(ionic);
  28        dev_dbg(ionic->dev, "%s: hb %d running %d UP %d\n",
  29                __func__, hb, netif_running(lif->netdev),
  30                test_bit(IONIC_LIF_F_UP, lif->state));
  31
  32        if (hb >= 0 &&
  33            !test_bit(IONIC_LIF_F_FW_RESET, lif->state))
  34                ionic_link_status_check_request(lif, CAN_NOT_SLEEP);
  35
  36        if (test_bit(IONIC_LIF_F_FILTER_SYNC_NEEDED, lif->state)) {
  37                work = kzalloc(sizeof(*work), GFP_ATOMIC);
  38                if (!work) {
  39                        netdev_err(lif->netdev, "rxmode change dropped\n");
  40                        return;
  41                }
  42
  43                work->type = IONIC_DW_TYPE_RX_MODE;
  44                netdev_dbg(lif->netdev, "deferred: rx_mode\n");
  45                ionic_lif_deferred_enqueue(&lif->deferred, work);
  46        }
  47}
  48
  49void ionic_init_devinfo(struct ionic *ionic)
  50{
  51        struct ionic_dev *idev = &ionic->idev;
  52
  53        idev->dev_info.asic_type = ioread8(&idev->dev_info_regs->asic_type);
  54        idev->dev_info.asic_rev = ioread8(&idev->dev_info_regs->asic_rev);
  55
  56        memcpy_fromio(idev->dev_info.fw_version,
  57                      idev->dev_info_regs->fw_version,
  58                      IONIC_DEVINFO_FWVERS_BUFLEN);
  59
  60        memcpy_fromio(idev->dev_info.serial_num,
  61                      idev->dev_info_regs->serial_num,
  62                      IONIC_DEVINFO_SERIAL_BUFLEN);
  63
  64        idev->dev_info.fw_version[IONIC_DEVINFO_FWVERS_BUFLEN] = 0;
  65        idev->dev_info.serial_num[IONIC_DEVINFO_SERIAL_BUFLEN] = 0;
  66
  67        dev_dbg(ionic->dev, "fw_version %s\n", idev->dev_info.fw_version);
  68}
  69
  70int ionic_dev_setup(struct ionic *ionic)
  71{
  72        struct ionic_dev_bar *bar = ionic->bars;
  73        unsigned int num_bars = ionic->num_bars;
  74        struct ionic_dev *idev = &ionic->idev;
  75        struct device *dev = ionic->dev;
  76        u32 sig;
  77
  78        /* BAR0: dev_cmd and interrupts */
  79        if (num_bars < 1) {
  80                dev_err(dev, "No bars found, aborting\n");
  81                return -EFAULT;
  82        }
  83
  84        if (bar->len < IONIC_BAR0_SIZE) {
  85                dev_err(dev, "Resource bar size %lu too small, aborting\n",
  86                        bar->len);
  87                return -EFAULT;
  88        }
  89
  90        idev->dev_info_regs = bar->vaddr + IONIC_BAR0_DEV_INFO_REGS_OFFSET;
  91        idev->dev_cmd_regs = bar->vaddr + IONIC_BAR0_DEV_CMD_REGS_OFFSET;
  92        idev->intr_status = bar->vaddr + IONIC_BAR0_INTR_STATUS_OFFSET;
  93        idev->intr_ctrl = bar->vaddr + IONIC_BAR0_INTR_CTRL_OFFSET;
  94
  95        idev->hwstamp_regs = &idev->dev_info_regs->hwstamp;
  96
  97        sig = ioread32(&idev->dev_info_regs->signature);
  98        if (sig != IONIC_DEV_INFO_SIGNATURE) {
  99                dev_err(dev, "Incompatible firmware signature %x", sig);
 100                return -EFAULT;
 101        }
 102
 103        ionic_init_devinfo(ionic);
 104
 105        /* BAR1: doorbells */
 106        bar++;
 107        if (num_bars < 2) {
 108                dev_err(dev, "Doorbell bar missing, aborting\n");
 109                return -EFAULT;
 110        }
 111
 112        timer_setup(&ionic->watchdog_timer, ionic_watchdog_cb, 0);
 113        ionic->watchdog_period = IONIC_WATCHDOG_SECS * HZ;
 114
 115        /* set times to ensure the first check will proceed */
 116        atomic_long_set(&idev->last_check_time, jiffies - 2 * HZ);
 117        idev->last_hb_time = jiffies - 2 * ionic->watchdog_period;
 118        /* init as ready, so no transition if the first check succeeds */
 119        idev->last_fw_hb = 0;
 120        idev->fw_hb_ready = true;
 121        idev->fw_status_ready = true;
 122        idev->fw_generation = IONIC_FW_STS_F_GENERATION &
 123                              ioread8(&idev->dev_info_regs->fw_status);
 124
 125        mod_timer(&ionic->watchdog_timer,
 126                  round_jiffies(jiffies + ionic->watchdog_period));
 127
 128        idev->db_pages = bar->vaddr;
 129        idev->phy_db_pages = bar->bus_addr;
 130
 131        return 0;
 132}
 133
 134/* Devcmd Interface */
 135int ionic_heartbeat_check(struct ionic *ionic)
 136{
 137        struct ionic_dev *idev = &ionic->idev;
 138        unsigned long check_time, last_check_time;
 139        bool fw_status_ready = true;
 140        bool fw_hb_ready;
 141        u8 fw_generation;
 142        u8 fw_status;
 143        u32 fw_hb;
 144
 145        /* wait a least one second before testing again */
 146        check_time = jiffies;
 147        last_check_time = atomic_long_read(&idev->last_check_time);
 148do_check_time:
 149        if (time_before(check_time, last_check_time + HZ))
 150                return 0;
 151        if (!atomic_long_try_cmpxchg_relaxed(&idev->last_check_time,
 152                                             &last_check_time, check_time)) {
 153                /* if called concurrently, only the first should proceed. */
 154                dev_dbg(ionic->dev, "%s: do_check_time again\n", __func__);
 155                goto do_check_time;
 156        }
 157
 158        /* firmware is useful only if the running bit is set and
 159         * fw_status != 0xff (bad PCI read)
 160         * If fw_status is not ready don't bother with the generation.
 161         */
 162        fw_status = ioread8(&idev->dev_info_regs->fw_status);
 163
 164        if (fw_status == 0xff || !(fw_status & IONIC_FW_STS_F_RUNNING)) {
 165                fw_status_ready = false;
 166        } else {
 167                fw_generation = fw_status & IONIC_FW_STS_F_GENERATION;
 168                if (idev->fw_generation != fw_generation) {
 169                        dev_info(ionic->dev, "FW generation 0x%02x -> 0x%02x\n",
 170                                 idev->fw_generation, fw_generation);
 171
 172                        idev->fw_generation = fw_generation;
 173
 174                        /* If the generation changed, the fw status is not
 175                         * ready so we need to trigger a fw-down cycle.  After
 176                         * the down, the next watchdog will see the fw is up
 177                         * and the generation value stable, so will trigger
 178                         * the fw-up activity.
 179                         */
 180                        fw_status_ready = false;
 181                }
 182        }
 183
 184        /* is this a transition? */
 185        if (fw_status_ready != idev->fw_status_ready) {
 186                struct ionic_lif *lif = ionic->lif;
 187                bool trigger = false;
 188
 189                idev->fw_status_ready = fw_status_ready;
 190
 191                if (!fw_status_ready) {
 192                        dev_info(ionic->dev, "FW stopped %u\n", fw_status);
 193                        if (lif && !test_bit(IONIC_LIF_F_FW_RESET, lif->state))
 194                                trigger = true;
 195                } else {
 196                        dev_info(ionic->dev, "FW running %u\n", fw_status);
 197                        if (lif && test_bit(IONIC_LIF_F_FW_RESET, lif->state))
 198                                trigger = true;
 199                }
 200
 201                if (trigger) {
 202                        struct ionic_deferred_work *work;
 203
 204                        work = kzalloc(sizeof(*work), GFP_ATOMIC);
 205                        if (work) {
 206                                work->type = IONIC_DW_TYPE_LIF_RESET;
 207                                work->fw_status = fw_status_ready;
 208                                ionic_lif_deferred_enqueue(&lif->deferred, work);
 209                        }
 210                }
 211        }
 212
 213        if (!fw_status_ready)
 214                return -ENXIO;
 215
 216        /* wait at least one watchdog period since the last heartbeat */
 217        last_check_time = idev->last_hb_time;
 218        if (time_before(check_time, last_check_time + ionic->watchdog_period))
 219                return 0;
 220
 221        fw_hb = ioread32(&idev->dev_info_regs->fw_heartbeat);
 222        fw_hb_ready = fw_hb != idev->last_fw_hb;
 223
 224        /* early FW version had no heartbeat, so fake it */
 225        if (!fw_hb_ready && !fw_hb)
 226                fw_hb_ready = true;
 227
 228        dev_dbg(ionic->dev, "%s: fw_hb %u last_fw_hb %u ready %u\n",
 229                __func__, fw_hb, idev->last_fw_hb, fw_hb_ready);
 230
 231        idev->last_fw_hb = fw_hb;
 232
 233        /* log a transition */
 234        if (fw_hb_ready != idev->fw_hb_ready) {
 235                idev->fw_hb_ready = fw_hb_ready;
 236                if (!fw_hb_ready)
 237                        dev_info(ionic->dev, "FW heartbeat stalled at %d\n", fw_hb);
 238                else
 239                        dev_info(ionic->dev, "FW heartbeat restored at %d\n", fw_hb);
 240        }
 241
 242        if (!fw_hb_ready)
 243                return -ENXIO;
 244
 245        idev->last_hb_time = check_time;
 246
 247        return 0;
 248}
 249
 250u8 ionic_dev_cmd_status(struct ionic_dev *idev)
 251{
 252        return ioread8(&idev->dev_cmd_regs->comp.comp.status);
 253}
 254
 255bool ionic_dev_cmd_done(struct ionic_dev *idev)
 256{
 257        return ioread32(&idev->dev_cmd_regs->done) & IONIC_DEV_CMD_DONE;
 258}
 259
 260void ionic_dev_cmd_comp(struct ionic_dev *idev, union ionic_dev_cmd_comp *comp)
 261{
 262        memcpy_fromio(comp, &idev->dev_cmd_regs->comp, sizeof(*comp));
 263}
 264
 265void ionic_dev_cmd_go(struct ionic_dev *idev, union ionic_dev_cmd *cmd)
 266{
 267        memcpy_toio(&idev->dev_cmd_regs->cmd, cmd, sizeof(*cmd));
 268        iowrite32(0, &idev->dev_cmd_regs->done);
 269        iowrite32(1, &idev->dev_cmd_regs->doorbell);
 270}
 271
 272/* Device commands */
 273void ionic_dev_cmd_identify(struct ionic_dev *idev, u8 ver)
 274{
 275        union ionic_dev_cmd cmd = {
 276                .identify.opcode = IONIC_CMD_IDENTIFY,
 277                .identify.ver = ver,
 278        };
 279
 280        ionic_dev_cmd_go(idev, &cmd);
 281}
 282
 283void ionic_dev_cmd_init(struct ionic_dev *idev)
 284{
 285        union ionic_dev_cmd cmd = {
 286                .init.opcode = IONIC_CMD_INIT,
 287                .init.type = 0,
 288        };
 289
 290        ionic_dev_cmd_go(idev, &cmd);
 291}
 292
 293void ionic_dev_cmd_reset(struct ionic_dev *idev)
 294{
 295        union ionic_dev_cmd cmd = {
 296                .reset.opcode = IONIC_CMD_RESET,
 297        };
 298
 299        ionic_dev_cmd_go(idev, &cmd);
 300}
 301
 302/* Port commands */
 303void ionic_dev_cmd_port_identify(struct ionic_dev *idev)
 304{
 305        union ionic_dev_cmd cmd = {
 306                .port_init.opcode = IONIC_CMD_PORT_IDENTIFY,
 307                .port_init.index = 0,
 308        };
 309
 310        ionic_dev_cmd_go(idev, &cmd);
 311}
 312
 313void ionic_dev_cmd_port_init(struct ionic_dev *idev)
 314{
 315        union ionic_dev_cmd cmd = {
 316                .port_init.opcode = IONIC_CMD_PORT_INIT,
 317                .port_init.index = 0,
 318                .port_init.info_pa = cpu_to_le64(idev->port_info_pa),
 319        };
 320
 321        ionic_dev_cmd_go(idev, &cmd);
 322}
 323
 324void ionic_dev_cmd_port_reset(struct ionic_dev *idev)
 325{
 326        union ionic_dev_cmd cmd = {
 327                .port_reset.opcode = IONIC_CMD_PORT_RESET,
 328                .port_reset.index = 0,
 329        };
 330
 331        ionic_dev_cmd_go(idev, &cmd);
 332}
 333
 334void ionic_dev_cmd_port_state(struct ionic_dev *idev, u8 state)
 335{
 336        union ionic_dev_cmd cmd = {
 337                .port_setattr.opcode = IONIC_CMD_PORT_SETATTR,
 338                .port_setattr.index = 0,
 339                .port_setattr.attr = IONIC_PORT_ATTR_STATE,
 340                .port_setattr.state = state,
 341        };
 342
 343        ionic_dev_cmd_go(idev, &cmd);
 344}
 345
 346void ionic_dev_cmd_port_speed(struct ionic_dev *idev, u32 speed)
 347{
 348        union ionic_dev_cmd cmd = {
 349                .port_setattr.opcode = IONIC_CMD_PORT_SETATTR,
 350                .port_setattr.index = 0,
 351                .port_setattr.attr = IONIC_PORT_ATTR_SPEED,
 352                .port_setattr.speed = cpu_to_le32(speed),
 353        };
 354
 355        ionic_dev_cmd_go(idev, &cmd);
 356}
 357
 358void ionic_dev_cmd_port_autoneg(struct ionic_dev *idev, u8 an_enable)
 359{
 360        union ionic_dev_cmd cmd = {
 361                .port_setattr.opcode = IONIC_CMD_PORT_SETATTR,
 362                .port_setattr.index = 0,
 363                .port_setattr.attr = IONIC_PORT_ATTR_AUTONEG,
 364                .port_setattr.an_enable = an_enable,
 365        };
 366
 367        ionic_dev_cmd_go(idev, &cmd);
 368}
 369
 370void ionic_dev_cmd_port_fec(struct ionic_dev *idev, u8 fec_type)
 371{
 372        union ionic_dev_cmd cmd = {
 373                .port_setattr.opcode = IONIC_CMD_PORT_SETATTR,
 374                .port_setattr.index = 0,
 375                .port_setattr.attr = IONIC_PORT_ATTR_FEC,
 376                .port_setattr.fec_type = fec_type,
 377        };
 378
 379        ionic_dev_cmd_go(idev, &cmd);
 380}
 381
 382void ionic_dev_cmd_port_pause(struct ionic_dev *idev, u8 pause_type)
 383{
 384        union ionic_dev_cmd cmd = {
 385                .port_setattr.opcode = IONIC_CMD_PORT_SETATTR,
 386                .port_setattr.index = 0,
 387                .port_setattr.attr = IONIC_PORT_ATTR_PAUSE,
 388                .port_setattr.pause_type = pause_type,
 389        };
 390
 391        ionic_dev_cmd_go(idev, &cmd);
 392}
 393
 394/* VF commands */
 395int ionic_set_vf_config(struct ionic *ionic, int vf, u8 attr, u8 *data)
 396{
 397        union ionic_dev_cmd cmd = {
 398                .vf_setattr.opcode = IONIC_CMD_VF_SETATTR,
 399                .vf_setattr.attr = attr,
 400                .vf_setattr.vf_index = cpu_to_le16(vf),
 401        };
 402        int err;
 403
 404        switch (attr) {
 405        case IONIC_VF_ATTR_SPOOFCHK:
 406                cmd.vf_setattr.spoofchk = *data;
 407                dev_dbg(ionic->dev, "%s: vf %d spoof %d\n",
 408                        __func__, vf, *data);
 409                break;
 410        case IONIC_VF_ATTR_TRUST:
 411                cmd.vf_setattr.trust = *data;
 412                dev_dbg(ionic->dev, "%s: vf %d trust %d\n",
 413                        __func__, vf, *data);
 414                break;
 415        case IONIC_VF_ATTR_LINKSTATE:
 416                cmd.vf_setattr.linkstate = *data;
 417                dev_dbg(ionic->dev, "%s: vf %d linkstate %d\n",
 418                        __func__, vf, *data);
 419                break;
 420        case IONIC_VF_ATTR_MAC:
 421                ether_addr_copy(cmd.vf_setattr.macaddr, data);
 422                dev_dbg(ionic->dev, "%s: vf %d macaddr %pM\n",
 423                        __func__, vf, data);
 424                break;
 425        case IONIC_VF_ATTR_VLAN:
 426                cmd.vf_setattr.vlanid = cpu_to_le16(*(u16 *)data);
 427                dev_dbg(ionic->dev, "%s: vf %d vlan %d\n",
 428                        __func__, vf, *(u16 *)data);
 429                break;
 430        case IONIC_VF_ATTR_RATE:
 431                cmd.vf_setattr.maxrate = cpu_to_le32(*(u32 *)data);
 432                dev_dbg(ionic->dev, "%s: vf %d maxrate %d\n",
 433                        __func__, vf, *(u32 *)data);
 434                break;
 435        case IONIC_VF_ATTR_STATSADDR:
 436                cmd.vf_setattr.stats_pa = cpu_to_le64(*(u64 *)data);
 437                dev_dbg(ionic->dev, "%s: vf %d stats_pa 0x%08llx\n",
 438                        __func__, vf, *(u64 *)data);
 439                break;
 440        default:
 441                return -EINVAL;
 442        }
 443
 444        mutex_lock(&ionic->dev_cmd_lock);
 445        ionic_dev_cmd_go(&ionic->idev, &cmd);
 446        err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
 447        mutex_unlock(&ionic->dev_cmd_lock);
 448
 449        return err;
 450}
 451
 452/* LIF commands */
 453void ionic_dev_cmd_queue_identify(struct ionic_dev *idev,
 454                                  u16 lif_type, u8 qtype, u8 qver)
 455{
 456        union ionic_dev_cmd cmd = {
 457                .q_identify.opcode = IONIC_CMD_Q_IDENTIFY,
 458                .q_identify.lif_type = cpu_to_le16(lif_type),
 459                .q_identify.type = qtype,
 460                .q_identify.ver = qver,
 461        };
 462
 463        ionic_dev_cmd_go(idev, &cmd);
 464}
 465
 466void ionic_dev_cmd_lif_identify(struct ionic_dev *idev, u8 type, u8 ver)
 467{
 468        union ionic_dev_cmd cmd = {
 469                .lif_identify.opcode = IONIC_CMD_LIF_IDENTIFY,
 470                .lif_identify.type = type,
 471                .lif_identify.ver = ver,
 472        };
 473
 474        ionic_dev_cmd_go(idev, &cmd);
 475}
 476
 477void ionic_dev_cmd_lif_init(struct ionic_dev *idev, u16 lif_index,
 478                            dma_addr_t info_pa)
 479{
 480        union ionic_dev_cmd cmd = {
 481                .lif_init.opcode = IONIC_CMD_LIF_INIT,
 482                .lif_init.index = cpu_to_le16(lif_index),
 483                .lif_init.info_pa = cpu_to_le64(info_pa),
 484        };
 485
 486        ionic_dev_cmd_go(idev, &cmd);
 487}
 488
 489void ionic_dev_cmd_lif_reset(struct ionic_dev *idev, u16 lif_index)
 490{
 491        union ionic_dev_cmd cmd = {
 492                .lif_init.opcode = IONIC_CMD_LIF_RESET,
 493                .lif_init.index = cpu_to_le16(lif_index),
 494        };
 495
 496        ionic_dev_cmd_go(idev, &cmd);
 497}
 498
 499void ionic_dev_cmd_adminq_init(struct ionic_dev *idev, struct ionic_qcq *qcq,
 500                               u16 lif_index, u16 intr_index)
 501{
 502        struct ionic_queue *q = &qcq->q;
 503        struct ionic_cq *cq = &qcq->cq;
 504
 505        union ionic_dev_cmd cmd = {
 506                .q_init.opcode = IONIC_CMD_Q_INIT,
 507                .q_init.lif_index = cpu_to_le16(lif_index),
 508                .q_init.type = q->type,
 509                .q_init.ver = qcq->q.lif->qtype_info[q->type].version,
 510                .q_init.index = cpu_to_le32(q->index),
 511                .q_init.flags = cpu_to_le16(IONIC_QINIT_F_IRQ |
 512                                            IONIC_QINIT_F_ENA),
 513                .q_init.pid = cpu_to_le16(q->pid),
 514                .q_init.intr_index = cpu_to_le16(intr_index),
 515                .q_init.ring_size = ilog2(q->num_descs),
 516                .q_init.ring_base = cpu_to_le64(q->base_pa),
 517                .q_init.cq_ring_base = cpu_to_le64(cq->base_pa),
 518        };
 519
 520        ionic_dev_cmd_go(idev, &cmd);
 521}
 522
 523int ionic_db_page_num(struct ionic_lif *lif, int pid)
 524{
 525        return (lif->hw_index * lif->dbid_count) + pid;
 526}
 527
 528int ionic_cq_init(struct ionic_lif *lif, struct ionic_cq *cq,
 529                  struct ionic_intr_info *intr,
 530                  unsigned int num_descs, size_t desc_size)
 531{
 532        unsigned int ring_size;
 533
 534        if (desc_size == 0 || !is_power_of_2(num_descs))
 535                return -EINVAL;
 536
 537        ring_size = ilog2(num_descs);
 538        if (ring_size < 2 || ring_size > 16)
 539                return -EINVAL;
 540
 541        cq->lif = lif;
 542        cq->bound_intr = intr;
 543        cq->num_descs = num_descs;
 544        cq->desc_size = desc_size;
 545        cq->tail_idx = 0;
 546        cq->done_color = 1;
 547
 548        return 0;
 549}
 550
 551void ionic_cq_map(struct ionic_cq *cq, void *base, dma_addr_t base_pa)
 552{
 553        struct ionic_cq_info *cur;
 554        unsigned int i;
 555
 556        cq->base = base;
 557        cq->base_pa = base_pa;
 558
 559        for (i = 0, cur = cq->info; i < cq->num_descs; i++, cur++)
 560                cur->cq_desc = base + (i * cq->desc_size);
 561}
 562
 563void ionic_cq_bind(struct ionic_cq *cq, struct ionic_queue *q)
 564{
 565        cq->bound_q = q;
 566}
 567
 568unsigned int ionic_cq_service(struct ionic_cq *cq, unsigned int work_to_do,
 569                              ionic_cq_cb cb, ionic_cq_done_cb done_cb,
 570                              void *done_arg)
 571{
 572        struct ionic_cq_info *cq_info;
 573        unsigned int work_done = 0;
 574
 575        if (work_to_do == 0)
 576                return 0;
 577
 578        cq_info = &cq->info[cq->tail_idx];
 579        while (cb(cq, cq_info)) {
 580                if (cq->tail_idx == cq->num_descs - 1)
 581                        cq->done_color = !cq->done_color;
 582                cq->tail_idx = (cq->tail_idx + 1) & (cq->num_descs - 1);
 583                cq_info = &cq->info[cq->tail_idx];
 584                DEBUG_STATS_CQE_CNT(cq);
 585
 586                if (++work_done >= work_to_do)
 587                        break;
 588        }
 589
 590        if (work_done && done_cb)
 591                done_cb(done_arg);
 592
 593        return work_done;
 594}
 595
 596int ionic_q_init(struct ionic_lif *lif, struct ionic_dev *idev,
 597                 struct ionic_queue *q, unsigned int index, const char *name,
 598                 unsigned int num_descs, size_t desc_size,
 599                 size_t sg_desc_size, unsigned int pid)
 600{
 601        unsigned int ring_size;
 602
 603        if (desc_size == 0 || !is_power_of_2(num_descs))
 604                return -EINVAL;
 605
 606        ring_size = ilog2(num_descs);
 607        if (ring_size < 2 || ring_size > 16)
 608                return -EINVAL;
 609
 610        q->lif = lif;
 611        q->idev = idev;
 612        q->index = index;
 613        q->num_descs = num_descs;
 614        q->desc_size = desc_size;
 615        q->sg_desc_size = sg_desc_size;
 616        q->tail_idx = 0;
 617        q->head_idx = 0;
 618        q->pid = pid;
 619
 620        snprintf(q->name, sizeof(q->name), "L%d-%s%u", lif->index, name, index);
 621
 622        return 0;
 623}
 624
 625void ionic_q_map(struct ionic_queue *q, void *base, dma_addr_t base_pa)
 626{
 627        struct ionic_desc_info *cur;
 628        unsigned int i;
 629
 630        q->base = base;
 631        q->base_pa = base_pa;
 632
 633        for (i = 0, cur = q->info; i < q->num_descs; i++, cur++)
 634                cur->desc = base + (i * q->desc_size);
 635}
 636
 637void ionic_q_sg_map(struct ionic_queue *q, void *base, dma_addr_t base_pa)
 638{
 639        struct ionic_desc_info *cur;
 640        unsigned int i;
 641
 642        q->sg_base = base;
 643        q->sg_base_pa = base_pa;
 644
 645        for (i = 0, cur = q->info; i < q->num_descs; i++, cur++)
 646                cur->sg_desc = base + (i * q->sg_desc_size);
 647}
 648
 649void ionic_q_post(struct ionic_queue *q, bool ring_doorbell, ionic_desc_cb cb,
 650                  void *cb_arg)
 651{
 652        struct ionic_desc_info *desc_info;
 653        struct ionic_lif *lif = q->lif;
 654        struct device *dev = q->dev;
 655
 656        desc_info = &q->info[q->head_idx];
 657        desc_info->cb = cb;
 658        desc_info->cb_arg = cb_arg;
 659
 660        q->head_idx = (q->head_idx + 1) & (q->num_descs - 1);
 661
 662        dev_dbg(dev, "lif=%d qname=%s qid=%d qtype=%d p_index=%d ringdb=%d\n",
 663                q->lif->index, q->name, q->hw_type, q->hw_index,
 664                q->head_idx, ring_doorbell);
 665
 666        if (ring_doorbell)
 667                ionic_dbell_ring(lif->kern_dbpage, q->hw_type,
 668                                 q->dbval | q->head_idx);
 669}
 670
 671static bool ionic_q_is_posted(struct ionic_queue *q, unsigned int pos)
 672{
 673        unsigned int mask, tail, head;
 674
 675        mask = q->num_descs - 1;
 676        tail = q->tail_idx;
 677        head = q->head_idx;
 678
 679        return ((pos - tail) & mask) < ((head - tail) & mask);
 680}
 681
 682void ionic_q_service(struct ionic_queue *q, struct ionic_cq_info *cq_info,
 683                     unsigned int stop_index)
 684{
 685        struct ionic_desc_info *desc_info;
 686        ionic_desc_cb cb;
 687        void *cb_arg;
 688        u16 index;
 689
 690        /* check for empty queue */
 691        if (q->tail_idx == q->head_idx)
 692                return;
 693
 694        /* stop index must be for a descriptor that is not yet completed */
 695        if (unlikely(!ionic_q_is_posted(q, stop_index)))
 696                dev_err(q->dev,
 697                        "ionic stop is not posted %s stop %u tail %u head %u\n",
 698                        q->name, stop_index, q->tail_idx, q->head_idx);
 699
 700        do {
 701                desc_info = &q->info[q->tail_idx];
 702                index = q->tail_idx;
 703                q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
 704
 705                cb = desc_info->cb;
 706                cb_arg = desc_info->cb_arg;
 707
 708                desc_info->cb = NULL;
 709                desc_info->cb_arg = NULL;
 710
 711                if (cb)
 712                        cb(q, desc_info, cq_info, cb_arg);
 713        } while (index != stop_index);
 714}
 715