1e4709475SRaju Rangoju /* 2e4709475SRaju Rangoju * This file is part of the Chelsio T6 Ethernet driver for Linux. 3e4709475SRaju Rangoju * 4e4709475SRaju Rangoju * Copyright (c) 2017-2018 Chelsio Communications, Inc. All rights reserved. 5e4709475SRaju Rangoju * 6e4709475SRaju Rangoju * This software is available to you under a choice of one of two 7e4709475SRaju Rangoju * licenses. You may choose to be licensed under the terms of the GNU 8e4709475SRaju Rangoju * General Public License (GPL) Version 2, available from the file 9e4709475SRaju Rangoju * COPYING in the main directory of this source tree, or the 10e4709475SRaju Rangoju * OpenIB.org BSD license below: 11e4709475SRaju Rangoju * 12e4709475SRaju Rangoju * Redistribution and use in source and binary forms, with or 13e4709475SRaju Rangoju * without modification, are permitted provided that the following 14e4709475SRaju Rangoju * conditions are met: 15e4709475SRaju Rangoju * 16e4709475SRaju Rangoju * - Redistributions of source code must retain the above 17e4709475SRaju Rangoju * copyright notice, this list of conditions and the following 18e4709475SRaju Rangoju * disclaimer. 19e4709475SRaju Rangoju * 20e4709475SRaju Rangoju * - Redistributions in binary form must reproduce the above 21e4709475SRaju Rangoju * copyright notice, this list of conditions and the following 22e4709475SRaju Rangoju * disclaimer in the documentation and/or other materials 23e4709475SRaju Rangoju * provided with the distribution. 24e4709475SRaju Rangoju * 25e4709475SRaju Rangoju * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26e4709475SRaju Rangoju * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27e4709475SRaju Rangoju * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28e4709475SRaju Rangoju * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29e4709475SRaju Rangoju * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30e4709475SRaju Rangoju * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31e4709475SRaju Rangoju * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32e4709475SRaju Rangoju * SOFTWARE. 33e4709475SRaju Rangoju */ 34e4709475SRaju Rangoju 35e4709475SRaju Rangoju #include "cxgb4.h" 36e4709475SRaju Rangoju #include "t4_msg.h" 37e4709475SRaju Rangoju #include "srq.h" 38e4709475SRaju Rangoju 39e4709475SRaju Rangoju struct srq_data *t4_init_srq(int srq_size) 40e4709475SRaju Rangoju { 41e4709475SRaju Rangoju struct srq_data *s; 42e4709475SRaju Rangoju 43e4709475SRaju Rangoju s = kvzalloc(sizeof(*s), GFP_KERNEL); 44e4709475SRaju Rangoju if (!s) 45e4709475SRaju Rangoju return NULL; 46e4709475SRaju Rangoju 47e4709475SRaju Rangoju s->srq_size = srq_size; 48e4709475SRaju Rangoju init_completion(&s->comp); 49e4709475SRaju Rangoju mutex_init(&s->lock); 50e4709475SRaju Rangoju 51e4709475SRaju Rangoju return s; 52e4709475SRaju Rangoju } 53e4709475SRaju Rangoju 54e4709475SRaju Rangoju /* cxgb4_get_srq_entry: read the SRQ table entry 55e4709475SRaju Rangoju * @dev: Pointer to the net_device 56e4709475SRaju Rangoju * @idx: Index to the srq 57e4709475SRaju Rangoju * @entryp: pointer to the srq entry 58e4709475SRaju Rangoju * 59e4709475SRaju Rangoju * Sends CPL_SRQ_TABLE_REQ message for the given index. 60e4709475SRaju Rangoju * Contents will be returned in CPL_SRQ_TABLE_RPL message. 61e4709475SRaju Rangoju * 62e4709475SRaju Rangoju * Returns zero if the read is successful, else a error 63e4709475SRaju Rangoju * number will be returned. Caller should not use the srq 64e4709475SRaju Rangoju * entry if the return value is non-zero. 65e4709475SRaju Rangoju * 66e4709475SRaju Rangoju * 67e4709475SRaju Rangoju */ 68e4709475SRaju Rangoju int cxgb4_get_srq_entry(struct net_device *dev, 69e4709475SRaju Rangoju int srq_idx, struct srq_entry *entryp) 70e4709475SRaju Rangoju { 71e4709475SRaju Rangoju struct cpl_srq_table_req *req; 72e4709475SRaju Rangoju struct adapter *adap; 73e4709475SRaju Rangoju struct sk_buff *skb; 74e4709475SRaju Rangoju struct srq_data *s; 75e4709475SRaju Rangoju int rc = -ENODEV; 76e4709475SRaju Rangoju 77e4709475SRaju Rangoju adap = netdev2adap(dev); 78e4709475SRaju Rangoju s = adap->srq; 79e4709475SRaju Rangoju 80e4709475SRaju Rangoju if (!(adap->flags & FULL_INIT_DONE) || !s) 81e4709475SRaju Rangoju goto out; 82e4709475SRaju Rangoju 83e4709475SRaju Rangoju skb = alloc_skb(sizeof(*req), GFP_KERNEL); 84e4709475SRaju Rangoju if (!skb) 85e4709475SRaju Rangoju return -ENOMEM; 86e4709475SRaju Rangoju req = (struct cpl_srq_table_req *) 87a6a188e4SYueHaibing __skb_put_zero(skb, sizeof(*req)); 88e4709475SRaju Rangoju INIT_TP_WR(req, 0); 89e4709475SRaju Rangoju OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SRQ_TABLE_REQ, 90e4709475SRaju Rangoju TID_TID_V(srq_idx) | 91e4709475SRaju Rangoju TID_QID_V(adap->sge.fw_evtq.abs_id))); 92e4709475SRaju Rangoju req->idx = srq_idx; 93e4709475SRaju Rangoju 94e4709475SRaju Rangoju mutex_lock(&s->lock); 95e4709475SRaju Rangoju 96e4709475SRaju Rangoju s->entryp = entryp; 97e4709475SRaju Rangoju t4_mgmt_tx(adap, skb); 98e4709475SRaju Rangoju 99e4709475SRaju Rangoju rc = wait_for_completion_timeout(&s->comp, SRQ_WAIT_TO); 100e4709475SRaju Rangoju if (rc) 101e4709475SRaju Rangoju rc = 0; 102e4709475SRaju Rangoju else /* !rc means we timed out */ 103e4709475SRaju Rangoju rc = -ETIMEDOUT; 104e4709475SRaju Rangoju 105e4709475SRaju Rangoju WARN_ON_ONCE(entryp->idx != srq_idx); 106e4709475SRaju Rangoju mutex_unlock(&s->lock); 107e4709475SRaju Rangoju out: 108e4709475SRaju Rangoju return rc; 109e4709475SRaju Rangoju } 110e4709475SRaju Rangoju EXPORT_SYMBOL(cxgb4_get_srq_entry); 111e4709475SRaju Rangoju 112e4709475SRaju Rangoju void do_srq_table_rpl(struct adapter *adap, 113e4709475SRaju Rangoju const struct cpl_srq_table_rpl *rpl) 114e4709475SRaju Rangoju { 115e4709475SRaju Rangoju unsigned int idx = TID_TID_G(GET_TID(rpl)); 116e4709475SRaju Rangoju struct srq_data *s = adap->srq; 117e4709475SRaju Rangoju struct srq_entry *e; 118e4709475SRaju Rangoju 119e4709475SRaju Rangoju if (unlikely(rpl->status != CPL_CONTAINS_READ_RPL)) { 120e4709475SRaju Rangoju dev_err(adap->pdev_dev, 121e4709475SRaju Rangoju "Unexpected SRQ_TABLE_RPL status %u for entry %u\n", 122e4709475SRaju Rangoju rpl->status, idx); 123e4709475SRaju Rangoju goto out; 124e4709475SRaju Rangoju } 125e4709475SRaju Rangoju 126e4709475SRaju Rangoju /* Store the read entry */ 127e4709475SRaju Rangoju e = s->entryp; 128e4709475SRaju Rangoju e->valid = 1; 129e4709475SRaju Rangoju e->idx = idx; 130e4709475SRaju Rangoju e->pdid = SRQT_PDID_G(be64_to_cpu(rpl->rsvd_pdid)); 131e4709475SRaju Rangoju e->qlen = SRQT_QLEN_G(be32_to_cpu(rpl->qlen_qbase)); 132e4709475SRaju Rangoju e->qbase = SRQT_QBASE_G(be32_to_cpu(rpl->qlen_qbase)); 133e4709475SRaju Rangoju e->cur_msn = be16_to_cpu(rpl->cur_msn); 134e4709475SRaju Rangoju e->max_msn = be16_to_cpu(rpl->max_msn); 135e4709475SRaju Rangoju out: 136e4709475SRaju Rangoju complete(&s->comp); 137e4709475SRaju Rangoju } 138