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