1278886Shselasky/* 2278886Shselasky * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved. 3278886Shselasky * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved. 4278886Shselasky * 5278886Shselasky * This software is available to you under a choice of one of two 6278886Shselasky * licenses. You may choose to be licensed under the terms of the GNU 7278886Shselasky * General Public License (GPL) Version 2, available from the file 8278886Shselasky * COPYING in the main directory of this source tree, or the 9278886Shselasky * OpenIB.org BSD license below: 10278886Shselasky * 11278886Shselasky * Redistribution and use in source and binary forms, with or 12278886Shselasky * without modification, are permitted provided that the following 13278886Shselasky * conditions are met: 14278886Shselasky * 15278886Shselasky * - Redistributions of source code must retain the above 16278886Shselasky * copyright notice, this list of conditions and the following 17278886Shselasky * disclaimer. 18278886Shselasky * 19278886Shselasky * - Redistributions in binary form must reproduce the above 20278886Shselasky * copyright notice, this list of conditions and the following 21278886Shselasky * disclaimer in the documentation and/or other materials 22278886Shselasky * provided with the distribution. 23278886Shselasky * 24278886Shselasky * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25278886Shselasky * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26278886Shselasky * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27278886Shselasky * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 28278886Shselasky * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 29278886Shselasky * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 30278886Shselasky * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31278886Shselasky * SOFTWARE. 32278886Shselasky */ 33278886Shselasky 34278886Shselasky#include "mlx4_ib.h" 35278886Shselasky#include "mlx4_exp.h" 36278886Shselasky#include <linux/mlx4/qp.h> 37278886Shselasky 38278886Shselaskyint mlx4_ib_exp_query_device(struct ib_device *ibdev, 39278886Shselasky struct ib_exp_device_attr *props) 40278886Shselasky{ 41278886Shselasky struct ib_device_attr *base = &props->base; 42278886Shselasky struct mlx4_ib_dev *dev = to_mdev(ibdev); 43278886Shselasky int ret = mlx4_ib_query_device(ibdev, &props->base); 44278886Shselasky 45278886Shselasky props->exp_comp_mask = IB_EXP_DEVICE_ATTR_INLINE_RECV_SZ; 46278886Shselasky props->inline_recv_sz = dev->dev->caps.max_rq_sg * sizeof(struct mlx4_wqe_data_seg); 47278886Shselasky props->device_cap_flags2 = 0; 48278886Shselasky 49278886Shselasky /* move RSS device cap from device_cap to device_cap_flags2 */ 50278886Shselasky if (base->device_cap_flags & IB_DEVICE_QPG) { 51278886Shselasky props->device_cap_flags2 |= IB_EXP_DEVICE_QPG; 52278886Shselasky if (base->device_cap_flags & IB_DEVICE_UD_RSS) 53278886Shselasky props->device_cap_flags2 |= IB_EXP_DEVICE_UD_RSS; 54278886Shselasky } 55278886Shselasky base->device_cap_flags &= ~(IB_DEVICE_QPG | 56278886Shselasky IB_DEVICE_UD_RSS | 57278886Shselasky IB_DEVICE_UD_TSS); 58278886Shselasky 59278886Shselasky if (base->max_rss_tbl_sz > 0) { 60278886Shselasky props->max_rss_tbl_sz = base->max_rss_tbl_sz; 61278886Shselasky props->exp_comp_mask |= IB_EXP_DEVICE_ATTR_RSS_TBL_SZ; 62278886Shselasky } else { 63278886Shselasky props->max_rss_tbl_sz = 0; 64278886Shselasky props->exp_comp_mask &= ~IB_EXP_DEVICE_ATTR_RSS_TBL_SZ; 65278886Shselasky } 66278886Shselasky 67278886Shselasky if (props->device_cap_flags2) 68278886Shselasky props->exp_comp_mask |= IB_EXP_DEVICE_ATTR_CAP_FLAGS2; 69278886Shselasky 70278886Shselasky return ret; 71278886Shselasky} 72278886Shselasky 73278886Shselasky/* 74278886Shselasky * Experimental functions 75278886Shselasky */ 76278886Shselaskystruct ib_qp *mlx4_ib_exp_create_qp(struct ib_pd *pd, 77278886Shselasky struct ib_exp_qp_init_attr *init_attr, 78278886Shselasky struct ib_udata *udata) 79278886Shselasky{ 80278886Shselasky int rwqe_size; 81278886Shselasky struct ib_qp *qp; 82278886Shselasky struct mlx4_ib_qp *mqp; 83278886Shselasky int use_inlr; 84278886Shselasky struct mlx4_ib_dev *dev; 85278886Shselasky 86278886Shselasky if (init_attr->max_inl_recv && !udata) 87278886Shselasky return ERR_PTR(-EINVAL); 88278886Shselasky 89278886Shselasky use_inlr = mlx4_ib_qp_has_rq((struct ib_qp_init_attr *)init_attr) && 90278886Shselasky init_attr->max_inl_recv && pd; 91278886Shselasky if (use_inlr) { 92278886Shselasky rwqe_size = roundup_pow_of_two(max(1U, init_attr->cap.max_recv_sge)) * 93278886Shselasky sizeof(struct mlx4_wqe_data_seg); 94278886Shselasky if (rwqe_size < init_attr->max_inl_recv) { 95278886Shselasky dev = to_mdev(pd->device); 96278886Shselasky init_attr->max_inl_recv = min(init_attr->max_inl_recv, 97278886Shselasky (u32)(dev->dev->caps.max_rq_sg * 98278886Shselasky sizeof(struct mlx4_wqe_data_seg))); 99278886Shselasky init_attr->cap.max_recv_sge = roundup_pow_of_two(init_attr->max_inl_recv) / 100278886Shselasky sizeof(struct mlx4_wqe_data_seg); 101278886Shselasky } 102278886Shselasky } else { 103278886Shselasky init_attr->max_inl_recv = 0; 104278886Shselasky } 105278886Shselasky qp = mlx4_ib_create_qp(pd, (struct ib_qp_init_attr *)init_attr, udata); 106278886Shselasky if (IS_ERR(qp)) 107278886Shselasky return qp; 108278886Shselasky 109278886Shselasky if (use_inlr) { 110278886Shselasky mqp = to_mqp(qp); 111278886Shselasky mqp->max_inlr_data = 1 << mqp->rq.wqe_shift; 112278886Shselasky init_attr->max_inl_recv = mqp->max_inlr_data; 113278886Shselasky } 114278886Shselasky 115278886Shselasky return qp; 116278886Shselasky} 117