Commit c5524413 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'rdma-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband

Pull InfiniBand/RDMA changes from Roland Dreier:
 - AF_IB (native IB addressing) for CMA from Sean Hefty
 - new mlx5 driver for Mellanox Connect-IB adapters (including post
   merge request fixes)
 - SRP fixes from Bart Van Assche (including fix to first merge request)
 - qib HW driver updates
 - resurrection of ocrdma HW driver development
 - uverbs conversion to create fds with O_CLOEXEC set
 - other small changes and fixes

* tag 'rdma-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband: (66 commits)
  mlx5: Return -EFAULT instead of -EPERM
  IB/qib: Log all SDMA errors unconditionally
  IB/qib: Fix module-level leak
  mlx5_core: Adjust hca_cap.uar_page_sz to conform to Connect-IB spec
  IB/srp: Let srp_abort() return FAST_IO_FAIL if TL offline
  IB/uverbs: Use get_unused_fd_flags(O_CLOEXEC) instead of get_unused_fd()
  mlx5_core: Fixes for sparse warnings
  IB/mlx5: Make profile[] static in main.c
  mlx5: Fix parameter type of health_handler_t
  mlx5: Add driver for Mellanox Connect-IB adapters
  IB/core: Add reserved values to enums for low-level driver use
  IB/srp: Bump driver version and release date
  IB/srp: Make HCA completion vector configurable
  IB/srp: Maintain a single connection per I_T nexus
  IB/srp: Fail I/O fast if target offline
  IB/srp: Skip host settle delay
  IB/srp: Avoid skipping srp_reset_host() after a transport error
  IB/srp: Fix remove_one crash due to resource exhaustion
  IB/qib: New transmitter tunning settings for Dell 1.1 backplane
  IB/core: Fix error return code in add_port()
  ...
