ocrdma_hw.c revision 2b50176d11866e59208a4ed1623b3fc0ca322690
1fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit/******************************************************************* 2fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * This file is part of the Emulex RoCE Device Driver for * 3fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * RoCE (RDMA over Converged Ethernet) CNA Adapters. * 4fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * Copyright (C) 2008-2012 Emulex. All rights reserved. * 5fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * EMULEX and SLI are trademarks of Emulex. * 6fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * www.emulex.com * 7fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * * 8fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * This program is free software; you can redistribute it and/or * 9fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * modify it under the terms of version 2 of the GNU General * 10fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * Public License as published by the Free Software Foundation. * 11fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * This program is distributed in the hope that it will be useful. * 12fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * 13fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * 14fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE * 15fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD * 16fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * TO BE LEGALLY INVALID. See the GNU General Public License for * 17fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * more details, a copy of which can be found in the file COPYING * 18fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * included with this package. * 19fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * 20fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * Contact Information: 21fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * linux-drivers@emulex.com 22fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * 23fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * Emulex 24fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * 3333 Susan Street 25fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * Costa Mesa, CA 92626 26fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit *******************************************************************/ 27fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 28fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit#include <linux/sched.h> 29fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit#include <linux/interrupt.h> 30fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit#include <linux/log2.h> 31fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit#include <linux/dma-mapping.h> 32fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 33fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit#include <rdma/ib_verbs.h> 34fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit#include <rdma/ib_user_verbs.h> 35fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit#include <rdma/ib_addr.h> 36fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 37fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit#include "ocrdma.h" 38fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit#include "ocrdma_hw.h" 39fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit#include "ocrdma_verbs.h" 40fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit#include "ocrdma_ah.h" 41fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 42fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditenum mbx_status { 43fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_FAILED = 1, 44fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_ILLEGAL_FIELD = 3, 45fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_OOR = 100, 46fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_INVALID_PD = 101, 47fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_PD_INUSE = 102, 48fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_INVALID_CQ = 103, 49fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_INVALID_QP = 104, 50fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_INVALID_LKEY = 105, 51fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_ORD_EXCEEDS = 106, 52fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_IRD_EXCEEDS = 107, 53fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_SENDQ_WQE_EXCEEDS = 108, 54fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_RECVQ_RQE_EXCEEDS = 109, 55fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_SGE_SEND_EXCEEDS = 110, 56fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_SGE_WRITE_EXCEEDS = 111, 57fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_SGE_RECV_EXCEEDS = 112, 58fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_INVALID_STATE_CHANGE = 113, 59fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_MW_BOUND = 114, 60fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_INVALID_VA = 115, 61fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_INVALID_LENGTH = 116, 62fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_INVALID_FBO = 117, 63fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_INVALID_ACC_RIGHTS = 118, 64fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_INVALID_PBE_SIZE = 119, 65fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_INVALID_PBL_ENTRY = 120, 66fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_INVALID_PBL_SHIFT = 121, 67fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_INVALID_SRQ_ID = 129, 68fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_SRQ_ERROR = 133, 69fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_RQE_EXCEEDS = 134, 70fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_MTU_EXCEEDS = 135, 71fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_MAX_QP_EXCEEDS = 136, 72fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_SRQ_LIMIT_EXCEEDS = 137, 73fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_SRQ_SIZE_UNDERUNS = 138, 74fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_QP_BOUND = 130, 75fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_INVALID_CHANGE = 139, 76fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_ATOMIC_OPS_UNSUP = 140, 77fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_INVALID_RNR_NAK_TIMER = 141, 78fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_MW_STILL_BOUND = 142, 79fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_PKEY_INDEX_INVALID = 143, 80fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_STATUS_PKEY_INDEX_EXCEEDS = 144 81fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit}; 82fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 83fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditenum additional_status { 84fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_ADDI_STATUS_INSUFFICIENT_RESOURCES = 22 85fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit}; 86fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 87fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditenum cqe_status { 88fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_CQE_STATUS_INSUFFICIENT_PRIVILEDGES = 1, 89fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_CQE_STATUS_INVALID_PARAMETER = 2, 90fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_CQE_STATUS_INSUFFICIENT_RESOURCES = 3, 91fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_CQE_STATUS_QUEUE_FLUSHING = 4, 92fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_CQE_STATUS_DMA_FAILED = 5 93fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit}; 94fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 95fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic inline void *ocrdma_get_eqe(struct ocrdma_eq *eq) 96fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 97f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala return eq->q.va + (eq->q.tail * sizeof(struct ocrdma_eqe)); 98fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 99fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 100fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic inline void ocrdma_eq_inc_tail(struct ocrdma_eq *eq) 101fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 102fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit eq->q.tail = (eq->q.tail + 1) & (OCRDMA_EQ_LEN - 1); 103fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 104fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 105fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic inline void *ocrdma_get_mcqe(struct ocrdma_dev *dev) 106fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 107fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_mcqe *cqe = (struct ocrdma_mcqe *) 108f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala (dev->mq.cq.va + (dev->mq.cq.tail * sizeof(struct ocrdma_mcqe))); 109fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 110fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!(le32_to_cpu(cqe->valid_ae_cmpl_cons) & OCRDMA_MCQE_VALID_MASK)) 111fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return NULL; 112fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return cqe; 113fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 114fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 115fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic inline void ocrdma_mcq_inc_tail(struct ocrdma_dev *dev) 116fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 117fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev->mq.cq.tail = (dev->mq.cq.tail + 1) & (OCRDMA_MQ_CQ_LEN - 1); 118fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 119fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 120fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic inline struct ocrdma_mqe *ocrdma_get_mqe(struct ocrdma_dev *dev) 121fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 122f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala return dev->mq.sq.va + (dev->mq.sq.head * sizeof(struct ocrdma_mqe)); 123fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 124fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 125fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic inline void ocrdma_mq_inc_head(struct ocrdma_dev *dev) 126fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 127fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev->mq.sq.head = (dev->mq.sq.head + 1) & (OCRDMA_MQ_LEN - 1); 128fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 129fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 130fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic inline void *ocrdma_get_mqe_rsp(struct ocrdma_dev *dev) 131fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 132f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala return dev->mq.sq.va + (dev->mqe_ctx.tag * sizeof(struct ocrdma_mqe)); 133fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 134fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 135fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditenum ib_qp_state get_ibqp_state(enum ocrdma_qp_state qps) 136fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 137fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit switch (qps) { 138fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_QPS_RST: 139fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return IB_QPS_RESET; 140fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_QPS_INIT: 141fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return IB_QPS_INIT; 142fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_QPS_RTR: 143fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return IB_QPS_RTR; 144fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_QPS_RTS: 145fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return IB_QPS_RTS; 146fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_QPS_SQD: 147fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_QPS_SQ_DRAINING: 148fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return IB_QPS_SQD; 149fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_QPS_SQE: 150fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return IB_QPS_SQE; 151fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_QPS_ERR: 152fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return IB_QPS_ERR; 1532b50176d11866e59208a4ed1623b3fc0ca322690Joe Perches } 154fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return IB_QPS_ERR; 155fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 156fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 157abe3afacc5762065244421569ad86afef11813bbRoland Dreierstatic enum ocrdma_qp_state get_ocrdma_qp_state(enum ib_qp_state qps) 158fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 159fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit switch (qps) { 160fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case IB_QPS_RESET: 161fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return OCRDMA_QPS_RST; 162fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case IB_QPS_INIT: 163fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return OCRDMA_QPS_INIT; 164fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case IB_QPS_RTR: 165fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return OCRDMA_QPS_RTR; 166fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case IB_QPS_RTS: 167fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return OCRDMA_QPS_RTS; 168fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case IB_QPS_SQD: 169fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return OCRDMA_QPS_SQD; 170fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case IB_QPS_SQE: 171fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return OCRDMA_QPS_SQE; 172fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case IB_QPS_ERR: 173fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return OCRDMA_QPS_ERR; 1742b50176d11866e59208a4ed1623b3fc0ca322690Joe Perches } 175fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return OCRDMA_QPS_ERR; 176fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 177fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 178fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic int ocrdma_get_mbx_errno(u32 status) 179fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 180f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala int err_num; 181fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u8 mbox_status = (status & OCRDMA_MBX_RSP_STATUS_MASK) >> 182fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_RSP_STATUS_SHIFT; 183fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u8 add_status = (status & OCRDMA_MBX_RSP_ASTATUS_MASK) >> 184fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_RSP_ASTATUS_SHIFT; 185fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 186fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit switch (mbox_status) { 187fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_OOR: 188fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_MAX_QP_EXCEEDS: 189fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit err_num = -EAGAIN; 190fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 191fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 192fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_INVALID_PD: 193fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_INVALID_CQ: 194fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_INVALID_SRQ_ID: 195fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_INVALID_QP: 196fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_INVALID_CHANGE: 197fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_MTU_EXCEEDS: 198fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_INVALID_RNR_NAK_TIMER: 199fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_PKEY_INDEX_INVALID: 200fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_PKEY_INDEX_EXCEEDS: 201fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_ILLEGAL_FIELD: 202fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_INVALID_PBL_ENTRY: 203fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_INVALID_LKEY: 204fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_INVALID_VA: 205fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_INVALID_LENGTH: 206fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_INVALID_FBO: 207fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_INVALID_ACC_RIGHTS: 208fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_INVALID_PBE_SIZE: 209fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_ATOMIC_OPS_UNSUP: 210fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_SRQ_ERROR: 211fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_SRQ_SIZE_UNDERUNS: 212fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit err_num = -EINVAL; 213fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 214fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 215fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_PD_INUSE: 216fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_QP_BOUND: 217fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_MW_STILL_BOUND: 218fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_MW_BOUND: 219fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit err_num = -EBUSY; 220fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 221fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 222fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_RECVQ_RQE_EXCEEDS: 223fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_SGE_RECV_EXCEEDS: 224fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_RQE_EXCEEDS: 225fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_SRQ_LIMIT_EXCEEDS: 226fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_ORD_EXCEEDS: 227fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_IRD_EXCEEDS: 228fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_SENDQ_WQE_EXCEEDS: 229fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_SGE_SEND_EXCEEDS: 230fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_SGE_WRITE_EXCEEDS: 231fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit err_num = -ENOBUFS; 232fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 233fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 234fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_STATUS_FAILED: 235fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit switch (add_status) { 236fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_ADDI_STATUS_INSUFFICIENT_RESOURCES: 237fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit err_num = -EAGAIN; 238fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 239fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 240fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit default: 241fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit err_num = -EFAULT; 242fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 243fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return err_num; 244fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 245fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 246fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic int ocrdma_get_mbx_cqe_errno(u16 cqe_status) 247fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 248fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int err_num = -EINVAL; 249fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 250fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit switch (cqe_status) { 251fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_CQE_STATUS_INSUFFICIENT_PRIVILEDGES: 252fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit err_num = -EPERM; 253fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 254fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_CQE_STATUS_INVALID_PARAMETER: 255fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit err_num = -EINVAL; 256fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 257fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_CQE_STATUS_INSUFFICIENT_RESOURCES: 258fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_CQE_STATUS_QUEUE_FLUSHING: 259f11220ee69f72cf08479f28fd494264ac6a9349bNaresh Gottumukkala err_num = -EINVAL; 260fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 261fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_MBX_CQE_STATUS_DMA_FAILED: 26243a6b4025c79ded5b44e58ba0db97c29dd38d718Naresh Gottumukkala default: 263f11220ee69f72cf08479f28fd494264ac6a9349bNaresh Gottumukkala err_num = -EINVAL; 264fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 265fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 266fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return err_num; 267fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 268fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 269fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditvoid ocrdma_ring_cq_db(struct ocrdma_dev *dev, u16 cq_id, bool armed, 270fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit bool solicited, u16 cqe_popped) 271fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 272fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u32 val = cq_id & OCRDMA_DB_CQ_RING_ID_MASK; 273fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 274fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit val |= ((cq_id & OCRDMA_DB_CQ_RING_ID_EXT_MASK) << 275fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_DB_CQ_RING_ID_EXT_MASK_SHIFT); 276fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 277fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (armed) 278fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit val |= (1 << OCRDMA_DB_CQ_REARM_SHIFT); 279fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (solicited) 280fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit val |= (1 << OCRDMA_DB_CQ_SOLICIT_SHIFT); 281fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit val |= (cqe_popped << OCRDMA_DB_CQ_NUM_POPPED_SHIFT); 282fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit iowrite32(val, dev->nic_info.db + OCRDMA_DB_CQ_OFFSET); 283fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 284fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 285fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic void ocrdma_ring_mq_db(struct ocrdma_dev *dev) 286fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 287fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u32 val = 0; 288fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 289fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit val |= dev->mq.sq.id & OCRDMA_MQ_ID_MASK; 290fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit val |= 1 << OCRDMA_MQ_NUM_MQE_SHIFT; 291fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit iowrite32(val, dev->nic_info.db + OCRDMA_DB_MQ_OFFSET); 292fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 293fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 294fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic void ocrdma_ring_eq_db(struct ocrdma_dev *dev, u16 eq_id, 295fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit bool arm, bool clear_int, u16 num_eqe) 296fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 297fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u32 val = 0; 298fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 299fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit val |= eq_id & OCRDMA_EQ_ID_MASK; 300fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit val |= ((eq_id & OCRDMA_EQ_ID_EXT_MASK) << OCRDMA_EQ_ID_EXT_MASK_SHIFT); 301fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (arm) 302fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit val |= (1 << OCRDMA_REARM_SHIFT); 303fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (clear_int) 304fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit val |= (1 << OCRDMA_EQ_CLR_SHIFT); 305fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit val |= (1 << OCRDMA_EQ_TYPE_SHIFT); 306fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit val |= (num_eqe << OCRDMA_NUM_EQE_SHIFT); 307fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit iowrite32(val, dev->nic_info.db + OCRDMA_DB_EQ_OFFSET); 308fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 309fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 310fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic void ocrdma_init_mch(struct ocrdma_mbx_hdr *cmd_hdr, 311fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u8 opcode, u8 subsys, u32 cmd_len) 312fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 313fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd_hdr->subsys_op = (opcode | (subsys << OCRDMA_MCH_SUBSYS_SHIFT)); 314fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd_hdr->timeout = 20; /* seconds */ 315fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd_hdr->cmd_len = cmd_len - sizeof(struct ocrdma_mbx_hdr); 316fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 317fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 318fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic void *ocrdma_init_emb_mqe(u8 opcode, u32 cmd_len) 319fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 320fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_mqe *mqe; 321fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 322fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit mqe = kzalloc(sizeof(struct ocrdma_mqe), GFP_KERNEL); 323fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!mqe) 324fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return NULL; 325fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit mqe->hdr.spcl_sge_cnt_emb |= 326fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (OCRDMA_MQE_EMBEDDED << OCRDMA_MQE_HDR_EMB_SHIFT) & 327fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MQE_HDR_EMB_MASK; 328fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit mqe->hdr.pyld_len = cmd_len - sizeof(struct ocrdma_mqe_hdr); 329fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 330fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_init_mch(&mqe->u.emb_req.mch, opcode, OCRDMA_SUBSYS_ROCE, 331fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit mqe->hdr.pyld_len); 332fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return mqe; 333fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 334fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 335fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic void ocrdma_free_q(struct ocrdma_dev *dev, struct ocrdma_queue_info *q) 336fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 337fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dma_free_coherent(&dev->nic_info.pdev->dev, q->size, q->va, q->dma); 338fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 339fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 340fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic int ocrdma_alloc_q(struct ocrdma_dev *dev, 341fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_queue_info *q, u16 len, u16 entry_size) 342fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 343fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit memset(q, 0, sizeof(*q)); 344fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit q->len = len; 345fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit q->entry_size = entry_size; 346fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit q->size = len * entry_size; 347fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit q->va = dma_alloc_coherent(&dev->nic_info.pdev->dev, q->size, 348fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit &q->dma, GFP_KERNEL); 349fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!q->va) 350fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return -ENOMEM; 351fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit memset(q->va, 0, q->size); 352fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return 0; 353fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 354fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 355fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic void ocrdma_build_q_pages(struct ocrdma_pa *q_pa, int cnt, 356fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dma_addr_t host_pa, int hw_page_size) 357fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 358fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int i; 359fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 360fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit for (i = 0; i < cnt; i++) { 361fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit q_pa[i].lo = (u32) (host_pa & 0xffffffff); 362fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit q_pa[i].hi = (u32) upper_32_bits(host_pa); 363fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit host_pa += hw_page_size; 364fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 365fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 366fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 367abe3afacc5762065244421569ad86afef11813bbRoland Dreierstatic int ocrdma_mbx_delete_q(struct ocrdma_dev *dev, struct ocrdma_queue_info *q, 368abe3afacc5762065244421569ad86afef11813bbRoland Dreier int queue_type) 369fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 370fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u8 opcode = 0; 371fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status; 372fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_delete_q_req *cmd = dev->mbx_cmd; 373fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 374fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit switch (queue_type) { 375fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case QTYPE_MCCQ: 376fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit opcode = OCRDMA_CMD_DELETE_MQ; 377fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 378fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case QTYPE_CQ: 379fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit opcode = OCRDMA_CMD_DELETE_CQ; 380fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 381fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case QTYPE_EQ: 382fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit opcode = OCRDMA_CMD_DELETE_EQ; 383fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 384fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit default: 385fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit BUG(); 386fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 387fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit memset(cmd, 0, sizeof(*cmd)); 388fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_init_mch(&cmd->req, opcode, OCRDMA_SUBSYS_COMMON, sizeof(*cmd)); 389fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->id = q->id; 390fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 391fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = be_roce_mcc_cmd(dev->nic_info.netdev, 392fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd, sizeof(*cmd), NULL, NULL); 393fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!status) 394fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit q->created = false; 395fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 396fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 397fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 398fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic int ocrdma_mbx_create_eq(struct ocrdma_dev *dev, struct ocrdma_eq *eq) 399fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 400fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status; 401fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_create_eq_req *cmd = dev->mbx_cmd; 402fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_create_eq_rsp *rsp = dev->mbx_cmd; 403fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 404fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit memset(cmd, 0, sizeof(*cmd)); 405fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_init_mch(&cmd->req, OCRDMA_CMD_CREATE_EQ, OCRDMA_SUBSYS_COMMON, 406fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit sizeof(*cmd)); 407fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 408c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala cmd->req.rsvd_version = 2; 409fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->num_pages = 4; 410fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->valid = OCRDMA_CREATE_EQ_VALID; 411fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->cnt = 4 << OCRDMA_CREATE_EQ_CNT_SHIFT; 412fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 413fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_build_q_pages(&cmd->pa[0], cmd->num_pages, eq->q.dma, 414fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit PAGE_SIZE_4K); 415fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = be_roce_mcc_cmd(dev->nic_info.netdev, cmd, sizeof(*cmd), NULL, 416fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit NULL); 417fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!status) { 418fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit eq->q.id = rsp->vector_eqid & 0xffff; 419c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala eq->vector = (rsp->vector_eqid >> 16) & 0xffff; 420fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit eq->q.created = true; 421fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 422fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 423fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 424fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 425fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic int ocrdma_create_eq(struct ocrdma_dev *dev, 426fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_eq *eq, u16 q_len) 427fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 428fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status; 429fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 430fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_alloc_q(dev, &eq->q, OCRDMA_EQ_LEN, 431fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit sizeof(struct ocrdma_eqe)); 432fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 433fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 434fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 435fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_mbx_create_eq(dev, eq); 436fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 437fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mbx_err; 438fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit eq->dev = dev; 439fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_ring_eq_db(dev, eq->q.id, true, true, 0); 440fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 441fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return 0; 442fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditmbx_err: 443fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_free_q(dev, &eq->q); 444fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 445fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 446fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 447fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic int ocrdma_get_irq(struct ocrdma_dev *dev, struct ocrdma_eq *eq) 448fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 449fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int irq; 450fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 451fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (dev->nic_info.intr_mode == BE_INTERRUPT_MODE_INTX) 452fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit irq = dev->nic_info.pdev->irq; 453fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit else 454fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit irq = dev->nic_info.msix.vector_list[eq->vector]; 455fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return irq; 456fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 457fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 458fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic void _ocrdma_destroy_eq(struct ocrdma_dev *dev, struct ocrdma_eq *eq) 459fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 460fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (eq->q.created) { 461fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_mbx_delete_q(dev, &eq->q, QTYPE_EQ); 462fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_free_q(dev, &eq->q); 463fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 464fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 465fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 466fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic void ocrdma_destroy_eq(struct ocrdma_dev *dev, struct ocrdma_eq *eq) 467fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 468fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int irq; 469fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 470fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit /* disarm EQ so that interrupts are not generated 471fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * during freeing and EQ delete is in progress. 472fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit */ 473fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_ring_eq_db(dev, eq->q.id, false, false, 0); 474fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 475fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit irq = ocrdma_get_irq(dev, eq); 476fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit free_irq(irq, eq); 477fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit _ocrdma_destroy_eq(dev, eq); 478fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 479fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 480c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkalastatic void ocrdma_destroy_eqs(struct ocrdma_dev *dev) 481fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 482fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int i; 483fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 484fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit for (i = 0; i < dev->eq_cnt; i++) 485c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala ocrdma_destroy_eq(dev, &dev->eq_tbl[i]); 486fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 487fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 488abe3afacc5762065244421569ad86afef11813bbRoland Dreierstatic int ocrdma_mbx_mq_cq_create(struct ocrdma_dev *dev, 489abe3afacc5762065244421569ad86afef11813bbRoland Dreier struct ocrdma_queue_info *cq, 490abe3afacc5762065244421569ad86afef11813bbRoland Dreier struct ocrdma_queue_info *eq) 491fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 492fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_create_cq_cmd *cmd = dev->mbx_cmd; 493fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_create_cq_cmd_rsp *rsp = dev->mbx_cmd; 494fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status; 495fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 496fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit memset(cmd, 0, sizeof(*cmd)); 497fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_init_mch(&cmd->req, OCRDMA_CMD_CREATE_CQ, 498fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_SUBSYS_COMMON, sizeof(*cmd)); 499fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 5001afc0454b6658ad2d0a87e594e1f06dc19c6977dNaresh Gottumukkala cmd->req.rsvd_version = OCRDMA_CREATE_CQ_VER2; 5011afc0454b6658ad2d0a87e594e1f06dc19c6977dNaresh Gottumukkala cmd->pgsz_pgcnt = (cq->size / OCRDMA_MIN_Q_PAGE_SIZE) << 5021afc0454b6658ad2d0a87e594e1f06dc19c6977dNaresh Gottumukkala OCRDMA_CREATE_CQ_PAGE_SIZE_SHIFT; 5031afc0454b6658ad2d0a87e594e1f06dc19c6977dNaresh Gottumukkala cmd->pgsz_pgcnt |= PAGES_4K_SPANNED(cq->va, cq->size); 5041afc0454b6658ad2d0a87e594e1f06dc19c6977dNaresh Gottumukkala 505fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->ev_cnt_flags = OCRDMA_CREATE_CQ_DEF_FLAGS; 5061afc0454b6658ad2d0a87e594e1f06dc19c6977dNaresh Gottumukkala cmd->eqn = eq->id; 5071afc0454b6658ad2d0a87e594e1f06dc19c6977dNaresh Gottumukkala cmd->cqe_count = cq->size / sizeof(struct ocrdma_mcqe); 508fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 5091afc0454b6658ad2d0a87e594e1f06dc19c6977dNaresh Gottumukkala ocrdma_build_q_pages(&cmd->pa[0], cq->size / OCRDMA_MIN_Q_PAGE_SIZE, 510fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cq->dma, PAGE_SIZE_4K); 511fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = be_roce_mcc_cmd(dev->nic_info.netdev, 512fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd, sizeof(*cmd), NULL, NULL); 513fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!status) { 5141afc0454b6658ad2d0a87e594e1f06dc19c6977dNaresh Gottumukkala cq->id = (u16) (rsp->cq_id & OCRDMA_CREATE_CQ_RSP_CQ_ID_MASK); 515fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cq->created = true; 516fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 517fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 518fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 519fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 520fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic u32 ocrdma_encoded_q_len(int q_len) 521fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 522fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u32 len_encoded = fls(q_len); /* log2(len) + 1 */ 523fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 524fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (len_encoded == 16) 525fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit len_encoded = 0; 526fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return len_encoded; 527fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 528fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 529fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic int ocrdma_mbx_create_mq(struct ocrdma_dev *dev, 530fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_queue_info *mq, 531fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_queue_info *cq) 532fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 533fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int num_pages, status; 534fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_create_mq_req *cmd = dev->mbx_cmd; 535fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_create_mq_rsp *rsp = dev->mbx_cmd; 536fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_pa *pa; 537fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 538fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit memset(cmd, 0, sizeof(*cmd)); 539fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit num_pages = PAGES_4K_SPANNED(mq->va, mq->size); 540fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 541b1d58b99194a121a44ec77571f84f62a6ccd6431Naresh Gottumukkala ocrdma_init_mch(&cmd->req, OCRDMA_CMD_CREATE_MQ_EXT, 542b1d58b99194a121a44ec77571f84f62a6ccd6431Naresh Gottumukkala OCRDMA_SUBSYS_COMMON, sizeof(*cmd)); 543b1d58b99194a121a44ec77571f84f62a6ccd6431Naresh Gottumukkala cmd->req.rsvd_version = 1; 544b1d58b99194a121a44ec77571f84f62a6ccd6431Naresh Gottumukkala cmd->cqid_pages = num_pages; 545b1d58b99194a121a44ec77571f84f62a6ccd6431Naresh Gottumukkala cmd->cqid_pages |= (cq->id << OCRDMA_CREATE_MQ_CQ_ID_SHIFT); 546b1d58b99194a121a44ec77571f84f62a6ccd6431Naresh Gottumukkala cmd->async_cqid_valid = OCRDMA_CREATE_MQ_ASYNC_CQ_VALID; 54784b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala 54884b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala cmd->async_event_bitmap = Bit(OCRDMA_ASYNC_GRP5_EVE_CODE); 54984b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala cmd->async_event_bitmap |= Bit(OCRDMA_ASYNC_RDMA_EVE_CODE); 55084b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala 551b1d58b99194a121a44ec77571f84f62a6ccd6431Naresh Gottumukkala cmd->async_cqid_ringsize = cq->id; 552b1d58b99194a121a44ec77571f84f62a6ccd6431Naresh Gottumukkala cmd->async_cqid_ringsize |= (ocrdma_encoded_q_len(mq->len) << 553b1d58b99194a121a44ec77571f84f62a6ccd6431Naresh Gottumukkala OCRDMA_CREATE_MQ_RING_SIZE_SHIFT); 554b1d58b99194a121a44ec77571f84f62a6ccd6431Naresh Gottumukkala cmd->valid = OCRDMA_CREATE_MQ_VALID; 555b1d58b99194a121a44ec77571f84f62a6ccd6431Naresh Gottumukkala pa = &cmd->pa[0]; 556b1d58b99194a121a44ec77571f84f62a6ccd6431Naresh Gottumukkala 557fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_build_q_pages(pa, num_pages, mq->dma, PAGE_SIZE_4K); 558fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = be_roce_mcc_cmd(dev->nic_info.netdev, 559fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd, sizeof(*cmd), NULL, NULL); 560fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!status) { 561fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit mq->id = rsp->id; 562fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit mq->created = true; 563fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 564fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 565fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 566fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 567fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic int ocrdma_create_mq(struct ocrdma_dev *dev) 568fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 569fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status; 570fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 571fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit /* Alloc completion queue for Mailbox queue */ 572fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_alloc_q(dev, &dev->mq.cq, OCRDMA_MQ_CQ_LEN, 573fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit sizeof(struct ocrdma_mcqe)); 574fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 575fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto alloc_err; 576fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 577c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala status = ocrdma_mbx_mq_cq_create(dev, &dev->mq.cq, &dev->eq_tbl[0].q); 578fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 579fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mbx_cq_free; 580fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 581fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit memset(&dev->mqe_ctx, 0, sizeof(dev->mqe_ctx)); 582fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit init_waitqueue_head(&dev->mqe_ctx.cmd_wait); 583fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit mutex_init(&dev->mqe_ctx.lock); 584fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 585fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit /* Alloc Mailbox queue */ 586fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_alloc_q(dev, &dev->mq.sq, OCRDMA_MQ_LEN, 587fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit sizeof(struct ocrdma_mqe)); 588fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 589fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mbx_cq_destroy; 590fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_mbx_create_mq(dev, &dev->mq.sq, &dev->mq.cq); 591fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 592fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mbx_q_free; 593fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_ring_cq_db(dev, dev->mq.cq.id, true, false, 0); 594fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return 0; 595fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 596fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditmbx_q_free: 597fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_free_q(dev, &dev->mq.sq); 598fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditmbx_cq_destroy: 599fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_mbx_delete_q(dev, &dev->mq.cq, QTYPE_CQ); 600fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditmbx_cq_free: 601fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_free_q(dev, &dev->mq.cq); 602fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditalloc_err: 603fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 604fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 605fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 606fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic void ocrdma_destroy_mq(struct ocrdma_dev *dev) 607fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 608fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_queue_info *mbxq, *cq; 609fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 610fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit /* mqe_ctx lock synchronizes with any other pending cmds. */ 611fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit mutex_lock(&dev->mqe_ctx.lock); 612fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit mbxq = &dev->mq.sq; 613fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (mbxq->created) { 614fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_mbx_delete_q(dev, mbxq, QTYPE_MCCQ); 615fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_free_q(dev, mbxq); 616fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 617fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit mutex_unlock(&dev->mqe_ctx.lock); 618fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 619fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cq = &dev->mq.cq; 620fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (cq->created) { 621fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_mbx_delete_q(dev, cq, QTYPE_CQ); 622fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_free_q(dev, cq); 623fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 624fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 625fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 626fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic void ocrdma_process_qpcat_error(struct ocrdma_dev *dev, 627fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_qp *qp) 628fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 629fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit enum ib_qp_state new_ib_qps = IB_QPS_ERR; 630fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit enum ib_qp_state old_ib_qps; 631fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 632fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (qp == NULL) 633fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit BUG(); 634057729cb234754d12e0b2a361c2fc85c6363cbf6Naresh Gottumukkala ocrdma_qp_state_change(qp, new_ib_qps, &old_ib_qps); 635fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 636fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 637fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic void ocrdma_dispatch_ibevent(struct ocrdma_dev *dev, 638fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_ae_mcqe *cqe) 639fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 640fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_qp *qp = NULL; 641fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_cq *cq = NULL; 642e9db29534d2bc7c5e24f0fdd4beff9001517d785Roland Dreier struct ib_event ib_evt; 643fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int cq_event = 0; 644fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int qp_event = 1; 645fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int srq_event = 0; 646fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int dev_event = 0; 647fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int type = (cqe->valid_ae_event & OCRDMA_AE_MCQE_EVENT_TYPE_MASK) >> 648fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_AE_MCQE_EVENT_TYPE_SHIFT; 649fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 650fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (cqe->qpvalid_qpid & OCRDMA_AE_MCQE_QPVALID) 651fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp = dev->qp_tbl[cqe->qpvalid_qpid & OCRDMA_AE_MCQE_QPID_MASK]; 652fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (cqe->cqvalid_cqid & OCRDMA_AE_MCQE_CQVALID) 653fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cq = dev->cq_tbl[cqe->cqvalid_cqid & OCRDMA_AE_MCQE_CQID_MASK]; 654fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 655e9db29534d2bc7c5e24f0fdd4beff9001517d785Roland Dreier ib_evt.device = &dev->ibdev; 656e9db29534d2bc7c5e24f0fdd4beff9001517d785Roland Dreier 657fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit switch (type) { 658fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_CQ_ERROR: 659fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ib_evt.element.cq = &cq->ibcq; 660fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ib_evt.event = IB_EVENT_CQ_ERR; 661fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cq_event = 1; 662fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp_event = 0; 663fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 664fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_CQ_OVERRUN_ERROR: 665fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ib_evt.element.cq = &cq->ibcq; 666fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ib_evt.event = IB_EVENT_CQ_ERR; 667fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 668fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_CQ_QPCAT_ERROR: 669fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ib_evt.element.qp = &qp->ibqp; 670fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ib_evt.event = IB_EVENT_QP_FATAL; 671fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_process_qpcat_error(dev, qp); 672fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 673fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_QP_ACCESS_ERROR: 674fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ib_evt.element.qp = &qp->ibqp; 675fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ib_evt.event = IB_EVENT_QP_ACCESS_ERR; 676fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 677fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_QP_COMM_EST_EVENT: 678fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ib_evt.element.qp = &qp->ibqp; 679fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ib_evt.event = IB_EVENT_COMM_EST; 680fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 681fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_SQ_DRAINED_EVENT: 682fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ib_evt.element.qp = &qp->ibqp; 683fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ib_evt.event = IB_EVENT_SQ_DRAINED; 684fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 685fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_DEVICE_FATAL_EVENT: 686fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ib_evt.element.port_num = 1; 687fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ib_evt.event = IB_EVENT_DEVICE_FATAL; 688fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp_event = 0; 689fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev_event = 1; 690fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 691fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_SRQCAT_ERROR: 692fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ib_evt.element.srq = &qp->srq->ibsrq; 693fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ib_evt.event = IB_EVENT_SRQ_ERR; 694fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit srq_event = 1; 695fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp_event = 0; 696fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 697fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_SRQ_LIMIT_EVENT: 698fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ib_evt.element.srq = &qp->srq->ibsrq; 699804eaf29bac4148aa265bedc62182ed41a4c6120Parav Pandit ib_evt.event = IB_EVENT_SRQ_LIMIT_REACHED; 700fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit srq_event = 1; 701fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp_event = 0; 702fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 703fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case OCRDMA_QP_LAST_WQE_EVENT: 704fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ib_evt.element.qp = &qp->ibqp; 705fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ib_evt.event = IB_EVENT_QP_LAST_WQE_REACHED; 706fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 707fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit default: 708fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cq_event = 0; 709fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp_event = 0; 710fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit srq_event = 0; 711fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev_event = 0; 712ef99c4c2ed63cb0deb94ea70fb47c2d6294e302eNaresh Gottumukkala pr_err("%s() unknown type=0x%x\n", __func__, type); 713fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 714fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 715fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 716fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (qp_event) { 717fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (qp->ibqp.event_handler) 718fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->ibqp.event_handler(&ib_evt, qp->ibqp.qp_context); 719fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } else if (cq_event) { 720fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (cq->ibcq.event_handler) 721fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cq->ibcq.event_handler(&ib_evt, cq->ibcq.cq_context); 722fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } else if (srq_event) { 723fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (qp->srq->ibsrq.event_handler) 724fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->srq->ibsrq.event_handler(&ib_evt, 725fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->srq->ibsrq. 726fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit srq_context); 727f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala } else if (dev_event) { 728fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ib_dispatch_event(&ib_evt); 729f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala } 730fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 731fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 732fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 73384b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkalastatic void ocrdma_process_grp5_aync(struct ocrdma_dev *dev, 73484b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala struct ocrdma_ae_mcqe *cqe) 73584b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala{ 73684b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala struct ocrdma_ae_pvid_mcqe *evt; 73784b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala int type = (cqe->valid_ae_event & OCRDMA_AE_MCQE_EVENT_TYPE_MASK) >> 73884b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala OCRDMA_AE_MCQE_EVENT_TYPE_SHIFT; 73984b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala 74084b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala switch (type) { 74184b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala case OCRDMA_ASYNC_EVENT_PVID_STATE: 74284b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala evt = (struct ocrdma_ae_pvid_mcqe *)cqe; 74384b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala if ((evt->tag_enabled & OCRDMA_AE_PVID_MCQE_ENABLED_MASK) >> 74484b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala OCRDMA_AE_PVID_MCQE_ENABLED_SHIFT) 74584b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala dev->pvid = ((evt->tag_enabled & 74684b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala OCRDMA_AE_PVID_MCQE_TAG_MASK) >> 74784b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala OCRDMA_AE_PVID_MCQE_TAG_SHIFT); 74884b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala break; 74984b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala default: 75084b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala /* Not interested evts. */ 75184b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala break; 75284b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala } 75384b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala} 75484b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala 75584b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala 756fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic void ocrdma_process_acqe(struct ocrdma_dev *dev, void *ae_cqe) 757fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 758fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit /* async CQE processing */ 759fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_ae_mcqe *cqe = ae_cqe; 760fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u32 evt_code = (cqe->valid_ae_event & OCRDMA_AE_MCQE_EVENT_CODE_MASK) >> 761fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_AE_MCQE_EVENT_CODE_SHIFT; 762fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 76384b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala if (evt_code == OCRDMA_ASYNC_RDMA_EVE_CODE) 764fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_dispatch_ibevent(dev, cqe); 76584b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala else if (evt_code == OCRDMA_ASYNC_GRP5_EVE_CODE) 76684b105db593e735b8304815c913f7eea222a0600Naresh Gottumukkala ocrdma_process_grp5_aync(dev, cqe); 767fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit else 768ef99c4c2ed63cb0deb94ea70fb47c2d6294e302eNaresh Gottumukkala pr_err("%s(%d) invalid evt code=0x%x\n", __func__, 769ef99c4c2ed63cb0deb94ea70fb47c2d6294e302eNaresh Gottumukkala dev->id, evt_code); 770fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 771fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 772fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic void ocrdma_process_mcqe(struct ocrdma_dev *dev, struct ocrdma_mcqe *cqe) 773fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 774fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (dev->mqe_ctx.tag == cqe->tag_lo && dev->mqe_ctx.cmd_done == false) { 775fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev->mqe_ctx.cqe_status = (cqe->status & 776fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MCQE_STATUS_MASK) >> OCRDMA_MCQE_STATUS_SHIFT; 777fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev->mqe_ctx.ext_status = 778fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (cqe->status & OCRDMA_MCQE_ESTATUS_MASK) 779fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit >> OCRDMA_MCQE_ESTATUS_SHIFT; 780fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev->mqe_ctx.cmd_done = true; 781fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit wake_up(&dev->mqe_ctx.cmd_wait); 782fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } else 783ef99c4c2ed63cb0deb94ea70fb47c2d6294e302eNaresh Gottumukkala pr_err("%s() cqe for invalid tag0x%x.expected=0x%x\n", 784ef99c4c2ed63cb0deb94ea70fb47c2d6294e302eNaresh Gottumukkala __func__, cqe->tag_lo, dev->mqe_ctx.tag); 785fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 786fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 787fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic int ocrdma_mq_cq_handler(struct ocrdma_dev *dev, u16 cq_id) 788fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 789fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u16 cqe_popped = 0; 790fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_mcqe *cqe; 791fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 792fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit while (1) { 793fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cqe = ocrdma_get_mcqe(dev); 794fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (cqe == NULL) 795fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 796fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_le32_to_cpu(cqe, sizeof(*cqe)); 797fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cqe_popped += 1; 798fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (cqe->valid_ae_cmpl_cons & OCRDMA_MCQE_AE_MASK) 799fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_process_acqe(dev, cqe); 800fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit else if (cqe->valid_ae_cmpl_cons & OCRDMA_MCQE_CMPL_MASK) 801fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_process_mcqe(dev, cqe); 802fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit else 803ef99c4c2ed63cb0deb94ea70fb47c2d6294e302eNaresh Gottumukkala pr_err("%s() cqe->compl is not set.\n", __func__); 804fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit memset(cqe, 0, sizeof(struct ocrdma_mcqe)); 805fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_mcq_inc_tail(dev); 806fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 807fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_ring_cq_db(dev, dev->mq.cq.id, true, false, cqe_popped); 808fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return 0; 809fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 810fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 811fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic void ocrdma_qp_buddy_cq_handler(struct ocrdma_dev *dev, 812fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_cq *cq) 813fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 814fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit unsigned long flags; 815fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_qp *qp; 816fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit bool buddy_cq_found = false; 817fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit /* Go through list of QPs in error state which are using this CQ 818fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * and invoke its callback handler to trigger CQE processing for 819fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * error/flushed CQE. It is rare to find more than few entries in 820fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * this list as most consumers stops after getting error CQE. 821fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * List is traversed only once when a matching buddy cq found for a QP. 822fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit */ 823fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit spin_lock_irqsave(&dev->flush_q_lock, flags); 824fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit list_for_each_entry(qp, &cq->sq_head, sq_entry) { 825fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (qp->srq) 826fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit continue; 827fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit /* if wq and rq share the same cq, than comp_handler 828fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * is already invoked. 829fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit */ 830fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (qp->sq_cq == qp->rq_cq) 831fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit continue; 832fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit /* if completion came on sq, rq's cq is buddy cq. 833fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * if completion came on rq, sq's cq is buddy cq. 834fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit */ 835fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (qp->sq_cq == cq) 836fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cq = qp->rq_cq; 837fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit else 838fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cq = qp->sq_cq; 839fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit buddy_cq_found = true; 840fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 841fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 842fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit spin_unlock_irqrestore(&dev->flush_q_lock, flags); 843fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (buddy_cq_found == false) 844fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return; 845fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (cq->ibcq.comp_handler) { 846fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit spin_lock_irqsave(&cq->comp_handler_lock, flags); 847fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (*cq->ibcq.comp_handler) (&cq->ibcq, cq->ibcq.cq_context); 848fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit spin_unlock_irqrestore(&cq->comp_handler_lock, flags); 849fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 850fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 851fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 852fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic void ocrdma_qp_cq_handler(struct ocrdma_dev *dev, u16 cq_idx) 853fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 854fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit unsigned long flags; 855fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_cq *cq; 856fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 857fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (cq_idx >= OCRDMA_MAX_CQ) 858fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit BUG(); 859fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 860fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cq = dev->cq_tbl[cq_idx]; 861fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (cq == NULL) { 862ef99c4c2ed63cb0deb94ea70fb47c2d6294e302eNaresh Gottumukkala pr_err("%s%d invalid id=0x%x\n", __func__, dev->id, cq_idx); 863fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return; 864fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 865fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit spin_lock_irqsave(&cq->cq_lock, flags); 866fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cq->armed = false; 867fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cq->solicited = false; 868fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit spin_unlock_irqrestore(&cq->cq_lock, flags); 869fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 870fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_ring_cq_db(dev, cq->id, false, false, 0); 871fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 872fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (cq->ibcq.comp_handler) { 873fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit spin_lock_irqsave(&cq->comp_handler_lock, flags); 874fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (*cq->ibcq.comp_handler) (&cq->ibcq, cq->ibcq.cq_context); 875fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit spin_unlock_irqrestore(&cq->comp_handler_lock, flags); 876fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 877fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_qp_buddy_cq_handler(dev, cq); 878fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 879fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 880fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic void ocrdma_cq_handler(struct ocrdma_dev *dev, u16 cq_id) 881fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 882fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit /* process the MQ-CQE. */ 883fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (cq_id == dev->mq.cq.id) 884fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_mq_cq_handler(dev, cq_id); 885fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit else 886fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_qp_cq_handler(dev, cq_id); 887fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 888fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 889fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic irqreturn_t ocrdma_irq_handler(int irq, void *handle) 890fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 891fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_eq *eq = handle; 892fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_dev *dev = eq->dev; 893fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_eqe eqe; 894fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_eqe *ptr; 895fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u16 eqe_popped = 0; 896fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u16 cq_id; 897fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit while (1) { 898fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ptr = ocrdma_get_eqe(eq); 899fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit eqe = *ptr; 900fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_le32_to_cpu(&eqe, sizeof(eqe)); 901fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if ((eqe.id_valid & OCRDMA_EQE_VALID_MASK) == 0) 902fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 903fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit eqe_popped += 1; 904fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ptr->id_valid = 0; 905fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit /* check whether its CQE or not. */ 906fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if ((eqe.id_valid & OCRDMA_EQE_FOR_CQE_MASK) == 0) { 907fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cq_id = eqe.id_valid >> OCRDMA_EQE_RESOURCE_ID_SHIFT; 908fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_cq_handler(dev, cq_id); 909fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 910fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_eq_inc_tail(eq); 911fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 912fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_ring_eq_db(dev, eq->q.id, true, true, eqe_popped); 913fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit /* Ring EQ doorbell with num_popped to 0 to enable interrupts again. */ 914fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (dev->nic_info.intr_mode == BE_INTERRUPT_MODE_INTX) 915fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_ring_eq_db(dev, eq->q.id, true, true, 0); 916fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return IRQ_HANDLED; 917fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 918fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 919fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic void ocrdma_post_mqe(struct ocrdma_dev *dev, struct ocrdma_mqe *cmd) 920fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 921fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_mqe *mqe; 922fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 923fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev->mqe_ctx.tag = dev->mq.sq.head; 924fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev->mqe_ctx.cmd_done = false; 925fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit mqe = ocrdma_get_mqe(dev); 926fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->hdr.tag_lo = dev->mq.sq.head; 927fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_copy_cpu_to_le32(mqe, cmd, sizeof(*mqe)); 928fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit /* make sure descriptor is written before ringing doorbell */ 929fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit wmb(); 930fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_mq_inc_head(dev); 931fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_ring_mq_db(dev); 932fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 933fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 934fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic int ocrdma_wait_mqe_cmpl(struct ocrdma_dev *dev) 935fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 936fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit long status; 937fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit /* 30 sec timeout */ 938fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = wait_event_timeout(dev->mqe_ctx.cmd_wait, 939fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (dev->mqe_ctx.cmd_done != false), 940fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit msecs_to_jiffies(30000)); 941fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 942fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return 0; 943fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit else 944fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return -1; 945fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 946fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 947fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit/* issue a mailbox command on the MQ */ 948fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic int ocrdma_mbx_cmd(struct ocrdma_dev *dev, struct ocrdma_mqe *mqe) 949fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 950fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status = 0; 951fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u16 cqe_status, ext_status; 952fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_mqe *rsp; 953fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 954fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit mutex_lock(&dev->mqe_ctx.lock); 955fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_post_mqe(dev, mqe); 956fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_wait_mqe_cmpl(dev); 957fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 958fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mbx_err; 959fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cqe_status = dev->mqe_ctx.cqe_status; 960fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ext_status = dev->mqe_ctx.ext_status; 961fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit rsp = ocrdma_get_mqe_rsp(dev); 962fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_copy_le32_to_cpu(mqe, rsp, (sizeof(*mqe))); 963fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (cqe_status || ext_status) { 964f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala pr_err("%s() opcode=0x%x, cqe_status=0x%x, ext_status=0x%x\n", 965f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala __func__, 966fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (rsp->u.rsp.subsys_op & OCRDMA_MBX_RSP_OPCODE_MASK) >> 967fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_RSP_OPCODE_SHIFT, cqe_status, ext_status); 968fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_get_mbx_cqe_errno(cqe_status); 969fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mbx_err; 970fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 971fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (mqe->u.rsp.status & OCRDMA_MBX_RSP_STATUS_MASK) 972fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_get_mbx_errno(mqe->u.rsp.status); 973fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditmbx_err: 974fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit mutex_unlock(&dev->mqe_ctx.lock); 975fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 976fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 977fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 978fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic void ocrdma_get_attr(struct ocrdma_dev *dev, 979fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_dev_attr *attr, 980fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_mbx_query_config *rsp) 981fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 982fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit attr->max_pd = 983fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (rsp->max_pd_ca_ack_delay & OCRDMA_MBX_QUERY_CFG_MAX_PD_MASK) >> 984fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_QUERY_CFG_MAX_PD_SHIFT; 985fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit attr->max_qp = 986fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (rsp->qp_srq_cq_ird_ord & OCRDMA_MBX_QUERY_CFG_MAX_QP_MASK) >> 987fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_QUERY_CFG_MAX_QP_SHIFT; 988fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit attr->max_send_sge = ((rsp->max_write_send_sge & 989fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK) >> 990fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT); 991fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit attr->max_recv_sge = (rsp->max_write_send_sge & 992fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK) >> 993fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT; 994634c5796a5c60964faf9d51892571ffe36ad24d5Mahesh Vardhamanaiah attr->max_srq_sge = (rsp->max_srq_rqe_sge & 995634c5796a5c60964faf9d51892571ffe36ad24d5Mahesh Vardhamanaiah OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_MASK) >> 996634c5796a5c60964faf9d51892571ffe36ad24d5Mahesh Vardhamanaiah OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_OFFSET; 99745e86b33ec8b33f9ed41d9f9005f9e663018f8f1Naresh Gottumukkala attr->max_rdma_sge = (rsp->max_write_send_sge & 99845e86b33ec8b33f9ed41d9f9005f9e663018f8f1Naresh Gottumukkala OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_MASK) >> 99945e86b33ec8b33f9ed41d9f9005f9e663018f8f1Naresh Gottumukkala OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_SHIFT; 1000fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit attr->max_ord_per_qp = (rsp->max_ird_ord_per_qp & 1001fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK) >> 1002fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT; 10037c33880c3cb2cda816d4d64852c6a81018b9bc1fNaresh Gottumukkala attr->max_srq = 10047c33880c3cb2cda816d4d64852c6a81018b9bc1fNaresh Gottumukkala (rsp->max_srq_rpir_qps & OCRDMA_MBX_QUERY_CFG_MAX_SRQ_MASK) >> 10057c33880c3cb2cda816d4d64852c6a81018b9bc1fNaresh Gottumukkala OCRDMA_MBX_QUERY_CFG_MAX_SRQ_OFFSET; 1006fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit attr->max_ird_per_qp = (rsp->max_ird_ord_per_qp & 1007fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_QUERY_CFG_MAX_IRD_PER_QP_MASK) >> 1008fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_QUERY_CFG_MAX_IRD_PER_QP_SHIFT; 1009fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit attr->cq_overflow_detect = (rsp->qp_srq_cq_ird_ord & 1010fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_QUERY_CFG_CQ_OVERFLOW_MASK) >> 1011fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_QUERY_CFG_CQ_OVERFLOW_SHIFT; 1012fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit attr->srq_supported = (rsp->qp_srq_cq_ird_ord & 1013fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_QUERY_CFG_SRQ_SUPPORTED_MASK) >> 1014fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_QUERY_CFG_SRQ_SUPPORTED_SHIFT; 1015fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit attr->local_ca_ack_delay = (rsp->max_pd_ca_ack_delay & 1016fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_QUERY_CFG_CA_ACK_DELAY_MASK) >> 1017fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_QUERY_CFG_CA_ACK_DELAY_SHIFT; 1018fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit attr->max_mr = rsp->max_mr; 1019fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit attr->max_mr_size = ~0ull; 1020fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit attr->max_fmr = 0; 1021fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit attr->max_pages_per_frmr = rsp->max_pages_per_frmr; 1022fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit attr->max_num_mr_pbl = rsp->max_num_mr_pbl; 1023fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit attr->max_cqe = rsp->max_cq_cqes_per_cq & 1024fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_QUERY_CFG_MAX_CQES_PER_CQ_MASK; 1025c43e9ab84d853f499a2fd531362973c8e505b342Naresh Gottumukkala attr->max_cq = (rsp->max_cq_cqes_per_cq & 1026c43e9ab84d853f499a2fd531362973c8e505b342Naresh Gottumukkala OCRDMA_MBX_QUERY_CFG_MAX_CQ_MASK) >> 1027c43e9ab84d853f499a2fd531362973c8e505b342Naresh Gottumukkala OCRDMA_MBX_QUERY_CFG_MAX_CQ_OFFSET; 1028fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit attr->wqe_size = ((rsp->wqe_rqe_stride_max_dpp_cqs & 1029fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_QUERY_CFG_MAX_WQE_SIZE_MASK) >> 1030fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_QUERY_CFG_MAX_WQE_SIZE_OFFSET) * 1031fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_WQE_STRIDE; 1032fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit attr->rqe_size = ((rsp->wqe_rqe_stride_max_dpp_cqs & 1033fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_QUERY_CFG_MAX_RQE_SIZE_MASK) >> 1034fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MBX_QUERY_CFG_MAX_RQE_SIZE_OFFSET) * 1035fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_WQE_STRIDE; 1036fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit attr->max_inline_data = 1037fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit attr->wqe_size - (sizeof(struct ocrdma_hdr_wqe) + 1038fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit sizeof(struct ocrdma_sge)); 1039fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) { 1040fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit attr->ird = 1; 1041fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit attr->ird_page_size = OCRDMA_MIN_Q_PAGE_SIZE; 1042fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit attr->num_ird_pages = MAX_OCRDMA_IRD_PAGES; 104307bb54244e466f1517357f47a498574f97c31e08Mahesh Vardhamanaiah } 104407bb54244e466f1517357f47a498574f97c31e08Mahesh Vardhamanaiah dev->attr.max_wqe = rsp->max_wqes_rqes_per_q >> 104507bb54244e466f1517357f47a498574f97c31e08Mahesh Vardhamanaiah OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET; 104607bb54244e466f1517357f47a498574f97c31e08Mahesh Vardhamanaiah dev->attr.max_rqe = rsp->max_wqes_rqes_per_q & 104707bb54244e466f1517357f47a498574f97c31e08Mahesh Vardhamanaiah OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_MASK; 1048fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1049fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1050fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic int ocrdma_check_fw_config(struct ocrdma_dev *dev, 1051fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_fw_conf_rsp *conf) 1052fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1053fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u32 fn_mode; 1054fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1055fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit fn_mode = conf->fn_mode & OCRDMA_FN_MODE_RDMA; 1056fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (fn_mode != OCRDMA_FN_MODE_RDMA) 1057fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return -EINVAL; 1058fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev->base_eqid = conf->base_eqid; 1059fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev->max_eq = conf->max_eq; 1060fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return 0; 1061fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1062fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1063fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit/* can be issued only during init time. */ 1064fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic int ocrdma_mbx_query_fw_ver(struct ocrdma_dev *dev) 1065fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1066fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status = -ENOMEM; 1067fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_mqe *cmd; 1068fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_fw_ver_rsp *rsp; 1069fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1070fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_GET_FW_VER, sizeof(*cmd)); 1071fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!cmd) 1072fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return -ENOMEM; 1073fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_init_mch((struct ocrdma_mbx_hdr *)&cmd->u.cmd[0], 1074fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CMD_GET_FW_VER, 1075fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_SUBSYS_COMMON, sizeof(*cmd)); 1076fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1077fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); 1078fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 1079fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mbx_err; 1080fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit rsp = (struct ocrdma_fw_ver_rsp *)cmd; 1081fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit memset(&dev->attr.fw_ver[0], 0, sizeof(dev->attr.fw_ver)); 1082fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit memcpy(&dev->attr.fw_ver[0], &rsp->running_ver[0], 1083fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit sizeof(rsp->running_ver)); 1084fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_le32_to_cpu(dev->attr.fw_ver, sizeof(rsp->running_ver)); 1085fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditmbx_err: 1086fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit kfree(cmd); 1087fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 1088fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1089fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1090fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit/* can be issued only during init time. */ 1091fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic int ocrdma_mbx_query_fw_config(struct ocrdma_dev *dev) 1092fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1093fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status = -ENOMEM; 1094fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_mqe *cmd; 1095fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_fw_conf_rsp *rsp; 1096fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1097fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_GET_FW_CONFIG, sizeof(*cmd)); 1098fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!cmd) 1099fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return -ENOMEM; 1100fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_init_mch((struct ocrdma_mbx_hdr *)&cmd->u.cmd[0], 1101fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CMD_GET_FW_CONFIG, 1102fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_SUBSYS_COMMON, sizeof(*cmd)); 1103fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); 1104fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 1105fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mbx_err; 1106fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit rsp = (struct ocrdma_fw_conf_rsp *)cmd; 1107fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_check_fw_config(dev, rsp); 1108fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditmbx_err: 1109fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit kfree(cmd); 1110fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 1111fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1112fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1113fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic int ocrdma_mbx_query_dev(struct ocrdma_dev *dev) 1114fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1115fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status = -ENOMEM; 1116fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_mbx_query_config *rsp; 1117fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_mqe *cmd; 1118fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1119fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_QUERY_CONFIG, sizeof(*cmd)); 1120fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!cmd) 1121fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 1122fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); 1123fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 1124fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mbx_err; 1125fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit rsp = (struct ocrdma_mbx_query_config *)cmd; 1126fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_get_attr(dev, &dev->attr, rsp); 1127fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditmbx_err: 1128fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit kfree(cmd); 1129fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 1130fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1131fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1132f24ceba6b6454f68f456981be2a337b6390d9aa0Naresh Gottumukkalaint ocrdma_mbx_get_link_speed(struct ocrdma_dev *dev, u8 *lnk_speed) 1133f24ceba6b6454f68f456981be2a337b6390d9aa0Naresh Gottumukkala{ 1134f24ceba6b6454f68f456981be2a337b6390d9aa0Naresh Gottumukkala int status = -ENOMEM; 1135f24ceba6b6454f68f456981be2a337b6390d9aa0Naresh Gottumukkala struct ocrdma_get_link_speed_rsp *rsp; 1136f24ceba6b6454f68f456981be2a337b6390d9aa0Naresh Gottumukkala struct ocrdma_mqe *cmd; 1137f24ceba6b6454f68f456981be2a337b6390d9aa0Naresh Gottumukkala 1138f24ceba6b6454f68f456981be2a337b6390d9aa0Naresh Gottumukkala cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_QUERY_NTWK_LINK_CONFIG_V1, 1139f24ceba6b6454f68f456981be2a337b6390d9aa0Naresh Gottumukkala sizeof(*cmd)); 1140f24ceba6b6454f68f456981be2a337b6390d9aa0Naresh Gottumukkala if (!cmd) 1141f24ceba6b6454f68f456981be2a337b6390d9aa0Naresh Gottumukkala return status; 1142f24ceba6b6454f68f456981be2a337b6390d9aa0Naresh Gottumukkala ocrdma_init_mch((struct ocrdma_mbx_hdr *)&cmd->u.cmd[0], 1143f24ceba6b6454f68f456981be2a337b6390d9aa0Naresh Gottumukkala OCRDMA_CMD_QUERY_NTWK_LINK_CONFIG_V1, 1144f24ceba6b6454f68f456981be2a337b6390d9aa0Naresh Gottumukkala OCRDMA_SUBSYS_COMMON, sizeof(*cmd)); 1145f24ceba6b6454f68f456981be2a337b6390d9aa0Naresh Gottumukkala 1146f24ceba6b6454f68f456981be2a337b6390d9aa0Naresh Gottumukkala ((struct ocrdma_mbx_hdr *)cmd->u.cmd)->rsvd_version = 0x1; 1147f24ceba6b6454f68f456981be2a337b6390d9aa0Naresh Gottumukkala 1148f24ceba6b6454f68f456981be2a337b6390d9aa0Naresh Gottumukkala status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); 1149f24ceba6b6454f68f456981be2a337b6390d9aa0Naresh Gottumukkala if (status) 1150f24ceba6b6454f68f456981be2a337b6390d9aa0Naresh Gottumukkala goto mbx_err; 1151f24ceba6b6454f68f456981be2a337b6390d9aa0Naresh Gottumukkala 1152f24ceba6b6454f68f456981be2a337b6390d9aa0Naresh Gottumukkala rsp = (struct ocrdma_get_link_speed_rsp *)cmd; 1153f24ceba6b6454f68f456981be2a337b6390d9aa0Naresh Gottumukkala *lnk_speed = rsp->phys_port_speed; 1154f24ceba6b6454f68f456981be2a337b6390d9aa0Naresh Gottumukkala 1155f24ceba6b6454f68f456981be2a337b6390d9aa0Naresh Gottumukkalambx_err: 1156f24ceba6b6454f68f456981be2a337b6390d9aa0Naresh Gottumukkala kfree(cmd); 1157f24ceba6b6454f68f456981be2a337b6390d9aa0Naresh Gottumukkala return status; 1158f24ceba6b6454f68f456981be2a337b6390d9aa0Naresh Gottumukkala} 1159f24ceba6b6454f68f456981be2a337b6390d9aa0Naresh Gottumukkala 1160fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditint ocrdma_mbx_alloc_pd(struct ocrdma_dev *dev, struct ocrdma_pd *pd) 1161fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1162fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status = -ENOMEM; 1163fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_alloc_pd *cmd; 1164fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_alloc_pd_rsp *rsp; 1165fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1166fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_ALLOC_PD, sizeof(*cmd)); 1167fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!cmd) 1168fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 1169fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (pd->dpp_enabled) 1170fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->enable_dpp_rsvd |= OCRDMA_ALLOC_PD_ENABLE_DPP; 1171fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); 1172fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 1173fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mbx_err; 1174fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit rsp = (struct ocrdma_alloc_pd_rsp *)cmd; 1175fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit pd->id = rsp->dpp_page_pdid & OCRDMA_ALLOC_PD_RSP_PDID_MASK; 1176fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (rsp->dpp_page_pdid & OCRDMA_ALLOC_PD_RSP_DPP) { 1177fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit pd->dpp_enabled = true; 1178fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit pd->dpp_page = rsp->dpp_page_pdid >> 1179fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_ALLOC_PD_RSP_DPP_PAGE_SHIFT; 1180fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } else { 1181fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit pd->dpp_enabled = false; 1182fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit pd->num_dpp_qp = 0; 1183fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 1184fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditmbx_err: 1185fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit kfree(cmd); 1186fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 1187fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1188fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1189fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditint ocrdma_mbx_dealloc_pd(struct ocrdma_dev *dev, struct ocrdma_pd *pd) 1190fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1191fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status = -ENOMEM; 1192fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_dealloc_pd *cmd; 1193fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1194fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_DEALLOC_PD, sizeof(*cmd)); 1195fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!cmd) 1196fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 1197fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->id = pd->id; 1198fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); 1199fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit kfree(cmd); 1200fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 1201fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1202fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1203fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic int ocrdma_build_q_conf(u32 *num_entries, int entry_size, 1204fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int *num_pages, int *page_size) 1205fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1206fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int i; 1207fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int mem_size; 1208fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1209fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit *num_entries = roundup_pow_of_two(*num_entries); 1210fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit mem_size = *num_entries * entry_size; 1211fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit /* find the possible lowest possible multiplier */ 1212fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit for (i = 0; i < OCRDMA_MAX_Q_PAGE_SIZE_CNT; i++) { 1213fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (mem_size <= (OCRDMA_Q_PAGE_BASE_SIZE << i)) 1214fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 1215fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 1216fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (i >= OCRDMA_MAX_Q_PAGE_SIZE_CNT) 1217fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return -EINVAL; 1218fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit mem_size = roundup(mem_size, 1219fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ((OCRDMA_Q_PAGE_BASE_SIZE << i) / OCRDMA_MAX_Q_PAGES)); 1220fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit *num_pages = 1221fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit mem_size / ((OCRDMA_Q_PAGE_BASE_SIZE << i) / OCRDMA_MAX_Q_PAGES); 1222fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit *page_size = ((OCRDMA_Q_PAGE_BASE_SIZE << i) / OCRDMA_MAX_Q_PAGES); 1223fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit *num_entries = mem_size / entry_size; 1224fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return 0; 1225fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1226fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1227fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic int ocrdma_mbx_create_ah_tbl(struct ocrdma_dev *dev) 1228fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1229fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int i ; 1230fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status = 0; 1231fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int max_ah; 1232fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_create_ah_tbl *cmd; 1233fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_create_ah_tbl_rsp *rsp; 1234fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct pci_dev *pdev = dev->nic_info.pdev; 1235fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dma_addr_t pa; 1236fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_pbe *pbes; 1237fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1238fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_CREATE_AH_TBL, sizeof(*cmd)); 1239fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!cmd) 1240fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 1241fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1242fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit max_ah = OCRDMA_MAX_AH; 1243fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev->av_tbl.size = sizeof(struct ocrdma_av) * max_ah; 1244fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1245fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit /* number of PBEs in PBL */ 1246fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->ah_conf = (OCRDMA_AH_TBL_PAGES << 1247fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_AH_NUM_PAGES_SHIFT) & 1248fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_AH_NUM_PAGES_MASK; 1249fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1250fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit /* page size */ 1251fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit for (i = 0; i < OCRDMA_MAX_Q_PAGE_SIZE_CNT; i++) { 1252fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (PAGE_SIZE == (OCRDMA_MIN_Q_PAGE_SIZE << i)) 1253fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 1254fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 1255fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->ah_conf |= (i << OCRDMA_CREATE_AH_PAGE_SIZE_SHIFT) & 1256fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_AH_PAGE_SIZE_MASK; 1257fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1258fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit /* ah_entry size */ 1259fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->ah_conf |= (sizeof(struct ocrdma_av) << 1260fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_AH_ENTRY_SIZE_SHIFT) & 1261fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_AH_ENTRY_SIZE_MASK; 1262fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1263fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev->av_tbl.pbl.va = dma_alloc_coherent(&pdev->dev, PAGE_SIZE, 1264fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit &dev->av_tbl.pbl.pa, 1265fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit GFP_KERNEL); 1266fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (dev->av_tbl.pbl.va == NULL) 1267fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mem_err; 1268fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1269fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev->av_tbl.va = dma_alloc_coherent(&pdev->dev, dev->av_tbl.size, 1270fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit &pa, GFP_KERNEL); 1271fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (dev->av_tbl.va == NULL) 1272fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mem_err_ah; 1273fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev->av_tbl.pa = pa; 1274fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev->av_tbl.num_ah = max_ah; 1275fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit memset(dev->av_tbl.va, 0, dev->av_tbl.size); 1276fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1277fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit pbes = (struct ocrdma_pbe *)dev->av_tbl.pbl.va; 1278fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit for (i = 0; i < dev->av_tbl.size / OCRDMA_MIN_Q_PAGE_SIZE; i++) { 1279fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit pbes[i].pa_lo = (u32) (pa & 0xffffffff); 1280fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit pbes[i].pa_hi = (u32) upper_32_bits(pa); 1281fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit pa += PAGE_SIZE; 1282fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 1283fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->tbl_addr[0].lo = (u32)(dev->av_tbl.pbl.pa & 0xFFFFFFFF); 1284fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->tbl_addr[0].hi = (u32)upper_32_bits(dev->av_tbl.pbl.pa); 1285fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); 1286fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 1287fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mbx_err; 1288fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit rsp = (struct ocrdma_create_ah_tbl_rsp *)cmd; 1289fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev->av_tbl.ahid = rsp->ahid & 0xFFFF; 1290fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit kfree(cmd); 1291fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return 0; 1292fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1293fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditmbx_err: 1294fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dma_free_coherent(&pdev->dev, dev->av_tbl.size, dev->av_tbl.va, 1295fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev->av_tbl.pa); 1296fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev->av_tbl.va = NULL; 1297fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditmem_err_ah: 1298fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dma_free_coherent(&pdev->dev, PAGE_SIZE, dev->av_tbl.pbl.va, 1299fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev->av_tbl.pbl.pa); 1300fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev->av_tbl.pbl.va = NULL; 1301fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev->av_tbl.size = 0; 1302fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditmem_err: 1303fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit kfree(cmd); 1304fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 1305fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1306fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1307fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic void ocrdma_mbx_delete_ah_tbl(struct ocrdma_dev *dev) 1308fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1309fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_delete_ah_tbl *cmd; 1310fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct pci_dev *pdev = dev->nic_info.pdev; 1311fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1312fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (dev->av_tbl.va == NULL) 1313fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return; 1314fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1315fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_DELETE_AH_TBL, sizeof(*cmd)); 1316fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!cmd) 1317fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return; 1318fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->ahid = dev->av_tbl.ahid; 1319fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1320fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); 1321fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dma_free_coherent(&pdev->dev, dev->av_tbl.size, dev->av_tbl.va, 1322fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev->av_tbl.pa); 1323fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dma_free_coherent(&pdev->dev, PAGE_SIZE, dev->av_tbl.pbl.va, 1324fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev->av_tbl.pbl.pa); 1325fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit kfree(cmd); 1326fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1327fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1328fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit/* Multiple CQs uses the EQ. This routine returns least used 1329fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * EQ to associate with CQ. This will distributes the interrupt 1330fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * processing and CPU load to associated EQ, vector and so to that CPU. 1331fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit */ 1332fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic u16 ocrdma_bind_eq(struct ocrdma_dev *dev) 1333fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1334fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int i, selected_eq = 0, cq_cnt = 0; 1335fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u16 eq_id; 1336fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1337fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit mutex_lock(&dev->dev_lock); 1338c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala cq_cnt = dev->eq_tbl[0].cq_cnt; 1339c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala eq_id = dev->eq_tbl[0].q.id; 1340fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit /* find the EQ which is has the least number of 1341fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * CQs associated with it. 1342fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit */ 1343fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit for (i = 0; i < dev->eq_cnt; i++) { 1344c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala if (dev->eq_tbl[i].cq_cnt < cq_cnt) { 1345c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala cq_cnt = dev->eq_tbl[i].cq_cnt; 1346c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala eq_id = dev->eq_tbl[i].q.id; 1347fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit selected_eq = i; 1348fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 1349fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 1350c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala dev->eq_tbl[selected_eq].cq_cnt += 1; 1351fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit mutex_unlock(&dev->dev_lock); 1352fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return eq_id; 1353fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1354fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1355fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic void ocrdma_unbind_eq(struct ocrdma_dev *dev, u16 eq_id) 1356fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1357fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int i; 1358fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1359fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit mutex_lock(&dev->dev_lock); 1360fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit for (i = 0; i < dev->eq_cnt; i++) { 1361c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala if (dev->eq_tbl[i].q.id != eq_id) 1362fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit continue; 1363c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala dev->eq_tbl[i].cq_cnt -= 1; 1364fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 1365fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 1366fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit mutex_unlock(&dev->dev_lock); 1367fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1368fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1369fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditint ocrdma_mbx_create_cq(struct ocrdma_dev *dev, struct ocrdma_cq *cq, 1370cffce99051b80c90630a9fff662a1b25e278069dNaresh Gottumukkala int entries, int dpp_cq, u16 pd_id) 1371fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1372fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status = -ENOMEM; int max_hw_cqe; 1373fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct pci_dev *pdev = dev->nic_info.pdev; 1374fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_create_cq *cmd; 1375fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_create_cq_rsp *rsp; 1376fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u32 hw_pages, cqe_size, page_size, cqe_count; 1377fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1378fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (entries > dev->attr.max_cqe) { 1379ef99c4c2ed63cb0deb94ea70fb47c2d6294e302eNaresh Gottumukkala pr_err("%s(%d) max_cqe=0x%x, requester_cqe=0x%x\n", 1380ef99c4c2ed63cb0deb94ea70fb47c2d6294e302eNaresh Gottumukkala __func__, dev->id, dev->attr.max_cqe, entries); 1381fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return -EINVAL; 1382fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 1383fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (dpp_cq && (dev->nic_info.dev_family != OCRDMA_GEN2_FAMILY)) 1384fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return -EINVAL; 1385fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1386fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (dpp_cq) { 1387fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cq->max_hw_cqe = 1; 1388fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit max_hw_cqe = 1; 1389fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cqe_size = OCRDMA_DPP_CQE_SIZE; 1390fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit hw_pages = 1; 1391fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } else { 1392fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cq->max_hw_cqe = dev->attr.max_cqe; 1393fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit max_hw_cqe = dev->attr.max_cqe; 1394fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cqe_size = sizeof(struct ocrdma_cqe); 1395fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit hw_pages = OCRDMA_CREATE_CQ_MAX_PAGES; 1396fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 1397fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1398fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cq->len = roundup(max_hw_cqe * cqe_size, OCRDMA_MIN_Q_PAGE_SIZE); 1399fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1400fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_CREATE_CQ, sizeof(*cmd)); 1401fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!cmd) 1402fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return -ENOMEM; 1403fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_init_mch(&cmd->cmd.req, OCRDMA_CMD_CREATE_CQ, 1404fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_SUBSYS_COMMON, sizeof(*cmd)); 1405fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cq->va = dma_alloc_coherent(&pdev->dev, cq->len, &cq->pa, GFP_KERNEL); 1406fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!cq->va) { 1407fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = -ENOMEM; 1408fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mem_err; 1409fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 1410fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit memset(cq->va, 0, cq->len); 1411fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit page_size = cq->len / hw_pages; 1412fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->cmd.pgsz_pgcnt = (page_size / OCRDMA_MIN_Q_PAGE_SIZE) << 1413fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_CQ_PAGE_SIZE_SHIFT; 1414fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->cmd.pgsz_pgcnt |= hw_pages; 1415fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->cmd.ev_cnt_flags = OCRDMA_CREATE_CQ_DEF_FLAGS; 1416fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1417fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cq->eqn = ocrdma_bind_eq(dev); 1418cffce99051b80c90630a9fff662a1b25e278069dNaresh Gottumukkala cmd->cmd.req.rsvd_version = OCRDMA_CREATE_CQ_VER3; 1419fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cqe_count = cq->len / cqe_size; 1420f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala if (cqe_count > 1024) { 1421fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit /* Set cnt to 3 to indicate more than 1024 cq entries */ 1422fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->cmd.ev_cnt_flags |= (0x3 << OCRDMA_CREATE_CQ_CNT_SHIFT); 1423f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala } else { 1424fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u8 count = 0; 1425fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit switch (cqe_count) { 1426fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case 256: 1427fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit count = 0; 1428fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 1429fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case 512: 1430fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit count = 1; 1431fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 1432fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case 1024: 1433fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit count = 2; 1434fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 1435fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit default: 1436fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mbx_err; 1437fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 1438fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->cmd.ev_cnt_flags |= (count << OCRDMA_CREATE_CQ_CNT_SHIFT); 1439fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 1440fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit /* shared eq between all the consumer cqs. */ 1441fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->cmd.eqn = cq->eqn; 1442fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) { 1443fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (dpp_cq) 1444fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->cmd.pgsz_pgcnt |= OCRDMA_CREATE_CQ_DPP << 1445fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_CQ_TYPE_SHIFT; 1446fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cq->phase_change = false; 1447fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->cmd.cqe_count = (cq->len / cqe_size); 1448fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } else { 1449fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->cmd.cqe_count = (cq->len / cqe_size) - 1; 1450fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->cmd.ev_cnt_flags |= OCRDMA_CREATE_CQ_FLAGS_AUTO_VALID; 1451fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cq->phase_change = true; 1452fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 1453fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1454cffce99051b80c90630a9fff662a1b25e278069dNaresh Gottumukkala cmd->cmd.pd_id = pd_id; /* valid only for v3 */ 1455fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_build_q_pages(&cmd->cmd.pa[0], hw_pages, cq->pa, page_size); 1456fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); 1457fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 1458fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mbx_err; 1459fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1460fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit rsp = (struct ocrdma_create_cq_rsp *)cmd; 1461fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cq->id = (u16) (rsp->rsp.cq_id & OCRDMA_CREATE_CQ_RSP_CQ_ID_MASK); 1462fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit kfree(cmd); 1463fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return 0; 1464fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditmbx_err: 1465fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_unbind_eq(dev, cq->eqn); 1466fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dma_free_coherent(&pdev->dev, cq->len, cq->va, cq->pa); 1467fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditmem_err: 1468fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit kfree(cmd); 1469fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 1470fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1471fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1472fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditint ocrdma_mbx_destroy_cq(struct ocrdma_dev *dev, struct ocrdma_cq *cq) 1473fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1474fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status = -ENOMEM; 1475fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_destroy_cq *cmd; 1476fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1477fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_DELETE_CQ, sizeof(*cmd)); 1478fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!cmd) 1479fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 1480fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_init_mch(&cmd->req, OCRDMA_CMD_DELETE_CQ, 1481fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_SUBSYS_COMMON, sizeof(*cmd)); 1482fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1483fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->bypass_flush_qid |= 1484fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (cq->id << OCRDMA_DESTROY_CQ_QID_SHIFT) & 1485fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_DESTROY_CQ_QID_MASK; 1486fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1487fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_unbind_eq(dev, cq->eqn); 1488fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); 1489fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 1490fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mbx_err; 1491fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dma_free_coherent(&dev->nic_info.pdev->dev, cq->len, cq->va, cq->pa); 1492fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditmbx_err: 1493fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit kfree(cmd); 1494fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 1495fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1496fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1497fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditint ocrdma_mbx_alloc_lkey(struct ocrdma_dev *dev, struct ocrdma_hw_mr *hwmr, 1498fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u32 pdid, int addr_check) 1499fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1500fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status = -ENOMEM; 1501fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_alloc_lkey *cmd; 1502fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_alloc_lkey_rsp *rsp; 1503fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1504fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_ALLOC_LKEY, sizeof(*cmd)); 1505fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!cmd) 1506fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 1507fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->pdid = pdid; 1508fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->pbl_sz_flags |= addr_check; 1509fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->pbl_sz_flags |= (hwmr->fr_mr << OCRDMA_ALLOC_LKEY_FMR_SHIFT); 1510fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->pbl_sz_flags |= 1511fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (hwmr->remote_wr << OCRDMA_ALLOC_LKEY_REMOTE_WR_SHIFT); 1512fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->pbl_sz_flags |= 1513fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (hwmr->remote_rd << OCRDMA_ALLOC_LKEY_REMOTE_RD_SHIFT); 1514fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->pbl_sz_flags |= 1515fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (hwmr->local_wr << OCRDMA_ALLOC_LKEY_LOCAL_WR_SHIFT); 1516fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->pbl_sz_flags |= 1517fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (hwmr->remote_atomic << OCRDMA_ALLOC_LKEY_REMOTE_ATOMIC_SHIFT); 1518fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->pbl_sz_flags |= 1519fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (hwmr->num_pbls << OCRDMA_ALLOC_LKEY_PBL_SIZE_SHIFT); 1520fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1521fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); 1522fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 1523fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mbx_err; 1524fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit rsp = (struct ocrdma_alloc_lkey_rsp *)cmd; 1525fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit hwmr->lkey = rsp->lrkey; 1526fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditmbx_err: 1527fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit kfree(cmd); 1528fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 1529fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1530fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1531fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditint ocrdma_mbx_dealloc_lkey(struct ocrdma_dev *dev, int fr_mr, u32 lkey) 1532fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1533fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status = -ENOMEM; 1534fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_dealloc_lkey *cmd; 1535fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1536fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_DEALLOC_LKEY, sizeof(*cmd)); 1537fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!cmd) 1538fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return -ENOMEM; 1539fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->lkey = lkey; 1540fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->rsvd_frmr = fr_mr ? 1 : 0; 1541fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); 1542fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 1543fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mbx_err; 1544fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditmbx_err: 1545fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit kfree(cmd); 1546fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 1547fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1548fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1549fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic int ocrdma_mbx_reg_mr(struct ocrdma_dev *dev, struct ocrdma_hw_mr *hwmr, 1550fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u32 pdid, u32 pbl_cnt, u32 pbe_size, u32 last) 1551fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1552fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status = -ENOMEM; 1553fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int i; 1554fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_reg_nsmr *cmd; 1555fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_reg_nsmr_rsp *rsp; 1556fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1557fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_REGISTER_NSMR, sizeof(*cmd)); 1558fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!cmd) 1559fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return -ENOMEM; 1560fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->num_pbl_pdid = 1561fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit pdid | (hwmr->num_pbls << OCRDMA_REG_NSMR_NUM_PBL_SHIFT); 15622b51a9b9eb6bf240d2592e10d2f8823dd1f5ee3eNaresh Gottumukkala cmd->fr_mr = hwmr->fr_mr; 1563fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1564fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->flags_hpage_pbe_sz |= (hwmr->remote_wr << 1565fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_REG_NSMR_REMOTE_WR_SHIFT); 1566fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->flags_hpage_pbe_sz |= (hwmr->remote_rd << 1567fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_REG_NSMR_REMOTE_RD_SHIFT); 1568fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->flags_hpage_pbe_sz |= (hwmr->local_wr << 1569fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_REG_NSMR_LOCAL_WR_SHIFT); 1570fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->flags_hpage_pbe_sz |= (hwmr->remote_atomic << 1571fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_REG_NSMR_REMOTE_ATOMIC_SHIFT); 1572fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->flags_hpage_pbe_sz |= (hwmr->mw_bind << 1573fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_REG_NSMR_BIND_MEMWIN_SHIFT); 1574fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->flags_hpage_pbe_sz |= (last << OCRDMA_REG_NSMR_LAST_SHIFT); 1575fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1576fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->flags_hpage_pbe_sz |= (hwmr->pbe_size / OCRDMA_MIN_HPAGE_SIZE); 1577fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->flags_hpage_pbe_sz |= (hwmr->pbl_size / OCRDMA_MIN_HPAGE_SIZE) << 1578fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_REG_NSMR_HPAGE_SIZE_SHIFT; 1579fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->totlen_low = hwmr->len; 1580fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->totlen_high = upper_32_bits(hwmr->len); 1581fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->fbo_low = (u32) (hwmr->fbo & 0xffffffff); 1582fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->fbo_high = (u32) upper_32_bits(hwmr->fbo); 1583fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->va_loaddr = (u32) hwmr->va; 1584fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->va_hiaddr = (u32) upper_32_bits(hwmr->va); 1585fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1586fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit for (i = 0; i < pbl_cnt; i++) { 1587fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->pbl[i].lo = (u32) (hwmr->pbl_table[i].pa & 0xffffffff); 1588fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->pbl[i].hi = upper_32_bits(hwmr->pbl_table[i].pa); 1589fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 1590fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); 1591fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 1592fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mbx_err; 1593fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit rsp = (struct ocrdma_reg_nsmr_rsp *)cmd; 1594fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit hwmr->lkey = rsp->lrkey; 1595fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditmbx_err: 1596fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit kfree(cmd); 1597fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 1598fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1599fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1600fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic int ocrdma_mbx_reg_mr_cont(struct ocrdma_dev *dev, 1601fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_hw_mr *hwmr, u32 pbl_cnt, 1602fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u32 pbl_offset, u32 last) 1603fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1604fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status = -ENOMEM; 1605fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int i; 1606fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_reg_nsmr_cont *cmd; 1607fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1608fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_REGISTER_NSMR_CONT, sizeof(*cmd)); 1609fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!cmd) 1610fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return -ENOMEM; 1611fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->lrkey = hwmr->lkey; 1612fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->num_pbl_offset = (pbl_cnt << OCRDMA_REG_NSMR_CONT_NUM_PBL_SHIFT) | 1613fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (pbl_offset & OCRDMA_REG_NSMR_CONT_PBL_SHIFT_MASK); 1614fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->last = last << OCRDMA_REG_NSMR_CONT_LAST_SHIFT; 1615fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1616fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit for (i = 0; i < pbl_cnt; i++) { 1617fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->pbl[i].lo = 1618fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (u32) (hwmr->pbl_table[i + pbl_offset].pa & 0xffffffff); 1619fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->pbl[i].hi = 1620fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit upper_32_bits(hwmr->pbl_table[i + pbl_offset].pa); 1621fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 1622fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); 1623fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 1624fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mbx_err; 1625fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditmbx_err: 1626fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit kfree(cmd); 1627fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 1628fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1629fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1630fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditint ocrdma_reg_mr(struct ocrdma_dev *dev, 1631fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_hw_mr *hwmr, u32 pdid, int acc) 1632fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1633fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status; 1634fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u32 last = 0; 1635fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u32 cur_pbl_cnt, pbl_offset; 1636fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u32 pending_pbl_cnt = hwmr->num_pbls; 1637fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1638fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit pbl_offset = 0; 1639fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cur_pbl_cnt = min(pending_pbl_cnt, MAX_OCRDMA_NSMR_PBL); 1640fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (cur_pbl_cnt == pending_pbl_cnt) 1641fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit last = 1; 1642fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1643fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_mbx_reg_mr(dev, hwmr, pdid, 1644fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cur_pbl_cnt, hwmr->pbe_size, last); 1645fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) { 1646ef99c4c2ed63cb0deb94ea70fb47c2d6294e302eNaresh Gottumukkala pr_err("%s() status=%d\n", __func__, status); 1647fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 1648fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 1649fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit /* if there is no more pbls to register then exit. */ 1650fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (last) 1651fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return 0; 1652fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1653fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit while (!last) { 1654fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit pbl_offset += cur_pbl_cnt; 1655fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit pending_pbl_cnt -= cur_pbl_cnt; 1656fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cur_pbl_cnt = min(pending_pbl_cnt, MAX_OCRDMA_NSMR_PBL); 1657fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit /* if we reach the end of the pbls, then need to set the last 1658fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit * bit, indicating no more pbls to register for this memory key. 1659fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit */ 1660fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (cur_pbl_cnt == pending_pbl_cnt) 1661fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit last = 1; 1662fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1663fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_mbx_reg_mr_cont(dev, hwmr, cur_pbl_cnt, 1664fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit pbl_offset, last); 1665fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 1666fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 1667fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 1668fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 1669ef99c4c2ed63cb0deb94ea70fb47c2d6294e302eNaresh Gottumukkala pr_err("%s() err. status=%d\n", __func__, status); 1670fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1671fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 1672fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1673fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1674fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditbool ocrdma_is_qp_in_sq_flushlist(struct ocrdma_cq *cq, struct ocrdma_qp *qp) 1675fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1676fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_qp *tmp; 1677fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit bool found = false; 1678fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit list_for_each_entry(tmp, &cq->sq_head, sq_entry) { 1679fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (qp == tmp) { 1680fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit found = true; 1681fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 1682fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 1683fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 1684fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return found; 1685fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1686fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1687fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditbool ocrdma_is_qp_in_rq_flushlist(struct ocrdma_cq *cq, struct ocrdma_qp *qp) 1688fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1689fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_qp *tmp; 1690fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit bool found = false; 1691fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit list_for_each_entry(tmp, &cq->rq_head, rq_entry) { 1692fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (qp == tmp) { 1693fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit found = true; 1694fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 1695fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 1696fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 1697fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return found; 1698fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1699fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1700fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditvoid ocrdma_flush_qp(struct ocrdma_qp *qp) 1701fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1702fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit bool found; 1703fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit unsigned long flags; 1704fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1705fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit spin_lock_irqsave(&qp->dev->flush_q_lock, flags); 1706fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit found = ocrdma_is_qp_in_sq_flushlist(qp->sq_cq, qp); 1707fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!found) 1708fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit list_add_tail(&qp->sq_entry, &qp->sq_cq->sq_head); 1709fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!qp->srq) { 1710fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit found = ocrdma_is_qp_in_rq_flushlist(qp->rq_cq, qp); 1711fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!found) 1712fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit list_add_tail(&qp->rq_entry, &qp->rq_cq->rq_head); 1713fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 1714fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit spin_unlock_irqrestore(&qp->dev->flush_q_lock, flags); 1715fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1716fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1717f11220ee69f72cf08479f28fd494264ac6a9349bNaresh Gottumukkalastatic void ocrdma_init_hwq_ptr(struct ocrdma_qp *qp) 1718f11220ee69f72cf08479f28fd494264ac6a9349bNaresh Gottumukkala{ 1719f11220ee69f72cf08479f28fd494264ac6a9349bNaresh Gottumukkala qp->sq.head = 0; 1720f11220ee69f72cf08479f28fd494264ac6a9349bNaresh Gottumukkala qp->sq.tail = 0; 1721f11220ee69f72cf08479f28fd494264ac6a9349bNaresh Gottumukkala qp->rq.head = 0; 1722f11220ee69f72cf08479f28fd494264ac6a9349bNaresh Gottumukkala qp->rq.tail = 0; 1723f11220ee69f72cf08479f28fd494264ac6a9349bNaresh Gottumukkala} 1724f11220ee69f72cf08479f28fd494264ac6a9349bNaresh Gottumukkala 1725057729cb234754d12e0b2a361c2fc85c6363cbf6Naresh Gottumukkalaint ocrdma_qp_state_change(struct ocrdma_qp *qp, enum ib_qp_state new_ib_state, 1726057729cb234754d12e0b2a361c2fc85c6363cbf6Naresh Gottumukkala enum ib_qp_state *old_ib_state) 1727fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1728fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit unsigned long flags; 1729fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status = 0; 1730fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit enum ocrdma_qp_state new_state; 1731fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit new_state = get_ocrdma_qp_state(new_ib_state); 1732fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1733fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit /* sync with wqe and rqe posting */ 1734fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit spin_lock_irqsave(&qp->q_lock, flags); 1735fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1736fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (old_ib_state) 1737fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit *old_ib_state = get_ibqp_state(qp->state); 1738fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (new_state == qp->state) { 1739fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit spin_unlock_irqrestore(&qp->q_lock, flags); 1740fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return 1; 1741fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 1742fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1743057729cb234754d12e0b2a361c2fc85c6363cbf6Naresh Gottumukkala 1744f11220ee69f72cf08479f28fd494264ac6a9349bNaresh Gottumukkala if (new_state == OCRDMA_QPS_INIT) { 1745f11220ee69f72cf08479f28fd494264ac6a9349bNaresh Gottumukkala ocrdma_init_hwq_ptr(qp); 1746f11220ee69f72cf08479f28fd494264ac6a9349bNaresh Gottumukkala ocrdma_del_flush_qp(qp); 1747f11220ee69f72cf08479f28fd494264ac6a9349bNaresh Gottumukkala } else if (new_state == OCRDMA_QPS_ERR) { 1748057729cb234754d12e0b2a361c2fc85c6363cbf6Naresh Gottumukkala ocrdma_flush_qp(qp); 1749f11220ee69f72cf08479f28fd494264ac6a9349bNaresh Gottumukkala } 1750057729cb234754d12e0b2a361c2fc85c6363cbf6Naresh Gottumukkala 1751057729cb234754d12e0b2a361c2fc85c6363cbf6Naresh Gottumukkala qp->state = new_state; 1752fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1753fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit spin_unlock_irqrestore(&qp->q_lock, flags); 1754fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 1755fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1756fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1757fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic u32 ocrdma_set_create_qp_mbx_access_flags(struct ocrdma_qp *qp) 1758fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1759fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u32 flags = 0; 1760fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (qp->cap_flags & OCRDMA_QP_INB_RD) 1761fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit flags |= OCRDMA_CREATE_QP_REQ_INB_RDEN_MASK; 1762fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (qp->cap_flags & OCRDMA_QP_INB_WR) 1763fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit flags |= OCRDMA_CREATE_QP_REQ_INB_WREN_MASK; 1764fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (qp->cap_flags & OCRDMA_QP_MW_BIND) 1765fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit flags |= OCRDMA_CREATE_QP_REQ_BIND_MEMWIN_MASK; 1766fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (qp->cap_flags & OCRDMA_QP_LKEY0) 1767fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit flags |= OCRDMA_CREATE_QP_REQ_ZERO_LKEYEN_MASK; 1768fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (qp->cap_flags & OCRDMA_QP_FAST_REG) 1769fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit flags |= OCRDMA_CREATE_QP_REQ_FMR_EN_MASK; 1770fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return flags; 1771fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1772fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1773fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic int ocrdma_set_create_qp_sq_cmd(struct ocrdma_create_qp_req *cmd, 1774fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ib_qp_init_attr *attrs, 1775fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_qp *qp) 1776fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1777fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status; 1778fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u32 len, hw_pages, hw_page_size; 1779fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dma_addr_t pa; 1780fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_dev *dev = qp->dev; 1781fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct pci_dev *pdev = dev->nic_info.pdev; 1782fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u32 max_wqe_allocated; 1783fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u32 max_sges = attrs->cap.max_send_sge; 1784fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 178543a6b4025c79ded5b44e58ba0db97c29dd38d718Naresh Gottumukkala /* QP1 may exceed 127 */ 178643a6b4025c79ded5b44e58ba0db97c29dd38d718Naresh Gottumukkala max_wqe_allocated = min_t(int, attrs->cap.max_send_wr + 1, 178743a6b4025c79ded5b44e58ba0db97c29dd38d718Naresh Gottumukkala dev->attr.max_wqe); 1788fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1789fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_build_q_conf(&max_wqe_allocated, 1790fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev->attr.wqe_size, &hw_pages, &hw_page_size); 1791fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) { 1792ef99c4c2ed63cb0deb94ea70fb47c2d6294e302eNaresh Gottumukkala pr_err("%s() req. max_send_wr=0x%x\n", __func__, 1793ef99c4c2ed63cb0deb94ea70fb47c2d6294e302eNaresh Gottumukkala max_wqe_allocated); 1794fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return -EINVAL; 1795fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 1796fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->sq.max_cnt = max_wqe_allocated; 1797fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit len = (hw_pages * hw_page_size); 1798fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1799fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->sq.va = dma_alloc_coherent(&pdev->dev, len, &pa, GFP_KERNEL); 1800fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!qp->sq.va) 1801fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return -EINVAL; 1802fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit memset(qp->sq.va, 0, len); 1803fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->sq.len = len; 1804fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->sq.pa = pa; 1805fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->sq.entry_size = dev->attr.wqe_size; 1806fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_build_q_pages(&cmd->wq_addr[0], hw_pages, pa, hw_page_size); 1807fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1808fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->type_pgsz_pdn |= (ilog2(hw_page_size / OCRDMA_MIN_Q_PAGE_SIZE) 1809fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit << OCRDMA_CREATE_QP_REQ_SQ_PAGE_SIZE_SHIFT); 1810fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->num_wq_rq_pages |= (hw_pages << 1811fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_REQ_NUM_WQ_PAGES_SHIFT) & 1812fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_REQ_NUM_WQ_PAGES_MASK; 1813fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->max_sge_send_write |= (max_sges << 1814fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_REQ_MAX_SGE_SEND_SHIFT) & 1815fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_REQ_MAX_SGE_SEND_MASK; 1816fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->max_sge_send_write |= (max_sges << 1817fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_REQ_MAX_SGE_WRITE_SHIFT) & 1818fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_REQ_MAX_SGE_WRITE_MASK; 1819fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->max_wqe_rqe |= (ilog2(qp->sq.max_cnt) << 1820fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_REQ_MAX_WQE_SHIFT) & 1821fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_REQ_MAX_WQE_MASK; 1822fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->wqe_rqe_size |= (dev->attr.wqe_size << 1823fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_REQ_WQE_SIZE_SHIFT) & 1824fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_REQ_WQE_SIZE_MASK; 1825fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return 0; 1826fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1827fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1828fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic int ocrdma_set_create_qp_rq_cmd(struct ocrdma_create_qp_req *cmd, 1829fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ib_qp_init_attr *attrs, 1830fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_qp *qp) 1831fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1832fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status; 1833fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u32 len, hw_pages, hw_page_size; 1834fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dma_addr_t pa = 0; 1835fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_dev *dev = qp->dev; 1836fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct pci_dev *pdev = dev->nic_info.pdev; 1837fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u32 max_rqe_allocated = attrs->cap.max_recv_wr + 1; 1838fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1839fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_build_q_conf(&max_rqe_allocated, dev->attr.rqe_size, 1840fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit &hw_pages, &hw_page_size); 1841fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) { 1842ef99c4c2ed63cb0deb94ea70fb47c2d6294e302eNaresh Gottumukkala pr_err("%s() req. max_recv_wr=0x%x\n", __func__, 1843ef99c4c2ed63cb0deb94ea70fb47c2d6294e302eNaresh Gottumukkala attrs->cap.max_recv_wr + 1); 1844fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 1845fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 1846fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->rq.max_cnt = max_rqe_allocated; 1847fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit len = (hw_pages * hw_page_size); 1848fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1849fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->rq.va = dma_alloc_coherent(&pdev->dev, len, &pa, GFP_KERNEL); 1850fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!qp->rq.va) 1851c94e15c5cb4d02579321382871eb87e17d10858eWei Yongjun return -ENOMEM; 1852fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit memset(qp->rq.va, 0, len); 1853fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->rq.pa = pa; 1854fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->rq.len = len; 1855fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->rq.entry_size = dev->attr.rqe_size; 1856fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1857fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_build_q_pages(&cmd->rq_addr[0], hw_pages, pa, hw_page_size); 1858fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->type_pgsz_pdn |= (ilog2(hw_page_size / OCRDMA_MIN_Q_PAGE_SIZE) << 1859fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_REQ_RQ_PAGE_SIZE_SHIFT); 1860fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->num_wq_rq_pages |= 1861fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (hw_pages << OCRDMA_CREATE_QP_REQ_NUM_RQ_PAGES_SHIFT) & 1862fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_REQ_NUM_RQ_PAGES_MASK; 1863fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->max_sge_recv_flags |= (attrs->cap.max_recv_sge << 1864fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_REQ_MAX_SGE_RECV_SHIFT) & 1865fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_REQ_MAX_SGE_RECV_MASK; 1866fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->max_wqe_rqe |= (ilog2(qp->rq.max_cnt) << 1867fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_REQ_MAX_RQE_SHIFT) & 1868fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_REQ_MAX_RQE_MASK; 1869fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->wqe_rqe_size |= (dev->attr.rqe_size << 1870fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_REQ_RQE_SIZE_SHIFT) & 1871fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_REQ_RQE_SIZE_MASK; 1872fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return 0; 1873fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1874fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1875fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic void ocrdma_set_create_qp_dpp_cmd(struct ocrdma_create_qp_req *cmd, 1876fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_pd *pd, 1877fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_qp *qp, 1878fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u8 enable_dpp_cq, u16 dpp_cq_id) 1879fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1880fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit pd->num_dpp_qp--; 1881fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->dpp_enabled = true; 1882fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->max_sge_recv_flags |= OCRDMA_CREATE_QP_REQ_ENABLE_DPP_MASK; 1883fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!enable_dpp_cq) 1884fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return; 1885fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->max_sge_recv_flags |= OCRDMA_CREATE_QP_REQ_ENABLE_DPP_MASK; 1886fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->dpp_credits_cqid = dpp_cq_id; 1887fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->dpp_credits_cqid |= OCRDMA_CREATE_QP_REQ_DPP_CREDIT_LIMIT << 1888fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_REQ_DPP_CREDIT_SHIFT; 1889fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1890fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1891fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic int ocrdma_set_create_qp_ird_cmd(struct ocrdma_create_qp_req *cmd, 1892fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_qp *qp) 1893fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1894fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_dev *dev = qp->dev; 1895fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct pci_dev *pdev = dev->nic_info.pdev; 1896fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dma_addr_t pa = 0; 1897fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int ird_page_size = dev->attr.ird_page_size; 1898fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int ird_q_len = dev->attr.num_ird_pages * ird_page_size; 189943a6b4025c79ded5b44e58ba0db97c29dd38d718Naresh Gottumukkala struct ocrdma_hdr_wqe *rqe; 190043a6b4025c79ded5b44e58ba0db97c29dd38d718Naresh Gottumukkala int i = 0; 1901fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1902fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (dev->attr.ird == 0) 1903fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return 0; 1904fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1905fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->ird_q_va = dma_alloc_coherent(&pdev->dev, ird_q_len, 1906fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit &pa, GFP_KERNEL); 1907fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!qp->ird_q_va) 1908fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return -ENOMEM; 1909fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit memset(qp->ird_q_va, 0, ird_q_len); 1910fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_build_q_pages(&cmd->ird_addr[0], dev->attr.num_ird_pages, 1911fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit pa, ird_page_size); 191243a6b4025c79ded5b44e58ba0db97c29dd38d718Naresh Gottumukkala for (; i < ird_q_len / dev->attr.rqe_size; i++) { 191343a6b4025c79ded5b44e58ba0db97c29dd38d718Naresh Gottumukkala rqe = (struct ocrdma_hdr_wqe *)(qp->ird_q_va + 191443a6b4025c79ded5b44e58ba0db97c29dd38d718Naresh Gottumukkala (i * dev->attr.rqe_size)); 191543a6b4025c79ded5b44e58ba0db97c29dd38d718Naresh Gottumukkala rqe->cw = 0; 191643a6b4025c79ded5b44e58ba0db97c29dd38d718Naresh Gottumukkala rqe->cw |= 2; 191743a6b4025c79ded5b44e58ba0db97c29dd38d718Naresh Gottumukkala rqe->cw |= (OCRDMA_TYPE_LKEY << OCRDMA_WQE_TYPE_SHIFT); 191843a6b4025c79ded5b44e58ba0db97c29dd38d718Naresh Gottumukkala rqe->cw |= (8 << OCRDMA_WQE_SIZE_SHIFT); 191943a6b4025c79ded5b44e58ba0db97c29dd38d718Naresh Gottumukkala rqe->cw |= (8 << OCRDMA_WQE_NXT_WQE_SIZE_SHIFT); 192043a6b4025c79ded5b44e58ba0db97c29dd38d718Naresh Gottumukkala } 1921fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return 0; 1922fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1923fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1924fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic void ocrdma_get_create_qp_rsp(struct ocrdma_create_qp_rsp *rsp, 1925fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_qp *qp, 1926fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ib_qp_init_attr *attrs, 1927fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u16 *dpp_offset, u16 *dpp_credit_lmt) 1928fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1929fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u32 max_wqe_allocated, max_rqe_allocated; 1930fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->id = rsp->qp_id & OCRDMA_CREATE_QP_RSP_QP_ID_MASK; 1931fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->rq.dbid = rsp->sq_rq_id & OCRDMA_CREATE_QP_RSP_RQ_ID_MASK; 1932fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->sq.dbid = rsp->sq_rq_id >> OCRDMA_CREATE_QP_RSP_SQ_ID_SHIFT; 1933fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->max_ird = rsp->max_ord_ird & OCRDMA_CREATE_QP_RSP_MAX_IRD_MASK; 1934fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->max_ord = (rsp->max_ord_ird >> OCRDMA_CREATE_QP_RSP_MAX_ORD_SHIFT); 1935fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->dpp_enabled = false; 1936fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (rsp->dpp_response & OCRDMA_CREATE_QP_RSP_DPP_ENABLED_MASK) { 1937fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->dpp_enabled = true; 1938fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit *dpp_credit_lmt = (rsp->dpp_response & 1939fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_RSP_DPP_CREDITS_MASK) >> 1940fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_RSP_DPP_CREDITS_SHIFT; 1941fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit *dpp_offset = (rsp->dpp_response & 1942fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_RSP_DPP_PAGE_OFFSET_MASK) >> 1943fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_RSP_DPP_PAGE_OFFSET_SHIFT; 1944fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 1945fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit max_wqe_allocated = 1946fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit rsp->max_wqe_rqe >> OCRDMA_CREATE_QP_RSP_MAX_WQE_SHIFT; 1947fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit max_wqe_allocated = 1 << max_wqe_allocated; 1948fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit max_rqe_allocated = 1 << ((u16)rsp->max_wqe_rqe); 1949fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1950fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->sq.max_cnt = max_wqe_allocated; 1951fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->sq.max_wqe_idx = max_wqe_allocated - 1; 1952fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1953fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!attrs->srq) { 1954fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->rq.max_cnt = max_rqe_allocated; 1955fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->rq.max_wqe_idx = max_rqe_allocated - 1; 1956fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 1957fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 1958fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1959fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditint ocrdma_mbx_create_qp(struct ocrdma_qp *qp, struct ib_qp_init_attr *attrs, 1960fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u8 enable_dpp_cq, u16 dpp_cq_id, u16 *dpp_offset, 1961fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u16 *dpp_credit_lmt) 1962fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 1963fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status = -ENOMEM; 1964fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u32 flags = 0; 1965fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_dev *dev = qp->dev; 1966fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_pd *pd = qp->pd; 1967fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct pci_dev *pdev = dev->nic_info.pdev; 1968fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_cq *cq; 1969fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_create_qp_req *cmd; 1970fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_create_qp_rsp *rsp; 1971fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int qptype; 1972fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1973fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit switch (attrs->qp_type) { 1974fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case IB_QPT_GSI: 1975fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qptype = OCRDMA_QPT_GSI; 1976fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 1977fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case IB_QPT_RC: 1978fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qptype = OCRDMA_QPT_RC; 1979fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 1980fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit case IB_QPT_UD: 1981fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qptype = OCRDMA_QPT_UD; 1982fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 1983fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit default: 1984fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return -EINVAL; 19852b50176d11866e59208a4ed1623b3fc0ca322690Joe Perches } 1986fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1987fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_CREATE_QP, sizeof(*cmd)); 1988fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!cmd) 1989fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 1990fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->type_pgsz_pdn |= (qptype << OCRDMA_CREATE_QP_REQ_QPT_SHIFT) & 1991fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_REQ_QPT_MASK; 1992fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_set_create_qp_sq_cmd(cmd, attrs, qp); 1993fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 1994fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto sq_err; 1995fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 1996fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (attrs->srq) { 1997fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_srq *srq = get_ocrdma_srq(attrs->srq); 1998fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->max_sge_recv_flags |= OCRDMA_CREATE_QP_REQ_USE_SRQ_MASK; 1999fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->rq_addr[0].lo = srq->id; 2000fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->srq = srq; 2001fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } else { 2002fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_set_create_qp_rq_cmd(cmd, attrs, qp); 2003fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 2004fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto rq_err; 2005fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 2006fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2007fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_set_create_qp_ird_cmd(cmd, qp); 2008fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 2009fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mbx_err; 2010fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2011fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->type_pgsz_pdn |= (pd->id << OCRDMA_CREATE_QP_REQ_PD_ID_SHIFT) & 2012fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_REQ_PD_ID_MASK; 2013fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2014fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit flags = ocrdma_set_create_qp_mbx_access_flags(qp); 2015fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2016fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->max_sge_recv_flags |= flags; 2017fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->max_ord_ird |= (dev->attr.max_ord_per_qp << 2018fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_REQ_MAX_ORD_SHIFT) & 2019fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_REQ_MAX_ORD_MASK; 2020fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->max_ord_ird |= (dev->attr.max_ird_per_qp << 2021fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_REQ_MAX_IRD_SHIFT) & 2022fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_REQ_MAX_IRD_MASK; 2023fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cq = get_ocrdma_cq(attrs->send_cq); 2024fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->wq_rq_cqid |= (cq->id << OCRDMA_CREATE_QP_REQ_WQ_CQID_SHIFT) & 2025fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_REQ_WQ_CQID_MASK; 2026fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->sq_cq = cq; 2027fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cq = get_ocrdma_cq(attrs->recv_cq); 2028fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->wq_rq_cqid |= (cq->id << OCRDMA_CREATE_QP_REQ_RQ_CQID_SHIFT) & 2029fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_QP_REQ_RQ_CQID_MASK; 2030fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->rq_cq = cq; 2031fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2032fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (pd->dpp_enabled && attrs->cap.max_inline_data && pd->num_dpp_qp && 2033f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala (attrs->cap.max_inline_data <= dev->attr.max_inline_data)) { 2034fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_set_create_qp_dpp_cmd(cmd, pd, qp, enable_dpp_cq, 2035fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dpp_cq_id); 2036f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala } 2037fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2038fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); 2039fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 2040fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mbx_err; 2041fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit rsp = (struct ocrdma_create_qp_rsp *)cmd; 2042fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_get_create_qp_rsp(rsp, qp, attrs, dpp_offset, dpp_credit_lmt); 2043fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->state = OCRDMA_QPS_RST; 2044fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit kfree(cmd); 2045fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return 0; 2046fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditmbx_err: 2047fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (qp->rq.va) 2048fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dma_free_coherent(&pdev->dev, qp->rq.len, qp->rq.va, qp->rq.pa); 2049fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditrq_err: 2050ef99c4c2ed63cb0deb94ea70fb47c2d6294e302eNaresh Gottumukkala pr_err("%s(%d) rq_err\n", __func__, dev->id); 2051fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dma_free_coherent(&pdev->dev, qp->sq.len, qp->sq.va, qp->sq.pa); 2052fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditsq_err: 2053ef99c4c2ed63cb0deb94ea70fb47c2d6294e302eNaresh Gottumukkala pr_err("%s(%d) sq_err\n", __func__, dev->id); 2054fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit kfree(cmd); 2055fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 2056fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 2057fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2058fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditint ocrdma_mbx_query_qp(struct ocrdma_dev *dev, struct ocrdma_qp *qp, 2059fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_qp_params *param) 2060fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 2061fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status = -ENOMEM; 2062fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_query_qp *cmd; 2063fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_query_qp_rsp *rsp; 2064fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2065fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_QUERY_QP, sizeof(*cmd)); 2066fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!cmd) 2067fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 2068fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->qp_id = qp->id; 2069fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); 2070fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 2071fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mbx_err; 2072fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit rsp = (struct ocrdma_query_qp_rsp *)cmd; 2073fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit memcpy(param, &rsp->params, sizeof(struct ocrdma_qp_params)); 2074fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditmbx_err: 2075fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit kfree(cmd); 2076fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 2077fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 2078fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2079fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditint ocrdma_resolve_dgid(struct ocrdma_dev *dev, union ib_gid *dgid, 2080fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u8 *mac_addr) 2081fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 2082fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct in6_addr in6; 2083fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2084fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit memcpy(&in6, dgid, sizeof in6); 2085f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala if (rdma_is_multicast_addr(&in6)) { 2086fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit rdma_get_mcast_mac(&in6, mac_addr); 2087f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala } else if (rdma_link_local_addr(&in6)) { 2088fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit rdma_get_ll_mac(&in6, mac_addr); 2089f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala } else { 2090ef99c4c2ed63cb0deb94ea70fb47c2d6294e302eNaresh Gottumukkala pr_err("%s() fail to resolve mac_addr.\n", __func__); 2091fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return -EINVAL; 2092fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 2093fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return 0; 2094fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 2095fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2096f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkalastatic int ocrdma_set_av_params(struct ocrdma_qp *qp, 2097fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_modify_qp *cmd, 2098fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ib_qp_attr *attrs) 2099fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 2100f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala int status; 2101fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ib_ah_attr *ah_attr = &attrs->ah_attr; 21029c58726ba96ad5f767ce2d8c42159c3075a98d6fNaresh Gottumukkala union ib_gid sgid, zgid; 2103fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u32 vlan_id; 2104fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u8 mac_addr[6]; 21059c58726ba96ad5f767ce2d8c42159c3075a98d6fNaresh Gottumukkala 2106fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if ((ah_attr->ah_flags & IB_AH_GRH) == 0) 2107f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala return -EINVAL; 2108fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->params.tclass_sq_psn |= 2109fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (ah_attr->grh.traffic_class << OCRDMA_QP_PARAMS_TCLASS_SHIFT); 2110fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->params.rnt_rc_sl_fl |= 2111fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (ah_attr->grh.flow_label & OCRDMA_QP_PARAMS_FLOW_LABEL_MASK); 21122b51a9b9eb6bf240d2592e10d2f8823dd1f5ee3eNaresh Gottumukkala cmd->params.rnt_rc_sl_fl |= (ah_attr->sl << OCRDMA_QP_PARAMS_SL_SHIFT); 2113fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->params.hop_lmt_rq_psn |= 2114fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (ah_attr->grh.hop_limit << OCRDMA_QP_PARAMS_HOP_LMT_SHIFT); 2115fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->flags |= OCRDMA_QP_PARA_FLOW_LBL_VALID; 2116fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit memcpy(&cmd->params.dgid[0], &ah_attr->grh.dgid.raw[0], 2117fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit sizeof(cmd->params.dgid)); 2118f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala status = ocrdma_query_gid(&qp->dev->ibdev, 1, 2119fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ah_attr->grh.sgid_index, &sgid); 2120f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala if (status) 2121f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala return status; 21229c58726ba96ad5f767ce2d8c42159c3075a98d6fNaresh Gottumukkala 21239c58726ba96ad5f767ce2d8c42159c3075a98d6fNaresh Gottumukkala memset(&zgid, 0, sizeof(zgid)); 21249c58726ba96ad5f767ce2d8c42159c3075a98d6fNaresh Gottumukkala if (!memcmp(&sgid, &zgid, sizeof(zgid))) 21259c58726ba96ad5f767ce2d8c42159c3075a98d6fNaresh Gottumukkala return -EINVAL; 21269c58726ba96ad5f767ce2d8c42159c3075a98d6fNaresh Gottumukkala 2127fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->sgid_idx = ah_attr->grh.sgid_index; 2128fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit memcpy(&cmd->params.sgid[0], &sgid.raw[0], sizeof(cmd->params.sgid)); 2129fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_resolve_dgid(qp->dev, &ah_attr->grh.dgid, &mac_addr[0]); 2130fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->params.dmac_b0_to_b3 = mac_addr[0] | (mac_addr[1] << 8) | 2131fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (mac_addr[2] << 16) | (mac_addr[3] << 24); 2132fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit /* convert them to LE format. */ 2133fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_cpu_to_le32(&cmd->params.dgid[0], sizeof(cmd->params.dgid)); 2134fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_cpu_to_le32(&cmd->params.sgid[0], sizeof(cmd->params.sgid)); 2135fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->params.vlan_dmac_b4_to_b5 = mac_addr[4] | (mac_addr[5] << 8); 2136fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit vlan_id = rdma_get_vlan_id(&sgid); 2137fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (vlan_id && (vlan_id < 0x1000)) { 2138fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->params.vlan_dmac_b4_to_b5 |= 2139fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit vlan_id << OCRDMA_QP_PARAMS_VLAN_SHIFT; 2140fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->flags |= OCRDMA_QP_PARA_VLAN_EN_VALID; 2141fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 2142f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala return 0; 2143fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 2144fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2145fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditstatic int ocrdma_set_qp_params(struct ocrdma_qp *qp, 2146fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_modify_qp *cmd, 2147fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ib_qp_attr *attrs, int attr_mask, 2148fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit enum ib_qp_state old_qps) 2149fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 2150fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status = 0; 2151fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2152fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (attr_mask & IB_QP_PKEY_INDEX) { 2153fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->params.path_mtu_pkey_indx |= (attrs->pkey_index & 2154fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_QP_PARAMS_PKEY_INDEX_MASK); 2155fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->flags |= OCRDMA_QP_PARA_PKEY_VALID; 2156fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 2157fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (attr_mask & IB_QP_QKEY) { 2158fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->qkey = attrs->qkey; 2159fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->params.qkey = attrs->qkey; 2160fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->flags |= OCRDMA_QP_PARA_QKEY_VALID; 2161fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 2162f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala if (attr_mask & IB_QP_AV) { 2163f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala status = ocrdma_set_av_params(qp, cmd, attrs); 2164f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala if (status) 2165f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala return status; 2166f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala } else if (qp->qp_type == IB_QPT_GSI || qp->qp_type == IB_QPT_UD) { 2167fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit /* set the default mac address for UD, GSI QPs */ 2168fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->params.dmac_b0_to_b3 = qp->dev->nic_info.mac_addr[0] | 2169fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (qp->dev->nic_info.mac_addr[1] << 8) | 2170fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (qp->dev->nic_info.mac_addr[2] << 16) | 2171fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (qp->dev->nic_info.mac_addr[3] << 24); 2172fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->params.vlan_dmac_b4_to_b5 = qp->dev->nic_info.mac_addr[4] | 2173fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (qp->dev->nic_info.mac_addr[5] << 8); 2174fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 2175fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if ((attr_mask & IB_QP_EN_SQD_ASYNC_NOTIFY) && 2176fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit attrs->en_sqd_async_notify) { 2177fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->params.max_sge_recv_flags |= 2178fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_QP_PARAMS_FLAGS_SQD_ASYNC; 2179fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->flags |= OCRDMA_QP_PARA_DST_QPN_VALID; 2180fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 2181fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (attr_mask & IB_QP_DEST_QPN) { 2182fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->params.ack_to_rnr_rtc_dest_qpn |= (attrs->dest_qp_num & 2183fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_QP_PARAMS_DEST_QPN_MASK); 2184fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->flags |= OCRDMA_QP_PARA_DST_QPN_VALID; 2185fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 2186fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (attr_mask & IB_QP_PATH_MTU) { 2187d3cb6c0b2a0d9f507fff8d7c74b2b334d6751beeNaresh Gottumukkala if (attrs->path_mtu < IB_MTU_256 || 2188d3cb6c0b2a0d9f507fff8d7c74b2b334d6751beeNaresh Gottumukkala attrs->path_mtu > IB_MTU_4096) { 2189fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = -EINVAL; 2190fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto pmtu_err; 2191fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 2192fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->params.path_mtu_pkey_indx |= 2193fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (ib_mtu_enum_to_int(attrs->path_mtu) << 2194fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_QP_PARAMS_PATH_MTU_SHIFT) & 2195fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_QP_PARAMS_PATH_MTU_MASK; 2196fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->flags |= OCRDMA_QP_PARA_PMTU_VALID; 2197fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 2198fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (attr_mask & IB_QP_TIMEOUT) { 2199fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->params.ack_to_rnr_rtc_dest_qpn |= attrs->timeout << 2200fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_QP_PARAMS_ACK_TIMEOUT_SHIFT; 2201fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->flags |= OCRDMA_QP_PARA_ACK_TO_VALID; 2202fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 2203fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (attr_mask & IB_QP_RETRY_CNT) { 2204fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->params.rnt_rc_sl_fl |= (attrs->retry_cnt << 2205fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_QP_PARAMS_RETRY_CNT_SHIFT) & 2206fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_QP_PARAMS_RETRY_CNT_MASK; 2207fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->flags |= OCRDMA_QP_PARA_RETRY_CNT_VALID; 2208fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 2209fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (attr_mask & IB_QP_MIN_RNR_TIMER) { 2210fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->params.rnt_rc_sl_fl |= (attrs->min_rnr_timer << 2211fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_QP_PARAMS_RNR_NAK_TIMER_SHIFT) & 2212fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_QP_PARAMS_RNR_NAK_TIMER_MASK; 2213fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->flags |= OCRDMA_QP_PARA_RNT_VALID; 2214fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 2215fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (attr_mask & IB_QP_RNR_RETRY) { 2216fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->params.ack_to_rnr_rtc_dest_qpn |= (attrs->rnr_retry << 2217fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_QP_PARAMS_RNR_RETRY_CNT_SHIFT) 2218fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit & OCRDMA_QP_PARAMS_RNR_RETRY_CNT_MASK; 2219fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->flags |= OCRDMA_QP_PARA_RRC_VALID; 2220fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 2221fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (attr_mask & IB_QP_SQ_PSN) { 2222fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->params.tclass_sq_psn |= (attrs->sq_psn & 0x00ffffff); 2223fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->flags |= OCRDMA_QP_PARA_SQPSN_VALID; 2224fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 2225fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (attr_mask & IB_QP_RQ_PSN) { 2226fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->params.hop_lmt_rq_psn |= (attrs->rq_psn & 0x00ffffff); 2227fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->flags |= OCRDMA_QP_PARA_RQPSN_VALID; 2228fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 2229fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC) { 2230fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (attrs->max_rd_atomic > qp->dev->attr.max_ord_per_qp) { 2231fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = -EINVAL; 2232fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto pmtu_err; 2233fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 2234fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->max_ord = attrs->max_rd_atomic; 2235fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->flags |= OCRDMA_QP_PARA_MAX_ORD_VALID; 2236fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 2237fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) { 2238fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (attrs->max_dest_rd_atomic > qp->dev->attr.max_ird_per_qp) { 2239fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = -EINVAL; 2240fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto pmtu_err; 2241fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 2242fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->max_ird = attrs->max_dest_rd_atomic; 2243fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->flags |= OCRDMA_QP_PARA_MAX_IRD_VALID; 2244fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 2245fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->params.max_ord_ird = (qp->max_ord << 2246fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_QP_PARAMS_MAX_ORD_SHIFT) | 2247fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (qp->max_ird & OCRDMA_QP_PARAMS_MAX_IRD_MASK); 2248fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditpmtu_err: 2249fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 2250fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 2251fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2252fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditint ocrdma_mbx_modify_qp(struct ocrdma_dev *dev, struct ocrdma_qp *qp, 2253fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ib_qp_attr *attrs, int attr_mask, 2254fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit enum ib_qp_state old_qps) 2255fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 2256fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status = -ENOMEM; 2257fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_modify_qp *cmd; 2258fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2259fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_MODIFY_QP, sizeof(*cmd)); 2260fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!cmd) 2261fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 2262fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2263fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->params.id = qp->id; 2264fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->flags = 0; 2265fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (attr_mask & IB_QP_STATE) { 2266fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->params.max_sge_recv_flags |= 2267fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (get_ocrdma_qp_state(attrs->qp_state) << 2268fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_QP_PARAMS_STATE_SHIFT) & 2269fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_QP_PARAMS_STATE_MASK; 2270fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->flags |= OCRDMA_QP_PARA_QPS_VALID; 2271f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala } else { 2272fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->params.max_sge_recv_flags |= 2273fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (qp->state << OCRDMA_QP_PARAMS_STATE_SHIFT) & 2274fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_QP_PARAMS_STATE_MASK; 2275f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala } 2276f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala 2277fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_set_qp_params(qp, cmd, attrs, attr_mask, old_qps); 2278fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 2279fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mbx_err; 2280fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); 2281fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 2282fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mbx_err; 2283c592c42331f685b73f19ee54cfebfac0084f6e93Roland Dreier 2284fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditmbx_err: 2285fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit kfree(cmd); 2286fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 2287fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 2288fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2289fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditint ocrdma_mbx_destroy_qp(struct ocrdma_dev *dev, struct ocrdma_qp *qp) 2290fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 2291fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status = -ENOMEM; 2292fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_destroy_qp *cmd; 2293fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct pci_dev *pdev = dev->nic_info.pdev; 2294fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2295fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_DELETE_QP, sizeof(*cmd)); 2296fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!cmd) 2297fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 2298fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->qp_id = qp->id; 2299fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); 2300fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 2301fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mbx_err; 2302c592c42331f685b73f19ee54cfebfac0084f6e93Roland Dreier 2303fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditmbx_err: 2304fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit kfree(cmd); 2305fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (qp->sq.va) 2306fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dma_free_coherent(&pdev->dev, qp->sq.len, qp->sq.va, qp->sq.pa); 2307fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!qp->srq && qp->rq.va) 2308fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dma_free_coherent(&pdev->dev, qp->rq.len, qp->rq.va, qp->rq.pa); 2309fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (qp->dpp_enabled) 2310fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit qp->pd->num_dpp_qp++; 2311fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 2312fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 2313fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 23141afc0454b6658ad2d0a87e594e1f06dc19c6977dNaresh Gottumukkalaint ocrdma_mbx_create_srq(struct ocrdma_dev *dev, struct ocrdma_srq *srq, 2315fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ib_srq_init_attr *srq_attr, 2316fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_pd *pd) 2317fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 2318fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status = -ENOMEM; 2319fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int hw_pages, hw_page_size; 2320fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int len; 2321fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_create_srq_rsp *rsp; 2322fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_create_srq *cmd; 2323fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dma_addr_t pa; 2324fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct pci_dev *pdev = dev->nic_info.pdev; 2325fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit u32 max_rqe_allocated; 2326fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2327fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_CREATE_SRQ, sizeof(*cmd)); 2328fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!cmd) 2329fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 2330fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2331fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->pgsz_pdid = pd->id & OCRDMA_CREATE_SRQ_PD_ID_MASK; 2332fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit max_rqe_allocated = srq_attr->attr.max_wr + 1; 2333fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_build_q_conf(&max_rqe_allocated, 2334fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev->attr.rqe_size, 2335fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit &hw_pages, &hw_page_size); 2336fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) { 2337ef99c4c2ed63cb0deb94ea70fb47c2d6294e302eNaresh Gottumukkala pr_err("%s() req. max_wr=0x%x\n", __func__, 2338ef99c4c2ed63cb0deb94ea70fb47c2d6294e302eNaresh Gottumukkala srq_attr->attr.max_wr); 2339fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = -EINVAL; 2340fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto ret; 2341fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 2342fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit len = hw_pages * hw_page_size; 2343fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit srq->rq.va = dma_alloc_coherent(&pdev->dev, len, &pa, GFP_KERNEL); 2344fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!srq->rq.va) { 2345fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = -ENOMEM; 2346fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto ret; 2347fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 2348fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_build_q_pages(&cmd->rq_addr[0], hw_pages, pa, hw_page_size); 2349fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2350fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit srq->rq.entry_size = dev->attr.rqe_size; 2351fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit srq->rq.pa = pa; 2352fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit srq->rq.len = len; 2353fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit srq->rq.max_cnt = max_rqe_allocated; 2354fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2355fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->max_sge_rqe = ilog2(max_rqe_allocated); 2356fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->max_sge_rqe |= srq_attr->attr.max_sge << 2357fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_SRQ_MAX_SGE_RECV_SHIFT; 2358fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2359fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->pgsz_pdid |= (ilog2(hw_page_size / OCRDMA_MIN_Q_PAGE_SIZE) 2360fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit << OCRDMA_CREATE_SRQ_PG_SZ_SHIFT); 2361fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->pages_rqe_sz |= (dev->attr.rqe_size 2362fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit << OCRDMA_CREATE_SRQ_RQE_SIZE_SHIFT) 2363fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit & OCRDMA_CREATE_SRQ_RQE_SIZE_MASK; 2364fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->pages_rqe_sz |= hw_pages << OCRDMA_CREATE_SRQ_NUM_RQ_PAGES_SHIFT; 2365fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2366fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); 2367fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 2368fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mbx_err; 2369fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit rsp = (struct ocrdma_create_srq_rsp *)cmd; 2370fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit srq->id = rsp->id; 2371fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit srq->rq.dbid = rsp->id; 2372fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit max_rqe_allocated = ((rsp->max_sge_rqe_allocated & 2373fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_SRQ_RSP_MAX_RQE_ALLOCATED_MASK) >> 2374fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_SRQ_RSP_MAX_RQE_ALLOCATED_SHIFT); 2375fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit max_rqe_allocated = (1 << max_rqe_allocated); 2376fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit srq->rq.max_cnt = max_rqe_allocated; 2377fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit srq->rq.max_wqe_idx = max_rqe_allocated - 1; 2378fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit srq->rq.max_sges = (rsp->max_sge_rqe_allocated & 2379fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_SRQ_RSP_MAX_SGE_RECV_ALLOCATED_MASK) >> 2380fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_CREATE_SRQ_RSP_MAX_SGE_RECV_ALLOCATED_SHIFT; 2381fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto ret; 2382fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditmbx_err: 2383fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dma_free_coherent(&pdev->dev, srq->rq.len, srq->rq.va, pa); 2384fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditret: 2385fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit kfree(cmd); 2386fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 2387fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 2388fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2389fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditint ocrdma_mbx_modify_srq(struct ocrdma_srq *srq, struct ib_srq_attr *srq_attr) 2390fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 2391fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status = -ENOMEM; 2392fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_modify_srq *cmd; 2393f11220ee69f72cf08479f28fd494264ac6a9349bNaresh Gottumukkala struct ocrdma_pd *pd = srq->pd; 2394f11220ee69f72cf08479f28fd494264ac6a9349bNaresh Gottumukkala struct ocrdma_dev *dev = get_ocrdma_dev(pd->ibpd.device); 23951afc0454b6658ad2d0a87e594e1f06dc19c6977dNaresh Gottumukkala 2396d7e19c0ad9baa0cfe7ef8b69a182a7db1dee6b52Naresh Gottumukkala cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_MODIFY_SRQ, sizeof(*cmd)); 2397fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!cmd) 2398fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 2399fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->id = srq->id; 2400fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->limit_max_rqe |= srq_attr->srq_limit << 2401fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_MODIFY_SRQ_LIMIT_SHIFT; 24021afc0454b6658ad2d0a87e594e1f06dc19c6977dNaresh Gottumukkala status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); 2403fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit kfree(cmd); 2404fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 2405fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 2406fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2407fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditint ocrdma_mbx_query_srq(struct ocrdma_srq *srq, struct ib_srq_attr *srq_attr) 2408fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 2409fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status = -ENOMEM; 2410fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_query_srq *cmd; 24111afc0454b6658ad2d0a87e594e1f06dc19c6977dNaresh Gottumukkala struct ocrdma_dev *dev = get_ocrdma_dev(srq->ibsrq.device); 24121afc0454b6658ad2d0a87e594e1f06dc19c6977dNaresh Gottumukkala 2413d7e19c0ad9baa0cfe7ef8b69a182a7db1dee6b52Naresh Gottumukkala cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_QUERY_SRQ, sizeof(*cmd)); 2414fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!cmd) 2415fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 2416fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->id = srq->rq.dbid; 24171afc0454b6658ad2d0a87e594e1f06dc19c6977dNaresh Gottumukkala status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); 2418fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status == 0) { 2419fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_query_srq_rsp *rsp = 2420fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit (struct ocrdma_query_srq_rsp *)cmd; 2421fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit srq_attr->max_sge = 2422fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit rsp->srq_lmt_max_sge & 2423fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_QUERY_SRQ_RSP_MAX_SGE_RECV_MASK; 2424fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit srq_attr->max_wr = 2425fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit rsp->max_rqe_pdid >> OCRDMA_QUERY_SRQ_RSP_MAX_RQE_SHIFT; 2426fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit srq_attr->srq_limit = rsp->srq_lmt_max_sge >> 2427fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_QUERY_SRQ_RSP_SRQ_LIMIT_SHIFT; 2428fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 2429fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit kfree(cmd); 2430fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 2431fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 2432fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2433fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditint ocrdma_mbx_destroy_srq(struct ocrdma_dev *dev, struct ocrdma_srq *srq) 2434fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 2435fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status = -ENOMEM; 2436fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_destroy_srq *cmd; 2437fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct pci_dev *pdev = dev->nic_info.pdev; 2438fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_DELETE_SRQ, sizeof(*cmd)); 2439fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (!cmd) 2440fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 2441fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit cmd->id = srq->id; 24421afc0454b6658ad2d0a87e594e1f06dc19c6977dNaresh Gottumukkala status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd); 2443fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (srq->rq.va) 2444fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dma_free_coherent(&pdev->dev, srq->rq.len, 2445fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit srq->rq.va, srq->rq.pa); 2446fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit kfree(cmd); 2447fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 2448fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 2449fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2450fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditint ocrdma_alloc_av(struct ocrdma_dev *dev, struct ocrdma_ah *ah) 2451fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 2452fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int i; 2453fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status = -EINVAL; 2454fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit struct ocrdma_av *av; 2455fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit unsigned long flags; 2456fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2457fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit av = dev->av_tbl.va; 2458fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit spin_lock_irqsave(&dev->av_tbl.lock, flags); 2459fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit for (i = 0; i < dev->av_tbl.num_ah; i++) { 2460fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (av->valid == 0) { 2461fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit av->valid = OCRDMA_AV_VALID; 2462fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ah->av = av; 2463fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ah->id = i; 2464fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = 0; 2465fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 2466fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 2467fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit av++; 2468fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 2469fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (i == dev->av_tbl.num_ah) 2470fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = -EAGAIN; 2471fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit spin_unlock_irqrestore(&dev->av_tbl.lock, flags); 2472fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 2473fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 2474fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2475fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditint ocrdma_free_av(struct ocrdma_dev *dev, struct ocrdma_ah *ah) 2476fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 2477fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit unsigned long flags; 2478fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit spin_lock_irqsave(&dev->av_tbl.lock, flags); 2479fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ah->av->valid = 0; 2480fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit spin_unlock_irqrestore(&dev->av_tbl.lock, flags); 2481fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return 0; 2482fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 2483fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2484c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkalastatic int ocrdma_create_eqs(struct ocrdma_dev *dev) 2485fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 2486da4964387d997244b043dd812540bed851c45c9eRoland Dreier int num_eq, i, status = 0; 2487fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int irq; 2488fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit unsigned long flags = 0; 2489fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2490fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit num_eq = dev->nic_info.msix.num_vectors - 2491fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev->nic_info.msix.start_vector; 2492fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (dev->nic_info.intr_mode == BE_INTERRUPT_MODE_INTX) { 2493fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit num_eq = 1; 2494fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit flags = IRQF_SHARED; 2495f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala } else { 2496fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit num_eq = min_t(u32, num_eq, num_online_cpus()); 2497f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala } 2498f99b1649dbb6342d618307faef1f214fd54928b9Naresh Gottumukkala 2499c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala if (!num_eq) 2500c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala return -EINVAL; 2501c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala 2502c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala dev->eq_tbl = kzalloc(sizeof(struct ocrdma_eq) * num_eq, GFP_KERNEL); 2503c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala if (!dev->eq_tbl) 2504fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return -ENOMEM; 2505fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2506fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit for (i = 0; i < num_eq; i++) { 2507c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala status = ocrdma_create_eq(dev, &dev->eq_tbl[i], 2508fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit OCRDMA_EQ_LEN); 2509fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) { 2510fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = -EINVAL; 2511fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit break; 2512fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 2513c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala sprintf(dev->eq_tbl[i].irq_name, "ocrdma%d-%d", 2514fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev->id, i); 2515c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala irq = ocrdma_get_irq(dev, &dev->eq_tbl[i]); 2516fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = request_irq(irq, ocrdma_irq_handler, flags, 2517c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala dev->eq_tbl[i].irq_name, 2518c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala &dev->eq_tbl[i]); 2519c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala if (status) 2520c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala goto done; 2521fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit dev->eq_cnt += 1; 2522fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit } 2523fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit /* one eq is sufficient for data path to work */ 2524c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala return 0; 2525c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkaladone: 2526c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala ocrdma_destroy_eqs(dev); 2527fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 2528fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 2529fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2530fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditint ocrdma_init_hw(struct ocrdma_dev *dev) 2531fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 2532fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit int status; 2533c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala 2534c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala /* create the eqs */ 2535c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala status = ocrdma_create_eqs(dev); 2536fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 2537fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto qpeq_err; 2538fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_create_mq(dev); 2539fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 2540fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto mq_err; 2541fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_mbx_query_fw_config(dev); 2542fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 2543fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto conf_err; 2544fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_mbx_query_dev(dev); 2545fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 2546fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto conf_err; 2547fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_mbx_query_fw_ver(dev); 2548fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 2549fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto conf_err; 2550fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit status = ocrdma_mbx_create_ah_tbl(dev); 2551fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit if (status) 2552fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit goto conf_err; 2553fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return 0; 2554fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2555fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditconf_err: 2556fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_destroy_mq(dev); 2557fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditmq_err: 2558c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala ocrdma_destroy_eqs(dev); 2559fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditqpeq_err: 2560ef99c4c2ed63cb0deb94ea70fb47c2d6294e302eNaresh Gottumukkala pr_err("%s() status=%d\n", __func__, status); 2561fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit return status; 2562fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 2563fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2564fe2caefcdf5869f308c102e3d64d40683bfad711Parav Panditvoid ocrdma_cleanup_hw(struct ocrdma_dev *dev) 2565fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit{ 2566fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_mbx_delete_ah_tbl(dev); 2567fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2568c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala /* cleanup the eqs */ 2569c88bd03ffccdb069fd9541bea347bdab8f4e7e6aNaresh Gottumukkala ocrdma_destroy_eqs(dev); 2570fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit 2571fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit /* cleanup the control path */ 2572fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit ocrdma_destroy_mq(dev); 2573fe2caefcdf5869f308c102e3d64d40683bfad711Parav Pandit} 2574