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 140 enum hinic_eq_type { 141 HINIC_AEQ, 142 HINIC_CEQ, 143 }; 144 145 enum hinic_aeq_type { 146 HINIC_MSG_FROM_MGMT_CPU = 2, 147 148 HINIC_MAX_AEQ_EVENTS, 149 }; 150 151 enum hinic_ceq_type { 152 HINIC_CEQ_CMDQ = 3, 153 154 HINIC_MAX_CEQ_EVENTS, 155 }; 156 157 enum hinic_eqe_state { 158 HINIC_EQE_ENABLED = BIT(0), 159 HINIC_EQE_RUNNING = BIT(1), 160 }; 161 162 struct hinic_aeq_elem { 163 u8 data[HINIC_AEQE_DATA_SIZE]; 164 u32 desc; 165 }; 166 167 struct hinic_eq_work { 168 struct work_struct work; 169 void *data; 170 }; 171 172 struct 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 197 struct hinic_hw_event_cb { 198 void (*hwe_handler)(void *handle, void *data, u8 size); 199 void *handle; 200 unsigned long hwe_state; 201 }; 202 203 struct 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 214 struct hinic_ceq_cb { 215 void (*handler)(void *handle, u32 ceqe_data); 216 void *handle; 217 enum hinic_eqe_state ceqe_state; 218 }; 219 220 struct 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 229 void 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 234 void hinic_aeq_unregister_hw_cb(struct hinic_aeqs *aeqs, 235 enum hinic_aeq_type event); 236 237 void 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 241 void hinic_ceq_unregister_cb(struct hinic_ceqs *ceqs, 242 enum hinic_ceq_type event); 243 244 int 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 248 void hinic_aeqs_free(struct hinic_aeqs *aeqs); 249 250 int 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 254 void hinic_ceqs_free(struct hinic_ceqs *ceqs); 255 256 #endif 257