18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Linux network driver for QLogic BR-series Converged Network Adapter.
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci/*
68c2ecf20Sopenharmony_ci * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
78c2ecf20Sopenharmony_ci * Copyright (c) 2014-2015 QLogic Corporation
88c2ecf20Sopenharmony_ci * All rights reserved
98c2ecf20Sopenharmony_ci * www.qlogic.com
108c2ecf20Sopenharmony_ci */
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci/* MSGQ module source file. */
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#include "bfi.h"
158c2ecf20Sopenharmony_ci#include "bfa_msgq.h"
168c2ecf20Sopenharmony_ci#include "bfa_ioc.h"
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#define call_cmdq_ent_cbfn(_cmdq_ent, _status)				\
198c2ecf20Sopenharmony_ci{									\
208c2ecf20Sopenharmony_ci	bfa_msgq_cmdcbfn_t cbfn;					\
218c2ecf20Sopenharmony_ci	void *cbarg;							\
228c2ecf20Sopenharmony_ci	cbfn = (_cmdq_ent)->cbfn;					\
238c2ecf20Sopenharmony_ci	cbarg = (_cmdq_ent)->cbarg;					\
248c2ecf20Sopenharmony_ci	(_cmdq_ent)->cbfn = NULL;					\
258c2ecf20Sopenharmony_ci	(_cmdq_ent)->cbarg = NULL;					\
268c2ecf20Sopenharmony_ci	if (cbfn) {							\
278c2ecf20Sopenharmony_ci		cbfn(cbarg, (_status));					\
288c2ecf20Sopenharmony_ci	}								\
298c2ecf20Sopenharmony_ci}
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_cistatic void bfa_msgq_cmdq_dbell(struct bfa_msgq_cmdq *cmdq);
328c2ecf20Sopenharmony_cistatic void bfa_msgq_cmdq_copy_rsp(struct bfa_msgq_cmdq *cmdq);
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_cienum cmdq_event {
358c2ecf20Sopenharmony_ci	CMDQ_E_START			= 1,
368c2ecf20Sopenharmony_ci	CMDQ_E_STOP			= 2,
378c2ecf20Sopenharmony_ci	CMDQ_E_FAIL			= 3,
388c2ecf20Sopenharmony_ci	CMDQ_E_POST			= 4,
398c2ecf20Sopenharmony_ci	CMDQ_E_INIT_RESP		= 5,
408c2ecf20Sopenharmony_ci	CMDQ_E_DB_READY			= 6,
418c2ecf20Sopenharmony_ci};
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_cibfa_fsm_state_decl(cmdq, stopped, struct bfa_msgq_cmdq, enum cmdq_event);
448c2ecf20Sopenharmony_cibfa_fsm_state_decl(cmdq, init_wait, struct bfa_msgq_cmdq, enum cmdq_event);
458c2ecf20Sopenharmony_cibfa_fsm_state_decl(cmdq, ready, struct bfa_msgq_cmdq, enum cmdq_event);
468c2ecf20Sopenharmony_cibfa_fsm_state_decl(cmdq, dbell_wait, struct bfa_msgq_cmdq,
478c2ecf20Sopenharmony_ci			enum cmdq_event);
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_cistatic void
508c2ecf20Sopenharmony_cicmdq_sm_stopped_entry(struct bfa_msgq_cmdq *cmdq)
518c2ecf20Sopenharmony_ci{
528c2ecf20Sopenharmony_ci	struct bfa_msgq_cmd_entry *cmdq_ent;
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci	cmdq->producer_index = 0;
558c2ecf20Sopenharmony_ci	cmdq->consumer_index = 0;
568c2ecf20Sopenharmony_ci	cmdq->flags = 0;
578c2ecf20Sopenharmony_ci	cmdq->token = 0;
588c2ecf20Sopenharmony_ci	cmdq->offset = 0;
598c2ecf20Sopenharmony_ci	cmdq->bytes_to_copy = 0;
608c2ecf20Sopenharmony_ci	while (!list_empty(&cmdq->pending_q)) {
618c2ecf20Sopenharmony_ci		cmdq_ent = list_first_entry(&cmdq->pending_q,
628c2ecf20Sopenharmony_ci					    struct bfa_msgq_cmd_entry, qe);
638c2ecf20Sopenharmony_ci		list_del(&cmdq_ent->qe);
648c2ecf20Sopenharmony_ci		call_cmdq_ent_cbfn(cmdq_ent, BFA_STATUS_FAILED);
658c2ecf20Sopenharmony_ci	}
668c2ecf20Sopenharmony_ci}
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_cistatic void
698c2ecf20Sopenharmony_cicmdq_sm_stopped(struct bfa_msgq_cmdq *cmdq, enum cmdq_event event)
708c2ecf20Sopenharmony_ci{
718c2ecf20Sopenharmony_ci	switch (event) {
728c2ecf20Sopenharmony_ci	case CMDQ_E_START:
738c2ecf20Sopenharmony_ci		bfa_fsm_set_state(cmdq, cmdq_sm_init_wait);
748c2ecf20Sopenharmony_ci		break;
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci	case CMDQ_E_STOP:
778c2ecf20Sopenharmony_ci	case CMDQ_E_FAIL:
788c2ecf20Sopenharmony_ci		/* No-op */
798c2ecf20Sopenharmony_ci		break;
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci	case CMDQ_E_POST:
828c2ecf20Sopenharmony_ci		cmdq->flags |= BFA_MSGQ_CMDQ_F_DB_UPDATE;
838c2ecf20Sopenharmony_ci		break;
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci	default:
868c2ecf20Sopenharmony_ci		bfa_sm_fault(event);
878c2ecf20Sopenharmony_ci	}
888c2ecf20Sopenharmony_ci}
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_cistatic void
918c2ecf20Sopenharmony_cicmdq_sm_init_wait_entry(struct bfa_msgq_cmdq *cmdq)
928c2ecf20Sopenharmony_ci{
938c2ecf20Sopenharmony_ci	bfa_wc_down(&cmdq->msgq->init_wc);
948c2ecf20Sopenharmony_ci}
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_cistatic void
978c2ecf20Sopenharmony_cicmdq_sm_init_wait(struct bfa_msgq_cmdq *cmdq, enum cmdq_event event)
988c2ecf20Sopenharmony_ci{
998c2ecf20Sopenharmony_ci	switch (event) {
1008c2ecf20Sopenharmony_ci	case CMDQ_E_STOP:
1018c2ecf20Sopenharmony_ci	case CMDQ_E_FAIL:
1028c2ecf20Sopenharmony_ci		bfa_fsm_set_state(cmdq, cmdq_sm_stopped);
1038c2ecf20Sopenharmony_ci		break;
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci	case CMDQ_E_POST:
1068c2ecf20Sopenharmony_ci		cmdq->flags |= BFA_MSGQ_CMDQ_F_DB_UPDATE;
1078c2ecf20Sopenharmony_ci		break;
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci	case CMDQ_E_INIT_RESP:
1108c2ecf20Sopenharmony_ci		if (cmdq->flags & BFA_MSGQ_CMDQ_F_DB_UPDATE) {
1118c2ecf20Sopenharmony_ci			cmdq->flags &= ~BFA_MSGQ_CMDQ_F_DB_UPDATE;
1128c2ecf20Sopenharmony_ci			bfa_fsm_set_state(cmdq, cmdq_sm_dbell_wait);
1138c2ecf20Sopenharmony_ci		} else
1148c2ecf20Sopenharmony_ci			bfa_fsm_set_state(cmdq, cmdq_sm_ready);
1158c2ecf20Sopenharmony_ci		break;
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci	default:
1188c2ecf20Sopenharmony_ci		bfa_sm_fault(event);
1198c2ecf20Sopenharmony_ci	}
1208c2ecf20Sopenharmony_ci}
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_cistatic void
1238c2ecf20Sopenharmony_cicmdq_sm_ready_entry(struct bfa_msgq_cmdq *cmdq)
1248c2ecf20Sopenharmony_ci{
1258c2ecf20Sopenharmony_ci}
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_cistatic void
1288c2ecf20Sopenharmony_cicmdq_sm_ready(struct bfa_msgq_cmdq *cmdq, enum cmdq_event event)
1298c2ecf20Sopenharmony_ci{
1308c2ecf20Sopenharmony_ci	switch (event) {
1318c2ecf20Sopenharmony_ci	case CMDQ_E_STOP:
1328c2ecf20Sopenharmony_ci	case CMDQ_E_FAIL:
1338c2ecf20Sopenharmony_ci		bfa_fsm_set_state(cmdq, cmdq_sm_stopped);
1348c2ecf20Sopenharmony_ci		break;
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ci	case CMDQ_E_POST:
1378c2ecf20Sopenharmony_ci		bfa_fsm_set_state(cmdq, cmdq_sm_dbell_wait);
1388c2ecf20Sopenharmony_ci		break;
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci	default:
1418c2ecf20Sopenharmony_ci		bfa_sm_fault(event);
1428c2ecf20Sopenharmony_ci	}
1438c2ecf20Sopenharmony_ci}
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_cistatic void
1468c2ecf20Sopenharmony_cicmdq_sm_dbell_wait_entry(struct bfa_msgq_cmdq *cmdq)
1478c2ecf20Sopenharmony_ci{
1488c2ecf20Sopenharmony_ci	bfa_msgq_cmdq_dbell(cmdq);
1498c2ecf20Sopenharmony_ci}
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_cistatic void
1528c2ecf20Sopenharmony_cicmdq_sm_dbell_wait(struct bfa_msgq_cmdq *cmdq, enum cmdq_event event)
1538c2ecf20Sopenharmony_ci{
1548c2ecf20Sopenharmony_ci	switch (event) {
1558c2ecf20Sopenharmony_ci	case CMDQ_E_STOP:
1568c2ecf20Sopenharmony_ci	case CMDQ_E_FAIL:
1578c2ecf20Sopenharmony_ci		bfa_fsm_set_state(cmdq, cmdq_sm_stopped);
1588c2ecf20Sopenharmony_ci		break;
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ci	case CMDQ_E_POST:
1618c2ecf20Sopenharmony_ci		cmdq->flags |= BFA_MSGQ_CMDQ_F_DB_UPDATE;
1628c2ecf20Sopenharmony_ci		break;
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_ci	case CMDQ_E_DB_READY:
1658c2ecf20Sopenharmony_ci		if (cmdq->flags & BFA_MSGQ_CMDQ_F_DB_UPDATE) {
1668c2ecf20Sopenharmony_ci			cmdq->flags &= ~BFA_MSGQ_CMDQ_F_DB_UPDATE;
1678c2ecf20Sopenharmony_ci			bfa_fsm_set_state(cmdq, cmdq_sm_dbell_wait);
1688c2ecf20Sopenharmony_ci		} else
1698c2ecf20Sopenharmony_ci			bfa_fsm_set_state(cmdq, cmdq_sm_ready);
1708c2ecf20Sopenharmony_ci		break;
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_ci	default:
1738c2ecf20Sopenharmony_ci		bfa_sm_fault(event);
1748c2ecf20Sopenharmony_ci	}
1758c2ecf20Sopenharmony_ci}
1768c2ecf20Sopenharmony_ci
1778c2ecf20Sopenharmony_cistatic void
1788c2ecf20Sopenharmony_cibfa_msgq_cmdq_dbell_ready(void *arg)
1798c2ecf20Sopenharmony_ci{
1808c2ecf20Sopenharmony_ci	struct bfa_msgq_cmdq *cmdq = (struct bfa_msgq_cmdq *)arg;
1818c2ecf20Sopenharmony_ci	bfa_fsm_send_event(cmdq, CMDQ_E_DB_READY);
1828c2ecf20Sopenharmony_ci}
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_cistatic void
1858c2ecf20Sopenharmony_cibfa_msgq_cmdq_dbell(struct bfa_msgq_cmdq *cmdq)
1868c2ecf20Sopenharmony_ci{
1878c2ecf20Sopenharmony_ci	struct bfi_msgq_h2i_db *dbell =
1888c2ecf20Sopenharmony_ci		(struct bfi_msgq_h2i_db *)(&cmdq->dbell_mb.msg[0]);
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ci	memset(dbell, 0, sizeof(struct bfi_msgq_h2i_db));
1918c2ecf20Sopenharmony_ci	bfi_h2i_set(dbell->mh, BFI_MC_MSGQ, BFI_MSGQ_H2I_DOORBELL_PI, 0);
1928c2ecf20Sopenharmony_ci	dbell->mh.mtag.i2htok = 0;
1938c2ecf20Sopenharmony_ci	dbell->idx.cmdq_pi = htons(cmdq->producer_index);
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_ci	if (!bfa_nw_ioc_mbox_queue(cmdq->msgq->ioc, &cmdq->dbell_mb,
1968c2ecf20Sopenharmony_ci				bfa_msgq_cmdq_dbell_ready, cmdq)) {
1978c2ecf20Sopenharmony_ci		bfa_msgq_cmdq_dbell_ready(cmdq);
1988c2ecf20Sopenharmony_ci	}
1998c2ecf20Sopenharmony_ci}
2008c2ecf20Sopenharmony_ci
2018c2ecf20Sopenharmony_cistatic void
2028c2ecf20Sopenharmony_ci__cmd_copy(struct bfa_msgq_cmdq *cmdq, struct bfa_msgq_cmd_entry *cmd)
2038c2ecf20Sopenharmony_ci{
2048c2ecf20Sopenharmony_ci	size_t len = cmd->msg_size;
2058c2ecf20Sopenharmony_ci	int num_entries = 0;
2068c2ecf20Sopenharmony_ci	size_t to_copy;
2078c2ecf20Sopenharmony_ci	u8 *src, *dst;
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_ci	src = (u8 *)cmd->msg_hdr;
2108c2ecf20Sopenharmony_ci	dst = (u8 *)cmdq->addr.kva;
2118c2ecf20Sopenharmony_ci	dst += (cmdq->producer_index * BFI_MSGQ_CMD_ENTRY_SIZE);
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_ci	while (len) {
2148c2ecf20Sopenharmony_ci		to_copy = (len < BFI_MSGQ_CMD_ENTRY_SIZE) ?
2158c2ecf20Sopenharmony_ci				len : BFI_MSGQ_CMD_ENTRY_SIZE;
2168c2ecf20Sopenharmony_ci		memcpy(dst, src, to_copy);
2178c2ecf20Sopenharmony_ci		len -= to_copy;
2188c2ecf20Sopenharmony_ci		src += BFI_MSGQ_CMD_ENTRY_SIZE;
2198c2ecf20Sopenharmony_ci		BFA_MSGQ_INDX_ADD(cmdq->producer_index, 1, cmdq->depth);
2208c2ecf20Sopenharmony_ci		dst = (u8 *)cmdq->addr.kva;
2218c2ecf20Sopenharmony_ci		dst += (cmdq->producer_index * BFI_MSGQ_CMD_ENTRY_SIZE);
2228c2ecf20Sopenharmony_ci		num_entries++;
2238c2ecf20Sopenharmony_ci	}
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_ci}
2268c2ecf20Sopenharmony_ci
2278c2ecf20Sopenharmony_cistatic void
2288c2ecf20Sopenharmony_cibfa_msgq_cmdq_ci_update(struct bfa_msgq_cmdq *cmdq, struct bfi_mbmsg *mb)
2298c2ecf20Sopenharmony_ci{
2308c2ecf20Sopenharmony_ci	struct bfi_msgq_i2h_db *dbell = (struct bfi_msgq_i2h_db *)mb;
2318c2ecf20Sopenharmony_ci	struct bfa_msgq_cmd_entry *cmd;
2328c2ecf20Sopenharmony_ci	int posted = 0;
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_ci	cmdq->consumer_index = ntohs(dbell->idx.cmdq_ci);
2358c2ecf20Sopenharmony_ci
2368c2ecf20Sopenharmony_ci	/* Walk through pending list to see if the command can be posted */
2378c2ecf20Sopenharmony_ci	while (!list_empty(&cmdq->pending_q)) {
2388c2ecf20Sopenharmony_ci		cmd = list_first_entry(&cmdq->pending_q,
2398c2ecf20Sopenharmony_ci				       struct bfa_msgq_cmd_entry, qe);
2408c2ecf20Sopenharmony_ci		if (ntohs(cmd->msg_hdr->num_entries) <=
2418c2ecf20Sopenharmony_ci			BFA_MSGQ_FREE_CNT(cmdq)) {
2428c2ecf20Sopenharmony_ci			list_del(&cmd->qe);
2438c2ecf20Sopenharmony_ci			__cmd_copy(cmdq, cmd);
2448c2ecf20Sopenharmony_ci			posted = 1;
2458c2ecf20Sopenharmony_ci			call_cmdq_ent_cbfn(cmd, BFA_STATUS_OK);
2468c2ecf20Sopenharmony_ci		} else {
2478c2ecf20Sopenharmony_ci			break;
2488c2ecf20Sopenharmony_ci		}
2498c2ecf20Sopenharmony_ci	}
2508c2ecf20Sopenharmony_ci
2518c2ecf20Sopenharmony_ci	if (posted)
2528c2ecf20Sopenharmony_ci		bfa_fsm_send_event(cmdq, CMDQ_E_POST);
2538c2ecf20Sopenharmony_ci}
2548c2ecf20Sopenharmony_ci
2558c2ecf20Sopenharmony_cistatic void
2568c2ecf20Sopenharmony_cibfa_msgq_cmdq_copy_next(void *arg)
2578c2ecf20Sopenharmony_ci{
2588c2ecf20Sopenharmony_ci	struct bfa_msgq_cmdq *cmdq = (struct bfa_msgq_cmdq *)arg;
2598c2ecf20Sopenharmony_ci
2608c2ecf20Sopenharmony_ci	if (cmdq->bytes_to_copy)
2618c2ecf20Sopenharmony_ci		bfa_msgq_cmdq_copy_rsp(cmdq);
2628c2ecf20Sopenharmony_ci}
2638c2ecf20Sopenharmony_ci
2648c2ecf20Sopenharmony_cistatic void
2658c2ecf20Sopenharmony_cibfa_msgq_cmdq_copy_req(struct bfa_msgq_cmdq *cmdq, struct bfi_mbmsg *mb)
2668c2ecf20Sopenharmony_ci{
2678c2ecf20Sopenharmony_ci	struct bfi_msgq_i2h_cmdq_copy_req *req =
2688c2ecf20Sopenharmony_ci		(struct bfi_msgq_i2h_cmdq_copy_req *)mb;
2698c2ecf20Sopenharmony_ci
2708c2ecf20Sopenharmony_ci	cmdq->token = 0;
2718c2ecf20Sopenharmony_ci	cmdq->offset = ntohs(req->offset);
2728c2ecf20Sopenharmony_ci	cmdq->bytes_to_copy = ntohs(req->len);
2738c2ecf20Sopenharmony_ci	bfa_msgq_cmdq_copy_rsp(cmdq);
2748c2ecf20Sopenharmony_ci}
2758c2ecf20Sopenharmony_ci
2768c2ecf20Sopenharmony_cistatic void
2778c2ecf20Sopenharmony_cibfa_msgq_cmdq_copy_rsp(struct bfa_msgq_cmdq *cmdq)
2788c2ecf20Sopenharmony_ci{
2798c2ecf20Sopenharmony_ci	struct bfi_msgq_h2i_cmdq_copy_rsp *rsp =
2808c2ecf20Sopenharmony_ci		(struct bfi_msgq_h2i_cmdq_copy_rsp *)&cmdq->copy_mb.msg[0];
2818c2ecf20Sopenharmony_ci	int copied;
2828c2ecf20Sopenharmony_ci	u8 *addr = (u8 *)cmdq->addr.kva;
2838c2ecf20Sopenharmony_ci
2848c2ecf20Sopenharmony_ci	memset(rsp, 0, sizeof(struct bfi_msgq_h2i_cmdq_copy_rsp));
2858c2ecf20Sopenharmony_ci	bfi_h2i_set(rsp->mh, BFI_MC_MSGQ, BFI_MSGQ_H2I_CMDQ_COPY_RSP, 0);
2868c2ecf20Sopenharmony_ci	rsp->mh.mtag.i2htok = htons(cmdq->token);
2878c2ecf20Sopenharmony_ci	copied = (cmdq->bytes_to_copy >= BFI_CMD_COPY_SZ) ? BFI_CMD_COPY_SZ :
2888c2ecf20Sopenharmony_ci		cmdq->bytes_to_copy;
2898c2ecf20Sopenharmony_ci	addr += cmdq->offset;
2908c2ecf20Sopenharmony_ci	memcpy(rsp->data, addr, copied);
2918c2ecf20Sopenharmony_ci
2928c2ecf20Sopenharmony_ci	cmdq->token++;
2938c2ecf20Sopenharmony_ci	cmdq->offset += copied;
2948c2ecf20Sopenharmony_ci	cmdq->bytes_to_copy -= copied;
2958c2ecf20Sopenharmony_ci
2968c2ecf20Sopenharmony_ci	if (!bfa_nw_ioc_mbox_queue(cmdq->msgq->ioc, &cmdq->copy_mb,
2978c2ecf20Sopenharmony_ci				bfa_msgq_cmdq_copy_next, cmdq)) {
2988c2ecf20Sopenharmony_ci		bfa_msgq_cmdq_copy_next(cmdq);
2998c2ecf20Sopenharmony_ci	}
3008c2ecf20Sopenharmony_ci}
3018c2ecf20Sopenharmony_ci
3028c2ecf20Sopenharmony_cistatic void
3038c2ecf20Sopenharmony_cibfa_msgq_cmdq_attach(struct bfa_msgq_cmdq *cmdq, struct bfa_msgq *msgq)
3048c2ecf20Sopenharmony_ci{
3058c2ecf20Sopenharmony_ci	cmdq->depth = BFA_MSGQ_CMDQ_NUM_ENTRY;
3068c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&cmdq->pending_q);
3078c2ecf20Sopenharmony_ci	cmdq->msgq = msgq;
3088c2ecf20Sopenharmony_ci	bfa_fsm_set_state(cmdq, cmdq_sm_stopped);
3098c2ecf20Sopenharmony_ci}
3108c2ecf20Sopenharmony_ci
3118c2ecf20Sopenharmony_cistatic void bfa_msgq_rspq_dbell(struct bfa_msgq_rspq *rspq);
3128c2ecf20Sopenharmony_ci
3138c2ecf20Sopenharmony_cienum rspq_event {
3148c2ecf20Sopenharmony_ci	RSPQ_E_START			= 1,
3158c2ecf20Sopenharmony_ci	RSPQ_E_STOP			= 2,
3168c2ecf20Sopenharmony_ci	RSPQ_E_FAIL			= 3,
3178c2ecf20Sopenharmony_ci	RSPQ_E_RESP			= 4,
3188c2ecf20Sopenharmony_ci	RSPQ_E_INIT_RESP		= 5,
3198c2ecf20Sopenharmony_ci	RSPQ_E_DB_READY			= 6,
3208c2ecf20Sopenharmony_ci};
3218c2ecf20Sopenharmony_ci
3228c2ecf20Sopenharmony_cibfa_fsm_state_decl(rspq, stopped, struct bfa_msgq_rspq, enum rspq_event);
3238c2ecf20Sopenharmony_cibfa_fsm_state_decl(rspq, init_wait, struct bfa_msgq_rspq,
3248c2ecf20Sopenharmony_ci			enum rspq_event);
3258c2ecf20Sopenharmony_cibfa_fsm_state_decl(rspq, ready, struct bfa_msgq_rspq, enum rspq_event);
3268c2ecf20Sopenharmony_cibfa_fsm_state_decl(rspq, dbell_wait, struct bfa_msgq_rspq,
3278c2ecf20Sopenharmony_ci			enum rspq_event);
3288c2ecf20Sopenharmony_ci
3298c2ecf20Sopenharmony_cistatic void
3308c2ecf20Sopenharmony_cirspq_sm_stopped_entry(struct bfa_msgq_rspq *rspq)
3318c2ecf20Sopenharmony_ci{
3328c2ecf20Sopenharmony_ci	rspq->producer_index = 0;
3338c2ecf20Sopenharmony_ci	rspq->consumer_index = 0;
3348c2ecf20Sopenharmony_ci	rspq->flags = 0;
3358c2ecf20Sopenharmony_ci}
3368c2ecf20Sopenharmony_ci
3378c2ecf20Sopenharmony_cistatic void
3388c2ecf20Sopenharmony_cirspq_sm_stopped(struct bfa_msgq_rspq *rspq, enum rspq_event event)
3398c2ecf20Sopenharmony_ci{
3408c2ecf20Sopenharmony_ci	switch (event) {
3418c2ecf20Sopenharmony_ci	case RSPQ_E_START:
3428c2ecf20Sopenharmony_ci		bfa_fsm_set_state(rspq, rspq_sm_init_wait);
3438c2ecf20Sopenharmony_ci		break;
3448c2ecf20Sopenharmony_ci
3458c2ecf20Sopenharmony_ci	case RSPQ_E_STOP:
3468c2ecf20Sopenharmony_ci	case RSPQ_E_FAIL:
3478c2ecf20Sopenharmony_ci		/* No-op */
3488c2ecf20Sopenharmony_ci		break;
3498c2ecf20Sopenharmony_ci
3508c2ecf20Sopenharmony_ci	default:
3518c2ecf20Sopenharmony_ci		bfa_sm_fault(event);
3528c2ecf20Sopenharmony_ci	}
3538c2ecf20Sopenharmony_ci}
3548c2ecf20Sopenharmony_ci
3558c2ecf20Sopenharmony_cistatic void
3568c2ecf20Sopenharmony_cirspq_sm_init_wait_entry(struct bfa_msgq_rspq *rspq)
3578c2ecf20Sopenharmony_ci{
3588c2ecf20Sopenharmony_ci	bfa_wc_down(&rspq->msgq->init_wc);
3598c2ecf20Sopenharmony_ci}
3608c2ecf20Sopenharmony_ci
3618c2ecf20Sopenharmony_cistatic void
3628c2ecf20Sopenharmony_cirspq_sm_init_wait(struct bfa_msgq_rspq *rspq, enum rspq_event event)
3638c2ecf20Sopenharmony_ci{
3648c2ecf20Sopenharmony_ci	switch (event) {
3658c2ecf20Sopenharmony_ci	case RSPQ_E_FAIL:
3668c2ecf20Sopenharmony_ci	case RSPQ_E_STOP:
3678c2ecf20Sopenharmony_ci		bfa_fsm_set_state(rspq, rspq_sm_stopped);
3688c2ecf20Sopenharmony_ci		break;
3698c2ecf20Sopenharmony_ci
3708c2ecf20Sopenharmony_ci	case RSPQ_E_INIT_RESP:
3718c2ecf20Sopenharmony_ci		bfa_fsm_set_state(rspq, rspq_sm_ready);
3728c2ecf20Sopenharmony_ci		break;
3738c2ecf20Sopenharmony_ci
3748c2ecf20Sopenharmony_ci	default:
3758c2ecf20Sopenharmony_ci		bfa_sm_fault(event);
3768c2ecf20Sopenharmony_ci	}
3778c2ecf20Sopenharmony_ci}
3788c2ecf20Sopenharmony_ci
3798c2ecf20Sopenharmony_cistatic void
3808c2ecf20Sopenharmony_cirspq_sm_ready_entry(struct bfa_msgq_rspq *rspq)
3818c2ecf20Sopenharmony_ci{
3828c2ecf20Sopenharmony_ci}
3838c2ecf20Sopenharmony_ci
3848c2ecf20Sopenharmony_cistatic void
3858c2ecf20Sopenharmony_cirspq_sm_ready(struct bfa_msgq_rspq *rspq, enum rspq_event event)
3868c2ecf20Sopenharmony_ci{
3878c2ecf20Sopenharmony_ci	switch (event) {
3888c2ecf20Sopenharmony_ci	case RSPQ_E_STOP:
3898c2ecf20Sopenharmony_ci	case RSPQ_E_FAIL:
3908c2ecf20Sopenharmony_ci		bfa_fsm_set_state(rspq, rspq_sm_stopped);
3918c2ecf20Sopenharmony_ci		break;
3928c2ecf20Sopenharmony_ci
3938c2ecf20Sopenharmony_ci	case RSPQ_E_RESP:
3948c2ecf20Sopenharmony_ci		bfa_fsm_set_state(rspq, rspq_sm_dbell_wait);
3958c2ecf20Sopenharmony_ci		break;
3968c2ecf20Sopenharmony_ci
3978c2ecf20Sopenharmony_ci	default:
3988c2ecf20Sopenharmony_ci		bfa_sm_fault(event);
3998c2ecf20Sopenharmony_ci	}
4008c2ecf20Sopenharmony_ci}
4018c2ecf20Sopenharmony_ci
4028c2ecf20Sopenharmony_cistatic void
4038c2ecf20Sopenharmony_cirspq_sm_dbell_wait_entry(struct bfa_msgq_rspq *rspq)
4048c2ecf20Sopenharmony_ci{
4058c2ecf20Sopenharmony_ci	if (!bfa_nw_ioc_is_disabled(rspq->msgq->ioc))
4068c2ecf20Sopenharmony_ci		bfa_msgq_rspq_dbell(rspq);
4078c2ecf20Sopenharmony_ci}
4088c2ecf20Sopenharmony_ci
4098c2ecf20Sopenharmony_cistatic void
4108c2ecf20Sopenharmony_cirspq_sm_dbell_wait(struct bfa_msgq_rspq *rspq, enum rspq_event event)
4118c2ecf20Sopenharmony_ci{
4128c2ecf20Sopenharmony_ci	switch (event) {
4138c2ecf20Sopenharmony_ci	case RSPQ_E_STOP:
4148c2ecf20Sopenharmony_ci	case RSPQ_E_FAIL:
4158c2ecf20Sopenharmony_ci		bfa_fsm_set_state(rspq, rspq_sm_stopped);
4168c2ecf20Sopenharmony_ci		break;
4178c2ecf20Sopenharmony_ci
4188c2ecf20Sopenharmony_ci	case RSPQ_E_RESP:
4198c2ecf20Sopenharmony_ci		rspq->flags |= BFA_MSGQ_RSPQ_F_DB_UPDATE;
4208c2ecf20Sopenharmony_ci		break;
4218c2ecf20Sopenharmony_ci
4228c2ecf20Sopenharmony_ci	case RSPQ_E_DB_READY:
4238c2ecf20Sopenharmony_ci		if (rspq->flags & BFA_MSGQ_RSPQ_F_DB_UPDATE) {
4248c2ecf20Sopenharmony_ci			rspq->flags &= ~BFA_MSGQ_RSPQ_F_DB_UPDATE;
4258c2ecf20Sopenharmony_ci			bfa_fsm_set_state(rspq, rspq_sm_dbell_wait);
4268c2ecf20Sopenharmony_ci		} else
4278c2ecf20Sopenharmony_ci			bfa_fsm_set_state(rspq, rspq_sm_ready);
4288c2ecf20Sopenharmony_ci		break;
4298c2ecf20Sopenharmony_ci
4308c2ecf20Sopenharmony_ci	default:
4318c2ecf20Sopenharmony_ci		bfa_sm_fault(event);
4328c2ecf20Sopenharmony_ci	}
4338c2ecf20Sopenharmony_ci}
4348c2ecf20Sopenharmony_ci
4358c2ecf20Sopenharmony_cistatic void
4368c2ecf20Sopenharmony_cibfa_msgq_rspq_dbell_ready(void *arg)
4378c2ecf20Sopenharmony_ci{
4388c2ecf20Sopenharmony_ci	struct bfa_msgq_rspq *rspq = (struct bfa_msgq_rspq *)arg;
4398c2ecf20Sopenharmony_ci	bfa_fsm_send_event(rspq, RSPQ_E_DB_READY);
4408c2ecf20Sopenharmony_ci}
4418c2ecf20Sopenharmony_ci
4428c2ecf20Sopenharmony_cistatic void
4438c2ecf20Sopenharmony_cibfa_msgq_rspq_dbell(struct bfa_msgq_rspq *rspq)
4448c2ecf20Sopenharmony_ci{
4458c2ecf20Sopenharmony_ci	struct bfi_msgq_h2i_db *dbell =
4468c2ecf20Sopenharmony_ci		(struct bfi_msgq_h2i_db *)(&rspq->dbell_mb.msg[0]);
4478c2ecf20Sopenharmony_ci
4488c2ecf20Sopenharmony_ci	memset(dbell, 0, sizeof(struct bfi_msgq_h2i_db));
4498c2ecf20Sopenharmony_ci	bfi_h2i_set(dbell->mh, BFI_MC_MSGQ, BFI_MSGQ_H2I_DOORBELL_CI, 0);
4508c2ecf20Sopenharmony_ci	dbell->mh.mtag.i2htok = 0;
4518c2ecf20Sopenharmony_ci	dbell->idx.rspq_ci = htons(rspq->consumer_index);
4528c2ecf20Sopenharmony_ci
4538c2ecf20Sopenharmony_ci	if (!bfa_nw_ioc_mbox_queue(rspq->msgq->ioc, &rspq->dbell_mb,
4548c2ecf20Sopenharmony_ci				bfa_msgq_rspq_dbell_ready, rspq)) {
4558c2ecf20Sopenharmony_ci		bfa_msgq_rspq_dbell_ready(rspq);
4568c2ecf20Sopenharmony_ci	}
4578c2ecf20Sopenharmony_ci}
4588c2ecf20Sopenharmony_ci
4598c2ecf20Sopenharmony_cistatic void
4608c2ecf20Sopenharmony_cibfa_msgq_rspq_pi_update(struct bfa_msgq_rspq *rspq, struct bfi_mbmsg *mb)
4618c2ecf20Sopenharmony_ci{
4628c2ecf20Sopenharmony_ci	struct bfi_msgq_i2h_db *dbell = (struct bfi_msgq_i2h_db *)mb;
4638c2ecf20Sopenharmony_ci	struct bfi_msgq_mhdr *msghdr;
4648c2ecf20Sopenharmony_ci	int num_entries;
4658c2ecf20Sopenharmony_ci	int mc;
4668c2ecf20Sopenharmony_ci	u8 *rspq_qe;
4678c2ecf20Sopenharmony_ci
4688c2ecf20Sopenharmony_ci	rspq->producer_index = ntohs(dbell->idx.rspq_pi);
4698c2ecf20Sopenharmony_ci
4708c2ecf20Sopenharmony_ci	while (rspq->consumer_index != rspq->producer_index) {
4718c2ecf20Sopenharmony_ci		rspq_qe = (u8 *)rspq->addr.kva;
4728c2ecf20Sopenharmony_ci		rspq_qe += (rspq->consumer_index * BFI_MSGQ_RSP_ENTRY_SIZE);
4738c2ecf20Sopenharmony_ci		msghdr = (struct bfi_msgq_mhdr *)rspq_qe;
4748c2ecf20Sopenharmony_ci
4758c2ecf20Sopenharmony_ci		mc = msghdr->msg_class;
4768c2ecf20Sopenharmony_ci		num_entries = ntohs(msghdr->num_entries);
4778c2ecf20Sopenharmony_ci
4788c2ecf20Sopenharmony_ci		if ((mc >= BFI_MC_MAX) || (rspq->rsphdlr[mc].cbfn == NULL))
4798c2ecf20Sopenharmony_ci			break;
4808c2ecf20Sopenharmony_ci
4818c2ecf20Sopenharmony_ci		(rspq->rsphdlr[mc].cbfn)(rspq->rsphdlr[mc].cbarg, msghdr);
4828c2ecf20Sopenharmony_ci
4838c2ecf20Sopenharmony_ci		BFA_MSGQ_INDX_ADD(rspq->consumer_index, num_entries,
4848c2ecf20Sopenharmony_ci				rspq->depth);
4858c2ecf20Sopenharmony_ci	}
4868c2ecf20Sopenharmony_ci
4878c2ecf20Sopenharmony_ci	bfa_fsm_send_event(rspq, RSPQ_E_RESP);
4888c2ecf20Sopenharmony_ci}
4898c2ecf20Sopenharmony_ci
4908c2ecf20Sopenharmony_cistatic void
4918c2ecf20Sopenharmony_cibfa_msgq_rspq_attach(struct bfa_msgq_rspq *rspq, struct bfa_msgq *msgq)
4928c2ecf20Sopenharmony_ci{
4938c2ecf20Sopenharmony_ci	rspq->depth = BFA_MSGQ_RSPQ_NUM_ENTRY;
4948c2ecf20Sopenharmony_ci	rspq->msgq = msgq;
4958c2ecf20Sopenharmony_ci	bfa_fsm_set_state(rspq, rspq_sm_stopped);
4968c2ecf20Sopenharmony_ci}
4978c2ecf20Sopenharmony_ci
4988c2ecf20Sopenharmony_cistatic void
4998c2ecf20Sopenharmony_cibfa_msgq_init_rsp(struct bfa_msgq *msgq,
5008c2ecf20Sopenharmony_ci		 struct bfi_mbmsg *mb)
5018c2ecf20Sopenharmony_ci{
5028c2ecf20Sopenharmony_ci	bfa_fsm_send_event(&msgq->cmdq, CMDQ_E_INIT_RESP);
5038c2ecf20Sopenharmony_ci	bfa_fsm_send_event(&msgq->rspq, RSPQ_E_INIT_RESP);
5048c2ecf20Sopenharmony_ci}
5058c2ecf20Sopenharmony_ci
5068c2ecf20Sopenharmony_cistatic void
5078c2ecf20Sopenharmony_cibfa_msgq_init(void *arg)
5088c2ecf20Sopenharmony_ci{
5098c2ecf20Sopenharmony_ci	struct bfa_msgq *msgq = (struct bfa_msgq *)arg;
5108c2ecf20Sopenharmony_ci	struct bfi_msgq_cfg_req *msgq_cfg =
5118c2ecf20Sopenharmony_ci		(struct bfi_msgq_cfg_req *)&msgq->init_mb.msg[0];
5128c2ecf20Sopenharmony_ci
5138c2ecf20Sopenharmony_ci	memset(msgq_cfg, 0, sizeof(struct bfi_msgq_cfg_req));
5148c2ecf20Sopenharmony_ci	bfi_h2i_set(msgq_cfg->mh, BFI_MC_MSGQ, BFI_MSGQ_H2I_INIT_REQ, 0);
5158c2ecf20Sopenharmony_ci	msgq_cfg->mh.mtag.i2htok = 0;
5168c2ecf20Sopenharmony_ci
5178c2ecf20Sopenharmony_ci	bfa_dma_be_addr_set(msgq_cfg->cmdq.addr, msgq->cmdq.addr.pa);
5188c2ecf20Sopenharmony_ci	msgq_cfg->cmdq.q_depth = htons(msgq->cmdq.depth);
5198c2ecf20Sopenharmony_ci	bfa_dma_be_addr_set(msgq_cfg->rspq.addr, msgq->rspq.addr.pa);
5208c2ecf20Sopenharmony_ci	msgq_cfg->rspq.q_depth = htons(msgq->rspq.depth);
5218c2ecf20Sopenharmony_ci
5228c2ecf20Sopenharmony_ci	bfa_nw_ioc_mbox_queue(msgq->ioc, &msgq->init_mb, NULL, NULL);
5238c2ecf20Sopenharmony_ci}
5248c2ecf20Sopenharmony_ci
5258c2ecf20Sopenharmony_cistatic void
5268c2ecf20Sopenharmony_cibfa_msgq_isr(void *cbarg, struct bfi_mbmsg *msg)
5278c2ecf20Sopenharmony_ci{
5288c2ecf20Sopenharmony_ci	struct bfa_msgq *msgq = (struct bfa_msgq *)cbarg;
5298c2ecf20Sopenharmony_ci
5308c2ecf20Sopenharmony_ci	switch (msg->mh.msg_id) {
5318c2ecf20Sopenharmony_ci	case BFI_MSGQ_I2H_INIT_RSP:
5328c2ecf20Sopenharmony_ci		bfa_msgq_init_rsp(msgq, msg);
5338c2ecf20Sopenharmony_ci		break;
5348c2ecf20Sopenharmony_ci
5358c2ecf20Sopenharmony_ci	case BFI_MSGQ_I2H_DOORBELL_PI:
5368c2ecf20Sopenharmony_ci		bfa_msgq_rspq_pi_update(&msgq->rspq, msg);
5378c2ecf20Sopenharmony_ci		break;
5388c2ecf20Sopenharmony_ci
5398c2ecf20Sopenharmony_ci	case BFI_MSGQ_I2H_DOORBELL_CI:
5408c2ecf20Sopenharmony_ci		bfa_msgq_cmdq_ci_update(&msgq->cmdq, msg);
5418c2ecf20Sopenharmony_ci		break;
5428c2ecf20Sopenharmony_ci
5438c2ecf20Sopenharmony_ci	case BFI_MSGQ_I2H_CMDQ_COPY_REQ:
5448c2ecf20Sopenharmony_ci		bfa_msgq_cmdq_copy_req(&msgq->cmdq, msg);
5458c2ecf20Sopenharmony_ci		break;
5468c2ecf20Sopenharmony_ci
5478c2ecf20Sopenharmony_ci	default:
5488c2ecf20Sopenharmony_ci		BUG_ON(1);
5498c2ecf20Sopenharmony_ci	}
5508c2ecf20Sopenharmony_ci}
5518c2ecf20Sopenharmony_ci
5528c2ecf20Sopenharmony_cistatic void
5538c2ecf20Sopenharmony_cibfa_msgq_notify(void *cbarg, enum bfa_ioc_event event)
5548c2ecf20Sopenharmony_ci{
5558c2ecf20Sopenharmony_ci	struct bfa_msgq *msgq = (struct bfa_msgq *)cbarg;
5568c2ecf20Sopenharmony_ci
5578c2ecf20Sopenharmony_ci	switch (event) {
5588c2ecf20Sopenharmony_ci	case BFA_IOC_E_ENABLED:
5598c2ecf20Sopenharmony_ci		bfa_wc_init(&msgq->init_wc, bfa_msgq_init, msgq);
5608c2ecf20Sopenharmony_ci		bfa_wc_up(&msgq->init_wc);
5618c2ecf20Sopenharmony_ci		bfa_fsm_send_event(&msgq->cmdq, CMDQ_E_START);
5628c2ecf20Sopenharmony_ci		bfa_wc_up(&msgq->init_wc);
5638c2ecf20Sopenharmony_ci		bfa_fsm_send_event(&msgq->rspq, RSPQ_E_START);
5648c2ecf20Sopenharmony_ci		bfa_wc_wait(&msgq->init_wc);
5658c2ecf20Sopenharmony_ci		break;
5668c2ecf20Sopenharmony_ci
5678c2ecf20Sopenharmony_ci	case BFA_IOC_E_DISABLED:
5688c2ecf20Sopenharmony_ci		bfa_fsm_send_event(&msgq->cmdq, CMDQ_E_STOP);
5698c2ecf20Sopenharmony_ci		bfa_fsm_send_event(&msgq->rspq, RSPQ_E_STOP);
5708c2ecf20Sopenharmony_ci		break;
5718c2ecf20Sopenharmony_ci
5728c2ecf20Sopenharmony_ci	case BFA_IOC_E_FAILED:
5738c2ecf20Sopenharmony_ci		bfa_fsm_send_event(&msgq->cmdq, CMDQ_E_FAIL);
5748c2ecf20Sopenharmony_ci		bfa_fsm_send_event(&msgq->rspq, RSPQ_E_FAIL);
5758c2ecf20Sopenharmony_ci		break;
5768c2ecf20Sopenharmony_ci
5778c2ecf20Sopenharmony_ci	default:
5788c2ecf20Sopenharmony_ci		break;
5798c2ecf20Sopenharmony_ci	}
5808c2ecf20Sopenharmony_ci}
5818c2ecf20Sopenharmony_ci
5828c2ecf20Sopenharmony_ciu32
5838c2ecf20Sopenharmony_cibfa_msgq_meminfo(void)
5848c2ecf20Sopenharmony_ci{
5858c2ecf20Sopenharmony_ci	return roundup(BFA_MSGQ_CMDQ_SIZE, BFA_DMA_ALIGN_SZ) +
5868c2ecf20Sopenharmony_ci		roundup(BFA_MSGQ_RSPQ_SIZE, BFA_DMA_ALIGN_SZ);
5878c2ecf20Sopenharmony_ci}
5888c2ecf20Sopenharmony_ci
5898c2ecf20Sopenharmony_civoid
5908c2ecf20Sopenharmony_cibfa_msgq_memclaim(struct bfa_msgq *msgq, u8 *kva, u64 pa)
5918c2ecf20Sopenharmony_ci{
5928c2ecf20Sopenharmony_ci	msgq->cmdq.addr.kva = kva;
5938c2ecf20Sopenharmony_ci	msgq->cmdq.addr.pa  = pa;
5948c2ecf20Sopenharmony_ci
5958c2ecf20Sopenharmony_ci	kva += roundup(BFA_MSGQ_CMDQ_SIZE, BFA_DMA_ALIGN_SZ);
5968c2ecf20Sopenharmony_ci	pa += roundup(BFA_MSGQ_CMDQ_SIZE, BFA_DMA_ALIGN_SZ);
5978c2ecf20Sopenharmony_ci
5988c2ecf20Sopenharmony_ci	msgq->rspq.addr.kva = kva;
5998c2ecf20Sopenharmony_ci	msgq->rspq.addr.pa = pa;
6008c2ecf20Sopenharmony_ci}
6018c2ecf20Sopenharmony_ci
6028c2ecf20Sopenharmony_civoid
6038c2ecf20Sopenharmony_cibfa_msgq_attach(struct bfa_msgq *msgq, struct bfa_ioc *ioc)
6048c2ecf20Sopenharmony_ci{
6058c2ecf20Sopenharmony_ci	msgq->ioc    = ioc;
6068c2ecf20Sopenharmony_ci
6078c2ecf20Sopenharmony_ci	bfa_msgq_cmdq_attach(&msgq->cmdq, msgq);
6088c2ecf20Sopenharmony_ci	bfa_msgq_rspq_attach(&msgq->rspq, msgq);
6098c2ecf20Sopenharmony_ci
6108c2ecf20Sopenharmony_ci	bfa_nw_ioc_mbox_regisr(msgq->ioc, BFI_MC_MSGQ, bfa_msgq_isr, msgq);
6118c2ecf20Sopenharmony_ci	bfa_ioc_notify_init(&msgq->ioc_notify, bfa_msgq_notify, msgq);
6128c2ecf20Sopenharmony_ci	bfa_nw_ioc_notify_register(msgq->ioc, &msgq->ioc_notify);
6138c2ecf20Sopenharmony_ci}
6148c2ecf20Sopenharmony_ci
6158c2ecf20Sopenharmony_civoid
6168c2ecf20Sopenharmony_cibfa_msgq_regisr(struct bfa_msgq *msgq, enum bfi_mclass mc,
6178c2ecf20Sopenharmony_ci		bfa_msgq_mcfunc_t cbfn, void *cbarg)
6188c2ecf20Sopenharmony_ci{
6198c2ecf20Sopenharmony_ci	msgq->rspq.rsphdlr[mc].cbfn	= cbfn;
6208c2ecf20Sopenharmony_ci	msgq->rspq.rsphdlr[mc].cbarg	= cbarg;
6218c2ecf20Sopenharmony_ci}
6228c2ecf20Sopenharmony_ci
6238c2ecf20Sopenharmony_civoid
6248c2ecf20Sopenharmony_cibfa_msgq_cmd_post(struct bfa_msgq *msgq,  struct bfa_msgq_cmd_entry *cmd)
6258c2ecf20Sopenharmony_ci{
6268c2ecf20Sopenharmony_ci	if (ntohs(cmd->msg_hdr->num_entries) <=
6278c2ecf20Sopenharmony_ci		BFA_MSGQ_FREE_CNT(&msgq->cmdq)) {
6288c2ecf20Sopenharmony_ci		__cmd_copy(&msgq->cmdq, cmd);
6298c2ecf20Sopenharmony_ci		call_cmdq_ent_cbfn(cmd, BFA_STATUS_OK);
6308c2ecf20Sopenharmony_ci		bfa_fsm_send_event(&msgq->cmdq, CMDQ_E_POST);
6318c2ecf20Sopenharmony_ci	} else {
6328c2ecf20Sopenharmony_ci		list_add_tail(&cmd->qe, &msgq->cmdq.pending_q);
6338c2ecf20Sopenharmony_ci	}
6348c2ecf20Sopenharmony_ci}
6358c2ecf20Sopenharmony_ci
6368c2ecf20Sopenharmony_civoid
6378c2ecf20Sopenharmony_cibfa_msgq_rsp_copy(struct bfa_msgq *msgq, u8 *buf, size_t buf_len)
6388c2ecf20Sopenharmony_ci{
6398c2ecf20Sopenharmony_ci	struct bfa_msgq_rspq *rspq = &msgq->rspq;
6408c2ecf20Sopenharmony_ci	size_t len = buf_len;
6418c2ecf20Sopenharmony_ci	size_t to_copy;
6428c2ecf20Sopenharmony_ci	int ci;
6438c2ecf20Sopenharmony_ci	u8 *src, *dst;
6448c2ecf20Sopenharmony_ci
6458c2ecf20Sopenharmony_ci	ci = rspq->consumer_index;
6468c2ecf20Sopenharmony_ci	src = (u8 *)rspq->addr.kva;
6478c2ecf20Sopenharmony_ci	src += (ci * BFI_MSGQ_RSP_ENTRY_SIZE);
6488c2ecf20Sopenharmony_ci	dst = buf;
6498c2ecf20Sopenharmony_ci
6508c2ecf20Sopenharmony_ci	while (len) {
6518c2ecf20Sopenharmony_ci		to_copy = (len < BFI_MSGQ_RSP_ENTRY_SIZE) ?
6528c2ecf20Sopenharmony_ci				len : BFI_MSGQ_RSP_ENTRY_SIZE;
6538c2ecf20Sopenharmony_ci		memcpy(dst, src, to_copy);
6548c2ecf20Sopenharmony_ci		len -= to_copy;
6558c2ecf20Sopenharmony_ci		dst += BFI_MSGQ_RSP_ENTRY_SIZE;
6568c2ecf20Sopenharmony_ci		BFA_MSGQ_INDX_ADD(ci, 1, rspq->depth);
6578c2ecf20Sopenharmony_ci		src = (u8 *)rspq->addr.kva;
6588c2ecf20Sopenharmony_ci		src += (ci * BFI_MSGQ_RSP_ENTRY_SIZE);
6598c2ecf20Sopenharmony_ci	}
6608c2ecf20Sopenharmony_ci}
661