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