Linux Audio
Check our new training course
Embedded Linux Audio
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* Copyright (c) 2021, Microsoft Corporation. */ #ifndef _HW_CHANNEL_H #define _HW_CHANNEL_H #define DEFAULT_LOG2_THROTTLING_FOR_ERROR_EQ 4 #define HW_CHANNEL_MAX_REQUEST_SIZE 0x1000 #define HW_CHANNEL_MAX_RESPONSE_SIZE 0x1000 #define HW_CHANNEL_VF_BOOTSTRAP_QUEUE_DEPTH 1 #define HWC_INIT_DATA_CQID 1 #define HWC_INIT_DATA_RQID 2 #define HWC_INIT_DATA_SQID 3 #define HWC_INIT_DATA_QUEUE_DEPTH 4 #define HWC_INIT_DATA_MAX_REQUEST 5 #define HWC_INIT_DATA_MAX_RESPONSE 6 #define HWC_INIT_DATA_MAX_NUM_CQS 7 #define HWC_INIT_DATA_PDID 8 #define HWC_INIT_DATA_GPA_MKEY 9 #define HWC_INIT_DATA_PF_DEST_RQ_ID 10 #define HWC_INIT_DATA_PF_DEST_CQ_ID 11 /* Structures labeled with "HW DATA" are exchanged with the hardware. All of * them are naturally aligned and hence don't need __packed. */ union hwc_init_eq_id_db { u32 as_uint32; struct { u32 eq_id : 16; u32 doorbell : 16; }; }; /* HW DATA */ union hwc_init_type_data { u32 as_uint32; struct { u32 value : 24; u32 type : 8; }; }; /* HW DATA */ struct hwc_rx_oob { u32 type : 6; u32 eom : 1; u32 som : 1; u32 vendor_err : 8; u32 reserved1 : 16; u32 src_virt_wq : 24; u32 src_vfid : 8; u32 reserved2; union { u32 wqe_addr_low; u32 wqe_offset; }; u32 wqe_addr_high; u32 client_data_unit : 14; u32 reserved3 : 18; u32 tx_oob_data_size; u32 chunk_offset : 21; u32 reserved4 : 11; }; /* HW DATA */ struct hwc_tx_oob { u32 reserved1; u32 reserved2; u32 vrq_id : 24; u32 dest_vfid : 8; u32 vrcq_id : 24; u32 reserved3 : 8; u32 vscq_id : 24; u32 loopback : 1; u32 lso_override: 1; u32 dest_pf : 1; u32 reserved4 : 5; u32 vsq_id : 24; u32 reserved5 : 8; }; /* HW DATA */ struct hwc_work_request { void *buf_va; void *buf_sge_addr; u32 buf_len; u32 msg_size; struct gdma_wqe_request wqe_req; struct hwc_tx_oob tx_oob; struct gdma_sge sge; }; /* hwc_dma_buf represents the array of in-flight WQEs. * mem_info as know as the GDMA mapped memory is partitioned and used by * in-flight WQEs. * The number of WQEs is determined by the number of in-flight messages. */ struct hwc_dma_buf { struct gdma_mem_info mem_info; u32 gpa_mkey; u32 num_reqs; struct hwc_work_request reqs[]; }; typedef void hwc_rx_event_handler_t(void *ctx, u32 gdma_rxq_id, const struct hwc_rx_oob *rx_oob); typedef void hwc_tx_event_handler_t(void *ctx, u32 gdma_txq_id, const struct hwc_rx_oob *rx_oob); struct hwc_cq { struct hw_channel_context *hwc; struct gdma_queue *gdma_cq; struct gdma_queue *gdma_eq; struct gdma_comp *comp_buf; u16 queue_depth; hwc_rx_event_handler_t *rx_event_handler; void *rx_event_ctx; hwc_tx_event_handler_t *tx_event_handler; void *tx_event_ctx; }; struct hwc_wq { struct hw_channel_context *hwc; struct gdma_queue *gdma_wq; struct hwc_dma_buf *msg_buf; u16 queue_depth; struct hwc_cq *hwc_cq; }; struct hwc_caller_ctx { struct completion comp_event; void *output_buf; u32 output_buflen; u32 error; /* Linux error code */ u32 status_code; }; struct hw_channel_context { struct gdma_dev *gdma_dev; struct device *dev; u16 num_inflight_msg; u32 max_req_msg_size; u16 hwc_init_q_depth_max; u32 hwc_init_max_req_msg_size; u32 hwc_init_max_resp_msg_size; struct completion hwc_init_eqe_comp; struct hwc_wq *rxq; struct hwc_wq *txq; struct hwc_cq *cq; struct semaphore sema; struct gdma_resource inflight_msg_res; u32 pf_dest_vrq_id; u32 pf_dest_vrcq_id; struct hwc_caller_ctx *caller_ctx; }; int mana_hwc_create_channel(struct gdma_context *gc); void mana_hwc_destroy_channel(struct gdma_context *gc); int mana_hwc_send_request(struct hw_channel_context *hwc, u32 req_len, const void *req, u32 resp_len, void *resp); #endif /* _HW_CHANNEL_H */