parents 85865511 e04abfa2
...@@ -54,6 +54,13 @@ Description: Interface for making ib_srp connect to a new target. ...@@ -54,6 +54,13 @@ Description: Interface for making ib_srp connect to a new target.
ib_srp. Specifying a value that exceeds cmd_sg_entries is ib_srp. Specifying a value that exceeds cmd_sg_entries is
only safe with partial memory descriptor list support enabled only safe with partial memory descriptor list support enabled
(allow_ext_sg=1). (allow_ext_sg=1).
* comp_vector, a number in the range 0..n-1 specifying the
MSI-X completion vector. Some HCA's allocate multiple (n)
MSI-X vectors per HCA port. If the IRQ affinity masks of
these interrupts have been configured such that each MSI-X
interrupt is handled by a different CPU then the comp_vector
parameter can be used to spread the SRP completion workload
over multiple CPU's.
What: /sys/class/infiniband_srp/srp-<hca>-<port_number>/ibdev What: /sys/class/infiniband_srp/srp-<hca>-<port_number>/ibdev
Date: January 2, 2006 Date: January 2, 2006
......
...@@ -5430,6 +5430,28 @@ W: http://linuxtv.org ...@@ -5430,6 +5430,28 @@ W: http://linuxtv.org
S: Odd Fixes S: Odd Fixes
F: drivers/media/radio/radio-miropcm20* F: drivers/media/radio/radio-miropcm20*
Mellanox MLX5 core VPI driver
M: Eli Cohen <eli@mellanox.com>
L: netdev@vger.kernel.org
L: linux-rdma@vger.kernel.org
W: http://www.mellanox.com
Q: http://patchwork.ozlabs.org/project/netdev/list/
Q: http://patchwork.kernel.org/project/linux-rdma/list/
T: git://openfabrics.org/~eli/connect-ib.git
S: Supported
F: drivers/net/ethernet/mellanox/mlx5/core/
F: include/linux/mlx5/
Mellanox MLX5 IB driver
M: Eli Cohen <eli@mellanox.com>
L: linux-rdma@vger.kernel.org
W: http://www.mellanox.com
Q: http://patchwork.kernel.org/project/linux-rdma/list/
T: git://openfabrics.org/~eli/connect-ib.git
S: Supported
F: include/linux/mlx5/
F: drivers/infiniband/hw/mlx5/
MODULE SUPPORT MODULE SUPPORT
M: Rusty Russell <rusty@rustcorp.com.au> M: Rusty Russell <rusty@rustcorp.com.au>
S: Maintained S: Maintained
......
...@@ -50,6 +50,7 @@ source "drivers/infiniband/hw/amso1100/Kconfig" ...@@ -50,6 +50,7 @@ source "drivers/infiniband/hw/amso1100/Kconfig"
source "drivers/infiniband/hw/cxgb3/Kconfig" source "drivers/infiniband/hw/cxgb3/Kconfig"
source "drivers/infiniband/hw/cxgb4/Kconfig" source "drivers/infiniband/hw/cxgb4/Kconfig"
source "drivers/infiniband/hw/mlx4/Kconfig" source "drivers/infiniband/hw/mlx4/Kconfig"
source "drivers/infiniband/hw/mlx5/Kconfig"
source "drivers/infiniband/hw/nes/Kconfig" source "drivers/infiniband/hw/nes/Kconfig"
source "drivers/infiniband/hw/ocrdma/Kconfig" source "drivers/infiniband/hw/ocrdma/Kconfig"
......
...@@ -7,6 +7,7 @@ obj-$(CONFIG_INFINIBAND_AMSO1100) += hw/amso1100/ ...@@ -7,6 +7,7 @@ obj-$(CONFIG_INFINIBAND_AMSO1100) += hw/amso1100/
obj-$(CONFIG_INFINIBAND_CXGB3) += hw/cxgb3/ obj-$(CONFIG_INFINIBAND_CXGB3) += hw/cxgb3/
obj-$(CONFIG_INFINIBAND_CXGB4) += hw/cxgb4/ obj-$(CONFIG_INFINIBAND_CXGB4) += hw/cxgb4/
obj-$(CONFIG_MLX4_INFINIBAND) += hw/mlx4/ obj-$(CONFIG_MLX4_INFINIBAND) += hw/mlx4/
obj-$(CONFIG_MLX5_INFINIBAND) += hw/mlx5/
obj-$(CONFIG_INFINIBAND_NES) += hw/nes/ obj-$(CONFIG_INFINIBAND_NES) += hw/nes/
obj-$(CONFIG_INFINIBAND_OCRDMA) += hw/ocrdma/ obj-$(CONFIG_INFINIBAND_OCRDMA) += hw/ocrdma/
obj-$(CONFIG_INFINIBAND_IPOIB) += ulp/ipoib/ obj-$(CONFIG_INFINIBAND_IPOIB) += ulp/ipoib/
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#include <net/addrconf.h> #include <net/addrconf.h>
#include <net/ip6_route.h> #include <net/ip6_route.h>
#include <rdma/ib_addr.h> #include <rdma/ib_addr.h>
#include <rdma/ib.h>
MODULE_AUTHOR("Sean Hefty"); MODULE_AUTHOR("Sean Hefty");
MODULE_DESCRIPTION("IB Address Translation"); MODULE_DESCRIPTION("IB Address Translation");
...@@ -70,6 +71,21 @@ static LIST_HEAD(req_list); ...@@ -70,6 +71,21 @@ static LIST_HEAD(req_list);
static DECLARE_DELAYED_WORK(work, process_req); static DECLARE_DELAYED_WORK(work, process_req);
static struct workqueue_struct *addr_wq; static struct workqueue_struct *addr_wq;
int rdma_addr_size(struct sockaddr *addr)
{
switch (addr->sa_family) {
case AF_INET:
return sizeof(struct sockaddr_in);
case AF_INET6:
return sizeof(struct sockaddr_in6);
case AF_IB:
return sizeof(struct sockaddr_ib);
default:
return 0;
}
}
EXPORT_SYMBOL(rdma_addr_size);
void rdma_addr_register_client(struct rdma_addr_client *client) void rdma_addr_register_client(struct rdma_addr_client *client)
{ {
atomic_set(&client->refcount, 1); atomic_set(&client->refcount, 1);
...@@ -369,12 +385,12 @@ int rdma_resolve_ip(struct rdma_addr_client *client, ...@@ -369,12 +385,12 @@ int rdma_resolve_ip(struct rdma_addr_client *client,
goto err; goto err;
} }
memcpy(src_in, src_addr, ip_addr_size(src_addr)); memcpy(src_in, src_addr, rdma_addr_size(src_addr));
} else { } else {
src_in->sa_family = dst_addr->sa_family; src_in->sa_family = dst_addr->sa_family;
} }
memcpy(dst_in, dst_addr, ip_addr_size(dst_addr)); memcpy(dst_in, dst_addr, rdma_addr_size(dst_addr));
req->addr = addr; req->addr = addr;
req->callback = callback; req->callback = callback;
req->context = context; req->context = context;
......
This diff is collapsed.
...@@ -652,6 +652,12 @@ void ib_sa_unpack_path(void *attribute, struct ib_sa_path_rec *rec) ...@@ -652,6 +652,12 @@ void ib_sa_unpack_path(void *attribute, struct ib_sa_path_rec *rec)
} }
EXPORT_SYMBOL(ib_sa_unpack_path); EXPORT_SYMBOL(ib_sa_unpack_path);
void ib_sa_pack_path(struct ib_sa_path_rec *rec, void *attribute)
{
ib_pack(path_rec_table, ARRAY_SIZE(path_rec_table), rec, attribute);
}
EXPORT_SYMBOL(ib_sa_pack_path);
static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query, static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query,
int status, int status,
struct ib_sa_mad *mad) struct ib_sa_mad *mad)
......
...@@ -545,8 +545,10 @@ static int add_port(struct ib_device *device, int port_num, ...@@ -545,8 +545,10 @@ static int add_port(struct ib_device *device, int port_num,
p->gid_group.name = "gids"; p->gid_group.name = "gids";
p->gid_group.attrs = alloc_group_attrs(show_port_gid, attr.gid_tbl_len); p->gid_group.attrs = alloc_group_attrs(show_port_gid, attr.gid_tbl_len);
if (!p->gid_group.attrs) if (!p->gid_group.attrs) {
ret = -ENOMEM;
goto err_remove_pma; goto err_remove_pma;
}
ret = sysfs_create_group(&p->kobj, &p->gid_group); ret = sysfs_create_group(&p->kobj, &p->gid_group);
if (ret) if (ret)
...@@ -555,8 +557,10 @@ static int add_port(struct ib_device *device, int port_num, ...@@ -555,8 +557,10 @@ static int add_port(struct ib_device *device, int port_num,
p->pkey_group.name = "pkeys"; p->pkey_group.name = "pkeys";
p->pkey_group.attrs = alloc_group_attrs(show_port_pkey, p->pkey_group.attrs = alloc_group_attrs(show_port_pkey,
attr.pkey_tbl_len); attr.pkey_tbl_len);
if (!p->pkey_group.attrs) if (!p->pkey_group.attrs) {
ret = -ENOMEM;
goto err_remove_gid; goto err_remove_gid;
}
ret = sysfs_create_group(&p->kobj, &p->pkey_group); ret = sysfs_create_group(&p->kobj, &p->pkey_group);
if (ret) if (ret)
......
This diff is collapsed.
...@@ -334,7 +334,7 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, ...@@ -334,7 +334,7 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
resp.num_comp_vectors = file->device->num_comp_vectors; resp.num_comp_vectors = file->device->num_comp_vectors;
ret = get_unused_fd(); ret = get_unused_fd_flags(O_CLOEXEC);
if (ret < 0) if (ret < 0)
goto err_free; goto err_free;
resp.async_fd = ret; resp.async_fd = ret;
...@@ -1184,7 +1184,7 @@ ssize_t ib_uverbs_create_comp_channel(struct ib_uverbs_file *file, ...@@ -1184,7 +1184,7 @@ ssize_t ib_uverbs_create_comp_channel(struct ib_uverbs_file *file,
if (copy_from_user(&cmd, buf, sizeof cmd)) if (copy_from_user(&cmd, buf, sizeof cmd))
return -EFAULT; return -EFAULT;
ret = get_unused_fd(); ret = get_unused_fd_flags(O_CLOEXEC);
if (ret < 0) if (ret < 0)
return ret; return ret;
resp.fd = ret; resp.fd = ret;
......
...@@ -883,7 +883,8 @@ u16 iwch_rqes_posted(struct iwch_qp *qhp) ...@@ -883,7 +883,8 @@ u16 iwch_rqes_posted(struct iwch_qp *qhp)
{ {
union t3_wr *wqe = qhp->wq.queue; union t3_wr *wqe = qhp->wq.queue;
u16 count = 0; u16 count = 0;
while ((count+1) != 0 && fw_riwrh_opcode((struct fw_riwrh *)wqe) == T3_WR_RCV) {
while (count < USHRT_MAX && fw_riwrh_opcode((struct fw_riwrh *)wqe) == T3_WR_RCV) {
count++; count++;
wqe++; wqe++;
} }
......
...@@ -211,6 +211,7 @@ static int ehca_create_slab_caches(void) ...@@ -211,6 +211,7 @@ static int ehca_create_slab_caches(void)
if (!ctblk_cache) { if (!ctblk_cache) {
ehca_gen_err("Cannot create ctblk SLAB cache."); ehca_gen_err("Cannot create ctblk SLAB cache.");
ehca_cleanup_small_qp_cache(); ehca_cleanup_small_qp_cache();
ret = -ENOMEM;
goto create_slab_caches6; goto create_slab_caches6;
} }
#endif #endif
......
config MLX5_INFINIBAND
tristate "Mellanox Connect-IB HCA support"
depends on NETDEVICES && ETHERNET && PCI && X86
select NET_VENDOR_MELLANOX
select MLX5_CORE
---help---
This driver provides low-level InfiniBand support for
Mellanox Connect-IB PCI Express host channel adapters (HCAs).
This is required to use InfiniBand protocols such as
IP-over-IB or SRP with these devices.
obj-$(CONFIG_MLX5_INFINIBAND) += mlx5_ib.o
mlx5_ib-y := main.o cq.o doorbell.o qp.o mem.o srq.o mr.o ah.o mad.o
/*
* Copyright (c) 2013, Mellanox Technologies inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* 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.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "mlx5_ib.h"
struct ib_ah *create_ib_ah(struct ib_ah_attr *ah_attr,
struct mlx5_ib_ah *ah)
{
if (ah_attr->ah_flags & IB_AH_GRH) {
memcpy(ah->av.rgid, &ah_attr->grh.dgid, 16);
ah->av.grh_gid_fl = cpu_to_be32(ah_attr->grh.flow_label |
(1 << 30) |
ah_attr->grh.sgid_index << 20);
ah->av.hop_limit = ah_attr->grh.hop_limit;
ah->av.tclass = ah_attr->grh.traffic_class;
}
ah->av.rlid = cpu_to_be16(ah_attr->dlid);
ah->av.fl_mlid = ah_attr->src_path_bits & 0x7f;
ah->av.stat_rate_sl = (ah_attr->static_rate << 4) | (ah_attr->sl & 0xf);
return &ah->ibah;
}
struct ib_ah *mlx5_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
{
struct mlx5_ib_ah *ah;
ah = kzalloc(sizeof(*ah), GFP_ATOMIC);
if (!ah)
return ERR_PTR(-ENOMEM);
return create_ib_ah(ah_attr, ah); /* never fails */
}
int mlx5_ib_query_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr)
{
struct mlx5_ib_ah *ah = to_mah(ibah);
u32 tmp;
memset(ah_attr, 0, sizeof(*ah_attr));
tmp = be32_to_cpu(ah->av.grh_gid_fl);
if (tmp & (1 << 30)) {
ah_attr->ah_flags = IB_AH_GRH;
ah_attr->grh.sgid_index = (tmp >> 20) & 0xff;
ah_attr->grh.flow_label = tmp & 0xfffff;
memcpy(&ah_attr->grh.dgid, ah->av.rgid, 16);
ah_attr->grh.hop_limit = ah->av.hop_limit;
ah_attr->grh.traffic_class = ah->av.tclass;
}
ah_attr->dlid = be16_to_cpu(ah->av.rlid);
ah_attr->static_rate = ah->av.stat_rate_sl >> 4;
ah_attr->sl = ah->av.stat_rate_sl & 0xf;
return 0;
}
int mlx5_ib_destroy_ah(struct ib_ah *ah)
{
kfree(to_mah(ah));
return 0;
}
This diff is collapsed.
/*
* Copyright (c) 2013, Mellanox Technologies inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* 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.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <linux/kref.h>
#include <linux/slab.h>
#include <rdma/ib_umem.h>
#include "mlx5_ib.h"
struct mlx5_ib_user_db_page {
struct list_head list;
struct ib_umem *umem;
unsigned long user_virt;
int refcnt;
};
int mlx5_ib_db_map_user(struct mlx5_ib_ucontext *context, unsigned long virt,
struct mlx5_db *db)
{
struct mlx5_ib_user_db_page *page;
struct ib_umem_chunk *chunk;
int err = 0;
mutex_lock(&context->db_page_mutex);
list_for_each_entry(page, &context->db_page_list, list)
if (page->user_virt == (virt & PAGE_MASK))
goto found;
page = kmalloc(sizeof(*page), GFP_KERNEL);
if (!page) {
err = -ENOMEM;
goto out;
}
page->user_virt = (virt & PAGE_MASK);
page->refcnt = 0;
page->umem = ib_umem_get(&context->ibucontext, virt & PAGE_MASK,
PAGE_SIZE, 0, 0);
if (IS_ERR(page->umem)) {
err = PTR_ERR(page->umem);
kfree(page);
goto out;
}
list_add(&page->list, &context->db_page_list);
found:
chunk = list_entry(page->umem->chunk_list.next, struct ib_umem_chunk, list);
db->dma = sg_dma_address(chunk->page_list) + (virt & ~PAGE_MASK);
db->u.user_page = page;
++page->refcnt;
out:
mutex_unlock(&context->db_page_mutex);
return err;
}
void mlx5_ib_db_unmap_user(struct mlx5_ib_ucontext *context, struct mlx5_db *db)
{
mutex_lock(&context->db_page_mutex);
if (!--db->u.user_page->refcnt) {
list_del(&db->u.user_page->list);
ib_umem_release(db->u.user_page->umem);
kfree(db->u.user_page);
}
mutex_unlock(&context->db_page_mutex);
}
/*
* Copyright (c) 2013, Mellanox Technologies inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* 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.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <linux/mlx5/cmd.h>
#include <rdma/ib_mad.h>
#include <rdma/ib_smi.h>
#include "mlx5_ib.h"
enum {
MLX5_IB_VENDOR_CLASS1 = 0x9,
MLX5_IB_VENDOR_CLASS2 = 0xa
};
int mlx5_MAD_IFC(struct mlx5_ib_dev *dev, int ignore_mkey, int ignore_bkey,
int port, struct ib_wc *in_wc, struct ib_grh *in_grh,
void *in_mad, void *response_mad)
{
u8 op_modifier = 0;
/* Key check traps can't be generated unless we have in_wc to
* tell us where to send the trap.
*/
if (ignore_mkey || !in_wc)
op_modifier |= 0x1;
if (ignore_bkey || !in_wc)
op_modifier |= 0x2;
return mlx5_core_mad_ifc(&dev->mdev, in_mad, response_mad, op_modifier, port);
}
int mlx5_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
struct ib_wc *in_wc, struct ib_grh *in_grh,
struct ib_mad *in_mad, struct ib_mad *out_mad)
{
u16 slid;
int err;
slid = in_wc ? in_wc->slid : be16_to_cpu(IB_LID_PERMISSIVE);
if (in_mad->mad_hdr.method == IB_MGMT_METHOD_TRAP && slid == 0)
return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED;
if (in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED ||
in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) {
if (in_mad->mad_hdr.method != IB_MGMT_METHOD_GET &&
in_mad->mad_hdr.method != IB_MGMT_METHOD_SET &&
in_mad->mad_hdr.method != IB_MGMT_METHOD_TRAP_REPRESS)
return IB_MAD_RESULT_SUCCESS;
/* Don't process SMInfo queries -- the SMA can't handle them.
*/
if (in_mad->mad_hdr.attr_id == IB_SMP_ATTR_SM_INFO)
return IB_MAD_RESULT_SUCCESS;
} else if (in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT ||
in_mad->mad_hdr.mgmt_class == MLX5_IB_VENDOR_CLASS1 ||
in_mad->mad_hdr.mgmt_class == MLX5_IB_VENDOR_CLASS2 ||
in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_CONG_MGMT) {
if (in_mad->mad_hdr.method != IB_MGMT_METHOD_GET &&
in_mad->mad_hdr.method != IB_MGMT_METHOD_SET)
return IB_MAD_RESULT_SUCCESS;
} else {
return IB_MAD_RESULT_SUCCESS;
}
err = mlx5_MAD_IFC(to_mdev(ibdev),
mad_flags & IB_MAD_IGNORE_MKEY,
mad_flags & IB_MAD_IGNORE_BKEY,
port_num, in_wc, in_grh, in_mad, out_mad);
if (err)
return IB_MAD_RESULT_FAILURE;
/* set return bit in status of directed route responses */
if (in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)
out_mad->mad_hdr.status |= cpu_to_be16(1 << 15);
if (in_mad->mad_hdr.method == IB_MGMT_METHOD_TRAP_REPRESS)
/* no response for trap repress */
return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED;
return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY;
}
int mlx5_query_ext_port_caps(struct mlx5_ib_dev *dev, u8 port)
{
struct ib_smp *in_mad = NULL;
struct ib_smp *out_mad = NULL;
int err = -ENOMEM;
u16 packet_error;
in_mad = kzalloc(sizeof(*in_mad), GFP_KERNEL);
out_mad = kmalloc(sizeof(*out_mad), GFP_KERNEL);
if (!in_mad || !out_mad)
goto out;
init_query_mad(in_mad);
in_mad->attr_id = MLX5_ATTR_EXTENDED_PORT_INFO;
in_mad->attr_mod = cpu_to_be32(port);
err = mlx5_MAD_IFC(dev, 1, 1, 1, NULL, NULL, in_mad, out_mad);
packet_error = be16_to_cpu(out_mad->status);
dev->mdev.caps.ext_port_cap[port - 1] = (!err && !packet_error) ?
MLX_EXT_PORT_CAP_FLAG_EXTENDED_PORT_INFO : 0;
out:
kfree(in_mad);
kfree(out_mad);
return err;
}
This diff is collapsed.
/*
* Copyright (c) 2013, Mellanox Technologies inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* 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.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <linux/module.h>
#include <rdma/ib_umem.h>
#include "mlx5_ib.h"
/* @umem: umem object to scan
* @addr: ib virtual address requested by the user
* @count: number of PAGE_SIZE pages covered by umem
* @shift: page shift for the compound pages found in the region
* @ncont: number of compund pages
* @order: log2 of the number of compound pages
*/
void mlx5_ib_cont_pages(struct ib_umem *umem, u64 addr, int *count, int *shift,
int *ncont, int *order)
{
struct ib_umem_chunk *chunk;
unsigned long tmp;
unsigned long m;
int i, j, k;
u64 base = 0;
int p = 0;
int skip;
int mask;
u64 len;
u64 pfn;
addr = addr >> PAGE_SHIFT;
tmp = (unsigned long)addr;
m = find_first_bit(&tmp, sizeof(tmp));
skip = 1 << m;
mask = skip - 1;
i = 0;
list_for_each_entry(chunk, &umem->chunk_list, list)
for (j = 0; j < chunk->nmap; j++) {
len = sg_dma_len(&chunk->page_list[j]) >> PAGE_SHIFT;
pfn = sg_dma_address(&chunk->page_list[j]) >> PAGE_SHIFT;
for (k = 0; k < len; k++) {
if (!(i & mask)) {
tmp = (unsigned long)pfn;
m = min(m, find_first_bit(&tmp, sizeof(tmp)));
skip = 1 << m;
mask = skip - 1;
base = pfn;
p = 0;
} else {
if (base + p != pfn) {
tmp = (unsigned long)p;
m = find_first_bit(&tmp, sizeof(tmp));
skip = 1 << m;
mask = skip - 1;
base = pfn;
p = 0;
}
}
p++;
i++;
}
}
if (i) {
m = min_t(unsigned long, ilog2(roundup_pow_of_two(i)), m);
if (order)
*order = ilog2(roundup_pow_of_two(i) >> m);
*ncont = DIV_ROUND_UP(i, (1 << m));
} else {
m = 0;
if (order)
*order = 0;
*ncont = 0;
}
*shift = PAGE_SHIFT + m;
*count = i;
}
void mlx5_ib_populate_pas(struct mlx5_ib_dev *dev, struct ib_umem *umem,
int page_shift, __be64 *pas, int umr)
{
int shift = page_shift - PAGE_SHIFT;
int mask = (1 << shift) - 1;
struct ib_umem_chunk *chunk;
int i, j, k;
u64 cur = 0;
u64 base;
int len;
i = 0;
list_for_each_entry(chunk, &umem->chunk_list, list)
for (j = 0; j < chunk->nmap; j++) {
len = sg_dma_len(&chunk->page_list[j]) >> PAGE_SHIFT;
base = sg_dma_address(&chunk->page_list[j]);
for (k = 0; k < len; k++) {
if (!(i & mask)) {
cur = base + (k << PAGE_SHIFT);
if (umr)
cur |= 3;
pas[i >> shift] = cpu_to_be64(cur);
mlx5_ib_dbg(dev, "pas[%d] 0x%llx\n",
i >> shift, be64_to_cpu(pas[i >> shift]));
} else
mlx5_ib_dbg(dev, "=====> 0x%llx\n",
base + (k << PAGE_SHIFT));
i++;
}
}
}
int mlx5_ib_get_buf_offset(u64 addr, int page_shift, u32 *offset)
{
u64 page_size;
u64 page_mask;
u64 off_size;
u64 off_mask;
u64 buf_off;
page_size = 1 << page_shift;
page_mask = page_size - 1;
buf_off = addr & page_mask;
off_size = page_size >> 6;
off_mask = off_size - 1;
if (buf_off & off_mask)
return -EINVAL;
*offset = buf_off >> ilog2(off_size);
return 0;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -378,7 +378,7 @@ static int ocrdma_alloc_resources(struct ocrdma_dev *dev) ...@@ -378,7 +378,7 @@ static int ocrdma_alloc_resources(struct ocrdma_dev *dev)
spin_lock_init(&dev->flush_q_lock); spin_lock_init(&dev->flush_q_lock);
return 0; return 0;
alloc_err: alloc_err:
ocrdma_err("%s(%d) error.\n", __func__, dev->id); pr_err("%s(%d) error.\n", __func__, dev->id);
return -ENOMEM; return -ENOMEM;
} }
...@@ -396,7 +396,7 @@ static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info) ...@@ -396,7 +396,7 @@ static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info)
dev = (struct ocrdma_dev *)ib_alloc_device(sizeof(struct ocrdma_dev)); dev = (struct ocrdma_dev *)ib_alloc_device(sizeof(struct ocrdma_dev));
if (!dev) { if (!dev) {
ocrdma_err("Unable to allocate ib device\n"); pr_err("Unable to allocate ib device\n");
return NULL; return NULL;
} }
dev->mbx_cmd = kzalloc(sizeof(struct ocrdma_mqe_emb_cmd), GFP_KERNEL); dev->mbx_cmd = kzalloc(sizeof(struct ocrdma_mqe_emb_cmd), GFP_KERNEL);
...@@ -437,7 +437,7 @@ static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info) ...@@ -437,7 +437,7 @@ static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info)
idr_err: idr_err:
kfree(dev->mbx_cmd); kfree(dev->mbx_cmd);
ib_dealloc_device(&dev->ibdev); ib_dealloc_device(&dev->ibdev);
ocrdma_err("%s() leaving. ret=%d\n", __func__, status); pr_err("%s() leaving. ret=%d\n", __func__, status);
return NULL; return NULL;
} }
......
...@@ -608,16 +608,8 @@ enum { ...@@ -608,16 +608,8 @@ enum {
OCRDMA_CREATE_MQ_ASYNC_CQ_VALID = Bit(0) OCRDMA_CREATE_MQ_ASYNC_CQ_VALID = Bit(0)
}; };
struct ocrdma_create_mq_v0 { struct ocrdma_create_mq_req {
u32 pages; struct ocrdma_mbx_hdr req;
u32 cqid_ringsize;
u32 valid;
u32 async_cqid_valid;
u32 rsvd;
struct ocrdma_pa pa[8];
} __packed;
struct ocrdma_create_mq_v1 {
u32 cqid_pages; u32 cqid_pages;
u32 async_event_bitmap; u32 async_event_bitmap;
u32 async_cqid_ringsize; u32 async_cqid_ringsize;
...@@ -627,14 +619,6 @@ struct ocrdma_create_mq_v1 { ...@@ -627,14 +619,6 @@ struct ocrdma_create_mq_v1 {
struct ocrdma_pa pa[8]; struct ocrdma_pa pa[8];
} __packed; } __packed;
struct ocrdma_create_mq_req {
struct ocrdma_mbx_hdr req;
union {
struct ocrdma_create_mq_v0 v0;
struct ocrdma_create_mq_v1 v1;
};
} __packed;
struct ocrdma_create_mq_rsp { struct ocrdma_create_mq_rsp {
struct ocrdma_mbx_rsp rsp; struct ocrdma_mbx_rsp rsp;
u32 id; u32 id;
...@@ -1550,21 +1534,6 @@ struct ocrdma_cqe { ...@@ -1550,21 +1534,6 @@ struct ocrdma_cqe {
u32 flags_status_srcqpn; /* w3 */ u32 flags_status_srcqpn; /* w3 */
} __packed; } __packed;
#define is_cqe_valid(cq, cqe) \
(((le32_to_cpu(cqe->flags_status_srcqpn) & OCRDMA_CQE_VALID)\
== cq->phase) ? 1 : 0)
#define is_cqe_for_sq(cqe) \
((le32_to_cpu(cqe->flags_status_srcqpn) & OCRDMA_CQE_QTYPE) ? 0 : 1)
#define is_cqe_for_rq(cqe) \
((le32_to_cpu(cqe->flags_status_srcqpn) & OCRDMA_CQE_QTYPE) ? 1 : 0)
#define is_cqe_invalidated(cqe) \
((le32_to_cpu(cqe->flags_status_srcqpn) & OCRDMA_CQE_INVALIDATE) ? \
1 : 0)
#define is_cqe_imm(cqe) \
((le32_to_cpu(cqe->flags_status_srcqpn) & OCRDMA_CQE_IMM) ? 1 : 0)
#define is_cqe_wr_imm(cqe) \
((le32_to_cpu(cqe->flags_status_srcqpn) & OCRDMA_CQE_WRITE_IMM) ? 1 : 0)
struct ocrdma_sge { struct ocrdma_sge {
u32 addr_hi; u32 addr_hi;
u32 addr_lo; u32 addr_lo;
......
This diff is collapsed.
...@@ -5,3 +5,11 @@ config INFINIBAND_QIB ...@@ -5,3 +5,11 @@ config INFINIBAND_QIB
This is a low-level driver for Intel PCIe QLE InfiniBand host This is a low-level driver for Intel PCIe QLE InfiniBand host
channel adapters. This driver does not support the Intel channel adapters. This driver does not support the Intel
HyperTransport card (model QHT7140). HyperTransport card (model QHT7140).
config INFINIBAND_QIB_DCA
bool "QIB DCA support"
depends on INFINIBAND_QIB && DCA && SMP && GENERIC_HARDIRQS && !(INFINIBAND_QIB=y && DCA=m)
default y
---help---
Setting this enables DCA support on some Intel chip sets
with the iba7322 HCA.
...@@ -13,3 +13,4 @@ ib_qib-$(CONFIG_PCI_MSI) += qib_iba6120.o ...@@ -13,3 +13,4 @@ ib_qib-$(CONFIG_PCI_MSI) += qib_iba6120.o
ib_qib-$(CONFIG_X86_64) += qib_wc_x86_64.o ib_qib-$(CONFIG_X86_64) += qib_wc_x86_64.o
ib_qib-$(CONFIG_PPC64) += qib_wc_ppc64.o ib_qib-$(CONFIG_PPC64) += qib_wc_ppc64.o
ib_qib-$(CONFIG_DEBUG_FS) += qib_debugfs.o
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -19,5 +19,6 @@ config NET_VENDOR_MELLANOX ...@@ -19,5 +19,6 @@ config NET_VENDOR_MELLANOX
if NET_VENDOR_MELLANOX if NET_VENDOR_MELLANOX
source "drivers/net/ethernet/mellanox/mlx4/Kconfig" source "drivers/net/ethernet/mellanox/mlx4/Kconfig"
source "drivers/net/ethernet/mellanox/mlx5/core/Kconfig"
endif # NET_VENDOR_MELLANOX endif # NET_VENDOR_MELLANOX
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment