]> git.proxmox.com Git - mirror_iproute2.git/blame - rdma/dev.c
Merge 'iproute2-master' into iproute2-next
[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);
4443c9c6 17 pr_out(" %s dev set [DEV] name DEVNAME\n", rd->filename);
40df8263
LR
18 return 0;
19}
20
21static const char *dev_caps_to_str(uint32_t idx)
22{
378dd31b 23#define RDMA_DEV_FLAGS_LOW(x) \
40df8263
LR
24 x(RESIZE_MAX_WR, 0) \
25 x(BAD_PKEY_CNTR, 1) \
26 x(BAD_QKEY_CNTR, 2) \
27 x(RAW_MULTI, 3) \
28 x(AUTO_PATH_MIG, 4) \
29 x(CHANGE_PHY_PORT, 5) \
30 x(UD_AV_PORT_ENFORCE_PORT_ENFORCE, 6) \
31 x(CURR_QP_STATE_MOD, 7) \
32 x(SHUTDOWN_PORT, 8) \
33 x(INIT_TYPE, 9) \
34 x(PORT_ACTIVE_EVENT, 10) \
35 x(SYS_IMAGE_GUID, 11) \
36 x(RC_RNR_NAK_GEN, 12) \
37 x(SRQ_RESIZE, 13) \
38 x(N_NOTIFY_CQ, 14) \
39 x(LOCAL_DMA_LKEY, 15) \
40 x(MEM_WINDOW, 17) \
41 x(UD_IP_CSUM, 18) \
42 x(UD_TSO, 19) \
43 x(XRC, 20) \
44 x(MEM_MGT_EXTENSIONS, 21) \
45 x(BLOCK_MULTICAST_LOOPBACK, 22) \
46 x(MEM_WINDOW_TYPE_2A, 23) \
47 x(MEM_WINDOW_TYPE_2B, 24) \
48 x(RC_IP_CSUM, 25) \
49 x(RAW_IP_CSUM, 26) \
50 x(CROSS_CHANNEL, 27) \
51 x(MANAGED_FLOW_STEERING, 29) \
52 x(SIGNATURE_HANDOVER, 30) \
378dd31b 53 x(ON_DEMAND_PAGING, 31)
40df8263 54
378dd31b
LR
55#define RDMA_DEV_FLAGS_HIGH(x) \
56 x(SG_GAPS_REG, 0) \
57 x(VIRTUAL_FUNCTION, 1) \
58 x(RAW_SCATTER_FCS, 2) \
59 x(RDMA_NETDEV_OPA_VNIC, 3) \
60 x(PCI_WRITE_END_PADDING, 4)
40df8263 61
378dd31b
LR
62 /*
63 * Separation below is needed to allow compilation of rdmatool
64 * on 32bits systems. On such systems, C-enum is limited to be
65 * int and can't hold more than 32 bits.
66 */
67 enum { RDMA_DEV_FLAGS_LOW(RDMA_BITMAP_ENUM) };
68 enum { RDMA_DEV_FLAGS_HIGH(RDMA_BITMAP_ENUM) };
69
70 static const char * const
71 rdma_dev_names_low[] = { RDMA_DEV_FLAGS_LOW(RDMA_BITMAP_NAMES) };
40df8263 72 static const char * const
378dd31b
LR
73 rdma_dev_names_high[] = { RDMA_DEV_FLAGS_HIGH(RDMA_BITMAP_NAMES) };
74 uint32_t high_idx;
75 #undef RDMA_DEV_FLAGS_LOW
76 #undef RDMA_DEV_FLAGS_HIGH
77
78 if (idx < ARRAY_SIZE(rdma_dev_names_low) && rdma_dev_names_low[idx])
79 return rdma_dev_names_low[idx];
80
81 high_idx = idx - ARRAY_SIZE(rdma_dev_names_low);
82 if (high_idx < ARRAY_SIZE(rdma_dev_names_high) &&
83 rdma_dev_names_high[high_idx])
84 return rdma_dev_names_high[high_idx];
40df8263 85
40df8263
LR
86 return "UNKNOWN";
87}
88
ef353e2e 89static void dev_print_caps(struct rd *rd, struct nlattr **tb)
40df8263
LR
90{
91 uint64_t caps;
92 uint32_t idx;
93
94 if (!tb[RDMA_NLDEV_ATTR_CAP_FLAGS])
95 return;
96
97 caps = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_CAP_FLAGS]);
98
ef353e2e
LR
99 if (rd->json_output) {
100 jsonw_name(rd->jw, "caps");
101 jsonw_start_array(rd->jw);
102 } else {
103 pr_out("\n caps: <");
104 }
40df8263
LR
105 for (idx = 0; caps; idx++) {
106 if (caps & 0x1) {
ef353e2e
LR
107 if (rd->json_output) {
108 jsonw_string(rd->jw, dev_caps_to_str(idx));
109 } else {
110 pr_out("%s", dev_caps_to_str(idx));
111 if (caps >> 0x1)
112 pr_out(", ");
113 }
40df8263
LR
114 }
115 caps >>= 0x1;
116 }
117
ef353e2e
LR
118 if (rd->json_output)
119 jsonw_end_array(rd->jw);
120 else
121 pr_out(">");
40df8263
LR
122}
123
ef353e2e 124static void dev_print_fw(struct rd *rd, struct nlattr **tb)
40df8263 125{
ef353e2e 126 const char *str;
40df8263
LR
127 if (!tb[RDMA_NLDEV_ATTR_FW_VERSION])
128 return;
129
ef353e2e
LR
130 str = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_FW_VERSION]);
131 if (rd->json_output)
132 jsonw_string_field(rd->jw, "fw", str);
133 else
134 pr_out("fw %s ", str);
40df8263
LR
135}
136
ef353e2e 137static void dev_print_node_guid(struct rd *rd, struct nlattr **tb)
40df8263
LR
138{
139 uint64_t node_guid;
ef353e2e
LR
140 uint16_t vp[4];
141 char str[32];
40df8263
LR
142
143 if (!tb[RDMA_NLDEV_ATTR_NODE_GUID])
144 return;
145
146 node_guid = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_NODE_GUID]);
ef353e2e
LR
147 memcpy(vp, &node_guid, sizeof(uint64_t));
148 snprintf(str, 32, "%04x:%04x:%04x:%04x", vp[3], vp[2], vp[1], vp[0]);
149 if (rd->json_output)
150 jsonw_string_field(rd->jw, "node_guid", str);
151 else
152 pr_out("node_guid %s ", str);
40df8263
LR
153}
154
ef353e2e 155static void dev_print_sys_image_guid(struct rd *rd, struct nlattr **tb)
40df8263
LR
156{
157 uint64_t sys_image_guid;
ef353e2e
LR
158 uint16_t vp[4];
159 char str[32];
40df8263
LR
160
161 if (!tb[RDMA_NLDEV_ATTR_SYS_IMAGE_GUID])
162 return;
163
164 sys_image_guid = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_SYS_IMAGE_GUID]);
ef353e2e
LR
165 memcpy(vp, &sys_image_guid, sizeof(uint64_t));
166 snprintf(str, 32, "%04x:%04x:%04x:%04x", vp[3], vp[2], vp[1], vp[0]);
167 if (rd->json_output)
168 jsonw_string_field(rd->jw, "sys_image_guid", str);
169 else
170 pr_out("sys_image_guid %s ", str);
40df8263
LR
171}
172
173static const char *node_type_to_str(uint8_t node_type)
174{
175 static const char * const node_type_str[] = { "unknown", "ca",
176 "switch", "router",
177 "rnic", "usnic",
178 "usnic_dp" };
179 if (node_type < ARRAY_SIZE(node_type_str))
180 return node_type_str[node_type];
181 return "unknown";
182}
183
ef353e2e 184static void dev_print_node_type(struct rd *rd, struct nlattr **tb)
40df8263 185{
ef353e2e 186 const char *node_str;
40df8263
LR
187 uint8_t node_type;
188
189 if (!tb[RDMA_NLDEV_ATTR_DEV_NODE_TYPE])
190 return;
191
192 node_type = mnl_attr_get_u8(tb[RDMA_NLDEV_ATTR_DEV_NODE_TYPE]);
ef353e2e
LR
193 node_str = node_type_to_str(node_type);
194 if (rd->json_output)
195 jsonw_string_field(rd->jw, "node_type", node_str);
196 else
197 pr_out("node_type %s ", node_str);
40df8263
LR
198}
199
200static int dev_parse_cb(const struct nlmsghdr *nlh, void *data)
201{
202 struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
203 struct rd *rd = data;
ef353e2e
LR
204 const char *name;
205 uint32_t idx;
40df8263
LR
206
207 mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
208 if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME])
209 return MNL_CB_ERROR;
210
ef353e2e
LR
211 idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
212 name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
213 if (rd->json_output) {
214 jsonw_uint_field(rd->jw, "ifindex", idx);
215 jsonw_string_field(rd->jw, "ifname", name);
216 } else {
217 pr_out("%u: %s: ", idx, name);
218 }
219
220 dev_print_node_type(rd, tb);
221 dev_print_fw(rd, tb);
222 dev_print_node_guid(rd, tb);
223 dev_print_sys_image_guid(rd, tb);
40df8263 224 if (rd->show_details)
ef353e2e 225 dev_print_caps(rd, tb);
40df8263 226
ef353e2e
LR
227 if (!rd->json_output)
228 pr_out("\n");
40df8263
LR
229 return MNL_CB_OK;
230}
231
232static int dev_no_args(struct rd *rd)
233{
234 uint32_t seq;
235 int ret;
236
237 rd_prepare_msg(rd, RDMA_NLDEV_CMD_GET,
238 &seq, (NLM_F_REQUEST | NLM_F_ACK));
239 mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx);
240 ret = rd_send_msg(rd);
241 if (ret)
242 return ret;
243
ef353e2e
LR
244 if (rd->json_output)
245 jsonw_start_object(rd->jw);
246 ret = rd_recv_msg(rd, dev_parse_cb, rd, seq);
247 if (rd->json_output)
248 jsonw_end_object(rd->jw);
249 return ret;
40df8263
LR
250}
251
252static int dev_one_show(struct rd *rd)
253{
254 const struct rd_cmd cmds[] = {
255 { NULL, dev_no_args},
256 { 0 }
257 };
258
259 return rd_exec_cmd(rd, cmds, "parameter");
260}
261
4443c9c6
LR
262static int dev_set_name(struct rd *rd)
263{
264 uint32_t seq;
265
266 if (rd_no_arg(rd)) {
267 pr_err("Please provide device new name.\n");
268 return -EINVAL;
269 }
270
271 rd_prepare_msg(rd, RDMA_NLDEV_CMD_SET,
272 &seq, (NLM_F_REQUEST | NLM_F_ACK));
273 mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx);
274 mnl_attr_put_strz(rd->nlh, RDMA_NLDEV_ATTR_DEV_NAME, rd_argv(rd));
275
276 return rd_send_msg(rd);
277}
278
279static int dev_one_set(struct rd *rd)
280{
281 const struct rd_cmd cmds[] = {
282 { NULL, dev_help},
283 { "name", dev_set_name},
284 { 0 }
285 };
286
287 return rd_exec_cmd(rd, cmds, "parameter");
288}
289
40df8263
LR
290static int dev_show(struct rd *rd)
291{
8b92a2c9 292 return rd_exec_dev(rd, dev_one_show);
40df8263
LR
293}
294
4443c9c6
LR
295static int dev_set(struct rd *rd)
296{
297 return rd_exec_require_dev(rd, dev_one_set);
298}
299
40df8263
LR
300int cmd_dev(struct rd *rd)
301{
302 const struct rd_cmd cmds[] = {
303 { NULL, dev_show },
304 { "show", dev_show },
305 { "list", dev_show },
4443c9c6 306 { "set", dev_set },
40df8263
LR
307 { "help", dev_help },
308 { 0 }
309 };
310
311 return rd_exec_cmd(rd, cmds, "dev command");
312}