cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

bfa_msgq.c (15124B)


      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(&cmdq->pending_q)) {
     61		cmdq_ent = list_first_entry(&cmdq->pending_q,
     62					    struct bfa_msgq_cmd_entry, qe);
     63		list_del(&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(&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(cmdq->msgq->ioc, &cmdq->dbell_mb,
    196				bfa_msgq_cmdq_dbell_ready, cmdq)) {
    197		bfa_msgq_cmdq_dbell_ready(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	int num_entries = 0;
    206	size_t to_copy;
    207	u8 *src, *dst;
    208
    209	src = (u8 *)cmd->msg_hdr;
    210	dst = (u8 *)cmdq->addr.kva;
    211	dst += (cmdq->producer_index * BFI_MSGQ_CMD_ENTRY_SIZE);
    212
    213	while (len) {
    214		to_copy = (len < BFI_MSGQ_CMD_ENTRY_SIZE) ?
    215				len : BFI_MSGQ_CMD_ENTRY_SIZE;
    216		memcpy(dst, src, to_copy);
    217		len -= to_copy;
    218		src += BFI_MSGQ_CMD_ENTRY_SIZE;
    219		BFA_MSGQ_INDX_ADD(cmdq->producer_index, 1, cmdq->depth);
    220		dst = (u8 *)cmdq->addr.kva;
    221		dst += (cmdq->producer_index * BFI_MSGQ_CMD_ENTRY_SIZE);
    222		num_entries++;
    223	}
    224
    225}
    226
    227static void
    228bfa_msgq_cmdq_ci_update(struct bfa_msgq_cmdq *cmdq, struct bfi_mbmsg *mb)
    229{
    230	struct bfi_msgq_i2h_db *dbell = (struct bfi_msgq_i2h_db *)mb;
    231	struct bfa_msgq_cmd_entry *cmd;
    232	int posted = 0;
    233
    234	cmdq->consumer_index = ntohs(dbell->idx.cmdq_ci);
    235
    236	/* Walk through pending list to see if the command can be posted */
    237	while (!list_empty(&cmdq->pending_q)) {
    238		cmd = list_first_entry(&cmdq->pending_q,
    239				       struct bfa_msgq_cmd_entry, qe);
    240		if (ntohs(cmd->msg_hdr->num_entries) <=
    241			BFA_MSGQ_FREE_CNT(cmdq)) {
    242			list_del(&cmd->qe);
    243			__cmd_copy(cmdq, cmd);
    244			posted = 1;
    245			call_cmdq_ent_cbfn(cmd, BFA_STATUS_OK);
    246		} else {
    247			break;
    248		}
    249	}
    250
    251	if (posted)
    252		bfa_fsm_send_event(cmdq, CMDQ_E_POST);
    253}
    254
    255static void
    256bfa_msgq_cmdq_copy_next(void *arg)
    257{
    258	struct bfa_msgq_cmdq *cmdq = (struct bfa_msgq_cmdq *)arg;
    259
    260	if (cmdq->bytes_to_copy)
    261		bfa_msgq_cmdq_copy_rsp(cmdq);
    262}
    263
    264static void
    265bfa_msgq_cmdq_copy_req(struct bfa_msgq_cmdq *cmdq, struct bfi_mbmsg *mb)
    266{
    267	struct bfi_msgq_i2h_cmdq_copy_req *req =
    268		(struct bfi_msgq_i2h_cmdq_copy_req *)mb;
    269
    270	cmdq->token = 0;
    271	cmdq->offset = ntohs(req->offset);
    272	cmdq->bytes_to_copy = ntohs(req->len);
    273	bfa_msgq_cmdq_copy_rsp(cmdq);
    274}
    275
    276static void
    277bfa_msgq_cmdq_copy_rsp(struct bfa_msgq_cmdq *cmdq)
    278{
    279	struct bfi_msgq_h2i_cmdq_copy_rsp *rsp =
    280		(struct bfi_msgq_h2i_cmdq_copy_rsp *)&cmdq->copy_mb.msg[0];
    281	int copied;
    282	u8 *addr = (u8 *)cmdq->addr.kva;
    283
    284	memset(rsp, 0, sizeof(struct bfi_msgq_h2i_cmdq_copy_rsp));
    285	bfi_h2i_set(rsp->mh, BFI_MC_MSGQ, BFI_MSGQ_H2I_CMDQ_COPY_RSP, 0);
    286	rsp->mh.mtag.i2htok = htons(cmdq->token);
    287	copied = (cmdq->bytes_to_copy >= BFI_CMD_COPY_SZ) ? BFI_CMD_COPY_SZ :
    288		cmdq->bytes_to_copy;
    289	addr += cmdq->offset;
    290	memcpy(rsp->data, addr, copied);
    291
    292	cmdq->token++;
    293	cmdq->offset += copied;
    294	cmdq->bytes_to_copy -= copied;
    295
    296	if (!bfa_nw_ioc_mbox_queue(cmdq->msgq->ioc, &cmdq->copy_mb,
    297				bfa_msgq_cmdq_copy_next, cmdq)) {
    298		bfa_msgq_cmdq_copy_next(cmdq);
    299	}
    300}
    301
    302static void
    303bfa_msgq_cmdq_attach(struct bfa_msgq_cmdq *cmdq, struct bfa_msgq *msgq)
    304{
    305	cmdq->depth = BFA_MSGQ_CMDQ_NUM_ENTRY;
    306	INIT_LIST_HEAD(&cmdq->pending_q);
    307	cmdq->msgq = msgq;
    308	bfa_fsm_set_state(cmdq, cmdq_sm_stopped);
    309}
    310
    311static void bfa_msgq_rspq_dbell(struct bfa_msgq_rspq *rspq);
    312
    313enum rspq_event {
    314	RSPQ_E_START			= 1,
    315	RSPQ_E_STOP			= 2,
    316	RSPQ_E_FAIL			= 3,
    317	RSPQ_E_RESP			= 4,
    318	RSPQ_E_INIT_RESP		= 5,
    319	RSPQ_E_DB_READY			= 6,
    320};
    321
    322bfa_fsm_state_decl(rspq, stopped, struct bfa_msgq_rspq, enum rspq_event);
    323bfa_fsm_state_decl(rspq, init_wait, struct bfa_msgq_rspq,
    324			enum rspq_event);
    325bfa_fsm_state_decl(rspq, ready, struct bfa_msgq_rspq, enum rspq_event);
    326bfa_fsm_state_decl(rspq, dbell_wait, struct bfa_msgq_rspq,
    327			enum rspq_event);
    328
    329static void
    330rspq_sm_stopped_entry(struct bfa_msgq_rspq *rspq)
    331{
    332	rspq->producer_index = 0;
    333	rspq->consumer_index = 0;
    334	rspq->flags = 0;
    335}
    336
    337static void
    338rspq_sm_stopped(struct bfa_msgq_rspq *rspq, enum rspq_event event)
    339{
    340	switch (event) {
    341	case RSPQ_E_START:
    342		bfa_fsm_set_state(rspq, rspq_sm_init_wait);
    343		break;
    344
    345	case RSPQ_E_STOP:
    346	case RSPQ_E_FAIL:
    347		/* No-op */
    348		break;
    349
    350	default:
    351		bfa_sm_fault(event);
    352	}
    353}
    354
    355static void
    356rspq_sm_init_wait_entry(struct bfa_msgq_rspq *rspq)
    357{
    358	bfa_wc_down(&rspq->msgq->init_wc);
    359}
    360
    361static void
    362rspq_sm_init_wait(struct bfa_msgq_rspq *rspq, enum rspq_event event)
    363{
    364	switch (event) {
    365	case RSPQ_E_FAIL:
    366	case RSPQ_E_STOP:
    367		bfa_fsm_set_state(rspq, rspq_sm_stopped);
    368		break;
    369
    370	case RSPQ_E_INIT_RESP:
    371		bfa_fsm_set_state(rspq, rspq_sm_ready);
    372		break;
    373
    374	default:
    375		bfa_sm_fault(event);
    376	}
    377}
    378
    379static void
    380rspq_sm_ready_entry(struct bfa_msgq_rspq *rspq)
    381{
    382}
    383
    384static void
    385rspq_sm_ready(struct bfa_msgq_rspq *rspq, enum rspq_event event)
    386{
    387	switch (event) {
    388	case RSPQ_E_STOP:
    389	case RSPQ_E_FAIL:
    390		bfa_fsm_set_state(rspq, rspq_sm_stopped);
    391		break;
    392
    393	case RSPQ_E_RESP:
    394		bfa_fsm_set_state(rspq, rspq_sm_dbell_wait);
    395		break;
    396
    397	default:
    398		bfa_sm_fault(event);
    399	}
    400}
    401
    402static void
    403rspq_sm_dbell_wait_entry(struct bfa_msgq_rspq *rspq)
    404{
    405	if (!bfa_nw_ioc_is_disabled(rspq->msgq->ioc))
    406		bfa_msgq_rspq_dbell(rspq);
    407}
    408
    409static void
    410rspq_sm_dbell_wait(struct bfa_msgq_rspq *rspq, enum rspq_event event)
    411{
    412	switch (event) {
    413	case RSPQ_E_STOP:
    414	case RSPQ_E_FAIL:
    415		bfa_fsm_set_state(rspq, rspq_sm_stopped);
    416		break;
    417
    418	case RSPQ_E_RESP:
    419		rspq->flags |= BFA_MSGQ_RSPQ_F_DB_UPDATE;
    420		break;
    421
    422	case RSPQ_E_DB_READY:
    423		if (rspq->flags & BFA_MSGQ_RSPQ_F_DB_UPDATE) {
    424			rspq->flags &= ~BFA_MSGQ_RSPQ_F_DB_UPDATE;
    425			bfa_fsm_set_state(rspq, rspq_sm_dbell_wait);
    426		} else
    427			bfa_fsm_set_state(rspq, rspq_sm_ready);
    428		break;
    429
    430	default:
    431		bfa_sm_fault(event);
    432	}
    433}
    434
    435static void
    436bfa_msgq_rspq_dbell_ready(void *arg)
    437{
    438	struct bfa_msgq_rspq *rspq = (struct bfa_msgq_rspq *)arg;
    439	bfa_fsm_send_event(rspq, RSPQ_E_DB_READY);
    440}
    441
    442static void
    443bfa_msgq_rspq_dbell(struct bfa_msgq_rspq *rspq)
    444{
    445	struct bfi_msgq_h2i_db *dbell =
    446		(struct bfi_msgq_h2i_db *)(&rspq->dbell_mb.msg[0]);
    447
    448	memset(dbell, 0, sizeof(struct bfi_msgq_h2i_db));
    449	bfi_h2i_set(dbell->mh, BFI_MC_MSGQ, BFI_MSGQ_H2I_DOORBELL_CI, 0);
    450	dbell->mh.mtag.i2htok = 0;
    451	dbell->idx.rspq_ci = htons(rspq->consumer_index);
    452
    453	if (!bfa_nw_ioc_mbox_queue(rspq->msgq->ioc, &rspq->dbell_mb,
    454				bfa_msgq_rspq_dbell_ready, rspq)) {
    455		bfa_msgq_rspq_dbell_ready(rspq);
    456	}
    457}
    458
    459static void
    460bfa_msgq_rspq_pi_update(struct bfa_msgq_rspq *rspq, struct bfi_mbmsg *mb)
    461{
    462	struct bfi_msgq_i2h_db *dbell = (struct bfi_msgq_i2h_db *)mb;
    463	struct bfi_msgq_mhdr *msghdr;
    464	int num_entries;
    465	int mc;
    466	u8 *rspq_qe;
    467
    468	rspq->producer_index = ntohs(dbell->idx.rspq_pi);
    469
    470	while (rspq->consumer_index != rspq->producer_index) {
    471		rspq_qe = (u8 *)rspq->addr.kva;
    472		rspq_qe += (rspq->consumer_index * BFI_MSGQ_RSP_ENTRY_SIZE);
    473		msghdr = (struct bfi_msgq_mhdr *)rspq_qe;
    474
    475		mc = msghdr->msg_class;
    476		num_entries = ntohs(msghdr->num_entries);
    477
    478		if ((mc >= BFI_MC_MAX) || (rspq->rsphdlr[mc].cbfn == NULL))
    479			break;
    480
    481		(rspq->rsphdlr[mc].cbfn)(rspq->rsphdlr[mc].cbarg, msghdr);
    482
    483		BFA_MSGQ_INDX_ADD(rspq->consumer_index, num_entries,
    484				rspq->depth);
    485	}
    486
    487	bfa_fsm_send_event(rspq, RSPQ_E_RESP);
    488}
    489
    490static void
    491bfa_msgq_rspq_attach(struct bfa_msgq_rspq *rspq, struct bfa_msgq *msgq)
    492{
    493	rspq->depth = BFA_MSGQ_RSPQ_NUM_ENTRY;
    494	rspq->msgq = msgq;
    495	bfa_fsm_set_state(rspq, rspq_sm_stopped);
    496}
    497
    498static void
    499bfa_msgq_init_rsp(struct bfa_msgq *msgq,
    500		 struct bfi_mbmsg *mb)
    501{
    502	bfa_fsm_send_event(&msgq->cmdq, CMDQ_E_INIT_RESP);
    503	bfa_fsm_send_event(&msgq->rspq, RSPQ_E_INIT_RESP);
    504}
    505
    506static void
    507bfa_msgq_init(void *arg)
    508{
    509	struct bfa_msgq *msgq = (struct bfa_msgq *)arg;
    510	struct bfi_msgq_cfg_req *msgq_cfg =
    511		(struct bfi_msgq_cfg_req *)&msgq->init_mb.msg[0];
    512
    513	memset(msgq_cfg, 0, sizeof(struct bfi_msgq_cfg_req));
    514	bfi_h2i_set(msgq_cfg->mh, BFI_MC_MSGQ, BFI_MSGQ_H2I_INIT_REQ, 0);
    515	msgq_cfg->mh.mtag.i2htok = 0;
    516
    517	bfa_dma_be_addr_set(msgq_cfg->cmdq.addr, msgq->cmdq.addr.pa);
    518	msgq_cfg->cmdq.q_depth = htons(msgq->cmdq.depth);
    519	bfa_dma_be_addr_set(msgq_cfg->rspq.addr, msgq->rspq.addr.pa);
    520	msgq_cfg->rspq.q_depth = htons(msgq->rspq.depth);
    521
    522	bfa_nw_ioc_mbox_queue(msgq->ioc, &msgq->init_mb, NULL, NULL);
    523}
    524
    525static void
    526bfa_msgq_isr(void *cbarg, struct bfi_mbmsg *msg)
    527{
    528	struct bfa_msgq *msgq = (struct bfa_msgq *)cbarg;
    529
    530	switch (msg->mh.msg_id) {
    531	case BFI_MSGQ_I2H_INIT_RSP:
    532		bfa_msgq_init_rsp(msgq, msg);
    533		break;
    534
    535	case BFI_MSGQ_I2H_DOORBELL_PI:
    536		bfa_msgq_rspq_pi_update(&msgq->rspq, msg);
    537		break;
    538
    539	case BFI_MSGQ_I2H_DOORBELL_CI:
    540		bfa_msgq_cmdq_ci_update(&msgq->cmdq, msg);
    541		break;
    542
    543	case BFI_MSGQ_I2H_CMDQ_COPY_REQ:
    544		bfa_msgq_cmdq_copy_req(&msgq->cmdq, msg);
    545		break;
    546
    547	default:
    548		BUG_ON(1);
    549	}
    550}
    551
    552static void
    553bfa_msgq_notify(void *cbarg, enum bfa_ioc_event event)
    554{
    555	struct bfa_msgq *msgq = (struct bfa_msgq *)cbarg;
    556
    557	switch (event) {
    558	case BFA_IOC_E_ENABLED:
    559		bfa_wc_init(&msgq->init_wc, bfa_msgq_init, msgq);
    560		bfa_wc_up(&msgq->init_wc);
    561		bfa_fsm_send_event(&msgq->cmdq, CMDQ_E_START);
    562		bfa_wc_up(&msgq->init_wc);
    563		bfa_fsm_send_event(&msgq->rspq, RSPQ_E_START);
    564		bfa_wc_wait(&msgq->init_wc);
    565		break;
    566
    567	case BFA_IOC_E_DISABLED:
    568		bfa_fsm_send_event(&msgq->cmdq, CMDQ_E_STOP);
    569		bfa_fsm_send_event(&msgq->rspq, RSPQ_E_STOP);
    570		break;
    571
    572	case BFA_IOC_E_FAILED:
    573		bfa_fsm_send_event(&msgq->cmdq, CMDQ_E_FAIL);
    574		bfa_fsm_send_event(&msgq->rspq, RSPQ_E_FAIL);
    575		break;
    576
    577	default:
    578		break;
    579	}
    580}
    581
    582u32
    583bfa_msgq_meminfo(void)
    584{
    585	return roundup(BFA_MSGQ_CMDQ_SIZE, BFA_DMA_ALIGN_SZ) +
    586		roundup(BFA_MSGQ_RSPQ_SIZE, BFA_DMA_ALIGN_SZ);
    587}
    588
    589void
    590bfa_msgq_memclaim(struct bfa_msgq *msgq, u8 *kva, u64 pa)
    591{
    592	msgq->cmdq.addr.kva = kva;
    593	msgq->cmdq.addr.pa  = pa;
    594
    595	kva += roundup(BFA_MSGQ_CMDQ_SIZE, BFA_DMA_ALIGN_SZ);
    596	pa += roundup(BFA_MSGQ_CMDQ_SIZE, BFA_DMA_ALIGN_SZ);
    597
    598	msgq->rspq.addr.kva = kva;
    599	msgq->rspq.addr.pa = pa;
    600}
    601
    602void
    603bfa_msgq_attach(struct bfa_msgq *msgq, struct bfa_ioc *ioc)
    604{
    605	msgq->ioc    = ioc;
    606
    607	bfa_msgq_cmdq_attach(&msgq->cmdq, msgq);
    608	bfa_msgq_rspq_attach(&msgq->rspq, msgq);
    609
    610	bfa_nw_ioc_mbox_regisr(msgq->ioc, BFI_MC_MSGQ, bfa_msgq_isr, msgq);
    611	bfa_ioc_notify_init(&msgq->ioc_notify, bfa_msgq_notify, msgq);
    612	bfa_nw_ioc_notify_register(msgq->ioc, &msgq->ioc_notify);
    613}
    614
    615void
    616bfa_msgq_regisr(struct bfa_msgq *msgq, enum bfi_mclass mc,
    617		bfa_msgq_mcfunc_t cbfn, void *cbarg)
    618{
    619	msgq->rspq.rsphdlr[mc].cbfn	= cbfn;
    620	msgq->rspq.rsphdlr[mc].cbarg	= cbarg;
    621}
    622
    623void
    624bfa_msgq_cmd_post(struct bfa_msgq *msgq,  struct bfa_msgq_cmd_entry *cmd)
    625{
    626	if (ntohs(cmd->msg_hdr->num_entries) <=
    627		BFA_MSGQ_FREE_CNT(&msgq->cmdq)) {
    628		__cmd_copy(&msgq->cmdq, cmd);
    629		call_cmdq_ent_cbfn(cmd, BFA_STATUS_OK);
    630		bfa_fsm_send_event(&msgq->cmdq, CMDQ_E_POST);
    631	} else {
    632		list_add_tail(&cmd->qe, &msgq->cmdq.pending_q);
    633	}
    634}
    635
    636void
    637bfa_msgq_rsp_copy(struct bfa_msgq *msgq, u8 *buf, size_t buf_len)
    638{
    639	struct bfa_msgq_rspq *rspq = &msgq->rspq;
    640	size_t len = buf_len;
    641	size_t to_copy;
    642	int ci;
    643	u8 *src, *dst;
    644
    645	ci = rspq->consumer_index;
    646	src = (u8 *)rspq->addr.kva;
    647	src += (ci * BFI_MSGQ_RSP_ENTRY_SIZE);
    648	dst = buf;
    649
    650	while (len) {
    651		to_copy = (len < BFI_MSGQ_RSP_ENTRY_SIZE) ?
    652				len : BFI_MSGQ_RSP_ENTRY_SIZE;
    653		memcpy(dst, src, to_copy);
    654		len -= to_copy;
    655		dst += BFI_MSGQ_RSP_ENTRY_SIZE;
    656		BFA_MSGQ_INDX_ADD(ci, 1, rspq->depth);
    657		src = (u8 *)rspq->addr.kva;
    658		src += (ci * BFI_MSGQ_RSP_ENTRY_SIZE);
    659	}
    660}