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

source code of linux/drivers/net/ethernet/brocade/bna/bfa_msgq.c