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_CMDQ_H 8 #define HINIC_CMDQ_H 9 10 #include <linux/types.h> 11 #include <linux/spinlock.h> 12 #include <linux/completion.h> 13 #include <linux/pci.h> 14 15 #include "hinic_hw_if.h" 16 #include "hinic_hw_wq.h" 17 18 #define HINIC_CMDQ_CTXT_CURR_WQE_PAGE_PFN_SHIFT 0 19 #define HINIC_CMDQ_CTXT_EQ_ID_SHIFT 56 20 #define HINIC_CMDQ_CTXT_CEQ_ARM_SHIFT 61 21 #define HINIC_CMDQ_CTXT_CEQ_EN_SHIFT 62 22 #define HINIC_CMDQ_CTXT_WRAPPED_SHIFT 63 23 24 #define HINIC_CMDQ_CTXT_CURR_WQE_PAGE_PFN_MASK 0xFFFFFFFFFFFFF 25 #define HINIC_CMDQ_CTXT_EQ_ID_MASK 0x1F 26 #define HINIC_CMDQ_CTXT_CEQ_ARM_MASK 0x1 27 #define HINIC_CMDQ_CTXT_CEQ_EN_MASK 0x1 28 #define HINIC_CMDQ_CTXT_WRAPPED_MASK 0x1 29 30 #define HINIC_CMDQ_CTXT_PAGE_INFO_SET(val, member) \ 31 (((u64)(val) & HINIC_CMDQ_CTXT_##member##_MASK) \ 32 << HINIC_CMDQ_CTXT_##member##_SHIFT) 33 34 #define HINIC_CMDQ_CTXT_PAGE_INFO_CLEAR(val, member) \ 35 ((val) & (~((u64)HINIC_CMDQ_CTXT_##member##_MASK \ 36 << HINIC_CMDQ_CTXT_##member##_SHIFT))) 37 38 #define HINIC_CMDQ_CTXT_WQ_BLOCK_PFN_SHIFT 0 39 #define HINIC_CMDQ_CTXT_CI_SHIFT 52 40 41 #define HINIC_CMDQ_CTXT_WQ_BLOCK_PFN_MASK 0xFFFFFFFFFFFFF 42 #define HINIC_CMDQ_CTXT_CI_MASK 0xFFF 43 44 #define HINIC_CMDQ_CTXT_BLOCK_INFO_SET(val, member) \ 45 (((u64)(val) & HINIC_CMDQ_CTXT_##member##_MASK) \ 46 << HINIC_CMDQ_CTXT_##member##_SHIFT) 47 48 #define HINIC_CMDQ_CTXT_BLOCK_INFO_CLEAR(val, member) \ 49 ((val) & (~((u64)HINIC_CMDQ_CTXT_##member##_MASK \ 50 << HINIC_CMDQ_CTXT_##member##_SHIFT))) 51 52 #define HINIC_SAVED_DATA_ARM_SHIFT 31 53 54 #define HINIC_SAVED_DATA_ARM_MASK 0x1 55 56 #define HINIC_SAVED_DATA_SET(val, member) \ 57 (((u32)(val) & HINIC_SAVED_DATA_##member##_MASK) \ 58 << HINIC_SAVED_DATA_##member##_SHIFT) 59 60 #define HINIC_SAVED_DATA_GET(val, member) \ 61 (((val) >> HINIC_SAVED_DATA_##member##_SHIFT) \ 62 & HINIC_SAVED_DATA_##member##_MASK) 63 64 #define HINIC_SAVED_DATA_CLEAR(val, member) \ 65 ((val) & (~(HINIC_SAVED_DATA_##member##_MASK \ 66 << HINIC_SAVED_DATA_##member##_SHIFT))) 67 68 #define HINIC_CMDQ_DB_INFO_HI_PROD_IDX_SHIFT 0 69 #define HINIC_CMDQ_DB_INFO_PATH_SHIFT 23 70 #define HINIC_CMDQ_DB_INFO_CMDQ_TYPE_SHIFT 24 71 #define HINIC_CMDQ_DB_INFO_DB_TYPE_SHIFT 27 72 73 #define HINIC_CMDQ_DB_INFO_HI_PROD_IDX_MASK 0xFF 74 #define HINIC_CMDQ_DB_INFO_PATH_MASK 0x1 75 #define HINIC_CMDQ_DB_INFO_CMDQ_TYPE_MASK 0x7 76 #define HINIC_CMDQ_DB_INFO_DB_TYPE_MASK 0x1F 77 78 #define HINIC_CMDQ_DB_INFO_SET(val, member) \ 79 (((u32)(val) & HINIC_CMDQ_DB_INFO_##member##_MASK) \ 80 << HINIC_CMDQ_DB_INFO_##member##_SHIFT) 81 82 #define HINIC_CMDQ_BUF_SIZE 2048 83 84 #define HINIC_CMDQ_BUF_HW_RSVD 8 85 #define HINIC_CMDQ_MAX_DATA_SIZE (HINIC_CMDQ_BUF_SIZE - \ 86 HINIC_CMDQ_BUF_HW_RSVD) 87 88 enum hinic_cmdq_type { 89 HINIC_CMDQ_SYNC, 90 91 HINIC_MAX_CMDQ_TYPES, 92 }; 93 94 enum hinic_set_arm_qtype { 95 HINIC_SET_ARM_CMDQ, 96 }; 97 98 enum hinic_cmd_ack_type { 99 HINIC_CMD_ACK_TYPE_CMDQ, 100 }; 101 102 struct hinic_cmdq_buf { 103 void *buf; 104 dma_addr_t dma_addr; 105 size_t size; 106 }; 107 108 struct hinic_cmdq_arm_bit { 109 u32 q_type; 110 u32 q_id; 111 }; 112 113 struct hinic_cmdq_ctxt_info { 114 u64 curr_wqe_page_pfn; 115 u64 wq_block_pfn; 116 }; 117 118 struct hinic_cmdq_ctxt { 119 u8 status; 120 u8 version; 121 u8 rsvd0[6]; 122 123 u16 func_idx; 124 u8 cmdq_type; 125 u8 rsvd1[1]; 126 127 u8 rsvd2[4]; 128 129 struct hinic_cmdq_ctxt_info ctxt_info; 130 }; 131 132 struct hinic_cmdq { 133 struct hinic_wq *wq; 134 135 enum hinic_cmdq_type cmdq_type; 136 int wrapped; 137 138 /* Lock for keeping the doorbell order */ 139 spinlock_t cmdq_lock; 140 141 struct completion **done; 142 int **errcode; 143 144 /* doorbell area */ 145 void __iomem *db_base; 146 }; 147 148 struct hinic_cmdqs { 149 struct hinic_hwif *hwif; 150 151 struct dma_pool *cmdq_buf_pool; 152 153 struct hinic_wq *saved_wqs; 154 155 struct hinic_cmdq_pages cmdq_pages; 156 157 struct hinic_cmdq cmdq[HINIC_MAX_CMDQ_TYPES]; 158 }; 159 160 int hinic_alloc_cmdq_buf(struct hinic_cmdqs *cmdqs, 161 struct hinic_cmdq_buf *cmdq_buf); 162 163 void hinic_free_cmdq_buf(struct hinic_cmdqs *cmdqs, 164 struct hinic_cmdq_buf *cmdq_buf); 165 166 int hinic_cmdq_direct_resp(struct hinic_cmdqs *cmdqs, 167 enum hinic_mod_type mod, u8 cmd, 168 struct hinic_cmdq_buf *buf_in, u64 *out_param); 169 170 int hinic_set_arm_bit(struct hinic_cmdqs *cmdqs, 171 enum hinic_set_arm_qtype q_type, u32 q_id); 172 173 int hinic_init_cmdqs(struct hinic_cmdqs *cmdqs, struct hinic_hwif *hwif, 174 void __iomem **db_area); 175 176 void hinic_free_cmdqs(struct hinic_cmdqs *cmdqs); 177 178 #endif 179