Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
Pull rdma updates from Jason Gunthorpe: "A smaller cycle this time. Notably we see another new driver, 'Soft iWarp', and the deletion of an ancient unused driver for nes. - Revise and simplify the signature offload RDMA MR APIs - More progress on hoisting object allocation boiler plate code out of the drivers - Driver bug fixes and revisions for hns, hfi1, efa, cxgb4, qib, i40iw - Tree wide cleanups: struct_size, put_user_page, xarray, rst doc conversion - Removal of obsolete ib_ucm chardev and nes driver - netlink based discovery of chardevs and autoloading of the modules providing them - Move more of the rdamvt/hfi1 uapi to include/uapi/rdma - New driver 'siw' for software based iWarp running on top of netdev, much like rxe's software RoCE. - mlx5 feature to report events in their raw devx format to userspace - Expose per-object counters through rdma tool - Adaptive interrupt moderation for RDMA (DIM), sharing the DIM core from netdev" * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: (194 commits) RMDA/siw: Require a 64 bit arch RDMA/siw: Mark expected switch fall-throughs RDMA/core: Fix -Wunused-const-variable warnings rdma/siw: Remove set but not used variable 's' rdma/siw: Add missing dependencies on LIBCRC32C and DMA_VIRT_OPS RDMA/siw: Add missing rtnl_lock around access to ifa rdma/siw: Use proper enumerated type in map_cqe_status RDMA/siw: Remove unnecessary kthread create/destroy printouts IB/rdmavt: Fix variable shadowing issue in rvt_create_cq RDMA/core: Fix race when resolving IP address RDMA/core: Make rdma_counter.h compile stand alone IB/core: Work on the caller socket net namespace in nldev_newlink() RDMA/rxe: Fill in wc byte_len with IB_WC_RECV_RDMA_WITH_IMM RDMA/mlx5: Set RDMA DIM to be enabled by default RDMA/nldev: Added configuration of RDMA dynamic interrupt moderation to netlink RDMA/core: Provide RDMA DIM support for ULPs linux/dim: Implement RDMA adaptive moderation (DIM) IB/mlx5: Report correctly tag matching rendezvous capability docs: infiniband: add it to the driver-api bookset IB/mlx5: Implement VHCA tunnel mechanism in DEVX ...
This commit is contained in:
@@ -8,25 +8,24 @@ config INFINIBAND_HNS
|
||||
is used in Hisilicon Hip06 and more further ICT SoC based on
|
||||
platform device.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called hns-roce.
|
||||
To compile HIP06 or HIP08 driver as module, choose M here.
|
||||
|
||||
config INFINIBAND_HNS_HIP06
|
||||
tristate "Hisilicon Hip06 Family RoCE support"
|
||||
bool "Hisilicon Hip06 Family RoCE support"
|
||||
depends on INFINIBAND_HNS && HNS && HNS_DSAF && HNS_ENET
|
||||
---help---
|
||||
RoCE driver support for Hisilicon RoCE engine in Hisilicon Hip06 and
|
||||
Hip07 SoC. These RoCE engines are platform devices.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called hns-roce-hw-v1.
|
||||
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"
|
||||
bool "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 as a module, choose M here: the module
|
||||
will be called hns-roce-hw-v2.
|
||||
To compile this driver, choose Y here: if INFINIBAND_HNS is m, this
|
||||
module will be called hns-roce-hw-v2.
|
||||
|
@@ -5,11 +5,16 @@
|
||||
|
||||
ccflags-y := -I $(srctree)/drivers/net/ethernet/hisilicon/hns3
|
||||
|
||||
obj-$(CONFIG_INFINIBAND_HNS) += hns-roce.o
|
||||
hns-roce-objs := hns_roce_main.o hns_roce_cmd.o hns_roce_pd.o \
|
||||
hns_roce_ah.o hns_roce_hem.o hns_roce_mr.o hns_roce_qp.o \
|
||||
hns_roce_cq.o hns_roce_alloc.o hns_roce_db.o hns_roce_srq.o hns_roce_restrack.o
|
||||
obj-$(CONFIG_INFINIBAND_HNS_HIP06) += hns-roce-hw-v1.o
|
||||
hns-roce-hw-v1-objs := hns_roce_hw_v1.o
|
||||
obj-$(CONFIG_INFINIBAND_HNS_HIP08) += hns-roce-hw-v2.o
|
||||
hns-roce-hw-v2-objs := hns_roce_hw_v2.o hns_roce_hw_v2_dfx.o
|
||||
|
||||
ifdef CONFIG_INFINIBAND_HNS_HIP06
|
||||
hns-roce-hw-v1-objs := hns_roce_hw_v1.o $(hns-roce-objs)
|
||||
obj-$(CONFIG_INFINIBAND_HNS) += hns-roce-hw-v1.o
|
||||
endif
|
||||
|
||||
ifdef CONFIG_INFINIBAND_HNS_HIP08
|
||||
hns-roce-hw-v2-objs := hns_roce_hw_v2.o hns_roce_hw_v2_dfx.o $(hns-roce-objs)
|
||||
obj-$(CONFIG_INFINIBAND_HNS) += hns-roce-hw-v2.o
|
||||
endif
|
||||
|
@@ -34,6 +34,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include "hns_roce_device.h"
|
||||
#include <rdma/ib_umem.h>
|
||||
|
||||
int hns_roce_bitmap_alloc(struct hns_roce_bitmap *bitmap, unsigned long *obj)
|
||||
{
|
||||
@@ -67,7 +68,6 @@ void hns_roce_bitmap_free(struct hns_roce_bitmap *bitmap, unsigned long obj,
|
||||
{
|
||||
hns_roce_bitmap_free_range(bitmap, obj, 1, rr);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_bitmap_free);
|
||||
|
||||
int hns_roce_bitmap_alloc_range(struct hns_roce_bitmap *bitmap, int cnt,
|
||||
int align, unsigned long *obj)
|
||||
@@ -174,7 +174,6 @@ void hns_roce_buf_free(struct hns_roce_dev *hr_dev, u32 size,
|
||||
kfree(buf->page_list);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_buf_free);
|
||||
|
||||
int hns_roce_buf_alloc(struct hns_roce_dev *hr_dev, u32 size, u32 max_direct,
|
||||
struct hns_roce_buf *buf, u32 page_shift)
|
||||
@@ -238,6 +237,104 @@ err_free:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
int hns_roce_get_kmem_bufs(struct hns_roce_dev *hr_dev, dma_addr_t *bufs,
|
||||
int buf_cnt, int start, struct hns_roce_buf *buf)
|
||||
{
|
||||
int i, end;
|
||||
int total;
|
||||
|
||||
end = start + buf_cnt;
|
||||
if (end > buf->npages) {
|
||||
dev_err(hr_dev->dev,
|
||||
"invalid kmem region,offset %d,buf_cnt %d,total %d!\n",
|
||||
start, buf_cnt, buf->npages);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
total = 0;
|
||||
for (i = start; i < end; i++)
|
||||
if (buf->nbufs == 1)
|
||||
bufs[total++] = buf->direct.map +
|
||||
((dma_addr_t)i << buf->page_shift);
|
||||
else
|
||||
bufs[total++] = buf->page_list[i].map;
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
int hns_roce_get_umem_bufs(struct hns_roce_dev *hr_dev, dma_addr_t *bufs,
|
||||
int buf_cnt, int start, struct ib_umem *umem,
|
||||
int page_shift)
|
||||
{
|
||||
struct ib_block_iter biter;
|
||||
int total = 0;
|
||||
int idx = 0;
|
||||
u64 addr;
|
||||
|
||||
if (page_shift < PAGE_SHIFT) {
|
||||
dev_err(hr_dev->dev, "invalid page shift %d!\n", page_shift);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* convert system page cnt to hw page cnt */
|
||||
rdma_for_each_block(umem->sg_head.sgl, &biter, umem->nmap,
|
||||
1 << page_shift) {
|
||||
addr = rdma_block_iter_dma_address(&biter);
|
||||
if (idx >= start) {
|
||||
bufs[total++] = addr;
|
||||
if (total >= buf_cnt)
|
||||
goto done;
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
|
||||
done:
|
||||
return total;
|
||||
}
|
||||
|
||||
void hns_roce_init_buf_region(struct hns_roce_buf_region *region, int hopnum,
|
||||
int offset, int buf_cnt)
|
||||
{
|
||||
if (hopnum == HNS_ROCE_HOP_NUM_0)
|
||||
region->hopnum = 0;
|
||||
else
|
||||
region->hopnum = hopnum;
|
||||
|
||||
region->offset = offset;
|
||||
region->count = buf_cnt;
|
||||
}
|
||||
|
||||
void hns_roce_free_buf_list(dma_addr_t **bufs, int region_cnt)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < region_cnt; i++) {
|
||||
kfree(bufs[i]);
|
||||
bufs[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int hns_roce_alloc_buf_list(struct hns_roce_buf_region *regions,
|
||||
dma_addr_t **bufs, int region_cnt)
|
||||
{
|
||||
struct hns_roce_buf_region *r;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < region_cnt; i++) {
|
||||
r = ®ions[i];
|
||||
bufs[i] = kcalloc(r->count, sizeof(dma_addr_t), GFP_KERNEL);
|
||||
if (!bufs[i])
|
||||
goto err_alloc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_alloc:
|
||||
hns_roce_free_buf_list(bufs, i);
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
void hns_roce_cleanup_bitmap(struct hns_roce_dev *hr_dev)
|
||||
{
|
||||
if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_SRQ)
|
||||
|
@@ -103,7 +103,6 @@ void hns_roce_cmd_event(struct hns_roce_dev *hr_dev, u16 token, u8 status,
|
||||
context->out_param = out_param;
|
||||
complete(&context->done);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_cmd_event);
|
||||
|
||||
/* this should be called with "use_events" */
|
||||
static int __hns_roce_cmd_mbox_wait(struct hns_roce_dev *hr_dev, u64 in_param,
|
||||
@@ -162,7 +161,7 @@ static int hns_roce_cmd_mbox_wait(struct hns_roce_dev *hr_dev, u64 in_param,
|
||||
u64 out_param, unsigned long in_modifier,
|
||||
u8 op_modifier, u16 op, unsigned long timeout)
|
||||
{
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
down(&hr_dev->cmd.event_sem);
|
||||
ret = __hns_roce_cmd_mbox_wait(hr_dev, in_param, out_param,
|
||||
@@ -204,7 +203,6 @@ int hns_roce_cmd_mbox(struct hns_roce_dev *hr_dev, u64 in_param, u64 out_param,
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_cmd_mbox);
|
||||
|
||||
int hns_roce_cmd_init(struct hns_roce_dev *hr_dev)
|
||||
{
|
||||
@@ -291,7 +289,6 @@ struct hns_roce_cmd_mailbox
|
||||
|
||||
return mailbox;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_alloc_cmd_mailbox);
|
||||
|
||||
void hns_roce_free_cmd_mailbox(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_cmd_mailbox *mailbox)
|
||||
@@ -302,4 +299,3 @@ void hns_roce_free_cmd_mailbox(struct hns_roce_dev *hr_dev,
|
||||
dma_pool_free(hr_dev->cmd.pool, mailbox->buf, mailbox->dma);
|
||||
kfree(mailbox);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_free_cmd_mailbox);
|
||||
|
@@ -205,7 +205,6 @@ void hns_roce_free_cq(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq)
|
||||
hns_roce_table_put(hr_dev, &cq_table->table, hr_cq->cqn);
|
||||
hns_roce_bitmap_free(&cq_table->bitmap, hr_cq->cqn, BITMAP_NO_RR);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_free_cq);
|
||||
|
||||
static int hns_roce_ib_get_cq_umem(struct hns_roce_dev *hr_dev,
|
||||
struct ib_udata *udata,
|
||||
@@ -235,8 +234,7 @@ static int hns_roce_ib_get_cq_umem(struct hns_roce_dev *hr_dev,
|
||||
&buf->hr_mtt);
|
||||
} else {
|
||||
ret = hns_roce_mtt_init(hr_dev, ib_umem_page_count(*umem),
|
||||
(*umem)->page_shift,
|
||||
&buf->hr_mtt);
|
||||
PAGE_SHIFT, &buf->hr_mtt);
|
||||
}
|
||||
if (ret)
|
||||
goto err_buf;
|
||||
@@ -300,15 +298,15 @@ static void hns_roce_ib_free_cq_buf(struct hns_roce_dev *hr_dev,
|
||||
&buf->hr_buf);
|
||||
}
|
||||
|
||||
struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev,
|
||||
const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata)
|
||||
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_dev);
|
||||
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 = NULL;
|
||||
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;
|
||||
@@ -319,13 +317,9 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev,
|
||||
if (cq_entries < 1 || cq_entries > hr_dev->caps.max_cqes) {
|
||||
dev_err(dev, "Creat CQ failed. entries=%d, max=%d\n",
|
||||
cq_entries, hr_dev->caps.max_cqes);
|
||||
return ERR_PTR(-EINVAL);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hr_cq = kzalloc(sizeof(*hr_cq), GFP_KERNEL);
|
||||
if (!hr_cq)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
if (hr_dev->caps.min_cqes)
|
||||
cq_entries = max(cq_entries, hr_dev->caps.min_cqes);
|
||||
|
||||
@@ -416,7 +410,7 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev,
|
||||
goto err_cqc;
|
||||
}
|
||||
|
||||
return &hr_cq->ib_cq;
|
||||
return 0;
|
||||
|
||||
err_cqc:
|
||||
hns_roce_free_cq(hr_dev, hr_cq);
|
||||
@@ -428,9 +422,8 @@ err_dbmap:
|
||||
|
||||
err_mtt:
|
||||
hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt);
|
||||
if (udata)
|
||||
ib_umem_release(hr_cq->umem);
|
||||
else
|
||||
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);
|
||||
|
||||
@@ -439,47 +432,37 @@ err_db:
|
||||
hns_roce_free_db(hr_dev, &hr_cq->db);
|
||||
|
||||
err_cq:
|
||||
kfree(hr_cq);
|
||||
return ERR_PTR(ret);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_ib_create_cq);
|
||||
|
||||
int hns_roce_ib_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
|
||||
void hns_roce_ib_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
|
||||
{
|
||||
struct hns_roce_dev *hr_dev = to_hr_dev(ib_cq->device);
|
||||
struct hns_roce_cq *hr_cq = to_hr_cq(ib_cq);
|
||||
int ret = 0;
|
||||
|
||||
if (hr_dev->hw->destroy_cq) {
|
||||
ret = hr_dev->hw->destroy_cq(ib_cq, udata);
|
||||
} else {
|
||||
hns_roce_free_cq(hr_dev, hr_cq);
|
||||
hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt);
|
||||
|
||||
if (udata) {
|
||||
ib_umem_release(hr_cq->umem);
|
||||
|
||||
if (hr_cq->db_en == 1)
|
||||
hns_roce_db_unmap_user(
|
||||
rdma_udata_to_drv_context(
|
||||
udata,
|
||||
struct hns_roce_ucontext,
|
||||
ibucontext),
|
||||
&hr_cq->db);
|
||||
} else {
|
||||
/* Free the buff of stored cq */
|
||||
hns_roce_ib_free_cq_buf(hr_dev, &hr_cq->hr_buf,
|
||||
ib_cq->cqe);
|
||||
if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB)
|
||||
hns_roce_free_db(hr_dev, &hr_cq->db);
|
||||
}
|
||||
|
||||
kfree(hr_cq);
|
||||
hr_dev->hw->destroy_cq(ib_cq, udata);
|
||||
return;
|
||||
}
|
||||
|
||||
return ret;
|
||||
hns_roce_free_cq(hr_dev, hr_cq);
|
||||
hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt);
|
||||
|
||||
ib_umem_release(hr_cq->umem);
|
||||
if (udata) {
|
||||
if (hr_cq->db_en == 1)
|
||||
hns_roce_db_unmap_user(rdma_udata_to_drv_context(
|
||||
udata,
|
||||
struct hns_roce_ucontext,
|
||||
ibucontext),
|
||||
&hr_cq->db);
|
||||
} else {
|
||||
/* Free the buff of stored cq */
|
||||
hns_roce_ib_free_cq_buf(hr_dev, &hr_cq->hr_buf, ib_cq->cqe);
|
||||
if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB)
|
||||
hns_roce_free_db(hr_dev, &hr_cq->db);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_ib_destroy_cq);
|
||||
|
||||
void hns_roce_cq_completion(struct hns_roce_dev *hr_dev, u32 cqn)
|
||||
{
|
||||
@@ -495,7 +478,6 @@ void hns_roce_cq_completion(struct hns_roce_dev *hr_dev, u32 cqn)
|
||||
++cq->arm_sn;
|
||||
cq->comp(cq);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_cq_completion);
|
||||
|
||||
void hns_roce_cq_event(struct hns_roce_dev *hr_dev, u32 cqn, int event_type)
|
||||
{
|
||||
@@ -517,7 +499,6 @@ void hns_roce_cq_event(struct hns_roce_dev *hr_dev, u32 cqn, int event_type)
|
||||
if (atomic_dec_and_test(&cq->refcount))
|
||||
complete(&cq->free);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_cq_event);
|
||||
|
||||
int hns_roce_init_cq_table(struct hns_roce_dev *hr_dev)
|
||||
{
|
||||
|
@@ -51,7 +51,6 @@ out:
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(hns_roce_db_map_user);
|
||||
|
||||
void hns_roce_db_unmap_user(struct hns_roce_ucontext *context,
|
||||
struct hns_roce_db *db)
|
||||
@@ -67,7 +66,6 @@ void hns_roce_db_unmap_user(struct hns_roce_ucontext *context,
|
||||
|
||||
mutex_unlock(&context->page_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL(hns_roce_db_unmap_user);
|
||||
|
||||
static struct hns_roce_db_pgdir *hns_roce_alloc_db_pgdir(
|
||||
struct device *dma_device)
|
||||
@@ -78,7 +76,8 @@ static struct hns_roce_db_pgdir *hns_roce_alloc_db_pgdir(
|
||||
if (!pgdir)
|
||||
return NULL;
|
||||
|
||||
bitmap_fill(pgdir->order1, HNS_ROCE_DB_PER_PAGE / 2);
|
||||
bitmap_fill(pgdir->order1,
|
||||
HNS_ROCE_DB_PER_PAGE / HNS_ROCE_DB_TYPE_COUNT);
|
||||
pgdir->bits[0] = pgdir->order0;
|
||||
pgdir->bits[1] = pgdir->order1;
|
||||
pgdir->page = dma_alloc_coherent(dma_device, PAGE_SIZE,
|
||||
@@ -116,7 +115,7 @@ found:
|
||||
db->u.pgdir = pgdir;
|
||||
db->index = i;
|
||||
db->db_record = pgdir->page + db->index;
|
||||
db->dma = pgdir->db_dma + db->index * 4;
|
||||
db->dma = pgdir->db_dma + db->index * HNS_ROCE_DB_UNIT_SIZE;
|
||||
db->order = order;
|
||||
|
||||
return 0;
|
||||
@@ -150,7 +149,6 @@ out:
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_alloc_db);
|
||||
|
||||
void hns_roce_free_db(struct hns_roce_dev *hr_dev, struct hns_roce_db *db)
|
||||
{
|
||||
@@ -170,7 +168,8 @@ void hns_roce_free_db(struct hns_roce_dev *hr_dev, struct hns_roce_db *db)
|
||||
i >>= o;
|
||||
set_bit(i, db->u.pgdir->bits[o]);
|
||||
|
||||
if (bitmap_full(db->u.pgdir->order1, HNS_ROCE_DB_PER_PAGE / 2)) {
|
||||
if (bitmap_full(db->u.pgdir->order1,
|
||||
HNS_ROCE_DB_PER_PAGE / HNS_ROCE_DB_TYPE_COUNT)) {
|
||||
dma_free_coherent(hr_dev->dev, PAGE_SIZE, db->u.pgdir->page,
|
||||
db->u.pgdir->db_dma);
|
||||
list_del(&db->u.pgdir->list);
|
||||
@@ -179,4 +178,3 @@ void hns_roce_free_db(struct hns_roce_dev *hr_dev, struct hns_roce_db *db)
|
||||
|
||||
mutex_unlock(&hr_dev->pgdir_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_free_db);
|
||||
|
@@ -37,9 +37,12 @@
|
||||
|
||||
#define DRV_NAME "hns_roce"
|
||||
|
||||
/* hip08 is a pci device, it includes two version according pci version id */
|
||||
#define PCI_REVISION_ID_HIP08_A 0x20
|
||||
#define PCI_REVISION_ID_HIP08_B 0x21
|
||||
|
||||
#define HNS_ROCE_HW_VER1 ('h' << 24 | 'i' << 16 | '0' << 8 | '6')
|
||||
|
||||
#define MAC_ADDR_OCTET_NUM 6
|
||||
#define HNS_ROCE_MAX_MSG_LEN 0x80000000
|
||||
|
||||
#define HNS_ROCE_ALOGN_UP(a, b) ((((a) + (b) - 1) / (b)) * (b))
|
||||
@@ -48,6 +51,10 @@
|
||||
|
||||
#define HNS_ROCE_BA_SIZE (32 * 4096)
|
||||
|
||||
#define BA_BYTE_LEN 8
|
||||
|
||||
#define BITS_PER_BYTE 8
|
||||
|
||||
/* Hardware specification only for v1 engine */
|
||||
#define HNS_ROCE_MIN_CQE_NUM 0x40
|
||||
#define HNS_ROCE_MIN_WQE_NUM 0x20
|
||||
@@ -55,6 +62,7 @@
|
||||
/* Hardware specification only for v1 engine */
|
||||
#define HNS_ROCE_MAX_INNER_MTPT_NUM 0x7
|
||||
#define HNS_ROCE_MAX_MTPT_PBL_NUM 0x100000
|
||||
#define HNS_ROCE_MAX_SGE_NUM 2
|
||||
|
||||
#define HNS_ROCE_EACH_FREE_CQ_WAIT_MSECS 20
|
||||
#define HNS_ROCE_MAX_FREE_CQ_WAIT_CNT \
|
||||
@@ -64,6 +72,9 @@
|
||||
|
||||
#define HNS_ROCE_MAX_IRQ_NUM 128
|
||||
|
||||
#define HNS_ROCE_SGE_IN_WQE 2
|
||||
#define HNS_ROCE_SGE_SHIFT 4
|
||||
|
||||
#define EQ_ENABLE 1
|
||||
#define EQ_DISABLE 0
|
||||
|
||||
@@ -81,6 +92,7 @@
|
||||
#define HNS_ROCE_MAX_PORTS 6
|
||||
#define HNS_ROCE_MAX_GID_NUM 16
|
||||
#define HNS_ROCE_GID_SIZE 16
|
||||
#define HNS_ROCE_SGE_SIZE 16
|
||||
|
||||
#define HNS_ROCE_HOP_NUM_0 0xff
|
||||
|
||||
@@ -111,6 +123,8 @@
|
||||
#define PAGES_SHIFT_24 24
|
||||
#define PAGES_SHIFT_32 32
|
||||
|
||||
#define HNS_ROCE_PCI_BAR_NUM 2
|
||||
|
||||
#define HNS_ROCE_IDX_QUE_ENTRY_SZ 4
|
||||
#define SRQ_DB_REG 0x230
|
||||
|
||||
@@ -213,6 +227,9 @@ enum hns_roce_mtt_type {
|
||||
MTT_TYPE_IDX
|
||||
};
|
||||
|
||||
#define HNS_ROCE_DB_TYPE_COUNT 2
|
||||
#define HNS_ROCE_DB_UNIT_SIZE 4
|
||||
|
||||
enum {
|
||||
HNS_ROCE_DB_PER_PAGE = PAGE_SIZE / 4
|
||||
};
|
||||
@@ -324,6 +341,29 @@ struct hns_roce_mtt {
|
||||
enum hns_roce_mtt_type mtt_type;
|
||||
};
|
||||
|
||||
struct hns_roce_buf_region {
|
||||
int offset; /* page offset */
|
||||
u32 count; /* page count*/
|
||||
int hopnum; /* addressing hop num */
|
||||
};
|
||||
|
||||
#define HNS_ROCE_MAX_BT_REGION 3
|
||||
#define HNS_ROCE_MAX_BT_LEVEL 3
|
||||
struct hns_roce_hem_list {
|
||||
struct list_head root_bt;
|
||||
/* link all bt dma mem by hop config */
|
||||
struct list_head mid_bt[HNS_ROCE_MAX_BT_REGION][HNS_ROCE_MAX_BT_LEVEL];
|
||||
struct list_head btm_bt; /* link all bottom bt in @mid_bt */
|
||||
dma_addr_t root_ba; /* pointer to the root ba table */
|
||||
int bt_pg_shift;
|
||||
};
|
||||
|
||||
/* memory translate region */
|
||||
struct hns_roce_mtr {
|
||||
struct hns_roce_hem_list hem_list;
|
||||
int buf_pg_shift;
|
||||
};
|
||||
|
||||
struct hns_roce_mw {
|
||||
struct ib_mw ibmw;
|
||||
u32 pdn;
|
||||
@@ -413,8 +453,8 @@ struct hns_roce_buf {
|
||||
struct hns_roce_db_pgdir {
|
||||
struct list_head list;
|
||||
DECLARE_BITMAP(order0, HNS_ROCE_DB_PER_PAGE);
|
||||
DECLARE_BITMAP(order1, HNS_ROCE_DB_PER_PAGE / 2);
|
||||
unsigned long *bits[2];
|
||||
DECLARE_BITMAP(order1, HNS_ROCE_DB_PER_PAGE / HNS_ROCE_DB_TYPE_COUNT);
|
||||
unsigned long *bits[HNS_ROCE_DB_TYPE_COUNT];
|
||||
u32 *page;
|
||||
dma_addr_t db_dma;
|
||||
};
|
||||
@@ -472,7 +512,7 @@ struct hns_roce_idx_que {
|
||||
u32 buf_size;
|
||||
struct ib_umem *umem;
|
||||
struct hns_roce_mtt mtt;
|
||||
u64 *bitmap;
|
||||
unsigned long *bitmap;
|
||||
};
|
||||
|
||||
struct hns_roce_srq {
|
||||
@@ -535,7 +575,7 @@ struct hns_roce_av {
|
||||
u8 hop_limit;
|
||||
__le32 sl_tclass_flowlabel;
|
||||
u8 dgid[HNS_ROCE_GID_SIZE];
|
||||
u8 mac[6];
|
||||
u8 mac[ETH_ALEN];
|
||||
__le16 vlan;
|
||||
bool vlan_en;
|
||||
};
|
||||
@@ -620,6 +660,14 @@ struct hns_roce_qp {
|
||||
|
||||
struct ib_umem *umem;
|
||||
struct hns_roce_mtt mtt;
|
||||
struct hns_roce_mtr mtr;
|
||||
|
||||
/* this define must less than HNS_ROCE_MAX_BT_REGION */
|
||||
#define HNS_ROCE_WQE_REGION_MAX 3
|
||||
struct hns_roce_buf_region regions[HNS_ROCE_WQE_REGION_MAX];
|
||||
int region_cnt;
|
||||
int wqe_bt_pg_shift;
|
||||
|
||||
u32 buff_size;
|
||||
struct mutex mutex;
|
||||
u8 port;
|
||||
@@ -830,6 +878,9 @@ struct hns_roce_caps {
|
||||
u32 mtt_ba_pg_sz;
|
||||
u32 mtt_buf_pg_sz;
|
||||
u32 mtt_hop_num;
|
||||
u32 wqe_sq_hop_num;
|
||||
u32 wqe_sge_hop_num;
|
||||
u32 wqe_rq_hop_num;
|
||||
u32 sccc_ba_pg_sz;
|
||||
u32 sccc_buf_pg_sz;
|
||||
u32 sccc_hop_num;
|
||||
@@ -921,7 +972,7 @@ struct hns_roce_hw {
|
||||
int (*poll_cq)(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc);
|
||||
int (*dereg_mr)(struct hns_roce_dev *hr_dev, struct hns_roce_mr *mr,
|
||||
struct ib_udata *udata);
|
||||
int (*destroy_cq)(struct ib_cq *ibcq, struct ib_udata *udata);
|
||||
void (*destroy_cq)(struct ib_cq *ibcq, struct ib_udata *udata);
|
||||
int (*modify_cq)(struct ib_cq *cq, u16 cq_count, u16 cq_period);
|
||||
int (*init_eq)(struct hns_roce_dev *hr_dev);
|
||||
void (*cleanup_eq)(struct hns_roce_dev *hr_dev);
|
||||
@@ -940,6 +991,16 @@ 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;
|
||||
@@ -962,7 +1023,7 @@ struct hns_roce_dev {
|
||||
struct hns_roce_caps caps;
|
||||
struct xarray qp_table_xa;
|
||||
|
||||
unsigned char dev_addr[HNS_ROCE_MAX_PORTS][MAC_ADDR_OCTET_NUM];
|
||||
unsigned char dev_addr[HNS_ROCE_MAX_PORTS][ETH_ALEN];
|
||||
u64 sys_image_guid;
|
||||
u32 vendor_id;
|
||||
u32 vendor_part_id;
|
||||
@@ -1084,6 +1145,19 @@ void hns_roce_mtt_cleanup(struct hns_roce_dev *hr_dev,
|
||||
int hns_roce_buf_write_mtt(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_mtt *mtt, struct hns_roce_buf *buf);
|
||||
|
||||
void hns_roce_mtr_init(struct hns_roce_mtr *mtr, int bt_pg_shift,
|
||||
int buf_pg_shift);
|
||||
int hns_roce_mtr_attach(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
|
||||
dma_addr_t **bufs, struct hns_roce_buf_region *regions,
|
||||
int region_cnt);
|
||||
void hns_roce_mtr_cleanup(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_mtr *mtr);
|
||||
|
||||
/* hns roce hw need current block and next block addr from mtt */
|
||||
#define MTT_MIN_COUNT 2
|
||||
int hns_roce_mtr_find(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
|
||||
int offset, u64 *mtt_buf, int mtt_max, u64 *base_addr);
|
||||
|
||||
int hns_roce_init_pd_table(struct hns_roce_dev *hr_dev);
|
||||
int hns_roce_init_mr_table(struct hns_roce_dev *hr_dev);
|
||||
int hns_roce_init_eq_table(struct hns_roce_dev *hr_dev);
|
||||
@@ -1148,6 +1222,18 @@ int hns_roce_buf_alloc(struct hns_roce_dev *hr_dev, u32 size, u32 max_direct,
|
||||
int hns_roce_ib_umem_write_mtt(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_mtt *mtt, struct ib_umem *umem);
|
||||
|
||||
void hns_roce_init_buf_region(struct hns_roce_buf_region *region, int hopnum,
|
||||
int offset, int buf_cnt);
|
||||
int hns_roce_alloc_buf_list(struct hns_roce_buf_region *regions,
|
||||
dma_addr_t **bufs, int count);
|
||||
void hns_roce_free_buf_list(dma_addr_t **bufs, int count);
|
||||
|
||||
int hns_roce_get_kmem_bufs(struct hns_roce_dev *hr_dev, dma_addr_t *bufs,
|
||||
int buf_cnt, int start, struct hns_roce_buf *buf);
|
||||
int hns_roce_get_umem_bufs(struct hns_roce_dev *hr_dev, dma_addr_t *bufs,
|
||||
int buf_cnt, int start, struct ib_umem *umem,
|
||||
int page_shift);
|
||||
|
||||
int hns_roce_create_srq(struct ib_srq *srq,
|
||||
struct ib_srq_init_attr *srq_init_attr,
|
||||
struct ib_udata *udata);
|
||||
@@ -1178,11 +1264,11 @@ void hns_roce_release_range_qp(struct hns_roce_dev *hr_dev, int base_qpn,
|
||||
__be32 send_ieth(const struct ib_send_wr *wr);
|
||||
int to_hr_qp_type(int qp_type);
|
||||
|
||||
struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev,
|
||||
const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata);
|
||||
int hns_roce_ib_create_cq(struct ib_cq *ib_cq,
|
||||
const struct ib_cq_init_attr *attr,
|
||||
struct ib_udata *udata);
|
||||
|
||||
int hns_roce_ib_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata);
|
||||
void hns_roce_ib_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata);
|
||||
void hns_roce_free_cq(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq);
|
||||
|
||||
int hns_roce_db_map_user(struct hns_roce_ucontext *context,
|
||||
|
@@ -56,7 +56,6 @@ bool hns_roce_check_whether_mhop(struct hns_roce_dev *hr_dev, u32 type)
|
||||
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_check_whether_mhop);
|
||||
|
||||
static bool hns_roce_check_hem_null(struct hns_roce_hem **hem, u64 start_idx,
|
||||
u32 bt_chunk_num)
|
||||
@@ -165,7 +164,7 @@ int hns_roce_calc_hem_mhop(struct hns_roce_dev *hr_dev,
|
||||
+ PAGE_SHIFT);
|
||||
mhop->bt_chunk_size = 1 << (hr_dev->caps.mtt_ba_pg_sz
|
||||
+ PAGE_SHIFT);
|
||||
mhop->ba_l0_num = mhop->bt_chunk_size / 8;
|
||||
mhop->ba_l0_num = mhop->bt_chunk_size / BA_BYTE_LEN;
|
||||
mhop->hop_num = hr_dev->caps.mtt_hop_num;
|
||||
break;
|
||||
case HEM_TYPE_CQE:
|
||||
@@ -173,7 +172,7 @@ int hns_roce_calc_hem_mhop(struct hns_roce_dev *hr_dev,
|
||||
+ PAGE_SHIFT);
|
||||
mhop->bt_chunk_size = 1 << (hr_dev->caps.cqe_ba_pg_sz
|
||||
+ PAGE_SHIFT);
|
||||
mhop->ba_l0_num = mhop->bt_chunk_size / 8;
|
||||
mhop->ba_l0_num = mhop->bt_chunk_size / BA_BYTE_LEN;
|
||||
mhop->hop_num = hr_dev->caps.cqe_hop_num;
|
||||
break;
|
||||
case HEM_TYPE_SRQWQE:
|
||||
@@ -181,7 +180,7 @@ int hns_roce_calc_hem_mhop(struct hns_roce_dev *hr_dev,
|
||||
+ PAGE_SHIFT);
|
||||
mhop->bt_chunk_size = 1 << (hr_dev->caps.srqwqe_ba_pg_sz
|
||||
+ PAGE_SHIFT);
|
||||
mhop->ba_l0_num = mhop->bt_chunk_size / 8;
|
||||
mhop->ba_l0_num = mhop->bt_chunk_size / BA_BYTE_LEN;
|
||||
mhop->hop_num = hr_dev->caps.srqwqe_hop_num;
|
||||
break;
|
||||
case HEM_TYPE_IDX:
|
||||
@@ -189,7 +188,7 @@ int hns_roce_calc_hem_mhop(struct hns_roce_dev *hr_dev,
|
||||
+ PAGE_SHIFT);
|
||||
mhop->bt_chunk_size = 1 << (hr_dev->caps.idx_ba_pg_sz
|
||||
+ PAGE_SHIFT);
|
||||
mhop->ba_l0_num = mhop->bt_chunk_size / 8;
|
||||
mhop->ba_l0_num = mhop->bt_chunk_size / BA_BYTE_LEN;
|
||||
mhop->hop_num = hr_dev->caps.idx_hop_num;
|
||||
break;
|
||||
default:
|
||||
@@ -206,7 +205,7 @@ int hns_roce_calc_hem_mhop(struct hns_roce_dev *hr_dev,
|
||||
* MTT/CQE alloc hem for bt pages.
|
||||
*/
|
||||
bt_num = hns_roce_get_bt_num(table->type, mhop->hop_num);
|
||||
chunk_ba_num = mhop->bt_chunk_size / 8;
|
||||
chunk_ba_num = mhop->bt_chunk_size / BA_BYTE_LEN;
|
||||
chunk_size = table->type < HEM_TYPE_MTT ? mhop->buf_chunk_size :
|
||||
mhop->bt_chunk_size;
|
||||
table_idx = (*obj & (table->num_obj - 1)) /
|
||||
@@ -234,7 +233,6 @@ int hns_roce_calc_hem_mhop(struct hns_roce_dev *hr_dev,
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_calc_hem_mhop);
|
||||
|
||||
static struct hns_roce_hem *hns_roce_alloc_hem(struct hns_roce_dev *hr_dev,
|
||||
int npages,
|
||||
@@ -376,18 +374,19 @@ static int hns_roce_set_hem(struct hns_roce_dev *hr_dev,
|
||||
|
||||
bt_cmd = hr_dev->reg_base + ROCEE_BT_CMD_H_REG;
|
||||
|
||||
end = msecs_to_jiffies(HW_SYNC_TIMEOUT_MSECS) + jiffies;
|
||||
while (1) {
|
||||
if (readl(bt_cmd) >> BT_CMD_SYNC_SHIFT) {
|
||||
if (!(time_before(jiffies, end))) {
|
||||
dev_err(dev, "Write bt_cmd err,hw_sync is not zero.\n");
|
||||
spin_unlock_irqrestore(lock, flags);
|
||||
return -EBUSY;
|
||||
}
|
||||
} else {
|
||||
end = HW_SYNC_TIMEOUT_MSECS;
|
||||
while (end) {
|
||||
if (!(readl(bt_cmd) >> BT_CMD_SYNC_SHIFT))
|
||||
break;
|
||||
}
|
||||
|
||||
mdelay(HW_SYNC_SLEEP_TIME_INTERVAL);
|
||||
end -= HW_SYNC_SLEEP_TIME_INTERVAL;
|
||||
}
|
||||
|
||||
if (end <= 0) {
|
||||
dev_err(dev, "Write bt_cmd err,hw_sync is not zero.\n");
|
||||
spin_unlock_irqrestore(lock, flags);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
bt_cmd_l = (u32)bt_ba;
|
||||
@@ -435,7 +434,7 @@ static int hns_roce_table_mhop_get(struct hns_roce_dev *hr_dev,
|
||||
buf_chunk_size = mhop.buf_chunk_size;
|
||||
bt_chunk_size = mhop.bt_chunk_size;
|
||||
hop_num = mhop.hop_num;
|
||||
chunk_ba_num = bt_chunk_size / 8;
|
||||
chunk_ba_num = bt_chunk_size / BA_BYTE_LEN;
|
||||
|
||||
bt_num = hns_roce_get_bt_num(table->type, hop_num);
|
||||
switch (bt_num) {
|
||||
@@ -620,7 +619,6 @@ out:
|
||||
mutex_unlock(&table->mutex);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_table_get);
|
||||
|
||||
static void hns_roce_table_mhop_put(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_hem_table *table,
|
||||
@@ -645,7 +643,7 @@ static void hns_roce_table_mhop_put(struct hns_roce_dev *hr_dev,
|
||||
|
||||
bt_chunk_size = mhop.bt_chunk_size;
|
||||
hop_num = mhop.hop_num;
|
||||
chunk_ba_num = bt_chunk_size / 8;
|
||||
chunk_ba_num = bt_chunk_size / BA_BYTE_LEN;
|
||||
|
||||
bt_num = hns_roce_get_bt_num(table->type, hop_num);
|
||||
switch (bt_num) {
|
||||
@@ -763,7 +761,6 @@ void hns_roce_table_put(struct hns_roce_dev *hr_dev,
|
||||
|
||||
mutex_unlock(&table->mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_table_put);
|
||||
|
||||
void *hns_roce_table_find(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_hem_table *table,
|
||||
@@ -799,7 +796,7 @@ void *hns_roce_table_find(struct hns_roce_dev *hr_dev,
|
||||
i = mhop.l0_idx;
|
||||
j = mhop.l1_idx;
|
||||
if (mhop.hop_num == 2)
|
||||
hem_idx = i * (mhop.bt_chunk_size / 8) + j;
|
||||
hem_idx = i * (mhop.bt_chunk_size / BA_BYTE_LEN) + j;
|
||||
else if (mhop.hop_num == 1 ||
|
||||
mhop.hop_num == HNS_ROCE_HOP_NUM_0)
|
||||
hem_idx = i;
|
||||
@@ -836,7 +833,6 @@ out:
|
||||
mutex_unlock(&table->mutex);
|
||||
return addr;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_table_find);
|
||||
|
||||
int hns_roce_table_get_range(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_hem_table *table,
|
||||
@@ -999,7 +995,7 @@ int hns_roce_init_hem_table(struct hns_roce_dev *hr_dev,
|
||||
}
|
||||
obj_per_chunk = buf_chunk_size / obj_size;
|
||||
num_hem = (nobj + obj_per_chunk - 1) / obj_per_chunk;
|
||||
bt_chunk_num = bt_chunk_size / 8;
|
||||
bt_chunk_num = bt_chunk_size / BA_BYTE_LEN;
|
||||
if (type >= HEM_TYPE_MTT)
|
||||
num_bt_l0 = bt_chunk_num;
|
||||
|
||||
@@ -1156,3 +1152,463 @@ void hns_roce_cleanup_hem(struct hns_roce_dev *hr_dev)
|
||||
&hr_dev->mr_table.mtt_cqe_table);
|
||||
hns_roce_cleanup_hem_table(hr_dev, &hr_dev->mr_table.mtt_table);
|
||||
}
|
||||
|
||||
struct roce_hem_item {
|
||||
struct list_head list; /* link all hems in the same bt level */
|
||||
struct list_head sibling; /* link all hems in last hop for mtt */
|
||||
void *addr;
|
||||
dma_addr_t dma_addr;
|
||||
size_t count; /* max ba numbers */
|
||||
int start; /* start buf offset in this hem */
|
||||
int end; /* end buf offset in this hem */
|
||||
};
|
||||
|
||||
static struct roce_hem_item *hem_list_alloc_item(struct hns_roce_dev *hr_dev,
|
||||
int start, int end,
|
||||
int count, bool exist_bt,
|
||||
int bt_level)
|
||||
{
|
||||
struct roce_hem_item *hem;
|
||||
|
||||
hem = kzalloc(sizeof(*hem), GFP_KERNEL);
|
||||
if (!hem)
|
||||
return NULL;
|
||||
|
||||
if (exist_bt) {
|
||||
hem->addr = dma_alloc_coherent(hr_dev->dev,
|
||||
count * BA_BYTE_LEN,
|
||||
&hem->dma_addr, GFP_KERNEL);
|
||||
if (!hem->addr) {
|
||||
kfree(hem);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
hem->count = count;
|
||||
hem->start = start;
|
||||
hem->end = end;
|
||||
INIT_LIST_HEAD(&hem->list);
|
||||
INIT_LIST_HEAD(&hem->sibling);
|
||||
|
||||
return hem;
|
||||
}
|
||||
|
||||
static void hem_list_free_item(struct hns_roce_dev *hr_dev,
|
||||
struct roce_hem_item *hem, bool exist_bt)
|
||||
{
|
||||
if (exist_bt)
|
||||
dma_free_coherent(hr_dev->dev, hem->count * BA_BYTE_LEN,
|
||||
hem->addr, hem->dma_addr);
|
||||
kfree(hem);
|
||||
}
|
||||
|
||||
static void hem_list_free_all(struct hns_roce_dev *hr_dev,
|
||||
struct list_head *head, bool exist_bt)
|
||||
{
|
||||
struct roce_hem_item *hem, *temp_hem;
|
||||
|
||||
list_for_each_entry_safe(hem, temp_hem, head, list) {
|
||||
list_del(&hem->list);
|
||||
hem_list_free_item(hr_dev, hem, exist_bt);
|
||||
}
|
||||
}
|
||||
|
||||
static void hem_list_link_bt(struct hns_roce_dev *hr_dev, void *base_addr,
|
||||
u64 table_addr)
|
||||
{
|
||||
*(u64 *)(base_addr) = table_addr;
|
||||
}
|
||||
|
||||
/* assign L0 table address to hem from root bt */
|
||||
static void hem_list_assign_bt(struct hns_roce_dev *hr_dev,
|
||||
struct roce_hem_item *hem, void *cpu_addr,
|
||||
u64 phy_addr)
|
||||
{
|
||||
hem->addr = cpu_addr;
|
||||
hem->dma_addr = (dma_addr_t)phy_addr;
|
||||
}
|
||||
|
||||
static inline bool hem_list_page_is_in_range(struct roce_hem_item *hem,
|
||||
int offset)
|
||||
{
|
||||
return (hem->start <= offset && offset <= hem->end);
|
||||
}
|
||||
|
||||
static struct roce_hem_item *hem_list_search_item(struct list_head *ba_list,
|
||||
int page_offset)
|
||||
{
|
||||
struct roce_hem_item *hem, *temp_hem;
|
||||
struct roce_hem_item *found = NULL;
|
||||
|
||||
list_for_each_entry_safe(hem, temp_hem, ba_list, list) {
|
||||
if (hem_list_page_is_in_range(hem, page_offset)) {
|
||||
found = hem;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
static bool hem_list_is_bottom_bt(int hopnum, int bt_level)
|
||||
{
|
||||
/*
|
||||
* hopnum base address table levels
|
||||
* 0 L0(buf)
|
||||
* 1 L0 -> buf
|
||||
* 2 L0 -> L1 -> buf
|
||||
* 3 L0 -> L1 -> L2 -> buf
|
||||
*/
|
||||
return bt_level >= (hopnum ? hopnum - 1 : hopnum);
|
||||
}
|
||||
|
||||
/**
|
||||
* calc base address entries num
|
||||
* @hopnum: num of mutihop addressing
|
||||
* @bt_level: base address table level
|
||||
* @unit: ba entries per bt page
|
||||
*/
|
||||
static u32 hem_list_calc_ba_range(int hopnum, int bt_level, int unit)
|
||||
{
|
||||
u32 step;
|
||||
int max;
|
||||
int i;
|
||||
|
||||
if (hopnum <= bt_level)
|
||||
return 0;
|
||||
/*
|
||||
* hopnum bt_level range
|
||||
* 1 0 unit
|
||||
* ------------
|
||||
* 2 0 unit * unit
|
||||
* 2 1 unit
|
||||
* ------------
|
||||
* 3 0 unit * unit * unit
|
||||
* 3 1 unit * unit
|
||||
* 3 2 unit
|
||||
*/
|
||||
step = 1;
|
||||
max = hopnum - bt_level;
|
||||
for (i = 0; i < max; i++)
|
||||
step = step * unit;
|
||||
|
||||
return step;
|
||||
}
|
||||
|
||||
/**
|
||||
* calc the root ba entries which could cover all regions
|
||||
* @regions: buf region array
|
||||
* @region_cnt: array size of @regions
|
||||
* @unit: ba entries per bt page
|
||||
*/
|
||||
int hns_roce_hem_list_calc_root_ba(const struct hns_roce_buf_region *regions,
|
||||
int region_cnt, int unit)
|
||||
{
|
||||
struct hns_roce_buf_region *r;
|
||||
int total = 0;
|
||||
int step;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < region_cnt; i++) {
|
||||
r = (struct hns_roce_buf_region *)®ions[i];
|
||||
if (r->hopnum > 1) {
|
||||
step = hem_list_calc_ba_range(r->hopnum, 1, unit);
|
||||
if (step > 0)
|
||||
total += (r->count + step - 1) / step;
|
||||
} else {
|
||||
total += r->count;
|
||||
}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
static int hem_list_alloc_mid_bt(struct hns_roce_dev *hr_dev,
|
||||
const struct hns_roce_buf_region *r, int unit,
|
||||
int offset, struct list_head *mid_bt,
|
||||
struct list_head *btm_bt)
|
||||
{
|
||||
struct roce_hem_item *hem_ptrs[HNS_ROCE_MAX_BT_LEVEL] = { NULL };
|
||||
struct list_head temp_list[HNS_ROCE_MAX_BT_LEVEL];
|
||||
struct roce_hem_item *cur, *pre;
|
||||
const int hopnum = r->hopnum;
|
||||
int start_aligned;
|
||||
int distance;
|
||||
int ret = 0;
|
||||
int max_ofs;
|
||||
int level;
|
||||
u32 step;
|
||||
int end;
|
||||
|
||||
if (hopnum <= 1)
|
||||
return 0;
|
||||
|
||||
if (hopnum > HNS_ROCE_MAX_BT_LEVEL) {
|
||||
dev_err(hr_dev->dev, "invalid hopnum %d!\n", hopnum);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (offset < r->offset) {
|
||||
dev_err(hr_dev->dev, "invalid offset %d,min %d!\n",
|
||||
offset, r->offset);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
distance = offset - r->offset;
|
||||
max_ofs = r->offset + r->count - 1;
|
||||
for (level = 0; level < hopnum; level++)
|
||||
INIT_LIST_HEAD(&temp_list[level]);
|
||||
|
||||
/* config L1 bt to last bt and link them to corresponding parent */
|
||||
for (level = 1; level < hopnum; level++) {
|
||||
cur = hem_list_search_item(&mid_bt[level], offset);
|
||||
if (cur) {
|
||||
hem_ptrs[level] = cur;
|
||||
continue;
|
||||
}
|
||||
|
||||
step = hem_list_calc_ba_range(hopnum, level, unit);
|
||||
if (step < 1) {
|
||||
ret = -EINVAL;
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
start_aligned = (distance / step) * step + r->offset;
|
||||
end = min_t(int, start_aligned + step - 1, max_ofs);
|
||||
cur = hem_list_alloc_item(hr_dev, start_aligned, end, unit,
|
||||
true, level);
|
||||
if (!cur) {
|
||||
ret = -ENOMEM;
|
||||
goto err_exit;
|
||||
}
|
||||
hem_ptrs[level] = cur;
|
||||
list_add(&cur->list, &temp_list[level]);
|
||||
if (hem_list_is_bottom_bt(hopnum, level))
|
||||
list_add(&cur->sibling, &temp_list[0]);
|
||||
|
||||
/* link bt to parent bt */
|
||||
if (level > 1) {
|
||||
pre = hem_ptrs[level - 1];
|
||||
step = (cur->start - pre->start) / step * BA_BYTE_LEN;
|
||||
hem_list_link_bt(hr_dev, pre->addr + step,
|
||||
cur->dma_addr);
|
||||
}
|
||||
}
|
||||
|
||||
list_splice(&temp_list[0], btm_bt);
|
||||
for (level = 1; level < hopnum; level++)
|
||||
list_splice(&temp_list[level], &mid_bt[level]);
|
||||
|
||||
return 0;
|
||||
|
||||
err_exit:
|
||||
for (level = 1; level < hopnum; level++)
|
||||
hem_list_free_all(hr_dev, &temp_list[level], true);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hem_list_alloc_root_bt(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_hem_list *hem_list, int unit,
|
||||
const struct hns_roce_buf_region *regions,
|
||||
int region_cnt)
|
||||
{
|
||||
struct roce_hem_item *hem, *temp_hem, *root_hem;
|
||||
struct list_head temp_list[HNS_ROCE_MAX_BT_REGION];
|
||||
const struct hns_roce_buf_region *r;
|
||||
struct list_head temp_root;
|
||||
struct list_head temp_btm;
|
||||
void *cpu_base;
|
||||
u64 phy_base;
|
||||
int ret = 0;
|
||||
int offset;
|
||||
int total;
|
||||
int step;
|
||||
int i;
|
||||
|
||||
r = ®ions[0];
|
||||
root_hem = hem_list_search_item(&hem_list->root_bt, r->offset);
|
||||
if (root_hem)
|
||||
return 0;
|
||||
|
||||
INIT_LIST_HEAD(&temp_root);
|
||||
total = r->offset;
|
||||
/* indicate to last region */
|
||||
r = ®ions[region_cnt - 1];
|
||||
root_hem = hem_list_alloc_item(hr_dev, total, r->offset + r->count - 1,
|
||||
unit, true, 0);
|
||||
if (!root_hem)
|
||||
return -ENOMEM;
|
||||
list_add(&root_hem->list, &temp_root);
|
||||
|
||||
hem_list->root_ba = root_hem->dma_addr;
|
||||
|
||||
INIT_LIST_HEAD(&temp_btm);
|
||||
for (i = 0; i < region_cnt; i++)
|
||||
INIT_LIST_HEAD(&temp_list[i]);
|
||||
|
||||
total = 0;
|
||||
for (i = 0; i < region_cnt && total < unit; i++) {
|
||||
r = ®ions[i];
|
||||
if (!r->count)
|
||||
continue;
|
||||
|
||||
/* all regions's mid[x][0] shared the root_bt's trunk */
|
||||
cpu_base = root_hem->addr + total * BA_BYTE_LEN;
|
||||
phy_base = root_hem->dma_addr + total * BA_BYTE_LEN;
|
||||
|
||||
/* if hopnum is 0 or 1, cut a new fake hem from the root bt
|
||||
* which's address share to all regions.
|
||||
*/
|
||||
if (hem_list_is_bottom_bt(r->hopnum, 0)) {
|
||||
hem = hem_list_alloc_item(hr_dev, r->offset,
|
||||
r->offset + r->count - 1,
|
||||
r->count, false, 0);
|
||||
if (!hem) {
|
||||
ret = -ENOMEM;
|
||||
goto err_exit;
|
||||
}
|
||||
hem_list_assign_bt(hr_dev, hem, cpu_base, phy_base);
|
||||
list_add(&hem->list, &temp_list[i]);
|
||||
list_add(&hem->sibling, &temp_btm);
|
||||
total += r->count;
|
||||
} else {
|
||||
step = hem_list_calc_ba_range(r->hopnum, 1, unit);
|
||||
if (step < 1) {
|
||||
ret = -EINVAL;
|
||||
goto err_exit;
|
||||
}
|
||||
/* if exist mid bt, link L1 to L0 */
|
||||
list_for_each_entry_safe(hem, temp_hem,
|
||||
&hem_list->mid_bt[i][1], list) {
|
||||
offset = hem->start / step * BA_BYTE_LEN;
|
||||
hem_list_link_bt(hr_dev, cpu_base + offset,
|
||||
hem->dma_addr);
|
||||
total++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list_splice(&temp_btm, &hem_list->btm_bt);
|
||||
list_splice(&temp_root, &hem_list->root_bt);
|
||||
for (i = 0; i < region_cnt; i++)
|
||||
list_splice(&temp_list[i], &hem_list->mid_bt[i][0]);
|
||||
|
||||
return 0;
|
||||
|
||||
err_exit:
|
||||
for (i = 0; i < region_cnt; i++)
|
||||
hem_list_free_all(hr_dev, &temp_list[i], false);
|
||||
|
||||
hem_list_free_all(hr_dev, &temp_root, true);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* construct the base address table and link them by address hop config */
|
||||
int hns_roce_hem_list_request(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_hem_list *hem_list,
|
||||
const struct hns_roce_buf_region *regions,
|
||||
int region_cnt)
|
||||
{
|
||||
const struct hns_roce_buf_region *r;
|
||||
int ofs, end;
|
||||
int ret = 0;
|
||||
int unit;
|
||||
int i;
|
||||
|
||||
if (region_cnt > HNS_ROCE_MAX_BT_REGION) {
|
||||
dev_err(hr_dev->dev, "invalid region region_cnt %d!\n",
|
||||
region_cnt);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
unit = (1 << hem_list->bt_pg_shift) / BA_BYTE_LEN;
|
||||
for (i = 0; i < region_cnt; i++) {
|
||||
r = ®ions[i];
|
||||
if (!r->count)
|
||||
continue;
|
||||
|
||||
end = r->offset + r->count;
|
||||
for (ofs = r->offset; ofs < end; ofs += unit) {
|
||||
ret = hem_list_alloc_mid_bt(hr_dev, r, unit, ofs,
|
||||
hem_list->mid_bt[i],
|
||||
&hem_list->btm_bt);
|
||||
if (ret) {
|
||||
dev_err(hr_dev->dev,
|
||||
"alloc hem trunk fail ret=%d!\n", ret);
|
||||
goto err_alloc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = hem_list_alloc_root_bt(hr_dev, hem_list, unit, regions,
|
||||
region_cnt);
|
||||
if (ret)
|
||||
dev_err(hr_dev->dev, "alloc hem root fail ret=%d!\n", ret);
|
||||
else
|
||||
return 0;
|
||||
|
||||
err_alloc:
|
||||
hns_roce_hem_list_release(hr_dev, hem_list);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void hns_roce_hem_list_release(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_hem_list *hem_list)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < HNS_ROCE_MAX_BT_REGION; i++)
|
||||
for (j = 0; j < HNS_ROCE_MAX_BT_LEVEL; j++)
|
||||
hem_list_free_all(hr_dev, &hem_list->mid_bt[i][j],
|
||||
j != 0);
|
||||
|
||||
hem_list_free_all(hr_dev, &hem_list->root_bt, true);
|
||||
INIT_LIST_HEAD(&hem_list->btm_bt);
|
||||
hem_list->root_ba = 0;
|
||||
}
|
||||
|
||||
void hns_roce_hem_list_init(struct hns_roce_hem_list *hem_list,
|
||||
int bt_page_order)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
INIT_LIST_HEAD(&hem_list->root_bt);
|
||||
INIT_LIST_HEAD(&hem_list->btm_bt);
|
||||
for (i = 0; i < HNS_ROCE_MAX_BT_REGION; i++)
|
||||
for (j = 0; j < HNS_ROCE_MAX_BT_LEVEL; j++)
|
||||
INIT_LIST_HEAD(&hem_list->mid_bt[i][j]);
|
||||
|
||||
hem_list->bt_pg_shift = bt_page_order;
|
||||
}
|
||||
|
||||
void *hns_roce_hem_list_find_mtt(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_hem_list *hem_list,
|
||||
int offset, int *mtt_cnt, u64 *phy_addr)
|
||||
{
|
||||
struct list_head *head = &hem_list->btm_bt;
|
||||
struct roce_hem_item *hem, *temp_hem;
|
||||
void *cpu_base = NULL;
|
||||
u64 phy_base = 0;
|
||||
int nr = 0;
|
||||
|
||||
list_for_each_entry_safe(hem, temp_hem, head, sibling) {
|
||||
if (hem_list_page_is_in_range(hem, offset)) {
|
||||
nr = offset - hem->start;
|
||||
cpu_base = hem->addr + nr * BA_BYTE_LEN;
|
||||
phy_base = hem->dma_addr + nr * BA_BYTE_LEN;
|
||||
nr = hem->end + 1 - offset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mtt_cnt)
|
||||
*mtt_cnt = nr;
|
||||
|
||||
if (phy_addr)
|
||||
*phy_addr = phy_base;
|
||||
|
||||
return cpu_base;
|
||||
}
|
||||
|
@@ -34,8 +34,8 @@
|
||||
#ifndef _HNS_ROCE_HEM_H
|
||||
#define _HNS_ROCE_HEM_H
|
||||
|
||||
#define HW_SYNC_TIMEOUT_MSECS 500
|
||||
#define HW_SYNC_SLEEP_TIME_INTERVAL 20
|
||||
#define HW_SYNC_TIMEOUT_MSECS (25 * HW_SYNC_SLEEP_TIME_INTERVAL)
|
||||
#define BT_CMD_SYNC_SHIFT 31
|
||||
|
||||
enum {
|
||||
@@ -133,6 +133,20 @@ int hns_roce_calc_hem_mhop(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_hem_mhop *mhop);
|
||||
bool hns_roce_check_whether_mhop(struct hns_roce_dev *hr_dev, u32 type);
|
||||
|
||||
void hns_roce_hem_list_init(struct hns_roce_hem_list *hem_list,
|
||||
int bt_page_order);
|
||||
int hns_roce_hem_list_calc_root_ba(const struct hns_roce_buf_region *regions,
|
||||
int region_cnt, int unit);
|
||||
int hns_roce_hem_list_request(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_hem_list *hem_list,
|
||||
const struct hns_roce_buf_region *regions,
|
||||
int region_cnt);
|
||||
void hns_roce_hem_list_release(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_hem_list *hem_list);
|
||||
void *hns_roce_hem_list_find_mtt(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_hem_list *hem_list,
|
||||
int offset, int *mtt_cnt, u64 *phy_addr);
|
||||
|
||||
static inline void hns_roce_hem_first(struct hns_roce_hem *hem,
|
||||
struct hns_roce_hem_iter *iter)
|
||||
{
|
||||
|
@@ -717,7 +717,7 @@ static int hns_roce_v1_rsv_lp_qp(struct hns_roce_dev *hr_dev)
|
||||
union ib_gid dgid;
|
||||
u64 subnet_prefix;
|
||||
int attr_mask = 0;
|
||||
int ret = -ENOMEM;
|
||||
int ret;
|
||||
int i, j;
|
||||
u8 queue_en[HNS_ROCE_V1_RESV_QP] = { 0 };
|
||||
u8 phy_port;
|
||||
@@ -730,10 +730,16 @@ static int hns_roce_v1_rsv_lp_qp(struct hns_roce_dev *hr_dev)
|
||||
/* Reserved cq for loop qp */
|
||||
cq_init_attr.cqe = HNS_ROCE_MIN_WQE_NUM * 2;
|
||||
cq_init_attr.comp_vector = 0;
|
||||
cq = hns_roce_ib_create_cq(&hr_dev->ib_dev, &cq_init_attr, NULL);
|
||||
if (IS_ERR(cq)) {
|
||||
dev_err(dev, "Create cq for reserved loop qp failed!");
|
||||
|
||||
ibdev = &hr_dev->ib_dev;
|
||||
cq = rdma_zalloc_drv_obj(ibdev, ib_cq);
|
||||
if (!cq)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = hns_roce_ib_create_cq(cq, &cq_init_attr, NULL);
|
||||
if (ret) {
|
||||
dev_err(dev, "Create cq for reserved loop qp failed!");
|
||||
goto alloc_cq_failed;
|
||||
}
|
||||
free_mr->mr_free_cq = to_hr_cq(cq);
|
||||
free_mr->mr_free_cq->ib_cq.device = &hr_dev->ib_dev;
|
||||
@@ -743,7 +749,6 @@ static int hns_roce_v1_rsv_lp_qp(struct hns_roce_dev *hr_dev)
|
||||
free_mr->mr_free_cq->ib_cq.cq_context = NULL;
|
||||
atomic_set(&free_mr->mr_free_cq->ib_cq.usecnt, 0);
|
||||
|
||||
ibdev = &hr_dev->ib_dev;
|
||||
pd = rdma_zalloc_drv_obj(ibdev, ib_pd);
|
||||
if (!pd)
|
||||
goto alloc_mem_failed;
|
||||
@@ -818,7 +823,7 @@ static int hns_roce_v1_rsv_lp_qp(struct hns_roce_dev *hr_dev)
|
||||
attr.dest_qp_num = hr_qp->qpn;
|
||||
memcpy(rdma_ah_retrieve_dmac(&attr.ah_attr),
|
||||
hr_dev->dev_addr[port],
|
||||
MAC_ADDR_OCTET_NUM);
|
||||
ETH_ALEN);
|
||||
|
||||
memcpy(&dgid.raw, &subnet_prefix, sizeof(u64));
|
||||
memcpy(&dgid.raw[8], hr_dev->dev_addr[port], 3);
|
||||
@@ -865,9 +870,9 @@ alloc_pd_failed:
|
||||
kfree(pd);
|
||||
|
||||
alloc_mem_failed:
|
||||
if (hns_roce_ib_destroy_cq(cq, NULL))
|
||||
dev_err(dev, "Destroy cq for create_lp_qp failed!\n");
|
||||
|
||||
hns_roce_ib_destroy_cq(cq, NULL);
|
||||
alloc_cq_failed:
|
||||
kfree(cq);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -894,10 +899,8 @@ static void hns_roce_v1_release_lp_qp(struct hns_roce_dev *hr_dev)
|
||||
i, ret);
|
||||
}
|
||||
|
||||
ret = hns_roce_ib_destroy_cq(&free_mr->mr_free_cq->ib_cq, NULL);
|
||||
if (ret)
|
||||
dev_err(dev, "Destroy cq for mr_free failed(%d)!\n", ret);
|
||||
|
||||
hns_roce_ib_destroy_cq(&free_mr->mr_free_cq->ib_cq, NULL);
|
||||
kfree(&free_mr->mr_free_cq->ib_cq);
|
||||
hns_roce_dealloc_pd(&free_mr->mr_free_pd->ibpd, NULL);
|
||||
kfree(&free_mr->mr_free_pd->ibpd);
|
||||
}
|
||||
@@ -966,8 +969,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 =
|
||||
msecs_to_jiffies(HNS_ROCE_V1_RECREATE_LP_QP_TIMEOUT_MSECS) + jiffies;
|
||||
unsigned long end = HNS_ROCE_V1_RECREATE_LP_QP_TIMEOUT_MSECS;
|
||||
|
||||
priv = (struct hns_roce_v1_priv *)hr_dev->priv;
|
||||
free_mr = &priv->free_mr;
|
||||
@@ -987,10 +989,11 @@ 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 (time_before_eq(jiffies, end)) {
|
||||
while (end) {
|
||||
if (try_wait_for_completion(&comp))
|
||||
return 0;
|
||||
msleep(HNS_ROCE_V1_RECREATE_LP_QP_WAIT_VALUE);
|
||||
end -= HNS_ROCE_V1_RECREATE_LP_QP_WAIT_VALUE;
|
||||
}
|
||||
|
||||
lp_qp_work->comp_flag = 0;
|
||||
@@ -1104,8 +1107,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 =
|
||||
msecs_to_jiffies(HNS_ROCE_V1_FREE_MR_TIMEOUT_MSECS) + jiffies;
|
||||
unsigned long end = HNS_ROCE_V1_FREE_MR_TIMEOUT_MSECS;
|
||||
unsigned long start = jiffies;
|
||||
int npages;
|
||||
int ret = 0;
|
||||
@@ -1135,10 +1137,11 @@ static int hns_roce_v1_dereg_mr(struct hns_roce_dev *hr_dev,
|
||||
|
||||
queue_work(free_mr->free_mr_wq, &(mr_work->work));
|
||||
|
||||
while (time_before_eq(jiffies, end)) {
|
||||
while (end) {
|
||||
if (try_wait_for_completion(&comp))
|
||||
goto free_mr;
|
||||
msleep(HNS_ROCE_V1_FREE_MR_WAIT_VALUE);
|
||||
end -= HNS_ROCE_V1_FREE_MR_WAIT_VALUE;
|
||||
}
|
||||
|
||||
mr_work->comp_flag = 0;
|
||||
@@ -1161,8 +1164,7 @@ free_mr:
|
||||
hns_roce_bitmap_free(&hr_dev->mr_table.mtpt_bitmap,
|
||||
key_to_hw_index(mr->key), 0);
|
||||
|
||||
if (mr->umem)
|
||||
ib_umem_release(mr->umem);
|
||||
ib_umem_release(mr->umem);
|
||||
|
||||
kfree(mr);
|
||||
|
||||
@@ -1557,6 +1559,7 @@ static int hns_roce_v1_profile(struct hns_roce_dev *hr_dev)
|
||||
caps->reserved_mrws = 1;
|
||||
caps->reserved_uars = 0;
|
||||
caps->reserved_cqs = 0;
|
||||
caps->reserved_qps = 12; /* 2 SQP per port, six ports total 12 */
|
||||
caps->chunk_sz = HNS_ROCE_V1_TABLE_CHUNK_SIZE;
|
||||
|
||||
for (i = 0; i < caps->num_ports; i++)
|
||||
@@ -1742,11 +1745,14 @@ static int hns_roce_v1_set_gid(struct hns_roce_dev *hr_dev, u8 port,
|
||||
int gid_index, const union ib_gid *gid,
|
||||
const struct ib_gid_attr *attr)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 *p = NULL;
|
||||
u8 gid_idx = 0;
|
||||
|
||||
gid_idx = hns_get_gid_index(hr_dev, port, gid_index);
|
||||
|
||||
spin_lock_irqsave(&hr_dev->iboe.lock, flags);
|
||||
|
||||
p = (u32 *)&gid->raw[0];
|
||||
roce_raw_write(*p, hr_dev->reg_base + ROCEE_PORT_GID_L_0_REG +
|
||||
(HNS_ROCE_V1_GID_NUM * gid_idx));
|
||||
@@ -1763,6 +1769,8 @@ static int hns_roce_v1_set_gid(struct hns_roce_dev *hr_dev, u8 port,
|
||||
roce_raw_write(*p, hr_dev->reg_base + ROCEE_PORT_GID_H_0_REG +
|
||||
(HNS_ROCE_V1_GID_NUM * gid_idx));
|
||||
|
||||
spin_unlock_irqrestore(&hr_dev->iboe.lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2458,10 +2466,10 @@ 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 = msecs_to_jiffies(HW_SYNC_TIMEOUT_MSECS) + jiffies;
|
||||
end = HW_SYNC_TIMEOUT_MSECS;
|
||||
while (1) {
|
||||
if (readl(bt_cmd) >> BT_CMD_SYNC_SHIFT) {
|
||||
if (!(time_before(jiffies, end))) {
|
||||
if (!end) {
|
||||
dev_err(dev, "Write bt_cmd err,hw_sync is not zero.\n");
|
||||
spin_unlock_irqrestore(&hr_dev->bt_cmd_lock,
|
||||
flags);
|
||||
@@ -2470,7 +2478,8 @@ static int hns_roce_v1_clear_hem(struct hns_roce_dev *hr_dev,
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
msleep(HW_SYNC_SLEEP_TIME_INTERVAL);
|
||||
mdelay(HW_SYNC_SLEEP_TIME_INTERVAL);
|
||||
end -= HW_SYNC_SLEEP_TIME_INTERVAL;
|
||||
}
|
||||
|
||||
bt_cmd_val[0] = (__le32)bt_ba;
|
||||
@@ -3633,9 +3642,8 @@ int hns_roce_v1_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
|
||||
|
||||
hns_roce_mtt_cleanup(hr_dev, &hr_qp->mtt);
|
||||
|
||||
if (udata)
|
||||
ib_umem_release(hr_qp->umem);
|
||||
else {
|
||||
ib_umem_release(hr_qp->umem);
|
||||
if (!udata) {
|
||||
kfree(hr_qp->sq.wrid);
|
||||
kfree(hr_qp->rq.wrid);
|
||||
|
||||
@@ -3649,7 +3657,7 @@ int hns_roce_v1_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hns_roce_v1_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
|
||||
static void hns_roce_v1_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
|
||||
{
|
||||
struct hns_roce_dev *hr_dev = to_hr_dev(ibcq->device);
|
||||
struct hns_roce_cq *hr_cq = to_hr_cq(ibcq);
|
||||
@@ -3658,7 +3666,6 @@ static int hns_roce_v1_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
|
||||
u32 cqe_cnt_cur;
|
||||
u32 cq_buf_size;
|
||||
int wait_time = 0;
|
||||
int ret = 0;
|
||||
|
||||
hns_roce_free_cq(hr_dev, hr_cq);
|
||||
|
||||
@@ -3680,7 +3687,6 @@ static int hns_roce_v1_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
|
||||
if (wait_time > HNS_ROCE_MAX_FREE_CQ_WAIT_CNT) {
|
||||
dev_warn(dev, "Destroy cq 0x%lx timeout!\n",
|
||||
hr_cq->cqn);
|
||||
ret = -ETIMEDOUT;
|
||||
break;
|
||||
}
|
||||
wait_time++;
|
||||
@@ -3688,17 +3694,12 @@ static int hns_roce_v1_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
|
||||
|
||||
hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt);
|
||||
|
||||
if (ibcq->uobject)
|
||||
ib_umem_release(hr_cq->umem);
|
||||
else {
|
||||
ib_umem_release(hr_cq->umem);
|
||||
if (!udata) {
|
||||
/* Free the buff of stored cq */
|
||||
cq_buf_size = (ibcq->cqe + 1) * hr_dev->caps.cq_entry_sz;
|
||||
hns_roce_buf_free(hr_dev, cq_buf_size, &hr_cq->hr_buf.hr_buf);
|
||||
}
|
||||
|
||||
kfree(hr_cq);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void set_eq_cons_index_v1(struct hns_roce_eq *eq, int req_not)
|
||||
@@ -3902,7 +3903,8 @@ static int hns_roce_v1_aeq_int(struct hns_roce_dev *hr_dev,
|
||||
*/
|
||||
dma_rmb();
|
||||
|
||||
dev_dbg(dev, "aeqe = %p, aeqe->asyn.event_type = 0x%lx\n", aeqe,
|
||||
dev_dbg(dev, "aeqe = %pK, aeqe->asyn.event_type = 0x%lx\n",
|
||||
aeqe,
|
||||
roce_get_field(aeqe->asyn,
|
||||
HNS_ROCE_AEQE_U32_4_EVENT_TYPE_M,
|
||||
HNS_ROCE_AEQE_U32_4_EVENT_TYPE_S));
|
||||
@@ -4265,7 +4267,6 @@ static int hns_roce_v1_create_eq(struct hns_roce_dev *hr_dev,
|
||||
}
|
||||
|
||||
eq->buf_list[i].map = tmp_dma_addr;
|
||||
memset(eq->buf_list[i].buf, 0, HNS_ROCE_BA_SIZE);
|
||||
}
|
||||
eq->cons_index = 0;
|
||||
roce_set_field(tmp, ROCEE_CAEP_AEQC_AEQE_SHIFT_CAEP_AEQC_STATE_M,
|
||||
|
@@ -1098,7 +1098,7 @@ static int hns_roce_cmq_send(struct hns_roce_dev *hr_dev,
|
||||
if (ret == CMD_RST_PRC_SUCCESS)
|
||||
return 0;
|
||||
if (ret == CMD_RST_PRC_EBUSY)
|
||||
return ret;
|
||||
return -EBUSY;
|
||||
|
||||
ret = __hns_roce_cmq_send(hr_dev, desc, num);
|
||||
if (ret) {
|
||||
@@ -1106,7 +1106,7 @@ static int hns_roce_cmq_send(struct hns_roce_dev *hr_dev,
|
||||
if (retval == CMD_RST_PRC_SUCCESS)
|
||||
return 0;
|
||||
else if (retval == CMD_RST_PRC_EBUSY)
|
||||
return retval;
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -1130,6 +1130,45 @@ static int hns_roce_cmq_query_hw_info(struct hns_roce_dev *hr_dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hns_roce_function_clear(struct hns_roce_dev *hr_dev)
|
||||
{
|
||||
struct hns_roce_func_clear *resp;
|
||||
struct hns_roce_cmq_desc desc;
|
||||
unsigned long end;
|
||||
int ret;
|
||||
|
||||
hns_roce_cmq_setup_basic_desc(&desc, HNS_ROCE_OPC_FUNC_CLEAR, false);
|
||||
resp = (struct hns_roce_func_clear *)desc.data;
|
||||
|
||||
ret = hns_roce_cmq_send(hr_dev, &desc, 1);
|
||||
if (ret) {
|
||||
dev_err(hr_dev->dev, "Func clear write failed, ret = %d.\n",
|
||||
ret);
|
||||
return;
|
||||
}
|
||||
|
||||
msleep(HNS_ROCE_V2_READ_FUNC_CLEAR_FLAG_INTERVAL);
|
||||
end = HNS_ROCE_V2_FUNC_CLEAR_TIMEOUT_MSECS;
|
||||
while (end) {
|
||||
msleep(HNS_ROCE_V2_READ_FUNC_CLEAR_FLAG_FAIL_WAIT);
|
||||
end -= HNS_ROCE_V2_READ_FUNC_CLEAR_FLAG_FAIL_WAIT;
|
||||
|
||||
hns_roce_cmq_setup_basic_desc(&desc, HNS_ROCE_OPC_FUNC_CLEAR,
|
||||
true);
|
||||
|
||||
ret = hns_roce_cmq_send(hr_dev, &desc, 1);
|
||||
if (ret)
|
||||
continue;
|
||||
|
||||
if (roce_get_bit(resp->func_done, FUNC_CLEAR_RST_FUN_DONE_S)) {
|
||||
hr_dev->is_reset = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
dev_err(hr_dev->dev, "Func clear fail.\n");
|
||||
}
|
||||
|
||||
static int hns_roce_query_fw_ver(struct hns_roce_dev *hr_dev)
|
||||
{
|
||||
struct hns_roce_query_fw_info *resp;
|
||||
@@ -1574,7 +1613,10 @@ static int hns_roce_v2_profile(struct hns_roce_dev *hr_dev)
|
||||
caps->mtt_ba_pg_sz = 0;
|
||||
caps->mtt_buf_pg_sz = 0;
|
||||
caps->mtt_hop_num = HNS_ROCE_MTT_HOP_NUM;
|
||||
caps->cqe_ba_pg_sz = 0;
|
||||
caps->wqe_sq_hop_num = 2;
|
||||
caps->wqe_sge_hop_num = 1;
|
||||
caps->wqe_rq_hop_num = 2;
|
||||
caps->cqe_ba_pg_sz = 6;
|
||||
caps->cqe_buf_pg_sz = 0;
|
||||
caps->cqe_hop_num = HNS_ROCE_CQE_HOP_NUM;
|
||||
caps->srqwqe_ba_pg_sz = 0;
|
||||
@@ -1774,7 +1816,6 @@ static int hns_roce_init_link_table(struct hns_roce_dev *hr_dev,
|
||||
goto err_alloc_buf_failed;
|
||||
|
||||
link_tbl->pg_list[i].map = t;
|
||||
memset(link_tbl->pg_list[i].buf, 0, buf_chk_sz);
|
||||
|
||||
entry[i].blk_ba0 = (t >> 12) & 0xffffffff;
|
||||
roce_set_field(entry[i].blk_ba1_nxt_ptr,
|
||||
@@ -1891,6 +1932,9 @@ static void hns_roce_v2_exit(struct hns_roce_dev *hr_dev)
|
||||
{
|
||||
struct hns_roce_v2_priv *priv = hr_dev->priv;
|
||||
|
||||
if (hr_dev->pci_dev->revision == 0x21)
|
||||
hns_roce_function_clear(hr_dev);
|
||||
|
||||
hns_roce_free_link_table(hr_dev, &priv->tpq);
|
||||
hns_roce_free_link_table(hr_dev, &priv->tsq);
|
||||
}
|
||||
@@ -1974,7 +2018,7 @@ static int hns_roce_v2_chk_mbox(struct hns_roce_dev *hr_dev,
|
||||
unsigned long timeout)
|
||||
{
|
||||
struct device *dev = hr_dev->dev;
|
||||
unsigned long end = 0;
|
||||
unsigned long end;
|
||||
u32 status;
|
||||
|
||||
end = msecs_to_jiffies(timeout) + jiffies;
|
||||
@@ -2340,15 +2384,10 @@ static void *get_srq_wqe(struct hns_roce_srq *srq, int n)
|
||||
|
||||
static void hns_roce_free_srq_wqe(struct hns_roce_srq *srq, int wqe_index)
|
||||
{
|
||||
u32 bitmap_num;
|
||||
int bit_num;
|
||||
|
||||
/* always called with interrupts disabled. */
|
||||
spin_lock(&srq->lock);
|
||||
|
||||
bitmap_num = wqe_index / (sizeof(u64) * 8);
|
||||
bit_num = wqe_index % (sizeof(u64) * 8);
|
||||
srq->idx_que.bitmap[bitmap_num] |= (1ULL << bit_num);
|
||||
bitmap_clear(srq->idx_que.bitmap, wqe_index, 1);
|
||||
srq->tail++;
|
||||
|
||||
spin_unlock(&srq->lock);
|
||||
@@ -2977,7 +3016,7 @@ static int hns_roce_v2_clear_hem(struct hns_roce_dev *hr_dev,
|
||||
{
|
||||
struct device *dev = hr_dev->dev;
|
||||
struct hns_roce_cmd_mailbox *mailbox;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
u16 op = 0xff;
|
||||
|
||||
if (!hns_roce_check_whether_mhop(hr_dev, table->type))
|
||||
@@ -3026,7 +3065,6 @@ static int hns_roce_v2_clear_hem(struct hns_roce_dev *hr_dev,
|
||||
}
|
||||
|
||||
static int hns_roce_v2_qp_modify(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_mtt *mtt,
|
||||
enum ib_qp_state cur_state,
|
||||
enum ib_qp_state new_state,
|
||||
struct hns_roce_v2_qp_context *context,
|
||||
@@ -3426,7 +3464,9 @@ static void modify_qp_init_to_init(struct ib_qp *ibqp,
|
||||
else
|
||||
roce_set_field(context->byte_4_sqpn_tst,
|
||||
V2_QPC_BYTE_4_SGE_SHIFT_M,
|
||||
V2_QPC_BYTE_4_SGE_SHIFT_S, hr_qp->sq.max_gs > 2 ?
|
||||
V2_QPC_BYTE_4_SGE_SHIFT_S,
|
||||
hr_qp->sq.max_gs >
|
||||
HNS_ROCE_V2_UC_RC_SGE_NUM_IN_WQE ?
|
||||
ilog2((unsigned int)hr_qp->sge.sge_cnt) : 0);
|
||||
|
||||
roce_set_field(qpc_mask->byte_4_sqpn_tst, V2_QPC_BYTE_4_SGE_SHIFT_M,
|
||||
@@ -3520,6 +3560,31 @@ static void modify_qp_init_to_init(struct ib_qp *ibqp,
|
||||
}
|
||||
}
|
||||
|
||||
static bool check_wqe_rq_mtt_count(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_qp *hr_qp, int mtt_cnt,
|
||||
u32 page_size)
|
||||
{
|
||||
struct device *dev = hr_dev->dev;
|
||||
|
||||
if (hr_qp->rq.wqe_cnt < 1)
|
||||
return true;
|
||||
|
||||
if (mtt_cnt < 1) {
|
||||
dev_err(dev, "qp(0x%lx) rqwqe buf ba find failed\n",
|
||||
hr_qp->qpn);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mtt_cnt < MTT_MIN_COUNT &&
|
||||
(hr_qp->rq.offset + page_size) < hr_qp->buff_size) {
|
||||
dev_err(dev, "qp(0x%lx) next rqwqe buf ba find failed\n",
|
||||
hr_qp->qpn);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
|
||||
const struct ib_qp_attr *attr, int attr_mask,
|
||||
struct hns_roce_v2_qp_context *context,
|
||||
@@ -3529,25 +3594,27 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
|
||||
struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
|
||||
struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
|
||||
struct device *dev = hr_dev->dev;
|
||||
u64 mtts[MTT_MIN_COUNT] = { 0 };
|
||||
dma_addr_t dma_handle_3;
|
||||
dma_addr_t dma_handle_2;
|
||||
dma_addr_t dma_handle;
|
||||
u64 wqe_sge_ba;
|
||||
u32 page_size;
|
||||
u8 port_num;
|
||||
u64 *mtts_3;
|
||||
u64 *mtts_2;
|
||||
u64 *mtts;
|
||||
int count;
|
||||
u8 *dmac;
|
||||
u8 *smac;
|
||||
int port;
|
||||
|
||||
/* Search qp buf's mtts */
|
||||
mtts = hns_roce_table_find(hr_dev, &hr_dev->mr_table.mtt_table,
|
||||
hr_qp->mtt.first_seg, &dma_handle);
|
||||
if (!mtts) {
|
||||
dev_err(dev, "qp buf pa find failed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
page_size = 1 << (hr_dev->caps.mtt_buf_pg_sz + PAGE_SHIFT);
|
||||
count = hns_roce_mtr_find(hr_dev, &hr_qp->mtr,
|
||||
hr_qp->rq.offset / page_size, mtts,
|
||||
MTT_MIN_COUNT, &wqe_sge_ba);
|
||||
if (!ibqp->srq)
|
||||
if (!check_wqe_rq_mtt_count(hr_dev, hr_qp, count, page_size))
|
||||
return -EINVAL;
|
||||
|
||||
/* Search IRRL's mtts */
|
||||
mtts_2 = hns_roce_table_find(hr_dev, &hr_dev->qp_table.irrl_table,
|
||||
@@ -3571,7 +3638,7 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
|
||||
}
|
||||
|
||||
dmac = (u8 *)attr->ah_attr.roce.dmac;
|
||||
context->wqe_sge_ba = (u32)(dma_handle >> 3);
|
||||
context->wqe_sge_ba = (u32)(wqe_sge_ba >> 3);
|
||||
qpc_mask->wqe_sge_ba = 0;
|
||||
|
||||
/*
|
||||
@@ -3581,22 +3648,23 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
|
||||
* 0 at the same time, else set them to 0x1.
|
||||
*/
|
||||
roce_set_field(context->byte_12_sq_hop, V2_QPC_BYTE_12_WQE_SGE_BA_M,
|
||||
V2_QPC_BYTE_12_WQE_SGE_BA_S, dma_handle >> (32 + 3));
|
||||
V2_QPC_BYTE_12_WQE_SGE_BA_S, wqe_sge_ba >> (32 + 3));
|
||||
roce_set_field(qpc_mask->byte_12_sq_hop, V2_QPC_BYTE_12_WQE_SGE_BA_M,
|
||||
V2_QPC_BYTE_12_WQE_SGE_BA_S, 0);
|
||||
|
||||
roce_set_field(context->byte_12_sq_hop, V2_QPC_BYTE_12_SQ_HOP_NUM_M,
|
||||
V2_QPC_BYTE_12_SQ_HOP_NUM_S,
|
||||
hr_dev->caps.mtt_hop_num == HNS_ROCE_HOP_NUM_0 ?
|
||||
0 : hr_dev->caps.mtt_hop_num);
|
||||
hr_dev->caps.wqe_sq_hop_num == HNS_ROCE_HOP_NUM_0 ?
|
||||
0 : hr_dev->caps.wqe_sq_hop_num);
|
||||
roce_set_field(qpc_mask->byte_12_sq_hop, V2_QPC_BYTE_12_SQ_HOP_NUM_M,
|
||||
V2_QPC_BYTE_12_SQ_HOP_NUM_S, 0);
|
||||
|
||||
roce_set_field(context->byte_20_smac_sgid_idx,
|
||||
V2_QPC_BYTE_20_SGE_HOP_NUM_M,
|
||||
V2_QPC_BYTE_20_SGE_HOP_NUM_S,
|
||||
((ibqp->qp_type == IB_QPT_GSI) || hr_qp->sq.max_gs > 2) ?
|
||||
hr_dev->caps.mtt_hop_num : 0);
|
||||
((ibqp->qp_type == IB_QPT_GSI) ||
|
||||
hr_qp->sq.max_gs > HNS_ROCE_V2_UC_RC_SGE_NUM_IN_WQE) ?
|
||||
hr_dev->caps.wqe_sge_hop_num : 0);
|
||||
roce_set_field(qpc_mask->byte_20_smac_sgid_idx,
|
||||
V2_QPC_BYTE_20_SGE_HOP_NUM_M,
|
||||
V2_QPC_BYTE_20_SGE_HOP_NUM_S, 0);
|
||||
@@ -3604,8 +3672,8 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
|
||||
roce_set_field(context->byte_20_smac_sgid_idx,
|
||||
V2_QPC_BYTE_20_RQ_HOP_NUM_M,
|
||||
V2_QPC_BYTE_20_RQ_HOP_NUM_S,
|
||||
hr_dev->caps.mtt_hop_num == HNS_ROCE_HOP_NUM_0 ?
|
||||
0 : hr_dev->caps.mtt_hop_num);
|
||||
hr_dev->caps.wqe_rq_hop_num == HNS_ROCE_HOP_NUM_0 ?
|
||||
0 : hr_dev->caps.wqe_rq_hop_num);
|
||||
roce_set_field(qpc_mask->byte_20_smac_sgid_idx,
|
||||
V2_QPC_BYTE_20_RQ_HOP_NUM_M,
|
||||
V2_QPC_BYTE_20_RQ_HOP_NUM_S, 0);
|
||||
@@ -3613,7 +3681,7 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
|
||||
roce_set_field(context->byte_16_buf_ba_pg_sz,
|
||||
V2_QPC_BYTE_16_WQE_SGE_BA_PG_SZ_M,
|
||||
V2_QPC_BYTE_16_WQE_SGE_BA_PG_SZ_S,
|
||||
hr_dev->caps.mtt_ba_pg_sz + PG_SHIFT_OFFSET);
|
||||
hr_qp->wqe_bt_pg_shift + PG_SHIFT_OFFSET);
|
||||
roce_set_field(qpc_mask->byte_16_buf_ba_pg_sz,
|
||||
V2_QPC_BYTE_16_WQE_SGE_BA_PG_SZ_M,
|
||||
V2_QPC_BYTE_16_WQE_SGE_BA_PG_SZ_S, 0);
|
||||
@@ -3626,29 +3694,24 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
|
||||
V2_QPC_BYTE_16_WQE_SGE_BUF_PG_SZ_M,
|
||||
V2_QPC_BYTE_16_WQE_SGE_BUF_PG_SZ_S, 0);
|
||||
|
||||
page_size = 1 << (hr_dev->caps.mtt_buf_pg_sz + PAGE_SHIFT);
|
||||
context->rq_cur_blk_addr = (u32)(mtts[hr_qp->rq.offset / page_size]
|
||||
>> PAGE_ADDR_SHIFT);
|
||||
context->rq_cur_blk_addr = (u32)(mtts[0] >> PAGE_ADDR_SHIFT);
|
||||
qpc_mask->rq_cur_blk_addr = 0;
|
||||
|
||||
roce_set_field(context->byte_92_srq_info,
|
||||
V2_QPC_BYTE_92_RQ_CUR_BLK_ADDR_M,
|
||||
V2_QPC_BYTE_92_RQ_CUR_BLK_ADDR_S,
|
||||
mtts[hr_qp->rq.offset / page_size]
|
||||
>> (32 + PAGE_ADDR_SHIFT));
|
||||
mtts[0] >> (32 + PAGE_ADDR_SHIFT));
|
||||
roce_set_field(qpc_mask->byte_92_srq_info,
|
||||
V2_QPC_BYTE_92_RQ_CUR_BLK_ADDR_M,
|
||||
V2_QPC_BYTE_92_RQ_CUR_BLK_ADDR_S, 0);
|
||||
|
||||
context->rq_nxt_blk_addr = (u32)(mtts[hr_qp->rq.offset / page_size + 1]
|
||||
>> PAGE_ADDR_SHIFT);
|
||||
context->rq_nxt_blk_addr = (u32)(mtts[1] >> PAGE_ADDR_SHIFT);
|
||||
qpc_mask->rq_nxt_blk_addr = 0;
|
||||
|
||||
roce_set_field(context->byte_104_rq_sge,
|
||||
V2_QPC_BYTE_104_RQ_NXT_BLK_ADDR_M,
|
||||
V2_QPC_BYTE_104_RQ_NXT_BLK_ADDR_S,
|
||||
mtts[hr_qp->rq.offset / page_size + 1]
|
||||
>> (32 + PAGE_ADDR_SHIFT));
|
||||
mtts[1] >> (32 + PAGE_ADDR_SHIFT));
|
||||
roce_set_field(qpc_mask->byte_104_rq_sge,
|
||||
V2_QPC_BYTE_104_RQ_NXT_BLK_ADDR_M,
|
||||
V2_QPC_BYTE_104_RQ_NXT_BLK_ADDR_S, 0);
|
||||
@@ -3708,13 +3771,14 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
|
||||
roce_set_field(qpc_mask->byte_20_smac_sgid_idx,
|
||||
V2_QPC_BYTE_20_SGID_IDX_M,
|
||||
V2_QPC_BYTE_20_SGID_IDX_S, 0);
|
||||
memcpy(&(context->dmac), dmac, 4);
|
||||
memcpy(&(context->dmac), dmac, sizeof(u32));
|
||||
roce_set_field(context->byte_52_udpspn_dmac, V2_QPC_BYTE_52_DMAC_M,
|
||||
V2_QPC_BYTE_52_DMAC_S, *((u16 *)(&dmac[4])));
|
||||
qpc_mask->dmac = 0;
|
||||
roce_set_field(qpc_mask->byte_52_udpspn_dmac, V2_QPC_BYTE_52_DMAC_M,
|
||||
V2_QPC_BYTE_52_DMAC_S, 0);
|
||||
|
||||
/* mtu*(2^LP_PKTN_INI) should not bigger than 1 message length 64kb */
|
||||
roce_set_field(context->byte_56_dqpn_err, V2_QPC_BYTE_56_LP_PKTN_INI_M,
|
||||
V2_QPC_BYTE_56_LP_PKTN_INI_S, 4);
|
||||
roce_set_field(qpc_mask->byte_56_dqpn_err, V2_QPC_BYTE_56_LP_PKTN_INI_M,
|
||||
@@ -3756,6 +3820,7 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp,
|
||||
roce_set_field(qpc_mask->byte_132_trrl, V2_QPC_BYTE_132_TRRL_TAIL_MAX_M,
|
||||
V2_QPC_BYTE_132_TRRL_TAIL_MAX_S, 0);
|
||||
|
||||
/* rocee send 2^lp_sgen_ini segs every time */
|
||||
roce_set_field(context->byte_168_irrl_idx,
|
||||
V2_QPC_BYTE_168_LP_SGEN_INI_M,
|
||||
V2_QPC_BYTE_168_LP_SGEN_INI_S, 3);
|
||||
@@ -3774,18 +3839,30 @@ static int modify_qp_rtr_to_rts(struct ib_qp *ibqp,
|
||||
struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
|
||||
struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
|
||||
struct device *dev = hr_dev->dev;
|
||||
dma_addr_t dma_handle;
|
||||
u64 sge_cur_blk = 0;
|
||||
u64 sq_cur_blk = 0;
|
||||
u32 page_size;
|
||||
u64 *mtts;
|
||||
int count;
|
||||
|
||||
/* Search qp buf's mtts */
|
||||
mtts = hns_roce_table_find(hr_dev, &hr_dev->mr_table.mtt_table,
|
||||
hr_qp->mtt.first_seg, &dma_handle);
|
||||
if (!mtts) {
|
||||
dev_err(dev, "qp buf pa find failed\n");
|
||||
count = hns_roce_mtr_find(hr_dev, &hr_qp->mtr, 0, &sq_cur_blk, 1, NULL);
|
||||
if (count < 1) {
|
||||
dev_err(dev, "qp(0x%lx) buf pa find failed\n", hr_qp->qpn);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (hr_qp->sge.offset) {
|
||||
page_size = 1 << (hr_dev->caps.mtt_buf_pg_sz + PAGE_SHIFT);
|
||||
count = hns_roce_mtr_find(hr_dev, &hr_qp->mtr,
|
||||
hr_qp->sge.offset / page_size,
|
||||
&sge_cur_blk, 1, NULL);
|
||||
if (count < 1) {
|
||||
dev_err(dev, "qp(0x%lx) sge pa find failed\n",
|
||||
hr_qp->qpn);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Not support alternate path and path migration */
|
||||
if ((attr_mask & IB_QP_ALT_PATH) ||
|
||||
(attr_mask & IB_QP_PATH_MIG_STATE)) {
|
||||
@@ -3799,37 +3876,37 @@ static int modify_qp_rtr_to_rts(struct ib_qp *ibqp,
|
||||
* we should set all bits of the relevant fields in context mask to
|
||||
* 0 at the same time, else set them to 0x1.
|
||||
*/
|
||||
context->sq_cur_blk_addr = (u32)(mtts[0] >> PAGE_ADDR_SHIFT);
|
||||
context->sq_cur_blk_addr = (u32)(sq_cur_blk >> PAGE_ADDR_SHIFT);
|
||||
roce_set_field(context->byte_168_irrl_idx,
|
||||
V2_QPC_BYTE_168_SQ_CUR_BLK_ADDR_M,
|
||||
V2_QPC_BYTE_168_SQ_CUR_BLK_ADDR_S,
|
||||
mtts[0] >> (32 + PAGE_ADDR_SHIFT));
|
||||
sq_cur_blk >> (32 + PAGE_ADDR_SHIFT));
|
||||
qpc_mask->sq_cur_blk_addr = 0;
|
||||
roce_set_field(qpc_mask->byte_168_irrl_idx,
|
||||
V2_QPC_BYTE_168_SQ_CUR_BLK_ADDR_M,
|
||||
V2_QPC_BYTE_168_SQ_CUR_BLK_ADDR_S, 0);
|
||||
|
||||
page_size = 1 << (hr_dev->caps.mtt_buf_pg_sz + PAGE_SHIFT);
|
||||
context->sq_cur_sge_blk_addr =
|
||||
((ibqp->qp_type == IB_QPT_GSI) || hr_qp->sq.max_gs > 2) ?
|
||||
((u32)(mtts[hr_qp->sge.offset / page_size]
|
||||
>> PAGE_ADDR_SHIFT)) : 0;
|
||||
context->sq_cur_sge_blk_addr = ((ibqp->qp_type == IB_QPT_GSI) ||
|
||||
hr_qp->sq.max_gs > HNS_ROCE_V2_UC_RC_SGE_NUM_IN_WQE) ?
|
||||
((u32)(sge_cur_blk >>
|
||||
PAGE_ADDR_SHIFT)) : 0;
|
||||
roce_set_field(context->byte_184_irrl_idx,
|
||||
V2_QPC_BYTE_184_SQ_CUR_SGE_BLK_ADDR_M,
|
||||
V2_QPC_BYTE_184_SQ_CUR_SGE_BLK_ADDR_S,
|
||||
((ibqp->qp_type == IB_QPT_GSI) || hr_qp->sq.max_gs > 2) ?
|
||||
(mtts[hr_qp->sge.offset / page_size] >>
|
||||
((ibqp->qp_type == IB_QPT_GSI) || hr_qp->sq.max_gs >
|
||||
HNS_ROCE_V2_UC_RC_SGE_NUM_IN_WQE) ?
|
||||
(sge_cur_blk >>
|
||||
(32 + PAGE_ADDR_SHIFT)) : 0);
|
||||
qpc_mask->sq_cur_sge_blk_addr = 0;
|
||||
roce_set_field(qpc_mask->byte_184_irrl_idx,
|
||||
V2_QPC_BYTE_184_SQ_CUR_SGE_BLK_ADDR_M,
|
||||
V2_QPC_BYTE_184_SQ_CUR_SGE_BLK_ADDR_S, 0);
|
||||
|
||||
context->rx_sq_cur_blk_addr = (u32)(mtts[0] >> PAGE_ADDR_SHIFT);
|
||||
context->rx_sq_cur_blk_addr = (u32)(sq_cur_blk >> PAGE_ADDR_SHIFT);
|
||||
roce_set_field(context->byte_232_irrl_sge,
|
||||
V2_QPC_BYTE_232_RX_SQ_CUR_BLK_ADDR_M,
|
||||
V2_QPC_BYTE_232_RX_SQ_CUR_BLK_ADDR_S,
|
||||
mtts[0] >> (32 + PAGE_ADDR_SHIFT));
|
||||
sq_cur_blk >> (32 + PAGE_ADDR_SHIFT));
|
||||
qpc_mask->rx_sq_cur_blk_addr = 0;
|
||||
roce_set_field(qpc_mask->byte_232_irrl_sge,
|
||||
V2_QPC_BYTE_232_RX_SQ_CUR_BLK_ADDR_M,
|
||||
@@ -4144,7 +4221,7 @@ static int hns_roce_v2_modify_qp(struct ib_qp *ibqp,
|
||||
roce_set_field(context->byte_224_retry_msg,
|
||||
V2_QPC_BYTE_224_RETRY_MSG_PSN_M,
|
||||
V2_QPC_BYTE_224_RETRY_MSG_PSN_S,
|
||||
attr->sq_psn >> 16);
|
||||
attr->sq_psn >> V2_QPC_BYTE_220_RETRY_MSG_PSN_S);
|
||||
roce_set_field(qpc_mask->byte_224_retry_msg,
|
||||
V2_QPC_BYTE_224_RETRY_MSG_PSN_M,
|
||||
V2_QPC_BYTE_224_RETRY_MSG_PSN_S, 0);
|
||||
@@ -4230,7 +4307,7 @@ static int hns_roce_v2_modify_qp(struct ib_qp *ibqp,
|
||||
V2_QPC_BYTE_60_QP_ST_S, 0);
|
||||
|
||||
/* SW pass context to HW */
|
||||
ret = hns_roce_v2_qp_modify(hr_dev, &hr_qp->mtt, cur_state, new_state,
|
||||
ret = hns_roce_v2_qp_modify(hr_dev, cur_state, new_state,
|
||||
context, hr_qp);
|
||||
if (ret) {
|
||||
dev_err(dev, "hns_roce_qp_modify failed(%d)\n", ret);
|
||||
@@ -4374,11 +4451,12 @@ static int hns_roce_v2_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
|
||||
V2_QPC_BYTE_56_DQPN_M,
|
||||
V2_QPC_BYTE_56_DQPN_S);
|
||||
qp_attr->qp_access_flags = ((roce_get_bit(context->byte_76_srqn_op_en,
|
||||
V2_QPC_BYTE_76_RRE_S)) << 2) |
|
||||
((roce_get_bit(context->byte_76_srqn_op_en,
|
||||
V2_QPC_BYTE_76_RWE_S)) << 1) |
|
||||
((roce_get_bit(context->byte_76_srqn_op_en,
|
||||
V2_QPC_BYTE_76_ATE_S)) << 3);
|
||||
V2_QPC_BYTE_76_RRE_S)) << V2_QP_RWE_S) |
|
||||
((roce_get_bit(context->byte_76_srqn_op_en,
|
||||
V2_QPC_BYTE_76_RWE_S)) << V2_QP_RRE_S) |
|
||||
((roce_get_bit(context->byte_76_srqn_op_en,
|
||||
V2_QPC_BYTE_76_ATE_S)) << V2_QP_ATE_S);
|
||||
|
||||
if (hr_qp->ibqp.qp_type == IB_QPT_RC ||
|
||||
hr_qp->ibqp.qp_type == IB_QPT_UC) {
|
||||
struct ib_global_route *grh =
|
||||
@@ -4487,7 +4565,7 @@ static int hns_roce_v2_destroy_qp_common(struct hns_roce_dev *hr_dev,
|
||||
(hr_qp->ibqp.qp_type == IB_QPT_UD))
|
||||
hns_roce_release_range_qp(hr_dev, hr_qp->qpn, 1);
|
||||
|
||||
hns_roce_mtt_cleanup(hr_dev, &hr_qp->mtt);
|
||||
hns_roce_mtr_cleanup(hr_dev, &hr_qp->mtr);
|
||||
|
||||
if (udata) {
|
||||
struct hns_roce_ucontext *context =
|
||||
@@ -4501,7 +4579,6 @@ static int hns_roce_v2_destroy_qp_common(struct hns_roce_dev *hr_dev,
|
||||
|
||||
if (hr_qp->rq.wqe_cnt && (hr_qp->rdb_en == 1))
|
||||
hns_roce_db_unmap_user(context, &hr_qp->rdb);
|
||||
ib_umem_release(hr_qp->umem);
|
||||
} else {
|
||||
kfree(hr_qp->sq.wrid);
|
||||
kfree(hr_qp->rq.wrid);
|
||||
@@ -4509,6 +4586,7 @@ static int hns_roce_v2_destroy_qp_common(struct hns_roce_dev *hr_dev,
|
||||
if (hr_qp->rq.wqe_cnt)
|
||||
hns_roce_free_db(hr_dev, &hr_qp->rdb);
|
||||
}
|
||||
ib_umem_release(hr_qp->umem);
|
||||
|
||||
if ((hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RQ_INLINE) &&
|
||||
hr_qp->rq.wqe_cnt) {
|
||||
@@ -4682,7 +4760,6 @@ static void hns_roce_irq_work_handle(struct work_struct *work)
|
||||
dev_warn(dev, "Path migration failed.\n");
|
||||
break;
|
||||
case HNS_ROCE_EVENT_TYPE_COMM_EST:
|
||||
dev_info(dev, "Communication established.\n");
|
||||
break;
|
||||
case HNS_ROCE_EVENT_TYPE_SQ_DRAINED:
|
||||
dev_warn(dev, "Send queue drained.\n");
|
||||
@@ -5151,8 +5228,8 @@ static void hns_roce_mhop_free_eq(struct hns_roce_dev *hr_dev,
|
||||
dma_free_coherent(dev, bt_chk_sz, eq->bt_l1[i],
|
||||
eq->l1_dma[i]);
|
||||
|
||||
for (j = 0; j < bt_chk_sz / 8; j++) {
|
||||
idx = i * (bt_chk_sz / 8) + j;
|
||||
for (j = 0; j < bt_chk_sz / BA_BYTE_LEN; j++) {
|
||||
idx = i * (bt_chk_sz / BA_BYTE_LEN) + j;
|
||||
if ((i == eq->l0_last_num - 1)
|
||||
&& j == eq->l1_last_num - 1) {
|
||||
eqe_alloc = (buf_chk_sz / eq->eqe_size)
|
||||
@@ -5368,9 +5445,9 @@ static int hns_roce_mhop_alloc_eq(struct hns_roce_dev *hr_dev,
|
||||
buf_chk_sz = 1 << (hr_dev->caps.eqe_buf_pg_sz + PAGE_SHIFT);
|
||||
bt_chk_sz = 1 << (hr_dev->caps.eqe_ba_pg_sz + PAGE_SHIFT);
|
||||
|
||||
ba_num = (PAGE_ALIGN(eq->entries * eq->eqe_size) + buf_chk_sz - 1)
|
||||
/ buf_chk_sz;
|
||||
bt_num = (ba_num + bt_chk_sz / 8 - 1) / (bt_chk_sz / 8);
|
||||
ba_num = DIV_ROUND_UP(PAGE_ALIGN(eq->entries * eq->eqe_size),
|
||||
buf_chk_sz);
|
||||
bt_num = DIV_ROUND_UP(ba_num, bt_chk_sz / BA_BYTE_LEN);
|
||||
|
||||
/* hop_num = 0 */
|
||||
if (mhop_num == HNS_ROCE_HOP_NUM_0) {
|
||||
@@ -5387,8 +5464,6 @@ static int hns_roce_mhop_alloc_eq(struct hns_roce_dev *hr_dev,
|
||||
eq->cur_eqe_ba = eq->l0_dma;
|
||||
eq->nxt_eqe_ba = 0;
|
||||
|
||||
memset(eq->bt_l0, 0, eq->entries * eq->eqe_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -5415,12 +5490,12 @@ static int hns_roce_mhop_alloc_eq(struct hns_roce_dev *hr_dev,
|
||||
goto err_dma_alloc_l0;
|
||||
|
||||
if (mhop_num == 1) {
|
||||
if (ba_num > (bt_chk_sz / 8))
|
||||
if (ba_num > (bt_chk_sz / BA_BYTE_LEN))
|
||||
dev_err(dev, "ba_num %d is too large for 1 hop\n",
|
||||
ba_num);
|
||||
|
||||
/* alloc buf */
|
||||
for (i = 0; i < bt_chk_sz / 8; i++) {
|
||||
for (i = 0; i < bt_chk_sz / BA_BYTE_LEN; i++) {
|
||||
if (eq_buf_cnt + 1 < ba_num) {
|
||||
size = buf_chk_sz;
|
||||
} else {
|
||||
@@ -5444,7 +5519,7 @@ static int hns_roce_mhop_alloc_eq(struct hns_roce_dev *hr_dev,
|
||||
|
||||
} else if (mhop_num == 2) {
|
||||
/* alloc L1 BT and buf */
|
||||
for (i = 0; i < bt_chk_sz / 8; i++) {
|
||||
for (i = 0; i < bt_chk_sz / BA_BYTE_LEN; i++) {
|
||||
eq->bt_l1[i] = dma_alloc_coherent(dev, bt_chk_sz,
|
||||
&(eq->l1_dma[i]),
|
||||
GFP_KERNEL);
|
||||
@@ -5452,8 +5527,8 @@ static int hns_roce_mhop_alloc_eq(struct hns_roce_dev *hr_dev,
|
||||
goto err_dma_alloc_l1;
|
||||
*(eq->bt_l0 + i) = eq->l1_dma[i];
|
||||
|
||||
for (j = 0; j < bt_chk_sz / 8; j++) {
|
||||
idx = i * bt_chk_sz / 8 + j;
|
||||
for (j = 0; j < bt_chk_sz / BA_BYTE_LEN; j++) {
|
||||
idx = i * bt_chk_sz / BA_BYTE_LEN + j;
|
||||
if (eq_buf_cnt + 1 < ba_num) {
|
||||
size = buf_chk_sz;
|
||||
} else {
|
||||
@@ -5498,8 +5573,8 @@ err_dma_alloc_l1:
|
||||
dma_free_coherent(dev, bt_chk_sz, eq->bt_l1[i],
|
||||
eq->l1_dma[i]);
|
||||
|
||||
for (j = 0; j < bt_chk_sz / 8; j++) {
|
||||
idx = i * bt_chk_sz / 8 + j;
|
||||
for (j = 0; j < bt_chk_sz / BA_BYTE_LEN; j++) {
|
||||
idx = i * bt_chk_sz / BA_BYTE_LEN + j;
|
||||
dma_free_coherent(dev, buf_chk_sz, eq->buf[idx],
|
||||
eq->buf_dma[idx]);
|
||||
}
|
||||
@@ -5522,11 +5597,11 @@ err_dma_alloc_buf:
|
||||
dma_free_coherent(dev, bt_chk_sz, eq->bt_l1[i],
|
||||
eq->l1_dma[i]);
|
||||
|
||||
for (j = 0; j < bt_chk_sz / 8; j++) {
|
||||
for (j = 0; j < bt_chk_sz / BA_BYTE_LEN; j++) {
|
||||
if (i == record_i && j >= record_j)
|
||||
break;
|
||||
|
||||
idx = i * bt_chk_sz / 8 + j;
|
||||
idx = i * bt_chk_sz / BA_BYTE_LEN + j;
|
||||
dma_free_coherent(dev, buf_chk_sz,
|
||||
eq->buf[idx],
|
||||
eq->buf_dma[idx]);
|
||||
@@ -5972,18 +6047,19 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int find_empty_entry(struct hns_roce_idx_que *idx_que)
|
||||
static int find_empty_entry(struct hns_roce_idx_que *idx_que,
|
||||
unsigned long size)
|
||||
{
|
||||
int bit_num;
|
||||
int i;
|
||||
int wqe_idx;
|
||||
|
||||
/* bitmap[i] is set zero if all bits are allocated */
|
||||
for (i = 0; idx_que->bitmap[i] == 0; ++i)
|
||||
;
|
||||
bit_num = ffs(idx_que->bitmap[i]);
|
||||
idx_que->bitmap[i] &= ~(1ULL << (bit_num - 1));
|
||||
if (unlikely(bitmap_full(idx_que->bitmap, size)))
|
||||
return -ENOSPC;
|
||||
|
||||
return i * sizeof(u64) * 8 + (bit_num - 1);
|
||||
wqe_idx = find_first_zero_bit(idx_que->bitmap, size);
|
||||
|
||||
bitmap_set(idx_que->bitmap, wqe_idx, 1);
|
||||
|
||||
return wqe_idx;
|
||||
}
|
||||
|
||||
static void fill_idx_queue(struct hns_roce_idx_que *idx_que,
|
||||
@@ -6029,7 +6105,13 @@ static int hns_roce_v2_post_srq_recv(struct ib_srq *ibsrq,
|
||||
break;
|
||||
}
|
||||
|
||||
wqe_idx = find_empty_entry(&srq->idx_que);
|
||||
wqe_idx = find_empty_entry(&srq->idx_que, srq->max);
|
||||
if (wqe_idx < 0) {
|
||||
ret = -ENOMEM;
|
||||
*bad_wr = wr;
|
||||
break;
|
||||
}
|
||||
|
||||
fill_idx_queue(&srq->idx_que, ind, wqe_idx);
|
||||
wqe = get_srq_wqe(srq, wqe_idx);
|
||||
dseg = (struct hns_roce_v2_wqe_data_seg *)wqe;
|
||||
@@ -6041,9 +6123,9 @@ static int hns_roce_v2_post_srq_recv(struct ib_srq *ibsrq,
|
||||
}
|
||||
|
||||
if (i < srq->max_gs) {
|
||||
dseg->len = 0;
|
||||
dseg->lkey = cpu_to_le32(0x100);
|
||||
dseg->addr = 0;
|
||||
dseg[i].len = 0;
|
||||
dseg[i].lkey = cpu_to_le32(0x100);
|
||||
dseg[i].addr = 0;
|
||||
}
|
||||
|
||||
srq->wrid[wqe_idx] = wr->wr_id;
|
||||
@@ -6059,7 +6141,8 @@ static int hns_roce_v2_post_srq_recv(struct ib_srq *ibsrq,
|
||||
*/
|
||||
wmb();
|
||||
|
||||
srq_db.byte_4 = HNS_ROCE_V2_SRQ_DB << 24 | srq->srqn;
|
||||
srq_db.byte_4 = HNS_ROCE_V2_SRQ_DB << V2_DB_BYTE_4_CMD_S |
|
||||
(srq->srqn & V2_DB_BYTE_4_TAG_M);
|
||||
srq_db.parameter = srq->head;
|
||||
|
||||
hns_roce_write64(hr_dev, (__le32 *)&srq_db, srq->db_reg_l);
|
||||
@@ -6301,6 +6384,7 @@ static int hns_roce_hw_v2_reset_notify_down(struct hnae3_handle *handle)
|
||||
if (!hr_dev)
|
||||
return 0;
|
||||
|
||||
hr_dev->is_reset = true;
|
||||
hr_dev->active = false;
|
||||
hr_dev->dis_db = true;
|
||||
|
||||
|
@@ -54,7 +54,7 @@
|
||||
#define HNS_ROCE_V2_MAX_CQ_NUM 0x100000
|
||||
#define HNS_ROCE_V2_MAX_CQC_TIMER_NUM 0x100
|
||||
#define HNS_ROCE_V2_MAX_SRQ_NUM 0x100000
|
||||
#define HNS_ROCE_V2_MAX_CQE_NUM 0x10000
|
||||
#define HNS_ROCE_V2_MAX_CQE_NUM 0x400000
|
||||
#define HNS_ROCE_V2_MAX_SRQWQE_NUM 0x8000
|
||||
#define HNS_ROCE_V2_MAX_RQ_SGE_NUM 0x100
|
||||
#define HNS_ROCE_V2_MAX_SQ_SGE_NUM 0xff
|
||||
@@ -241,6 +241,7 @@ enum hns_roce_opcode_type {
|
||||
HNS_ROCE_OPC_POST_MB = 0x8504,
|
||||
HNS_ROCE_OPC_QUERY_MB_ST = 0x8505,
|
||||
HNS_ROCE_OPC_CFG_BT_ATTR = 0x8506,
|
||||
HNS_ROCE_OPC_FUNC_CLEAR = 0x8508,
|
||||
HNS_ROCE_OPC_CLR_SCCC = 0x8509,
|
||||
HNS_ROCE_OPC_QUERY_SCCC = 0x850a,
|
||||
HNS_ROCE_OPC_RESET_SCCC = 0x850b,
|
||||
@@ -886,6 +887,10 @@ struct hns_roce_v2_qp_context {
|
||||
#define V2_QPC_BYTE_256_SQ_FLUSH_IDX_S 16
|
||||
#define V2_QPC_BYTE_256_SQ_FLUSH_IDX_M GENMASK(31, 16)
|
||||
|
||||
#define V2_QP_RWE_S 1 /* rdma write enable */
|
||||
#define V2_QP_RRE_S 2 /* rdma read enable */
|
||||
#define V2_QP_ATE_S 3 /* rdma atomic enable */
|
||||
|
||||
struct hns_roce_v2_cqe {
|
||||
__le32 byte_4;
|
||||
union {
|
||||
@@ -1226,6 +1231,22 @@ struct hns_roce_query_fw_info {
|
||||
__le32 rsv[5];
|
||||
};
|
||||
|
||||
struct hns_roce_func_clear {
|
||||
__le32 rst_funcid_en;
|
||||
__le32 func_done;
|
||||
__le32 rsv[4];
|
||||
};
|
||||
|
||||
#define FUNC_CLEAR_RST_FUN_DONE_S 0
|
||||
/* Each physical function manages up to 248 virtual functions;
|
||||
* it takes up to 100ms for each function to execute clear;
|
||||
* if an abnormal reset occurs, it is executed twice at most;
|
||||
* so it takes up to 249 * 2 * 100ms.
|
||||
*/
|
||||
#define HNS_ROCE_V2_FUNC_CLEAR_TIMEOUT_MSECS (249 * 2 * 100)
|
||||
#define HNS_ROCE_V2_READ_FUNC_CLEAR_FLAG_INTERVAL 40
|
||||
#define HNS_ROCE_V2_READ_FUNC_CLEAR_FLAG_FAIL_WAIT 20
|
||||
|
||||
struct hns_roce_cfg_llm_a {
|
||||
__le32 base_addr_l;
|
||||
__le32 base_addr_h;
|
||||
|
@@ -57,17 +57,16 @@ int hns_get_gid_index(struct hns_roce_dev *hr_dev, u8 port, int gid_index)
|
||||
{
|
||||
return gid_index * hr_dev->caps.num_ports + port;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_get_gid_index);
|
||||
|
||||
static int hns_roce_set_mac(struct hns_roce_dev *hr_dev, u8 port, u8 *addr)
|
||||
{
|
||||
u8 phy_port;
|
||||
u32 i = 0;
|
||||
|
||||
if (!memcmp(hr_dev->dev_addr[port], addr, MAC_ADDR_OCTET_NUM))
|
||||
if (!memcmp(hr_dev->dev_addr[port], addr, ETH_ALEN))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < MAC_ADDR_OCTET_NUM; i++)
|
||||
for (i = 0; i < ETH_ALEN; i++)
|
||||
hr_dev->dev_addr[port][i] = addr[i];
|
||||
|
||||
phy_port = hr_dev->iboe.phy_port[port];
|
||||
@@ -78,18 +77,13 @@ static int hns_roce_add_gid(const struct ib_gid_attr *attr, void **context)
|
||||
{
|
||||
struct hns_roce_dev *hr_dev = to_hr_dev(attr->device);
|
||||
u8 port = attr->port_num - 1;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
if (port >= hr_dev->caps.num_ports)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&hr_dev->iboe.lock, flags);
|
||||
|
||||
ret = hr_dev->hw->set_gid(hr_dev, port, attr->index, &attr->gid, attr);
|
||||
|
||||
spin_unlock_irqrestore(&hr_dev->iboe.lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -98,18 +92,13 @@ static int hns_roce_del_gid(const struct ib_gid_attr *attr, void **context)
|
||||
struct hns_roce_dev *hr_dev = to_hr_dev(attr->device);
|
||||
struct ib_gid_attr zattr = { };
|
||||
u8 port = attr->port_num - 1;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
if (port >= hr_dev->caps.num_ports)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&hr_dev->iboe.lock, flags);
|
||||
|
||||
ret = hr_dev->hw->set_gid(hr_dev, port, attr->index, &zgid, &zattr);
|
||||
|
||||
spin_unlock_irqrestore(&hr_dev->iboe.lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -272,7 +261,8 @@ static int hns_roce_query_port(struct ib_device *ib_dev, u8 port_num,
|
||||
props->active_mtu = mtu ? min(props->max_mtu, mtu) : IB_MTU_256;
|
||||
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) ? 5 : 3;
|
||||
props->phys_state = (props->state == IB_PORT_ACTIVE) ?
|
||||
HNS_ROCE_PHY_LINKUP : HNS_ROCE_PHY_DISABLED;
|
||||
|
||||
spin_unlock_irqrestore(&hr_dev->iboe.lock, flags);
|
||||
|
||||
@@ -319,7 +309,7 @@ static int hns_roce_modify_port(struct ib_device *ib_dev, u8 port_num, int mask,
|
||||
static int hns_roce_alloc_ucontext(struct ib_ucontext *uctx,
|
||||
struct ib_udata *udata)
|
||||
{
|
||||
int ret = 0;
|
||||
int ret;
|
||||
struct hns_roce_ucontext *context = to_hr_ucontext(uctx);
|
||||
struct hns_roce_ib_alloc_ucontext_resp resp = {};
|
||||
struct hns_roce_dev *hr_dev = to_hr_dev(uctx->device);
|
||||
@@ -423,6 +413,11 @@ static void hns_roce_unregister_device(struct hns_roce_dev *hr_dev)
|
||||
}
|
||||
|
||||
static const struct ib_device_ops hns_roce_dev_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.driver_id = RDMA_DRIVER_HNS,
|
||||
.uverbs_abi_ver = 1,
|
||||
.uverbs_no_driver_id_binding = 1,
|
||||
|
||||
.add_gid = hns_roce_add_gid,
|
||||
.alloc_pd = hns_roce_alloc_pd,
|
||||
.alloc_ucontext = hns_roce_alloc_ucontext,
|
||||
@@ -451,6 +446,7 @@ static const struct ib_device_ops hns_roce_dev_ops = {
|
||||
.reg_user_mr = hns_roce_reg_user_mr,
|
||||
|
||||
INIT_RDMA_OBJ_SIZE(ib_ah, hns_roce_ah, ibah),
|
||||
INIT_RDMA_OBJ_SIZE(ib_cq, hns_roce_cq, ib_cq),
|
||||
INIT_RDMA_OBJ_SIZE(ib_pd, hns_roce_pd, ibpd),
|
||||
INIT_RDMA_OBJ_SIZE(ib_ucontext, hns_roce_ucontext, ibucontext),
|
||||
};
|
||||
@@ -489,14 +485,12 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev)
|
||||
|
||||
ib_dev = &hr_dev->ib_dev;
|
||||
|
||||
ib_dev->owner = THIS_MODULE;
|
||||
ib_dev->node_type = RDMA_NODE_IB_CA;
|
||||
ib_dev->dev.parent = dev;
|
||||
|
||||
ib_dev->phys_port_cnt = hr_dev->caps.num_ports;
|
||||
ib_dev->local_dma_lkey = hr_dev->caps.reserved_lkey;
|
||||
ib_dev->num_comp_vectors = hr_dev->caps.num_comp_vectors;
|
||||
ib_dev->uverbs_abi_ver = 1;
|
||||
ib_dev->uverbs_cmd_mask =
|
||||
(1ULL << IB_USER_VERBS_CMD_GET_CONTEXT) |
|
||||
(1ULL << IB_USER_VERBS_CMD_QUERY_DEVICE) |
|
||||
@@ -545,7 +539,6 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev)
|
||||
ib_set_device_ops(ib_dev, hr_dev->hw->hns_roce_dev_srq_ops);
|
||||
}
|
||||
|
||||
ib_dev->driver_id = RDMA_DRIVER_HNS;
|
||||
ib_set_device_ops(ib_dev, hr_dev->hw->hns_roce_dev_ops);
|
||||
ib_set_device_ops(ib_dev, &hns_roce_dev_ops);
|
||||
for (i = 0; i < hr_dev->caps.num_ports; i++) {
|
||||
@@ -980,7 +973,6 @@ error_failed_cmq_init:
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_init);
|
||||
|
||||
void hns_roce_exit(struct hns_roce_dev *hr_dev)
|
||||
{
|
||||
@@ -1001,7 +993,6 @@ void hns_roce_exit(struct hns_roce_dev *hr_dev)
|
||||
if (hr_dev->hw->reset)
|
||||
hr_dev->hw->reset(hr_dev, false);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_exit);
|
||||
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
MODULE_AUTHOR("Wei Hu <xavier.huwei@huawei.com>");
|
||||
|
@@ -47,7 +47,6 @@ unsigned long key_to_hw_index(u32 key)
|
||||
{
|
||||
return (key << 24) | (key >> 8);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(key_to_hw_index);
|
||||
|
||||
static int hns_roce_sw2hw_mpt(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_cmd_mailbox *mailbox,
|
||||
@@ -66,7 +65,6 @@ int hns_roce_hw2sw_mpt(struct hns_roce_dev *hr_dev,
|
||||
mpt_index, !mailbox, HNS_ROCE_CMD_HW2SW_MPT,
|
||||
HNS_ROCE_CMD_TIMEOUT_MSECS);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_hw2sw_mpt);
|
||||
|
||||
static int hns_roce_buddy_alloc(struct hns_roce_buddy *buddy, int order,
|
||||
unsigned long *seg)
|
||||
@@ -293,7 +291,6 @@ void hns_roce_mtt_cleanup(struct hns_roce_dev *hr_dev, struct hns_roce_mtt *mtt)
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_mtt_cleanup);
|
||||
|
||||
static void hns_roce_loop_free(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_mr *mr, int err_loop_index,
|
||||
@@ -314,11 +311,11 @@ static void hns_roce_loop_free(struct hns_roce_dev *hr_dev,
|
||||
dma_free_coherent(dev, pbl_bt_sz, mr->pbl_bt_l1[i],
|
||||
mr->pbl_l1_dma_addr[i]);
|
||||
|
||||
for (j = 0; j < pbl_bt_sz / 8; j++) {
|
||||
for (j = 0; j < pbl_bt_sz / BA_BYTE_LEN; j++) {
|
||||
if (i == loop_i && j >= loop_j)
|
||||
break;
|
||||
|
||||
bt_idx = i * pbl_bt_sz / 8 + j;
|
||||
bt_idx = i * pbl_bt_sz / BA_BYTE_LEN + j;
|
||||
dma_free_coherent(dev, pbl_bt_sz,
|
||||
mr->pbl_bt_l2[bt_idx],
|
||||
mr->pbl_l2_dma_addr[bt_idx]);
|
||||
@@ -329,8 +326,8 @@ static void hns_roce_loop_free(struct hns_roce_dev *hr_dev,
|
||||
dma_free_coherent(dev, pbl_bt_sz, mr->pbl_bt_l1[i],
|
||||
mr->pbl_l1_dma_addr[i]);
|
||||
|
||||
for (j = 0; j < pbl_bt_sz / 8; j++) {
|
||||
bt_idx = i * pbl_bt_sz / 8 + j;
|
||||
for (j = 0; j < pbl_bt_sz / BA_BYTE_LEN; j++) {
|
||||
bt_idx = i * pbl_bt_sz / BA_BYTE_LEN + j;
|
||||
dma_free_coherent(dev, pbl_bt_sz,
|
||||
mr->pbl_bt_l2[bt_idx],
|
||||
mr->pbl_l2_dma_addr[bt_idx]);
|
||||
@@ -533,7 +530,7 @@ static int hns_roce_mr_alloc(struct hns_roce_dev *hr_dev, u32 pd, u64 iova,
|
||||
{
|
||||
struct device *dev = hr_dev->dev;
|
||||
unsigned long index = 0;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
/* Allocate a key for mr from mr_table */
|
||||
ret = hns_roce_bitmap_alloc(&hr_dev->mr_table.mtpt_bitmap, &index);
|
||||
@@ -559,7 +556,8 @@ static int hns_roce_mr_alloc(struct hns_roce_dev *hr_dev, u32 pd, u64 iova,
|
||||
mr->pbl_l0_dma_addr = 0;
|
||||
} else {
|
||||
if (!hr_dev->caps.pbl_hop_num) {
|
||||
mr->pbl_buf = dma_alloc_coherent(dev, npages * 8,
|
||||
mr->pbl_buf = dma_alloc_coherent(dev,
|
||||
npages * BA_BYTE_LEN,
|
||||
&(mr->pbl_dma_addr),
|
||||
GFP_KERNEL);
|
||||
if (!mr->pbl_buf)
|
||||
@@ -590,9 +588,8 @@ static void hns_roce_mhop_free(struct hns_roce_dev *hr_dev,
|
||||
if (mhop_num == HNS_ROCE_HOP_NUM_0)
|
||||
return;
|
||||
|
||||
/* hop_num = 1 */
|
||||
if (mhop_num == 1) {
|
||||
dma_free_coherent(dev, (unsigned int)(npages * 8),
|
||||
dma_free_coherent(dev, (unsigned int)(npages * BA_BYTE_LEN),
|
||||
mr->pbl_buf, mr->pbl_dma_addr);
|
||||
return;
|
||||
}
|
||||
@@ -603,12 +600,13 @@ static void hns_roce_mhop_free(struct hns_roce_dev *hr_dev,
|
||||
if (mhop_num == 2) {
|
||||
for (i = 0; i < mr->l0_chunk_last_num; i++) {
|
||||
if (i == mr->l0_chunk_last_num - 1) {
|
||||
npages_allocated = i * (pbl_bt_sz / 8);
|
||||
npages_allocated =
|
||||
i * (pbl_bt_sz / BA_BYTE_LEN);
|
||||
|
||||
dma_free_coherent(dev,
|
||||
(npages - npages_allocated) * 8,
|
||||
mr->pbl_bt_l1[i],
|
||||
mr->pbl_l1_dma_addr[i]);
|
||||
(npages - npages_allocated) * BA_BYTE_LEN,
|
||||
mr->pbl_bt_l1[i],
|
||||
mr->pbl_l1_dma_addr[i]);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -621,16 +619,17 @@ static void hns_roce_mhop_free(struct hns_roce_dev *hr_dev,
|
||||
dma_free_coherent(dev, pbl_bt_sz, mr->pbl_bt_l1[i],
|
||||
mr->pbl_l1_dma_addr[i]);
|
||||
|
||||
for (j = 0; j < pbl_bt_sz / 8; j++) {
|
||||
bt_idx = i * (pbl_bt_sz / 8) + j;
|
||||
for (j = 0; j < pbl_bt_sz / BA_BYTE_LEN; j++) {
|
||||
bt_idx = i * (pbl_bt_sz / BA_BYTE_LEN) + j;
|
||||
|
||||
if ((i == mr->l0_chunk_last_num - 1)
|
||||
&& j == mr->l1_chunk_last_num - 1) {
|
||||
npages_allocated = bt_idx *
|
||||
(pbl_bt_sz / 8);
|
||||
(pbl_bt_sz / BA_BYTE_LEN);
|
||||
|
||||
dma_free_coherent(dev,
|
||||
(npages - npages_allocated) * 8,
|
||||
(npages - npages_allocated) *
|
||||
BA_BYTE_LEN,
|
||||
mr->pbl_bt_l2[bt_idx],
|
||||
mr->pbl_l2_dma_addr[bt_idx]);
|
||||
|
||||
@@ -675,7 +674,8 @@ static void hns_roce_mr_free(struct hns_roce_dev *hr_dev,
|
||||
npages = ib_umem_page_count(mr->umem);
|
||||
|
||||
if (!hr_dev->caps.pbl_hop_num)
|
||||
dma_free_coherent(dev, (unsigned int)(npages * 8),
|
||||
dma_free_coherent(dev,
|
||||
(unsigned int)(npages * BA_BYTE_LEN),
|
||||
mr->pbl_buf, mr->pbl_dma_addr);
|
||||
else
|
||||
hns_roce_mhop_free(hr_dev, mr);
|
||||
@@ -1059,6 +1059,7 @@ static int hns_roce_ib_umem_write_mr(struct hns_roce_dev *hr_dev,
|
||||
for_each_sg_dma_page(umem->sg_head.sgl, &sg_iter, umem->nmap, 0) {
|
||||
page_addr = sg_page_iter_dma_address(&sg_iter);
|
||||
if (!hr_dev->caps.pbl_hop_num) {
|
||||
/* for hip06, page addr is aligned to 4K */
|
||||
mr->pbl_buf[i++] = page_addr >> 12;
|
||||
} else if (hr_dev->caps.pbl_hop_num == 1) {
|
||||
mr->pbl_buf[i++] = page_addr;
|
||||
@@ -1069,7 +1070,7 @@ static int hns_roce_ib_umem_write_mr(struct hns_roce_dev *hr_dev,
|
||||
mr->pbl_bt_l2[i][j] = page_addr;
|
||||
|
||||
j++;
|
||||
if (j >= (pbl_bt_sz / 8)) {
|
||||
if (j >= (pbl_bt_sz / BA_BYTE_LEN)) {
|
||||
i++;
|
||||
j = 0;
|
||||
}
|
||||
@@ -1117,7 +1118,8 @@ struct ib_mr *hns_roce_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
|
||||
} else {
|
||||
u64 pbl_size = 1;
|
||||
|
||||
bt_size = (1 << (hr_dev->caps.pbl_ba_pg_sz + PAGE_SHIFT)) / 8;
|
||||
bt_size = (1 << (hr_dev->caps.pbl_ba_pg_sz + PAGE_SHIFT)) /
|
||||
BA_BYTE_LEN;
|
||||
for (i = 0; i < hr_dev->caps.pbl_hop_num; i++)
|
||||
pbl_size *= bt_size;
|
||||
if (n > pbl_size) {
|
||||
@@ -1293,9 +1295,7 @@ int hns_roce_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata)
|
||||
} else {
|
||||
hns_roce_mr_free(hr_dev, mr);
|
||||
|
||||
if (mr->umem)
|
||||
ib_umem_release(mr->umem);
|
||||
|
||||
ib_umem_release(mr->umem);
|
||||
kfree(mr);
|
||||
}
|
||||
|
||||
@@ -1491,3 +1491,119 @@ int hns_roce_dealloc_mw(struct ib_mw *ibmw)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hns_roce_mtr_init(struct hns_roce_mtr *mtr, int bt_pg_shift,
|
||||
int buf_pg_shift)
|
||||
{
|
||||
hns_roce_hem_list_init(&mtr->hem_list, bt_pg_shift);
|
||||
mtr->buf_pg_shift = buf_pg_shift;
|
||||
}
|
||||
|
||||
void hns_roce_mtr_cleanup(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_mtr *mtr)
|
||||
{
|
||||
hns_roce_hem_list_release(hr_dev, &mtr->hem_list);
|
||||
}
|
||||
|
||||
static int hns_roce_write_mtr(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_mtr *mtr, dma_addr_t *bufs,
|
||||
struct hns_roce_buf_region *r)
|
||||
{
|
||||
int offset;
|
||||
int count;
|
||||
int npage;
|
||||
u64 *mtts;
|
||||
int end;
|
||||
int i;
|
||||
|
||||
offset = r->offset;
|
||||
end = offset + r->count;
|
||||
npage = 0;
|
||||
while (offset < end) {
|
||||
mtts = hns_roce_hem_list_find_mtt(hr_dev, &mtr->hem_list,
|
||||
offset, &count, NULL);
|
||||
if (!mtts)
|
||||
return -ENOBUFS;
|
||||
|
||||
/* 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);
|
||||
else
|
||||
mtts[i] = cpu_to_le64(bufs[npage]);
|
||||
|
||||
npage++;
|
||||
}
|
||||
offset += count;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hns_roce_mtr_attach(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
|
||||
dma_addr_t **bufs, struct hns_roce_buf_region *regions,
|
||||
int region_cnt)
|
||||
{
|
||||
struct hns_roce_buf_region *r;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
ret = hns_roce_hem_list_request(hr_dev, &mtr->hem_list, regions,
|
||||
region_cnt);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < region_cnt; i++) {
|
||||
r = ®ions[i];
|
||||
ret = hns_roce_write_mtr(hr_dev, mtr, bufs[i], r);
|
||||
if (ret) {
|
||||
dev_err(hr_dev->dev,
|
||||
"write mtr[%d/%d] err %d,offset=%d.\n",
|
||||
i, region_cnt, ret, r->offset);
|
||||
goto err_write;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_write:
|
||||
hns_roce_hem_list_release(hr_dev, &mtr->hem_list);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int hns_roce_mtr_find(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
|
||||
int offset, u64 *mtt_buf, int mtt_max, u64 *base_addr)
|
||||
{
|
||||
u64 *mtts = mtt_buf;
|
||||
int mtt_count;
|
||||
int total = 0;
|
||||
u64 *addr;
|
||||
int npage;
|
||||
int left;
|
||||
|
||||
if (mtts == NULL || mtt_max < 1)
|
||||
goto done;
|
||||
|
||||
left = mtt_max;
|
||||
while (left > 0) {
|
||||
mtt_count = 0;
|
||||
addr = hns_roce_hem_list_find_mtt(hr_dev, &mtr->hem_list,
|
||||
offset + total,
|
||||
&mtt_count, NULL);
|
||||
if (!addr || !mtt_count)
|
||||
goto done;
|
||||
|
||||
npage = min(mtt_count, left);
|
||||
memcpy(&mtts[total], addr, BA_BYTE_LEN * npage);
|
||||
left -= npage;
|
||||
total += npage;
|
||||
}
|
||||
|
||||
done:
|
||||
if (base_addr)
|
||||
*base_addr = mtr->hem_list.root_ba;
|
||||
|
||||
return total;
|
||||
}
|
||||
|
@@ -83,18 +83,16 @@ int hns_roce_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_alloc_pd);
|
||||
|
||||
void hns_roce_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata)
|
||||
{
|
||||
hns_roce_pd_free(to_hr_dev(pd->device), to_hr_pd(pd)->pdn);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_dealloc_pd);
|
||||
|
||||
int hns_roce_uar_alloc(struct hns_roce_dev *hr_dev, struct hns_roce_uar *uar)
|
||||
{
|
||||
struct resource *res;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
/* Using bitmap to manager UAR index */
|
||||
ret = hns_roce_bitmap_alloc(&hr_dev->uar_table.bitmap, &uar->logic_idx);
|
||||
|
@@ -64,7 +64,6 @@ void hns_roce_qp_event(struct hns_roce_dev *hr_dev, u32 qpn, int event_type)
|
||||
if (atomic_dec_and_test(&qp->refcount))
|
||||
complete(&qp->free);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_qp_event);
|
||||
|
||||
static void hns_roce_ib_qp_event(struct hns_roce_qp *hr_qp,
|
||||
enum hns_roce_event type)
|
||||
@@ -139,7 +138,6 @@ enum hns_roce_qp_state to_hns_roce_state(enum ib_qp_state state)
|
||||
return HNS_ROCE_QP_NUM_STATE;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(to_hns_roce_state);
|
||||
|
||||
static int hns_roce_gsi_qp_alloc(struct hns_roce_dev *hr_dev, unsigned long qpn,
|
||||
struct hns_roce_qp *hr_qp)
|
||||
@@ -242,7 +240,6 @@ void hns_roce_qp_remove(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp)
|
||||
__xa_erase(xa, hr_qp->qpn & (hr_dev->caps.num_qps - 1));
|
||||
xa_unlock_irqrestore(xa, flags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_qp_remove);
|
||||
|
||||
void hns_roce_qp_free(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp)
|
||||
{
|
||||
@@ -257,22 +254,19 @@ void hns_roce_qp_free(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp)
|
||||
hns_roce_table_put(hr_dev, &qp_table->trrl_table,
|
||||
hr_qp->qpn);
|
||||
hns_roce_table_put(hr_dev, &qp_table->irrl_table, hr_qp->qpn);
|
||||
hns_roce_table_put(hr_dev, &qp_table->qp_table, hr_qp->qpn);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_qp_free);
|
||||
|
||||
void hns_roce_release_range_qp(struct hns_roce_dev *hr_dev, int base_qpn,
|
||||
int cnt)
|
||||
{
|
||||
struct hns_roce_qp_table *qp_table = &hr_dev->qp_table;
|
||||
|
||||
if (base_qpn < SQP_NUM)
|
||||
if (base_qpn < hr_dev->caps.reserved_qps)
|
||||
return;
|
||||
|
||||
hns_roce_bitmap_free_range(&qp_table->bitmap, base_qpn, cnt, BITMAP_RR);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_release_range_qp);
|
||||
|
||||
static int hns_roce_set_rq_size(struct hns_roce_dev *hr_dev,
|
||||
struct ib_qp_cap *cap, bool is_user, int has_rq,
|
||||
@@ -392,8 +386,8 @@ static int hns_roce_set_user_sq_size(struct hns_roce_dev *hr_dev,
|
||||
hr_qp->sq.wqe_shift), PAGE_SIZE);
|
||||
} else {
|
||||
page_size = 1 << (hr_dev->caps.mtt_buf_pg_sz + PAGE_SHIFT);
|
||||
hr_qp->sge.sge_cnt =
|
||||
max(page_size / (1 << hr_qp->sge.sge_shift), ex_sge_num);
|
||||
hr_qp->sge.sge_cnt = ex_sge_num ?
|
||||
max(page_size / (1 << hr_qp->sge.sge_shift), ex_sge_num) : 0;
|
||||
hr_qp->buff_size = HNS_ROCE_ALOGN_UP((hr_qp->rq.wqe_cnt <<
|
||||
hr_qp->rq.wqe_shift), page_size) +
|
||||
HNS_ROCE_ALOGN_UP((hr_qp->sge.sge_cnt <<
|
||||
@@ -422,6 +416,91 @@ static int hns_roce_set_user_sq_size(struct hns_roce_dev *hr_dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int split_wqe_buf_region(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_qp *hr_qp,
|
||||
struct hns_roce_buf_region *regions,
|
||||
int region_max, int page_shift)
|
||||
{
|
||||
int page_size = 1 << page_shift;
|
||||
bool is_extend_sge;
|
||||
int region_cnt = 0;
|
||||
int buf_size;
|
||||
int buf_cnt;
|
||||
|
||||
if (hr_qp->buff_size < 1 || region_max < 1)
|
||||
return region_cnt;
|
||||
|
||||
if (hr_qp->sge.sge_cnt > 0)
|
||||
is_extend_sge = true;
|
||||
else
|
||||
is_extend_sge = false;
|
||||
|
||||
/* sq region */
|
||||
if (is_extend_sge)
|
||||
buf_size = hr_qp->sge.offset - hr_qp->sq.offset;
|
||||
else
|
||||
buf_size = hr_qp->rq.offset - hr_qp->sq.offset;
|
||||
|
||||
if (buf_size > 0 && region_cnt < region_max) {
|
||||
buf_cnt = DIV_ROUND_UP(buf_size, page_size);
|
||||
hns_roce_init_buf_region(®ions[region_cnt],
|
||||
hr_dev->caps.wqe_sq_hop_num,
|
||||
hr_qp->sq.offset / page_size,
|
||||
buf_cnt);
|
||||
region_cnt++;
|
||||
}
|
||||
|
||||
/* sge region */
|
||||
if (is_extend_sge) {
|
||||
buf_size = hr_qp->rq.offset - hr_qp->sge.offset;
|
||||
if (buf_size > 0 && region_cnt < region_max) {
|
||||
buf_cnt = DIV_ROUND_UP(buf_size, page_size);
|
||||
hns_roce_init_buf_region(®ions[region_cnt],
|
||||
hr_dev->caps.wqe_sge_hop_num,
|
||||
hr_qp->sge.offset / page_size,
|
||||
buf_cnt);
|
||||
region_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
/* rq region */
|
||||
buf_size = hr_qp->buff_size - hr_qp->rq.offset;
|
||||
if (buf_size > 0) {
|
||||
buf_cnt = DIV_ROUND_UP(buf_size, page_size);
|
||||
hns_roce_init_buf_region(®ions[region_cnt],
|
||||
hr_dev->caps.wqe_rq_hop_num,
|
||||
hr_qp->rq.offset / page_size,
|
||||
buf_cnt);
|
||||
region_cnt++;
|
||||
}
|
||||
|
||||
return region_cnt;
|
||||
}
|
||||
|
||||
static int calc_wqe_bt_page_shift(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_buf_region *regions,
|
||||
int region_cnt)
|
||||
{
|
||||
int bt_pg_shift;
|
||||
int ba_num;
|
||||
int ret;
|
||||
|
||||
bt_pg_shift = PAGE_SHIFT + hr_dev->caps.mtt_ba_pg_sz;
|
||||
|
||||
/* all root ba entries must in one bt page */
|
||||
do {
|
||||
ba_num = (1 << bt_pg_shift) / BA_BYTE_LEN;
|
||||
ret = hns_roce_hem_list_calc_root_ba(regions, region_cnt,
|
||||
ba_num);
|
||||
if (ret <= ba_num)
|
||||
break;
|
||||
|
||||
bt_pg_shift++;
|
||||
} while (ret > ba_num);
|
||||
|
||||
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)
|
||||
@@ -534,15 +613,17 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
|
||||
struct ib_udata *udata, unsigned long sqpn,
|
||||
struct hns_roce_qp *hr_qp)
|
||||
{
|
||||
dma_addr_t *buf_list[ARRAY_SIZE(hr_qp->regions)] = { 0 };
|
||||
struct device *dev = hr_dev->dev;
|
||||
struct hns_roce_ib_create_qp ucmd;
|
||||
struct hns_roce_ib_create_qp_resp resp = {};
|
||||
struct hns_roce_ucontext *uctx = rdma_udata_to_drv_context(
|
||||
udata, struct hns_roce_ucontext, ibucontext);
|
||||
struct hns_roce_buf_region *r;
|
||||
unsigned long qpn = 0;
|
||||
int ret = 0;
|
||||
u32 page_shift;
|
||||
u32 npages;
|
||||
int buf_count;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
mutex_init(&hr_qp->mutex);
|
||||
@@ -596,6 +677,7 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
|
||||
init_attr->cap.max_recv_sge];
|
||||
}
|
||||
|
||||
page_shift = PAGE_SHIFT + hr_dev->caps.mtt_buf_pg_sz;
|
||||
if (udata) {
|
||||
if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd))) {
|
||||
dev_err(dev, "ib_copy_from_udata error for create qp\n");
|
||||
@@ -617,32 +699,28 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
|
||||
ret = PTR_ERR(hr_qp->umem);
|
||||
goto err_rq_sge_list;
|
||||
}
|
||||
|
||||
hr_qp->mtt.mtt_type = MTT_TYPE_WQE;
|
||||
page_shift = PAGE_SHIFT;
|
||||
if (hr_dev->caps.mtt_buf_pg_sz) {
|
||||
npages = (ib_umem_page_count(hr_qp->umem) +
|
||||
(1 << hr_dev->caps.mtt_buf_pg_sz) - 1) /
|
||||
(1 << hr_dev->caps.mtt_buf_pg_sz);
|
||||
page_shift += hr_dev->caps.mtt_buf_pg_sz;
|
||||
ret = hns_roce_mtt_init(hr_dev, npages,
|
||||
page_shift,
|
||||
&hr_qp->mtt);
|
||||
} else {
|
||||
ret = hns_roce_mtt_init(hr_dev,
|
||||
ib_umem_page_count(hr_qp->umem),
|
||||
page_shift, &hr_qp->mtt);
|
||||
}
|
||||
hr_qp->region_cnt = split_wqe_buf_region(hr_dev, hr_qp,
|
||||
hr_qp->regions, ARRAY_SIZE(hr_qp->regions),
|
||||
page_shift);
|
||||
ret = hns_roce_alloc_buf_list(hr_qp->regions, buf_list,
|
||||
hr_qp->region_cnt);
|
||||
if (ret) {
|
||||
dev_err(dev, "hns_roce_mtt_init error for create qp\n");
|
||||
goto err_buf;
|
||||
dev_err(dev, "alloc buf_list error for create qp\n");
|
||||
goto err_alloc_list;
|
||||
}
|
||||
|
||||
ret = hns_roce_ib_umem_write_mtt(hr_dev, &hr_qp->mtt,
|
||||
hr_qp->umem);
|
||||
if (ret) {
|
||||
dev_err(dev, "hns_roce_ib_umem_write_mtt error for create qp\n");
|
||||
goto err_mtt;
|
||||
for (i = 0; i < hr_qp->region_cnt; i++) {
|
||||
r = &hr_qp->regions[i];
|
||||
buf_count = hns_roce_get_umem_bufs(hr_dev,
|
||||
buf_list[i], r->count, r->offset,
|
||||
hr_qp->umem, page_shift);
|
||||
if (buf_count != r->count) {
|
||||
dev_err(dev,
|
||||
"get umem buf err, expect %d,ret %d.\n",
|
||||
r->count, buf_count);
|
||||
ret = -ENOBUFS;
|
||||
goto err_get_bufs;
|
||||
}
|
||||
}
|
||||
|
||||
if ((hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_SQ_RECORD_DB) &&
|
||||
@@ -653,7 +731,7 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
|
||||
&hr_qp->sdb);
|
||||
if (ret) {
|
||||
dev_err(dev, "sq record doorbell map failed!\n");
|
||||
goto err_mtt;
|
||||
goto err_get_bufs;
|
||||
}
|
||||
|
||||
/* indicate kernel supports sq record db */
|
||||
@@ -715,7 +793,6 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
|
||||
}
|
||||
|
||||
/* Allocate QP buf */
|
||||
page_shift = PAGE_SHIFT + hr_dev->caps.mtt_buf_pg_sz;
|
||||
if (hns_roce_buf_alloc(hr_dev, hr_qp->buff_size,
|
||||
(1 << page_shift) * 2,
|
||||
&hr_qp->hr_buf, page_shift)) {
|
||||
@@ -723,21 +800,28 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
|
||||
ret = -ENOMEM;
|
||||
goto err_db;
|
||||
}
|
||||
|
||||
hr_qp->mtt.mtt_type = MTT_TYPE_WQE;
|
||||
/* Write MTT */
|
||||
ret = hns_roce_mtt_init(hr_dev, hr_qp->hr_buf.npages,
|
||||
hr_qp->hr_buf.page_shift, &hr_qp->mtt);
|
||||
hr_qp->region_cnt = split_wqe_buf_region(hr_dev, hr_qp,
|
||||
hr_qp->regions, ARRAY_SIZE(hr_qp->regions),
|
||||
page_shift);
|
||||
ret = hns_roce_alloc_buf_list(hr_qp->regions, buf_list,
|
||||
hr_qp->region_cnt);
|
||||
if (ret) {
|
||||
dev_err(dev, "hns_roce_mtt_init error for kernel create qp\n");
|
||||
goto err_buf;
|
||||
dev_err(dev, "alloc buf_list error for create qp!\n");
|
||||
goto err_alloc_list;
|
||||
}
|
||||
|
||||
ret = hns_roce_buf_write_mtt(hr_dev, &hr_qp->mtt,
|
||||
&hr_qp->hr_buf);
|
||||
if (ret) {
|
||||
dev_err(dev, "hns_roce_buf_write_mtt error for kernel create qp\n");
|
||||
goto err_mtt;
|
||||
for (i = 0; i < hr_qp->region_cnt; i++) {
|
||||
r = &hr_qp->regions[i];
|
||||
buf_count = hns_roce_get_kmem_bufs(hr_dev,
|
||||
buf_list[i], r->count, r->offset,
|
||||
&hr_qp->hr_buf);
|
||||
if (buf_count != r->count) {
|
||||
dev_err(dev,
|
||||
"get kmem buf err, expect %d,ret %d.\n",
|
||||
r->count, buf_count);
|
||||
ret = -ENOBUFS;
|
||||
goto err_get_bufs;
|
||||
}
|
||||
}
|
||||
|
||||
hr_qp->sq.wrid = kcalloc(hr_qp->sq.wqe_cnt, sizeof(u64),
|
||||
@@ -761,6 +845,17 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
|
||||
}
|
||||
}
|
||||
|
||||
hr_qp->wqe_bt_pg_shift = calc_wqe_bt_page_shift(hr_dev, hr_qp->regions,
|
||||
hr_qp->region_cnt);
|
||||
hns_roce_mtr_init(&hr_qp->mtr, PAGE_SHIFT + hr_qp->wqe_bt_pg_shift,
|
||||
page_shift);
|
||||
ret = hns_roce_mtr_attach(hr_dev, &hr_qp->mtr, buf_list,
|
||||
hr_qp->regions, hr_qp->region_cnt);
|
||||
if (ret) {
|
||||
dev_err(dev, "mtr attach error for create qp\n");
|
||||
goto err_mtr;
|
||||
}
|
||||
|
||||
if (init_attr->qp_type == IB_QPT_GSI &&
|
||||
hr_dev->hw_rev == HNS_ROCE_HW_VER1) {
|
||||
/* In v1 engine, GSI QP context in RoCE engine's register */
|
||||
@@ -796,6 +891,7 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
|
||||
}
|
||||
|
||||
hr_qp->event = hns_roce_ib_qp_event;
|
||||
hns_roce_free_buf_list(buf_list, hr_qp->region_cnt);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -810,6 +906,9 @@ err_qpn:
|
||||
if (!sqpn)
|
||||
hns_roce_release_range_qp(hr_dev, qpn, 1);
|
||||
|
||||
err_mtr:
|
||||
hns_roce_mtr_cleanup(hr_dev, &hr_qp->mtr);
|
||||
|
||||
err_wrid:
|
||||
if (udata) {
|
||||
if ((hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) &&
|
||||
@@ -829,14 +928,13 @@ err_sq_dbmap:
|
||||
hns_roce_qp_has_sq(init_attr))
|
||||
hns_roce_db_unmap_user(uctx, &hr_qp->sdb);
|
||||
|
||||
err_mtt:
|
||||
hns_roce_mtt_cleanup(hr_dev, &hr_qp->mtt);
|
||||
err_get_bufs:
|
||||
hns_roce_free_buf_list(buf_list, hr_qp->region_cnt);
|
||||
|
||||
err_buf:
|
||||
if (hr_qp->umem)
|
||||
ib_umem_release(hr_qp->umem);
|
||||
else
|
||||
err_alloc_list:
|
||||
if (!hr_qp->umem)
|
||||
hns_roce_buf_free(hr_dev, hr_qp->buff_size, &hr_qp->hr_buf);
|
||||
ib_umem_release(hr_qp->umem);
|
||||
|
||||
err_db:
|
||||
if (!udata && hns_roce_qp_has_rq(init_attr) &&
|
||||
@@ -923,7 +1021,6 @@ struct ib_qp *hns_roce_create_qp(struct ib_pd *pd,
|
||||
|
||||
return &hr_qp->ibqp;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_create_qp);
|
||||
|
||||
int to_hr_qp_type(int qp_type)
|
||||
{
|
||||
@@ -942,7 +1039,6 @@ int to_hr_qp_type(int qp_type)
|
||||
|
||||
return transport_type;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(to_hr_qp_type);
|
||||
|
||||
int hns_roce_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
|
||||
int attr_mask, struct ib_udata *udata)
|
||||
@@ -1062,7 +1158,6 @@ void hns_roce_lock_cqs(struct hns_roce_cq *send_cq, struct hns_roce_cq *recv_cq)
|
||||
spin_lock_nested(&send_cq->lock, SINGLE_DEPTH_NESTING);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_lock_cqs);
|
||||
|
||||
void hns_roce_unlock_cqs(struct hns_roce_cq *send_cq,
|
||||
struct hns_roce_cq *recv_cq) __releases(&send_cq->lock)
|
||||
@@ -1079,7 +1174,6 @@ void hns_roce_unlock_cqs(struct hns_roce_cq *send_cq,
|
||||
spin_unlock_irq(&recv_cq->lock);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_unlock_cqs);
|
||||
|
||||
static void *get_wqe(struct hns_roce_qp *hr_qp, int offset)
|
||||
{
|
||||
@@ -1091,20 +1185,17 @@ void *get_recv_wqe(struct hns_roce_qp *hr_qp, int n)
|
||||
{
|
||||
return get_wqe(hr_qp, hr_qp->rq.offset + (n << hr_qp->rq.wqe_shift));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(get_recv_wqe);
|
||||
|
||||
void *get_send_wqe(struct hns_roce_qp *hr_qp, int n)
|
||||
{
|
||||
return get_wqe(hr_qp, hr_qp->sq.offset + (n << hr_qp->sq.wqe_shift));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(get_send_wqe);
|
||||
|
||||
void *get_send_extend_sge(struct hns_roce_qp *hr_qp, int n)
|
||||
{
|
||||
return hns_roce_buf_offset(&hr_qp->hr_buf, hr_qp->sge.offset +
|
||||
(n << hr_qp->sge.sge_shift));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(get_send_extend_sge);
|
||||
|
||||
bool hns_roce_wq_overflow(struct hns_roce_wq *hr_wq, int nreq,
|
||||
struct ib_cq *ib_cq)
|
||||
@@ -1123,7 +1214,6 @@ bool hns_roce_wq_overflow(struct hns_roce_wq *hr_wq, int nreq,
|
||||
|
||||
return cur + nreq >= hr_wq->max_post;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_wq_overflow);
|
||||
|
||||
int hns_roce_init_qp_table(struct hns_roce_dev *hr_dev)
|
||||
{
|
||||
@@ -1135,11 +1225,7 @@ int hns_roce_init_qp_table(struct hns_roce_dev *hr_dev)
|
||||
mutex_init(&qp_table->scc_mutex);
|
||||
xa_init(&hr_dev->qp_table_xa);
|
||||
|
||||
/* In hw v1, a port include two SQP, six ports total 12 */
|
||||
if (hr_dev->caps.max_sq_sg <= 2)
|
||||
reserved_from_bot = SQP_NUM;
|
||||
else
|
||||
reserved_from_bot = hr_dev->caps.reserved_qps;
|
||||
reserved_from_bot = hr_dev->caps.reserved_qps;
|
||||
|
||||
ret = hns_roce_bitmap_init(&qp_table->bitmap, hr_dev->caps.num_qps,
|
||||
hr_dev->caps.num_qps - 1, reserved_from_bot,
|
||||
|
@@ -30,7 +30,6 @@ void hns_roce_srq_event(struct hns_roce_dev *hr_dev, u32 srqn, int event_type)
|
||||
if (atomic_dec_and_test(&srq->refcount))
|
||||
complete(&srq->free);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hns_roce_srq_event);
|
||||
|
||||
static void hns_roce_ib_srq_event(struct hns_roce_srq *srq,
|
||||
enum hns_roce_event event_type)
|
||||
@@ -181,28 +180,19 @@ static int hns_roce_create_idx_que(struct ib_pd *pd, struct hns_roce_srq *srq,
|
||||
{
|
||||
struct hns_roce_dev *hr_dev = to_hr_dev(pd->device);
|
||||
struct hns_roce_idx_que *idx_que = &srq->idx_que;
|
||||
u32 bitmap_num;
|
||||
int i;
|
||||
|
||||
bitmap_num = HNS_ROCE_ALOGN_UP(srq->max, 8 * sizeof(u64));
|
||||
|
||||
idx_que->bitmap = kcalloc(1, bitmap_num / 8, GFP_KERNEL);
|
||||
idx_que->bitmap = bitmap_zalloc(srq->max, GFP_KERNEL);
|
||||
if (!idx_que->bitmap)
|
||||
return -ENOMEM;
|
||||
|
||||
bitmap_num = bitmap_num / (8 * sizeof(u64));
|
||||
|
||||
idx_que->buf_size = srq->idx_que.buf_size;
|
||||
|
||||
if (hns_roce_buf_alloc(hr_dev, idx_que->buf_size, (1 << page_shift) * 2,
|
||||
&idx_que->idx_buf, page_shift)) {
|
||||
kfree(idx_que->bitmap);
|
||||
bitmap_free(idx_que->bitmap);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
for (i = 0; i < bitmap_num; i++)
|
||||
idx_que->bitmap[i] = ~(0UL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -264,8 +254,7 @@ int hns_roce_create_srq(struct ib_srq *ib_srq,
|
||||
} else
|
||||
ret = hns_roce_mtt_init(hr_dev,
|
||||
ib_umem_page_count(srq->umem),
|
||||
srq->umem->page_shift,
|
||||
&srq->mtt);
|
||||
PAGE_SHIFT, &srq->mtt);
|
||||
if (ret)
|
||||
goto err_buf;
|
||||
|
||||
@@ -291,10 +280,9 @@ int hns_roce_create_srq(struct ib_srq *ib_srq,
|
||||
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),
|
||||
srq->idx_que.umem->page_shift,
|
||||
&srq->idx_que.mtt);
|
||||
ret = hns_roce_mtt_init(
|
||||
hr_dev, ib_umem_page_count(srq->idx_que.umem),
|
||||
PAGE_SHIFT, &srq->idx_que.mtt);
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
@@ -391,21 +379,19 @@ err_idx_buf:
|
||||
hns_roce_mtt_cleanup(hr_dev, &srq->idx_que.mtt);
|
||||
|
||||
err_idx_mtt:
|
||||
if (udata)
|
||||
ib_umem_release(srq->idx_que.umem);
|
||||
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);
|
||||
kfree(srq->idx_que.bitmap);
|
||||
bitmap_free(srq->idx_que.bitmap);
|
||||
|
||||
err_srq_mtt:
|
||||
hns_roce_mtt_cleanup(hr_dev, &srq->mtt);
|
||||
|
||||
err_buf:
|
||||
if (udata)
|
||||
ib_umem_release(srq->umem);
|
||||
else
|
||||
ib_umem_release(srq->umem);
|
||||
if (!udata)
|
||||
hns_roce_buf_free(hr_dev, srq_buf_size, &srq->buf);
|
||||
|
||||
return ret;
|
||||
@@ -419,15 +405,15 @@ void hns_roce_destroy_srq(struct ib_srq *ibsrq, struct ib_udata *udata)
|
||||
hns_roce_srq_free(hr_dev, srq);
|
||||
hns_roce_mtt_cleanup(hr_dev, &srq->mtt);
|
||||
|
||||
if (ibsrq->uobject) {
|
||||
if (udata) {
|
||||
hns_roce_mtt_cleanup(hr_dev, &srq->idx_que.mtt);
|
||||
ib_umem_release(srq->idx_que.umem);
|
||||
ib_umem_release(srq->umem);
|
||||
} else {
|
||||
kvfree(srq->wrid);
|
||||
hns_roce_buf_free(hr_dev, srq->max << srq->wqe_shift,
|
||||
&srq->buf);
|
||||
}
|
||||
ib_umem_release(srq->idx_que.umem);
|
||||
ib_umem_release(srq->umem);
|
||||
}
|
||||
|
||||
int hns_roce_init_srq_table(struct hns_roce_dev *hr_dev)
|
||||
|
Reference in New Issue
Block a user