Skip to content

Commit 54d3892

Browse files
authored
Merge pull request #10 from xyan264/enumerate-fix
Fix device enumeration for 'switchtec list' command
2 parents b4da9d0 + 5706aea commit 54d3892

File tree

1 file changed

+151
-51
lines changed

1 file changed

+151
-51
lines changed

plugins/microchip/switchtec-nvme.c

Lines changed: 151 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -241,17 +241,43 @@ static int scan_pax_dev_filter(const struct dirent *d)
241241

242242
#define NVME_CLASS 0x010802
243243
#define CAP_PF 0x3
244+
245+
static int pax_enum_ep(struct switchtec_gfms_db_ep_port_ep *ep,
246+
struct switchtec_gfms_db_ep_port_attached_device_function *functions,
247+
int max_functions)
248+
{
249+
int n;
250+
int j;
251+
int index = 0;
252+
struct switchtec_gfms_db_ep_port_attached_device_function *function;
253+
254+
n = ep->ep_hdr.function_number;
255+
for (j = 0; j < n; j++) {
256+
function = &ep->functions[j];
257+
if (function->sriov_cap_pf == CAP_PF &&
258+
function->device_class == NVME_CLASS) {
259+
memcpy(&functions[index++], function,
260+
sizeof(*function));
261+
262+
if (index >= max_functions)
263+
return index;
264+
}
265+
}
266+
267+
return index;
268+
}
269+
244270
static int pax_get_nvme_pf_functions(struct pax_nvme_device *pax,
245-
struct switchtec_gfms_db_ep_port_attached_device_function *functions,
246-
int max_functions)
271+
struct switchtec_gfms_db_ep_port_attached_device_function *functions,
272+
int max_functions)
247273
{
248274
int i, j;
249275
int index;
250276
int ret;
251277
int n;
252278
struct switchtec_gfms_db_pax_all pax_all;
253279
struct switchtec_gfms_db_ep_port *ep_port;
254-
struct switchtec_gfms_db_ep_port_attached_device_function *function;
280+
struct switchtec_gfms_db_ep_port_ep *ep;
255281

256282
ret = switchtec_fab_gfms_db_dump_pax_all(pax->dev, &pax_all);
257283
if (ret)
@@ -261,37 +287,141 @@ static int pax_get_nvme_pf_functions(struct pax_nvme_device *pax,
261287
for (i = 0; i < pax_all.ep_port_all.ep_port_count; i++) {
262288
ep_port = &pax_all.ep_port_all.ep_ports[i];
263289
if (ep_port->port_hdr.type == SWITCHTEC_GFMS_DB_TYPE_EP) {
264-
n = ep_port->ep_ep.ep_hdr.function_number;
290+
ep = &ep_port->ep_ep;
291+
ret = pax_enum_ep(ep, functions + index,
292+
max_functions - index);
293+
index += ret;
294+
} else if (ep_port->port_hdr.type ==
295+
SWITCHTEC_GFMS_DB_TYPE_SWITCH) {
296+
n = ep_port->port_hdr.ep_count;
297+
265298
for (j = 0; j < n; j++) {
266-
function = &ep_port->ep_ep.functions[j];
267-
if (function->sriov_cap_pf == CAP_PF
268-
&& function->device_class == NVME_CLASS)
269-
memcpy(&functions[index++],
270-
function,
271-
sizeof(*function));
299+
ep = ep_port->ep_switch.switch_eps + j;
300+
ret = pax_enum_ep(ep, functions + index,
301+
max_functions - index);
302+
303+
index += ret;
272304
}
273305
}
274306
}
275307

276308
return index;
277309
}
278310

311+
static int pax_build_nvme_pf_list(struct pax_nvme_device *pax,
312+
struct switchtec_gfms_db_ep_port_attached_device_function *functions,
313+
int function_n,
314+
struct list_item *list_items,
315+
char *path)
316+
{
317+
int j;
318+
int k;
319+
int ret;
320+
int idx = 0;
321+
char node[300];
322+
__u32 ns_list[1024];
323+
324+
for (j = 0; j < function_n; j++) {
325+
pax->pdfid = functions[j].pdfid;
326+
ret = switchtec_ep_tunnel_status(pax->dev, pax->pdfid,
327+
&pax->channel_status);
328+
if (ret)
329+
switchtec_perror("Getting EP tunnel status");
330+
331+
if (pax->channel_status == SWITCHTEC_EP_TUNNEL_DISABLED)
332+
switchtec_ep_tunnel_enable(pax->dev, pax->pdfid);
333+
334+
ret = nvme_identify_ns_list(0, 0, 1, ns_list);
335+
if (!ret) {
336+
for (k = 0; k < 1024; k++)
337+
if (ns_list[k]) {
338+
sprintf(node, "0x%04hxn%d@%s",
339+
pax->pdfid, ns_list[k], path);
340+
pax->ns_id = ns_list[k];
341+
ret = get_nvme_info(0,
342+
&list_items[idx++],
343+
node);
344+
}
345+
} else if (ret > 0) {
346+
fprintf(stderr, "NVMe Status:%s(%x) NSID:%d\n",
347+
nvme_status_to_string(ret), ret, 0);
348+
} else {
349+
perror("id namespace list");
350+
}
351+
352+
if (pax->channel_status == SWITCHTEC_EP_TUNNEL_DISABLED)
353+
switchtec_ep_tunnel_disable(pax->dev, pax->pdfid);
354+
}
355+
356+
return idx;
357+
}
358+
359+
static int pax_get_nvme_pf_list(struct pax_nvme_device *pax,
360+
struct list_item *list_items,
361+
char *path)
362+
{
363+
int i;
364+
int ret;
365+
int count = 0;
366+
uint8_t r_type;
367+
struct switchtec_fab_topo_info topo_info;
368+
struct switchtec_gfms_db_fabric_general fg;
369+
struct switchtec_gfms_db_ep_port_attached_device_function funcs[1024];
370+
371+
for(i = 0; i < SWITCHTEC_MAX_PORTS; i++)
372+
topo_info.port_info_list[i].phys_port_id = 0xff;
373+
374+
ret = switchtec_set_pax_id(pax->dev, SWITCHTEC_PAX_ID_LOCAL);
375+
if (ret)
376+
return -1;
377+
378+
ret = switchtec_topo_info_dump(pax->dev, &topo_info);
379+
if (ret)
380+
return -2;
381+
382+
ret = switchtec_fab_gfms_db_dump_fabric_general(pax->dev, &fg);
383+
if (ret)
384+
return -3;
385+
386+
for (i = 0; i < 16; i++) {
387+
if (topo_info.route_port[i] == 0xff && fg.hdr.pax_idx != i)
388+
continue;
389+
390+
r_type = fg.body.pax_idx[i].reachable_type;
391+
392+
if (fg.hdr.pax_idx == i ||
393+
r_type == SWITCHTEC_GFMS_DB_REACH_UC ||
394+
r_type == SWITCHTEC_GFMS_DB_REACH_BC) {
395+
ret = switchtec_set_pax_id(pax->dev, i);
396+
if (ret)
397+
continue;
398+
399+
ret = pax_get_nvme_pf_functions(pax, funcs + count,
400+
1024 - count);
401+
if (ret <= 0)
402+
continue;
403+
404+
ret = pax_build_nvme_pf_list(pax, funcs + count, ret,
405+
list_items + count, path);
406+
count += ret;
407+
}
408+
}
409+
410+
switchtec_set_pax_id(pax->dev, SWITCHTEC_PAX_ID_LOCAL);
411+
return count;
412+
}
413+
279414
static int switchtec_pax_list(int argc, char **argv, struct command *command,
280415
struct plugin *plugin)
281416
{
282417
char path[264];
283-
char node[300];
284418
struct list_item *list_items;
285-
unsigned int i, j, k, n;
286-
int function_n;
419+
unsigned int i;
420+
unsigned int n;
287421
unsigned int index;
288-
int fd = 0;
289422
int fmt, ret;
290-
int err;
291423
struct dirent **pax_devices;
292424
struct pax_nvme_device *pax;
293-
__u32 ns_list[1024] = {0};
294-
struct switchtec_gfms_db_ep_port_attached_device_function functions[1024];
295425

296426
const char *desc = "Retrieve basic information for the given Microsemi device";
297427
struct config {
@@ -351,41 +481,11 @@ static int switchtec_pax_list(int argc, char **argv, struct command *command,
351481
return -ENODEV;
352482
}
353483
global_device = &pax->device;
354-
switchtec_set_pax_id(pax->dev, SWITCHTEC_PAX_ID_LOCAL);
355484

356-
function_n = pax_get_nvme_pf_functions(pax, functions, 1024);
357-
if(function_n < 0) {
358-
switchtec_close(pax->dev);
359-
free(pax);
360-
continue;
361-
}
362-
for (j = 0; j < function_n; j++) {
363-
pax->pdfid = functions[j].pdfid;
364-
memset(ns_list, 0, sizeof(ns_list));
365-
ret = switchtec_ep_tunnel_status(pax->dev, pax->pdfid, &pax->channel_status);
366-
if (ret)
367-
switchtec_perror("Getting EP tunnel status");
368-
369-
if (pax->channel_status == SWITCHTEC_EP_TUNNEL_DISABLED)
370-
switchtec_ep_tunnel_enable(pax->dev, pax->pdfid);
371-
372-
err = nvme_identify_ns_list(0, 0, 1, ns_list);
373-
if (!err) {
374-
for (k = 0; k < 1024; k++)
375-
if (ns_list[k]) {
376-
sprintf(node, "0x%04hxn%d@%s", pax->pdfid, ns_list[k], path);
377-
pax->ns_id = ns_list[k];
378-
ret = get_nvme_info(fd, &list_items[index++], node);
379-
}
380-
} else if (err > 0)
381-
fprintf(stderr, "NVMe Status:%s(%x) NSID:%d\n",
382-
nvme_status_to_string(err), err, 0);
383-
else
384-
perror("id namespace list");
385-
386-
if (pax->channel_status == SWITCHTEC_EP_TUNNEL_DISABLED)
387-
switchtec_ep_tunnel_disable(pax->dev, pax->pdfid);
388-
}
485+
ret = pax_get_nvme_pf_list(pax, list_items + index, path);
486+
if (ret > 0)
487+
index += ret;
488+
389489
switchtec_close(pax->dev);
390490
free(pax);
391491
}

0 commit comments

Comments
 (0)