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.
9 * Authors: Leon Romanovsky <leonro@mellanox.com>
14 static int link_help(struct rd
*rd
)
16 pr_out("Usage: %s link show [DEV/PORT_INDEX]\n", rd
->filename
);
20 static const char *caps_to_str(uint32_t idx
)
22 #define RDMA_PORT_FLAGS(x) \
33 x(SYS_IMAGE_GUIG, 11) \
34 x(PKEY_SW_EXT_PORT_TRAP, 12) \
35 x(EXTENDED_SPEEDS, 14) \
42 x(CAP_MASK_NOTICE, 22) \
48 enum { RDMA_PORT_FLAGS(RDMA_BITMAP_ENUM
) };
50 static const char * const
51 rdma_port_names
[] = { RDMA_PORT_FLAGS(RDMA_BITMAP_NAMES
) };
52 #undef RDMA_PORT_FLAGS
54 if (idx
< ARRAY_SIZE(rdma_port_names
) && rdma_port_names
[idx
])
55 return rdma_port_names
[idx
];
59 static void link_print_caps(struct nlattr
**tb
)
64 if (!tb
[RDMA_NLDEV_ATTR_CAP_FLAGS
])
67 caps
= mnl_attr_get_u64(tb
[RDMA_NLDEV_ATTR_CAP_FLAGS
]);
70 for (idx
= 0; caps
; idx
++) {
72 pr_out("%s", caps_to_str(idx
));
82 static void link_print_subnet_prefix(struct nlattr
**tb
)
84 uint64_t subnet_prefix
;
86 if (!tb
[RDMA_NLDEV_ATTR_SUBNET_PREFIX
])
89 subnet_prefix
= mnl_attr_get_u64(tb
[RDMA_NLDEV_ATTR_SUBNET_PREFIX
]);
90 rd_print_u64("subnet_prefix", subnet_prefix
);
93 static void link_print_lid(struct nlattr
**tb
)
95 if (!tb
[RDMA_NLDEV_ATTR_LID
])
99 mnl_attr_get_u32(tb
[RDMA_NLDEV_ATTR_LID
]));
102 static void link_print_sm_lid(struct nlattr
**tb
)
104 if (!tb
[RDMA_NLDEV_ATTR_SM_LID
])
108 mnl_attr_get_u32(tb
[RDMA_NLDEV_ATTR_SM_LID
]));
111 static void link_print_lmc(struct nlattr
**tb
)
113 if (!tb
[RDMA_NLDEV_ATTR_LMC
])
116 pr_out("lmc %u ", mnl_attr_get_u8(tb
[RDMA_NLDEV_ATTR_LMC
]));
119 static const char *link_state_to_str(uint8_t link_state
)
121 static const char * const link_state_str
[] = { "NOP", "DOWN",
125 if (link_state
< ARRAY_SIZE(link_state_str
))
126 return link_state_str
[link_state
];
130 static void link_print_state(struct nlattr
**tb
)
134 if (!tb
[RDMA_NLDEV_ATTR_PORT_STATE
])
137 state
= mnl_attr_get_u8(tb
[RDMA_NLDEV_ATTR_PORT_STATE
]);
138 pr_out("state %s ", link_state_to_str(state
));
141 static const char *phys_state_to_str(uint8_t phys_state
)
143 static const char * const phys_state_str
[] = { "NOP", "SLEEP",
144 "POLLING", "DISABLED",
146 "LINK_ERROR_RECOVER",
147 "PHY_TEST", "UNKNOWN",
149 "UNKNOWN", "OPA_TEST" };
150 if (phys_state
< ARRAY_SIZE(phys_state_str
))
151 return phys_state_str
[phys_state
];
155 static void link_print_phys_state(struct nlattr
**tb
)
159 if (!tb
[RDMA_NLDEV_ATTR_PORT_PHYS_STATE
])
162 phys_state
= mnl_attr_get_u8(tb
[RDMA_NLDEV_ATTR_PORT_PHYS_STATE
]);
163 pr_out("physical_state %s ", phys_state_to_str(phys_state
));
166 static int link_parse_cb(const struct nlmsghdr
*nlh
, void *data
)
168 struct nlattr
*tb
[RDMA_NLDEV_ATTR_MAX
] = {};
169 struct rd
*rd
= data
;
171 mnl_attr_parse(nlh
, 0, rd_attr_cb
, tb
);
172 if (!tb
[RDMA_NLDEV_ATTR_DEV_INDEX
] || !tb
[RDMA_NLDEV_ATTR_DEV_NAME
])
175 if (!tb
[RDMA_NLDEV_ATTR_PORT_INDEX
]) {
176 pr_err("This tool doesn't support switches yet\n");
180 pr_out("%u/%u: %s/%u: ",
181 mnl_attr_get_u32(tb
[RDMA_NLDEV_ATTR_DEV_INDEX
]),
182 mnl_attr_get_u32(tb
[RDMA_NLDEV_ATTR_PORT_INDEX
]),
183 mnl_attr_get_str(tb
[RDMA_NLDEV_ATTR_DEV_NAME
]),
184 mnl_attr_get_u32(tb
[RDMA_NLDEV_ATTR_PORT_INDEX
]));
185 link_print_subnet_prefix(tb
);
187 link_print_sm_lid(tb
);
189 link_print_state(tb
);
190 link_print_phys_state(tb
);
191 if (rd
->show_details
)
198 static int link_no_args(struct rd
*rd
)
203 rd_prepare_msg(rd
, RDMA_NLDEV_CMD_PORT_GET
, &seq
,
204 (NLM_F_REQUEST
| NLM_F_ACK
));
205 mnl_attr_put_u32(rd
->nlh
, RDMA_NLDEV_ATTR_DEV_INDEX
, rd
->dev_idx
);
206 mnl_attr_put_u32(rd
->nlh
, RDMA_NLDEV_ATTR_PORT_INDEX
, rd
->port_idx
);
207 ret
= rd_send_msg(rd
);
211 return rd_recv_msg(rd
, link_parse_cb
, rd
, seq
);
214 static int link_one_show(struct rd
*rd
)
216 const struct rd_cmd cmds
[] = {
217 { NULL
, link_no_args
},
221 return rd_exec_cmd(rd
, cmds
, "parameter");
224 static int link_show(struct rd
*rd
)
226 struct dev_map
*dev_map
;
231 list_for_each_entry(dev_map
, &rd
->dev_map_list
, list
) {
232 rd
->dev_idx
= dev_map
->idx
;
233 for (port
= 1; port
< dev_map
->num_ports
+ 1; port
++) {
235 ret
= link_one_show(rd
);
242 dev_map
= dev_map_lookup(rd
, true);
243 port
= get_port_from_argv(rd
);
244 if (!dev_map
|| port
> dev_map
->num_ports
) {
245 pr_err("Wrong device name\n");
249 rd
->dev_idx
= dev_map
->idx
;
250 rd
->port_idx
= port
? : 1;
251 for (; rd
->port_idx
< dev_map
->num_ports
+ 1; rd
->port_idx
++) {
252 ret
= link_one_show(rd
);
257 * We got request to show link for devname
266 int cmd_link(struct rd
*rd
)
268 const struct rd_cmd cmds
[] = {
270 { "show", link_show
},
271 { "list", link_show
},
272 { "help", link_help
},
276 return rd_exec_cmd(rd
, cmds
, "link command");