You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
staging/rdma: remove deprecated ehca driver
This driver was moved to staging for eventual deletion. Time to complete that task. Signed-off-by: Doug Ledford <dledford@redhat.com>
This commit is contained in:
@@ -4177,13 +4177,6 @@ W: http://aeschi.ch.eu.org/efs/
|
||||
S: Orphan
|
||||
F: fs/efs/
|
||||
|
||||
EHCA (IBM GX bus InfiniBand adapter) DRIVER
|
||||
M: Hoang-Nam Nguyen <hnguyen@de.ibm.com>
|
||||
M: Christoph Raisch <raisch@de.ibm.com>
|
||||
L: linux-rdma@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/infiniband/hw/ehca/
|
||||
|
||||
EHEA (IBM pSeries eHEA 10Gb ethernet adapter) DRIVER
|
||||
M: Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
|
||||
L: netdev@vger.kernel.org
|
||||
|
||||
@@ -22,8 +22,6 @@ menuconfig STAGING_RDMA
|
||||
# Please keep entries in alphabetic order
|
||||
if STAGING_RDMA
|
||||
|
||||
source "drivers/staging/rdma/ehca/Kconfig"
|
||||
|
||||
source "drivers/staging/rdma/hfi1/Kconfig"
|
||||
|
||||
source "drivers/staging/rdma/ipath/Kconfig"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# Entries for RDMA_STAGING tree
|
||||
obj-$(CONFIG_INFINIBAND_EHCA) += ehca/
|
||||
obj-$(CONFIG_INFINIBAND_HFI1) += hfi1/
|
||||
obj-$(CONFIG_INFINIBAND_IPATH) += ipath/
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
config INFINIBAND_EHCA
|
||||
tristate "eHCA support"
|
||||
depends on IBMEBUS
|
||||
---help---
|
||||
This driver supports the deprecated IBM pSeries eHCA InfiniBand
|
||||
adapter.
|
||||
|
||||
To compile the driver as a module, choose M here. The module
|
||||
will be called ib_ehca.
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
# Authors: Heiko J Schick <schickhj@de.ibm.com>
|
||||
# Christoph Raisch <raisch@de.ibm.com>
|
||||
# Joachim Fenkes <fenkes@de.ibm.com>
|
||||
#
|
||||
# Copyright (c) 2005 IBM Corporation
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is distributed under a dual license of GPL v2.0 and OpenIB BSD.
|
||||
|
||||
obj-$(CONFIG_INFINIBAND_EHCA) += ib_ehca.o
|
||||
|
||||
ib_ehca-objs = ehca_main.o ehca_hca.o ehca_mcast.o ehca_pd.o ehca_av.o ehca_eq.o \
|
||||
ehca_cq.o ehca_qp.o ehca_sqp.o ehca_mrmw.o ehca_reqs.o ehca_irq.o \
|
||||
ehca_uverbs.o ipz_pt_fn.o hcp_if.o hcp_phyp.o
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
9/2015
|
||||
|
||||
The ehca driver has been deprecated and moved to drivers/staging/rdma.
|
||||
It will be removed in the 4.6 merge window.
|
||||
@@ -1,279 +0,0 @@
|
||||
/*
|
||||
* IBM eServer eHCA Infiniband device driver for Linux on POWER
|
||||
*
|
||||
* address vector functions
|
||||
*
|
||||
* Authors: Hoang-Nam Nguyen <hnguyen@de.ibm.com>
|
||||
* Khadija Souissi <souissik@de.ibm.com>
|
||||
* Reinhard Ernst <rernst@de.ibm.com>
|
||||
* Christoph Raisch <raisch@de.ibm.com>
|
||||
*
|
||||
* Copyright (c) 2005 IBM Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is distributed under a dual license of GPL v2.0 and OpenIB
|
||||
* BSD.
|
||||
*
|
||||
* OpenIB BSD License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "ehca_tools.h"
|
||||
#include "ehca_iverbs.h"
|
||||
#include "hcp_if.h"
|
||||
|
||||
static struct kmem_cache *av_cache;
|
||||
|
||||
int ehca_calc_ipd(struct ehca_shca *shca, int port,
|
||||
enum ib_rate path_rate, u32 *ipd)
|
||||
{
|
||||
int path = ib_rate_to_mult(path_rate);
|
||||
int link, ret;
|
||||
struct ib_port_attr pa;
|
||||
|
||||
if (path_rate == IB_RATE_PORT_CURRENT) {
|
||||
*ipd = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (unlikely(path < 0)) {
|
||||
ehca_err(&shca->ib_device, "Invalid static rate! path_rate=%x",
|
||||
path_rate);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = ehca_query_port(&shca->ib_device, port, &pa);
|
||||
if (unlikely(ret < 0)) {
|
||||
ehca_err(&shca->ib_device, "Failed to query port ret=%i", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
link = ib_width_enum_to_int(pa.active_width) * pa.active_speed;
|
||||
|
||||
if (path >= link)
|
||||
/* no need to throttle if path faster than link */
|
||||
*ipd = 0;
|
||||
else
|
||||
/* IPD = round((link / path) - 1) */
|
||||
*ipd = ((link + (path >> 1)) / path) - 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct ib_ah *ehca_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
|
||||
{
|
||||
int ret;
|
||||
struct ehca_av *av;
|
||||
struct ehca_shca *shca = container_of(pd->device, struct ehca_shca,
|
||||
ib_device);
|
||||
|
||||
av = kmem_cache_alloc(av_cache, GFP_KERNEL);
|
||||
if (!av) {
|
||||
ehca_err(pd->device, "Out of memory pd=%p ah_attr=%p",
|
||||
pd, ah_attr);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
av->av.sl = ah_attr->sl;
|
||||
av->av.dlid = ah_attr->dlid;
|
||||
av->av.slid_path_bits = ah_attr->src_path_bits;
|
||||
|
||||
if (ehca_static_rate < 0) {
|
||||
u32 ipd;
|
||||
|
||||
if (ehca_calc_ipd(shca, ah_attr->port_num,
|
||||
ah_attr->static_rate, &ipd)) {
|
||||
ret = -EINVAL;
|
||||
goto create_ah_exit1;
|
||||
}
|
||||
av->av.ipd = ipd;
|
||||
} else
|
||||
av->av.ipd = ehca_static_rate;
|
||||
|
||||
av->av.lnh = ah_attr->ah_flags;
|
||||
av->av.grh.word_0 = EHCA_BMASK_SET(GRH_IPVERSION_MASK, 6);
|
||||
av->av.grh.word_0 |= EHCA_BMASK_SET(GRH_TCLASS_MASK,
|
||||
ah_attr->grh.traffic_class);
|
||||
av->av.grh.word_0 |= EHCA_BMASK_SET(GRH_FLOWLABEL_MASK,
|
||||
ah_attr->grh.flow_label);
|
||||
av->av.grh.word_0 |= EHCA_BMASK_SET(GRH_HOPLIMIT_MASK,
|
||||
ah_attr->grh.hop_limit);
|
||||
av->av.grh.word_0 |= EHCA_BMASK_SET(GRH_NEXTHEADER_MASK, 0x1B);
|
||||
/* set sgid in grh.word_1 */
|
||||
if (ah_attr->ah_flags & IB_AH_GRH) {
|
||||
int rc;
|
||||
struct ib_port_attr port_attr;
|
||||
union ib_gid gid;
|
||||
|
||||
memset(&port_attr, 0, sizeof(port_attr));
|
||||
rc = ehca_query_port(pd->device, ah_attr->port_num,
|
||||
&port_attr);
|
||||
if (rc) { /* invalid port number */
|
||||
ret = -EINVAL;
|
||||
ehca_err(pd->device, "Invalid port number "
|
||||
"ehca_query_port() returned %x "
|
||||
"pd=%p ah_attr=%p", rc, pd, ah_attr);
|
||||
goto create_ah_exit1;
|
||||
}
|
||||
memset(&gid, 0, sizeof(gid));
|
||||
rc = ehca_query_gid(pd->device,
|
||||
ah_attr->port_num,
|
||||
ah_attr->grh.sgid_index, &gid);
|
||||
if (rc) {
|
||||
ret = -EINVAL;
|
||||
ehca_err(pd->device, "Failed to retrieve sgid "
|
||||
"ehca_query_gid() returned %x "
|
||||
"pd=%p ah_attr=%p", rc, pd, ah_attr);
|
||||
goto create_ah_exit1;
|
||||
}
|
||||
memcpy(&av->av.grh.word_1, &gid, sizeof(gid));
|
||||
}
|
||||
av->av.pmtu = shca->max_mtu;
|
||||
|
||||
/* dgid comes in grh.word_3 */
|
||||
memcpy(&av->av.grh.word_3, &ah_attr->grh.dgid,
|
||||
sizeof(ah_attr->grh.dgid));
|
||||
|
||||
return &av->ib_ah;
|
||||
|
||||
create_ah_exit1:
|
||||
kmem_cache_free(av_cache, av);
|
||||
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
int ehca_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
|
||||
{
|
||||
struct ehca_av *av;
|
||||
struct ehca_ud_av new_ehca_av;
|
||||
struct ehca_shca *shca = container_of(ah->pd->device, struct ehca_shca,
|
||||
ib_device);
|
||||
|
||||
memset(&new_ehca_av, 0, sizeof(new_ehca_av));
|
||||
new_ehca_av.sl = ah_attr->sl;
|
||||
new_ehca_av.dlid = ah_attr->dlid;
|
||||
new_ehca_av.slid_path_bits = ah_attr->src_path_bits;
|
||||
new_ehca_av.ipd = ah_attr->static_rate;
|
||||
new_ehca_av.lnh = EHCA_BMASK_SET(GRH_FLAG_MASK,
|
||||
(ah_attr->ah_flags & IB_AH_GRH) > 0);
|
||||
new_ehca_av.grh.word_0 = EHCA_BMASK_SET(GRH_TCLASS_MASK,
|
||||
ah_attr->grh.traffic_class);
|
||||
new_ehca_av.grh.word_0 |= EHCA_BMASK_SET(GRH_FLOWLABEL_MASK,
|
||||
ah_attr->grh.flow_label);
|
||||
new_ehca_av.grh.word_0 |= EHCA_BMASK_SET(GRH_HOPLIMIT_MASK,
|
||||
ah_attr->grh.hop_limit);
|
||||
new_ehca_av.grh.word_0 |= EHCA_BMASK_SET(GRH_NEXTHEADER_MASK, 0x1b);
|
||||
|
||||
/* set sgid in grh.word_1 */
|
||||
if (ah_attr->ah_flags & IB_AH_GRH) {
|
||||
int rc;
|
||||
struct ib_port_attr port_attr;
|
||||
union ib_gid gid;
|
||||
|
||||
memset(&port_attr, 0, sizeof(port_attr));
|
||||
rc = ehca_query_port(ah->device, ah_attr->port_num,
|
||||
&port_attr);
|
||||
if (rc) { /* invalid port number */
|
||||
ehca_err(ah->device, "Invalid port number "
|
||||
"ehca_query_port() returned %x "
|
||||
"ah=%p ah_attr=%p port_num=%x",
|
||||
rc, ah, ah_attr, ah_attr->port_num);
|
||||
return -EINVAL;
|
||||
}
|
||||
memset(&gid, 0, sizeof(gid));
|
||||
rc = ehca_query_gid(ah->device,
|
||||
ah_attr->port_num,
|
||||
ah_attr->grh.sgid_index, &gid);
|
||||
if (rc) {
|
||||
ehca_err(ah->device, "Failed to retrieve sgid "
|
||||
"ehca_query_gid() returned %x "
|
||||
"ah=%p ah_attr=%p port_num=%x "
|
||||
"sgid_index=%x",
|
||||
rc, ah, ah_attr, ah_attr->port_num,
|
||||
ah_attr->grh.sgid_index);
|
||||
return -EINVAL;
|
||||
}
|
||||
memcpy(&new_ehca_av.grh.word_1, &gid, sizeof(gid));
|
||||
}
|
||||
|
||||
new_ehca_av.pmtu = shca->max_mtu;
|
||||
|
||||
memcpy(&new_ehca_av.grh.word_3, &ah_attr->grh.dgid,
|
||||
sizeof(ah_attr->grh.dgid));
|
||||
|
||||
av = container_of(ah, struct ehca_av, ib_ah);
|
||||
av->av = new_ehca_av;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ehca_query_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
|
||||
{
|
||||
struct ehca_av *av = container_of(ah, struct ehca_av, ib_ah);
|
||||
|
||||
memcpy(&ah_attr->grh.dgid, &av->av.grh.word_3,
|
||||
sizeof(ah_attr->grh.dgid));
|
||||
ah_attr->sl = av->av.sl;
|
||||
|
||||
ah_attr->dlid = av->av.dlid;
|
||||
|
||||
ah_attr->src_path_bits = av->av.slid_path_bits;
|
||||
ah_attr->static_rate = av->av.ipd;
|
||||
ah_attr->ah_flags = EHCA_BMASK_GET(GRH_FLAG_MASK, av->av.lnh);
|
||||
ah_attr->grh.traffic_class = EHCA_BMASK_GET(GRH_TCLASS_MASK,
|
||||
av->av.grh.word_0);
|
||||
ah_attr->grh.hop_limit = EHCA_BMASK_GET(GRH_HOPLIMIT_MASK,
|
||||
av->av.grh.word_0);
|
||||
ah_attr->grh.flow_label = EHCA_BMASK_GET(GRH_FLOWLABEL_MASK,
|
||||
av->av.grh.word_0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ehca_destroy_ah(struct ib_ah *ah)
|
||||
{
|
||||
kmem_cache_free(av_cache, container_of(ah, struct ehca_av, ib_ah));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ehca_init_av_cache(void)
|
||||
{
|
||||
av_cache = kmem_cache_create("ehca_cache_av",
|
||||
sizeof(struct ehca_av), 0,
|
||||
SLAB_HWCACHE_ALIGN,
|
||||
NULL);
|
||||
if (!av_cache)
|
||||
return -ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ehca_cleanup_av_cache(void)
|
||||
{
|
||||
kmem_cache_destroy(av_cache);
|
||||
}
|
||||
@@ -1,481 +0,0 @@
|
||||
/*
|
||||
* IBM eServer eHCA Infiniband device driver for Linux on POWER
|
||||
*
|
||||
* Struct definition for eHCA internal structures
|
||||
*
|
||||
* Authors: Heiko J Schick <schickhj@de.ibm.com>
|
||||
* Christoph Raisch <raisch@de.ibm.com>
|
||||
* Joachim Fenkes <fenkes@de.ibm.com>
|
||||
*
|
||||
* Copyright (c) 2005 IBM Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is distributed under a dual license of GPL v2.0 and OpenIB
|
||||
* BSD.
|
||||
*
|
||||
* OpenIB BSD License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __EHCA_CLASSES_H__
|
||||
#define __EHCA_CLASSES_H__
|
||||
|
||||
struct ehca_module;
|
||||
struct ehca_qp;
|
||||
struct ehca_cq;
|
||||
struct ehca_eq;
|
||||
struct ehca_mr;
|
||||
struct ehca_mw;
|
||||
struct ehca_pd;
|
||||
struct ehca_av;
|
||||
|
||||
#include <linux/wait.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#include <rdma/ib_verbs.h>
|
||||
#include <rdma/ib_user_verbs.h>
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
#include "ehca_classes_pSeries.h"
|
||||
#endif
|
||||
#include "ipz_pt_fn.h"
|
||||
#include "ehca_qes.h"
|
||||
#include "ehca_irq.h"
|
||||
|
||||
#define EHCA_EQE_CACHE_SIZE 20
|
||||
#define EHCA_MAX_NUM_QUEUES 0xffff
|
||||
|
||||
struct ehca_eqe_cache_entry {
|
||||
struct ehca_eqe *eqe;
|
||||
struct ehca_cq *cq;
|
||||
};
|
||||
|
||||
struct ehca_eq {
|
||||
u32 length;
|
||||
struct ipz_queue ipz_queue;
|
||||
struct ipz_eq_handle ipz_eq_handle;
|
||||
struct work_struct work;
|
||||
struct h_galpas galpas;
|
||||
int is_initialized;
|
||||
struct ehca_pfeq pf;
|
||||
spinlock_t spinlock;
|
||||
struct tasklet_struct interrupt_task;
|
||||
u32 ist;
|
||||
spinlock_t irq_spinlock;
|
||||
struct ehca_eqe_cache_entry eqe_cache[EHCA_EQE_CACHE_SIZE];
|
||||
};
|
||||
|
||||
struct ehca_sma_attr {
|
||||
u16 lid, lmc, sm_sl, sm_lid;
|
||||
u16 pkey_tbl_len, pkeys[16];
|
||||
};
|
||||
|
||||
struct ehca_sport {
|
||||
struct ib_cq *ibcq_aqp1;
|
||||
struct ib_qp *ibqp_sqp[2];
|
||||
/* lock to serialze modify_qp() calls for sqp in normal
|
||||
* and irq path (when event PORT_ACTIVE is received first time)
|
||||
*/
|
||||
spinlock_t mod_sqp_lock;
|
||||
enum ib_port_state port_state;
|
||||
struct ehca_sma_attr saved_attr;
|
||||
u32 pma_qp_nr;
|
||||
};
|
||||
|
||||
#define HCA_CAP_MR_PGSIZE_4K 0x80000000
|
||||
#define HCA_CAP_MR_PGSIZE_64K 0x40000000
|
||||
#define HCA_CAP_MR_PGSIZE_1M 0x20000000
|
||||
#define HCA_CAP_MR_PGSIZE_16M 0x10000000
|
||||
|
||||
struct ehca_shca {
|
||||
struct ib_device ib_device;
|
||||
struct platform_device *ofdev;
|
||||
u8 num_ports;
|
||||
int hw_level;
|
||||
struct list_head shca_list;
|
||||
struct ipz_adapter_handle ipz_hca_handle;
|
||||
struct ehca_sport sport[2];
|
||||
struct ehca_eq eq;
|
||||
struct ehca_eq neq;
|
||||
struct ehca_mr *maxmr;
|
||||
struct ehca_pd *pd;
|
||||
struct h_galpas galpas;
|
||||
struct mutex modify_mutex;
|
||||
u64 hca_cap;
|
||||
/* MR pgsize: bit 0-3 means 4K, 64K, 1M, 16M respectively */
|
||||
u32 hca_cap_mr_pgsize;
|
||||
int max_mtu;
|
||||
int max_num_qps;
|
||||
int max_num_cqs;
|
||||
atomic_t num_cqs;
|
||||
atomic_t num_qps;
|
||||
};
|
||||
|
||||
struct ehca_pd {
|
||||
struct ib_pd ib_pd;
|
||||
struct ipz_pd fw_pd;
|
||||
/* small queue mgmt */
|
||||
struct mutex lock;
|
||||
struct list_head free[2];
|
||||
struct list_head full[2];
|
||||
};
|
||||
|
||||
enum ehca_ext_qp_type {
|
||||
EQPT_NORMAL = 0,
|
||||
EQPT_LLQP = 1,
|
||||
EQPT_SRQBASE = 2,
|
||||
EQPT_SRQ = 3,
|
||||
};
|
||||
|
||||
/* struct to cache modify_qp()'s parms for GSI/SMI qp */
|
||||
struct ehca_mod_qp_parm {
|
||||
int mask;
|
||||
struct ib_qp_attr attr;
|
||||
};
|
||||
|
||||
#define EHCA_MOD_QP_PARM_MAX 4
|
||||
|
||||
#define QMAP_IDX_MASK 0xFFFFULL
|
||||
|
||||
/* struct for tracking if cqes have been reported to the application */
|
||||
struct ehca_qmap_entry {
|
||||
u16 app_wr_id;
|
||||
u8 reported;
|
||||
u8 cqe_req;
|
||||
};
|
||||
|
||||
struct ehca_queue_map {
|
||||
struct ehca_qmap_entry *map;
|
||||
unsigned int entries;
|
||||
unsigned int tail;
|
||||
unsigned int left_to_poll;
|
||||
unsigned int next_wqe_idx; /* Idx to first wqe to be flushed */
|
||||
};
|
||||
|
||||
/* function to calculate the next index for the qmap */
|
||||
static inline unsigned int next_index(unsigned int cur_index, unsigned int limit)
|
||||
{
|
||||
unsigned int temp = cur_index + 1;
|
||||
return (temp == limit) ? 0 : temp;
|
||||
}
|
||||
|
||||
struct ehca_qp {
|
||||
union {
|
||||
struct ib_qp ib_qp;
|
||||
struct ib_srq ib_srq;
|
||||
};
|
||||
u32 qp_type;
|
||||
enum ehca_ext_qp_type ext_type;
|
||||
enum ib_qp_state state;
|
||||
struct ipz_queue ipz_squeue;
|
||||
struct ehca_queue_map sq_map;
|
||||
struct ipz_queue ipz_rqueue;
|
||||
struct ehca_queue_map rq_map;
|
||||
struct h_galpas galpas;
|
||||
u32 qkey;
|
||||
u32 real_qp_num;
|
||||
u32 token;
|
||||
spinlock_t spinlock_s;
|
||||
spinlock_t spinlock_r;
|
||||
u32 sq_max_inline_data_size;
|
||||
struct ipz_qp_handle ipz_qp_handle;
|
||||
struct ehca_pfqp pf;
|
||||
struct ib_qp_init_attr init_attr;
|
||||
struct ehca_cq *send_cq;
|
||||
struct ehca_cq *recv_cq;
|
||||
unsigned int sqerr_purgeflag;
|
||||
struct hlist_node list_entries;
|
||||
/* array to cache modify_qp()'s parms for GSI/SMI qp */
|
||||
struct ehca_mod_qp_parm *mod_qp_parm;
|
||||
int mod_qp_parm_idx;
|
||||
/* mmap counter for resources mapped into user space */
|
||||
u32 mm_count_squeue;
|
||||
u32 mm_count_rqueue;
|
||||
u32 mm_count_galpa;
|
||||
/* unsolicited ack circumvention */
|
||||
int unsol_ack_circ;
|
||||
int mtu_shift;
|
||||
u32 message_count;
|
||||
u32 packet_count;
|
||||
atomic_t nr_events; /* events seen */
|
||||
wait_queue_head_t wait_completion;
|
||||
int mig_armed;
|
||||
struct list_head sq_err_node;
|
||||
struct list_head rq_err_node;
|
||||
};
|
||||
|
||||
#define IS_SRQ(qp) (qp->ext_type == EQPT_SRQ)
|
||||
#define HAS_SQ(qp) (qp->ext_type != EQPT_SRQ)
|
||||
#define HAS_RQ(qp) (qp->ext_type != EQPT_SRQBASE)
|
||||
|
||||
/* must be power of 2 */
|
||||
#define QP_HASHTAB_LEN 8
|
||||
|
||||
struct ehca_cq {
|
||||
struct ib_cq ib_cq;
|
||||
struct ipz_queue ipz_queue;
|
||||
struct h_galpas galpas;
|
||||
spinlock_t spinlock;
|
||||
u32 cq_number;
|
||||
u32 token;
|
||||
u32 nr_of_entries;
|
||||
struct ipz_cq_handle ipz_cq_handle;
|
||||
struct ehca_pfcq pf;
|
||||
spinlock_t cb_lock;
|
||||
struct hlist_head qp_hashtab[QP_HASHTAB_LEN];
|
||||
struct list_head entry;
|
||||
u32 nr_callbacks; /* #events assigned to cpu by scaling code */
|
||||
atomic_t nr_events; /* #events seen */
|
||||
wait_queue_head_t wait_completion;
|
||||
spinlock_t task_lock;
|
||||
/* mmap counter for resources mapped into user space */
|
||||
u32 mm_count_queue;
|
||||
u32 mm_count_galpa;
|
||||
struct list_head sqp_err_list;
|
||||
struct list_head rqp_err_list;
|
||||
};
|
||||
|
||||
enum ehca_mr_flag {
|
||||
EHCA_MR_FLAG_FMR = 0x80000000, /* FMR, created with ehca_alloc_fmr */
|
||||
EHCA_MR_FLAG_MAXMR = 0x40000000, /* max-MR */
|
||||
};
|
||||
|
||||
struct ehca_mr {
|
||||
union {
|
||||
struct ib_mr ib_mr; /* must always be first in ehca_mr */
|
||||
struct ib_fmr ib_fmr; /* must always be first in ehca_mr */
|
||||
} ib;
|
||||
struct ib_umem *umem;
|
||||
spinlock_t mrlock;
|
||||
|
||||
enum ehca_mr_flag flags;
|
||||
u32 num_kpages; /* number of kernel pages */
|
||||
u32 num_hwpages; /* number of hw pages to form MR */
|
||||
u64 hwpage_size; /* hw page size used for this MR */
|
||||
int acl; /* ACL (stored here for usage in reregister) */
|
||||
u64 *start; /* virtual start address (stored here for */
|
||||
/* usage in reregister) */
|
||||
u64 size; /* size (stored here for usage in reregister) */
|
||||
u32 fmr_page_size; /* page size for FMR */
|
||||
u32 fmr_max_pages; /* max pages for FMR */
|
||||
u32 fmr_max_maps; /* max outstanding maps for FMR */
|
||||
u32 fmr_map_cnt; /* map counter for FMR */
|
||||
/* fw specific data */
|
||||
struct ipz_mrmw_handle ipz_mr_handle; /* MR handle for h-calls */
|
||||
struct h_galpas galpas;
|
||||
};
|
||||
|
||||
struct ehca_mw {
|
||||
struct ib_mw ib_mw; /* gen2 mw, must always be first in ehca_mw */
|
||||
spinlock_t mwlock;
|
||||
|
||||
u8 never_bound; /* indication MW was never bound */
|
||||
struct ipz_mrmw_handle ipz_mw_handle; /* MW handle for h-calls */
|
||||
struct h_galpas galpas;
|
||||
};
|
||||
|
||||
enum ehca_mr_pgi_type {
|
||||
EHCA_MR_PGI_PHYS = 1, /* type of ehca_reg_phys_mr,
|
||||
* ehca_rereg_phys_mr,
|
||||
* ehca_reg_internal_maxmr */
|
||||
EHCA_MR_PGI_USER = 2, /* type of ehca_reg_user_mr */
|
||||
EHCA_MR_PGI_FMR = 3 /* type of ehca_map_phys_fmr */
|
||||
};
|
||||
|
||||
struct ehca_mr_pginfo {
|
||||
enum ehca_mr_pgi_type type;
|
||||
u64 num_kpages;
|
||||
u64 kpage_cnt;
|
||||
u64 hwpage_size; /* hw page size used for this MR */
|
||||
u64 num_hwpages; /* number of hw pages */
|
||||
u64 hwpage_cnt; /* counter for hw pages */
|
||||
u64 next_hwpage; /* next hw page in buffer/chunk/listelem */
|
||||
|
||||
union {
|
||||
struct { /* type EHCA_MR_PGI_PHYS section */
|
||||
u64 addr;
|
||||
u16 size;
|
||||
} phy;
|
||||
struct { /* type EHCA_MR_PGI_USER section */
|
||||
struct ib_umem *region;
|
||||
struct scatterlist *next_sg;
|
||||
u64 next_nmap;
|
||||
} usr;
|
||||
struct { /* type EHCA_MR_PGI_FMR section */
|
||||
u64 fmr_pgsize;
|
||||
u64 *page_list;
|
||||
u64 next_listelem;
|
||||
} fmr;
|
||||
} u;
|
||||
};
|
||||
|
||||
/* output parameters for MR/FMR hipz calls */
|
||||
struct ehca_mr_hipzout_parms {
|
||||
struct ipz_mrmw_handle handle;
|
||||
u32 lkey;
|
||||
u32 rkey;
|
||||
u64 len;
|
||||
u64 vaddr;
|
||||
u32 acl;
|
||||
};
|
||||
|
||||
/* output parameters for MW hipz calls */
|
||||
struct ehca_mw_hipzout_parms {
|
||||
struct ipz_mrmw_handle handle;
|
||||
u32 rkey;
|
||||
};
|
||||
|
||||
struct ehca_av {
|
||||
struct ib_ah ib_ah;
|
||||
struct ehca_ud_av av;
|
||||
};
|
||||
|
||||
struct ehca_ucontext {
|
||||
struct ib_ucontext ib_ucontext;
|
||||
};
|
||||
|
||||
int ehca_init_pd_cache(void);
|
||||
void ehca_cleanup_pd_cache(void);
|
||||
int ehca_init_cq_cache(void);
|
||||
void ehca_cleanup_cq_cache(void);
|
||||
int ehca_init_qp_cache(void);
|
||||
void ehca_cleanup_qp_cache(void);
|
||||
int ehca_init_av_cache(void);
|
||||
void ehca_cleanup_av_cache(void);
|
||||
int ehca_init_mrmw_cache(void);
|
||||
void ehca_cleanup_mrmw_cache(void);
|
||||
int ehca_init_small_qp_cache(void);
|
||||
void ehca_cleanup_small_qp_cache(void);
|
||||
|
||||
extern rwlock_t ehca_qp_idr_lock;
|
||||
extern rwlock_t ehca_cq_idr_lock;
|
||||
extern struct idr ehca_qp_idr;
|
||||
extern struct idr ehca_cq_idr;
|
||||
extern spinlock_t shca_list_lock;
|
||||
|
||||
extern int ehca_static_rate;
|
||||
extern int ehca_port_act_time;
|
||||
extern bool ehca_use_hp_mr;
|
||||
extern bool ehca_scaling_code;
|
||||
extern int ehca_lock_hcalls;
|
||||
extern int ehca_nr_ports;
|
||||
extern int ehca_max_cq;
|
||||
extern int ehca_max_qp;
|
||||
|
||||
struct ipzu_queue_resp {
|
||||
u32 qe_size; /* queue entry size */
|
||||
u32 act_nr_of_sg;
|
||||
u32 queue_length; /* queue length allocated in bytes */
|
||||
u32 pagesize;
|
||||
u32 toggle_state;
|
||||
u32 offset; /* save offset within a page for small_qp */
|
||||
};
|
||||
|
||||
struct ehca_create_cq_resp {
|
||||
u32 cq_number;
|
||||
u32 token;
|
||||
struct ipzu_queue_resp ipz_queue;
|
||||
u32 fw_handle_ofs;
|
||||
u32 dummy;
|
||||
};
|
||||
|
||||
struct ehca_create_qp_resp {
|
||||
u32 qp_num;
|
||||
u32 token;
|
||||
u32 qp_type;
|
||||
u32 ext_type;
|
||||
u32 qkey;
|
||||
/* qp_num assigned by ehca: sqp0/1 may have got different numbers */
|
||||
u32 real_qp_num;
|
||||
u32 fw_handle_ofs;
|
||||
u32 dummy;
|
||||
struct ipzu_queue_resp ipz_squeue;
|
||||
struct ipzu_queue_resp ipz_rqueue;
|
||||
};
|
||||
|
||||
struct ehca_alloc_cq_parms {
|
||||
u32 nr_cqe;
|
||||
u32 act_nr_of_entries;
|
||||
u32 act_pages;
|
||||
struct ipz_eq_handle eq_handle;
|
||||
};
|
||||
|
||||
enum ehca_service_type {
|
||||
ST_RC = 0,
|
||||
ST_UC = 1,
|
||||
ST_RD = 2,
|
||||
ST_UD = 3,
|
||||
};
|
||||
|
||||
enum ehca_ll_comp_flags {
|
||||
LLQP_SEND_COMP = 0x20,
|
||||
LLQP_RECV_COMP = 0x40,
|
||||
LLQP_COMP_MASK = 0x60,
|
||||
};
|
||||
|
||||
struct ehca_alloc_queue_parms {
|
||||
/* input parameters */
|
||||
int max_wr;
|
||||
int max_sge;
|
||||
int page_size;
|
||||
int is_small;
|
||||
|
||||
/* output parameters */
|
||||
u16 act_nr_wqes;
|
||||
u8 act_nr_sges;
|
||||
u32 queue_size; /* bytes for small queues, pages otherwise */
|
||||
};
|
||||
|
||||
struct ehca_alloc_qp_parms {
|
||||
struct ehca_alloc_queue_parms squeue;
|
||||
struct ehca_alloc_queue_parms rqueue;
|
||||
|
||||
/* input parameters */
|
||||
enum ehca_service_type servicetype;
|
||||
int qp_storage;
|
||||
int sigtype;
|
||||
enum ehca_ext_qp_type ext_type;
|
||||
enum ehca_ll_comp_flags ll_comp_flags;
|
||||
int ud_av_l_key_ctl;
|
||||
|
||||
u32 token;
|
||||
struct ipz_eq_handle eq_handle;
|
||||
struct ipz_pd pd;
|
||||
struct ipz_cq_handle send_cq_handle, recv_cq_handle;
|
||||
|
||||
u32 srq_qpn, srq_token, srq_limit;
|
||||
|
||||
/* output parameters */
|
||||
u32 real_qp_num;
|
||||
struct ipz_qp_handle qp_handle;
|
||||
struct h_galpas galpas;
|
||||
};
|
||||
|
||||
int ehca_cq_assign_qp(struct ehca_cq *cq, struct ehca_qp *qp);
|
||||
int ehca_cq_unassign_qp(struct ehca_cq *cq, unsigned int qp_num);
|
||||
struct ehca_qp *ehca_cq_get_qp(struct ehca_cq *cq, int qp_num);
|
||||
|
||||
#endif
|
||||
@@ -1,208 +0,0 @@
|
||||
/*
|
||||
* IBM eServer eHCA Infiniband device driver for Linux on POWER
|
||||
*
|
||||
* pSeries interface definitions
|
||||
*
|
||||
* Authors: Waleri Fomin <fomin@de.ibm.com>
|
||||
* Christoph Raisch <raisch@de.ibm.com>
|
||||
*
|
||||
* Copyright (c) 2005 IBM Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is distributed under a dual license of GPL v2.0 and OpenIB
|
||||
* BSD.
|
||||
*
|
||||
* OpenIB BSD License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __EHCA_CLASSES_PSERIES_H__
|
||||
#define __EHCA_CLASSES_PSERIES_H__
|
||||
|
||||
#include "hcp_phyp.h"
|
||||
#include "ipz_pt_fn.h"
|
||||
|
||||
|
||||
struct ehca_pfqp {
|
||||
struct ipz_qpt sqpt;
|
||||
struct ipz_qpt rqpt;
|
||||
};
|
||||
|
||||
struct ehca_pfcq {
|
||||
struct ipz_qpt qpt;
|
||||
u32 cqnr;
|
||||
};
|
||||
|
||||
struct ehca_pfeq {
|
||||
struct ipz_qpt qpt;
|
||||
struct h_galpa galpa;
|
||||
u32 eqnr;
|
||||
};
|
||||
|
||||
struct ipz_adapter_handle {
|
||||
u64 handle;
|
||||
};
|
||||
|
||||
struct ipz_cq_handle {
|
||||
u64 handle;
|
||||
};
|
||||
|
||||
struct ipz_eq_handle {
|
||||
u64 handle;
|
||||
};
|
||||
|
||||
struct ipz_qp_handle {
|
||||
u64 handle;
|
||||
};
|
||||
struct ipz_mrmw_handle {
|
||||
u64 handle;
|
||||
};
|
||||
|
||||
struct ipz_pd {
|
||||
u32 value;
|
||||
};
|
||||
|
||||
struct hcp_modify_qp_control_block {
|
||||
u32 qkey; /* 00 */
|
||||
u32 rdd; /* reliable datagram domain */
|
||||
u32 send_psn; /* 02 */
|
||||
u32 receive_psn; /* 03 */
|
||||
u32 prim_phys_port; /* 04 */
|
||||
u32 alt_phys_port; /* 05 */
|
||||
u32 prim_p_key_idx; /* 06 */
|
||||
u32 alt_p_key_idx; /* 07 */
|
||||
u32 rdma_atomic_ctrl; /* 08 */
|
||||
u32 qp_state; /* 09 */
|
||||
u32 reserved_10; /* 10 */
|
||||
u32 rdma_nr_atomic_resp_res; /* 11 */
|
||||
u32 path_migration_state; /* 12 */
|
||||
u32 rdma_atomic_outst_dest_qp; /* 13 */
|
||||
u32 dest_qp_nr; /* 14 */
|
||||
u32 min_rnr_nak_timer_field; /* 15 */
|
||||
u32 service_level; /* 16 */
|
||||
u32 send_grh_flag; /* 17 */
|
||||
u32 retry_count; /* 18 */
|
||||
u32 timeout; /* 19 */
|
||||
u32 path_mtu; /* 20 */
|
||||
u32 max_static_rate; /* 21 */
|
||||
u32 dlid; /* 22 */
|
||||
u32 rnr_retry_count; /* 23 */
|
||||
u32 source_path_bits; /* 24 */
|
||||
u32 traffic_class; /* 25 */
|
||||
u32 hop_limit; /* 26 */
|
||||
u32 source_gid_idx; /* 27 */
|
||||
u32 flow_label; /* 28 */
|
||||
u32 reserved_29; /* 29 */
|
||||
union { /* 30 */
|
||||
u64 dw[2];
|
||||
u8 byte[16];
|
||||
} dest_gid;
|
||||
u32 service_level_al; /* 34 */
|
||||
u32 send_grh_flag_al; /* 35 */
|
||||
u32 retry_count_al; /* 36 */
|
||||
u32 timeout_al; /* 37 */
|
||||
u32 max_static_rate_al; /* 38 */
|
||||
u32 dlid_al; /* 39 */
|
||||
u32 rnr_retry_count_al; /* 40 */
|
||||
u32 source_path_bits_al; /* 41 */
|
||||
u32 traffic_class_al; /* 42 */
|
||||
u32 hop_limit_al; /* 43 */
|
||||
u32 source_gid_idx_al; /* 44 */
|
||||
u32 flow_label_al; /* 45 */
|
||||
u32 reserved_46; /* 46 */
|
||||
u32 reserved_47; /* 47 */
|
||||
union { /* 48 */
|
||||
u64 dw[2];
|
||||
u8 byte[16];
|
||||
} dest_gid_al;
|
||||
u32 max_nr_outst_send_wr; /* 52 */
|
||||
u32 max_nr_outst_recv_wr; /* 53 */
|
||||
u32 disable_ete_credit_check; /* 54 */
|
||||
u32 qp_number; /* 55 */
|
||||
u64 send_queue_handle; /* 56 */
|
||||
u64 recv_queue_handle; /* 58 */
|
||||
u32 actual_nr_sges_in_sq_wqe; /* 60 */
|
||||
u32 actual_nr_sges_in_rq_wqe; /* 61 */
|
||||
u32 qp_enable; /* 62 */
|
||||
u32 curr_srq_limit; /* 63 */
|
||||
u64 qp_aff_asyn_ev_log_reg; /* 64 */
|
||||
u64 shared_rq_hndl; /* 66 */
|
||||
u64 trigg_doorbell_qp_hndl; /* 68 */
|
||||
u32 reserved_70_127[58]; /* 70 */
|
||||
};
|
||||
|
||||
#define MQPCB_MASK_QKEY EHCA_BMASK_IBM( 0, 0)
|
||||
#define MQPCB_MASK_SEND_PSN EHCA_BMASK_IBM( 2, 2)
|
||||
#define MQPCB_MASK_RECEIVE_PSN EHCA_BMASK_IBM( 3, 3)
|
||||
#define MQPCB_MASK_PRIM_PHYS_PORT EHCA_BMASK_IBM( 4, 4)
|
||||
#define MQPCB_PRIM_PHYS_PORT EHCA_BMASK_IBM(24, 31)
|
||||
#define MQPCB_MASK_ALT_PHYS_PORT EHCA_BMASK_IBM( 5, 5)
|
||||
#define MQPCB_MASK_PRIM_P_KEY_IDX EHCA_BMASK_IBM( 6, 6)
|
||||
#define MQPCB_PRIM_P_KEY_IDX EHCA_BMASK_IBM(24, 31)
|
||||
#define MQPCB_MASK_ALT_P_KEY_IDX EHCA_BMASK_IBM( 7, 7)
|
||||
#define MQPCB_MASK_RDMA_ATOMIC_CTRL EHCA_BMASK_IBM( 8, 8)
|
||||
#define MQPCB_MASK_QP_STATE EHCA_BMASK_IBM( 9, 9)
|
||||
#define MQPCB_MASK_RDMA_NR_ATOMIC_RESP_RES EHCA_BMASK_IBM(11, 11)
|
||||
#define MQPCB_MASK_PATH_MIGRATION_STATE EHCA_BMASK_IBM(12, 12)
|
||||
#define MQPCB_MASK_RDMA_ATOMIC_OUTST_DEST_QP EHCA_BMASK_IBM(13, 13)
|
||||
#define MQPCB_MASK_DEST_QP_NR EHCA_BMASK_IBM(14, 14)
|
||||
#define MQPCB_MASK_MIN_RNR_NAK_TIMER_FIELD EHCA_BMASK_IBM(15, 15)
|
||||
#define MQPCB_MASK_SERVICE_LEVEL EHCA_BMASK_IBM(16, 16)
|
||||
#define MQPCB_MASK_SEND_GRH_FLAG EHCA_BMASK_IBM(17, 17)
|
||||
#define MQPCB_MASK_RETRY_COUNT EHCA_BMASK_IBM(18, 18)
|
||||
#define MQPCB_MASK_TIMEOUT EHCA_BMASK_IBM(19, 19)
|
||||
#define MQPCB_MASK_PATH_MTU EHCA_BMASK_IBM(20, 20)
|
||||
#define MQPCB_MASK_MAX_STATIC_RATE EHCA_BMASK_IBM(21, 21)
|
||||
#define MQPCB_MASK_DLID EHCA_BMASK_IBM(22, 22)
|
||||
#define MQPCB_MASK_RNR_RETRY_COUNT EHCA_BMASK_IBM(23, 23)
|
||||
#define MQPCB_MASK_SOURCE_PATH_BITS EHCA_BMASK_IBM(24, 24)
|
||||
#define MQPCB_MASK_TRAFFIC_CLASS EHCA_BMASK_IBM(25, 25)
|
||||
#define MQPCB_MASK_HOP_LIMIT EHCA_BMASK_IBM(26, 26)
|
||||
#define MQPCB_MASK_SOURCE_GID_IDX EHCA_BMASK_IBM(27, 27)
|
||||
#define MQPCB_MASK_FLOW_LABEL EHCA_BMASK_IBM(28, 28)
|
||||
#define MQPCB_MASK_DEST_GID EHCA_BMASK_IBM(30, 30)
|
||||
#define MQPCB_MASK_SERVICE_LEVEL_AL EHCA_BMASK_IBM(31, 31)
|
||||
#define MQPCB_MASK_SEND_GRH_FLAG_AL EHCA_BMASK_IBM(32, 32)
|
||||
#define MQPCB_MASK_RETRY_COUNT_AL EHCA_BMASK_IBM(33, 33)
|
||||
#define MQPCB_MASK_TIMEOUT_AL EHCA_BMASK_IBM(34, 34)
|
||||
#define MQPCB_MASK_MAX_STATIC_RATE_AL EHCA_BMASK_IBM(35, 35)
|
||||
#define MQPCB_MASK_DLID_AL EHCA_BMASK_IBM(36, 36)
|
||||
#define MQPCB_MASK_RNR_RETRY_COUNT_AL EHCA_BMASK_IBM(37, 37)
|
||||
#define MQPCB_MASK_SOURCE_PATH_BITS_AL EHCA_BMASK_IBM(38, 38)
|
||||
#define MQPCB_MASK_TRAFFIC_CLASS_AL EHCA_BMASK_IBM(39, 39)
|
||||
#define MQPCB_MASK_HOP_LIMIT_AL EHCA_BMASK_IBM(40, 40)
|
||||
#define MQPCB_MASK_SOURCE_GID_IDX_AL EHCA_BMASK_IBM(41, 41)
|
||||
#define MQPCB_MASK_FLOW_LABEL_AL EHCA_BMASK_IBM(42, 42)
|
||||
#define MQPCB_MASK_DEST_GID_AL EHCA_BMASK_IBM(44, 44)
|
||||
#define MQPCB_MASK_MAX_NR_OUTST_SEND_WR EHCA_BMASK_IBM(45, 45)
|
||||
#define MQPCB_MASK_MAX_NR_OUTST_RECV_WR EHCA_BMASK_IBM(46, 46)
|
||||
#define MQPCB_MASK_DISABLE_ETE_CREDIT_CHECK EHCA_BMASK_IBM(47, 47)
|
||||
#define MQPCB_MASK_QP_ENABLE EHCA_BMASK_IBM(48, 48)
|
||||
#define MQPCB_MASK_CURR_SRQ_LIMIT EHCA_BMASK_IBM(49, 49)
|
||||
#define MQPCB_MASK_QP_AFF_ASYN_EV_LOG_REG EHCA_BMASK_IBM(50, 50)
|
||||
#define MQPCB_MASK_SHARED_RQ_HNDL EHCA_BMASK_IBM(51, 51)
|
||||
|
||||
#endif /* __EHCA_CLASSES_PSERIES_H__ */
|
||||
@@ -1,397 +0,0 @@
|
||||
/*
|
||||
* IBM eServer eHCA Infiniband device driver for Linux on POWER
|
||||
*
|
||||
* Completion queue handling
|
||||
*
|
||||
* Authors: Waleri Fomin <fomin@de.ibm.com>
|
||||
* Khadija Souissi <souissi@de.ibm.com>
|
||||
* Reinhard Ernst <rernst@de.ibm.com>
|
||||
* Heiko J Schick <schickhj@de.ibm.com>
|
||||
* Hoang-Nam Nguyen <hnguyen@de.ibm.com>
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2005 IBM Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is distributed under a dual license of GPL v2.0 and OpenIB
|
||||
* BSD.
|
||||
*
|
||||
* OpenIB BSD License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "ehca_iverbs.h"
|
||||
#include "ehca_classes.h"
|
||||
#include "ehca_irq.h"
|
||||
#include "hcp_if.h"
|
||||
|
||||
static struct kmem_cache *cq_cache;
|
||||
|
||||
int ehca_cq_assign_qp(struct ehca_cq *cq, struct ehca_qp *qp)
|
||||
{
|
||||
unsigned int qp_num = qp->real_qp_num;
|
||||
unsigned int key = qp_num & (QP_HASHTAB_LEN-1);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&cq->spinlock, flags);
|
||||
hlist_add_head(&qp->list_entries, &cq->qp_hashtab[key]);
|
||||
spin_unlock_irqrestore(&cq->spinlock, flags);
|
||||
|
||||
ehca_dbg(cq->ib_cq.device, "cq_num=%x real_qp_num=%x",
|
||||
cq->cq_number, qp_num);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ehca_cq_unassign_qp(struct ehca_cq *cq, unsigned int real_qp_num)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
unsigned int key = real_qp_num & (QP_HASHTAB_LEN-1);
|
||||
struct hlist_node *iter;
|
||||
struct ehca_qp *qp;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&cq->spinlock, flags);
|
||||
hlist_for_each(iter, &cq->qp_hashtab[key]) {
|
||||
qp = hlist_entry(iter, struct ehca_qp, list_entries);
|
||||
if (qp->real_qp_num == real_qp_num) {
|
||||
hlist_del(iter);
|
||||
ehca_dbg(cq->ib_cq.device,
|
||||
"removed qp from cq .cq_num=%x real_qp_num=%x",
|
||||
cq->cq_number, real_qp_num);
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&cq->spinlock, flags);
|
||||
if (ret)
|
||||
ehca_err(cq->ib_cq.device,
|
||||
"qp not found cq_num=%x real_qp_num=%x",
|
||||
cq->cq_number, real_qp_num);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct ehca_qp *ehca_cq_get_qp(struct ehca_cq *cq, int real_qp_num)
|
||||
{
|
||||
struct ehca_qp *ret = NULL;
|
||||
unsigned int key = real_qp_num & (QP_HASHTAB_LEN-1);
|
||||
struct hlist_node *iter;
|
||||
struct ehca_qp *qp;
|
||||
hlist_for_each(iter, &cq->qp_hashtab[key]) {
|
||||
qp = hlist_entry(iter, struct ehca_qp, list_entries);
|
||||
if (qp->real_qp_num == real_qp_num) {
|
||||
ret = qp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct ib_cq *ehca_create_cq(struct ib_device *device,
|
||||
const struct ib_cq_init_attr *attr,
|
||||
struct ib_ucontext *context,
|
||||
struct ib_udata *udata)
|
||||
{
|
||||
int cqe = attr->cqe;
|
||||
static const u32 additional_cqe = 20;
|
||||
struct ib_cq *cq;
|
||||
struct ehca_cq *my_cq;
|
||||
struct ehca_shca *shca =
|
||||
container_of(device, struct ehca_shca, ib_device);
|
||||
struct ipz_adapter_handle adapter_handle;
|
||||
struct ehca_alloc_cq_parms param; /* h_call's out parameters */
|
||||
struct h_galpa gal;
|
||||
void *vpage;
|
||||
u32 counter;
|
||||
u64 rpage, cqx_fec, h_ret;
|
||||
int rc, i;
|
||||
unsigned long flags;
|
||||
|
||||
if (attr->flags)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
if (cqe >= 0xFFFFFFFF - 64 - additional_cqe)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
if (!atomic_add_unless(&shca->num_cqs, 1, shca->max_num_cqs)) {
|
||||
ehca_err(device, "Unable to create CQ, max number of %i "
|
||||
"CQs reached.", shca->max_num_cqs);
|
||||
ehca_err(device, "To increase the maximum number of CQs "
|
||||
"use the number_of_cqs module parameter.\n");
|
||||
return ERR_PTR(-ENOSPC);
|
||||
}
|
||||
|
||||
my_cq = kmem_cache_zalloc(cq_cache, GFP_KERNEL);
|
||||
if (!my_cq) {
|
||||
ehca_err(device, "Out of memory for ehca_cq struct device=%p",
|
||||
device);
|
||||
atomic_dec(&shca->num_cqs);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
memset(¶m, 0, sizeof(struct ehca_alloc_cq_parms));
|
||||
|
||||
spin_lock_init(&my_cq->spinlock);
|
||||
spin_lock_init(&my_cq->cb_lock);
|
||||
spin_lock_init(&my_cq->task_lock);
|
||||
atomic_set(&my_cq->nr_events, 0);
|
||||
init_waitqueue_head(&my_cq->wait_completion);
|
||||
|
||||
cq = &my_cq->ib_cq;
|
||||
|
||||
adapter_handle = shca->ipz_hca_handle;
|
||||
param.eq_handle = shca->eq.ipz_eq_handle;
|
||||
|
||||
idr_preload(GFP_KERNEL);
|
||||
write_lock_irqsave(&ehca_cq_idr_lock, flags);
|
||||
rc = idr_alloc(&ehca_cq_idr, my_cq, 0, 0x2000000, GFP_NOWAIT);
|
||||
write_unlock_irqrestore(&ehca_cq_idr_lock, flags);
|
||||
idr_preload_end();
|
||||
|
||||
if (rc < 0) {
|
||||
cq = ERR_PTR(-ENOMEM);
|
||||
ehca_err(device, "Can't allocate new idr entry. device=%p",
|
||||
device);
|
||||
goto create_cq_exit1;
|
||||
}
|
||||
my_cq->token = rc;
|
||||
|
||||
/*
|
||||
* CQs maximum depth is 4GB-64, but we need additional 20 as buffer
|
||||
* for receiving errors CQEs.
|
||||
*/
|
||||
param.nr_cqe = cqe + additional_cqe;
|
||||
h_ret = hipz_h_alloc_resource_cq(adapter_handle, my_cq, ¶m);
|
||||
|
||||
if (h_ret != H_SUCCESS) {
|
||||
ehca_err(device, "hipz_h_alloc_resource_cq() failed "
|
||||
"h_ret=%lli device=%p", h_ret, device);
|
||||
cq = ERR_PTR(ehca2ib_return_code(h_ret));
|
||||
goto create_cq_exit2;
|
||||
}
|
||||
|
||||
rc = ipz_queue_ctor(NULL, &my_cq->ipz_queue, param.act_pages,
|
||||
EHCA_PAGESIZE, sizeof(struct ehca_cqe), 0, 0);
|
||||
if (!rc) {
|
||||
ehca_err(device, "ipz_queue_ctor() failed ipz_rc=%i device=%p",
|
||||
rc, device);
|
||||
cq = ERR_PTR(-EINVAL);
|
||||
goto create_cq_exit3;
|
||||
}
|
||||
|
||||
for (counter = 0; counter < param.act_pages; counter++) {
|
||||
vpage = ipz_qpageit_get_inc(&my_cq->ipz_queue);
|
||||
if (!vpage) {
|
||||
ehca_err(device, "ipz_qpageit_get_inc() "
|
||||
"returns NULL device=%p", device);
|
||||
cq = ERR_PTR(-EAGAIN);
|
||||
goto create_cq_exit4;
|
||||
}
|
||||
rpage = __pa(vpage);
|
||||
|
||||
h_ret = hipz_h_register_rpage_cq(adapter_handle,
|
||||
my_cq->ipz_cq_handle,
|
||||
&my_cq->pf,
|
||||
0,
|
||||
0,
|
||||
rpage,
|
||||
1,
|
||||
my_cq->galpas.
|
||||
kernel);
|
||||
|
||||
if (h_ret < H_SUCCESS) {
|
||||
ehca_err(device, "hipz_h_register_rpage_cq() failed "
|
||||
"ehca_cq=%p cq_num=%x h_ret=%lli counter=%i "
|
||||
"act_pages=%i", my_cq, my_cq->cq_number,
|
||||
h_ret, counter, param.act_pages);
|
||||
cq = ERR_PTR(-EINVAL);
|
||||
goto create_cq_exit4;
|
||||
}
|
||||
|
||||
if (counter == (param.act_pages - 1)) {
|
||||
vpage = ipz_qpageit_get_inc(&my_cq->ipz_queue);
|
||||
if ((h_ret != H_SUCCESS) || vpage) {
|
||||
ehca_err(device, "Registration of pages not "
|
||||
"complete ehca_cq=%p cq_num=%x "
|
||||
"h_ret=%lli", my_cq, my_cq->cq_number,
|
||||
h_ret);
|
||||
cq = ERR_PTR(-EAGAIN);
|
||||
goto create_cq_exit4;
|
||||
}
|
||||
} else {
|
||||
if (h_ret != H_PAGE_REGISTERED) {
|
||||
ehca_err(device, "Registration of page failed "
|
||||
"ehca_cq=%p cq_num=%x h_ret=%lli "
|
||||
"counter=%i act_pages=%i",
|
||||
my_cq, my_cq->cq_number,
|
||||
h_ret, counter, param.act_pages);
|
||||
cq = ERR_PTR(-ENOMEM);
|
||||
goto create_cq_exit4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ipz_qeit_reset(&my_cq->ipz_queue);
|
||||
|
||||
gal = my_cq->galpas.kernel;
|
||||
cqx_fec = hipz_galpa_load(gal, CQTEMM_OFFSET(cqx_fec));
|
||||
ehca_dbg(device, "ehca_cq=%p cq_num=%x CQX_FEC=%llx",
|
||||
my_cq, my_cq->cq_number, cqx_fec);
|
||||
|
||||
my_cq->ib_cq.cqe = my_cq->nr_of_entries =
|
||||
param.act_nr_of_entries - additional_cqe;
|
||||
my_cq->cq_number = (my_cq->ipz_cq_handle.handle) & 0xffff;
|
||||
|
||||
for (i = 0; i < QP_HASHTAB_LEN; i++)
|
||||
INIT_HLIST_HEAD(&my_cq->qp_hashtab[i]);
|
||||
|
||||
INIT_LIST_HEAD(&my_cq->sqp_err_list);
|
||||
INIT_LIST_HEAD(&my_cq->rqp_err_list);
|
||||
|
||||
if (context) {
|
||||
struct ipz_queue *ipz_queue = &my_cq->ipz_queue;
|
||||
struct ehca_create_cq_resp resp;
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
resp.cq_number = my_cq->cq_number;
|
||||
resp.token = my_cq->token;
|
||||
resp.ipz_queue.qe_size = ipz_queue->qe_size;
|
||||
resp.ipz_queue.act_nr_of_sg = ipz_queue->act_nr_of_sg;
|
||||
resp.ipz_queue.queue_length = ipz_queue->queue_length;
|
||||
resp.ipz_queue.pagesize = ipz_queue->pagesize;
|
||||
resp.ipz_queue.toggle_state = ipz_queue->toggle_state;
|
||||
resp.fw_handle_ofs = (u32)
|
||||
(my_cq->galpas.user.fw_handle & (PAGE_SIZE - 1));
|
||||
if (ib_copy_to_udata(udata, &resp, sizeof(resp))) {
|
||||
ehca_err(device, "Copy to udata failed.");
|
||||
cq = ERR_PTR(-EFAULT);
|
||||
goto create_cq_exit4;
|
||||
}
|
||||
}
|
||||
|
||||
return cq;
|
||||
|
||||
create_cq_exit4:
|
||||
ipz_queue_dtor(NULL, &my_cq->ipz_queue);
|
||||
|
||||
create_cq_exit3:
|
||||
h_ret = hipz_h_destroy_cq(adapter_handle, my_cq, 1);
|
||||
if (h_ret != H_SUCCESS)
|
||||
ehca_err(device, "hipz_h_destroy_cq() failed ehca_cq=%p "
|
||||
"cq_num=%x h_ret=%lli", my_cq, my_cq->cq_number, h_ret);
|
||||
|
||||
create_cq_exit2:
|
||||
write_lock_irqsave(&ehca_cq_idr_lock, flags);
|
||||
idr_remove(&ehca_cq_idr, my_cq->token);
|
||||
write_unlock_irqrestore(&ehca_cq_idr_lock, flags);
|
||||
|
||||
create_cq_exit1:
|
||||
kmem_cache_free(cq_cache, my_cq);
|
||||
|
||||
atomic_dec(&shca->num_cqs);
|
||||
return cq;
|
||||
}
|
||||
|
||||
int ehca_destroy_cq(struct ib_cq *cq)
|
||||
{
|
||||
u64 h_ret;
|
||||
struct ehca_cq *my_cq = container_of(cq, struct ehca_cq, ib_cq);
|
||||
int cq_num = my_cq->cq_number;
|
||||
struct ib_device *device = cq->device;
|
||||
struct ehca_shca *shca = container_of(device, struct ehca_shca,
|
||||
ib_device);
|
||||
struct ipz_adapter_handle adapter_handle = shca->ipz_hca_handle;
|
||||
unsigned long flags;
|
||||
|
||||
if (cq->uobject) {
|
||||
if (my_cq->mm_count_galpa || my_cq->mm_count_queue) {
|
||||
ehca_err(device, "Resources still referenced in "
|
||||
"user space cq_num=%x", my_cq->cq_number);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* remove the CQ from the idr first to make sure
|
||||
* no more interrupt tasklets will touch this CQ
|
||||
*/
|
||||
write_lock_irqsave(&ehca_cq_idr_lock, flags);
|
||||
idr_remove(&ehca_cq_idr, my_cq->token);
|
||||
write_unlock_irqrestore(&ehca_cq_idr_lock, flags);
|
||||
|
||||
/* now wait until all pending events have completed */
|
||||
wait_event(my_cq->wait_completion, !atomic_read(&my_cq->nr_events));
|
||||
|
||||
/* nobody's using our CQ any longer -- we can destroy it */
|
||||
h_ret = hipz_h_destroy_cq(adapter_handle, my_cq, 0);
|
||||
if (h_ret == H_R_STATE) {
|
||||
/* cq in err: read err data and destroy it forcibly */
|
||||
ehca_dbg(device, "ehca_cq=%p cq_num=%x resource=%llx in err "
|
||||
"state. Try to delete it forcibly.",
|
||||
my_cq, cq_num, my_cq->ipz_cq_handle.handle);
|
||||
ehca_error_data(shca, my_cq, my_cq->ipz_cq_handle.handle);
|
||||
h_ret = hipz_h_destroy_cq(adapter_handle, my_cq, 1);
|
||||
if (h_ret == H_SUCCESS)
|
||||
ehca_dbg(device, "cq_num=%x deleted successfully.",
|
||||
cq_num);
|
||||
}
|
||||
if (h_ret != H_SUCCESS) {
|
||||
ehca_err(device, "hipz_h_destroy_cq() failed h_ret=%lli "
|
||||
"ehca_cq=%p cq_num=%x", h_ret, my_cq, cq_num);
|
||||
return ehca2ib_return_code(h_ret);
|
||||
}
|
||||
ipz_queue_dtor(NULL, &my_cq->ipz_queue);
|
||||
kmem_cache_free(cq_cache, my_cq);
|
||||
|
||||
atomic_dec(&shca->num_cqs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ehca_resize_cq(struct ib_cq *cq, int cqe, struct ib_udata *udata)
|
||||
{
|
||||
/* TODO: proper resize needs to be done */
|
||||
ehca_err(cq->device, "not implemented yet");
|
||||
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
int ehca_init_cq_cache(void)
|
||||
{
|
||||
cq_cache = kmem_cache_create("ehca_cache_cq",
|
||||
sizeof(struct ehca_cq), 0,
|
||||
SLAB_HWCACHE_ALIGN,
|
||||
NULL);
|
||||
if (!cq_cache)
|
||||
return -ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ehca_cleanup_cq_cache(void)
|
||||
{
|
||||
kmem_cache_destroy(cq_cache);
|
||||
}
|
||||
@@ -1,189 +0,0 @@
|
||||
/*
|
||||
* IBM eServer eHCA Infiniband device driver for Linux on POWER
|
||||
*
|
||||
* Event queue handling
|
||||
*
|
||||
* Authors: Waleri Fomin <fomin@de.ibm.com>
|
||||
* Khadija Souissi <souissi@de.ibm.com>
|
||||
* Reinhard Ernst <rernst@de.ibm.com>
|
||||
* Heiko J Schick <schickhj@de.ibm.com>
|
||||
* Hoang-Nam Nguyen <hnguyen@de.ibm.com>
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2005 IBM Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is distributed under a dual license of GPL v2.0 and OpenIB
|
||||
* BSD.
|
||||
*
|
||||
* OpenIB BSD License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "ehca_classes.h"
|
||||
#include "ehca_irq.h"
|
||||
#include "ehca_iverbs.h"
|
||||
#include "ehca_qes.h"
|
||||
#include "hcp_if.h"
|
||||
#include "ipz_pt_fn.h"
|
||||
|
||||
int ehca_create_eq(struct ehca_shca *shca,
|
||||
struct ehca_eq *eq,
|
||||
const enum ehca_eq_type type, const u32 length)
|
||||
{
|
||||
int ret;
|
||||
u64 h_ret;
|
||||
u32 nr_pages;
|
||||
u32 i;
|
||||
void *vpage;
|
||||
struct ib_device *ib_dev = &shca->ib_device;
|
||||
|
||||
spin_lock_init(&eq->spinlock);
|
||||
spin_lock_init(&eq->irq_spinlock);
|
||||
eq->is_initialized = 0;
|
||||
|
||||
if (type != EHCA_EQ && type != EHCA_NEQ) {
|
||||
ehca_err(ib_dev, "Invalid EQ type %x. eq=%p", type, eq);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!length) {
|
||||
ehca_err(ib_dev, "EQ length must not be zero. eq=%p", eq);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
h_ret = hipz_h_alloc_resource_eq(shca->ipz_hca_handle,
|
||||
&eq->pf,
|
||||
type,
|
||||
length,
|
||||
&eq->ipz_eq_handle,
|
||||
&eq->length,
|
||||
&nr_pages, &eq->ist);
|
||||
|
||||
if (h_ret != H_SUCCESS) {
|
||||
ehca_err(ib_dev, "Can't allocate EQ/NEQ. eq=%p", eq);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = ipz_queue_ctor(NULL, &eq->ipz_queue, nr_pages,
|
||||
EHCA_PAGESIZE, sizeof(struct ehca_eqe), 0, 0);
|
||||
if (!ret) {
|
||||
ehca_err(ib_dev, "Can't allocate EQ pages eq=%p", eq);
|
||||
goto create_eq_exit1;
|
||||
}
|
||||
|
||||
for (i = 0; i < nr_pages; i++) {
|
||||
u64 rpage;
|
||||
|
||||
vpage = ipz_qpageit_get_inc(&eq->ipz_queue);
|
||||
if (!vpage)
|
||||
goto create_eq_exit2;
|
||||
|
||||
rpage = __pa(vpage);
|
||||
h_ret = hipz_h_register_rpage_eq(shca->ipz_hca_handle,
|
||||
eq->ipz_eq_handle,
|
||||
&eq->pf,
|
||||
0, 0, rpage, 1);
|
||||
|
||||
if (i == (nr_pages - 1)) {
|
||||
/* last page */
|
||||
vpage = ipz_qpageit_get_inc(&eq->ipz_queue);
|
||||
if (h_ret != H_SUCCESS || vpage)
|
||||
goto create_eq_exit2;
|
||||
} else {
|
||||
if (h_ret != H_PAGE_REGISTERED)
|
||||
goto create_eq_exit2;
|
||||
}
|
||||
}
|
||||
|
||||
ipz_qeit_reset(&eq->ipz_queue);
|
||||
|
||||
/* register interrupt handlers and initialize work queues */
|
||||
if (type == EHCA_EQ) {
|
||||
tasklet_init(&eq->interrupt_task, ehca_tasklet_eq, (long)shca);
|
||||
|
||||
ret = ibmebus_request_irq(eq->ist, ehca_interrupt_eq,
|
||||
0, "ehca_eq",
|
||||
(void *)shca);
|
||||
if (ret < 0)
|
||||
ehca_err(ib_dev, "Can't map interrupt handler.");
|
||||
} else if (type == EHCA_NEQ) {
|
||||
tasklet_init(&eq->interrupt_task, ehca_tasklet_neq, (long)shca);
|
||||
|
||||
ret = ibmebus_request_irq(eq->ist, ehca_interrupt_neq,
|
||||
0, "ehca_neq",
|
||||
(void *)shca);
|
||||
if (ret < 0)
|
||||
ehca_err(ib_dev, "Can't map interrupt handler.");
|
||||
}
|
||||
|
||||
eq->is_initialized = 1;
|
||||
|
||||
return 0;
|
||||
|
||||
create_eq_exit2:
|
||||
ipz_queue_dtor(NULL, &eq->ipz_queue);
|
||||
|
||||
create_eq_exit1:
|
||||
hipz_h_destroy_eq(shca->ipz_hca_handle, eq);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
void *ehca_poll_eq(struct ehca_shca *shca, struct ehca_eq *eq)
|
||||
{
|
||||
unsigned long flags;
|
||||
void *eqe;
|
||||
|
||||
spin_lock_irqsave(&eq->spinlock, flags);
|
||||
eqe = ipz_eqit_eq_get_inc_valid(&eq->ipz_queue);
|
||||
spin_unlock_irqrestore(&eq->spinlock, flags);
|
||||
|
||||
return eqe;
|
||||
}
|
||||
|
||||
int ehca_destroy_eq(struct ehca_shca *shca, struct ehca_eq *eq)
|
||||
{
|
||||
unsigned long flags;
|
||||
u64 h_ret;
|
||||
|
||||
ibmebus_free_irq(eq->ist, (void *)shca);
|
||||
|
||||
spin_lock_irqsave(&shca_list_lock, flags);
|
||||
eq->is_initialized = 0;
|
||||
spin_unlock_irqrestore(&shca_list_lock, flags);
|
||||
|
||||
tasklet_kill(&eq->interrupt_task);
|
||||
|
||||
h_ret = hipz_h_destroy_eq(shca->ipz_hca_handle, eq);
|
||||
|
||||
if (h_ret != H_SUCCESS) {
|
||||
ehca_err(&shca->ib_device, "Can't free EQ resources.");
|
||||
return -EINVAL;
|
||||
}
|
||||
ipz_queue_dtor(NULL, &eq->ipz_queue);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,414 +0,0 @@
|
||||
/*
|
||||
* IBM eServer eHCA Infiniband device driver for Linux on POWER
|
||||
*
|
||||
* HCA query functions
|
||||
*
|
||||
* Authors: Heiko J Schick <schickhj@de.ibm.com>
|
||||
* Christoph Raisch <raisch@de.ibm.com>
|
||||
*
|
||||
* Copyright (c) 2005 IBM Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is distributed under a dual license of GPL v2.0 and OpenIB
|
||||
* BSD.
|
||||
*
|
||||
* OpenIB BSD License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <linux/gfp.h>
|
||||
|
||||
#include "ehca_tools.h"
|
||||
#include "ehca_iverbs.h"
|
||||
#include "hcp_if.h"
|
||||
|
||||
static unsigned int limit_uint(unsigned int value)
|
||||
{
|
||||
return min_t(unsigned int, value, INT_MAX);
|
||||
}
|
||||
|
||||
int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props,
|
||||
struct ib_udata *uhw)
|
||||
{
|
||||
int i, ret = 0;
|
||||
struct ehca_shca *shca = container_of(ibdev, struct ehca_shca,
|
||||
ib_device);
|
||||
struct hipz_query_hca *rblock;
|
||||
|
||||
static const u32 cap_mapping[] = {
|
||||
IB_DEVICE_RESIZE_MAX_WR, HCA_CAP_WQE_RESIZE,
|
||||
IB_DEVICE_BAD_PKEY_CNTR, HCA_CAP_BAD_P_KEY_CTR,
|
||||
IB_DEVICE_BAD_QKEY_CNTR, HCA_CAP_Q_KEY_VIOL_CTR,
|
||||
IB_DEVICE_RAW_MULTI, HCA_CAP_RAW_PACKET_MCAST,
|
||||
IB_DEVICE_AUTO_PATH_MIG, HCA_CAP_AUTO_PATH_MIG,
|
||||
IB_DEVICE_CHANGE_PHY_PORT, HCA_CAP_SQD_RTS_PORT_CHANGE,
|
||||
IB_DEVICE_UD_AV_PORT_ENFORCE, HCA_CAP_AH_PORT_NR_CHECK,
|
||||
IB_DEVICE_CURR_QP_STATE_MOD, HCA_CAP_CUR_QP_STATE_MOD,
|
||||
IB_DEVICE_SHUTDOWN_PORT, HCA_CAP_SHUTDOWN_PORT,
|
||||
IB_DEVICE_INIT_TYPE, HCA_CAP_INIT_TYPE,
|
||||
IB_DEVICE_PORT_ACTIVE_EVENT, HCA_CAP_PORT_ACTIVE_EVENT,
|
||||
};
|
||||
|
||||
if (uhw->inlen || uhw->outlen)
|
||||
return -EINVAL;
|
||||
|
||||
rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
|
||||
if (!rblock) {
|
||||
ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (hipz_h_query_hca(shca->ipz_hca_handle, rblock) != H_SUCCESS) {
|
||||
ehca_err(&shca->ib_device, "Can't query device properties");
|
||||
ret = -EINVAL;
|
||||
goto query_device1;
|
||||
}
|
||||
|
||||
memset(props, 0, sizeof(struct ib_device_attr));
|
||||
props->page_size_cap = shca->hca_cap_mr_pgsize;
|
||||
props->fw_ver = rblock->hw_ver;
|
||||
props->max_mr_size = rblock->max_mr_size;
|
||||
props->vendor_id = rblock->vendor_id >> 8;
|
||||
props->vendor_part_id = rblock->vendor_part_id >> 16;
|
||||
props->hw_ver = rblock->hw_ver;
|
||||
props->max_qp = limit_uint(rblock->max_qp);
|
||||
props->max_qp_wr = limit_uint(rblock->max_wqes_wq);
|
||||
props->max_sge = limit_uint(rblock->max_sge);
|
||||
props->max_sge_rd = limit_uint(rblock->max_sge_rd);
|
||||
props->max_cq = limit_uint(rblock->max_cq);
|
||||
props->max_cqe = limit_uint(rblock->max_cqe);
|
||||
props->max_mr = limit_uint(rblock->max_mr);
|
||||
props->max_mw = limit_uint(rblock->max_mw);
|
||||
props->max_pd = limit_uint(rblock->max_pd);
|
||||
props->max_ah = limit_uint(rblock->max_ah);
|
||||
props->max_ee = limit_uint(rblock->max_rd_ee_context);
|
||||
props->max_rdd = limit_uint(rblock->max_rd_domain);
|
||||
props->max_fmr = limit_uint(rblock->max_mr);
|
||||
props->max_qp_rd_atom = limit_uint(rblock->max_rr_qp);
|
||||
props->max_ee_rd_atom = limit_uint(rblock->max_rr_ee_context);
|
||||
props->max_res_rd_atom = limit_uint(rblock->max_rr_hca);
|
||||
props->max_qp_init_rd_atom = limit_uint(rblock->max_act_wqs_qp);
|
||||
props->max_ee_init_rd_atom = limit_uint(rblock->max_act_wqs_ee_context);
|
||||
|
||||
if (EHCA_BMASK_GET(HCA_CAP_SRQ, shca->hca_cap)) {
|
||||
props->max_srq = limit_uint(props->max_qp);
|
||||
props->max_srq_wr = limit_uint(props->max_qp_wr);
|
||||
props->max_srq_sge = 3;
|
||||
}
|
||||
|
||||
props->max_pkeys = 16;
|
||||
/* Some FW versions say 0 here; insert sensible value in that case */
|
||||
props->local_ca_ack_delay = rblock->local_ca_ack_delay ?
|
||||
min_t(u8, rblock->local_ca_ack_delay, 255) : 12;
|
||||
props->max_raw_ipv6_qp = limit_uint(rblock->max_raw_ipv6_qp);
|
||||
props->max_raw_ethy_qp = limit_uint(rblock->max_raw_ethy_qp);
|
||||
props->max_mcast_grp = limit_uint(rblock->max_mcast_grp);
|
||||
props->max_mcast_qp_attach = limit_uint(rblock->max_mcast_qp_attach);
|
||||
props->max_total_mcast_qp_attach
|
||||
= limit_uint(rblock->max_total_mcast_qp_attach);
|
||||
|
||||
/* translate device capabilities */
|
||||
props->device_cap_flags = IB_DEVICE_SYS_IMAGE_GUID |
|
||||
IB_DEVICE_RC_RNR_NAK_GEN | IB_DEVICE_N_NOTIFY_CQ;
|
||||
for (i = 0; i < ARRAY_SIZE(cap_mapping); i += 2)
|
||||
if (rblock->hca_cap_indicators & cap_mapping[i + 1])
|
||||
props->device_cap_flags |= cap_mapping[i];
|
||||
|
||||
query_device1:
|
||||
ehca_free_fw_ctrlblock(rblock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static enum ib_mtu map_mtu(struct ehca_shca *shca, u32 fw_mtu)
|
||||
{
|
||||
switch (fw_mtu) {
|
||||
case 0x1:
|
||||
return IB_MTU_256;
|
||||
case 0x2:
|
||||
return IB_MTU_512;
|
||||
case 0x3:
|
||||
return IB_MTU_1024;
|
||||
case 0x4:
|
||||
return IB_MTU_2048;
|
||||
case 0x5:
|
||||
return IB_MTU_4096;
|
||||
default:
|
||||
ehca_err(&shca->ib_device, "Unknown MTU size: %x.",
|
||||
fw_mtu);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static u8 map_number_of_vls(struct ehca_shca *shca, u32 vl_cap)
|
||||
{
|
||||
switch (vl_cap) {
|
||||
case 0x1:
|
||||
return 1;
|
||||
case 0x2:
|
||||
return 2;
|
||||
case 0x3:
|
||||
return 4;
|
||||
case 0x4:
|
||||
return 8;
|
||||
case 0x5:
|
||||
return 15;
|
||||
default:
|
||||
ehca_err(&shca->ib_device, "invalid Vl Capability: %x.",
|
||||
vl_cap);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int ehca_query_port(struct ib_device *ibdev,
|
||||
u8 port, struct ib_port_attr *props)
|
||||
{
|
||||
int ret = 0;
|
||||
u64 h_ret;
|
||||
struct ehca_shca *shca = container_of(ibdev, struct ehca_shca,
|
||||
ib_device);
|
||||
struct hipz_query_port *rblock;
|
||||
|
||||
rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
|
||||
if (!rblock) {
|
||||
ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
h_ret = hipz_h_query_port(shca->ipz_hca_handle, port, rblock);
|
||||
if (h_ret != H_SUCCESS) {
|
||||
ehca_err(&shca->ib_device, "Can't query port properties");
|
||||
ret = -EINVAL;
|
||||
goto query_port1;
|
||||
}
|
||||
|
||||
memset(props, 0, sizeof(struct ib_port_attr));
|
||||
|
||||
props->active_mtu = props->max_mtu = map_mtu(shca, rblock->max_mtu);
|
||||
props->port_cap_flags = rblock->capability_mask;
|
||||
props->gid_tbl_len = rblock->gid_tbl_len;
|
||||
if (rblock->max_msg_sz)
|
||||
props->max_msg_sz = rblock->max_msg_sz;
|
||||
else
|
||||
props->max_msg_sz = 0x1 << 31;
|
||||
props->bad_pkey_cntr = rblock->bad_pkey_cntr;
|
||||
props->qkey_viol_cntr = rblock->qkey_viol_cntr;
|
||||
props->pkey_tbl_len = rblock->pkey_tbl_len;
|
||||
props->lid = rblock->lid;
|
||||
props->sm_lid = rblock->sm_lid;
|
||||
props->lmc = rblock->lmc;
|
||||
props->sm_sl = rblock->sm_sl;
|
||||
props->subnet_timeout = rblock->subnet_timeout;
|
||||
props->init_type_reply = rblock->init_type_reply;
|
||||
props->max_vl_num = map_number_of_vls(shca, rblock->vl_cap);
|
||||
|
||||
if (rblock->state && rblock->phys_width) {
|
||||
props->phys_state = rblock->phys_pstate;
|
||||
props->state = rblock->phys_state;
|
||||
props->active_width = rblock->phys_width;
|
||||
props->active_speed = rblock->phys_speed;
|
||||
} else {
|
||||
/* old firmware releases don't report physical
|
||||
* port info, so use default values
|
||||
*/
|
||||
props->phys_state = 5;
|
||||
props->state = rblock->state;
|
||||
props->active_width = IB_WIDTH_12X;
|
||||
props->active_speed = IB_SPEED_SDR;
|
||||
}
|
||||
|
||||
query_port1:
|
||||
ehca_free_fw_ctrlblock(rblock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ehca_query_sma_attr(struct ehca_shca *shca,
|
||||
u8 port, struct ehca_sma_attr *attr)
|
||||
{
|
||||
int ret = 0;
|
||||
u64 h_ret;
|
||||
struct hipz_query_port *rblock;
|
||||
|
||||
rblock = ehca_alloc_fw_ctrlblock(GFP_ATOMIC);
|
||||
if (!rblock) {
|
||||
ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
h_ret = hipz_h_query_port(shca->ipz_hca_handle, port, rblock);
|
||||
if (h_ret != H_SUCCESS) {
|
||||
ehca_err(&shca->ib_device, "Can't query port properties");
|
||||
ret = -EINVAL;
|
||||
goto query_sma_attr1;
|
||||
}
|
||||
|
||||
memset(attr, 0, sizeof(struct ehca_sma_attr));
|
||||
|
||||
attr->lid = rblock->lid;
|
||||
attr->lmc = rblock->lmc;
|
||||
attr->sm_sl = rblock->sm_sl;
|
||||
attr->sm_lid = rblock->sm_lid;
|
||||
|
||||
attr->pkey_tbl_len = rblock->pkey_tbl_len;
|
||||
memcpy(attr->pkeys, rblock->pkey_entries, sizeof(attr->pkeys));
|
||||
|
||||
query_sma_attr1:
|
||||
ehca_free_fw_ctrlblock(rblock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey)
|
||||
{
|
||||
int ret = 0;
|
||||
u64 h_ret;
|
||||
struct ehca_shca *shca;
|
||||
struct hipz_query_port *rblock;
|
||||
|
||||
shca = container_of(ibdev, struct ehca_shca, ib_device);
|
||||
if (index > 16) {
|
||||
ehca_err(&shca->ib_device, "Invalid index: %x.", index);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
|
||||
if (!rblock) {
|
||||
ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
h_ret = hipz_h_query_port(shca->ipz_hca_handle, port, rblock);
|
||||
if (h_ret != H_SUCCESS) {
|
||||
ehca_err(&shca->ib_device, "Can't query port properties");
|
||||
ret = -EINVAL;
|
||||
goto query_pkey1;
|
||||
}
|
||||
|
||||
memcpy(pkey, &rblock->pkey_entries + index, sizeof(u16));
|
||||
|
||||
query_pkey1:
|
||||
ehca_free_fw_ctrlblock(rblock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ehca_query_gid(struct ib_device *ibdev, u8 port,
|
||||
int index, union ib_gid *gid)
|
||||
{
|
||||
int ret = 0;
|
||||
u64 h_ret;
|
||||
struct ehca_shca *shca = container_of(ibdev, struct ehca_shca,
|
||||
ib_device);
|
||||
struct hipz_query_port *rblock;
|
||||
|
||||
if (index < 0 || index > 255) {
|
||||
ehca_err(&shca->ib_device, "Invalid index: %x.", index);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
|
||||
if (!rblock) {
|
||||
ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
h_ret = hipz_h_query_port(shca->ipz_hca_handle, port, rblock);
|
||||
if (h_ret != H_SUCCESS) {
|
||||
ehca_err(&shca->ib_device, "Can't query port properties");
|
||||
ret = -EINVAL;
|
||||
goto query_gid1;
|
||||
}
|
||||
|
||||
memcpy(&gid->raw[0], &rblock->gid_prefix, sizeof(u64));
|
||||
memcpy(&gid->raw[8], &rblock->guid_entries[index], sizeof(u64));
|
||||
|
||||
query_gid1:
|
||||
ehca_free_fw_ctrlblock(rblock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const u32 allowed_port_caps = (
|
||||
IB_PORT_SM | IB_PORT_LED_INFO_SUP | IB_PORT_CM_SUP |
|
||||
IB_PORT_SNMP_TUNNEL_SUP | IB_PORT_DEVICE_MGMT_SUP |
|
||||
IB_PORT_VENDOR_CLASS_SUP);
|
||||
|
||||
int ehca_modify_port(struct ib_device *ibdev,
|
||||
u8 port, int port_modify_mask,
|
||||
struct ib_port_modify *props)
|
||||
{
|
||||
int ret = 0;
|
||||
struct ehca_shca *shca;
|
||||
struct hipz_query_port *rblock;
|
||||
u32 cap;
|
||||
u64 hret;
|
||||
|
||||
shca = container_of(ibdev, struct ehca_shca, ib_device);
|
||||
if ((props->set_port_cap_mask | props->clr_port_cap_mask)
|
||||
& ~allowed_port_caps) {
|
||||
ehca_err(&shca->ib_device, "Non-changeable bits set in masks "
|
||||
"set=%x clr=%x allowed=%x", props->set_port_cap_mask,
|
||||
props->clr_port_cap_mask, allowed_port_caps);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (mutex_lock_interruptible(&shca->modify_mutex))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
|
||||
if (!rblock) {
|
||||
ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
|
||||
ret = -ENOMEM;
|
||||
goto modify_port1;
|
||||
}
|
||||
|
||||
hret = hipz_h_query_port(shca->ipz_hca_handle, port, rblock);
|
||||
if (hret != H_SUCCESS) {
|
||||
ehca_err(&shca->ib_device, "Can't query port properties");
|
||||
ret = -EINVAL;
|
||||
goto modify_port2;
|
||||
}
|
||||
|
||||
cap = (rblock->capability_mask | props->set_port_cap_mask)
|
||||
& ~props->clr_port_cap_mask;
|
||||
|
||||
hret = hipz_h_modify_port(shca->ipz_hca_handle, port,
|
||||
cap, props->init_type, port_modify_mask);
|
||||
if (hret != H_SUCCESS) {
|
||||
ehca_err(&shca->ib_device, "Modify port failed h_ret=%lli",
|
||||
hret);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
modify_port2:
|
||||
ehca_free_fw_ctrlblock(rblock);
|
||||
|
||||
modify_port1:
|
||||
mutex_unlock(&shca->modify_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* IBM eServer eHCA Infiniband device driver for Linux on POWER
|
||||
*
|
||||
* Function definitions and structs for EQs, NEQs and interrupts
|
||||
*
|
||||
* Authors: Heiko J Schick <schickhj@de.ibm.com>
|
||||
* Khadija Souissi <souissi@de.ibm.com>
|
||||
*
|
||||
* Copyright (c) 2005 IBM Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is distributed under a dual license of GPL v2.0 and OpenIB
|
||||
* BSD.
|
||||
*
|
||||
* OpenIB BSD License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __EHCA_IRQ_H
|
||||
#define __EHCA_IRQ_H
|
||||
|
||||
|
||||
struct ehca_shca;
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
int ehca_error_data(struct ehca_shca *shca, void *data, u64 resource);
|
||||
|
||||
irqreturn_t ehca_interrupt_neq(int irq, void *dev_id);
|
||||
void ehca_tasklet_neq(unsigned long data);
|
||||
|
||||
irqreturn_t ehca_interrupt_eq(int irq, void *dev_id);
|
||||
void ehca_tasklet_eq(unsigned long data);
|
||||
void ehca_process_eq(struct ehca_shca *shca, int is_irq);
|
||||
|
||||
struct ehca_cpu_comp_task {
|
||||
struct list_head cq_list;
|
||||
spinlock_t task_lock;
|
||||
int cq_jobs;
|
||||
int active;
|
||||
};
|
||||
|
||||
struct ehca_comp_pool {
|
||||
struct ehca_cpu_comp_task __percpu *cpu_comp_tasks;
|
||||
struct task_struct * __percpu *cpu_comp_threads;
|
||||
int last_cpu;
|
||||
spinlock_t last_cpu_lock;
|
||||
};
|
||||
|
||||
int ehca_create_comp_pool(void);
|
||||
void ehca_destroy_comp_pool(void);
|
||||
|
||||
#endif
|
||||
@@ -1,202 +0,0 @@
|
||||
/*
|
||||
* IBM eServer eHCA Infiniband device driver for Linux on POWER
|
||||
*
|
||||
* Function definitions for internal functions
|
||||
*
|
||||
* Authors: Heiko J Schick <schickhj@de.ibm.com>
|
||||
* Dietmar Decker <ddecker@de.ibm.com>
|
||||
*
|
||||
* Copyright (c) 2005 IBM Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is distributed under a dual license of GPL v2.0 and OpenIB
|
||||
* BSD.
|
||||
*
|
||||
* OpenIB BSD License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __EHCA_IVERBS_H__
|
||||
#define __EHCA_IVERBS_H__
|
||||
|
||||
#include "ehca_classes.h"
|
||||
|
||||
int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props,
|
||||
struct ib_udata *uhw);
|
||||
|
||||
int ehca_query_port(struct ib_device *ibdev, u8 port,
|
||||
struct ib_port_attr *props);
|
||||
|
||||
enum rdma_protocol_type
|
||||
ehca_query_protocol(struct ib_device *device, u8 port_num);
|
||||
|
||||
int ehca_query_sma_attr(struct ehca_shca *shca, u8 port,
|
||||
struct ehca_sma_attr *attr);
|
||||
|
||||
int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 * pkey);
|
||||
|
||||
int ehca_query_gid(struct ib_device *ibdev, u8 port, int index,
|
||||
union ib_gid *gid);
|
||||
|
||||
int ehca_modify_port(struct ib_device *ibdev, u8 port, int port_modify_mask,
|
||||
struct ib_port_modify *props);
|
||||
|
||||
struct ib_pd *ehca_alloc_pd(struct ib_device *device,
|
||||
struct ib_ucontext *context,
|
||||
struct ib_udata *udata);
|
||||
|
||||
int ehca_dealloc_pd(struct ib_pd *pd);
|
||||
|
||||
struct ib_ah *ehca_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr);
|
||||
|
||||
int ehca_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr);
|
||||
|
||||
int ehca_query_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr);
|
||||
|
||||
int ehca_destroy_ah(struct ib_ah *ah);
|
||||
|
||||
struct ib_mr *ehca_get_dma_mr(struct ib_pd *pd, int mr_access_flags);
|
||||
|
||||
struct ib_mr *ehca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
|
||||
u64 virt, int mr_access_flags,
|
||||
struct ib_udata *udata);
|
||||
|
||||
int ehca_dereg_mr(struct ib_mr *mr);
|
||||
|
||||
struct ib_mw *ehca_alloc_mw(struct ib_pd *pd, enum ib_mw_type type);
|
||||
|
||||
int ehca_dealloc_mw(struct ib_mw *mw);
|
||||
|
||||
struct ib_fmr *ehca_alloc_fmr(struct ib_pd *pd,
|
||||
int mr_access_flags,
|
||||
struct ib_fmr_attr *fmr_attr);
|
||||
|
||||
int ehca_map_phys_fmr(struct ib_fmr *fmr,
|
||||
u64 *page_list, int list_len, u64 iova);
|
||||
|
||||
int ehca_unmap_fmr(struct list_head *fmr_list);
|
||||
|
||||
int ehca_dealloc_fmr(struct ib_fmr *fmr);
|
||||
|
||||
enum ehca_eq_type {
|
||||
EHCA_EQ = 0, /* Event Queue */
|
||||
EHCA_NEQ /* Notification Event Queue */
|
||||
};
|
||||
|
||||
int ehca_create_eq(struct ehca_shca *shca, struct ehca_eq *eq,
|
||||
enum ehca_eq_type type, const u32 length);
|
||||
|
||||
int ehca_destroy_eq(struct ehca_shca *shca, struct ehca_eq *eq);
|
||||
|
||||
void *ehca_poll_eq(struct ehca_shca *shca, struct ehca_eq *eq);
|
||||
|
||||
|
||||
struct ib_cq *ehca_create_cq(struct ib_device *device,
|
||||
const struct ib_cq_init_attr *attr,
|
||||
struct ib_ucontext *context,
|
||||
struct ib_udata *udata);
|
||||
|
||||
int ehca_destroy_cq(struct ib_cq *cq);
|
||||
|
||||
int ehca_resize_cq(struct ib_cq *cq, int cqe, struct ib_udata *udata);
|
||||
|
||||
int ehca_poll_cq(struct ib_cq *cq, int num_entries, struct ib_wc *wc);
|
||||
|
||||
int ehca_peek_cq(struct ib_cq *cq, int wc_cnt);
|
||||
|
||||
int ehca_req_notify_cq(struct ib_cq *cq, enum ib_cq_notify_flags notify_flags);
|
||||
|
||||
struct ib_qp *ehca_create_qp(struct ib_pd *pd,
|
||||
struct ib_qp_init_attr *init_attr,
|
||||
struct ib_udata *udata);
|
||||
|
||||
int ehca_destroy_qp(struct ib_qp *qp);
|
||||
|
||||
int ehca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
|
||||
struct ib_udata *udata);
|
||||
|
||||
int ehca_query_qp(struct ib_qp *qp, struct ib_qp_attr *qp_attr,
|
||||
int qp_attr_mask, struct ib_qp_init_attr *qp_init_attr);
|
||||
|
||||
int ehca_post_send(struct ib_qp *qp, struct ib_send_wr *send_wr,
|
||||
struct ib_send_wr **bad_send_wr);
|
||||
|
||||
int ehca_post_recv(struct ib_qp *qp, struct ib_recv_wr *recv_wr,
|
||||
struct ib_recv_wr **bad_recv_wr);
|
||||
|
||||
int ehca_post_srq_recv(struct ib_srq *srq,
|
||||
struct ib_recv_wr *recv_wr,
|
||||
struct ib_recv_wr **bad_recv_wr);
|
||||
|
||||
struct ib_srq *ehca_create_srq(struct ib_pd *pd,
|
||||
struct ib_srq_init_attr *init_attr,
|
||||
struct ib_udata *udata);
|
||||
|
||||
int ehca_modify_srq(struct ib_srq *srq, struct ib_srq_attr *attr,
|
||||
enum ib_srq_attr_mask attr_mask, struct ib_udata *udata);
|
||||
|
||||
int ehca_query_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr);
|
||||
|
||||
int ehca_destroy_srq(struct ib_srq *srq);
|
||||
|
||||
u64 ehca_define_sqp(struct ehca_shca *shca, struct ehca_qp *ibqp,
|
||||
struct ib_qp_init_attr *qp_init_attr);
|
||||
|
||||
int ehca_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid);
|
||||
|
||||
int ehca_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid);
|
||||
|
||||
struct ib_ucontext *ehca_alloc_ucontext(struct ib_device *device,
|
||||
struct ib_udata *udata);
|
||||
|
||||
int ehca_dealloc_ucontext(struct ib_ucontext *context);
|
||||
|
||||
int ehca_mmap(struct ib_ucontext *context, struct vm_area_struct *vma);
|
||||
|
||||
int ehca_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
|
||||
const struct ib_wc *in_wc, const struct ib_grh *in_grh,
|
||||
const struct ib_mad_hdr *in, size_t in_mad_size,
|
||||
struct ib_mad_hdr *out, size_t *out_mad_size,
|
||||
u16 *out_mad_pkey_index);
|
||||
|
||||
void ehca_poll_eqs(unsigned long data);
|
||||
|
||||
int ehca_calc_ipd(struct ehca_shca *shca, int port,
|
||||
enum ib_rate path_rate, u32 *ipd);
|
||||
|
||||
void ehca_add_to_err_list(struct ehca_qp *qp, int on_sq);
|
||||
|
||||
#ifdef CONFIG_PPC_64K_PAGES
|
||||
void *ehca_alloc_fw_ctrlblock(gfp_t flags);
|
||||
void ehca_free_fw_ctrlblock(void *ptr);
|
||||
#else
|
||||
#define ehca_alloc_fw_ctrlblock(flags) ((void *)get_zeroed_page(flags))
|
||||
#define ehca_free_fw_ctrlblock(ptr) free_page((unsigned long)(ptr))
|
||||
#endif
|
||||
|
||||
void ehca_recover_sqp(struct ib_qp *sqp);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,131 +0,0 @@
|
||||
/*
|
||||
* IBM eServer eHCA Infiniband device driver for Linux on POWER
|
||||
*
|
||||
* mcast functions
|
||||
*
|
||||
* Authors: Khadija Souissi <souissik@de.ibm.com>
|
||||
* Waleri Fomin <fomin@de.ibm.com>
|
||||
* Reinhard Ernst <rernst@de.ibm.com>
|
||||
* Hoang-Nam Nguyen <hnguyen@de.ibm.com>
|
||||
* Heiko J Schick <schickhj@de.ibm.com>
|
||||
*
|
||||
* Copyright (c) 2005 IBM Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is distributed under a dual license of GPL v2.0 and OpenIB
|
||||
* BSD.
|
||||
*
|
||||
* OpenIB BSD License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/err.h>
|
||||
#include "ehca_classes.h"
|
||||
#include "ehca_tools.h"
|
||||
#include "ehca_qes.h"
|
||||
#include "ehca_iverbs.h"
|
||||
#include "hcp_if.h"
|
||||
|
||||
#define MAX_MC_LID 0xFFFE
|
||||
#define MIN_MC_LID 0xC000 /* Multicast limits */
|
||||
#define EHCA_VALID_MULTICAST_GID(gid) ((gid)[0] == 0xFF)
|
||||
#define EHCA_VALID_MULTICAST_LID(lid) \
|
||||
(((lid) >= MIN_MC_LID) && ((lid) <= MAX_MC_LID))
|
||||
|
||||
int ehca_attach_mcast(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
|
||||
{
|
||||
struct ehca_qp *my_qp = container_of(ibqp, struct ehca_qp, ib_qp);
|
||||
struct ehca_shca *shca = container_of(ibqp->device, struct ehca_shca,
|
||||
ib_device);
|
||||
union ib_gid my_gid;
|
||||
u64 subnet_prefix, interface_id, h_ret;
|
||||
|
||||
if (ibqp->qp_type != IB_QPT_UD) {
|
||||
ehca_err(ibqp->device, "invalid qp_type=%x", ibqp->qp_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!(EHCA_VALID_MULTICAST_GID(gid->raw))) {
|
||||
ehca_err(ibqp->device, "invalid mulitcast gid");
|
||||
return -EINVAL;
|
||||
} else if ((lid < MIN_MC_LID) || (lid > MAX_MC_LID)) {
|
||||
ehca_err(ibqp->device, "invalid mulitcast lid=%x", lid);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(&my_gid, gid->raw, sizeof(union ib_gid));
|
||||
|
||||
subnet_prefix = be64_to_cpu(my_gid.global.subnet_prefix);
|
||||
interface_id = be64_to_cpu(my_gid.global.interface_id);
|
||||
h_ret = hipz_h_attach_mcqp(shca->ipz_hca_handle,
|
||||
my_qp->ipz_qp_handle,
|
||||
my_qp->galpas.kernel,
|
||||
lid, subnet_prefix, interface_id);
|
||||
if (h_ret != H_SUCCESS)
|
||||
ehca_err(ibqp->device,
|
||||
"ehca_qp=%p qp_num=%x hipz_h_attach_mcqp() failed "
|
||||
"h_ret=%lli", my_qp, ibqp->qp_num, h_ret);
|
||||
|
||||
return ehca2ib_return_code(h_ret);
|
||||
}
|
||||
|
||||
int ehca_detach_mcast(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
|
||||
{
|
||||
struct ehca_qp *my_qp = container_of(ibqp, struct ehca_qp, ib_qp);
|
||||
struct ehca_shca *shca = container_of(ibqp->pd->device,
|
||||
struct ehca_shca, ib_device);
|
||||
union ib_gid my_gid;
|
||||
u64 subnet_prefix, interface_id, h_ret;
|
||||
|
||||
if (ibqp->qp_type != IB_QPT_UD) {
|
||||
ehca_err(ibqp->device, "invalid qp_type %x", ibqp->qp_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!(EHCA_VALID_MULTICAST_GID(gid->raw))) {
|
||||
ehca_err(ibqp->device, "invalid mulitcast gid");
|
||||
return -EINVAL;
|
||||
} else if ((lid < MIN_MC_LID) || (lid > MAX_MC_LID)) {
|
||||
ehca_err(ibqp->device, "invalid mulitcast lid=%x", lid);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(&my_gid, gid->raw, sizeof(union ib_gid));
|
||||
|
||||
subnet_prefix = be64_to_cpu(my_gid.global.subnet_prefix);
|
||||
interface_id = be64_to_cpu(my_gid.global.interface_id);
|
||||
h_ret = hipz_h_detach_mcqp(shca->ipz_hca_handle,
|
||||
my_qp->ipz_qp_handle,
|
||||
my_qp->galpas.kernel,
|
||||
lid, subnet_prefix, interface_id);
|
||||
if (h_ret != H_SUCCESS)
|
||||
ehca_err(ibqp->device,
|
||||
"ehca_qp=%p qp_num=%x hipz_h_detach_mcqp() failed "
|
||||
"h_ret=%lli", my_qp, ibqp->qp_num, h_ret);
|
||||
|
||||
return ehca2ib_return_code(h_ret);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
* IBM eServer eHCA Infiniband device driver for Linux on POWER
|
||||
*
|
||||
* MR/MW declarations and inline functions
|
||||
*
|
||||
* Authors: Dietmar Decker <ddecker@de.ibm.com>
|
||||
* Christoph Raisch <raisch@de.ibm.com>
|
||||
*
|
||||
* Copyright (c) 2005 IBM Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is distributed under a dual license of GPL v2.0 and OpenIB
|
||||
* BSD.
|
||||
*
|
||||
* OpenIB BSD License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _EHCA_MRMW_H_
|
||||
#define _EHCA_MRMW_H_
|
||||
|
||||
enum ehca_reg_type {
|
||||
EHCA_REG_MR,
|
||||
EHCA_REG_BUSMAP_MR
|
||||
};
|
||||
|
||||
int ehca_reg_mr(struct ehca_shca *shca,
|
||||
struct ehca_mr *e_mr,
|
||||
u64 *iova_start,
|
||||
u64 size,
|
||||
int acl,
|
||||
struct ehca_pd *e_pd,
|
||||
struct ehca_mr_pginfo *pginfo,
|
||||
u32 *lkey,
|
||||
u32 *rkey,
|
||||
enum ehca_reg_type reg_type);
|
||||
|
||||
int ehca_reg_mr_rpages(struct ehca_shca *shca,
|
||||
struct ehca_mr *e_mr,
|
||||
struct ehca_mr_pginfo *pginfo);
|
||||
|
||||
int ehca_rereg_mr(struct ehca_shca *shca,
|
||||
struct ehca_mr *e_mr,
|
||||
u64 *iova_start,
|
||||
u64 size,
|
||||
int mr_access_flags,
|
||||
struct ehca_pd *e_pd,
|
||||
struct ehca_mr_pginfo *pginfo,
|
||||
u32 *lkey,
|
||||
u32 *rkey);
|
||||
|
||||
int ehca_unmap_one_fmr(struct ehca_shca *shca,
|
||||
struct ehca_mr *e_fmr);
|
||||
|
||||
int ehca_reg_smr(struct ehca_shca *shca,
|
||||
struct ehca_mr *e_origmr,
|
||||
struct ehca_mr *e_newmr,
|
||||
u64 *iova_start,
|
||||
int acl,
|
||||
struct ehca_pd *e_pd,
|
||||
u32 *lkey,
|
||||
u32 *rkey);
|
||||
|
||||
int ehca_reg_internal_maxmr(struct ehca_shca *shca,
|
||||
struct ehca_pd *e_pd,
|
||||
struct ehca_mr **maxmr);
|
||||
|
||||
int ehca_reg_maxmr(struct ehca_shca *shca,
|
||||
struct ehca_mr *e_newmr,
|
||||
u64 *iova_start,
|
||||
int acl,
|
||||
struct ehca_pd *e_pd,
|
||||
u32 *lkey,
|
||||
u32 *rkey);
|
||||
|
||||
int ehca_dereg_internal_maxmr(struct ehca_shca *shca);
|
||||
|
||||
int ehca_fmr_check_page_list(struct ehca_mr *e_fmr,
|
||||
u64 *page_list,
|
||||
int list_len);
|
||||
|
||||
int ehca_set_pagebuf(struct ehca_mr_pginfo *pginfo,
|
||||
u32 number,
|
||||
u64 *kpage);
|
||||
|
||||
int ehca_mr_is_maxmr(u64 size,
|
||||
u64 *iova_start);
|
||||
|
||||
void ehca_mrmw_map_acl(int ib_acl,
|
||||
u32 *hipz_acl);
|
||||
|
||||
void ehca_mrmw_set_pgsize_hipz_acl(u32 pgsize, u32 *hipz_acl);
|
||||
|
||||
void ehca_mrmw_reverse_map_acl(const u32 *hipz_acl,
|
||||
int *ib_acl);
|
||||
|
||||
void ehca_mr_deletenew(struct ehca_mr *mr);
|
||||
|
||||
int ehca_create_busmap(void);
|
||||
|
||||
void ehca_destroy_busmap(void);
|
||||
|
||||
extern struct ib_dma_mapping_ops ehca_dma_mapping_ops;
|
||||
#endif /*_EHCA_MRMW_H_*/
|
||||
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
* IBM eServer eHCA Infiniband device driver for Linux on POWER
|
||||
*
|
||||
* PD functions
|
||||
*
|
||||
* Authors: Christoph Raisch <raisch@de.ibm.com>
|
||||
*
|
||||
* Copyright (c) 2005 IBM Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is distributed under a dual license of GPL v2.0 and OpenIB
|
||||
* BSD.
|
||||
*
|
||||
* OpenIB BSD License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "ehca_tools.h"
|
||||
#include "ehca_iverbs.h"
|
||||
|
||||
static struct kmem_cache *pd_cache;
|
||||
|
||||
struct ib_pd *ehca_alloc_pd(struct ib_device *device,
|
||||
struct ib_ucontext *context, struct ib_udata *udata)
|
||||
{
|
||||
struct ehca_pd *pd;
|
||||
int i;
|
||||
|
||||
pd = kmem_cache_zalloc(pd_cache, GFP_KERNEL);
|
||||
if (!pd) {
|
||||
ehca_err(device, "device=%p context=%p out of memory",
|
||||
device, context);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
INIT_LIST_HEAD(&pd->free[i]);
|
||||
INIT_LIST_HEAD(&pd->full[i]);
|
||||
}
|
||||
mutex_init(&pd->lock);
|
||||
|
||||
/*
|
||||
* Kernel PD: when device = -1, 0
|
||||
* User PD: when context != -1
|
||||
*/
|
||||
if (!context) {
|
||||
/*
|
||||
* Kernel PDs after init reuses always
|
||||
* the one created in ehca_shca_reopen()
|
||||
*/
|
||||
struct ehca_shca *shca = container_of(device, struct ehca_shca,
|
||||
ib_device);
|
||||
pd->fw_pd.value = shca->pd->fw_pd.value;
|
||||
} else
|
||||
pd->fw_pd.value = (u64)pd;
|
||||
|
||||
return &pd->ib_pd;
|
||||
}
|
||||
|
||||
int ehca_dealloc_pd(struct ib_pd *pd)
|
||||
{
|
||||
struct ehca_pd *my_pd = container_of(pd, struct ehca_pd, ib_pd);
|
||||
int i, leftovers = 0;
|
||||
struct ipz_small_queue_page *page, *tmp;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
list_splice(&my_pd->full[i], &my_pd->free[i]);
|
||||
list_for_each_entry_safe(page, tmp, &my_pd->free[i], list) {
|
||||
leftovers = 1;
|
||||
free_page(page->page);
|
||||
kmem_cache_free(small_qp_cache, page);
|
||||
}
|
||||
}
|
||||
|
||||
if (leftovers)
|
||||
ehca_warn(pd->device,
|
||||
"Some small queue pages were not freed");
|
||||
|
||||
kmem_cache_free(pd_cache, my_pd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ehca_init_pd_cache(void)
|
||||
{
|
||||
pd_cache = kmem_cache_create("ehca_cache_pd",
|
||||
sizeof(struct ehca_pd), 0,
|
||||
SLAB_HWCACHE_ALIGN,
|
||||
NULL);
|
||||
if (!pd_cache)
|
||||
return -ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ehca_cleanup_pd_cache(void)
|
||||
{
|
||||
kmem_cache_destroy(pd_cache);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user