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
Merge branches 'core', 'cxgb4', 'iser', 'mlx4', 'mlx5', 'ocrdma', 'odp', 'qib' and 'srp' into for-next
This commit is contained in:
+1
-1
@@ -8450,7 +8450,7 @@ S: Maintained
|
||||
F: drivers/scsi/sr*
|
||||
|
||||
SCSI RDMA PROTOCOL (SRP) INITIATOR
|
||||
M: Bart Van Assche <bvanassche@acm.org>
|
||||
M: Bart Van Assche <bart.vanassche@sandisk.com>
|
||||
L: linux-rdma@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.openfabrics.org
|
||||
|
||||
@@ -294,7 +294,8 @@ int ib_umem_odp_get(struct ib_ucontext *context, struct ib_umem *umem)
|
||||
if (likely(ib_umem_start(umem) != ib_umem_end(umem)))
|
||||
rbt_ib_umem_insert(&umem->odp_data->interval_tree,
|
||||
&context->umem_tree);
|
||||
if (likely(!atomic_read(&context->notifier_count)))
|
||||
if (likely(!atomic_read(&context->notifier_count)) ||
|
||||
context->odp_mrs_count == 1)
|
||||
umem->odp_data->mn_counters_active = true;
|
||||
else
|
||||
list_add(&umem->odp_data->no_private_counters,
|
||||
|
||||
@@ -258,5 +258,6 @@ IB_UVERBS_DECLARE_CMD(close_xrcd);
|
||||
|
||||
IB_UVERBS_DECLARE_EX_CMD(create_flow);
|
||||
IB_UVERBS_DECLARE_EX_CMD(destroy_flow);
|
||||
IB_UVERBS_DECLARE_EX_CMD(query_device);
|
||||
|
||||
#endif /* UVERBS_H */
|
||||
|
||||
@@ -400,6 +400,52 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void copy_query_dev_fields(struct ib_uverbs_file *file,
|
||||
struct ib_uverbs_query_device_resp *resp,
|
||||
struct ib_device_attr *attr)
|
||||
{
|
||||
resp->fw_ver = attr->fw_ver;
|
||||
resp->node_guid = file->device->ib_dev->node_guid;
|
||||
resp->sys_image_guid = attr->sys_image_guid;
|
||||
resp->max_mr_size = attr->max_mr_size;
|
||||
resp->page_size_cap = attr->page_size_cap;
|
||||
resp->vendor_id = attr->vendor_id;
|
||||
resp->vendor_part_id = attr->vendor_part_id;
|
||||
resp->hw_ver = attr->hw_ver;
|
||||
resp->max_qp = attr->max_qp;
|
||||
resp->max_qp_wr = attr->max_qp_wr;
|
||||
resp->device_cap_flags = attr->device_cap_flags;
|
||||
resp->max_sge = attr->max_sge;
|
||||
resp->max_sge_rd = attr->max_sge_rd;
|
||||
resp->max_cq = attr->max_cq;
|
||||
resp->max_cqe = attr->max_cqe;
|
||||
resp->max_mr = attr->max_mr;
|
||||
resp->max_pd = attr->max_pd;
|
||||
resp->max_qp_rd_atom = attr->max_qp_rd_atom;
|
||||
resp->max_ee_rd_atom = attr->max_ee_rd_atom;
|
||||
resp->max_res_rd_atom = attr->max_res_rd_atom;
|
||||
resp->max_qp_init_rd_atom = attr->max_qp_init_rd_atom;
|
||||
resp->max_ee_init_rd_atom = attr->max_ee_init_rd_atom;
|
||||
resp->atomic_cap = attr->atomic_cap;
|
||||
resp->max_ee = attr->max_ee;
|
||||
resp->max_rdd = attr->max_rdd;
|
||||
resp->max_mw = attr->max_mw;
|
||||
resp->max_raw_ipv6_qp = attr->max_raw_ipv6_qp;
|
||||
resp->max_raw_ethy_qp = attr->max_raw_ethy_qp;
|
||||
resp->max_mcast_grp = attr->max_mcast_grp;
|
||||
resp->max_mcast_qp_attach = attr->max_mcast_qp_attach;
|
||||
resp->max_total_mcast_qp_attach = attr->max_total_mcast_qp_attach;
|
||||
resp->max_ah = attr->max_ah;
|
||||
resp->max_fmr = attr->max_fmr;
|
||||
resp->max_map_per_fmr = attr->max_map_per_fmr;
|
||||
resp->max_srq = attr->max_srq;
|
||||
resp->max_srq_wr = attr->max_srq_wr;
|
||||
resp->max_srq_sge = attr->max_srq_sge;
|
||||
resp->max_pkeys = attr->max_pkeys;
|
||||
resp->local_ca_ack_delay = attr->local_ca_ack_delay;
|
||||
resp->phys_port_cnt = file->device->ib_dev->phys_port_cnt;
|
||||
}
|
||||
|
||||
ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file,
|
||||
const char __user *buf,
|
||||
int in_len, int out_len)
|
||||
@@ -420,47 +466,7 @@ ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file,
|
||||
return ret;
|
||||
|
||||
memset(&resp, 0, sizeof resp);
|
||||
|
||||
resp.fw_ver = attr.fw_ver;
|
||||
resp.node_guid = file->device->ib_dev->node_guid;
|
||||
resp.sys_image_guid = attr.sys_image_guid;
|
||||
resp.max_mr_size = attr.max_mr_size;
|
||||
resp.page_size_cap = attr.page_size_cap;
|
||||
resp.vendor_id = attr.vendor_id;
|
||||
resp.vendor_part_id = attr.vendor_part_id;
|
||||
resp.hw_ver = attr.hw_ver;
|
||||
resp.max_qp = attr.max_qp;
|
||||
resp.max_qp_wr = attr.max_qp_wr;
|
||||
resp.device_cap_flags = attr.device_cap_flags;
|
||||
resp.max_sge = attr.max_sge;
|
||||
resp.max_sge_rd = attr.max_sge_rd;
|
||||
resp.max_cq = attr.max_cq;
|
||||
resp.max_cqe = attr.max_cqe;
|
||||
resp.max_mr = attr.max_mr;
|
||||
resp.max_pd = attr.max_pd;
|
||||
resp.max_qp_rd_atom = attr.max_qp_rd_atom;
|
||||
resp.max_ee_rd_atom = attr.max_ee_rd_atom;
|
||||
resp.max_res_rd_atom = attr.max_res_rd_atom;
|
||||
resp.max_qp_init_rd_atom = attr.max_qp_init_rd_atom;
|
||||
resp.max_ee_init_rd_atom = attr.max_ee_init_rd_atom;
|
||||
resp.atomic_cap = attr.atomic_cap;
|
||||
resp.max_ee = attr.max_ee;
|
||||
resp.max_rdd = attr.max_rdd;
|
||||
resp.max_mw = attr.max_mw;
|
||||
resp.max_raw_ipv6_qp = attr.max_raw_ipv6_qp;
|
||||
resp.max_raw_ethy_qp = attr.max_raw_ethy_qp;
|
||||
resp.max_mcast_grp = attr.max_mcast_grp;
|
||||
resp.max_mcast_qp_attach = attr.max_mcast_qp_attach;
|
||||
resp.max_total_mcast_qp_attach = attr.max_total_mcast_qp_attach;
|
||||
resp.max_ah = attr.max_ah;
|
||||
resp.max_fmr = attr.max_fmr;
|
||||
resp.max_map_per_fmr = attr.max_map_per_fmr;
|
||||
resp.max_srq = attr.max_srq;
|
||||
resp.max_srq_wr = attr.max_srq_wr;
|
||||
resp.max_srq_sge = attr.max_srq_sge;
|
||||
resp.max_pkeys = attr.max_pkeys;
|
||||
resp.local_ca_ack_delay = attr.local_ca_ack_delay;
|
||||
resp.phys_port_cnt = file->device->ib_dev->phys_port_cnt;
|
||||
copy_query_dev_fields(file, &resp, &attr);
|
||||
|
||||
if (copy_to_user((void __user *) (unsigned long) cmd.response,
|
||||
&resp, sizeof resp))
|
||||
@@ -3288,3 +3294,64 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file,
|
||||
|
||||
return ret ? ret : in_len;
|
||||
}
|
||||
|
||||
int ib_uverbs_ex_query_device(struct ib_uverbs_file *file,
|
||||
struct ib_udata *ucore,
|
||||
struct ib_udata *uhw)
|
||||
{
|
||||
struct ib_uverbs_ex_query_device_resp resp;
|
||||
struct ib_uverbs_ex_query_device cmd;
|
||||
struct ib_device_attr attr;
|
||||
struct ib_device *device;
|
||||
int err;
|
||||
|
||||
device = file->device->ib_dev;
|
||||
if (ucore->inlen < sizeof(cmd))
|
||||
return -EINVAL;
|
||||
|
||||
err = ib_copy_from_udata(&cmd, ucore, sizeof(cmd));
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (cmd.comp_mask)
|
||||
return -EINVAL;
|
||||
|
||||
if (cmd.reserved)
|
||||
return -EINVAL;
|
||||
|
||||
resp.response_length = offsetof(typeof(resp), odp_caps);
|
||||
|
||||
if (ucore->outlen < resp.response_length)
|
||||
return -ENOSPC;
|
||||
|
||||
err = device->query_device(device, &attr);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
copy_query_dev_fields(file, &resp.base, &attr);
|
||||
resp.comp_mask = 0;
|
||||
|
||||
if (ucore->outlen < resp.response_length + sizeof(resp.odp_caps))
|
||||
goto end;
|
||||
|
||||
#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
|
||||
resp.odp_caps.general_caps = attr.odp_caps.general_caps;
|
||||
resp.odp_caps.per_transport_caps.rc_odp_caps =
|
||||
attr.odp_caps.per_transport_caps.rc_odp_caps;
|
||||
resp.odp_caps.per_transport_caps.uc_odp_caps =
|
||||
attr.odp_caps.per_transport_caps.uc_odp_caps;
|
||||
resp.odp_caps.per_transport_caps.ud_odp_caps =
|
||||
attr.odp_caps.per_transport_caps.ud_odp_caps;
|
||||
resp.odp_caps.reserved = 0;
|
||||
#else
|
||||
memset(&resp.odp_caps, 0, sizeof(resp.odp_caps));
|
||||
#endif
|
||||
resp.response_length += sizeof(resp.odp_caps);
|
||||
|
||||
end:
|
||||
err = ib_copy_to_udata(ucore, &resp, resp.response_length);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -123,6 +123,7 @@ static int (*uverbs_ex_cmd_table[])(struct ib_uverbs_file *file,
|
||||
struct ib_udata *uhw) = {
|
||||
[IB_USER_VERBS_EX_CMD_CREATE_FLOW] = ib_uverbs_ex_create_flow,
|
||||
[IB_USER_VERBS_EX_CMD_DESTROY_FLOW] = ib_uverbs_ex_destroy_flow,
|
||||
[IB_USER_VERBS_EX_CMD_QUERY_DEVICE] = ib_uverbs_ex_query_device,
|
||||
};
|
||||
|
||||
static void ib_uverbs_add_one(struct ib_device *device);
|
||||
|
||||
@@ -225,13 +225,20 @@ int c4iw_ev_handler(struct c4iw_dev *dev, u32 qid)
|
||||
struct c4iw_cq *chp;
|
||||
unsigned long flag;
|
||||
|
||||
spin_lock_irqsave(&dev->lock, flag);
|
||||
chp = get_chp(dev, qid);
|
||||
if (chp) {
|
||||
atomic_inc(&chp->refcnt);
|
||||
spin_unlock_irqrestore(&dev->lock, flag);
|
||||
t4_clear_cq_armed(&chp->cq);
|
||||
spin_lock_irqsave(&chp->comp_handler_lock, flag);
|
||||
(*chp->ibcq.comp_handler)(&chp->ibcq, chp->ibcq.cq_context);
|
||||
spin_unlock_irqrestore(&chp->comp_handler_lock, flag);
|
||||
} else
|
||||
if (atomic_dec_and_test(&chp->refcnt))
|
||||
wake_up(&chp->wait);
|
||||
} else {
|
||||
PDBG("%s unknown cqid 0x%x\n", __func__, qid);
|
||||
spin_unlock_irqrestore(&dev->lock, flag);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -196,7 +196,7 @@ static inline int c4iw_num_stags(struct c4iw_rdev *rdev)
|
||||
return (int)(rdev->lldi.vr->stag.size >> 5);
|
||||
}
|
||||
|
||||
#define C4IW_WR_TO (30*HZ)
|
||||
#define C4IW_WR_TO (60*HZ)
|
||||
|
||||
struct c4iw_wr_wait {
|
||||
struct completion completion;
|
||||
@@ -220,22 +220,21 @@ static inline int c4iw_wait_for_reply(struct c4iw_rdev *rdev,
|
||||
u32 hwtid, u32 qpid,
|
||||
const char *func)
|
||||
{
|
||||
unsigned to = C4IW_WR_TO;
|
||||
int ret;
|
||||
|
||||
do {
|
||||
ret = wait_for_completion_timeout(&wr_waitp->completion, to);
|
||||
if (!ret) {
|
||||
printk(KERN_ERR MOD "%s - Device %s not responding - "
|
||||
"tid %u qpid %u\n", func,
|
||||
pci_name(rdev->lldi.pdev), hwtid, qpid);
|
||||
if (c4iw_fatal_error(rdev)) {
|
||||
wr_waitp->ret = -EIO;
|
||||
break;
|
||||
}
|
||||
to = to << 2;
|
||||
}
|
||||
} while (!ret);
|
||||
if (c4iw_fatal_error(rdev)) {
|
||||
wr_waitp->ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = wait_for_completion_timeout(&wr_waitp->completion, C4IW_WR_TO);
|
||||
if (!ret) {
|
||||
PDBG("%s - Device %s not responding (disabling device) - tid %u qpid %u\n",
|
||||
func, pci_name(rdev->lldi.pdev), hwtid, qpid);
|
||||
rdev->flags |= T4_FATAL_ERROR;
|
||||
wr_waitp->ret = -EIO;
|
||||
}
|
||||
out:
|
||||
if (wr_waitp->ret)
|
||||
PDBG("%s: FW reply %d tid %u qpid %u\n",
|
||||
pci_name(rdev->lldi.pdev), wr_waitp->ret, hwtid, qpid);
|
||||
|
||||
@@ -908,9 +908,6 @@ void ipath_chip_cleanup(struct ipath_devdata *);
|
||||
/* clean up any chip type-specific stuff */
|
||||
void ipath_chip_done(void);
|
||||
|
||||
/* check to see if we have to force ordering for write combining */
|
||||
int ipath_unordered_wc(void);
|
||||
|
||||
void ipath_disarm_piobufs(struct ipath_devdata *, unsigned first,
|
||||
unsigned cnt);
|
||||
void ipath_cancel_sends(struct ipath_devdata *, int);
|
||||
|
||||
@@ -47,16 +47,3 @@ int ipath_enable_wc(struct ipath_devdata *dd)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipath_unordered_wc - indicate whether write combining is unordered
|
||||
*
|
||||
* Because our performance depends on our ability to do write
|
||||
* combining mmio writes in the most efficient way, we need to
|
||||
* know if we are on a processor that may reorder stores when
|
||||
* write combining.
|
||||
*/
|
||||
int ipath_unordered_wc(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -167,18 +167,3 @@ void ipath_disable_wc(struct ipath_devdata *dd)
|
||||
dd->ipath_wc_cookie = 0; /* even on failure */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ipath_unordered_wc - indicate whether write combining is ordered
|
||||
*
|
||||
* Because our performance depends on our ability to do write combining mmio
|
||||
* writes in the most efficient way, we need to know if we are on an Intel
|
||||
* or AMD x86_64 processor. AMD x86_64 processors flush WC buffers out in
|
||||
* the order completed, and so no special flushing is required to get
|
||||
* correct ordering. Intel processors, however, will flush write buffers
|
||||
* out in "random" orders, and so explicit ordering is needed at times.
|
||||
*/
|
||||
int ipath_unordered_wc(void)
|
||||
{
|
||||
return boot_cpu_data.x86_vendor != X86_VENDOR_AMD;
|
||||
}
|
||||
|
||||
@@ -372,7 +372,7 @@ int mlx4_ib_demux_cm_handler(struct ib_device *ibdev, int port, int *slave,
|
||||
*slave = mlx4_ib_find_real_gid(ibdev, port, gid.global.interface_id);
|
||||
if (*slave < 0) {
|
||||
mlx4_ib_warn(ibdev, "failed matching slave_id by gid (0x%llx)\n",
|
||||
gid.global.interface_id);
|
||||
be64_to_cpu(gid.global.interface_id));
|
||||
return -ENOENT;
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -367,8 +367,7 @@ int mlx4_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata)
|
||||
int err;
|
||||
|
||||
mutex_lock(&cq->resize_mutex);
|
||||
|
||||
if (entries < 1) {
|
||||
if (entries < 1 || entries > dev->dev->caps.max_cqes) {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -379,7 +378,7 @@ int mlx4_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (entries > dev->dev->caps.max_cqes) {
|
||||
if (entries > dev->dev->caps.max_cqes + 1) {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -392,7 +391,7 @@ int mlx4_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata)
|
||||
/* Can't be smaller than the number of outstanding CQEs */
|
||||
outst_cqe = mlx4_ib_get_outstanding_cqes(cq);
|
||||
if (entries < outst_cqe + 1) {
|
||||
err = 0;
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
@@ -1222,8 +1222,7 @@ static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
|
||||
struct mlx4_ib_qp *mqp = to_mqp(ibqp);
|
||||
u64 reg_id;
|
||||
struct mlx4_ib_steering *ib_steering = NULL;
|
||||
enum mlx4_protocol prot = (gid->raw[1] == 0x0e) ?
|
||||
MLX4_PROT_IB_IPV4 : MLX4_PROT_IB_IPV6;
|
||||
enum mlx4_protocol prot = MLX4_PROT_IB_IPV6;
|
||||
|
||||
if (mdev->dev->caps.steering_mode ==
|
||||
MLX4_STEERING_MODE_DEVICE_MANAGED) {
|
||||
@@ -1236,8 +1235,10 @@ static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
|
||||
!!(mqp->flags &
|
||||
MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK),
|
||||
prot, ®_id);
|
||||
if (err)
|
||||
if (err) {
|
||||
pr_err("multicast attach op failed, err %d\n", err);
|
||||
goto err_malloc;
|
||||
}
|
||||
|
||||
err = add_gid_entry(ibqp, gid);
|
||||
if (err)
|
||||
@@ -1285,8 +1286,7 @@ static int mlx4_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
|
||||
struct net_device *ndev;
|
||||
struct mlx4_ib_gid_entry *ge;
|
||||
u64 reg_id = 0;
|
||||
enum mlx4_protocol prot = (gid->raw[1] == 0x0e) ?
|
||||
MLX4_PROT_IB_IPV4 : MLX4_PROT_IB_IPV6;
|
||||
enum mlx4_protocol prot = MLX4_PROT_IB_IPV6;
|
||||
|
||||
if (mdev->dev->caps.steering_mode ==
|
||||
MLX4_STEERING_MODE_DEVICE_MANAGED) {
|
||||
|
||||
@@ -1674,8 +1674,10 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
|
||||
qp->mlx4_ib_qp_type == MLX4_IB_QPT_PROXY_GSI ||
|
||||
qp->mlx4_ib_qp_type == MLX4_IB_QPT_TUN_GSI) {
|
||||
err = handle_eth_ud_smac_index(dev, qp, (u8 *)attr->smac, context);
|
||||
if (err)
|
||||
return -EINVAL;
|
||||
if (err) {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (qp->mlx4_ib_qp_type == MLX4_IB_QPT_PROXY_GSI)
|
||||
dev->qp1_proxy[qp->port - 1] = qp;
|
||||
}
|
||||
|
||||
@@ -997,7 +997,7 @@ static int get_port_caps(struct mlx5_ib_dev *dev)
|
||||
struct ib_device_attr *dprops = NULL;
|
||||
struct ib_port_attr *pprops = NULL;
|
||||
struct mlx5_general_caps *gen;
|
||||
int err = 0;
|
||||
int err = -ENOMEM;
|
||||
int port;
|
||||
|
||||
gen = &dev->mdev->caps.gen;
|
||||
@@ -1331,6 +1331,8 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
|
||||
(1ull << IB_USER_VERBS_CMD_DESTROY_SRQ) |
|
||||
(1ull << IB_USER_VERBS_CMD_CREATE_XSRQ) |
|
||||
(1ull << IB_USER_VERBS_CMD_OPEN_QP);
|
||||
dev->ib_dev.uverbs_ex_cmd_mask =
|
||||
(1ull << IB_USER_VERBS_EX_CMD_QUERY_DEVICE);
|
||||
|
||||
dev->ib_dev.query_device = mlx5_ib_query_device;
|
||||
dev->ib_dev.query_port = mlx5_ib_query_port;
|
||||
|
||||
@@ -1012,6 +1012,7 @@ static struct mlx5_ib_mr *reg_create(struct ib_pd *pd, u64 virt_addr,
|
||||
goto err_2;
|
||||
}
|
||||
mr->umem = umem;
|
||||
mr->dev = dev;
|
||||
mr->live = 1;
|
||||
kvfree(in);
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#include <be_roce.h>
|
||||
#include "ocrdma_sli.h"
|
||||
|
||||
#define OCRDMA_ROCE_DRV_VERSION "10.2.287.0u"
|
||||
#define OCRDMA_ROCE_DRV_VERSION "10.4.205.0u"
|
||||
|
||||
#define OCRDMA_ROCE_DRV_DESC "Emulex OneConnect RoCE Driver"
|
||||
#define OCRDMA_NODE_DESC "Emulex OneConnect RoCE HCA"
|
||||
@@ -55,12 +55,19 @@
|
||||
#define OCRDMA_UVERBS(CMD_NAME) (1ull << IB_USER_VERBS_CMD_##CMD_NAME)
|
||||
|
||||
#define convert_to_64bit(lo, hi) ((u64)hi << 32 | (u64)lo)
|
||||
#define EQ_INTR_PER_SEC_THRSH_HI 150000
|
||||
#define EQ_INTR_PER_SEC_THRSH_LOW 100000
|
||||
#define EQ_AIC_MAX_EQD 20
|
||||
#define EQ_AIC_MIN_EQD 0
|
||||
|
||||
void ocrdma_eqd_set_task(struct work_struct *work);
|
||||
|
||||
struct ocrdma_dev_attr {
|
||||
u8 fw_ver[32];
|
||||
u32 vendor_id;
|
||||
u32 device_id;
|
||||
u16 max_pd;
|
||||
u16 max_dpp_pds;
|
||||
u16 max_cq;
|
||||
u16 max_cqe;
|
||||
u16 max_qp;
|
||||
@@ -116,12 +123,19 @@ struct ocrdma_queue_info {
|
||||
bool created;
|
||||
};
|
||||
|
||||
struct ocrdma_aic_obj { /* Adaptive interrupt coalescing (AIC) info */
|
||||
u32 prev_eqd;
|
||||
u64 eq_intr_cnt;
|
||||
u64 prev_eq_intr_cnt;
|
||||
};
|
||||
|
||||
struct ocrdma_eq {
|
||||
struct ocrdma_queue_info q;
|
||||
u32 vector;
|
||||
int cq_cnt;
|
||||
struct ocrdma_dev *dev;
|
||||
char irq_name[32];
|
||||
struct ocrdma_aic_obj aic_obj;
|
||||
};
|
||||
|
||||
struct ocrdma_mq {
|
||||
@@ -171,6 +185,21 @@ struct ocrdma_stats {
|
||||
struct ocrdma_dev *dev;
|
||||
};
|
||||
|
||||
struct ocrdma_pd_resource_mgr {
|
||||
u32 pd_norm_start;
|
||||
u16 pd_norm_count;
|
||||
u16 pd_norm_thrsh;
|
||||
u16 max_normal_pd;
|
||||
u32 pd_dpp_start;
|
||||
u16 pd_dpp_count;
|
||||
u16 pd_dpp_thrsh;
|
||||
u16 max_dpp_pd;
|
||||
u16 dpp_page_index;
|
||||
unsigned long *pd_norm_bitmap;
|
||||
unsigned long *pd_dpp_bitmap;
|
||||
bool pd_prealloc_valid;
|
||||
};
|
||||
|
||||
struct stats_mem {
|
||||
struct ocrdma_mqe mqe;
|
||||
void *va;
|
||||
@@ -198,6 +227,7 @@ struct ocrdma_dev {
|
||||
|
||||
struct ocrdma_eq *eq_tbl;
|
||||
int eq_cnt;
|
||||
struct delayed_work eqd_work;
|
||||
u16 base_eqid;
|
||||
u16 max_eq;
|
||||
|
||||
@@ -255,7 +285,12 @@ struct ocrdma_dev {
|
||||
struct ocrdma_stats rx_qp_err_stats;
|
||||
struct ocrdma_stats tx_dbg_stats;
|
||||
struct ocrdma_stats rx_dbg_stats;
|
||||
struct ocrdma_stats driver_stats;
|
||||
struct ocrdma_stats reset_stats;
|
||||
struct dentry *dir;
|
||||
atomic_t async_err_stats[OCRDMA_MAX_ASYNC_ERRORS];
|
||||
atomic_t cqe_err_stats[OCRDMA_MAX_CQE_ERR];
|
||||
struct ocrdma_pd_resource_mgr *pd_mgr;
|
||||
};
|
||||
|
||||
struct ocrdma_cq {
|
||||
@@ -335,7 +370,6 @@ struct ocrdma_srq {
|
||||
|
||||
struct ocrdma_qp {
|
||||
struct ib_qp ibqp;
|
||||
struct ocrdma_dev *dev;
|
||||
|
||||
u8 __iomem *sq_db;
|
||||
struct ocrdma_qp_hwq_info sq;
|
||||
|
||||
@@ -29,19 +29,22 @@
|
||||
#include <net/netevent.h>
|
||||
|
||||
#include <rdma/ib_addr.h>
|
||||
#include <rdma/ib_mad.h>
|
||||
|
||||
#include "ocrdma.h"
|
||||
#include "ocrdma_verbs.h"
|
||||
#include "ocrdma_ah.h"
|
||||
#include "ocrdma_hw.h"
|
||||
#include "ocrdma_stats.h"
|
||||
|
||||
#define OCRDMA_VID_PCP_SHIFT 0xD
|
||||
|
||||
static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah,
|
||||
struct ib_ah_attr *attr, union ib_gid *sgid, int pdid)
|
||||
struct ib_ah_attr *attr, union ib_gid *sgid,
|
||||
int pdid, bool *isvlan)
|
||||
{
|
||||
int status = 0;
|
||||
u16 vlan_tag; bool vlan_enabled = false;
|
||||
u16 vlan_tag;
|
||||
struct ocrdma_eth_vlan eth;
|
||||
struct ocrdma_grh grh;
|
||||
int eth_sz;
|
||||
@@ -59,7 +62,7 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah,
|
||||
vlan_tag |= (dev->sl & 0x07) << OCRDMA_VID_PCP_SHIFT;
|
||||
eth.vlan_tag = cpu_to_be16(vlan_tag);
|
||||
eth_sz = sizeof(struct ocrdma_eth_vlan);
|
||||
vlan_enabled = true;
|
||||
*isvlan = true;
|
||||
} else {
|
||||
eth.eth_type = cpu_to_be16(OCRDMA_ROCE_ETH_TYPE);
|
||||
eth_sz = sizeof(struct ocrdma_eth_basic);
|
||||
@@ -82,7 +85,7 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah,
|
||||
/* Eth HDR */
|
||||
memcpy(&ah->av->eth_hdr, ð, eth_sz);
|
||||
memcpy((u8 *)ah->av + eth_sz, &grh, sizeof(struct ocrdma_grh));
|
||||
if (vlan_enabled)
|
||||
if (*isvlan)
|
||||
ah->av->valid |= OCRDMA_AV_VLAN_VALID;
|
||||
ah->av->valid = cpu_to_le32(ah->av->valid);
|
||||
return status;
|
||||
@@ -91,6 +94,7 @@ static inline int set_av_attr(struct ocrdma_dev *dev, struct ocrdma_ah *ah,
|
||||
struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr)
|
||||
{
|
||||
u32 *ahid_addr;
|
||||
bool isvlan = false;
|
||||
int status;
|
||||
struct ocrdma_ah *ah;
|
||||
struct ocrdma_pd *pd = get_ocrdma_pd(ibpd);
|
||||
@@ -127,15 +131,20 @@ struct ib_ah *ocrdma_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr)
|
||||
}
|
||||
}
|
||||
|
||||
status = set_av_attr(dev, ah, attr, &sgid, pd->id);
|
||||
status = set_av_attr(dev, ah, attr, &sgid, pd->id, &isvlan);
|
||||
if (status)
|
||||
goto av_conf_err;
|
||||
|
||||
/* if pd is for the user process, pass the ah_id to user space */
|
||||
if ((pd->uctx) && (pd->uctx->ah_tbl.va)) {
|
||||
ahid_addr = pd->uctx->ah_tbl.va + attr->dlid;
|
||||
*ahid_addr = ah->id;
|
||||
*ahid_addr = 0;
|
||||
*ahid_addr |= ah->id & OCRDMA_AH_ID_MASK;
|
||||
if (isvlan)
|
||||
*ahid_addr |= (OCRDMA_AH_VLAN_VALID_MASK <<
|
||||
OCRDMA_AH_VLAN_VALID_SHIFT);
|
||||
}
|
||||
|
||||
return &ah->ibah;
|
||||
|
||||
av_conf_err:
|
||||
@@ -191,5 +200,20 @@ int ocrdma_process_mad(struct ib_device *ibdev,
|
||||
struct ib_grh *in_grh,
|
||||
struct ib_mad *in_mad, struct ib_mad *out_mad)
|
||||
{
|
||||
return IB_MAD_RESULT_SUCCESS;
|
||||
int status;
|
||||
struct ocrdma_dev *dev;
|
||||
|
||||
switch (in_mad->mad_hdr.mgmt_class) {
|
||||
case IB_MGMT_CLASS_PERF_MGMT:
|
||||
dev = get_ocrdma_dev(ibdev);
|
||||
if (!ocrdma_pma_counters(dev, out_mad))
|
||||
status = IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY;
|
||||
else
|
||||
status = IB_MAD_RESULT_SUCCESS;
|
||||
break;
|
||||
default:
|
||||
status = IB_MAD_RESULT_SUCCESS;
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,12 @@
|
||||
#ifndef __OCRDMA_AH_H__
|
||||
#define __OCRDMA_AH_H__
|
||||
|
||||
enum {
|
||||
OCRDMA_AH_ID_MASK = 0x3FF,
|
||||
OCRDMA_AH_VLAN_VALID_MASK = 0x01,
|
||||
OCRDMA_AH_VLAN_VALID_SHIFT = 0x1F
|
||||
};
|
||||
|
||||
struct ib_ah *ocrdma_create_ah(struct ib_pd *, struct ib_ah_attr *);
|
||||
int ocrdma_destroy_ah(struct ib_ah *);
|
||||
int ocrdma_query_ah(struct ib_ah *, struct ib_ah_attr *);
|
||||
|
||||
@@ -734,6 +734,9 @@ static void ocrdma_dispatch_ibevent(struct ocrdma_dev *dev,
|
||||
break;
|
||||
}
|
||||
|
||||
if (type < OCRDMA_MAX_ASYNC_ERRORS)
|
||||
atomic_inc(&dev->async_err_stats[type]);
|
||||
|
||||
if (qp_event) {
|
||||
if (qp->ibqp.event_handler)
|
||||
qp->ibqp.event_handler(&ib_evt, qp->ibqp.qp_context);
|
||||
@@ -831,20 +834,20 @@ static int ocrdma_mq_cq_handler(struct ocrdma_dev *dev, u16 cq_id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ocrdma_qp_buddy_cq_handler(struct ocrdma_dev *dev,
|
||||
struct ocrdma_cq *cq)
|
||||
static struct ocrdma_cq *_ocrdma_qp_buddy_cq_handler(struct ocrdma_dev *dev,
|
||||
struct ocrdma_cq *cq, bool sq)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct ocrdma_qp *qp;
|
||||
bool buddy_cq_found = false;
|
||||
/* Go through list of QPs in error state which are using this CQ
|
||||
* and invoke its callback handler to trigger CQE processing for
|
||||
* error/flushed CQE. It is rare to find more than few entries in
|
||||
* this list as most consumers stops after getting error CQE.
|
||||
* List is traversed only once when a matching buddy cq found for a QP.
|
||||
*/
|
||||
spin_lock_irqsave(&dev->flush_q_lock, flags);
|
||||
list_for_each_entry(qp, &cq->sq_head, sq_entry) {
|
||||
struct list_head *cur;
|
||||
struct ocrdma_cq *bcq = NULL;
|
||||
struct list_head *head = sq?(&cq->sq_head):(&cq->rq_head);
|
||||
|
||||
list_for_each(cur, head) {
|
||||
if (sq)
|
||||
qp = list_entry(cur, struct ocrdma_qp, sq_entry);
|
||||
else
|
||||
qp = list_entry(cur, struct ocrdma_qp, rq_entry);
|
||||
|
||||
if (qp->srq)
|
||||
continue;
|
||||
/* if wq and rq share the same cq, than comp_handler
|
||||
@@ -856,19 +859,41 @@ static void ocrdma_qp_buddy_cq_handler(struct ocrdma_dev *dev,
|
||||
* if completion came on rq, sq's cq is buddy cq.
|
||||
*/
|
||||
if (qp->sq_cq == cq)
|
||||
cq = qp->rq_cq;
|
||||
bcq = qp->rq_cq;
|
||||
else
|
||||
cq = qp->sq_cq;
|
||||
buddy_cq_found = true;
|
||||
break;
|
||||
bcq = qp->sq_cq;
|
||||
return bcq;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void ocrdma_qp_buddy_cq_handler(struct ocrdma_dev *dev,
|
||||
struct ocrdma_cq *cq)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct ocrdma_cq *bcq = NULL;
|
||||
|
||||
/* Go through list of QPs in error state which are using this CQ
|
||||
* and invoke its callback handler to trigger CQE processing for
|
||||
* error/flushed CQE. It is rare to find more than few entries in
|
||||
* this list as most consumers stops after getting error CQE.
|
||||
* List is traversed only once when a matching buddy cq found for a QP.
|
||||
*/
|
||||
spin_lock_irqsave(&dev->flush_q_lock, flags);
|
||||
/* Check if buddy CQ is present.
|
||||
* true - Check for SQ CQ
|
||||
* false - Check for RQ CQ
|
||||
*/
|
||||
bcq = _ocrdma_qp_buddy_cq_handler(dev, cq, true);
|
||||
if (bcq == NULL)
|
||||
bcq = _ocrdma_qp_buddy_cq_handler(dev, cq, false);
|
||||
spin_unlock_irqrestore(&dev->flush_q_lock, flags);
|
||||
if (buddy_cq_found == false)
|
||||
return;
|
||||
if (cq->ibcq.comp_handler) {
|
||||
spin_lock_irqsave(&cq->comp_handler_lock, flags);
|
||||
(*cq->ibcq.comp_handler) (&cq->ibcq, cq->ibcq.cq_context);
|
||||
spin_unlock_irqrestore(&cq->comp_handler_lock, flags);
|
||||
|
||||
/* if there is valid buddy cq, look for its completion handler */
|
||||
if (bcq && bcq->ibcq.comp_handler) {
|
||||
spin_lock_irqsave(&bcq->comp_handler_lock, flags);
|
||||
(*bcq->ibcq.comp_handler) (&bcq->ibcq, bcq->ibcq.cq_context);
|
||||
spin_unlock_irqrestore(&bcq->comp_handler_lock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -935,6 +960,7 @@ static irqreturn_t ocrdma_irq_handler(int irq, void *handle)
|
||||
|
||||
} while (budget);
|
||||
|
||||
eq->aic_obj.eq_intr_cnt++;
|
||||
ocrdma_ring_eq_db(dev, eq->q.id, true, true, 0);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@@ -1050,6 +1076,9 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev,
|
||||
attr->max_pd =
|
||||
(rsp->max_pd_ca_ack_delay & OCRDMA_MBX_QUERY_CFG_MAX_PD_MASK) >>
|
||||
OCRDMA_MBX_QUERY_CFG_MAX_PD_SHIFT;
|
||||
attr->max_dpp_pds =
|
||||
(rsp->max_dpp_pds_credits & OCRDMA_MBX_QUERY_CFG_MAX_DPP_PDS_MASK) >>
|
||||
OCRDMA_MBX_QUERY_CFG_MAX_DPP_PDS_OFFSET;
|
||||
attr->max_qp =
|
||||
(rsp->qp_srq_cq_ird_ord & OCRDMA_MBX_QUERY_CFG_MAX_QP_MASK) >>
|
||||
OCRDMA_MBX_QUERY_CFG_MAX_QP_SHIFT;
|
||||
@@ -1396,6 +1425,122 @@ int ocrdma_mbx_dealloc_pd(struct ocrdma_dev *dev, struct ocrdma_pd *pd)
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static int ocrdma_mbx_alloc_pd_range(struct ocrdma_dev *dev)
|
||||
{
|
||||
int status = -ENOMEM;
|
||||
size_t pd_bitmap_size;
|
||||
struct ocrdma_alloc_pd_range *cmd;
|
||||
struct ocrdma_alloc_pd_range_rsp *rsp;
|
||||
|
||||
/* Pre allocate the DPP PDs */
|
||||
cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_ALLOC_PD_RANGE, sizeof(*cmd));
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
cmd->pd_count = dev->attr.max_dpp_pds;
|
||||
cmd->enable_dpp_rsvd |= OCRDMA_ALLOC_PD_ENABLE_DPP;
|
||||
status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd);
|
||||
if (status)
|
||||
goto mbx_err;
|
||||
rsp = (struct ocrdma_alloc_pd_range_rsp *)cmd;
|
||||
|
||||
if ((rsp->dpp_page_pdid & OCRDMA_ALLOC_PD_RSP_DPP) && rsp->pd_count) {
|
||||
dev->pd_mgr->dpp_page_index = rsp->dpp_page_pdid >>
|
||||
OCRDMA_ALLOC_PD_RSP_DPP_PAGE_SHIFT;
|
||||
dev->pd_mgr->pd_dpp_start = rsp->dpp_page_pdid &
|
||||
OCRDMA_ALLOC_PD_RNG_RSP_START_PDID_MASK;
|
||||
dev->pd_mgr->max_dpp_pd = rsp->pd_count;
|
||||
pd_bitmap_size = BITS_TO_LONGS(rsp->pd_count) * sizeof(long);
|
||||
dev->pd_mgr->pd_dpp_bitmap = kzalloc(pd_bitmap_size,
|
||||
GFP_KERNEL);
|
||||
}
|
||||
kfree(cmd);
|
||||
|
||||
cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_ALLOC_PD_RANGE, sizeof(*cmd));
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd->pd_count = dev->attr.max_pd - dev->attr.max_dpp_pds;
|
||||
status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd);
|
||||
if (status)
|
||||
goto mbx_err;
|
||||
rsp = (struct ocrdma_alloc_pd_range_rsp *)cmd;
|
||||
if (rsp->pd_count) {
|
||||
dev->pd_mgr->pd_norm_start = rsp->dpp_page_pdid &
|
||||
OCRDMA_ALLOC_PD_RNG_RSP_START_PDID_MASK;
|
||||
dev->pd_mgr->max_normal_pd = rsp->pd_count;
|
||||
pd_bitmap_size = BITS_TO_LONGS(rsp->pd_count) * sizeof(long);
|
||||
dev->pd_mgr->pd_norm_bitmap = kzalloc(pd_bitmap_size,
|
||||
GFP_KERNEL);
|
||||
}
|
||||
|
||||
if (dev->pd_mgr->pd_norm_bitmap || dev->pd_mgr->pd_dpp_bitmap) {
|
||||
/* Enable PD resource manager */
|
||||
dev->pd_mgr->pd_prealloc_valid = true;
|
||||
} else {
|
||||
return -ENOMEM;
|
||||
}
|
||||
mbx_err:
|
||||
kfree(cmd);
|
||||
return status;
|
||||
}
|
||||
|
||||
static void ocrdma_mbx_dealloc_pd_range(struct ocrdma_dev *dev)
|
||||
{
|
||||
struct ocrdma_dealloc_pd_range *cmd;
|
||||
|
||||
/* return normal PDs to firmware */
|
||||
cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_DEALLOC_PD_RANGE, sizeof(*cmd));
|
||||
if (!cmd)
|
||||
goto mbx_err;
|
||||
|
||||
if (dev->pd_mgr->max_normal_pd) {
|
||||
cmd->start_pd_id = dev->pd_mgr->pd_norm_start;
|
||||
cmd->pd_count = dev->pd_mgr->max_normal_pd;
|
||||
ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd);
|
||||
}
|
||||
|
||||
if (dev->pd_mgr->max_dpp_pd) {
|
||||
kfree(cmd);
|
||||
/* return DPP PDs to firmware */
|
||||
cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_DEALLOC_PD_RANGE,
|
||||
sizeof(*cmd));
|
||||
if (!cmd)
|
||||
goto mbx_err;
|
||||
|
||||
cmd->start_pd_id = dev->pd_mgr->pd_dpp_start;
|
||||
cmd->pd_count = dev->pd_mgr->max_dpp_pd;
|
||||
ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd);
|
||||
}
|
||||
mbx_err:
|
||||
kfree(cmd);
|
||||
}
|
||||
|
||||
void ocrdma_alloc_pd_pool(struct ocrdma_dev *dev)
|
||||
{
|
||||
int status;
|
||||
|
||||
dev->pd_mgr = kzalloc(sizeof(struct ocrdma_pd_resource_mgr),
|
||||
GFP_KERNEL);
|
||||
if (!dev->pd_mgr) {
|
||||
pr_err("%s(%d)Memory allocation failure.\n", __func__, dev->id);
|
||||
return;
|
||||
}
|
||||
status = ocrdma_mbx_alloc_pd_range(dev);
|
||||
if (status) {
|
||||
pr_err("%s(%d) Unable to initialize PD pool, using default.\n",
|
||||
__func__, dev->id);
|
||||
}
|
||||
}
|
||||
|
||||
static void ocrdma_free_pd_pool(struct ocrdma_dev *dev)
|
||||
{
|
||||
ocrdma_mbx_dealloc_pd_range(dev);
|
||||
kfree(dev->pd_mgr->pd_norm_bitmap);
|
||||
kfree(dev->pd_mgr->pd_dpp_bitmap);
|
||||
kfree(dev->pd_mgr);
|
||||
}
|
||||
|
||||
static int ocrdma_build_q_conf(u32 *num_entries, int entry_size,
|
||||
int *num_pages, int *page_size)
|
||||
{
|
||||
@@ -1896,8 +2041,9 @@ void ocrdma_flush_qp(struct ocrdma_qp *qp)
|
||||
{
|
||||
bool found;
|
||||
unsigned long flags;
|
||||
struct ocrdma_dev *dev = get_ocrdma_dev(qp->ibqp.device);
|
||||
|
||||
spin_lock_irqsave(&qp->dev->flush_q_lock, flags);
|
||||
spin_lock_irqsave(&dev->flush_q_lock, flags);
|
||||
found = ocrdma_is_qp_in_sq_flushlist(qp->sq_cq, qp);
|
||||
if (!found)
|
||||
list_add_tail(&qp->sq_entry, &qp->sq_cq->sq_head);
|
||||
@@ -1906,7 +2052,7 @@ void ocrdma_flush_qp(struct ocrdma_qp *qp)
|
||||
if (!found)
|
||||
list_add_tail(&qp->rq_entry, &qp->rq_cq->rq_head);
|
||||
}
|
||||
spin_unlock_irqrestore(&qp->dev->flush_q_lock, flags);
|
||||
spin_unlock_irqrestore(&dev->flush_q_lock, flags);
|
||||
}
|
||||
|
||||
static void ocrdma_init_hwq_ptr(struct ocrdma_qp *qp)
|
||||
@@ -1972,7 +2118,8 @@ static int ocrdma_set_create_qp_sq_cmd(struct ocrdma_create_qp_req *cmd,
|
||||
int status;
|
||||
u32 len, hw_pages, hw_page_size;
|
||||
dma_addr_t pa;
|
||||
struct ocrdma_dev *dev = qp->dev;
|
||||
struct ocrdma_pd *pd = qp->pd;
|
||||
struct ocrdma_dev *dev = get_ocrdma_dev(pd->ibpd.device);
|
||||
struct pci_dev *pdev = dev->nic_info.pdev;
|
||||
u32 max_wqe_allocated;
|
||||
u32 max_sges = attrs->cap.max_send_sge;
|
||||
@@ -2027,7 +2174,8 @@ static int ocrdma_set_create_qp_rq_cmd(struct ocrdma_create_qp_req *cmd,
|
||||
int status;
|
||||
u32 len, hw_pages, hw_page_size;
|
||||
dma_addr_t pa = 0;
|
||||
struct ocrdma_dev *dev = qp->dev;
|
||||
struct ocrdma_pd *pd = qp->pd;
|
||||
struct ocrdma_dev *dev = get_ocrdma_dev(pd->ibpd.device);
|
||||
struct pci_dev *pdev = dev->nic_info.pdev;
|
||||
u32 max_rqe_allocated = attrs->cap.max_recv_wr + 1;
|
||||
|
||||
@@ -2086,7 +2234,8 @@ static void ocrdma_set_create_qp_dpp_cmd(struct ocrdma_create_qp_req *cmd,
|
||||
static int ocrdma_set_create_qp_ird_cmd(struct ocrdma_create_qp_req *cmd,
|
||||
struct ocrdma_qp *qp)
|
||||
{
|
||||
struct ocrdma_dev *dev = qp->dev;
|
||||
struct ocrdma_pd *pd = qp->pd;
|
||||
struct ocrdma_dev *dev = get_ocrdma_dev(pd->ibpd.device);
|
||||
struct pci_dev *pdev = dev->nic_info.pdev;
|
||||
dma_addr_t pa = 0;
|
||||
int ird_page_size = dev->attr.ird_page_size;
|
||||
@@ -2157,8 +2306,8 @@ int ocrdma_mbx_create_qp(struct ocrdma_qp *qp, struct ib_qp_init_attr *attrs,
|
||||
{
|
||||
int status = -ENOMEM;
|
||||
u32 flags = 0;
|
||||
struct ocrdma_dev *dev = qp->dev;
|
||||
struct ocrdma_pd *pd = qp->pd;
|
||||
struct ocrdma_dev *dev = get_ocrdma_dev(pd->ibpd.device);
|
||||
struct pci_dev *pdev = dev->nic_info.pdev;
|
||||
struct ocrdma_cq *cq;
|
||||
struct ocrdma_create_qp_req *cmd;
|
||||
@@ -2281,11 +2430,12 @@ static int ocrdma_set_av_params(struct ocrdma_qp *qp,
|
||||
union ib_gid sgid, zgid;
|
||||
u32 vlan_id;
|
||||
u8 mac_addr[6];
|
||||
struct ocrdma_dev *dev = get_ocrdma_dev(qp->ibqp.device);
|
||||
|
||||
if ((ah_attr->ah_flags & IB_AH_GRH) == 0)
|
||||
return -EINVAL;
|
||||
if (atomic_cmpxchg(&qp->dev->update_sl, 1, 0))
|
||||
ocrdma_init_service_level(qp->dev);
|
||||
if (atomic_cmpxchg(&dev->update_sl, 1, 0))
|
||||
ocrdma_init_service_level(dev);
|
||||
cmd->params.tclass_sq_psn |=
|
||||
(ah_attr->grh.traffic_class << OCRDMA_QP_PARAMS_TCLASS_SHIFT);
|
||||
cmd->params.rnt_rc_sl_fl |=
|
||||
@@ -2296,7 +2446,7 @@ static int ocrdma_set_av_params(struct ocrdma_qp *qp,
|
||||
cmd->flags |= OCRDMA_QP_PARA_FLOW_LBL_VALID;
|
||||
memcpy(&cmd->params.dgid[0], &ah_attr->grh.dgid.raw[0],
|
||||
sizeof(cmd->params.dgid));
|
||||
status = ocrdma_query_gid(&qp->dev->ibdev, 1,
|
||||
status = ocrdma_query_gid(&dev->ibdev, 1,
|
||||
ah_attr->grh.sgid_index, &sgid);
|
||||
if (status)
|
||||
return status;
|
||||
@@ -2307,7 +2457,9 @@ static int ocrdma_set_av_params(struct ocrdma_qp *qp,
|
||||
|
||||
qp->sgid_idx = ah_attr->grh.sgid_index;
|
||||
memcpy(&cmd->params.sgid[0], &sgid.raw[0], sizeof(cmd->params.sgid));
|
||||
ocrdma_resolve_dmac(qp->dev, ah_attr, &mac_addr[0]);
|
||||
status = ocrdma_resolve_dmac(dev, ah_attr, &mac_addr[0]);
|
||||
if (status)
|
||||
return status;
|
||||
cmd->params.dmac_b0_to_b3 = mac_addr[0] | (mac_addr[1] << 8) |
|
||||
(mac_addr[2] << 16) | (mac_addr[3] << 24);
|
||||
/* convert them to LE format. */
|
||||
@@ -2320,7 +2472,7 @@ static int ocrdma_set_av_params(struct ocrdma_qp *qp,
|
||||
vlan_id << OCRDMA_QP_PARAMS_VLAN_SHIFT;
|
||||
cmd->flags |= OCRDMA_QP_PARA_VLAN_EN_VALID;
|
||||
cmd->params.rnt_rc_sl_fl |=
|
||||
(qp->dev->sl & 0x07) << OCRDMA_QP_PARAMS_SL_SHIFT;
|
||||
(dev->sl & 0x07) << OCRDMA_QP_PARAMS_SL_SHIFT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -2330,6 +2482,7 @@ static int ocrdma_set_qp_params(struct ocrdma_qp *qp,
|
||||
struct ib_qp_attr *attrs, int attr_mask)
|
||||
{
|
||||
int status = 0;
|
||||
struct ocrdma_dev *dev = get_ocrdma_dev(qp->ibqp.device);
|
||||
|
||||
if (attr_mask & IB_QP_PKEY_INDEX) {
|
||||
cmd->params.path_mtu_pkey_indx |= (attrs->pkey_index &
|
||||
@@ -2347,12 +2500,12 @@ static int ocrdma_set_qp_params(struct ocrdma_qp *qp,
|
||||
return status;
|
||||
} else if (qp->qp_type == IB_QPT_GSI || qp->qp_type == IB_QPT_UD) {
|
||||
/* set the default mac address for UD, GSI QPs */
|
||||
cmd->params.dmac_b0_to_b3 = qp->dev->nic_info.mac_addr[0] |
|
||||
(qp->dev->nic_info.mac_addr[1] << 8) |
|
||||
(qp->dev->nic_info.mac_addr[2] << 16) |
|
||||
(qp->dev->nic_info.mac_addr[3] << 24);
|
||||
cmd->params.vlan_dmac_b4_to_b5 = qp->dev->nic_info.mac_addr[4] |
|
||||
(qp->dev->nic_info.mac_addr[5] << 8);
|
||||
cmd->params.dmac_b0_to_b3 = dev->nic_info.mac_addr[0] |
|
||||
(dev->nic_info.mac_addr[1] << 8) |
|
||||
(dev->nic_info.mac_addr[2] << 16) |
|
||||
(dev->nic_info.mac_addr[3] << 24);
|
||||
cmd->params.vlan_dmac_b4_to_b5 = dev->nic_info.mac_addr[4] |
|
||||
(dev->nic_info.mac_addr[5] << 8);
|
||||
}
|
||||
if ((attr_mask & IB_QP_EN_SQD_ASYNC_NOTIFY) &&
|
||||
attrs->en_sqd_async_notify) {
|
||||
@@ -2409,7 +2562,7 @@ static int ocrdma_set_qp_params(struct ocrdma_qp *qp,
|
||||
cmd->flags |= OCRDMA_QP_PARA_RQPSN_VALID;
|
||||
}
|
||||
if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC) {
|
||||
if (attrs->max_rd_atomic > qp->dev->attr.max_ord_per_qp) {
|
||||
if (attrs->max_rd_atomic > dev->attr.max_ord_per_qp) {
|
||||
status = -EINVAL;
|
||||
goto pmtu_err;
|
||||
}
|
||||
@@ -2417,7 +2570,7 @@ static int ocrdma_set_qp_params(struct ocrdma_qp *qp,
|
||||
cmd->flags |= OCRDMA_QP_PARA_MAX_ORD_VALID;
|
||||
}
|
||||
if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) {
|
||||
if (attrs->max_dest_rd_atomic > qp->dev->attr.max_ird_per_qp) {
|
||||
if (attrs->max_dest_rd_atomic > dev->attr.max_ird_per_qp) {
|
||||
status = -EINVAL;
|
||||
goto pmtu_err;
|
||||
}
|
||||
@@ -2870,6 +3023,82 @@ done:
|
||||
return status;
|
||||
}
|
||||
|
||||
static int ocrdma_mbx_modify_eqd(struct ocrdma_dev *dev, struct ocrdma_eq *eq,
|
||||
int num)
|
||||
{
|
||||
int i, status = -ENOMEM;
|
||||
struct ocrdma_modify_eqd_req *cmd;
|
||||
|
||||
cmd = ocrdma_init_emb_mqe(OCRDMA_CMD_MODIFY_EQ_DELAY, sizeof(*cmd));
|
||||
if (!cmd)
|
||||
return status;
|
||||
|
||||
ocrdma_init_mch(&cmd->cmd.req, OCRDMA_CMD_MODIFY_EQ_DELAY,
|
||||
OCRDMA_SUBSYS_COMMON, sizeof(*cmd));
|
||||
|
||||
cmd->cmd.num_eq = num;
|
||||
for (i = 0; i < num; i++) {
|
||||
cmd->cmd.set_eqd[i].eq_id = eq[i].q.id;
|
||||
cmd->cmd.set_eqd[i].phase = 0;
|
||||
cmd->cmd.set_eqd[i].delay_multiplier =
|
||||
(eq[i].aic_obj.prev_eqd * 65)/100;
|
||||
}
|
||||
status = ocrdma_mbx_cmd(dev, (struct ocrdma_mqe *)cmd);
|
||||
if (status)
|
||||
goto mbx_err;
|
||||
mbx_err:
|
||||
kfree(cmd);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int ocrdma_modify_eqd(struct ocrdma_dev *dev, struct ocrdma_eq *eq,
|
||||
int num)
|
||||
{
|
||||
int num_eqs, i = 0;
|
||||
if (num > 8) {
|
||||
while (num) {
|
||||
num_eqs = min(num, 8);
|
||||
ocrdma_mbx_modify_eqd(dev, &eq[i], num_eqs);
|
||||
i += num_eqs;
|
||||
num -= num_eqs;
|
||||
}
|
||||
} else {
|
||||
ocrdma_mbx_modify_eqd(dev, eq, num);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ocrdma_eqd_set_task(struct work_struct *work)
|
||||
{
|
||||
struct ocrdma_dev *dev =
|
||||
container_of(work, struct ocrdma_dev, eqd_work.work);
|
||||
struct ocrdma_eq *eq = 0;
|
||||
int i, num = 0, status = -EINVAL;
|
||||
u64 eq_intr;
|
||||
|
||||
for (i = 0; i < dev->eq_cnt; i++) {
|
||||
eq = &dev->eq_tbl[i];
|
||||
if (eq->aic_obj.eq_intr_cnt > eq->aic_obj.prev_eq_intr_cnt) {
|
||||
eq_intr = eq->aic_obj.eq_intr_cnt -
|
||||
eq->aic_obj.prev_eq_intr_cnt;
|
||||
if ((eq_intr > EQ_INTR_PER_SEC_THRSH_HI) &&
|
||||
(eq->aic_obj.prev_eqd == EQ_AIC_MIN_EQD)) {
|
||||
eq->aic_obj.prev_eqd = EQ_AIC_MAX_EQD;
|
||||
num++;
|
||||
} else if ((eq_intr < EQ_INTR_PER_SEC_THRSH_LOW) &&
|
||||
(eq->aic_obj.prev_eqd == EQ_AIC_MAX_EQD)) {
|
||||
eq->aic_obj.prev_eqd = EQ_AIC_MIN_EQD;
|
||||
num++;
|
||||
}
|
||||
}
|
||||
eq->aic_obj.prev_eq_intr_cnt = eq->aic_obj.eq_intr_cnt;
|
||||
}
|
||||
|
||||
if (num)
|
||||
status = ocrdma_modify_eqd(dev, &dev->eq_tbl[0], num);
|
||||
schedule_delayed_work(&dev->eqd_work, msecs_to_jiffies(1000));
|
||||
}
|
||||
|
||||
int ocrdma_init_hw(struct ocrdma_dev *dev)
|
||||
{
|
||||
int status;
|
||||
@@ -2915,6 +3144,7 @@ qpeq_err:
|
||||
|
||||
void ocrdma_cleanup_hw(struct ocrdma_dev *dev)
|
||||
{
|
||||
ocrdma_free_pd_pool(dev);
|
||||
ocrdma_mbx_delete_ah_tbl(dev);
|
||||
|
||||
/* cleanup the eqs */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user