1*de1e4e89SAndroid Build Coastguard Worker /*
2*de1e4e89SAndroid Build Coastguard Worker * link.c RDMA tool
3*de1e4e89SAndroid Build Coastguard Worker *
4*de1e4e89SAndroid Build Coastguard Worker * This program is free software; you can redistribute it and/or
5*de1e4e89SAndroid Build Coastguard Worker * modify it under the terms of the GNU General Public License
6*de1e4e89SAndroid Build Coastguard Worker * as published by the Free Software Foundation; either version
7*de1e4e89SAndroid Build Coastguard Worker * 2 of the License, or (at your option) any later version.
8*de1e4e89SAndroid Build Coastguard Worker *
9*de1e4e89SAndroid Build Coastguard Worker * Authors: Leon Romanovsky <[email protected]>
10*de1e4e89SAndroid Build Coastguard Worker */
11*de1e4e89SAndroid Build Coastguard Worker
12*de1e4e89SAndroid Build Coastguard Worker #include "rdma.h"
13*de1e4e89SAndroid Build Coastguard Worker
link_help(struct rd * rd)14*de1e4e89SAndroid Build Coastguard Worker static int link_help(struct rd *rd)
15*de1e4e89SAndroid Build Coastguard Worker {
16*de1e4e89SAndroid Build Coastguard Worker pr_out("Usage: %s link show [DEV/PORT_INDEX]\n", rd->filename);
17*de1e4e89SAndroid Build Coastguard Worker return 0;
18*de1e4e89SAndroid Build Coastguard Worker }
19*de1e4e89SAndroid Build Coastguard Worker
caps_to_str(uint32_t idx)20*de1e4e89SAndroid Build Coastguard Worker static const char *caps_to_str(uint32_t idx)
21*de1e4e89SAndroid Build Coastguard Worker {
22*de1e4e89SAndroid Build Coastguard Worker #define RDMA_PORT_FLAGS(x) \
23*de1e4e89SAndroid Build Coastguard Worker x(SM, 1) \
24*de1e4e89SAndroid Build Coastguard Worker x(NOTICE, 2) \
25*de1e4e89SAndroid Build Coastguard Worker x(TRAP, 3) \
26*de1e4e89SAndroid Build Coastguard Worker x(OPT_IPD, 4) \
27*de1e4e89SAndroid Build Coastguard Worker x(AUTO_MIGR, 5) \
28*de1e4e89SAndroid Build Coastguard Worker x(SL_MAP, 6) \
29*de1e4e89SAndroid Build Coastguard Worker x(MKEY_NVRAM, 7) \
30*de1e4e89SAndroid Build Coastguard Worker x(PKEY_NVRAM, 8) \
31*de1e4e89SAndroid Build Coastguard Worker x(LED_INFO, 9) \
32*de1e4e89SAndroid Build Coastguard Worker x(SM_DISABLED, 10) \
33*de1e4e89SAndroid Build Coastguard Worker x(SYS_IMAGE_GUIG, 11) \
34*de1e4e89SAndroid Build Coastguard Worker x(PKEY_SW_EXT_PORT_TRAP, 12) \
35*de1e4e89SAndroid Build Coastguard Worker x(EXTENDED_SPEEDS, 14) \
36*de1e4e89SAndroid Build Coastguard Worker x(CM, 16) \
37*de1e4e89SAndroid Build Coastguard Worker x(SNMP_TUNNEL, 17) \
38*de1e4e89SAndroid Build Coastguard Worker x(REINIT, 18) \
39*de1e4e89SAndroid Build Coastguard Worker x(DEVICE_MGMT, 19) \
40*de1e4e89SAndroid Build Coastguard Worker x(VENDOR_CLASS, 20) \
41*de1e4e89SAndroid Build Coastguard Worker x(DR_NOTICE, 21) \
42*de1e4e89SAndroid Build Coastguard Worker x(CAP_MASK_NOTICE, 22) \
43*de1e4e89SAndroid Build Coastguard Worker x(BOOT_MGMT, 23) \
44*de1e4e89SAndroid Build Coastguard Worker x(LINK_LATENCY, 24) \
45*de1e4e89SAndroid Build Coastguard Worker x(CLIENT_REG, 25) \
46*de1e4e89SAndroid Build Coastguard Worker x(IP_BASED_GIDS, 26)
47*de1e4e89SAndroid Build Coastguard Worker
48*de1e4e89SAndroid Build Coastguard Worker enum { RDMA_PORT_FLAGS(RDMA_BITMAP_ENUM) };
49*de1e4e89SAndroid Build Coastguard Worker
50*de1e4e89SAndroid Build Coastguard Worker static const char * const
51*de1e4e89SAndroid Build Coastguard Worker rdma_port_names[] = { RDMA_PORT_FLAGS(RDMA_BITMAP_NAMES) };
52*de1e4e89SAndroid Build Coastguard Worker #undef RDMA_PORT_FLAGS
53*de1e4e89SAndroid Build Coastguard Worker
54*de1e4e89SAndroid Build Coastguard Worker if (idx < ARRAY_SIZE(rdma_port_names) && rdma_port_names[idx])
55*de1e4e89SAndroid Build Coastguard Worker return rdma_port_names[idx];
56*de1e4e89SAndroid Build Coastguard Worker return "UNKNOWN";
57*de1e4e89SAndroid Build Coastguard Worker }
58*de1e4e89SAndroid Build Coastguard Worker
link_print_caps(struct rd * rd,struct nlattr ** tb)59*de1e4e89SAndroid Build Coastguard Worker static void link_print_caps(struct rd *rd, struct nlattr **tb)
60*de1e4e89SAndroid Build Coastguard Worker {
61*de1e4e89SAndroid Build Coastguard Worker uint64_t caps;
62*de1e4e89SAndroid Build Coastguard Worker uint32_t idx;
63*de1e4e89SAndroid Build Coastguard Worker
64*de1e4e89SAndroid Build Coastguard Worker if (!tb[RDMA_NLDEV_ATTR_CAP_FLAGS])
65*de1e4e89SAndroid Build Coastguard Worker return;
66*de1e4e89SAndroid Build Coastguard Worker
67*de1e4e89SAndroid Build Coastguard Worker caps = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_CAP_FLAGS]);
68*de1e4e89SAndroid Build Coastguard Worker
69*de1e4e89SAndroid Build Coastguard Worker if (rd->json_output) {
70*de1e4e89SAndroid Build Coastguard Worker jsonw_name(rd->jw, "caps");
71*de1e4e89SAndroid Build Coastguard Worker jsonw_start_array(rd->jw);
72*de1e4e89SAndroid Build Coastguard Worker } else {
73*de1e4e89SAndroid Build Coastguard Worker pr_out("\n caps: <");
74*de1e4e89SAndroid Build Coastguard Worker }
75*de1e4e89SAndroid Build Coastguard Worker for (idx = 0; caps; idx++) {
76*de1e4e89SAndroid Build Coastguard Worker if (caps & 0x1) {
77*de1e4e89SAndroid Build Coastguard Worker if (rd->json_output) {
78*de1e4e89SAndroid Build Coastguard Worker jsonw_string(rd->jw, caps_to_str(idx));
79*de1e4e89SAndroid Build Coastguard Worker } else {
80*de1e4e89SAndroid Build Coastguard Worker pr_out("%s", caps_to_str(idx));
81*de1e4e89SAndroid Build Coastguard Worker if (caps >> 0x1)
82*de1e4e89SAndroid Build Coastguard Worker pr_out(", ");
83*de1e4e89SAndroid Build Coastguard Worker }
84*de1e4e89SAndroid Build Coastguard Worker }
85*de1e4e89SAndroid Build Coastguard Worker caps >>= 0x1;
86*de1e4e89SAndroid Build Coastguard Worker }
87*de1e4e89SAndroid Build Coastguard Worker
88*de1e4e89SAndroid Build Coastguard Worker if (rd->json_output)
89*de1e4e89SAndroid Build Coastguard Worker jsonw_end_array(rd->jw);
90*de1e4e89SAndroid Build Coastguard Worker else
91*de1e4e89SAndroid Build Coastguard Worker pr_out(">");
92*de1e4e89SAndroid Build Coastguard Worker }
93*de1e4e89SAndroid Build Coastguard Worker
link_print_subnet_prefix(struct rd * rd,struct nlattr ** tb)94*de1e4e89SAndroid Build Coastguard Worker static void link_print_subnet_prefix(struct rd *rd, struct nlattr **tb)
95*de1e4e89SAndroid Build Coastguard Worker {
96*de1e4e89SAndroid Build Coastguard Worker uint64_t subnet_prefix;
97*de1e4e89SAndroid Build Coastguard Worker uint16_t vp[4];
98*de1e4e89SAndroid Build Coastguard Worker char str[32];
99*de1e4e89SAndroid Build Coastguard Worker
100*de1e4e89SAndroid Build Coastguard Worker if (!tb[RDMA_NLDEV_ATTR_SUBNET_PREFIX])
101*de1e4e89SAndroid Build Coastguard Worker return;
102*de1e4e89SAndroid Build Coastguard Worker
103*de1e4e89SAndroid Build Coastguard Worker subnet_prefix = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_SUBNET_PREFIX]);
104*de1e4e89SAndroid Build Coastguard Worker memcpy(vp, &subnet_prefix, sizeof(uint64_t));
105*de1e4e89SAndroid Build Coastguard Worker snprintf(str, 32, "%04x:%04x:%04x:%04x", vp[3], vp[2], vp[1], vp[0]);
106*de1e4e89SAndroid Build Coastguard Worker if (rd->json_output)
107*de1e4e89SAndroid Build Coastguard Worker jsonw_string_field(rd->jw, "subnet_prefix", str);
108*de1e4e89SAndroid Build Coastguard Worker else
109*de1e4e89SAndroid Build Coastguard Worker pr_out("subnet_prefix %s ", str);
110*de1e4e89SAndroid Build Coastguard Worker }
111*de1e4e89SAndroid Build Coastguard Worker
link_print_lid(struct rd * rd,struct nlattr ** tb)112*de1e4e89SAndroid Build Coastguard Worker static void link_print_lid(struct rd *rd, struct nlattr **tb)
113*de1e4e89SAndroid Build Coastguard Worker {
114*de1e4e89SAndroid Build Coastguard Worker uint32_t lid;
115*de1e4e89SAndroid Build Coastguard Worker
116*de1e4e89SAndroid Build Coastguard Worker if (!tb[RDMA_NLDEV_ATTR_LID])
117*de1e4e89SAndroid Build Coastguard Worker return;
118*de1e4e89SAndroid Build Coastguard Worker
119*de1e4e89SAndroid Build Coastguard Worker lid = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_LID]);
120*de1e4e89SAndroid Build Coastguard Worker if (rd->json_output)
121*de1e4e89SAndroid Build Coastguard Worker jsonw_uint_field(rd->jw, "lid", lid);
122*de1e4e89SAndroid Build Coastguard Worker else
123*de1e4e89SAndroid Build Coastguard Worker pr_out("lid %u ", lid);
124*de1e4e89SAndroid Build Coastguard Worker }
125*de1e4e89SAndroid Build Coastguard Worker
link_print_sm_lid(struct rd * rd,struct nlattr ** tb)126*de1e4e89SAndroid Build Coastguard Worker static void link_print_sm_lid(struct rd *rd, struct nlattr **tb)
127*de1e4e89SAndroid Build Coastguard Worker {
128*de1e4e89SAndroid Build Coastguard Worker uint32_t sm_lid;
129*de1e4e89SAndroid Build Coastguard Worker
130*de1e4e89SAndroid Build Coastguard Worker if (!tb[RDMA_NLDEV_ATTR_SM_LID])
131*de1e4e89SAndroid Build Coastguard Worker return;
132*de1e4e89SAndroid Build Coastguard Worker
133*de1e4e89SAndroid Build Coastguard Worker sm_lid = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_SM_LID]);
134*de1e4e89SAndroid Build Coastguard Worker if (rd->json_output)
135*de1e4e89SAndroid Build Coastguard Worker jsonw_uint_field(rd->jw, "sm_lid", sm_lid);
136*de1e4e89SAndroid Build Coastguard Worker else
137*de1e4e89SAndroid Build Coastguard Worker pr_out("sm_lid %u ", sm_lid);
138*de1e4e89SAndroid Build Coastguard Worker }
139*de1e4e89SAndroid Build Coastguard Worker
link_print_lmc(struct rd * rd,struct nlattr ** tb)140*de1e4e89SAndroid Build Coastguard Worker static void link_print_lmc(struct rd *rd, struct nlattr **tb)
141*de1e4e89SAndroid Build Coastguard Worker {
142*de1e4e89SAndroid Build Coastguard Worker uint8_t lmc;
143*de1e4e89SAndroid Build Coastguard Worker
144*de1e4e89SAndroid Build Coastguard Worker if (!tb[RDMA_NLDEV_ATTR_LMC])
145*de1e4e89SAndroid Build Coastguard Worker return;
146*de1e4e89SAndroid Build Coastguard Worker
147*de1e4e89SAndroid Build Coastguard Worker lmc = mnl_attr_get_u8(tb[RDMA_NLDEV_ATTR_LMC]);
148*de1e4e89SAndroid Build Coastguard Worker if (rd->json_output)
149*de1e4e89SAndroid Build Coastguard Worker jsonw_uint_field(rd->jw, "lmc", lmc);
150*de1e4e89SAndroid Build Coastguard Worker else
151*de1e4e89SAndroid Build Coastguard Worker pr_out("lmc %u ", lmc);
152*de1e4e89SAndroid Build Coastguard Worker }
153*de1e4e89SAndroid Build Coastguard Worker
link_state_to_str(uint8_t link_state)154*de1e4e89SAndroid Build Coastguard Worker static const char *link_state_to_str(uint8_t link_state)
155*de1e4e89SAndroid Build Coastguard Worker {
156*de1e4e89SAndroid Build Coastguard Worker static const char * const link_state_str[] = { "NOP", "DOWN",
157*de1e4e89SAndroid Build Coastguard Worker "INIT", "ARMED",
158*de1e4e89SAndroid Build Coastguard Worker "ACTIVE",
159*de1e4e89SAndroid Build Coastguard Worker "ACTIVE_DEFER" };
160*de1e4e89SAndroid Build Coastguard Worker if (link_state < ARRAY_SIZE(link_state_str))
161*de1e4e89SAndroid Build Coastguard Worker return link_state_str[link_state];
162*de1e4e89SAndroid Build Coastguard Worker return "UNKNOWN";
163*de1e4e89SAndroid Build Coastguard Worker }
164*de1e4e89SAndroid Build Coastguard Worker
link_print_state(struct rd * rd,struct nlattr ** tb)165*de1e4e89SAndroid Build Coastguard Worker static void link_print_state(struct rd *rd, struct nlattr **tb)
166*de1e4e89SAndroid Build Coastguard Worker {
167*de1e4e89SAndroid Build Coastguard Worker uint8_t state;
168*de1e4e89SAndroid Build Coastguard Worker
169*de1e4e89SAndroid Build Coastguard Worker if (!tb[RDMA_NLDEV_ATTR_PORT_STATE])
170*de1e4e89SAndroid Build Coastguard Worker return;
171*de1e4e89SAndroid Build Coastguard Worker
172*de1e4e89SAndroid Build Coastguard Worker state = mnl_attr_get_u8(tb[RDMA_NLDEV_ATTR_PORT_STATE]);
173*de1e4e89SAndroid Build Coastguard Worker if (rd->json_output)
174*de1e4e89SAndroid Build Coastguard Worker jsonw_string_field(rd->jw, "state", link_state_to_str(state));
175*de1e4e89SAndroid Build Coastguard Worker else
176*de1e4e89SAndroid Build Coastguard Worker pr_out("state %s ", link_state_to_str(state));
177*de1e4e89SAndroid Build Coastguard Worker }
178*de1e4e89SAndroid Build Coastguard Worker
phys_state_to_str(uint8_t phys_state)179*de1e4e89SAndroid Build Coastguard Worker static const char *phys_state_to_str(uint8_t phys_state)
180*de1e4e89SAndroid Build Coastguard Worker {
181*de1e4e89SAndroid Build Coastguard Worker static const char * const phys_state_str[] = { "NOP", "SLEEP",
182*de1e4e89SAndroid Build Coastguard Worker "POLLING", "DISABLED",
183*de1e4e89SAndroid Build Coastguard Worker "ARMED", "LINK_UP",
184*de1e4e89SAndroid Build Coastguard Worker "LINK_ERROR_RECOVER",
185*de1e4e89SAndroid Build Coastguard Worker "PHY_TEST", "UNKNOWN",
186*de1e4e89SAndroid Build Coastguard Worker "OPA_OFFLINE",
187*de1e4e89SAndroid Build Coastguard Worker "UNKNOWN", "OPA_TEST" };
188*de1e4e89SAndroid Build Coastguard Worker if (phys_state < ARRAY_SIZE(phys_state_str))
189*de1e4e89SAndroid Build Coastguard Worker return phys_state_str[phys_state];
190*de1e4e89SAndroid Build Coastguard Worker return "UNKNOWN";
191*de1e4e89SAndroid Build Coastguard Worker };
192*de1e4e89SAndroid Build Coastguard Worker
link_print_phys_state(struct rd * rd,struct nlattr ** tb)193*de1e4e89SAndroid Build Coastguard Worker static void link_print_phys_state(struct rd *rd, struct nlattr **tb)
194*de1e4e89SAndroid Build Coastguard Worker {
195*de1e4e89SAndroid Build Coastguard Worker uint8_t phys_state;
196*de1e4e89SAndroid Build Coastguard Worker
197*de1e4e89SAndroid Build Coastguard Worker if (!tb[RDMA_NLDEV_ATTR_PORT_PHYS_STATE])
198*de1e4e89SAndroid Build Coastguard Worker return;
199*de1e4e89SAndroid Build Coastguard Worker
200*de1e4e89SAndroid Build Coastguard Worker phys_state = mnl_attr_get_u8(tb[RDMA_NLDEV_ATTR_PORT_PHYS_STATE]);
201*de1e4e89SAndroid Build Coastguard Worker if (rd->json_output)
202*de1e4e89SAndroid Build Coastguard Worker jsonw_string_field(rd->jw, "physical_state",
203*de1e4e89SAndroid Build Coastguard Worker phys_state_to_str(phys_state));
204*de1e4e89SAndroid Build Coastguard Worker else
205*de1e4e89SAndroid Build Coastguard Worker pr_out("physical_state %s ", phys_state_to_str(phys_state));
206*de1e4e89SAndroid Build Coastguard Worker }
207*de1e4e89SAndroid Build Coastguard Worker
link_parse_cb(const struct nlmsghdr * nlh,void * data)208*de1e4e89SAndroid Build Coastguard Worker static int link_parse_cb(const struct nlmsghdr *nlh, void *data)
209*de1e4e89SAndroid Build Coastguard Worker {
210*de1e4e89SAndroid Build Coastguard Worker struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {};
211*de1e4e89SAndroid Build Coastguard Worker struct rd *rd = data;
212*de1e4e89SAndroid Build Coastguard Worker uint32_t port, idx;
213*de1e4e89SAndroid Build Coastguard Worker char name[32];
214*de1e4e89SAndroid Build Coastguard Worker
215*de1e4e89SAndroid Build Coastguard Worker mnl_attr_parse(nlh, 0, rd_attr_cb, tb);
216*de1e4e89SAndroid Build Coastguard Worker if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME])
217*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
218*de1e4e89SAndroid Build Coastguard Worker
219*de1e4e89SAndroid Build Coastguard Worker if (!tb[RDMA_NLDEV_ATTR_PORT_INDEX]) {
220*de1e4e89SAndroid Build Coastguard Worker pr_err("This tool doesn't support switches yet\n");
221*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
222*de1e4e89SAndroid Build Coastguard Worker }
223*de1e4e89SAndroid Build Coastguard Worker
224*de1e4e89SAndroid Build Coastguard Worker idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]);
225*de1e4e89SAndroid Build Coastguard Worker port = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_PORT_INDEX]);
226*de1e4e89SAndroid Build Coastguard Worker snprintf(name, 32, "%s/%u",
227*de1e4e89SAndroid Build Coastguard Worker mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]), port);
228*de1e4e89SAndroid Build Coastguard Worker
229*de1e4e89SAndroid Build Coastguard Worker if (rd->json_output) {
230*de1e4e89SAndroid Build Coastguard Worker jsonw_uint_field(rd->jw, "ifindex", idx);
231*de1e4e89SAndroid Build Coastguard Worker jsonw_uint_field(rd->jw, "port", port);
232*de1e4e89SAndroid Build Coastguard Worker jsonw_string_field(rd->jw, "ifname", name);
233*de1e4e89SAndroid Build Coastguard Worker
234*de1e4e89SAndroid Build Coastguard Worker } else {
235*de1e4e89SAndroid Build Coastguard Worker pr_out("%u/%u: %s: ", idx, port, name);
236*de1e4e89SAndroid Build Coastguard Worker }
237*de1e4e89SAndroid Build Coastguard Worker
238*de1e4e89SAndroid Build Coastguard Worker link_print_subnet_prefix(rd, tb);
239*de1e4e89SAndroid Build Coastguard Worker link_print_lid(rd, tb);
240*de1e4e89SAndroid Build Coastguard Worker link_print_sm_lid(rd, tb);
241*de1e4e89SAndroid Build Coastguard Worker link_print_lmc(rd, tb);
242*de1e4e89SAndroid Build Coastguard Worker link_print_state(rd, tb);
243*de1e4e89SAndroid Build Coastguard Worker link_print_phys_state(rd, tb);
244*de1e4e89SAndroid Build Coastguard Worker if (rd->show_details)
245*de1e4e89SAndroid Build Coastguard Worker link_print_caps(rd, tb);
246*de1e4e89SAndroid Build Coastguard Worker
247*de1e4e89SAndroid Build Coastguard Worker if (!rd->json_output)
248*de1e4e89SAndroid Build Coastguard Worker pr_out("\n");
249*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_OK;
250*de1e4e89SAndroid Build Coastguard Worker }
251*de1e4e89SAndroid Build Coastguard Worker
link_no_args(struct rd * rd)252*de1e4e89SAndroid Build Coastguard Worker static int link_no_args(struct rd *rd)
253*de1e4e89SAndroid Build Coastguard Worker {
254*de1e4e89SAndroid Build Coastguard Worker uint32_t seq;
255*de1e4e89SAndroid Build Coastguard Worker int ret;
256*de1e4e89SAndroid Build Coastguard Worker
257*de1e4e89SAndroid Build Coastguard Worker rd_prepare_msg(rd, RDMA_NLDEV_CMD_PORT_GET, &seq,
258*de1e4e89SAndroid Build Coastguard Worker (NLM_F_REQUEST | NLM_F_ACK));
259*de1e4e89SAndroid Build Coastguard Worker mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_DEV_INDEX, rd->dev_idx);
260*de1e4e89SAndroid Build Coastguard Worker mnl_attr_put_u32(rd->nlh, RDMA_NLDEV_ATTR_PORT_INDEX, rd->port_idx);
261*de1e4e89SAndroid Build Coastguard Worker ret = rd_send_msg(rd);
262*de1e4e89SAndroid Build Coastguard Worker if (ret)
263*de1e4e89SAndroid Build Coastguard Worker return ret;
264*de1e4e89SAndroid Build Coastguard Worker
265*de1e4e89SAndroid Build Coastguard Worker if (rd->json_output)
266*de1e4e89SAndroid Build Coastguard Worker jsonw_start_object(rd->jw);
267*de1e4e89SAndroid Build Coastguard Worker ret = rd_recv_msg(rd, link_parse_cb, rd, seq);
268*de1e4e89SAndroid Build Coastguard Worker if (rd->json_output)
269*de1e4e89SAndroid Build Coastguard Worker jsonw_end_object(rd->jw);
270*de1e4e89SAndroid Build Coastguard Worker return ret;
271*de1e4e89SAndroid Build Coastguard Worker }
272*de1e4e89SAndroid Build Coastguard Worker
link_one_show(struct rd * rd)273*de1e4e89SAndroid Build Coastguard Worker static int link_one_show(struct rd *rd)
274*de1e4e89SAndroid Build Coastguard Worker {
275*de1e4e89SAndroid Build Coastguard Worker const struct rd_cmd cmds[] = {
276*de1e4e89SAndroid Build Coastguard Worker { NULL, link_no_args},
277*de1e4e89SAndroid Build Coastguard Worker { 0 }
278*de1e4e89SAndroid Build Coastguard Worker };
279*de1e4e89SAndroid Build Coastguard Worker
280*de1e4e89SAndroid Build Coastguard Worker return rd_exec_cmd(rd, cmds, "parameter");
281*de1e4e89SAndroid Build Coastguard Worker }
282*de1e4e89SAndroid Build Coastguard Worker
link_show(struct rd * rd)283*de1e4e89SAndroid Build Coastguard Worker static int link_show(struct rd *rd)
284*de1e4e89SAndroid Build Coastguard Worker {
285*de1e4e89SAndroid Build Coastguard Worker struct dev_map *dev_map;
286*de1e4e89SAndroid Build Coastguard Worker uint32_t port;
287*de1e4e89SAndroid Build Coastguard Worker int ret = 0;
288*de1e4e89SAndroid Build Coastguard Worker
289*de1e4e89SAndroid Build Coastguard Worker if (rd->json_output)
290*de1e4e89SAndroid Build Coastguard Worker jsonw_start_array(rd->jw);
291*de1e4e89SAndroid Build Coastguard Worker if (rd_no_arg(rd)) {
292*de1e4e89SAndroid Build Coastguard Worker list_for_each_entry(dev_map, &rd->dev_map_list, list) {
293*de1e4e89SAndroid Build Coastguard Worker rd->dev_idx = dev_map->idx;
294*de1e4e89SAndroid Build Coastguard Worker for (port = 1; port < dev_map->num_ports + 1; port++) {
295*de1e4e89SAndroid Build Coastguard Worker rd->port_idx = port;
296*de1e4e89SAndroid Build Coastguard Worker ret = link_one_show(rd);
297*de1e4e89SAndroid Build Coastguard Worker if (ret)
298*de1e4e89SAndroid Build Coastguard Worker goto out;
299*de1e4e89SAndroid Build Coastguard Worker }
300*de1e4e89SAndroid Build Coastguard Worker }
301*de1e4e89SAndroid Build Coastguard Worker
302*de1e4e89SAndroid Build Coastguard Worker } else {
303*de1e4e89SAndroid Build Coastguard Worker dev_map = dev_map_lookup(rd, true);
304*de1e4e89SAndroid Build Coastguard Worker port = get_port_from_argv(rd);
305*de1e4e89SAndroid Build Coastguard Worker if (!dev_map || port > dev_map->num_ports) {
306*de1e4e89SAndroid Build Coastguard Worker pr_err("Wrong device name\n");
307*de1e4e89SAndroid Build Coastguard Worker ret = -ENOENT;
308*de1e4e89SAndroid Build Coastguard Worker goto out;
309*de1e4e89SAndroid Build Coastguard Worker }
310*de1e4e89SAndroid Build Coastguard Worker rd_arg_inc(rd);
311*de1e4e89SAndroid Build Coastguard Worker rd->dev_idx = dev_map->idx;
312*de1e4e89SAndroid Build Coastguard Worker rd->port_idx = port ? : 1;
313*de1e4e89SAndroid Build Coastguard Worker for (; rd->port_idx < dev_map->num_ports + 1; rd->port_idx++) {
314*de1e4e89SAndroid Build Coastguard Worker ret = link_one_show(rd);
315*de1e4e89SAndroid Build Coastguard Worker if (ret)
316*de1e4e89SAndroid Build Coastguard Worker goto out;
317*de1e4e89SAndroid Build Coastguard Worker if (port)
318*de1e4e89SAndroid Build Coastguard Worker /*
319*de1e4e89SAndroid Build Coastguard Worker * We got request to show link for devname
320*de1e4e89SAndroid Build Coastguard Worker * with port index.
321*de1e4e89SAndroid Build Coastguard Worker */
322*de1e4e89SAndroid Build Coastguard Worker break;
323*de1e4e89SAndroid Build Coastguard Worker }
324*de1e4e89SAndroid Build Coastguard Worker }
325*de1e4e89SAndroid Build Coastguard Worker
326*de1e4e89SAndroid Build Coastguard Worker out:
327*de1e4e89SAndroid Build Coastguard Worker if (rd->json_output)
328*de1e4e89SAndroid Build Coastguard Worker jsonw_end_array(rd->jw);
329*de1e4e89SAndroid Build Coastguard Worker return ret;
330*de1e4e89SAndroid Build Coastguard Worker }
331*de1e4e89SAndroid Build Coastguard Worker
cmd_link(struct rd * rd)332*de1e4e89SAndroid Build Coastguard Worker int cmd_link(struct rd *rd)
333*de1e4e89SAndroid Build Coastguard Worker {
334*de1e4e89SAndroid Build Coastguard Worker const struct rd_cmd cmds[] = {
335*de1e4e89SAndroid Build Coastguard Worker { NULL, link_show },
336*de1e4e89SAndroid Build Coastguard Worker { "show", link_show },
337*de1e4e89SAndroid Build Coastguard Worker { "list", link_show },
338*de1e4e89SAndroid Build Coastguard Worker { "help", link_help },
339*de1e4e89SAndroid Build Coastguard Worker { 0 }
340*de1e4e89SAndroid Build Coastguard Worker };
341*de1e4e89SAndroid Build Coastguard Worker
342*de1e4e89SAndroid Build Coastguard Worker return rd_exec_cmd(rd, cmds, "link command");
343*de1e4e89SAndroid Build Coastguard Worker }
344