1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#include "bfi.h"
23#include "bfa_msgq.h"
24#include "bfa_ioc.h"
25
26#define call_cmdq_ent_cbfn(_cmdq_ent, _status) \
27{ \
28 bfa_msgq_cmdcbfn_t cbfn; \
29 void *cbarg; \
30 cbfn = (_cmdq_ent)->cbfn; \
31 cbarg = (_cmdq_ent)->cbarg; \
32 (_cmdq_ent)->cbfn = NULL; \
33 (_cmdq_ent)->cbarg = NULL; \
34 if (cbfn) { \
35 cbfn(cbarg, (_status)); \
36 } \
37}
38
39static void bfa_msgq_cmdq_dbell(struct bfa_msgq_cmdq *cmdq);
40static void bfa_msgq_cmdq_copy_rsp(struct bfa_msgq_cmdq *cmdq);
41
42enum cmdq_event {
43 CMDQ_E_START = 1,
44 CMDQ_E_STOP = 2,
45 CMDQ_E_FAIL = 3,
46 CMDQ_E_POST = 4,
47 CMDQ_E_INIT_RESP = 5,
48 CMDQ_E_DB_READY = 6,
49};
50
51bfa_fsm_state_decl(cmdq, stopped, struct bfa_msgq_cmdq, enum cmdq_event);
52bfa_fsm_state_decl(cmdq, init_wait, struct bfa_msgq_cmdq, enum cmdq_event);
53bfa_fsm_state_decl(cmdq, ready, struct bfa_msgq_cmdq, enum cmdq_event);
54bfa_fsm_state_decl(cmdq, dbell_wait, struct bfa_msgq_cmdq,
55 enum cmdq_event);
56
57static void
58cmdq_sm_stopped_entry(struct bfa_msgq_cmdq *cmdq)
59{
60 struct bfa_msgq_cmd_entry *cmdq_ent;
61
62 cmdq->producer_index = 0;
63 cmdq->consumer_index = 0;
64 cmdq->flags = 0;
65 cmdq->token = 0;
66 cmdq->offset = 0;
67 cmdq->bytes_to_copy = 0;
68 while (!list_empty(&cmdq->pending_q)) {
69 cmdq_ent = list_first_entry(&cmdq->pending_q,
70 struct bfa_msgq_cmd_entry, qe);
71 list_del(&cmdq_ent->qe);
72 call_cmdq_ent_cbfn(cmdq_ent, BFA_STATUS_FAILED);
73 }
74}
75
76static void
77cmdq_sm_stopped(struct bfa_msgq_cmdq *cmdq, enum cmdq_event event)
78{
79 switch (event) {
80 case CMDQ_E_START:
81 bfa_fsm_set_state(cmdq, cmdq_sm_init_wait);
82 break;
83
84 case CMDQ_E_STOP:
85 case CMDQ_E_FAIL:
86
87 break;
88
89 case CMDQ_E_POST:
90 cmdq->flags |= BFA_MSGQ_CMDQ_F_DB_UPDATE;
91 break;
92
93 default:
94 bfa_sm_fault(event);
95 }
96}
97
98static void
99cmdq_sm_init_wait_entry(struct bfa_msgq_cmdq *cmdq)
100{
101 bfa_wc_down(&cmdq->msgq->init_wc);
102}
103
104static void
105cmdq_sm_init_wait(struct bfa_msgq_cmdq *cmdq, enum cmdq_event event)
106{
107 switch (event) {
108 case CMDQ_E_STOP:
109 case CMDQ_E_FAIL:
110 bfa_fsm_set_state(cmdq, cmdq_sm_stopped);
111 break;
112
113 case CMDQ_E_POST:
114 cmdq->flags |= BFA_MSGQ_CMDQ_F_DB_UPDATE;
115 break;
116
117 case CMDQ_E_INIT_RESP:
118 if (cmdq->flags & BFA_MSGQ_CMDQ_F_DB_UPDATE) {
119 cmdq->flags &= ~BFA_MSGQ_CMDQ_F_DB_UPDATE;
120 bfa_fsm_set_state(cmdq, cmdq_sm_dbell_wait);
121 } else
122 bfa_fsm_set_state(cmdq, cmdq_sm_ready);
123 break;
124
125 default:
126 bfa_sm_fault(event);
127 }
128}
129
130static void
131cmdq_sm_ready_entry(struct bfa_msgq_cmdq *cmdq)
132{
133}
134
135static void
136cmdq_sm_ready(struct bfa_msgq_cmdq *cmdq, enum cmdq_event event)
137{
138 switch (event) {
139 case CMDQ_E_STOP:
140 case CMDQ_E_FAIL:
141 bfa_fsm_set_state(cmdq, cmdq_sm_stopped);
142 break;
143
144 case CMDQ_E_POST:
145 bfa_fsm_set_state(cmdq, cmdq_sm_dbell_wait);
146 break;
147
148 default:
149 bfa_sm_fault(event);
150 }
151}
152
153static void
154cmdq_sm_dbell_wait_entry(struct bfa_msgq_cmdq *cmdq)
155{
156 bfa_msgq_cmdq_dbell(cmdq);
157}
158
159static void
160cmdq_sm_dbell_wait(struct bfa_msgq_cmdq *cmdq, enum cmdq_event event)
161{
162 switch (event) {
163 case CMDQ_E_STOP:
164 case CMDQ_E_FAIL:
165 bfa_fsm_set_state(cmdq, cmdq_sm_stopped);
166 break;
167
168 case CMDQ_E_POST:
169 cmdq->flags |= BFA_MSGQ_CMDQ_F_DB_UPDATE;
170 break;
171
172 case CMDQ_E_DB_READY:
173 if (cmdq->flags & BFA_MSGQ_CMDQ_F_DB_UPDATE) {
174 cmdq->flags &= ~BFA_MSGQ_CMDQ_F_DB_UPDATE;
175 bfa_fsm_set_state(cmdq, cmdq_sm_dbell_wait);
176 } else
177 bfa_fsm_set_state(cmdq, cmdq_sm_ready);
178 break;
179
180 default:
181 bfa_sm_fault(event);
182 }
183}
184
185static void
186bfa_msgq_cmdq_dbell_ready(void *arg)
187{
188 struct bfa_msgq_cmdq *cmdq = (struct bfa_msgq_cmdq *)arg;
189 bfa_fsm_send_event(cmdq, CMDQ_E_DB_READY);
190}
191
192static void
193bfa_msgq_cmdq_dbell(struct bfa_msgq_cmdq *cmdq)
194{
195 struct bfi_msgq_h2i_db *dbell =
196 (struct bfi_msgq_h2i_db *)(&cmdq->dbell_mb.msg[0]);
197
198 memset(dbell, 0, sizeof(struct bfi_msgq_h2i_db));
199 bfi_h2i_set(dbell->mh, BFI_MC_MSGQ, BFI_MSGQ_H2I_DOORBELL_PI, 0);
200 dbell->mh.mtag.i2htok = 0;
201 dbell->idx.cmdq_pi = htons(cmdq->producer_index);
202
203 if (!bfa_nw_ioc_mbox_queue(cmdq->msgq->ioc, &cmdq->dbell_mb,
204 bfa_msgq_cmdq_dbell_ready, cmdq)) {
205 bfa_msgq_cmdq_dbell_ready(cmdq);
206 }
207}
208
209static void
210__cmd_copy(struct bfa_msgq_cmdq *cmdq, struct bfa_msgq_cmd_entry *cmd)
211{
212 size_t len = cmd->msg_size;
213 int num_entries = 0;
214 size_t to_copy;
215 u8 *src, *dst;
216
217 src = (u8 *)cmd->msg_hdr;
218 dst = (u8 *)cmdq->addr.kva;
219 dst += (cmdq->producer_index * BFI_MSGQ_CMD_ENTRY_SIZE);
220
221 while (len) {
222 to_copy = (len < BFI_MSGQ_CMD_ENTRY_SIZE) ?
223 len : BFI_MSGQ_CMD_ENTRY_SIZE;
224 memcpy(dst, src, to_copy);
225 len -= to_copy;
226 src += BFI_MSGQ_CMD_ENTRY_SIZE;
227 BFA_MSGQ_INDX_ADD(cmdq->producer_index, 1, cmdq->depth);
228 dst = (u8 *)cmdq->addr.kva;
229 dst += (cmdq->producer_index * BFI_MSGQ_CMD_ENTRY_SIZE);
230 num_entries++;
231 }
232
233}
234
235static void
236bfa_msgq_cmdq_ci_update(struct bfa_msgq_cmdq *cmdq, struct bfi_mbmsg *mb)
237{
238 struct bfi_msgq_i2h_db *dbell = (struct bfi_msgq_i2h_db *)mb;
239 struct bfa_msgq_cmd_entry *cmd;
240 int posted = 0;
241
242 cmdq->consumer_index = ntohs(dbell->idx.cmdq_ci);
243
244
245 while (!list_empty(&cmdq->pending_q)) {
246 cmd = list_first_entry(&cmdq->pending_q,
247 struct bfa_msgq_cmd_entry, qe);
248 if (ntohs(cmd->msg_hdr->num_entries) <=
249 BFA_MSGQ_FREE_CNT(cmdq)) {
250 list_del(&cmd->qe);
251 __cmd_copy(cmdq, cmd);
252 posted = 1;
253 call_cmdq_ent_cbfn(cmd, BFA_STATUS_OK);
254 } else {
255 break;
256 }
257 }
258
259 if (posted)
260 bfa_fsm_send_event(cmdq, CMDQ_E_POST);
261}
262
263static void
264bfa_msgq_cmdq_copy_next(void *arg)
265{
266 struct bfa_msgq_cmdq *cmdq = (struct bfa_msgq_cmdq *)arg;
267
268 if (cmdq->bytes_to_copy)
269 bfa_msgq_cmdq_copy_rsp(cmdq);
270}
271
272static void
273bfa_msgq_cmdq_copy_req(struct bfa_msgq_cmdq *cmdq, struct bfi_mbmsg *mb)
274{
275 struct bfi_msgq_i2h_cmdq_copy_req *req =
276 (struct bfi_msgq_i2h_cmdq_copy_req *)mb;
277
278 cmdq->token = 0;
279 cmdq->offset = ntohs(req->offset);
280 cmdq->bytes_to_copy = ntohs(req->len);
281 bfa_msgq_cmdq_copy_rsp(cmdq);
282}
283
284static void
285bfa_msgq_cmdq_copy_rsp(struct bfa_msgq_cmdq *cmdq)
286{
287 struct bfi_msgq_h2i_cmdq_copy_rsp *rsp =
288 (struct bfi_msgq_h2i_cmdq_copy_rsp *)&cmdq->copy_mb.msg[0];
289 int copied;
290 u8 *addr = (u8 *)cmdq->addr.kva;
291
292 memset(rsp, 0, sizeof(struct bfi_msgq_h2i_cmdq_copy_rsp));
293 bfi_h2i_set(rsp->mh, BFI_MC_MSGQ, BFI_MSGQ_H2I_CMDQ_COPY_RSP, 0);
294 rsp->mh.mtag.i2htok = htons(cmdq->token);
295 copied = (cmdq->bytes_to_copy >= BFI_CMD_COPY_SZ) ? BFI_CMD_COPY_SZ :
296 cmdq->bytes_to_copy;
297 addr += cmdq->offset;
298 memcpy(rsp->data, addr, copied);
299
300 cmdq->token++;
301 cmdq->offset += copied;
302 cmdq->bytes_to_copy -= copied;
303
304 if (!bfa_nw_ioc_mbox_queue(cmdq->msgq->ioc, &cmdq->copy_mb,
305 bfa_msgq_cmdq_copy_next, cmdq)) {
306 bfa_msgq_cmdq_copy_next(cmdq);
307 }
308}
309
310static void
311bfa_msgq_cmdq_attach(struct bfa_msgq_cmdq *cmdq, struct bfa_msgq *msgq)
312{
313 cmdq->depth = BFA_MSGQ_CMDQ_NUM_ENTRY;
314 INIT_LIST_HEAD(&cmdq->pending_q);
315 cmdq->msgq = msgq;
316 bfa_fsm_set_state(cmdq, cmdq_sm_stopped);
317}
318
319static void bfa_msgq_rspq_dbell(struct bfa_msgq_rspq *rspq);
320
321enum rspq_event {
322 RSPQ_E_START = 1,
323 RSPQ_E_STOP = 2,
324 RSPQ_E_FAIL = 3,
325 RSPQ_E_RESP = 4,
326 RSPQ_E_INIT_RESP = 5,
327 RSPQ_E_DB_READY = 6,
328};
329
330bfa_fsm_state_decl(rspq, stopped, struct bfa_msgq_rspq, enum rspq_event);
331bfa_fsm_state_decl(rspq, init_wait, struct bfa_msgq_rspq,
332 enum rspq_event);
333bfa_fsm_state_decl(rspq, ready, struct bfa_msgq_rspq, enum rspq_event);
334bfa_fsm_state_decl(rspq, dbell_wait, struct bfa_msgq_rspq,
335 enum rspq_event);
336
337static void
338rspq_sm_stopped_entry(struct bfa_msgq_rspq *rspq)
339{
340 rspq->producer_index = 0;
341 rspq->consumer_index = 0;
342 rspq->flags = 0;
343}
344
345static void
346rspq_sm_stopped(struct bfa_msgq_rspq *rspq, enum rspq_event event)
347{
348 switch (event) {
349 case RSPQ_E_START:
350 bfa_fsm_set_state(rspq, rspq_sm_init_wait);
351 break;
352
353 case RSPQ_E_STOP:
354 case RSPQ_E_FAIL:
355
356 break;
357
358 default:
359 bfa_sm_fault(event);
360 }
361}
362
363static void
364rspq_sm_init_wait_entry(struct bfa_msgq_rspq *rspq)
365{
366 bfa_wc_down(&rspq->msgq->init_wc);
367}
368
369static void
370rspq_sm_init_wait(struct bfa_msgq_rspq *rspq, enum rspq_event event)
371{
372 switch (event) {
373 case RSPQ_E_FAIL:
374 case RSPQ_E_STOP:
375 bfa_fsm_set_state(rspq, rspq_sm_stopped);
376 break;
377
378 case RSPQ_E_INIT_RESP:
379 bfa_fsm_set_state(rspq, rspq_sm_ready);
380 break;
381
382 default:
383 bfa_sm_fault(event);
384 }
385}
386
387static void
388rspq_sm_ready_entry(struct bfa_msgq_rspq *rspq)
389{
390}
391
392static void
393rspq_sm_ready(struct bfa_msgq_rspq *rspq, enum rspq_event event)
394{
395 switch (event) {
396 case RSPQ_E_STOP:
397 case RSPQ_E_FAIL:
398 bfa_fsm_set_state(rspq, rspq_sm_stopped);
399 break;
400
401 case RSPQ_E_RESP:
402 bfa_fsm_set_state(rspq, rspq_sm_dbell_wait);
403 break;
404
405 default:
406 bfa_sm_fault(event);
407 }
408}
409
410static void
411rspq_sm_dbell_wait_entry(struct bfa_msgq_rspq *rspq)
412{
413 if (!bfa_nw_ioc_is_disabled(rspq->msgq->ioc))
414 bfa_msgq_rspq_dbell(rspq);
415}
416
417static void
418rspq_sm_dbell_wait(struct bfa_msgq_rspq *rspq, enum rspq_event event)
419{
420 switch (event) {
421 case RSPQ_E_STOP:
422 case RSPQ_E_FAIL:
423 bfa_fsm_set_state(rspq, rspq_sm_stopped);
424 break;
425
426 case RSPQ_E_RESP:
427 rspq->flags |= BFA_MSGQ_RSPQ_F_DB_UPDATE;
428 break;
429
430 case RSPQ_E_DB_READY:
431 if (rspq->flags & BFA_MSGQ_RSPQ_F_DB_UPDATE) {
432 rspq->flags &= ~BFA_MSGQ_RSPQ_F_DB_UPDATE;
433 bfa_fsm_set_state(rspq, rspq_sm_dbell_wait);
434 } else
435 bfa_fsm_set_state(rspq, rspq_sm_ready);
436 break;
437
438 default:
439 bfa_sm_fault(event);
440 }
441}
442
443static void
444bfa_msgq_rspq_dbell_ready(void *arg)
445{
446 struct bfa_msgq_rspq *rspq = (struct bfa_msgq_rspq *)arg;
447 bfa_fsm_send_event(rspq, RSPQ_E_DB_READY);
448}
449
450static void
451bfa_msgq_rspq_dbell(struct bfa_msgq_rspq *rspq)
452{
453 struct bfi_msgq_h2i_db *dbell =
454 (struct bfi_msgq_h2i_db *)(&rspq->dbell_mb.msg[0]);
455
456 memset(dbell, 0, sizeof(struct bfi_msgq_h2i_db));
457 bfi_h2i_set(dbell->mh, BFI_MC_MSGQ, BFI_MSGQ_H2I_DOORBELL_CI, 0);
458 dbell->mh.mtag.i2htok = 0;
459 dbell->idx.rspq_ci = htons(rspq->consumer_index);
460
461 if (!bfa_nw_ioc_mbox_queue(rspq->msgq->ioc, &rspq->dbell_mb,
462 bfa_msgq_rspq_dbell_ready, rspq)) {
463 bfa_msgq_rspq_dbell_ready(rspq);
464 }
465}
466
467static void
468bfa_msgq_rspq_pi_update(struct bfa_msgq_rspq *rspq, struct bfi_mbmsg *mb)
469{
470 struct bfi_msgq_i2h_db *dbell = (struct bfi_msgq_i2h_db *)mb;
471 struct bfi_msgq_mhdr *msghdr;
472 int num_entries;
473 int mc;
474 u8 *rspq_qe;
475
476 rspq->producer_index = ntohs(dbell->idx.rspq_pi);
477
478 while (rspq->consumer_index != rspq->producer_index) {
479 rspq_qe = (u8 *)rspq->addr.kva;
480 rspq_qe += (rspq->consumer_index * BFI_MSGQ_RSP_ENTRY_SIZE);
481 msghdr = (struct bfi_msgq_mhdr *)rspq_qe;
482
483 mc = msghdr->msg_class;
484 num_entries = ntohs(msghdr->num_entries);
485
486 if ((mc >= BFI_MC_MAX) || (rspq->rsphdlr[mc].cbfn == NULL))
487 break;
488
489 (rspq->rsphdlr[mc].cbfn)(rspq->rsphdlr[mc].cbarg, msghdr);
490
491 BFA_MSGQ_INDX_ADD(rspq->consumer_index, num_entries,
492 rspq->depth);
493 }
494
495 bfa_fsm_send_event(rspq, RSPQ_E_RESP);
496}
497
498static void
499bfa_msgq_rspq_attach(struct bfa_msgq_rspq *rspq, struct bfa_msgq *msgq)
500{
501 rspq->depth = BFA_MSGQ_RSPQ_NUM_ENTRY;
502 rspq->msgq = msgq;
503 bfa_fsm_set_state(rspq, rspq_sm_stopped);
504}
505
506static void
507bfa_msgq_init_rsp(struct bfa_msgq *msgq,
508 struct bfi_mbmsg *mb)
509{
510 bfa_fsm_send_event(&msgq->cmdq, CMDQ_E_INIT_RESP);
511 bfa_fsm_send_event(&msgq->rspq, RSPQ_E_INIT_RESP);
512}
513
514static void
515bfa_msgq_init(void *arg)
516{
517 struct bfa_msgq *msgq = (struct bfa_msgq *)arg;
518 struct bfi_msgq_cfg_req *msgq_cfg =
519 (struct bfi_msgq_cfg_req *)&msgq->init_mb.msg[0];
520
521 memset(msgq_cfg, 0, sizeof(struct bfi_msgq_cfg_req));
522 bfi_h2i_set(msgq_cfg->mh, BFI_MC_MSGQ, BFI_MSGQ_H2I_INIT_REQ, 0);
523 msgq_cfg->mh.mtag.i2htok = 0;
524
525 bfa_dma_be_addr_set(msgq_cfg->cmdq.addr, msgq->cmdq.addr.pa);
526 msgq_cfg->cmdq.q_depth = htons(msgq->cmdq.depth);
527 bfa_dma_be_addr_set(msgq_cfg->rspq.addr, msgq->rspq.addr.pa);
528 msgq_cfg->rspq.q_depth = htons(msgq->rspq.depth);
529
530 bfa_nw_ioc_mbox_queue(msgq->ioc, &msgq->init_mb, NULL, NULL);
531}
532
533static void
534bfa_msgq_isr(void *cbarg, struct bfi_mbmsg *msg)
535{
536 struct bfa_msgq *msgq = (struct bfa_msgq *)cbarg;
537
538 switch (msg->mh.msg_id) {
539 case BFI_MSGQ_I2H_INIT_RSP:
540 bfa_msgq_init_rsp(msgq, msg);
541 break;
542
543 case BFI_MSGQ_I2H_DOORBELL_PI:
544 bfa_msgq_rspq_pi_update(&msgq->rspq, msg);
545 break;
546
547 case BFI_MSGQ_I2H_DOORBELL_CI:
548 bfa_msgq_cmdq_ci_update(&msgq->cmdq, msg);
549 break;
550
551 case BFI_MSGQ_I2H_CMDQ_COPY_REQ:
552 bfa_msgq_cmdq_copy_req(&msgq->cmdq, msg);
553 break;
554
555 default:
556 BUG_ON(1);
557 }
558}
559
560static void
561bfa_msgq_notify(void *cbarg, enum bfa_ioc_event event)
562{
563 struct bfa_msgq *msgq = (struct bfa_msgq *)cbarg;
564
565 switch (event) {
566 case BFA_IOC_E_ENABLED:
567 bfa_wc_init(&msgq->init_wc, bfa_msgq_init, msgq);
568 bfa_wc_up(&msgq->init_wc);
569 bfa_fsm_send_event(&msgq->cmdq, CMDQ_E_START);
570 bfa_wc_up(&msgq->init_wc);
571 bfa_fsm_send_event(&msgq->rspq, RSPQ_E_START);
572 bfa_wc_wait(&msgq->init_wc);
573 break;
574
575 case BFA_IOC_E_DISABLED:
576 bfa_fsm_send_event(&msgq->cmdq, CMDQ_E_STOP);
577 bfa_fsm_send_event(&msgq->rspq, RSPQ_E_STOP);
578 break;
579
580 case BFA_IOC_E_FAILED:
581 bfa_fsm_send_event(&msgq->cmdq, CMDQ_E_FAIL);
582 bfa_fsm_send_event(&msgq->rspq, RSPQ_E_FAIL);
583 break;
584
585 default:
586 break;
587 }
588}
589
590u32
591bfa_msgq_meminfo(void)
592{
593 return roundup(BFA_MSGQ_CMDQ_SIZE, BFA_DMA_ALIGN_SZ) +
594 roundup(BFA_MSGQ_RSPQ_SIZE, BFA_DMA_ALIGN_SZ);
595}
596
597void
598bfa_msgq_memclaim(struct bfa_msgq *msgq, u8 *kva, u64 pa)
599{
600 msgq->cmdq.addr.kva = kva;
601 msgq->cmdq.addr.pa = pa;
602
603 kva += roundup(BFA_MSGQ_CMDQ_SIZE, BFA_DMA_ALIGN_SZ);
604 pa += roundup(BFA_MSGQ_CMDQ_SIZE, BFA_DMA_ALIGN_SZ);
605
606 msgq->rspq.addr.kva = kva;
607 msgq->rspq.addr.pa = pa;
608}
609
610void
611bfa_msgq_attach(struct bfa_msgq *msgq, struct bfa_ioc *ioc)
612{
613 msgq->ioc = ioc;
614
615 bfa_msgq_cmdq_attach(&msgq->cmdq, msgq);
616 bfa_msgq_rspq_attach(&msgq->rspq, msgq);
617
618 bfa_nw_ioc_mbox_regisr(msgq->ioc, BFI_MC_MSGQ, bfa_msgq_isr, msgq);
619 bfa_ioc_notify_init(&msgq->ioc_notify, bfa_msgq_notify, msgq);
620 bfa_nw_ioc_notify_register(msgq->ioc, &msgq->ioc_notify);
621}
622
623void
624bfa_msgq_regisr(struct bfa_msgq *msgq, enum bfi_mclass mc,
625 bfa_msgq_mcfunc_t cbfn, void *cbarg)
626{
627 msgq->rspq.rsphdlr[mc].cbfn = cbfn;
628 msgq->rspq.rsphdlr[mc].cbarg = cbarg;
629}
630
631void
632bfa_msgq_cmd_post(struct bfa_msgq *msgq, struct bfa_msgq_cmd_entry *cmd)
633{
634 if (ntohs(cmd->msg_hdr->num_entries) <=
635 BFA_MSGQ_FREE_CNT(&msgq->cmdq)) {
636 __cmd_copy(&msgq->cmdq, cmd);
637 call_cmdq_ent_cbfn(cmd, BFA_STATUS_OK);
638 bfa_fsm_send_event(&msgq->cmdq, CMDQ_E_POST);
639 } else {
640 list_add_tail(&cmd->qe, &msgq->cmdq.pending_q);
641 }
642}
643
644void
645bfa_msgq_rsp_copy(struct bfa_msgq *msgq, u8 *buf, size_t buf_len)
646{
647 struct bfa_msgq_rspq *rspq = &msgq->rspq;
648 size_t len = buf_len;
649 size_t to_copy;
650 int ci;
651 u8 *src, *dst;
652
653 ci = rspq->consumer_index;
654 src = (u8 *)rspq->addr.kva;
655 src += (ci * BFI_MSGQ_RSP_ENTRY_SIZE);
656 dst = buf;
657
658 while (len) {
659 to_copy = (len < BFI_MSGQ_RSP_ENTRY_SIZE) ?
660 len : BFI_MSGQ_RSP_ENTRY_SIZE;
661 memcpy(dst, src, to_copy);
662 len -= to_copy;
663 dst += BFI_MSGQ_RSP_ENTRY_SIZE;
664 BFA_MSGQ_INDX_ADD(ci, 1, rspq->depth);
665 src = (u8 *)rspq->addr.kva;
666 src += (ci * BFI_MSGQ_RSP_ENTRY_SIZE);
667 }
668}
669