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