summaryrefslogtreecommitdiff
path: root/drivers/infiniband/hw/hns/hns_roce_restrack.c
blob: 06871731ac43a72bde2c9df27ddde99740809732 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
// Copyright (c) 2019 Hisilicon Limited.

#include <rdma/rdma_cm.h>
#include <rdma/restrack.h>
#include <uapi/rdma/rdma_netlink.h>
#include "hnae3.h"
#include "hns_roce_common.h"
#include "hns_roce_device.h"
#include "hns_roce_hw_v2.h"

static int hns_roce_fill_cq(struct sk_buff *msg,
			    struct hns_roce_v2_cq_context *context)
{
	if (rdma_nl_put_driver_u32(msg, "state",
				   roce_get_field(context->byte_4_pg_ceqn,
						  V2_CQC_BYTE_4_ARM_ST_M,
						  V2_CQC_BYTE_4_ARM_ST_S)))
		goto err;

	if (rdma_nl_put_driver_u32(msg, "ceqn",
				   roce_get_field(context->byte_4_pg_ceqn,
						  V2_CQC_BYTE_4_CEQN_M,
						  V2_CQC_BYTE_4_CEQN_S)))
		goto err;

	if (rdma_nl_put_driver_u32(msg, "cqn",
				   roce_get_field(context->byte_8_cqn,
						  V2_CQC_BYTE_8_CQN_M,
						  V2_CQC_BYTE_8_CQN_S)))
		goto err;

	if (rdma_nl_put_driver_u32(msg, "hopnum",
				   roce_get_field(context->byte_16_hop_addr,
						  V2_CQC_BYTE_16_CQE_HOP_NUM_M,
						  V2_CQC_BYTE_16_CQE_HOP_NUM_S)))
		goto err;

	if (rdma_nl_put_driver_u32(
		    msg, "pi",
		    roce_get_field(context->byte_28_cq_pi,
				   V2_CQC_BYTE_28_CQ_PRODUCER_IDX_M,
				   V2_CQC_BYTE_28_CQ_PRODUCER_IDX_S)))
		goto err;

	if (rdma_nl_put_driver_u32(
		    msg, "ci",
		    roce_get_field(context->byte_32_cq_ci,
				   V2_CQC_BYTE_32_CQ_CONSUMER_IDX_M,
				   V2_CQC_BYTE_32_CQ_CONSUMER_IDX_S)))
		goto err;

	if (rdma_nl_put_driver_u32(
		    msg, "coalesce",
		    roce_get_field(context->byte_56_cqe_period_maxcnt,
				   V2_CQC_BYTE_56_CQ_MAX_CNT_M,
				   V2_CQC_BYTE_56_CQ_MAX_CNT_S)))
		goto err;

	if (rdma_nl_put_driver_u32(
		    msg, "period",
		    roce_get_field(context->byte_56_cqe_period_maxcnt,
				   V2_CQC_BYTE_56_CQ_PERIOD_M,
				   V2_CQC_BYTE_56_CQ_PERIOD_S)))
		goto err;

	if (rdma_nl_put_driver_u32(msg, "cnt",
				   roce_get_field(context->byte_52_cqe_cnt,
						  V2_CQC_BYTE_52_CQE_CNT_M,
						  V2_CQC_BYTE_52_CQE_CNT_S)))
		goto err;

	return 0;

err:
	return -EMSGSIZE;
}

static int hns_roce_fill_res_cq_entry(struct sk_buff *msg,
				      struct rdma_restrack_entry *res)
{
	struct ib_cq *ib_cq = container_of(res, struct ib_cq, res);
	struct hns_roce_dev *hr_dev = to_hr_dev(ib_cq->device);
	struct hns_roce_cq *hr_cq = to_hr_cq(ib_cq);
	struct hns_roce_v2_cq_context *context;
	struct nlattr *table_attr;
	int ret;

	if (!hr_dev->dfx->query_cqc_info)
		return -EINVAL;

	context = kzalloc(sizeof(struct hns_roce_v2_cq_context), GFP_KERNEL);
	if (!context)
		return -ENOMEM;

	ret = hr_dev->dfx->query_cqc_info(hr_dev, hr_cq->cqn, (int *)context);
	if (ret)
		goto err;

	table_attr = nla_nest_start(msg, RDMA_NLDEV_ATTR_DRIVER);
	if (!table_attr) {
		ret = -EMSGSIZE;
		goto err;
	}

	if (hns_roce_fill_cq(msg, context)) {
		ret = -EMSGSIZE;
		goto err_cancel_table;
	}

	nla_nest_end(msg, table_attr);
	kfree(context);

	return 0;

err_cancel_table:
	nla_nest_cancel(msg, table_attr);
err:
	kfree(context);
	return ret;
}

int hns_roce_fill_res_entry(struct sk_buff *msg,
			    struct rdma_restrack_entry *res)
{
	if (res->type == RDMA_RESTRACK_CQ)
		return hns_roce_fill_res_cq_entry(msg, res);

	return 0;
}