Linux Audio

Check our new training course

Loading...
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
  2/*
  3 * Copyright(c) 2016 - 2019 Intel Corporation.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  4 */
  5
  6#include <linux/slab.h>
  7#include "ah.h"
  8#include "vt.h" /* for prints */
  9
 10/**
 11 * rvt_check_ah - validate the attributes of AH
 12 * @ibdev: the ib device
 13 * @ah_attr: the attributes of the AH
 14 *
 15 * If driver supports a more detailed check_ah function call back to it
 16 * otherwise just check the basics.
 17 *
 18 * Return: 0 on success
 19 */
 20int rvt_check_ah(struct ib_device *ibdev,
 21		 struct rdma_ah_attr *ah_attr)
 22{
 23	int err;
 24	int port_num = rdma_ah_get_port_num(ah_attr);
 25	struct ib_port_attr port_attr;
 26	struct rvt_dev_info *rdi = ib_to_rvt(ibdev);
 27	u8 ah_flags = rdma_ah_get_ah_flags(ah_attr);
 28	u8 static_rate = rdma_ah_get_static_rate(ah_attr);
 29
 30	err = ib_query_port(ibdev, port_num, &port_attr);
 31	if (err)
 32		return -EINVAL;
 33	if (port_num < 1 ||
 34	    port_num > ibdev->phys_port_cnt)
 35		return -EINVAL;
 36	if (static_rate != IB_RATE_PORT_CURRENT &&
 37	    ib_rate_to_mbps(static_rate) < 0)
 38		return -EINVAL;
 39	if ((ah_flags & IB_AH_GRH) &&
 40	    rdma_ah_read_grh(ah_attr)->sgid_index >= port_attr.gid_tbl_len)
 41		return -EINVAL;
 
 
 
 
 
 
 
 
 42	if (rdi->driver_f.check_ah)
 43		return rdi->driver_f.check_ah(ibdev, ah_attr);
 44	return 0;
 45}
 46EXPORT_SYMBOL(rvt_check_ah);
 47
 48/**
 49 * rvt_create_ah - create an address handle
 50 * @ibah: the IB address handle
 51 * @init_attr: the attributes of the AH
 52 * @udata: pointer to user's input output buffer information.
 53 *
 54 * This may be called from interrupt context.
 55 *
 56 * Return: 0 on success
 57 */
 58int rvt_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr,
 59		  struct ib_udata *udata)
 60{
 61	struct rvt_ah *ah = ibah_to_rvtah(ibah);
 62	struct rvt_dev_info *dev = ib_to_rvt(ibah->device);
 63	unsigned long flags;
 64
 65	if (rvt_check_ah(ibah->device, init_attr->ah_attr))
 66		return -EINVAL;
 
 
 
 
 67
 68	spin_lock_irqsave(&dev->n_ahs_lock, flags);
 69	if (dev->n_ahs_allocated == dev->dparms.props.max_ah) {
 70		spin_unlock_irqrestore(&dev->n_ahs_lock, flags);
 71		return -ENOMEM;
 
 72	}
 73
 74	dev->n_ahs_allocated++;
 75	spin_unlock_irqrestore(&dev->n_ahs_lock, flags);
 76
 77	rdma_copy_ah_attr(&ah->attr, init_attr->ah_attr);
 
 78
 79	if (dev->driver_f.notify_new_ah)
 80		dev->driver_f.notify_new_ah(ibah->device,
 81					    init_attr->ah_attr, ah);
 82
 83	return 0;
 84}
 85
 86/**
 87 * rvt_destroy_ah - Destroy an address handle
 88 * @ibah: address handle
 89 * @destroy_flags: destroy address handle flags (see enum rdma_destroy_ah_flags)
 90 * Return: 0 on success
 91 */
 92int rvt_destroy_ah(struct ib_ah *ibah, u32 destroy_flags)
 93{
 94	struct rvt_dev_info *dev = ib_to_rvt(ibah->device);
 95	struct rvt_ah *ah = ibah_to_rvtah(ibah);
 96	unsigned long flags;
 97
 
 
 
 98	spin_lock_irqsave(&dev->n_ahs_lock, flags);
 99	dev->n_ahs_allocated--;
100	spin_unlock_irqrestore(&dev->n_ahs_lock, flags);
101
102	rdma_destroy_ah_attr(&ah->attr);
 
103	return 0;
104}
105
106/**
107 * rvt_modify_ah - modify an ah with given attrs
108 * @ibah: address handle to modify
109 * @ah_attr: attrs to apply
110 *
111 * Return: 0 on success
112 */
113int rvt_modify_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr)
114{
115	struct rvt_ah *ah = ibah_to_rvtah(ibah);
116
117	if (rvt_check_ah(ibah->device, ah_attr))
118		return -EINVAL;
119
120	ah->attr = *ah_attr;
121
122	return 0;
123}
124
125/**
126 * rvt_query_ah - return attrs for ah
127 * @ibah: address handle to query
128 * @ah_attr: return info in this
129 *
130 * Return: always 0
131 */
132int rvt_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr)
133{
134	struct rvt_ah *ah = ibah_to_rvtah(ibah);
135
136	*ah_attr = ah->attr;
137
138	return 0;
139}
v4.10.11
 
  1/*
  2 * Copyright(c) 2016 Intel Corporation.
  3 *
  4 * This file is provided under a dual BSD/GPLv2 license.  When using or
  5 * redistributing this file, you may do so under either license.
  6 *
  7 * GPL LICENSE SUMMARY
  8 *
  9 * This program is free software; you can redistribute it and/or modify
 10 * it under the terms of version 2 of the GNU General Public License as
 11 * published by the Free Software Foundation.
 12 *
 13 * This program is distributed in the hope that it will be useful, but
 14 * WITHOUT ANY WARRANTY; without even the implied warranty of
 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 16 * General Public License for more details.
 17 *
 18 * BSD LICENSE
 19 *
 20 * Redistribution and use in source and binary forms, with or without
 21 * modification, are permitted provided that the following conditions
 22 * are met:
 23 *
 24 *  - Redistributions of source code must retain the above copyright
 25 *    notice, this list of conditions and the following disclaimer.
 26 *  - Redistributions in binary form must reproduce the above copyright
 27 *    notice, this list of conditions and the following disclaimer in
 28 *    the documentation and/or other materials provided with the
 29 *    distribution.
 30 *  - Neither the name of Intel Corporation nor the names of its
 31 *    contributors may be used to endorse or promote products derived
 32 *    from this software without specific prior written permission.
 33 *
 34 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 35 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 36 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 37 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 38 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 39 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 40 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 41 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 42 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 43 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 44 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 45 *
 46 */
 47
 48#include <linux/slab.h>
 49#include "ah.h"
 50#include "vt.h" /* for prints */
 51
 52/**
 53 * rvt_check_ah - validate the attributes of AH
 54 * @ibdev: the ib device
 55 * @ah_attr: the attributes of the AH
 56 *
 57 * If driver supports a more detailed check_ah function call back to it
 58 * otherwise just check the basics.
 59 *
 60 * Return: 0 on success
 61 */
 62int rvt_check_ah(struct ib_device *ibdev,
 63		 struct ib_ah_attr *ah_attr)
 64{
 65	int err;
 
 66	struct ib_port_attr port_attr;
 67	struct rvt_dev_info *rdi = ib_to_rvt(ibdev);
 68	enum rdma_link_layer link = rdma_port_get_link_layer(ibdev,
 69							     ah_attr->port_num);
 70
 71	err = ib_query_port(ibdev, ah_attr->port_num, &port_attr);
 72	if (err)
 73		return -EINVAL;
 74	if (ah_attr->port_num < 1 ||
 75	    ah_attr->port_num > ibdev->phys_port_cnt)
 76		return -EINVAL;
 77	if (ah_attr->static_rate != IB_RATE_PORT_CURRENT &&
 78	    ib_rate_to_mbps(ah_attr->static_rate) < 0)
 79		return -EINVAL;
 80	if ((ah_attr->ah_flags & IB_AH_GRH) &&
 81	    ah_attr->grh.sgid_index >= port_attr.gid_tbl_len)
 82		return -EINVAL;
 83	if (link != IB_LINK_LAYER_ETHERNET) {
 84		if (ah_attr->dlid == 0)
 85			return -EINVAL;
 86		if (ah_attr->dlid >= be16_to_cpu(IB_MULTICAST_LID_BASE) &&
 87		    ah_attr->dlid != be16_to_cpu(IB_LID_PERMISSIVE) &&
 88		    !(ah_attr->ah_flags & IB_AH_GRH))
 89			return -EINVAL;
 90	}
 91	if (rdi->driver_f.check_ah)
 92		return rdi->driver_f.check_ah(ibdev, ah_attr);
 93	return 0;
 94}
 95EXPORT_SYMBOL(rvt_check_ah);
 96
 97/**
 98 * rvt_create_ah - create an address handle
 99 * @pd: the protection domain
100 * @ah_attr: the attributes of the AH
 
101 *
102 * This may be called from interrupt context.
103 *
104 * Return: newly allocated ah
105 */
106struct ib_ah *rvt_create_ah(struct ib_pd *pd,
107			    struct ib_ah_attr *ah_attr)
108{
109	struct rvt_ah *ah;
110	struct rvt_dev_info *dev = ib_to_rvt(pd->device);
111	unsigned long flags;
112
113	if (rvt_check_ah(pd->device, ah_attr))
114		return ERR_PTR(-EINVAL);
115
116	ah = kmalloc(sizeof(*ah), GFP_ATOMIC);
117	if (!ah)
118		return ERR_PTR(-ENOMEM);
119
120	spin_lock_irqsave(&dev->n_ahs_lock, flags);
121	if (dev->n_ahs_allocated == dev->dparms.props.max_ah) {
122		spin_unlock(&dev->n_ahs_lock);
123		kfree(ah);
124		return ERR_PTR(-ENOMEM);
125	}
126
127	dev->n_ahs_allocated++;
128	spin_unlock_irqrestore(&dev->n_ahs_lock, flags);
129
130	ah->attr = *ah_attr;
131	atomic_set(&ah->refcount, 0);
132
133	if (dev->driver_f.notify_new_ah)
134		dev->driver_f.notify_new_ah(pd->device, ah_attr, ah);
 
135
136	return &ah->ibah;
137}
138
139/**
140 * rvt_destory_ah - Destory an address handle
141 * @ibah: address handle
142 *
143 * Return: 0 on success
144 */
145int rvt_destroy_ah(struct ib_ah *ibah)
146{
147	struct rvt_dev_info *dev = ib_to_rvt(ibah->device);
148	struct rvt_ah *ah = ibah_to_rvtah(ibah);
149	unsigned long flags;
150
151	if (atomic_read(&ah->refcount) != 0)
152		return -EBUSY;
153
154	spin_lock_irqsave(&dev->n_ahs_lock, flags);
155	dev->n_ahs_allocated--;
156	spin_unlock_irqrestore(&dev->n_ahs_lock, flags);
157
158	kfree(ah);
159
160	return 0;
161}
162
163/**
164 * rvt_modify_ah - modify an ah with given attrs
165 * @ibah: address handle to modify
166 * @ah_attr: attrs to apply
167 *
168 * Return: 0 on success
169 */
170int rvt_modify_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr)
171{
172	struct rvt_ah *ah = ibah_to_rvtah(ibah);
173
174	if (rvt_check_ah(ibah->device, ah_attr))
175		return -EINVAL;
176
177	ah->attr = *ah_attr;
178
179	return 0;
180}
181
182/**
183 * rvt_query_ah - return attrs for ah
184 * @ibah: address handle to query
185 * @ah_attr: return info in this
186 *
187 * Return: always 0
188 */
189int rvt_query_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr)
190{
191	struct rvt_ah *ah = ibah_to_rvtah(ibah);
192
193	*ah_attr = ah->attr;
194
195	return 0;
196}