Commit fb92d8fb authored by Doug Ledford's avatar Doug Ledford

Merge branches 'cxgb4-4.8', 'mlx5-4.8' and 'fw-version' into k.o/for-4.8

...@@ -311,6 +311,15 @@ static int read_port_immutable(struct ib_device *device) ...@@ -311,6 +311,15 @@ static int read_port_immutable(struct ib_device *device)
return 0; return 0;
} }
void ib_get_device_fw_str(struct ib_device *dev, char *str, size_t str_len)
{
if (dev->get_dev_fw_str)
dev->get_dev_fw_str(dev, str, str_len);
else
str[0] = '\0';
}
EXPORT_SYMBOL(ib_get_device_fw_str);
/** /**
* ib_register_device - Register an IB device with IB core * ib_register_device - Register an IB device with IB core
* @device:Device to register * @device:Device to register
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <linux/stat.h> #include <linux/stat.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/ethtool.h>
#include <rdma/ib_mad.h> #include <rdma/ib_mad.h>
#include <rdma/ib_pma.h> #include <rdma/ib_pma.h>
...@@ -1196,16 +1197,28 @@ static ssize_t set_node_desc(struct device *device, ...@@ -1196,16 +1197,28 @@ static ssize_t set_node_desc(struct device *device,
return count; return count;
} }
static ssize_t show_fw_ver(struct device *device, struct device_attribute *attr,
char *buf)
{
struct ib_device *dev = container_of(device, struct ib_device, dev);
ib_get_device_fw_str(dev, buf, PAGE_SIZE);
strlcat(buf, "\n", PAGE_SIZE);
return strlen(buf);
}
static DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL); static DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL);
static DEVICE_ATTR(sys_image_guid, S_IRUGO, show_sys_image_guid, NULL); static DEVICE_ATTR(sys_image_guid, S_IRUGO, show_sys_image_guid, NULL);
static DEVICE_ATTR(node_guid, S_IRUGO, show_node_guid, NULL); static DEVICE_ATTR(node_guid, S_IRUGO, show_node_guid, NULL);
static DEVICE_ATTR(node_desc, S_IRUGO | S_IWUSR, show_node_desc, set_node_desc); static DEVICE_ATTR(node_desc, S_IRUGO | S_IWUSR, show_node_desc, set_node_desc);
static DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);
static struct device_attribute *ib_class_attributes[] = { static struct device_attribute *ib_class_attributes[] = {
&dev_attr_node_type, &dev_attr_node_type,
&dev_attr_sys_image_guid, &dev_attr_sys_image_guid,
&dev_attr_node_guid, &dev_attr_node_guid,
&dev_attr_node_desc &dev_attr_node_desc,
&dev_attr_fw_ver,
}; };
static void free_port_list_attributes(struct ib_device *device) static void free_port_list_attributes(struct ib_device *device)
......
...@@ -162,6 +162,10 @@ struct ib_uqp_object { ...@@ -162,6 +162,10 @@ struct ib_uqp_object {
struct ib_uxrcd_object *uxrcd; struct ib_uxrcd_object *uxrcd;
}; };
struct ib_uwq_object {
struct ib_uevent_object uevent;
};
struct ib_ucq_object { struct ib_ucq_object {
struct ib_uobject uobject; struct ib_uobject uobject;
struct ib_uverbs_file *uverbs_file; struct ib_uverbs_file *uverbs_file;
...@@ -181,6 +185,8 @@ extern struct idr ib_uverbs_qp_idr; ...@@ -181,6 +185,8 @@ extern struct idr ib_uverbs_qp_idr;
extern struct idr ib_uverbs_srq_idr; extern struct idr ib_uverbs_srq_idr;
extern struct idr ib_uverbs_xrcd_idr; extern struct idr ib_uverbs_xrcd_idr;
extern struct idr ib_uverbs_rule_idr; extern struct idr ib_uverbs_rule_idr;
extern struct idr ib_uverbs_wq_idr;
extern struct idr ib_uverbs_rwq_ind_tbl_idr;
void idr_remove_uobj(struct idr *idp, struct ib_uobject *uobj); void idr_remove_uobj(struct idr *idp, struct ib_uobject *uobj);
...@@ -199,6 +205,7 @@ void ib_uverbs_release_uevent(struct ib_uverbs_file *file, ...@@ -199,6 +205,7 @@ void ib_uverbs_release_uevent(struct ib_uverbs_file *file,
void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context); void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context);
void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr); void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr);
void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr); void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr);
void ib_uverbs_wq_event_handler(struct ib_event *event, void *context_ptr);
void ib_uverbs_srq_event_handler(struct ib_event *event, void *context_ptr); void ib_uverbs_srq_event_handler(struct ib_event *event, void *context_ptr);
void ib_uverbs_event_handler(struct ib_event_handler *handler, void ib_uverbs_event_handler(struct ib_event_handler *handler,
struct ib_event *event); struct ib_event *event);
...@@ -219,6 +226,7 @@ struct ib_uverbs_flow_spec { ...@@ -219,6 +226,7 @@ struct ib_uverbs_flow_spec {
struct ib_uverbs_flow_spec_eth eth; struct ib_uverbs_flow_spec_eth eth;
struct ib_uverbs_flow_spec_ipv4 ipv4; struct ib_uverbs_flow_spec_ipv4 ipv4;
struct ib_uverbs_flow_spec_tcp_udp tcp_udp; struct ib_uverbs_flow_spec_tcp_udp tcp_udp;
struct ib_uverbs_flow_spec_ipv6 ipv6;
}; };
}; };
...@@ -275,5 +283,10 @@ IB_UVERBS_DECLARE_EX_CMD(destroy_flow); ...@@ -275,5 +283,10 @@ IB_UVERBS_DECLARE_EX_CMD(destroy_flow);
IB_UVERBS_DECLARE_EX_CMD(query_device); IB_UVERBS_DECLARE_EX_CMD(query_device);
IB_UVERBS_DECLARE_EX_CMD(create_cq); IB_UVERBS_DECLARE_EX_CMD(create_cq);
IB_UVERBS_DECLARE_EX_CMD(create_qp); IB_UVERBS_DECLARE_EX_CMD(create_qp);
IB_UVERBS_DECLARE_EX_CMD(create_wq);
IB_UVERBS_DECLARE_EX_CMD(modify_wq);
IB_UVERBS_DECLARE_EX_CMD(destroy_wq);
IB_UVERBS_DECLARE_EX_CMD(create_rwq_ind_table);
IB_UVERBS_DECLARE_EX_CMD(destroy_rwq_ind_table);
#endif /* UVERBS_H */ #endif /* UVERBS_H */
This diff is collapsed.
...@@ -76,6 +76,8 @@ DEFINE_IDR(ib_uverbs_qp_idr); ...@@ -76,6 +76,8 @@ DEFINE_IDR(ib_uverbs_qp_idr);
DEFINE_IDR(ib_uverbs_srq_idr); DEFINE_IDR(ib_uverbs_srq_idr);
DEFINE_IDR(ib_uverbs_xrcd_idr); DEFINE_IDR(ib_uverbs_xrcd_idr);
DEFINE_IDR(ib_uverbs_rule_idr); DEFINE_IDR(ib_uverbs_rule_idr);
DEFINE_IDR(ib_uverbs_wq_idr);
DEFINE_IDR(ib_uverbs_rwq_ind_tbl_idr);
static DEFINE_SPINLOCK(map_lock); static DEFINE_SPINLOCK(map_lock);
static DECLARE_BITMAP(dev_map, IB_UVERBS_MAX_DEVICES); static DECLARE_BITMAP(dev_map, IB_UVERBS_MAX_DEVICES);
...@@ -130,6 +132,11 @@ static int (*uverbs_ex_cmd_table[])(struct ib_uverbs_file *file, ...@@ -130,6 +132,11 @@ static int (*uverbs_ex_cmd_table[])(struct ib_uverbs_file *file,
[IB_USER_VERBS_EX_CMD_QUERY_DEVICE] = ib_uverbs_ex_query_device, [IB_USER_VERBS_EX_CMD_QUERY_DEVICE] = ib_uverbs_ex_query_device,
[IB_USER_VERBS_EX_CMD_CREATE_CQ] = ib_uverbs_ex_create_cq, [IB_USER_VERBS_EX_CMD_CREATE_CQ] = ib_uverbs_ex_create_cq,
[IB_USER_VERBS_EX_CMD_CREATE_QP] = ib_uverbs_ex_create_qp, [IB_USER_VERBS_EX_CMD_CREATE_QP] = ib_uverbs_ex_create_qp,
[IB_USER_VERBS_EX_CMD_CREATE_WQ] = ib_uverbs_ex_create_wq,
[IB_USER_VERBS_EX_CMD_MODIFY_WQ] = ib_uverbs_ex_modify_wq,
[IB_USER_VERBS_EX_CMD_DESTROY_WQ] = ib_uverbs_ex_destroy_wq,
[IB_USER_VERBS_EX_CMD_CREATE_RWQ_IND_TBL] = ib_uverbs_ex_create_rwq_ind_table,
[IB_USER_VERBS_EX_CMD_DESTROY_RWQ_IND_TBL] = ib_uverbs_ex_destroy_rwq_ind_table,
}; };
static void ib_uverbs_add_one(struct ib_device *device); static void ib_uverbs_add_one(struct ib_device *device);
...@@ -265,6 +272,27 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, ...@@ -265,6 +272,27 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file,
kfree(uqp); kfree(uqp);
} }
list_for_each_entry_safe(uobj, tmp, &context->rwq_ind_tbl_list, list) {
struct ib_rwq_ind_table *rwq_ind_tbl = uobj->object;
struct ib_wq **ind_tbl = rwq_ind_tbl->ind_tbl;
idr_remove_uobj(&ib_uverbs_rwq_ind_tbl_idr, uobj);
ib_destroy_rwq_ind_table(rwq_ind_tbl);
kfree(ind_tbl);
kfree(uobj);
}
list_for_each_entry_safe(uobj, tmp, &context->wq_list, list) {
struct ib_wq *wq = uobj->object;
struct ib_uwq_object *uwq =
container_of(uobj, struct ib_uwq_object, uevent.uobject);
idr_remove_uobj(&ib_uverbs_wq_idr, uobj);
ib_destroy_wq(wq);
ib_uverbs_release_uevent(file, &uwq->uevent);
kfree(uwq);
}
list_for_each_entry_safe(uobj, tmp, &context->srq_list, list) { list_for_each_entry_safe(uobj, tmp, &context->srq_list, list) {
struct ib_srq *srq = uobj->object; struct ib_srq *srq = uobj->object;
struct ib_uevent_object *uevent = struct ib_uevent_object *uevent =
...@@ -568,6 +596,16 @@ void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr) ...@@ -568,6 +596,16 @@ void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr)
&uobj->events_reported); &uobj->events_reported);
} }
void ib_uverbs_wq_event_handler(struct ib_event *event, void *context_ptr)
{
struct ib_uevent_object *uobj = container_of(event->element.wq->uobject,
struct ib_uevent_object, uobject);
ib_uverbs_async_handler(context_ptr, uobj->uobject.user_handle,
event->event, &uobj->event_list,
&uobj->events_reported);
}
void ib_uverbs_srq_event_handler(struct ib_event *event, void *context_ptr) void ib_uverbs_srq_event_handler(struct ib_event *event, void *context_ptr)
{ {
struct ib_uevent_object *uobj; struct ib_uevent_object *uobj;
......
...@@ -754,6 +754,12 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd, ...@@ -754,6 +754,12 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
struct ib_qp *qp; struct ib_qp *qp;
int ret; int ret;
if (qp_init_attr->rwq_ind_tbl &&
(qp_init_attr->recv_cq ||
qp_init_attr->srq || qp_init_attr->cap.max_recv_wr ||
qp_init_attr->cap.max_recv_sge))
return ERR_PTR(-EINVAL);
/* /*
* If the callers is using the RDMA API calculate the resources * If the callers is using the RDMA API calculate the resources
* needed for the RDMA READ/WRITE operations. * needed for the RDMA READ/WRITE operations.
...@@ -771,6 +777,7 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd, ...@@ -771,6 +777,7 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
qp->real_qp = qp; qp->real_qp = qp;
qp->uobject = NULL; qp->uobject = NULL;
qp->qp_type = qp_init_attr->qp_type; qp->qp_type = qp_init_attr->qp_type;
qp->rwq_ind_tbl = qp_init_attr->rwq_ind_tbl;
atomic_set(&qp->usecnt, 0); atomic_set(&qp->usecnt, 0);
qp->mrs_used = 0; qp->mrs_used = 0;
...@@ -788,7 +795,8 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd, ...@@ -788,7 +795,8 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
qp->srq = NULL; qp->srq = NULL;
} else { } else {
qp->recv_cq = qp_init_attr->recv_cq; qp->recv_cq = qp_init_attr->recv_cq;
atomic_inc(&qp_init_attr->recv_cq->usecnt); if (qp_init_attr->recv_cq)
atomic_inc(&qp_init_attr->recv_cq->usecnt);
qp->srq = qp_init_attr->srq; qp->srq = qp_init_attr->srq;
if (qp->srq) if (qp->srq)
atomic_inc(&qp_init_attr->srq->usecnt); atomic_inc(&qp_init_attr->srq->usecnt);
...@@ -799,7 +807,10 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd, ...@@ -799,7 +807,10 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
qp->xrcd = NULL; qp->xrcd = NULL;
atomic_inc(&pd->usecnt); atomic_inc(&pd->usecnt);
atomic_inc(&qp_init_attr->send_cq->usecnt); if (qp_init_attr->send_cq)
atomic_inc(&qp_init_attr->send_cq->usecnt);
if (qp_init_attr->rwq_ind_tbl)
atomic_inc(&qp->rwq_ind_tbl->usecnt);
if (qp_init_attr->cap.max_rdma_ctxs) { if (qp_init_attr->cap.max_rdma_ctxs) {
ret = rdma_rw_init_mrs(qp, qp_init_attr); ret = rdma_rw_init_mrs(qp, qp_init_attr);
...@@ -1279,6 +1290,7 @@ int ib_destroy_qp(struct ib_qp *qp) ...@@ -1279,6 +1290,7 @@ int ib_destroy_qp(struct ib_qp *qp)
struct ib_pd *pd; struct ib_pd *pd;
struct ib_cq *scq, *rcq; struct ib_cq *scq, *rcq;
struct ib_srq *srq; struct ib_srq *srq;
struct ib_rwq_ind_table *ind_tbl;
int ret; int ret;
WARN_ON_ONCE(qp->mrs_used > 0); WARN_ON_ONCE(qp->mrs_used > 0);
...@@ -1293,6 +1305,7 @@ int ib_destroy_qp(struct ib_qp *qp) ...@@ -1293,6 +1305,7 @@ int ib_destroy_qp(struct ib_qp *qp)
scq = qp->send_cq; scq = qp->send_cq;
rcq = qp->recv_cq; rcq = qp->recv_cq;
srq = qp->srq; srq = qp->srq;
ind_tbl = qp->rwq_ind_tbl;
if (!qp->uobject) if (!qp->uobject)
rdma_rw_cleanup_mrs(qp); rdma_rw_cleanup_mrs(qp);
...@@ -1307,6 +1320,8 @@ int ib_destroy_qp(struct ib_qp *qp) ...@@ -1307,6 +1320,8 @@ int ib_destroy_qp(struct ib_qp *qp)
atomic_dec(&rcq->usecnt); atomic_dec(&rcq->usecnt);
if (srq) if (srq)
atomic_dec(&srq->usecnt); atomic_dec(&srq->usecnt);
if (ind_tbl)
atomic_dec(&ind_tbl->usecnt);
} }
return ret; return ret;
...@@ -1554,6 +1569,150 @@ int ib_dealloc_xrcd(struct ib_xrcd *xrcd) ...@@ -1554,6 +1569,150 @@ int ib_dealloc_xrcd(struct ib_xrcd *xrcd)
} }
EXPORT_SYMBOL(ib_dealloc_xrcd); EXPORT_SYMBOL(ib_dealloc_xrcd);
/**
* ib_create_wq - Creates a WQ associated with the specified protection
* domain.
* @pd: The protection domain associated with the WQ.
* @wq_init_attr: A list of initial attributes required to create the
* WQ. If WQ creation succeeds, then the attributes are updated to
* the actual capabilities of the created WQ.
*
* wq_init_attr->max_wr and wq_init_attr->max_sge determine
* the requested size of the WQ, and set to the actual values allocated
* on return.
* If ib_create_wq() succeeds, then max_wr and max_sge will always be
* at least as large as the requested values.
*/
struct ib_wq *ib_create_wq(struct ib_pd *pd,
struct ib_wq_init_attr *wq_attr)
{
struct ib_wq *wq;
if (!pd->device->create_wq)
return ERR_PTR(-ENOSYS);
wq = pd->device->create_wq(pd, wq_attr, NULL);
if (!IS_ERR(wq)) {
wq->event_handler = wq_attr->event_handler;
wq->wq_context = wq_attr->wq_context;
wq->wq_type = wq_attr->wq_type;
wq->cq = wq_attr->cq;
wq->device = pd->device;
wq->pd = pd;
wq->uobject = NULL;
atomic_inc(&pd->usecnt);
atomic_inc(&wq_attr->cq->usecnt);
atomic_set(&wq->usecnt, 0);
}
return wq;
}
EXPORT_SYMBOL(ib_create_wq);
/**
* ib_destroy_wq - Destroys the specified WQ.
* @wq: The WQ to destroy.
*/
int ib_destroy_wq(struct ib_wq *wq)
{
int err;
struct ib_cq *cq = wq->cq;
struct ib_pd *pd = wq->pd;
if (atomic_read(&wq->usecnt))
return -EBUSY;
err = wq->device->destroy_wq(wq);
if (!err) {
atomic_dec(&pd->usecnt);
atomic_dec(&cq->usecnt);
}
return err;
}
EXPORT_SYMBOL(ib_destroy_wq);
/**
* ib_modify_wq - Modifies the specified WQ.
* @wq: The WQ to modify.
* @wq_attr: On input, specifies the WQ attributes to modify.
* @wq_attr_mask: A bit-mask used to specify which attributes of the WQ
* are being modified.
* On output, the current values of selected WQ attributes are returned.
*/
int ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *wq_attr,
u32 wq_attr_mask)
{
int err;
if (!wq->device->modify_wq)
return -ENOSYS;
err = wq->device->modify_wq(wq, wq_attr, wq_attr_mask, NULL);
return err;
}
EXPORT_SYMBOL(ib_modify_wq);
/*
* ib_create_rwq_ind_table - Creates a RQ Indirection Table.
* @device: The device on which to create the rwq indirection table.
* @ib_rwq_ind_table_init_attr: A list of initial attributes required to
* create the Indirection Table.
*
* Note: The life time of ib_rwq_ind_table_init_attr->ind_tbl is not less
* than the created ib_rwq_ind_table object and the caller is responsible
* for its memory allocation/free.
*/
struct ib_rwq_ind_table *ib_create_rwq_ind_table(struct ib_device *device,
struct ib_rwq_ind_table_init_attr *init_attr)
{
struct ib_rwq_ind_table *rwq_ind_table;
int i;
u32 table_size;
if (!device->create_rwq_ind_table)
return ERR_PTR(-ENOSYS);
table_size = (1 << init_attr->log_ind_tbl_size);
rwq_ind_table = device->create_rwq_ind_table(device,
init_attr, NULL);
if (IS_ERR(rwq_ind_table))
return rwq_ind_table;
rwq_ind_table->ind_tbl = init_attr->ind_tbl;
rwq_ind_table->log_ind_tbl_size = init_attr->log_ind_tbl_size;
rwq_ind_table->device = device;
rwq_ind_table->uobject = NULL;
atomic_set(&rwq_ind_table->usecnt, 0);
for (i = 0; i < table_size; i++)
atomic_inc(&rwq_ind_table->ind_tbl[i]->usecnt);
return rwq_ind_table;
}
EXPORT_SYMBOL(ib_create_rwq_ind_table);
/*
* ib_destroy_rwq_ind_table - Destroys the specified Indirection Table.
* @wq_ind_table: The Indirection Table to destroy.
*/
int ib_destroy_rwq_ind_table(struct ib_rwq_ind_table *rwq_ind_table)
{
int err, i;
u32 table_size = (1 << rwq_ind_table->log_ind_tbl_size);
struct ib_wq **ind_tbl = rwq_ind_table->ind_tbl;
if (atomic_read(&rwq_ind_table->usecnt))
return -EBUSY;
err = rwq_ind_table->device->destroy_rwq_ind_table(rwq_ind_table);
if (!err) {
for (i = 0; i < table_size; i++)
atomic_dec(&ind_tbl[i]->usecnt);
}
return err;
}
EXPORT_SYMBOL(ib_destroy_rwq_ind_table);
struct ib_flow *ib_create_flow(struct ib_qp *qp, struct ib_flow *ib_create_flow(struct ib_qp *qp,
struct ib_flow_attr *flow_attr, struct ib_flow_attr *flow_attr,
int domain) int domain)
......
...@@ -1183,18 +1183,6 @@ static ssize_t show_rev(struct device *dev, struct device_attribute *attr, ...@@ -1183,18 +1183,6 @@ static ssize_t show_rev(struct device *dev, struct device_attribute *attr,
return sprintf(buf, "%d\n", iwch_dev->rdev.t3cdev_p->type); return sprintf(buf, "%d\n", iwch_dev->rdev.t3cdev_p->type);
} }
static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr, char *buf)
{
struct iwch_dev *iwch_dev = container_of(dev, struct iwch_dev,
ibdev.dev);
struct ethtool_drvinfo info;
struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev;
PDBG("%s dev 0x%p\n", __func__, dev);
lldev->ethtool_ops->get_drvinfo(lldev, &info);
return sprintf(buf, "%s\n", info.fw_version);
}
static ssize_t show_hca(struct device *dev, struct device_attribute *attr, static ssize_t show_hca(struct device *dev, struct device_attribute *attr,
char *buf) char *buf)
{ {
...@@ -1334,13 +1322,11 @@ static int iwch_get_mib(struct ib_device *ibdev, struct rdma_hw_stats *stats, ...@@ -1334,13 +1322,11 @@ static int iwch_get_mib(struct ib_device *ibdev, struct rdma_hw_stats *stats,
} }
static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL); static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
static DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);
static DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL); static DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL);
static DEVICE_ATTR(board_id, S_IRUGO, show_board, NULL); static DEVICE_ATTR(board_id, S_IRUGO, show_board, NULL);
static struct device_attribute *iwch_class_attributes[] = { static struct device_attribute *iwch_class_attributes[] = {
&dev_attr_hw_rev, &dev_attr_hw_rev,
&dev_attr_fw_ver,
&dev_attr_hca_type, &dev_attr_hca_type,
&dev_attr_board_id, &dev_attr_board_id,
}; };
...@@ -1362,6 +1348,18 @@ static int iwch_port_immutable(struct ib_device *ibdev, u8 port_num, ...@@ -1362,6 +1348,18 @@ static int iwch_port_immutable(struct ib_device *ibdev, u8 port_num,
return 0; return 0;
} }
static void get_dev_fw_ver_str(struct ib_device *ibdev, char *str,
size_t str_len)
{
struct iwch_dev *iwch_dev = to_iwch_dev(ibdev);
struct ethtool_drvinfo info;
struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev;
PDBG("%s dev 0x%p\n", __func__, iwch_dev);
lldev->ethtool_ops->get_drvinfo(lldev, &info);
snprintf(str, str_len, "%s", info.fw_version);
}
int iwch_register_device(struct iwch_dev *dev) int iwch_register_device(struct iwch_dev *dev)
{ {
int ret; int ret;
...@@ -1437,6 +1435,7 @@ int iwch_register_device(struct iwch_dev *dev) ...@@ -1437,6 +1435,7 @@ int iwch_register_device(struct iwch_dev *dev)
dev->ibdev.get_hw_stats = iwch_get_mib; dev->ibdev.get_hw_stats = iwch_get_mib;
dev->ibdev.uverbs_abi_ver = IWCH_UVERBS_ABI_VERSION; dev->ibdev.uverbs_abi_ver = IWCH_UVERBS_ABI_VERSION;
dev->ibdev.get_port_immutable = iwch_port_immutable; dev->ibdev.get_port_immutable = iwch_port_immutable;
dev->ibdev.get_dev_fw_str = get_dev_fw_ver_str;
dev->ibdev.iwcm = kmalloc(sizeof(struct iw_cm_verbs), GFP_KERNEL); dev->ibdev.iwcm = kmalloc(sizeof(struct iw_cm_verbs), GFP_KERNEL);
if (!dev->ibdev.iwcm) if (!dev->ibdev.iwcm)
......
This diff is collapsed.
...@@ -33,19 +33,15 @@ ...@@ -33,19 +33,15 @@
#include "iw_cxgb4.h" #include "iw_cxgb4.h"
static int destroy_cq(struct c4iw_rdev *rdev, struct t4_cq *cq, static int destroy_cq(struct c4iw_rdev *rdev, struct t4_cq *cq,
struct c4iw_dev_ucontext *uctx) struct c4iw_dev_ucontext *uctx, struct sk_buff *skb)
{ {
struct fw_ri_res_wr *res_wr; struct fw_ri_res_wr *res_wr;
struct fw_ri_res *res; struct fw_ri_res *res;
int wr_len; int wr_len;
struct c4iw_wr_wait wr_wait; struct c4iw_wr_wait wr_wait;
struct sk_buff *skb;
int ret; int ret;
wr_len = sizeof *res_wr + sizeof *res; wr_len = sizeof *res_wr + sizeof *res;
skb = alloc_skb(wr_len, GFP_KERNEL);
if (!skb)
return -ENOMEM;
set_wr_txq(skb, CPL_PRIORITY_CONTROL, 0); set_wr_txq(skb, CPL_PRIORITY_CONTROL, 0);
res_wr = (struct fw_ri_res_wr *)__skb_put(skb, wr_len); res_wr = (struct fw_ri_res_wr *)__skb_put(skb, wr_len);
...@@ -863,7 +859,9 @@ int c4iw_destroy_cq(struct ib_cq *ib_cq) ...@@ -863,7 +859,9 @@ int c4iw_destroy_cq(struct ib_cq *ib_cq)
ucontext = ib_cq->uobject ? to_c4iw_ucontext(ib_cq->uobject->context) ucontext = ib_cq->uobject ? to_c4iw_ucontext(ib_cq->uobject->context)
: NULL; : NULL;
destroy_cq(&chp->rhp->rdev, &chp->cq, destroy_cq(&chp->rhp->rdev, &chp->cq,
ucontext ? &ucontext->uctx : &chp->cq.rdev->uctx); ucontext ? &ucontext->uctx : &chp->cq.rdev->uctx,
chp->destroy_skb);
chp->destroy_skb = NULL;
kfree(chp); kfree(chp);
return 0; return 0;
} }
...@@ -879,7 +877,7 @@ struct ib_cq *c4iw_create_cq(struct ib_device *ibdev, ...@@ -879,7 +877,7 @@ struct ib_cq *c4iw_create_cq(struct ib_device *ibdev,
struct c4iw_cq *chp; struct c4iw_cq *chp;
struct c4iw_create_cq_resp uresp; struct c4iw_create_cq_resp uresp;
struct c4iw_ucontext *ucontext = NULL; struct c4iw_ucontext *ucontext = NULL;
int ret; int ret, wr_len;
size_t memsize, hwentries; size_t memsize, hwentries;
struct c4iw_mm_entry *mm, *mm2; struct c4iw_mm_entry *mm, *mm2;
...@@ -896,6 +894,13 @@ struct ib_cq *c4iw_create_cq(struct ib_device *ibdev, ...@@ -896,6 +894,13 @@ struct ib_cq *c4iw_create_cq(struct ib_device *ibdev,
if (!chp) if (!chp)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
wr_len = sizeof(struct fw_ri_res_wr) + sizeof(struct fw_ri_res);
chp->destroy_skb = alloc_skb(wr_len, GFP_KERNEL);
if (!chp->destroy_skb) {
ret = -ENOMEM;
goto err1;
}
if (ib_context) if (ib_context)
ucontext = to_c4iw_ucontext(ib_context); ucontext = to_c4iw_ucontext(ib_context);
...@@ -936,7 +941,7 @@ struct ib_cq *c4iw_create_cq(struct ib_device *ibdev, ...@@ -936,7 +941,7 @@ struct ib_cq *c4iw_create_cq(struct ib_device *ibdev,
ret = create_cq(&rhp->rdev, &chp->cq, ret = create_cq(&rhp->rdev, &chp->cq,
ucontext ? &ucontext->uctx : &rhp->rdev.uctx); ucontext ? &ucontext->uctx : &rhp->rdev.uctx);
if (ret) if (ret)
goto err1; goto err2;
chp->rhp = rhp; chp->rhp = rhp;
chp->cq.size--; /* status page */ chp->cq.size--; /* status page */
...@@ -947,15 +952,15 @@ struct ib_cq *c4iw_create_cq(struct ib_device *ibdev, ...@@ -947,15 +952,15 @@ struct ib_cq *c4iw_create_cq(struct ib_device *ibdev,
init_waitqueue_head(&chp->wait); init_waitqueue_head(&chp->wait);
ret = insert_handle(rhp, &rhp->cqidr, chp, chp->cq.cqid); ret = insert_handle(rhp, &rhp->cqidr, chp, chp->cq.cqid);
if (ret) if (ret)
goto err2; goto err3;
if (ucontext) { if (ucontext) {
mm = kmalloc(sizeof *mm, GFP_KERNEL); mm = kmalloc(sizeof *mm, GFP_KERNEL);
if (!mm) if (!mm)
goto err3; goto err4;
mm2 = kmalloc(sizeof *mm2, GFP_KERNEL); mm2 = kmalloc(sizeof *mm2, GFP_KERNEL);
if (!mm2) if (!mm2)
goto err4; goto err5;
uresp.qid_mask = rhp->rdev.cqmask; uresp.qid_mask = rhp->rdev.cqmask;
uresp.cqid = chp->cq.cqid; uresp.cqid = chp->cq.cqid;
...@@ -970,7 +975,7 @@ struct ib_cq *c4iw_create_cq(struct ib_device *ibdev, ...@@ -970,7 +975,7 @@ struct ib_cq *c4iw_create_cq(struct ib_device *ibdev,
ret = ib_copy_to_udata(udata, &uresp, ret = ib_copy_to_udata(udata, &uresp,
sizeof(uresp) - sizeof(uresp.reserved)); sizeof(uresp) - sizeof(uresp.reserved));
if (ret) if (ret)
goto err5; goto err6;
mm->key = uresp.key; mm->key = uresp.key;
mm->addr = virt_to_phys(chp->cq.queue); mm->addr = virt_to_phys(chp->cq.queue);
...@@ -986,15 +991,18 @@ struct ib_cq *c4iw_create_cq(struct ib_device *ibdev, ...@@ -986,15 +991,18 @@ struct ib_cq *c4iw_create_cq(struct ib_device *ibdev,
__func__, chp->cq.cqid, chp, chp->cq.size, __func__, chp->cq.cqid, chp, chp->cq.size,
chp->cq.memsize, (unsigned long long) chp->cq.dma_addr); chp->cq.memsize, (unsigned long long) chp->cq.dma_addr);
return &chp->ibcq; return &chp->ibcq;
err5: err6:
kfree(mm2); kfree(mm2);
err4: err5:
kfree(mm); kfree(mm);
err3: err4:
remove_handle(rhp, &rhp->cqidr, chp->cq.cqid); remove_handle(rhp, &rhp->cqidr, chp->cq.cqid);
err2: err3:
destroy_cq(&chp->rhp->rdev, &chp->cq, destroy_cq(&chp->rhp->rdev, &chp->cq,
ucontext ? &ucontext->uctx : &rhp->rdev.uctx); ucontext ? &ucontext->uctx : &rhp->rdev.uctx,
chp->destroy_skb);
err2:
kfree_skb(chp->destroy_skb);
err1: err1:
kfree(chp); kfree(chp);
return ERR_PTR(ret); return ERR_PTR(ret);
......
...@@ -317,7 +317,7 @@ static int qp_open(struct inode *inode, struct file *file) ...@@ -317,7 +317,7 @@ static int qp_open(struct inode *inode, struct file *file)
idr_for_each(&qpd->devp->qpidr, count_idrs, &count); idr_for_each(&qpd->devp->qpidr, count_idrs, &count);
spin_unlock_irq(&qpd->devp->lock); spin_unlock_irq(&qpd->devp->lock);
qpd->bufsize = count * 128; qpd->bufsize = count * 180;
qpd->buf = vmalloc(qpd->bufsize); qpd->buf = vmalloc(qpd->bufsize);
if (!qpd->buf) { if (!qpd->buf) {
kfree(qpd); kfree(qpd);
......
...@@ -384,6 +384,7 @@ struct c4iw_mr { ...@@ -384,6 +384,7 @@ struct c4iw_mr {
struct ib_mr ibmr; struct ib_mr ibmr;
struct ib_umem *umem; struct ib_umem *umem;
struct c4iw_dev *rhp; struct c4iw_dev *rhp;
struct sk_buff *dereg_skb;
u64 kva; u64 kva;
struct tpt_attributes attr; struct tpt_attributes attr;
u64 *mpl; u64 *mpl;
...@@ -400,6 +401,7 @@ static inline struct c4iw_mr *to_c4iw_mr(struct ib_mr *ibmr) ...@@ -400,6 +401,7 @@ static inline struct c4iw_mr *to_c4iw_mr(struct ib_mr *ibmr)
struct c4iw_mw { struct c4iw_mw {
struct ib_mw ibmw; struct ib_mw ibmw;
struct c4iw_dev *rhp; struct c4iw_dev *rhp;
struct sk_buff *dereg_skb;
u64 kva; u64 kva;
struct tpt_attributes attr; struct tpt_attributes attr;
}; };
...@@ -412,6 +414,7 @@ static inline struct c4iw_mw *to_c4iw_mw(struct ib_mw *ibmw) ...@@ -412,6 +414,7 @@ static inline struct c4iw_mw *to_c4iw_mw(struct ib_mw *ibmw)
struct c4iw_cq { struct c4iw_cq {
struct ib_cq ibcq; struct ib_cq ibcq;
struct c4iw_dev *rhp; struct c4iw_dev *rhp;
struct sk_buff *destroy_skb;
struct t4_cq cq; struct t4_cq cq;
spinlock_t lock; spinlock_t lock;
spinlock_t comp_handler_lock; spinlock_t comp_handler_lock;
...@@ -789,10 +792,29 @@ enum c4iw_ep_history { ...@@ -789,10 +792,29 @@ enum c4iw_ep_history {
CM_ID_DEREFED = 28, CM_ID_DEREFED = 28,
}; };
enum conn_pre_alloc_buffers {
CN_ABORT_REQ_BUF,
CN_ABORT_RPL_BUF,
CN_CLOSE_CON_REQ_BUF,
CN_DESTROY_BUF,
CN_FLOWC_BUF,
CN_MAX_CON_BUF
};
#define FLOWC_LEN 80
union cpl_wr_size {
struct cpl_abort_req abrt_req;
struct cpl_abort_rpl abrt_rpl;
struct fw_ri_wr ri_req;
struct cpl_close_con_req close_req;
char flowc_buf[FLOWC_LEN];
};
struct c4iw_ep_common { struct c4iw_ep_common {
struct iw_cm_id *cm_id; struct iw_cm_id *cm_id;
struct c4iw_qp *qp; struct c4iw_qp *qp;
struct c4iw_dev *dev; struct c4iw_dev *dev;
struct sk_buff_head ep_skb_list;
enum c4iw_ep_state state; enum c4iw_ep_state state;
struct kref kref; struct kref kref;
struct mutex mutex; struct mutex mutex;
......
This diff is collapsed.
...@@ -409,20 +409,6 @@ static ssize_t show_rev(struct device *dev, struct device_attribute *attr, ...@@ -409,20 +409,6 @@ static ssize_t show_rev(struct device *dev, struct device_attribute *attr,
CHELSIO_CHIP_RELEASE(c4iw_dev->rdev.lldi.adapter_type)); CHELSIO_CHIP_RELEASE(c4iw_dev->rdev.lldi.adapter_type));
} }
static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct c4iw_dev *c4iw_dev = container_of(dev, struct c4iw_dev,
ibdev.dev);
PDBG("%s dev 0x%p\n", __func__, dev);
return sprintf(buf, "%u.%u.%u.%u\n",
FW_HDR_FW_VER_MAJOR_G(c4iw_dev->rdev.lldi.fw_vers),
FW_HDR_FW_VER_MINOR_G(c4iw_dev->rdev.lldi.fw_vers),
FW_HDR_FW_VER_MICRO_G(c4iw_dev->rdev.lldi.fw_vers),
FW_HDR_FW_VER_BUILD_G(c4iw_dev->rdev.lldi.fw_vers));
}
static ssize_t show_hca(struct device *dev, struct device_attribute *attr, static ssize_t show_hca(struct device *dev, struct device_attribute *attr,
char *buf) char *buf)
{ {
...@@ -502,13 +488,11 @@ static int c4iw_get_mib(struct ib_device *ibdev, ...@@ -502,13 +488,11 @@ static int c4iw_get_mib(struct ib_device *ibdev,
} }
static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL); static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
static DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);
static DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL); static DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL);
static DEVICE_ATTR(board_id, S_IRUGO, show_board, NULL); static DEVICE_ATTR(board_id, S_IRUGO, show_board, NULL);
static struct device_attribute *c4iw_class_attributes[] = { static struct device_attribute *c4iw_class_attributes[] = {
&dev_attr_hw_rev, &dev_attr_hw_rev,
&dev_attr_fw_ver,
&dev_attr_hca_type, &dev_attr_hca_type,
&dev_attr_board_id, &dev_attr_board_id,
}; };
...@@ -530,6 +514,20 @@ static int c4iw_port_immutable(struct ib_device *ibdev, u8 port_num, ...@@ -530,6 +514,20 @@ static int c4iw_port_immutable(struct ib_device *ibdev, u8 port_num,
return 0; return 0;
} }
static void get_dev_fw_str(struct ib_device *dev, char *str,
size_t str_len)
{
struct c4iw_dev *c4iw_dev = container_of(dev, struct c4iw_dev,
ibdev);
PDBG("%s dev 0x%p\n", __func__, dev);
snprintf(str, str_len, "%u.%u.%u.%u",
FW_HDR_FW_VER_MAJOR_G(c4iw_dev->rdev.lldi.fw_vers),
FW_HDR_FW_VER_MINOR_G(c4iw_dev->rdev.lldi.fw_vers),
FW_HDR_FW_VER_MICRO_G(c4iw_dev->rdev.lldi.fw_vers),
FW_HDR_FW_VER_BUILD_G(c4iw_dev->rdev.lldi.fw_vers));
}
int c4iw_register_device(struct c4iw_dev *dev) int c4iw_register_device(struct c4iw_dev *dev)
{ {
int ret; int ret;
...@@ -605,6 +603,7 @@ int c4iw_register_device(struct c4iw_dev *dev) ...@@ -605,6 +603,7 @@ int c4iw_register_device(struct c4iw_dev *dev)
dev->ibdev.get_hw_stats = c4iw_get_mib; dev->ibdev.get_hw_stats = c4iw_get_mib;
dev->ibdev.uverbs_abi_ver = C4IW_UVERBS_ABI_VERSION; dev->ibdev.uverbs_abi_ver = C4IW_UVERBS_ABI_VERSION;
dev->ibdev.get_port_immutable = c4iw_port_immutable; dev->ibdev.get_port_immutable = c4iw_port_immutable;
dev->ibdev.get_dev_fw_str = get_dev_fw_str;
dev->ibdev.drain_sq = c4iw_drain_sq; dev->ibdev.drain_sq = c4iw_drain_sq;
dev->ibdev.drain_rq = c4iw_drain_rq; dev->ibdev.drain_rq = c4iw_drain_rq;
......
...@@ -1081,9 +1081,10 @@ static void post_terminate(struct c4iw_qp *qhp, struct t4_cqe *err_cqe, ...@@ -1081,9 +1081,10 @@ static void post_terminate(struct c4iw_qp *qhp, struct t4_cqe *err_cqe,
PDBG("%s qhp %p qid 0x%x tid %u\n", __func__, qhp, qhp->wq.sq.qid, PDBG("%s qhp %p qid 0x%x tid %u\n", __func__, qhp, qhp->wq.sq.qid,
qhp->ep->hwtid); qhp->ep->hwtid);
skb = alloc_skb(sizeof *wqe, gfp); skb = skb_dequeue(&qhp->ep->com.ep_skb_list);
if (!skb) if (WARN_ON(!skb))
return; return;
set_wr_txq(skb, CPL_PRIORITY_DATA, qhp->ep->txq_idx); set_wr_txq(skb, CPL_PRIORITY_DATA, qhp->ep->txq_idx);
wqe = (struct fw_ri_wr *)__skb_put(skb, sizeof(*wqe)); wqe = (struct fw_ri_wr *)__skb_put(skb, sizeof(*wqe));
...@@ -1202,9 +1203,10 @@ static int rdma_fini(struct c4iw_dev *rhp, struct c4iw_qp *qhp, ...@@ -1202,9 +1203,10 @@ static int rdma_fini(struct c4iw_dev *rhp, struct c4iw_qp *qhp,
PDBG("%s qhp %p qid 0x%x tid %u\n", __func__, qhp, qhp->wq.sq.qid, PDBG("%s qhp %p qid 0x%x tid %u\n", __func__, qhp, qhp->wq.sq.qid,
ep->hwtid); ep->hwtid);
skb = alloc_skb(sizeof *wqe, GFP_KERNEL); skb = skb_dequeue(&ep->com.ep_skb_list);
if (!skb) if (WARN_ON(!skb))
return -ENOMEM; return -ENOMEM;
set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx); set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx);
wqe = (struct fw_ri_wr *)__skb_put(skb, sizeof(*wqe)); wqe = (struct fw_ri_wr *)__skb_put(skb, sizeof(*wqe));
......
...@@ -1174,6 +1174,8 @@ struct hfi1_devdata { ...@@ -1174,6 +1174,8 @@ struct hfi1_devdata {
/* 8051 firmware version helper */ /* 8051 firmware version helper */
#define dc8051_ver(a, b) ((a) << 8 | (b)) #define dc8051_ver(a, b) ((a) << 8 | (b))
#define dc8051_ver_maj(a) ((a & 0xff00) >> 8)
#define dc8051_ver_min(a) (a & 0x00ff)
/* f_put_tid types */ /* f_put_tid types */
#define PT_EXPECTED 0 #define PT_EXPECTED 0
......
...@@ -1291,9 +1291,12 @@ int hfi1_verbs_send(struct rvt_qp *qp, struct hfi1_pkt_state *ps) ...@@ -1291,9 +1291,12 @@ int hfi1_verbs_send(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
static void hfi1_fill_device_attr(struct hfi1_devdata *dd) static void hfi1_fill_device_attr(struct hfi1_devdata *dd)
{ {
struct rvt_dev_info *rdi = &dd->verbs_dev.rdi; struct rvt_dev_info *rdi = &dd->verbs_dev.rdi;
u16 ver = dd->dc8051_ver;
memset(&rdi->dparms.props, 0, sizeof(rdi->dparms.props)); memset(&rdi->dparms.props, 0, sizeof(rdi->dparms.props));
rdi->dparms.props.fw_ver = ((u64)(dc8051_ver_maj(ver)) << 16) |
(u64)dc8051_ver_min(ver);
rdi->dparms.props.device_cap_flags = IB_DEVICE_BAD_PKEY_CNTR | rdi->dparms.props.device_cap_flags = IB_DEVICE_BAD_PKEY_CNTR |
IB_DEVICE_BAD_QKEY_CNTR | IB_DEVICE_SHUTDOWN_PORT | IB_DEVICE_BAD_QKEY_CNTR | IB_DEVICE_SHUTDOWN_PORT |
IB_DEVICE_SYS_IMAGE_GUID | IB_DEVICE_RC_RNR_NAK_GEN | IB_DEVICE_SYS_IMAGE_GUID | IB_DEVICE_RC_RNR_NAK_GEN |
...@@ -1567,6 +1570,17 @@ static void init_ibport(struct hfi1_pportdata *ppd) ...@@ -1567,6 +1570,17 @@ static void init_ibport(struct hfi1_pportdata *ppd)
RCU_INIT_POINTER(ibp->rvp.qp[1], NULL); RCU_INIT_POINTER(ibp->rvp.qp[1], NULL);
} }
static void hfi1_get_dev_fw_str(struct ib_device *ibdev, char *str,
size_t str_len)
{
struct rvt_dev_info *rdi = ib_to_rvt(ibdev);
struct hfi1_ibdev *dev = dev_from_rdi(rdi);
u16 ver = dd_from_dev(dev)->dc8051_ver;
snprintf(str, str_len, "%u.%u", dc8051_ver_maj(ver),
dc8051_ver_min(ver));
}
/** /**
* hfi1_register_ib_device - register our device with the infiniband core * hfi1_register_ib_device - register our device with the infiniband core
* @dd: the device data structure * @dd: the device data structure
...@@ -1613,6 +1627,7 @@ int hfi1_register_ib_device(struct hfi1_devdata *dd) ...@@ -1613,6 +1627,7 @@ int hfi1_register_ib_device(struct hfi1_devdata *dd)
/* keep process mad in the driver */ /* keep process mad in the driver */
ibdev->process_mad = hfi1_process_mad; ibdev->process_mad = hfi1_process_mad;
ibdev->get_dev_fw_str = hfi1_get_dev_fw_str;
strncpy(ibdev->node_desc, init_utsname()->nodename, strncpy(ibdev->node_desc, init_utsname()->nodename,
sizeof(ibdev->node_desc)); sizeof(ibdev->node_desc));
......
...@@ -1972,18 +1972,6 @@ static ssize_t i40iw_show_rev(struct device *dev, ...@@ -1972,18 +1972,6 @@ static ssize_t i40iw_show_rev(struct device *dev,
return sprintf(buf, "%x\n", hw_rev); return sprintf(buf, "%x\n", hw_rev);
} }
/**
* i40iw_show_fw_ver
*/
static ssize_t i40iw_show_fw_ver(struct device *dev,
struct device_attribute *attr, char *buf)
{
u32 firmware_version = I40IW_FW_VERSION;
return sprintf(buf, "%u.%u\n", firmware_version,
(firmware_version & 0x000000ff));
}
/** /**
* i40iw_show_hca * i40iw_show_hca
*/ */
...@@ -2004,13 +1992,11 @@ static ssize_t i40iw_show_board(struct device *dev, ...@@ -2004,13 +1992,11 @@ static ssize_t i40iw_show_board(struct device *dev,
} }
static DEVICE_ATTR(hw_rev, S_IRUGO, i40iw_show_rev, NULL); static DEVICE_ATTR(hw_rev, S_IRUGO, i40iw_show_rev, NULL);
static DEVICE_ATTR(fw_ver, S_IRUGO, i40iw_show_fw_ver, NULL);
static DEVICE_ATTR(hca_type, S_IRUGO, i40iw_show_hca, NULL); static DEVICE_ATTR(hca_type, S_IRUGO, i40iw_show_hca, NULL);
static DEVICE_ATTR(board_id, S_IRUGO, i40iw_show_board, NULL); static DEVICE_ATTR(board_id, S_IRUGO, i40iw_show_board, NULL);
static struct device_attribute *i40iw_dev_attributes[] = { static struct device_attribute *i40iw_dev_attributes[] = {
&dev_attr_hw_rev, &dev_attr_hw_rev,
&dev_attr_fw_ver,
&dev_attr_hca_type, &dev_attr_hca_type,
&dev_attr_board_id &dev_attr_board_id
}; };
...@@ -2427,6 +2413,15 @@ static const char * const i40iw_hw_stat_names[] = { ...@@ -2427,6 +2413,15 @@ static const char * const i40iw_hw_stat_names[] = {
"iwRdmaInv" "iwRdmaInv"
}; };
static void i40iw_get_dev_fw_str(struct ib_device *dev, char *str,
size_t str_len)
{
u32 firmware_version = I40IW_FW_VERSION;
snprintf(str, str_len, "%u.%u", firmware_version,
(firmware_version & 0x000000ff));
}
/** /**
* i40iw_alloc_hw_stats - Allocate a hw stats structure * i40iw_alloc_hw_stats - Allocate a hw stats structure
* @ibdev: device pointer from stack * @ibdev: device pointer from stack
...@@ -2650,6 +2645,7 @@ static struct i40iw_ib_device *i40iw_init_rdma_device(struct i40iw_device *iwdev ...@@ -2650,6 +2645,7 @@ static struct i40iw_ib_device *i40iw_init_rdma_device(struct i40iw_device *iwdev
memcpy(iwibdev->ibdev.iwcm->ifname, netdev->name, memcpy(iwibdev->ibdev.iwcm->ifname, netdev->name,
sizeof(iwibdev->ibdev.iwcm->ifname)); sizeof(iwibdev->ibdev.iwcm->ifname));
iwibdev->ibdev.get_port_immutable = i40iw_port_immutable; iwibdev->ibdev.get_port_immutable = i40iw_port_immutable;
iwibdev->ibdev.get_dev_fw_str = i40iw_get_dev_fw_str;
iwibdev->ibdev.poll_cq = i40iw_poll_cq; iwibdev->ibdev.poll_cq = i40iw_poll_cq;
iwibdev->ibdev.req_notify_cq = i40iw_req_notify_cq; iwibdev->ibdev.req_notify_cq = i40iw_req_notify_cq;
iwibdev->ibdev.post_send = i40iw_post_send; iwibdev->ibdev.post_send = i40iw_post_send;
......
...@@ -2022,16 +2022,6 @@ static ssize_t show_hca(struct device *device, struct device_attribute *attr, ...@@ -2022,16 +2022,6 @@ static ssize_t show_hca(struct device *device, struct device_attribute *attr,
return sprintf(buf, "MT%d\n", dev->dev->persist->pdev->device); return sprintf(buf, "MT%d\n", dev->dev->persist->pdev->device);
} }
static ssize_t show_fw_ver(struct device *device, struct device_attribute *attr,
char *buf)
{
struct mlx4_ib_dev *dev =
container_of(device, struct mlx4_ib_dev, ib_dev.dev);
return sprintf(buf, "%d.%d.%d\n", (int) (dev->dev->caps.fw_ver >> 32),
(int) (dev->dev->caps.fw_ver >> 16) & 0xffff,
(int) dev->dev->caps.fw_ver & 0xffff);
}
static ssize_t show_rev(struct device *device, struct device_attribute *attr, static ssize_t show_rev(struct device *device, struct device_attribute *attr,
char *buf) char *buf)
{ {
...@@ -2050,13 +2040,11 @@ static ssize_t show_board(struct device *device, struct device_attribute *attr, ...@@ -2050,13 +2040,11 @@ static ssize_t show_board(struct device *device, struct device_attribute *attr,
} }
static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL); static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
static DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);
static DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL); static DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL);
static DEVICE_ATTR(board_id, S_IRUGO, show_board, NULL); static DEVICE_ATTR(board_id, S_IRUGO, show_board, NULL);
static struct device_attribute *mlx4_class_attributes[] = { static struct device_attribute *mlx4_class_attributes[] = {
&dev_attr_hw_rev, &dev_attr_hw_rev,
&dev_attr_fw_ver,
&dev_attr_hca_type, &dev_attr_hca_type,
&dev_attr_board_id &dev_attr_board_id
}; };
...@@ -2277,6 +2265,17 @@ static int mlx4_port_immutable(struct ib_device *ibdev, u8 port_num, ...@@ -2277,6 +2265,17 @@ static int mlx4_port_immutable(struct ib_device *ibdev, u8 port_num,
return 0; return 0;
} }
static void get_fw_ver_str(struct ib_device *device, char *str,
size_t str_len)
{
struct mlx4_ib_dev *dev =
container_of(device, struct mlx4_ib_dev, ib_dev);
snprintf(str, str_len, "%d.%d.%d",
(int) (dev->dev->caps.fw_ver >> 32),
(int) (dev->dev->caps.fw_ver >> 16) & 0xffff,
(int) dev->dev->caps.fw_ver & 0xffff);
}
static void *mlx4_ib_add(struct mlx4_dev *dev) static void *mlx4_ib_add(struct mlx4_dev *dev)
{ {
struct mlx4_ib_dev *ibdev; struct mlx4_ib_dev *ibdev;
...@@ -2410,6 +2409,7 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) ...@@ -2410,6 +2409,7 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
ibdev->ib_dev.detach_mcast = mlx4_ib_mcg_detach; ibdev->ib_dev.detach_mcast = mlx4_ib_mcg_detach;
ibdev->ib_dev.process_mad = mlx4_ib_process_mad; ibdev->ib_dev.process_mad = mlx4_ib_process_mad;
ibdev->ib_dev.get_port_immutable = mlx4_port_immutable; ibdev->ib_dev.get_port_immutable = mlx4_port_immutable;
ibdev->ib_dev.get_dev_fw_str = get_fw_ver_str;
ibdev->ib_dev.disassociate_ucontext = mlx4_ib_disassociate_ucontext; ibdev->ib_dev.disassociate_ucontext = mlx4_ib_disassociate_ucontext;
if (!mlx4_is_slave(ibdev->dev)) { if (!mlx4_is_slave(ibdev->dev)) {
......
...@@ -424,6 +424,83 @@ static void get_sig_err_item(struct mlx5_sig_err_cqe *cqe, ...@@ -424,6 +424,83 @@ static void get_sig_err_item(struct mlx5_sig_err_cqe *cqe,
item->key = be32_to_cpu(cqe->mkey); item->key = be32_to_cpu(cqe->mkey);
} }
static void sw_send_comp(struct mlx5_ib_qp *qp, int num_entries,
struct ib_wc *wc, int *npolled)
{
struct mlx5_ib_wq *wq;
unsigned int cur;
unsigned int idx;
int np;
int i;
wq = &qp->sq;
cur = wq->head - wq->tail;
np = *npolled;
if (cur == 0)
return;
for (i = 0; i < cur && np < num_entries; i++) {
idx = wq->last_poll & (wq->wqe_cnt - 1);
wc->wr_id = wq->wrid[idx];
wc->status = IB_WC_WR_FLUSH_ERR;
wc->vendor_err = MLX5_CQE_SYNDROME_WR_FLUSH_ERR;
wq->tail++;
np++;
wc->qp = &qp->ibqp;
wc++;
wq->last_poll = wq->w_list[idx].next;
}
*npolled = np;
}
static void sw_recv_comp(struct mlx5_ib_qp *qp, int num_entries,
struct ib_wc *wc, int *npolled)
{
struct mlx5_ib_wq *wq;
unsigned int cur;
int np;
int i;
wq = &qp->rq;
cur = wq->head - wq->tail;
np = *npolled;
if (cur == 0)
return;
for (i = 0; i < cur && np < num_entries; i++) {
wc->wr_id = wq->wrid[wq->tail & (wq->wqe_cnt - 1)];
wc->status = IB_WC_WR_FLUSH_ERR;
wc->vendor_err = MLX5_CQE_SYNDROME_WR_FLUSH_ERR;
wq->tail++;
np++;
wc->qp = &qp->ibqp;
wc++;
}
*npolled = np;
}
static void mlx5_ib_poll_sw_comp(struct mlx5_ib_cq *cq, int num_entries,
struct ib_wc *wc, int *npolled)
{
struct mlx5_ib_qp *qp;
*npolled = 0;
/* Find uncompleted WQEs belonging to that cq and retrun mmics ones */
list_for_each_entry(qp, &cq->list_send_qp, cq_send_list) {
sw_send_comp(qp, num_entries, wc + *npolled, npolled);
if (*npolled >= num_entries)
return;
}
list_for_each_entry(qp, &cq->list_recv_qp, cq_recv_list) {
sw_recv_comp(qp, num_entries, wc + *npolled, npolled);
if (*npolled >= num_entries)
return;
}
}
static int mlx5_poll_one(struct mlx5_ib_cq *cq, static int mlx5_poll_one(struct mlx5_ib_cq *cq,
struct mlx5_ib_qp **cur_qp, struct mlx5_ib_qp **cur_qp,
struct ib_wc *wc) struct ib_wc *wc)
...@@ -594,12 +671,18 @@ int mlx5_ib_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc) ...@@ -594,12 +671,18 @@ int mlx5_ib_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc)
{ {
struct mlx5_ib_cq *cq = to_mcq(ibcq); struct mlx5_ib_cq *cq = to_mcq(ibcq);
struct mlx5_ib_qp *cur_qp = NULL; struct mlx5_ib_qp *cur_qp = NULL;
struct mlx5_ib_dev *dev = to_mdev(cq->ibcq.device);
struct mlx5_core_dev *mdev = dev->mdev;
unsigned long flags; unsigned long flags;
int soft_polled = 0; int soft_polled = 0;
int npolled; int npolled;
int err = 0; int err = 0;
spin_lock_irqsave(&cq->lock, flags); spin_lock_irqsave(&cq->lock, flags);
if (mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) {
mlx5_ib_poll_sw_comp(cq, num_entries, wc, &npolled);
goto out;
}
if (unlikely(!list_empty(&cq->wc_list))) if (unlikely(!list_empty(&cq->wc_list)))
soft_polled = poll_soft_wc(cq, num_entries, wc); soft_polled = poll_soft_wc(cq, num_entries, wc);
...@@ -612,7 +695,7 @@ int mlx5_ib_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc) ...@@ -612,7 +695,7 @@ int mlx5_ib_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc)
if (npolled) if (npolled)
mlx5_cq_set_ci(&cq->mcq); mlx5_cq_set_ci(&cq->mcq);
out:
spin_unlock_irqrestore(&cq->lock, flags); spin_unlock_irqrestore(&cq->lock, flags);
if (err == 0 || err == -EAGAIN) if (err == 0 || err == -EAGAIN)
...@@ -843,6 +926,8 @@ struct ib_cq *mlx5_ib_create_cq(struct ib_device *ibdev, ...@@ -843,6 +926,8 @@ struct ib_cq *mlx5_ib_create_cq(struct ib_device *ibdev,
cq->resize_buf = NULL; cq->resize_buf = NULL;
cq->resize_umem = NULL; cq->resize_umem = NULL;
cq->create_flags = attr->flags; cq->create_flags = attr->flags;
INIT_LIST_HEAD(&cq->list_send_qp);
INIT_LIST_HEAD(&cq->list_recv_qp);
if (context) { if (context) {
err = create_cq_user(dev, udata, context, cq, entries, err = create_cq_user(dev, udata, context, cq, entries,
......
This diff is collapsed.
...@@ -105,6 +105,11 @@ enum { ...@@ -105,6 +105,11 @@ enum {
MLX5_CQE_VERSION_V1, MLX5_CQE_VERSION_V1,
}; };
struct mlx5_ib_vma_private_data {
struct list_head list;
struct vm_area_struct *vma;
};
struct mlx5_ib_ucontext { struct mlx5_ib_ucontext {
struct ib_ucontext ibucontext; struct ib_ucontext ibucontext;
struct list_head db_page_list; struct list_head db_page_list;
...@@ -116,6 +121,7 @@ struct mlx5_ib_ucontext { ...@@ -116,6 +121,7 @@ struct mlx5_ib_ucontext {
u8 cqe_version; u8 cqe_version;
/* Transport Domain number */ /* Transport Domain number */
u32 tdn; u32 tdn;
struct list_head vma_private_list;
}; };
static inline struct mlx5_ib_ucontext *to_mucontext(struct ib_ucontext *ibucontext) static inline struct mlx5_ib_ucontext *to_mucontext(struct ib_ucontext *ibucontext)
...@@ -217,12 +223,41 @@ struct mlx5_ib_wq { ...@@ -217,12 +223,41 @@ struct mlx5_ib_wq {
void *qend; void *qend;
}; };
struct mlx5_ib_rwq {
struct ib_wq ibwq;
u32 rqn;
u32 rq_num_pas;
u32 log_rq_stride;
u32 log_rq_size;
u32 rq_page_offset;
u32 log_page_size;
struct ib_umem *umem;
size_t buf_size;
unsigned int page_shift;
int create_type;
struct mlx5_db db;
u32 user_index;
u32 wqe_count;
u32 wqe_shift;
int wq_sig;
};
enum { enum {
MLX5_QP_USER, MLX5_QP_USER,
MLX5_QP_KERNEL, MLX5_QP_KERNEL,
MLX5_QP_EMPTY MLX5_QP_EMPTY
}; };
enum {
MLX5_WQ_USER,
MLX5_WQ_KERNEL
};
struct mlx5_ib_rwq_ind_table {
struct ib_rwq_ind_table ib_rwq_ind_tbl;
u32 rqtn;
};
/* /*
* Connect-IB can trigger up to four concurrent pagefaults * Connect-IB can trigger up to four concurrent pagefaults
* per-QP. * per-QP.
...@@ -266,6 +301,10 @@ struct mlx5_ib_qp_trans { ...@@ -266,6 +301,10 @@ struct mlx5_ib_qp_trans {
u8 resp_depth; u8 resp_depth;
}; };
struct mlx5_ib_rss_qp {
u32 tirn;
};
struct mlx5_ib_rq { struct mlx5_ib_rq {
struct mlx5_ib_qp_base base; struct mlx5_ib_qp_base base;
struct mlx5_ib_wq *rq; struct mlx5_ib_wq *rq;
...@@ -294,6 +333,7 @@ struct mlx5_ib_qp { ...@@ -294,6 +333,7 @@ struct mlx5_ib_qp {
union { union {
struct mlx5_ib_qp_trans trans_qp; struct mlx5_ib_qp_trans trans_qp;
struct mlx5_ib_raw_packet_qp raw_packet_qp; struct mlx5_ib_raw_packet_qp raw_packet_qp;
struct mlx5_ib_rss_qp rss_qp;
}; };
struct mlx5_buf buf; struct mlx5_buf buf;
...@@ -340,6 +380,9 @@ struct mlx5_ib_qp { ...@@ -340,6 +380,9 @@ struct mlx5_ib_qp {
spinlock_t disable_page_faults_lock; spinlock_t disable_page_faults_lock;
struct mlx5_ib_pfault pagefaults[MLX5_IB_PAGEFAULT_CONTEXTS]; struct mlx5_ib_pfault pagefaults[MLX5_IB_PAGEFAULT_CONTEXTS];
#endif #endif
struct list_head qps_list;
struct list_head cq_recv_list;
struct list_head cq_send_list;
}; };
struct mlx5_ib_cq_buf { struct mlx5_ib_cq_buf {
...@@ -401,6 +444,8 @@ struct mlx5_ib_cq { ...@@ -401,6 +444,8 @@ struct mlx5_ib_cq {
struct mlx5_ib_cq_buf *resize_buf; struct mlx5_ib_cq_buf *resize_buf;
struct ib_umem *resize_umem; struct ib_umem *resize_umem;
int cqe_size; int cqe_size;
struct list_head list_send_qp;
struct list_head list_recv_qp;
u32 create_flags; u32 create_flags;
struct list_head wc_list; struct list_head wc_list;
enum ib_cq_notify_flags notify_flags; enum ib_cq_notify_flags notify_flags;
...@@ -546,6 +591,10 @@ struct mlx5_ib_resources { ...@@ -546,6 +591,10 @@ struct mlx5_ib_resources {
struct mutex mutex; struct mutex mutex;
}; };
struct mlx5_ib_port {
u16 q_cnt_id;
};
struct mlx5_roce { struct mlx5_roce {
/* Protect mlx5_ib_get_netdev from invoking dev_hold() with a NULL /* Protect mlx5_ib_get_netdev from invoking dev_hold() with a NULL
* netdev pointer * netdev pointer
...@@ -581,6 +630,11 @@ struct mlx5_ib_dev { ...@@ -581,6 +630,11 @@ struct mlx5_ib_dev {
struct srcu_struct mr_srcu; struct srcu_struct mr_srcu;
#endif #endif
struct mlx5_ib_flow_db flow_db; struct mlx5_ib_flow_db flow_db;
/* protect resources needed as part of reset flow */
spinlock_t reset_flow_resource_lock;
struct list_head qp_list;
/* Array with num_ports elements */
struct mlx5_ib_port *port;
}; };
static inline struct mlx5_ib_cq *to_mibcq(struct mlx5_core_cq *mcq) static inline struct mlx5_ib_cq *to_mibcq(struct mlx5_core_cq *mcq)
...@@ -628,6 +682,16 @@ static inline struct mlx5_ib_qp *to_mqp(struct ib_qp *ibqp) ...@@ -628,6 +682,16 @@ static inline struct mlx5_ib_qp *to_mqp(struct ib_qp *ibqp)
return container_of(ibqp, struct mlx5_ib_qp, ibqp); return container_of(ibqp, struct mlx5_ib_qp, ibqp);
} }
static inline struct mlx5_ib_rwq *to_mrwq(struct ib_wq *ibwq)
{
return container_of(ibwq, struct mlx5_ib_rwq, ibwq);
}
static inline struct mlx5_ib_rwq_ind_table *to_mrwq_ind_table(struct ib_rwq_ind_table *ib_rwq_ind_tbl)
{
return container_of(ib_rwq_ind_tbl, struct mlx5_ib_rwq_ind_table, ib_rwq_ind_tbl);
}
static inline struct mlx5_ib_srq *to_mibsrq(struct mlx5_core_srq *msrq) static inline struct mlx5_ib_srq *to_mibsrq(struct mlx5_core_srq *msrq)
{ {
return container_of(msrq, struct mlx5_ib_srq, msrq); return container_of(msrq, struct mlx5_ib_srq, msrq);
...@@ -762,6 +826,16 @@ int mlx5_mr_cache_cleanup(struct mlx5_ib_dev *dev); ...@@ -762,6 +826,16 @@ int mlx5_mr_cache_cleanup(struct mlx5_ib_dev *dev);
int mlx5_mr_ib_cont_pages(struct ib_umem *umem, u64 addr, int *count, int *shift); int mlx5_mr_ib_cont_pages(struct ib_umem *umem, u64 addr, int *count, int *shift);
int mlx5_ib_check_mr_status(struct ib_mr *ibmr, u32 check_mask, int mlx5_ib_check_mr_status(struct ib_mr *ibmr, u32 check_mask,
struct ib_mr_status *mr_status); struct ib_mr_status *mr_status);
struct ib_wq *mlx5_ib_create_wq(struct ib_pd *pd,
struct ib_wq_init_attr *init_attr,
struct ib_udata *udata);
int mlx5_ib_destroy_wq(struct ib_wq *wq);
int mlx5_ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *wq_attr,
u32 wq_attr_mask, struct ib_udata *udata);
struct ib_rwq_ind_table *mlx5_ib_create_rwq_ind_table(struct ib_device *device,
struct ib_rwq_ind_table_init_attr *init_attr,
struct ib_udata *udata);
int mlx5_ib_destroy_rwq_ind_table(struct ib_rwq_ind_table *wq_ind_table);
#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING #ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
extern struct workqueue_struct *mlx5_ib_page_fault_wq; extern struct workqueue_struct *mlx5_ib_page_fault_wq;
......
...@@ -1193,12 +1193,16 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, ...@@ -1193,12 +1193,16 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
static int unreg_umr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr) static int unreg_umr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr)
{ {
struct mlx5_core_dev *mdev = dev->mdev;
struct umr_common *umrc = &dev->umrc; struct umr_common *umrc = &dev->umrc;
struct mlx5_ib_umr_context umr_context; struct mlx5_ib_umr_context umr_context;
struct mlx5_umr_wr umrwr = {}; struct mlx5_umr_wr umrwr = {};
struct ib_send_wr *bad; struct ib_send_wr *bad;
int err; int err;
if (mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR)
return 0;
mlx5_ib_init_umr_context(&umr_context); mlx5_ib_init_umr_context(&umr_context);
umrwr.wr.wr_cqe = &umr_context.cqe; umrwr.wr.wr_cqe = &umr_context.cqe;
......
This diff is collapsed.
...@@ -74,14 +74,12 @@ static void mlx5_ib_srq_event(struct mlx5_core_srq *srq, enum mlx5_event type) ...@@ -74,14 +74,12 @@ static void mlx5_ib_srq_event(struct mlx5_core_srq *srq, enum mlx5_event type)
} }
static int create_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq, static int create_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq,
struct mlx5_create_srq_mbox_in **in, struct mlx5_srq_attr *in,
struct ib_udata *udata, int buf_size, int *inlen, struct ib_udata *udata, int buf_size)
int is_xrc)
{ {
struct mlx5_ib_dev *dev = to_mdev(pd->device); struct mlx5_ib_dev *dev = to_mdev(pd->device);
struct mlx5_ib_create_srq ucmd = {}; struct mlx5_ib_create_srq ucmd = {};
size_t ucmdlen; size_t ucmdlen;
void *xsrqc;
int err; int err;
int npages; int npages;
int page_shift; int page_shift;
...@@ -104,7 +102,7 @@ static int create_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq, ...@@ -104,7 +102,7 @@ static int create_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq,
udata->inlen - sizeof(ucmd))) udata->inlen - sizeof(ucmd)))
return -EINVAL; return -EINVAL;
if (is_xrc) { if (in->type == IB_SRQT_XRC) {
err = get_srq_user_index(to_mucontext(pd->uobject->context), err = get_srq_user_index(to_mucontext(pd->uobject->context),
&ucmd, udata->inlen, &uidx); &ucmd, udata->inlen, &uidx);
if (err) if (err)
...@@ -130,14 +128,13 @@ static int create_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq, ...@@ -130,14 +128,13 @@ static int create_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq,
goto err_umem; goto err_umem;
} }
*inlen = sizeof(**in) + sizeof(*(*in)->pas) * ncont; in->pas = mlx5_vzalloc(sizeof(*in->pas) * ncont);
*in = mlx5_vzalloc(*inlen); if (!in->pas) {
if (!(*in)) {
err = -ENOMEM; err = -ENOMEM;
goto err_umem; goto err_umem;
} }
mlx5_ib_populate_pas(dev, srq->umem, page_shift, (*in)->pas, 0); mlx5_ib_populate_pas(dev, srq->umem, page_shift, in->pas, 0);
err = mlx5_ib_db_map_user(to_mucontext(pd->uobject->context), err = mlx5_ib_db_map_user(to_mucontext(pd->uobject->context),
ucmd.db_addr, &srq->db); ucmd.db_addr, &srq->db);
...@@ -146,20 +143,16 @@ static int create_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq, ...@@ -146,20 +143,16 @@ static int create_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq,
goto err_in; goto err_in;
} }
(*in)->ctx.log_pg_sz = page_shift - MLX5_ADAPTER_PAGE_SHIFT; in->log_page_size = page_shift - MLX5_ADAPTER_PAGE_SHIFT;
(*in)->ctx.pgoff_cqn = cpu_to_be32(offset << 26); in->page_offset = offset;
if (MLX5_CAP_GEN(dev->mdev, cqe_version) == MLX5_CQE_VERSION_V1 &&
if ((MLX5_CAP_GEN(dev->mdev, cqe_version) == MLX5_CQE_VERSION_V1) && in->type == IB_SRQT_XRC)
is_xrc){ in->user_index = uidx;
xsrqc = MLX5_ADDR_OF(create_xrc_srq_in, *in,
xrc_srq_context_entry);
MLX5_SET(xrc_srqc, xsrqc, user_index, uidx);
}
return 0; return 0;
err_in: err_in:
kvfree(*in); kvfree(in->pas);
err_umem: err_umem:
ib_umem_release(srq->umem); ib_umem_release(srq->umem);
...@@ -168,15 +161,13 @@ static int create_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq, ...@@ -168,15 +161,13 @@ static int create_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq,
} }
static int create_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq, static int create_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq,
struct mlx5_create_srq_mbox_in **in, int buf_size, struct mlx5_srq_attr *in, int buf_size)
int *inlen, int is_xrc)
{ {
int err; int err;
int i; int i;
struct mlx5_wqe_srq_next_seg *next; struct mlx5_wqe_srq_next_seg *next;
int page_shift; int page_shift;
int npages; int npages;
void *xsrqc;
err = mlx5_db_alloc(dev->mdev, &srq->db); err = mlx5_db_alloc(dev->mdev, &srq->db);
if (err) { if (err) {
...@@ -204,13 +195,12 @@ static int create_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq, ...@@ -204,13 +195,12 @@ static int create_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq,
npages = DIV_ROUND_UP(srq->buf.npages, 1 << (page_shift - PAGE_SHIFT)); npages = DIV_ROUND_UP(srq->buf.npages, 1 << (page_shift - PAGE_SHIFT));
mlx5_ib_dbg(dev, "buf_size %d, page_shift %d, npages %d, calc npages %d\n", mlx5_ib_dbg(dev, "buf_size %d, page_shift %d, npages %d, calc npages %d\n",
buf_size, page_shift, srq->buf.npages, npages); buf_size, page_shift, srq->buf.npages, npages);
*inlen = sizeof(**in) + sizeof(*(*in)->pas) * npages; in->pas = mlx5_vzalloc(sizeof(*in->pas) * npages);
*in = mlx5_vzalloc(*inlen); if (!in->pas) {
if (!*in) {
err = -ENOMEM; err = -ENOMEM;
goto err_buf; goto err_buf;
} }
mlx5_fill_page_array(&srq->buf, (*in)->pas); mlx5_fill_page_array(&srq->buf, in->pas);
srq->wrid = kmalloc(srq->msrq.max * sizeof(u64), GFP_KERNEL); srq->wrid = kmalloc(srq->msrq.max * sizeof(u64), GFP_KERNEL);
if (!srq->wrid) { if (!srq->wrid) {
...@@ -221,20 +211,15 @@ static int create_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq, ...@@ -221,20 +211,15 @@ static int create_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq,
} }
srq->wq_sig = !!srq_signature; srq->wq_sig = !!srq_signature;
(*in)->ctx.log_pg_sz = page_shift - MLX5_ADAPTER_PAGE_SHIFT; in->log_page_size = page_shift - MLX5_ADAPTER_PAGE_SHIFT;
if (MLX5_CAP_GEN(dev->mdev, cqe_version) == MLX5_CQE_VERSION_V1 &&
if ((MLX5_CAP_GEN(dev->mdev, cqe_version) == MLX5_CQE_VERSION_V1) && in->type == IB_SRQT_XRC)
is_xrc){ in->user_index = MLX5_IB_DEFAULT_UIDX;
xsrqc = MLX5_ADDR_OF(create_xrc_srq_in, *in,
xrc_srq_context_entry);
/* 0xffffff means we ask to work with cqe version 0 */
MLX5_SET(xrc_srqc, xsrqc, user_index, MLX5_IB_DEFAULT_UIDX);
}
return 0; return 0;
err_in: err_in:
kvfree(*in); kvfree(in->pas);
err_buf: err_buf:
mlx5_buf_free(dev->mdev, &srq->buf); mlx5_buf_free(dev->mdev, &srq->buf);
...@@ -267,10 +252,7 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd, ...@@ -267,10 +252,7 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
int desc_size; int desc_size;
int buf_size; int buf_size;
int err; int err;
struct mlx5_create_srq_mbox_in *uninitialized_var(in); struct mlx5_srq_attr in = {0};
int uninitialized_var(inlen);
int is_xrc;
u32 flgs, xrcdn;
__u32 max_srq_wqes = 1 << MLX5_CAP_GEN(dev->mdev, log_max_srq_sz); __u32 max_srq_wqes = 1 << MLX5_CAP_GEN(dev->mdev, log_max_srq_sz);
/* Sanity check SRQ size before proceeding */ /* Sanity check SRQ size before proceeding */
...@@ -302,14 +284,10 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd, ...@@ -302,14 +284,10 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
desc_size, init_attr->attr.max_wr, srq->msrq.max, srq->msrq.max_gs, desc_size, init_attr->attr.max_wr, srq->msrq.max, srq->msrq.max_gs,
srq->msrq.max_avail_gather); srq->msrq.max_avail_gather);
is_xrc = (init_attr->srq_type == IB_SRQT_XRC);
if (pd->uobject) if (pd->uobject)
err = create_srq_user(pd, srq, &in, udata, buf_size, &inlen, err = create_srq_user(pd, srq, &in, udata, buf_size);
is_xrc);
else else
err = create_srq_kernel(dev, srq, &in, buf_size, &inlen, err = create_srq_kernel(dev, srq, &in, buf_size);
is_xrc);
if (err) { if (err) {
mlx5_ib_warn(dev, "create srq %s failed, err %d\n", mlx5_ib_warn(dev, "create srq %s failed, err %d\n",
...@@ -317,23 +295,23 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd, ...@@ -317,23 +295,23 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
goto err_srq; goto err_srq;
} }
in->ctx.state_log_sz = ilog2(srq->msrq.max); in.type = init_attr->srq_type;
flgs = ((srq->msrq.wqe_shift - 4) | (is_xrc << 5) | (srq->wq_sig << 7)) << 24; in.log_size = ilog2(srq->msrq.max);
xrcdn = 0; in.wqe_shift = srq->msrq.wqe_shift - 4;
if (is_xrc) { if (srq->wq_sig)
xrcdn = to_mxrcd(init_attr->ext.xrc.xrcd)->xrcdn; in.flags |= MLX5_SRQ_FLAG_WQ_SIG;
in->ctx.pgoff_cqn |= cpu_to_be32(to_mcq(init_attr->ext.xrc.cq)->mcq.cqn); if (init_attr->srq_type == IB_SRQT_XRC) {
in.xrcd = to_mxrcd(init_attr->ext.xrc.xrcd)->xrcdn;
in.cqn = to_mcq(init_attr->ext.xrc.cq)->mcq.cqn;
} else if (init_attr->srq_type == IB_SRQT_BASIC) { } else if (init_attr->srq_type == IB_SRQT_BASIC) {
xrcdn = to_mxrcd(dev->devr.x0)->xrcdn; in.xrcd = to_mxrcd(dev->devr.x0)->xrcdn;
in->ctx.pgoff_cqn |= cpu_to_be32(to_mcq(dev->devr.c0)->mcq.cqn); in.cqn = to_mcq(dev->devr.c0)->mcq.cqn;
} }
in->ctx.flags_xrcd = cpu_to_be32((flgs & 0xFF000000) | (xrcdn & 0xFFFFFF)); in.pd = to_mpd(pd)->pdn;
in.db_record = srq->db.dma;
in->ctx.pd = cpu_to_be32(to_mpd(pd)->pdn); err = mlx5_core_create_srq(dev->mdev, &srq->msrq, &in);
in->ctx.db_record = cpu_to_be64(srq->db.dma); kvfree(in.pas);
err = mlx5_core_create_srq(dev->mdev, &srq->msrq, in, inlen, is_xrc);
kvfree(in);
if (err) { if (err) {
mlx5_ib_dbg(dev, "create SRQ failed, err %d\n", err); mlx5_ib_dbg(dev, "create SRQ failed, err %d\n", err);
goto err_usr_kern_srq; goto err_usr_kern_srq;
...@@ -401,7 +379,7 @@ int mlx5_ib_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *srq_attr) ...@@ -401,7 +379,7 @@ int mlx5_ib_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *srq_attr)
struct mlx5_ib_dev *dev = to_mdev(ibsrq->device); struct mlx5_ib_dev *dev = to_mdev(ibsrq->device);
struct mlx5_ib_srq *srq = to_msrq(ibsrq); struct mlx5_ib_srq *srq = to_msrq(ibsrq);
int ret; int ret;
struct mlx5_query_srq_mbox_out *out; struct mlx5_srq_attr *out;
out = kzalloc(sizeof(*out), GFP_KERNEL); out = kzalloc(sizeof(*out), GFP_KERNEL);
if (!out) if (!out)
...@@ -411,7 +389,7 @@ int mlx5_ib_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *srq_attr) ...@@ -411,7 +389,7 @@ int mlx5_ib_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *srq_attr)
if (ret) if (ret)
goto out_box; goto out_box;
srq_attr->srq_limit = be16_to_cpu(out->ctx.lwm); srq_attr->srq_limit = out->lwm;
srq_attr->max_wr = srq->msrq.max - 1; srq_attr->max_wr = srq->msrq.max - 1;
srq_attr->max_sge = srq->msrq.max_gs; srq_attr->max_sge = srq->msrq.max_gs;
...@@ -458,6 +436,8 @@ int mlx5_ib_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr, ...@@ -458,6 +436,8 @@ int mlx5_ib_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
struct mlx5_ib_srq *srq = to_msrq(ibsrq); struct mlx5_ib_srq *srq = to_msrq(ibsrq);
struct mlx5_wqe_srq_next_seg *next; struct mlx5_wqe_srq_next_seg *next;
struct mlx5_wqe_data_seg *scat; struct mlx5_wqe_data_seg *scat;
struct mlx5_ib_dev *dev = to_mdev(ibsrq->device);
struct mlx5_core_dev *mdev = dev->mdev;
unsigned long flags; unsigned long flags;
int err = 0; int err = 0;
int nreq; int nreq;
...@@ -465,6 +445,12 @@ int mlx5_ib_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr, ...@@ -465,6 +445,12 @@ int mlx5_ib_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
spin_lock_irqsave(&srq->lock, flags); spin_lock_irqsave(&srq->lock, flags);
if (mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) {
err = -EIO;
*bad_wr = wr;
goto out;
}
for (nreq = 0; wr; nreq++, wr = wr->next) { for (nreq = 0; wr; nreq++, wr = wr->next) {
if (unlikely(wr->num_sge > srq->msrq.max_gs)) { if (unlikely(wr->num_sge > srq->msrq.max_gs)) {
err = -EINVAL; err = -EINVAL;
...@@ -507,7 +493,7 @@ int mlx5_ib_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr, ...@@ -507,7 +493,7 @@ int mlx5_ib_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
*srq->db.db = cpu_to_be32(srq->wqe_ctr); *srq->db.db = cpu_to_be32(srq->wqe_ctr);
} }
out:
spin_unlock_irqrestore(&srq->lock, flags); spin_unlock_irqrestore(&srq->lock, flags);
return err; return err;
......
...@@ -46,6 +46,10 @@ enum { ...@@ -46,6 +46,10 @@ enum {
MLX5_SRQ_FLAG_SIGNATURE = 1 << 0, MLX5_SRQ_FLAG_SIGNATURE = 1 << 0,
}; };
enum {
MLX5_WQ_FLAG_SIGNATURE = 1 << 0,
};
/* Increment this value if any changes that break userspace ABI /* Increment this value if any changes that break userspace ABI
* compatibility are made. * compatibility are made.
...@@ -79,6 +83,10 @@ enum mlx5_ib_alloc_ucontext_resp_mask { ...@@ -79,6 +83,10 @@ enum mlx5_ib_alloc_ucontext_resp_mask {
MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_CORE_CLOCK_OFFSET = 1UL << 0, MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_CORE_CLOCK_OFFSET = 1UL << 0,
}; };
enum mlx5_user_cmds_supp_uhw {
MLX5_USER_CMDS_SUPP_UHW_QUERY_DEVICE = 1 << 0,
};
struct mlx5_ib_alloc_ucontext_resp { struct mlx5_ib_alloc_ucontext_resp {
__u32 qp_tab_size; __u32 qp_tab_size;
__u32 bf_reg_size; __u32 bf_reg_size;
...@@ -94,8 +102,8 @@ struct mlx5_ib_alloc_ucontext_resp { ...@@ -94,8 +102,8 @@ struct mlx5_ib_alloc_ucontext_resp {
__u32 comp_mask; __u32 comp_mask;
__u32 response_length; __u32 response_length;
__u8 cqe_version; __u8 cqe_version;
__u8 reserved2; __u8 cmds_supp_uhw;
__u16 reserved3; __u16 reserved2;
__u64 hca_core_clock_offset; __u64 hca_core_clock_offset;
}; };
...@@ -103,6 +111,22 @@ struct mlx5_ib_alloc_pd_resp { ...@@ -103,6 +111,22 @@ struct mlx5_ib_alloc_pd_resp {
__u32 pdn; __u32 pdn;
}; };
struct mlx5_ib_tso_caps {
__u32 max_tso; /* Maximum tso payload size in bytes */
/* Corresponding bit will be set if qp type from
* 'enum ib_qp_type' is supported, e.g.
* supported_qpts |= 1 << IB_QPT_UD
*/
__u32 supported_qpts;
};
struct mlx5_ib_query_device_resp {
__u32 comp_mask;
__u32 response_length;
struct mlx5_ib_tso_caps tso_caps;
};
struct mlx5_ib_create_cq { struct mlx5_ib_create_cq {
__u64 buf_addr; __u64 buf_addr;
__u64 db_addr; __u64 db_addr;
...@@ -148,6 +172,40 @@ struct mlx5_ib_create_qp { ...@@ -148,6 +172,40 @@ struct mlx5_ib_create_qp {
__u64 sq_buf_addr; __u64 sq_buf_addr;
}; };
/* RX Hash function flags */
enum mlx5_rx_hash_function_flags {
MLX5_RX_HASH_FUNC_TOEPLITZ = 1 << 0,
};
/*
* RX Hash flags, these flags allows to set which incoming packet's field should
* participates in RX Hash. Each flag represent certain packet's field,
* when the flag is set the field that is represented by the flag will
* participate in RX Hash calculation.
* Note: *IPV4 and *IPV6 flags can't be enabled together on the same QP
* and *TCP and *UDP flags can't be enabled together on the same QP.
*/
enum mlx5_rx_hash_fields {
MLX5_RX_HASH_SRC_IPV4 = 1 << 0,
MLX5_RX_HASH_DST_IPV4 = 1 << 1,
MLX5_RX_HASH_SRC_IPV6 = 1 << 2,
MLX5_RX_HASH_DST_IPV6 = 1 << 3,
MLX5_RX_HASH_SRC_PORT_TCP = 1 << 4,
MLX5_RX_HASH_DST_PORT_TCP = 1 << 5,
MLX5_RX_HASH_SRC_PORT_UDP = 1 << 6,
MLX5_RX_HASH_DST_PORT_UDP = 1 << 7
};
struct mlx5_ib_create_qp_rss {
__u64 rx_hash_fields_mask; /* enum mlx5_rx_hash_fields */
__u8 rx_hash_function; /* enum mlx5_rx_hash_function_flags */
__u8 rx_key_len; /* valid only for Toeplitz */
__u8 reserved[6];
__u8 rx_hash_key[128]; /* valid only for Toeplitz */
__u32 comp_mask;
__u32 reserved1;
};
struct mlx5_ib_create_qp_resp { struct mlx5_ib_create_qp_resp {
__u32 uuar_index; __u32 uuar_index;
}; };
...@@ -159,6 +217,32 @@ struct mlx5_ib_alloc_mw { ...@@ -159,6 +217,32 @@ struct mlx5_ib_alloc_mw {
__u16 reserved2; __u16 reserved2;
}; };
struct mlx5_ib_create_wq {
__u64 buf_addr;
__u64 db_addr;
__u32 rq_wqe_count;
__u32 rq_wqe_shift;
__u32 user_index;
__u32 flags;
__u32 comp_mask;
__u32 reserved;
};
struct mlx5_ib_create_wq_resp {
__u32 response_length;
__u32 reserved;
};
struct mlx5_ib_create_rwq_ind_tbl_resp {
__u32 response_length;
__u32 reserved;
};
struct mlx5_ib_modify_wq {
__u32 comp_mask;
__u32 reserved;
};
static inline int get_qp_user_index(struct mlx5_ib_ucontext *ucontext, static inline int get_qp_user_index(struct mlx5_ib_ucontext *ucontext,
struct mlx5_ib_create_qp *ucmd, struct mlx5_ib_create_qp *ucmd,
int inlen, int inlen,
......
...@@ -1081,16 +1081,6 @@ static ssize_t show_rev(struct device *device, struct device_attribute *attr, ...@@ -1081,16 +1081,6 @@ static ssize_t show_rev(struct device *device, struct device_attribute *attr,
return sprintf(buf, "%x\n", dev->rev_id); return sprintf(buf, "%x\n", dev->rev_id);
} }
static ssize_t show_fw_ver(struct device *device, struct device_attribute *attr,
char *buf)
{
struct mthca_dev *dev =
container_of(device, struct mthca_dev, ib_dev.dev);
return sprintf(buf, "%d.%d.%d\n", (int) (dev->fw_ver >> 32),
(int) (dev->fw_ver >> 16) & 0xffff,
(int) dev->fw_ver & 0xffff);
}
static ssize_t show_hca(struct device *device, struct device_attribute *attr, static ssize_t show_hca(struct device *device, struct device_attribute *attr,
char *buf) char *buf)
{ {
...@@ -1120,13 +1110,11 @@ static ssize_t show_board(struct device *device, struct device_attribute *attr, ...@@ -1120,13 +1110,11 @@ static ssize_t show_board(struct device *device, struct device_attribute *attr,
} }
static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL); static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
static DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);
static DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL); static DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL);
static DEVICE_ATTR(board_id, S_IRUGO, show_board, NULL); static DEVICE_ATTR(board_id, S_IRUGO, show_board, NULL);
static struct device_attribute *mthca_dev_attributes[] = { static struct device_attribute *mthca_dev_attributes[] = {
&dev_attr_hw_rev, &dev_attr_hw_rev,
&dev_attr_fw_ver,
&dev_attr_hca_type, &dev_attr_hca_type,
&dev_attr_board_id &dev_attr_board_id
}; };
...@@ -1187,6 +1175,17 @@ static int mthca_port_immutable(struct ib_device *ibdev, u8 port_num, ...@@ -1187,6 +1175,17 @@ static int mthca_port_immutable(struct ib_device *ibdev, u8 port_num,
return 0; return 0;
} }
static void get_dev_fw_str(struct ib_device *device, char *str,
size_t str_len)
{
struct mthca_dev *dev =
container_of(device, struct mthca_dev, ib_dev);
snprintf(str, str_len, "%d.%d.%d",
(int) (dev->fw_ver >> 32),
(int) (dev->fw_ver >> 16) & 0xffff,
(int) dev->fw_ver & 0xffff);
}
int mthca_register_device(struct mthca_dev *dev) int mthca_register_device(struct mthca_dev *dev)
{ {
int ret; int ret;
...@@ -1266,6 +1265,7 @@ int mthca_register_device(struct mthca_dev *dev) ...@@ -1266,6 +1265,7 @@ int mthca_register_device(struct mthca_dev *dev)
dev->ib_dev.reg_user_mr = mthca_reg_user_mr; dev->ib_dev.reg_user_mr = mthca_reg_user_mr;
dev->ib_dev.dereg_mr = mthca_dereg_mr; dev->ib_dev.dereg_mr = mthca_dereg_mr;
dev->ib_dev.get_port_immutable = mthca_port_immutable; dev->ib_dev.get_port_immutable = mthca_port_immutable;
dev->ib_dev.get_dev_fw_str = get_dev_fw_str;
if (dev->mthca_flags & MTHCA_FLAG_FMR) { if (dev->mthca_flags & MTHCA_FLAG_FMR) {
dev->ib_dev.alloc_fmr = mthca_alloc_fmr; dev->ib_dev.alloc_fmr = mthca_alloc_fmr;
......
...@@ -2605,23 +2605,6 @@ static ssize_t show_rev(struct device *dev, struct device_attribute *attr, ...@@ -2605,23 +2605,6 @@ static ssize_t show_rev(struct device *dev, struct device_attribute *attr,
} }
/**
* show_fw_ver
*/
static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct nes_ib_device *nesibdev =
container_of(dev, struct nes_ib_device, ibdev.dev);
struct nes_vnic *nesvnic = nesibdev->nesvnic;
nes_debug(NES_DBG_INIT, "\n");
return sprintf(buf, "%u.%u\n",
(nesvnic->nesdev->nesadapter->firmware_version >> 16),
(nesvnic->nesdev->nesadapter->firmware_version & 0x000000ff));
}
/** /**
* show_hca * show_hca
*/ */
...@@ -2645,13 +2628,11 @@ static ssize_t show_board(struct device *dev, struct device_attribute *attr, ...@@ -2645,13 +2628,11 @@ static ssize_t show_board(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL); static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
static DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);
static DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL); static DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL);
static DEVICE_ATTR(board_id, S_IRUGO, show_board, NULL); static DEVICE_ATTR(board_id, S_IRUGO, show_board, NULL);
static struct device_attribute *nes_dev_attributes[] = { static struct device_attribute *nes_dev_attributes[] = {
&dev_attr_hw_rev, &dev_attr_hw_rev,
&dev_attr_fw_ver,
&dev_attr_hca_type, &dev_attr_hca_type,
&dev_attr_board_id &dev_attr_board_id
}; };
...@@ -3703,6 +3684,19 @@ static int nes_port_immutable(struct ib_device *ibdev, u8 port_num, ...@@ -3703,6 +3684,19 @@ static int nes_port_immutable(struct ib_device *ibdev, u8 port_num,
return 0; return 0;
} }
static void get_dev_fw_str(struct ib_device *dev, char *str,
size_t str_len)
{
struct nes_ib_device *nesibdev =
container_of(dev, struct nes_ib_device, ibdev);
struct nes_vnic *nesvnic = nesibdev->nesvnic;
nes_debug(NES_DBG_INIT, "\n");
snprintf(str, str_len, "%u.%u",
(nesvnic->nesdev->nesadapter->firmware_version >> 16),
(nesvnic->nesdev->nesadapter->firmware_version & 0x000000ff));
}
/** /**
* nes_init_ofa_device * nes_init_ofa_device
*/ */
...@@ -3802,6 +3796,7 @@ struct nes_ib_device *nes_init_ofa_device(struct net_device *netdev) ...@@ -3802,6 +3796,7 @@ struct nes_ib_device *nes_init_ofa_device(struct net_device *netdev)
nesibdev->ibdev.iwcm->create_listen = nes_create_listen; nesibdev->ibdev.iwcm->create_listen = nes_create_listen;
nesibdev->ibdev.iwcm->destroy_listen = nes_destroy_listen; nesibdev->ibdev.iwcm->destroy_listen = nes_destroy_listen;
nesibdev->ibdev.get_port_immutable = nes_port_immutable; nesibdev->ibdev.get_port_immutable = nes_port_immutable;
nesibdev->ibdev.get_dev_fw_str = get_dev_fw_str;
memcpy(nesibdev->ibdev.iwcm->ifname, netdev->name, memcpy(nesibdev->ibdev.iwcm->ifname, netdev->name,
sizeof(nesibdev->ibdev.iwcm->ifname)); sizeof(nesibdev->ibdev.iwcm->ifname));
......
...@@ -107,6 +107,14 @@ static int ocrdma_port_immutable(struct ib_device *ibdev, u8 port_num, ...@@ -107,6 +107,14 @@ static int ocrdma_port_immutable(struct ib_device *ibdev, u8 port_num,
return 0; return 0;
} }
static void get_dev_fw_str(struct ib_device *device, char *str,
size_t str_len)
{
struct ocrdma_dev *dev = get_ocrdma_dev(device);
snprintf(str, str_len, "%s", &dev->attr.fw_ver[0]);
}
static int ocrdma_register_device(struct ocrdma_dev *dev) static int ocrdma_register_device(struct ocrdma_dev *dev)
{ {
strlcpy(dev->ibdev.name, "ocrdma%d", IB_DEVICE_NAME_MAX); strlcpy(dev->ibdev.name, "ocrdma%d", IB_DEVICE_NAME_MAX);
...@@ -193,6 +201,7 @@ static int ocrdma_register_device(struct ocrdma_dev *dev) ...@@ -193,6 +201,7 @@ static int ocrdma_register_device(struct ocrdma_dev *dev)
dev->ibdev.process_mad = ocrdma_process_mad; dev->ibdev.process_mad = ocrdma_process_mad;
dev->ibdev.get_port_immutable = ocrdma_port_immutable; dev->ibdev.get_port_immutable = ocrdma_port_immutable;
dev->ibdev.get_dev_fw_str = get_dev_fw_str;
if (ocrdma_get_asic_type(dev) == OCRDMA_ASIC_GEN_SKH_R) { if (ocrdma_get_asic_type(dev) == OCRDMA_ASIC_GEN_SKH_R) {
dev->ibdev.uverbs_cmd_mask |= dev->ibdev.uverbs_cmd_mask |=
...@@ -262,14 +271,6 @@ static ssize_t show_rev(struct device *device, struct device_attribute *attr, ...@@ -262,14 +271,6 @@ static ssize_t show_rev(struct device *device, struct device_attribute *attr,
return scnprintf(buf, PAGE_SIZE, "0x%x\n", dev->nic_info.pdev->vendor); return scnprintf(buf, PAGE_SIZE, "0x%x\n", dev->nic_info.pdev->vendor);
} }
static ssize_t show_fw_ver(struct device *device, struct device_attribute *attr,
char *buf)
{
struct ocrdma_dev *dev = dev_get_drvdata(device);
return scnprintf(buf, PAGE_SIZE, "%s\n", &dev->attr.fw_ver[0]);
}
static ssize_t show_hca_type(struct device *device, static ssize_t show_hca_type(struct device *device,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
...@@ -279,12 +280,10 @@ static ssize_t show_hca_type(struct device *device, ...@@ -279,12 +280,10 @@ static ssize_t show_hca_type(struct device *device,
} }
static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL); static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
static DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL);
static DEVICE_ATTR(hca_type, S_IRUGO, show_hca_type, NULL); static DEVICE_ATTR(hca_type, S_IRUGO, show_hca_type, NULL);
static struct device_attribute *ocrdma_attributes[] = { static struct device_attribute *ocrdma_attributes[] = {
&dev_attr_hw_rev, &dev_attr_hw_rev,
&dev_attr_fw_ver,
&dev_attr_hca_type &dev_attr_hca_type
}; };
......
...@@ -331,6 +331,21 @@ static int usnic_port_immutable(struct ib_device *ibdev, u8 port_num, ...@@ -331,6 +331,21 @@ static int usnic_port_immutable(struct ib_device *ibdev, u8 port_num,
return 0; return 0;
} }
static void usnic_get_dev_fw_str(struct ib_device *device,
char *str,
size_t str_len)
{
struct usnic_ib_dev *us_ibdev =
container_of(device, struct usnic_ib_dev, ib_dev);
struct ethtool_drvinfo info;
mutex_lock(&us_ibdev->usdev_lock);
us_ibdev->netdev->ethtool_ops->get_drvinfo(us_ibdev->netdev, &info);
mutex_unlock(&us_ibdev->usdev_lock);
snprintf(str, str_len, "%s", info.fw_version);
}
/* Start of PF discovery section */ /* Start of PF discovery section */
static void *usnic_ib_device_add(struct pci_dev *dev) static void *usnic_ib_device_add(struct pci_dev *dev)
{ {
...@@ -414,6 +429,7 @@ static void *usnic_ib_device_add(struct pci_dev *dev) ...@@ -414,6 +429,7 @@ static void *usnic_ib_device_add(struct pci_dev *dev)
us_ibdev->ib_dev.req_notify_cq = usnic_ib_req_notify_cq; us_ibdev->ib_dev.req_notify_cq = usnic_ib_req_notify_cq;
us_ibdev->ib_dev.get_dma_mr = usnic_ib_get_dma_mr; us_ibdev->ib_dev.get_dma_mr = usnic_ib_get_dma_mr;
us_ibdev->ib_dev.get_port_immutable = usnic_port_immutable; us_ibdev->ib_dev.get_port_immutable = usnic_port_immutable;
us_ibdev->ib_dev.get_dev_fw_str = usnic_get_dev_fw_str;
if (ib_register_device(&us_ibdev->ib_dev, NULL)) if (ib_register_device(&us_ibdev->ib_dev, NULL))
......
...@@ -45,21 +45,6 @@ ...@@ -45,21 +45,6 @@
#include "usnic_ib_verbs.h" #include "usnic_ib_verbs.h"
#include "usnic_log.h" #include "usnic_log.h"
static ssize_t usnic_ib_show_fw_ver(struct device *device,
struct device_attribute *attr,
char *buf)
{
struct usnic_ib_dev *us_ibdev =
container_of(device, struct usnic_ib_dev, ib_dev.dev);
struct ethtool_drvinfo info;
mutex_lock(&us_ibdev->usdev_lock);
us_ibdev->netdev->ethtool_ops->get_drvinfo(us_ibdev->netdev, &info);
mutex_unlock(&us_ibdev->usdev_lock);
return scnprintf(buf, PAGE_SIZE, "%s\n", info.fw_version);
}
static ssize_t usnic_ib_show_board(struct device *device, static ssize_t usnic_ib_show_board(struct device *device,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
...@@ -192,7 +177,6 @@ usnic_ib_show_cq_per_vf(struct device *device, struct device_attribute *attr, ...@@ -192,7 +177,6 @@ usnic_ib_show_cq_per_vf(struct device *device, struct device_attribute *attr,
us_ibdev->vf_res_cnt[USNIC_VNIC_RES_TYPE_CQ]); us_ibdev->vf_res_cnt[USNIC_VNIC_RES_TYPE_CQ]);
} }
static DEVICE_ATTR(fw_ver, S_IRUGO, usnic_ib_show_fw_ver, NULL);
static DEVICE_ATTR(board_id, S_IRUGO, usnic_ib_show_board, NULL); static DEVICE_ATTR(board_id, S_IRUGO, usnic_ib_show_board, NULL);
static DEVICE_ATTR(config, S_IRUGO, usnic_ib_show_config, NULL); static DEVICE_ATTR(config, S_IRUGO, usnic_ib_show_config, NULL);
static DEVICE_ATTR(iface, S_IRUGO, usnic_ib_show_iface, NULL); static DEVICE_ATTR(iface, S_IRUGO, usnic_ib_show_iface, NULL);
...@@ -201,7 +185,6 @@ static DEVICE_ATTR(qp_per_vf, S_IRUGO, usnic_ib_show_qp_per_vf, NULL); ...@@ -201,7 +185,6 @@ static DEVICE_ATTR(qp_per_vf, S_IRUGO, usnic_ib_show_qp_per_vf, NULL);
static DEVICE_ATTR(cq_per_vf, S_IRUGO, usnic_ib_show_cq_per_vf, NULL); static DEVICE_ATTR(cq_per_vf, S_IRUGO, usnic_ib_show_cq_per_vf, NULL);
static struct device_attribute *usnic_class_attributes[] = { static struct device_attribute *usnic_class_attributes[] = {
&dev_attr_fw_ver,
&dev_attr_board_id, &dev_attr_board_id,
&dev_attr_config, &dev_attr_config,
&dev_attr_iface, &dev_attr_iface,
......
...@@ -62,10 +62,8 @@ static void ipoib_get_drvinfo(struct net_device *netdev, ...@@ -62,10 +62,8 @@ static void ipoib_get_drvinfo(struct net_device *netdev,
{ {
struct ipoib_dev_priv *priv = netdev_priv(netdev); struct ipoib_dev_priv *priv = netdev_priv(netdev);
snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), ib_get_device_fw_str(priv->ca, drvinfo->fw_version,
"%d.%d.%d", (int)(priv->ca->attrs.fw_ver >> 32), sizeof(drvinfo->fw_version));
(int)(priv->ca->attrs.fw_ver >> 16) & 0xffff,
(int)priv->ca->attrs.fw_ver & 0xffff);
strlcpy(drvinfo->bus_info, dev_name(priv->ca->dma_device), strlcpy(drvinfo->bus_info, dev_name(priv->ca->dma_device),
sizeof(drvinfo->bus_info)); sizeof(drvinfo->bus_info));
......
...@@ -104,6 +104,8 @@ enum { ...@@ -104,6 +104,8 @@ enum {
enum CPL_error { enum CPL_error {
CPL_ERR_NONE = 0, CPL_ERR_NONE = 0,
CPL_ERR_TCAM_PARITY = 1,
CPL_ERR_TCAM_MISS = 2,
CPL_ERR_TCAM_FULL = 3, CPL_ERR_TCAM_FULL = 3,
CPL_ERR_BAD_LENGTH = 15, CPL_ERR_BAD_LENGTH = 15,
CPL_ERR_BAD_ROUTE = 18, CPL_ERR_BAD_ROUTE = 18,
......
...@@ -85,6 +85,7 @@ int mlx5_core_create_rq(struct mlx5_core_dev *dev, u32 *in, int inlen, u32 *rqn) ...@@ -85,6 +85,7 @@ int mlx5_core_create_rq(struct mlx5_core_dev *dev, u32 *in, int inlen, u32 *rqn)
return err; return err;
} }
EXPORT_SYMBOL(mlx5_core_create_rq);
int mlx5_core_modify_rq(struct mlx5_core_dev *dev, u32 rqn, u32 *in, int inlen) int mlx5_core_modify_rq(struct mlx5_core_dev *dev, u32 rqn, u32 *in, int inlen)
{ {
...@@ -110,6 +111,7 @@ void mlx5_core_destroy_rq(struct mlx5_core_dev *dev, u32 rqn) ...@@ -110,6 +111,7 @@ void mlx5_core_destroy_rq(struct mlx5_core_dev *dev, u32 rqn)
mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out)); mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
} }
EXPORT_SYMBOL(mlx5_core_destroy_rq);
int mlx5_core_query_rq(struct mlx5_core_dev *dev, u32 rqn, u32 *out) int mlx5_core_query_rq(struct mlx5_core_dev *dev, u32 rqn, u32 *out)
{ {
...@@ -430,6 +432,7 @@ int mlx5_core_create_rqt(struct mlx5_core_dev *dev, u32 *in, int inlen, ...@@ -430,6 +432,7 @@ int mlx5_core_create_rqt(struct mlx5_core_dev *dev, u32 *in, int inlen,
return err; return err;
} }
EXPORT_SYMBOL(mlx5_core_create_rqt);
int mlx5_core_modify_rqt(struct mlx5_core_dev *dev, u32 rqtn, u32 *in, int mlx5_core_modify_rqt(struct mlx5_core_dev *dev, u32 rqtn, u32 *in,
int inlen) int inlen)
...@@ -455,3 +458,4 @@ void mlx5_core_destroy_rqt(struct mlx5_core_dev *dev, u32 rqtn) ...@@ -455,3 +458,4 @@ void mlx5_core_destroy_rqt(struct mlx5_core_dev *dev, u32 rqtn)
mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out)); mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, sizeof(out));
} }
EXPORT_SYMBOL(mlx5_core_destroy_rqt);
...@@ -58,6 +58,8 @@ struct mlx5_core_cq { ...@@ -58,6 +58,8 @@ struct mlx5_core_cq {
void (*comp)(struct mlx5_core_cq *); void (*comp)(struct mlx5_core_cq *);
void *priv; void *priv;
} tasklet_ctx; } tasklet_ctx;
int reset_notify_added;
struct list_head reset_notify;
}; };
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include <linux/mlx5/device.h> #include <linux/mlx5/device.h>
#include <linux/mlx5/doorbell.h> #include <linux/mlx5/doorbell.h>
#include <linux/mlx5/srq.h>
enum { enum {
MLX5_RQ_BITMASK_VSD = 1 << 1, MLX5_RQ_BITMASK_VSD = 1 << 1,
...@@ -772,11 +773,10 @@ struct mlx5_cmd_mailbox *mlx5_alloc_cmd_mailbox_chain(struct mlx5_core_dev *dev, ...@@ -772,11 +773,10 @@ struct mlx5_cmd_mailbox *mlx5_alloc_cmd_mailbox_chain(struct mlx5_core_dev *dev,
void mlx5_free_cmd_mailbox_chain(struct mlx5_core_dev *dev, void mlx5_free_cmd_mailbox_chain(struct mlx5_core_dev *dev,
struct mlx5_cmd_mailbox *head); struct mlx5_cmd_mailbox *head);
int mlx5_core_create_srq(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq, int mlx5_core_create_srq(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq,
struct mlx5_create_srq_mbox_in *in, int inlen, struct mlx5_srq_attr *in);
int is_xrc);
int mlx5_core_destroy_srq(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq); int mlx5_core_destroy_srq(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq);
int mlx5_core_query_srq(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq, int mlx5_core_query_srq(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq,
struct mlx5_query_srq_mbox_out *out); struct mlx5_srq_attr *out);
int mlx5_core_arm_srq(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq, int mlx5_core_arm_srq(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq,
u16 lwm, int is_srq); u16 lwm, int is_srq);
void mlx5_init_mkey_table(struct mlx5_core_dev *dev); void mlx5_init_mkey_table(struct mlx5_core_dev *dev);
......
This diff is collapsed.
...@@ -555,9 +555,9 @@ struct mlx5_destroy_qp_mbox_out { ...@@ -555,9 +555,9 @@ struct mlx5_destroy_qp_mbox_out {
struct mlx5_modify_qp_mbox_in { struct mlx5_modify_qp_mbox_in {
struct mlx5_inbox_hdr hdr; struct mlx5_inbox_hdr hdr;
__be32 qpn; __be32 qpn;
u8 rsvd1[4];
__be32 optparam;
u8 rsvd0[4]; u8 rsvd0[4];
__be32 optparam;
u8 rsvd1[4];
struct mlx5_qp_context ctx; struct mlx5_qp_context ctx;
u8 rsvd2[16]; u8 rsvd2[16];
}; };
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment