mirror of https://gitee.com/openkylin/linux.git
RDMA subsystem updates for 5.4
This cycle mainly saw lots of bug fixes and clean up code across the core code and several drivers, few new functional changes were made. - Many cleanup and bug fixes for hns - Various small bug fixes and cleanups in hfi1, mlx5, usnic, qed, bnxt_re, efa - Share the query_port code between all the iWarp drivers - General rework and cleanup of the ODP MR umem code to fit better with the mmu notifier get/put scheme - Support rdma netlink in non init_net name spaces - mlx5 support for XRC devx and DC ODP -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEfB7FMLh+8QxL+6i3OG33FX4gmxoFAl2A1ugACgkQOG33FX4g mxp+EQ//Ug8CyyDs40SGZztItoGghuQ4TVA2pXtuZ9LkFVJRWhYPJGOadHIYXqGO KQJJpZPQ02HTZUPWBZNKmD5bwHfErm4cS73/mVmUpximnUqu/UsLRJp8SIGmBg1D W1Lz1BJX24MdV8aUnChYvdL5Hbl52q+BaE99Z0haOvW7I3YnKJC34mR8m/A5MiRf rsNIZNPHdq2U6pKLgCbOyXib8yBcJQqBb8x4WNAoB1h4MOx+ir5QLfr3ozrZs1an xXgqyiOBmtkUgCMIpXC4juPN/6gw3Y5nkk2VIWY+MAY1a7jZPbI+6LJZZ1Uk8R44 Lf2KSzabFMMYGKJYE1Znxk+JWV8iE+m+n6wWEfRM9l0b4gXXbrtKgaouFbsLcsQA CvBEQuiFSO9Kq01JPaAN1XDmhqyTarG6lHjXnW7ifNlLXnPbR1RJlprycExOhp0c axum5K2fRNW2+uZJt+zynMjk2kyjT1lnlsr1Rbgc4Pyionaiydg7zwpiac7y/bdS F7/WqdmPiff78KMi187EF5pjFqMWhthvBtTbWDuuxaxc2nrXSdiCUN+96j1amQUH yU/7AZzlnKeKEQQCR4xddsSs2eTrXiLLFRLk9GCK2eh4cUN212eHTrPLKkQf1cN+ ydYbR2pxw3B38LCCNBy+bL+u7e/Tyehs4ynATMpBuEgc5iocTwE= =zHXW -----END PGP SIGNATURE----- Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma Pull RDMA subsystem updates from Jason Gunthorpe: "This cycle mainly saw lots of bug fixes and clean up code across the core code and several drivers, few new functional changes were made. - Many cleanup and bug fixes for hns - Various small bug fixes and cleanups in hfi1, mlx5, usnic, qed, bnxt_re, efa - Share the query_port code between all the iWarp drivers - General rework and cleanup of the ODP MR umem code to fit better with the mmu notifier get/put scheme - Support rdma netlink in non init_net name spaces - mlx5 support for XRC devx and DC ODP" * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: (99 commits) RDMA: Fix double-free in srq creation error flow RDMA/efa: Fix incorrect error print IB/mlx5: Free mpi in mp_slave mode IB/mlx5: Use the original address for the page during free_pages RDMA/bnxt_re: Fix spelling mistake "missin_resp" -> "missing_resp" RDMA/hns: Package operations of rq inline buffer into separate functions RDMA/hns: Optimize cmd init and mode selection for hip08 IB/hfi1: Define variables as unsigned long to fix KASAN warning IB/{rdmavt, hfi1, qib}: Add a counter for credit waits IB/hfi1: Add traces for TID RDMA READ RDMA/siw: Relax from kmap_atomic() use in TX path IB/iser: Support up to 16MB data transfer in a single command RDMA/siw: Fix page address mapping in TX path RDMA: Fix goto target to release the allocated memory RDMA/usnic: Avoid overly large buffers on stack RDMA/odp: Add missing cast for 32 bit RDMA/hns: Use devm_platform_ioremap_resource() to simplify code Documentation/infiniband: update name of some functions RDMA/cma: Fix false error message RDMA/hns: Fix wrong assignment of qp_access_flags ...
This commit is contained in:
commit
018c6837f3
|
@ -29,10 +29,10 @@ Sleeping and interrupt context
|
|||
The corresponding functions exported to upper level protocol
|
||||
consumers:
|
||||
|
||||
- ib_create_ah
|
||||
- ib_modify_ah
|
||||
- ib_query_ah
|
||||
- ib_destroy_ah
|
||||
- rdma_create_ah
|
||||
- rdma_modify_ah
|
||||
- rdma_query_ah
|
||||
- rdma_destroy_ah
|
||||
- ib_post_send
|
||||
- ib_post_recv
|
||||
- ib_req_notify_cq
|
||||
|
|
|
@ -183,7 +183,7 @@ static int ib_nl_ip_send_msg(struct rdma_dev_addr *dev_addr,
|
|||
|
||||
/* Repair the nlmsg header length */
|
||||
nlmsg_end(skb, nlh);
|
||||
rdma_nl_multicast(skb, RDMA_NL_GROUP_LS, GFP_KERNEL);
|
||||
rdma_nl_multicast(&init_net, skb, RDMA_NL_GROUP_LS, GFP_KERNEL);
|
||||
|
||||
/* Make the request retry, so when we get the response from userspace
|
||||
* we will have something.
|
||||
|
|
|
@ -810,6 +810,7 @@ static void release_gid_table(struct ib_device *device,
|
|||
if (leak)
|
||||
return;
|
||||
|
||||
mutex_destroy(&table->lock);
|
||||
kfree(table->data_vec);
|
||||
kfree(table);
|
||||
}
|
||||
|
|
|
@ -3046,7 +3046,7 @@ static void addr_handler(int status, struct sockaddr *src_addr,
|
|||
if (status)
|
||||
pr_debug_ratelimited("RDMA CM: ADDR_ERROR: failed to acquire device. status %d\n",
|
||||
status);
|
||||
} else {
|
||||
} else if (status) {
|
||||
pr_debug_ratelimited("RDMA CM: ADDR_ERROR: failed to resolve IP. status %d\n", status);
|
||||
}
|
||||
|
||||
|
|
|
@ -342,12 +342,18 @@ static struct configfs_subsystem cma_subsys = {
|
|||
|
||||
int __init cma_configfs_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
config_group_init(&cma_subsys.su_group);
|
||||
mutex_init(&cma_subsys.su_mutex);
|
||||
return configfs_register_subsystem(&cma_subsys);
|
||||
ret = configfs_register_subsystem(&cma_subsys);
|
||||
if (ret)
|
||||
mutex_destroy(&cma_subsys.su_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void __exit cma_configfs_exit(void)
|
||||
{
|
||||
configfs_unregister_subsystem(&cma_subsys);
|
||||
mutex_destroy(&cma_subsys.su_mutex);
|
||||
}
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
#include <linux/list.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/cgroup_rdma.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <net/netns/generic.h>
|
||||
|
||||
#include <rdma/ib_verbs.h>
|
||||
#include <rdma/opa_addr.h>
|
||||
|
@ -54,8 +56,26 @@ struct pkey_index_qp_list {
|
|||
struct list_head qp_list;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct rdma_dev_net - rdma net namespace metadata for a net
|
||||
* @nl_sock: Pointer to netlink socket
|
||||
* @net: Pointer to owner net namespace
|
||||
* @id: xarray id to identify the net namespace.
|
||||
*/
|
||||
struct rdma_dev_net {
|
||||
struct sock *nl_sock;
|
||||
possible_net_t net;
|
||||
u32 id;
|
||||
};
|
||||
|
||||
extern const struct attribute_group ib_dev_attr_group;
|
||||
extern bool ib_devices_shared_netns;
|
||||
extern unsigned int rdma_dev_net_id;
|
||||
|
||||
static inline struct rdma_dev_net *rdma_net_to_dev_net(struct net *net)
|
||||
{
|
||||
return net_generic(net, rdma_dev_net_id);
|
||||
}
|
||||
|
||||
int ib_device_register_sysfs(struct ib_device *device);
|
||||
void ib_device_unregister_sysfs(struct ib_device *device);
|
||||
|
@ -179,7 +199,6 @@ void ib_mad_cleanup(void);
|
|||
int ib_sa_init(void);
|
||||
void ib_sa_cleanup(void);
|
||||
|
||||
int rdma_nl_init(void);
|
||||
void rdma_nl_exit(void);
|
||||
|
||||
int ib_nl_handle_resolve_resp(struct sk_buff *skb,
|
||||
|
@ -365,4 +384,7 @@ void ib_port_unregister_module_stat(struct kobject *kobj);
|
|||
|
||||
int ib_device_set_netns_put(struct sk_buff *skb,
|
||||
struct ib_device *dev, u32 ns_fd);
|
||||
|
||||
int rdma_nl_net_init(struct rdma_dev_net *rnet);
|
||||
void rdma_nl_net_exit(struct rdma_dev_net *rnet);
|
||||
#endif /* _CORE_PRIV_H */
|
||||
|
|
|
@ -599,7 +599,7 @@ int rdma_counter_get_mode(struct ib_device *dev, u8 port,
|
|||
void rdma_counter_init(struct ib_device *dev)
|
||||
{
|
||||
struct rdma_port_counter *port_counter;
|
||||
u32 port;
|
||||
u32 port, i;
|
||||
|
||||
if (!dev->port_data)
|
||||
return;
|
||||
|
@ -620,13 +620,12 @@ void rdma_counter_init(struct ib_device *dev)
|
|||
return;
|
||||
|
||||
fail:
|
||||
rdma_for_each_port(dev, port) {
|
||||
for (i = port; i >= rdma_start_port(dev); i--) {
|
||||
port_counter = &dev->port_data[port].port_counter;
|
||||
kfree(port_counter->hstats);
|
||||
port_counter->hstats = NULL;
|
||||
mutex_destroy(&port_counter->lock);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void rdma_counter_release(struct ib_device *dev)
|
||||
|
@ -637,5 +636,6 @@ void rdma_counter_release(struct ib_device *dev)
|
|||
rdma_for_each_port(dev, port) {
|
||||
port_counter = &dev->port_data[port].port_counter;
|
||||
kfree(port_counter->hstats);
|
||||
mutex_destroy(&port_counter->lock);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -252,6 +252,34 @@ struct ib_cq *__ib_alloc_cq_user(struct ib_device *dev, void *private,
|
|||
}
|
||||
EXPORT_SYMBOL(__ib_alloc_cq_user);
|
||||
|
||||
/**
|
||||
* __ib_alloc_cq_any - allocate a completion queue
|
||||
* @dev: device to allocate the CQ for
|
||||
* @private: driver private data, accessible from cq->cq_context
|
||||
* @nr_cqe: number of CQEs to allocate
|
||||
* @poll_ctx: context to poll the CQ from
|
||||
* @caller: module owner name
|
||||
*
|
||||
* Attempt to spread ULP Completion Queues over each device's interrupt
|
||||
* vectors. A simple best-effort mechanism is used.
|
||||
*/
|
||||
struct ib_cq *__ib_alloc_cq_any(struct ib_device *dev, void *private,
|
||||
int nr_cqe, enum ib_poll_context poll_ctx,
|
||||
const char *caller)
|
||||
{
|
||||
static atomic_t counter;
|
||||
int comp_vector = 0;
|
||||
|
||||
if (dev->num_comp_vectors > 1)
|
||||
comp_vector =
|
||||
atomic_inc_return(&counter) %
|
||||
min_t(int, dev->num_comp_vectors, num_online_cpus());
|
||||
|
||||
return __ib_alloc_cq_user(dev, private, nr_cqe, comp_vector, poll_ctx,
|
||||
caller, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL(__ib_alloc_cq_any);
|
||||
|
||||
/**
|
||||
* ib_free_cq_user - free a completion queue
|
||||
* @cq: completion queue to free.
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <net/netns/generic.h>
|
||||
#include <linux/security.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/hashtable.h>
|
||||
|
@ -111,17 +110,7 @@ static void ib_client_put(struct ib_client *client)
|
|||
*/
|
||||
#define CLIENT_DATA_REGISTERED XA_MARK_1
|
||||
|
||||
/**
|
||||
* struct rdma_dev_net - rdma net namespace metadata for a net
|
||||
* @net: Pointer to owner net namespace
|
||||
* @id: xarray id to identify the net namespace.
|
||||
*/
|
||||
struct rdma_dev_net {
|
||||
possible_net_t net;
|
||||
u32 id;
|
||||
};
|
||||
|
||||
static unsigned int rdma_dev_net_id;
|
||||
unsigned int rdma_dev_net_id;
|
||||
|
||||
/*
|
||||
* A list of net namespaces is maintained in an xarray. This is necessary
|
||||
|
@ -514,6 +503,9 @@ static void ib_device_release(struct device *device)
|
|||
rcu_head);
|
||||
}
|
||||
|
||||
mutex_destroy(&dev->unregistration_lock);
|
||||
mutex_destroy(&dev->compat_devs_mutex);
|
||||
|
||||
xa_destroy(&dev->compat_devs);
|
||||
xa_destroy(&dev->client_data);
|
||||
kfree_rcu(dev, rcu_head);
|
||||
|
@ -1060,7 +1052,7 @@ int rdma_compatdev_set(u8 enable)
|
|||
|
||||
static void rdma_dev_exit_net(struct net *net)
|
||||
{
|
||||
struct rdma_dev_net *rnet = net_generic(net, rdma_dev_net_id);
|
||||
struct rdma_dev_net *rnet = rdma_net_to_dev_net(net);
|
||||
struct ib_device *dev;
|
||||
unsigned long index;
|
||||
int ret;
|
||||
|
@ -1094,25 +1086,32 @@ static void rdma_dev_exit_net(struct net *net)
|
|||
}
|
||||
up_read(&devices_rwsem);
|
||||
|
||||
rdma_nl_net_exit(rnet);
|
||||
xa_erase(&rdma_nets, rnet->id);
|
||||
}
|
||||
|
||||
static __net_init int rdma_dev_init_net(struct net *net)
|
||||
{
|
||||
struct rdma_dev_net *rnet = net_generic(net, rdma_dev_net_id);
|
||||
struct rdma_dev_net *rnet = rdma_net_to_dev_net(net);
|
||||
unsigned long index;
|
||||
struct ib_device *dev;
|
||||
int ret;
|
||||
|
||||
write_pnet(&rnet->net, net);
|
||||
|
||||
ret = rdma_nl_net_init(rnet);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* No need to create any compat devices in default init_net. */
|
||||
if (net_eq(net, &init_net))
|
||||
return 0;
|
||||
|
||||
write_pnet(&rnet->net, net);
|
||||
|
||||
ret = xa_alloc(&rdma_nets, &rnet->id, rnet, xa_limit_32b, GFP_KERNEL);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
rdma_nl_net_exit(rnet);
|
||||
return ret;
|
||||
}
|
||||
|
||||
down_read(&devices_rwsem);
|
||||
xa_for_each_marked (&devices, index, dev, DEVICE_REGISTERED) {
|
||||
|
@ -1974,6 +1973,74 @@ void ib_dispatch_event(struct ib_event *event)
|
|||
}
|
||||
EXPORT_SYMBOL(ib_dispatch_event);
|
||||
|
||||
static int iw_query_port(struct ib_device *device,
|
||||
u8 port_num,
|
||||
struct ib_port_attr *port_attr)
|
||||
{
|
||||
struct in_device *inetdev;
|
||||
struct net_device *netdev;
|
||||
int err;
|
||||
|
||||
memset(port_attr, 0, sizeof(*port_attr));
|
||||
|
||||
netdev = ib_device_get_netdev(device, port_num);
|
||||
if (!netdev)
|
||||
return -ENODEV;
|
||||
|
||||
dev_put(netdev);
|
||||
|
||||
port_attr->max_mtu = IB_MTU_4096;
|
||||
port_attr->active_mtu = ib_mtu_int_to_enum(netdev->mtu);
|
||||
|
||||
if (!netif_carrier_ok(netdev)) {
|
||||
port_attr->state = IB_PORT_DOWN;
|
||||
port_attr->phys_state = IB_PORT_PHYS_STATE_DISABLED;
|
||||
} else {
|
||||
inetdev = in_dev_get(netdev);
|
||||
|
||||
if (inetdev && inetdev->ifa_list) {
|
||||
port_attr->state = IB_PORT_ACTIVE;
|
||||
port_attr->phys_state = IB_PORT_PHYS_STATE_LINK_UP;
|
||||
in_dev_put(inetdev);
|
||||
} else {
|
||||
port_attr->state = IB_PORT_INIT;
|
||||
port_attr->phys_state =
|
||||
IB_PORT_PHYS_STATE_PORT_CONFIGURATION_TRAINING;
|
||||
}
|
||||
}
|
||||
|
||||
err = device->ops.query_port(device, port_num, port_attr);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __ib_query_port(struct ib_device *device,
|
||||
u8 port_num,
|
||||
struct ib_port_attr *port_attr)
|
||||
{
|
||||
union ib_gid gid = {};
|
||||
int err;
|
||||
|
||||
memset(port_attr, 0, sizeof(*port_attr));
|
||||
|
||||
err = device->ops.query_port(device, port_num, port_attr);
|
||||
if (err || port_attr->subnet_prefix)
|
||||
return err;
|
||||
|
||||
if (rdma_port_get_link_layer(device, port_num) !=
|
||||
IB_LINK_LAYER_INFINIBAND)
|
||||
return 0;
|
||||
|
||||
err = device->ops.query_gid(device, port_num, 0, &gid);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
port_attr->subnet_prefix = be64_to_cpu(gid.global.subnet_prefix);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ib_query_port - Query IB port attributes
|
||||
* @device:Device to query
|
||||
|
@ -1987,26 +2054,13 @@ int ib_query_port(struct ib_device *device,
|
|||
u8 port_num,
|
||||
struct ib_port_attr *port_attr)
|
||||
{
|
||||
union ib_gid gid;
|
||||
int err;
|
||||
|
||||
if (!rdma_is_port_valid(device, port_num))
|
||||
return -EINVAL;
|
||||
|
||||
memset(port_attr, 0, sizeof(*port_attr));
|
||||
err = device->ops.query_port(device, port_num, port_attr);
|
||||
if (err || port_attr->subnet_prefix)
|
||||
return err;
|
||||
|
||||
if (rdma_port_get_link_layer(device, port_num) != IB_LINK_LAYER_INFINIBAND)
|
||||
return 0;
|
||||
|
||||
err = device->ops.query_gid(device, port_num, 0, &gid);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
port_attr->subnet_prefix = be64_to_cpu(gid.global.subnet_prefix);
|
||||
return 0;
|
||||
if (rdma_protocol_iwarp(device, port_num))
|
||||
return iw_query_port(device, port_num, port_attr);
|
||||
else
|
||||
return __ib_query_port(device, port_num, port_attr);
|
||||
}
|
||||
EXPORT_SYMBOL(ib_query_port);
|
||||
|
||||
|
@ -2661,12 +2715,6 @@ static int __init ib_core_init(void)
|
|||
goto err_comp_unbound;
|
||||
}
|
||||
|
||||
ret = rdma_nl_init();
|
||||
if (ret) {
|
||||
pr_warn("Couldn't init IB netlink interface: err %d\n", ret);
|
||||
goto err_sysfs;
|
||||
}
|
||||
|
||||
ret = addr_init();
|
||||
if (ret) {
|
||||
pr_warn("Could't init IB address resolution\n");
|
||||
|
@ -2712,8 +2760,6 @@ static int __init ib_core_init(void)
|
|||
err_addr:
|
||||
addr_cleanup();
|
||||
err_ibnl:
|
||||
rdma_nl_exit();
|
||||
err_sysfs:
|
||||
class_unregister(&ib_class);
|
||||
err_comp_unbound:
|
||||
destroy_workqueue(ib_comp_unbound_wq);
|
||||
|
|
|
@ -148,13 +148,6 @@ static void ib_fmr_batch_release(struct ib_fmr_pool *pool)
|
|||
hlist_del_init(&fmr->cache_node);
|
||||
fmr->remap_count = 0;
|
||||
list_add_tail(&fmr->fmr->list, &fmr_list);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (fmr->ref_count !=0) {
|
||||
pr_warn(PFX "Unmapping FMR 0x%08x with ref count %d\n",
|
||||
fmr, fmr->ref_count);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
list_splice_init(&pool->dirty_list, &unmap_list);
|
||||
|
@ -496,12 +489,6 @@ void ib_fmr_pool_unmap(struct ib_pool_fmr *fmr)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (fmr->ref_count < 0)
|
||||
pr_warn(PFX "FMR %p has ref count %d < 0\n",
|
||||
fmr, fmr->ref_count);
|
||||
#endif
|
||||
|
||||
spin_unlock_irqrestore(&pool->pool_lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL(ib_fmr_pool_unmap);
|
||||
|
|
|
@ -112,7 +112,7 @@ int iwpm_register_pid(struct iwpm_dev_data *pm_msg, u8 nl_client)
|
|||
pr_debug("%s: Multicasting a nlmsg (dev = %s ifname = %s iwpm = %s)\n",
|
||||
__func__, pm_msg->dev_name, pm_msg->if_name, iwpm_ulib_name);
|
||||
|
||||
ret = rdma_nl_multicast(skb, RDMA_NL_GROUP_IWPM, GFP_KERNEL);
|
||||
ret = rdma_nl_multicast(&init_net, skb, RDMA_NL_GROUP_IWPM, GFP_KERNEL);
|
||||
if (ret) {
|
||||
skb = NULL; /* skb is freed in the netlink send-op handling */
|
||||
iwpm_user_pid = IWPM_PID_UNAVAILABLE;
|
||||
|
@ -124,8 +124,7 @@ int iwpm_register_pid(struct iwpm_dev_data *pm_msg, u8 nl_client)
|
|||
return ret;
|
||||
pid_query_error:
|
||||
pr_info("%s: %s (client = %d)\n", __func__, err_str, nl_client);
|
||||
if (skb)
|
||||
dev_kfree_skb(skb);
|
||||
dev_kfree_skb(skb);
|
||||
if (nlmsg_request)
|
||||
iwpm_free_nlmsg_request(&nlmsg_request->kref);
|
||||
return ret;
|
||||
|
@ -202,7 +201,7 @@ int iwpm_add_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client)
|
|||
nlmsg_end(skb, nlh);
|
||||
nlmsg_request->req_buffer = pm_msg;
|
||||
|
||||
ret = rdma_nl_unicast_wait(skb, iwpm_user_pid);
|
||||
ret = rdma_nl_unicast_wait(&init_net, skb, iwpm_user_pid);
|
||||
if (ret) {
|
||||
skb = NULL; /* skb is freed in the netlink send-op handling */
|
||||
iwpm_user_pid = IWPM_PID_UNDEFINED;
|
||||
|
@ -214,8 +213,7 @@ int iwpm_add_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client)
|
|||
add_mapping_error:
|
||||
pr_info("%s: %s (client = %d)\n", __func__, err_str, nl_client);
|
||||
add_mapping_error_nowarn:
|
||||
if (skb)
|
||||
dev_kfree_skb(skb);
|
||||
dev_kfree_skb(skb);
|
||||
if (nlmsg_request)
|
||||
iwpm_free_nlmsg_request(&nlmsg_request->kref);
|
||||
return ret;
|
||||
|
@ -297,7 +295,7 @@ int iwpm_add_and_query_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client)
|
|||
nlmsg_end(skb, nlh);
|
||||
nlmsg_request->req_buffer = pm_msg;
|
||||
|
||||
ret = rdma_nl_unicast_wait(skb, iwpm_user_pid);
|
||||
ret = rdma_nl_unicast_wait(&init_net, skb, iwpm_user_pid);
|
||||
if (ret) {
|
||||
skb = NULL; /* skb is freed in the netlink send-op handling */
|
||||
err_str = "Unable to send a nlmsg";
|
||||
|
@ -308,8 +306,7 @@ int iwpm_add_and_query_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client)
|
|||
query_mapping_error:
|
||||
pr_info("%s: %s (client = %d)\n", __func__, err_str, nl_client);
|
||||
query_mapping_error_nowarn:
|
||||
if (skb)
|
||||
dev_kfree_skb(skb);
|
||||
dev_kfree_skb(skb);
|
||||
if (nlmsg_request)
|
||||
iwpm_free_nlmsg_request(&nlmsg_request->kref);
|
||||
return ret;
|
||||
|
@ -364,7 +361,7 @@ int iwpm_remove_mapping(struct sockaddr_storage *local_addr, u8 nl_client)
|
|||
|
||||
nlmsg_end(skb, nlh);
|
||||
|
||||
ret = rdma_nl_unicast_wait(skb, iwpm_user_pid);
|
||||
ret = rdma_nl_unicast_wait(&init_net, skb, iwpm_user_pid);
|
||||
if (ret) {
|
||||
skb = NULL; /* skb is freed in the netlink send-op handling */
|
||||
iwpm_user_pid = IWPM_PID_UNDEFINED;
|
||||
|
|
|
@ -645,7 +645,7 @@ static int send_mapinfo_num(u32 mapping_num, u8 nl_client, int iwpm_pid)
|
|||
|
||||
nlmsg_end(skb, nlh);
|
||||
|
||||
ret = rdma_nl_unicast(skb, iwpm_pid);
|
||||
ret = rdma_nl_unicast(&init_net, skb, iwpm_pid);
|
||||
if (ret) {
|
||||
skb = NULL;
|
||||
err_str = "Unable to send a nlmsg";
|
||||
|
@ -655,8 +655,7 @@ static int send_mapinfo_num(u32 mapping_num, u8 nl_client, int iwpm_pid)
|
|||
return 0;
|
||||
mapinfo_num_error:
|
||||
pr_info("%s: %s\n", __func__, err_str);
|
||||
if (skb)
|
||||
dev_kfree_skb(skb);
|
||||
dev_kfree_skb(skb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -674,7 +673,7 @@ static int send_nlmsg_done(struct sk_buff *skb, u8 nl_client, int iwpm_pid)
|
|||
return -ENOMEM;
|
||||
}
|
||||
nlh->nlmsg_type = NLMSG_DONE;
|
||||
ret = rdma_nl_unicast(skb, iwpm_pid);
|
||||
ret = rdma_nl_unicast(&init_net, skb, iwpm_pid);
|
||||
if (ret)
|
||||
pr_warn("%s Unable to send a nlmsg\n", __func__);
|
||||
return ret;
|
||||
|
@ -778,8 +777,7 @@ int iwpm_send_mapinfo(u8 nl_client, int iwpm_pid)
|
|||
send_mapping_info_exit:
|
||||
if (ret) {
|
||||
pr_warn("%s: %s (ret = %d)\n", __func__, err_str, ret);
|
||||
if (skb)
|
||||
dev_kfree_skb(skb);
|
||||
dev_kfree_skb(skb);
|
||||
return ret;
|
||||
}
|
||||
send_nlmsg_done(skb, nl_client, iwpm_pid);
|
||||
|
@ -824,7 +822,7 @@ int iwpm_send_hello(u8 nl_client, int iwpm_pid, u16 abi_version)
|
|||
goto hello_num_error;
|
||||
nlmsg_end(skb, nlh);
|
||||
|
||||
ret = rdma_nl_unicast(skb, iwpm_pid);
|
||||
ret = rdma_nl_unicast(&init_net, skb, iwpm_pid);
|
||||
if (ret) {
|
||||
skb = NULL;
|
||||
err_str = "Unable to send a nlmsg";
|
||||
|
@ -834,7 +832,6 @@ int iwpm_send_hello(u8 nl_client, int iwpm_pid, u16 abi_version)
|
|||
return 0;
|
||||
hello_num_error:
|
||||
pr_info("%s: %s\n", __func__, err_str);
|
||||
if (skb)
|
||||
dev_kfree_skb(skb);
|
||||
dev_kfree_skb(skb);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -36,20 +36,22 @@
|
|||
#include <linux/export.h>
|
||||
#include <net/netlink.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <net/netns/generic.h>
|
||||
#include <net/sock.h>
|
||||
#include <rdma/rdma_netlink.h>
|
||||
#include <linux/module.h>
|
||||
#include "core_priv.h"
|
||||
|
||||
static DEFINE_MUTEX(rdma_nl_mutex);
|
||||
static struct sock *nls;
|
||||
static struct {
|
||||
const struct rdma_nl_cbs *cb_table;
|
||||
} rdma_nl_types[RDMA_NL_NUM_CLIENTS];
|
||||
|
||||
bool rdma_nl_chk_listeners(unsigned int group)
|
||||
{
|
||||
return netlink_has_listeners(nls, group);
|
||||
struct rdma_dev_net *rnet = rdma_net_to_dev_net(&init_net);
|
||||
|
||||
return netlink_has_listeners(rnet->nl_sock, group);
|
||||
}
|
||||
EXPORT_SYMBOL(rdma_nl_chk_listeners);
|
||||
|
||||
|
@ -73,13 +75,21 @@ static bool is_nl_msg_valid(unsigned int type, unsigned int op)
|
|||
return (op < max_num_ops[type]) ? true : false;
|
||||
}
|
||||
|
||||
static bool is_nl_valid(unsigned int type, unsigned int op)
|
||||
static bool
|
||||
is_nl_valid(const struct sk_buff *skb, unsigned int type, unsigned int op)
|
||||
{
|
||||
const struct rdma_nl_cbs *cb_table;
|
||||
|
||||
if (!is_nl_msg_valid(type, op))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Currently only NLDEV client is supporting netlink commands in
|
||||
* non init_net net namespace.
|
||||
*/
|
||||
if (sock_net(skb->sk) != &init_net && type != RDMA_NL_NLDEV)
|
||||
return false;
|
||||
|
||||
if (!rdma_nl_types[type].cb_table) {
|
||||
mutex_unlock(&rdma_nl_mutex);
|
||||
request_module("rdma-netlink-subsys-%d", type);
|
||||
|
@ -161,7 +171,7 @@ static int rdma_nl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||
unsigned int op = RDMA_NL_GET_OP(type);
|
||||
const struct rdma_nl_cbs *cb_table;
|
||||
|
||||
if (!is_nl_valid(index, op))
|
||||
if (!is_nl_valid(skb, index, op))
|
||||
return -EINVAL;
|
||||
|
||||
cb_table = rdma_nl_types[index].cb_table;
|
||||
|
@ -185,7 +195,7 @@ static int rdma_nl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||
.dump = cb_table[op].dump,
|
||||
};
|
||||
if (c.dump)
|
||||
return netlink_dump_start(nls, skb, nlh, &c);
|
||||
return netlink_dump_start(skb->sk, skb, nlh, &c);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -258,52 +268,65 @@ static void rdma_nl_rcv(struct sk_buff *skb)
|
|||
mutex_unlock(&rdma_nl_mutex);
|
||||
}
|
||||
|
||||
int rdma_nl_unicast(struct sk_buff *skb, u32 pid)
|
||||
int rdma_nl_unicast(struct net *net, struct sk_buff *skb, u32 pid)
|
||||
{
|
||||
struct rdma_dev_net *rnet = rdma_net_to_dev_net(net);
|
||||
int err;
|
||||
|
||||
err = netlink_unicast(nls, skb, pid, MSG_DONTWAIT);
|
||||
err = netlink_unicast(rnet->nl_sock, skb, pid, MSG_DONTWAIT);
|
||||
return (err < 0) ? err : 0;
|
||||
}
|
||||
EXPORT_SYMBOL(rdma_nl_unicast);
|
||||
|
||||
int rdma_nl_unicast_wait(struct sk_buff *skb, __u32 pid)
|
||||
int rdma_nl_unicast_wait(struct net *net, struct sk_buff *skb, __u32 pid)
|
||||
{
|
||||
struct rdma_dev_net *rnet = rdma_net_to_dev_net(net);
|
||||
int err;
|
||||
|
||||
err = netlink_unicast(nls, skb, pid, 0);
|
||||
err = netlink_unicast(rnet->nl_sock, skb, pid, 0);
|
||||
return (err < 0) ? err : 0;
|
||||
}
|
||||
EXPORT_SYMBOL(rdma_nl_unicast_wait);
|
||||
|
||||
int rdma_nl_multicast(struct sk_buff *skb, unsigned int group, gfp_t flags)
|
||||
int rdma_nl_multicast(struct net *net, struct sk_buff *skb,
|
||||
unsigned int group, gfp_t flags)
|
||||
{
|
||||
return nlmsg_multicast(nls, skb, 0, group, flags);
|
||||
struct rdma_dev_net *rnet = rdma_net_to_dev_net(net);
|
||||
|
||||
return nlmsg_multicast(rnet->nl_sock, skb, 0, group, flags);
|
||||
}
|
||||
EXPORT_SYMBOL(rdma_nl_multicast);
|
||||
|
||||
int __init rdma_nl_init(void)
|
||||
{
|
||||
struct netlink_kernel_cfg cfg = {
|
||||
.input = rdma_nl_rcv,
|
||||
};
|
||||
|
||||
nls = netlink_kernel_create(&init_net, NETLINK_RDMA, &cfg);
|
||||
if (!nls)
|
||||
return -ENOMEM;
|
||||
|
||||
nls->sk_sndtimeo = 10 * HZ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rdma_nl_exit(void)
|
||||
{
|
||||
int idx;
|
||||
|
||||
for (idx = 0; idx < RDMA_NL_NUM_CLIENTS; idx++)
|
||||
rdma_nl_unregister(idx);
|
||||
WARN(rdma_nl_types[idx].cb_table,
|
||||
"Netlink client %d wasn't released prior to unloading %s\n",
|
||||
idx, KBUILD_MODNAME);
|
||||
}
|
||||
|
||||
netlink_kernel_release(nls);
|
||||
int rdma_nl_net_init(struct rdma_dev_net *rnet)
|
||||
{
|
||||
struct net *net = read_pnet(&rnet->net);
|
||||
struct netlink_kernel_cfg cfg = {
|
||||
.input = rdma_nl_rcv,
|
||||
};
|
||||
struct sock *nls;
|
||||
|
||||
nls = netlink_kernel_create(net, NETLINK_RDMA, &cfg);
|
||||
if (!nls)
|
||||
return -ENOMEM;
|
||||
|
||||
nls->sk_sndtimeo = 10 * HZ;
|
||||
rnet->nl_sock = nls;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rdma_nl_net_exit(struct rdma_dev_net *rnet)
|
||||
{
|
||||
netlink_kernel_release(rnet->nl_sock);
|
||||
}
|
||||
|
||||
MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_RDMA);
|
||||
|
|
|
@ -831,7 +831,7 @@ static int nldev_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||
nlmsg_end(msg, nlh);
|
||||
|
||||
ib_device_put(device);
|
||||
return rdma_nl_unicast(msg, NETLINK_CB(skb).portid);
|
||||
return rdma_nl_unicast(sock_net(skb->sk), msg, NETLINK_CB(skb).portid);
|
||||
|
||||
err_free:
|
||||
nlmsg_free(msg);
|
||||
|
@ -971,7 +971,7 @@ static int nldev_port_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||
nlmsg_end(msg, nlh);
|
||||
ib_device_put(device);
|
||||
|
||||
return rdma_nl_unicast(msg, NETLINK_CB(skb).portid);
|
||||
return rdma_nl_unicast(sock_net(skb->sk), msg, NETLINK_CB(skb).portid);
|
||||
|
||||
err_free:
|
||||
nlmsg_free(msg);
|
||||
|
@ -1073,7 +1073,7 @@ static int nldev_res_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||
|
||||
nlmsg_end(msg, nlh);
|
||||
ib_device_put(device);
|
||||
return rdma_nl_unicast(msg, NETLINK_CB(skb).portid);
|
||||
return rdma_nl_unicast(sock_net(skb->sk), msg, NETLINK_CB(skb).portid);
|
||||
|
||||
err_free:
|
||||
nlmsg_free(msg);
|
||||
|
@ -1250,7 +1250,7 @@ static int res_get_common_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||
|
||||
nlmsg_end(msg, nlh);
|
||||
ib_device_put(device);
|
||||
return rdma_nl_unicast(msg, NETLINK_CB(skb).portid);
|
||||
return rdma_nl_unicast(sock_net(skb->sk), msg, NETLINK_CB(skb).portid);
|
||||
|
||||
err_free:
|
||||
nlmsg_free(msg);
|
||||
|
@ -1595,7 +1595,7 @@ static int nldev_get_chardev(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||
put_device(data.cdev);
|
||||
if (ibdev)
|
||||
ib_device_put(ibdev);
|
||||
return rdma_nl_unicast(msg, NETLINK_CB(skb).portid);
|
||||
return rdma_nl_unicast(sock_net(skb->sk), msg, NETLINK_CB(skb).portid);
|
||||
|
||||
out_data:
|
||||
put_device(data.cdev);
|
||||
|
@ -1635,7 +1635,7 @@ static int nldev_sys_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||
return err;
|
||||
}
|
||||
nlmsg_end(msg, nlh);
|
||||
return rdma_nl_unicast(msg, NETLINK_CB(skb).portid);
|
||||
return rdma_nl_unicast(sock_net(skb->sk), msg, NETLINK_CB(skb).portid);
|
||||
}
|
||||
|
||||
static int nldev_set_sys_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
|
@ -1733,7 +1733,7 @@ static int nldev_stat_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||
|
||||
nlmsg_end(msg, nlh);
|
||||
ib_device_put(device);
|
||||
return rdma_nl_unicast(msg, NETLINK_CB(skb).portid);
|
||||
return rdma_nl_unicast(sock_net(skb->sk), msg, NETLINK_CB(skb).portid);
|
||||
|
||||
err_fill:
|
||||
rdma_counter_unbind_qpn(device, port, qpn, cntn);
|
||||
|
@ -1801,7 +1801,7 @@ static int nldev_stat_del_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||
|
||||
nlmsg_end(msg, nlh);
|
||||
ib_device_put(device);
|
||||
return rdma_nl_unicast(msg, NETLINK_CB(skb).portid);
|
||||
return rdma_nl_unicast(sock_net(skb->sk), msg, NETLINK_CB(skb).portid);
|
||||
|
||||
err_fill:
|
||||
rdma_counter_bind_qpn(device, port, qpn, cntn);
|
||||
|
@ -1892,7 +1892,7 @@ static int stat_get_doit_default_counter(struct sk_buff *skb,
|
|||
mutex_unlock(&stats->lock);
|
||||
nlmsg_end(msg, nlh);
|
||||
ib_device_put(device);
|
||||
return rdma_nl_unicast(msg, NETLINK_CB(skb).portid);
|
||||
return rdma_nl_unicast(sock_net(skb->sk), msg, NETLINK_CB(skb).portid);
|
||||
|
||||
err_table:
|
||||
nla_nest_cancel(msg, table_attr);
|
||||
|
@ -1964,7 +1964,7 @@ static int stat_get_doit_qp(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||
|
||||
nlmsg_end(msg, nlh);
|
||||
ib_device_put(device);
|
||||
return rdma_nl_unicast(msg, NETLINK_CB(skb).portid);
|
||||
return rdma_nl_unicast(sock_net(skb->sk), msg, NETLINK_CB(skb).portid);
|
||||
|
||||
err_msg:
|
||||
nlmsg_free(msg);
|
||||
|
|
|
@ -860,7 +860,7 @@ static int ib_nl_send_msg(struct ib_sa_query *query, gfp_t gfp_mask)
|
|||
/* Repair the nlmsg header length */
|
||||
nlmsg_end(skb, nlh);
|
||||
|
||||
return rdma_nl_multicast(skb, RDMA_NL_GROUP_LS, gfp_mask);
|
||||
return rdma_nl_multicast(&init_net, skb, RDMA_NL_GROUP_LS, gfp_mask);
|
||||
}
|
||||
|
||||
static int ib_nl_make_request(struct ib_sa_query *query, gfp_t gfp_mask)
|
||||
|
|
|
@ -289,6 +289,24 @@ static ssize_t rate_show(struct ib_port *p, struct port_attribute *unused,
|
|||
ib_width_enum_to_int(attr.active_width), speed);
|
||||
}
|
||||
|
||||
static const char *phys_state_to_str(enum ib_port_phys_state phys_state)
|
||||
{
|
||||
static const char * phys_state_str[] = {
|
||||
"<unknown>",
|
||||
"Sleep",
|
||||
"Polling",
|
||||
"Disabled",
|
||||
"PortConfigurationTraining",
|
||||
"LinkUp",
|
||||
"LinkErrorRecovery",
|
||||
"Phy Test",
|
||||
};
|
||||
|
||||
if (phys_state < ARRAY_SIZE(phys_state_str))
|
||||
return phys_state_str[phys_state];
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
static ssize_t phys_state_show(struct ib_port *p, struct port_attribute *unused,
|
||||
char *buf)
|
||||
{
|
||||
|
@ -300,16 +318,8 @@ static ssize_t phys_state_show(struct ib_port *p, struct port_attribute *unused,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (attr.phys_state) {
|
||||
case 1: return sprintf(buf, "1: Sleep\n");
|
||||
case 2: return sprintf(buf, "2: Polling\n");
|
||||
case 3: return sprintf(buf, "3: Disabled\n");
|
||||
case 4: return sprintf(buf, "4: PortConfigurationTraining\n");
|
||||
case 5: return sprintf(buf, "5: LinkUp\n");
|
||||
case 6: return sprintf(buf, "6: LinkErrorRecovery\n");
|
||||
case 7: return sprintf(buf, "7: Phy Test\n");
|
||||
default: return sprintf(buf, "%d: <unknown>\n", attr.phys_state);
|
||||
}
|
||||
return sprintf(buf, "%d: %s\n", attr.phys_state,
|
||||
phys_state_to_str(attr.phys_state));
|
||||
}
|
||||
|
||||
static ssize_t link_layer_show(struct ib_port *p, struct port_attribute *unused,
|
||||
|
|
|
@ -218,7 +218,7 @@ static inline int ib_init_umem_odp(struct ib_umem_odp *umem_odp)
|
|||
umem_odp->interval_tree.start =
|
||||
ALIGN_DOWN(umem_odp->umem.address, page_size);
|
||||
if (check_add_overflow(umem_odp->umem.address,
|
||||
umem_odp->umem.length,
|
||||
(unsigned long)umem_odp->umem.length,
|
||||
&umem_odp->interval_tree.last))
|
||||
return -EOVERFLOW;
|
||||
umem_odp->interval_tree.last =
|
||||
|
|
|
@ -1042,7 +1042,7 @@ static int ib_umad_close(struct inode *inode, struct file *filp)
|
|||
ib_unregister_mad_agent(file->agent[i]);
|
||||
|
||||
mutex_unlock(&file->port->file_mutex);
|
||||
|
||||
mutex_destroy(&file->mutex);
|
||||
kfree(file);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -3479,7 +3479,8 @@ static int __uverbs_create_xsrq(struct uverbs_attr_bundle *attrs,
|
|||
|
||||
err_copy:
|
||||
ib_destroy_srq_user(srq, uverbs_get_cleared_udata(attrs));
|
||||
|
||||
/* It was released in ib_destroy_srq_user */
|
||||
srq = NULL;
|
||||
err_free:
|
||||
kfree(srq);
|
||||
err_put:
|
||||
|
|
|
@ -120,6 +120,8 @@ static void ib_uverbs_release_dev(struct device *device)
|
|||
|
||||
uverbs_destroy_api(dev->uapi);
|
||||
cleanup_srcu_struct(&dev->disassociate_srcu);
|
||||
mutex_destroy(&dev->lists_mutex);
|
||||
mutex_destroy(&dev->xrcd_tree_mutex);
|
||||
kfree(dev);
|
||||
}
|
||||
|
||||
|
@ -212,6 +214,8 @@ void ib_uverbs_release_file(struct kref *ref)
|
|||
|
||||
if (file->disassociate_page)
|
||||
__free_pages(file->disassociate_page, 0);
|
||||
mutex_destroy(&file->umap_lock);
|
||||
mutex_destroy(&file->ucontext_lock);
|
||||
kfree(file);
|
||||
}
|
||||
|
||||
|
|
|
@ -2259,6 +2259,7 @@ int ib_dealloc_xrcd(struct ib_xrcd *xrcd, struct ib_udata *udata)
|
|||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
mutex_destroy(&xrcd->tgt_qp_mutex);
|
||||
|
||||
return xrcd->device->ops.dealloc_xrcd(xrcd, udata);
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ static const char * const bnxt_re_stat_name[] = {
|
|||
[BNXT_RE_SEQ_ERR_NAKS_RCVD] = "seq_err_naks_rcvd",
|
||||
[BNXT_RE_MAX_RETRY_EXCEEDED] = "max_retry_exceeded",
|
||||
[BNXT_RE_RNR_NAKS_RCVD] = "rnr_naks_rcvd",
|
||||
[BNXT_RE_MISSING_RESP] = "missin_resp",
|
||||
[BNXT_RE_MISSING_RESP] = "missing_resp",
|
||||
[BNXT_RE_UNRECOVERABLE_ERR] = "unrecoverable_err",
|
||||
[BNXT_RE_BAD_RESP_ERR] = "bad_resp_err",
|
||||
[BNXT_RE_LOCAL_QP_OP_ERR] = "local_qp_op_err",
|
||||
|
|
|
@ -220,10 +220,10 @@ int bnxt_re_query_port(struct ib_device *ibdev, u8 port_num,
|
|||
|
||||
if (netif_running(rdev->netdev) && netif_carrier_ok(rdev->netdev)) {
|
||||
port_attr->state = IB_PORT_ACTIVE;
|
||||
port_attr->phys_state = 5;
|
||||
port_attr->phys_state = IB_PORT_PHYS_STATE_LINK_UP;
|
||||
} else {
|
||||
port_attr->state = IB_PORT_DOWN;
|
||||
port_attr->phys_state = 3;
|
||||
port_attr->phys_state = IB_PORT_PHYS_STATE_DISABLED;
|
||||
}
|
||||
port_attr->max_mtu = IB_MTU_4096;
|
||||
port_attr->active_mtu = iboe_get_mtu(rdev->netdev->mtu);
|
||||
|
@ -1398,7 +1398,7 @@ int bnxt_re_create_srq(struct ib_srq *ib_srq,
|
|||
dev_err(rdev_to_dev(rdev), "SRQ copy to udata failed!");
|
||||
bnxt_qplib_destroy_srq(&rdev->qplib_res,
|
||||
&srq->qplib_srq);
|
||||
goto exit;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
if (nq)
|
||||
|
|
|
@ -1473,7 +1473,6 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
|
|||
&rdev->active_width);
|
||||
set_bit(BNXT_RE_FLAG_ISSUE_ROCE_STATS, &rdev->flags);
|
||||
bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1, IB_EVENT_PORT_ACTIVE);
|
||||
bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1, IB_EVENT_GID_CHANGE);
|
||||
|
||||
return 0;
|
||||
free_sctx:
|
||||
|
|
|
@ -991,33 +991,8 @@ static int iwch_query_device(struct ib_device *ibdev, struct ib_device_attr *pro
|
|||
static int iwch_query_port(struct ib_device *ibdev,
|
||||
u8 port, struct ib_port_attr *props)
|
||||
{
|
||||
struct iwch_dev *dev;
|
||||
struct net_device *netdev;
|
||||
struct in_device *inetdev;
|
||||
|
||||
pr_debug("%s ibdev %p\n", __func__, ibdev);
|
||||
|
||||
dev = to_iwch_dev(ibdev);
|
||||
netdev = dev->rdev.port_info.lldevs[port-1];
|
||||
|
||||
/* props being zeroed by the caller, avoid zeroing it here */
|
||||
props->max_mtu = IB_MTU_4096;
|
||||
props->active_mtu = ib_mtu_int_to_enum(netdev->mtu);
|
||||
|
||||
if (!netif_carrier_ok(netdev))
|
||||
props->state = IB_PORT_DOWN;
|
||||
else {
|
||||
inetdev = in_dev_get(netdev);
|
||||
if (inetdev) {
|
||||
if (inetdev->ifa_list)
|
||||
props->state = IB_PORT_ACTIVE;
|
||||
else
|
||||
props->state = IB_PORT_INIT;
|
||||
in_dev_put(inetdev);
|
||||
} else
|
||||
props->state = IB_PORT_INIT;
|
||||
}
|
||||
|
||||
props->port_cap_flags =
|
||||
IB_PORT_CM_SUP |
|
||||
IB_PORT_SNMP_TUNNEL_SUP |
|
||||
|
@ -1273,8 +1248,24 @@ static const struct ib_device_ops iwch_dev_ops = {
|
|||
INIT_RDMA_OBJ_SIZE(ib_ucontext, iwch_ucontext, ibucontext),
|
||||
};
|
||||
|
||||
static int set_netdevs(struct ib_device *ib_dev, struct cxio_rdev *rdev)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < rdev->port_info.nports; i++) {
|
||||
ret = ib_device_set_netdev(ib_dev, rdev->port_info.lldevs[i],
|
||||
i + 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iwch_register_device(struct iwch_dev *dev)
|
||||
{
|
||||
int err;
|
||||
|
||||
pr_debug("%s iwch_dev %p\n", __func__, dev);
|
||||
memset(&dev->ibdev.node_guid, 0, sizeof(dev->ibdev.node_guid));
|
||||
memcpy(&dev->ibdev.node_guid, dev->rdev.t3cdev_p->lldev->dev_addr, 6);
|
||||
|
@ -1315,6 +1306,10 @@ int iwch_register_device(struct iwch_dev *dev)
|
|||
|
||||
rdma_set_device_sysfs_group(&dev->ibdev, &iwch_attr_group);
|
||||
ib_set_device_ops(&dev->ibdev, &iwch_dev_ops);
|
||||
err = set_netdevs(&dev->ibdev, &dev->rdev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return ib_register_device(&dev->ibdev, "cxgb3_%d");
|
||||
}
|
||||
|
||||
|
|
|
@ -305,32 +305,8 @@ static int c4iw_query_device(struct ib_device *ibdev, struct ib_device_attr *pro
|
|||
static int c4iw_query_port(struct ib_device *ibdev, u8 port,
|
||||
struct ib_port_attr *props)
|
||||
{
|
||||
struct c4iw_dev *dev;
|
||||
struct net_device *netdev;
|
||||
struct in_device *inetdev;
|
||||
|
||||
pr_debug("ibdev %p\n", ibdev);
|
||||
|
||||
dev = to_c4iw_dev(ibdev);
|
||||
netdev = dev->rdev.lldi.ports[port-1];
|
||||
/* props being zeroed by the caller, avoid zeroing it here */
|
||||
props->max_mtu = IB_MTU_4096;
|
||||
props->active_mtu = ib_mtu_int_to_enum(netdev->mtu);
|
||||
|
||||
if (!netif_carrier_ok(netdev))
|
||||
props->state = IB_PORT_DOWN;
|
||||
else {
|
||||
inetdev = in_dev_get(netdev);
|
||||
if (inetdev) {
|
||||
if (inetdev->ifa_list)
|
||||
props->state = IB_PORT_ACTIVE;
|
||||
else
|
||||
props->state = IB_PORT_INIT;
|
||||
in_dev_put(inetdev);
|
||||
} else
|
||||
props->state = IB_PORT_INIT;
|
||||
}
|
||||
|
||||
props->port_cap_flags =
|
||||
IB_PORT_CM_SUP |
|
||||
IB_PORT_SNMP_TUNNEL_SUP |
|
||||
|
|
|
@ -156,5 +156,8 @@ int efa_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
|
|||
int qp_attr_mask, struct ib_udata *udata);
|
||||
enum rdma_link_layer efa_port_link_layer(struct ib_device *ibdev,
|
||||
u8 port_num);
|
||||
struct rdma_hw_stats *efa_alloc_hw_stats(struct ib_device *ibdev, u8 port_num);
|
||||
int efa_get_hw_stats(struct ib_device *ibdev, struct rdma_hw_stats *stats,
|
||||
u8 port_num, int index);
|
||||
|
||||
#endif /* _EFA_H_ */
|
||||
|
|
|
@ -109,17 +109,19 @@ static u32 efa_com_reg_read32(struct efa_com_dev *edev, u16 offset)
|
|||
} while (time_is_after_jiffies(exp_time));
|
||||
|
||||
if (read_resp->req_id != mmio_read->seq_num) {
|
||||
ibdev_err(edev->efa_dev,
|
||||
"Reading register timed out. expected: req id[%u] offset[%#x] actual: req id[%u] offset[%#x]\n",
|
||||
mmio_read->seq_num, offset, read_resp->req_id,
|
||||
read_resp->reg_off);
|
||||
ibdev_err_ratelimited(
|
||||
edev->efa_dev,
|
||||
"Reading register timed out. expected: req id[%u] offset[%#x] actual: req id[%u] offset[%#x]\n",
|
||||
mmio_read->seq_num, offset, read_resp->req_id,
|
||||
read_resp->reg_off);
|
||||
err = EFA_MMIO_READ_INVALID;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (read_resp->reg_off != offset) {
|
||||
ibdev_err(edev->efa_dev,
|
||||
"Reading register failed: wrong offset provided\n");
|
||||
ibdev_err_ratelimited(
|
||||
edev->efa_dev,
|
||||
"Reading register failed: wrong offset provided\n");
|
||||
err = EFA_MMIO_READ_INVALID;
|
||||
goto out;
|
||||
}
|
||||
|
@ -293,9 +295,10 @@ static struct efa_comp_ctx *efa_com_get_comp_ctx(struct efa_com_admin_queue *aq,
|
|||
u16 ctx_id = cmd_id & (aq->depth - 1);
|
||||
|
||||
if (aq->comp_ctx[ctx_id].occupied && capture) {
|
||||
ibdev_err(aq->efa_dev,
|
||||
"Completion context for command_id %#x is occupied\n",
|
||||
cmd_id);
|
||||
ibdev_err_ratelimited(
|
||||
aq->efa_dev,
|
||||
"Completion context for command_id %#x is occupied\n",
|
||||
cmd_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -401,7 +404,7 @@ static struct efa_comp_ctx *efa_com_submit_admin_cmd(struct efa_com_admin_queue
|
|||
|
||||
spin_lock(&aq->sq.lock);
|
||||
if (!test_bit(EFA_AQ_STATE_RUNNING_BIT, &aq->state)) {
|
||||
ibdev_err(aq->efa_dev, "Admin queue is closed\n");
|
||||
ibdev_err_ratelimited(aq->efa_dev, "Admin queue is closed\n");
|
||||
spin_unlock(&aq->sq.lock);
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
@ -519,8 +522,9 @@ static int efa_com_wait_and_process_admin_cq_polling(struct efa_comp_ctx *comp_c
|
|||
break;
|
||||
|
||||
if (time_is_before_jiffies(timeout)) {
|
||||
ibdev_err(aq->efa_dev,
|
||||
"Wait for completion (polling) timeout\n");
|
||||
ibdev_err_ratelimited(
|
||||
aq->efa_dev,
|
||||
"Wait for completion (polling) timeout\n");
|
||||
/* EFA didn't have any completion */
|
||||
atomic64_inc(&aq->stats.no_completion);
|
||||
|
||||
|
@ -561,17 +565,19 @@ static int efa_com_wait_and_process_admin_cq_interrupts(struct efa_comp_ctx *com
|
|||
atomic64_inc(&aq->stats.no_completion);
|
||||
|
||||
if (comp_ctx->status == EFA_CMD_COMPLETED)
|
||||
ibdev_err(aq->efa_dev,
|
||||
"The device sent a completion but the driver didn't receive any MSI-X interrupt for admin cmd %s(%d) status %d (ctx: 0x%p, sq producer: %d, sq consumer: %d, cq consumer: %d)\n",
|
||||
efa_com_cmd_str(comp_ctx->cmd_opcode),
|
||||
comp_ctx->cmd_opcode, comp_ctx->status,
|
||||
comp_ctx, aq->sq.pc, aq->sq.cc, aq->cq.cc);
|
||||
ibdev_err_ratelimited(
|
||||
aq->efa_dev,
|
||||
"The device sent a completion but the driver didn't receive any MSI-X interrupt for admin cmd %s(%d) status %d (ctx: 0x%p, sq producer: %d, sq consumer: %d, cq consumer: %d)\n",
|
||||
efa_com_cmd_str(comp_ctx->cmd_opcode),
|
||||
comp_ctx->cmd_opcode, comp_ctx->status,
|
||||
comp_ctx, aq->sq.pc, aq->sq.cc, aq->cq.cc);
|
||||
else
|
||||
ibdev_err(aq->efa_dev,
|
||||
"The device didn't send any completion for admin cmd %s(%d) status %d (ctx 0x%p, sq producer: %d, sq consumer: %d, cq consumer: %d)\n",
|
||||
efa_com_cmd_str(comp_ctx->cmd_opcode),
|
||||
comp_ctx->cmd_opcode, comp_ctx->status,
|
||||
comp_ctx, aq->sq.pc, aq->sq.cc, aq->cq.cc);
|
||||
ibdev_err_ratelimited(
|
||||
aq->efa_dev,
|
||||
"The device didn't send any completion for admin cmd %s(%d) status %d (ctx 0x%p, sq producer: %d, sq consumer: %d, cq consumer: %d)\n",
|
||||
efa_com_cmd_str(comp_ctx->cmd_opcode),
|
||||
comp_ctx->cmd_opcode, comp_ctx->status,
|
||||
comp_ctx, aq->sq.pc, aq->sq.cc, aq->cq.cc);
|
||||
|
||||
clear_bit(EFA_AQ_STATE_RUNNING_BIT, &aq->state);
|
||||
err = -ETIME;
|
||||
|
@ -633,10 +639,11 @@ int efa_com_cmd_exec(struct efa_com_admin_queue *aq,
|
|||
cmd->aq_common_descriptor.opcode);
|
||||
comp_ctx = efa_com_submit_admin_cmd(aq, cmd, cmd_size, comp, comp_size);
|
||||
if (IS_ERR(comp_ctx)) {
|
||||
ibdev_err(aq->efa_dev,
|
||||
"Failed to submit command %s (opcode %u) err %ld\n",
|
||||
efa_com_cmd_str(cmd->aq_common_descriptor.opcode),
|
||||
cmd->aq_common_descriptor.opcode, PTR_ERR(comp_ctx));
|
||||
ibdev_err_ratelimited(
|
||||
aq->efa_dev,
|
||||
"Failed to submit command %s (opcode %u) err %ld\n",
|
||||
efa_com_cmd_str(cmd->aq_common_descriptor.opcode),
|
||||
cmd->aq_common_descriptor.opcode, PTR_ERR(comp_ctx));
|
||||
|
||||
up(&aq->avail_cmds);
|
||||
return PTR_ERR(comp_ctx);
|
||||
|
@ -644,11 +651,12 @@ int efa_com_cmd_exec(struct efa_com_admin_queue *aq,
|
|||
|
||||
err = efa_com_wait_and_process_admin_cq(comp_ctx, aq);
|
||||
if (err)
|
||||
ibdev_err(aq->efa_dev,
|
||||
"Failed to process command %s (opcode %u) comp_status %d err %d\n",
|
||||
efa_com_cmd_str(cmd->aq_common_descriptor.opcode),
|
||||
cmd->aq_common_descriptor.opcode,
|
||||
comp_ctx->comp_status, err);
|
||||
ibdev_err_ratelimited(
|
||||
aq->efa_dev,
|
||||
"Failed to process command %s (opcode %u) comp_status %d err %d\n",
|
||||
efa_com_cmd_str(cmd->aq_common_descriptor.opcode),
|
||||
cmd->aq_common_descriptor.opcode, comp_ctx->comp_status,
|
||||
err);
|
||||
|
||||
up(&aq->avail_cmds);
|
||||
|
||||
|
|
|
@ -44,7 +44,8 @@ int efa_com_create_qp(struct efa_com_dev *edev,
|
|||
(struct efa_admin_acq_entry *)&cmd_completion,
|
||||
sizeof(cmd_completion));
|
||||
if (err) {
|
||||
ibdev_err(edev->efa_dev, "Failed to create qp [%d]\n", err);
|
||||
ibdev_err_ratelimited(edev->efa_dev,
|
||||
"Failed to create qp [%d]\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -82,9 +83,10 @@ int efa_com_modify_qp(struct efa_com_dev *edev,
|
|||
(struct efa_admin_acq_entry *)&resp,
|
||||
sizeof(resp));
|
||||
if (err) {
|
||||
ibdev_err(edev->efa_dev,
|
||||
"Failed to modify qp-%u modify_mask[%#x] [%d]\n",
|
||||
cmd.qp_handle, cmd.modify_mask, err);
|
||||
ibdev_err_ratelimited(
|
||||
edev->efa_dev,
|
||||
"Failed to modify qp-%u modify_mask[%#x] [%d]\n",
|
||||
cmd.qp_handle, cmd.modify_mask, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -109,8 +111,9 @@ int efa_com_query_qp(struct efa_com_dev *edev,
|
|||
(struct efa_admin_acq_entry *)&resp,
|
||||
sizeof(resp));
|
||||
if (err) {
|
||||
ibdev_err(edev->efa_dev, "Failed to query qp-%u [%d]\n",
|
||||
cmd.qp_handle, err);
|
||||
ibdev_err_ratelimited(edev->efa_dev,
|
||||
"Failed to query qp-%u [%d]\n",
|
||||
cmd.qp_handle, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -139,8 +142,9 @@ int efa_com_destroy_qp(struct efa_com_dev *edev,
|
|||
(struct efa_admin_acq_entry *)&cmd_completion,
|
||||
sizeof(cmd_completion));
|
||||
if (err) {
|
||||
ibdev_err(edev->efa_dev, "Failed to destroy qp-%u [%d]\n",
|
||||
qp_cmd.qp_handle, err);
|
||||
ibdev_err_ratelimited(edev->efa_dev,
|
||||
"Failed to destroy qp-%u [%d]\n",
|
||||
qp_cmd.qp_handle, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -173,7 +177,8 @@ int efa_com_create_cq(struct efa_com_dev *edev,
|
|||
(struct efa_admin_acq_entry *)&cmd_completion,
|
||||
sizeof(cmd_completion));
|
||||
if (err) {
|
||||
ibdev_err(edev->efa_dev, "Failed to create cq[%d]\n", err);
|
||||
ibdev_err_ratelimited(edev->efa_dev,
|
||||
"Failed to create cq[%d]\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -201,8 +206,9 @@ int efa_com_destroy_cq(struct efa_com_dev *edev,
|
|||
sizeof(destroy_resp));
|
||||
|
||||
if (err) {
|
||||
ibdev_err(edev->efa_dev, "Failed to destroy CQ-%u [%d]\n",
|
||||
params->cq_idx, err);
|
||||
ibdev_err_ratelimited(edev->efa_dev,
|
||||
"Failed to destroy CQ-%u [%d]\n",
|
||||
params->cq_idx, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -250,7 +256,8 @@ int efa_com_register_mr(struct efa_com_dev *edev,
|
|||
(struct efa_admin_acq_entry *)&cmd_completion,
|
||||
sizeof(cmd_completion));
|
||||
if (err) {
|
||||
ibdev_err(edev->efa_dev, "Failed to register mr [%d]\n", err);
|
||||
ibdev_err_ratelimited(edev->efa_dev,
|
||||
"Failed to register mr [%d]\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -277,9 +284,9 @@ int efa_com_dereg_mr(struct efa_com_dev *edev,
|
|||
(struct efa_admin_acq_entry *)&cmd_completion,
|
||||
sizeof(cmd_completion));
|
||||
if (err) {
|
||||
ibdev_err(edev->efa_dev,
|
||||
"Failed to de-register mr(lkey-%u) [%d]\n",
|
||||
mr_cmd.l_key, err);
|
||||
ibdev_err_ratelimited(edev->efa_dev,
|
||||
"Failed to de-register mr(lkey-%u) [%d]\n",
|
||||
mr_cmd.l_key, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -306,8 +313,9 @@ int efa_com_create_ah(struct efa_com_dev *edev,
|
|||
(struct efa_admin_acq_entry *)&cmd_completion,
|
||||
sizeof(cmd_completion));
|
||||
if (err) {
|
||||
ibdev_err(edev->efa_dev, "Failed to create ah for %pI6 [%d]\n",
|
||||
ah_cmd.dest_addr, err);
|
||||
ibdev_err_ratelimited(edev->efa_dev,
|
||||
"Failed to create ah for %pI6 [%d]\n",
|
||||
ah_cmd.dest_addr, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -334,8 +342,9 @@ int efa_com_destroy_ah(struct efa_com_dev *edev,
|
|||
(struct efa_admin_acq_entry *)&cmd_completion,
|
||||
sizeof(cmd_completion));
|
||||
if (err) {
|
||||
ibdev_err(edev->efa_dev, "Failed to destroy ah-%d pd-%d [%d]\n",
|
||||
ah_cmd.ah, ah_cmd.pd, err);
|
||||
ibdev_err_ratelimited(edev->efa_dev,
|
||||
"Failed to destroy ah-%d pd-%d [%d]\n",
|
||||
ah_cmd.ah, ah_cmd.pd, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -367,8 +376,9 @@ static int efa_com_get_feature_ex(struct efa_com_dev *edev,
|
|||
int err;
|
||||
|
||||
if (!efa_com_check_supported_feature_id(edev, feature_id)) {
|
||||
ibdev_err(edev->efa_dev, "Feature %d isn't supported\n",
|
||||
feature_id);
|
||||
ibdev_err_ratelimited(edev->efa_dev,
|
||||
"Feature %d isn't supported\n",
|
||||
feature_id);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
@ -396,9 +406,10 @@ static int efa_com_get_feature_ex(struct efa_com_dev *edev,
|
|||
sizeof(*get_resp));
|
||||
|
||||
if (err) {
|
||||
ibdev_err(edev->efa_dev,
|
||||
"Failed to submit get_feature command %d [%d]\n",
|
||||
feature_id, err);
|
||||
ibdev_err_ratelimited(
|
||||
edev->efa_dev,
|
||||
"Failed to submit get_feature command %d [%d]\n",
|
||||
feature_id, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -421,8 +432,9 @@ int efa_com_get_network_attr(struct efa_com_dev *edev,
|
|||
err = efa_com_get_feature(edev, &resp,
|
||||
EFA_ADMIN_NETWORK_ATTR);
|
||||
if (err) {
|
||||
ibdev_err(edev->efa_dev,
|
||||
"Failed to get network attributes %d\n", err);
|
||||
ibdev_err_ratelimited(edev->efa_dev,
|
||||
"Failed to get network attributes %d\n",
|
||||
err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -441,8 +453,9 @@ int efa_com_get_device_attr(struct efa_com_dev *edev,
|
|||
|
||||
err = efa_com_get_feature(edev, &resp, EFA_ADMIN_DEVICE_ATTR);
|
||||
if (err) {
|
||||
ibdev_err(edev->efa_dev, "Failed to get device attributes %d\n",
|
||||
err);
|
||||
ibdev_err_ratelimited(edev->efa_dev,
|
||||
"Failed to get device attributes %d\n",
|
||||
err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -456,9 +469,10 @@ int efa_com_get_device_attr(struct efa_com_dev *edev,
|
|||
result->db_bar = resp.u.device_attr.db_bar;
|
||||
|
||||
if (result->admin_api_version < 1) {
|
||||
ibdev_err(edev->efa_dev,
|
||||
"Failed to get device attr api version [%u < 1]\n",
|
||||
result->admin_api_version);
|
||||
ibdev_err_ratelimited(
|
||||
edev->efa_dev,
|
||||
"Failed to get device attr api version [%u < 1]\n",
|
||||
result->admin_api_version);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -466,8 +480,9 @@ int efa_com_get_device_attr(struct efa_com_dev *edev,
|
|||
err = efa_com_get_feature(edev, &resp,
|
||||
EFA_ADMIN_QUEUE_ATTR);
|
||||
if (err) {
|
||||
ibdev_err(edev->efa_dev,
|
||||
"Failed to get network attributes %d\n", err);
|
||||
ibdev_err_ratelimited(edev->efa_dev,
|
||||
"Failed to get queue attributes %d\n",
|
||||
err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -497,7 +512,8 @@ int efa_com_get_hw_hints(struct efa_com_dev *edev,
|
|||
|
||||
err = efa_com_get_feature(edev, &resp, EFA_ADMIN_HW_HINTS);
|
||||
if (err) {
|
||||
ibdev_err(edev->efa_dev, "Failed to get hw hints %d\n", err);
|
||||
ibdev_err_ratelimited(edev->efa_dev,
|
||||
"Failed to get hw hints %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -520,8 +536,9 @@ static int efa_com_set_feature_ex(struct efa_com_dev *edev,
|
|||
int err;
|
||||
|
||||
if (!efa_com_check_supported_feature_id(edev, feature_id)) {
|
||||
ibdev_err(edev->efa_dev, "Feature %d isn't supported\n",
|
||||
feature_id);
|
||||
ibdev_err_ratelimited(edev->efa_dev,
|
||||
"Feature %d isn't supported\n",
|
||||
feature_id);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
@ -545,9 +562,10 @@ static int efa_com_set_feature_ex(struct efa_com_dev *edev,
|
|||
sizeof(*set_resp));
|
||||
|
||||
if (err) {
|
||||
ibdev_err(edev->efa_dev,
|
||||
"Failed to submit set_feature command %d error: %d\n",
|
||||
feature_id, err);
|
||||
ibdev_err_ratelimited(
|
||||
edev->efa_dev,
|
||||
"Failed to submit set_feature command %d error: %d\n",
|
||||
feature_id, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -574,8 +592,9 @@ int efa_com_set_aenq_config(struct efa_com_dev *edev, u32 groups)
|
|||
|
||||
err = efa_com_get_feature(edev, &get_resp, EFA_ADMIN_AENQ_CONFIG);
|
||||
if (err) {
|
||||
ibdev_err(edev->efa_dev, "Failed to get aenq attributes: %d\n",
|
||||
err);
|
||||
ibdev_err_ratelimited(edev->efa_dev,
|
||||
"Failed to get aenq attributes: %d\n",
|
||||
err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -585,9 +604,10 @@ int efa_com_set_aenq_config(struct efa_com_dev *edev, u32 groups)
|
|||
get_resp.u.aenq.enabled_groups);
|
||||
|
||||
if ((get_resp.u.aenq.supported_groups & groups) != groups) {
|
||||
ibdev_err(edev->efa_dev,
|
||||
"Trying to set unsupported aenq groups[%#x] supported[%#x]\n",
|
||||
groups, get_resp.u.aenq.supported_groups);
|
||||
ibdev_err_ratelimited(
|
||||
edev->efa_dev,
|
||||
"Trying to set unsupported aenq groups[%#x] supported[%#x]\n",
|
||||
groups, get_resp.u.aenq.supported_groups);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
@ -595,8 +615,9 @@ int efa_com_set_aenq_config(struct efa_com_dev *edev, u32 groups)
|
|||
err = efa_com_set_feature(edev, &set_resp, &cmd,
|
||||
EFA_ADMIN_AENQ_CONFIG);
|
||||
if (err) {
|
||||
ibdev_err(edev->efa_dev, "Failed to set aenq attributes: %d\n",
|
||||
err);
|
||||
ibdev_err_ratelimited(edev->efa_dev,
|
||||
"Failed to set aenq attributes: %d\n",
|
||||
err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -619,7 +640,8 @@ int efa_com_alloc_pd(struct efa_com_dev *edev,
|
|||
(struct efa_admin_acq_entry *)&resp,
|
||||
sizeof(resp));
|
||||
if (err) {
|
||||
ibdev_err(edev->efa_dev, "Failed to allocate pd[%d]\n", err);
|
||||
ibdev_err_ratelimited(edev->efa_dev,
|
||||
"Failed to allocate pd[%d]\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -645,8 +667,9 @@ int efa_com_dealloc_pd(struct efa_com_dev *edev,
|
|||
(struct efa_admin_acq_entry *)&resp,
|
||||
sizeof(resp));
|
||||
if (err) {
|
||||
ibdev_err(edev->efa_dev, "Failed to deallocate pd-%u [%d]\n",
|
||||
cmd.pd, err);
|
||||
ibdev_err_ratelimited(edev->efa_dev,
|
||||
"Failed to deallocate pd-%u [%d]\n",
|
||||
cmd.pd, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -669,7 +692,8 @@ int efa_com_alloc_uar(struct efa_com_dev *edev,
|
|||
(struct efa_admin_acq_entry *)&resp,
|
||||
sizeof(resp));
|
||||
if (err) {
|
||||
ibdev_err(edev->efa_dev, "Failed to allocate uar[%d]\n", err);
|
||||
ibdev_err_ratelimited(edev->efa_dev,
|
||||
"Failed to allocate uar[%d]\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -695,10 +719,47 @@ int efa_com_dealloc_uar(struct efa_com_dev *edev,
|
|||
(struct efa_admin_acq_entry *)&resp,
|
||||
sizeof(resp));
|
||||
if (err) {
|
||||
ibdev_err(edev->efa_dev, "Failed to deallocate uar-%u [%d]\n",
|
||||
cmd.uar, err);
|
||||
ibdev_err_ratelimited(edev->efa_dev,
|
||||
"Failed to deallocate uar-%u [%d]\n",
|
||||
cmd.uar, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int efa_com_get_stats(struct efa_com_dev *edev,
|
||||
struct efa_com_get_stats_params *params,
|
||||
union efa_com_get_stats_result *result)
|
||||
{
|
||||
struct efa_com_admin_queue *aq = &edev->aq;
|
||||
struct efa_admin_aq_get_stats_cmd cmd = {};
|
||||
struct efa_admin_acq_get_stats_resp resp;
|
||||
int err;
|
||||
|
||||
cmd.aq_common_descriptor.opcode = EFA_ADMIN_GET_STATS;
|
||||
cmd.type = params->type;
|
||||
cmd.scope = params->scope;
|
||||
cmd.scope_modifier = params->scope_modifier;
|
||||
|
||||
err = efa_com_cmd_exec(aq,
|
||||
(struct efa_admin_aq_entry *)&cmd,
|
||||
sizeof(cmd),
|
||||
(struct efa_admin_acq_entry *)&resp,
|
||||
sizeof(resp));
|
||||
if (err) {
|
||||
ibdev_err_ratelimited(
|
||||
edev->efa_dev,
|
||||
"Failed to get stats type-%u scope-%u.%u [%d]\n",
|
||||
cmd.type, cmd.scope, cmd.scope_modifier, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
result->basic_stats.tx_bytes = resp.basic_stats.tx_bytes;
|
||||
result->basic_stats.tx_pkts = resp.basic_stats.tx_pkts;
|
||||
result->basic_stats.rx_bytes = resp.basic_stats.rx_bytes;
|
||||
result->basic_stats.rx_pkts = resp.basic_stats.rx_pkts;
|
||||
result->basic_stats.rx_drops = resp.basic_stats.rx_drops;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -225,6 +225,26 @@ struct efa_com_dealloc_uar_params {
|
|||
u16 uarn;
|
||||
};
|
||||
|
||||
struct efa_com_get_stats_params {
|
||||
/* see enum efa_admin_get_stats_type */
|
||||
u8 type;
|
||||
/* see enum efa_admin_get_stats_scope */
|
||||
u8 scope;
|
||||
u16 scope_modifier;
|
||||
};
|
||||
|
||||
struct efa_com_basic_stats {
|
||||
u64 tx_bytes;
|
||||
u64 tx_pkts;
|
||||
u64 rx_bytes;
|
||||
u64 rx_pkts;
|
||||
u64 rx_drops;
|
||||
};
|
||||
|
||||
union efa_com_get_stats_result {
|
||||
struct efa_com_basic_stats basic_stats;
|
||||
};
|
||||
|
||||
void efa_com_set_dma_addr(dma_addr_t addr, u32 *addr_high, u32 *addr_low);
|
||||
int efa_com_create_qp(struct efa_com_dev *edev,
|
||||
struct efa_com_create_qp_params *params,
|
||||
|
@ -266,5 +286,8 @@ int efa_com_alloc_uar(struct efa_com_dev *edev,
|
|||
struct efa_com_alloc_uar_result *result);
|
||||
int efa_com_dealloc_uar(struct efa_com_dev *edev,
|
||||
struct efa_com_dealloc_uar_params *params);
|
||||
int efa_com_get_stats(struct efa_com_dev *edev,
|
||||
struct efa_com_get_stats_params *params,
|
||||
union efa_com_get_stats_result *result);
|
||||
|
||||
#endif /* _EFA_COM_CMD_H_ */
|
||||
|
|
|
@ -201,6 +201,7 @@ static const struct ib_device_ops efa_dev_ops = {
|
|||
.driver_id = RDMA_DRIVER_EFA,
|
||||
.uverbs_abi_ver = EFA_UVERBS_ABI_VERSION,
|
||||
|
||||
.alloc_hw_stats = efa_alloc_hw_stats,
|
||||
.alloc_pd = efa_alloc_pd,
|
||||
.alloc_ucontext = efa_alloc_ucontext,
|
||||
.create_ah = efa_create_ah,
|
||||
|
@ -212,6 +213,7 @@ static const struct ib_device_ops efa_dev_ops = {
|
|||
.destroy_ah = efa_destroy_ah,
|
||||
.destroy_cq = efa_destroy_cq,
|
||||
.destroy_qp = efa_destroy_qp,
|
||||
.get_hw_stats = efa_get_hw_stats,
|
||||
.get_link_layer = efa_port_link_layer,
|
||||
.get_port_immutable = efa_get_port_immutable,
|
||||
.mmap = efa_mmap,
|
||||
|
|
|
@ -41,6 +41,33 @@ static inline u64 get_mmap_key(const struct efa_mmap_entry *efa)
|
|||
((u64)efa->mmap_page << PAGE_SHIFT);
|
||||
}
|
||||
|
||||
#define EFA_DEFINE_STATS(op) \
|
||||
op(EFA_TX_BYTES, "tx_bytes") \
|
||||
op(EFA_TX_PKTS, "tx_pkts") \
|
||||
op(EFA_RX_BYTES, "rx_bytes") \
|
||||
op(EFA_RX_PKTS, "rx_pkts") \
|
||||
op(EFA_RX_DROPS, "rx_drops") \
|
||||
op(EFA_SUBMITTED_CMDS, "submitted_cmds") \
|
||||
op(EFA_COMPLETED_CMDS, "completed_cmds") \
|
||||
op(EFA_NO_COMPLETION_CMDS, "no_completion_cmds") \
|
||||
op(EFA_KEEP_ALIVE_RCVD, "keep_alive_rcvd") \
|
||||
op(EFA_ALLOC_PD_ERR, "alloc_pd_err") \
|
||||
op(EFA_CREATE_QP_ERR, "create_qp_err") \
|
||||
op(EFA_REG_MR_ERR, "reg_mr_err") \
|
||||
op(EFA_ALLOC_UCONTEXT_ERR, "alloc_ucontext_err") \
|
||||
op(EFA_CREATE_AH_ERR, "create_ah_err")
|
||||
|
||||
#define EFA_STATS_ENUM(ename, name) ename,
|
||||
#define EFA_STATS_STR(ename, name) [ename] = name,
|
||||
|
||||
enum efa_hw_stats {
|
||||
EFA_DEFINE_STATS(EFA_STATS_ENUM)
|
||||
};
|
||||
|
||||
static const char *const efa_stats_names[] = {
|
||||
EFA_DEFINE_STATS(EFA_STATS_STR)
|
||||
};
|
||||
|
||||
#define EFA_CHUNK_PAYLOAD_SHIFT 12
|
||||
#define EFA_CHUNK_PAYLOAD_SIZE BIT(EFA_CHUNK_PAYLOAD_SHIFT)
|
||||
#define EFA_CHUNK_PAYLOAD_PTR_SIZE 8
|
||||
|
@ -121,7 +148,7 @@ static inline struct efa_ah *to_eah(struct ib_ah *ibah)
|
|||
}
|
||||
|
||||
#define field_avail(x, fld, sz) (offsetof(typeof(x), fld) + \
|
||||
sizeof(((typeof(x) *)0)->fld) <= (sz))
|
||||
FIELD_SIZEOF(typeof(x), fld) <= (sz))
|
||||
|
||||
#define is_reserved_cleared(reserved) \
|
||||
!memchr_inv(reserved, 0, sizeof(reserved))
|
||||
|
@ -306,7 +333,7 @@ int efa_query_port(struct ib_device *ibdev, u8 port,
|
|||
props->lmc = 1;
|
||||
|
||||
props->state = IB_PORT_ACTIVE;
|
||||
props->phys_state = 5;
|
||||
props->phys_state = IB_PORT_PHYS_STATE_LINK_UP;
|
||||
props->gid_tbl_len = 1;
|
||||
props->pkey_tbl_len = 1;
|
||||
props->active_speed = IB_SPEED_EDR;
|
||||
|
@ -1473,14 +1500,12 @@ int efa_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata)
|
|||
|
||||
ibdev_dbg(&dev->ibdev, "Deregister mr[%d]\n", ibmr->lkey);
|
||||
|
||||
if (mr->umem) {
|
||||
params.l_key = mr->ibmr.lkey;
|
||||
err = efa_com_dereg_mr(&dev->edev, ¶ms);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
ib_umem_release(mr->umem);
|
||||
params.l_key = mr->ibmr.lkey;
|
||||
err = efa_com_dereg_mr(&dev->edev, ¶ms);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
ib_umem_release(mr->umem);
|
||||
kfree(mr);
|
||||
|
||||
return 0;
|
||||
|
@ -1727,6 +1752,54 @@ void efa_destroy_ah(struct ib_ah *ibah, u32 flags)
|
|||
efa_ah_destroy(dev, ah);
|
||||
}
|
||||
|
||||
struct rdma_hw_stats *efa_alloc_hw_stats(struct ib_device *ibdev, u8 port_num)
|
||||
{
|
||||
return rdma_alloc_hw_stats_struct(efa_stats_names,
|
||||
ARRAY_SIZE(efa_stats_names),
|
||||
RDMA_HW_STATS_DEFAULT_LIFESPAN);
|
||||
}
|
||||
|
||||
int efa_get_hw_stats(struct ib_device *ibdev, struct rdma_hw_stats *stats,
|
||||
u8 port_num, int index)
|
||||
{
|
||||
struct efa_com_get_stats_params params = {};
|
||||
union efa_com_get_stats_result result;
|
||||
struct efa_dev *dev = to_edev(ibdev);
|
||||
struct efa_com_basic_stats *bs;
|
||||
struct efa_com_stats_admin *as;
|
||||
struct efa_stats *s;
|
||||
int err;
|
||||
|
||||
params.type = EFA_ADMIN_GET_STATS_TYPE_BASIC;
|
||||
params.scope = EFA_ADMIN_GET_STATS_SCOPE_ALL;
|
||||
|
||||
err = efa_com_get_stats(&dev->edev, ¶ms, &result);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
bs = &result.basic_stats;
|
||||
stats->value[EFA_TX_BYTES] = bs->tx_bytes;
|
||||
stats->value[EFA_TX_PKTS] = bs->tx_pkts;
|
||||
stats->value[EFA_RX_BYTES] = bs->rx_bytes;
|
||||
stats->value[EFA_RX_PKTS] = bs->rx_pkts;
|
||||
stats->value[EFA_RX_DROPS] = bs->rx_drops;
|
||||
|
||||
as = &dev->edev.aq.stats;
|
||||
stats->value[EFA_SUBMITTED_CMDS] = atomic64_read(&as->submitted_cmd);
|
||||
stats->value[EFA_COMPLETED_CMDS] = atomic64_read(&as->completed_cmd);
|
||||
stats->value[EFA_NO_COMPLETION_CMDS] = atomic64_read(&as->no_completion);
|
||||
|
||||
s = &dev->stats;
|
||||
stats->value[EFA_KEEP_ALIVE_RCVD] = atomic64_read(&s->keep_alive_rcvd);
|
||||
stats->value[EFA_ALLOC_PD_ERR] = atomic64_read(&s->sw_stats.alloc_pd_err);
|
||||
stats->value[EFA_CREATE_QP_ERR] = atomic64_read(&s->sw_stats.create_qp_err);
|
||||
stats->value[EFA_REG_MR_ERR] = atomic64_read(&s->sw_stats.reg_mr_err);
|
||||
stats->value[EFA_ALLOC_UCONTEXT_ERR] = atomic64_read(&s->sw_stats.alloc_ucontext_err);
|
||||
stats->value[EFA_CREATE_AH_ERR] = atomic64_read(&s->sw_stats.create_ah_err);
|
||||
|
||||
return ARRAY_SIZE(efa_stats_names);
|
||||
}
|
||||
|
||||
enum rdma_link_layer efa_port_link_layer(struct ib_device *ibdev,
|
||||
u8 port_num)
|
||||
{
|
||||
|
|
|
@ -4101,6 +4101,7 @@ def_access_ibp_counter(rc_dupreq);
|
|||
def_access_ibp_counter(rdma_seq);
|
||||
def_access_ibp_counter(unaligned);
|
||||
def_access_ibp_counter(seq_naks);
|
||||
def_access_ibp_counter(rc_crwaits);
|
||||
|
||||
static struct cntr_entry dev_cntrs[DEV_CNTR_LAST] = {
|
||||
[C_RCV_OVF] = RXE32_DEV_CNTR_ELEM(RcvOverflow, RCV_BUF_OVFL_CNT, CNTR_SYNTH),
|
||||
|
@ -5119,6 +5120,7 @@ static struct cntr_entry port_cntrs[PORT_CNTR_LAST] = {
|
|||
[C_SW_IBP_RDMA_SEQ] = SW_IBP_CNTR(RdmaSeq, rdma_seq),
|
||||
[C_SW_IBP_UNALIGNED] = SW_IBP_CNTR(Unaligned, unaligned),
|
||||
[C_SW_IBP_SEQ_NAK] = SW_IBP_CNTR(SeqNak, seq_naks),
|
||||
[C_SW_IBP_RC_CRWAITS] = SW_IBP_CNTR(RcCrWait, rc_crwaits),
|
||||
[C_SW_CPU_RC_ACKS] = CNTR_ELEM("RcAcks", 0, 0, CNTR_NORMAL,
|
||||
access_sw_cpu_rc_acks),
|
||||
[C_SW_CPU_RC_QACKS] = CNTR_ELEM("RcQacks", 0, 0, CNTR_NORMAL,
|
||||
|
|
|
@ -1245,6 +1245,7 @@ enum {
|
|||
C_SW_IBP_RDMA_SEQ,
|
||||
C_SW_IBP_UNALIGNED,
|
||||
C_SW_IBP_SEQ_NAK,
|
||||
C_SW_IBP_RC_CRWAITS,
|
||||
C_SW_CPU_RC_ACKS,
|
||||
C_SW_CPU_RC_QACKS,
|
||||
C_SW_CPU_RC_DELAYED_COMP,
|
||||
|
|
|
@ -2326,7 +2326,7 @@ struct opa_port_status_req {
|
|||
__be32 vl_select_mask;
|
||||
};
|
||||
|
||||
#define VL_MASK_ALL 0x000080ff
|
||||
#define VL_MASK_ALL 0x00000000000080ffUL
|
||||
|
||||
struct opa_port_status_rsp {
|
||||
__u8 port_num;
|
||||
|
@ -2625,15 +2625,14 @@ static int pma_get_opa_classportinfo(struct opa_pma_mad *pmp,
|
|||
}
|
||||
|
||||
static void a0_portstatus(struct hfi1_pportdata *ppd,
|
||||
struct opa_port_status_rsp *rsp, u32 vl_select_mask)
|
||||
struct opa_port_status_rsp *rsp)
|
||||
{
|
||||
if (!is_bx(ppd->dd)) {
|
||||
unsigned long vl;
|
||||
u64 sum_vl_xmit_wait = 0;
|
||||
u32 vl_all_mask = VL_MASK_ALL;
|
||||
unsigned long vl_all_mask = VL_MASK_ALL;
|
||||
|
||||
for_each_set_bit(vl, (unsigned long *)&(vl_all_mask),
|
||||
8 * sizeof(vl_all_mask)) {
|
||||
for_each_set_bit(vl, &vl_all_mask, BITS_PER_LONG) {
|
||||
u64 tmp = sum_vl_xmit_wait +
|
||||
read_port_cntr(ppd, C_TX_WAIT_VL,
|
||||
idx_from_vl(vl));
|
||||
|
@ -2730,12 +2729,12 @@ static int pma_get_opa_portstatus(struct opa_pma_mad *pmp,
|
|||
(struct opa_port_status_req *)pmp->data;
|
||||
struct hfi1_devdata *dd = dd_from_ibdev(ibdev);
|
||||
struct opa_port_status_rsp *rsp;
|
||||
u32 vl_select_mask = be32_to_cpu(req->vl_select_mask);
|
||||
unsigned long vl_select_mask = be32_to_cpu(req->vl_select_mask);
|
||||
unsigned long vl;
|
||||
size_t response_data_size;
|
||||
u32 nports = be32_to_cpu(pmp->mad_hdr.attr_mod) >> 24;
|
||||
u8 port_num = req->port_num;
|
||||
u8 num_vls = hweight32(vl_select_mask);
|
||||
u8 num_vls = hweight64(vl_select_mask);
|
||||
struct _vls_pctrs *vlinfo;
|
||||
struct hfi1_ibport *ibp = to_iport(ibdev, port);
|
||||
struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
|
||||
|
@ -2770,7 +2769,7 @@ static int pma_get_opa_portstatus(struct opa_pma_mad *pmp,
|
|||
|
||||
hfi1_read_link_quality(dd, &rsp->link_quality_indicator);
|
||||
|
||||
rsp->vl_select_mask = cpu_to_be32(vl_select_mask);
|
||||
rsp->vl_select_mask = cpu_to_be32((u32)vl_select_mask);
|
||||
rsp->port_xmit_data = cpu_to_be64(read_dev_cntr(dd, C_DC_XMIT_FLITS,
|
||||
CNTR_INVALID_VL));
|
||||
rsp->port_rcv_data = cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_FLITS,
|
||||
|
@ -2841,8 +2840,7 @@ static int pma_get_opa_portstatus(struct opa_pma_mad *pmp,
|
|||
* So in the for_each_set_bit() loop below, we don't need
|
||||
* any additional checks for vl.
|
||||
*/
|
||||
for_each_set_bit(vl, (unsigned long *)&(vl_select_mask),
|
||||
8 * sizeof(vl_select_mask)) {
|
||||
for_each_set_bit(vl, &vl_select_mask, BITS_PER_LONG) {
|
||||
memset(vlinfo, 0, sizeof(*vlinfo));
|
||||
|
||||
tmp = read_dev_cntr(dd, C_DC_RX_FLIT_VL, idx_from_vl(vl));
|
||||
|
@ -2883,7 +2881,7 @@ static int pma_get_opa_portstatus(struct opa_pma_mad *pmp,
|
|||
vfi++;
|
||||
}
|
||||
|
||||
a0_portstatus(ppd, rsp, vl_select_mask);
|
||||
a0_portstatus(ppd, rsp);
|
||||
|
||||
if (resp_len)
|
||||
*resp_len += response_data_size;
|
||||
|
@ -2930,16 +2928,14 @@ static u64 get_error_counter_summary(struct ib_device *ibdev, u8 port,
|
|||
return error_counter_summary;
|
||||
}
|
||||
|
||||
static void a0_datacounters(struct hfi1_pportdata *ppd, struct _port_dctrs *rsp,
|
||||
u32 vl_select_mask)
|
||||
static void a0_datacounters(struct hfi1_pportdata *ppd, struct _port_dctrs *rsp)
|
||||
{
|
||||
if (!is_bx(ppd->dd)) {
|
||||
unsigned long vl;
|
||||
u64 sum_vl_xmit_wait = 0;
|
||||
u32 vl_all_mask = VL_MASK_ALL;
|
||||
unsigned long vl_all_mask = VL_MASK_ALL;
|
||||
|
||||
for_each_set_bit(vl, (unsigned long *)&(vl_all_mask),
|
||||
8 * sizeof(vl_all_mask)) {
|
||||
for_each_set_bit(vl, &vl_all_mask, BITS_PER_LONG) {
|
||||
u64 tmp = sum_vl_xmit_wait +
|
||||
read_port_cntr(ppd, C_TX_WAIT_VL,
|
||||
idx_from_vl(vl));
|
||||
|
@ -2994,7 +2990,7 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp,
|
|||
u64 port_mask;
|
||||
u8 port_num;
|
||||
unsigned long vl;
|
||||
u32 vl_select_mask;
|
||||
unsigned long vl_select_mask;
|
||||
int vfi;
|
||||
u16 link_width;
|
||||
u16 link_speed;
|
||||
|
@ -3071,8 +3067,7 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp,
|
|||
* So in the for_each_set_bit() loop below, we don't need
|
||||
* any additional checks for vl.
|
||||
*/
|
||||
for_each_set_bit(vl, (unsigned long *)&(vl_select_mask),
|
||||
8 * sizeof(req->vl_select_mask)) {
|
||||
for_each_set_bit(vl, &vl_select_mask, BITS_PER_LONG) {
|
||||
memset(vlinfo, 0, sizeof(*vlinfo));
|
||||
|
||||
rsp->vls[vfi].port_vl_xmit_data =
|
||||
|
@ -3120,7 +3115,7 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp,
|
|||
vfi++;
|
||||
}
|
||||
|
||||
a0_datacounters(ppd, rsp, vl_select_mask);
|
||||
a0_datacounters(ppd, rsp);
|
||||
|
||||
if (resp_len)
|
||||
*resp_len += response_data_size;
|
||||
|
@ -3215,7 +3210,7 @@ static int pma_get_opa_porterrors(struct opa_pma_mad *pmp,
|
|||
struct _vls_ectrs *vlinfo;
|
||||
unsigned long vl;
|
||||
u64 port_mask, tmp;
|
||||
u32 vl_select_mask;
|
||||
unsigned long vl_select_mask;
|
||||
int vfi;
|
||||
|
||||
req = (struct opa_port_error_counters64_msg *)pmp->data;
|
||||
|
@ -3273,8 +3268,7 @@ static int pma_get_opa_porterrors(struct opa_pma_mad *pmp,
|
|||
vlinfo = &rsp->vls[0];
|
||||
vfi = 0;
|
||||
vl_select_mask = be32_to_cpu(req->vl_select_mask);
|
||||
for_each_set_bit(vl, (unsigned long *)&(vl_select_mask),
|
||||
8 * sizeof(req->vl_select_mask)) {
|
||||
for_each_set_bit(vl, &vl_select_mask, BITS_PER_LONG) {
|
||||
memset(vlinfo, 0, sizeof(*vlinfo));
|
||||
rsp->vls[vfi].port_vl_xmit_discards =
|
||||
cpu_to_be64(read_port_cntr(ppd, C_SW_XMIT_DSCD_VL,
|
||||
|
@ -3485,7 +3479,7 @@ static int pma_set_opa_portstatus(struct opa_pma_mad *pmp,
|
|||
u32 nports = be32_to_cpu(pmp->mad_hdr.attr_mod) >> 24;
|
||||
u64 portn = be64_to_cpu(req->port_select_mask[3]);
|
||||
u32 counter_select = be32_to_cpu(req->counter_select_mask);
|
||||
u32 vl_select_mask = VL_MASK_ALL; /* clear all per-vl cnts */
|
||||
unsigned long vl_select_mask = VL_MASK_ALL; /* clear all per-vl cnts */
|
||||
unsigned long vl;
|
||||
|
||||
if ((nports != 1) || (portn != 1 << port)) {
|
||||
|
@ -3579,8 +3573,7 @@ static int pma_set_opa_portstatus(struct opa_pma_mad *pmp,
|
|||
if (counter_select & CS_UNCORRECTABLE_ERRORS)
|
||||
write_dev_cntr(dd, C_DC_UNC_ERR, CNTR_INVALID_VL, 0);
|
||||
|
||||
for_each_set_bit(vl, (unsigned long *)&(vl_select_mask),
|
||||
8 * sizeof(vl_select_mask)) {
|
||||
for_each_set_bit(vl, &vl_select_mask, BITS_PER_LONG) {
|
||||
if (counter_select & CS_PORT_XMIT_DATA)
|
||||
write_port_cntr(ppd, C_TX_FLIT_VL, idx_from_vl(vl), 0);
|
||||
|
||||
|
|
|
@ -595,11 +595,8 @@ int hfi1_make_rc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
|
|||
case IB_WR_SEND_WITH_IMM:
|
||||
case IB_WR_SEND_WITH_INV:
|
||||
/* If no credit, return. */
|
||||
if (!(qp->s_flags & RVT_S_UNLIMITED_CREDIT) &&
|
||||
rvt_cmp_msn(wqe->ssn, qp->s_lsn + 1) > 0) {
|
||||
qp->s_flags |= RVT_S_WAIT_SSN_CREDIT;
|
||||
if (!rvt_rc_credit_avail(qp, wqe))
|
||||
goto bail;
|
||||
}
|
||||
if (len > pmtu) {
|
||||
qp->s_state = OP(SEND_FIRST);
|
||||
len = pmtu;
|
||||
|
@ -632,11 +629,8 @@ int hfi1_make_rc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
|
|||
goto no_flow_control;
|
||||
case IB_WR_RDMA_WRITE_WITH_IMM:
|
||||
/* If no credit, return. */
|
||||
if (!(qp->s_flags & RVT_S_UNLIMITED_CREDIT) &&
|
||||
rvt_cmp_msn(wqe->ssn, qp->s_lsn + 1) > 0) {
|
||||
qp->s_flags |= RVT_S_WAIT_SSN_CREDIT;
|
||||
if (!rvt_rc_credit_avail(qp, wqe))
|
||||
goto bail;
|
||||
}
|
||||
no_flow_control:
|
||||
put_ib_reth_vaddr(
|
||||
wqe->rdma_wr.remote_addr,
|
||||
|
@ -1483,6 +1477,11 @@ static void update_num_rd_atomic(struct rvt_qp *qp, u32 psn,
|
|||
req->ack_pending = cur_seg - req->comp_seg;
|
||||
priv->pending_tid_r_segs += req->ack_pending;
|
||||
qp->s_num_rd_atomic += req->ack_pending;
|
||||
trace_hfi1_tid_req_update_num_rd_atomic(qp, 0,
|
||||
wqe->wr.opcode,
|
||||
wqe->psn,
|
||||
wqe->lpsn,
|
||||
req);
|
||||
} else {
|
||||
priv->pending_tid_r_segs += req->total_segs;
|
||||
qp->s_num_rd_atomic += req->total_segs;
|
||||
|
|
|
@ -2646,6 +2646,9 @@ static bool handle_read_kdeth_eflags(struct hfi1_ctxtdata *rcd,
|
|||
u32 fpsn;
|
||||
|
||||
lockdep_assert_held(&qp->r_lock);
|
||||
trace_hfi1_rsp_read_kdeth_eflags(qp, ibpsn);
|
||||
trace_hfi1_sender_read_kdeth_eflags(qp);
|
||||
trace_hfi1_tid_read_sender_kdeth_eflags(qp, 0);
|
||||
spin_lock(&qp->s_lock);
|
||||
/* If the psn is out of valid range, drop the packet */
|
||||
if (cmp_psn(ibpsn, qp->s_last_psn) < 0 ||
|
||||
|
@ -2710,6 +2713,8 @@ static bool handle_read_kdeth_eflags(struct hfi1_ctxtdata *rcd,
|
|||
goto s_unlock;
|
||||
|
||||
req = wqe_to_tid_req(wqe);
|
||||
trace_hfi1_tid_req_read_kdeth_eflags(qp, 0, wqe->wr.opcode, wqe->psn,
|
||||
wqe->lpsn, req);
|
||||
switch (rcv_type) {
|
||||
case RHF_RCV_TYPE_EXPECTED:
|
||||
switch (rte) {
|
||||
|
@ -2724,6 +2729,9 @@ static bool handle_read_kdeth_eflags(struct hfi1_ctxtdata *rcd,
|
|||
* packets that could be still in the fabric.
|
||||
*/
|
||||
flow = &req->flows[req->clear_tail];
|
||||
trace_hfi1_tid_flow_read_kdeth_eflags(qp,
|
||||
req->clear_tail,
|
||||
flow);
|
||||
if (priv->s_flags & HFI1_R_TID_SW_PSN) {
|
||||
diff = cmp_psn(psn,
|
||||
flow->flow_state.r_next_psn);
|
||||
|
|
|
@ -627,6 +627,12 @@ DEFINE_EVENT(/* event */
|
|||
TP_ARGS(qp, index, flow)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(/* event */
|
||||
hfi1_tid_flow_template, hfi1_tid_flow_read_kdeth_eflags,
|
||||
TP_PROTO(struct rvt_qp *qp, int index, struct tid_rdma_flow *flow),
|
||||
TP_ARGS(qp, index, flow)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(/* tid_node */
|
||||
hfi1_tid_node_template,
|
||||
TP_PROTO(struct rvt_qp *qp, const char *msg, u32 index, u32 base,
|
||||
|
@ -851,6 +857,12 @@ DEFINE_EVENT(/* event */
|
|||
TP_ARGS(qp, psn)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(/* event */
|
||||
hfi1_responder_info_template, hfi1_rsp_read_kdeth_eflags,
|
||||
TP_PROTO(struct rvt_qp *qp, u32 psn),
|
||||
TP_ARGS(qp, psn)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(/* sender_info */
|
||||
hfi1_sender_info_template,
|
||||
TP_PROTO(struct rvt_qp *qp),
|
||||
|
@ -955,6 +967,12 @@ DEFINE_EVENT(/* event */
|
|||
TP_ARGS(qp)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(/* event */
|
||||
hfi1_sender_info_template, hfi1_sender_read_kdeth_eflags,
|
||||
TP_PROTO(struct rvt_qp *qp),
|
||||
TP_ARGS(qp)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(/* tid_read_sender */
|
||||
hfi1_tid_read_sender_template,
|
||||
TP_PROTO(struct rvt_qp *qp, char newreq),
|
||||
|
@ -1015,6 +1033,12 @@ DEFINE_EVENT(/* event */
|
|||
TP_ARGS(qp, newreq)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(/* event */
|
||||
hfi1_tid_read_sender_template, hfi1_tid_read_sender_kdeth_eflags,
|
||||
TP_PROTO(struct rvt_qp *qp, char newreq),
|
||||
TP_ARGS(qp, newreq)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(/* tid_rdma_request */
|
||||
hfi1_tid_rdma_request_template,
|
||||
TP_PROTO(struct rvt_qp *qp, char newreq, u8 opcode, u32 psn, u32 lpsn,
|
||||
|
@ -1215,6 +1239,13 @@ DEFINE_EVENT(/* event */
|
|||
TP_ARGS(qp, newreq, opcode, psn, lpsn, req)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(/* event */
|
||||
hfi1_tid_rdma_request_template, hfi1_tid_req_read_kdeth_eflags,
|
||||
TP_PROTO(struct rvt_qp *qp, char newreq, u8 opcode, u32 psn, u32 lpsn,
|
||||
struct tid_rdma_request *req),
|
||||
TP_ARGS(qp, newreq, opcode, psn, lpsn, req)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(/* event */
|
||||
hfi1_tid_rdma_request_template, hfi1_tid_req_make_rc_ack_write,
|
||||
TP_PROTO(struct rvt_qp *qp, char newreq, u8 opcode, u32 psn, u32 lpsn,
|
||||
|
@ -1229,6 +1260,13 @@ DEFINE_EVENT(/* event */
|
|||
TP_ARGS(qp, newreq, opcode, psn, lpsn, req)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(/* event */
|
||||
hfi1_tid_rdma_request_template, hfi1_tid_req_update_num_rd_atomic,
|
||||
TP_PROTO(struct rvt_qp *qp, char newreq, u8 opcode, u32 psn, u32 lpsn,
|
||||
struct tid_rdma_request *req),
|
||||
TP_ARGS(qp, newreq, opcode, psn, lpsn, req)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(/* rc_rcv_err */
|
||||
hfi1_rc_rcv_err_template,
|
||||
TP_PROTO(struct rvt_qp *qp, u32 opcode, u32 psn, int diff),
|
||||
|
|
|
@ -110,12 +110,6 @@ enum pkt_q_sdma_state {
|
|||
SDMA_PKT_Q_DEFERRED,
|
||||
};
|
||||
|
||||
/*
|
||||
* Maximum retry attempts to submit a TX request
|
||||
* before putting the process to sleep.
|
||||
*/
|
||||
#define MAX_DEFER_RETRY_COUNT 1
|
||||
|
||||
#define SDMA_IOWAIT_TIMEOUT 1000 /* in milliseconds */
|
||||
|
||||
#define SDMA_DBG(req, fmt, ...) \
|
||||
|
|
|
@ -874,16 +874,17 @@ int hfi1_verbs_send_dma(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
|
|||
else
|
||||
pbc |= (ib_is_sc5(sc5) << PBC_DC_INFO_SHIFT);
|
||||
|
||||
if (unlikely(hfi1_dbg_should_fault_tx(qp, ps->opcode)))
|
||||
pbc = hfi1_fault_tx(qp, ps->opcode, pbc);
|
||||
pbc = create_pbc(ppd,
|
||||
pbc,
|
||||
qp->srate_mbps,
|
||||
vl,
|
||||
plen);
|
||||
|
||||
/* Update HCRC based on packet opcode */
|
||||
pbc = update_hcrc(ps->opcode, pbc);
|
||||
if (unlikely(hfi1_dbg_should_fault_tx(qp, ps->opcode)))
|
||||
pbc = hfi1_fault_tx(qp, ps->opcode, pbc);
|
||||
else
|
||||
/* Update HCRC based on packet opcode */
|
||||
pbc = update_hcrc(ps->opcode, pbc);
|
||||
}
|
||||
tx->wqe = qp->s_wqe;
|
||||
ret = build_verbs_tx_desc(tx->sde, len, tx, ahg_info, pbc);
|
||||
|
@ -1030,12 +1031,12 @@ int hfi1_verbs_send_pio(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
|
|||
else
|
||||
pbc |= (ib_is_sc5(sc5) << PBC_DC_INFO_SHIFT);
|
||||
|
||||
pbc = create_pbc(ppd, pbc, qp->srate_mbps, vl, plen);
|
||||
if (unlikely(hfi1_dbg_should_fault_tx(qp, ps->opcode)))
|
||||
pbc = hfi1_fault_tx(qp, ps->opcode, pbc);
|
||||
pbc = create_pbc(ppd, pbc, qp->srate_mbps, vl, plen);
|
||||
|
||||
/* Update HCRC based on packet opcode */
|
||||
pbc = update_hcrc(ps->opcode, pbc);
|
||||
else
|
||||
/* Update HCRC based on packet opcode */
|
||||
pbc = update_hcrc(ps->opcode, pbc);
|
||||
}
|
||||
if (cb)
|
||||
iowait_pio_inc(&priv->s_iowait);
|
||||
|
|
|
@ -8,8 +8,6 @@ config INFINIBAND_HNS
|
|||
is used in Hisilicon Hip06 and more further ICT SoC based on
|
||||
platform device.
|
||||
|
||||
To compile HIP06 or HIP08 driver as module, choose M here.
|
||||
|
||||
config INFINIBAND_HNS_HIP06
|
||||
tristate "Hisilicon Hip06 Family RoCE support"
|
||||
depends on INFINIBAND_HNS && HNS && HNS_DSAF && HNS_ENET
|
||||
|
@ -17,15 +15,9 @@ config INFINIBAND_HNS_HIP06
|
|||
RoCE driver support for Hisilicon RoCE engine in Hisilicon Hip06 and
|
||||
Hip07 SoC. These RoCE engines are platform devices.
|
||||
|
||||
To compile this driver, choose Y here: if INFINIBAND_HNS is m, this
|
||||
module will be called hns-roce-hw-v1
|
||||
|
||||
config INFINIBAND_HNS_HIP08
|
||||
tristate "Hisilicon Hip08 Family RoCE support"
|
||||
depends on INFINIBAND_HNS && PCI && HNS3
|
||||
---help---
|
||||
RoCE driver support for Hisilicon RoCE engine in Hisilicon Hip08 SoC.
|
||||
The RoCE engine is a PCI device.
|
||||
|
||||
To compile this driver, choose Y here: if INFINIBAND_HNS is m, this
|
||||
module will be called hns-roce-hw-v2.
|
||||
|
|
|
@ -66,11 +66,9 @@ int hns_roce_create_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr,
|
|||
HNS_ROCE_VLAN_SL_SHIFT;
|
||||
}
|
||||
|
||||
ah->av.port_pd = cpu_to_le32(to_hr_pd(ibah->pd)->pdn |
|
||||
(rdma_ah_get_port_num(ah_attr) <<
|
||||
HNS_ROCE_PORT_NUM_SHIFT));
|
||||
ah->av.port = rdma_ah_get_port_num(ah_attr);
|
||||
ah->av.gid_index = grh->sgid_index;
|
||||
ah->av.vlan = cpu_to_le16(vlan_tag);
|
||||
ah->av.vlan = vlan_tag;
|
||||
ah->av.vlan_en = vlan_en;
|
||||
dev_dbg(dev, "gid_index = 0x%x,vlan = 0x%x\n", ah->av.gid_index,
|
||||
ah->av.vlan);
|
||||
|
@ -79,8 +77,7 @@ int hns_roce_create_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr,
|
|||
ah->av.stat_rate = IB_RATE_10_GBPS;
|
||||
|
||||
memcpy(ah->av.dgid, grh->dgid.raw, HNS_ROCE_GID_SIZE);
|
||||
ah->av.sl_tclass_flowlabel = cpu_to_le32(rdma_ah_get_sl(ah_attr) <<
|
||||
HNS_ROCE_SL_SHIFT);
|
||||
ah->av.sl = rdma_ah_get_sl(ah_attr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -91,17 +88,11 @@ int hns_roce_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr)
|
|||
|
||||
memset(ah_attr, 0, sizeof(*ah_attr));
|
||||
|
||||
rdma_ah_set_sl(ah_attr, (le32_to_cpu(ah->av.sl_tclass_flowlabel) >>
|
||||
HNS_ROCE_SL_SHIFT));
|
||||
rdma_ah_set_port_num(ah_attr, (le32_to_cpu(ah->av.port_pd) >>
|
||||
HNS_ROCE_PORT_NUM_SHIFT));
|
||||
rdma_ah_set_sl(ah_attr, ah->av.sl);
|
||||
rdma_ah_set_port_num(ah_attr, ah->av.port);
|
||||
rdma_ah_set_static_rate(ah_attr, ah->av.stat_rate);
|
||||
rdma_ah_set_grh(ah_attr, NULL,
|
||||
(le32_to_cpu(ah->av.sl_tclass_flowlabel) &
|
||||
HNS_ROCE_FLOW_LABEL_MASK), ah->av.gid_index,
|
||||
ah->av.hop_limit,
|
||||
(le32_to_cpu(ah->av.sl_tclass_flowlabel) >>
|
||||
HNS_ROCE_TCLASS_SHIFT));
|
||||
rdma_ah_set_grh(ah_attr, NULL, ah->av.flowlabel,
|
||||
ah->av.gid_index, ah->av.hop_limit, ah->av.tclass);
|
||||
rdma_ah_set_dgid_raw(ah_attr, ah->av.dgid);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -211,7 +211,6 @@ int hns_roce_cmd_init(struct hns_roce_dev *hr_dev)
|
|||
mutex_init(&hr_dev->cmd.hcr_mutex);
|
||||
sema_init(&hr_dev->cmd.poll_sem, 1);
|
||||
hr_dev->cmd.use_events = 0;
|
||||
hr_dev->cmd.toggle = 1;
|
||||
hr_dev->cmd.max_cmds = CMD_MAX_NUM;
|
||||
hr_dev->cmd.pool = dma_pool_create("hns_roce_cmd", dev,
|
||||
HNS_ROCE_MAILBOX_SIZE,
|
||||
|
@ -252,23 +251,15 @@ int hns_roce_cmd_use_events(struct hns_roce_dev *hr_dev)
|
|||
hr_cmd->token_mask = CMD_TOKEN_MASK;
|
||||
hr_cmd->use_events = 1;
|
||||
|
||||
down(&hr_cmd->poll_sem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hns_roce_cmd_use_polling(struct hns_roce_dev *hr_dev)
|
||||
{
|
||||
struct hns_roce_cmdq *hr_cmd = &hr_dev->cmd;
|
||||
int i;
|
||||
|
||||
hr_cmd->use_events = 0;
|
||||
|
||||
for (i = 0; i < hr_cmd->max_cmds; ++i)
|
||||
down(&hr_cmd->event_sem);
|
||||
|
||||
kfree(hr_cmd->context);
|
||||
up(&hr_cmd->poll_sem);
|
||||
hr_cmd->use_events = 0;
|
||||
}
|
||||
|
||||
struct hns_roce_cmd_mailbox
|
||||
|
|
|
@ -83,7 +83,6 @@ static int hns_roce_sw2hw_cq(struct hns_roce_dev *dev,
|
|||
|
||||
static int hns_roce_cq_alloc(struct hns_roce_dev *hr_dev, int nent,
|
||||
struct hns_roce_mtt *hr_mtt,
|
||||
struct hns_roce_uar *hr_uar,
|
||||
struct hns_roce_cq *hr_cq, int vector)
|
||||
{
|
||||
struct hns_roce_cmd_mailbox *mailbox;
|
||||
|
@ -154,7 +153,6 @@ static int hns_roce_cq_alloc(struct hns_roce_dev *hr_dev, int nent,
|
|||
|
||||
hr_cq->cons_index = 0;
|
||||
hr_cq->arm_sn = 1;
|
||||
hr_cq->uar = hr_uar;
|
||||
|
||||
atomic_set(&hr_cq->refcount, 1);
|
||||
init_completion(&hr_cq->free);
|
||||
|
@ -298,21 +296,127 @@ static void hns_roce_ib_free_cq_buf(struct hns_roce_dev *hr_dev,
|
|||
&buf->hr_buf);
|
||||
}
|
||||
|
||||
static int create_user_cq(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_cq *hr_cq,
|
||||
struct ib_udata *udata,
|
||||
struct hns_roce_ib_create_cq_resp *resp,
|
||||
int cq_entries)
|
||||
{
|
||||
struct hns_roce_ib_create_cq ucmd;
|
||||
struct device *dev = hr_dev->dev;
|
||||
int ret;
|
||||
struct hns_roce_ucontext *context = rdma_udata_to_drv_context(
|
||||
udata, struct hns_roce_ucontext, ibucontext);
|
||||
|
||||
if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd))) {
|
||||
dev_err(dev, "Failed to copy_from_udata.\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
/* Get user space address, write it into mtt table */
|
||||
ret = hns_roce_ib_get_cq_umem(hr_dev, udata, &hr_cq->hr_buf,
|
||||
&hr_cq->umem, ucmd.buf_addr,
|
||||
cq_entries);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to get_cq_umem.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) &&
|
||||
(udata->outlen >= sizeof(*resp))) {
|
||||
ret = hns_roce_db_map_user(context, udata, ucmd.db_addr,
|
||||
&hr_cq->db);
|
||||
if (ret) {
|
||||
dev_err(dev, "cq record doorbell map failed!\n");
|
||||
goto err_mtt;
|
||||
}
|
||||
hr_cq->db_en = 1;
|
||||
resp->cap_flags |= HNS_ROCE_SUPPORT_CQ_RECORD_DB;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_mtt:
|
||||
hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt);
|
||||
ib_umem_release(hr_cq->umem);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int create_kernel_cq(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_cq *hr_cq, int cq_entries)
|
||||
{
|
||||
struct device *dev = hr_dev->dev;
|
||||
struct hns_roce_uar *uar;
|
||||
int ret;
|
||||
|
||||
if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) {
|
||||
ret = hns_roce_alloc_db(hr_dev, &hr_cq->db, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
hr_cq->set_ci_db = hr_cq->db.db_record;
|
||||
*hr_cq->set_ci_db = 0;
|
||||
hr_cq->db_en = 1;
|
||||
}
|
||||
|
||||
/* Init mtt table and write buff address to mtt table */
|
||||
ret = hns_roce_ib_alloc_cq_buf(hr_dev, &hr_cq->hr_buf, cq_entries);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to alloc_cq_buf.\n");
|
||||
goto err_db;
|
||||
}
|
||||
|
||||
uar = &hr_dev->priv_uar;
|
||||
hr_cq->cq_db_l = hr_dev->reg_base + hr_dev->odb_offset +
|
||||
DB_REG_OFFSET * uar->index;
|
||||
|
||||
return 0;
|
||||
|
||||
err_db:
|
||||
if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB)
|
||||
hns_roce_free_db(hr_dev, &hr_cq->db);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void destroy_user_cq(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_cq *hr_cq,
|
||||
struct ib_udata *udata,
|
||||
struct hns_roce_ib_create_cq_resp *resp)
|
||||
{
|
||||
struct hns_roce_ucontext *context = rdma_udata_to_drv_context(
|
||||
udata, struct hns_roce_ucontext, ibucontext);
|
||||
|
||||
if ((hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) &&
|
||||
(udata->outlen >= sizeof(*resp)))
|
||||
hns_roce_db_unmap_user(context, &hr_cq->db);
|
||||
|
||||
hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt);
|
||||
ib_umem_release(hr_cq->umem);
|
||||
}
|
||||
|
||||
static void destroy_kernel_cq(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_cq *hr_cq)
|
||||
{
|
||||
hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt);
|
||||
hns_roce_ib_free_cq_buf(hr_dev, &hr_cq->hr_buf, hr_cq->ib_cq.cqe);
|
||||
|
||||
if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB)
|
||||
hns_roce_free_db(hr_dev, &hr_cq->db);
|
||||
}
|
||||
|
||||
int hns_roce_ib_create_cq(struct ib_cq *ib_cq,
|
||||
const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata)
|
||||
{
|
||||
struct hns_roce_dev *hr_dev = to_hr_dev(ib_cq->device);
|
||||
struct device *dev = hr_dev->dev;
|
||||
struct hns_roce_ib_create_cq ucmd;
|
||||
struct hns_roce_ib_create_cq_resp resp = {};
|
||||
struct hns_roce_cq *hr_cq = to_hr_cq(ib_cq);
|
||||
struct hns_roce_uar *uar = NULL;
|
||||
int vector = attr->comp_vector;
|
||||
int cq_entries = attr->cqe;
|
||||
int ret;
|
||||
struct hns_roce_ucontext *context = rdma_udata_to_drv_context(
|
||||
udata, struct hns_roce_ucontext, ibucontext);
|
||||
|
||||
if (cq_entries < 1 || cq_entries > hr_dev->caps.max_cqes) {
|
||||
dev_err(dev, "Creat CQ failed. entries=%d, max=%d\n",
|
||||
|
@ -328,61 +432,21 @@ int hns_roce_ib_create_cq(struct ib_cq *ib_cq,
|
|||
spin_lock_init(&hr_cq->lock);
|
||||
|
||||
if (udata) {
|
||||
if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd))) {
|
||||
dev_err(dev, "Failed to copy_from_udata.\n");
|
||||
ret = -EFAULT;
|
||||
goto err_cq;
|
||||
}
|
||||
|
||||
/* Get user space address, write it into mtt table */
|
||||
ret = hns_roce_ib_get_cq_umem(hr_dev, udata, &hr_cq->hr_buf,
|
||||
&hr_cq->umem, ucmd.buf_addr,
|
||||
cq_entries);
|
||||
ret = create_user_cq(hr_dev, hr_cq, udata, &resp, cq_entries);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to get_cq_umem.\n");
|
||||
dev_err(dev, "Create cq failed in user mode!\n");
|
||||
goto err_cq;
|
||||
}
|
||||
|
||||
if ((hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) &&
|
||||
(udata->outlen >= sizeof(resp))) {
|
||||
ret = hns_roce_db_map_user(context, udata, ucmd.db_addr,
|
||||
&hr_cq->db);
|
||||
if (ret) {
|
||||
dev_err(dev, "cq record doorbell map failed!\n");
|
||||
goto err_mtt;
|
||||
}
|
||||
hr_cq->db_en = 1;
|
||||
resp.cap_flags |= HNS_ROCE_SUPPORT_CQ_RECORD_DB;
|
||||
}
|
||||
|
||||
/* Get user space parameters */
|
||||
uar = &context->uar;
|
||||
} else {
|
||||
if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) {
|
||||
ret = hns_roce_alloc_db(hr_dev, &hr_cq->db, 1);
|
||||
if (ret)
|
||||
goto err_cq;
|
||||
|
||||
hr_cq->set_ci_db = hr_cq->db.db_record;
|
||||
*hr_cq->set_ci_db = 0;
|
||||
hr_cq->db_en = 1;
|
||||
}
|
||||
|
||||
/* Init mmt table and write buff address to mtt table */
|
||||
ret = hns_roce_ib_alloc_cq_buf(hr_dev, &hr_cq->hr_buf,
|
||||
cq_entries);
|
||||
ret = create_kernel_cq(hr_dev, hr_cq, cq_entries);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to alloc_cq_buf.\n");
|
||||
goto err_db;
|
||||
dev_err(dev, "Create cq failed in kernel mode!\n");
|
||||
goto err_cq;
|
||||
}
|
||||
|
||||
uar = &hr_dev->priv_uar;
|
||||
hr_cq->cq_db_l = hr_dev->reg_base + hr_dev->odb_offset +
|
||||
DB_REG_OFFSET * uar->index;
|
||||
}
|
||||
|
||||
/* Allocate cq index, fill cq_context */
|
||||
ret = hns_roce_cq_alloc(hr_dev, cq_entries, &hr_cq->hr_buf.hr_mtt, uar,
|
||||
ret = hns_roce_cq_alloc(hr_dev, cq_entries, &hr_cq->hr_buf.hr_mtt,
|
||||
hr_cq, vector);
|
||||
if (ret) {
|
||||
dev_err(dev, "Creat CQ .Failed to cq_alloc.\n");
|
||||
|
@ -416,20 +480,10 @@ int hns_roce_ib_create_cq(struct ib_cq *ib_cq,
|
|||
hns_roce_free_cq(hr_dev, hr_cq);
|
||||
|
||||
err_dbmap:
|
||||
if (udata && (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) &&
|
||||
(udata->outlen >= sizeof(resp)))
|
||||
hns_roce_db_unmap_user(context, &hr_cq->db);
|
||||
|
||||
err_mtt:
|
||||
hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt);
|
||||
ib_umem_release(hr_cq->umem);
|
||||
if (!udata)
|
||||
hns_roce_ib_free_cq_buf(hr_dev, &hr_cq->hr_buf,
|
||||
hr_cq->ib_cq.cqe);
|
||||
|
||||
err_db:
|
||||
if (!udata && (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB))
|
||||
hns_roce_free_db(hr_dev, &hr_cq->db);
|
||||
if (udata)
|
||||
destroy_user_cq(hr_dev, hr_cq, udata, &resp);
|
||||
else
|
||||
destroy_kernel_cq(hr_dev, hr_cq);
|
||||
|
||||
err_cq:
|
||||
return ret;
|
||||
|
|
|
@ -84,7 +84,6 @@
|
|||
#define HNS_ROCE_CEQ_ENTRY_SIZE 0x4
|
||||
#define HNS_ROCE_AEQ_ENTRY_SIZE 0x10
|
||||
|
||||
/* 4G/4K = 1M */
|
||||
#define HNS_ROCE_SL_SHIFT 28
|
||||
#define HNS_ROCE_TCLASS_SHIFT 20
|
||||
#define HNS_ROCE_FLOW_LABEL_MASK 0xfffff
|
||||
|
@ -128,6 +127,11 @@
|
|||
#define HNS_ROCE_IDX_QUE_ENTRY_SZ 4
|
||||
#define SRQ_DB_REG 0x230
|
||||
|
||||
/* The chip implementation of the consumer index is calculated
|
||||
* according to twice the actual EQ depth
|
||||
*/
|
||||
#define EQ_DEPTH_COEFF 2
|
||||
|
||||
enum {
|
||||
HNS_ROCE_SUPPORT_RQ_RECORD_DB = 1 << 0,
|
||||
HNS_ROCE_SUPPORT_SQ_RECORD_DB = 1 << 1,
|
||||
|
@ -322,7 +326,7 @@ struct hns_roce_hem_table {
|
|||
unsigned long num_hem;
|
||||
/* HEM entry record obj total num */
|
||||
unsigned long num_obj;
|
||||
/*Single obj size */
|
||||
/* Single obj size */
|
||||
unsigned long obj_size;
|
||||
unsigned long table_chunk_size;
|
||||
int lowmem;
|
||||
|
@ -343,7 +347,7 @@ struct hns_roce_mtt {
|
|||
|
||||
struct hns_roce_buf_region {
|
||||
int offset; /* page offset */
|
||||
u32 count; /* page count*/
|
||||
u32 count; /* page count */
|
||||
int hopnum; /* addressing hop num */
|
||||
};
|
||||
|
||||
|
@ -384,25 +388,25 @@ struct hns_roce_mr {
|
|||
u64 size; /* Address range of MR */
|
||||
u32 key; /* Key of MR */
|
||||
u32 pd; /* PD num of MR */
|
||||
u32 access;/* Access permission of MR */
|
||||
u32 access; /* Access permission of MR */
|
||||
u32 npages;
|
||||
int enabled; /* MR's active status */
|
||||
int type; /* MR's register type */
|
||||
u64 *pbl_buf;/* MR's PBL space */
|
||||
u64 *pbl_buf; /* MR's PBL space */
|
||||
dma_addr_t pbl_dma_addr; /* MR's PBL space PA */
|
||||
u32 pbl_size;/* PA number in the PBL */
|
||||
u64 pbl_ba;/* page table address */
|
||||
u32 l0_chunk_last_num;/* L0 last number */
|
||||
u32 l1_chunk_last_num;/* L1 last number */
|
||||
u64 **pbl_bt_l2;/* PBL BT L2 */
|
||||
u64 **pbl_bt_l1;/* PBL BT L1 */
|
||||
u64 *pbl_bt_l0;/* PBL BT L0 */
|
||||
dma_addr_t *pbl_l2_dma_addr;/* PBL BT L2 dma addr */
|
||||
dma_addr_t *pbl_l1_dma_addr;/* PBL BT L1 dma addr */
|
||||
dma_addr_t pbl_l0_dma_addr;/* PBL BT L0 dma addr */
|
||||
u32 pbl_ba_pg_sz;/* BT chunk page size */
|
||||
u32 pbl_buf_pg_sz;/* buf chunk page size */
|
||||
u32 pbl_hop_num;/* multi-hop number */
|
||||
u32 pbl_size; /* PA number in the PBL */
|
||||
u64 pbl_ba; /* page table address */
|
||||
u32 l0_chunk_last_num; /* L0 last number */
|
||||
u32 l1_chunk_last_num; /* L1 last number */
|
||||
u64 **pbl_bt_l2; /* PBL BT L2 */
|
||||
u64 **pbl_bt_l1; /* PBL BT L1 */
|
||||
u64 *pbl_bt_l0; /* PBL BT L0 */
|
||||
dma_addr_t *pbl_l2_dma_addr; /* PBL BT L2 dma addr */
|
||||
dma_addr_t *pbl_l1_dma_addr; /* PBL BT L1 dma addr */
|
||||
dma_addr_t pbl_l0_dma_addr; /* PBL BT L0 dma addr */
|
||||
u32 pbl_ba_pg_sz; /* BT chunk page size */
|
||||
u32 pbl_buf_pg_sz; /* buf chunk page size */
|
||||
u32 pbl_hop_num; /* multi-hop number */
|
||||
};
|
||||
|
||||
struct hns_roce_mr_table {
|
||||
|
@ -425,16 +429,16 @@ struct hns_roce_wq {
|
|||
u32 max_post;
|
||||
int max_gs;
|
||||
int offset;
|
||||
int wqe_shift;/* WQE size */
|
||||
int wqe_shift; /* WQE size */
|
||||
u32 head;
|
||||
u32 tail;
|
||||
void __iomem *db_reg_l;
|
||||
};
|
||||
|
||||
struct hns_roce_sge {
|
||||
int sge_cnt; /* SGE num */
|
||||
int sge_cnt; /* SGE num */
|
||||
int offset;
|
||||
int sge_shift;/* SGE size */
|
||||
int sge_shift; /* SGE size */
|
||||
};
|
||||
|
||||
struct hns_roce_buf_list {
|
||||
|
@ -569,14 +573,16 @@ struct hns_roce_raq_table {
|
|||
};
|
||||
|
||||
struct hns_roce_av {
|
||||
__le32 port_pd;
|
||||
u8 port;
|
||||
u8 gid_index;
|
||||
u8 stat_rate;
|
||||
u8 hop_limit;
|
||||
__le32 sl_tclass_flowlabel;
|
||||
u32 flowlabel;
|
||||
u8 sl;
|
||||
u8 tclass;
|
||||
u8 dgid[HNS_ROCE_GID_SIZE];
|
||||
u8 mac[ETH_ALEN];
|
||||
__le16 vlan;
|
||||
u16 vlan;
|
||||
bool vlan_en;
|
||||
};
|
||||
|
||||
|
@ -618,7 +624,6 @@ struct hns_roce_cmdq {
|
|||
* close device, switch into poll mode(non event mode)
|
||||
*/
|
||||
u8 use_events;
|
||||
u8 toggle;
|
||||
};
|
||||
|
||||
struct hns_roce_cmd_mailbox {
|
||||
|
@ -652,10 +657,8 @@ struct hns_roce_qp {
|
|||
u8 rdb_en;
|
||||
u8 sdb_en;
|
||||
u32 doorbell_qpn;
|
||||
__le32 sq_signal_bits;
|
||||
u32 sq_signal_bits;
|
||||
u32 sq_next_wqe;
|
||||
int sq_max_wqes_per_wr;
|
||||
int sq_spare_wqes;
|
||||
struct hns_roce_wq sq;
|
||||
|
||||
struct ib_umem *umem;
|
||||
|
@ -709,7 +712,7 @@ enum {
|
|||
};
|
||||
|
||||
struct hns_roce_ceqe {
|
||||
u32 comp;
|
||||
__le32 comp;
|
||||
};
|
||||
|
||||
struct hns_roce_aeqe {
|
||||
|
@ -752,7 +755,7 @@ struct hns_roce_eq {
|
|||
struct hns_roce_dev *hr_dev;
|
||||
void __iomem *doorbell;
|
||||
|
||||
int type_flag;/* Aeq:1 ceq:0 */
|
||||
int type_flag; /* Aeq:1 ceq:0 */
|
||||
int eqn;
|
||||
u32 entries;
|
||||
int log_entries;
|
||||
|
@ -798,22 +801,22 @@ struct hns_roce_caps {
|
|||
int local_ca_ack_delay;
|
||||
int num_uars;
|
||||
u32 phy_num_uars;
|
||||
u32 max_sq_sg; /* 2 */
|
||||
u32 max_sq_inline; /* 32 */
|
||||
u32 max_rq_sg; /* 2 */
|
||||
u32 max_sq_sg;
|
||||
u32 max_sq_inline;
|
||||
u32 max_rq_sg;
|
||||
u32 max_extend_sg;
|
||||
int num_qps; /* 256k */
|
||||
int num_qps;
|
||||
int reserved_qps;
|
||||
int num_qpc_timer;
|
||||
int num_cqc_timer;
|
||||
u32 max_srq_sg;
|
||||
int num_srqs;
|
||||
u32 max_wqes; /* 16k */
|
||||
u32 max_wqes;
|
||||
u32 max_srqs;
|
||||
u32 max_srq_wrs;
|
||||
u32 max_srq_sges;
|
||||
u32 max_sq_desc_sz; /* 64 */
|
||||
u32 max_rq_desc_sz; /* 64 */
|
||||
u32 max_sq_desc_sz;
|
||||
u32 max_rq_desc_sz;
|
||||
u32 max_srq_desc_sz;
|
||||
int max_qp_init_rdma;
|
||||
int max_qp_dest_rdma;
|
||||
|
@ -824,7 +827,7 @@ struct hns_roce_caps {
|
|||
int reserved_cqs;
|
||||
int reserved_srqs;
|
||||
u32 max_srqwqes;
|
||||
int num_aeq_vectors; /* 1 */
|
||||
int num_aeq_vectors;
|
||||
int num_comp_vectors;
|
||||
int num_other_vectors;
|
||||
int num_mtpts;
|
||||
|
@ -905,7 +908,7 @@ struct hns_roce_caps {
|
|||
u32 sl_num;
|
||||
u32 tsq_buf_pg_sz;
|
||||
u32 tpq_buf_pg_sz;
|
||||
u32 chunk_sz; /* chunk size in non multihop mode*/
|
||||
u32 chunk_sz; /* chunk size in non multihop mode */
|
||||
u64 flags;
|
||||
};
|
||||
|
||||
|
@ -991,16 +994,6 @@ struct hns_roce_hw {
|
|||
const struct ib_device_ops *hns_roce_dev_srq_ops;
|
||||
};
|
||||
|
||||
enum hns_phy_state {
|
||||
HNS_ROCE_PHY_SLEEP = 1,
|
||||
HNS_ROCE_PHY_POLLING = 2,
|
||||
HNS_ROCE_PHY_DISABLED = 3,
|
||||
HNS_ROCE_PHY_TRAINING = 4,
|
||||
HNS_ROCE_PHY_LINKUP = 5,
|
||||
HNS_ROCE_PHY_LINKERR = 6,
|
||||
HNS_ROCE_PHY_TEST = 7
|
||||
};
|
||||
|
||||
struct hns_roce_dev {
|
||||
struct ib_device ib_dev;
|
||||
struct platform_device *pdev;
|
||||
|
@ -1045,8 +1038,8 @@ struct hns_roce_dev {
|
|||
int loop_idc;
|
||||
u32 sdb_offset;
|
||||
u32 odb_offset;
|
||||
dma_addr_t tptr_dma_addr; /*only for hw v1*/
|
||||
u32 tptr_size; /*only for hw v1*/
|
||||
dma_addr_t tptr_dma_addr; /* only for hw v1 */
|
||||
u32 tptr_size; /* only for hw v1 */
|
||||
const struct hns_roce_hw *hw;
|
||||
void *priv;
|
||||
struct workqueue_struct *irq_workq;
|
||||
|
|
|
@ -41,29 +41,57 @@
|
|||
|
||||
bool hns_roce_check_whether_mhop(struct hns_roce_dev *hr_dev, u32 type)
|
||||
{
|
||||
if ((hr_dev->caps.qpc_hop_num && type == HEM_TYPE_QPC) ||
|
||||
(hr_dev->caps.mpt_hop_num && type == HEM_TYPE_MTPT) ||
|
||||
(hr_dev->caps.cqc_hop_num && type == HEM_TYPE_CQC) ||
|
||||
(hr_dev->caps.srqc_hop_num && type == HEM_TYPE_SRQC) ||
|
||||
(hr_dev->caps.sccc_hop_num && type == HEM_TYPE_SCCC) ||
|
||||
(hr_dev->caps.qpc_timer_hop_num && type == HEM_TYPE_QPC_TIMER) ||
|
||||
(hr_dev->caps.cqc_timer_hop_num && type == HEM_TYPE_CQC_TIMER) ||
|
||||
(hr_dev->caps.cqe_hop_num && type == HEM_TYPE_CQE) ||
|
||||
(hr_dev->caps.mtt_hop_num && type == HEM_TYPE_MTT) ||
|
||||
(hr_dev->caps.srqwqe_hop_num && type == HEM_TYPE_SRQWQE) ||
|
||||
(hr_dev->caps.idx_hop_num && type == HEM_TYPE_IDX))
|
||||
return true;
|
||||
int hop_num = 0;
|
||||
|
||||
return false;
|
||||
switch (type) {
|
||||
case HEM_TYPE_QPC:
|
||||
hop_num = hr_dev->caps.qpc_hop_num;
|
||||
break;
|
||||
case HEM_TYPE_MTPT:
|
||||
hop_num = hr_dev->caps.mpt_hop_num;
|
||||
break;
|
||||
case HEM_TYPE_CQC:
|
||||
hop_num = hr_dev->caps.cqc_hop_num;
|
||||
break;
|
||||
case HEM_TYPE_SRQC:
|
||||
hop_num = hr_dev->caps.srqc_hop_num;
|
||||
break;
|
||||
case HEM_TYPE_SCCC:
|
||||
hop_num = hr_dev->caps.sccc_hop_num;
|
||||
break;
|
||||
case HEM_TYPE_QPC_TIMER:
|
||||
hop_num = hr_dev->caps.qpc_timer_hop_num;
|
||||
break;
|
||||
case HEM_TYPE_CQC_TIMER:
|
||||
hop_num = hr_dev->caps.cqc_timer_hop_num;
|
||||
break;
|
||||
case HEM_TYPE_CQE:
|
||||
hop_num = hr_dev->caps.cqe_hop_num;
|
||||
break;
|
||||
case HEM_TYPE_MTT:
|
||||
hop_num = hr_dev->caps.mtt_hop_num;
|
||||
break;
|
||||
case HEM_TYPE_SRQWQE:
|
||||
hop_num = hr_dev->caps.srqwqe_hop_num;
|
||||
break;
|
||||
case HEM_TYPE_IDX:
|
||||
hop_num = hr_dev->caps.idx_hop_num;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return hop_num ? true : false;
|
||||
}
|
||||
|
||||
static bool hns_roce_check_hem_null(struct hns_roce_hem **hem, u64 start_idx,
|
||||
u32 bt_chunk_num)
|
||||
u32 bt_chunk_num, u64 hem_max_num)
|
||||
{
|
||||
int i;
|
||||
u64 check_max_num = start_idx + bt_chunk_num;
|
||||
u64 i;
|
||||
|
||||
for (i = 0; i < bt_chunk_num; i++)
|
||||
if (hem[start_idx + i])
|
||||
for (i = start_idx; (i < check_max_num) && (i < hem_max_num); i++)
|
||||
if (hem[i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -92,17 +120,13 @@ static int hns_roce_get_bt_num(u32 table_type, u32 hop_num)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int hns_roce_calc_hem_mhop(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_hem_table *table, unsigned long *obj,
|
||||
struct hns_roce_hem_mhop *mhop)
|
||||
static int get_hem_table_config(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_hem_mhop *mhop,
|
||||
u32 type)
|
||||
{
|
||||
struct device *dev = hr_dev->dev;
|
||||
u32 chunk_ba_num;
|
||||
u32 table_idx;
|
||||
u32 bt_num;
|
||||
u32 chunk_size;
|
||||
|
||||
switch (table->type) {
|
||||
switch (type) {
|
||||
case HEM_TYPE_QPC:
|
||||
mhop->buf_chunk_size = 1 << (hr_dev->caps.qpc_buf_pg_sz
|
||||
+ PAGE_SHIFT);
|
||||
|
@ -193,10 +217,26 @@ int hns_roce_calc_hem_mhop(struct hns_roce_dev *hr_dev,
|
|||
break;
|
||||
default:
|
||||
dev_err(dev, "Table %d not support multi-hop addressing!\n",
|
||||
table->type);
|
||||
type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hns_roce_calc_hem_mhop(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_hem_table *table, unsigned long *obj,
|
||||
struct hns_roce_hem_mhop *mhop)
|
||||
{
|
||||
struct device *dev = hr_dev->dev;
|
||||
u32 chunk_ba_num;
|
||||
u32 table_idx;
|
||||
u32 bt_num;
|
||||
u32 chunk_size;
|
||||
|
||||
if (get_hem_table_config(hr_dev, mhop, table->type))
|
||||
return -EINVAL;
|
||||
|
||||
if (!obj)
|
||||
return 0;
|
||||
|
||||
|
@ -324,13 +364,13 @@ static int hns_roce_set_hem(struct hns_roce_dev *hr_dev,
|
|||
{
|
||||
spinlock_t *lock = &hr_dev->bt_cmd_lock;
|
||||
struct device *dev = hr_dev->dev;
|
||||
unsigned long end = 0;
|
||||
long end;
|
||||
unsigned long flags;
|
||||
struct hns_roce_hem_iter iter;
|
||||
void __iomem *bt_cmd;
|
||||
u32 bt_cmd_h_val = 0;
|
||||
u32 bt_cmd_val[2];
|
||||
u32 bt_cmd_l = 0;
|
||||
__le32 bt_cmd_val[2];
|
||||
__le32 bt_cmd_h = 0;
|
||||
__le32 bt_cmd_l = 0;
|
||||
u64 bt_ba = 0;
|
||||
int ret = 0;
|
||||
|
||||
|
@ -340,30 +380,20 @@ static int hns_roce_set_hem(struct hns_roce_dev *hr_dev,
|
|||
|
||||
switch (table->type) {
|
||||
case HEM_TYPE_QPC:
|
||||
roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
|
||||
ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, HEM_TYPE_QPC);
|
||||
break;
|
||||
case HEM_TYPE_MTPT:
|
||||
roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
|
||||
ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S,
|
||||
HEM_TYPE_MTPT);
|
||||
break;
|
||||
case HEM_TYPE_CQC:
|
||||
roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
|
||||
ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, HEM_TYPE_CQC);
|
||||
break;
|
||||
case HEM_TYPE_SRQC:
|
||||
roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
|
||||
ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S,
|
||||
HEM_TYPE_SRQC);
|
||||
roce_set_field(bt_cmd_h, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
|
||||
ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, table->type);
|
||||
break;
|
||||
default:
|
||||
return ret;
|
||||
}
|
||||
roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_M,
|
||||
|
||||
roce_set_field(bt_cmd_h, ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_M,
|
||||
ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_S, obj);
|
||||
roce_set_bit(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_S, 0);
|
||||
roce_set_bit(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_HW_SYNS_S, 1);
|
||||
roce_set_bit(bt_cmd_h, ROCEE_BT_CMD_H_ROCEE_BT_CMD_S, 0);
|
||||
roce_set_bit(bt_cmd_h, ROCEE_BT_CMD_H_ROCEE_BT_CMD_HW_SYNS_S, 1);
|
||||
|
||||
/* Currently iter only a chunk */
|
||||
for (hns_roce_hem_first(table->hem[i], &iter);
|
||||
|
@ -375,7 +405,7 @@ static int hns_roce_set_hem(struct hns_roce_dev *hr_dev,
|
|||
bt_cmd = hr_dev->reg_base + ROCEE_BT_CMD_H_REG;
|
||||
|
||||
end = HW_SYNC_TIMEOUT_MSECS;
|
||||
while (end) {
|
||||
while (end > 0) {
|
||||
if (!(readl(bt_cmd) >> BT_CMD_SYNC_SHIFT))
|
||||
break;
|
||||
|
||||
|
@ -389,13 +419,13 @@ static int hns_roce_set_hem(struct hns_roce_dev *hr_dev,
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
bt_cmd_l = (u32)bt_ba;
|
||||
roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_M,
|
||||
bt_cmd_l = cpu_to_le32(bt_ba);
|
||||
roce_set_field(bt_cmd_h, ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_M,
|
||||
ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_S,
|
||||
bt_ba >> BT_BA_SHIFT);
|
||||
|
||||
bt_cmd_val[0] = bt_cmd_l;
|
||||
bt_cmd_val[1] = bt_cmd_h_val;
|
||||
bt_cmd_val[1] = bt_cmd_h;
|
||||
hns_roce_write64_k(bt_cmd_val,
|
||||
hr_dev->reg_base + ROCEE_BT_CMD_L_REG);
|
||||
spin_unlock_irqrestore(lock, flags);
|
||||
|
@ -457,6 +487,12 @@ static int hns_roce_table_mhop_get(struct hns_roce_dev *hr_dev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (unlikely(hem_idx >= table->num_hem)) {
|
||||
dev_err(dev, "Table %d exceed hem limt idx = %llu,max = %lu!\n",
|
||||
table->type, hem_idx, table->num_hem);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&table->mutex);
|
||||
|
||||
if (table->hem[hem_idx]) {
|
||||
|
@ -693,7 +729,7 @@ static void hns_roce_table_mhop_put(struct hns_roce_dev *hr_dev,
|
|||
if (check_whether_bt_num_2(table->type, hop_num)) {
|
||||
start_idx = mhop.l0_idx * chunk_ba_num;
|
||||
if (hns_roce_check_hem_null(table->hem, start_idx,
|
||||
chunk_ba_num)) {
|
||||
chunk_ba_num, table->num_hem)) {
|
||||
if (table->type < HEM_TYPE_MTT &&
|
||||
hr_dev->hw->clear_hem(hr_dev, table, obj, 0))
|
||||
dev_warn(dev, "Clear HEM base address failed.\n");
|
||||
|
@ -707,7 +743,7 @@ static void hns_roce_table_mhop_put(struct hns_roce_dev *hr_dev,
|
|||
start_idx = mhop.l0_idx * chunk_ba_num * chunk_ba_num +
|
||||
mhop.l1_idx * chunk_ba_num;
|
||||
if (hns_roce_check_hem_null(table->hem, start_idx,
|
||||
chunk_ba_num)) {
|
||||
chunk_ba_num, table->num_hem)) {
|
||||
if (hr_dev->hw->clear_hem(hr_dev, table, obj, 1))
|
||||
dev_warn(dev, "Clear HEM base address failed.\n");
|
||||
|
||||
|
@ -791,7 +827,8 @@ void *hns_roce_table_find(struct hns_roce_dev *hr_dev,
|
|||
} else {
|
||||
u32 seg_size = 64; /* 8 bytes per BA and 8 BA per segment */
|
||||
|
||||
hns_roce_calc_hem_mhop(hr_dev, table, &mhop_obj, &mhop);
|
||||
if (hns_roce_calc_hem_mhop(hr_dev, table, &mhop_obj, &mhop))
|
||||
goto out;
|
||||
/* mtt mhop */
|
||||
i = mhop.l0_idx;
|
||||
j = mhop.l1_idx;
|
||||
|
@ -840,11 +877,13 @@ int hns_roce_table_get_range(struct hns_roce_dev *hr_dev,
|
|||
{
|
||||
struct hns_roce_hem_mhop mhop;
|
||||
unsigned long inc = table->table_chunk_size / table->obj_size;
|
||||
unsigned long i;
|
||||
unsigned long i = 0;
|
||||
int ret;
|
||||
|
||||
if (hns_roce_check_whether_mhop(hr_dev, table->type)) {
|
||||
hns_roce_calc_hem_mhop(hr_dev, table, NULL, &mhop);
|
||||
ret = hns_roce_calc_hem_mhop(hr_dev, table, NULL, &mhop);
|
||||
if (ret)
|
||||
goto fail;
|
||||
inc = mhop.bt_chunk_size / table->obj_size;
|
||||
}
|
||||
|
||||
|
@ -874,7 +913,8 @@ void hns_roce_table_put_range(struct hns_roce_dev *hr_dev,
|
|||
unsigned long i;
|
||||
|
||||
if (hns_roce_check_whether_mhop(hr_dev, table->type)) {
|
||||
hns_roce_calc_hem_mhop(hr_dev, table, NULL, &mhop);
|
||||
if (hns_roce_calc_hem_mhop(hr_dev, table, NULL, &mhop))
|
||||
return;
|
||||
inc = mhop.bt_chunk_size / table->obj_size;
|
||||
}
|
||||
|
||||
|
@ -887,7 +927,6 @@ int hns_roce_init_hem_table(struct hns_roce_dev *hr_dev,
|
|||
unsigned long obj_size, unsigned long nobj,
|
||||
int use_lowmem)
|
||||
{
|
||||
struct device *dev = hr_dev->dev;
|
||||
unsigned long obj_per_chunk;
|
||||
unsigned long num_hem;
|
||||
|
||||
|
@ -900,99 +939,21 @@ int hns_roce_init_hem_table(struct hns_roce_dev *hr_dev,
|
|||
if (!table->hem)
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
struct hns_roce_hem_mhop mhop = {};
|
||||
unsigned long buf_chunk_size;
|
||||
unsigned long bt_chunk_size;
|
||||
unsigned long bt_chunk_num;
|
||||
unsigned long num_bt_l0 = 0;
|
||||
u32 hop_num;
|
||||
|
||||
switch (type) {
|
||||
case HEM_TYPE_QPC:
|
||||
buf_chunk_size = 1 << (hr_dev->caps.qpc_buf_pg_sz
|
||||
+ PAGE_SHIFT);
|
||||
bt_chunk_size = 1 << (hr_dev->caps.qpc_ba_pg_sz
|
||||
+ PAGE_SHIFT);
|
||||
num_bt_l0 = hr_dev->caps.qpc_bt_num;
|
||||
hop_num = hr_dev->caps.qpc_hop_num;
|
||||
break;
|
||||
case HEM_TYPE_MTPT:
|
||||
buf_chunk_size = 1 << (hr_dev->caps.mpt_buf_pg_sz
|
||||
+ PAGE_SHIFT);
|
||||
bt_chunk_size = 1 << (hr_dev->caps.mpt_ba_pg_sz
|
||||
+ PAGE_SHIFT);
|
||||
num_bt_l0 = hr_dev->caps.mpt_bt_num;
|
||||
hop_num = hr_dev->caps.mpt_hop_num;
|
||||
break;
|
||||
case HEM_TYPE_CQC:
|
||||
buf_chunk_size = 1 << (hr_dev->caps.cqc_buf_pg_sz
|
||||
+ PAGE_SHIFT);
|
||||
bt_chunk_size = 1 << (hr_dev->caps.cqc_ba_pg_sz
|
||||
+ PAGE_SHIFT);
|
||||
num_bt_l0 = hr_dev->caps.cqc_bt_num;
|
||||
hop_num = hr_dev->caps.cqc_hop_num;
|
||||
break;
|
||||
case HEM_TYPE_SCCC:
|
||||
buf_chunk_size = 1 << (hr_dev->caps.sccc_buf_pg_sz
|
||||
+ PAGE_SHIFT);
|
||||
bt_chunk_size = 1 << (hr_dev->caps.sccc_ba_pg_sz
|
||||
+ PAGE_SHIFT);
|
||||
num_bt_l0 = hr_dev->caps.sccc_bt_num;
|
||||
hop_num = hr_dev->caps.sccc_hop_num;
|
||||
break;
|
||||
case HEM_TYPE_QPC_TIMER:
|
||||
buf_chunk_size = 1 << (hr_dev->caps.qpc_timer_buf_pg_sz
|
||||
+ PAGE_SHIFT);
|
||||
bt_chunk_size = 1 << (hr_dev->caps.qpc_timer_ba_pg_sz
|
||||
+ PAGE_SHIFT);
|
||||
num_bt_l0 = hr_dev->caps.qpc_timer_bt_num;
|
||||
hop_num = hr_dev->caps.qpc_timer_hop_num;
|
||||
break;
|
||||
case HEM_TYPE_CQC_TIMER:
|
||||
buf_chunk_size = 1 << (hr_dev->caps.cqc_timer_buf_pg_sz
|
||||
+ PAGE_SHIFT);
|
||||
bt_chunk_size = 1 << (hr_dev->caps.cqc_timer_ba_pg_sz
|
||||
+ PAGE_SHIFT);
|
||||
num_bt_l0 = hr_dev->caps.cqc_timer_bt_num;
|
||||
hop_num = hr_dev->caps.cqc_timer_hop_num;
|
||||
break;
|
||||
case HEM_TYPE_SRQC:
|
||||
buf_chunk_size = 1 << (hr_dev->caps.srqc_buf_pg_sz
|
||||
+ PAGE_SHIFT);
|
||||
bt_chunk_size = 1 << (hr_dev->caps.srqc_ba_pg_sz
|
||||
+ PAGE_SHIFT);
|
||||
num_bt_l0 = hr_dev->caps.srqc_bt_num;
|
||||
hop_num = hr_dev->caps.srqc_hop_num;
|
||||
break;
|
||||
case HEM_TYPE_MTT:
|
||||
buf_chunk_size = 1 << (hr_dev->caps.mtt_ba_pg_sz
|
||||
+ PAGE_SHIFT);
|
||||
bt_chunk_size = buf_chunk_size;
|
||||
hop_num = hr_dev->caps.mtt_hop_num;
|
||||
break;
|
||||
case HEM_TYPE_CQE:
|
||||
buf_chunk_size = 1 << (hr_dev->caps.cqe_ba_pg_sz
|
||||
+ PAGE_SHIFT);
|
||||
bt_chunk_size = buf_chunk_size;
|
||||
hop_num = hr_dev->caps.cqe_hop_num;
|
||||
break;
|
||||
case HEM_TYPE_SRQWQE:
|
||||
buf_chunk_size = 1 << (hr_dev->caps.srqwqe_ba_pg_sz
|
||||
+ PAGE_SHIFT);
|
||||
bt_chunk_size = buf_chunk_size;
|
||||
hop_num = hr_dev->caps.srqwqe_hop_num;
|
||||
break;
|
||||
case HEM_TYPE_IDX:
|
||||
buf_chunk_size = 1 << (hr_dev->caps.idx_ba_pg_sz
|
||||
+ PAGE_SHIFT);
|
||||
bt_chunk_size = buf_chunk_size;
|
||||
hop_num = hr_dev->caps.idx_hop_num;
|
||||
break;
|
||||
default:
|
||||
dev_err(dev,
|
||||
"Table %d not support to init hem table here!\n",
|
||||
type);
|
||||
if (get_hem_table_config(hr_dev, &mhop, type))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
buf_chunk_size = mhop.buf_chunk_size;
|
||||
bt_chunk_size = mhop.bt_chunk_size;
|
||||
num_bt_l0 = mhop.ba_l0_num;
|
||||
hop_num = mhop.hop_num;
|
||||
|
||||
obj_per_chunk = buf_chunk_size / obj_size;
|
||||
num_hem = (nobj + obj_per_chunk - 1) / obj_per_chunk;
|
||||
bt_chunk_num = bt_chunk_size / BA_BYTE_LEN;
|
||||
|
@ -1075,7 +1036,8 @@ static void hns_roce_cleanup_mhop_hem_table(struct hns_roce_dev *hr_dev,
|
|||
int i;
|
||||
u64 obj;
|
||||
|
||||
hns_roce_calc_hem_mhop(hr_dev, table, NULL, &mhop);
|
||||
if (hns_roce_calc_hem_mhop(hr_dev, table, NULL, &mhop))
|
||||
return;
|
||||
buf_chunk_size = table->type < HEM_TYPE_MTT ? mhop.buf_chunk_size :
|
||||
mhop.bt_chunk_size;
|
||||
|
||||
|
|
|
@ -102,9 +102,9 @@ struct hns_roce_hem_mhop {
|
|||
u32 buf_chunk_size;
|
||||
u32 bt_chunk_size;
|
||||
u32 ba_l0_num;
|
||||
u32 l0_idx;/* level 0 base address table index */
|
||||
u32 l1_idx;/* level 1 base address table index */
|
||||
u32 l2_idx;/* level 2 base address table index */
|
||||
u32 l0_idx; /* level 0 base address table index */
|
||||
u32 l1_idx; /* level 1 base address table index */
|
||||
u32 l2_idx; /* level 2 base address table index */
|
||||
};
|
||||
|
||||
void hns_roce_free_hem(struct hns_roce_dev *hr_dev, struct hns_roce_hem *hem);
|
||||
|
|
|
@ -73,7 +73,7 @@ static int hns_roce_v1_post_send(struct ib_qp *ibqp,
|
|||
int ps_opcode = 0, i = 0;
|
||||
unsigned long flags = 0;
|
||||
void *wqe = NULL;
|
||||
u32 doorbell[2];
|
||||
__le32 doorbell[2];
|
||||
int nreq = 0;
|
||||
u32 ind = 0;
|
||||
int ret = 0;
|
||||
|
@ -175,13 +175,11 @@ static int hns_roce_v1_post_send(struct ib_qp *ibqp,
|
|||
roce_set_field(ud_sq_wqe->u32_36,
|
||||
UD_SEND_WQE_U32_36_FLOW_LABEL_M,
|
||||
UD_SEND_WQE_U32_36_FLOW_LABEL_S,
|
||||
ah->av.sl_tclass_flowlabel &
|
||||
HNS_ROCE_FLOW_LABEL_MASK);
|
||||
ah->av.flowlabel);
|
||||
roce_set_field(ud_sq_wqe->u32_36,
|
||||
UD_SEND_WQE_U32_36_PRIORITY_M,
|
||||
UD_SEND_WQE_U32_36_PRIORITY_S,
|
||||
le32_to_cpu(ah->av.sl_tclass_flowlabel) >>
|
||||
HNS_ROCE_SL_SHIFT);
|
||||
ah->av.sl);
|
||||
roce_set_field(ud_sq_wqe->u32_36,
|
||||
UD_SEND_WQE_U32_36_SGID_INDEX_M,
|
||||
UD_SEND_WQE_U32_36_SGID_INDEX_S,
|
||||
|
@ -195,8 +193,7 @@ static int hns_roce_v1_post_send(struct ib_qp *ibqp,
|
|||
roce_set_field(ud_sq_wqe->u32_40,
|
||||
UD_SEND_WQE_U32_40_TRAFFIC_CLASS_M,
|
||||
UD_SEND_WQE_U32_40_TRAFFIC_CLASS_S,
|
||||
ah->av.sl_tclass_flowlabel >>
|
||||
HNS_ROCE_TCLASS_SHIFT);
|
||||
ah->av.tclass);
|
||||
|
||||
memcpy(&ud_sq_wqe->dgid[0], &ah->av.dgid[0], GID_LEN);
|
||||
|
||||
|
@ -335,10 +332,10 @@ static int hns_roce_v1_post_send(struct ib_qp *ibqp,
|
|||
SQ_DOORBELL_U32_8_QPN_S, qp->doorbell_qpn);
|
||||
roce_set_bit(sq_db.u32_8, SQ_DOORBELL_HW_SYNC_S, 1);
|
||||
|
||||
doorbell[0] = le32_to_cpu(sq_db.u32_4);
|
||||
doorbell[1] = le32_to_cpu(sq_db.u32_8);
|
||||
doorbell[0] = sq_db.u32_4;
|
||||
doorbell[1] = sq_db.u32_8;
|
||||
|
||||
hns_roce_write64_k((__le32 *)doorbell, qp->sq.db_reg_l);
|
||||
hns_roce_write64_k(doorbell, qp->sq.db_reg_l);
|
||||
qp->sq_next_wqe = ind;
|
||||
}
|
||||
|
||||
|
@ -363,7 +360,7 @@ static int hns_roce_v1_post_recv(struct ib_qp *ibqp,
|
|||
struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
|
||||
struct device *dev = &hr_dev->pdev->dev;
|
||||
struct hns_roce_rq_db rq_db;
|
||||
uint32_t doorbell[2] = {0};
|
||||
__le32 doorbell[2] = {0};
|
||||
|
||||
spin_lock_irqsave(&hr_qp->rq.lock, flags);
|
||||
ind = hr_qp->rq.head & (hr_qp->rq.wqe_cnt - 1);
|
||||
|
@ -437,11 +434,10 @@ static int hns_roce_v1_post_recv(struct ib_qp *ibqp,
|
|||
roce_set_bit(rq_db.u32_8, RQ_DOORBELL_U32_8_HW_SYNC_S,
|
||||
1);
|
||||
|
||||
doorbell[0] = le32_to_cpu(rq_db.u32_4);
|
||||
doorbell[1] = le32_to_cpu(rq_db.u32_8);
|
||||
doorbell[0] = rq_db.u32_4;
|
||||
doorbell[1] = rq_db.u32_8;
|
||||
|
||||
hns_roce_write64_k((__le32 *)doorbell,
|
||||
hr_qp->rq.db_reg_l);
|
||||
hns_roce_write64_k(doorbell, hr_qp->rq.db_reg_l);
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&hr_qp->rq.lock, flags);
|
||||
|
@ -715,7 +711,7 @@ static int hns_roce_v1_rsv_lp_qp(struct hns_roce_dev *hr_dev)
|
|||
struct ib_cq *cq;
|
||||
struct ib_pd *pd;
|
||||
union ib_gid dgid;
|
||||
u64 subnet_prefix;
|
||||
__be64 subnet_prefix;
|
||||
int attr_mask = 0;
|
||||
int ret;
|
||||
int i, j;
|
||||
|
@ -971,7 +967,7 @@ static int hns_roce_v1_recreate_lp_qp(struct hns_roce_dev *hr_dev)
|
|||
struct hns_roce_free_mr *free_mr;
|
||||
struct hns_roce_v1_priv *priv;
|
||||
struct completion comp;
|
||||
unsigned long end = HNS_ROCE_V1_RECREATE_LP_QP_TIMEOUT_MSECS;
|
||||
long end = HNS_ROCE_V1_RECREATE_LP_QP_TIMEOUT_MSECS;
|
||||
|
||||
priv = (struct hns_roce_v1_priv *)hr_dev->priv;
|
||||
free_mr = &priv->free_mr;
|
||||
|
@ -991,7 +987,7 @@ static int hns_roce_v1_recreate_lp_qp(struct hns_roce_dev *hr_dev)
|
|||
|
||||
queue_work(free_mr->free_mr_wq, &(lp_qp_work->work));
|
||||
|
||||
while (end) {
|
||||
while (end > 0) {
|
||||
if (try_wait_for_completion(&comp))
|
||||
return 0;
|
||||
msleep(HNS_ROCE_V1_RECREATE_LP_QP_WAIT_VALUE);
|
||||
|
@ -1109,7 +1105,7 @@ static int hns_roce_v1_dereg_mr(struct hns_roce_dev *hr_dev,
|
|||
struct hns_roce_free_mr *free_mr;
|
||||
struct hns_roce_v1_priv *priv;
|
||||
struct completion comp;
|
||||
unsigned long end = HNS_ROCE_V1_FREE_MR_TIMEOUT_MSECS;
|
||||
long end = HNS_ROCE_V1_FREE_MR_TIMEOUT_MSECS;
|
||||
unsigned long start = jiffies;
|
||||
int npages;
|
||||
int ret = 0;
|
||||
|
@ -1139,7 +1135,7 @@ static int hns_roce_v1_dereg_mr(struct hns_roce_dev *hr_dev,
|
|||
|
||||
queue_work(free_mr->free_mr_wq, &(mr_work->work));
|
||||
|
||||
while (end) {
|
||||
while (end > 0) {
|
||||
if (try_wait_for_completion(&comp))
|
||||
goto free_mr;
|
||||
msleep(HNS_ROCE_V1_FREE_MR_WAIT_VALUE);
|
||||
|
@ -2165,7 +2161,7 @@ static int hns_roce_v1_req_notify_cq(struct ib_cq *ibcq,
|
|||
{
|
||||
struct hns_roce_cq *hr_cq = to_hr_cq(ibcq);
|
||||
u32 notification_flag;
|
||||
__le32 doorbell[2];
|
||||
__le32 doorbell[2] = {};
|
||||
|
||||
notification_flag = (flags & IB_CQ_SOLICITED_MASK) ==
|
||||
IB_CQ_SOLICITED ? CQ_DB_REQ_NOT : CQ_DB_REQ_NOT_SOL;
|
||||
|
@ -2430,7 +2426,8 @@ static int hns_roce_v1_clear_hem(struct hns_roce_dev *hr_dev,
|
|||
{
|
||||
struct device *dev = &hr_dev->pdev->dev;
|
||||
struct hns_roce_v1_priv *priv;
|
||||
unsigned long end = 0, flags = 0;
|
||||
unsigned long flags = 0;
|
||||
long end = HW_SYNC_TIMEOUT_MSECS;
|
||||
__le32 bt_cmd_val[2] = {0};
|
||||
void __iomem *bt_cmd;
|
||||
u64 bt_ba = 0;
|
||||
|
@ -2439,18 +2436,12 @@ static int hns_roce_v1_clear_hem(struct hns_roce_dev *hr_dev,
|
|||
|
||||
switch (table->type) {
|
||||
case HEM_TYPE_QPC:
|
||||
roce_set_field(bt_cmd_val[1], ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
|
||||
ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, HEM_TYPE_QPC);
|
||||
bt_ba = priv->bt_table.qpc_buf.map >> 12;
|
||||
break;
|
||||
case HEM_TYPE_MTPT:
|
||||
roce_set_field(bt_cmd_val[1], ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
|
||||
ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, HEM_TYPE_MTPT);
|
||||
bt_ba = priv->bt_table.mtpt_buf.map >> 12;
|
||||
break;
|
||||
case HEM_TYPE_CQC:
|
||||
roce_set_field(bt_cmd_val[1], ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
|
||||
ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, HEM_TYPE_CQC);
|
||||
bt_ba = priv->bt_table.cqc_buf.map >> 12;
|
||||
break;
|
||||
case HEM_TYPE_SRQC:
|
||||
|
@ -2459,6 +2450,8 @@ static int hns_roce_v1_clear_hem(struct hns_roce_dev *hr_dev,
|
|||
default:
|
||||
return 0;
|
||||
}
|
||||
roce_set_field(bt_cmd_val[1], ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
|
||||
ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, table->type);
|
||||
roce_set_field(bt_cmd_val[1], ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_M,
|
||||
ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_S, obj);
|
||||
roce_set_bit(bt_cmd_val[1], ROCEE_BT_CMD_H_ROCEE_BT_CMD_S, 0);
|
||||
|
@ -2468,7 +2461,6 @@ static int hns_roce_v1_clear_hem(struct hns_roce_dev *hr_dev,
|
|||
|
||||
bt_cmd = hr_dev->reg_base + ROCEE_BT_CMD_H_REG;
|
||||
|
||||
end = HW_SYNC_TIMEOUT_MSECS;
|
||||
while (1) {
|
||||
if (readl(bt_cmd) >> BT_CMD_SYNC_SHIFT) {
|
||||
if (!end) {
|
||||
|
@ -2484,7 +2476,7 @@ static int hns_roce_v1_clear_hem(struct hns_roce_dev *hr_dev,
|
|||
end -= HW_SYNC_SLEEP_TIME_INTERVAL;
|
||||
}
|
||||
|
||||
bt_cmd_val[0] = (__le32)bt_ba;
|
||||
bt_cmd_val[0] = cpu_to_le32(bt_ba);
|
||||
roce_set_field(bt_cmd_val[1], ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_M,
|
||||
ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_S, bt_ba >> 32);
|
||||
hns_roce_write64_k(bt_cmd_val, hr_dev->reg_base + ROCEE_BT_CMD_L_REG);
|
||||
|
@ -2627,7 +2619,7 @@ static int hns_roce_v1_m_sqp(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
|
|||
QP1C_BYTES_16_PORT_NUM_S, hr_qp->phy_port);
|
||||
roce_set_bit(context->qp1c_bytes_16,
|
||||
QP1C_BYTES_16_SIGNALING_TYPE_S,
|
||||
le32_to_cpu(hr_qp->sq_signal_bits));
|
||||
hr_qp->sq_signal_bits);
|
||||
roce_set_bit(context->qp1c_bytes_16, QP1C_BYTES_16_RQ_BA_FLG_S,
|
||||
1);
|
||||
roce_set_bit(context->qp1c_bytes_16, QP1C_BYTES_16_SQ_BA_FLG_S,
|
||||
|
@ -2933,7 +2925,7 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
|
|||
1);
|
||||
roce_set_bit(context->qpc_bytes_32,
|
||||
QP_CONTEXT_QPC_BYTE_32_SIGNALING_TYPE_S,
|
||||
le32_to_cpu(hr_qp->sq_signal_bits));
|
||||
hr_qp->sq_signal_bits);
|
||||
|
||||
port = (attr_mask & IB_QP_PORT) ? (attr->port_num - 1) :
|
||||
hr_qp->port;
|
||||
|
@ -3578,7 +3570,7 @@ static int hns_roce_v1_q_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
|
|||
qp_attr->retry_cnt = roce_get_field(context->qpc_bytes_148,
|
||||
QP_CONTEXT_QPC_BYTES_148_RETRY_COUNT_M,
|
||||
QP_CONTEXT_QPC_BYTES_148_RETRY_COUNT_S);
|
||||
qp_attr->rnr_retry = (u8)context->rnr_retry;
|
||||
qp_attr->rnr_retry = (u8)le32_to_cpu(context->rnr_retry);
|
||||
|
||||
done:
|
||||
qp_attr->cur_qp_state = qp_attr->qp_state;
|
||||
|
@ -4021,7 +4013,8 @@ static int hns_roce_v1_ceq_int(struct hns_roce_dev *hr_dev,
|
|||
++eq->cons_index;
|
||||
ceqes_found = 1;
|
||||
|
||||
if (eq->cons_index > 2 * hr_dev->caps.ceqe_depth - 1) {
|
||||
if (eq->cons_index >
|
||||
EQ_DEPTH_COEFF * hr_dev->caps.ceqe_depth - 1) {
|
||||
dev_warn(&eq->hr_dev->pdev->dev,
|
||||
"cons_index overflow, set back to 0.\n");
|
||||
eq->cons_index = 0;
|
||||
|
@ -4518,7 +4511,6 @@ static int hns_roce_get_cfg(struct hns_roce_dev *hr_dev)
|
|||
struct platform_device *pdev = NULL;
|
||||
struct net_device *netdev = NULL;
|
||||
struct device_node *net_node;
|
||||
struct resource *res;
|
||||
int port_cnt = 0;
|
||||
u8 phy_port;
|
||||
int ret;
|
||||
|
@ -4557,8 +4549,7 @@ static int hns_roce_get_cfg(struct hns_roce_dev *hr_dev)
|
|||
}
|
||||
|
||||
/* get the mapped register base address */
|
||||
res = platform_get_resource(hr_dev->pdev, IORESOURCE_MEM, 0);
|
||||
hr_dev->reg_base = devm_ioremap_resource(dev, res);
|
||||
hr_dev->reg_base = devm_platform_ioremap_resource(hr_dev->pdev, 0);
|
||||
if (IS_ERR(hr_dev->reg_base))
|
||||
return PTR_ERR(hr_dev->reg_base);
|
||||
|
||||
|
@ -4633,10 +4624,8 @@ static int hns_roce_get_cfg(struct hns_roce_dev *hr_dev)
|
|||
/* fetch the interrupt numbers */
|
||||
for (i = 0; i < HNS_ROCE_V1_MAX_IRQ_NUM; i++) {
|
||||
hr_dev->irq[i] = platform_get_irq(hr_dev->pdev, i);
|
||||
if (hr_dev->irq[i] <= 0) {
|
||||
dev_err(dev, "platform get of irq[=%d] failed!\n", i);
|
||||
if (hr_dev->irq[i] <= 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -96,7 +96,10 @@
|
|||
#define HNS_ROCE_V2_UC_RC_SGE_NUM_IN_WQE 2
|
||||
#define HNS_ROCE_V2_RSV_QPS 8
|
||||
|
||||
#define HNS_ROCE_V2_HW_RST_TIMEOUT 1000
|
||||
#define HNS_ROCE_V2_HW_RST_TIMEOUT 1000
|
||||
#define HNS_ROCE_V2_HW_RST_UNINT_DELAY 100
|
||||
|
||||
#define HNS_ROCE_V2_HW_RST_COMPLETION_WAIT 20
|
||||
|
||||
#define HNS_ROCE_CONTEXT_HOP_NUM 1
|
||||
#define HNS_ROCE_SCCC_HOP_NUM 1
|
||||
|
@ -126,8 +129,6 @@
|
|||
#define HNS_ROCE_CMD_FLAG_ERR_INTR BIT(HNS_ROCE_CMD_FLAG_ERR_INTR_SHIFT)
|
||||
|
||||
#define HNS_ROCE_CMQ_DESC_NUM_S 3
|
||||
#define HNS_ROCE_CMQ_EN_B 16
|
||||
#define HNS_ROCE_CMQ_ENABLE BIT(HNS_ROCE_CMQ_EN_B)
|
||||
|
||||
#define HNS_ROCE_CMQ_SCC_CLR_DONE_CNT 5
|
||||
|
||||
|
|
|
@ -262,7 +262,8 @@ static int hns_roce_query_port(struct ib_device *ib_dev, u8 port_num,
|
|||
props->state = (netif_running(net_dev) && netif_carrier_ok(net_dev)) ?
|
||||
IB_PORT_ACTIVE : IB_PORT_DOWN;
|
||||
props->phys_state = (props->state == IB_PORT_ACTIVE) ?
|
||||
HNS_ROCE_PHY_LINKUP : HNS_ROCE_PHY_DISABLED;
|
||||
IB_PORT_PHYS_STATE_LINK_UP :
|
||||
IB_PORT_PHYS_STATE_DISABLED;
|
||||
|
||||
spin_unlock_irqrestore(&hr_dev->iboe.lock, flags);
|
||||
|
||||
|
@ -901,6 +902,7 @@ int hns_roce_init(struct hns_roce_dev *hr_dev)
|
|||
goto error_failed_cmd_init;
|
||||
}
|
||||
|
||||
/* EQ depends on poll mode, event mode depends on EQ */
|
||||
ret = hr_dev->hw->init_eq(hr_dev);
|
||||
if (ret) {
|
||||
dev_err(dev, "eq init failed!\n");
|
||||
|
@ -910,8 +912,9 @@ int hns_roce_init(struct hns_roce_dev *hr_dev)
|
|||
if (hr_dev->cmd_mod) {
|
||||
ret = hns_roce_cmd_use_events(hr_dev);
|
||||
if (ret) {
|
||||
dev_err(dev, "Switch to event-driven cmd failed!\n");
|
||||
goto error_failed_use_event;
|
||||
dev_warn(dev,
|
||||
"Cmd event mode failed, set back to poll!\n");
|
||||
hns_roce_cmd_use_polling(hr_dev);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -954,8 +957,6 @@ int hns_roce_init(struct hns_roce_dev *hr_dev)
|
|||
error_failed_init_hem:
|
||||
if (hr_dev->cmd_mod)
|
||||
hns_roce_cmd_use_polling(hr_dev);
|
||||
|
||||
error_failed_use_event:
|
||||
hr_dev->hw->cleanup_eq(hr_dev);
|
||||
|
||||
error_failed_eq_table:
|
||||
|
|
|
@ -347,49 +347,178 @@ static void hns_roce_loop_free(struct hns_roce_dev *hr_dev,
|
|||
mr->pbl_bt_l0 = NULL;
|
||||
mr->pbl_l0_dma_addr = 0;
|
||||
}
|
||||
static int pbl_1hop_alloc(struct hns_roce_dev *hr_dev, int npages,
|
||||
struct hns_roce_mr *mr, u32 pbl_bt_sz)
|
||||
{
|
||||
struct device *dev = hr_dev->dev;
|
||||
|
||||
if (npages > pbl_bt_sz / 8) {
|
||||
dev_err(dev, "npages %d is larger than buf_pg_sz!",
|
||||
npages);
|
||||
return -EINVAL;
|
||||
}
|
||||
mr->pbl_buf = dma_alloc_coherent(dev, npages * 8,
|
||||
&(mr->pbl_dma_addr),
|
||||
GFP_KERNEL);
|
||||
if (!mr->pbl_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
mr->pbl_size = npages;
|
||||
mr->pbl_ba = mr->pbl_dma_addr;
|
||||
mr->pbl_hop_num = 1;
|
||||
mr->pbl_ba_pg_sz = hr_dev->caps.pbl_ba_pg_sz;
|
||||
mr->pbl_buf_pg_sz = hr_dev->caps.pbl_buf_pg_sz;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int pbl_2hop_alloc(struct hns_roce_dev *hr_dev, int npages,
|
||||
struct hns_roce_mr *mr, u32 pbl_bt_sz)
|
||||
{
|
||||
struct device *dev = hr_dev->dev;
|
||||
int npages_allocated;
|
||||
u64 pbl_last_bt_num;
|
||||
u64 pbl_bt_cnt = 0;
|
||||
u64 size;
|
||||
int i;
|
||||
|
||||
pbl_last_bt_num = (npages + pbl_bt_sz / 8 - 1) / (pbl_bt_sz / 8);
|
||||
|
||||
/* alloc L1 BT */
|
||||
for (i = 0; i < pbl_bt_sz / 8; i++) {
|
||||
if (pbl_bt_cnt + 1 < pbl_last_bt_num) {
|
||||
size = pbl_bt_sz;
|
||||
} else {
|
||||
npages_allocated = i * (pbl_bt_sz / 8);
|
||||
size = (npages - npages_allocated) * 8;
|
||||
}
|
||||
mr->pbl_bt_l1[i] = dma_alloc_coherent(dev, size,
|
||||
&(mr->pbl_l1_dma_addr[i]),
|
||||
GFP_KERNEL);
|
||||
if (!mr->pbl_bt_l1[i]) {
|
||||
hns_roce_loop_free(hr_dev, mr, 1, i, 0);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
*(mr->pbl_bt_l0 + i) = mr->pbl_l1_dma_addr[i];
|
||||
|
||||
pbl_bt_cnt++;
|
||||
if (pbl_bt_cnt >= pbl_last_bt_num)
|
||||
break;
|
||||
}
|
||||
|
||||
mr->l0_chunk_last_num = i + 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pbl_3hop_alloc(struct hns_roce_dev *hr_dev, int npages,
|
||||
struct hns_roce_mr *mr, u32 pbl_bt_sz)
|
||||
{
|
||||
struct device *dev = hr_dev->dev;
|
||||
int mr_alloc_done = 0;
|
||||
int npages_allocated;
|
||||
u64 pbl_last_bt_num;
|
||||
u64 pbl_bt_cnt = 0;
|
||||
u64 bt_idx;
|
||||
u64 size;
|
||||
int i;
|
||||
int j = 0;
|
||||
|
||||
pbl_last_bt_num = (npages + pbl_bt_sz / 8 - 1) / (pbl_bt_sz / 8);
|
||||
|
||||
mr->pbl_l2_dma_addr = kcalloc(pbl_last_bt_num,
|
||||
sizeof(*mr->pbl_l2_dma_addr),
|
||||
GFP_KERNEL);
|
||||
if (!mr->pbl_l2_dma_addr)
|
||||
return -ENOMEM;
|
||||
|
||||
mr->pbl_bt_l2 = kcalloc(pbl_last_bt_num,
|
||||
sizeof(*mr->pbl_bt_l2),
|
||||
GFP_KERNEL);
|
||||
if (!mr->pbl_bt_l2)
|
||||
goto err_kcalloc_bt_l2;
|
||||
|
||||
/* alloc L1, L2 BT */
|
||||
for (i = 0; i < pbl_bt_sz / 8; i++) {
|
||||
mr->pbl_bt_l1[i] = dma_alloc_coherent(dev, pbl_bt_sz,
|
||||
&(mr->pbl_l1_dma_addr[i]),
|
||||
GFP_KERNEL);
|
||||
if (!mr->pbl_bt_l1[i]) {
|
||||
hns_roce_loop_free(hr_dev, mr, 1, i, 0);
|
||||
goto err_dma_alloc_l0;
|
||||
}
|
||||
|
||||
*(mr->pbl_bt_l0 + i) = mr->pbl_l1_dma_addr[i];
|
||||
|
||||
for (j = 0; j < pbl_bt_sz / 8; j++) {
|
||||
bt_idx = i * pbl_bt_sz / 8 + j;
|
||||
|
||||
if (pbl_bt_cnt + 1 < pbl_last_bt_num) {
|
||||
size = pbl_bt_sz;
|
||||
} else {
|
||||
npages_allocated = bt_idx *
|
||||
(pbl_bt_sz / 8);
|
||||
size = (npages - npages_allocated) * 8;
|
||||
}
|
||||
mr->pbl_bt_l2[bt_idx] = dma_alloc_coherent(
|
||||
dev, size,
|
||||
&(mr->pbl_l2_dma_addr[bt_idx]),
|
||||
GFP_KERNEL);
|
||||
if (!mr->pbl_bt_l2[bt_idx]) {
|
||||
hns_roce_loop_free(hr_dev, mr, 2, i, j);
|
||||
goto err_dma_alloc_l0;
|
||||
}
|
||||
|
||||
*(mr->pbl_bt_l1[i] + j) =
|
||||
mr->pbl_l2_dma_addr[bt_idx];
|
||||
|
||||
pbl_bt_cnt++;
|
||||
if (pbl_bt_cnt >= pbl_last_bt_num) {
|
||||
mr_alloc_done = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mr_alloc_done)
|
||||
break;
|
||||
}
|
||||
|
||||
mr->l0_chunk_last_num = i + 1;
|
||||
mr->l1_chunk_last_num = j + 1;
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
err_dma_alloc_l0:
|
||||
kfree(mr->pbl_bt_l2);
|
||||
mr->pbl_bt_l2 = NULL;
|
||||
|
||||
err_kcalloc_bt_l2:
|
||||
kfree(mr->pbl_l2_dma_addr);
|
||||
mr->pbl_l2_dma_addr = NULL;
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
/* PBL multi hop addressing */
|
||||
static int hns_roce_mhop_alloc(struct hns_roce_dev *hr_dev, int npages,
|
||||
struct hns_roce_mr *mr)
|
||||
{
|
||||
struct device *dev = hr_dev->dev;
|
||||
int mr_alloc_done = 0;
|
||||
int npages_allocated;
|
||||
int i = 0, j = 0;
|
||||
u32 pbl_bt_sz;
|
||||
u32 mhop_num;
|
||||
u64 pbl_last_bt_num;
|
||||
u64 pbl_bt_cnt = 0;
|
||||
u64 bt_idx;
|
||||
u64 size;
|
||||
|
||||
mhop_num = (mr->type == MR_TYPE_FRMR ? 1 : hr_dev->caps.pbl_hop_num);
|
||||
pbl_bt_sz = 1 << (hr_dev->caps.pbl_ba_pg_sz + PAGE_SHIFT);
|
||||
pbl_last_bt_num = (npages + pbl_bt_sz / 8 - 1) / (pbl_bt_sz / 8);
|
||||
|
||||
if (mhop_num == HNS_ROCE_HOP_NUM_0)
|
||||
return 0;
|
||||
|
||||
/* hop_num = 1 */
|
||||
if (mhop_num == 1) {
|
||||
if (npages > pbl_bt_sz / 8) {
|
||||
dev_err(dev, "npages %d is larger than buf_pg_sz!",
|
||||
npages);
|
||||
return -EINVAL;
|
||||
}
|
||||
mr->pbl_buf = dma_alloc_coherent(dev, npages * 8,
|
||||
&(mr->pbl_dma_addr),
|
||||
GFP_KERNEL);
|
||||
if (!mr->pbl_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
mr->pbl_size = npages;
|
||||
mr->pbl_ba = mr->pbl_dma_addr;
|
||||
mr->pbl_hop_num = mhop_num;
|
||||
mr->pbl_ba_pg_sz = hr_dev->caps.pbl_ba_pg_sz;
|
||||
mr->pbl_buf_pg_sz = hr_dev->caps.pbl_buf_pg_sz;
|
||||
return 0;
|
||||
}
|
||||
if (mhop_num == 1)
|
||||
return pbl_1hop_alloc(hr_dev, npages, mr, pbl_bt_sz);
|
||||
|
||||
mr->pbl_l1_dma_addr = kcalloc(pbl_bt_sz / 8,
|
||||
sizeof(*mr->pbl_l1_dma_addr),
|
||||
|
@ -402,100 +531,23 @@ static int hns_roce_mhop_alloc(struct hns_roce_dev *hr_dev, int npages,
|
|||
if (!mr->pbl_bt_l1)
|
||||
goto err_kcalloc_bt_l1;
|
||||
|
||||
if (mhop_num == 3) {
|
||||
mr->pbl_l2_dma_addr = kcalloc(pbl_last_bt_num,
|
||||
sizeof(*mr->pbl_l2_dma_addr),
|
||||
GFP_KERNEL);
|
||||
if (!mr->pbl_l2_dma_addr)
|
||||
goto err_kcalloc_l2_dma;
|
||||
|
||||
mr->pbl_bt_l2 = kcalloc(pbl_last_bt_num,
|
||||
sizeof(*mr->pbl_bt_l2),
|
||||
GFP_KERNEL);
|
||||
if (!mr->pbl_bt_l2)
|
||||
goto err_kcalloc_bt_l2;
|
||||
}
|
||||
|
||||
/* alloc L0 BT */
|
||||
mr->pbl_bt_l0 = dma_alloc_coherent(dev, pbl_bt_sz,
|
||||
&(mr->pbl_l0_dma_addr),
|
||||
GFP_KERNEL);
|
||||
if (!mr->pbl_bt_l0)
|
||||
goto err_dma_alloc_l0;
|
||||
goto err_kcalloc_l2_dma;
|
||||
|
||||
if (mhop_num == 2) {
|
||||
/* alloc L1 BT */
|
||||
for (i = 0; i < pbl_bt_sz / 8; i++) {
|
||||
if (pbl_bt_cnt + 1 < pbl_last_bt_num) {
|
||||
size = pbl_bt_sz;
|
||||
} else {
|
||||
npages_allocated = i * (pbl_bt_sz / 8);
|
||||
size = (npages - npages_allocated) * 8;
|
||||
}
|
||||
mr->pbl_bt_l1[i] = dma_alloc_coherent(dev, size,
|
||||
&(mr->pbl_l1_dma_addr[i]),
|
||||
GFP_KERNEL);
|
||||
if (!mr->pbl_bt_l1[i]) {
|
||||
hns_roce_loop_free(hr_dev, mr, 1, i, 0);
|
||||
goto err_dma_alloc_l0;
|
||||
}
|
||||
|
||||
*(mr->pbl_bt_l0 + i) = mr->pbl_l1_dma_addr[i];
|
||||
|
||||
pbl_bt_cnt++;
|
||||
if (pbl_bt_cnt >= pbl_last_bt_num)
|
||||
break;
|
||||
}
|
||||
} else if (mhop_num == 3) {
|
||||
/* alloc L1, L2 BT */
|
||||
for (i = 0; i < pbl_bt_sz / 8; i++) {
|
||||
mr->pbl_bt_l1[i] = dma_alloc_coherent(dev, pbl_bt_sz,
|
||||
&(mr->pbl_l1_dma_addr[i]),
|
||||
GFP_KERNEL);
|
||||
if (!mr->pbl_bt_l1[i]) {
|
||||
hns_roce_loop_free(hr_dev, mr, 1, i, 0);
|
||||
goto err_dma_alloc_l0;
|
||||
}
|
||||
|
||||
*(mr->pbl_bt_l0 + i) = mr->pbl_l1_dma_addr[i];
|
||||
|
||||
for (j = 0; j < pbl_bt_sz / 8; j++) {
|
||||
bt_idx = i * pbl_bt_sz / 8 + j;
|
||||
|
||||
if (pbl_bt_cnt + 1 < pbl_last_bt_num) {
|
||||
size = pbl_bt_sz;
|
||||
} else {
|
||||
npages_allocated = bt_idx *
|
||||
(pbl_bt_sz / 8);
|
||||
size = (npages - npages_allocated) * 8;
|
||||
}
|
||||
mr->pbl_bt_l2[bt_idx] = dma_alloc_coherent(
|
||||
dev, size,
|
||||
&(mr->pbl_l2_dma_addr[bt_idx]),
|
||||
GFP_KERNEL);
|
||||
if (!mr->pbl_bt_l2[bt_idx]) {
|
||||
hns_roce_loop_free(hr_dev, mr, 2, i, j);
|
||||
goto err_dma_alloc_l0;
|
||||
}
|
||||
|
||||
*(mr->pbl_bt_l1[i] + j) =
|
||||
mr->pbl_l2_dma_addr[bt_idx];
|
||||
|
||||
pbl_bt_cnt++;
|
||||
if (pbl_bt_cnt >= pbl_last_bt_num) {
|
||||
mr_alloc_done = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mr_alloc_done)
|
||||
break;
|
||||
}
|
||||
if (pbl_2hop_alloc(hr_dev, npages, mr, pbl_bt_sz))
|
||||
goto err_kcalloc_l2_dma;
|
||||
}
|
||||
|
||||
if (mhop_num == 3) {
|
||||
if (pbl_3hop_alloc(hr_dev, npages, mr, pbl_bt_sz))
|
||||
goto err_kcalloc_l2_dma;
|
||||
}
|
||||
|
||||
mr->l0_chunk_last_num = i + 1;
|
||||
if (mhop_num == 3)
|
||||
mr->l1_chunk_last_num = j + 1;
|
||||
|
||||
mr->pbl_size = npages;
|
||||
mr->pbl_ba = mr->pbl_l0_dma_addr;
|
||||
|
@ -505,14 +557,6 @@ static int hns_roce_mhop_alloc(struct hns_roce_dev *hr_dev, int npages,
|
|||
|
||||
return 0;
|
||||
|
||||
err_dma_alloc_l0:
|
||||
kfree(mr->pbl_bt_l2);
|
||||
mr->pbl_bt_l2 = NULL;
|
||||
|
||||
err_kcalloc_bt_l2:
|
||||
kfree(mr->pbl_l2_dma_addr);
|
||||
mr->pbl_l2_dma_addr = NULL;
|
||||
|
||||
err_kcalloc_l2_dma:
|
||||
kfree(mr->pbl_bt_l1);
|
||||
mr->pbl_bt_l1 = NULL;
|
||||
|
@ -1161,6 +1205,83 @@ struct ib_mr *hns_roce_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
|
|||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
static int rereg_mr_trans(struct ib_mr *ibmr, int flags,
|
||||
u64 start, u64 length,
|
||||
u64 virt_addr, int mr_access_flags,
|
||||
struct hns_roce_cmd_mailbox *mailbox,
|
||||
u32 pdn, struct ib_udata *udata)
|
||||
{
|
||||
struct hns_roce_dev *hr_dev = to_hr_dev(ibmr->device);
|
||||
struct hns_roce_mr *mr = to_hr_mr(ibmr);
|
||||
struct device *dev = hr_dev->dev;
|
||||
int npages;
|
||||
int ret;
|
||||
|
||||
if (mr->size != ~0ULL) {
|
||||
npages = ib_umem_page_count(mr->umem);
|
||||
|
||||
if (hr_dev->caps.pbl_hop_num)
|
||||
hns_roce_mhop_free(hr_dev, mr);
|
||||
else
|
||||
dma_free_coherent(dev, npages * 8,
|
||||
mr->pbl_buf, mr->pbl_dma_addr);
|
||||
}
|
||||
ib_umem_release(mr->umem);
|
||||
|
||||
mr->umem = ib_umem_get(udata, start, length, mr_access_flags, 0);
|
||||
if (IS_ERR(mr->umem)) {
|
||||
ret = PTR_ERR(mr->umem);
|
||||
mr->umem = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
npages = ib_umem_page_count(mr->umem);
|
||||
|
||||
if (hr_dev->caps.pbl_hop_num) {
|
||||
ret = hns_roce_mhop_alloc(hr_dev, npages, mr);
|
||||
if (ret)
|
||||
goto release_umem;
|
||||
} else {
|
||||
mr->pbl_buf = dma_alloc_coherent(dev, npages * 8,
|
||||
&(mr->pbl_dma_addr),
|
||||
GFP_KERNEL);
|
||||
if (!mr->pbl_buf) {
|
||||
ret = -ENOMEM;
|
||||
goto release_umem;
|
||||
}
|
||||
}
|
||||
|
||||
ret = hr_dev->hw->rereg_write_mtpt(hr_dev, mr, flags, pdn,
|
||||
mr_access_flags, virt_addr,
|
||||
length, mailbox->buf);
|
||||
if (ret)
|
||||
goto release_umem;
|
||||
|
||||
|
||||
ret = hns_roce_ib_umem_write_mr(hr_dev, mr, mr->umem);
|
||||
if (ret) {
|
||||
if (mr->size != ~0ULL) {
|
||||
npages = ib_umem_page_count(mr->umem);
|
||||
|
||||
if (hr_dev->caps.pbl_hop_num)
|
||||
hns_roce_mhop_free(hr_dev, mr);
|
||||
else
|
||||
dma_free_coherent(dev, npages * 8,
|
||||
mr->pbl_buf,
|
||||
mr->pbl_dma_addr);
|
||||
}
|
||||
|
||||
goto release_umem;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
release_umem:
|
||||
ib_umem_release(mr->umem);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int hns_roce_rereg_user_mr(struct ib_mr *ibmr, int flags, u64 start, u64 length,
|
||||
u64 virt_addr, int mr_access_flags, struct ib_pd *pd,
|
||||
struct ib_udata *udata)
|
||||
|
@ -1171,7 +1292,6 @@ int hns_roce_rereg_user_mr(struct ib_mr *ibmr, int flags, u64 start, u64 length,
|
|||
struct device *dev = hr_dev->dev;
|
||||
unsigned long mtpt_idx;
|
||||
u32 pdn = 0;
|
||||
int npages;
|
||||
int ret;
|
||||
|
||||
if (!mr->enabled)
|
||||
|
@ -1198,73 +1318,25 @@ int hns_roce_rereg_user_mr(struct ib_mr *ibmr, int flags, u64 start, u64 length,
|
|||
pdn = to_hr_pd(pd)->pdn;
|
||||
|
||||
if (flags & IB_MR_REREG_TRANS) {
|
||||
if (mr->size != ~0ULL) {
|
||||
npages = ib_umem_page_count(mr->umem);
|
||||
|
||||
if (hr_dev->caps.pbl_hop_num)
|
||||
hns_roce_mhop_free(hr_dev, mr);
|
||||
else
|
||||
dma_free_coherent(dev, npages * 8, mr->pbl_buf,
|
||||
mr->pbl_dma_addr);
|
||||
}
|
||||
ib_umem_release(mr->umem);
|
||||
|
||||
mr->umem =
|
||||
ib_umem_get(udata, start, length, mr_access_flags, 0);
|
||||
if (IS_ERR(mr->umem)) {
|
||||
ret = PTR_ERR(mr->umem);
|
||||
mr->umem = NULL;
|
||||
ret = rereg_mr_trans(ibmr, flags,
|
||||
start, length,
|
||||
virt_addr, mr_access_flags,
|
||||
mailbox, pdn, udata);
|
||||
if (ret)
|
||||
goto free_cmd_mbox;
|
||||
}
|
||||
npages = ib_umem_page_count(mr->umem);
|
||||
|
||||
if (hr_dev->caps.pbl_hop_num) {
|
||||
ret = hns_roce_mhop_alloc(hr_dev, npages, mr);
|
||||
if (ret)
|
||||
goto release_umem;
|
||||
} else {
|
||||
mr->pbl_buf = dma_alloc_coherent(dev, npages * 8,
|
||||
&(mr->pbl_dma_addr),
|
||||
GFP_KERNEL);
|
||||
if (!mr->pbl_buf) {
|
||||
ret = -ENOMEM;
|
||||
goto release_umem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = hr_dev->hw->rereg_write_mtpt(hr_dev, mr, flags, pdn,
|
||||
mr_access_flags, virt_addr,
|
||||
length, mailbox->buf);
|
||||
if (ret) {
|
||||
if (flags & IB_MR_REREG_TRANS)
|
||||
goto release_umem;
|
||||
else
|
||||
} else {
|
||||
ret = hr_dev->hw->rereg_write_mtpt(hr_dev, mr, flags, pdn,
|
||||
mr_access_flags, virt_addr,
|
||||
length, mailbox->buf);
|
||||
if (ret)
|
||||
goto free_cmd_mbox;
|
||||
}
|
||||
|
||||
if (flags & IB_MR_REREG_TRANS) {
|
||||
ret = hns_roce_ib_umem_write_mr(hr_dev, mr, mr->umem);
|
||||
if (ret) {
|
||||
if (mr->size != ~0ULL) {
|
||||
npages = ib_umem_page_count(mr->umem);
|
||||
|
||||
if (hr_dev->caps.pbl_hop_num)
|
||||
hns_roce_mhop_free(hr_dev, mr);
|
||||
else
|
||||
dma_free_coherent(dev, npages * 8,
|
||||
mr->pbl_buf,
|
||||
mr->pbl_dma_addr);
|
||||
}
|
||||
|
||||
goto release_umem;
|
||||
}
|
||||
}
|
||||
|
||||
ret = hns_roce_sw2hw_mpt(hr_dev, mailbox, mtpt_idx);
|
||||
if (ret) {
|
||||
dev_err(dev, "SW2HW_MPT failed (%d)\n", ret);
|
||||
goto release_umem;
|
||||
ib_umem_release(mr->umem);
|
||||
goto free_cmd_mbox;
|
||||
}
|
||||
|
||||
mr->enabled = 1;
|
||||
|
@ -1275,9 +1347,6 @@ int hns_roce_rereg_user_mr(struct ib_mr *ibmr, int flags, u64 start, u64 length,
|
|||
|
||||
return 0;
|
||||
|
||||
release_umem:
|
||||
ib_umem_release(mr->umem);
|
||||
|
||||
free_cmd_mbox:
|
||||
hns_roce_free_cmd_mailbox(hr_dev, mailbox);
|
||||
|
||||
|
@ -1357,7 +1426,7 @@ static int hns_roce_set_page(struct ib_mr *ibmr, u64 addr)
|
|||
{
|
||||
struct hns_roce_mr *mr = to_hr_mr(ibmr);
|
||||
|
||||
mr->pbl_buf[mr->npages++] = cpu_to_le64(addr);
|
||||
mr->pbl_buf[mr->npages++] = addr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1528,10 +1597,9 @@ static int hns_roce_write_mtr(struct hns_roce_dev *hr_dev,
|
|||
/* Save page addr, low 12 bits : 0 */
|
||||
for (i = 0; i < count; i++) {
|
||||
if (hr_dev->hw_rev == HNS_ROCE_HW_VER1)
|
||||
mtts[i] = cpu_to_le64(bufs[npage] >>
|
||||
PAGE_ADDR_SHIFT);
|
||||
mtts[i] = bufs[npage] >> PAGE_ADDR_SHIFT;
|
||||
else
|
||||
mtts[i] = cpu_to_le64(bufs[npage]);
|
||||
mtts[i] = bufs[npage];
|
||||
|
||||
npage++;
|
||||
}
|
||||
|
|
|
@ -324,31 +324,46 @@ static int hns_roce_set_rq_size(struct hns_roce_dev *hr_dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int hns_roce_set_user_sq_size(struct hns_roce_dev *hr_dev,
|
||||
struct ib_qp_cap *cap,
|
||||
struct hns_roce_qp *hr_qp,
|
||||
struct hns_roce_ib_create_qp *ucmd)
|
||||
static int check_sq_size_with_integrity(struct hns_roce_dev *hr_dev,
|
||||
struct ib_qp_cap *cap,
|
||||
struct hns_roce_ib_create_qp *ucmd)
|
||||
{
|
||||
u32 roundup_sq_stride = roundup_pow_of_two(hr_dev->caps.max_sq_desc_sz);
|
||||
u8 max_sq_stride = ilog2(roundup_sq_stride);
|
||||
u32 ex_sge_num;
|
||||
u32 page_size;
|
||||
u32 max_cnt;
|
||||
|
||||
/* Sanity check SQ size before proceeding */
|
||||
if ((u32)(1 << ucmd->log_sq_bb_count) > hr_dev->caps.max_wqes ||
|
||||
ucmd->log_sq_stride > max_sq_stride ||
|
||||
ucmd->log_sq_stride < HNS_ROCE_IB_MIN_SQ_STRIDE) {
|
||||
dev_err(hr_dev->dev, "check SQ size error!\n");
|
||||
ibdev_err(&hr_dev->ib_dev, "check SQ size error!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (cap->max_send_sge > hr_dev->caps.max_sq_sg) {
|
||||
dev_err(hr_dev->dev, "SQ sge error! max_send_sge=%d\n",
|
||||
cap->max_send_sge);
|
||||
ibdev_err(&hr_dev->ib_dev, "SQ sge error! max_send_sge=%d\n",
|
||||
cap->max_send_sge);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hns_roce_set_user_sq_size(struct hns_roce_dev *hr_dev,
|
||||
struct ib_qp_cap *cap,
|
||||
struct hns_roce_qp *hr_qp,
|
||||
struct hns_roce_ib_create_qp *ucmd)
|
||||
{
|
||||
u32 ex_sge_num;
|
||||
u32 page_size;
|
||||
u32 max_cnt;
|
||||
int ret;
|
||||
|
||||
ret = check_sq_size_with_integrity(hr_dev, cap, ucmd);
|
||||
if (ret) {
|
||||
ibdev_err(&hr_dev->ib_dev, "Sanity check sq size failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
hr_qp->sq.wqe_cnt = 1 << ucmd->log_sq_bb_count;
|
||||
hr_qp->sq.wqe_shift = ucmd->log_sq_stride;
|
||||
|
||||
|
@ -501,43 +516,10 @@ static int calc_wqe_bt_page_shift(struct hns_roce_dev *hr_dev,
|
|||
return bt_pg_shift - PAGE_SHIFT;
|
||||
}
|
||||
|
||||
static int hns_roce_set_kernel_sq_size(struct hns_roce_dev *hr_dev,
|
||||
struct ib_qp_cap *cap,
|
||||
struct hns_roce_qp *hr_qp)
|
||||
static int set_extend_sge_param(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_qp *hr_qp)
|
||||
{
|
||||
struct device *dev = hr_dev->dev;
|
||||
u32 page_size;
|
||||
u32 max_cnt;
|
||||
int size;
|
||||
|
||||
if (cap->max_send_wr > hr_dev->caps.max_wqes ||
|
||||
cap->max_send_sge > hr_dev->caps.max_sq_sg ||
|
||||
cap->max_inline_data > hr_dev->caps.max_sq_inline) {
|
||||
dev_err(dev, "SQ WR or sge or inline data error!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hr_qp->sq.wqe_shift = ilog2(hr_dev->caps.max_sq_desc_sz);
|
||||
hr_qp->sq_max_wqes_per_wr = 1;
|
||||
hr_qp->sq_spare_wqes = 0;
|
||||
|
||||
if (hr_dev->caps.min_wqes)
|
||||
max_cnt = max(cap->max_send_wr, hr_dev->caps.min_wqes);
|
||||
else
|
||||
max_cnt = cap->max_send_wr;
|
||||
|
||||
hr_qp->sq.wqe_cnt = roundup_pow_of_two(max_cnt);
|
||||
if ((u32)hr_qp->sq.wqe_cnt > hr_dev->caps.max_wqes) {
|
||||
dev_err(dev, "while setting kernel sq size, sq.wqe_cnt too large\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Get data_seg numbers */
|
||||
max_cnt = max(1U, cap->max_send_sge);
|
||||
if (hr_dev->caps.max_sq_sg <= 2)
|
||||
hr_qp->sq.max_gs = roundup_pow_of_two(max_cnt);
|
||||
else
|
||||
hr_qp->sq.max_gs = max_cnt;
|
||||
|
||||
if (hr_qp->sq.max_gs > 2) {
|
||||
hr_qp->sge.sge_cnt = roundup_pow_of_two(hr_qp->sq.wqe_cnt *
|
||||
|
@ -560,6 +542,52 @@ static int hns_roce_set_kernel_sq_size(struct hns_roce_dev *hr_dev,
|
|||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hns_roce_set_kernel_sq_size(struct hns_roce_dev *hr_dev,
|
||||
struct ib_qp_cap *cap,
|
||||
struct hns_roce_qp *hr_qp)
|
||||
{
|
||||
struct device *dev = hr_dev->dev;
|
||||
u32 page_size;
|
||||
u32 max_cnt;
|
||||
int size;
|
||||
int ret;
|
||||
|
||||
if (cap->max_send_wr > hr_dev->caps.max_wqes ||
|
||||
cap->max_send_sge > hr_dev->caps.max_sq_sg ||
|
||||
cap->max_inline_data > hr_dev->caps.max_sq_inline) {
|
||||
dev_err(dev, "SQ WR or sge or inline data error!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hr_qp->sq.wqe_shift = ilog2(hr_dev->caps.max_sq_desc_sz);
|
||||
|
||||
if (hr_dev->caps.min_wqes)
|
||||
max_cnt = max(cap->max_send_wr, hr_dev->caps.min_wqes);
|
||||
else
|
||||
max_cnt = cap->max_send_wr;
|
||||
|
||||
hr_qp->sq.wqe_cnt = roundup_pow_of_two(max_cnt);
|
||||
if ((u32)hr_qp->sq.wqe_cnt > hr_dev->caps.max_wqes) {
|
||||
dev_err(dev, "while setting kernel sq size, sq.wqe_cnt too large\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Get data_seg numbers */
|
||||
max_cnt = max(1U, cap->max_send_sge);
|
||||
if (hr_dev->caps.max_sq_sg <= 2)
|
||||
hr_qp->sq.max_gs = roundup_pow_of_two(max_cnt);
|
||||
else
|
||||
hr_qp->sq.max_gs = max_cnt;
|
||||
|
||||
ret = set_extend_sge_param(hr_dev, hr_qp);
|
||||
if (ret) {
|
||||
dev_err(dev, "set extend sge parameters fail\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Get buf size, SQ and RQ are aligned to PAGE_SIZE */
|
||||
page_size = 1 << (hr_dev->caps.mtt_buf_pg_sz + PAGE_SHIFT);
|
||||
hr_qp->sq.offset = 0;
|
||||
|
@ -607,13 +635,57 @@ static int hns_roce_qp_has_rq(struct ib_qp_init_attr *attr)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int alloc_rq_inline_buf(struct hns_roce_qp *hr_qp,
|
||||
struct ib_qp_init_attr *init_attr)
|
||||
{
|
||||
u32 max_recv_sge = init_attr->cap.max_recv_sge;
|
||||
struct hns_roce_rinl_wqe *wqe_list;
|
||||
u32 wqe_cnt = hr_qp->rq.wqe_cnt;
|
||||
int i;
|
||||
|
||||
/* allocate recv inline buf */
|
||||
wqe_list = kcalloc(wqe_cnt, sizeof(struct hns_roce_rinl_wqe),
|
||||
GFP_KERNEL);
|
||||
|
||||
if (!wqe_list)
|
||||
goto err;
|
||||
|
||||
/* Allocate a continuous buffer for all inline sge we need */
|
||||
wqe_list[0].sg_list = kcalloc(wqe_cnt, (max_recv_sge *
|
||||
sizeof(struct hns_roce_rinl_sge)),
|
||||
GFP_KERNEL);
|
||||
if (!wqe_list[0].sg_list)
|
||||
goto err_wqe_list;
|
||||
|
||||
/* Assign buffers of sg_list to each inline wqe */
|
||||
for (i = 1; i < wqe_cnt; i++)
|
||||
wqe_list[i].sg_list = &wqe_list[0].sg_list[i * max_recv_sge];
|
||||
|
||||
hr_qp->rq_inl_buf.wqe_list = wqe_list;
|
||||
hr_qp->rq_inl_buf.wqe_cnt = wqe_cnt;
|
||||
|
||||
return 0;
|
||||
|
||||
err_wqe_list:
|
||||
kfree(wqe_list);
|
||||
|
||||
err:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void free_rq_inline_buf(struct hns_roce_qp *hr_qp)
|
||||
{
|
||||
kfree(hr_qp->rq_inl_buf.wqe_list[0].sg_list);
|
||||
kfree(hr_qp->rq_inl_buf.wqe_list);
|
||||
}
|
||||
|
||||
static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
|
||||
struct ib_pd *ib_pd,
|
||||
struct ib_qp_init_attr *init_attr,
|
||||
struct ib_udata *udata, unsigned long sqpn,
|
||||
struct hns_roce_qp *hr_qp)
|
||||
{
|
||||
dma_addr_t *buf_list[ARRAY_SIZE(hr_qp->regions)] = { 0 };
|
||||
dma_addr_t *buf_list[ARRAY_SIZE(hr_qp->regions)] = { NULL };
|
||||
struct device *dev = hr_dev->dev;
|
||||
struct hns_roce_ib_create_qp ucmd;
|
||||
struct hns_roce_ib_create_qp_resp resp = {};
|
||||
|
@ -635,9 +707,9 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
|
|||
hr_qp->ibqp.qp_type = init_attr->qp_type;
|
||||
|
||||
if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR)
|
||||
hr_qp->sq_signal_bits = cpu_to_le32(IB_SIGNAL_ALL_WR);
|
||||
hr_qp->sq_signal_bits = IB_SIGNAL_ALL_WR;
|
||||
else
|
||||
hr_qp->sq_signal_bits = cpu_to_le32(IB_SIGNAL_REQ_WR);
|
||||
hr_qp->sq_signal_bits = IB_SIGNAL_REQ_WR;
|
||||
|
||||
ret = hns_roce_set_rq_size(hr_dev, &init_attr->cap, udata,
|
||||
hns_roce_qp_has_rq(init_attr), hr_qp);
|
||||
|
@ -648,33 +720,11 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
|
|||
|
||||
if ((hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RQ_INLINE) &&
|
||||
hns_roce_qp_has_rq(init_attr)) {
|
||||
/* allocate recv inline buf */
|
||||
hr_qp->rq_inl_buf.wqe_list = kcalloc(hr_qp->rq.wqe_cnt,
|
||||
sizeof(struct hns_roce_rinl_wqe),
|
||||
GFP_KERNEL);
|
||||
if (!hr_qp->rq_inl_buf.wqe_list) {
|
||||
ret = -ENOMEM;
|
||||
ret = alloc_rq_inline_buf(hr_qp, init_attr);
|
||||
if (ret) {
|
||||
dev_err(dev, "allocate receive inline buffer failed\n");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
hr_qp->rq_inl_buf.wqe_cnt = hr_qp->rq.wqe_cnt;
|
||||
|
||||
/* Firstly, allocate a list of sge space buffer */
|
||||
hr_qp->rq_inl_buf.wqe_list[0].sg_list =
|
||||
kcalloc(hr_qp->rq_inl_buf.wqe_cnt,
|
||||
init_attr->cap.max_recv_sge *
|
||||
sizeof(struct hns_roce_rinl_sge),
|
||||
GFP_KERNEL);
|
||||
if (!hr_qp->rq_inl_buf.wqe_list[0].sg_list) {
|
||||
ret = -ENOMEM;
|
||||
goto err_wqe_list;
|
||||
}
|
||||
|
||||
for (i = 1; i < hr_qp->rq_inl_buf.wqe_cnt; i++)
|
||||
/* Secondly, reallocate the buffer */
|
||||
hr_qp->rq_inl_buf.wqe_list[i].sg_list =
|
||||
&hr_qp->rq_inl_buf.wqe_list[0].sg_list[i *
|
||||
init_attr->cap.max_recv_sge];
|
||||
}
|
||||
|
||||
page_shift = PAGE_SHIFT + hr_dev->caps.mtt_buf_pg_sz;
|
||||
|
@ -682,14 +732,14 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
|
|||
if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd))) {
|
||||
dev_err(dev, "ib_copy_from_udata error for create qp\n");
|
||||
ret = -EFAULT;
|
||||
goto err_rq_sge_list;
|
||||
goto err_alloc_rq_inline_buf;
|
||||
}
|
||||
|
||||
ret = hns_roce_set_user_sq_size(hr_dev, &init_attr->cap, hr_qp,
|
||||
&ucmd);
|
||||
if (ret) {
|
||||
dev_err(dev, "hns_roce_set_user_sq_size error for create qp\n");
|
||||
goto err_rq_sge_list;
|
||||
goto err_alloc_rq_inline_buf;
|
||||
}
|
||||
|
||||
hr_qp->umem = ib_umem_get(udata, ucmd.buf_addr,
|
||||
|
@ -697,7 +747,7 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
|
|||
if (IS_ERR(hr_qp->umem)) {
|
||||
dev_err(dev, "ib_umem_get error for create qp\n");
|
||||
ret = PTR_ERR(hr_qp->umem);
|
||||
goto err_rq_sge_list;
|
||||
goto err_alloc_rq_inline_buf;
|
||||
}
|
||||
hr_qp->region_cnt = split_wqe_buf_region(hr_dev, hr_qp,
|
||||
hr_qp->regions, ARRAY_SIZE(hr_qp->regions),
|
||||
|
@ -758,13 +808,13 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
|
|||
IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK) {
|
||||
dev_err(dev, "init_attr->create_flags error!\n");
|
||||
ret = -EINVAL;
|
||||
goto err_rq_sge_list;
|
||||
goto err_alloc_rq_inline_buf;
|
||||
}
|
||||
|
||||
if (init_attr->create_flags & IB_QP_CREATE_IPOIB_UD_LSO) {
|
||||
dev_err(dev, "init_attr->create_flags error!\n");
|
||||
ret = -EINVAL;
|
||||
goto err_rq_sge_list;
|
||||
goto err_alloc_rq_inline_buf;
|
||||
}
|
||||
|
||||
/* Set SQ size */
|
||||
|
@ -772,7 +822,7 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
|
|||
hr_qp);
|
||||
if (ret) {
|
||||
dev_err(dev, "hns_roce_set_kernel_sq_size error!\n");
|
||||
goto err_rq_sge_list;
|
||||
goto err_alloc_rq_inline_buf;
|
||||
}
|
||||
|
||||
/* QP doorbell register address */
|
||||
|
@ -786,7 +836,7 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
|
|||
ret = hns_roce_alloc_db(hr_dev, &hr_qp->rdb, 0);
|
||||
if (ret) {
|
||||
dev_err(dev, "rq record doorbell alloc failed!\n");
|
||||
goto err_rq_sge_list;
|
||||
goto err_alloc_rq_inline_buf;
|
||||
}
|
||||
*hr_qp->rdb.db_record = 0;
|
||||
hr_qp->rdb_en = 1;
|
||||
|
@ -826,11 +876,18 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
|
|||
|
||||
hr_qp->sq.wrid = kcalloc(hr_qp->sq.wqe_cnt, sizeof(u64),
|
||||
GFP_KERNEL);
|
||||
hr_qp->rq.wrid = kcalloc(hr_qp->rq.wqe_cnt, sizeof(u64),
|
||||
GFP_KERNEL);
|
||||
if (!hr_qp->sq.wrid || !hr_qp->rq.wrid) {
|
||||
if (ZERO_OR_NULL_PTR(hr_qp->sq.wrid)) {
|
||||
ret = -ENOMEM;
|
||||
goto err_wrid;
|
||||
goto err_get_bufs;
|
||||
}
|
||||
|
||||
if (hr_qp->rq.wqe_cnt) {
|
||||
hr_qp->rq.wrid = kcalloc(hr_qp->rq.wqe_cnt, sizeof(u64),
|
||||
GFP_KERNEL);
|
||||
if (ZERO_OR_NULL_PTR(hr_qp->rq.wrid)) {
|
||||
ret = -ENOMEM;
|
||||
goto err_sq_wrid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -875,7 +932,7 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
|
|||
if (sqpn)
|
||||
hr_qp->doorbell_qpn = 1;
|
||||
else
|
||||
hr_qp->doorbell_qpn = cpu_to_le64(hr_qp->qpn);
|
||||
hr_qp->doorbell_qpn = (u32)hr_qp->qpn;
|
||||
|
||||
if (udata) {
|
||||
ret = ib_copy_to_udata(udata, &resp,
|
||||
|
@ -916,8 +973,8 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
|
|||
hns_roce_qp_has_rq(init_attr))
|
||||
hns_roce_db_unmap_user(uctx, &hr_qp->rdb);
|
||||
} else {
|
||||
kfree(hr_qp->sq.wrid);
|
||||
kfree(hr_qp->rq.wrid);
|
||||
if (hr_qp->rq.wqe_cnt)
|
||||
kfree(hr_qp->rq.wrid);
|
||||
}
|
||||
|
||||
err_sq_dbmap:
|
||||
|
@ -928,6 +985,10 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
|
|||
hns_roce_qp_has_sq(init_attr))
|
||||
hns_roce_db_unmap_user(uctx, &hr_qp->sdb);
|
||||
|
||||
err_sq_wrid:
|
||||
if (!udata)
|
||||
kfree(hr_qp->sq.wrid);
|
||||
|
||||
err_get_bufs:
|
||||
hns_roce_free_buf_list(buf_list, hr_qp->region_cnt);
|
||||
|
||||
|
@ -941,13 +1002,10 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
|
|||
(hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB))
|
||||
hns_roce_free_db(hr_dev, &hr_qp->rdb);
|
||||
|
||||
err_rq_sge_list:
|
||||
if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RQ_INLINE)
|
||||
kfree(hr_qp->rq_inl_buf.wqe_list[0].sg_list);
|
||||
|
||||
err_wqe_list:
|
||||
if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RQ_INLINE)
|
||||
kfree(hr_qp->rq_inl_buf.wqe_list);
|
||||
err_alloc_rq_inline_buf:
|
||||
if ((hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RQ_INLINE) &&
|
||||
hns_roce_qp_has_rq(init_attr))
|
||||
free_rq_inline_buf(hr_qp);
|
||||
|
||||
err_out:
|
||||
return ret;
|
||||
|
@ -958,7 +1016,7 @@ struct ib_qp *hns_roce_create_qp(struct ib_pd *pd,
|
|||
struct ib_udata *udata)
|
||||
{
|
||||
struct hns_roce_dev *hr_dev = to_hr_dev(pd->device);
|
||||
struct device *dev = hr_dev->dev;
|
||||
struct ib_device *ibdev = &hr_dev->ib_dev;
|
||||
struct hns_roce_sqp *hr_sqp;
|
||||
struct hns_roce_qp *hr_qp;
|
||||
int ret;
|
||||
|
@ -972,7 +1030,8 @@ struct ib_qp *hns_roce_create_qp(struct ib_pd *pd,
|
|||
ret = hns_roce_create_qp_common(hr_dev, pd, init_attr, udata, 0,
|
||||
hr_qp);
|
||||
if (ret) {
|
||||
dev_err(dev, "Create RC QP failed\n");
|
||||
ibdev_err(ibdev, "Create RC QP 0x%06lx failed(%d)\n",
|
||||
hr_qp->qpn, ret);
|
||||
kfree(hr_qp);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
@ -984,7 +1043,7 @@ struct ib_qp *hns_roce_create_qp(struct ib_pd *pd,
|
|||
case IB_QPT_GSI: {
|
||||
/* Userspace is not allowed to create special QPs: */
|
||||
if (udata) {
|
||||
dev_err(dev, "not support usr space GSI\n");
|
||||
ibdev_err(ibdev, "not support usr space GSI\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
|
@ -1006,7 +1065,7 @@ struct ib_qp *hns_roce_create_qp(struct ib_pd *pd,
|
|||
ret = hns_roce_create_qp_common(hr_dev, pd, init_attr, udata,
|
||||
hr_qp->ibqp.qp_num, hr_qp);
|
||||
if (ret) {
|
||||
dev_err(dev, "Create GSI QP failed!\n");
|
||||
ibdev_err(ibdev, "Create GSI QP failed!\n");
|
||||
kfree(hr_sqp);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
@ -1014,7 +1073,8 @@ struct ib_qp *hns_roce_create_qp(struct ib_pd *pd,
|
|||
break;
|
||||
}
|
||||
default:{
|
||||
dev_err(dev, "not support QP type %d\n", init_attr->qp_type);
|
||||
ibdev_err(ibdev, "not support QP type %d\n",
|
||||
init_attr->qp_type);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
}
|
||||
|
@ -1040,23 +1100,88 @@ int to_hr_qp_type(int qp_type)
|
|||
return transport_type;
|
||||
}
|
||||
|
||||
static int check_mtu_validate(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_qp *hr_qp,
|
||||
struct ib_qp_attr *attr, int attr_mask)
|
||||
{
|
||||
enum ib_mtu active_mtu;
|
||||
int p;
|
||||
|
||||
p = attr_mask & IB_QP_PORT ? (attr->port_num - 1) : hr_qp->port;
|
||||
active_mtu = iboe_get_mtu(hr_dev->iboe.netdevs[p]->mtu);
|
||||
|
||||
if ((hr_dev->caps.max_mtu >= IB_MTU_2048 &&
|
||||
attr->path_mtu > hr_dev->caps.max_mtu) ||
|
||||
attr->path_mtu < IB_MTU_256 || attr->path_mtu > active_mtu) {
|
||||
ibdev_err(&hr_dev->ib_dev,
|
||||
"attr path_mtu(%d)invalid while modify qp",
|
||||
attr->path_mtu);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hns_roce_check_qp_attr(struct ib_qp *ibqp, struct ib_qp_attr *attr,
|
||||
int attr_mask)
|
||||
{
|
||||
struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
|
||||
struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
|
||||
int p;
|
||||
|
||||
if ((attr_mask & IB_QP_PORT) &&
|
||||
(attr->port_num == 0 || attr->port_num > hr_dev->caps.num_ports)) {
|
||||
ibdev_err(&hr_dev->ib_dev,
|
||||
"attr port_num invalid.attr->port_num=%d\n",
|
||||
attr->port_num);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (attr_mask & IB_QP_PKEY_INDEX) {
|
||||
p = attr_mask & IB_QP_PORT ? (attr->port_num - 1) : hr_qp->port;
|
||||
if (attr->pkey_index >= hr_dev->caps.pkey_table_len[p]) {
|
||||
ibdev_err(&hr_dev->ib_dev,
|
||||
"attr pkey_index invalid.attr->pkey_index=%d\n",
|
||||
attr->pkey_index);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC &&
|
||||
attr->max_rd_atomic > hr_dev->caps.max_qp_init_rdma) {
|
||||
ibdev_err(&hr_dev->ib_dev,
|
||||
"attr max_rd_atomic invalid.attr->max_rd_atomic=%d\n",
|
||||
attr->max_rd_atomic);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC &&
|
||||
attr->max_dest_rd_atomic > hr_dev->caps.max_qp_dest_rdma) {
|
||||
ibdev_err(&hr_dev->ib_dev,
|
||||
"attr max_dest_rd_atomic invalid.attr->max_dest_rd_atomic=%d\n",
|
||||
attr->max_dest_rd_atomic);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (attr_mask & IB_QP_PATH_MTU)
|
||||
return check_mtu_validate(hr_dev, hr_qp, attr, attr_mask);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hns_roce_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
|
||||
int attr_mask, struct ib_udata *udata)
|
||||
{
|
||||
struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
|
||||
struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
|
||||
enum ib_qp_state cur_state, new_state;
|
||||
struct device *dev = hr_dev->dev;
|
||||
int ret = -EINVAL;
|
||||
int p;
|
||||
enum ib_mtu active_mtu;
|
||||
|
||||
mutex_lock(&hr_qp->mutex);
|
||||
|
||||
cur_state = attr_mask & IB_QP_CUR_STATE ?
|
||||
attr->cur_qp_state : (enum ib_qp_state)hr_qp->state;
|
||||
new_state = attr_mask & IB_QP_STATE ?
|
||||
attr->qp_state : cur_state;
|
||||
new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state;
|
||||
|
||||
if (ibqp->uobject &&
|
||||
(attr_mask & IB_QP_STATE) && new_state == IB_QPS_ERR) {
|
||||
|
@ -1066,67 +1191,27 @@ int hns_roce_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
|
|||
if (hr_qp->rdb_en == 1)
|
||||
hr_qp->rq.head = *(int *)(hr_qp->rdb.virt_addr);
|
||||
} else {
|
||||
dev_warn(dev, "flush cqe is not supported in userspace!\n");
|
||||
ibdev_warn(&hr_dev->ib_dev,
|
||||
"flush cqe is not supported in userspace!\n");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type,
|
||||
attr_mask)) {
|
||||
dev_err(dev, "ib_modify_qp_is_ok failed\n");
|
||||
ibdev_err(&hr_dev->ib_dev, "ib_modify_qp_is_ok failed\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((attr_mask & IB_QP_PORT) &&
|
||||
(attr->port_num == 0 || attr->port_num > hr_dev->caps.num_ports)) {
|
||||
dev_err(dev, "attr port_num invalid.attr->port_num=%d\n",
|
||||
attr->port_num);
|
||||
ret = hns_roce_check_qp_attr(ibqp, attr, attr_mask);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (attr_mask & IB_QP_PKEY_INDEX) {
|
||||
p = attr_mask & IB_QP_PORT ? (attr->port_num - 1) : hr_qp->port;
|
||||
if (attr->pkey_index >= hr_dev->caps.pkey_table_len[p]) {
|
||||
dev_err(dev, "attr pkey_index invalid.attr->pkey_index=%d\n",
|
||||
attr->pkey_index);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (attr_mask & IB_QP_PATH_MTU) {
|
||||
p = attr_mask & IB_QP_PORT ? (attr->port_num - 1) : hr_qp->port;
|
||||
active_mtu = iboe_get_mtu(hr_dev->iboe.netdevs[p]->mtu);
|
||||
|
||||
if ((hr_dev->caps.max_mtu == IB_MTU_4096 &&
|
||||
attr->path_mtu > IB_MTU_4096) ||
|
||||
(hr_dev->caps.max_mtu == IB_MTU_2048 &&
|
||||
attr->path_mtu > IB_MTU_2048) ||
|
||||
attr->path_mtu < IB_MTU_256 ||
|
||||
attr->path_mtu > active_mtu) {
|
||||
dev_err(dev, "attr path_mtu(%d)invalid while modify qp",
|
||||
attr->path_mtu);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC &&
|
||||
attr->max_rd_atomic > hr_dev->caps.max_qp_init_rdma) {
|
||||
dev_err(dev, "attr max_rd_atomic invalid.attr->max_rd_atomic=%d\n",
|
||||
attr->max_rd_atomic);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC &&
|
||||
attr->max_dest_rd_atomic > hr_dev->caps.max_qp_dest_rdma) {
|
||||
dev_err(dev, "attr max_dest_rd_atomic invalid.attr->max_dest_rd_atomic=%d\n",
|
||||
attr->max_dest_rd_atomic);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (cur_state == new_state && cur_state == IB_QPS_RESET) {
|
||||
if (hr_dev->caps.min_wqes) {
|
||||
ret = -EPERM;
|
||||
dev_err(dev, "cur_state=%d new_state=%d\n", cur_state,
|
||||
ibdev_err(&hr_dev->ib_dev,
|
||||
"cur_state=%d new_state=%d\n", cur_state,
|
||||
new_state);
|
||||
} else {
|
||||
ret = 0;
|
||||
|
|
|
@ -175,6 +175,76 @@ static void hns_roce_srq_free(struct hns_roce_dev *hr_dev,
|
|||
hns_roce_bitmap_free(&srq_table->bitmap, srq->srqn, BITMAP_NO_RR);
|
||||
}
|
||||
|
||||
static int create_user_srq(struct hns_roce_srq *srq, struct ib_udata *udata,
|
||||
int srq_buf_size)
|
||||
{
|
||||
struct hns_roce_dev *hr_dev = to_hr_dev(srq->ibsrq.device);
|
||||
struct hns_roce_ib_create_srq ucmd;
|
||||
u32 page_shift;
|
||||
u32 npages;
|
||||
int ret;
|
||||
|
||||
if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd)))
|
||||
return -EFAULT;
|
||||
|
||||
srq->umem = ib_umem_get(udata, ucmd.buf_addr, srq_buf_size, 0, 0);
|
||||
if (IS_ERR(srq->umem))
|
||||
return PTR_ERR(srq->umem);
|
||||
|
||||
npages = (ib_umem_page_count(srq->umem) +
|
||||
(1 << hr_dev->caps.srqwqe_buf_pg_sz) - 1) /
|
||||
(1 << hr_dev->caps.srqwqe_buf_pg_sz);
|
||||
page_shift = PAGE_SHIFT + hr_dev->caps.srqwqe_buf_pg_sz;
|
||||
ret = hns_roce_mtt_init(hr_dev, npages, page_shift, &srq->mtt);
|
||||
if (ret)
|
||||
goto err_user_buf;
|
||||
|
||||
ret = hns_roce_ib_umem_write_mtt(hr_dev, &srq->mtt, srq->umem);
|
||||
if (ret)
|
||||
goto err_user_srq_mtt;
|
||||
|
||||
/* config index queue BA */
|
||||
srq->idx_que.umem = ib_umem_get(udata, ucmd.que_addr,
|
||||
srq->idx_que.buf_size, 0, 0);
|
||||
if (IS_ERR(srq->idx_que.umem)) {
|
||||
dev_err(hr_dev->dev, "ib_umem_get error for index queue\n");
|
||||
ret = PTR_ERR(srq->idx_que.umem);
|
||||
goto err_user_srq_mtt;
|
||||
}
|
||||
|
||||
ret = hns_roce_mtt_init(hr_dev, ib_umem_page_count(srq->idx_que.umem),
|
||||
PAGE_SHIFT, &srq->idx_que.mtt);
|
||||
|
||||
if (ret) {
|
||||
dev_err(hr_dev->dev, "hns_roce_mtt_init error for idx que\n");
|
||||
goto err_user_idx_mtt;
|
||||
}
|
||||
|
||||
ret = hns_roce_ib_umem_write_mtt(hr_dev, &srq->idx_que.mtt,
|
||||
srq->idx_que.umem);
|
||||
if (ret) {
|
||||
dev_err(hr_dev->dev,
|
||||
"hns_roce_ib_umem_write_mtt error for idx que\n");
|
||||
goto err_user_idx_buf;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_user_idx_buf:
|
||||
hns_roce_mtt_cleanup(hr_dev, &srq->idx_que.mtt);
|
||||
|
||||
err_user_idx_mtt:
|
||||
ib_umem_release(srq->idx_que.umem);
|
||||
|
||||
err_user_srq_mtt:
|
||||
hns_roce_mtt_cleanup(hr_dev, &srq->mtt);
|
||||
|
||||
err_user_buf:
|
||||
ib_umem_release(srq->umem);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hns_roce_create_idx_que(struct ib_pd *pd, struct hns_roce_srq *srq,
|
||||
u32 page_shift)
|
||||
{
|
||||
|
@ -196,6 +266,93 @@ static int hns_roce_create_idx_que(struct ib_pd *pd, struct hns_roce_srq *srq,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int create_kernel_srq(struct hns_roce_srq *srq, int srq_buf_size)
|
||||
{
|
||||
struct hns_roce_dev *hr_dev = to_hr_dev(srq->ibsrq.device);
|
||||
u32 page_shift = PAGE_SHIFT + hr_dev->caps.srqwqe_buf_pg_sz;
|
||||
int ret;
|
||||
|
||||
if (hns_roce_buf_alloc(hr_dev, srq_buf_size, (1 << page_shift) * 2,
|
||||
&srq->buf, page_shift))
|
||||
return -ENOMEM;
|
||||
|
||||
srq->head = 0;
|
||||
srq->tail = srq->max - 1;
|
||||
|
||||
ret = hns_roce_mtt_init(hr_dev, srq->buf.npages, srq->buf.page_shift,
|
||||
&srq->mtt);
|
||||
if (ret)
|
||||
goto err_kernel_buf;
|
||||
|
||||
ret = hns_roce_buf_write_mtt(hr_dev, &srq->mtt, &srq->buf);
|
||||
if (ret)
|
||||
goto err_kernel_srq_mtt;
|
||||
|
||||
page_shift = PAGE_SHIFT + hr_dev->caps.idx_buf_pg_sz;
|
||||
ret = hns_roce_create_idx_que(srq->ibsrq.pd, srq, page_shift);
|
||||
if (ret) {
|
||||
dev_err(hr_dev->dev, "Create idx queue fail(%d)!\n", ret);
|
||||
goto err_kernel_srq_mtt;
|
||||
}
|
||||
|
||||
/* Init mtt table for idx_que */
|
||||
ret = hns_roce_mtt_init(hr_dev, srq->idx_que.idx_buf.npages,
|
||||
srq->idx_que.idx_buf.page_shift,
|
||||
&srq->idx_que.mtt);
|
||||
if (ret)
|
||||
goto err_kernel_create_idx;
|
||||
|
||||
/* Write buffer address into the mtt table */
|
||||
ret = hns_roce_buf_write_mtt(hr_dev, &srq->idx_que.mtt,
|
||||
&srq->idx_que.idx_buf);
|
||||
if (ret)
|
||||
goto err_kernel_idx_buf;
|
||||
|
||||
srq->wrid = kvmalloc_array(srq->max, sizeof(u64), GFP_KERNEL);
|
||||
if (!srq->wrid) {
|
||||
ret = -ENOMEM;
|
||||
goto err_kernel_idx_buf;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_kernel_idx_buf:
|
||||
hns_roce_mtt_cleanup(hr_dev, &srq->idx_que.mtt);
|
||||
|
||||
err_kernel_create_idx:
|
||||
hns_roce_buf_free(hr_dev, srq->idx_que.buf_size,
|
||||
&srq->idx_que.idx_buf);
|
||||
kfree(srq->idx_que.bitmap);
|
||||
|
||||
err_kernel_srq_mtt:
|
||||
hns_roce_mtt_cleanup(hr_dev, &srq->mtt);
|
||||
|
||||
err_kernel_buf:
|
||||
hns_roce_buf_free(hr_dev, srq_buf_size, &srq->buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void destroy_user_srq(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_srq *srq)
|
||||
{
|
||||
hns_roce_mtt_cleanup(hr_dev, &srq->idx_que.mtt);
|
||||
ib_umem_release(srq->idx_que.umem);
|
||||
hns_roce_mtt_cleanup(hr_dev, &srq->mtt);
|
||||
ib_umem_release(srq->umem);
|
||||
}
|
||||
|
||||
static void destroy_kernel_srq(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_srq *srq, int srq_buf_size)
|
||||
{
|
||||
kvfree(srq->wrid);
|
||||
hns_roce_mtt_cleanup(hr_dev, &srq->idx_que.mtt);
|
||||
hns_roce_buf_free(hr_dev, srq->idx_que.buf_size, &srq->idx_que.idx_buf);
|
||||
kfree(srq->idx_que.bitmap);
|
||||
hns_roce_mtt_cleanup(hr_dev, &srq->mtt);
|
||||
hns_roce_buf_free(hr_dev, srq_buf_size, &srq->buf);
|
||||
}
|
||||
|
||||
int hns_roce_create_srq(struct ib_srq *ib_srq,
|
||||
struct ib_srq_init_attr *srq_init_attr,
|
||||
struct ib_udata *udata)
|
||||
|
@ -205,9 +362,7 @@ int hns_roce_create_srq(struct ib_srq *ib_srq,
|
|||
struct hns_roce_srq *srq = to_hr_srq(ib_srq);
|
||||
int srq_desc_size;
|
||||
int srq_buf_size;
|
||||
u32 page_shift;
|
||||
int ret = 0;
|
||||
u32 npages;
|
||||
u32 cqn;
|
||||
|
||||
/* Check the actual SRQ wqe and SRQ sge num */
|
||||
|
@ -233,115 +388,16 @@ int hns_roce_create_srq(struct ib_srq *ib_srq,
|
|||
srq->idx_que.mtt.mtt_type = MTT_TYPE_IDX;
|
||||
|
||||
if (udata) {
|
||||
struct hns_roce_ib_create_srq ucmd;
|
||||
|
||||
if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd)))
|
||||
return -EFAULT;
|
||||
|
||||
srq->umem =
|
||||
ib_umem_get(udata, ucmd.buf_addr, srq_buf_size, 0, 0);
|
||||
if (IS_ERR(srq->umem))
|
||||
return PTR_ERR(srq->umem);
|
||||
|
||||
if (hr_dev->caps.srqwqe_buf_pg_sz) {
|
||||
npages = (ib_umem_page_count(srq->umem) +
|
||||
(1 << hr_dev->caps.srqwqe_buf_pg_sz) - 1) /
|
||||
(1 << hr_dev->caps.srqwqe_buf_pg_sz);
|
||||
page_shift = PAGE_SHIFT + hr_dev->caps.srqwqe_buf_pg_sz;
|
||||
ret = hns_roce_mtt_init(hr_dev, npages,
|
||||
page_shift,
|
||||
&srq->mtt);
|
||||
} else
|
||||
ret = hns_roce_mtt_init(hr_dev,
|
||||
ib_umem_page_count(srq->umem),
|
||||
PAGE_SHIFT, &srq->mtt);
|
||||
if (ret)
|
||||
goto err_buf;
|
||||
|
||||
ret = hns_roce_ib_umem_write_mtt(hr_dev, &srq->mtt, srq->umem);
|
||||
if (ret)
|
||||
goto err_srq_mtt;
|
||||
|
||||
/* config index queue BA */
|
||||
srq->idx_que.umem = ib_umem_get(udata, ucmd.que_addr,
|
||||
srq->idx_que.buf_size, 0, 0);
|
||||
if (IS_ERR(srq->idx_que.umem)) {
|
||||
dev_err(hr_dev->dev,
|
||||
"ib_umem_get error for index queue\n");
|
||||
ret = PTR_ERR(srq->idx_que.umem);
|
||||
goto err_srq_mtt;
|
||||
}
|
||||
|
||||
if (hr_dev->caps.idx_buf_pg_sz) {
|
||||
npages = (ib_umem_page_count(srq->idx_que.umem) +
|
||||
(1 << hr_dev->caps.idx_buf_pg_sz) - 1) /
|
||||
(1 << hr_dev->caps.idx_buf_pg_sz);
|
||||
page_shift = PAGE_SHIFT + hr_dev->caps.idx_buf_pg_sz;
|
||||
ret = hns_roce_mtt_init(hr_dev, npages,
|
||||
page_shift, &srq->idx_que.mtt);
|
||||
} else {
|
||||
ret = hns_roce_mtt_init(
|
||||
hr_dev, ib_umem_page_count(srq->idx_que.umem),
|
||||
PAGE_SHIFT, &srq->idx_que.mtt);
|
||||
}
|
||||
|
||||
ret = create_user_srq(srq, udata, srq_buf_size);
|
||||
if (ret) {
|
||||
dev_err(hr_dev->dev,
|
||||
"hns_roce_mtt_init error for idx que\n");
|
||||
goto err_idx_mtt;
|
||||
}
|
||||
|
||||
ret = hns_roce_ib_umem_write_mtt(hr_dev, &srq->idx_que.mtt,
|
||||
srq->idx_que.umem);
|
||||
if (ret) {
|
||||
dev_err(hr_dev->dev,
|
||||
"hns_roce_ib_umem_write_mtt error for idx que\n");
|
||||
goto err_idx_buf;
|
||||
dev_err(hr_dev->dev, "Create user srq failed\n");
|
||||
goto err_srq;
|
||||
}
|
||||
} else {
|
||||
page_shift = PAGE_SHIFT + hr_dev->caps.srqwqe_buf_pg_sz;
|
||||
if (hns_roce_buf_alloc(hr_dev, srq_buf_size,
|
||||
(1 << page_shift) * 2, &srq->buf,
|
||||
page_shift))
|
||||
return -ENOMEM;
|
||||
|
||||
srq->head = 0;
|
||||
srq->tail = srq->max - 1;
|
||||
|
||||
ret = hns_roce_mtt_init(hr_dev, srq->buf.npages,
|
||||
srq->buf.page_shift, &srq->mtt);
|
||||
if (ret)
|
||||
goto err_buf;
|
||||
|
||||
ret = hns_roce_buf_write_mtt(hr_dev, &srq->mtt, &srq->buf);
|
||||
if (ret)
|
||||
goto err_srq_mtt;
|
||||
|
||||
page_shift = PAGE_SHIFT + hr_dev->caps.idx_buf_pg_sz;
|
||||
ret = hns_roce_create_idx_que(ib_srq->pd, srq, page_shift);
|
||||
ret = create_kernel_srq(srq, srq_buf_size);
|
||||
if (ret) {
|
||||
dev_err(hr_dev->dev, "Create idx queue fail(%d)!\n",
|
||||
ret);
|
||||
goto err_srq_mtt;
|
||||
}
|
||||
|
||||
/* Init mtt table for idx_que */
|
||||
ret = hns_roce_mtt_init(hr_dev, srq->idx_que.idx_buf.npages,
|
||||
srq->idx_que.idx_buf.page_shift,
|
||||
&srq->idx_que.mtt);
|
||||
if (ret)
|
||||
goto err_create_idx;
|
||||
|
||||
/* Write buffer address into the mtt table */
|
||||
ret = hns_roce_buf_write_mtt(hr_dev, &srq->idx_que.mtt,
|
||||
&srq->idx_que.idx_buf);
|
||||
if (ret)
|
||||
goto err_idx_buf;
|
||||
|
||||
srq->wrid = kvmalloc_array(srq->max, sizeof(u64), GFP_KERNEL);
|
||||
if (!srq->wrid) {
|
||||
ret = -ENOMEM;
|
||||
goto err_idx_buf;
|
||||
dev_err(hr_dev->dev, "Create kernel srq failed\n");
|
||||
goto err_srq;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -356,7 +412,6 @@ int hns_roce_create_srq(struct ib_srq *ib_srq,
|
|||
goto err_wrid;
|
||||
|
||||
srq->event = hns_roce_ib_srq_event;
|
||||
srq->ibsrq.ext.xrc.srq_num = srq->srqn;
|
||||
resp.srqn = srq->srqn;
|
||||
|
||||
if (udata) {
|
||||
|
@ -373,27 +428,12 @@ int hns_roce_create_srq(struct ib_srq *ib_srq,
|
|||
hns_roce_srq_free(hr_dev, srq);
|
||||
|
||||
err_wrid:
|
||||
kvfree(srq->wrid);
|
||||
|
||||
err_idx_buf:
|
||||
hns_roce_mtt_cleanup(hr_dev, &srq->idx_que.mtt);
|
||||
|
||||
err_idx_mtt:
|
||||
ib_umem_release(srq->idx_que.umem);
|
||||
|
||||
err_create_idx:
|
||||
hns_roce_buf_free(hr_dev, srq->idx_que.buf_size,
|
||||
&srq->idx_que.idx_buf);
|
||||
bitmap_free(srq->idx_que.bitmap);
|
||||
|
||||
err_srq_mtt:
|
||||
hns_roce_mtt_cleanup(hr_dev, &srq->mtt);
|
||||
|
||||
err_buf:
|
||||
ib_umem_release(srq->umem);
|
||||
if (!udata)
|
||||
hns_roce_buf_free(hr_dev, srq_buf_size, &srq->buf);
|
||||
if (udata)
|
||||
destroy_user_srq(hr_dev, srq);
|
||||
else
|
||||
destroy_kernel_srq(hr_dev, srq, srq_buf_size);
|
||||
|
||||
err_srq:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -97,18 +97,7 @@ static int i40iw_query_port(struct ib_device *ibdev,
|
|||
u8 port,
|
||||
struct ib_port_attr *props)
|
||||
{
|
||||
struct i40iw_device *iwdev = to_iwdev(ibdev);
|
||||
struct net_device *netdev = iwdev->netdev;
|
||||
|
||||
/* props being zeroed by the caller, avoid zeroing it here */
|
||||
props->max_mtu = IB_MTU_4096;
|
||||
props->active_mtu = ib_mtu_int_to_enum(netdev->mtu);
|
||||
|
||||
props->lid = 1;
|
||||
if (netif_carrier_ok(iwdev->netdev))
|
||||
props->state = IB_PORT_ACTIVE;
|
||||
else
|
||||
props->state = IB_PORT_DOWN;
|
||||
props->port_cap_flags = IB_PORT_CM_SUP | IB_PORT_REINIT_SUP |
|
||||
IB_PORT_VENDOR_CLASS_SUP | IB_PORT_BOOT_MGMT_SUP;
|
||||
props->gid_tbl_len = 1;
|
||||
|
|
|
@ -734,7 +734,8 @@ static int ib_link_query_port(struct ib_device *ibdev, u8 port,
|
|||
|
||||
static u8 state_to_phys_state(enum ib_port_state state)
|
||||
{
|
||||
return state == IB_PORT_ACTIVE ? 5 : 3;
|
||||
return state == IB_PORT_ACTIVE ?
|
||||
IB_PORT_PHYS_STATE_LINK_UP : IB_PORT_PHYS_STATE_DISABLED;
|
||||
}
|
||||
|
||||
static int eth_link_query_port(struct ib_device *ibdev, u8 port,
|
||||
|
|
|
@ -377,6 +377,7 @@ static struct ib_umem *mlx4_get_umem_mr(struct ib_udata *udata, u64 start,
|
|||
* again
|
||||
*/
|
||||
if (!ib_access_writable(access_flags)) {
|
||||
unsigned long untagged_start = untagged_addr(start);
|
||||
struct vm_area_struct *vma;
|
||||
|
||||
down_read(¤t->mm->mmap_sem);
|
||||
|
@ -385,9 +386,9 @@ static struct ib_umem *mlx4_get_umem_mr(struct ib_udata *udata, u64 start,
|
|||
* cover the memory, but for now it requires a single vma to
|
||||
* entirely cover the MR to support RO mappings.
|
||||
*/
|
||||
vma = find_vma(current->mm, start);
|
||||
if (vma && vma->vm_end >= start + length &&
|
||||
vma->vm_start <= start) {
|
||||
vma = find_vma(current->mm, untagged_start);
|
||||
if (vma && vma->vm_end >= untagged_start + length &&
|
||||
vma->vm_start <= untagged_start) {
|
||||
if (vma->vm_flags & VM_WRITE)
|
||||
access_flags |= IB_ACCESS_LOCAL_WRITE;
|
||||
} else {
|
||||
|
|
|
@ -325,7 +325,7 @@ static int send_wqe_overhead(enum mlx4_ib_qp_type type, u32 flags)
|
|||
}
|
||||
|
||||
static int set_rq_size(struct mlx4_ib_dev *dev, struct ib_qp_cap *cap,
|
||||
bool is_user, int has_rq, struct mlx4_ib_qp *qp,
|
||||
bool is_user, bool has_rq, struct mlx4_ib_qp *qp,
|
||||
u32 inl_recv_sz)
|
||||
{
|
||||
/* Sanity check RQ size before proceeding */
|
||||
|
@ -506,10 +506,10 @@ static void free_proxy_bufs(struct ib_device *dev, struct mlx4_ib_qp *qp)
|
|||
kfree(qp->sqp_proxy_rcv);
|
||||
}
|
||||
|
||||
static int qp_has_rq(struct ib_qp_init_attr *attr)
|
||||
static bool qp_has_rq(struct ib_qp_init_attr *attr)
|
||||
{
|
||||
if (attr->qp_type == IB_QPT_XRC_INI || attr->qp_type == IB_QPT_XRC_TGT)
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
return !attr->srq;
|
||||
}
|
||||
|
@ -855,12 +855,143 @@ static void mlx4_ib_release_wqn(struct mlx4_ib_ucontext *context,
|
|||
mutex_unlock(&context->wqn_ranges_mutex);
|
||||
}
|
||||
|
||||
static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
|
||||
enum mlx4_ib_source_type src,
|
||||
struct ib_qp_init_attr *init_attr,
|
||||
static int create_rq(struct ib_pd *pd, struct ib_qp_init_attr *init_attr,
|
||||
struct ib_udata *udata, struct mlx4_ib_qp *qp)
|
||||
{
|
||||
struct mlx4_ib_dev *dev = to_mdev(pd->device);
|
||||
int qpn;
|
||||
int err;
|
||||
struct mlx4_ib_ucontext *context = rdma_udata_to_drv_context(
|
||||
udata, struct mlx4_ib_ucontext, ibucontext);
|
||||
struct mlx4_ib_cq *mcq;
|
||||
unsigned long flags;
|
||||
int range_size;
|
||||
struct mlx4_ib_create_wq wq;
|
||||
size_t copy_len;
|
||||
int shift;
|
||||
int n;
|
||||
|
||||
qp->mlx4_ib_qp_type = MLX4_IB_QPT_RAW_PACKET;
|
||||
|
||||
mutex_init(&qp->mutex);
|
||||
spin_lock_init(&qp->sq.lock);
|
||||
spin_lock_init(&qp->rq.lock);
|
||||
INIT_LIST_HEAD(&qp->gid_list);
|
||||
INIT_LIST_HEAD(&qp->steering_rules);
|
||||
|
||||
qp->state = IB_QPS_RESET;
|
||||
|
||||
copy_len = min(sizeof(struct mlx4_ib_create_wq), udata->inlen);
|
||||
|
||||
if (ib_copy_from_udata(&wq, udata, copy_len)) {
|
||||
err = -EFAULT;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (wq.comp_mask || wq.reserved[0] || wq.reserved[1] ||
|
||||
wq.reserved[2]) {
|
||||
pr_debug("user command isn't supported\n");
|
||||
err = -EOPNOTSUPP;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (wq.log_range_size > ilog2(dev->dev->caps.max_rss_tbl_sz)) {
|
||||
pr_debug("WQN range size must be equal or smaller than %d\n",
|
||||
dev->dev->caps.max_rss_tbl_sz);
|
||||
err = -EOPNOTSUPP;
|
||||
goto err;
|
||||
}
|
||||
range_size = 1 << wq.log_range_size;
|
||||
|
||||
if (init_attr->create_flags & IB_QP_CREATE_SCATTER_FCS)
|
||||
qp->flags |= MLX4_IB_QP_SCATTER_FCS;
|
||||
|
||||
err = set_rq_size(dev, &init_attr->cap, true, true, qp, qp->inl_recv_sz);
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
qp->sq_no_prefetch = 1;
|
||||
qp->sq.wqe_cnt = 1;
|
||||
qp->sq.wqe_shift = MLX4_IB_MIN_SQ_STRIDE;
|
||||
qp->buf_size = (qp->rq.wqe_cnt << qp->rq.wqe_shift) +
|
||||
(qp->sq.wqe_cnt << qp->sq.wqe_shift);
|
||||
|
||||
qp->umem = ib_umem_get(udata, wq.buf_addr, qp->buf_size, 0, 0);
|
||||
if (IS_ERR(qp->umem)) {
|
||||
err = PTR_ERR(qp->umem);
|
||||
goto err;
|
||||
}
|
||||
|
||||
n = ib_umem_page_count(qp->umem);
|
||||
shift = mlx4_ib_umem_calc_optimal_mtt_size(qp->umem, 0, &n);
|
||||
err = mlx4_mtt_init(dev->dev, n, shift, &qp->mtt);
|
||||
|
||||
if (err)
|
||||
goto err_buf;
|
||||
|
||||
err = mlx4_ib_umem_write_mtt(dev, &qp->mtt, qp->umem);
|
||||
if (err)
|
||||
goto err_mtt;
|
||||
|
||||
err = mlx4_ib_db_map_user(udata, wq.db_addr, &qp->db);
|
||||
if (err)
|
||||
goto err_mtt;
|
||||
qp->mqp.usage = MLX4_RES_USAGE_USER_VERBS;
|
||||
|
||||
err = mlx4_ib_alloc_wqn(context, qp, range_size, &qpn);
|
||||
if (err)
|
||||
goto err_wrid;
|
||||
|
||||
err = mlx4_qp_alloc(dev->dev, qpn, &qp->mqp);
|
||||
if (err)
|
||||
goto err_qpn;
|
||||
|
||||
/*
|
||||
* Hardware wants QPN written in big-endian order (after
|
||||
* shifting) for send doorbell. Precompute this value to save
|
||||
* a little bit when posting sends.
|
||||
*/
|
||||
qp->doorbell_qpn = swab32(qp->mqp.qpn << 8);
|
||||
|
||||
qp->mqp.event = mlx4_ib_wq_event;
|
||||
|
||||
spin_lock_irqsave(&dev->reset_flow_resource_lock, flags);
|
||||
mlx4_ib_lock_cqs(to_mcq(init_attr->send_cq),
|
||||
to_mcq(init_attr->recv_cq));
|
||||
/* Maintain device to QPs access, needed for further handling
|
||||
* via reset flow
|
||||
*/
|
||||
list_add_tail(&qp->qps_list, &dev->qp_list);
|
||||
/* Maintain CQ to QPs access, needed for further handling
|
||||
* via reset flow
|
||||
*/
|
||||
mcq = to_mcq(init_attr->send_cq);
|
||||
list_add_tail(&qp->cq_send_list, &mcq->send_qp_list);
|
||||
mcq = to_mcq(init_attr->recv_cq);
|
||||
list_add_tail(&qp->cq_recv_list, &mcq->recv_qp_list);
|
||||
mlx4_ib_unlock_cqs(to_mcq(init_attr->send_cq),
|
||||
to_mcq(init_attr->recv_cq));
|
||||
spin_unlock_irqrestore(&dev->reset_flow_resource_lock, flags);
|
||||
return 0;
|
||||
|
||||
err_qpn:
|
||||
mlx4_ib_release_wqn(context, qp, 0);
|
||||
err_wrid:
|
||||
mlx4_ib_db_unmap_user(context, &qp->db);
|
||||
|
||||
err_mtt:
|
||||
mlx4_mtt_cleanup(dev->dev, &qp->mtt);
|
||||
err_buf:
|
||||
ib_umem_release(qp->umem);
|
||||
err:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int create_qp_common(struct ib_pd *pd, struct ib_qp_init_attr *init_attr,
|
||||
struct ib_udata *udata, int sqpn,
|
||||
struct mlx4_ib_qp **caller_qp)
|
||||
{
|
||||
struct mlx4_ib_dev *dev = to_mdev(pd->device);
|
||||
int qpn;
|
||||
int err;
|
||||
struct mlx4_ib_sqp *sqp = NULL;
|
||||
|
@ -870,7 +1001,6 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
|
|||
enum mlx4_ib_qp_type qp_type = (enum mlx4_ib_qp_type) init_attr->qp_type;
|
||||
struct mlx4_ib_cq *mcq;
|
||||
unsigned long flags;
|
||||
int range_size = 0;
|
||||
|
||||
/* When tunneling special qps, we use a plain UD qp */
|
||||
if (sqpn) {
|
||||
|
@ -921,15 +1051,13 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
|
|||
if (!sqp)
|
||||
return -ENOMEM;
|
||||
qp = &sqp->qp;
|
||||
qp->pri.vid = 0xFFFF;
|
||||
qp->alt.vid = 0xFFFF;
|
||||
} else {
|
||||
qp = kzalloc(sizeof(struct mlx4_ib_qp), GFP_KERNEL);
|
||||
if (!qp)
|
||||
return -ENOMEM;
|
||||
qp->pri.vid = 0xFFFF;
|
||||
qp->alt.vid = 0xFFFF;
|
||||
}
|
||||
qp->pri.vid = 0xFFFF;
|
||||
qp->alt.vid = 0xFFFF;
|
||||
} else
|
||||
qp = *caller_qp;
|
||||
|
||||
|
@ -941,48 +1069,24 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
|
|||
INIT_LIST_HEAD(&qp->gid_list);
|
||||
INIT_LIST_HEAD(&qp->steering_rules);
|
||||
|
||||
qp->state = IB_QPS_RESET;
|
||||
qp->state = IB_QPS_RESET;
|
||||
if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR)
|
||||
qp->sq_signal_bits = cpu_to_be32(MLX4_WQE_CTRL_CQ_UPDATE);
|
||||
|
||||
|
||||
if (udata) {
|
||||
union {
|
||||
struct mlx4_ib_create_qp qp;
|
||||
struct mlx4_ib_create_wq wq;
|
||||
} ucmd;
|
||||
struct mlx4_ib_create_qp ucmd;
|
||||
size_t copy_len;
|
||||
int shift;
|
||||
int n;
|
||||
|
||||
copy_len = (src == MLX4_IB_QP_SRC) ?
|
||||
sizeof(struct mlx4_ib_create_qp) :
|
||||
min(sizeof(struct mlx4_ib_create_wq), udata->inlen);
|
||||
copy_len = sizeof(struct mlx4_ib_create_qp);
|
||||
|
||||
if (ib_copy_from_udata(&ucmd, udata, copy_len)) {
|
||||
err = -EFAULT;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (src == MLX4_IB_RWQ_SRC) {
|
||||
if (ucmd.wq.comp_mask || ucmd.wq.reserved[0] ||
|
||||
ucmd.wq.reserved[1] || ucmd.wq.reserved[2]) {
|
||||
pr_debug("user command isn't supported\n");
|
||||
err = -EOPNOTSUPP;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ucmd.wq.log_range_size >
|
||||
ilog2(dev->dev->caps.max_rss_tbl_sz)) {
|
||||
pr_debug("WQN range size must be equal or smaller than %d\n",
|
||||
dev->dev->caps.max_rss_tbl_sz);
|
||||
err = -EOPNOTSUPP;
|
||||
goto err;
|
||||
}
|
||||
range_size = 1 << ucmd.wq.log_range_size;
|
||||
} else {
|
||||
qp->inl_recv_sz = ucmd.qp.inl_recv_sz;
|
||||
}
|
||||
qp->inl_recv_sz = ucmd.inl_recv_sz;
|
||||
|
||||
if (init_attr->create_flags & IB_QP_CREATE_SCATTER_FCS) {
|
||||
if (!(dev->dev->caps.flags &
|
||||
|
@ -1000,30 +1104,14 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
|
|||
if (err)
|
||||
goto err;
|
||||
|
||||
if (src == MLX4_IB_QP_SRC) {
|
||||
qp->sq_no_prefetch = ucmd.qp.sq_no_prefetch;
|
||||
qp->sq_no_prefetch = ucmd.sq_no_prefetch;
|
||||
|
||||
err = set_user_sq_size(dev, qp,
|
||||
(struct mlx4_ib_create_qp *)
|
||||
&ucmd);
|
||||
if (err)
|
||||
goto err;
|
||||
} else {
|
||||
qp->sq_no_prefetch = 1;
|
||||
qp->sq.wqe_cnt = 1;
|
||||
qp->sq.wqe_shift = MLX4_IB_MIN_SQ_STRIDE;
|
||||
/* Allocated buffer expects to have at least that SQ
|
||||
* size.
|
||||
*/
|
||||
qp->buf_size = (qp->rq.wqe_cnt << qp->rq.wqe_shift) +
|
||||
(qp->sq.wqe_cnt << qp->sq.wqe_shift);
|
||||
}
|
||||
err = set_user_sq_size(dev, qp, &ucmd);
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
qp->umem =
|
||||
ib_umem_get(udata,
|
||||
(src == MLX4_IB_QP_SRC) ? ucmd.qp.buf_addr :
|
||||
ucmd.wq.buf_addr,
|
||||
qp->buf_size, 0, 0);
|
||||
ib_umem_get(udata, ucmd.buf_addr, qp->buf_size, 0, 0);
|
||||
if (IS_ERR(qp->umem)) {
|
||||
err = PTR_ERR(qp->umem);
|
||||
goto err;
|
||||
|
@ -1041,11 +1129,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
|
|||
goto err_mtt;
|
||||
|
||||
if (qp_has_rq(init_attr)) {
|
||||
err = mlx4_ib_db_map_user(udata,
|
||||
(src == MLX4_IB_QP_SRC) ?
|
||||
ucmd.qp.db_addr :
|
||||
ucmd.wq.db_addr,
|
||||
&qp->db);
|
||||
err = mlx4_ib_db_map_user(udata, ucmd.db_addr, &qp->db);
|
||||
if (err)
|
||||
goto err_mtt;
|
||||
}
|
||||
|
@ -1115,10 +1199,6 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
|
|||
goto err_wrid;
|
||||
}
|
||||
}
|
||||
} else if (src == MLX4_IB_RWQ_SRC) {
|
||||
err = mlx4_ib_alloc_wqn(context, qp, range_size, &qpn);
|
||||
if (err)
|
||||
goto err_wrid;
|
||||
} else {
|
||||
/* Raw packet QPNs may not have bits 6,7 set in their qp_num;
|
||||
* otherwise, the WQE BlueFlame setup flow wrongly causes
|
||||
|
@ -1157,8 +1237,7 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
|
|||
*/
|
||||
qp->doorbell_qpn = swab32(qp->mqp.qpn << 8);
|
||||
|
||||
qp->mqp.event = (src == MLX4_IB_QP_SRC) ? mlx4_ib_qp_event :
|
||||
mlx4_ib_wq_event;
|
||||
qp->mqp.event = mlx4_ib_qp_event;
|
||||
|
||||
if (!*caller_qp)
|
||||
*caller_qp = qp;
|
||||
|
@ -1186,8 +1265,6 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
|
|||
if (!sqpn) {
|
||||
if (qp->flags & MLX4_IB_QP_NETIF)
|
||||
mlx4_ib_steer_qp_free(dev, qpn, 1);
|
||||
else if (src == MLX4_IB_RWQ_SRC)
|
||||
mlx4_ib_release_wqn(context, qp, 0);
|
||||
else
|
||||
mlx4_qp_release_range(dev->dev, qpn, 1);
|
||||
}
|
||||
|
@ -1518,8 +1595,7 @@ static struct ib_qp *_mlx4_ib_create_qp(struct ib_pd *pd,
|
|||
/* fall through */
|
||||
case IB_QPT_UD:
|
||||
{
|
||||
err = create_qp_common(to_mdev(pd->device), pd, MLX4_IB_QP_SRC,
|
||||
init_attr, udata, 0, &qp);
|
||||
err = create_qp_common(pd, init_attr, udata, 0, &qp);
|
||||
if (err) {
|
||||
kfree(qp);
|
||||
return ERR_PTR(err);
|
||||
|
@ -1549,8 +1625,7 @@ static struct ib_qp *_mlx4_ib_create_qp(struct ib_pd *pd,
|
|||
sqpn = get_sqp_num(to_mdev(pd->device), init_attr);
|
||||
}
|
||||
|
||||
err = create_qp_common(to_mdev(pd->device), pd, MLX4_IB_QP_SRC,
|
||||
init_attr, udata, sqpn, &qp);
|
||||
err = create_qp_common(pd, init_attr, udata, sqpn, &qp);
|
||||
if (err)
|
||||
return ERR_PTR(err);
|
||||
|
||||
|
@ -4047,8 +4122,8 @@ struct ib_wq *mlx4_ib_create_wq(struct ib_pd *pd,
|
|||
struct ib_wq_init_attr *init_attr,
|
||||
struct ib_udata *udata)
|
||||
{
|
||||
struct mlx4_ib_dev *dev;
|
||||
struct ib_qp_init_attr ib_qp_init_attr;
|
||||
struct mlx4_dev *dev = to_mdev(pd->device)->dev;
|
||||
struct ib_qp_init_attr ib_qp_init_attr = {};
|
||||
struct mlx4_ib_qp *qp;
|
||||
struct mlx4_ib_create_wq ucmd;
|
||||
int err, required_cmd_sz;
|
||||
|
@ -4073,14 +4148,13 @@ struct ib_wq *mlx4_ib_create_wq(struct ib_pd *pd,
|
|||
if (udata->outlen)
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
||||
dev = to_mdev(pd->device);
|
||||
|
||||
if (init_attr->wq_type != IB_WQT_RQ) {
|
||||
pr_debug("unsupported wq type %d\n", init_attr->wq_type);
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
if (init_attr->create_flags & ~IB_WQ_FLAGS_SCATTER_FCS) {
|
||||
if (init_attr->create_flags & ~IB_WQ_FLAGS_SCATTER_FCS ||
|
||||
!(dev->caps.flags & MLX4_DEV_CAP_FLAG_FCS_KEEP)) {
|
||||
pr_debug("unsupported create_flags %u\n",
|
||||
init_attr->create_flags);
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
@ -4093,7 +4167,6 @@ struct ib_wq *mlx4_ib_create_wq(struct ib_pd *pd,
|
|||
qp->pri.vid = 0xFFFF;
|
||||
qp->alt.vid = 0xFFFF;
|
||||
|
||||
memset(&ib_qp_init_attr, 0, sizeof(ib_qp_init_attr));
|
||||
ib_qp_init_attr.qp_context = init_attr->wq_context;
|
||||
ib_qp_init_attr.qp_type = IB_QPT_RAW_PACKET;
|
||||
ib_qp_init_attr.cap.max_recv_wr = init_attr->max_wr;
|
||||
|
@ -4104,8 +4177,7 @@ struct ib_wq *mlx4_ib_create_wq(struct ib_pd *pd,
|
|||
if (init_attr->create_flags & IB_WQ_FLAGS_SCATTER_FCS)
|
||||
ib_qp_init_attr.create_flags |= IB_QP_CREATE_SCATTER_FCS;
|
||||
|
||||
err = create_qp_common(dev, pd, MLX4_IB_RWQ_SRC, &ib_qp_init_attr,
|
||||
udata, 0, &qp);
|
||||
err = create_rq(pd, &ib_qp_init_attr, udata, qp);
|
||||
if (err) {
|
||||
kfree(qp);
|
||||
return ERR_PTR(err);
|
||||
|
|
|
@ -233,6 +233,8 @@ static bool is_legacy_obj_event_num(u16 event_num)
|
|||
case MLX5_EVENT_TYPE_SRQ_CATAS_ERROR:
|
||||
case MLX5_EVENT_TYPE_DCT_DRAINED:
|
||||
case MLX5_EVENT_TYPE_COMP:
|
||||
case MLX5_EVENT_TYPE_DCT_KEY_VIOLATION:
|
||||
case MLX5_EVENT_TYPE_XRQ_ERROR:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
@ -315,8 +317,10 @@ static u16 get_event_obj_type(unsigned long event_type, struct mlx5_eqe *eqe)
|
|||
case MLX5_EVENT_TYPE_SRQ_CATAS_ERROR:
|
||||
return eqe->data.qp_srq.type;
|
||||
case MLX5_EVENT_TYPE_CQ_ERROR:
|
||||
case MLX5_EVENT_TYPE_XRQ_ERROR:
|
||||
return 0;
|
||||
case MLX5_EVENT_TYPE_DCT_DRAINED:
|
||||
case MLX5_EVENT_TYPE_DCT_KEY_VIOLATION:
|
||||
return MLX5_EVENT_QUEUE_TYPE_DCT;
|
||||
default:
|
||||
return MLX5_GET(affiliated_event_header, &eqe->data, obj_type);
|
||||
|
@ -542,6 +546,8 @@ static u64 devx_get_obj_id(const void *in)
|
|||
break;
|
||||
case MLX5_CMD_OP_ARM_XRQ:
|
||||
case MLX5_CMD_OP_SET_XRQ_DC_PARAMS_ENTRY:
|
||||
case MLX5_CMD_OP_RELEASE_XRQ_ERROR:
|
||||
case MLX5_CMD_OP_MODIFY_XRQ:
|
||||
obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_XRQ,
|
||||
MLX5_GET(arm_xrq_in, in, xrqn));
|
||||
break;
|
||||
|
@ -776,6 +782,14 @@ static bool devx_is_obj_create_cmd(const void *in, u16 *opcode)
|
|||
return true;
|
||||
return false;
|
||||
}
|
||||
case MLX5_CMD_OP_CREATE_PSV:
|
||||
{
|
||||
u8 num_psv = MLX5_GET(create_psv_in, in, num_psv);
|
||||
|
||||
if (num_psv == 1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -810,6 +824,8 @@ static bool devx_is_obj_modify_cmd(const void *in)
|
|||
case MLX5_CMD_OP_ARM_DCT_FOR_KEY_VIOLATION:
|
||||
case MLX5_CMD_OP_ARM_XRQ:
|
||||
case MLX5_CMD_OP_SET_XRQ_DC_PARAMS_ENTRY:
|
||||
case MLX5_CMD_OP_RELEASE_XRQ_ERROR:
|
||||
case MLX5_CMD_OP_MODIFY_XRQ:
|
||||
return true;
|
||||
case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY:
|
||||
{
|
||||
|
@ -1216,6 +1232,12 @@ static void devx_obj_build_destroy_cmd(void *in, void *out, void *din,
|
|||
case MLX5_CMD_OP_ALLOC_XRCD:
|
||||
MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DEALLOC_XRCD);
|
||||
break;
|
||||
case MLX5_CMD_OP_CREATE_PSV:
|
||||
MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
|
||||
MLX5_CMD_OP_DESTROY_PSV);
|
||||
MLX5_SET(destroy_psv_in, din, psvn,
|
||||
MLX5_GET(create_psv_out, out, psv0_index));
|
||||
break;
|
||||
default:
|
||||
/* The entry must match to one of the devx_is_obj_create_cmd */
|
||||
WARN_ON(true);
|
||||
|
@ -2286,7 +2308,11 @@ static u32 devx_get_obj_id_from_event(unsigned long event_type, void *data)
|
|||
case MLX5_EVENT_TYPE_WQ_ACCESS_ERROR:
|
||||
obj_id = be32_to_cpu(eqe->data.qp_srq.qp_srq_n) & 0xffffff;
|
||||
break;
|
||||
case MLX5_EVENT_TYPE_XRQ_ERROR:
|
||||
obj_id = be32_to_cpu(eqe->data.xrq_err.type_xrqn) & 0xffffff;
|
||||
break;
|
||||
case MLX5_EVENT_TYPE_DCT_DRAINED:
|
||||
case MLX5_EVENT_TYPE_DCT_KEY_VIOLATION:
|
||||
obj_id = be32_to_cpu(eqe->data.dct.dctn) & 0xffffff;
|
||||
break;
|
||||
case MLX5_EVENT_TYPE_CQ_ERROR:
|
||||
|
|
|
@ -32,6 +32,9 @@ mlx5_ib_ft_type_to_namespace(enum mlx5_ib_uapi_flow_table_type table_type,
|
|||
case MLX5_IB_UAPI_FLOW_TABLE_TYPE_FDB:
|
||||
*namespace = MLX5_FLOW_NAMESPACE_FDB;
|
||||
break;
|
||||
case MLX5_IB_UAPI_FLOW_TABLE_TYPE_RDMA_RX:
|
||||
*namespace = MLX5_FLOW_NAMESPACE_RDMA_RX;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -101,6 +104,11 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
|
|||
if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_FDB && !dest_devx)
|
||||
return -EINVAL;
|
||||
|
||||
/* Allow only DEVX object or QP as dest when inserting to RDMA_RX */
|
||||
if ((fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_RDMA_RX) &&
|
||||
((!dest_devx && !dest_qp) || (dest_devx && dest_qp)))
|
||||
return -EINVAL;
|
||||
|
||||
if (dest_devx) {
|
||||
devx_obj = uverbs_attr_get_obj(
|
||||
attrs, MLX5_IB_ATTR_CREATE_FLOW_DEST_DEVX);
|
||||
|
@ -112,8 +120,9 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
|
|||
*/
|
||||
if (!mlx5_ib_devx_is_flow_dest(devx_obj, &dest_id, &dest_type))
|
||||
return -EINVAL;
|
||||
/* Allow only flow table as dest when inserting to FDB */
|
||||
if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_FDB &&
|
||||
/* Allow only flow table as dest when inserting to FDB or RDMA_RX */
|
||||
if ((fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_FDB ||
|
||||
fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_RDMA_RX) &&
|
||||
dest_type != MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE)
|
||||
return -EINVAL;
|
||||
} else if (dest_qp) {
|
||||
|
|
|
@ -535,7 +535,7 @@ static int mlx5_query_port_roce(struct ib_device *device, u8 port_num,
|
|||
props->max_msg_sz = 1 << MLX5_CAP_GEN(dev->mdev, log_max_msg);
|
||||
props->pkey_tbl_len = 1;
|
||||
props->state = IB_PORT_DOWN;
|
||||
props->phys_state = 3;
|
||||
props->phys_state = IB_PORT_PHYS_STATE_DISABLED;
|
||||
|
||||
mlx5_query_nic_vport_qkey_viol_cntr(mdev, &qkey_viol_cntr);
|
||||
props->qkey_viol_cntr = qkey_viol_cntr;
|
||||
|
@ -561,7 +561,7 @@ static int mlx5_query_port_roce(struct ib_device *device, u8 port_num,
|
|||
|
||||
if (netif_running(ndev) && netif_carrier_ok(ndev)) {
|
||||
props->state = IB_PORT_ACTIVE;
|
||||
props->phys_state = 5;
|
||||
props->phys_state = IB_PORT_PHYS_STATE_LINK_UP;
|
||||
}
|
||||
|
||||
ndev_ib_mtu = iboe_get_mtu(ndev->mtu);
|
||||
|
@ -3971,6 +3971,11 @@ _get_flow_table(struct mlx5_ib_dev *dev,
|
|||
esw_encap)
|
||||
flags |= MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT;
|
||||
priority = FDB_BYPASS_PATH;
|
||||
} else if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_RDMA_RX) {
|
||||
max_table_size =
|
||||
BIT(MLX5_CAP_FLOWTABLE_RDMA_RX(dev->mdev,
|
||||
log_max_ft_size));
|
||||
priority = fs_matcher->priority;
|
||||
}
|
||||
|
||||
max_table_size = min_t(int, max_table_size, MLX5_FS_MAX_ENTRIES);
|
||||
|
@ -3985,6 +3990,8 @@ _get_flow_table(struct mlx5_ib_dev *dev,
|
|||
prio = &dev->flow_db->egress_prios[priority];
|
||||
else if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_FDB)
|
||||
prio = &dev->flow_db->fdb;
|
||||
else if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_RDMA_RX)
|
||||
prio = &dev->flow_db->rdma_rx[priority];
|
||||
|
||||
if (!prio)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
@ -5326,11 +5333,21 @@ static const struct mlx5_ib_counter ext_ppcnt_cnts[] = {
|
|||
INIT_EXT_PPCNT_COUNTER(rx_icrc_encapsulated),
|
||||
};
|
||||
|
||||
static bool is_mdev_switchdev_mode(const struct mlx5_core_dev *mdev)
|
||||
{
|
||||
return MLX5_ESWITCH_MANAGER(mdev) &&
|
||||
mlx5_ib_eswitch_mode(mdev->priv.eswitch) ==
|
||||
MLX5_ESWITCH_OFFLOADS;
|
||||
}
|
||||
|
||||
static void mlx5_ib_dealloc_counters(struct mlx5_ib_dev *dev)
|
||||
{
|
||||
int num_cnt_ports;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < dev->num_ports; i++) {
|
||||
num_cnt_ports = is_mdev_switchdev_mode(dev->mdev) ? 1 : dev->num_ports;
|
||||
|
||||
for (i = 0; i < num_cnt_ports; i++) {
|
||||
if (dev->port[i].cnts.set_id_valid)
|
||||
mlx5_core_dealloc_q_counter(dev->mdev,
|
||||
dev->port[i].cnts.set_id);
|
||||
|
@ -5432,13 +5449,15 @@ static void mlx5_ib_fill_counters(struct mlx5_ib_dev *dev,
|
|||
|
||||
static int mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev)
|
||||
{
|
||||
int num_cnt_ports;
|
||||
int err = 0;
|
||||
int i;
|
||||
bool is_shared;
|
||||
|
||||
is_shared = MLX5_CAP_GEN(dev->mdev, log_max_uctx) != 0;
|
||||
num_cnt_ports = is_mdev_switchdev_mode(dev->mdev) ? 1 : dev->num_ports;
|
||||
|
||||
for (i = 0; i < dev->num_ports; i++) {
|
||||
for (i = 0; i < num_cnt_ports; i++) {
|
||||
err = __mlx5_ib_alloc_counters(dev, &dev->port[i].cnts);
|
||||
if (err)
|
||||
goto err_alloc;
|
||||
|
@ -5458,7 +5477,6 @@ static int mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev)
|
|||
}
|
||||
dev->port[i].cnts.set_id_valid = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_alloc:
|
||||
|
@ -5466,25 +5484,50 @@ static int mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev)
|
|||
return err;
|
||||
}
|
||||
|
||||
static const struct mlx5_ib_counters *get_counters(struct mlx5_ib_dev *dev,
|
||||
u8 port_num)
|
||||
{
|
||||
return is_mdev_switchdev_mode(dev->mdev) ? &dev->port[0].cnts :
|
||||
&dev->port[port_num].cnts;
|
||||
}
|
||||
|
||||
/**
|
||||
* mlx5_ib_get_counters_id - Returns counters id to use for device+port
|
||||
* @dev: Pointer to mlx5 IB device
|
||||
* @port_num: Zero based port number
|
||||
*
|
||||
* mlx5_ib_get_counters_id() Returns counters set id to use for given
|
||||
* device port combination in switchdev and non switchdev mode of the
|
||||
* parent device.
|
||||
*/
|
||||
u16 mlx5_ib_get_counters_id(struct mlx5_ib_dev *dev, u8 port_num)
|
||||
{
|
||||
const struct mlx5_ib_counters *cnts = get_counters(dev, port_num);
|
||||
|
||||
return cnts->set_id;
|
||||
}
|
||||
|
||||
static struct rdma_hw_stats *mlx5_ib_alloc_hw_stats(struct ib_device *ibdev,
|
||||
u8 port_num)
|
||||
{
|
||||
struct mlx5_ib_dev *dev = to_mdev(ibdev);
|
||||
struct mlx5_ib_port *port = &dev->port[port_num - 1];
|
||||
const struct mlx5_ib_counters *cnts;
|
||||
bool is_switchdev = is_mdev_switchdev_mode(dev->mdev);
|
||||
|
||||
/* We support only per port stats */
|
||||
if (port_num == 0)
|
||||
if ((is_switchdev && port_num) || (!is_switchdev && !port_num))
|
||||
return NULL;
|
||||
|
||||
return rdma_alloc_hw_stats_struct(port->cnts.names,
|
||||
port->cnts.num_q_counters +
|
||||
port->cnts.num_cong_counters +
|
||||
port->cnts.num_ext_ppcnt_counters,
|
||||
cnts = get_counters(dev, port_num - 1);
|
||||
|
||||
return rdma_alloc_hw_stats_struct(cnts->names,
|
||||
cnts->num_q_counters +
|
||||
cnts->num_cong_counters +
|
||||
cnts->num_ext_ppcnt_counters,
|
||||
RDMA_HW_STATS_DEFAULT_LIFESPAN);
|
||||
}
|
||||
|
||||
static int mlx5_ib_query_q_counters(struct mlx5_core_dev *mdev,
|
||||
struct mlx5_ib_port *port,
|
||||
const struct mlx5_ib_counters *cnts,
|
||||
struct rdma_hw_stats *stats,
|
||||
u16 set_id)
|
||||
{
|
||||
|
@ -5501,8 +5544,8 @@ static int mlx5_ib_query_q_counters(struct mlx5_core_dev *mdev,
|
|||
if (ret)
|
||||
goto free;
|
||||
|
||||
for (i = 0; i < port->cnts.num_q_counters; i++) {
|
||||
val = *(__be32 *)(out + port->cnts.offsets[i]);
|
||||
for (i = 0; i < cnts->num_q_counters; i++) {
|
||||
val = *(__be32 *)(out + cnts->offsets[i]);
|
||||
stats->value[i] = (u64)be32_to_cpu(val);
|
||||
}
|
||||
|
||||
|
@ -5512,10 +5555,10 @@ static int mlx5_ib_query_q_counters(struct mlx5_core_dev *mdev,
|
|||
}
|
||||
|
||||
static int mlx5_ib_query_ext_ppcnt_counters(struct mlx5_ib_dev *dev,
|
||||
struct mlx5_ib_port *port,
|
||||
struct rdma_hw_stats *stats)
|
||||
const struct mlx5_ib_counters *cnts,
|
||||
struct rdma_hw_stats *stats)
|
||||
{
|
||||
int offset = port->cnts.num_q_counters + port->cnts.num_cong_counters;
|
||||
int offset = cnts->num_q_counters + cnts->num_cong_counters;
|
||||
int sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
|
||||
int ret, i;
|
||||
void *out;
|
||||
|
@ -5528,12 +5571,10 @@ static int mlx5_ib_query_ext_ppcnt_counters(struct mlx5_ib_dev *dev,
|
|||
if (ret)
|
||||
goto free;
|
||||
|
||||
for (i = 0; i < port->cnts.num_ext_ppcnt_counters; i++) {
|
||||
for (i = 0; i < cnts->num_ext_ppcnt_counters; i++)
|
||||
stats->value[i + offset] =
|
||||
be64_to_cpup((__be64 *)(out +
|
||||
port->cnts.offsets[i + offset]));
|
||||
}
|
||||
|
||||
cnts->offsets[i + offset]));
|
||||
free:
|
||||
kvfree(out);
|
||||
return ret;
|
||||
|
@ -5544,7 +5585,7 @@ static int mlx5_ib_get_hw_stats(struct ib_device *ibdev,
|
|||
u8 port_num, int index)
|
||||
{
|
||||
struct mlx5_ib_dev *dev = to_mdev(ibdev);
|
||||
struct mlx5_ib_port *port = &dev->port[port_num - 1];
|
||||
const struct mlx5_ib_counters *cnts = get_counters(dev, port_num - 1);
|
||||
struct mlx5_core_dev *mdev;
|
||||
int ret, num_counters;
|
||||
u8 mdev_port_num;
|
||||
|
@ -5552,18 +5593,17 @@ static int mlx5_ib_get_hw_stats(struct ib_device *ibdev,
|
|||
if (!stats)
|
||||
return -EINVAL;
|
||||
|
||||
num_counters = port->cnts.num_q_counters +
|
||||
port->cnts.num_cong_counters +
|
||||
port->cnts.num_ext_ppcnt_counters;
|
||||
num_counters = cnts->num_q_counters +
|
||||
cnts->num_cong_counters +
|
||||
cnts->num_ext_ppcnt_counters;
|
||||
|
||||
/* q_counters are per IB device, query the master mdev */
|
||||
ret = mlx5_ib_query_q_counters(dev->mdev, port, stats,
|
||||
port->cnts.set_id);
|
||||
ret = mlx5_ib_query_q_counters(dev->mdev, cnts, stats, cnts->set_id);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (MLX5_CAP_PCAM_FEATURE(dev->mdev, rx_icrc_encapsulated_counter)) {
|
||||
ret = mlx5_ib_query_ext_ppcnt_counters(dev, port, stats);
|
||||
ret = mlx5_ib_query_ext_ppcnt_counters(dev, cnts, stats);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
@ -5580,10 +5620,10 @@ static int mlx5_ib_get_hw_stats(struct ib_device *ibdev,
|
|||
}
|
||||
ret = mlx5_lag_query_cong_counters(dev->mdev,
|
||||
stats->value +
|
||||
port->cnts.num_q_counters,
|
||||
port->cnts.num_cong_counters,
|
||||
port->cnts.offsets +
|
||||
port->cnts.num_q_counters);
|
||||
cnts->num_q_counters,
|
||||
cnts->num_cong_counters,
|
||||
cnts->offsets +
|
||||
cnts->num_q_counters);
|
||||
|
||||
mlx5_ib_put_native_port_mdev(dev, port_num);
|
||||
if (ret)
|
||||
|
@ -5598,20 +5638,22 @@ static struct rdma_hw_stats *
|
|||
mlx5_ib_counter_alloc_stats(struct rdma_counter *counter)
|
||||
{
|
||||
struct mlx5_ib_dev *dev = to_mdev(counter->device);
|
||||
struct mlx5_ib_port *port = &dev->port[counter->port - 1];
|
||||
const struct mlx5_ib_counters *cnts =
|
||||
get_counters(dev, counter->port - 1);
|
||||
|
||||
/* Q counters are in the beginning of all counters */
|
||||
return rdma_alloc_hw_stats_struct(port->cnts.names,
|
||||
port->cnts.num_q_counters,
|
||||
return rdma_alloc_hw_stats_struct(cnts->names,
|
||||
cnts->num_q_counters,
|
||||
RDMA_HW_STATS_DEFAULT_LIFESPAN);
|
||||
}
|
||||
|
||||
static int mlx5_ib_counter_update_stats(struct rdma_counter *counter)
|
||||
{
|
||||
struct mlx5_ib_dev *dev = to_mdev(counter->device);
|
||||
struct mlx5_ib_port *port = &dev->port[counter->port - 1];
|
||||
const struct mlx5_ib_counters *cnts =
|
||||
get_counters(dev, counter->port - 1);
|
||||
|
||||
return mlx5_ib_query_q_counters(dev->mdev, port,
|
||||
return mlx5_ib_query_q_counters(dev->mdev, cnts,
|
||||
counter->stats, counter->id);
|
||||
}
|
||||
|
||||
|
@ -5788,7 +5830,6 @@ static void init_delay_drop(struct mlx5_ib_dev *dev)
|
|||
mlx5_ib_warn(dev, "Failed to init delay drop debugfs\n");
|
||||
}
|
||||
|
||||
/* The mlx5_ib_multiport_mutex should be held when calling this function */
|
||||
static void mlx5_ib_unbind_slave_port(struct mlx5_ib_dev *ibdev,
|
||||
struct mlx5_ib_multiport_info *mpi)
|
||||
{
|
||||
|
@ -5798,6 +5839,8 @@ static void mlx5_ib_unbind_slave_port(struct mlx5_ib_dev *ibdev,
|
|||
int err;
|
||||
int i;
|
||||
|
||||
lockdep_assert_held(&mlx5_ib_multiport_mutex);
|
||||
|
||||
mlx5_ib_cleanup_cong_debugfs(ibdev, port_num);
|
||||
|
||||
spin_lock(&port->mp.mpi_lock);
|
||||
|
@ -5847,13 +5890,14 @@ static void mlx5_ib_unbind_slave_port(struct mlx5_ib_dev *ibdev,
|
|||
ibdev->port[port_num].roce.last_port_state = IB_PORT_DOWN;
|
||||
}
|
||||
|
||||
/* The mlx5_ib_multiport_mutex should be held when calling this function */
|
||||
static bool mlx5_ib_bind_slave_port(struct mlx5_ib_dev *ibdev,
|
||||
struct mlx5_ib_multiport_info *mpi)
|
||||
{
|
||||
u8 port_num = mlx5_core_native_port_num(mpi->mdev) - 1;
|
||||
int err;
|
||||
|
||||
lockdep_assert_held(&mlx5_ib_multiport_mutex);
|
||||
|
||||
spin_lock(&ibdev->port[port_num].mp.mpi_lock);
|
||||
if (ibdev->port[port_num].mp.mpi) {
|
||||
mlx5_ib_dbg(ibdev, "port %d already affiliated.\n",
|
||||
|
@ -6882,7 +6926,7 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
|
|||
dev->port = kcalloc(num_ports, sizeof(*dev->port),
|
||||
GFP_KERNEL);
|
||||
if (!dev->port) {
|
||||
ib_dealloc_device((struct ib_device *)dev);
|
||||
ib_dealloc_device(&dev->ib_dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -6909,6 +6953,7 @@ static void mlx5_ib_remove(struct mlx5_core_dev *mdev, void *context)
|
|||
mlx5_ib_unbind_slave_port(mpi->ibdev, mpi);
|
||||
list_del(&mpi->list);
|
||||
mutex_unlock(&mlx5_ib_multiport_mutex);
|
||||
kfree(mpi);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -200,6 +200,7 @@ struct mlx5_ib_flow_db {
|
|||
struct mlx5_ib_flow_prio sniffer[MLX5_IB_NUM_SNIFFER_FTS];
|
||||
struct mlx5_ib_flow_prio egress[MLX5_IB_NUM_EGRESS_FTS];
|
||||
struct mlx5_ib_flow_prio fdb;
|
||||
struct mlx5_ib_flow_prio rdma_rx[MLX5_IB_NUM_FLOW_FT];
|
||||
struct mlx5_flow_table *lag_demux_ft;
|
||||
/* Protect flow steering bypass flow tables
|
||||
* when add/del flow rules.
|
||||
|
@ -1476,6 +1477,7 @@ int bfregn_to_uar_index(struct mlx5_ib_dev *dev,
|
|||
bool dyn_bfreg);
|
||||
|
||||
int mlx5_ib_qp_set_counter(struct ib_qp *qp, struct rdma_counter *counter);
|
||||
u16 mlx5_ib_get_counters_id(struct mlx5_ib_dev *dev, u8 port_num);
|
||||
|
||||
static inline bool mlx5_ib_can_use_umr(struct mlx5_ib_dev *dev,
|
||||
bool do_modify_atomic)
|
||||
|
|
|
@ -982,17 +982,6 @@ static int pagefault_data_segments(struct mlx5_ib_dev *dev,
|
|||
return ret < 0 ? ret : npages;
|
||||
}
|
||||
|
||||
static const u32 mlx5_ib_odp_opcode_cap[] = {
|
||||
[MLX5_OPCODE_SEND] = IB_ODP_SUPPORT_SEND,
|
||||
[MLX5_OPCODE_SEND_IMM] = IB_ODP_SUPPORT_SEND,
|
||||
[MLX5_OPCODE_SEND_INVAL] = IB_ODP_SUPPORT_SEND,
|
||||
[MLX5_OPCODE_RDMA_WRITE] = IB_ODP_SUPPORT_WRITE,
|
||||
[MLX5_OPCODE_RDMA_WRITE_IMM] = IB_ODP_SUPPORT_WRITE,
|
||||
[MLX5_OPCODE_RDMA_READ] = IB_ODP_SUPPORT_READ,
|
||||
[MLX5_OPCODE_ATOMIC_CS] = IB_ODP_SUPPORT_ATOMIC,
|
||||
[MLX5_OPCODE_ATOMIC_FA] = IB_ODP_SUPPORT_ATOMIC,
|
||||
};
|
||||
|
||||
/*
|
||||
* Parse initiator WQE. Advances the wqe pointer to point at the
|
||||
* scatter-gather list, and set wqe_end to the end of the WQE.
|
||||
|
@ -1003,12 +992,8 @@ static int mlx5_ib_mr_initiator_pfault_handler(
|
|||
{
|
||||
struct mlx5_wqe_ctrl_seg *ctrl = *wqe;
|
||||
u16 wqe_index = pfault->wqe.wqe_index;
|
||||
u32 transport_caps;
|
||||
struct mlx5_base_av *av;
|
||||
unsigned ds, opcode;
|
||||
#if defined(DEBUG)
|
||||
u32 ctrl_wqe_index, ctrl_qpn;
|
||||
#endif
|
||||
u32 qpn = qp->trans_qp.base.mqp.qpn;
|
||||
|
||||
ds = be32_to_cpu(ctrl->qpn_ds) & MLX5_WQE_CTRL_DS_MASK;
|
||||
|
@ -1024,58 +1009,17 @@ static int mlx5_ib_mr_initiator_pfault_handler(
|
|||
return -EFAULT;
|
||||
}
|
||||
|
||||
#if defined(DEBUG)
|
||||
ctrl_wqe_index = (be32_to_cpu(ctrl->opmod_idx_opcode) &
|
||||
MLX5_WQE_CTRL_WQE_INDEX_MASK) >>
|
||||
MLX5_WQE_CTRL_WQE_INDEX_SHIFT;
|
||||
if (wqe_index != ctrl_wqe_index) {
|
||||
mlx5_ib_err(dev, "Got WQE with invalid wqe_index. wqe_index=0x%x, qpn=0x%x ctrl->wqe_index=0x%x\n",
|
||||
wqe_index, qpn,
|
||||
ctrl_wqe_index);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
ctrl_qpn = (be32_to_cpu(ctrl->qpn_ds) & MLX5_WQE_CTRL_QPN_MASK) >>
|
||||
MLX5_WQE_CTRL_QPN_SHIFT;
|
||||
if (qpn != ctrl_qpn) {
|
||||
mlx5_ib_err(dev, "Got WQE with incorrect QP number. wqe_index=0x%x, qpn=0x%x ctrl->qpn=0x%x\n",
|
||||
wqe_index, qpn,
|
||||
ctrl_qpn);
|
||||
return -EFAULT;
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
*wqe_end = *wqe + ds * MLX5_WQE_DS_UNITS;
|
||||
*wqe += sizeof(*ctrl);
|
||||
|
||||
opcode = be32_to_cpu(ctrl->opmod_idx_opcode) &
|
||||
MLX5_WQE_CTRL_OPCODE_MASK;
|
||||
|
||||
switch (qp->ibqp.qp_type) {
|
||||
case IB_QPT_XRC_INI:
|
||||
if (qp->ibqp.qp_type == IB_QPT_XRC_INI)
|
||||
*wqe += sizeof(struct mlx5_wqe_xrc_seg);
|
||||
transport_caps = dev->odp_caps.per_transport_caps.xrc_odp_caps;
|
||||
break;
|
||||
case IB_QPT_RC:
|
||||
transport_caps = dev->odp_caps.per_transport_caps.rc_odp_caps;
|
||||
break;
|
||||
case IB_QPT_UD:
|
||||
transport_caps = dev->odp_caps.per_transport_caps.ud_odp_caps;
|
||||
break;
|
||||
default:
|
||||
mlx5_ib_err(dev, "ODP fault on QP of an unsupported transport 0x%x\n",
|
||||
qp->ibqp.qp_type);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (unlikely(opcode >= ARRAY_SIZE(mlx5_ib_odp_opcode_cap) ||
|
||||
!(transport_caps & mlx5_ib_odp_opcode_cap[opcode]))) {
|
||||
mlx5_ib_err(dev, "ODP fault on QP of an unsupported opcode 0x%x\n",
|
||||
opcode);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (qp->ibqp.qp_type == IB_QPT_UD) {
|
||||
if (qp->ibqp.qp_type == IB_QPT_UD ||
|
||||
qp->qp_sub_type == MLX5_IB_QPT_DCI) {
|
||||
av = *wqe;
|
||||
if (av->dqp_dct & cpu_to_be32(MLX5_EXTENDED_UD_AV))
|
||||
*wqe += sizeof(struct mlx5_av);
|
||||
|
@ -1138,19 +1082,6 @@ static int mlx5_ib_mr_responder_pfault_handler_rq(struct mlx5_ib_dev *dev,
|
|||
return -EFAULT;
|
||||
}
|
||||
|
||||
switch (qp->ibqp.qp_type) {
|
||||
case IB_QPT_RC:
|
||||
if (!(dev->odp_caps.per_transport_caps.rc_odp_caps &
|
||||
IB_ODP_SUPPORT_RECV))
|
||||
goto invalid_transport_or_opcode;
|
||||
break;
|
||||
default:
|
||||
invalid_transport_or_opcode:
|
||||
mlx5_ib_err(dev, "ODP fault on QP of an unsupported transport. transport: 0x%x\n",
|
||||
qp->ibqp.qp_type);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
*wqe_end = wqe + wqe_size;
|
||||
|
||||
return 0;
|
||||
|
@ -1200,7 +1131,7 @@ static void mlx5_ib_mr_wqe_pfault_handler(struct mlx5_ib_dev *dev,
|
|||
{
|
||||
bool sq = pfault->type & MLX5_PFAULT_REQUESTOR;
|
||||
u16 wqe_index = pfault->wqe.wqe_index;
|
||||
void *wqe = NULL, *wqe_end = NULL;
|
||||
void *wqe, *wqe_start = NULL, *wqe_end = NULL;
|
||||
u32 bytes_mapped, total_wqe_bytes;
|
||||
struct mlx5_core_rsc_common *res;
|
||||
int resume_with_error = 1;
|
||||
|
@ -1221,12 +1152,13 @@ static void mlx5_ib_mr_wqe_pfault_handler(struct mlx5_ib_dev *dev,
|
|||
goto resolve_page_fault;
|
||||
}
|
||||
|
||||
wqe = (void *)__get_free_page(GFP_KERNEL);
|
||||
if (!wqe) {
|
||||
wqe_start = (void *)__get_free_page(GFP_KERNEL);
|
||||
if (!wqe_start) {
|
||||
mlx5_ib_err(dev, "Error allocating memory for IO page fault handling.\n");
|
||||
goto resolve_page_fault;
|
||||
}
|
||||
|
||||
wqe = wqe_start;
|
||||
qp = (res->res == MLX5_RES_QP) ? res_to_qp(res) : NULL;
|
||||
if (qp && sq) {
|
||||
ret = mlx5_ib_read_user_wqe_sq(qp, wqe_index, wqe, PAGE_SIZE,
|
||||
|
@ -1281,7 +1213,7 @@ static void mlx5_ib_mr_wqe_pfault_handler(struct mlx5_ib_dev *dev,
|
|||
pfault->wqe.wq_num, resume_with_error,
|
||||
pfault->type);
|
||||
mlx5_core_res_put(res);
|
||||
free_page((unsigned long)wqe);
|
||||
free_page((unsigned long)wqe_start);
|
||||
}
|
||||
|
||||
static int pages_in_range(u64 address, u32 length)
|
||||
|
|
|
@ -3386,19 +3386,16 @@ static int __mlx5_ib_qp_set_counter(struct ib_qp *qp,
|
|||
struct mlx5_ib_dev *dev = to_mdev(qp->device);
|
||||
struct mlx5_ib_qp *mqp = to_mqp(qp);
|
||||
struct mlx5_qp_context context = {};
|
||||
struct mlx5_ib_port *mibport = NULL;
|
||||
struct mlx5_ib_qp_base *base;
|
||||
u32 set_id;
|
||||
|
||||
if (!MLX5_CAP_GEN(dev->mdev, rts2rts_qp_counters_set_id))
|
||||
return 0;
|
||||
|
||||
if (counter) {
|
||||
if (counter)
|
||||
set_id = counter->id;
|
||||
} else {
|
||||
mibport = &dev->port[mqp->port - 1];
|
||||
set_id = mibport->cnts.set_id;
|
||||
}
|
||||
else
|
||||
set_id = mlx5_ib_get_counters_id(dev, mqp->port - 1);
|
||||
|
||||
base = &mqp->trans_qp.base;
|
||||
context.qp_counter_set_usr_page &= cpu_to_be32(0xffffff);
|
||||
|
@ -3459,7 +3456,6 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
|
|||
struct mlx5_ib_cq *send_cq, *recv_cq;
|
||||
struct mlx5_qp_context *context;
|
||||
struct mlx5_ib_pd *pd;
|
||||
struct mlx5_ib_port *mibport = NULL;
|
||||
enum mlx5_qp_state mlx5_cur, mlx5_new;
|
||||
enum mlx5_qp_optpar optpar;
|
||||
u32 set_id = 0;
|
||||
|
@ -3624,11 +3620,10 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
|
|||
if (qp->flags & MLX5_IB_QP_UNDERLAY)
|
||||
port_num = 0;
|
||||
|
||||
mibport = &dev->port[port_num];
|
||||
if (ibqp->counter)
|
||||
set_id = ibqp->counter->id;
|
||||
else
|
||||
set_id = mibport->cnts.set_id;
|
||||
set_id = mlx5_ib_get_counters_id(dev, port_num);
|
||||
context->qp_counter_set_usr_page |=
|
||||
cpu_to_be32(set_id << 24);
|
||||
}
|
||||
|
@ -3817,6 +3812,8 @@ static int mlx5_ib_modify_dct(struct ib_qp *ibqp, struct ib_qp_attr *attr,
|
|||
|
||||
dctc = MLX5_ADDR_OF(create_dct_in, qp->dct.in, dct_context_entry);
|
||||
if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {
|
||||
u16 set_id;
|
||||
|
||||
required |= IB_QP_ACCESS_FLAGS | IB_QP_PKEY_INDEX | IB_QP_PORT;
|
||||
if (!is_valid_mask(attr_mask, required, 0))
|
||||
return -EINVAL;
|
||||
|
@ -3843,7 +3840,9 @@ static int mlx5_ib_modify_dct(struct ib_qp *ibqp, struct ib_qp_attr *attr,
|
|||
}
|
||||
MLX5_SET(dctc, dctc, pkey_index, attr->pkey_index);
|
||||
MLX5_SET(dctc, dctc, port, attr->port_num);
|
||||
MLX5_SET(dctc, dctc, counter_set_id, dev->port[attr->port_num - 1].cnts.set_id);
|
||||
|
||||
set_id = mlx5_ib_get_counters_id(dev, attr->port_num - 1);
|
||||
MLX5_SET(dctc, dctc, counter_set_id, set_id);
|
||||
|
||||
} else if (cur_state == IB_QPS_INIT && new_state == IB_QPS_RTR) {
|
||||
struct mlx5_ib_modify_qp_resp resp = {};
|
||||
|
@ -6345,11 +6344,13 @@ int mlx5_ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *wq_attr,
|
|||
}
|
||||
|
||||
if (curr_wq_state == IB_WQS_RESET && wq_state == IB_WQS_RDY) {
|
||||
u16 set_id;
|
||||
|
||||
set_id = mlx5_ib_get_counters_id(dev, 0);
|
||||
if (MLX5_CAP_GEN(dev->mdev, modify_rq_counter_set_id)) {
|
||||
MLX5_SET64(modify_rq_in, in, modify_bitmask,
|
||||
MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_RQ_COUNTER_SET_ID);
|
||||
MLX5_SET(rqc, rqc, counter_set_id,
|
||||
dev->port->cnts.set_id);
|
||||
MLX5_SET(rqc, rqc, counter_set_id, set_id);
|
||||
} else
|
||||
dev_info_once(
|
||||
&dev->ib_dev.dev,
|
||||
|
|
|
@ -163,10 +163,10 @@ int ocrdma_query_port(struct ib_device *ibdev,
|
|||
netdev = dev->nic_info.netdev;
|
||||
if (netif_running(netdev) && netif_oper_up(netdev)) {
|
||||
port_state = IB_PORT_ACTIVE;
|
||||
props->phys_state = 5;
|
||||
props->phys_state = IB_PORT_PHYS_STATE_LINK_UP;
|
||||
} else {
|
||||
port_state = IB_PORT_DOWN;
|
||||
props->phys_state = 3;
|
||||
props->phys_state = IB_PORT_PHYS_STATE_DISABLED;
|
||||
}
|
||||
props->max_mtu = IB_MTU_4096;
|
||||
props->active_mtu = iboe_get_mtu(netdev->mtu);
|
||||
|
|
|
@ -826,7 +826,7 @@ static int qedr_init_hw(struct qedr_dev *dev)
|
|||
if (rc)
|
||||
goto out;
|
||||
|
||||
dev->db_addr = (void __iomem *)(uintptr_t)out_params.dpi_addr;
|
||||
dev->db_addr = out_params.dpi_addr;
|
||||
dev->db_phys_addr = out_params.dpi_phys_addr;
|
||||
dev->db_size = out_params.dpi_size;
|
||||
dev->dpi = out_params.dpi;
|
||||
|
|
|
@ -229,7 +229,7 @@ struct qedr_ucontext {
|
|||
struct ib_ucontext ibucontext;
|
||||
struct qedr_dev *dev;
|
||||
struct qedr_pd *pd;
|
||||
u64 dpi_addr;
|
||||
void __iomem *dpi_addr;
|
||||
u64 dpi_phys_addr;
|
||||
u32 dpi_size;
|
||||
u16 dpi;
|
||||
|
|
|
@ -221,10 +221,10 @@ int qedr_query_port(struct ib_device *ibdev, u8 port, struct ib_port_attr *attr)
|
|||
/* *attr being zeroed by the caller, avoid zeroing it here */
|
||||
if (rdma_port->port_state == QED_RDMA_PORT_UP) {
|
||||
attr->state = IB_PORT_ACTIVE;
|
||||
attr->phys_state = 5;
|
||||
attr->phys_state = IB_PORT_PHYS_STATE_LINK_UP;
|
||||
} else {
|
||||
attr->state = IB_PORT_DOWN;
|
||||
attr->phys_state = 3;
|
||||
attr->phys_state = IB_PORT_PHYS_STATE_DISABLED;
|
||||
}
|
||||
attr->max_mtu = IB_MTU_4096;
|
||||
attr->active_mtu = iboe_get_mtu(dev->ndev->mtu);
|
||||
|
@ -2451,7 +2451,6 @@ int qedr_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
|
|||
struct qedr_dev *dev = qp->dev;
|
||||
struct ib_qp_attr attr;
|
||||
int attr_mask = 0;
|
||||
int rc = 0;
|
||||
|
||||
DP_DEBUG(dev, QEDR_MSG_QP, "destroy qp: destroying %p, qp type=%d\n",
|
||||
qp, qp->qp_type);
|
||||
|
@ -2496,7 +2495,7 @@ int qedr_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
|
|||
xa_erase_irq(&dev->qps, qp->qp_id);
|
||||
kfree(qp);
|
||||
}
|
||||
return rc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qedr_create_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr, u32 flags,
|
||||
|
|
|
@ -1789,7 +1789,6 @@ static void unlock_expected_tids(struct qib_ctxtdata *rcd)
|
|||
|
||||
static int qib_close(struct inode *in, struct file *fp)
|
||||
{
|
||||
int ret = 0;
|
||||
struct qib_filedata *fd;
|
||||
struct qib_ctxtdata *rcd;
|
||||
struct qib_devdata *dd;
|
||||
|
@ -1873,7 +1872,7 @@ static int qib_close(struct inode *in, struct file *fp)
|
|||
|
||||
bail:
|
||||
kfree(fd);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qib_ctxt_info(struct file *fp, struct qib_ctxt_info __user *uinfo)
|
||||
|
|
|
@ -313,11 +313,8 @@ int qib_make_rc_req(struct rvt_qp *qp, unsigned long *flags)
|
|||
case IB_WR_SEND:
|
||||
case IB_WR_SEND_WITH_IMM:
|
||||
/* If no credit, return. */
|
||||
if (!(qp->s_flags & RVT_S_UNLIMITED_CREDIT) &&
|
||||
rvt_cmp_msn(wqe->ssn, qp->s_lsn + 1) > 0) {
|
||||
qp->s_flags |= RVT_S_WAIT_SSN_CREDIT;
|
||||
if (!rvt_rc_credit_avail(qp, wqe))
|
||||
goto bail;
|
||||
}
|
||||
if (len > pmtu) {
|
||||
qp->s_state = OP(SEND_FIRST);
|
||||
len = pmtu;
|
||||
|
@ -344,11 +341,8 @@ int qib_make_rc_req(struct rvt_qp *qp, unsigned long *flags)
|
|||
goto no_flow_control;
|
||||
case IB_WR_RDMA_WRITE_WITH_IMM:
|
||||
/* If no credit, return. */
|
||||
if (!(qp->s_flags & RVT_S_UNLIMITED_CREDIT) &&
|
||||
rvt_cmp_msn(wqe->ssn, qp->s_lsn + 1) > 0) {
|
||||
qp->s_flags |= RVT_S_WAIT_SSN_CREDIT;
|
||||
if (!rvt_rc_credit_avail(qp, wqe))
|
||||
goto bail;
|
||||
}
|
||||
no_flow_control:
|
||||
ohdr->u.rc.reth.vaddr =
|
||||
cpu_to_be64(wqe->rdma_wr.remote_addr);
|
||||
|
|
|
@ -436,6 +436,7 @@ QIB_DIAGC_ATTR(dmawait);
|
|||
QIB_DIAGC_ATTR(unaligned);
|
||||
QIB_DIAGC_ATTR(rc_dupreq);
|
||||
QIB_DIAGC_ATTR(rc_seqnak);
|
||||
QIB_DIAGC_ATTR(rc_crwaits);
|
||||
|
||||
static struct attribute *diagc_default_attributes[] = {
|
||||
&qib_diagc_attr_rc_resends.attr,
|
||||
|
@ -453,6 +454,7 @@ static struct attribute *diagc_default_attributes[] = {
|
|||
&qib_diagc_attr_unaligned.attr,
|
||||
&qib_diagc_attr_rc_dupreq.attr,
|
||||
&qib_diagc_attr_rc_seqnak.attr,
|
||||
&qib_diagc_attr_rc_crwaits.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
|
@ -89,9 +89,15 @@ static void usnic_ib_dump_vf(struct usnic_ib_vf *vf, char *buf, int buf_sz)
|
|||
|
||||
void usnic_ib_log_vf(struct usnic_ib_vf *vf)
|
||||
{
|
||||
char buf[1000];
|
||||
usnic_ib_dump_vf(vf, buf, sizeof(buf));
|
||||
char *buf = kzalloc(1000, GFP_KERNEL);
|
||||
|
||||
if (!buf)
|
||||
return;
|
||||
|
||||
usnic_ib_dump_vf(vf, buf, 1000);
|
||||
usnic_dbg("%s\n", buf);
|
||||
|
||||
kfree(buf);
|
||||
}
|
||||
|
||||
/* Start of netdev section */
|
||||
|
|
|
@ -194,7 +194,7 @@ find_free_vf_and_create_qp_grp(struct usnic_ib_dev *us_ibdev,
|
|||
return ERR_CAST(dev_list);
|
||||
for (i = 0; dev_list[i]; i++) {
|
||||
dev = dev_list[i];
|
||||
vf = pci_get_drvdata(to_pci_dev(dev));
|
||||
vf = dev_get_drvdata(dev);
|
||||
spin_lock(&vf->lock);
|
||||
vnic = vf->vnic;
|
||||
if (!usnic_vnic_check_room(vnic, res_spec)) {
|
||||
|
@ -356,13 +356,14 @@ int usnic_ib_query_port(struct ib_device *ibdev, u8 port,
|
|||
|
||||
if (!us_ibdev->ufdev->link_up) {
|
||||
props->state = IB_PORT_DOWN;
|
||||
props->phys_state = 3;
|
||||
props->phys_state = IB_PORT_PHYS_STATE_DISABLED;
|
||||
} else if (!us_ibdev->ufdev->inaddr) {
|
||||
props->state = IB_PORT_INIT;
|
||||
props->phys_state = 4;
|
||||
props->phys_state =
|
||||
IB_PORT_PHYS_STATE_PORT_CONFIGURATION_TRAINING;
|
||||
} else {
|
||||
props->state = IB_PORT_ACTIVE;
|
||||
props->phys_state = 5;
|
||||
props->phys_state = IB_PORT_PHYS_STATE_LINK_UP;
|
||||
}
|
||||
|
||||
props->port_cap_flags = 0;
|
||||
|
|
|
@ -65,10 +65,6 @@
|
|||
*/
|
||||
#define RXE_UVERBS_ABI_VERSION 2
|
||||
|
||||
#define RDMA_LINK_PHYS_STATE_LINK_UP (5)
|
||||
#define RDMA_LINK_PHYS_STATE_DISABLED (3)
|
||||
#define RDMA_LINK_PHYS_STATE_POLLING (2)
|
||||
|
||||
#define RXE_ROCE_V2_SPORT (0xc000)
|
||||
|
||||
static inline u32 rxe_crc32(struct rxe_dev *rxe,
|
||||
|
|
|
@ -154,7 +154,7 @@ enum rxe_port_param {
|
|||
RXE_PORT_ACTIVE_WIDTH = IB_WIDTH_1X,
|
||||
RXE_PORT_ACTIVE_SPEED = 1,
|
||||
RXE_PORT_PKEY_TBL_LEN = 64,
|
||||
RXE_PORT_PHYS_STATE = 2,
|
||||
RXE_PORT_PHYS_STATE = IB_PORT_PHYS_STATE_POLLING,
|
||||
RXE_PORT_SUBNET_PREFIX = 0xfe80000000000000ULL,
|
||||
};
|
||||
|
||||
|
|
|
@ -69,11 +69,11 @@ static int rxe_query_port(struct ib_device *dev,
|
|||
&attr->active_width);
|
||||
|
||||
if (attr->state == IB_PORT_ACTIVE)
|
||||
attr->phys_state = RDMA_LINK_PHYS_STATE_LINK_UP;
|
||||
attr->phys_state = IB_PORT_PHYS_STATE_LINK_UP;
|
||||
else if (dev_get_flags(rxe->ndev) & IFF_UP)
|
||||
attr->phys_state = RDMA_LINK_PHYS_STATE_POLLING;
|
||||
attr->phys_state = IB_PORT_PHYS_STATE_POLLING;
|
||||
else
|
||||
attr->phys_state = RDMA_LINK_PHYS_STATE_DISABLED;
|
||||
attr->phys_state = IB_PORT_PHYS_STATE_DISABLED;
|
||||
|
||||
mutex_unlock(&rxe->usdev_lock);
|
||||
|
||||
|
|
|
@ -76,16 +76,15 @@ static int siw_try_1seg(struct siw_iwarp_tx *c_tx, void *paddr)
|
|||
if (unlikely(!p))
|
||||
return -EFAULT;
|
||||
|
||||
buffer = kmap_atomic(p);
|
||||
buffer = kmap(p);
|
||||
|
||||
if (likely(PAGE_SIZE - off >= bytes)) {
|
||||
memcpy(paddr, buffer + off, bytes);
|
||||
kunmap_atomic(buffer);
|
||||
} else {
|
||||
unsigned long part = bytes - (PAGE_SIZE - off);
|
||||
|
||||
memcpy(paddr, buffer + off, part);
|
||||
kunmap_atomic(buffer);
|
||||
kunmap(p);
|
||||
|
||||
if (!mem->is_pbl)
|
||||
p = siw_get_upage(mem->umem,
|
||||
|
@ -97,11 +96,10 @@ static int siw_try_1seg(struct siw_iwarp_tx *c_tx, void *paddr)
|
|||
if (unlikely(!p))
|
||||
return -EFAULT;
|
||||
|
||||
buffer = kmap_atomic(p);
|
||||
memcpy(paddr + part, buffer,
|
||||
bytes - part);
|
||||
kunmap_atomic(buffer);
|
||||
buffer = kmap(p);
|
||||
memcpy(paddr + part, buffer, bytes - part);
|
||||
}
|
||||
kunmap(p);
|
||||
}
|
||||
}
|
||||
return (int)bytes;
|
||||
|
@ -518,11 +516,12 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
|
|||
c_tx->mpa_crc_hd,
|
||||
iov[seg].iov_base,
|
||||
plen);
|
||||
} else if (do_crc)
|
||||
crypto_shash_update(
|
||||
c_tx->mpa_crc_hd,
|
||||
page_address(p) + fp_off,
|
||||
plen);
|
||||
} else if (do_crc) {
|
||||
crypto_shash_update(c_tx->mpa_crc_hd,
|
||||
kmap(p) + fp_off,
|
||||
plen);
|
||||
kunmap(p);
|
||||
}
|
||||
} else {
|
||||
u64 va = sge->laddr + sge_off;
|
||||
|
||||
|
|
|
@ -206,7 +206,8 @@ int siw_query_port(struct ib_device *base_dev, u8 port,
|
|||
attr->gid_tbl_len = 1;
|
||||
attr->max_msg_sz = -1;
|
||||
attr->max_mtu = ib_mtu_int_to_enum(sdev->netdev->mtu);
|
||||
attr->phys_state = sdev->state == IB_PORT_ACTIVE ? 5 : 3;
|
||||
attr->phys_state = sdev->state == IB_PORT_ACTIVE ?
|
||||
IB_PORT_PHYS_STATE_LINK_UP : IB_PORT_PHYS_STATE_DISABLED;
|
||||
attr->pkey_tbl_len = 1;
|
||||
attr->port_cap_flags = IB_PORT_CM_SUP | IB_PORT_DEVICE_MGMT_SUP;
|
||||
attr->state = sdev->state;
|
||||
|
|
|
@ -102,9 +102,10 @@
|
|||
|
||||
/* Default support is 512KB I/O size */
|
||||
#define ISER_DEF_MAX_SECTORS 1024
|
||||
#define ISCSI_ISER_DEF_SG_TABLESIZE ((ISER_DEF_MAX_SECTORS * 512) >> SHIFT_4K)
|
||||
/* Maximum support is 8MB I/O size */
|
||||
#define ISCSI_ISER_MAX_SG_TABLESIZE ((16384 * 512) >> SHIFT_4K)
|
||||
#define ISCSI_ISER_DEF_SG_TABLESIZE \
|
||||
((ISER_DEF_MAX_SECTORS * SECTOR_SIZE) >> SHIFT_4K)
|
||||
/* Maximum support is 16MB I/O size */
|
||||
#define ISCSI_ISER_MAX_SG_TABLESIZE ((32768 * SECTOR_SIZE) >> SHIFT_4K)
|
||||
|
||||
#define ISER_DEF_XMIT_CMDS_DEFAULT 512
|
||||
#if ISCSI_DEF_XMIT_CMDS_MAX > ISER_DEF_XMIT_CMDS_DEFAULT
|
||||
|
|
|
@ -1767,8 +1767,8 @@ static int srpt_create_ch_ib(struct srpt_rdma_ch *ch)
|
|||
goto out;
|
||||
|
||||
retry:
|
||||
ch->cq = ib_alloc_cq(sdev->device, ch, ch->rq_size + sq_size,
|
||||
0 /* XXX: spread CQs */, IB_POLL_WORKQUEUE);
|
||||
ch->cq = ib_alloc_cq_any(sdev->device, ch, ch->rq_size + sq_size,
|
||||
IB_POLL_WORKQUEUE);
|
||||
if (IS_ERR(ch->cq)) {
|
||||
ret = PTR_ERR(ch->cq);
|
||||
pr_err("failed to create CQ cqe= %d ret= %d\n",
|
||||
|
|
|
@ -188,8 +188,7 @@ int mlx5_rl_add_rate(struct mlx5_core_dev *dev, u16 *index,
|
|||
/* new rate limit */
|
||||
err = mlx5_set_pp_rate_limit_cmd(dev, entry->index, rl);
|
||||
if (err) {
|
||||
mlx5_core_err(dev, "Failed configuring rate limit(err %d): \
|
||||
rate %u, max_burst_sz %u, typical_pkt_sz %u\n",
|
||||
mlx5_core_err(dev, "Failed configuring rate limit(err %d): rate %u, max_burst_sz %u, typical_pkt_sz %u\n",
|
||||
err, rl->rate, rl->max_burst_sz,
|
||||
rl->typical_pkt_sz);
|
||||
goto out;
|
||||
|
@ -218,8 +217,7 @@ void mlx5_rl_remove_rate(struct mlx5_core_dev *dev, struct mlx5_rate_limit *rl)
|
|||
mutex_lock(&table->rl_lock);
|
||||
entry = find_rl_entry(table, rl);
|
||||
if (!entry || !entry->refcount) {
|
||||
mlx5_core_warn(dev, "Rate %u, max_burst_sz %u typical_pkt_sz %u \
|
||||
are not configured\n",
|
||||
mlx5_core_warn(dev, "Rate %u, max_burst_sz %u typical_pkt_sz %u are not configured\n",
|
||||
rl->rate, rl->max_burst_sz, rl->typical_pkt_sz);
|
||||
goto out;
|
||||
}
|
||||
|
|
|
@ -798,9 +798,8 @@ static int qed_rdma_add_user(void *rdma_cxt,
|
|||
/* Calculate the corresponding DPI address */
|
||||
dpi_start_offset = p_hwfn->dpi_start_offset;
|
||||
|
||||
out_params->dpi_addr = (u64)((u8 __iomem *)p_hwfn->doorbells +
|
||||
dpi_start_offset +
|
||||
((out_params->dpi) * p_hwfn->dpi_size));
|
||||
out_params->dpi_addr = p_hwfn->doorbells + dpi_start_offset +
|
||||
out_params->dpi * p_hwfn->dpi_size;
|
||||
|
||||
out_params->dpi_phys_addr = p_hwfn->db_phys_addr +
|
||||
dpi_start_offset +
|
||||
|
|
|
@ -1654,15 +1654,17 @@ static struct smbd_connection *_smbd_get_connection(
|
|||
|
||||
info->send_cq = NULL;
|
||||
info->recv_cq = NULL;
|
||||
info->send_cq = ib_alloc_cq(info->id->device, info,
|
||||
info->send_credit_target, 0, IB_POLL_SOFTIRQ);
|
||||
info->send_cq =
|
||||
ib_alloc_cq_any(info->id->device, info,
|
||||
info->send_credit_target, IB_POLL_SOFTIRQ);
|
||||
if (IS_ERR(info->send_cq)) {
|
||||
info->send_cq = NULL;
|
||||
goto alloc_cq_failed;
|
||||
}
|
||||
|
||||
info->recv_cq = ib_alloc_cq(info->id->device, info,
|
||||
info->receive_credit_max, 0, IB_POLL_SOFTIRQ);
|
||||
info->recv_cq =
|
||||
ib_alloc_cq_any(info->id->device, info,
|
||||
info->receive_credit_max, IB_POLL_SOFTIRQ);
|
||||
if (IS_ERR(info->recv_cq)) {
|
||||
info->recv_cq = NULL;
|
||||
goto alloc_cq_failed;
|
||||
|
|
|
@ -881,12 +881,6 @@ header-test- += net/xdp.h
|
|||
header-test- += net/xdp_priv.h
|
||||
header-test- += pcmcia/cistpl.h
|
||||
header-test- += pcmcia/ds.h
|
||||
header-test- += rdma/ib.h
|
||||
header-test- += rdma/iw_portmap.h
|
||||
header-test- += rdma/opa_port_info.h
|
||||
header-test- += rdma/rdmavt_cq.h
|
||||
header-test- += rdma/restrack.h
|
||||
header-test- += rdma/signature.h
|
||||
header-test- += rdma/tid_rdma_defs.h
|
||||
header-test- += scsi/fc/fc_encaps.h
|
||||
header-test- += scsi/fc/fc_fc2.h
|
||||
|
|
|
@ -328,6 +328,7 @@ enum mlx5_event {
|
|||
MLX5_EVENT_TYPE_GPIO_EVENT = 0x15,
|
||||
MLX5_EVENT_TYPE_PORT_MODULE_EVENT = 0x16,
|
||||
MLX5_EVENT_TYPE_TEMP_WARN_EVENT = 0x17,
|
||||
MLX5_EVENT_TYPE_XRQ_ERROR = 0x18,
|
||||
MLX5_EVENT_TYPE_REMOTE_CONFIG = 0x19,
|
||||
MLX5_EVENT_TYPE_GENERAL_EVENT = 0x22,
|
||||
MLX5_EVENT_TYPE_MONITOR_COUNTER = 0x24,
|
||||
|
@ -345,6 +346,7 @@ enum mlx5_event {
|
|||
MLX5_EVENT_TYPE_ESW_FUNCTIONS_CHANGED = 0xe,
|
||||
|
||||
MLX5_EVENT_TYPE_DCT_DRAINED = 0x1c,
|
||||
MLX5_EVENT_TYPE_DCT_KEY_VIOLATION = 0x1d,
|
||||
|
||||
MLX5_EVENT_TYPE_FPGA_ERROR = 0x20,
|
||||
MLX5_EVENT_TYPE_FPGA_QP_ERROR = 0x21,
|
||||
|
@ -584,6 +586,12 @@ struct mlx5_eqe_cq_err {
|
|||
u8 syndrome;
|
||||
};
|
||||
|
||||
struct mlx5_eqe_xrq_err {
|
||||
__be32 reserved1[5];
|
||||
__be32 type_xrqn;
|
||||
__be32 reserved2;
|
||||
};
|
||||
|
||||
struct mlx5_eqe_port_state {
|
||||
u8 reserved0[8];
|
||||
u8 port;
|
||||
|
@ -698,6 +706,7 @@ union ev_data {
|
|||
struct mlx5_eqe_pps pps;
|
||||
struct mlx5_eqe_dct dct;
|
||||
struct mlx5_eqe_temp_warning temp_warning;
|
||||
struct mlx5_eqe_xrq_err xrq_err;
|
||||
} __packed;
|
||||
|
||||
struct mlx5_eqe {
|
||||
|
|
|
@ -225,7 +225,7 @@ struct qed_rdma_start_in_params {
|
|||
|
||||
struct qed_rdma_add_user_out_params {
|
||||
u16 dpi;
|
||||
u64 dpi_addr;
|
||||
void __iomem *dpi_addr;
|
||||
u64 dpi_phys_addr;
|
||||
u32 dpi_size;
|
||||
u16 wid_count;
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
#include <linux/types.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/cred.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/fs.h>
|
||||
|
||||
struct ib_addr {
|
||||
union {
|
||||
|
|
|
@ -98,15 +98,54 @@ void ibdev_info(const struct ib_device *ibdev, const char *format, ...);
|
|||
#if defined(CONFIG_DYNAMIC_DEBUG)
|
||||
#define ibdev_dbg(__dev, format, args...) \
|
||||
dynamic_ibdev_dbg(__dev, format, ##args)
|
||||
#elif defined(DEBUG)
|
||||
#define ibdev_dbg(__dev, format, args...) \
|
||||
ibdev_printk(KERN_DEBUG, __dev, format, ##args)
|
||||
#else
|
||||
__printf(2, 3) __cold
|
||||
static inline
|
||||
void ibdev_dbg(const struct ib_device *ibdev, const char *format, ...) {}
|
||||
#endif
|
||||
|
||||
#define ibdev_level_ratelimited(ibdev_level, ibdev, fmt, ...) \
|
||||
do { \
|
||||
static DEFINE_RATELIMIT_STATE(_rs, \
|
||||
DEFAULT_RATELIMIT_INTERVAL, \
|
||||
DEFAULT_RATELIMIT_BURST); \
|
||||
if (__ratelimit(&_rs)) \
|
||||
ibdev_level(ibdev, fmt, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define ibdev_emerg_ratelimited(ibdev, fmt, ...) \
|
||||
ibdev_level_ratelimited(ibdev_emerg, ibdev, fmt, ##__VA_ARGS__)
|
||||
#define ibdev_alert_ratelimited(ibdev, fmt, ...) \
|
||||
ibdev_level_ratelimited(ibdev_alert, ibdev, fmt, ##__VA_ARGS__)
|
||||
#define ibdev_crit_ratelimited(ibdev, fmt, ...) \
|
||||
ibdev_level_ratelimited(ibdev_crit, ibdev, fmt, ##__VA_ARGS__)
|
||||
#define ibdev_err_ratelimited(ibdev, fmt, ...) \
|
||||
ibdev_level_ratelimited(ibdev_err, ibdev, fmt, ##__VA_ARGS__)
|
||||
#define ibdev_warn_ratelimited(ibdev, fmt, ...) \
|
||||
ibdev_level_ratelimited(ibdev_warn, ibdev, fmt, ##__VA_ARGS__)
|
||||
#define ibdev_notice_ratelimited(ibdev, fmt, ...) \
|
||||
ibdev_level_ratelimited(ibdev_notice, ibdev, fmt, ##__VA_ARGS__)
|
||||
#define ibdev_info_ratelimited(ibdev, fmt, ...) \
|
||||
ibdev_level_ratelimited(ibdev_info, ibdev, fmt, ##__VA_ARGS__)
|
||||
|
||||
#if defined(CONFIG_DYNAMIC_DEBUG)
|
||||
/* descriptor check is first to prevent flooding with "callbacks suppressed" */
|
||||
#define ibdev_dbg_ratelimited(ibdev, fmt, ...) \
|
||||
do { \
|
||||
static DEFINE_RATELIMIT_STATE(_rs, \
|
||||
DEFAULT_RATELIMIT_INTERVAL, \
|
||||
DEFAULT_RATELIMIT_BURST); \
|
||||
DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \
|
||||
if (DYNAMIC_DEBUG_BRANCH(descriptor) && __ratelimit(&_rs)) \
|
||||
__dynamic_ibdev_dbg(&descriptor, ibdev, fmt, \
|
||||
##__VA_ARGS__); \
|
||||
} while (0)
|
||||
#else
|
||||
__printf(2, 3) __cold
|
||||
static inline
|
||||
void ibdev_dbg_ratelimited(const struct ib_device *ibdev, const char *format, ...) {}
|
||||
#endif
|
||||
|
||||
union ib_gid {
|
||||
u8 raw[16];
|
||||
struct {
|
||||
|
@ -451,6 +490,16 @@ enum ib_port_state {
|
|||
IB_PORT_ACTIVE_DEFER = 5
|
||||
};
|
||||
|
||||
enum ib_port_phys_state {
|
||||
IB_PORT_PHYS_STATE_SLEEP = 1,
|
||||
IB_PORT_PHYS_STATE_POLLING = 2,
|
||||
IB_PORT_PHYS_STATE_DISABLED = 3,
|
||||
IB_PORT_PHYS_STATE_PORT_CONFIGURATION_TRAINING = 4,
|
||||
IB_PORT_PHYS_STATE_LINK_UP = 5,
|
||||
IB_PORT_PHYS_STATE_LINK_ERROR_RECOVERY = 6,
|
||||
IB_PORT_PHYS_STATE_PHY_TEST = 7,
|
||||
};
|
||||
|
||||
enum ib_port_width {
|
||||
IB_WIDTH_1X = 1,
|
||||
IB_WIDTH_2X = 16,
|
||||
|
@ -3710,6 +3759,25 @@ static inline struct ib_cq *ib_alloc_cq(struct ib_device *dev, void *private,
|
|||
NULL);
|
||||
}
|
||||
|
||||
struct ib_cq *__ib_alloc_cq_any(struct ib_device *dev, void *private,
|
||||
int nr_cqe, enum ib_poll_context poll_ctx,
|
||||
const char *caller);
|
||||
|
||||
/**
|
||||
* ib_alloc_cq_any: Allocate kernel CQ
|
||||
* @dev: The IB device
|
||||
* @private: Private data attached to the CQE
|
||||
* @nr_cqe: Number of CQEs in the CQ
|
||||
* @poll_ctx: Context used for polling the CQ
|
||||
*/
|
||||
static inline struct ib_cq *ib_alloc_cq_any(struct ib_device *dev,
|
||||
void *private, int nr_cqe,
|
||||
enum ib_poll_context poll_ctx)
|
||||
{
|
||||
return __ib_alloc_cq_any(dev, private, nr_cqe, poll_ctx,
|
||||
KBUILD_MODNAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* ib_free_cq_user - Free kernel/user CQ
|
||||
* @cq: The CQ to free
|
||||
|
|
|
@ -33,6 +33,9 @@
|
|||
#ifndef _IW_PORTMAP_H
|
||||
#define _IW_PORTMAP_H
|
||||
|
||||
#include <linux/socket.h>
|
||||
#include <linux/netlink.h>
|
||||
|
||||
#define IWPM_ULIBNAME_SIZE 32
|
||||
#define IWPM_DEVNAME_SIZE 32
|
||||
#define IWPM_IFNAME_SIZE 16
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
#if !defined(OPA_PORT_INFO_H)
|
||||
#define OPA_PORT_INFO_H
|
||||
|
||||
#include <rdma/opa_smi.h>
|
||||
|
||||
#define OPA_PORT_LINK_MODE_NOP 0 /* No change */
|
||||
#define OPA_PORT_LINK_MODE_OPA 4 /* Port mode is OPA */
|
||||
|
||||
|
|
|
@ -76,28 +76,32 @@ int ibnl_put_attr(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||
|
||||
/**
|
||||
* Send the supplied skb to a specific userspace PID.
|
||||
* @net: Net namespace in which to send the skb
|
||||
* @skb: The netlink skb
|
||||
* @pid: Userspace netlink process ID
|
||||
* Returns 0 on success or a negative error code.
|
||||
*/
|
||||
int rdma_nl_unicast(struct sk_buff *skb, u32 pid);
|
||||
int rdma_nl_unicast(struct net *net, struct sk_buff *skb, u32 pid);
|
||||
|
||||
/**
|
||||
* Send, with wait/1 retry, the supplied skb to a specific userspace PID.
|
||||
* @net: Net namespace in which to send the skb
|
||||
* @skb: The netlink skb
|
||||
* @pid: Userspace netlink process ID
|
||||
* Returns 0 on success or a negative error code.
|
||||
*/
|
||||
int rdma_nl_unicast_wait(struct sk_buff *skb, __u32 pid);
|
||||
int rdma_nl_unicast_wait(struct net *net, struct sk_buff *skb, __u32 pid);
|
||||
|
||||
/**
|
||||
* Send the supplied skb to a netlink group.
|
||||
* @net: Net namespace in which to send the skb
|
||||
* @skb: The netlink skb
|
||||
* @group: Netlink group ID
|
||||
* @flags: allocation flags
|
||||
* Returns 0 on success or a negative error code.
|
||||
*/
|
||||
int rdma_nl_multicast(struct sk_buff *skb, unsigned int group, gfp_t flags);
|
||||
int rdma_nl_multicast(struct net *net, struct sk_buff *skb,
|
||||
unsigned int group, gfp_t flags);
|
||||
|
||||
/**
|
||||
* Check if there are any listeners to the netlink group
|
||||
|
|
|
@ -116,6 +116,7 @@ struct rvt_ibport {
|
|||
u64 n_unaligned;
|
||||
u64 n_rc_dupreq;
|
||||
u64 n_rc_seqnak;
|
||||
u64 n_rc_crwaits;
|
||||
u16 pkey_violations;
|
||||
u16 qkey_violations;
|
||||
u16 mkey_violations;
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
|
||||
#include <linux/kthread.h>
|
||||
#include <rdma/ib_user_verbs.h>
|
||||
#include <rdma/ib_verbs.h>
|
||||
|
||||
/*
|
||||
* Define an ib_cq_notify value that is not valid so we know when CQ
|
||||
|
|
|
@ -973,6 +973,41 @@ static inline void rvt_free_rq(struct rvt_rq *rq)
|
|||
rq->wq = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* rvt_to_iport - Get the ibport pointer
|
||||
* @qp: the qp pointer
|
||||
*
|
||||
* This function returns the ibport pointer from the qp pointer.
|
||||
*/
|
||||
static inline struct rvt_ibport *rvt_to_iport(struct rvt_qp *qp)
|
||||
{
|
||||
struct rvt_dev_info *rdi = ib_to_rvt(qp->ibqp.device);
|
||||
|
||||
return rdi->ports[qp->port_num - 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* rvt_rc_credit_avail - Check if there are enough RC credits for the request
|
||||
* @qp: the qp
|
||||
* @wqe: the request
|
||||
*
|
||||
* This function returns false when there are not enough credits for the given
|
||||
* request and true otherwise.
|
||||
*/
|
||||
static inline bool rvt_rc_credit_avail(struct rvt_qp *qp, struct rvt_swqe *wqe)
|
||||
{
|
||||
lockdep_assert_held(&qp->s_lock);
|
||||
if (!(qp->s_flags & RVT_S_UNLIMITED_CREDIT) &&
|
||||
rvt_cmp_msn(wqe->ssn, qp->s_lsn + 1) > 0) {
|
||||
struct rvt_ibport *rvp = rvt_to_iport(qp);
|
||||
|
||||
qp->s_flags |= RVT_S_WAIT_SSN_CREDIT;
|
||||
rvp->n_rc_crwaits++;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
struct rvt_qp_iter *rvt_qp_iter_init(struct rvt_dev_info *rdi,
|
||||
u64 v,
|
||||
void (*cb)(struct rvt_qp *qp, u64 v));
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#ifndef _RDMA_SIGNATURE_H_
|
||||
#define _RDMA_SIGNATURE_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
enum ib_signature_prot_cap {
|
||||
IB_PROT_T10DIF_TYPE_1 = 1,
|
||||
IB_PROT_T10DIF_TYPE_2 = 1 << 1,
|
||||
|
|
|
@ -43,6 +43,7 @@ enum mlx5_ib_uapi_flow_table_type {
|
|||
MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_RX = 0x0,
|
||||
MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX = 0x1,
|
||||
MLX5_IB_UAPI_FLOW_TABLE_TYPE_FDB = 0x2,
|
||||
MLX5_IB_UAPI_FLOW_TABLE_TYPE_RDMA_RX = 0x3,
|
||||
};
|
||||
|
||||
enum mlx5_ib_uapi_flow_action_packet_reformat_type {
|
||||
|
|
|
@ -685,9 +685,9 @@ rdma_create_trans(struct p9_client *client, const char *addr, char *args)
|
|||
goto error;
|
||||
|
||||
/* Create the Completion Queue */
|
||||
rdma->cq = ib_alloc_cq(rdma->cm_id->device, client,
|
||||
opts.sq_depth + opts.rq_depth + 1,
|
||||
0, IB_POLL_SOFTIRQ);
|
||||
rdma->cq = ib_alloc_cq_any(rdma->cm_id->device, client,
|
||||
opts.sq_depth + opts.rq_depth + 1,
|
||||
IB_POLL_SOFTIRQ);
|
||||
if (IS_ERR(rdma->cq))
|
||||
goto error;
|
||||
|
||||
|
|
|
@ -454,14 +454,14 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
|
|||
dprintk("svcrdma: error creating PD for connect request\n");
|
||||
goto errout;
|
||||
}
|
||||
newxprt->sc_sq_cq = ib_alloc_cq(dev, newxprt, newxprt->sc_sq_depth,
|
||||
0, IB_POLL_WORKQUEUE);
|
||||
newxprt->sc_sq_cq = ib_alloc_cq_any(dev, newxprt, newxprt->sc_sq_depth,
|
||||
IB_POLL_WORKQUEUE);
|
||||
if (IS_ERR(newxprt->sc_sq_cq)) {
|
||||
dprintk("svcrdma: error creating SQ CQ for connect request\n");
|
||||
goto errout;
|
||||
}
|
||||
newxprt->sc_rq_cq = ib_alloc_cq(dev, newxprt, rq_depth,
|
||||
0, IB_POLL_WORKQUEUE);
|
||||
newxprt->sc_rq_cq =
|
||||
ib_alloc_cq_any(dev, newxprt, rq_depth, IB_POLL_WORKQUEUE);
|
||||
if (IS_ERR(newxprt->sc_rq_cq)) {
|
||||
dprintk("svcrdma: error creating RQ CQ for connect request\n");
|
||||
goto errout;
|
||||
|
|
|
@ -521,18 +521,17 @@ int rpcrdma_ep_create(struct rpcrdma_xprt *r_xprt)
|
|||
init_waitqueue_head(&ep->rep_connect_wait);
|
||||
ep->rep_receive_count = 0;
|
||||
|
||||
sendcq = ib_alloc_cq(ia->ri_id->device, NULL,
|
||||
ep->rep_attr.cap.max_send_wr + 1,
|
||||
ia->ri_id->device->num_comp_vectors > 1 ? 1 : 0,
|
||||
IB_POLL_WORKQUEUE);
|
||||
sendcq = ib_alloc_cq_any(ia->ri_id->device, NULL,
|
||||
ep->rep_attr.cap.max_send_wr + 1,
|
||||
IB_POLL_WORKQUEUE);
|
||||
if (IS_ERR(sendcq)) {
|
||||
rc = PTR_ERR(sendcq);
|
||||
goto out1;
|
||||
}
|
||||
|
||||
recvcq = ib_alloc_cq(ia->ri_id->device, NULL,
|
||||
ep->rep_attr.cap.max_recv_wr + 1,
|
||||
0, IB_POLL_WORKQUEUE);
|
||||
recvcq = ib_alloc_cq_any(ia->ri_id->device, NULL,
|
||||
ep->rep_attr.cap.max_recv_wr + 1,
|
||||
IB_POLL_WORKQUEUE);
|
||||
if (IS_ERR(recvcq)) {
|
||||
rc = PTR_ERR(recvcq);
|
||||
goto out2;
|
||||
|
|
Loading…
Reference in New Issue