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