mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
RDMA v6.11 merge window
Usual collection of small improvements and fixes: - Bug fixes and minor improvments in efa, irdma, mlx4, mlx5, rxe, hf1, qib, ocrdma - bnxt_re support for MSN, which is a new retransmit logic - Initial mana support for RC qps - Use after free bug and cleanups in iwcm - Reduce resource usage in mlx5 when RDMA verbs features are not used - New verb to drain shared recieve queues, similar to normal recieve queues. This is necessary to allow ULPs a clean shutdown. Used in the iscsi rdma target - mlx5 support for more than 16 bits of doorbell indexes - Doorbell moderation support for bnxt_re - IB multi-plane support for mlx5 - New EFA adaptor PCI IDs - RDMA_NAME_ASSIGN_TYPE_USER to hint to userspace that it shouldn't rename the device - A collection of hns bugs - Fix long standing bug in bnxt_re with incorrect endian handling of immediate data -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQRRRCHOFoQz/8F5bUaFwuHvBreFYQUCZpfvKQAKCRCFwuHvBreF YXomAP46gZpGv5mlMOAXePRuKq6glNZWl3pVuwuycnlmjQcEUQD/dhQbJz0rZKBr swuibPo83bFacfXJL7Wxd48m4G3EfgI= =1eXu -----END PGP SIGNATURE----- Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma Pull rdma updates from Jason Gunthorpe: "Usual collection of small improvements and fixes: - Bug fixes and minor improvments in efa, irdma, mlx4, mlx5, rxe, hf1, qib, ocrdma - bnxt_re support for MSN, which is a new retransmit logic - Initial mana support for RC qps - Use after free bug and cleanups in iwcm - Reduce resource usage in mlx5 when RDMA verbs features are not used - New verb to drain shared recieve queues, similar to normal recieve queues. This is necessary to allow ULPs a clean shutdown. Used in the iscsi rdma target - mlx5 support for more than 16 bits of doorbell indexes - Doorbell moderation support for bnxt_re - IB multi-plane support for mlx5 - New EFA adaptor PCI IDs - RDMA_NAME_ASSIGN_TYPE_USER to hint to userspace that it shouldn't rename the device - A collection of hns bugs - Fix long standing bug in bnxt_re with incorrect endian handling of immediate data" * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: (65 commits) IB/hfi1: Constify struct flag_table RDMA/mana_ib: Set correct device into ib bnxt_re: Fix imm_data endianness RDMA: Fix netdev tracker in ib_device_set_netdev RDMA/hns: Fix mbx timing out before CMD execution is completed RDMA/hns: Fix insufficient extend DB for VFs. RDMA/hns: Fix undifined behavior caused by invalid max_sge RDMA/hns: Fix shift-out-bounds when max_inline_data is 0 RDMA/hns: Fix missing pagesize and alignment check in FRMR RDMA/hns: Fix unmatch exception handling when init eq table fails RDMA/hns: Fix soft lockup under heavy CEQE load RDMA/hns: Check atomic wr length RDMA/ocrdma: Don't inline statistics functions RDMA/core: Introduce "name_assign_type" for an IB device RDMA/qib: Fix truncation compilation warnings in qib_verbs.c RDMA/qib: Fix truncation compilation warnings in qib_init.c RDMA/efa: Add EFA 0xefa3 PCI ID RDMA/mlx5: Support per-plane port IB counters by querying PPCNT register net/mlx5: mlx5_ifc update for accessing ppcnt register of plane ports RDMA/mlx5: Add plane index support when querying PTYS registers ...
This commit is contained in:
commit
3d51520954
@ -11207,7 +11207,7 @@ F: include/linux/net/intel/iidc.h
|
||||
|
||||
INTEL ETHERNET PROTOCOL DRIVER FOR RDMA
|
||||
M: Mustafa Ismail <mustafa.ismail@intel.com>
|
||||
M: Shiraz Saleem <shiraz.saleem@intel.com>
|
||||
M: Tatyana Nikolova <tatyana.e.nikolova@intel.com>
|
||||
L: linux-rdma@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/infiniband/hw/irdma/
|
||||
|
@ -59,7 +59,16 @@ __ib_get_agent_port(const struct ib_device *device, int port_num)
|
||||
struct ib_agent_port_private *entry;
|
||||
|
||||
list_for_each_entry(entry, &ib_agent_port_list, port_list) {
|
||||
if (entry->agent[1]->device == device &&
|
||||
/* Need to check both agent[0] and agent[1], as an agent port
|
||||
* may only have one of them
|
||||
*/
|
||||
if (entry->agent[0] &&
|
||||
entry->agent[0]->device == device &&
|
||||
entry->agent[0]->port_num == port_num)
|
||||
return entry;
|
||||
|
||||
if (entry->agent[1] &&
|
||||
entry->agent[1]->device == device &&
|
||||
entry->agent[1]->port_num == port_num)
|
||||
return entry;
|
||||
}
|
||||
@ -172,14 +181,16 @@ int ib_agent_port_open(struct ib_device *device, int port_num)
|
||||
}
|
||||
}
|
||||
|
||||
/* Obtain send only MAD agent for GSI QP */
|
||||
port_priv->agent[1] = ib_register_mad_agent(device, port_num,
|
||||
IB_QPT_GSI, NULL, 0,
|
||||
&agent_send_handler,
|
||||
NULL, NULL, 0);
|
||||
if (IS_ERR(port_priv->agent[1])) {
|
||||
ret = PTR_ERR(port_priv->agent[1]);
|
||||
goto error3;
|
||||
if (rdma_cap_ib_cm(device, port_num)) {
|
||||
/* Obtain send only MAD agent for GSI QP */
|
||||
port_priv->agent[1] = ib_register_mad_agent(device, port_num,
|
||||
IB_QPT_GSI, NULL, 0,
|
||||
&agent_send_handler,
|
||||
NULL, NULL, 0);
|
||||
if (IS_ERR(port_priv->agent[1])) {
|
||||
ret = PTR_ERR(port_priv->agent[1]);
|
||||
goto error3;
|
||||
}
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&ib_agent_port_list_lock, flags);
|
||||
@ -212,7 +223,8 @@ int ib_agent_port_close(struct ib_device *device, int port_num)
|
||||
list_del(&port_priv->port_list);
|
||||
spin_unlock_irqrestore(&ib_agent_port_list_lock, flags);
|
||||
|
||||
ib_unregister_mad_agent(port_priv->agent[1]);
|
||||
if (port_priv->agent[1])
|
||||
ib_unregister_mad_agent(port_priv->agent[1]);
|
||||
if (port_priv->agent[0])
|
||||
ib_unregister_mad_agent(port_priv->agent[0]);
|
||||
|
||||
|
@ -794,7 +794,6 @@ err_free_table:
|
||||
static void release_gid_table(struct ib_device *device,
|
||||
struct ib_gid_table *table)
|
||||
{
|
||||
bool leak = false;
|
||||
int i;
|
||||
|
||||
if (!table)
|
||||
@ -803,15 +802,12 @@ static void release_gid_table(struct ib_device *device,
|
||||
for (i = 0; i < table->sz; i++) {
|
||||
if (is_gid_entry_free(table->data_vec[i]))
|
||||
continue;
|
||||
if (kref_read(&table->data_vec[i]->kref) > 1) {
|
||||
dev_err(&device->dev,
|
||||
"GID entry ref leak for index %d ref=%u\n", i,
|
||||
kref_read(&table->data_vec[i]->kref));
|
||||
leak = true;
|
||||
}
|
||||
|
||||
WARN_ONCE(true,
|
||||
"GID entry ref leak for dev %s index %d ref=%u\n",
|
||||
dev_name(&device->dev), i,
|
||||
kref_read(&table->data_vec[i]->kref));
|
||||
}
|
||||
if (leak)
|
||||
return;
|
||||
|
||||
mutex_destroy(&table->lock);
|
||||
kfree(table->data_vec);
|
||||
|
@ -503,6 +503,7 @@ static void ib_device_release(struct device *device)
|
||||
rcu_head);
|
||||
}
|
||||
|
||||
mutex_destroy(&dev->subdev_lock);
|
||||
mutex_destroy(&dev->unregistration_lock);
|
||||
mutex_destroy(&dev->compat_devs_mutex);
|
||||
|
||||
@ -641,6 +642,11 @@ struct ib_device *_ib_alloc_device(size_t size)
|
||||
BIT_ULL(IB_USER_VERBS_CMD_REG_MR) |
|
||||
BIT_ULL(IB_USER_VERBS_CMD_REREG_MR) |
|
||||
BIT_ULL(IB_USER_VERBS_CMD_RESIZE_CQ);
|
||||
|
||||
mutex_init(&device->subdev_lock);
|
||||
INIT_LIST_HEAD(&device->subdev_list_head);
|
||||
INIT_LIST_HEAD(&device->subdev_list);
|
||||
|
||||
return device;
|
||||
}
|
||||
EXPORT_SYMBOL(_ib_alloc_device);
|
||||
@ -1461,6 +1467,18 @@ EXPORT_SYMBOL(ib_register_device);
|
||||
/* Callers must hold a get on the device. */
|
||||
static void __ib_unregister_device(struct ib_device *ib_dev)
|
||||
{
|
||||
struct ib_device *sub, *tmp;
|
||||
|
||||
mutex_lock(&ib_dev->subdev_lock);
|
||||
list_for_each_entry_safe_reverse(sub, tmp,
|
||||
&ib_dev->subdev_list_head,
|
||||
subdev_list) {
|
||||
list_del(&sub->subdev_list);
|
||||
ib_dev->ops.del_sub_dev(sub);
|
||||
ib_device_put(ib_dev);
|
||||
}
|
||||
mutex_unlock(&ib_dev->subdev_lock);
|
||||
|
||||
/*
|
||||
* We have a registration lock so that all the calls to unregister are
|
||||
* fully fenced, once any unregister returns the device is truely
|
||||
@ -2146,6 +2164,9 @@ int ib_device_set_netdev(struct ib_device *ib_dev, struct net_device *ndev,
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
if (!rdma_is_port_valid(ib_dev, port))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Drivers wish to call this before ib_register_driver, so we have to
|
||||
* setup the port data early.
|
||||
@ -2154,9 +2175,6 @@ int ib_device_set_netdev(struct ib_device *ib_dev, struct net_device *ndev,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!rdma_is_port_valid(ib_dev, port))
|
||||
return -EINVAL;
|
||||
|
||||
pdata = &ib_dev->port_data[port];
|
||||
spin_lock_irqsave(&pdata->netdev_lock, flags);
|
||||
old_ndev = rcu_dereference_protected(
|
||||
@ -2166,16 +2184,12 @@ int ib_device_set_netdev(struct ib_device *ib_dev, struct net_device *ndev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (old_ndev)
|
||||
netdev_tracker_free(ndev, &pdata->netdev_tracker);
|
||||
if (ndev)
|
||||
netdev_hold(ndev, &pdata->netdev_tracker, GFP_ATOMIC);
|
||||
rcu_assign_pointer(pdata->netdev, ndev);
|
||||
netdev_put(old_ndev, &pdata->netdev_tracker);
|
||||
netdev_hold(ndev, &pdata->netdev_tracker, GFP_ATOMIC);
|
||||
spin_unlock_irqrestore(&pdata->netdev_lock, flags);
|
||||
|
||||
add_ndev_hash(pdata);
|
||||
__dev_put(old_ndev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ib_device_set_netdev);
|
||||
@ -2597,6 +2611,7 @@ void ib_set_device_ops(struct ib_device *dev, const struct ib_device_ops *ops)
|
||||
ops->uverbs_no_driver_id_binding;
|
||||
|
||||
SET_DEVICE_OP(dev_ops, add_gid);
|
||||
SET_DEVICE_OP(dev_ops, add_sub_dev);
|
||||
SET_DEVICE_OP(dev_ops, advise_mr);
|
||||
SET_DEVICE_OP(dev_ops, alloc_dm);
|
||||
SET_DEVICE_OP(dev_ops, alloc_hw_device_stats);
|
||||
@ -2631,6 +2646,7 @@ void ib_set_device_ops(struct ib_device *dev, const struct ib_device_ops *ops)
|
||||
SET_DEVICE_OP(dev_ops, dealloc_ucontext);
|
||||
SET_DEVICE_OP(dev_ops, dealloc_xrcd);
|
||||
SET_DEVICE_OP(dev_ops, del_gid);
|
||||
SET_DEVICE_OP(dev_ops, del_sub_dev);
|
||||
SET_DEVICE_OP(dev_ops, dereg_mr);
|
||||
SET_DEVICE_OP(dev_ops, destroy_ah);
|
||||
SET_DEVICE_OP(dev_ops, destroy_counters);
|
||||
@ -2727,6 +2743,55 @@ void ib_set_device_ops(struct ib_device *dev, const struct ib_device_ops *ops)
|
||||
}
|
||||
EXPORT_SYMBOL(ib_set_device_ops);
|
||||
|
||||
int ib_add_sub_device(struct ib_device *parent,
|
||||
enum rdma_nl_dev_type type,
|
||||
const char *name)
|
||||
{
|
||||
struct ib_device *sub;
|
||||
int ret = 0;
|
||||
|
||||
if (!parent->ops.add_sub_dev || !parent->ops.del_sub_dev)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!ib_device_try_get(parent))
|
||||
return -EINVAL;
|
||||
|
||||
sub = parent->ops.add_sub_dev(parent, type, name);
|
||||
if (IS_ERR(sub)) {
|
||||
ib_device_put(parent);
|
||||
return PTR_ERR(sub);
|
||||
}
|
||||
|
||||
sub->type = type;
|
||||
sub->parent = parent;
|
||||
|
||||
mutex_lock(&parent->subdev_lock);
|
||||
list_add_tail(&parent->subdev_list_head, &sub->subdev_list);
|
||||
mutex_unlock(&parent->subdev_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(ib_add_sub_device);
|
||||
|
||||
int ib_del_sub_device_and_put(struct ib_device *sub)
|
||||
{
|
||||
struct ib_device *parent = sub->parent;
|
||||
|
||||
if (!parent)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
mutex_lock(&parent->subdev_lock);
|
||||
list_del(&sub->subdev_list);
|
||||
mutex_unlock(&parent->subdev_lock);
|
||||
|
||||
ib_device_put(sub);
|
||||
parent->ops.del_sub_dev(sub);
|
||||
ib_device_put(parent);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ib_del_sub_device_and_put);
|
||||
|
||||
#ifdef CONFIG_INFINIBAND_VIRT_DMA
|
||||
int ib_dma_virt_map_sg(struct ib_device *dev, struct scatterlist *sg, int nents)
|
||||
{
|
||||
|
@ -143,8 +143,8 @@ static struct iwcm_work *get_work(struct iwcm_id_private *cm_id_priv)
|
||||
|
||||
if (list_empty(&cm_id_priv->work_free_list))
|
||||
return NULL;
|
||||
work = list_entry(cm_id_priv->work_free_list.next, struct iwcm_work,
|
||||
free_list);
|
||||
work = list_first_entry(&cm_id_priv->work_free_list, struct iwcm_work,
|
||||
free_list);
|
||||
list_del_init(&work->free_list);
|
||||
return work;
|
||||
}
|
||||
@ -206,17 +206,17 @@ static void free_cm_id(struct iwcm_id_private *cm_id_priv)
|
||||
|
||||
/*
|
||||
* Release a reference on cm_id. If the last reference is being
|
||||
* released, free the cm_id and return 1.
|
||||
* released, free the cm_id and return 'true'.
|
||||
*/
|
||||
static int iwcm_deref_id(struct iwcm_id_private *cm_id_priv)
|
||||
static bool iwcm_deref_id(struct iwcm_id_private *cm_id_priv)
|
||||
{
|
||||
if (refcount_dec_and_test(&cm_id_priv->refcount)) {
|
||||
BUG_ON(!list_empty(&cm_id_priv->work_list));
|
||||
free_cm_id(cm_id_priv);
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void add_ref(struct iw_cm_id *cm_id)
|
||||
@ -368,8 +368,10 @@ EXPORT_SYMBOL(iw_cm_disconnect);
|
||||
*
|
||||
* Clean up all resources associated with the connection and release
|
||||
* the initial reference taken by iw_create_cm_id.
|
||||
*
|
||||
* Returns true if and only if the last cm_id_priv reference has been dropped.
|
||||
*/
|
||||
static void destroy_cm_id(struct iw_cm_id *cm_id)
|
||||
static bool destroy_cm_id(struct iw_cm_id *cm_id)
|
||||
{
|
||||
struct iwcm_id_private *cm_id_priv;
|
||||
struct ib_qp *qp;
|
||||
@ -439,7 +441,7 @@ static void destroy_cm_id(struct iw_cm_id *cm_id)
|
||||
iwpm_remove_mapping(&cm_id->local_addr, RDMA_NL_IWCM);
|
||||
}
|
||||
|
||||
(void)iwcm_deref_id(cm_id_priv);
|
||||
return iwcm_deref_id(cm_id_priv);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -450,7 +452,8 @@ static void destroy_cm_id(struct iw_cm_id *cm_id)
|
||||
*/
|
||||
void iw_destroy_cm_id(struct iw_cm_id *cm_id)
|
||||
{
|
||||
destroy_cm_id(cm_id);
|
||||
if (!destroy_cm_id(cm_id))
|
||||
flush_workqueue(iwcm_wq);
|
||||
}
|
||||
EXPORT_SYMBOL(iw_destroy_cm_id);
|
||||
|
||||
@ -1017,16 +1020,13 @@ static void cm_work_handler(struct work_struct *_work)
|
||||
struct iw_cm_event levent;
|
||||
struct iwcm_id_private *cm_id_priv = work->cm_id;
|
||||
unsigned long flags;
|
||||
int empty;
|
||||
int ret = 0;
|
||||
|
||||
spin_lock_irqsave(&cm_id_priv->lock, flags);
|
||||
empty = list_empty(&cm_id_priv->work_list);
|
||||
while (!empty) {
|
||||
work = list_entry(cm_id_priv->work_list.next,
|
||||
struct iwcm_work, list);
|
||||
while (!list_empty(&cm_id_priv->work_list)) {
|
||||
work = list_first_entry(&cm_id_priv->work_list,
|
||||
struct iwcm_work, list);
|
||||
list_del_init(&work->list);
|
||||
empty = list_empty(&cm_id_priv->work_list);
|
||||
levent = work->event;
|
||||
put_work(work);
|
||||
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
|
||||
@ -1034,13 +1034,11 @@ static void cm_work_handler(struct work_struct *_work)
|
||||
if (!test_bit(IWCM_F_DROP_EVENTS, &cm_id_priv->flags)) {
|
||||
ret = process_event(cm_id_priv, &levent);
|
||||
if (ret)
|
||||
destroy_cm_id(&cm_id_priv->id);
|
||||
WARN_ON_ONCE(destroy_cm_id(&cm_id_priv->id));
|
||||
} else
|
||||
pr_debug("dropping event %d\n", levent.event);
|
||||
if (iwcm_deref_id(cm_id_priv))
|
||||
return;
|
||||
if (empty)
|
||||
return;
|
||||
spin_lock_irqsave(&cm_id_priv->lock, flags);
|
||||
}
|
||||
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
|
||||
@ -1093,11 +1091,8 @@ static int cm_event_handler(struct iw_cm_id *cm_id,
|
||||
}
|
||||
|
||||
refcount_inc(&cm_id_priv->refcount);
|
||||
if (list_empty(&cm_id_priv->work_list)) {
|
||||
list_add_tail(&work->list, &cm_id_priv->work_list);
|
||||
queue_work(iwcm_wq, &work->work);
|
||||
} else
|
||||
list_add_tail(&work->list, &cm_id_priv->work_list);
|
||||
list_add_tail(&work->list, &cm_id_priv->work_list);
|
||||
queue_work(iwcm_wq, &work->work);
|
||||
out:
|
||||
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
|
||||
return ret;
|
||||
|
@ -2983,9 +2983,12 @@ static int ib_mad_port_open(struct ib_device *device,
|
||||
if (ret)
|
||||
goto error6;
|
||||
}
|
||||
ret = create_mad_qp(&port_priv->qp_info[1], IB_QPT_GSI);
|
||||
if (ret)
|
||||
goto error7;
|
||||
|
||||
if (rdma_cap_ib_cm(device, port_num)) {
|
||||
ret = create_mad_qp(&port_priv->qp_info[1], IB_QPT_GSI);
|
||||
if (ret)
|
||||
goto error7;
|
||||
}
|
||||
|
||||
snprintf(name, sizeof(name), "ib_mad%u", port_num);
|
||||
port_priv->wq = alloc_ordered_workqueue(name, WQ_MEM_RECLAIM);
|
||||
|
@ -167,6 +167,9 @@ static const struct nla_policy nldev_policy[RDMA_NLDEV_ATTR_MAX] = {
|
||||
[RDMA_NLDEV_ATTR_STAT_HWCOUNTER_DYNAMIC] = { .type = NLA_U8 },
|
||||
[RDMA_NLDEV_SYS_ATTR_PRIVILEGED_QKEY_MODE] = { .type = NLA_U8 },
|
||||
[RDMA_NLDEV_ATTR_DRIVER_DETAILS] = { .type = NLA_U8 },
|
||||
[RDMA_NLDEV_ATTR_DEV_TYPE] = { .type = NLA_U8 },
|
||||
[RDMA_NLDEV_ATTR_PARENT_NAME] = { .type = NLA_NUL_STRING },
|
||||
[RDMA_NLDEV_ATTR_NAME_ASSIGN_TYPE] = { .type = NLA_U8 },
|
||||
};
|
||||
|
||||
static int put_driver_name_print_type(struct sk_buff *msg, const char *name,
|
||||
@ -301,6 +304,19 @@ static int fill_dev_info(struct sk_buff *msg, struct ib_device *device)
|
||||
if (nla_put_u8(msg, RDMA_NLDEV_ATTR_DEV_DIM, device->use_cq_dim))
|
||||
return -EMSGSIZE;
|
||||
|
||||
if (device->type &&
|
||||
nla_put_u8(msg, RDMA_NLDEV_ATTR_DEV_TYPE, device->type))
|
||||
return -EMSGSIZE;
|
||||
|
||||
if (device->parent &&
|
||||
nla_put_string(msg, RDMA_NLDEV_ATTR_PARENT_NAME,
|
||||
dev_name(&device->parent->dev)))
|
||||
return -EMSGSIZE;
|
||||
|
||||
if (nla_put_u8(msg, RDMA_NLDEV_ATTR_NAME_ASSIGN_TYPE,
|
||||
device->name_assign_type))
|
||||
return -EMSGSIZE;
|
||||
|
||||
/*
|
||||
* Link type is determined on first port and mlx4 device
|
||||
* which can potentially have two different link type for the same
|
||||
@ -2548,6 +2564,56 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nldev_newdev(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct nlattr *tb[RDMA_NLDEV_ATTR_MAX];
|
||||
enum rdma_nl_dev_type type;
|
||||
struct ib_device *parent;
|
||||
char name[IFNAMSIZ] = {};
|
||||
u32 parentid;
|
||||
int ret;
|
||||
|
||||
ret = nlmsg_parse(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
|
||||
nldev_policy, extack);
|
||||
if (ret || !tb[RDMA_NLDEV_ATTR_DEV_INDEX] ||
|
||||
!tb[RDMA_NLDEV_ATTR_DEV_NAME] || !tb[RDMA_NLDEV_ATTR_DEV_TYPE])
|
||||
return -EINVAL;
|
||||
|
||||
nla_strscpy(name, tb[RDMA_NLDEV_ATTR_DEV_NAME], sizeof(name));
|
||||
type = nla_get_u8(tb[RDMA_NLDEV_ATTR_DEV_TYPE]);
|
||||
parentid = nla_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
|
||||
parent = ib_device_get_by_index(sock_net(skb->sk), parentid);
|
||||
if (!parent)
|
||||
return -EINVAL;
|
||||
|
||||
ret = ib_add_sub_device(parent, type, name);
|
||||
ib_device_put(parent);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nldev_deldev(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct nlattr *tb[RDMA_NLDEV_ATTR_MAX];
|
||||
struct ib_device *device;
|
||||
u32 devid;
|
||||
int ret;
|
||||
|
||||
ret = nlmsg_parse(nlh, 0, tb, RDMA_NLDEV_ATTR_MAX - 1,
|
||||
nldev_policy, extack);
|
||||
if (ret || !tb[RDMA_NLDEV_ATTR_DEV_INDEX])
|
||||
return -EINVAL;
|
||||
|
||||
devid = nla_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
|
||||
device = ib_device_get_by_index(sock_net(skb->sk), devid);
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
|
||||
return ib_del_sub_device_and_put(device);
|
||||
}
|
||||
|
||||
static const struct rdma_nl_cbs nldev_cb_table[RDMA_NLDEV_NUM_OPS] = {
|
||||
[RDMA_NLDEV_CMD_GET] = {
|
||||
.doit = nldev_get_doit,
|
||||
@ -2646,6 +2712,14 @@ static const struct rdma_nl_cbs nldev_cb_table[RDMA_NLDEV_NUM_OPS] = {
|
||||
[RDMA_NLDEV_CMD_STAT_GET_STATUS] = {
|
||||
.doit = nldev_stat_get_counter_status_doit,
|
||||
},
|
||||
[RDMA_NLDEV_CMD_NEWDEV] = {
|
||||
.doit = nldev_newdev,
|
||||
.flags = RDMA_NL_ADMIN_PERM,
|
||||
},
|
||||
[RDMA_NLDEV_CMD_DELDEV] = {
|
||||
.doit = nldev_deldev,
|
||||
.flags = RDMA_NL_ADMIN_PERM,
|
||||
},
|
||||
};
|
||||
|
||||
void __init nldev_init(void)
|
||||
|
@ -1321,15 +1321,17 @@ static int ib_umad_init_port(struct ib_device *device, int port_num,
|
||||
if (ret)
|
||||
goto err_cdev;
|
||||
|
||||
ib_umad_init_port_dev(&port->sm_dev, port, device);
|
||||
port->sm_dev.devt = base_issm;
|
||||
dev_set_name(&port->sm_dev, "issm%d", port->dev_num);
|
||||
cdev_init(&port->sm_cdev, &umad_sm_fops);
|
||||
port->sm_cdev.owner = THIS_MODULE;
|
||||
if (rdma_cap_ib_smi(device, port_num)) {
|
||||
ib_umad_init_port_dev(&port->sm_dev, port, device);
|
||||
port->sm_dev.devt = base_issm;
|
||||
dev_set_name(&port->sm_dev, "issm%d", port->dev_num);
|
||||
cdev_init(&port->sm_cdev, &umad_sm_fops);
|
||||
port->sm_cdev.owner = THIS_MODULE;
|
||||
|
||||
ret = cdev_device_add(&port->sm_cdev, &port->sm_dev);
|
||||
if (ret)
|
||||
goto err_dev;
|
||||
ret = cdev_device_add(&port->sm_cdev, &port->sm_dev);
|
||||
if (ret)
|
||||
goto err_dev;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@ -1345,9 +1347,13 @@ err_cdev:
|
||||
static void ib_umad_kill_port(struct ib_umad_port *port)
|
||||
{
|
||||
struct ib_umad_file *file;
|
||||
bool has_smi = false;
|
||||
int id;
|
||||
|
||||
cdev_device_del(&port->sm_cdev, &port->sm_dev);
|
||||
if (rdma_cap_ib_smi(port->ib_dev, port->port_num)) {
|
||||
cdev_device_del(&port->sm_cdev, &port->sm_dev);
|
||||
has_smi = true;
|
||||
}
|
||||
cdev_device_del(&port->cdev, &port->dev);
|
||||
|
||||
mutex_lock(&port->file_mutex);
|
||||
@ -1373,7 +1379,8 @@ static void ib_umad_kill_port(struct ib_umad_port *port)
|
||||
ida_free(&umad_ida, port->dev_num);
|
||||
|
||||
/* balances device_initialize() */
|
||||
put_device(&port->sm_dev);
|
||||
if (has_smi)
|
||||
put_device(&port->sm_dev);
|
||||
put_device(&port->dev);
|
||||
}
|
||||
|
||||
|
@ -1051,7 +1051,7 @@ static int create_cq(struct uverbs_attr_bundle *attrs,
|
||||
rdma_restrack_new(&cq->res, RDMA_RESTRACK_CQ);
|
||||
rdma_restrack_set_name(&cq->res, NULL);
|
||||
|
||||
ret = ib_dev->ops.create_cq(cq, &attr, &attrs->driver_udata);
|
||||
ret = ib_dev->ops.create_cq(cq, &attr, attrs);
|
||||
if (ret)
|
||||
goto err_free;
|
||||
rdma_restrack_add(&cq->res);
|
||||
|
@ -1114,7 +1114,8 @@ static int ib_uverbs_add_one(struct ib_device *device)
|
||||
struct ib_uverbs_device *uverbs_dev;
|
||||
int ret;
|
||||
|
||||
if (!device->ops.alloc_ucontext)
|
||||
if (!device->ops.alloc_ucontext ||
|
||||
device->type == RDMA_DEVICE_TYPE_SMI)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
uverbs_dev = kzalloc(sizeof(*uverbs_dev), GFP_KERNEL);
|
||||
|
@ -128,7 +128,7 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(
|
||||
rdma_restrack_new(&cq->res, RDMA_RESTRACK_CQ);
|
||||
rdma_restrack_set_name(&cq->res, NULL);
|
||||
|
||||
ret = ib_dev->ops.create_cq(cq, &attr, &attrs->driver_udata);
|
||||
ret = ib_dev->ops.create_cq(cq, &attr, attrs);
|
||||
if (ret)
|
||||
goto err_free;
|
||||
|
||||
|
@ -1101,6 +1101,16 @@ EXPORT_SYMBOL(ib_destroy_srq_user);
|
||||
|
||||
/* Queue pairs */
|
||||
|
||||
static void __ib_qp_event_handler(struct ib_event *event, void *context)
|
||||
{
|
||||
struct ib_qp *qp = event->element.qp;
|
||||
|
||||
if (event->event == IB_EVENT_QP_LAST_WQE_REACHED)
|
||||
complete(&qp->srq_completion);
|
||||
if (qp->registered_event_handler)
|
||||
qp->registered_event_handler(event, qp->qp_context);
|
||||
}
|
||||
|
||||
static void __ib_shared_qp_event_handler(struct ib_event *event, void *context)
|
||||
{
|
||||
struct ib_qp *qp = context;
|
||||
@ -1221,13 +1231,15 @@ static struct ib_qp *create_qp(struct ib_device *dev, struct ib_pd *pd,
|
||||
qp->qp_type = attr->qp_type;
|
||||
qp->rwq_ind_tbl = attr->rwq_ind_tbl;
|
||||
qp->srq = attr->srq;
|
||||
qp->event_handler = attr->event_handler;
|
||||
qp->event_handler = __ib_qp_event_handler;
|
||||
qp->registered_event_handler = attr->event_handler;
|
||||
qp->port = attr->port_num;
|
||||
qp->qp_context = attr->qp_context;
|
||||
|
||||
spin_lock_init(&qp->mr_lock);
|
||||
INIT_LIST_HEAD(&qp->rdma_mrs);
|
||||
INIT_LIST_HEAD(&qp->sig_mrs);
|
||||
init_completion(&qp->srq_completion);
|
||||
|
||||
qp->send_cq = attr->send_cq;
|
||||
qp->recv_cq = attr->recv_cq;
|
||||
@ -2884,6 +2896,72 @@ static void __ib_drain_rq(struct ib_qp *qp)
|
||||
wait_for_completion(&rdrain.done);
|
||||
}
|
||||
|
||||
/*
|
||||
* __ib_drain_srq() - Block until Last WQE Reached event arrives, or timeout
|
||||
* expires.
|
||||
* @qp: queue pair associated with SRQ to drain
|
||||
*
|
||||
* Quoting 10.3.1 Queue Pair and EE Context States:
|
||||
*
|
||||
* Note, for QPs that are associated with an SRQ, the Consumer should take the
|
||||
* QP through the Error State before invoking a Destroy QP or a Modify QP to the
|
||||
* Reset State. The Consumer may invoke the Destroy QP without first performing
|
||||
* a Modify QP to the Error State and waiting for the Affiliated Asynchronous
|
||||
* Last WQE Reached Event. However, if the Consumer does not wait for the
|
||||
* Affiliated Asynchronous Last WQE Reached Event, then WQE and Data Segment
|
||||
* leakage may occur. Therefore, it is good programming practice to tear down a
|
||||
* QP that is associated with an SRQ by using the following process:
|
||||
*
|
||||
* - Put the QP in the Error State
|
||||
* - Wait for the Affiliated Asynchronous Last WQE Reached Event;
|
||||
* - either:
|
||||
* drain the CQ by invoking the Poll CQ verb and either wait for CQ
|
||||
* to be empty or the number of Poll CQ operations has exceeded
|
||||
* CQ capacity size;
|
||||
* - or
|
||||
* post another WR that completes on the same CQ and wait for this
|
||||
* WR to return as a WC;
|
||||
* - and then invoke a Destroy QP or Reset QP.
|
||||
*
|
||||
* We use the first option.
|
||||
*/
|
||||
static void __ib_drain_srq(struct ib_qp *qp)
|
||||
{
|
||||
struct ib_qp_attr attr = { .qp_state = IB_QPS_ERR };
|
||||
struct ib_cq *cq;
|
||||
int n, polled = 0;
|
||||
int ret;
|
||||
|
||||
if (!qp->srq) {
|
||||
WARN_ONCE(1, "QP 0x%p is not associated with SRQ\n", qp);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = ib_modify_qp(qp, &attr, IB_QP_STATE);
|
||||
if (ret) {
|
||||
WARN_ONCE(ret, "failed to drain shared recv queue: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ib_srq_has_cq(qp->srq->srq_type)) {
|
||||
cq = qp->srq->ext.cq;
|
||||
} else if (qp->recv_cq) {
|
||||
cq = qp->recv_cq;
|
||||
} else {
|
||||
WARN_ONCE(1, "QP 0x%p has no CQ associated with SRQ\n", qp);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wait_for_completion_timeout(&qp->srq_completion, 60 * HZ) > 0) {
|
||||
while (polled != cq->cqe) {
|
||||
n = ib_process_cq_direct(cq, cq->cqe - polled);
|
||||
if (!n)
|
||||
return;
|
||||
polled += n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ib_drain_sq() - Block until all SQ CQEs have been consumed by the
|
||||
* application.
|
||||
@ -2962,6 +3040,8 @@ void ib_drain_qp(struct ib_qp *qp)
|
||||
ib_drain_sq(qp);
|
||||
if (!qp->srq)
|
||||
ib_drain_rq(qp);
|
||||
else
|
||||
__ib_drain_srq(qp);
|
||||
}
|
||||
EXPORT_SYMBOL(ib_drain_qp);
|
||||
|
||||
|
@ -129,9 +129,15 @@ struct bnxt_re_pacing {
|
||||
#define BNXT_RE_PACING_ALARM_TH_MULTIPLE 2 /* Multiple of pacing algo threshold */
|
||||
/* Default do_pacing value when there is no congestion */
|
||||
#define BNXT_RE_DBR_DO_PACING_NO_CONGESTION 0x7F /* 1 in 512 probability */
|
||||
#define BNXT_RE_DB_FIFO_ROOM_MASK 0x1FFF8000
|
||||
#define BNXT_RE_MAX_FIFO_DEPTH 0x2c00
|
||||
#define BNXT_RE_DB_FIFO_ROOM_SHIFT 15
|
||||
|
||||
#define BNXT_RE_MAX_FIFO_DEPTH_P5 0x2c00
|
||||
#define BNXT_RE_MAX_FIFO_DEPTH_P7 0x8000
|
||||
|
||||
#define BNXT_RE_MAX_FIFO_DEPTH(ctx) \
|
||||
(bnxt_qplib_is_chip_gen_p7((ctx)) ? \
|
||||
BNXT_RE_MAX_FIFO_DEPTH_P7 :\
|
||||
BNXT_RE_MAX_FIFO_DEPTH_P5)
|
||||
|
||||
#define BNXT_RE_GRC_FIFO_REG_BASE 0x2000
|
||||
|
||||
#define MAX_CQ_HASH_BITS (16)
|
||||
|
@ -2479,7 +2479,7 @@ static int bnxt_re_build_send_wqe(struct bnxt_re_qp *qp,
|
||||
break;
|
||||
case IB_WR_SEND_WITH_IMM:
|
||||
wqe->type = BNXT_QPLIB_SWQE_TYPE_SEND_WITH_IMM;
|
||||
wqe->send.imm_data = wr->ex.imm_data;
|
||||
wqe->send.imm_data = be32_to_cpu(wr->ex.imm_data);
|
||||
break;
|
||||
case IB_WR_SEND_WITH_INV:
|
||||
wqe->type = BNXT_QPLIB_SWQE_TYPE_SEND_WITH_INV;
|
||||
@ -2509,7 +2509,7 @@ static int bnxt_re_build_rdma_wqe(const struct ib_send_wr *wr,
|
||||
break;
|
||||
case IB_WR_RDMA_WRITE_WITH_IMM:
|
||||
wqe->type = BNXT_QPLIB_SWQE_TYPE_RDMA_WRITE_WITH_IMM;
|
||||
wqe->rdma.imm_data = wr->ex.imm_data;
|
||||
wqe->rdma.imm_data = be32_to_cpu(wr->ex.imm_data);
|
||||
break;
|
||||
case IB_WR_RDMA_READ:
|
||||
wqe->type = BNXT_QPLIB_SWQE_TYPE_RDMA_READ;
|
||||
@ -2948,10 +2948,11 @@ int bnxt_re_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
|
||||
}
|
||||
|
||||
int bnxt_re_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata)
|
||||
struct uverbs_attr_bundle *attrs)
|
||||
{
|
||||
struct bnxt_re_cq *cq = container_of(ibcq, struct bnxt_re_cq, ib_cq);
|
||||
struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibcq->device, ibdev);
|
||||
struct ib_udata *udata = &attrs->driver_udata;
|
||||
struct bnxt_re_ucontext *uctx =
|
||||
rdma_udata_to_drv_context(udata, struct bnxt_re_ucontext, ib_uctx);
|
||||
struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr;
|
||||
@ -3581,7 +3582,7 @@ static void bnxt_re_process_res_shadow_qp_wc(struct bnxt_re_qp *gsi_sqp,
|
||||
wc->byte_len = orig_cqe->length;
|
||||
wc->qp = &gsi_qp->ib_qp;
|
||||
|
||||
wc->ex.imm_data = orig_cqe->immdata;
|
||||
wc->ex.imm_data = cpu_to_be32(le32_to_cpu(orig_cqe->immdata));
|
||||
wc->src_qp = orig_cqe->src_qp;
|
||||
memcpy(wc->smac, orig_cqe->smac, ETH_ALEN);
|
||||
if (bnxt_re_is_vlan_pkt(orig_cqe, &vlan_id, &sl)) {
|
||||
@ -3726,7 +3727,7 @@ int bnxt_re_poll_cq(struct ib_cq *ib_cq, int num_entries, struct ib_wc *wc)
|
||||
(unsigned long)(cqe->qp_handle),
|
||||
struct bnxt_re_qp, qplib_qp);
|
||||
wc->qp = &qp->ib_qp;
|
||||
wc->ex.imm_data = cqe->immdata;
|
||||
wc->ex.imm_data = cpu_to_be32(le32_to_cpu(cqe->immdata));
|
||||
wc->src_qp = cqe->src_qp;
|
||||
memcpy(wc->smac, cqe->smac, ETH_ALEN);
|
||||
wc->port_num = 1;
|
||||
@ -4201,6 +4202,9 @@ int bnxt_re_alloc_ucontext(struct ib_ucontext *ctx, struct ib_udata *udata)
|
||||
if (rdev->pacing.dbr_pacing)
|
||||
resp.comp_mask |= BNXT_RE_UCNTX_CMASK_DBR_PACING_ENABLED;
|
||||
|
||||
if (_is_host_msn_table(rdev->qplib_res.dattr->dev_cap_flags2))
|
||||
resp.comp_mask |= BNXT_RE_UCNTX_CMASK_MSN_TABLE_ENABLED;
|
||||
|
||||
if (udata->inlen >= sizeof(ureq)) {
|
||||
rc = ib_copy_from_udata(&ureq, udata, min(udata->inlen, sizeof(ureq)));
|
||||
if (rc)
|
||||
|
@ -221,7 +221,7 @@ int bnxt_re_post_send(struct ib_qp *qp, const struct ib_send_wr *send_wr,
|
||||
int bnxt_re_post_recv(struct ib_qp *qp, const struct ib_recv_wr *recv_wr,
|
||||
const struct ib_recv_wr **bad_recv_wr);
|
||||
int bnxt_re_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata);
|
||||
struct uverbs_attr_bundle *attrs);
|
||||
int bnxt_re_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata);
|
||||
int bnxt_re_destroy_cq(struct ib_cq *cq, struct ib_udata *udata);
|
||||
int bnxt_re_poll_cq(struct ib_cq *cq, int num_entries, struct ib_wc *wc);
|
||||
|
@ -423,6 +423,7 @@ int bnxt_re_hwrm_qcaps(struct bnxt_re_dev *rdev)
|
||||
struct hwrm_func_qcaps_input req = {};
|
||||
struct bnxt_qplib_chip_ctx *cctx;
|
||||
struct bnxt_fw_msg fw_msg = {};
|
||||
u32 flags_ext2;
|
||||
int rc;
|
||||
|
||||
cctx = rdev->chip_ctx;
|
||||
@ -436,14 +437,15 @@ int bnxt_re_hwrm_qcaps(struct bnxt_re_dev *rdev)
|
||||
return rc;
|
||||
cctx->modes.db_push = le32_to_cpu(resp.flags) & FUNC_QCAPS_RESP_FLAGS_WCB_PUSH_MODE;
|
||||
|
||||
cctx->modes.dbr_pacing =
|
||||
le32_to_cpu(resp.flags_ext2) &
|
||||
FUNC_QCAPS_RESP_FLAGS_EXT2_DBR_PACING_EXT_SUPPORTED;
|
||||
flags_ext2 = le32_to_cpu(resp.flags_ext2);
|
||||
cctx->modes.dbr_pacing = flags_ext2 & FUNC_QCAPS_RESP_FLAGS_EXT2_DBR_PACING_EXT_SUPPORTED ||
|
||||
flags_ext2 & FUNC_QCAPS_RESP_FLAGS_EXT2_DBR_PACING_V0_SUPPORTED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bnxt_re_hwrm_dbr_pacing_qcfg(struct bnxt_re_dev *rdev)
|
||||
{
|
||||
struct bnxt_qplib_db_pacing_data *pacing_data = rdev->qplib_res.pacing_data;
|
||||
struct hwrm_func_dbr_pacing_qcfg_output resp = {};
|
||||
struct hwrm_func_dbr_pacing_qcfg_input req = {};
|
||||
struct bnxt_en_dev *en_dev = rdev->en_dev;
|
||||
@ -465,6 +467,13 @@ static int bnxt_re_hwrm_dbr_pacing_qcfg(struct bnxt_re_dev *rdev)
|
||||
cctx->dbr_stat_db_fifo =
|
||||
le32_to_cpu(resp.dbr_stat_db_fifo_reg) &
|
||||
~FUNC_DBR_PACING_QCFG_RESP_DBR_STAT_DB_FIFO_REG_ADDR_SPACE_MASK;
|
||||
|
||||
pacing_data->fifo_max_depth = le32_to_cpu(resp.dbr_stat_db_max_fifo_depth);
|
||||
if (!pacing_data->fifo_max_depth)
|
||||
pacing_data->fifo_max_depth = BNXT_RE_MAX_FIFO_DEPTH(cctx);
|
||||
pacing_data->fifo_room_mask = le32_to_cpu(resp.dbr_stat_db_fifo_reg_fifo_room_mask);
|
||||
pacing_data->fifo_room_shift = resp.dbr_stat_db_fifo_reg_fifo_room_shift;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -479,23 +488,45 @@ static void bnxt_re_set_default_pacing_data(struct bnxt_re_dev *rdev)
|
||||
pacing_data->pacing_th * BNXT_RE_PACING_ALARM_TH_MULTIPLE;
|
||||
}
|
||||
|
||||
static u32 __get_fifo_occupancy(struct bnxt_re_dev *rdev)
|
||||
{
|
||||
struct bnxt_qplib_db_pacing_data *pacing_data = rdev->qplib_res.pacing_data;
|
||||
u32 read_val, fifo_occup;
|
||||
|
||||
read_val = readl(rdev->en_dev->bar0 + rdev->pacing.dbr_db_fifo_reg_off);
|
||||
fifo_occup = pacing_data->fifo_max_depth -
|
||||
((read_val & pacing_data->fifo_room_mask) >>
|
||||
pacing_data->fifo_room_shift);
|
||||
return fifo_occup;
|
||||
}
|
||||
|
||||
static bool is_dbr_fifo_full(struct bnxt_re_dev *rdev)
|
||||
{
|
||||
u32 max_occup, fifo_occup;
|
||||
|
||||
fifo_occup = __get_fifo_occupancy(rdev);
|
||||
max_occup = BNXT_RE_MAX_FIFO_DEPTH(rdev->chip_ctx) - 1;
|
||||
if (fifo_occup == max_occup)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void __wait_for_fifo_occupancy_below_th(struct bnxt_re_dev *rdev)
|
||||
{
|
||||
u32 read_val, fifo_occup;
|
||||
struct bnxt_qplib_db_pacing_data *pacing_data = rdev->qplib_res.pacing_data;
|
||||
u32 fifo_occup;
|
||||
|
||||
/* loop shouldn't run infintely as the occupancy usually goes
|
||||
* below pacing algo threshold as soon as pacing kicks in.
|
||||
*/
|
||||
while (1) {
|
||||
read_val = readl(rdev->en_dev->bar0 + rdev->pacing.dbr_db_fifo_reg_off);
|
||||
fifo_occup = BNXT_RE_MAX_FIFO_DEPTH -
|
||||
((read_val & BNXT_RE_DB_FIFO_ROOM_MASK) >>
|
||||
BNXT_RE_DB_FIFO_ROOM_SHIFT);
|
||||
fifo_occup = __get_fifo_occupancy(rdev);
|
||||
/* Fifo occupancy cannot be greater the MAX FIFO depth */
|
||||
if (fifo_occup > BNXT_RE_MAX_FIFO_DEPTH)
|
||||
if (fifo_occup > pacing_data->fifo_max_depth)
|
||||
break;
|
||||
|
||||
if (fifo_occup < rdev->qplib_res.pacing_data->pacing_th)
|
||||
if (fifo_occup < pacing_data->pacing_th)
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -546,16 +577,13 @@ static void bnxt_re_pacing_timer_exp(struct work_struct *work)
|
||||
struct bnxt_re_dev *rdev = container_of(work, struct bnxt_re_dev,
|
||||
dbq_pacing_work.work);
|
||||
struct bnxt_qplib_db_pacing_data *pacing_data;
|
||||
u32 read_val, fifo_occup;
|
||||
u32 fifo_occup;
|
||||
|
||||
if (!mutex_trylock(&rdev->pacing.dbq_lock))
|
||||
return;
|
||||
|
||||
pacing_data = rdev->qplib_res.pacing_data;
|
||||
read_val = readl(rdev->en_dev->bar0 + rdev->pacing.dbr_db_fifo_reg_off);
|
||||
fifo_occup = BNXT_RE_MAX_FIFO_DEPTH -
|
||||
((read_val & BNXT_RE_DB_FIFO_ROOM_MASK) >>
|
||||
BNXT_RE_DB_FIFO_ROOM_SHIFT);
|
||||
fifo_occup = __get_fifo_occupancy(rdev);
|
||||
|
||||
if (fifo_occup > pacing_data->pacing_th)
|
||||
goto restart_timer;
|
||||
@ -594,7 +622,7 @@ void bnxt_re_pacing_alert(struct bnxt_re_dev *rdev)
|
||||
* Increase the alarm_th to max so that other user lib instances do not
|
||||
* keep alerting the driver.
|
||||
*/
|
||||
pacing_data->alarm_th = BNXT_RE_MAX_FIFO_DEPTH;
|
||||
pacing_data->alarm_th = pacing_data->fifo_max_depth;
|
||||
pacing_data->do_pacing = BNXT_RE_MAX_DBR_DO_PACING;
|
||||
cancel_work_sync(&rdev->dbq_fifo_check_work);
|
||||
schedule_work(&rdev->dbq_fifo_check_work);
|
||||
@ -603,9 +631,6 @@ void bnxt_re_pacing_alert(struct bnxt_re_dev *rdev)
|
||||
|
||||
static int bnxt_re_initialize_dbr_pacing(struct bnxt_re_dev *rdev)
|
||||
{
|
||||
if (bnxt_re_hwrm_dbr_pacing_qcfg(rdev))
|
||||
return -EIO;
|
||||
|
||||
/* Allocate a page for app use */
|
||||
rdev->pacing.dbr_page = (void *)__get_free_page(GFP_KERNEL);
|
||||
if (!rdev->pacing.dbr_page)
|
||||
@ -614,6 +639,12 @@ static int bnxt_re_initialize_dbr_pacing(struct bnxt_re_dev *rdev)
|
||||
memset((u8 *)rdev->pacing.dbr_page, 0, PAGE_SIZE);
|
||||
rdev->qplib_res.pacing_data = (struct bnxt_qplib_db_pacing_data *)rdev->pacing.dbr_page;
|
||||
|
||||
if (bnxt_re_hwrm_dbr_pacing_qcfg(rdev)) {
|
||||
free_page((u64)rdev->pacing.dbr_page);
|
||||
rdev->pacing.dbr_page = NULL;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* MAP HW window 2 for reading db fifo depth */
|
||||
writel(rdev->chip_ctx->dbr_stat_db_fifo & BNXT_GRC_BASE_MASK,
|
||||
rdev->en_dev->bar0 + BNXT_GRCPF_REG_WINDOW_BASE_OUT + 4);
|
||||
@ -623,13 +654,16 @@ static int bnxt_re_initialize_dbr_pacing(struct bnxt_re_dev *rdev)
|
||||
rdev->pacing.dbr_bar_addr =
|
||||
pci_resource_start(rdev->qplib_res.pdev, 0) + rdev->pacing.dbr_db_fifo_reg_off;
|
||||
|
||||
if (is_dbr_fifo_full(rdev)) {
|
||||
free_page((u64)rdev->pacing.dbr_page);
|
||||
rdev->pacing.dbr_page = NULL;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
rdev->pacing.pacing_algo_th = BNXT_RE_PACING_ALGO_THRESHOLD;
|
||||
rdev->pacing.dbq_pacing_time = BNXT_RE_DBR_PACING_TIME;
|
||||
rdev->pacing.dbr_def_do_pacing = BNXT_RE_DBR_DO_PACING_NO_CONGESTION;
|
||||
rdev->pacing.do_pacing_save = rdev->pacing.dbr_def_do_pacing;
|
||||
rdev->qplib_res.pacing_data->fifo_max_depth = BNXT_RE_MAX_FIFO_DEPTH;
|
||||
rdev->qplib_res.pacing_data->fifo_room_mask = BNXT_RE_DB_FIFO_ROOM_MASK;
|
||||
rdev->qplib_res.pacing_data->fifo_room_shift = BNXT_RE_DB_FIFO_ROOM_SHIFT;
|
||||
rdev->qplib_res.pacing_data->grc_reg_offset = rdev->pacing.dbr_db_fifo_reg_off;
|
||||
bnxt_re_set_default_pacing_data(rdev);
|
||||
/* Initialize worker for DBR Pacing */
|
||||
|
@ -984,7 +984,7 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
|
||||
u16 nsge;
|
||||
|
||||
if (res->dattr)
|
||||
qp->dev_cap_flags = res->dattr->dev_cap_flags;
|
||||
qp->is_host_msn_tbl = _is_host_msn_table(res->dattr->dev_cap_flags2);
|
||||
|
||||
sq->dbinfo.flags = 0;
|
||||
bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req,
|
||||
@ -1002,7 +1002,7 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
|
||||
sizeof(struct sq_psn_search_ext) :
|
||||
sizeof(struct sq_psn_search);
|
||||
|
||||
if (BNXT_RE_HW_RETX(qp->dev_cap_flags)) {
|
||||
if (qp->is_host_msn_tbl) {
|
||||
psn_sz = sizeof(struct sq_msn_search);
|
||||
qp->msn = 0;
|
||||
}
|
||||
@ -1016,7 +1016,7 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
|
||||
hwq_attr.aux_depth = psn_sz ? bnxt_qplib_set_sq_size(sq, qp->wqe_mode)
|
||||
: 0;
|
||||
/* Update msn tbl size */
|
||||
if (BNXT_RE_HW_RETX(qp->dev_cap_flags) && psn_sz) {
|
||||
if (qp->is_host_msn_tbl && psn_sz) {
|
||||
hwq_attr.aux_depth = roundup_pow_of_two(bnxt_qplib_set_sq_size(sq, qp->wqe_mode));
|
||||
qp->msn_tbl_sz = hwq_attr.aux_depth;
|
||||
qp->msn = 0;
|
||||
@ -1637,7 +1637,7 @@ static void bnxt_qplib_fill_psn_search(struct bnxt_qplib_qp *qp,
|
||||
if (!swq->psn_search)
|
||||
return;
|
||||
/* Handle MSN differently on cap flags */
|
||||
if (BNXT_RE_HW_RETX(qp->dev_cap_flags)) {
|
||||
if (qp->is_host_msn_tbl) {
|
||||
bnxt_qplib_fill_msn_search(qp, wqe, swq);
|
||||
return;
|
||||
}
|
||||
@ -1819,7 +1819,7 @@ int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp,
|
||||
}
|
||||
|
||||
swq = bnxt_qplib_get_swqe(sq, &wqe_idx);
|
||||
bnxt_qplib_pull_psn_buff(qp, sq, swq, BNXT_RE_HW_RETX(qp->dev_cap_flags));
|
||||
bnxt_qplib_pull_psn_buff(qp, sq, swq, qp->is_host_msn_tbl);
|
||||
|
||||
idx = 0;
|
||||
swq->slot_idx = hwq->prod;
|
||||
@ -2009,7 +2009,7 @@ int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp,
|
||||
rc = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
if (!BNXT_RE_HW_RETX(qp->dev_cap_flags) || msn_update) {
|
||||
if (!qp->is_host_msn_tbl || msn_update) {
|
||||
swq->next_psn = sq->psn & BTH_PSN_MASK;
|
||||
bnxt_qplib_fill_psn_search(qp, wqe, swq);
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ struct bnxt_qplib_swqe {
|
||||
/* Send, with imm, inval key */
|
||||
struct {
|
||||
union {
|
||||
__be32 imm_data;
|
||||
u32 imm_data;
|
||||
u32 inv_key;
|
||||
};
|
||||
u32 q_key;
|
||||
@ -182,7 +182,7 @@ struct bnxt_qplib_swqe {
|
||||
/* RDMA write, with imm, read */
|
||||
struct {
|
||||
union {
|
||||
__be32 imm_data;
|
||||
u32 imm_data;
|
||||
u32 inv_key;
|
||||
};
|
||||
u64 remote_va;
|
||||
@ -340,7 +340,7 @@ struct bnxt_qplib_qp {
|
||||
struct list_head rq_flush;
|
||||
u32 msn;
|
||||
u32 msn_tbl_sz;
|
||||
u16 dev_cap_flags;
|
||||
bool is_host_msn_tbl;
|
||||
};
|
||||
|
||||
#define BNXT_QPLIB_MAX_CQE_ENTRY_SIZE sizeof(struct cq_base)
|
||||
@ -389,7 +389,7 @@ struct bnxt_qplib_cqe {
|
||||
u16 cfa_meta;
|
||||
u64 wr_id;
|
||||
union {
|
||||
__be32 immdata;
|
||||
__le32 immdata;
|
||||
u32 invrkey;
|
||||
};
|
||||
u64 qp_handle;
|
||||
|
@ -554,6 +554,12 @@ static inline bool _is_hw_retx_supported(u16 dev_cap_flags)
|
||||
|
||||
#define BNXT_RE_HW_RETX(a) _is_hw_retx_supported((a))
|
||||
|
||||
static inline bool _is_host_msn_table(u16 dev_cap_ext_flags2)
|
||||
{
|
||||
return (dev_cap_ext_flags2 & CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_MASK) ==
|
||||
CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_HOST_MSN_TABLE;
|
||||
}
|
||||
|
||||
static inline u8 bnxt_qplib_dbr_pacing_en(struct bnxt_qplib_chip_ctx *cctx)
|
||||
{
|
||||
return cctx->modes.dbr_pacing;
|
||||
|
@ -156,6 +156,7 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw,
|
||||
(0x01 << RCFW_DBR_BASE_PAGE_SHIFT);
|
||||
attr->max_sgid = BNXT_QPLIB_NUM_GIDS_SUPPORTED;
|
||||
attr->dev_cap_flags = le16_to_cpu(sb->dev_cap_flags);
|
||||
attr->dev_cap_flags2 = le16_to_cpu(sb->dev_cap_ext_flags_2);
|
||||
|
||||
bnxt_qplib_query_version(rcfw, attr->fw_ver);
|
||||
|
||||
|
@ -72,6 +72,7 @@ struct bnxt_qplib_dev_attr {
|
||||
u8 tqm_alloc_reqs[MAX_TQM_ALLOC_REQ];
|
||||
bool is_atomic;
|
||||
u16 dev_cap_flags;
|
||||
u16 dev_cap_flags2;
|
||||
u32 max_dpi;
|
||||
};
|
||||
|
||||
|
@ -2157,8 +2157,36 @@ struct creq_query_func_resp_sb {
|
||||
__le32 tqm_alloc_reqs[12];
|
||||
__le32 max_dpi;
|
||||
u8 max_sge_var_wqe;
|
||||
u8 reserved_8;
|
||||
u8 dev_cap_ext_flags;
|
||||
#define CREQ_QUERY_FUNC_RESP_SB_ATOMIC_OPS_NOT_SUPPORTED 0x1UL
|
||||
#define CREQ_QUERY_FUNC_RESP_SB_DRV_VERSION_RGTR_SUPPORTED 0x2UL
|
||||
#define CREQ_QUERY_FUNC_RESP_SB_CREATE_QP_BATCH_SUPPORTED 0x4UL
|
||||
#define CREQ_QUERY_FUNC_RESP_SB_DESTROY_QP_BATCH_SUPPORTED 0x8UL
|
||||
#define CREQ_QUERY_FUNC_RESP_SB_ROCE_STATS_EXT_CTX_SUPPORTED 0x10UL
|
||||
#define CREQ_QUERY_FUNC_RESP_SB_CREATE_SRQ_SGE_SUPPORTED 0x20UL
|
||||
#define CREQ_QUERY_FUNC_RESP_SB_FIXED_SIZE_WQE_DISABLED 0x40UL
|
||||
#define CREQ_QUERY_FUNC_RESP_SB_DCN_SUPPORTED 0x80UL
|
||||
__le16 max_inline_data_var_wqe;
|
||||
__le32 start_qid;
|
||||
u8 max_msn_table_size;
|
||||
u8 reserved8_1;
|
||||
__le16 dev_cap_ext_flags_2;
|
||||
#define CREQ_QUERY_FUNC_RESP_SB_OPTIMIZE_MODIFY_QP_SUPPORTED 0x1UL
|
||||
#define CREQ_QUERY_FUNC_RESP_SB_CHANGE_UDP_SRC_PORT_WQE_SUPPORTED 0x2UL
|
||||
#define CREQ_QUERY_FUNC_RESP_SB_CQ_COALESCING_SUPPORTED 0x4UL
|
||||
#define CREQ_QUERY_FUNC_RESP_SB_MEMORY_REGION_RO_SUPPORTED 0x8UL
|
||||
#define CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_MASK 0x30UL
|
||||
#define CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_SFT 4
|
||||
#define CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_HOST_PSN_TABLE (0x0UL << 4)
|
||||
#define CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_HOST_MSN_TABLE (0x1UL << 4)
|
||||
#define CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_IQM_MSN_TABLE (0x2UL << 4)
|
||||
#define CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_LAST \
|
||||
CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_IQM_MSN_TABLE
|
||||
__le16 max_xp_qp_size;
|
||||
__le16 create_qp_batch_size;
|
||||
__le16 destroy_qp_batch_size;
|
||||
__le16 reserved16;
|
||||
__le64 reserved64;
|
||||
};
|
||||
|
||||
/* cmdq_set_func_resources (size:448b/56B) */
|
||||
|
@ -995,8 +995,9 @@ int c4iw_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
|
||||
}
|
||||
|
||||
int c4iw_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata)
|
||||
struct uverbs_attr_bundle *attrs)
|
||||
{
|
||||
struct ib_udata *udata = &attrs->driver_udata;
|
||||
struct ib_device *ibdev = ibcq->device;
|
||||
int entries = attr->cqe;
|
||||
int vector = attr->comp_vector;
|
||||
|
@ -978,7 +978,7 @@ int c4iw_dereg_mr(struct ib_mr *ib_mr, struct ib_udata *udata);
|
||||
int c4iw_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata);
|
||||
void c4iw_cq_rem_ref(struct c4iw_cq *chp);
|
||||
int c4iw_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata);
|
||||
struct uverbs_attr_bundle *attrs);
|
||||
int c4iw_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags);
|
||||
int c4iw_modify_srq(struct ib_srq *ib_srq, struct ib_srq_attr *attr,
|
||||
enum ib_srq_attr_mask srq_attr_mask,
|
||||
|
@ -161,7 +161,7 @@ int efa_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *init_attr,
|
||||
struct ib_udata *udata);
|
||||
int efa_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata);
|
||||
int efa_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata);
|
||||
struct uverbs_attr_bundle *attrs);
|
||||
struct ib_mr *efa_reg_mr(struct ib_pd *ibpd, u64 start, u64 length,
|
||||
u64 virt_addr, int access_flags,
|
||||
struct ib_udata *udata);
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
|
||||
/*
|
||||
* Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All rights reserved.
|
||||
* Copyright 2018-2024 Amazon.com, Inc. or its affiliates. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "efa_com.h"
|
||||
@ -406,8 +406,8 @@ static struct efa_comp_ctx *efa_com_submit_admin_cmd(struct efa_com_admin_queue
|
||||
return comp_ctx;
|
||||
}
|
||||
|
||||
static void efa_com_handle_single_admin_completion(struct efa_com_admin_queue *aq,
|
||||
struct efa_admin_acq_entry *cqe)
|
||||
static int efa_com_handle_single_admin_completion(struct efa_com_admin_queue *aq,
|
||||
struct efa_admin_acq_entry *cqe)
|
||||
{
|
||||
struct efa_comp_ctx *comp_ctx;
|
||||
u16 cmd_id;
|
||||
@ -416,11 +416,11 @@ static void efa_com_handle_single_admin_completion(struct efa_com_admin_queue *a
|
||||
EFA_ADMIN_ACQ_COMMON_DESC_COMMAND_ID);
|
||||
|
||||
comp_ctx = efa_com_get_comp_ctx(aq, cmd_id, false);
|
||||
if (!comp_ctx) {
|
||||
if (comp_ctx->status != EFA_CMD_SUBMITTED) {
|
||||
ibdev_err(aq->efa_dev,
|
||||
"comp_ctx is NULL. Changing the admin queue running state\n");
|
||||
clear_bit(EFA_AQ_STATE_RUNNING_BIT, &aq->state);
|
||||
return;
|
||||
"Received completion with unexpected command id[%d], sq producer: %d, sq consumer: %d, cq consumer: %d\n",
|
||||
cmd_id, aq->sq.pc, aq->sq.cc, aq->cq.cc);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
comp_ctx->status = EFA_CMD_COMPLETED;
|
||||
@ -428,14 +428,17 @@ static void efa_com_handle_single_admin_completion(struct efa_com_admin_queue *a
|
||||
|
||||
if (!test_bit(EFA_AQ_STATE_POLLING_BIT, &aq->state))
|
||||
complete(&comp_ctx->wait_event);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void efa_com_handle_admin_completion(struct efa_com_admin_queue *aq)
|
||||
{
|
||||
struct efa_admin_acq_entry *cqe;
|
||||
u16 queue_size_mask;
|
||||
u16 comp_num = 0;
|
||||
u16 comp_cmds = 0;
|
||||
u8 phase;
|
||||
int err;
|
||||
u16 ci;
|
||||
|
||||
queue_size_mask = aq->depth - 1;
|
||||
@ -453,10 +456,12 @@ static void efa_com_handle_admin_completion(struct efa_com_admin_queue *aq)
|
||||
* phase bit was validated
|
||||
*/
|
||||
dma_rmb();
|
||||
efa_com_handle_single_admin_completion(aq, cqe);
|
||||
err = efa_com_handle_single_admin_completion(aq, cqe);
|
||||
if (!err)
|
||||
comp_cmds++;
|
||||
|
||||
aq->cq.cc++;
|
||||
ci++;
|
||||
comp_num++;
|
||||
if (ci == aq->depth) {
|
||||
ci = 0;
|
||||
phase = !phase;
|
||||
@ -465,10 +470,9 @@ static void efa_com_handle_admin_completion(struct efa_com_admin_queue *aq)
|
||||
cqe = &aq->cq.entries[ci];
|
||||
}
|
||||
|
||||
aq->cq.cc += comp_num;
|
||||
aq->cq.phase = phase;
|
||||
aq->sq.cc += comp_num;
|
||||
atomic64_add(comp_num, &aq->stats.completed_cmd);
|
||||
aq->sq.cc += comp_cmds;
|
||||
atomic64_add(comp_cmds, &aq->stats.completed_cmd);
|
||||
}
|
||||
|
||||
static int efa_com_comp_status_to_errno(u8 comp_status)
|
||||
|
@ -16,11 +16,13 @@
|
||||
#define PCI_DEV_ID_EFA0_VF 0xefa0
|
||||
#define PCI_DEV_ID_EFA1_VF 0xefa1
|
||||
#define PCI_DEV_ID_EFA2_VF 0xefa2
|
||||
#define PCI_DEV_ID_EFA3_VF 0xefa3
|
||||
|
||||
static const struct pci_device_id efa_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA0_VF) },
|
||||
{ PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA1_VF) },
|
||||
{ PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA2_VF) },
|
||||
{ PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA3_VF) },
|
||||
{ }
|
||||
};
|
||||
|
||||
@ -190,15 +192,23 @@ static int efa_request_doorbell_bar(struct efa_dev *dev)
|
||||
{
|
||||
u8 db_bar_idx = dev->dev_attr.db_bar;
|
||||
struct pci_dev *pdev = dev->pdev;
|
||||
int bars;
|
||||
int pci_mem_bars;
|
||||
int db_bar;
|
||||
int err;
|
||||
|
||||
if (!(BIT(db_bar_idx) & EFA_BASE_BAR_MASK)) {
|
||||
bars = pci_select_bars(pdev, IORESOURCE_MEM) & BIT(db_bar_idx);
|
||||
db_bar = BIT(db_bar_idx);
|
||||
if (!(db_bar & EFA_BASE_BAR_MASK)) {
|
||||
pci_mem_bars = pci_select_bars(pdev, IORESOURCE_MEM);
|
||||
if (db_bar & ~pci_mem_bars) {
|
||||
dev_err(&pdev->dev,
|
||||
"Doorbells BAR unavailable. Requested %#x, available %#x\n",
|
||||
db_bar, pci_mem_bars);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
err = pci_request_selected_regions(pdev, bars, DRV_MODULE_NAME);
|
||||
err = pci_request_selected_regions(pdev, db_bar, DRV_MODULE_NAME);
|
||||
if (err) {
|
||||
dev_err(&dev->pdev->dev,
|
||||
dev_err(&pdev->dev,
|
||||
"pci_request_selected_regions for bar %d failed %d\n",
|
||||
db_bar_idx, err);
|
||||
return err;
|
||||
@ -531,7 +541,7 @@ static struct efa_dev *efa_probe_device(struct pci_dev *pdev)
|
||||
{
|
||||
struct efa_com_dev *edev;
|
||||
struct efa_dev *dev;
|
||||
int bars;
|
||||
int pci_mem_bars;
|
||||
int err;
|
||||
|
||||
err = pci_enable_device_mem(pdev);
|
||||
@ -556,8 +566,14 @@ static struct efa_dev *efa_probe_device(struct pci_dev *pdev)
|
||||
dev->pdev = pdev;
|
||||
xa_init(&dev->cqs_xa);
|
||||
|
||||
bars = pci_select_bars(pdev, IORESOURCE_MEM) & EFA_BASE_BAR_MASK;
|
||||
err = pci_request_selected_regions(pdev, bars, DRV_MODULE_NAME);
|
||||
pci_mem_bars = pci_select_bars(pdev, IORESOURCE_MEM);
|
||||
if (EFA_BASE_BAR_MASK & ~pci_mem_bars) {
|
||||
dev_err(&pdev->dev, "BARs unavailable. Requested %#x, available %#x\n",
|
||||
(int)EFA_BASE_BAR_MASK, pci_mem_bars);
|
||||
err = -ENODEV;
|
||||
goto err_ibdev_destroy;
|
||||
}
|
||||
err = pci_request_selected_regions(pdev, EFA_BASE_BAR_MASK, DRV_MODULE_NAME);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "pci_request_selected_regions failed %d\n",
|
||||
err);
|
||||
|
@ -26,10 +26,6 @@ enum {
|
||||
EFA_MMAP_IO_NC,
|
||||
};
|
||||
|
||||
#define EFA_AENQ_ENABLED_GROUPS \
|
||||
(BIT(EFA_ADMIN_FATAL_ERROR) | BIT(EFA_ADMIN_WARNING) | \
|
||||
BIT(EFA_ADMIN_NOTIFICATION) | BIT(EFA_ADMIN_KEEP_ALIVE))
|
||||
|
||||
struct efa_user_mmap_entry {
|
||||
struct rdma_user_mmap_entry rdma_entry;
|
||||
u64 address;
|
||||
@ -524,7 +520,7 @@ static int qp_mmap_entries_setup(struct efa_qp *qp,
|
||||
|
||||
address = dev->mem_bar_addr + resp->llq_desc_offset;
|
||||
length = PAGE_ALIGN(params->sq_ring_size_in_bytes +
|
||||
(resp->llq_desc_offset & ~PAGE_MASK));
|
||||
offset_in_page(resp->llq_desc_offset));
|
||||
|
||||
qp->llq_desc_mmap_entry =
|
||||
efa_user_mmap_entry_insert(&ucontext->ibucontext,
|
||||
@ -1084,8 +1080,9 @@ static int cq_mmap_entries_setup(struct efa_dev *dev, struct efa_cq *cq,
|
||||
}
|
||||
|
||||
int efa_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata)
|
||||
struct uverbs_attr_bundle *attrs)
|
||||
{
|
||||
struct ib_udata *udata = &attrs->driver_udata;
|
||||
struct efa_ucontext *ucontext = rdma_udata_to_drv_context(
|
||||
udata, struct efa_ucontext, ibucontext);
|
||||
struct efa_com_create_cq_params params = {};
|
||||
|
@ -1628,8 +1628,9 @@ err_out:
|
||||
}
|
||||
|
||||
int erdma_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata)
|
||||
struct uverbs_attr_bundle *attrs)
|
||||
{
|
||||
struct ib_udata *udata = &attrs->driver_udata;
|
||||
struct erdma_cq *cq = to_ecq(ibcq);
|
||||
struct erdma_dev *dev = to_edev(ibcq->device);
|
||||
unsigned int depth = attr->cqe;
|
||||
|
@ -329,7 +329,7 @@ int erdma_query_device(struct ib_device *dev, struct ib_device_attr *attr,
|
||||
int erdma_get_port_immutable(struct ib_device *dev, u32 port,
|
||||
struct ib_port_immutable *ib_port_immutable);
|
||||
int erdma_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *data);
|
||||
struct uverbs_attr_bundle *attrs);
|
||||
int erdma_query_port(struct ib_device *dev, u32 port,
|
||||
struct ib_port_attr *attr);
|
||||
int erdma_query_gid(struct ib_device *dev, u32 port, int idx,
|
||||
|
@ -251,7 +251,7 @@ struct flag_table {
|
||||
/*
|
||||
* CCE Error flags.
|
||||
*/
|
||||
static struct flag_table cce_err_status_flags[] = {
|
||||
static const struct flag_table cce_err_status_flags[] = {
|
||||
/* 0*/ FLAG_ENTRY0("CceCsrParityErr",
|
||||
CCE_ERR_STATUS_CCE_CSR_PARITY_ERR_SMASK),
|
||||
/* 1*/ FLAG_ENTRY0("CceCsrReadBadAddrErr",
|
||||
@ -341,7 +341,7 @@ static struct flag_table cce_err_status_flags[] = {
|
||||
* Misc Error flags
|
||||
*/
|
||||
#define MES(text) MISC_ERR_STATUS_MISC_##text##_ERR_SMASK
|
||||
static struct flag_table misc_err_status_flags[] = {
|
||||
static const struct flag_table misc_err_status_flags[] = {
|
||||
/* 0*/ FLAG_ENTRY0("CSR_PARITY", MES(CSR_PARITY)),
|
||||
/* 1*/ FLAG_ENTRY0("CSR_READ_BAD_ADDR", MES(CSR_READ_BAD_ADDR)),
|
||||
/* 2*/ FLAG_ENTRY0("CSR_WRITE_BAD_ADDR", MES(CSR_WRITE_BAD_ADDR)),
|
||||
@ -360,7 +360,7 @@ static struct flag_table misc_err_status_flags[] = {
|
||||
/*
|
||||
* TXE PIO Error flags and consequences
|
||||
*/
|
||||
static struct flag_table pio_err_status_flags[] = {
|
||||
static const struct flag_table pio_err_status_flags[] = {
|
||||
/* 0*/ FLAG_ENTRY("PioWriteBadCtxt",
|
||||
SEC_WRITE_DROPPED,
|
||||
SEND_PIO_ERR_STATUS_PIO_WRITE_BAD_CTXT_ERR_SMASK),
|
||||
@ -502,7 +502,7 @@ static struct flag_table pio_err_status_flags[] = {
|
||||
/*
|
||||
* TXE SDMA Error flags
|
||||
*/
|
||||
static struct flag_table sdma_err_status_flags[] = {
|
||||
static const struct flag_table sdma_err_status_flags[] = {
|
||||
/* 0*/ FLAG_ENTRY0("SDmaRpyTagErr",
|
||||
SEND_DMA_ERR_STATUS_SDMA_RPY_TAG_ERR_SMASK),
|
||||
/* 1*/ FLAG_ENTRY0("SDmaCsrParityErr",
|
||||
@ -530,7 +530,7 @@ static struct flag_table sdma_err_status_flags[] = {
|
||||
* TXE Egress Error flags
|
||||
*/
|
||||
#define SEES(text) SEND_EGRESS_ERR_STATUS_##text##_ERR_SMASK
|
||||
static struct flag_table egress_err_status_flags[] = {
|
||||
static const struct flag_table egress_err_status_flags[] = {
|
||||
/* 0*/ FLAG_ENTRY0("TxPktIntegrityMemCorErr", SEES(TX_PKT_INTEGRITY_MEM_COR)),
|
||||
/* 1*/ FLAG_ENTRY0("TxPktIntegrityMemUncErr", SEES(TX_PKT_INTEGRITY_MEM_UNC)),
|
||||
/* 2 reserved */
|
||||
@ -631,7 +631,7 @@ static struct flag_table egress_err_status_flags[] = {
|
||||
* TXE Egress Error Info flags
|
||||
*/
|
||||
#define SEEI(text) SEND_EGRESS_ERR_INFO_##text##_ERR_SMASK
|
||||
static struct flag_table egress_err_info_flags[] = {
|
||||
static const struct flag_table egress_err_info_flags[] = {
|
||||
/* 0*/ FLAG_ENTRY0("Reserved", 0ull),
|
||||
/* 1*/ FLAG_ENTRY0("VLErr", SEEI(VL)),
|
||||
/* 2*/ FLAG_ENTRY0("JobKeyErr", SEEI(JOB_KEY)),
|
||||
@ -680,7 +680,7 @@ static struct flag_table egress_err_info_flags[] = {
|
||||
* TXE Send error flags
|
||||
*/
|
||||
#define SES(name) SEND_ERR_STATUS_SEND_##name##_ERR_SMASK
|
||||
static struct flag_table send_err_status_flags[] = {
|
||||
static const struct flag_table send_err_status_flags[] = {
|
||||
/* 0*/ FLAG_ENTRY0("SendCsrParityErr", SES(CSR_PARITY)),
|
||||
/* 1*/ FLAG_ENTRY0("SendCsrReadBadAddrErr", SES(CSR_READ_BAD_ADDR)),
|
||||
/* 2*/ FLAG_ENTRY0("SendCsrWriteBadAddrErr", SES(CSR_WRITE_BAD_ADDR))
|
||||
@ -689,7 +689,7 @@ static struct flag_table send_err_status_flags[] = {
|
||||
/*
|
||||
* TXE Send Context Error flags and consequences
|
||||
*/
|
||||
static struct flag_table sc_err_status_flags[] = {
|
||||
static const struct flag_table sc_err_status_flags[] = {
|
||||
/* 0*/ FLAG_ENTRY("InconsistentSop",
|
||||
SEC_PACKET_DROPPED | SEC_SC_HALTED,
|
||||
SEND_CTXT_ERR_STATUS_PIO_INCONSISTENT_SOP_ERR_SMASK),
|
||||
@ -712,7 +712,7 @@ static struct flag_table sc_err_status_flags[] = {
|
||||
* RXE Receive Error flags
|
||||
*/
|
||||
#define RXES(name) RCV_ERR_STATUS_RX_##name##_ERR_SMASK
|
||||
static struct flag_table rxe_err_status_flags[] = {
|
||||
static const struct flag_table rxe_err_status_flags[] = {
|
||||
/* 0*/ FLAG_ENTRY0("RxDmaCsrCorErr", RXES(DMA_CSR_COR)),
|
||||
/* 1*/ FLAG_ENTRY0("RxDcIntfParityErr", RXES(DC_INTF_PARITY)),
|
||||
/* 2*/ FLAG_ENTRY0("RxRcvHdrUncErr", RXES(RCV_HDR_UNC)),
|
||||
@ -847,7 +847,7 @@ static struct flag_table rxe_err_status_flags[] = {
|
||||
* DCC Error Flags
|
||||
*/
|
||||
#define DCCE(name) DCC_ERR_FLG_##name##_SMASK
|
||||
static struct flag_table dcc_err_flags[] = {
|
||||
static const struct flag_table dcc_err_flags[] = {
|
||||
FLAG_ENTRY0("bad_l2_err", DCCE(BAD_L2_ERR)),
|
||||
FLAG_ENTRY0("bad_sc_err", DCCE(BAD_SC_ERR)),
|
||||
FLAG_ENTRY0("bad_mid_tail_err", DCCE(BAD_MID_TAIL_ERR)),
|
||||
@ -900,7 +900,7 @@ static struct flag_table dcc_err_flags[] = {
|
||||
* LCB error flags
|
||||
*/
|
||||
#define LCBE(name) DC_LCB_ERR_FLG_##name##_SMASK
|
||||
static struct flag_table lcb_err_flags[] = {
|
||||
static const struct flag_table lcb_err_flags[] = {
|
||||
/* 0*/ FLAG_ENTRY0("CSR_PARITY_ERR", LCBE(CSR_PARITY_ERR)),
|
||||
/* 1*/ FLAG_ENTRY0("INVALID_CSR_ADDR", LCBE(INVALID_CSR_ADDR)),
|
||||
/* 2*/ FLAG_ENTRY0("RST_FOR_FAILED_DESKEW", LCBE(RST_FOR_FAILED_DESKEW)),
|
||||
@ -943,7 +943,7 @@ static struct flag_table lcb_err_flags[] = {
|
||||
* DC8051 Error Flags
|
||||
*/
|
||||
#define D8E(name) DC_DC8051_ERR_FLG_##name##_SMASK
|
||||
static struct flag_table dc8051_err_flags[] = {
|
||||
static const struct flag_table dc8051_err_flags[] = {
|
||||
FLAG_ENTRY0("SET_BY_8051", D8E(SET_BY_8051)),
|
||||
FLAG_ENTRY0("LOST_8051_HEART_BEAT", D8E(LOST_8051_HEART_BEAT)),
|
||||
FLAG_ENTRY0("CRAM_MBE", D8E(CRAM_MBE)),
|
||||
@ -962,7 +962,7 @@ static struct flag_table dc8051_err_flags[] = {
|
||||
*
|
||||
* Flags in DC8051_DBG_ERR_INFO_SET_BY_8051.ERROR field.
|
||||
*/
|
||||
static struct flag_table dc8051_info_err_flags[] = {
|
||||
static const struct flag_table dc8051_info_err_flags[] = {
|
||||
FLAG_ENTRY0("Spico ROM check failed", SPICO_ROM_FAILED),
|
||||
FLAG_ENTRY0("Unknown frame received", UNKNOWN_FRAME),
|
||||
FLAG_ENTRY0("Target BER not met", TARGET_BER_NOT_MET),
|
||||
@ -986,7 +986,7 @@ static struct flag_table dc8051_info_err_flags[] = {
|
||||
*
|
||||
* Flags in DC8051_DBG_ERR_INFO_SET_BY_8051.HOST_MSG field.
|
||||
*/
|
||||
static struct flag_table dc8051_info_host_msg_flags[] = {
|
||||
static const struct flag_table dc8051_info_host_msg_flags[] = {
|
||||
FLAG_ENTRY0("Host request done", 0x0001),
|
||||
FLAG_ENTRY0("BC PWR_MGM message", 0x0002),
|
||||
FLAG_ENTRY0("BC SMA message", 0x0004),
|
||||
@ -5275,7 +5275,7 @@ done:
|
||||
* the buffer. End in '*' if the buffer is too short.
|
||||
*/
|
||||
static char *flag_string(char *buf, int buf_len, u64 flags,
|
||||
struct flag_table *table, int table_size)
|
||||
const struct flag_table *table, int table_size)
|
||||
{
|
||||
char extra[32];
|
||||
char *p = buf;
|
||||
|
@ -40,7 +40,7 @@ static unsigned long mmu_node_last(struct mmu_rb_node *node)
|
||||
}
|
||||
|
||||
int hfi1_mmu_rb_register(void *ops_arg,
|
||||
struct mmu_rb_ops *ops,
|
||||
const struct mmu_rb_ops *ops,
|
||||
struct workqueue_struct *wq,
|
||||
struct mmu_rb_handler **handler)
|
||||
{
|
||||
|
@ -42,7 +42,7 @@ struct mmu_rb_handler {
|
||||
/* Begin on a new cachline boundary here */
|
||||
struct rb_root_cached root ____cacheline_aligned_in_smp;
|
||||
void *ops_arg;
|
||||
struct mmu_rb_ops *ops;
|
||||
const struct mmu_rb_ops *ops;
|
||||
struct list_head lru_list;
|
||||
struct work_struct del_work;
|
||||
struct list_head del_list;
|
||||
@ -51,7 +51,7 @@ struct mmu_rb_handler {
|
||||
};
|
||||
|
||||
int hfi1_mmu_rb_register(void *ops_arg,
|
||||
struct mmu_rb_ops *ops,
|
||||
const struct mmu_rb_ops *ops,
|
||||
struct workqueue_struct *wq,
|
||||
struct mmu_rb_handler **handler);
|
||||
void hfi1_mmu_rb_unregister(struct mmu_rb_handler *handler);
|
||||
|
@ -26,7 +26,7 @@ static int sdma_rb_evict(void *arg, struct mmu_rb_node *mnode, void *arg2,
|
||||
bool *stop);
|
||||
static void sdma_rb_remove(void *arg, struct mmu_rb_node *mnode);
|
||||
|
||||
static struct mmu_rb_ops sdma_rb_ops = {
|
||||
static const struct mmu_rb_ops sdma_rb_ops = {
|
||||
.filter = sdma_rb_filter,
|
||||
.evict = sdma_rb_evict,
|
||||
.remove = sdma_rb_remove,
|
||||
|
@ -353,9 +353,10 @@ static int set_cqe_size(struct hns_roce_cq *hr_cq, struct ib_udata *udata,
|
||||
}
|
||||
|
||||
int hns_roce_create_cq(struct ib_cq *ib_cq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata)
|
||||
struct uverbs_attr_bundle *attrs)
|
||||
{
|
||||
struct hns_roce_dev *hr_dev = to_hr_dev(ib_cq->device);
|
||||
struct ib_udata *udata = &attrs->driver_udata;
|
||||
struct hns_roce_ib_create_cq_resp resp = {};
|
||||
struct hns_roce_cq *hr_cq = to_hr_cq(ib_cq);
|
||||
struct ib_device *ibdev = &hr_dev->ib_dev;
|
||||
|
@ -83,6 +83,7 @@
|
||||
#define MR_TYPE_DMA 0x03
|
||||
|
||||
#define HNS_ROCE_FRMR_MAX_PA 512
|
||||
#define HNS_ROCE_FRMR_ALIGN_SIZE 128
|
||||
|
||||
#define PKEY_ID 0xffff
|
||||
#define NODE_DESC_SIZE 64
|
||||
@ -91,6 +92,8 @@
|
||||
/* Configure to HW for PAGE_SIZE larger than 4KB */
|
||||
#define PG_SHIFT_OFFSET (PAGE_SHIFT - 12)
|
||||
|
||||
#define ATOMIC_WR_LEN 8
|
||||
|
||||
#define HNS_ROCE_IDX_QUE_ENTRY_SZ 4
|
||||
#define SRQ_DB_REG 0x230
|
||||
|
||||
@ -187,6 +190,9 @@ enum {
|
||||
#define HNS_HW_PAGE_SHIFT 12
|
||||
#define HNS_HW_PAGE_SIZE (1 << HNS_HW_PAGE_SHIFT)
|
||||
|
||||
#define HNS_HW_MAX_PAGE_SHIFT 27
|
||||
#define HNS_HW_MAX_PAGE_SIZE (1 << HNS_HW_MAX_PAGE_SHIFT)
|
||||
|
||||
struct hns_roce_uar {
|
||||
u64 pfn;
|
||||
unsigned long index;
|
||||
@ -715,6 +721,7 @@ struct hns_roce_eq {
|
||||
int shift;
|
||||
int event_type;
|
||||
int sub_type;
|
||||
struct work_struct work;
|
||||
};
|
||||
|
||||
struct hns_roce_eq_table {
|
||||
@ -1267,7 +1274,7 @@ __be32 send_ieth(const struct ib_send_wr *wr);
|
||||
int to_hr_qp_type(int qp_type);
|
||||
|
||||
int hns_roce_create_cq(struct ib_cq *ib_cq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata);
|
||||
struct uverbs_attr_bundle *attrs);
|
||||
|
||||
int hns_roce_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata);
|
||||
int hns_roce_db_map_user(struct hns_roce_ucontext *context, unsigned long virt,
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <net/addrconf.h>
|
||||
#include <rdma/ib_addr.h>
|
||||
#include <rdma/ib_cache.h>
|
||||
@ -591,11 +592,16 @@ static inline int set_rc_wqe(struct hns_roce_qp *qp,
|
||||
(wr->send_flags & IB_SEND_SIGNALED) ? 1 : 0);
|
||||
|
||||
if (wr->opcode == IB_WR_ATOMIC_CMP_AND_SWP ||
|
||||
wr->opcode == IB_WR_ATOMIC_FETCH_AND_ADD)
|
||||
wr->opcode == IB_WR_ATOMIC_FETCH_AND_ADD) {
|
||||
if (msg_len != ATOMIC_WR_LEN)
|
||||
return -EINVAL;
|
||||
set_atomic_seg(wr, rc_sq_wqe, valid_num_sge);
|
||||
else if (wr->opcode != IB_WR_REG_MR)
|
||||
} else if (wr->opcode != IB_WR_REG_MR) {
|
||||
ret = set_rwqe_data_seg(&qp->ibqp, wr, rc_sq_wqe,
|
||||
&curr_idx, valid_num_sge);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* The pipeline can sequentially post all valid WQEs into WQ buffer,
|
||||
@ -1269,12 +1275,38 @@ static int hns_roce_cmd_err_convert_errno(u16 desc_ret)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static u32 hns_roce_cmdq_tx_timeout(u16 opcode, u32 tx_timeout)
|
||||
{
|
||||
static const struct hns_roce_cmdq_tx_timeout_map cmdq_tx_timeout[] = {
|
||||
{HNS_ROCE_OPC_POST_MB, HNS_ROCE_OPC_POST_MB_TIMEOUT},
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cmdq_tx_timeout); i++)
|
||||
if (cmdq_tx_timeout[i].opcode == opcode)
|
||||
return cmdq_tx_timeout[i].tx_timeout;
|
||||
|
||||
return tx_timeout;
|
||||
}
|
||||
|
||||
static void hns_roce_wait_csq_done(struct hns_roce_dev *hr_dev, u16 opcode)
|
||||
{
|
||||
struct hns_roce_v2_priv *priv = hr_dev->priv;
|
||||
u32 tx_timeout = hns_roce_cmdq_tx_timeout(opcode, priv->cmq.tx_timeout);
|
||||
u32 timeout = 0;
|
||||
|
||||
do {
|
||||
if (hns_roce_cmq_csq_done(hr_dev))
|
||||
break;
|
||||
udelay(1);
|
||||
} while (++timeout < tx_timeout);
|
||||
}
|
||||
|
||||
static int __hns_roce_cmq_send(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_cmq_desc *desc, int num)
|
||||
{
|
||||
struct hns_roce_v2_priv *priv = hr_dev->priv;
|
||||
struct hns_roce_v2_cmq_ring *csq = &priv->cmq.csq;
|
||||
u32 timeout = 0;
|
||||
u16 desc_ret;
|
||||
u32 tail;
|
||||
int ret;
|
||||
@ -1295,12 +1327,7 @@ static int __hns_roce_cmq_send(struct hns_roce_dev *hr_dev,
|
||||
|
||||
atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_CMDS_CNT]);
|
||||
|
||||
do {
|
||||
if (hns_roce_cmq_csq_done(hr_dev))
|
||||
break;
|
||||
udelay(1);
|
||||
} while (++timeout < priv->cmq.tx_timeout);
|
||||
|
||||
hns_roce_wait_csq_done(hr_dev, le16_to_cpu(desc->opcode));
|
||||
if (hns_roce_cmq_csq_done(hr_dev)) {
|
||||
ret = 0;
|
||||
for (i = 0; i < num; i++) {
|
||||
@ -2457,14 +2484,16 @@ static int set_llm_cfg_to_hw(struct hns_roce_dev *hr_dev,
|
||||
static struct hns_roce_link_table *
|
||||
alloc_link_table_buf(struct hns_roce_dev *hr_dev)
|
||||
{
|
||||
u16 total_sl = hr_dev->caps.sl_num * hr_dev->func_num;
|
||||
struct hns_roce_v2_priv *priv = hr_dev->priv;
|
||||
struct hns_roce_link_table *link_tbl;
|
||||
u32 pg_shift, size, min_size;
|
||||
|
||||
link_tbl = &priv->ext_llm;
|
||||
pg_shift = hr_dev->caps.llm_buf_pg_sz + PAGE_SHIFT;
|
||||
size = hr_dev->caps.num_qps * HNS_ROCE_V2_EXT_LLM_ENTRY_SZ;
|
||||
min_size = HNS_ROCE_EXT_LLM_MIN_PAGES(hr_dev->caps.sl_num) << pg_shift;
|
||||
size = hr_dev->caps.num_qps * hr_dev->func_num *
|
||||
HNS_ROCE_V2_EXT_LLM_ENTRY_SZ;
|
||||
min_size = HNS_ROCE_EXT_LLM_MIN_PAGES(total_sl) << pg_shift;
|
||||
|
||||
/* Alloc data table */
|
||||
size = max(size, min_size);
|
||||
@ -6135,33 +6164,11 @@ static struct hns_roce_ceqe *next_ceqe_sw_v2(struct hns_roce_eq *eq)
|
||||
!!(eq->cons_index & eq->entries)) ? ceqe : NULL;
|
||||
}
|
||||
|
||||
static irqreturn_t hns_roce_v2_ceq_int(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_eq *eq)
|
||||
static irqreturn_t hns_roce_v2_ceq_int(struct hns_roce_eq *eq)
|
||||
{
|
||||
struct hns_roce_ceqe *ceqe = next_ceqe_sw_v2(eq);
|
||||
irqreturn_t ceqe_found = IRQ_NONE;
|
||||
u32 cqn;
|
||||
queue_work(system_bh_wq, &eq->work);
|
||||
|
||||
while (ceqe) {
|
||||
/* Make sure we read CEQ entry after we have checked the
|
||||
* ownership bit
|
||||
*/
|
||||
dma_rmb();
|
||||
|
||||
cqn = hr_reg_read(ceqe, CEQE_CQN);
|
||||
|
||||
hns_roce_cq_completion(hr_dev, cqn);
|
||||
|
||||
++eq->cons_index;
|
||||
ceqe_found = IRQ_HANDLED;
|
||||
atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_CEQE_CNT]);
|
||||
|
||||
ceqe = next_ceqe_sw_v2(eq);
|
||||
}
|
||||
|
||||
update_eq_db(eq);
|
||||
|
||||
return IRQ_RETVAL(ceqe_found);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t hns_roce_v2_msix_interrupt_eq(int irq, void *eq_ptr)
|
||||
@ -6172,7 +6179,7 @@ static irqreturn_t hns_roce_v2_msix_interrupt_eq(int irq, void *eq_ptr)
|
||||
|
||||
if (eq->type_flag == HNS_ROCE_CEQ)
|
||||
/* Completion event interrupt */
|
||||
int_work = hns_roce_v2_ceq_int(hr_dev, eq);
|
||||
int_work = hns_roce_v2_ceq_int(eq);
|
||||
else
|
||||
/* Asynchronous event interrupt */
|
||||
int_work = hns_roce_v2_aeq_int(hr_dev, eq);
|
||||
@ -6384,9 +6391,16 @@ static void hns_roce_v2_int_mask_enable(struct hns_roce_dev *hr_dev,
|
||||
roce_write(hr_dev, ROCEE_VF_ABN_INT_CFG_REG, enable_flag);
|
||||
}
|
||||
|
||||
static void hns_roce_v2_destroy_eqc(struct hns_roce_dev *hr_dev, u32 eqn)
|
||||
static void free_eq_buf(struct hns_roce_dev *hr_dev, struct hns_roce_eq *eq)
|
||||
{
|
||||
hns_roce_mtr_destroy(hr_dev, &eq->mtr);
|
||||
}
|
||||
|
||||
static void hns_roce_v2_destroy_eqc(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_eq *eq)
|
||||
{
|
||||
struct device *dev = hr_dev->dev;
|
||||
int eqn = eq->eqn;
|
||||
int ret;
|
||||
u8 cmd;
|
||||
|
||||
@ -6397,12 +6411,9 @@ static void hns_roce_v2_destroy_eqc(struct hns_roce_dev *hr_dev, u32 eqn)
|
||||
|
||||
ret = hns_roce_destroy_hw_ctx(hr_dev, cmd, eqn & HNS_ROCE_V2_EQN_M);
|
||||
if (ret)
|
||||
dev_err(dev, "[mailbox cmd] destroy eqc(%u) failed.\n", eqn);
|
||||
}
|
||||
dev_err(dev, "[mailbox cmd] destroy eqc(%d) failed.\n", eqn);
|
||||
|
||||
static void free_eq_buf(struct hns_roce_dev *hr_dev, struct hns_roce_eq *eq)
|
||||
{
|
||||
hns_roce_mtr_destroy(hr_dev, &eq->mtr);
|
||||
free_eq_buf(hr_dev, eq);
|
||||
}
|
||||
|
||||
static void init_eq_config(struct hns_roce_dev *hr_dev, struct hns_roce_eq *eq)
|
||||
@ -6540,6 +6551,34 @@ free_cmd_mbox:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void hns_roce_ceq_work(struct work_struct *work)
|
||||
{
|
||||
struct hns_roce_eq *eq = from_work(eq, work, work);
|
||||
struct hns_roce_ceqe *ceqe = next_ceqe_sw_v2(eq);
|
||||
struct hns_roce_dev *hr_dev = eq->hr_dev;
|
||||
int ceqe_num = 0;
|
||||
u32 cqn;
|
||||
|
||||
while (ceqe && ceqe_num < hr_dev->caps.ceqe_depth) {
|
||||
/* Make sure we read CEQ entry after we have checked the
|
||||
* ownership bit
|
||||
*/
|
||||
dma_rmb();
|
||||
|
||||
cqn = hr_reg_read(ceqe, CEQE_CQN);
|
||||
|
||||
hns_roce_cq_completion(hr_dev, cqn);
|
||||
|
||||
++eq->cons_index;
|
||||
++ceqe_num;
|
||||
atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_CEQE_CNT]);
|
||||
|
||||
ceqe = next_ceqe_sw_v2(eq);
|
||||
}
|
||||
|
||||
update_eq_db(eq);
|
||||
}
|
||||
|
||||
static int __hns_roce_request_irq(struct hns_roce_dev *hr_dev, int irq_num,
|
||||
int comp_num, int aeq_num, int other_num)
|
||||
{
|
||||
@ -6571,21 +6610,24 @@ static int __hns_roce_request_irq(struct hns_roce_dev *hr_dev, int irq_num,
|
||||
j - other_num - aeq_num);
|
||||
|
||||
for (j = 0; j < irq_num; j++) {
|
||||
if (j < other_num)
|
||||
if (j < other_num) {
|
||||
ret = request_irq(hr_dev->irq[j],
|
||||
hns_roce_v2_msix_interrupt_abn,
|
||||
0, hr_dev->irq_names[j], hr_dev);
|
||||
|
||||
else if (j < (other_num + comp_num))
|
||||
} else if (j < (other_num + comp_num)) {
|
||||
INIT_WORK(&eq_table->eq[j - other_num].work,
|
||||
hns_roce_ceq_work);
|
||||
ret = request_irq(eq_table->eq[j - other_num].irq,
|
||||
hns_roce_v2_msix_interrupt_eq,
|
||||
0, hr_dev->irq_names[j + aeq_num],
|
||||
&eq_table->eq[j - other_num]);
|
||||
else
|
||||
} else {
|
||||
ret = request_irq(eq_table->eq[j - other_num].irq,
|
||||
hns_roce_v2_msix_interrupt_eq,
|
||||
0, hr_dev->irq_names[j - comp_num],
|
||||
&eq_table->eq[j - other_num]);
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
dev_err(hr_dev->dev, "request irq error!\n");
|
||||
goto err_request_failed;
|
||||
@ -6595,12 +6637,16 @@ static int __hns_roce_request_irq(struct hns_roce_dev *hr_dev, int irq_num,
|
||||
return 0;
|
||||
|
||||
err_request_failed:
|
||||
for (j -= 1; j >= 0; j--)
|
||||
if (j < other_num)
|
||||
for (j -= 1; j >= 0; j--) {
|
||||
if (j < other_num) {
|
||||
free_irq(hr_dev->irq[j], hr_dev);
|
||||
else
|
||||
free_irq(eq_table->eq[j - other_num].irq,
|
||||
&eq_table->eq[j - other_num]);
|
||||
continue;
|
||||
}
|
||||
free_irq(eq_table->eq[j - other_num].irq,
|
||||
&eq_table->eq[j - other_num]);
|
||||
if (j < other_num + comp_num)
|
||||
cancel_work_sync(&eq_table->eq[j - other_num].work);
|
||||
}
|
||||
|
||||
err_kzalloc_failed:
|
||||
for (i -= 1; i >= 0; i--)
|
||||
@ -6621,8 +6667,11 @@ static void __hns_roce_free_irq(struct hns_roce_dev *hr_dev)
|
||||
for (i = 0; i < hr_dev->caps.num_other_vectors; i++)
|
||||
free_irq(hr_dev->irq[i], hr_dev);
|
||||
|
||||
for (i = 0; i < eq_num; i++)
|
||||
for (i = 0; i < eq_num; i++) {
|
||||
free_irq(hr_dev->eq_table.eq[i].irq, &hr_dev->eq_table.eq[i]);
|
||||
if (i < hr_dev->caps.num_comp_vectors)
|
||||
cancel_work_sync(&hr_dev->eq_table.eq[i].work);
|
||||
}
|
||||
|
||||
for (i = 0; i < irq_num; i++)
|
||||
kfree(hr_dev->irq_names[i]);
|
||||
@ -6711,7 +6760,7 @@ err_request_irq_fail:
|
||||
|
||||
err_create_eq_fail:
|
||||
for (i -= 1; i >= 0; i--)
|
||||
free_eq_buf(hr_dev, &eq_table->eq[i]);
|
||||
hns_roce_v2_destroy_eqc(hr_dev, &eq_table->eq[i]);
|
||||
kfree(eq_table->eq);
|
||||
|
||||
return ret;
|
||||
@ -6731,11 +6780,8 @@ static void hns_roce_v2_cleanup_eq_table(struct hns_roce_dev *hr_dev)
|
||||
__hns_roce_free_irq(hr_dev);
|
||||
destroy_workqueue(hr_dev->irq_workq);
|
||||
|
||||
for (i = 0; i < eq_num; i++) {
|
||||
hns_roce_v2_destroy_eqc(hr_dev, i);
|
||||
|
||||
free_eq_buf(hr_dev, &eq_table->eq[i]);
|
||||
}
|
||||
for (i = 0; i < eq_num; i++)
|
||||
hns_roce_v2_destroy_eqc(hr_dev, &eq_table->eq[i]);
|
||||
|
||||
kfree(eq_table->eq);
|
||||
}
|
||||
|
@ -224,6 +224,12 @@ enum hns_roce_opcode_type {
|
||||
HNS_SWITCH_PARAMETER_CFG = 0x1033,
|
||||
};
|
||||
|
||||
#define HNS_ROCE_OPC_POST_MB_TIMEOUT 35000
|
||||
struct hns_roce_cmdq_tx_timeout_map {
|
||||
u16 opcode;
|
||||
u32 tx_timeout;
|
||||
};
|
||||
|
||||
enum {
|
||||
TYPE_CRQ,
|
||||
TYPE_CSQ,
|
||||
|
@ -443,6 +443,11 @@ int hns_roce_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents,
|
||||
struct hns_roce_mtr *mtr = &mr->pbl_mtr;
|
||||
int ret, sg_num = 0;
|
||||
|
||||
if (!IS_ALIGNED(*sg_offset, HNS_ROCE_FRMR_ALIGN_SIZE) ||
|
||||
ibmr->page_size < HNS_HW_PAGE_SIZE ||
|
||||
ibmr->page_size > HNS_HW_MAX_PAGE_SIZE)
|
||||
return sg_num;
|
||||
|
||||
mr->npages = 0;
|
||||
mr->page_list = kvcalloc(mr->pbl_mtr.hem_cfg.buf_pg_count,
|
||||
sizeof(dma_addr_t), GFP_KERNEL);
|
||||
|
@ -532,13 +532,15 @@ static unsigned int get_sge_num_from_max_inl_data(bool is_ud_or_gsi,
|
||||
{
|
||||
unsigned int inline_sge;
|
||||
|
||||
inline_sge = roundup_pow_of_two(max_inline_data) / HNS_ROCE_SGE_SIZE;
|
||||
if (!max_inline_data)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* if max_inline_data less than
|
||||
* HNS_ROCE_SGE_IN_WQE * HNS_ROCE_SGE_SIZE,
|
||||
* In addition to ud's mode, no need to extend sge.
|
||||
*/
|
||||
inline_sge = roundup_pow_of_two(max_inline_data) / HNS_ROCE_SGE_SIZE;
|
||||
if (!is_ud_or_gsi && inline_sge <= HNS_ROCE_SGE_IN_WQE)
|
||||
inline_sge = 0;
|
||||
|
||||
|
@ -297,7 +297,7 @@ static int set_srq_basic_param(struct hns_roce_srq *srq,
|
||||
|
||||
max_sge = proc_srq_sge(hr_dev, srq, !!udata);
|
||||
if (attr->max_wr > hr_dev->caps.max_srq_wrs ||
|
||||
attr->max_sge > max_sge) {
|
||||
attr->max_sge > max_sge || !attr->max_sge) {
|
||||
ibdev_err(&hr_dev->ib_dev,
|
||||
"invalid SRQ attr, depth = %u, sge = %u.\n",
|
||||
attr->max_wr, attr->max_sge);
|
||||
|
@ -239,7 +239,7 @@ struct irdma_qv_info {
|
||||
|
||||
struct irdma_qvlist_info {
|
||||
u32 num_vectors;
|
||||
struct irdma_qv_info qv_info[];
|
||||
struct irdma_qv_info qv_info[] __counted_by(num_vectors);
|
||||
};
|
||||
|
||||
struct irdma_gen_ops {
|
||||
|
@ -2035,14 +2035,15 @@ static inline int cq_validate_flags(u32 flags, u8 hw_rev)
|
||||
* irdma_create_cq - create cq
|
||||
* @ibcq: CQ allocated
|
||||
* @attr: attributes for cq
|
||||
* @udata: user data
|
||||
* @attrs: uverbs attribute bundle
|
||||
*/
|
||||
static int irdma_create_cq(struct ib_cq *ibcq,
|
||||
const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata)
|
||||
struct uverbs_attr_bundle *attrs)
|
||||
{
|
||||
#define IRDMA_CREATE_CQ_MIN_REQ_LEN offsetofend(struct irdma_create_cq_req, user_cq_buf)
|
||||
#define IRDMA_CREATE_CQ_MIN_RESP_LEN offsetofend(struct irdma_create_cq_resp, cq_size)
|
||||
struct ib_udata *udata = &attrs->driver_udata;
|
||||
struct ib_device *ibdev = ibcq->device;
|
||||
struct irdma_device *iwdev = to_iwdev(ibdev);
|
||||
struct irdma_pci_f *rf = iwdev->rf;
|
||||
|
@ -6,8 +6,9 @@
|
||||
#include "mana_ib.h"
|
||||
|
||||
int mana_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata)
|
||||
struct uverbs_attr_bundle *attrs)
|
||||
{
|
||||
struct ib_udata *udata = &attrs->driver_udata;
|
||||
struct mana_ib_cq *cq = container_of(ibcq, struct mana_ib_cq, ibcq);
|
||||
struct mana_ib_create_cq_resp resp = {};
|
||||
struct mana_ib_ucontext *mana_ucontext;
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "mana_ib.h"
|
||||
#include <net/mana/mana_auxiliary.h>
|
||||
#include <net/addrconf.h>
|
||||
|
||||
MODULE_DESCRIPTION("Microsoft Azure Network Adapter IB driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
@ -55,7 +56,7 @@ static int mana_ib_probe(struct auxiliary_device *adev,
|
||||
{
|
||||
struct mana_adev *madev = container_of(adev, struct mana_adev, adev);
|
||||
struct gdma_dev *mdev = madev->mdev;
|
||||
struct net_device *upper_ndev;
|
||||
struct net_device *ndev;
|
||||
struct mana_context *mc;
|
||||
struct mana_ib_dev *dev;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
@ -83,16 +84,17 @@ static int mana_ib_probe(struct auxiliary_device *adev,
|
||||
dev->ib_dev.num_comp_vectors = mdev->gdma_context->max_num_queues;
|
||||
dev->ib_dev.dev.parent = mdev->gdma_context->dev;
|
||||
|
||||
rcu_read_lock(); /* required to get upper dev */
|
||||
upper_ndev = netdev_master_upper_dev_get_rcu(mc->ports[0]);
|
||||
if (!upper_ndev) {
|
||||
rcu_read_lock(); /* required to get primary netdev */
|
||||
ndev = mana_get_primary_netdev_rcu(mc, 0);
|
||||
if (!ndev) {
|
||||
rcu_read_unlock();
|
||||
ret = -ENODEV;
|
||||
ibdev_err(&dev->ib_dev, "Failed to get master netdev");
|
||||
ibdev_err(&dev->ib_dev, "Failed to get netdev for IB port 1");
|
||||
goto free_ib_device;
|
||||
}
|
||||
ether_addr_copy(mac_addr, upper_ndev->dev_addr);
|
||||
ret = ib_device_set_netdev(&dev->ib_dev, upper_ndev, 1);
|
||||
ether_addr_copy(mac_addr, ndev->dev_addr);
|
||||
addrconf_addr_eui48((u8 *)&dev->ib_dev.node_guid, ndev->dev_addr);
|
||||
ret = ib_device_set_netdev(&dev->ib_dev, ndev, 1);
|
||||
rcu_read_unlock();
|
||||
if (ret) {
|
||||
ibdev_err(&dev->ib_dev, "Failed to set ib netdev, ret %d", ret);
|
||||
@ -124,6 +126,7 @@ static int mana_ib_probe(struct auxiliary_device *adev,
|
||||
if (ret)
|
||||
goto destroy_eqs;
|
||||
|
||||
xa_init_flags(&dev->qp_table_wq, XA_FLAGS_LOCK_IRQ);
|
||||
ret = mana_ib_gd_config_mac(dev, ADDR_OP_ADD, mac_addr);
|
||||
if (ret) {
|
||||
ibdev_err(&dev->ib_dev, "Failed to add Mac address, ret %d",
|
||||
@ -141,6 +144,7 @@ static int mana_ib_probe(struct auxiliary_device *adev,
|
||||
return 0;
|
||||
|
||||
destroy_rnic:
|
||||
xa_destroy(&dev->qp_table_wq);
|
||||
mana_ib_gd_destroy_rnic_adapter(dev);
|
||||
destroy_eqs:
|
||||
mana_ib_destroy_eqs(dev);
|
||||
@ -156,6 +160,7 @@ static void mana_ib_remove(struct auxiliary_device *adev)
|
||||
struct mana_ib_dev *dev = dev_get_drvdata(&adev->dev);
|
||||
|
||||
ib_unregister_device(&dev->ib_dev);
|
||||
xa_destroy(&dev->qp_table_wq);
|
||||
mana_ib_gd_destroy_rnic_adapter(dev);
|
||||
mana_ib_destroy_eqs(dev);
|
||||
mana_gd_deregister_device(dev->gdma_dev);
|
||||
|
@ -547,14 +547,27 @@ int mana_ib_query_device(struct ib_device *ibdev, struct ib_device_attr *props,
|
||||
struct mana_ib_dev *dev = container_of(ibdev,
|
||||
struct mana_ib_dev, ib_dev);
|
||||
|
||||
memset(props, 0, sizeof(*props));
|
||||
props->max_mr_size = MANA_IB_MAX_MR_SIZE;
|
||||
props->page_size_cap = PAGE_SZ_BM;
|
||||
props->max_qp = dev->adapter_caps.max_qp_count;
|
||||
props->max_qp_wr = dev->adapter_caps.max_qp_wr;
|
||||
props->device_cap_flags = IB_DEVICE_RC_RNR_NAK_GEN;
|
||||
props->max_send_sge = dev->adapter_caps.max_send_sge_count;
|
||||
props->max_recv_sge = dev->adapter_caps.max_recv_sge_count;
|
||||
props->max_sge_rd = dev->adapter_caps.max_recv_sge_count;
|
||||
props->max_cq = dev->adapter_caps.max_cq_count;
|
||||
props->max_cqe = dev->adapter_caps.max_qp_wr;
|
||||
props->max_mr = dev->adapter_caps.max_mr_count;
|
||||
props->max_mr_size = MANA_IB_MAX_MR_SIZE;
|
||||
props->max_send_sge = dev->adapter_caps.max_send_sge_count;
|
||||
props->max_recv_sge = dev->adapter_caps.max_recv_sge_count;
|
||||
props->max_pd = dev->adapter_caps.max_pd_count;
|
||||
props->max_qp_rd_atom = dev->adapter_caps.max_inbound_read_limit;
|
||||
props->max_res_rd_atom = props->max_qp_rd_atom * props->max_qp;
|
||||
props->max_qp_init_rd_atom = dev->adapter_caps.max_outbound_read_limit;
|
||||
props->atomic_cap = IB_ATOMIC_NONE;
|
||||
props->masked_atomic_cap = IB_ATOMIC_NONE;
|
||||
props->max_ah = INT_MAX;
|
||||
props->max_pkeys = 1;
|
||||
props->local_ca_ack_delay = MANA_CA_ACK_DELAY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -654,6 +667,33 @@ int mana_ib_gd_query_adapter_caps(struct mana_ib_dev *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
mana_ib_event_handler(void *ctx, struct gdma_queue *q, struct gdma_event *event)
|
||||
{
|
||||
struct mana_ib_dev *mdev = (struct mana_ib_dev *)ctx;
|
||||
struct mana_ib_qp *qp;
|
||||
struct ib_event ev;
|
||||
u32 qpn;
|
||||
|
||||
switch (event->type) {
|
||||
case GDMA_EQE_RNIC_QP_FATAL:
|
||||
qpn = event->details[0];
|
||||
qp = mana_get_qp_ref(mdev, qpn);
|
||||
if (!qp)
|
||||
break;
|
||||
if (qp->ibqp.event_handler) {
|
||||
ev.device = qp->ibqp.device;
|
||||
ev.element.qp = &qp->ibqp;
|
||||
ev.event = IB_EVENT_QP_FATAL;
|
||||
qp->ibqp.event_handler(&ev, qp->ibqp.qp_context);
|
||||
}
|
||||
mana_put_qp_ref(qp);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int mana_ib_create_eqs(struct mana_ib_dev *mdev)
|
||||
{
|
||||
struct gdma_context *gc = mdev_to_gc(mdev);
|
||||
@ -663,7 +703,7 @@ int mana_ib_create_eqs(struct mana_ib_dev *mdev)
|
||||
spec.type = GDMA_EQ;
|
||||
spec.monitor_avl_buf = false;
|
||||
spec.queue_size = EQ_SIZE;
|
||||
spec.eq.callback = NULL;
|
||||
spec.eq.callback = mana_ib_event_handler;
|
||||
spec.eq.context = mdev;
|
||||
spec.eq.log2_throttle_limit = LOG2_EQ_THROTTLE;
|
||||
spec.eq.msix_index = 0;
|
||||
@ -678,7 +718,7 @@ int mana_ib_create_eqs(struct mana_ib_dev *mdev)
|
||||
err = -ENOMEM;
|
||||
goto destroy_fatal_eq;
|
||||
}
|
||||
|
||||
spec.eq.callback = NULL;
|
||||
for (i = 0; i < mdev->ib_dev.num_comp_vectors; i++) {
|
||||
spec.eq.msix_index = (i + 1) % gc->num_msix_usable;
|
||||
err = mana_gd_create_mana_eq(mdev->gdma_dev, &spec, &mdev->eqs[i]);
|
||||
@ -888,3 +928,62 @@ int mana_ib_gd_destroy_cq(struct mana_ib_dev *mdev, struct mana_ib_cq *cq)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mana_ib_gd_create_rc_qp(struct mana_ib_dev *mdev, struct mana_ib_qp *qp,
|
||||
struct ib_qp_init_attr *attr, u32 doorbell, u64 flags)
|
||||
{
|
||||
struct mana_ib_cq *send_cq = container_of(qp->ibqp.send_cq, struct mana_ib_cq, ibcq);
|
||||
struct mana_ib_cq *recv_cq = container_of(qp->ibqp.recv_cq, struct mana_ib_cq, ibcq);
|
||||
struct mana_ib_pd *pd = container_of(qp->ibqp.pd, struct mana_ib_pd, ibpd);
|
||||
struct gdma_context *gc = mdev_to_gc(mdev);
|
||||
struct mana_rnic_create_qp_resp resp = {};
|
||||
struct mana_rnic_create_qp_req req = {};
|
||||
int err, i;
|
||||
|
||||
mana_gd_init_req_hdr(&req.hdr, MANA_IB_CREATE_RC_QP, sizeof(req), sizeof(resp));
|
||||
req.hdr.dev_id = gc->mana_ib.dev_id;
|
||||
req.adapter = mdev->adapter_handle;
|
||||
req.pd_handle = pd->pd_handle;
|
||||
req.send_cq_handle = send_cq->cq_handle;
|
||||
req.recv_cq_handle = recv_cq->cq_handle;
|
||||
for (i = 0; i < MANA_RC_QUEUE_TYPE_MAX; i++)
|
||||
req.dma_region[i] = qp->rc_qp.queues[i].gdma_region;
|
||||
req.doorbell_page = doorbell;
|
||||
req.max_send_wr = attr->cap.max_send_wr;
|
||||
req.max_recv_wr = attr->cap.max_recv_wr;
|
||||
req.max_send_sge = attr->cap.max_send_sge;
|
||||
req.max_recv_sge = attr->cap.max_recv_sge;
|
||||
req.flags = flags;
|
||||
|
||||
err = mana_gd_send_request(gc, sizeof(req), &req, sizeof(resp), &resp);
|
||||
if (err) {
|
||||
ibdev_err(&mdev->ib_dev, "Failed to create rc qp err %d", err);
|
||||
return err;
|
||||
}
|
||||
qp->qp_handle = resp.rc_qp_handle;
|
||||
for (i = 0; i < MANA_RC_QUEUE_TYPE_MAX; i++) {
|
||||
qp->rc_qp.queues[i].id = resp.queue_ids[i];
|
||||
/* The GDMA regions are now owned by the RNIC QP handle */
|
||||
qp->rc_qp.queues[i].gdma_region = GDMA_INVALID_DMA_REGION;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mana_ib_gd_destroy_rc_qp(struct mana_ib_dev *mdev, struct mana_ib_qp *qp)
|
||||
{
|
||||
struct mana_rnic_destroy_rc_qp_resp resp = {0};
|
||||
struct mana_rnic_destroy_rc_qp_req req = {0};
|
||||
struct gdma_context *gc = mdev_to_gc(mdev);
|
||||
int err;
|
||||
|
||||
mana_gd_init_req_hdr(&req.hdr, MANA_IB_DESTROY_RC_QP, sizeof(req), sizeof(resp));
|
||||
req.hdr.dev_id = gc->mana_ib.dev_id;
|
||||
req.adapter = mdev->adapter_handle;
|
||||
req.rc_qp_handle = qp->qp_handle;
|
||||
err = mana_gd_send_request(gc, sizeof(req), &req, sizeof(resp), &resp);
|
||||
if (err) {
|
||||
ibdev_err(&mdev->ib_dev, "Failed to destroy rc qp err %d", err);
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -27,6 +27,11 @@
|
||||
*/
|
||||
#define MANA_IB_MAX_MR 0xFFFFFFu
|
||||
|
||||
/*
|
||||
* The CA timeout is approx. 260ms (4us * 2^(DELAY))
|
||||
*/
|
||||
#define MANA_CA_ACK_DELAY 16
|
||||
|
||||
struct mana_ib_adapter_caps {
|
||||
u32 max_sq_id;
|
||||
u32 max_rq_id;
|
||||
@ -57,6 +62,7 @@ struct mana_ib_dev {
|
||||
mana_handle_t adapter_handle;
|
||||
struct gdma_queue *fatal_err_eq;
|
||||
struct gdma_queue **eqs;
|
||||
struct xarray qp_table_wq;
|
||||
struct mana_ib_adapter_caps adapter_caps;
|
||||
};
|
||||
|
||||
@ -95,14 +101,33 @@ struct mana_ib_cq {
|
||||
mana_handle_t cq_handle;
|
||||
};
|
||||
|
||||
enum mana_rc_queue_type {
|
||||
MANA_RC_SEND_QUEUE_REQUESTER = 0,
|
||||
MANA_RC_SEND_QUEUE_RESPONDER,
|
||||
MANA_RC_SEND_QUEUE_FMR,
|
||||
MANA_RC_RECV_QUEUE_REQUESTER,
|
||||
MANA_RC_RECV_QUEUE_RESPONDER,
|
||||
MANA_RC_QUEUE_TYPE_MAX,
|
||||
};
|
||||
|
||||
struct mana_ib_rc_qp {
|
||||
struct mana_ib_queue queues[MANA_RC_QUEUE_TYPE_MAX];
|
||||
};
|
||||
|
||||
struct mana_ib_qp {
|
||||
struct ib_qp ibqp;
|
||||
|
||||
mana_handle_t qp_handle;
|
||||
struct mana_ib_queue raw_sq;
|
||||
union {
|
||||
struct mana_ib_queue raw_sq;
|
||||
struct mana_ib_rc_qp rc_qp;
|
||||
};
|
||||
|
||||
/* The port on the IB device, starting with 1 */
|
||||
u32 port;
|
||||
|
||||
refcount_t refcount;
|
||||
struct completion free;
|
||||
};
|
||||
|
||||
struct mana_ib_ucontext {
|
||||
@ -122,6 +147,9 @@ enum mana_ib_command_code {
|
||||
MANA_IB_CONFIG_MAC_ADDR = 0x30005,
|
||||
MANA_IB_CREATE_CQ = 0x30008,
|
||||
MANA_IB_DESTROY_CQ = 0x30009,
|
||||
MANA_IB_CREATE_RC_QP = 0x3000a,
|
||||
MANA_IB_DESTROY_RC_QP = 0x3000b,
|
||||
MANA_IB_SET_QP_STATE = 0x3000d,
|
||||
};
|
||||
|
||||
struct mana_ib_query_adapter_caps_req {
|
||||
@ -230,11 +258,105 @@ struct mana_rnic_destroy_cq_resp {
|
||||
struct gdma_resp_hdr hdr;
|
||||
}; /* HW Data */
|
||||
|
||||
enum mana_rnic_create_rc_flags {
|
||||
MANA_RC_FLAG_NO_FMR = 2,
|
||||
};
|
||||
|
||||
struct mana_rnic_create_qp_req {
|
||||
struct gdma_req_hdr hdr;
|
||||
mana_handle_t adapter;
|
||||
mana_handle_t pd_handle;
|
||||
mana_handle_t send_cq_handle;
|
||||
mana_handle_t recv_cq_handle;
|
||||
u64 dma_region[MANA_RC_QUEUE_TYPE_MAX];
|
||||
u64 deprecated[2];
|
||||
u64 flags;
|
||||
u32 doorbell_page;
|
||||
u32 max_send_wr;
|
||||
u32 max_recv_wr;
|
||||
u32 max_send_sge;
|
||||
u32 max_recv_sge;
|
||||
u32 reserved;
|
||||
}; /* HW Data */
|
||||
|
||||
struct mana_rnic_create_qp_resp {
|
||||
struct gdma_resp_hdr hdr;
|
||||
mana_handle_t rc_qp_handle;
|
||||
u32 queue_ids[MANA_RC_QUEUE_TYPE_MAX];
|
||||
u32 reserved;
|
||||
}; /* HW Data*/
|
||||
|
||||
struct mana_rnic_destroy_rc_qp_req {
|
||||
struct gdma_req_hdr hdr;
|
||||
mana_handle_t adapter;
|
||||
mana_handle_t rc_qp_handle;
|
||||
}; /* HW Data */
|
||||
|
||||
struct mana_rnic_destroy_rc_qp_resp {
|
||||
struct gdma_resp_hdr hdr;
|
||||
}; /* HW Data */
|
||||
|
||||
struct mana_ib_ah_attr {
|
||||
u8 src_addr[16];
|
||||
u8 dest_addr[16];
|
||||
u8 src_mac[ETH_ALEN];
|
||||
u8 dest_mac[ETH_ALEN];
|
||||
u8 src_addr_type;
|
||||
u8 dest_addr_type;
|
||||
u8 hop_limit;
|
||||
u8 traffic_class;
|
||||
u16 src_port;
|
||||
u16 dest_port;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct mana_rnic_set_qp_state_req {
|
||||
struct gdma_req_hdr hdr;
|
||||
mana_handle_t adapter;
|
||||
mana_handle_t qp_handle;
|
||||
u64 attr_mask;
|
||||
u32 qp_state;
|
||||
u32 path_mtu;
|
||||
u32 rq_psn;
|
||||
u32 sq_psn;
|
||||
u32 dest_qpn;
|
||||
u32 max_dest_rd_atomic;
|
||||
u32 retry_cnt;
|
||||
u32 rnr_retry;
|
||||
u32 min_rnr_timer;
|
||||
u32 reserved;
|
||||
struct mana_ib_ah_attr ah_attr;
|
||||
}; /* HW Data */
|
||||
|
||||
struct mana_rnic_set_qp_state_resp {
|
||||
struct gdma_resp_hdr hdr;
|
||||
}; /* HW Data */
|
||||
|
||||
static inline struct gdma_context *mdev_to_gc(struct mana_ib_dev *mdev)
|
||||
{
|
||||
return mdev->gdma_dev->gdma_context;
|
||||
}
|
||||
|
||||
static inline struct mana_ib_qp *mana_get_qp_ref(struct mana_ib_dev *mdev,
|
||||
uint32_t qid)
|
||||
{
|
||||
struct mana_ib_qp *qp;
|
||||
unsigned long flag;
|
||||
|
||||
xa_lock_irqsave(&mdev->qp_table_wq, flag);
|
||||
qp = xa_load(&mdev->qp_table_wq, qid);
|
||||
if (qp)
|
||||
refcount_inc(&qp->refcount);
|
||||
xa_unlock_irqrestore(&mdev->qp_table_wq, flag);
|
||||
return qp;
|
||||
}
|
||||
|
||||
static inline void mana_put_qp_ref(struct mana_ib_qp *qp)
|
||||
{
|
||||
if (refcount_dec_and_test(&qp->refcount))
|
||||
complete(&qp->free);
|
||||
}
|
||||
|
||||
static inline struct net_device *mana_ib_get_netdev(struct ib_device *ibdev, u32 port)
|
||||
{
|
||||
struct mana_ib_dev *mdev = container_of(ibdev, struct mana_ib_dev, ib_dev);
|
||||
@ -307,7 +429,7 @@ void mana_ib_uncfg_vport(struct mana_ib_dev *dev, struct mana_ib_pd *pd,
|
||||
u32 port);
|
||||
|
||||
int mana_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata);
|
||||
struct uverbs_attr_bundle *attrs);
|
||||
|
||||
int mana_ib_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata);
|
||||
|
||||
@ -354,4 +476,8 @@ int mana_ib_gd_config_mac(struct mana_ib_dev *mdev, enum mana_ib_addr_op op, u8
|
||||
int mana_ib_gd_create_cq(struct mana_ib_dev *mdev, struct mana_ib_cq *cq, u32 doorbell);
|
||||
|
||||
int mana_ib_gd_destroy_cq(struct mana_ib_dev *mdev, struct mana_ib_cq *cq);
|
||||
|
||||
int mana_ib_gd_create_rc_qp(struct mana_ib_dev *mdev, struct mana_ib_qp *qp,
|
||||
struct ib_qp_init_attr *attr, u32 doorbell, u64 flags);
|
||||
int mana_ib_gd_destroy_rc_qp(struct mana_ib_dev *mdev, struct mana_ib_qp *qp);
|
||||
#endif
|
||||
|
@ -398,6 +398,98 @@ err_free_vport:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mana_table_store_qp(struct mana_ib_dev *mdev, struct mana_ib_qp *qp)
|
||||
{
|
||||
refcount_set(&qp->refcount, 1);
|
||||
init_completion(&qp->free);
|
||||
return xa_insert_irq(&mdev->qp_table_wq, qp->ibqp.qp_num, qp,
|
||||
GFP_KERNEL);
|
||||
}
|
||||
|
||||
static void mana_table_remove_qp(struct mana_ib_dev *mdev,
|
||||
struct mana_ib_qp *qp)
|
||||
{
|
||||
xa_erase_irq(&mdev->qp_table_wq, qp->ibqp.qp_num);
|
||||
mana_put_qp_ref(qp);
|
||||
wait_for_completion(&qp->free);
|
||||
}
|
||||
|
||||
static int mana_ib_create_rc_qp(struct ib_qp *ibqp, struct ib_pd *ibpd,
|
||||
struct ib_qp_init_attr *attr, struct ib_udata *udata)
|
||||
{
|
||||
struct mana_ib_dev *mdev = container_of(ibpd->device, struct mana_ib_dev, ib_dev);
|
||||
struct mana_ib_qp *qp = container_of(ibqp, struct mana_ib_qp, ibqp);
|
||||
struct mana_ib_create_rc_qp_resp resp = {};
|
||||
struct mana_ib_ucontext *mana_ucontext;
|
||||
struct mana_ib_create_rc_qp ucmd = {};
|
||||
int i, err, j;
|
||||
u64 flags = 0;
|
||||
u32 doorbell;
|
||||
|
||||
if (!udata || udata->inlen < sizeof(ucmd))
|
||||
return -EINVAL;
|
||||
|
||||
mana_ucontext = rdma_udata_to_drv_context(udata, struct mana_ib_ucontext, ibucontext);
|
||||
doorbell = mana_ucontext->doorbell;
|
||||
flags = MANA_RC_FLAG_NO_FMR;
|
||||
err = ib_copy_from_udata(&ucmd, udata, min(sizeof(ucmd), udata->inlen));
|
||||
if (err) {
|
||||
ibdev_dbg(&mdev->ib_dev, "Failed to copy from udata, %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
for (i = 0, j = 0; i < MANA_RC_QUEUE_TYPE_MAX; ++i) {
|
||||
/* skip FMR for user-level RC QPs */
|
||||
if (i == MANA_RC_SEND_QUEUE_FMR) {
|
||||
qp->rc_qp.queues[i].id = INVALID_QUEUE_ID;
|
||||
qp->rc_qp.queues[i].gdma_region = GDMA_INVALID_DMA_REGION;
|
||||
continue;
|
||||
}
|
||||
err = mana_ib_create_queue(mdev, ucmd.queue_buf[j], ucmd.queue_size[j],
|
||||
&qp->rc_qp.queues[i]);
|
||||
if (err) {
|
||||
ibdev_err(&mdev->ib_dev, "Failed to create queue %d, err %d\n", i, err);
|
||||
goto destroy_queues;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
|
||||
err = mana_ib_gd_create_rc_qp(mdev, qp, attr, doorbell, flags);
|
||||
if (err) {
|
||||
ibdev_err(&mdev->ib_dev, "Failed to create rc qp %d\n", err);
|
||||
goto destroy_queues;
|
||||
}
|
||||
qp->ibqp.qp_num = qp->rc_qp.queues[MANA_RC_RECV_QUEUE_RESPONDER].id;
|
||||
qp->port = attr->port_num;
|
||||
|
||||
if (udata) {
|
||||
for (i = 0, j = 0; i < MANA_RC_QUEUE_TYPE_MAX; ++i) {
|
||||
if (i == MANA_RC_SEND_QUEUE_FMR)
|
||||
continue;
|
||||
resp.queue_id[j] = qp->rc_qp.queues[i].id;
|
||||
j++;
|
||||
}
|
||||
err = ib_copy_to_udata(udata, &resp, min(sizeof(resp), udata->outlen));
|
||||
if (err) {
|
||||
ibdev_dbg(&mdev->ib_dev, "Failed to copy to udata, %d\n", err);
|
||||
goto destroy_qp;
|
||||
}
|
||||
}
|
||||
|
||||
err = mana_table_store_qp(mdev, qp);
|
||||
if (err)
|
||||
goto destroy_qp;
|
||||
|
||||
return 0;
|
||||
|
||||
destroy_qp:
|
||||
mana_ib_gd_destroy_rc_qp(mdev, qp);
|
||||
destroy_queues:
|
||||
while (i-- > 0)
|
||||
mana_ib_destroy_queue(mdev, &qp->rc_qp.queues[i]);
|
||||
return err;
|
||||
}
|
||||
|
||||
int mana_ib_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attr,
|
||||
struct ib_udata *udata)
|
||||
{
|
||||
@ -409,8 +501,9 @@ int mana_ib_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attr,
|
||||
udata);
|
||||
|
||||
return mana_ib_create_qp_raw(ibqp, ibqp->pd, attr, udata);
|
||||
case IB_QPT_RC:
|
||||
return mana_ib_create_rc_qp(ibqp, ibqp->pd, attr, udata);
|
||||
default:
|
||||
/* Creating QP other than IB_QPT_RAW_PACKET is not supported */
|
||||
ibdev_dbg(ibqp->device, "Creating QP type %u not supported\n",
|
||||
attr->qp_type);
|
||||
}
|
||||
@ -418,11 +511,79 @@ int mana_ib_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attr,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int mana_ib_gd_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
|
||||
int attr_mask, struct ib_udata *udata)
|
||||
{
|
||||
struct mana_ib_dev *mdev = container_of(ibqp->device, struct mana_ib_dev, ib_dev);
|
||||
struct mana_ib_qp *qp = container_of(ibqp, struct mana_ib_qp, ibqp);
|
||||
struct mana_rnic_set_qp_state_resp resp = {};
|
||||
struct mana_rnic_set_qp_state_req req = {};
|
||||
struct gdma_context *gc = mdev_to_gc(mdev);
|
||||
struct mana_port_context *mpc;
|
||||
struct net_device *ndev;
|
||||
int err;
|
||||
|
||||
mana_gd_init_req_hdr(&req.hdr, MANA_IB_SET_QP_STATE, sizeof(req), sizeof(resp));
|
||||
req.hdr.dev_id = gc->mana_ib.dev_id;
|
||||
req.adapter = mdev->adapter_handle;
|
||||
req.qp_handle = qp->qp_handle;
|
||||
req.qp_state = attr->qp_state;
|
||||
req.attr_mask = attr_mask;
|
||||
req.path_mtu = attr->path_mtu;
|
||||
req.rq_psn = attr->rq_psn;
|
||||
req.sq_psn = attr->sq_psn;
|
||||
req.dest_qpn = attr->dest_qp_num;
|
||||
req.max_dest_rd_atomic = attr->max_dest_rd_atomic;
|
||||
req.retry_cnt = attr->retry_cnt;
|
||||
req.rnr_retry = attr->rnr_retry;
|
||||
req.min_rnr_timer = attr->min_rnr_timer;
|
||||
if (attr_mask & IB_QP_AV) {
|
||||
ndev = mana_ib_get_netdev(&mdev->ib_dev, ibqp->port);
|
||||
if (!ndev) {
|
||||
ibdev_dbg(&mdev->ib_dev, "Invalid port %u in QP %u\n",
|
||||
ibqp->port, ibqp->qp_num);
|
||||
return -EINVAL;
|
||||
}
|
||||
mpc = netdev_priv(ndev);
|
||||
copy_in_reverse(req.ah_attr.src_mac, mpc->mac_addr, ETH_ALEN);
|
||||
copy_in_reverse(req.ah_attr.dest_mac, attr->ah_attr.roce.dmac, ETH_ALEN);
|
||||
copy_in_reverse(req.ah_attr.src_addr, attr->ah_attr.grh.sgid_attr->gid.raw,
|
||||
sizeof(union ib_gid));
|
||||
copy_in_reverse(req.ah_attr.dest_addr, attr->ah_attr.grh.dgid.raw,
|
||||
sizeof(union ib_gid));
|
||||
if (rdma_gid_attr_network_type(attr->ah_attr.grh.sgid_attr) == RDMA_NETWORK_IPV4) {
|
||||
req.ah_attr.src_addr_type = SGID_TYPE_IPV4;
|
||||
req.ah_attr.dest_addr_type = SGID_TYPE_IPV4;
|
||||
} else {
|
||||
req.ah_attr.src_addr_type = SGID_TYPE_IPV6;
|
||||
req.ah_attr.dest_addr_type = SGID_TYPE_IPV6;
|
||||
}
|
||||
req.ah_attr.dest_port = ROCE_V2_UDP_DPORT;
|
||||
req.ah_attr.src_port = rdma_get_udp_sport(attr->ah_attr.grh.flow_label,
|
||||
ibqp->qp_num, attr->dest_qp_num);
|
||||
req.ah_attr.traffic_class = attr->ah_attr.grh.traffic_class;
|
||||
req.ah_attr.hop_limit = attr->ah_attr.grh.hop_limit;
|
||||
}
|
||||
|
||||
err = mana_gd_send_request(gc, sizeof(req), &req, sizeof(resp), &resp);
|
||||
if (err) {
|
||||
ibdev_err(&mdev->ib_dev, "Failed modify qp err %d", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mana_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
|
||||
int attr_mask, struct ib_udata *udata)
|
||||
{
|
||||
/* modify_qp is not supported by this version of the driver */
|
||||
return -EOPNOTSUPP;
|
||||
switch (ibqp->qp_type) {
|
||||
case IB_QPT_RC:
|
||||
return mana_ib_gd_modify_qp(ibqp, attr, attr_mask, udata);
|
||||
default:
|
||||
ibdev_dbg(ibqp->device, "Modify QP type %u not supported", ibqp->qp_type);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
static int mana_ib_destroy_qp_rss(struct mana_ib_qp *qp,
|
||||
@ -473,6 +634,24 @@ static int mana_ib_destroy_qp_raw(struct mana_ib_qp *qp, struct ib_udata *udata)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mana_ib_destroy_rc_qp(struct mana_ib_qp *qp, struct ib_udata *udata)
|
||||
{
|
||||
struct mana_ib_dev *mdev =
|
||||
container_of(qp->ibqp.device, struct mana_ib_dev, ib_dev);
|
||||
int i;
|
||||
|
||||
mana_table_remove_qp(mdev, qp);
|
||||
|
||||
/* Ignore return code as there is not much we can do about it.
|
||||
* The error message is printed inside.
|
||||
*/
|
||||
mana_ib_gd_destroy_rc_qp(mdev, qp);
|
||||
for (i = 0; i < MANA_RC_QUEUE_TYPE_MAX; ++i)
|
||||
mana_ib_destroy_queue(mdev, &qp->rc_qp.queues[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mana_ib_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
|
||||
{
|
||||
struct mana_ib_qp *qp = container_of(ibqp, struct mana_ib_qp, ibqp);
|
||||
@ -484,7 +663,8 @@ int mana_ib_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
|
||||
udata);
|
||||
|
||||
return mana_ib_destroy_qp_raw(qp, udata);
|
||||
|
||||
case IB_QPT_RC:
|
||||
return mana_ib_destroy_rc_qp(qp, udata);
|
||||
default:
|
||||
ibdev_dbg(ibqp->device, "Unexpected QP type %u\n",
|
||||
ibqp->qp_type);
|
||||
|
@ -829,7 +829,7 @@ void mlx4_ib_destroy_alias_guid_service(struct mlx4_ib_dev *dev)
|
||||
|
||||
int mlx4_ib_init_alias_guid_service(struct mlx4_ib_dev *dev)
|
||||
{
|
||||
char alias_wq_name[15];
|
||||
char alias_wq_name[22];
|
||||
int ret = 0;
|
||||
int i, j;
|
||||
union ib_gid gid;
|
||||
|
@ -172,8 +172,9 @@ err_buf:
|
||||
|
||||
#define CQ_CREATE_FLAGS_SUPPORTED IB_UVERBS_CQ_FLAGS_TIMESTAMP_COMPLETION
|
||||
int mlx4_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata)
|
||||
struct uverbs_attr_bundle *attrs)
|
||||
{
|
||||
struct ib_udata *udata = &attrs->driver_udata;
|
||||
struct ib_device *ibdev = ibcq->device;
|
||||
int entries = attr->cqe;
|
||||
int vector = attr->comp_vector;
|
||||
|
@ -2158,7 +2158,7 @@ static int mlx4_ib_alloc_demux_ctx(struct mlx4_ib_dev *dev,
|
||||
struct mlx4_ib_demux_ctx *ctx,
|
||||
int port)
|
||||
{
|
||||
char name[12];
|
||||
char name[21];
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
|
@ -767,7 +767,7 @@ int mlx4_ib_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents,
|
||||
int mlx4_ib_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period);
|
||||
int mlx4_ib_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata);
|
||||
int mlx4_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata);
|
||||
struct uverbs_attr_bundle *attrs);
|
||||
int mlx4_ib_destroy_cq(struct ib_cq *cq, struct ib_udata *udata);
|
||||
int mlx4_ib_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc);
|
||||
int mlx4_ib_arm_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags);
|
||||
|
@ -177,7 +177,7 @@ int mlx5_cmd_xrcd_dealloc(struct mlx5_core_dev *dev, u32 xrcdn, u16 uid)
|
||||
return mlx5_cmd_exec_in(dev, dealloc_xrcd, in);
|
||||
}
|
||||
|
||||
int mlx5_cmd_mad_ifc(struct mlx5_core_dev *dev, const void *inb, void *outb,
|
||||
int mlx5_cmd_mad_ifc(struct mlx5_ib_dev *dev, const void *inb, void *outb,
|
||||
u16 opmod, u8 port)
|
||||
{
|
||||
int outlen = MLX5_ST_SZ_BYTES(mad_ifc_out);
|
||||
@ -195,12 +195,18 @@ int mlx5_cmd_mad_ifc(struct mlx5_core_dev *dev, const void *inb, void *outb,
|
||||
|
||||
MLX5_SET(mad_ifc_in, in, opcode, MLX5_CMD_OP_MAD_IFC);
|
||||
MLX5_SET(mad_ifc_in, in, op_mod, opmod);
|
||||
MLX5_SET(mad_ifc_in, in, port, port);
|
||||
if (dev->ib_dev.type == RDMA_DEVICE_TYPE_SMI) {
|
||||
MLX5_SET(mad_ifc_in, in, plane_index, port);
|
||||
MLX5_SET(mad_ifc_in, in, port,
|
||||
smi_to_native_portnum(dev, port));
|
||||
} else {
|
||||
MLX5_SET(mad_ifc_in, in, port, port);
|
||||
}
|
||||
|
||||
data = MLX5_ADDR_OF(mad_ifc_in, in, mad);
|
||||
memcpy(data, inb, MLX5_FLD_SZ_BYTES(mad_ifc_in, mad));
|
||||
|
||||
err = mlx5_cmd_exec_inout(dev, mad_ifc, in, out);
|
||||
err = mlx5_cmd_exec_inout(dev->mdev, mad_ifc, in, out);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
|
@ -54,7 +54,7 @@ int mlx5_cmd_detach_mcg(struct mlx5_core_dev *dev, union ib_gid *mgid,
|
||||
u32 qpn, u16 uid);
|
||||
int mlx5_cmd_xrcd_alloc(struct mlx5_core_dev *dev, u32 *xrcdn, u16 uid);
|
||||
int mlx5_cmd_xrcd_dealloc(struct mlx5_core_dev *dev, u32 xrcdn, u16 uid);
|
||||
int mlx5_cmd_mad_ifc(struct mlx5_core_dev *dev, const void *inb, void *outb,
|
||||
int mlx5_cmd_mad_ifc(struct mlx5_ib_dev *dev, const void *inb, void *outb,
|
||||
u16 opmod, u8 port);
|
||||
int mlx5_cmd_uar_alloc(struct mlx5_core_dev *dev, u32 *uarn, u16 uid);
|
||||
int mlx5_cmd_uar_dealloc(struct mlx5_core_dev *dev, u32 uarn, u16 uid);
|
||||
|
@ -38,6 +38,9 @@
|
||||
#include "srq.h"
|
||||
#include "qp.h"
|
||||
|
||||
#define UVERBS_MODULE_NAME mlx5_ib
|
||||
#include <rdma/uverbs_named_ioctl.h>
|
||||
|
||||
static void mlx5_ib_cq_comp(struct mlx5_core_cq *cq, struct mlx5_eqe *eqe)
|
||||
{
|
||||
struct ib_cq *ibcq = &to_mibcq(cq)->ibcq;
|
||||
@ -714,7 +717,8 @@ static int mini_cqe_res_format_to_hw(struct mlx5_ib_dev *dev, u8 format)
|
||||
|
||||
static int create_cq_user(struct mlx5_ib_dev *dev, struct ib_udata *udata,
|
||||
struct mlx5_ib_cq *cq, int entries, u32 **cqb,
|
||||
int *cqe_size, int *index, int *inlen)
|
||||
int *cqe_size, int *index, int *inlen,
|
||||
struct uverbs_attr_bundle *attrs)
|
||||
{
|
||||
struct mlx5_ib_create_cq ucmd = {};
|
||||
unsigned long page_size;
|
||||
@ -788,7 +792,11 @@ static int create_cq_user(struct mlx5_ib_dev *dev, struct ib_udata *udata,
|
||||
order_base_2(page_size) - MLX5_ADAPTER_PAGE_SHIFT);
|
||||
MLX5_SET(cqc, cqc, page_offset, page_offset_quantized);
|
||||
|
||||
if (ucmd.flags & MLX5_IB_CREATE_CQ_FLAGS_UAR_PAGE_INDEX) {
|
||||
if (uverbs_attr_is_valid(attrs, MLX5_IB_ATTR_CREATE_CQ_UAR_INDEX)) {
|
||||
err = uverbs_copy_from(index, attrs, MLX5_IB_ATTR_CREATE_CQ_UAR_INDEX);
|
||||
if (err)
|
||||
goto err_cqb;
|
||||
} else if (ucmd.flags & MLX5_IB_CREATE_CQ_FLAGS_UAR_PAGE_INDEX) {
|
||||
*index = ucmd.uar_page_index;
|
||||
} else if (context->bfregi.lib_uar_dyn) {
|
||||
err = -EINVAL;
|
||||
@ -942,8 +950,9 @@ static void notify_soft_wc_handler(struct work_struct *work)
|
||||
}
|
||||
|
||||
int mlx5_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata)
|
||||
struct uverbs_attr_bundle *attrs)
|
||||
{
|
||||
struct ib_udata *udata = &attrs->driver_udata;
|
||||
struct ib_device *ibdev = ibcq->device;
|
||||
int entries = attr->cqe;
|
||||
int vector = attr->comp_vector;
|
||||
@ -980,7 +989,7 @@ int mlx5_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
|
||||
|
||||
if (udata) {
|
||||
err = create_cq_user(dev, udata, cq, entries, &cqb, &cqe_size,
|
||||
&index, &inlen);
|
||||
&index, &inlen, attrs);
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
@ -1442,3 +1451,17 @@ int mlx5_ib_generate_wc(struct ib_cq *ibcq, struct ib_wc *wc)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ADD_UVERBS_ATTRIBUTES_SIMPLE(
|
||||
mlx5_ib_cq_create,
|
||||
UVERBS_OBJECT_CQ,
|
||||
UVERBS_METHOD_CQ_CREATE,
|
||||
UVERBS_ATTR_PTR_IN(
|
||||
MLX5_IB_ATTR_CREATE_CQ_UAR_INDEX,
|
||||
UVERBS_ATTR_TYPE(u32),
|
||||
UA_OPTIONAL));
|
||||
|
||||
const struct uapi_definition mlx5_ib_create_cq_defs[] = {
|
||||
UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_CQ, &mlx5_ib_cq_create),
|
||||
{},
|
||||
};
|
||||
|
@ -69,7 +69,7 @@ static int mlx5_MAD_IFC(struct mlx5_ib_dev *dev, int ignore_mkey,
|
||||
if (ignore_bkey || !in_wc)
|
||||
op_modifier |= 0x2;
|
||||
|
||||
return mlx5_cmd_mad_ifc(dev->mdev, in_mad, response_mad, op_modifier,
|
||||
return mlx5_cmd_mad_ifc(dev, in_mad, response_mad, op_modifier,
|
||||
port);
|
||||
}
|
||||
|
||||
@ -147,8 +147,39 @@ static void pma_cnt_assign(struct ib_pma_portcounters *pma_cnt,
|
||||
vl_15_dropped);
|
||||
}
|
||||
|
||||
static int query_ib_ppcnt(struct mlx5_core_dev *dev, u8 port_num, void *out,
|
||||
size_t sz)
|
||||
static void pma_cnt_ext_assign_ppcnt(struct ib_pma_portcounters_ext *cnt_ext,
|
||||
void *out)
|
||||
{
|
||||
void *out_pma = MLX5_ADDR_OF(ppcnt_reg, out,
|
||||
counter_set);
|
||||
|
||||
#define MLX5_GET_EXT_CNTR(counter_name) \
|
||||
MLX5_GET64(ib_ext_port_cntrs_grp_data_layout, \
|
||||
out_pma, counter_name##_high)
|
||||
|
||||
cnt_ext->port_xmit_data =
|
||||
cpu_to_be64(MLX5_GET_EXT_CNTR(port_xmit_data) >> 2);
|
||||
cnt_ext->port_rcv_data =
|
||||
cpu_to_be64(MLX5_GET_EXT_CNTR(port_rcv_data) >> 2);
|
||||
|
||||
cnt_ext->port_xmit_packets =
|
||||
cpu_to_be64(MLX5_GET_EXT_CNTR(port_xmit_pkts));
|
||||
cnt_ext->port_rcv_packets =
|
||||
cpu_to_be64(MLX5_GET_EXT_CNTR(port_rcv_pkts));
|
||||
|
||||
cnt_ext->port_unicast_xmit_packets =
|
||||
cpu_to_be64(MLX5_GET_EXT_CNTR(port_unicast_xmit_pkts));
|
||||
cnt_ext->port_unicast_rcv_packets =
|
||||
cpu_to_be64(MLX5_GET_EXT_CNTR(port_unicast_rcv_pkts));
|
||||
|
||||
cnt_ext->port_multicast_xmit_packets =
|
||||
cpu_to_be64(MLX5_GET_EXT_CNTR(port_multicast_xmit_pkts));
|
||||
cnt_ext->port_multicast_rcv_packets =
|
||||
cpu_to_be64(MLX5_GET_EXT_CNTR(port_multicast_rcv_pkts));
|
||||
}
|
||||
|
||||
static int query_ib_ppcnt(struct mlx5_core_dev *dev, u8 port_num, u8 plane_num,
|
||||
void *out, size_t sz, bool ext)
|
||||
{
|
||||
u32 *in;
|
||||
int err;
|
||||
@ -160,8 +191,14 @@ static int query_ib_ppcnt(struct mlx5_core_dev *dev, u8 port_num, void *out,
|
||||
}
|
||||
|
||||
MLX5_SET(ppcnt_reg, in, local_port, port_num);
|
||||
MLX5_SET(ppcnt_reg, in, plane_ind, plane_num);
|
||||
|
||||
MLX5_SET(ppcnt_reg, in, grp, MLX5_INFINIBAND_PORT_COUNTERS_GROUP);
|
||||
if (ext)
|
||||
MLX5_SET(ppcnt_reg, in, grp,
|
||||
MLX5_INFINIBAND_EXTENDED_PORT_COUNTERS_GROUP);
|
||||
else
|
||||
MLX5_SET(ppcnt_reg, in, grp,
|
||||
MLX5_INFINIBAND_PORT_COUNTERS_GROUP);
|
||||
err = mlx5_core_access_reg(dev, in, sz, out,
|
||||
sz, MLX5_REG_PPCNT, 0, 0);
|
||||
|
||||
@ -189,7 +226,8 @@ static int process_pma_cmd(struct mlx5_ib_dev *dev, u32 port_num,
|
||||
mdev_port_num = 1;
|
||||
}
|
||||
if (MLX5_CAP_GEN(dev->mdev, num_ports) == 1 &&
|
||||
!mlx5_core_mp_enabled(mdev)) {
|
||||
!mlx5_core_mp_enabled(mdev) &&
|
||||
dev->ib_dev.type != RDMA_DEVICE_TYPE_SMI) {
|
||||
/* set local port to one for Function-Per-Port HCA. */
|
||||
mdev = dev->mdev;
|
||||
mdev_port_num = 1;
|
||||
@ -208,7 +246,8 @@ static int process_pma_cmd(struct mlx5_ib_dev *dev, u32 port_num,
|
||||
if (in_mad->mad_hdr.attr_id == IB_PMA_PORT_COUNTERS_EXT) {
|
||||
struct ib_pma_portcounters_ext *pma_cnt_ext =
|
||||
(struct ib_pma_portcounters_ext *)(out_mad->data + 40);
|
||||
int sz = MLX5_ST_SZ_BYTES(query_vport_counter_out);
|
||||
int sz = max(MLX5_ST_SZ_BYTES(query_vport_counter_out),
|
||||
MLX5_ST_SZ_BYTES(ppcnt_reg));
|
||||
|
||||
out_cnt = kvzalloc(sz, GFP_KERNEL);
|
||||
if (!out_cnt) {
|
||||
@ -216,10 +255,18 @@ static int process_pma_cmd(struct mlx5_ib_dev *dev, u32 port_num,
|
||||
goto done;
|
||||
}
|
||||
|
||||
err = mlx5_core_query_vport_counter(mdev, 0, 0, mdev_port_num,
|
||||
out_cnt);
|
||||
if (!err)
|
||||
pma_cnt_ext_assign(pma_cnt_ext, out_cnt);
|
||||
if (dev->ib_dev.type == RDMA_DEVICE_TYPE_SMI) {
|
||||
err = query_ib_ppcnt(mdev, mdev_port_num,
|
||||
port_num, out_cnt, sz, 1);
|
||||
if (!err)
|
||||
pma_cnt_ext_assign_ppcnt(pma_cnt_ext, out_cnt);
|
||||
} else {
|
||||
err = mlx5_core_query_vport_counter(mdev, 0, 0,
|
||||
mdev_port_num,
|
||||
out_cnt);
|
||||
if (!err)
|
||||
pma_cnt_ext_assign(pma_cnt_ext, out_cnt);
|
||||
}
|
||||
} else {
|
||||
struct ib_pma_portcounters *pma_cnt =
|
||||
(struct ib_pma_portcounters *)(out_mad->data + 40);
|
||||
@ -231,7 +278,7 @@ static int process_pma_cmd(struct mlx5_ib_dev *dev, u32 port_num,
|
||||
goto done;
|
||||
}
|
||||
|
||||
err = query_ib_ppcnt(mdev, mdev_port_num, out_cnt, sz);
|
||||
err = query_ib_ppcnt(mdev, mdev_port_num, 0, out_cnt, sz, 0);
|
||||
if (!err)
|
||||
pma_cnt_assign(pma_cnt, out_cnt);
|
||||
}
|
||||
|
@ -282,6 +282,14 @@ struct mlx5_core_dev *mlx5_ib_get_native_port_mdev(struct mlx5_ib_dev *ibdev,
|
||||
struct mlx5_ib_multiport_info *mpi;
|
||||
struct mlx5_ib_port *port;
|
||||
|
||||
if (ibdev->ib_dev.type == RDMA_DEVICE_TYPE_SMI) {
|
||||
if (native_port_num)
|
||||
*native_port_num = smi_to_native_portnum(ibdev,
|
||||
ib_port_num);
|
||||
return ibdev->mdev;
|
||||
|
||||
}
|
||||
|
||||
if (!mlx5_core_mp_enabled(ibdev->mdev) ||
|
||||
ll != IB_LINK_LAYER_ETHERNET) {
|
||||
if (native_port_num)
|
||||
@ -503,10 +511,10 @@ static int mlx5_query_port_roce(struct ib_device *device, u32 port_num,
|
||||
*/
|
||||
if (dev->is_rep)
|
||||
err = mlx5_query_port_ptys(mdev, out, sizeof(out), MLX5_PTYS_EN,
|
||||
1);
|
||||
1, 0);
|
||||
else
|
||||
err = mlx5_query_port_ptys(mdev, out, sizeof(out), MLX5_PTYS_EN,
|
||||
mdev_port_num);
|
||||
mdev_port_num, 0);
|
||||
if (err)
|
||||
goto out;
|
||||
ext = !!MLX5_GET_ETH_PROTO(ptys_reg, out, true, eth_proto_capability);
|
||||
@ -1333,11 +1341,11 @@ static int mlx5_query_hca_port(struct ib_device *ibdev, u32 port,
|
||||
struct mlx5_ib_dev *dev = to_mdev(ibdev);
|
||||
struct mlx5_core_dev *mdev = dev->mdev;
|
||||
struct mlx5_hca_vport_context *rep;
|
||||
u8 vl_hw_cap, plane_index = 0;
|
||||
u16 max_mtu;
|
||||
u16 oper_mtu;
|
||||
int err;
|
||||
u16 ib_link_width_oper;
|
||||
u8 vl_hw_cap;
|
||||
|
||||
rep = kzalloc(sizeof(*rep), GFP_KERNEL);
|
||||
if (!rep) {
|
||||
@ -1347,6 +1355,11 @@ static int mlx5_query_hca_port(struct ib_device *ibdev, u32 port,
|
||||
|
||||
/* props being zeroed by the caller, avoid zeroing it here */
|
||||
|
||||
if (ibdev->type == RDMA_DEVICE_TYPE_SMI) {
|
||||
plane_index = port;
|
||||
port = smi_to_native_portnum(dev, port);
|
||||
}
|
||||
|
||||
err = mlx5_query_hca_vport_context(mdev, 0, port, 0, rep);
|
||||
if (err)
|
||||
goto out;
|
||||
@ -1357,7 +1370,14 @@ static int mlx5_query_hca_port(struct ib_device *ibdev, u32 port,
|
||||
props->sm_sl = rep->sm_sl;
|
||||
props->state = rep->vport_state;
|
||||
props->phys_state = rep->port_physical_state;
|
||||
props->port_cap_flags = rep->cap_mask1;
|
||||
|
||||
props->port_cap_flags = rep->cap_mask1;
|
||||
if (dev->num_plane) {
|
||||
props->port_cap_flags |= IB_PORT_SM_DISABLED;
|
||||
props->port_cap_flags &= ~IB_PORT_SM;
|
||||
} else if (ibdev->type == RDMA_DEVICE_TYPE_SMI)
|
||||
props->port_cap_flags &= ~IB_PORT_CM_SUP;
|
||||
|
||||
props->gid_tbl_len = mlx5_get_gid_table_len(MLX5_CAP_GEN(mdev, gid_table_size));
|
||||
props->max_msg_sz = 1 << MLX5_CAP_GEN(mdev, log_max_msg);
|
||||
props->pkey_tbl_len = mlx5_to_sw_pkey_sz(MLX5_CAP_GEN(mdev, pkey_table_size));
|
||||
@ -1370,7 +1390,7 @@ static int mlx5_query_hca_port(struct ib_device *ibdev, u32 port,
|
||||
props->port_cap_flags2 = rep->cap_mask2;
|
||||
|
||||
err = mlx5_query_ib_port_oper(mdev, &ib_link_width_oper,
|
||||
&props->active_speed, port);
|
||||
&props->active_speed, port, plane_index);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
@ -2776,6 +2796,23 @@ static int mlx5_ib_event_slave_port(struct notifier_block *nb,
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static int mlx5_ib_get_plane_num(struct mlx5_core_dev *mdev, u8 *num_plane)
|
||||
{
|
||||
struct mlx5_hca_vport_context vport_ctx;
|
||||
int err;
|
||||
|
||||
*num_plane = 0;
|
||||
if (!MLX5_CAP_GEN(mdev, ib_virt))
|
||||
return 0;
|
||||
|
||||
err = mlx5_query_hca_vport_context(mdev, 0, 1, 0, &vport_ctx);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
*num_plane = vport_ctx.num_plane;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_has_smi_cap(struct mlx5_ib_dev *dev)
|
||||
{
|
||||
struct mlx5_hca_vport_context vport_ctx;
|
||||
@ -2786,10 +2823,15 @@ static int set_has_smi_cap(struct mlx5_ib_dev *dev)
|
||||
return 0;
|
||||
|
||||
for (port = 1; port <= dev->num_ports; port++) {
|
||||
if (!MLX5_CAP_GEN(dev->mdev, ib_virt)) {
|
||||
if (dev->num_plane) {
|
||||
dev->port_caps[port - 1].has_smi = false;
|
||||
continue;
|
||||
} else if (!MLX5_CAP_GEN(dev->mdev, ib_virt) ||
|
||||
dev->ib_dev.type == RDMA_DEVICE_TYPE_SMI) {
|
||||
dev->port_caps[port - 1].has_smi = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
err = mlx5_query_hca_vport_context(dev->mdev, 0, port, 0,
|
||||
&vport_ctx);
|
||||
if (err) {
|
||||
@ -2823,37 +2865,72 @@ static u8 mlx5_get_umr_fence(u8 umr_fence_cap)
|
||||
}
|
||||
}
|
||||
|
||||
static int mlx5_ib_dev_res_init(struct mlx5_ib_dev *dev)
|
||||
int mlx5_ib_dev_res_cq_init(struct mlx5_ib_dev *dev)
|
||||
{
|
||||
struct mlx5_ib_resources *devr = &dev->devr;
|
||||
struct ib_cq_init_attr cq_attr = {.cqe = 1};
|
||||
struct ib_device *ibdev;
|
||||
struct ib_pd *pd;
|
||||
struct ib_cq *cq;
|
||||
int ret = 0;
|
||||
|
||||
|
||||
/*
|
||||
* devr->c0 is set once, never changed until device unload.
|
||||
* Avoid taking the mutex if initialization is already done.
|
||||
*/
|
||||
if (devr->c0)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&devr->cq_lock);
|
||||
if (devr->c0)
|
||||
goto unlock;
|
||||
|
||||
ibdev = &dev->ib_dev;
|
||||
pd = ib_alloc_pd(ibdev, 0);
|
||||
if (IS_ERR(pd)) {
|
||||
ret = PTR_ERR(pd);
|
||||
mlx5_ib_err(dev, "Couldn't allocate PD for res init, err=%d\n", ret);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
cq = ib_create_cq(ibdev, NULL, NULL, NULL, &cq_attr);
|
||||
if (IS_ERR(cq)) {
|
||||
ret = PTR_ERR(cq);
|
||||
mlx5_ib_err(dev, "Couldn't create CQ for res init, err=%d\n", ret);
|
||||
ib_dealloc_pd(pd);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
devr->p0 = pd;
|
||||
devr->c0 = cq;
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&devr->cq_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mlx5_ib_dev_res_srq_init(struct mlx5_ib_dev *dev)
|
||||
{
|
||||
struct mlx5_ib_resources *devr = &dev->devr;
|
||||
struct ib_srq_init_attr attr;
|
||||
struct ib_device *ibdev;
|
||||
struct ib_cq_init_attr cq_attr = {.cqe = 1};
|
||||
int port;
|
||||
struct ib_srq *s0, *s1;
|
||||
int ret = 0;
|
||||
|
||||
ibdev = &dev->ib_dev;
|
||||
/*
|
||||
* devr->s1 is set once, never changed until device unload.
|
||||
* Avoid taking the mutex if initialization is already done.
|
||||
*/
|
||||
if (devr->s1)
|
||||
return 0;
|
||||
|
||||
if (!MLX5_CAP_GEN(dev->mdev, xrc))
|
||||
return -EOPNOTSUPP;
|
||||
mutex_lock(&devr->srq_lock);
|
||||
if (devr->s1)
|
||||
goto unlock;
|
||||
|
||||
devr->p0 = ib_alloc_pd(ibdev, 0);
|
||||
if (IS_ERR(devr->p0))
|
||||
return PTR_ERR(devr->p0);
|
||||
|
||||
devr->c0 = ib_create_cq(ibdev, NULL, NULL, NULL, &cq_attr);
|
||||
if (IS_ERR(devr->c0)) {
|
||||
ret = PTR_ERR(devr->c0);
|
||||
goto error1;
|
||||
}
|
||||
|
||||
ret = mlx5_cmd_xrcd_alloc(dev->mdev, &devr->xrcdn0, 0);
|
||||
ret = mlx5_ib_dev_res_cq_init(dev);
|
||||
if (ret)
|
||||
goto error2;
|
||||
|
||||
ret = mlx5_cmd_xrcd_alloc(dev->mdev, &devr->xrcdn1, 0);
|
||||
if (ret)
|
||||
goto error3;
|
||||
goto unlock;
|
||||
|
||||
memset(&attr, 0, sizeof(attr));
|
||||
attr.attr.max_sge = 1;
|
||||
@ -2861,10 +2938,11 @@ static int mlx5_ib_dev_res_init(struct mlx5_ib_dev *dev)
|
||||
attr.srq_type = IB_SRQT_XRC;
|
||||
attr.ext.cq = devr->c0;
|
||||
|
||||
devr->s0 = ib_create_srq(devr->p0, &attr);
|
||||
if (IS_ERR(devr->s0)) {
|
||||
ret = PTR_ERR(devr->s0);
|
||||
goto err_create;
|
||||
s0 = ib_create_srq(devr->p0, &attr);
|
||||
if (IS_ERR(s0)) {
|
||||
ret = PTR_ERR(s0);
|
||||
mlx5_ib_err(dev, "Couldn't create SRQ 0 for res init, err=%d\n", ret);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
memset(&attr, 0, sizeof(attr));
|
||||
@ -2872,29 +2950,48 @@ static int mlx5_ib_dev_res_init(struct mlx5_ib_dev *dev)
|
||||
attr.attr.max_wr = 1;
|
||||
attr.srq_type = IB_SRQT_BASIC;
|
||||
|
||||
devr->s1 = ib_create_srq(devr->p0, &attr);
|
||||
if (IS_ERR(devr->s1)) {
|
||||
ret = PTR_ERR(devr->s1);
|
||||
goto error6;
|
||||
s1 = ib_create_srq(devr->p0, &attr);
|
||||
if (IS_ERR(s1)) {
|
||||
ret = PTR_ERR(s1);
|
||||
mlx5_ib_err(dev, "Couldn't create SRQ 1 for res init, err=%d\n", ret);
|
||||
ib_destroy_srq(s0);
|
||||
}
|
||||
|
||||
devr->s0 = s0;
|
||||
devr->s1 = s1;
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&devr->srq_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mlx5_ib_dev_res_init(struct mlx5_ib_dev *dev)
|
||||
{
|
||||
struct mlx5_ib_resources *devr = &dev->devr;
|
||||
int port;
|
||||
int ret;
|
||||
|
||||
if (!MLX5_CAP_GEN(dev->mdev, xrc))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = mlx5_cmd_xrcd_alloc(dev->mdev, &devr->xrcdn0, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = mlx5_cmd_xrcd_alloc(dev->mdev, &devr->xrcdn1, 0);
|
||||
if (ret) {
|
||||
mlx5_cmd_xrcd_dealloc(dev->mdev, devr->xrcdn0, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (port = 0; port < ARRAY_SIZE(devr->ports); ++port)
|
||||
INIT_WORK(&devr->ports[port].pkey_change_work,
|
||||
pkey_change_handler);
|
||||
|
||||
return 0;
|
||||
mutex_init(&devr->cq_lock);
|
||||
mutex_init(&devr->srq_lock);
|
||||
|
||||
error6:
|
||||
ib_destroy_srq(devr->s0);
|
||||
err_create:
|
||||
mlx5_cmd_xrcd_dealloc(dev->mdev, devr->xrcdn1, 0);
|
||||
error3:
|
||||
mlx5_cmd_xrcd_dealloc(dev->mdev, devr->xrcdn0, 0);
|
||||
error2:
|
||||
ib_destroy_cq(devr->c0);
|
||||
error1:
|
||||
ib_dealloc_pd(devr->p0);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mlx5_ib_dev_res_cleanup(struct mlx5_ib_dev *dev)
|
||||
@ -2911,12 +3008,20 @@ static void mlx5_ib_dev_res_cleanup(struct mlx5_ib_dev *dev)
|
||||
for (port = 0; port < ARRAY_SIZE(devr->ports); ++port)
|
||||
cancel_work_sync(&devr->ports[port].pkey_change_work);
|
||||
|
||||
ib_destroy_srq(devr->s1);
|
||||
ib_destroy_srq(devr->s0);
|
||||
/* After s0/s1 init, they are not unset during the device lifetime. */
|
||||
if (devr->s1) {
|
||||
ib_destroy_srq(devr->s1);
|
||||
ib_destroy_srq(devr->s0);
|
||||
}
|
||||
mlx5_cmd_xrcd_dealloc(dev->mdev, devr->xrcdn1, 0);
|
||||
mlx5_cmd_xrcd_dealloc(dev->mdev, devr->xrcdn0, 0);
|
||||
ib_destroy_cq(devr->c0);
|
||||
ib_dealloc_pd(devr->p0);
|
||||
/* After p0/c0 init, they are not unset during the device lifetime. */
|
||||
if (devr->c0) {
|
||||
ib_destroy_cq(devr->c0);
|
||||
ib_dealloc_pd(devr->p0);
|
||||
}
|
||||
mutex_destroy(&devr->cq_lock);
|
||||
mutex_destroy(&devr->srq_lock);
|
||||
}
|
||||
|
||||
static u32 get_core_cap_flags(struct ib_device *ibdev,
|
||||
@ -2932,6 +3037,13 @@ static u32 get_core_cap_flags(struct ib_device *ibdev,
|
||||
if (rep->grh_required)
|
||||
ret |= RDMA_CORE_CAP_IB_GRH_REQUIRED;
|
||||
|
||||
if (dev->num_plane)
|
||||
return ret | RDMA_CORE_CAP_PROT_IB | RDMA_CORE_CAP_IB_MAD |
|
||||
RDMA_CORE_CAP_IB_CM | RDMA_CORE_CAP_IB_SA |
|
||||
RDMA_CORE_CAP_AF_IB;
|
||||
else if (ibdev->type == RDMA_DEVICE_TYPE_SMI)
|
||||
return ret | RDMA_CORE_CAP_IB_MAD | RDMA_CORE_CAP_IB_SMI;
|
||||
|
||||
if (ll == IB_LINK_LAYER_INFINIBAND)
|
||||
return ret | RDMA_CORE_PORT_IBA_IB;
|
||||
|
||||
@ -2967,6 +3079,9 @@ static int mlx5_port_immutable(struct ib_device *ibdev, u32 port_num,
|
||||
return err;
|
||||
|
||||
if (ll == IB_LINK_LAYER_INFINIBAND) {
|
||||
if (ibdev->type == RDMA_DEVICE_TYPE_SMI)
|
||||
port_num = smi_to_native_portnum(dev, port_num);
|
||||
|
||||
err = mlx5_query_hca_vport_context(dev->mdev, 0, port_num, 0,
|
||||
&rep);
|
||||
if (err)
|
||||
@ -3687,6 +3802,7 @@ static const struct uapi_definition mlx5_ib_defs[] = {
|
||||
UAPI_DEF_CHAIN(mlx5_ib_qos_defs),
|
||||
UAPI_DEF_CHAIN(mlx5_ib_std_types_defs),
|
||||
UAPI_DEF_CHAIN(mlx5_ib_dm_defs),
|
||||
UAPI_DEF_CHAIN(mlx5_ib_create_cq_defs),
|
||||
|
||||
UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_DEVICE, &mlx5_ib_query_context),
|
||||
UAPI_DEF_CHAIN_OBJ_TREE_NAMED(MLX5_IB_OBJECT_VAR,
|
||||
@ -3766,12 +3882,18 @@ err:
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct ib_device *mlx5_ib_add_sub_dev(struct ib_device *parent,
|
||||
enum rdma_nl_dev_type type,
|
||||
const char *name);
|
||||
static void mlx5_ib_del_sub_dev(struct ib_device *sub_dev);
|
||||
|
||||
static const struct ib_device_ops mlx5_ib_dev_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.driver_id = RDMA_DRIVER_MLX5,
|
||||
.uverbs_abi_ver = MLX5_IB_UVERBS_ABI_VERSION,
|
||||
|
||||
.add_gid = mlx5_ib_add_gid,
|
||||
.add_sub_dev = mlx5_ib_add_sub_dev,
|
||||
.alloc_mr = mlx5_ib_alloc_mr,
|
||||
.alloc_mr_integrity = mlx5_ib_alloc_mr_integrity,
|
||||
.alloc_pd = mlx5_ib_alloc_pd,
|
||||
@ -3786,6 +3908,7 @@ static const struct ib_device_ops mlx5_ib_dev_ops = {
|
||||
.dealloc_pd = mlx5_ib_dealloc_pd,
|
||||
.dealloc_ucontext = mlx5_ib_dealloc_ucontext,
|
||||
.del_gid = mlx5_ib_del_gid,
|
||||
.del_sub_dev = mlx5_ib_del_sub_dev,
|
||||
.dereg_mr = mlx5_ib_dereg_mr,
|
||||
.destroy_ah = mlx5_ib_destroy_ah,
|
||||
.destroy_cq = mlx5_ib_destroy_cq,
|
||||
@ -4075,7 +4198,10 @@ static int mlx5_ib_stage_ib_reg_init(struct mlx5_ib_dev *dev)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
if (!mlx5_lag_is_active(dev->mdev))
|
||||
if (dev->sub_dev_name) {
|
||||
name = dev->sub_dev_name;
|
||||
ib_mark_name_assigned_by_user(&dev->ib_dev);
|
||||
} else if (!mlx5_lag_is_active(dev->mdev))
|
||||
name = "mlx5_%d";
|
||||
else
|
||||
name = "mlx5_bond_%d";
|
||||
@ -4086,6 +4212,7 @@ static void mlx5_ib_stage_pre_ib_reg_umr_cleanup(struct mlx5_ib_dev *dev)
|
||||
{
|
||||
mlx5_mkey_cache_cleanup(dev);
|
||||
mlx5r_umr_resource_cleanup(dev);
|
||||
mlx5r_umr_cleanup(dev);
|
||||
}
|
||||
|
||||
static void mlx5_ib_stage_ib_reg_cleanup(struct mlx5_ib_dev *dev)
|
||||
@ -4097,7 +4224,7 @@ static int mlx5_ib_stage_post_ib_reg_umr_init(struct mlx5_ib_dev *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = mlx5r_umr_resource_init(dev);
|
||||
ret = mlx5r_umr_init(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -4335,6 +4462,89 @@ const struct mlx5_ib_profile raw_eth_profile = {
|
||||
NULL),
|
||||
};
|
||||
|
||||
static const struct mlx5_ib_profile plane_profile = {
|
||||
STAGE_CREATE(MLX5_IB_STAGE_INIT,
|
||||
mlx5_ib_stage_init_init,
|
||||
mlx5_ib_stage_init_cleanup),
|
||||
STAGE_CREATE(MLX5_IB_STAGE_CAPS,
|
||||
mlx5_ib_stage_caps_init,
|
||||
mlx5_ib_stage_caps_cleanup),
|
||||
STAGE_CREATE(MLX5_IB_STAGE_NON_DEFAULT_CB,
|
||||
mlx5_ib_stage_non_default_cb,
|
||||
NULL),
|
||||
STAGE_CREATE(MLX5_IB_STAGE_QP,
|
||||
mlx5_init_qp_table,
|
||||
mlx5_cleanup_qp_table),
|
||||
STAGE_CREATE(MLX5_IB_STAGE_SRQ,
|
||||
mlx5_init_srq_table,
|
||||
mlx5_cleanup_srq_table),
|
||||
STAGE_CREATE(MLX5_IB_STAGE_DEVICE_RESOURCES,
|
||||
mlx5_ib_dev_res_init,
|
||||
mlx5_ib_dev_res_cleanup),
|
||||
STAGE_CREATE(MLX5_IB_STAGE_BFREG,
|
||||
mlx5_ib_stage_bfrag_init,
|
||||
mlx5_ib_stage_bfrag_cleanup),
|
||||
STAGE_CREATE(MLX5_IB_STAGE_IB_REG,
|
||||
mlx5_ib_stage_ib_reg_init,
|
||||
mlx5_ib_stage_ib_reg_cleanup),
|
||||
};
|
||||
|
||||
static struct ib_device *mlx5_ib_add_sub_dev(struct ib_device *parent,
|
||||
enum rdma_nl_dev_type type,
|
||||
const char *name)
|
||||
{
|
||||
struct mlx5_ib_dev *mparent = to_mdev(parent), *mplane;
|
||||
enum rdma_link_layer ll;
|
||||
int ret;
|
||||
|
||||
if (mparent->smi_dev)
|
||||
return ERR_PTR(-EEXIST);
|
||||
|
||||
ll = mlx5_port_type_cap_to_rdma_ll(MLX5_CAP_GEN(mparent->mdev,
|
||||
port_type));
|
||||
if (type != RDMA_DEVICE_TYPE_SMI || !mparent->num_plane ||
|
||||
ll != IB_LINK_LAYER_INFINIBAND ||
|
||||
!MLX5_CAP_GEN_2(mparent->mdev, multiplane_qp_ud))
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
||||
mplane = ib_alloc_device(mlx5_ib_dev, ib_dev);
|
||||
if (!mplane)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
mplane->port = kcalloc(mparent->num_plane * mparent->num_ports,
|
||||
sizeof(*mplane->port), GFP_KERNEL);
|
||||
if (!mplane->port) {
|
||||
ret = -ENOMEM;
|
||||
goto fail_kcalloc;
|
||||
}
|
||||
|
||||
mplane->ib_dev.type = type;
|
||||
mplane->mdev = mparent->mdev;
|
||||
mplane->num_ports = mparent->num_plane;
|
||||
mplane->sub_dev_name = name;
|
||||
|
||||
ret = __mlx5_ib_add(mplane, &plane_profile);
|
||||
if (ret)
|
||||
goto fail_ib_add;
|
||||
|
||||
mparent->smi_dev = mplane;
|
||||
return &mplane->ib_dev;
|
||||
|
||||
fail_ib_add:
|
||||
kfree(mplane->port);
|
||||
fail_kcalloc:
|
||||
ib_dealloc_device(&mplane->ib_dev);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
static void mlx5_ib_del_sub_dev(struct ib_device *sub_dev)
|
||||
{
|
||||
struct mlx5_ib_dev *mdev = to_mdev(sub_dev);
|
||||
|
||||
to_mdev(sub_dev->parent)->smi_dev = NULL;
|
||||
__mlx5_ib_remove(mdev, mdev->profile, MLX5_IB_STAGE_MAX);
|
||||
}
|
||||
|
||||
static int mlx5r_mp_probe(struct auxiliary_device *adev,
|
||||
const struct auxiliary_device_id *id)
|
||||
{
|
||||
@ -4412,11 +4622,18 @@ static int mlx5r_probe(struct auxiliary_device *adev,
|
||||
dev = ib_alloc_device(mlx5_ib_dev, ib_dev);
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
|
||||
if (ll == IB_LINK_LAYER_INFINIBAND) {
|
||||
ret = mlx5_ib_get_plane_num(mdev, &dev->num_plane);
|
||||
if (ret)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
dev->port = kcalloc(num_ports, sizeof(*dev->port),
|
||||
GFP_KERNEL);
|
||||
if (!dev->port) {
|
||||
ib_dealloc_device(&dev->ib_dev);
|
||||
return -ENOMEM;
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
dev->mdev = mdev;
|
||||
@ -4428,14 +4645,17 @@ static int mlx5r_probe(struct auxiliary_device *adev,
|
||||
profile = &pf_profile;
|
||||
|
||||
ret = __mlx5_ib_add(dev, profile);
|
||||
if (ret) {
|
||||
kfree(dev->port);
|
||||
ib_dealloc_device(&dev->ib_dev);
|
||||
return ret;
|
||||
}
|
||||
if (ret)
|
||||
goto fail_ib_add;
|
||||
|
||||
auxiliary_set_drvdata(adev, dev);
|
||||
return 0;
|
||||
|
||||
fail_ib_add:
|
||||
kfree(dev->port);
|
||||
fail:
|
||||
ib_dealloc_device(&dev->ib_dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void mlx5r_remove(struct auxiliary_device *adev)
|
||||
|
@ -115,6 +115,19 @@ unsigned long __mlx5_umem_find_best_quantized_pgoff(
|
||||
__mlx5_bit_sz(typ, page_offset_fld), 0, scale, \
|
||||
page_offset_quantized)
|
||||
|
||||
static inline unsigned long
|
||||
mlx5_umem_dmabuf_find_best_pgsz(struct ib_umem_dmabuf *umem_dmabuf)
|
||||
{
|
||||
/*
|
||||
* mkeys used for dmabuf are fixed at PAGE_SIZE because we must be able
|
||||
* to hold any sgl after a move operation. Ideally the mkc page size
|
||||
* could be changed at runtime to be optimal, but right now the driver
|
||||
* cannot do that.
|
||||
*/
|
||||
return ib_umem_find_best_pgsz(&umem_dmabuf->umem, PAGE_SIZE,
|
||||
umem_dmabuf->umem.iova);
|
||||
}
|
||||
|
||||
enum {
|
||||
MLX5_IB_MMAP_OFFSET_START = 9,
|
||||
MLX5_IB_MMAP_OFFSET_END = 255,
|
||||
@ -751,6 +764,8 @@ struct umr_common {
|
||||
*/
|
||||
struct mutex lock;
|
||||
unsigned int state;
|
||||
/* Protects from repeat UMR QP creation */
|
||||
struct mutex init_lock;
|
||||
};
|
||||
|
||||
#define NUM_MKEYS_PER_PAGE \
|
||||
@ -822,11 +837,13 @@ struct mlx5_ib_port_resources {
|
||||
|
||||
struct mlx5_ib_resources {
|
||||
struct ib_cq *c0;
|
||||
struct mutex cq_lock;
|
||||
u32 xrcdn0;
|
||||
u32 xrcdn1;
|
||||
struct ib_pd *p0;
|
||||
struct ib_srq *s0;
|
||||
struct ib_srq *s1;
|
||||
struct mutex srq_lock;
|
||||
struct mlx5_ib_port_resources ports[2];
|
||||
};
|
||||
|
||||
@ -1172,6 +1189,10 @@ struct mlx5_ib_dev {
|
||||
#ifdef CONFIG_MLX5_MACSEC
|
||||
struct mlx5_macsec macsec;
|
||||
#endif
|
||||
|
||||
u8 num_plane;
|
||||
struct mlx5_ib_dev *smi_dev;
|
||||
const char *sub_dev_name;
|
||||
};
|
||||
|
||||
static inline struct mlx5_ib_cq *to_mibcq(struct mlx5_core_cq *mcq)
|
||||
@ -1270,6 +1291,8 @@ to_mmmap(struct rdma_user_mmap_entry *rdma_entry)
|
||||
struct mlx5_user_mmap_entry, rdma_entry);
|
||||
}
|
||||
|
||||
int mlx5_ib_dev_res_cq_init(struct mlx5_ib_dev *dev);
|
||||
int mlx5_ib_dev_res_srq_init(struct mlx5_ib_dev *dev);
|
||||
int mlx5_ib_db_map_user(struct mlx5_ib_ucontext *context, unsigned long virt,
|
||||
struct mlx5_db *db);
|
||||
void mlx5_ib_db_unmap_user(struct mlx5_ib_ucontext *context, struct mlx5_db *db);
|
||||
@ -1309,7 +1332,7 @@ int mlx5_ib_read_wqe_rq(struct mlx5_ib_qp *qp, int wqe_index, void *buffer,
|
||||
int mlx5_ib_read_wqe_srq(struct mlx5_ib_srq *srq, int wqe_index, void *buffer,
|
||||
size_t buflen, size_t *bc);
|
||||
int mlx5_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata);
|
||||
struct uverbs_attr_bundle *attrs);
|
||||
int mlx5_ib_destroy_cq(struct ib_cq *cq, struct ib_udata *udata);
|
||||
int mlx5_ib_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc);
|
||||
int mlx5_ib_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags);
|
||||
@ -1509,6 +1532,7 @@ extern const struct uapi_definition mlx5_ib_devx_defs[];
|
||||
extern const struct uapi_definition mlx5_ib_flow_defs[];
|
||||
extern const struct uapi_definition mlx5_ib_qos_defs[];
|
||||
extern const struct uapi_definition mlx5_ib_std_types_defs[];
|
||||
extern const struct uapi_definition mlx5_ib_create_cq_defs[];
|
||||
|
||||
static inline int is_qp1(enum ib_qp_type qp_type)
|
||||
{
|
||||
@ -1677,4 +1701,10 @@ static inline bool mlx5_umem_needs_ats(struct mlx5_ib_dev *dev,
|
||||
int set_roce_addr(struct mlx5_ib_dev *dev, u32 port_num,
|
||||
unsigned int index, const union ib_gid *gid,
|
||||
const struct ib_gid_attr *attr);
|
||||
|
||||
static inline u32 smi_to_native_portnum(struct mlx5_ib_dev *dev, u32 port)
|
||||
{
|
||||
return (port - 1) / dev->num_ports + 1;
|
||||
}
|
||||
|
||||
#endif /* MLX5_IB_H */
|
||||
|
@ -1470,6 +1470,7 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
|
||||
{
|
||||
struct mlx5_ib_dev *dev = to_mdev(pd->device);
|
||||
struct ib_umem *umem;
|
||||
int err;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_INFINIBAND_USER_MEM))
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
@ -1477,6 +1478,10 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
|
||||
mlx5_ib_dbg(dev, "start 0x%llx, iova 0x%llx, length 0x%llx, access_flags 0x%x\n",
|
||||
start, iova, length, access_flags);
|
||||
|
||||
err = mlx5r_umr_resource_init(dev);
|
||||
if (err)
|
||||
return ERR_PTR(err);
|
||||
|
||||
if (access_flags & IB_ACCESS_ON_DEMAND)
|
||||
return create_user_odp_mr(pd, start, length, iova, access_flags,
|
||||
udata);
|
||||
@ -1523,6 +1528,10 @@ struct ib_mr *mlx5_ib_reg_user_mr_dmabuf(struct ib_pd *pd, u64 offset,
|
||||
"offset 0x%llx, virt_addr 0x%llx, length 0x%llx, fd %d, access_flags 0x%x\n",
|
||||
offset, virt_addr, length, fd, access_flags);
|
||||
|
||||
err = mlx5r_umr_resource_init(dev);
|
||||
if (err)
|
||||
return ERR_PTR(err);
|
||||
|
||||
/* dmabuf requires xlt update via umr to work. */
|
||||
if (!mlx5r_umr_can_load_pas(dev, length))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
@ -705,10 +705,8 @@ static int pagefault_dmabuf_mr(struct mlx5_ib_mr *mr, size_t bcnt,
|
||||
return err;
|
||||
}
|
||||
|
||||
page_size = mlx5_umem_find_best_pgsz(&umem_dmabuf->umem, mkc,
|
||||
log_page_size, 0,
|
||||
umem_dmabuf->umem.iova);
|
||||
if (unlikely(page_size < PAGE_SIZE)) {
|
||||
page_size = mlx5_umem_dmabuf_find_best_pgsz(umem_dmabuf);
|
||||
if (!page_size) {
|
||||
ib_umem_dmabuf_unmap_pages(umem_dmabuf);
|
||||
err = -EINVAL;
|
||||
} else {
|
||||
|
@ -3234,6 +3234,10 @@ int mlx5_ib_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attr,
|
||||
enum ib_qp_type type;
|
||||
int err;
|
||||
|
||||
err = mlx5_ib_dev_res_srq_init(dev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = check_qp_type(dev, attr, &type);
|
||||
if (err)
|
||||
return err;
|
||||
@ -4213,7 +4217,12 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
|
||||
|
||||
/* todo implement counter_index functionality */
|
||||
|
||||
if (is_sqp(qp->type))
|
||||
if (dev->ib_dev.type == RDMA_DEVICE_TYPE_SMI && is_qp0(qp->type)) {
|
||||
MLX5_SET(ads, pri_path, vhca_port_num,
|
||||
smi_to_native_portnum(dev, qp->port));
|
||||
if (cur_state == IB_QPS_INIT && new_state == IB_QPS_RTR)
|
||||
MLX5_SET(ads, pri_path, plane_index, qp->port);
|
||||
} else if (is_sqp(qp->type))
|
||||
MLX5_SET(ads, pri_path, vhca_port_num, qp->port);
|
||||
|
||||
if (attr_mask & IB_QP_PORT)
|
||||
|
@ -249,7 +249,8 @@ int mlx5_qpc_create_qp(struct mlx5_ib_dev *dev, struct mlx5_core_qp *qp,
|
||||
if (err)
|
||||
goto err_cmd;
|
||||
|
||||
mlx5_debug_qp_add(dev->mdev, qp);
|
||||
if (dev->ib_dev.type != RDMA_DEVICE_TYPE_SMI)
|
||||
mlx5_debug_qp_add(dev->mdev, qp);
|
||||
|
||||
return 0;
|
||||
|
||||
@ -307,7 +308,8 @@ int mlx5_core_destroy_qp(struct mlx5_ib_dev *dev, struct mlx5_core_qp *qp)
|
||||
{
|
||||
u32 in[MLX5_ST_SZ_DW(destroy_qp_in)] = {};
|
||||
|
||||
mlx5_debug_qp_remove(dev->mdev, qp);
|
||||
if (dev->ib_dev.type != RDMA_DEVICE_TYPE_SMI)
|
||||
mlx5_debug_qp_remove(dev->mdev, qp);
|
||||
|
||||
destroy_resource_common(dev, qp);
|
||||
|
||||
@ -504,7 +506,9 @@ int mlx5_init_qp_table(struct mlx5_ib_dev *dev)
|
||||
spin_lock_init(&table->lock);
|
||||
INIT_RADIX_TREE(&table->tree, GFP_ATOMIC);
|
||||
xa_init(&table->dct_xa);
|
||||
mlx5_qp_debugfs_init(dev->mdev);
|
||||
|
||||
if (dev->ib_dev.type != RDMA_DEVICE_TYPE_SMI)
|
||||
mlx5_qp_debugfs_init(dev->mdev);
|
||||
|
||||
table->nb.notifier_call = rsc_event_notifier;
|
||||
mlx5_notifier_register(dev->mdev, &table->nb);
|
||||
@ -517,7 +521,8 @@ void mlx5_cleanup_qp_table(struct mlx5_ib_dev *dev)
|
||||
struct mlx5_qp_table *table = &dev->qp_table;
|
||||
|
||||
mlx5_notifier_unregister(dev->mdev, &table->nb);
|
||||
mlx5_qp_debugfs_cleanup(dev->mdev);
|
||||
if (dev->ib_dev.type != RDMA_DEVICE_TYPE_SMI)
|
||||
mlx5_qp_debugfs_cleanup(dev->mdev);
|
||||
}
|
||||
|
||||
int mlx5_core_qp_query(struct mlx5_ib_dev *dev, struct mlx5_core_qp *qp,
|
||||
|
@ -216,6 +216,10 @@ int mlx5_ib_create_srq(struct ib_srq *ib_srq,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = mlx5_ib_dev_res_cq_init(dev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
mutex_init(&srq->mutex);
|
||||
spin_lock_init(&srq->lock);
|
||||
srq->msrq.max = roundup_pow_of_two(init_attr->attr.max_wr + 1);
|
||||
|
@ -135,22 +135,28 @@ static int mlx5r_umr_qp_rst2rts(struct mlx5_ib_dev *dev, struct ib_qp *qp)
|
||||
int mlx5r_umr_resource_init(struct mlx5_ib_dev *dev)
|
||||
{
|
||||
struct ib_qp_init_attr init_attr = {};
|
||||
struct ib_pd *pd;
|
||||
struct ib_cq *cq;
|
||||
struct ib_qp *qp;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
pd = ib_alloc_pd(&dev->ib_dev, 0);
|
||||
if (IS_ERR(pd)) {
|
||||
mlx5_ib_dbg(dev, "Couldn't create PD for sync UMR QP\n");
|
||||
return PTR_ERR(pd);
|
||||
}
|
||||
|
||||
/*
|
||||
* UMR qp is set once, never changed until device unload.
|
||||
* Avoid taking the mutex if initialization is already done.
|
||||
*/
|
||||
if (dev->umrc.qp)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&dev->umrc.init_lock);
|
||||
/* First user allocates the UMR resources. Skip if already allocated. */
|
||||
if (dev->umrc.qp)
|
||||
goto unlock;
|
||||
|
||||
cq = ib_alloc_cq(&dev->ib_dev, NULL, 128, 0, IB_POLL_SOFTIRQ);
|
||||
if (IS_ERR(cq)) {
|
||||
mlx5_ib_dbg(dev, "Couldn't create CQ for sync UMR QP\n");
|
||||
ret = PTR_ERR(cq);
|
||||
goto destroy_pd;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
init_attr.send_cq = cq;
|
||||
@ -160,7 +166,7 @@ int mlx5r_umr_resource_init(struct mlx5_ib_dev *dev)
|
||||
init_attr.cap.max_send_sge = 1;
|
||||
init_attr.qp_type = MLX5_IB_QPT_REG_UMR;
|
||||
init_attr.port_num = 1;
|
||||
qp = ib_create_qp(pd, &init_attr);
|
||||
qp = ib_create_qp(dev->umrc.pd, &init_attr);
|
||||
if (IS_ERR(qp)) {
|
||||
mlx5_ib_dbg(dev, "Couldn't create sync UMR QP\n");
|
||||
ret = PTR_ERR(qp);
|
||||
@ -171,22 +177,22 @@ int mlx5r_umr_resource_init(struct mlx5_ib_dev *dev)
|
||||
if (ret)
|
||||
goto destroy_qp;
|
||||
|
||||
dev->umrc.qp = qp;
|
||||
dev->umrc.cq = cq;
|
||||
dev->umrc.pd = pd;
|
||||
|
||||
sema_init(&dev->umrc.sem, MAX_UMR_WR);
|
||||
mutex_init(&dev->umrc.lock);
|
||||
dev->umrc.state = MLX5_UMR_STATE_ACTIVE;
|
||||
dev->umrc.qp = qp;
|
||||
|
||||
mutex_unlock(&dev->umrc.init_lock);
|
||||
return 0;
|
||||
|
||||
destroy_qp:
|
||||
ib_destroy_qp(qp);
|
||||
destroy_cq:
|
||||
ib_free_cq(cq);
|
||||
destroy_pd:
|
||||
ib_dealloc_pd(pd);
|
||||
unlock:
|
||||
mutex_unlock(&dev->umrc.init_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -194,8 +200,31 @@ void mlx5r_umr_resource_cleanup(struct mlx5_ib_dev *dev)
|
||||
{
|
||||
if (dev->umrc.state == MLX5_UMR_STATE_UNINIT)
|
||||
return;
|
||||
mutex_destroy(&dev->umrc.lock);
|
||||
/* After device init, UMR cp/qp are not unset during the lifetime. */
|
||||
ib_destroy_qp(dev->umrc.qp);
|
||||
ib_free_cq(dev->umrc.cq);
|
||||
}
|
||||
|
||||
int mlx5r_umr_init(struct mlx5_ib_dev *dev)
|
||||
{
|
||||
struct ib_pd *pd;
|
||||
|
||||
pd = ib_alloc_pd(&dev->ib_dev, 0);
|
||||
if (IS_ERR(pd)) {
|
||||
mlx5_ib_dbg(dev, "Couldn't create PD for sync UMR QP\n");
|
||||
return PTR_ERR(pd);
|
||||
}
|
||||
dev->umrc.pd = pd;
|
||||
|
||||
mutex_init(&dev->umrc.init_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mlx5r_umr_cleanup(struct mlx5_ib_dev *dev)
|
||||
{
|
||||
mutex_destroy(&dev->umrc.init_lock);
|
||||
ib_dealloc_pd(dev->umrc.pd);
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,9 @@
|
||||
int mlx5r_umr_resource_init(struct mlx5_ib_dev *dev);
|
||||
void mlx5r_umr_resource_cleanup(struct mlx5_ib_dev *dev);
|
||||
|
||||
int mlx5r_umr_init(struct mlx5_ib_dev *dev);
|
||||
void mlx5r_umr_cleanup(struct mlx5_ib_dev *dev);
|
||||
|
||||
static inline bool mlx5r_umr_can_load_pas(struct mlx5_ib_dev *dev,
|
||||
size_t length)
|
||||
{
|
||||
|
@ -574,8 +574,9 @@ static int mthca_destroy_qp(struct ib_qp *qp, struct ib_udata *udata)
|
||||
|
||||
static int mthca_create_cq(struct ib_cq *ibcq,
|
||||
const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata)
|
||||
struct uverbs_attr_bundle *attrs)
|
||||
{
|
||||
struct ib_udata *udata = &attrs->driver_udata;
|
||||
struct ib_device *ibdev = ibcq->device;
|
||||
int entries = attr->cqe;
|
||||
struct mthca_create_cq ucmd;
|
||||
|
@ -46,7 +46,7 @@
|
||||
|
||||
static struct dentry *ocrdma_dbgfs_dir;
|
||||
|
||||
static int ocrdma_add_stat(char *start, char *pcur,
|
||||
static noinline_for_stack int ocrdma_add_stat(char *start, char *pcur,
|
||||
char *name, u64 count)
|
||||
{
|
||||
char buff[128] = {0};
|
||||
@ -99,7 +99,7 @@ void ocrdma_release_stats_resources(struct ocrdma_dev *dev)
|
||||
kfree(mem->debugfs_mem);
|
||||
}
|
||||
|
||||
static char *ocrdma_resource_stats(struct ocrdma_dev *dev)
|
||||
static noinline_for_stack char *ocrdma_resource_stats(struct ocrdma_dev *dev)
|
||||
{
|
||||
char *stats = dev->stats_mem.debugfs_mem, *pcur;
|
||||
struct ocrdma_rdma_stats_resp *rdma_stats =
|
||||
@ -216,7 +216,7 @@ static char *ocrdma_resource_stats(struct ocrdma_dev *dev)
|
||||
return stats;
|
||||
}
|
||||
|
||||
static char *ocrdma_rx_stats(struct ocrdma_dev *dev)
|
||||
static noinline_for_stack char *ocrdma_rx_stats(struct ocrdma_dev *dev)
|
||||
{
|
||||
char *stats = dev->stats_mem.debugfs_mem, *pcur;
|
||||
struct ocrdma_rdma_stats_resp *rdma_stats =
|
||||
@ -284,7 +284,7 @@ static u64 ocrdma_sysfs_rcv_data(struct ocrdma_dev *dev)
|
||||
rx_stats->roce_frame_bytes_hi))/4;
|
||||
}
|
||||
|
||||
static char *ocrdma_tx_stats(struct ocrdma_dev *dev)
|
||||
static noinline_for_stack char *ocrdma_tx_stats(struct ocrdma_dev *dev)
|
||||
{
|
||||
char *stats = dev->stats_mem.debugfs_mem, *pcur;
|
||||
struct ocrdma_rdma_stats_resp *rdma_stats =
|
||||
@ -358,7 +358,7 @@ static u64 ocrdma_sysfs_xmit_data(struct ocrdma_dev *dev)
|
||||
tx_stats->read_rsp_bytes_hi))/4;
|
||||
}
|
||||
|
||||
static char *ocrdma_wqe_stats(struct ocrdma_dev *dev)
|
||||
static noinline_for_stack char *ocrdma_wqe_stats(struct ocrdma_dev *dev)
|
||||
{
|
||||
char *stats = dev->stats_mem.debugfs_mem, *pcur;
|
||||
struct ocrdma_rdma_stats_resp *rdma_stats =
|
||||
@ -391,7 +391,7 @@ static char *ocrdma_wqe_stats(struct ocrdma_dev *dev)
|
||||
return stats;
|
||||
}
|
||||
|
||||
static char *ocrdma_db_errstats(struct ocrdma_dev *dev)
|
||||
static noinline_for_stack char *ocrdma_db_errstats(struct ocrdma_dev *dev)
|
||||
{
|
||||
char *stats = dev->stats_mem.debugfs_mem, *pcur;
|
||||
struct ocrdma_rdma_stats_resp *rdma_stats =
|
||||
@ -412,7 +412,7 @@ static char *ocrdma_db_errstats(struct ocrdma_dev *dev)
|
||||
return stats;
|
||||
}
|
||||
|
||||
static char *ocrdma_rxqp_errstats(struct ocrdma_dev *dev)
|
||||
static noinline_for_stack char *ocrdma_rxqp_errstats(struct ocrdma_dev *dev)
|
||||
{
|
||||
char *stats = dev->stats_mem.debugfs_mem, *pcur;
|
||||
struct ocrdma_rdma_stats_resp *rdma_stats =
|
||||
@ -438,7 +438,7 @@ static char *ocrdma_rxqp_errstats(struct ocrdma_dev *dev)
|
||||
return stats;
|
||||
}
|
||||
|
||||
static char *ocrdma_txqp_errstats(struct ocrdma_dev *dev)
|
||||
static noinline_for_stack char *ocrdma_txqp_errstats(struct ocrdma_dev *dev)
|
||||
{
|
||||
char *stats = dev->stats_mem.debugfs_mem, *pcur;
|
||||
struct ocrdma_rdma_stats_resp *rdma_stats =
|
||||
@ -462,7 +462,7 @@ static char *ocrdma_txqp_errstats(struct ocrdma_dev *dev)
|
||||
return stats;
|
||||
}
|
||||
|
||||
static char *ocrdma_tx_dbg_stats(struct ocrdma_dev *dev)
|
||||
static noinline_for_stack char *ocrdma_tx_dbg_stats(struct ocrdma_dev *dev)
|
||||
{
|
||||
int i;
|
||||
char *pstats = dev->stats_mem.debugfs_mem;
|
||||
@ -480,7 +480,7 @@ static char *ocrdma_tx_dbg_stats(struct ocrdma_dev *dev)
|
||||
return dev->stats_mem.debugfs_mem;
|
||||
}
|
||||
|
||||
static char *ocrdma_rx_dbg_stats(struct ocrdma_dev *dev)
|
||||
static noinline_for_stack char *ocrdma_rx_dbg_stats(struct ocrdma_dev *dev)
|
||||
{
|
||||
int i;
|
||||
char *pstats = dev->stats_mem.debugfs_mem;
|
||||
@ -498,7 +498,7 @@ static char *ocrdma_rx_dbg_stats(struct ocrdma_dev *dev)
|
||||
return dev->stats_mem.debugfs_mem;
|
||||
}
|
||||
|
||||
static char *ocrdma_driver_dbg_stats(struct ocrdma_dev *dev)
|
||||
static noinline_for_stack char *ocrdma_driver_dbg_stats(struct ocrdma_dev *dev)
|
||||
{
|
||||
char *stats = dev->stats_mem.debugfs_mem, *pcur;
|
||||
|
||||
|
@ -963,8 +963,9 @@ err:
|
||||
}
|
||||
|
||||
int ocrdma_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata)
|
||||
struct uverbs_attr_bundle *attrs)
|
||||
{
|
||||
struct ib_udata *udata = &attrs->driver_udata;
|
||||
struct ib_device *ibdev = ibcq->device;
|
||||
int entries = attr->cqe;
|
||||
struct ocrdma_cq *cq = get_ocrdma_cq(ibcq);
|
||||
|
@ -70,7 +70,7 @@ int ocrdma_alloc_pd(struct ib_pd *pd, struct ib_udata *udata);
|
||||
int ocrdma_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata);
|
||||
|
||||
int ocrdma_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata);
|
||||
struct uverbs_attr_bundle *attrs);
|
||||
int ocrdma_resize_cq(struct ib_cq *, int cqe, struct ib_udata *);
|
||||
int ocrdma_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata);
|
||||
|
||||
|
@ -900,8 +900,9 @@ int qedr_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags)
|
||||
}
|
||||
|
||||
int qedr_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata)
|
||||
struct uverbs_attr_bundle *attrs)
|
||||
{
|
||||
struct ib_udata *udata = &attrs->driver_udata;
|
||||
struct ib_device *ibdev = ibcq->device;
|
||||
struct qedr_ucontext *ctx = rdma_udata_to_drv_context(
|
||||
udata, struct qedr_ucontext, ibucontext);
|
||||
|
@ -52,7 +52,7 @@ int qedr_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata);
|
||||
int qedr_alloc_xrcd(struct ib_xrcd *ibxrcd, struct ib_udata *udata);
|
||||
int qedr_dealloc_xrcd(struct ib_xrcd *ibxrcd, struct ib_udata *udata);
|
||||
int qedr_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata);
|
||||
struct uverbs_attr_bundle *attrs);
|
||||
int qedr_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata);
|
||||
int qedr_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags);
|
||||
int qedr_create_qp(struct ib_qp *qp, struct ib_qp_init_attr *attrs,
|
||||
|
@ -581,7 +581,7 @@ static int qib_create_workqueues(struct qib_devdata *dd)
|
||||
for (pidx = 0; pidx < dd->num_pports; ++pidx) {
|
||||
ppd = dd->pport + pidx;
|
||||
if (!ppd->qib_wq) {
|
||||
char wq_name[8]; /* 3 + 2 + 1 + 1 + 1 */
|
||||
char wq_name[23];
|
||||
|
||||
snprintf(wq_name, sizeof(wq_name), "qib%d_%d",
|
||||
dd->unit, pidx);
|
||||
|
@ -1551,7 +1551,7 @@ int qib_register_ib_device(struct qib_devdata *dd)
|
||||
ibdev->dev.parent = &dd->pcidev->dev;
|
||||
|
||||
snprintf(ibdev->node_desc, sizeof(ibdev->node_desc),
|
||||
"Intel Infiniband HCA %s", init_utsname()->nodename);
|
||||
"Intel Infiniband HCA %.42s", init_utsname()->nodename);
|
||||
|
||||
/*
|
||||
* Fill in rvt info object.
|
||||
|
@ -577,7 +577,7 @@ out_unlock:
|
||||
}
|
||||
|
||||
int usnic_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata)
|
||||
struct uverbs_attr_bundle *attrs)
|
||||
{
|
||||
if (attr->flags)
|
||||
return -EOPNOTSUPP;
|
||||
|
@ -56,7 +56,7 @@ int usnic_ib_destroy_qp(struct ib_qp *qp, struct ib_udata *udata);
|
||||
int usnic_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
|
||||
int attr_mask, struct ib_udata *udata);
|
||||
int usnic_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata);
|
||||
struct uverbs_attr_bundle *attrs);
|
||||
int usnic_ib_destroy_cq(struct ib_cq *cq, struct ib_udata *udata);
|
||||
struct ib_mr *usnic_ib_reg_mr(struct ib_pd *pd, u64 start, u64 length,
|
||||
u64 virt_addr, int access_flags,
|
||||
|
@ -94,13 +94,14 @@ int pvrdma_req_notify_cq(struct ib_cq *ibcq,
|
||||
* pvrdma_create_cq - create completion queue
|
||||
* @ibcq: Allocated CQ
|
||||
* @attr: completion queue attributes
|
||||
* @udata: user data
|
||||
* @attrs: bundle
|
||||
*
|
||||
* @return: 0 on success
|
||||
*/
|
||||
int pvrdma_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata)
|
||||
struct uverbs_attr_bundle *attrs)
|
||||
{
|
||||
struct ib_udata *udata = &attrs->driver_udata;
|
||||
struct ib_device *ibdev = ibcq->device;
|
||||
int entries = attr->cqe;
|
||||
struct pvrdma_dev *dev = to_vdev(ibdev);
|
||||
|
@ -375,7 +375,7 @@ struct ib_mr *pvrdma_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
|
||||
int pvrdma_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg,
|
||||
int sg_nents, unsigned int *sg_offset);
|
||||
int pvrdma_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata);
|
||||
struct uverbs_attr_bundle *attrs);
|
||||
int pvrdma_destroy_cq(struct ib_cq *cq, struct ib_udata *udata);
|
||||
int pvrdma_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc);
|
||||
int pvrdma_req_notify_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags);
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <rdma/uverbs_ioctl.h>
|
||||
#include "cq.h"
|
||||
#include "vt.h"
|
||||
#include "trace.h"
|
||||
@ -149,15 +150,16 @@ static void send_complete(struct work_struct *work)
|
||||
* rvt_create_cq - create a completion queue
|
||||
* @ibcq: Allocated CQ
|
||||
* @attr: creation attributes
|
||||
* @udata: user data for libibverbs.so
|
||||
* @attrs: uverbs bundle
|
||||
*
|
||||
* Called by ib_create_cq() in the generic verbs code.
|
||||
*
|
||||
* Return: 0 on success
|
||||
*/
|
||||
int rvt_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata)
|
||||
struct uverbs_attr_bundle *attrs)
|
||||
{
|
||||
struct ib_udata *udata = &attrs->driver_udata;
|
||||
struct ib_device *ibdev = ibcq->device;
|
||||
struct rvt_dev_info *rdi = ib_to_rvt(ibdev);
|
||||
struct rvt_cq *cq = ibcq_to_rvtcq(ibcq);
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include <rdma/rdmavt_cq.h>
|
||||
|
||||
int rvt_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata);
|
||||
struct uverbs_attr_bundle *attrs);
|
||||
int rvt_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata);
|
||||
int rvt_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags notify_flags);
|
||||
int rvt_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata);
|
||||
|
@ -537,6 +537,7 @@ int rxe_net_add(const char *ibdev_name, struct net_device *ndev)
|
||||
return -ENOMEM;
|
||||
|
||||
rxe->ndev = ndev;
|
||||
ib_mark_name_assigned_by_user(&rxe->ib_dev);
|
||||
|
||||
err = rxe_add(rxe, ndev->mtu, ibdev_name);
|
||||
if (err) {
|
||||
|
@ -424,7 +424,7 @@ static struct sk_buff *init_req_packet(struct rxe_qp *qp,
|
||||
int paylen;
|
||||
int solicited;
|
||||
u32 qp_num;
|
||||
int ack_req;
|
||||
int ack_req = 0;
|
||||
|
||||
/* length from start of bth to end of icrc */
|
||||
paylen = rxe_opcode[opcode].length + payload + pad + RXE_ICRC_SIZE;
|
||||
@ -445,8 +445,9 @@ static struct sk_buff *init_req_packet(struct rxe_qp *qp,
|
||||
qp_num = (pkt->mask & RXE_DETH_MASK) ? ibwr->wr.ud.remote_qpn :
|
||||
qp->attr.dest_qp_num;
|
||||
|
||||
ack_req = ((pkt->mask & RXE_END_MASK) ||
|
||||
(qp->req.noack_pkts++ > RXE_MAX_PKT_PER_ACK));
|
||||
if (qp_type(qp) != IB_QPT_UD && qp_type(qp) != IB_QPT_UC)
|
||||
ack_req = ((pkt->mask & RXE_END_MASK) ||
|
||||
(qp->req.noack_pkts++ > RXE_MAX_PKT_PER_ACK));
|
||||
if (ack_req)
|
||||
qp->req.noack_pkts = 0;
|
||||
|
||||
|
@ -1053,8 +1053,9 @@ static int rxe_post_recv(struct ib_qp *ibqp, const struct ib_recv_wr *wr,
|
||||
|
||||
/* cq */
|
||||
static int rxe_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata)
|
||||
struct uverbs_attr_bundle *attrs)
|
||||
{
|
||||
struct ib_udata *udata = &attrs->driver_udata;
|
||||
struct ib_device *dev = ibcq->device;
|
||||
struct rxe_dev *rxe = to_rdev(dev);
|
||||
struct rxe_cq *cq = to_rcq(ibcq);
|
||||
|
@ -485,6 +485,7 @@ static int siw_newlink(const char *basedev_name, struct net_device *netdev)
|
||||
else
|
||||
sdev->state = IB_PORT_DOWN;
|
||||
|
||||
ib_mark_name_assigned_by_user(&sdev->base_dev);
|
||||
rv = siw_device_register(sdev, basedev_name);
|
||||
if (rv)
|
||||
ib_dealloc_device(&sdev->base_dev);
|
||||
|
@ -1124,12 +1124,13 @@ int siw_destroy_cq(struct ib_cq *base_cq, struct ib_udata *udata)
|
||||
*
|
||||
* @base_cq: CQ as allocated by RDMA midlayer
|
||||
* @attr: Initial CQ attributes
|
||||
* @udata: relates to user context
|
||||
* @attrs: uverbs bundle
|
||||
*/
|
||||
|
||||
int siw_create_cq(struct ib_cq *base_cq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata)
|
||||
struct uverbs_attr_bundle *attrs)
|
||||
{
|
||||
struct ib_udata *udata = &attrs->driver_udata;
|
||||
struct siw_device *sdev = to_siw_dev(base_cq->device);
|
||||
struct siw_cq *cq = to_siw_cq(base_cq);
|
||||
int rv, size = attr->cqe;
|
||||
|
@ -43,7 +43,7 @@ int siw_get_port_immutable(struct ib_device *base_dev, u32 port,
|
||||
int siw_query_device(struct ib_device *base_dev, struct ib_device_attr *attr,
|
||||
struct ib_udata *udata);
|
||||
int siw_create_cq(struct ib_cq *base_cq, const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata);
|
||||
struct uverbs_attr_bundle *attrs);
|
||||
int siw_query_port(struct ib_device *base_dev, u32 port,
|
||||
struct ib_port_attr *attr);
|
||||
int siw_query_gid(struct ib_device *base_dev, u32 port, int idx,
|
||||
|
@ -91,9 +91,6 @@ isert_qp_event_callback(struct ib_event *e, void *context)
|
||||
case IB_EVENT_COMM_EST:
|
||||
rdma_notify(isert_conn->cm_id, IB_EVENT_COMM_EST);
|
||||
break;
|
||||
case IB_EVENT_QP_LAST_WQE_REACHED:
|
||||
isert_warn("Reached TX IB_EVENT_QP_LAST_WQE_REACHED\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ void mlx5_port_query_eth_autoneg(struct mlx5_core_dev *dev, u8 *an_status,
|
||||
*an_disable_cap = 0;
|
||||
*an_disable_admin = 0;
|
||||
|
||||
if (mlx5_query_port_ptys(dev, out, sizeof(out), MLX5_PTYS_EN, 1))
|
||||
if (mlx5_query_port_ptys(dev, out, sizeof(out), MLX5_PTYS_EN, 1, 0))
|
||||
return;
|
||||
|
||||
*an_status = MLX5_GET(ptys_reg, out, an_status);
|
||||
|
@ -1195,7 +1195,7 @@ static int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv,
|
||||
bool ext;
|
||||
int err;
|
||||
|
||||
err = mlx5_query_port_ptys(mdev, out, sizeof(out), MLX5_PTYS_EN, 1);
|
||||
err = mlx5_query_port_ptys(mdev, out, sizeof(out), MLX5_PTYS_EN, 1, 0);
|
||||
if (err) {
|
||||
netdev_err(priv->netdev, "%s: query port ptys failed: %d\n",
|
||||
__func__, err);
|
||||
|
@ -215,7 +215,7 @@ static int mlx5i_get_link_ksettings(struct net_device *netdev,
|
||||
int speed, ret;
|
||||
|
||||
ret = mlx5_query_ib_port_oper(mdev, &ib_link_width_oper, &ib_proto_oper,
|
||||
1);
|
||||
1, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -144,11 +144,13 @@ int mlx5_set_port_caps(struct mlx5_core_dev *dev, u8 port_num, u32 caps)
|
||||
EXPORT_SYMBOL_GPL(mlx5_set_port_caps);
|
||||
|
||||
int mlx5_query_port_ptys(struct mlx5_core_dev *dev, u32 *ptys,
|
||||
int ptys_size, int proto_mask, u8 local_port)
|
||||
int ptys_size, int proto_mask,
|
||||
u8 local_port, u8 plane_index)
|
||||
{
|
||||
u32 in[MLX5_ST_SZ_DW(ptys_reg)] = {0};
|
||||
|
||||
MLX5_SET(ptys_reg, in, local_port, local_port);
|
||||
MLX5_SET(ptys_reg, in, plane_ind, plane_index);
|
||||
MLX5_SET(ptys_reg, in, proto_mask, proto_mask);
|
||||
return mlx5_core_access_reg(dev, in, sizeof(in), ptys,
|
||||
ptys_size, MLX5_REG_PTYS, 0, 0);
|
||||
@ -167,13 +169,13 @@ int mlx5_set_port_beacon(struct mlx5_core_dev *dev, u16 beacon_duration)
|
||||
}
|
||||
|
||||
int mlx5_query_ib_port_oper(struct mlx5_core_dev *dev, u16 *link_width_oper,
|
||||
u16 *proto_oper, u8 local_port)
|
||||
u16 *proto_oper, u8 local_port, u8 plane_index)
|
||||
{
|
||||
u32 out[MLX5_ST_SZ_DW(ptys_reg)];
|
||||
int err;
|
||||
|
||||
err = mlx5_query_port_ptys(dev, out, sizeof(out), MLX5_PTYS_IB,
|
||||
local_port);
|
||||
local_port, plane_index);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -1114,7 +1116,7 @@ int mlx5_port_query_eth_proto(struct mlx5_core_dev *dev, u8 port, bool ext,
|
||||
if (!eproto)
|
||||
return -EINVAL;
|
||||
|
||||
err = mlx5_query_port_ptys(dev, out, sizeof(out), MLX5_PTYS_EN, port);
|
||||
err = mlx5_query_port_ptys(dev, out, sizeof(out), MLX5_PTYS_EN, port, 0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -737,6 +737,7 @@ int mlx5_query_hca_vport_context(struct mlx5_core_dev *dev,
|
||||
rep->grh_required = MLX5_GET_PR(hca_vport_context, ctx, grh_required);
|
||||
rep->sys_image_guid = MLX5_GET64_PR(hca_vport_context, ctx,
|
||||
system_image_guid);
|
||||
rep->num_plane = MLX5_GET_PR(hca_vport_context, ctx, num_port_plane);
|
||||
|
||||
ex:
|
||||
kvfree(out);
|
||||
|
@ -380,6 +380,7 @@ static void mana_gd_process_eqe(struct gdma_queue *eq)
|
||||
case GDMA_EQE_HWC_INIT_EQ_ID_DB:
|
||||
case GDMA_EQE_HWC_INIT_DATA:
|
||||
case GDMA_EQE_HWC_INIT_DONE:
|
||||
case GDMA_EQE_RNIC_QP_FATAL:
|
||||
if (!eq->eq.callback)
|
||||
break;
|
||||
|
||||
|
@ -3007,3 +3007,22 @@ out:
|
||||
gd->gdma_context = NULL;
|
||||
kfree(ac);
|
||||
}
|
||||
|
||||
struct net_device *mana_get_primary_netdev_rcu(struct mana_context *ac, u32 port_index)
|
||||
{
|
||||
struct net_device *ndev;
|
||||
|
||||
RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
|
||||
"Taking primary netdev without holding the RCU read lock");
|
||||
if (port_index >= ac->num_ports)
|
||||
return NULL;
|
||||
|
||||
/* When mana is used in netvsc, the upper netdevice should be returned. */
|
||||
if (ac->ports[port_index]->flags & IFF_SLAVE)
|
||||
ndev = netdev_master_upper_dev_get_rcu(ac->ports[port_index]);
|
||||
else
|
||||
ndev = ac->ports[port_index];
|
||||
|
||||
return ndev;
|
||||
}
|
||||
EXPORT_SYMBOL_NS(mana_get_primary_netdev_rcu, NET_MANA);
|
||||
|
@ -1467,6 +1467,7 @@ enum {
|
||||
MLX5_PER_TRAFFIC_CLASS_CONGESTION_GROUP = 0x13,
|
||||
MLX5_PHYSICAL_LAYER_STATISTICAL_GROUP = 0x16,
|
||||
MLX5_INFINIBAND_PORT_COUNTERS_GROUP = 0x20,
|
||||
MLX5_INFINIBAND_EXTENDED_PORT_COUNTERS_GROUP = 0x21,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -917,6 +917,7 @@ struct mlx5_hca_vport_context {
|
||||
u16 qkey_violation_counter;
|
||||
u16 pkey_violation_counter;
|
||||
bool grh_required;
|
||||
u8 num_plane;
|
||||
};
|
||||
|
||||
#define STRUCT_FIELD(header, field) \
|
||||
|
@ -793,7 +793,7 @@ struct mlx5_ifc_ads_bits {
|
||||
u8 reserved_at_2[0xe];
|
||||
u8 pkey_index[0x10];
|
||||
|
||||
u8 reserved_at_20[0x8];
|
||||
u8 plane_index[0x8];
|
||||
u8 grh[0x1];
|
||||
u8 mlid[0x7];
|
||||
u8 rlid[0x10];
|
||||
@ -1992,7 +1992,8 @@ struct mlx5_ifc_cmd_hca_cap_2_bits {
|
||||
u8 reserved_at_c0[0x8];
|
||||
u8 migration_multi_load[0x1];
|
||||
u8 migration_tracking_state[0x1];
|
||||
u8 reserved_at_ca[0x6];
|
||||
u8 multiplane_qp_ud[0x1];
|
||||
u8 reserved_at_cb[0x5];
|
||||
u8 migration_in_chunks[0x1];
|
||||
u8 reserved_at_d1[0x1];
|
||||
u8 sf_eq_usage[0x1];
|
||||
@ -2663,6 +2664,46 @@ struct mlx5_ifc_ib_port_cntrs_grp_data_layout_bits {
|
||||
u8 port_xmit_wait[0x20];
|
||||
};
|
||||
|
||||
struct mlx5_ifc_ib_ext_port_cntrs_grp_data_layout_bits {
|
||||
u8 reserved_at_0[0x300];
|
||||
|
||||
u8 port_xmit_data_high[0x20];
|
||||
|
||||
u8 port_xmit_data_low[0x20];
|
||||
|
||||
u8 port_rcv_data_high[0x20];
|
||||
|
||||
u8 port_rcv_data_low[0x20];
|
||||
|
||||
u8 port_xmit_pkts_high[0x20];
|
||||
|
||||
u8 port_xmit_pkts_low[0x20];
|
||||
|
||||
u8 port_rcv_pkts_high[0x20];
|
||||
|
||||
u8 port_rcv_pkts_low[0x20];
|
||||
|
||||
u8 reserved_at_400[0x80];
|
||||
|
||||
u8 port_unicast_xmit_pkts_high[0x20];
|
||||
|
||||
u8 port_unicast_xmit_pkts_low[0x20];
|
||||
|
||||
u8 port_multicast_xmit_pkts_high[0x20];
|
||||
|
||||
u8 port_multicast_xmit_pkts_low[0x20];
|
||||
|
||||
u8 port_unicast_rcv_pkts_high[0x20];
|
||||
|
||||
u8 port_unicast_rcv_pkts_low[0x20];
|
||||
|
||||
u8 port_multicast_rcv_pkts_high[0x20];
|
||||
|
||||
u8 port_multicast_rcv_pkts_low[0x20];
|
||||
|
||||
u8 reserved_at_580[0x240];
|
||||
};
|
||||
|
||||
struct mlx5_ifc_eth_per_tc_prio_grp_data_layout_bits {
|
||||
u8 transmit_queue_high[0x20];
|
||||
|
||||
@ -4185,7 +4226,8 @@ struct mlx5_ifc_hca_vport_context_bits {
|
||||
u8 has_smi[0x1];
|
||||
u8 has_raw[0x1];
|
||||
u8 grh_required[0x1];
|
||||
u8 reserved_at_104[0xc];
|
||||
u8 reserved_at_104[0x4];
|
||||
u8 num_port_plane[0x8];
|
||||
u8 port_physical_state[0x4];
|
||||
u8 vport_state_policy[0x4];
|
||||
u8 port_state[0x4];
|
||||
@ -4554,6 +4596,7 @@ union mlx5_ifc_eth_cntrs_grp_data_layout_auto_bits {
|
||||
struct mlx5_ifc_eth_per_tc_prio_grp_data_layout_bits eth_per_tc_prio_grp_data_layout;
|
||||
struct mlx5_ifc_eth_per_tc_congest_prio_grp_data_layout_bits eth_per_tc_congest_prio_grp_data_layout;
|
||||
struct mlx5_ifc_ib_port_cntrs_grp_data_layout_bits ib_port_cntrs_grp_data_layout;
|
||||
struct mlx5_ifc_ib_ext_port_cntrs_grp_data_layout_bits ib_ext_port_cntrs_grp_data_layout;
|
||||
struct mlx5_ifc_phys_layer_cntrs_bits phys_layer_cntrs;
|
||||
struct mlx5_ifc_phys_layer_statistical_cntrs_bits phys_layer_statistical_cntrs;
|
||||
u8 reserved_at_0[0x7c0];
|
||||
@ -7705,7 +7748,7 @@ struct mlx5_ifc_mad_ifc_in_bits {
|
||||
u8 op_mod[0x10];
|
||||
|
||||
u8 remote_lid[0x10];
|
||||
u8 reserved_at_50[0x8];
|
||||
u8 plane_index[0x8];
|
||||
u8 port[0x8];
|
||||
|
||||
u8 reserved_at_60[0x20];
|
||||
@ -9634,7 +9677,9 @@ struct mlx5_ifc_ptys_reg_bits {
|
||||
u8 an_disable_cap[0x1];
|
||||
u8 reserved_at_3[0x5];
|
||||
u8 local_port[0x8];
|
||||
u8 reserved_at_10[0xd];
|
||||
u8 reserved_at_10[0x8];
|
||||
u8 plane_ind[0x4];
|
||||
u8 reserved_at_1c[0x1];
|
||||
u8 proto_mask[0x3];
|
||||
|
||||
u8 an_status[0x4];
|
||||
@ -9860,8 +9905,10 @@ struct mlx5_ifc_ppcnt_reg_bits {
|
||||
u8 grp[0x6];
|
||||
|
||||
u8 clr[0x1];
|
||||
u8 reserved_at_21[0x1c];
|
||||
u8 prio_tc[0x3];
|
||||
u8 reserved_at_21[0x13];
|
||||
u8 plane_ind[0x4];
|
||||
u8 reserved_at_38[0x3];
|
||||
u8 prio_tc[0x5];
|
||||
|
||||
union mlx5_ifc_eth_cntrs_grp_data_layout_auto_bits counter_set;
|
||||
};
|
||||
|
@ -155,10 +155,11 @@ struct mlx5_port_eth_proto {
|
||||
|
||||
int mlx5_set_port_caps(struct mlx5_core_dev *dev, u8 port_num, u32 caps);
|
||||
int mlx5_query_port_ptys(struct mlx5_core_dev *dev, u32 *ptys,
|
||||
int ptys_size, int proto_mask, u8 local_port);
|
||||
int ptys_size, int proto_mask,
|
||||
u8 local_port, u8 plane_index);
|
||||
|
||||
int mlx5_query_ib_port_oper(struct mlx5_core_dev *dev, u16 *link_width_oper,
|
||||
u16 *proto_oper, u8 local_port);
|
||||
u16 *proto_oper, u8 local_port, u8 plane_index);
|
||||
void mlx5_toggle_port_link(struct mlx5_core_dev *dev);
|
||||
int mlx5_set_port_admin_status(struct mlx5_core_dev *dev,
|
||||
enum mlx5_port_status status);
|
||||
|
@ -576,9 +576,12 @@ static inline const char *mlx5_qp_state_str(int state)
|
||||
|
||||
static inline int mlx5_get_qp_default_ts(struct mlx5_core_dev *dev)
|
||||
{
|
||||
return !MLX5_CAP_ROCE(dev, qp_ts_format) ?
|
||||
MLX5_TIMESTAMP_FORMAT_FREE_RUNNING :
|
||||
MLX5_TIMESTAMP_FORMAT_DEFAULT;
|
||||
u8 supported_ts_cap = mlx5_get_roce_state(dev) ?
|
||||
MLX5_CAP_ROCE(dev, qp_ts_format) :
|
||||
MLX5_CAP_GEN(dev, sq_ts_format);
|
||||
|
||||
return supported_ts_cap ? MLX5_TIMESTAMP_FORMAT_DEFAULT :
|
||||
MLX5_TIMESTAMP_FORMAT_FREE_RUNNING;
|
||||
}
|
||||
|
||||
#endif /* MLX5_QP_H */
|
||||
|
@ -60,6 +60,7 @@ enum gdma_eqe_type {
|
||||
GDMA_EQE_HWC_INIT_DONE = 131,
|
||||
GDMA_EQE_HWC_SOC_RECONFIG = 132,
|
||||
GDMA_EQE_HWC_SOC_RECONFIG_DATA = 133,
|
||||
GDMA_EQE_RNIC_QP_FATAL = 176,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -798,4 +798,6 @@ void mana_destroy_wq_obj(struct mana_port_context *apc, u32 wq_type,
|
||||
int mana_cfg_vport(struct mana_port_context *apc, u32 protection_dom_id,
|
||||
u32 doorbell_pg_id);
|
||||
void mana_uncfg_vport(struct mana_port_context *apc);
|
||||
|
||||
struct net_device *mana_get_primary_netdev_rcu(struct mana_context *ac, u32 port_index);
|
||||
#endif /* _MANA_H */
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user