linux/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
<<
>>
Prefs
   1/*
   2 * Broadcom NetXtreme-E RoCE driver.
   3 *
   4 * Copyright (c) 2016 - 2017, Broadcom. All rights reserved.  The term
   5 * Broadcom refers to Broadcom Limited and/or its subsidiaries.
   6 *
   7 * This software is available to you under a choice of one of two
   8 * licenses.  You may choose to be licensed under the terms of the GNU
   9 * General Public License (GPL) Version 2, available from the file
  10 * COPYING in the main directory of this source tree, or the
  11 * BSD license below:
  12 *
  13 * Redistribution and use in source and binary forms, with or without
  14 * modification, are permitted provided that the following conditions
  15 * are met:
  16 *
  17 * 1. Redistributions of source code must retain the above copyright
  18 *    notice, this list of conditions and the following disclaimer.
  19 * 2. Redistributions in binary form must reproduce the above copyright
  20 *    notice, this list of conditions and the following disclaimer in
  21 *    the documentation and/or other materials provided with the
  22 *    distribution.
  23 *
  24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
  25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  26 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  27 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
  28 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  31 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  32 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  33 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  34 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35 *
  36 * Description: RDMA Controller HW interface (header)
  37 */
  38
  39#ifndef __BNXT_QPLIB_RCFW_H__
  40#define __BNXT_QPLIB_RCFW_H__
  41
  42#define RCFW_CMDQ_TRIG_VAL              1
  43#define RCFW_COMM_PCI_BAR_REGION        0
  44#define RCFW_COMM_CONS_PCI_BAR_REGION   2
  45#define RCFW_COMM_BASE_OFFSET           0x600
  46#define RCFW_PF_COMM_PROD_OFFSET        0xc
  47#define RCFW_VF_COMM_PROD_OFFSET        0xc
  48#define RCFW_COMM_TRIG_OFFSET           0x100
  49#define RCFW_COMM_SIZE                  0x104
  50
  51#define RCFW_DBR_PCI_BAR_REGION         2
  52#define RCFW_DBR_BASE_PAGE_SHIFT        12
  53
  54#define RCFW_CMD_PREP(req, CMD, cmd_flags)                              \
  55        do {                                                            \
  56                memset(&(req), 0, sizeof((req)));                       \
  57                (req).opcode = CMDQ_BASE_OPCODE_##CMD;                  \
  58                (req).cmd_size = sizeof((req));                         \
  59                (req).flags = cpu_to_le16(cmd_flags);                   \
  60        } while (0)
  61
  62#define RCFW_CMD_WAIT_TIME_MS           20000 /* 20 Seconds timeout */
  63
  64/* Cmdq contains a fix number of a 16-Byte slots */
  65struct bnxt_qplib_cmdqe {
  66        u8              data[16];
  67};
  68
  69/* CMDQ elements */
  70#define BNXT_QPLIB_CMDQE_MAX_CNT_256    256
  71#define BNXT_QPLIB_CMDQE_MAX_CNT_8192   8192
  72#define BNXT_QPLIB_CMDQE_UNITS          sizeof(struct bnxt_qplib_cmdqe)
  73#define BNXT_QPLIB_CMDQE_BYTES(depth)   ((depth) * BNXT_QPLIB_CMDQE_UNITS)
  74
  75static inline u32 bnxt_qplib_cmdqe_npages(u32 depth)
  76{
  77        u32 npages;
  78
  79        npages = BNXT_QPLIB_CMDQE_BYTES(depth) / PAGE_SIZE;
  80        if (BNXT_QPLIB_CMDQE_BYTES(depth) % PAGE_SIZE)
  81                npages++;
  82        return npages;
  83}
  84
  85static inline u32 bnxt_qplib_cmdqe_page_size(u32 depth)
  86{
  87        return (bnxt_qplib_cmdqe_npages(depth) * PAGE_SIZE);
  88}
  89
  90/* Set the cmd_size to a factor of CMDQE unit */
  91static inline void bnxt_qplib_set_cmd_slots(struct cmdq_base *req)
  92{
  93        req->cmd_size = (req->cmd_size + BNXT_QPLIB_CMDQE_UNITS - 1) /
  94                         BNXT_QPLIB_CMDQE_UNITS;
  95}
  96
  97#define RCFW_MAX_COOKIE_VALUE           0x7FFF
  98#define RCFW_CMD_IS_BLOCKING            0x8000
  99#define RCFW_BLOCKED_CMD_WAIT_COUNT     0x4E20
 100
 101#define HWRM_VERSION_RCFW_CMDQ_DEPTH_CHECK 0x1000900020011ULL
 102
 103/* Crsq buf is 1024-Byte */
 104struct bnxt_qplib_crsbe {
 105        u8                      data[1024];
 106};
 107
 108/* CREQ */
 109/* Allocate 1 per QP for async error notification for now */
 110#define BNXT_QPLIB_CREQE_MAX_CNT        (64 * 1024)
 111#define BNXT_QPLIB_CREQE_UNITS          16      /* 16-Bytes per prod unit */
 112#define CREQ_CMP_VALID(hdr, raw_cons, cp_bit)                   \
 113        (!!((hdr)->v & CREQ_BASE_V) ==                          \
 114           !((raw_cons) & (cp_bit)))
 115#define CREQ_ENTRY_POLL_BUDGET          0x100
 116
 117/* HWQ */
 118typedef int (*aeq_handler_t)(struct bnxt_qplib_rcfw *, void *, void *);
 119
 120struct bnxt_qplib_crsqe {
 121        struct creq_qp_event    *resp;
 122        u32                     req_size;
 123};
 124
 125struct bnxt_qplib_rcfw_sbuf {
 126        void *sb;
 127        dma_addr_t dma_addr;
 128        u32 size;
 129};
 130
 131struct bnxt_qplib_qp_node {
 132        u32 qp_id;              /* QP id */
 133        void *qp_handle;        /* ptr to qplib_qp */
 134};
 135
 136#define BNXT_QPLIB_OOS_COUNT_MASK 0xFFFFFFFF
 137
 138#define FIRMWARE_INITIALIZED_FLAG       (0)
 139#define FIRMWARE_FIRST_FLAG             (31)
 140#define FIRMWARE_TIMED_OUT              (3)
 141#define ERR_DEVICE_DETACHED             (4)
 142
 143struct bnxt_qplib_cmdq_mbox {
 144        struct bnxt_qplib_reg_desc      reg;
 145        void __iomem                    *prod;
 146        void __iomem                    *db;
 147};
 148
 149struct bnxt_qplib_cmdq_ctx {
 150        struct bnxt_qplib_hwq           hwq;
 151        struct bnxt_qplib_cmdq_mbox     cmdq_mbox;
 152        wait_queue_head_t               waitq;
 153        unsigned long                   flags;
 154        unsigned long                   *cmdq_bitmap;
 155        u32                             bmap_size;
 156        u32                             seq_num;
 157};
 158
 159struct bnxt_qplib_creq_db {
 160        struct bnxt_qplib_reg_desc      reg;
 161        struct bnxt_qplib_db_info       dbinfo;
 162};
 163
 164struct bnxt_qplib_creq_stat {
 165        u64     creq_qp_event_processed;
 166        u64     creq_func_event_processed;
 167};
 168
 169struct bnxt_qplib_creq_ctx {
 170        struct bnxt_qplib_hwq           hwq;
 171        struct bnxt_qplib_creq_db       creq_db;
 172        struct bnxt_qplib_creq_stat     stats;
 173        struct tasklet_struct           creq_tasklet;
 174        aeq_handler_t                   aeq_handler;
 175        u16                             ring_id;
 176        int                             msix_vec;
 177        bool                            requested; /*irq handler installed */
 178};
 179
 180/* RCFW Communication Channels */
 181struct bnxt_qplib_rcfw {
 182        struct pci_dev          *pdev;
 183        struct bnxt_qplib_res   *res;
 184        struct bnxt_qplib_cmdq_ctx      cmdq;
 185        struct bnxt_qplib_creq_ctx      creq;
 186        struct bnxt_qplib_crsqe         *crsqe_tbl;
 187        int qp_tbl_size;
 188        struct bnxt_qplib_qp_node *qp_tbl;
 189        u64 oos_prev;
 190        u32 init_oos_stats;
 191        u32 cmdq_depth;
 192};
 193
 194void bnxt_qplib_free_rcfw_channel(struct bnxt_qplib_rcfw *rcfw);
 195int bnxt_qplib_alloc_rcfw_channel(struct bnxt_qplib_res *res,
 196                                  struct bnxt_qplib_rcfw *rcfw,
 197                                  struct bnxt_qplib_ctx *ctx,
 198                                  int qp_tbl_sz);
 199void bnxt_qplib_rcfw_stop_irq(struct bnxt_qplib_rcfw *rcfw, bool kill);
 200void bnxt_qplib_disable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw);
 201int bnxt_qplib_rcfw_start_irq(struct bnxt_qplib_rcfw *rcfw, int msix_vector,
 202                              bool need_init);
 203int bnxt_qplib_enable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw,
 204                                   int msix_vector,
 205                                   int cp_bar_reg_off, int virt_fn,
 206                                   aeq_handler_t aeq_handler);
 207
 208struct bnxt_qplib_rcfw_sbuf *bnxt_qplib_rcfw_alloc_sbuf(
 209                                struct bnxt_qplib_rcfw *rcfw,
 210                                u32 size);
 211void bnxt_qplib_rcfw_free_sbuf(struct bnxt_qplib_rcfw *rcfw,
 212                               struct bnxt_qplib_rcfw_sbuf *sbuf);
 213int bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw,
 214                                 struct cmdq_base *req, struct creq_base *resp,
 215                                 void *sbuf, u8 is_block);
 216
 217int bnxt_qplib_deinit_rcfw(struct bnxt_qplib_rcfw *rcfw);
 218int bnxt_qplib_init_rcfw(struct bnxt_qplib_rcfw *rcfw,
 219                         struct bnxt_qplib_ctx *ctx, int is_virtfn);
 220void bnxt_qplib_mark_qp_error(void *qp_handle);
 221static inline u32 map_qp_id_to_tbl_indx(u32 qid, struct bnxt_qplib_rcfw *rcfw)
 222{
 223        /* Last index of the qp_tbl is for QP1 ie. qp_tbl_size - 1*/
 224        return (qid == 1) ? rcfw->qp_tbl_size - 1 : qid % rcfw->qp_tbl_size - 2;
 225}
 226#endif /* __BNXT_QPLIB_RCFW_H__ */
 227