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_MSG_FROM_MGMT_CPU = 2,
 147
 148        HINIC_MAX_AEQ_EVENTS,
 149};
 150
 151enum hinic_ceq_type {
 152        HINIC_CEQ_CMDQ = 3,
 153
 154        HINIC_MAX_CEQ_EVENTS,
 155};
 156
 157enum hinic_eqe_state {
 158        HINIC_EQE_ENABLED = BIT(0),
 159        HINIC_EQE_RUNNING = BIT(1),
 160};
 161
 162struct hinic_aeq_elem {
 163        u8      data[HINIC_AEQE_DATA_SIZE];
 164        u32     desc;
 165};
 166
 167struct hinic_eq_work {
 168        struct work_struct      work;
 169        void                    *data;
 170};
 171
 172struct hinic_eq {
 173        struct hinic_hwif       *hwif;
 174
 175        enum hinic_eq_type      type;
 176        int                     q_id;
 177        u32                     q_len;
 178        u32                     page_size;
 179
 180        u32                     cons_idx;
 181        int                     wrapped;
 182
 183        size_t                  elem_size;
 184        int                     num_pages;
 185        int                     num_elem_in_pg;
 186
 187        struct msix_entry       msix_entry;
 188
 189        dma_addr_t              *dma_addr;
 190        void                    **virt_addr;
 191
 192        struct hinic_eq_work    aeq_work;
 193
 194        struct tasklet_struct   ceq_tasklet;
 195};
 196
 197struct hinic_hw_event_cb {
 198        void    (*hwe_handler)(void *handle, void *data, u8 size);
 199        void                    *handle;
 200        unsigned long           hwe_state;
 201};
 202
 203struct hinic_aeqs {
 204        struct hinic_hwif       *hwif;
 205
 206        struct hinic_eq         aeq[HINIC_MAX_AEQS];
 207        int                     num_aeqs;
 208
 209        struct hinic_hw_event_cb hwe_cb[HINIC_MAX_AEQ_EVENTS];
 210
 211        struct workqueue_struct *workq;
 212};
 213
 214struct hinic_ceq_cb {
 215        void    (*handler)(void *handle, u32 ceqe_data);
 216        void                    *handle;
 217        enum hinic_eqe_state    ceqe_state;
 218};
 219
 220struct hinic_ceqs {
 221        struct hinic_hwif       *hwif;
 222
 223        struct hinic_eq         ceq[HINIC_MAX_CEQS];
 224        int                     num_ceqs;
 225
 226        struct hinic_ceq_cb     ceq_cb[HINIC_MAX_CEQ_EVENTS];
 227};
 228
 229void hinic_aeq_register_hw_cb(struct hinic_aeqs *aeqs,
 230                              enum hinic_aeq_type event, void *handle,
 231                              void (*hwe_handler)(void *handle, void *data,
 232                                                  u8 size));
 233
 234void hinic_aeq_unregister_hw_cb(struct hinic_aeqs *aeqs,
 235                                enum hinic_aeq_type event);
 236
 237void hinic_ceq_register_cb(struct hinic_ceqs *ceqs,
 238                           enum hinic_ceq_type event, void *handle,
 239                           void (*ceq_cb)(void *handle, u32 ceqe_data));
 240
 241void hinic_ceq_unregister_cb(struct hinic_ceqs *ceqs,
 242                             enum hinic_ceq_type event);
 243
 244int hinic_aeqs_init(struct hinic_aeqs *aeqs, struct hinic_hwif *hwif,
 245                    int num_aeqs, u32 q_len, u32 page_size,
 246                    struct msix_entry *msix_entries);
 247
 248void hinic_aeqs_free(struct hinic_aeqs *aeqs);
 249
 250int hinic_ceqs_init(struct hinic_ceqs *ceqs, struct hinic_hwif *hwif,
 251                    int num_ceqs, u32 q_len, u32 page_size,
 252                    struct msix_entry *msix_entries);
 253
 254void hinic_ceqs_free(struct hinic_ceqs *ceqs);
 255
 256#endif
 257