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