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