@@ -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+
244270static 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+
279414static 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