hinic_hw_eqs.h (7797B)
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_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#endif