]> git.proxmox.com Git - mirror_iproute2.git/blame - rdma/dev.c
rdma: Add dev object
[mirror_iproute2.git] / rdma / dev.c
CommitLineData
40df8263
LR
1/*
2 * dev.c RDMA tool
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Authors: Leon Romanovsky <leonro@mellanox.com>
10 */
11
12#include "rdma.h"
13
14static int dev_help(struct rd *rd)
15{
16 pr_out("Usage: %s dev show [DEV]\n", rd->filename);
17 return 0;
18}
19
20static const char *dev_caps_to_str(uint32_t idx)
21{
22#define RDMA_DEV_FLAGS(x) \
23 x(RESIZE_MAX_WR, 0) \
24 x(BAD_PKEY_CNTR, 1) \
25 x(BAD_QKEY_CNTR, 2) \
26 x(RAW_MULTI, 3) \
27 x(AUTO_PATH_MIG, 4) \
28 x(CHANGE_PHY_PORT, 5) \
29 x(UD_AV_PORT_ENFORCE_PORT_ENFORCE, 6) \
30 x(CURR_QP_STATE_MOD, 7) \
31 x(SHUTDOWN_PORT, 8) \
32 x(INIT_TYPE, 9) \
33 x(PORT_ACTIVE_EVENT, 10) \
34 x(SYS_IMAGE_GUID, 11) \
35 x(RC_RNR_NAK_GEN, 12) \
36 x(SRQ_RESIZE, 13) \
37 x(N_NOTIFY_CQ, 14) \
38 x(LOCAL_DMA_LKEY, 15) \
39 x(MEM_WINDOW, 17) \
40 x(UD_IP_CSUM, 18) \
41 x(UD_TSO, 19) \
42 x(XRC, 20) \
43 x(MEM_MGT_EXTENSIONS, 21) \
44 x(BLOCK_MULTICAST_LOOPBACK, 22) \
45 x(MEM_WINDOW_TYPE_2A, 23) \
46 x(MEM_WINDOW_TYPE_2B, 24) \
47 x(RC_IP_CSUM, 25) \
48 x(RAW_IP_CSUM, 26) \
49 x(CROSS_CHANNEL, 27) \
50 x(MANAGED_FLOW_STEERING, 29) \
51 x(SIGNATURE_HANDOVER, 30) \
52 x(ON_DEMAND_PAGING, 31) \
53 x(SG_GAPS_REG, 32) \
54 x(VIRTUAL_FUNCTION, 33) \
55 x(RAW_SCATTER_FCS, 34) \
56 x(RDMA_NETDEV_OPA_VNIC, 35)
57
58 enum { RDMA_DEV_FLAGS(RDMA_BITMAP_ENUM) };
59
60 static const char * const
61 rdma_dev_names[] = { RDMA_DEV_FLAGS(RDMA_BITMAP_NAMES) };
62 #undef RDMA_DEV_FLAGS
63
64 if (idx < ARRAY_SIZE(rdma_dev_names) && rdma_dev_names[idx])
65 return rdma_dev_names[idx];
66 return "UNKNOWN";
67}
68
69static void dev_print_caps(struct nlattr **tb)
70{
71 uint64_t caps;
72 uint32_t idx;
73
74 if (!tb[RDMA_NLDEV_ATTR_CAP_FLAGS])
75 return;
76
77 caps = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_CAP_FLAGS]);
78
79 pr_out("\n caps: <");
80 for (idx = 0; caps; idx++) {
81 if (caps & 0x1) {
82 pr_out("%s", dev_caps_to_str(idx));
83 if (caps >> 0x1)
84 pr_out(", ");
85 }
86 caps >>= 0x1;
87 }
88
89 pr_out(">");
90}
91
92static void dev_print_fw(struct nlattr **tb)
93{
94 if (!tb[RDMA_NLDEV_ATTR_FW_VERSION])
95 return;
96
97 pr_out("fw %s ",
98 mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_FW_VERSION]));
99}
100
101static void dev_print_node_guid(struct nlattr **tb)
102{
103 uint64_t node_guid;
104
105 if (!tb[RDMA_NLDEV_ATTR_NODE_GUID])
106 return;
107
108 node_guid = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_NODE_GUID]);
109 rd_print_u64("node_guid", node_guid);
110}
111
112static void dev_print_sys_image_guid(struct nlattr **tb)
113{
114 uint64_t sys_image_guid;
115
116 if (!tb[RDMA_NLDEV_ATTR_SYS_IMAGE_GUID])
117 return;
118
119 sys_image_guid = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_SYS_IMAGE_GUID]);
120 rd_print_u64("sys_image_guid", sys_image_guid);
121}
122
123static const char *node_type_to_str(uint8_t node_type)
124{
125 static const char * const node_type_str[] = { "unknown", "ca",
126 "switch", "router",
127 "rnic", "usnic",
128 "usnic_dp" };
129 if (node_type < ARRAY_SIZE(node_type_str))
130 return node_type_str[node_type];
131 return "unknown";
132}
133
134static void dev_print_node_type(struct nlattr **tb)
135{
136 uint8_t node_type;
137
138 if (!tb[RDMA_NLDEV_ATTR_DEV_NODE_TYPE])
139 return;
140
141 node_type = mnl_attr_get_u8(tb[RDMA_NLDEV_ATTR_DEV_NODE_TYPE]);
142 pr_out("node_type %s ", node_type_to_str(node_type));
143}
144
145static int dev_parse_cb(const struct nlmsghdr *nlh, void *data)
146{
147 struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
148 struct rd *rd = data;
149
150 mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
151 if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME])
152 return MNL_CB_ERROR;
153
154 pr_out("%u: %s: ",
155 mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]),
156 mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]));
157 dev_print_node_type(tb);
158 dev_print_fw(tb);
159 dev_print_node_guid(tb);
160 dev_print_sys_image_guid(tb);
161 if (rd->show_details)
162 dev_print_caps(tb);
163
164 pr_out("\n");
165 return MNL_CB_OK;
166}
167
168static int dev_no_args(struct rd *rd)
169{
170 uint32_t seq;
171 int ret;
172
173 rd_prepare_msg(rd, RDMA_NLDEV_CMD_GET,
174 &seq, (NLM_F_REQUEST | NLM_F_ACK));
175 mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx);
176 ret = rd_send_msg(rd);
177 if (ret)
178 return ret;
179
180 return rd_recv_msg(rd, dev_parse_cb, rd, seq);
181}
182
183static int dev_one_show(struct rd *rd)
184{
185 const struct rd_cmd cmds[] = {
186 { NULL, dev_no_args},
187 { 0 }
188 };
189
190 return rd_exec_cmd(rd, cmds, "parameter");
191}
192
193static int dev_show(struct rd *rd)
194{
195 struct dev_map *dev_map;
196 int ret = 0;
197
198 if (rd_no_arg(rd)) {
199 list_for_each_entry(dev_map, &rd->dev_map_list, list) {
200 rd->dev_idx = dev_map->idx;
201 ret = dev_one_show(rd);
202 if (ret)
203 return ret;
204 }
205
206 } else {
207 dev_map = dev_map_lookup(rd, false);
208 if (!dev_map) {
209 pr_err("Wrong device name\n");
210 return -ENOENT;
211 }
212 rd_arg_inc(rd);
213 rd->dev_idx = dev_map->idx;
214 ret = dev_one_show(rd);
215 }
216 return ret;
217}
218
219int cmd_dev(struct rd *rd)
220{
221 const struct rd_cmd cmds[] = {
222 { NULL, dev_show },
223 { "show", dev_show },
224 { "list", dev_show },
225 { "help", dev_help },
226 { 0 }
227 };
228
229 return rd_exec_cmd(rd, cmds, "dev command");
230}