]> git.proxmox.com Git - mirror_iproute2.git/blob - rdma/dev.c
drop support for DECnet
[mirror_iproute2.git] / rdma / dev.c
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
14 static int dev_help(struct rd *rd)
15 {
16 pr_out("Usage: %s dev show [DEV]\n", rd->filename);
17 pr_out(" %s dev set [DEV] name DEVNAME\n", rd->filename);
18 return 0;
19 }
20
21 static const char *dev_caps_to_str(uint32_t idx)
22 {
23 #define RDMA_DEV_FLAGS(x) \
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) \
53 x(ON_DEMAND_PAGING, 31) \
54 x(SG_GAPS_REG, 32) \
55 x(VIRTUAL_FUNCTION, 33) \
56 x(RAW_SCATTER_FCS, 34) \
57 x(RDMA_NETDEV_OPA_VNIC, 35) \
58 x(PCI_WRITE_END_PADDING, 36)
59
60 enum { RDMA_DEV_FLAGS(RDMA_BITMAP_ENUM) };
61
62 static const char * const
63 rdma_dev_names[] = { RDMA_DEV_FLAGS(RDMA_BITMAP_NAMES) };
64 #undef RDMA_DEV_FLAGS
65
66 if (idx < ARRAY_SIZE(rdma_dev_names) && rdma_dev_names[idx])
67 return rdma_dev_names[idx];
68 return "UNKNOWN";
69 }
70
71 static void dev_print_caps(struct rd *rd, struct nlattr **tb)
72 {
73 uint64_t caps;
74 uint32_t idx;
75
76 if (!tb[RDMA_NLDEV_ATTR_CAP_FLAGS])
77 return;
78
79 caps = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_CAP_FLAGS]);
80
81 if (rd->json_output) {
82 jsonw_name(rd->jw, "caps");
83 jsonw_start_array(rd->jw);
84 } else {
85 pr_out("\n caps: <");
86 }
87 for (idx = 0; caps; idx++) {
88 if (caps & 0x1) {
89 if (rd->json_output) {
90 jsonw_string(rd->jw, dev_caps_to_str(idx));
91 } else {
92 pr_out("%s", dev_caps_to_str(idx));
93 if (caps >> 0x1)
94 pr_out(", ");
95 }
96 }
97 caps >>= 0x1;
98 }
99
100 if (rd->json_output)
101 jsonw_end_array(rd->jw);
102 else
103 pr_out(">");
104 }
105
106 static void dev_print_fw(struct rd *rd, struct nlattr **tb)
107 {
108 const char *str;
109 if (!tb[RDMA_NLDEV_ATTR_FW_VERSION])
110 return;
111
112 str = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_FW_VERSION]);
113 if (rd->json_output)
114 jsonw_string_field(rd->jw, "fw", str);
115 else
116 pr_out("fw %s ", str);
117 }
118
119 static void dev_print_node_guid(struct rd *rd, struct nlattr **tb)
120 {
121 uint64_t node_guid;
122 uint16_t vp[4];
123 char str[32];
124
125 if (!tb[RDMA_NLDEV_ATTR_NODE_GUID])
126 return;
127
128 node_guid = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_NODE_GUID]);
129 memcpy(vp, &node_guid, sizeof(uint64_t));
130 snprintf(str, 32, "%04x:%04x:%04x:%04x", vp[3], vp[2], vp[1], vp[0]);
131 if (rd->json_output)
132 jsonw_string_field(rd->jw, "node_guid", str);
133 else
134 pr_out("node_guid %s ", str);
135 }
136
137 static void dev_print_sys_image_guid(struct rd *rd, struct nlattr **tb)
138 {
139 uint64_t sys_image_guid;
140 uint16_t vp[4];
141 char str[32];
142
143 if (!tb[RDMA_NLDEV_ATTR_SYS_IMAGE_GUID])
144 return;
145
146 sys_image_guid = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_SYS_IMAGE_GUID]);
147 memcpy(vp, &sys_image_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, "sys_image_guid", str);
151 else
152 pr_out("sys_image_guid %s ", str);
153 }
154
155 static const char *node_type_to_str(uint8_t node_type)
156 {
157 static const char * const node_type_str[] = { "unknown", "ca",
158 "switch", "router",
159 "rnic", "usnic",
160 "usnic_dp" };
161 if (node_type < ARRAY_SIZE(node_type_str))
162 return node_type_str[node_type];
163 return "unknown";
164 }
165
166 static void dev_print_node_type(struct rd *rd, struct nlattr **tb)
167 {
168 const char *node_str;
169 uint8_t node_type;
170
171 if (!tb[RDMA_NLDEV_ATTR_DEV_NODE_TYPE])
172 return;
173
174 node_type = mnl_attr_get_u8(tb[RDMA_NLDEV_ATTR_DEV_NODE_TYPE]);
175 node_str = node_type_to_str(node_type);
176 if (rd->json_output)
177 jsonw_string_field(rd->jw, "node_type", node_str);
178 else
179 pr_out("node_type %s ", node_str);
180 }
181
182 static int dev_parse_cb(const struct nlmsghdr *nlh, void *data)
183 {
184 struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
185 struct rd *rd = data;
186 const char *name;
187 uint32_t idx;
188
189 mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
190 if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME])
191 return MNL_CB_ERROR;
192
193 idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
194 name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]);
195 if (rd->json_output) {
196 jsonw_uint_field(rd->jw, "ifindex", idx);
197 jsonw_string_field(rd->jw, "ifname", name);
198 } else {
199 pr_out("%u: %s: ", idx, name);
200 }
201
202 dev_print_node_type(rd, tb);
203 dev_print_fw(rd, tb);
204 dev_print_node_guid(rd, tb);
205 dev_print_sys_image_guid(rd, tb);
206 if (rd->show_details)
207 dev_print_caps(rd, tb);
208
209 if (!rd->json_output)
210 pr_out("\n");
211 return MNL_CB_OK;
212 }
213
214 static int dev_no_args(struct rd *rd)
215 {
216 uint32_t seq;
217 int ret;
218
219 rd_prepare_msg(rd, RDMA_NLDEV_CMD_GET,
220 &seq, (NLM_F_REQUEST | NLM_F_ACK));
221 mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx);
222 ret = rd_send_msg(rd);
223 if (ret)
224 return ret;
225
226 if (rd->json_output)
227 jsonw_start_object(rd->jw);
228 ret = rd_recv_msg(rd, dev_parse_cb, rd, seq);
229 if (rd->json_output)
230 jsonw_end_object(rd->jw);
231 return ret;
232 }
233
234 static int dev_one_show(struct rd *rd)
235 {
236 const struct rd_cmd cmds[] = {
237 { NULL, dev_no_args},
238 { 0 }
239 };
240
241 return rd_exec_cmd(rd, cmds, "parameter");
242 }
243
244 static int dev_set_name(struct rd *rd)
245 {
246 uint32_t seq;
247
248 if (rd_no_arg(rd)) {
249 pr_err("Please provide device new name.\n");
250 return -EINVAL;
251 }
252
253 rd_prepare_msg(rd, RDMA_NLDEV_CMD_SET,
254 &seq, (NLM_F_REQUEST | NLM_F_ACK));
255 mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx);
256 mnl_attr_put_strz(rd->nlh, RDMA_NLDEV_ATTR_DEV_NAME, rd_argv(rd));
257
258 return rd_send_msg(rd);
259 }
260
261 static int dev_one_set(struct rd *rd)
262 {
263 const struct rd_cmd cmds[] = {
264 { NULL, dev_help},
265 { "name", dev_set_name},
266 { 0 }
267 };
268
269 return rd_exec_cmd(rd, cmds, "parameter");
270 }
271
272 static int dev_show(struct rd *rd)
273 {
274 return rd_exec_dev(rd, dev_one_show);
275 }
276
277 static int dev_set(struct rd *rd)
278 {
279 return rd_exec_require_dev(rd, dev_one_set);
280 }
281
282 int cmd_dev(struct rd *rd)
283 {
284 const struct rd_cmd cmds[] = {
285 { NULL, dev_show },
286 { "show", dev_show },
287 { "list", dev_show },
288 { "set", dev_set },
289 { "help", dev_help },
290 { 0 }
291 };
292
293 return rd_exec_cmd(rd, cmds, "dev command");
294 }