263 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * Huawei HiNIC PCI Express Linux driver4 * Copyright(c) 2017 Huawei Technologies Co., Ltd5 */6 7#ifndef HINIC_HW_EQS_H8#define HINIC_HW_EQS_H9 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 020#define HINIC_AEQ_CTRL_0_DMA_ATTR_SHIFT 1221#define HINIC_AEQ_CTRL_0_PCI_INTF_IDX_SHIFT 2022#define HINIC_AEQ_CTRL_0_INT_MODE_SHIFT 3123 24#define HINIC_AEQ_CTRL_0_INT_IDX_MASK 0x3FF25#define HINIC_AEQ_CTRL_0_DMA_ATTR_MASK 0x3F26#define HINIC_AEQ_CTRL_0_PCI_INTF_IDX_MASK 0x327#define HINIC_AEQ_CTRL_0_INT_MODE_MASK 0x128 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 038#define HINIC_AEQ_CTRL_1_ELEM_SIZE_SHIFT 2439#define HINIC_AEQ_CTRL_1_PAGE_SIZE_SHIFT 2840 41#define HINIC_AEQ_CTRL_1_LEN_MASK 0x1FFFFF42#define HINIC_AEQ_CTRL_1_ELEM_SIZE_MASK 0x343#define HINIC_AEQ_CTRL_1_PAGE_SIZE_MASK 0xF44 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 054#define HINIC_CEQ_CTRL_0_DMA_ATTR_SHIFT 1255#define HINIC_CEQ_CTRL_0_KICK_THRESH_SHIFT 2056#define HINIC_CEQ_CTRL_0_PCI_INTF_IDX_SHIFT 2457#define HINIC_CEQ_CTRL_0_INTR_MODE_SHIFT 3158 59#define HINIC_CEQ_CTRL_0_INTR_IDX_MASK 0x3FF60#define HINIC_CEQ_CTRL_0_DMA_ATTR_MASK 0x3F61#define HINIC_CEQ_CTRL_0_KICK_THRESH_MASK 0xF62#define HINIC_CEQ_CTRL_0_PCI_INTF_IDX_MASK 0x363#define HINIC_CEQ_CTRL_0_INTR_MODE_MASK 0x164 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 074#define HINIC_CEQ_CTRL_1_PAGE_SIZE_SHIFT 2875 76#define HINIC_CEQ_CTRL_1_LEN_MASK 0x1FFFFF77#define HINIC_CEQ_CTRL_1_PAGE_SIZE_MASK 0xF78 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 088#define HINIC_EQ_ELEM_DESC_SRC_SHIFT 789#define HINIC_EQ_ELEM_DESC_SIZE_SHIFT 890#define HINIC_EQ_ELEM_DESC_WRAPPED_SHIFT 3191 92#define HINIC_EQ_ELEM_DESC_TYPE_MASK 0x7F93#define HINIC_EQ_ELEM_DESC_SRC_MASK 0x194#define HINIC_EQ_ELEM_DESC_SIZE_MASK 0xFF95#define HINIC_EQ_ELEM_DESC_WRAPPED_MASK 0x196 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 0106#define HINIC_EQ_CI_WRAPPED_SHIFT 20107#define HINIC_EQ_CI_XOR_CHKSUM_SHIFT 24108#define HINIC_EQ_CI_INT_ARMED_SHIFT 31109 110#define HINIC_EQ_CI_IDX_MASK 0xFFFFF111#define HINIC_EQ_CI_WRAPPED_MASK 0x1112#define HINIC_EQ_CI_XOR_CHKSUM_MASK 0xF113#define HINIC_EQ_CI_INT_ARMED_MASK 0x1114 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 4124#define HINIC_MAX_CEQS 32125 126#define HINIC_AEQE_SIZE 64127#define HINIC_CEQE_SIZE 4128 129#define HINIC_AEQE_DESC_SIZE 4130#define HINIC_AEQE_DATA_SIZE \131 (HINIC_AEQE_SIZE - HINIC_AEQE_DESC_SIZE)132 133#define HINIC_DEFAULT_AEQ_LEN 64134#define HINIC_DEFAULT_CEQ_LEN 1024135 136#define HINIC_EQ_PAGE_SIZE SZ_4K137 138#define HINIC_CEQ_ID_CMDQ 0139 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#endif263