Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * This file is part of the Chelsio T6 Ethernet driver for Linux.
0003  *
0004  * Copyright (c) 2017-2018 Chelsio Communications, Inc. All rights reserved.
0005  *
0006  * This software is available to you under a choice of one of two
0007  * licenses.  You may choose to be licensed under the terms of the GNU
0008  * General Public License (GPL) Version 2, available from the file
0009  * COPYING in the main directory of this source tree, or the
0010  * OpenIB.org BSD license below:
0011  *
0012  *     Redistribution and use in source and binary forms, with or
0013  *     without modification, are permitted provided that the following
0014  *     conditions are met:
0015  *
0016  *      - Redistributions of source code must retain the above
0017  *        copyright notice, this list of conditions and the following
0018  *        disclaimer.
0019  *
0020  *      - Redistributions in binary form must reproduce the above
0021  *        copyright notice, this list of conditions and the following
0022  *        disclaimer in the documentation and/or other materials
0023  *        provided with the distribution.
0024  *
0025  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
0026  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
0027  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
0028  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
0029  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
0030  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
0031  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
0032  * SOFTWARE.
0033  */
0034 
0035 #include "cxgb4.h"
0036 #include "t4_msg.h"
0037 #include "srq.h"
0038 
0039 struct srq_data *t4_init_srq(int srq_size)
0040 {
0041     struct srq_data *s;
0042 
0043     s = kvzalloc(sizeof(*s), GFP_KERNEL);
0044     if (!s)
0045         return NULL;
0046 
0047     s->srq_size = srq_size;
0048     init_completion(&s->comp);
0049     mutex_init(&s->lock);
0050 
0051     return s;
0052 }
0053 
0054 /* cxgb4_get_srq_entry: read the SRQ table entry
0055  * @dev: Pointer to the net_device
0056  * @idx: Index to the srq
0057  * @entryp: pointer to the srq entry
0058  *
0059  * Sends CPL_SRQ_TABLE_REQ message for the given index.
0060  * Contents will be returned in CPL_SRQ_TABLE_RPL message.
0061  *
0062  * Returns zero if the read is successful, else a error
0063  * number will be returned. Caller should not use the srq
0064  * entry if the return value is non-zero.
0065  *
0066  *
0067  */
0068 int cxgb4_get_srq_entry(struct net_device *dev,
0069             int srq_idx, struct srq_entry *entryp)
0070 {
0071     struct cpl_srq_table_req *req;
0072     struct adapter *adap;
0073     struct sk_buff *skb;
0074     struct srq_data *s;
0075     int rc = -ENODEV;
0076 
0077     adap = netdev2adap(dev);
0078     s = adap->srq;
0079 
0080     if (!(adap->flags & CXGB4_FULL_INIT_DONE) || !s)
0081         goto out;
0082 
0083     skb = alloc_skb(sizeof(*req), GFP_KERNEL);
0084     if (!skb)
0085         return -ENOMEM;
0086     req = (struct cpl_srq_table_req *)
0087         __skb_put_zero(skb, sizeof(*req));
0088     INIT_TP_WR(req, 0);
0089     OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SRQ_TABLE_REQ,
0090                           TID_TID_V(srq_idx) |
0091                 TID_QID_V(adap->sge.fw_evtq.abs_id)));
0092     req->idx = srq_idx;
0093 
0094     mutex_lock(&s->lock);
0095 
0096     s->entryp = entryp;
0097     t4_mgmt_tx(adap, skb);
0098 
0099     rc = wait_for_completion_timeout(&s->comp, SRQ_WAIT_TO);
0100     if (rc)
0101         rc = 0;
0102     else /* !rc means we timed out */
0103         rc = -ETIMEDOUT;
0104 
0105     WARN_ON_ONCE(entryp->idx != srq_idx);
0106     mutex_unlock(&s->lock);
0107 out:
0108     return rc;
0109 }
0110 EXPORT_SYMBOL(cxgb4_get_srq_entry);
0111 
0112 void do_srq_table_rpl(struct adapter *adap,
0113               const struct cpl_srq_table_rpl *rpl)
0114 {
0115     unsigned int idx = TID_TID_G(GET_TID(rpl));
0116     struct srq_data *s = adap->srq;
0117     struct srq_entry *e;
0118 
0119     if (unlikely(rpl->status != CPL_CONTAINS_READ_RPL)) {
0120         dev_err(adap->pdev_dev,
0121             "Unexpected SRQ_TABLE_RPL status %u for entry %u\n",
0122                 rpl->status, idx);
0123         goto out;
0124     }
0125 
0126     /* Store the read entry */
0127     e = s->entryp;
0128     e->valid = 1;
0129     e->idx = idx;
0130     e->pdid = SRQT_PDID_G(be64_to_cpu(rpl->rsvd_pdid));
0131     e->qlen = SRQT_QLEN_G(be32_to_cpu(rpl->qlen_qbase));
0132     e->qbase = SRQT_QBASE_G(be32_to_cpu(rpl->qlen_qbase));
0133     e->cur_msn = be16_to_cpu(rpl->cur_msn);
0134     e->max_msn = be16_to_cpu(rpl->max_msn);
0135 out:
0136     complete(&s->comp);
0137 }