@@ -440,6 +440,81 @@ int ib_find_cached_gid_by_port(struct ib_device *ib_dev,
440
440
}
441
441
EXPORT_SYMBOL (ib_find_cached_gid_by_port );
442
442
443
+ /**
444
+ * ib_find_gid_by_filter - Returns the GID table index where a specified
445
+ * GID value occurs
446
+ * @device: The device to query.
447
+ * @gid: The GID value to search for.
448
+ * @port_num: The port number of the device where the GID value could be
449
+ * searched.
450
+ * @filter: The filter function is executed on any matching GID in the table.
451
+ * If the filter function returns true, the corresponding index is returned,
452
+ * otherwise, we continue searching the GID table. It's guaranteed that
453
+ * while filter is executed, ndev field is valid and the structure won't
454
+ * change. filter is executed in an atomic context. filter must not be NULL.
455
+ * @index: The index into the cached GID table where the GID was found. This
456
+ * parameter may be NULL.
457
+ *
458
+ * ib_cache_gid_find_by_filter() searches for the specified GID value
459
+ * of which the filter function returns true in the port's GID table.
460
+ * This function is only supported on RoCE ports.
461
+ *
462
+ */
463
+ static int ib_cache_gid_find_by_filter (struct ib_device * ib_dev ,
464
+ const union ib_gid * gid ,
465
+ u8 port ,
466
+ bool (* filter )(const union ib_gid * ,
467
+ const struct ib_gid_attr * ,
468
+ void * ),
469
+ void * context ,
470
+ u16 * index )
471
+ {
472
+ struct ib_gid_table * * ports_table = ib_dev -> cache .gid_cache ;
473
+ struct ib_gid_table * table ;
474
+ unsigned int i ;
475
+ bool found = false;
476
+
477
+ if (!ports_table )
478
+ return - EOPNOTSUPP ;
479
+
480
+ if (port < rdma_start_port (ib_dev ) ||
481
+ port > rdma_end_port (ib_dev ) ||
482
+ !rdma_protocol_roce (ib_dev , port ))
483
+ return - EPROTONOSUPPORT ;
484
+
485
+ table = ports_table [port - rdma_start_port (ib_dev )];
486
+
487
+ for (i = 0 ; i < table -> sz ; i ++ ) {
488
+ struct ib_gid_attr attr ;
489
+ unsigned long flags ;
490
+
491
+ read_lock_irqsave (& table -> data_vec [i ].lock , flags );
492
+ if (table -> data_vec [i ].props & GID_TABLE_ENTRY_INVALID )
493
+ goto next ;
494
+
495
+ if (memcmp (gid , & table -> data_vec [i ].gid , sizeof (* gid )))
496
+ goto next ;
497
+
498
+ memcpy (& attr , & table -> data_vec [i ].attr , sizeof (attr ));
499
+
500
+ if (filter (gid , & attr , context ))
501
+ found = true;
502
+
503
+ next :
504
+ read_unlock_irqrestore (& table -> data_vec [i ].lock , flags );
505
+
506
+ if (found )
507
+ break ;
508
+ }
509
+
510
+ if (!found )
511
+ return - ENOENT ;
512
+
513
+ if (index )
514
+ * index = i ;
515
+ return 0 ;
516
+ }
517
+
443
518
static struct ib_gid_table * alloc_gid_table (int sz )
444
519
{
445
520
unsigned int i ;
@@ -670,6 +745,24 @@ int ib_find_cached_gid(struct ib_device *device,
670
745
}
671
746
EXPORT_SYMBOL (ib_find_cached_gid );
672
747
748
+ int ib_find_gid_by_filter (struct ib_device * device ,
749
+ const union ib_gid * gid ,
750
+ u8 port_num ,
751
+ bool (* filter )(const union ib_gid * gid ,
752
+ const struct ib_gid_attr * ,
753
+ void * ),
754
+ void * context , u16 * index )
755
+ {
756
+ /* Only RoCE GID table supports filter function */
757
+ if (!rdma_cap_roce_gid_table (device , port_num ) && filter )
758
+ return - EPROTONOSUPPORT ;
759
+
760
+ return ib_cache_gid_find_by_filter (device , gid ,
761
+ port_num , filter ,
762
+ context , index );
763
+ }
764
+ EXPORT_SYMBOL (ib_find_gid_by_filter );
765
+
673
766
int ib_get_cached_pkey (struct ib_device * device ,
674
767
u8 port_num ,
675
768
int index ,
0 commit comments