@@ -671,6 +671,91 @@ static void mlx5e_sync_netdev_addr(struct mlx5e_priv *priv)
671
671
netif_addr_unlock_bh (netdev );
672
672
}
673
673
674
+ static void mlx5e_fill_addr_array (struct mlx5e_priv * priv , int list_type ,
675
+ u8 addr_array [][ETH_ALEN ], int size )
676
+ {
677
+ bool is_uc = (list_type == MLX5_NVPRT_LIST_TYPE_UC );
678
+ struct net_device * ndev = priv -> netdev ;
679
+ struct mlx5e_eth_addr_hash_node * hn ;
680
+ struct hlist_head * addr_list ;
681
+ struct hlist_node * tmp ;
682
+ int i = 0 ;
683
+ int hi ;
684
+
685
+ addr_list = is_uc ? priv -> eth_addr .netdev_uc : priv -> eth_addr .netdev_mc ;
686
+
687
+ if (is_uc ) /* Make sure our own address is pushed first */
688
+ ether_addr_copy (addr_array [i ++ ], ndev -> dev_addr );
689
+ else if (priv -> eth_addr .broadcast_enabled )
690
+ ether_addr_copy (addr_array [i ++ ], ndev -> broadcast );
691
+
692
+ mlx5e_for_each_hash_node (hn , tmp , addr_list , hi ) {
693
+ if (ether_addr_equal (ndev -> dev_addr , hn -> ai .addr ))
694
+ continue ;
695
+ if (i >= size )
696
+ break ;
697
+ ether_addr_copy (addr_array [i ++ ], hn -> ai .addr );
698
+ }
699
+ }
700
+
701
+ static void mlx5e_vport_context_update_addr_list (struct mlx5e_priv * priv ,
702
+ int list_type )
703
+ {
704
+ bool is_uc = (list_type == MLX5_NVPRT_LIST_TYPE_UC );
705
+ struct mlx5e_eth_addr_hash_node * hn ;
706
+ u8 (* addr_array )[ETH_ALEN ] = NULL ;
707
+ struct hlist_head * addr_list ;
708
+ struct hlist_node * tmp ;
709
+ int max_size ;
710
+ int size ;
711
+ int err ;
712
+ int hi ;
713
+
714
+ size = is_uc ? 0 : (priv -> eth_addr .broadcast_enabled ? 1 : 0 );
715
+ max_size = is_uc ?
716
+ 1 << MLX5_CAP_GEN (priv -> mdev , log_max_current_uc_list ) :
717
+ 1 << MLX5_CAP_GEN (priv -> mdev , log_max_current_mc_list );
718
+
719
+ addr_list = is_uc ? priv -> eth_addr .netdev_uc : priv -> eth_addr .netdev_mc ;
720
+ mlx5e_for_each_hash_node (hn , tmp , addr_list , hi )
721
+ size ++ ;
722
+
723
+ if (size > max_size ) {
724
+ netdev_warn (priv -> netdev ,
725
+ "netdev %s list size (%d) > (%d) max vport list size, some addresses will be dropped\n" ,
726
+ is_uc ? "UC" : "MC" , size , max_size );
727
+ size = max_size ;
728
+ }
729
+
730
+ if (size ) {
731
+ addr_array = kcalloc (size , ETH_ALEN , GFP_KERNEL );
732
+ if (!addr_array ) {
733
+ err = - ENOMEM ;
734
+ goto out ;
735
+ }
736
+ mlx5e_fill_addr_array (priv , list_type , addr_array , size );
737
+ }
738
+
739
+ err = mlx5_modify_nic_vport_mac_list (priv -> mdev , list_type , addr_array , size );
740
+ out :
741
+ if (err )
742
+ netdev_err (priv -> netdev ,
743
+ "Failed to modify vport %s list err(%d)\n" ,
744
+ is_uc ? "UC" : "MC" , err );
745
+ kfree (addr_array );
746
+ }
747
+
748
+ static void mlx5e_vport_context_update (struct mlx5e_priv * priv )
749
+ {
750
+ struct mlx5e_eth_addr_db * ea = & priv -> eth_addr ;
751
+
752
+ mlx5e_vport_context_update_addr_list (priv , MLX5_NVPRT_LIST_TYPE_UC );
753
+ mlx5e_vport_context_update_addr_list (priv , MLX5_NVPRT_LIST_TYPE_MC );
754
+ mlx5_modify_nic_vport_promisc (priv -> mdev , 0 ,
755
+ ea -> allmulti_enabled ,
756
+ ea -> promisc_enabled );
757
+ }
758
+
674
759
static void mlx5e_apply_netdev_addr (struct mlx5e_priv * priv )
675
760
{
676
761
struct mlx5e_eth_addr_hash_node * hn ;
@@ -748,6 +833,8 @@ void mlx5e_set_rx_mode_work(struct work_struct *work)
748
833
ea -> promisc_enabled = promisc_enabled ;
749
834
ea -> allmulti_enabled = allmulti_enabled ;
750
835
ea -> broadcast_enabled = broadcast_enabled ;
836
+
837
+ mlx5e_vport_context_update (priv );
751
838
}
752
839
753
840
void mlx5e_init_eth_addr (struct mlx5e_priv * priv )
0 commit comments