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