linux/drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3 * Huawei HiNIC PCI Express Linux driver
   4 * Copyright(c) 2017 Huawei Technologies Co., Ltd
   5 */
   6
   7#ifndef HINIC_HW_EQS_H
   8#define HINIC_HW_EQS_H
   9
  10#include <linux/types.h>
  11#include <linux/workqueue.h>
  12#include <linux/pci.h>
  13#include <linux/sizes.h>
  14#include <linux/bitops.h>
  15#include <linux/interrupt.h>
  16
  17#include "hinic_hw_if.h"
  18
  19#define HINIC_AEQ_CTRL_0_INT_IDX_SHIFT          0
  20#define HINIC_AEQ_CTRL_0_DMA_ATTR_SHIFT         12
  21#define HINIC_AEQ_CTRL_0_PCI_INTF_IDX_SHIFT     20
  22#define HINIC_AEQ_CTRL_0_INT_MODE_SHIFT         31
  23
  24#define HINIC_AEQ_CTRL_0_INT_IDX_MASK           0x3FF
  25#define HINIC_AEQ_CTRL_0_DMA_ATTR_MASK          0x3F
  26#define HINIC_AEQ_CTRL_0_PCI_INTF_IDX_MASK      0x3
  27#define HINIC_AEQ_CTRL_0_INT_MODE_MASK          0x1
  28
  29#define HINIC_AEQ_CTRL_0_SET(val, member)       \
  30                        (((u32)(val) & HINIC_AEQ_CTRL_0_##member##_MASK) << \
  31                         HINIC_AEQ_CTRL_0_##member##_SHIFT)
  32
  33#define HINIC_AEQ_CTRL_0_CLEAR(val, member)     \
  34                        ((val) & (~(HINIC_AEQ_CTRL_0_##member##_MASK \
  35                         << HINIC_AEQ_CTRL_0_##member##_SHIFT)))
  36
  37#define HINIC_AEQ_CTRL_1_LEN_SHIFT              0
  38#define HINIC_AEQ_CTRL_1_ELEM_SIZE_SHIFT        24
  39#define HINIC_AEQ_CTRL_1_PAGE_SIZE_SHIFT        28
  40
  41#define HINIC_AEQ_CTRL_1_LEN_MASK               0x1FFFFF
  42#define HINIC_AEQ_CTRL_1_ELEM_SIZE_MASK         0x3
  43#define HINIC_AEQ_CTRL_1_PAGE_SIZE_MASK         0xF
  44
  45#define HINIC_AEQ_CTRL_1_SET(val, member)       \
  46                        (((u32)(val) & HINIC_AEQ_CTRL_1_##member##_MASK) << \
  47                         HINIC_AEQ_CTRL_1_##member##_SHIFT)
  48
  49#define HINIC_AEQ_CTRL_1_CLEAR(val, member)     \
  50                        ((val) & (~(HINIC_AEQ_CTRL_1_##member##_MASK \
  51                         << HINIC_AEQ_CTRL_1_##member##_SHIFT)))
  52
  53#define HINIC_CEQ_CTRL_0_INTR_IDX_SHIFT         0
  54#define HINIC_CEQ_CTRL_0_DMA_ATTR_SHIFT         12
  55#define HINIC_CEQ_CTRL_0_KICK_THRESH_SHIFT      20
  56#define HINIC_CEQ_CTRL_0_PCI_INTF_IDX_SHIFT     24
  57#define HINIC_CEQ_CTRL_0_INTR_MODE_SHIFT        31
  58
  59#define HINIC_CEQ_CTRL_0_INTR_IDX_MASK          0x3FF
  60#define HINIC_CEQ_CTRL_0_DMA_ATTR_MASK          0x3F
  61#define HINIC_CEQ_CTRL_0_KICK_THRESH_MASK       0xF
  62#define HINIC_CEQ_CTRL_0_PCI_INTF_IDX_MASK      0x3
  63#define HINIC_CEQ_CTRL_0_INTR_MODE_MASK         0x1
  64
  65#define HINIC_CEQ_CTRL_0_SET(val, member)       \
  66                        (((u32)(val) & HINIC_CEQ_CTRL_0_##member##_MASK) << \
  67                         HINIC_CEQ_CTRL_0_##member##_SHIFT)
  68
  69#define HINIC_CEQ_CTRL_0_CLEAR(val, member)     \
  70                        ((val) & (~(HINIC_CEQ_CTRL_0_##member##_MASK \
  71                         << HINIC_CEQ_CTRL_0_##member##_SHIFT)))
  72
  73#define HINIC_CEQ_CTRL_1_LEN_SHIFT              0
  74#define HINIC_CEQ_CTRL_1_PAGE_SIZE_SHIFT        28
  75
  76#define HINIC_CEQ_CTRL_1_LEN_MASK               0x1FFFFF
  77#define HINIC_CEQ_CTRL_1_PAGE_SIZE_MASK         0xF
  78
  79#define HINIC_CEQ_CTRL_1_SET(val, member)       \
  80                        (((u32)(val) & HINIC_CEQ_CTRL_1_##member##_MASK) << \
  81                         HINIC_CEQ_CTRL_1_##member##_SHIFT)
  82
  83#define HINIC_CEQ_CTRL_1_CLEAR(val, member)     \
  84                        ((val) & (~(HINIC_CEQ_CTRL_1_##member##_MASK \
  85                         << HINIC_CEQ_CTRL_1_##member##_SHIFT)))
  86
  87#define HINIC_EQ_ELEM_DESC_TYPE_SHIFT           0
  88#define HINIC_EQ_ELEM_DESC_SRC_SHIFT            7
  89#define HINIC_EQ_ELEM_DESC_SIZE_SHIFT           8
  90#define HINIC_EQ_ELEM_DESC_WRAPPED_SHIFT        31
  91
  92#define HINIC_EQ_ELEM_DESC_TYPE_MASK            0x7F
  93#define HINIC_EQ_ELEM_DESC_SRC_MASK             0x1
  94#define HINIC_EQ_ELEM_DESC_SIZE_MASK            0xFF
  95#define HINIC_EQ_ELEM_DESC_WRAPPED_MASK         0x1
  96
  97#define HINIC_EQ_ELEM_DESC_SET(val, member)     \
  98                        (((u32)(val) & HINIC_EQ_ELEM_DESC_##member##_MASK) << \
  99                         HINIC_EQ_ELEM_DESC_##member##_SHIFT)
 100
 101#define HINIC_EQ_ELEM_DESC_GET(val, member)     \
 102                        (((val) >> HINIC_EQ_ELEM_DESC_##member##_SHIFT) & \
 103                         HINIC_EQ_ELEM_DESC_##member##_MASK)
 104
 105#define HINIC_EQ_CI_IDX_SHIFT                   0
 106#define HINIC_EQ_CI_WRAPPED_SHIFT               20
 107#define HINIC_EQ_CI_XOR_CHKSUM_SHIFT            24
 108#define HINIC_EQ_CI_INT_ARMED_SHIFT             31
 109
 110#define HINIC_EQ_CI_IDX_MASK                    0xFFFFF
 111#define HINIC_EQ_CI_WRAPPED_MASK                0x1
 112#define HINIC_EQ_CI_XOR_CHKSUM_MASK             0xF
 113#define HINIC_EQ_CI_INT_ARMED_MASK              0x1
 114
 115#define HINIC_EQ_CI_SET(val, member)            \
 116                        (((u32)(val) & HINIC_EQ_CI_##member##_MASK) << \
 117                         HINIC_EQ_CI_##member##_SHIFT)
 118
 119#define HINIC_EQ_CI_CLEAR(val, member)          \
 120                        ((val) & (~(HINIC_EQ_CI_##member##_MASK \
 121                         << HINIC_EQ_CI_##member##_SHIFT)))
 122
 123#define HINIC_MAX_AEQS                  4
 124#define HINIC_MAX_CEQS                  32
 125
 126#define HINIC_AEQE_SIZE                 64
 127#define HINIC_CEQE_SIZE                 4
 128
 129#define HINIC_AEQE_DESC_SIZE            4
 130#define HINIC_AEQE_DATA_SIZE            \
 131                        (HINIC_AEQE_SIZE - HINIC_AEQE_DESC_SIZE)
 132
 133#define HINIC_DEFAULT_AEQ_LEN           64
 134#define HINIC_DEFAULT_CEQ_LEN           1024
 135
 136#define HINIC_EQ_PAGE_SIZE              SZ_4K
 137
 138#define HINIC_CEQ_ID_CMDQ               0
 139
 140enum hinic_eq_type {
 141        HINIC_AEQ,
 142        HINIC_CEQ,
 143};
 144
 145enum hinic_aeq_type {
 146        HINIC_MBX_FROM_FUNC = 1,
 147        HINIC_MSG_FROM_MGMT_CPU = 2,
 148        HINIC_MBX_SEND_RSLT = 5,
 149        HINIC_MAX_AEQ_EVENTS,
 150};
 151
 152enum hinic_ceq_type {
 153        HINIC_CEQ_CMDQ = 3,
 154
 155        HINIC_MAX_CEQ_EVENTS,
 156};
 157
 158enum hinic_eqe_state {
 159        HINIC_EQE_ENABLED = BIT(0),
 160        HINIC_EQE_RUNNING = BIT(1),
 161};
 162
 163struct hinic_aeq_elem {
 164        u8      data[HINIC_AEQE_DATA_SIZE];
 165        __be32  desc;
 166};
 167
 168struct hinic_eq_work {
 169        struct work_struct      work;
 170        void                    *data;
 171};
 172
 173struct hinic_eq {
 174        struct hinic_hwif       *hwif;
 175        struct hinic_hwdev      *hwdev;
 176        enum hinic_eq_type      type;
 177        int                     q_id;
 178        u32                     q_len;
 179        u32                     page_size;
 180
 181        u32                     cons_idx;
 182        int                     wrapped;
 183
 184        size_t                  elem_size;
 185        int                     num_pages;
 186        int                     num_elem_in_pg;
 187
 188        struct msix_entry       msix_entry;
 189        char                    irq_name[64];
 190
 191        dma_addr_t              *dma_addr;
 192        void                    **virt_addr;
 193
 194        struct hinic_eq_work    aeq_work;
 195
 196        struct tasklet_struct   ceq_tasklet;
 197};
 198
 199struct hinic_hw_event_cb {
 200        void    (*hwe_handler)(void *handle, void *data, u8 size);
 201        void                    *handle;
 202        unsigned long           hwe_state;
 203};
 204
 205struct hinic_aeqs {
 206        struct hinic_hwif       *hwif;
 207
 208        struct hinic_eq         aeq[HINIC_MAX_AEQS];
 209        int                     num_aeqs;
 210
 211        struct hinic_hw_event_cb hwe_cb[HINIC_MAX_AEQ_EVENTS];
 212
 213        struct workqueue_struct *workq;
 214};
 215
 216struct hinic_ceq_cb {
 217        void    (*handler)(void *handle, u32 ceqe_data);
 218        void                    *handle;
 219        enum hinic_eqe_state    ceqe_state;
 220};
 221
 222struct hinic_ceqs {
 223        struct hinic_hwif       *hwif;
 224        struct hinic_hwdev              *hwdev;
 225        struct hinic_eq         ceq[HINIC_MAX_CEQS];
 226        int                     num_ceqs;
 227
 228        struct hinic_ceq_cb     ceq_cb[HINIC_MAX_CEQ_EVENTS];
 229};
 230
 231void hinic_aeq_register_hw_cb(struct hinic_aeqs *aeqs,
 232                              enum hinic_aeq_type event, void *handle,
 233                              void (*hwe_handler)(void *handle, void *data,
 234                                                  u8 size));
 235
 236void hinic_aeq_unregister_hw_cb(struct hinic_aeqs *aeqs,
 237                                enum hinic_aeq_type event);
 238
 239void hinic_ceq_register_cb(struct hinic_ceqs *ceqs,
 240                           enum hinic_ceq_type event, void *handle,
 241                           void (*ceq_cb)(void *handle, u32 ceqe_data));
 242
 243void hinic_ceq_unregister_cb(struct hinic_ceqs *ceqs,
 244                             enum hinic_ceq_type event);
 245
 246int hinic_aeqs_init(struct hinic_aeqs *aeqs, struct hinic_hwif *hwif,
 247                    int num_aeqs, u32 q_len, u32 page_size,
 248                    struct msix_entry *msix_entries);
 249
 250void hinic_aeqs_free(struct hinic_aeqs *aeqs);
 251
 252int hinic_ceqs_init(struct hinic_ceqs *ceqs, struct hinic_hwif *hwif,
 253                    int num_ceqs, u32 q_len, u32 page_size,
 254                    struct msix_entry *msix_entries);
 255
 256void hinic_ceqs_free(struct hinic_ceqs *ceqs);
 257
 258void hinic_dump_ceq_info(struct hinic_hwdev *hwdev);
 259
 260void hinic_dump_aeq_info(struct hinic_hwdev *hwdev);
 261
 262#endif
 263