1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
3 /* Authors: Cheng Xu <chengyou@linux.alibaba.com> */
4 /* Kai Shen <kaishen@linux.alibaba.com> */
5 /* Copyright (c) 2020-2022, Alibaba Group. */
9 static void arm_cmdq_cq(struct erdma_cmdq
*cmdq
)
11 struct erdma_dev
*dev
= container_of(cmdq
, struct erdma_dev
, cmdq
);
12 u64 db_data
= FIELD_PREP(ERDMA_CQDB_CI_MASK
, cmdq
->cq
.ci
) |
13 FIELD_PREP(ERDMA_CQDB_ARM_MASK
, 1) |
14 FIELD_PREP(ERDMA_CQDB_CMDSN_MASK
, cmdq
->cq
.cmdsn
) |
15 FIELD_PREP(ERDMA_CQDB_IDX_MASK
, cmdq
->cq
.cmdsn
);
17 *cmdq
->cq
.dbrec
= db_data
;
18 writeq(db_data
, dev
->func_bar
+ ERDMA_CMDQ_CQDB_REG
);
20 atomic64_inc(&cmdq
->cq
.armed_num
);
23 static void kick_cmdq_db(struct erdma_cmdq
*cmdq
)
25 struct erdma_dev
*dev
= container_of(cmdq
, struct erdma_dev
, cmdq
);
26 u64 db_data
= FIELD_PREP(ERDMA_CMD_HDR_WQEBB_INDEX_MASK
, cmdq
->sq
.pi
);
28 *cmdq
->sq
.dbrec
= db_data
;
29 writeq(db_data
, dev
->func_bar
+ ERDMA_CMDQ_SQDB_REG
);
32 static struct erdma_comp_wait
*get_comp_wait(struct erdma_cmdq
*cmdq
)
36 spin_lock(&cmdq
->lock
);
37 comp_idx
= find_first_zero_bit(cmdq
->comp_wait_bitmap
,
38 cmdq
->max_outstandings
);
39 if (comp_idx
== cmdq
->max_outstandings
) {
40 spin_unlock(&cmdq
->lock
);
41 return ERR_PTR(-ENOMEM
);
44 __set_bit(comp_idx
, cmdq
->comp_wait_bitmap
);
45 spin_unlock(&cmdq
->lock
);
47 return &cmdq
->wait_pool
[comp_idx
];
50 static void put_comp_wait(struct erdma_cmdq
*cmdq
,
51 struct erdma_comp_wait
*comp_wait
)
55 cmdq
->wait_pool
[comp_wait
->ctx_id
].cmd_status
= ERDMA_CMD_STATUS_INIT
;
56 spin_lock(&cmdq
->lock
);
57 used
= __test_and_clear_bit(comp_wait
->ctx_id
, cmdq
->comp_wait_bitmap
);
58 spin_unlock(&cmdq
->lock
);
63 static int erdma_cmdq_wait_res_init(struct erdma_dev
*dev
,
64 struct erdma_cmdq
*cmdq
)
69 devm_kcalloc(&dev
->pdev
->dev
, cmdq
->max_outstandings
,
70 sizeof(struct erdma_comp_wait
), GFP_KERNEL
);
74 spin_lock_init(&cmdq
->lock
);
75 cmdq
->comp_wait_bitmap
= devm_bitmap_zalloc(
76 &dev
->pdev
->dev
, cmdq
->max_outstandings
, GFP_KERNEL
);
77 if (!cmdq
->comp_wait_bitmap
)
80 for (i
= 0; i
< cmdq
->max_outstandings
; i
++) {
81 init_completion(&cmdq
->wait_pool
[i
].wait_event
);
82 cmdq
->wait_pool
[i
].ctx_id
= i
;
88 static int erdma_cmdq_sq_init(struct erdma_dev
*dev
)
90 struct erdma_cmdq
*cmdq
= &dev
->cmdq
;
91 struct erdma_cmdq_sq
*sq
= &cmdq
->sq
;
93 sq
->wqebb_cnt
= SQEBB_COUNT(ERDMA_CMDQ_SQE_SIZE
);
94 sq
->depth
= cmdq
->max_outstandings
* sq
->wqebb_cnt
;
96 sq
->qbuf
= dma_alloc_coherent(&dev
->pdev
->dev
, sq
->depth
<< SQEBB_SHIFT
,
97 &sq
->qbuf_dma_addr
, GFP_KERNEL
);
101 sq
->dbrec
= dma_pool_zalloc(dev
->db_pool
, GFP_KERNEL
, &sq
->dbrec_dma
);
105 spin_lock_init(&sq
->lock
);
107 erdma_reg_write32(dev
, ERDMA_REGS_CMDQ_SQ_ADDR_H_REG
,
108 upper_32_bits(sq
->qbuf_dma_addr
));
109 erdma_reg_write32(dev
, ERDMA_REGS_CMDQ_SQ_ADDR_L_REG
,
110 lower_32_bits(sq
->qbuf_dma_addr
));
111 erdma_reg_write32(dev
, ERDMA_REGS_CMDQ_DEPTH_REG
, sq
->depth
);
112 erdma_reg_write64(dev
, ERDMA_CMDQ_SQ_DB_HOST_ADDR_REG
, sq
->dbrec_dma
);
117 dma_free_coherent(&dev
->pdev
->dev
, sq
->depth
<< SQEBB_SHIFT
,
118 sq
->qbuf
, sq
->qbuf_dma_addr
);
123 static int erdma_cmdq_cq_init(struct erdma_dev
*dev
)
125 struct erdma_cmdq
*cmdq
= &dev
->cmdq
;
126 struct erdma_cmdq_cq
*cq
= &cmdq
->cq
;
128 cq
->depth
= cmdq
->sq
.depth
;
129 cq
->qbuf
= dma_alloc_coherent(&dev
->pdev
->dev
, cq
->depth
<< CQE_SHIFT
,
130 &cq
->qbuf_dma_addr
, GFP_KERNEL
);
134 spin_lock_init(&cq
->lock
);
136 cq
->dbrec
= dma_pool_zalloc(dev
->db_pool
, GFP_KERNEL
, &cq
->dbrec_dma
);
140 atomic64_set(&cq
->armed_num
, 0);
142 erdma_reg_write32(dev
, ERDMA_REGS_CMDQ_CQ_ADDR_H_REG
,
143 upper_32_bits(cq
->qbuf_dma_addr
));
144 erdma_reg_write32(dev
, ERDMA_REGS_CMDQ_CQ_ADDR_L_REG
,
145 lower_32_bits(cq
->qbuf_dma_addr
));
146 erdma_reg_write64(dev
, ERDMA_CMDQ_CQ_DB_HOST_ADDR_REG
, cq
->dbrec_dma
);
151 dma_free_coherent(&dev
->pdev
->dev
, cq
->depth
<< CQE_SHIFT
, cq
->qbuf
,
157 static int erdma_cmdq_eq_init(struct erdma_dev
*dev
)
159 struct erdma_cmdq
*cmdq
= &dev
->cmdq
;
160 struct erdma_eq
*eq
= &cmdq
->eq
;
163 ret
= erdma_eq_common_init(dev
, eq
, cmdq
->max_outstandings
);
167 eq
->db
= dev
->func_bar
+ ERDMA_REGS_CEQ_DB_BASE_REG
;
169 erdma_reg_write32(dev
, ERDMA_REGS_CMDQ_EQ_ADDR_H_REG
,
170 upper_32_bits(eq
->qbuf_dma_addr
));
171 erdma_reg_write32(dev
, ERDMA_REGS_CMDQ_EQ_ADDR_L_REG
,
172 lower_32_bits(eq
->qbuf_dma_addr
));
173 erdma_reg_write32(dev
, ERDMA_REGS_CMDQ_EQ_DEPTH_REG
, eq
->depth
);
174 erdma_reg_write64(dev
, ERDMA_CMDQ_EQ_DB_HOST_ADDR_REG
, eq
->dbrec_dma
);
179 int erdma_cmdq_init(struct erdma_dev
*dev
)
181 struct erdma_cmdq
*cmdq
= &dev
->cmdq
;
184 cmdq
->max_outstandings
= ERDMA_CMDQ_MAX_OUTSTANDING
;
185 cmdq
->use_event
= false;
187 sema_init(&cmdq
->credits
, cmdq
->max_outstandings
);
189 err
= erdma_cmdq_wait_res_init(dev
, cmdq
);
193 err
= erdma_cmdq_sq_init(dev
);
197 err
= erdma_cmdq_cq_init(dev
);
201 err
= erdma_cmdq_eq_init(dev
);
205 set_bit(ERDMA_CMDQ_STATE_OK_BIT
, &cmdq
->state
);
210 dma_free_coherent(&dev
->pdev
->dev
, cmdq
->cq
.depth
<< CQE_SHIFT
,
211 cmdq
->cq
.qbuf
, cmdq
->cq
.qbuf_dma_addr
);
213 dma_pool_free(dev
->db_pool
, cmdq
->cq
.dbrec
, cmdq
->cq
.dbrec_dma
);
216 dma_free_coherent(&dev
->pdev
->dev
, cmdq
->sq
.depth
<< SQEBB_SHIFT
,
217 cmdq
->sq
.qbuf
, cmdq
->sq
.qbuf_dma_addr
);
219 dma_pool_free(dev
->db_pool
, cmdq
->sq
.dbrec
, cmdq
->sq
.dbrec_dma
);
224 void erdma_finish_cmdq_init(struct erdma_dev
*dev
)
226 /* after device init successfully, change cmdq to event mode. */
227 dev
->cmdq
.use_event
= true;
228 arm_cmdq_cq(&dev
->cmdq
);
231 void erdma_cmdq_destroy(struct erdma_dev
*dev
)
233 struct erdma_cmdq
*cmdq
= &dev
->cmdq
;
235 clear_bit(ERDMA_CMDQ_STATE_OK_BIT
, &cmdq
->state
);
237 erdma_eq_destroy(dev
, &cmdq
->eq
);
239 dma_free_coherent(&dev
->pdev
->dev
, cmdq
->sq
.depth
<< SQEBB_SHIFT
,
240 cmdq
->sq
.qbuf
, cmdq
->sq
.qbuf_dma_addr
);
242 dma_pool_free(dev
->db_pool
, cmdq
->sq
.dbrec
, cmdq
->sq
.dbrec_dma
);
244 dma_free_coherent(&dev
->pdev
->dev
, cmdq
->cq
.depth
<< CQE_SHIFT
,
245 cmdq
->cq
.qbuf
, cmdq
->cq
.qbuf_dma_addr
);
247 dma_pool_free(dev
->db_pool
, cmdq
->cq
.dbrec
, cmdq
->cq
.dbrec_dma
);
250 static void *get_next_valid_cmdq_cqe(struct erdma_cmdq
*cmdq
)
252 __be32
*cqe
= get_queue_entry(cmdq
->cq
.qbuf
, cmdq
->cq
.ci
,
253 cmdq
->cq
.depth
, CQE_SHIFT
);
254 u32 owner
= FIELD_GET(ERDMA_CQE_HDR_OWNER_MASK
,
255 be32_to_cpu(READ_ONCE(*cqe
)));
257 return owner
^ !!(cmdq
->cq
.ci
& cmdq
->cq
.depth
) ? cqe
: NULL
;
260 static void push_cmdq_sqe(struct erdma_cmdq
*cmdq
, u64
*req
, size_t req_len
,
261 struct erdma_comp_wait
*comp_wait
)
266 comp_wait
->cmd_status
= ERDMA_CMD_STATUS_ISSUED
;
267 reinit_completion(&comp_wait
->wait_event
);
268 comp_wait
->sq_pi
= cmdq
->sq
.pi
;
270 wqe
= get_queue_entry(cmdq
->sq
.qbuf
, cmdq
->sq
.pi
, cmdq
->sq
.depth
,
272 memcpy(wqe
, req
, req_len
);
274 cmdq
->sq
.pi
+= cmdq
->sq
.wqebb_cnt
;
275 hdr
|= FIELD_PREP(ERDMA_CMD_HDR_WQEBB_INDEX_MASK
, cmdq
->sq
.pi
) |
276 FIELD_PREP(ERDMA_CMD_HDR_CONTEXT_COOKIE_MASK
,
278 FIELD_PREP(ERDMA_CMD_HDR_WQEBB_CNT_MASK
, cmdq
->sq
.wqebb_cnt
- 1);
279 *wqe
= cpu_to_le64(hdr
);
284 static int erdma_poll_single_cmd_completion(struct erdma_cmdq
*cmdq
)
286 struct erdma_comp_wait
*comp_wait
;
292 cqe
= get_next_valid_cmdq_cqe(cmdq
);
299 hdr0
= be32_to_cpu(*cqe
);
300 sqe_idx
= be32_to_cpu(*(cqe
+ 1));
302 sqe
= get_queue_entry(cmdq
->sq
.qbuf
, sqe_idx
, cmdq
->sq
.depth
,
304 ctx_id
= FIELD_GET(ERDMA_CMD_HDR_CONTEXT_COOKIE_MASK
, *sqe
);
305 comp_wait
= &cmdq
->wait_pool
[ctx_id
];
306 if (comp_wait
->cmd_status
!= ERDMA_CMD_STATUS_ISSUED
)
309 comp_wait
->cmd_status
= ERDMA_CMD_STATUS_FINISHED
;
310 comp_wait
->comp_status
= FIELD_GET(ERDMA_CQE_HDR_SYNDROME_MASK
, hdr0
);
311 cmdq
->sq
.ci
+= cmdq
->sq
.wqebb_cnt
;
312 /* Copy 16B comp data after cqe hdr to outer */
313 be32_to_cpu_array(comp_wait
->comp_data
, cqe
+ 2, 4);
316 complete(&comp_wait
->wait_event
);
321 static void erdma_polling_cmd_completions(struct erdma_cmdq
*cmdq
)
326 spin_lock_irqsave(&cmdq
->cq
.lock
, flags
);
328 /* We must have less than # of max_outstandings
329 * completions at one time.
331 for (comp_num
= 0; comp_num
< cmdq
->max_outstandings
; comp_num
++)
332 if (erdma_poll_single_cmd_completion(cmdq
))
335 if (comp_num
&& cmdq
->use_event
)
338 spin_unlock_irqrestore(&cmdq
->cq
.lock
, flags
);
341 void erdma_cmdq_completion_handler(struct erdma_cmdq
*cmdq
)
345 if (!test_bit(ERDMA_CMDQ_STATE_OK_BIT
, &cmdq
->state
) ||
349 while (get_next_valid_eqe(&cmdq
->eq
)) {
356 erdma_polling_cmd_completions(cmdq
);
359 notify_eq(&cmdq
->eq
);
362 static int erdma_poll_cmd_completion(struct erdma_comp_wait
*comp_ctx
,
363 struct erdma_cmdq
*cmdq
, u32 timeout
)
365 unsigned long comp_timeout
= jiffies
+ msecs_to_jiffies(timeout
);
368 erdma_polling_cmd_completions(cmdq
);
369 if (comp_ctx
->cmd_status
!= ERDMA_CMD_STATUS_ISSUED
)
372 if (time_is_before_jiffies(comp_timeout
))
381 static int erdma_wait_cmd_completion(struct erdma_comp_wait
*comp_ctx
,
382 struct erdma_cmdq
*cmdq
, u32 timeout
)
384 unsigned long flags
= 0;
386 wait_for_completion_timeout(&comp_ctx
->wait_event
,
387 msecs_to_jiffies(timeout
));
389 if (unlikely(comp_ctx
->cmd_status
!= ERDMA_CMD_STATUS_FINISHED
)) {
390 spin_lock_irqsave(&cmdq
->cq
.lock
, flags
);
391 comp_ctx
->cmd_status
= ERDMA_CMD_STATUS_TIMEOUT
;
392 spin_unlock_irqrestore(&cmdq
->cq
.lock
, flags
);
399 void erdma_cmdq_build_reqhdr(u64
*hdr
, u32 mod
, u32 op
)
401 *hdr
= FIELD_PREP(ERDMA_CMD_HDR_SUB_MOD_MASK
, mod
) |
402 FIELD_PREP(ERDMA_CMD_HDR_OPCODE_MASK
, op
);
405 int erdma_post_cmd_wait(struct erdma_cmdq
*cmdq
, void *req
, u32 req_size
,
406 u64
*resp0
, u64
*resp1
)
408 struct erdma_comp_wait
*comp_wait
;
411 if (!test_bit(ERDMA_CMDQ_STATE_OK_BIT
, &cmdq
->state
))
414 down(&cmdq
->credits
);
416 comp_wait
= get_comp_wait(cmdq
);
417 if (IS_ERR(comp_wait
)) {
418 clear_bit(ERDMA_CMDQ_STATE_OK_BIT
, &cmdq
->state
);
419 set_bit(ERDMA_CMDQ_STATE_CTX_ERR_BIT
, &cmdq
->state
);
421 return PTR_ERR(comp_wait
);
424 spin_lock(&cmdq
->sq
.lock
);
425 push_cmdq_sqe(cmdq
, req
, req_size
, comp_wait
);
426 spin_unlock(&cmdq
->sq
.lock
);
429 ret
= erdma_wait_cmd_completion(comp_wait
, cmdq
,
430 ERDMA_CMDQ_TIMEOUT_MS
);
432 ret
= erdma_poll_cmd_completion(comp_wait
, cmdq
,
433 ERDMA_CMDQ_TIMEOUT_MS
);
436 set_bit(ERDMA_CMDQ_STATE_TIMEOUT_BIT
, &cmdq
->state
);
437 clear_bit(ERDMA_CMDQ_STATE_OK_BIT
, &cmdq
->state
);
441 if (comp_wait
->comp_status
)
444 if (resp0
&& resp1
) {
445 *resp0
= *((u64
*)&comp_wait
->comp_data
[0]);
446 *resp1
= *((u64
*)&comp_wait
->comp_data
[2]);
448 put_comp_wait(cmdq
, comp_wait
);