@@ -1080,6 +1080,81 @@ void mlx5_eswitch_del_send_to_vport_rule(struct mlx5_flow_handle *rule)
1080
1080
mlx5_del_flow_rules (rule );
1081
1081
}
1082
1082
1083
+ static void mlx5_eswitch_del_send_to_vport_meta_rules (struct mlx5_eswitch * esw )
1084
+ {
1085
+ struct mlx5_flow_handle * * flows = esw -> fdb_table .offloads .send_to_vport_meta_rules ;
1086
+ int i = 0 , num_vfs = esw -> esw_funcs .num_vfs , vport_num ;
1087
+
1088
+ if (!num_vfs || !flows )
1089
+ return ;
1090
+
1091
+ mlx5_esw_for_each_vf_vport_num (esw , vport_num , num_vfs )
1092
+ mlx5_del_flow_rules (flows [i ++ ]);
1093
+
1094
+ kvfree (flows );
1095
+ }
1096
+
1097
+ static int
1098
+ mlx5_eswitch_add_send_to_vport_meta_rules (struct mlx5_eswitch * esw )
1099
+ {
1100
+ int num_vfs , vport_num , rule_idx = 0 , err = 0 ;
1101
+ struct mlx5_flow_destination dest = {};
1102
+ struct mlx5_flow_act flow_act = {0 };
1103
+ struct mlx5_flow_handle * flow_rule ;
1104
+ struct mlx5_flow_handle * * flows ;
1105
+ struct mlx5_flow_spec * spec ;
1106
+
1107
+ num_vfs = esw -> esw_funcs .num_vfs ;
1108
+ flows = kvzalloc (num_vfs * sizeof (* flows ), GFP_KERNEL );
1109
+ if (!flows )
1110
+ return - ENOMEM ;
1111
+
1112
+ spec = kvzalloc (sizeof (* spec ), GFP_KERNEL );
1113
+ if (!spec ) {
1114
+ err = - ENOMEM ;
1115
+ goto alloc_err ;
1116
+ }
1117
+
1118
+ MLX5_SET (fte_match_param , spec -> match_criteria ,
1119
+ misc_parameters_2 .metadata_reg_c_0 , mlx5_eswitch_get_vport_metadata_mask ());
1120
+ MLX5_SET (fte_match_param , spec -> match_criteria ,
1121
+ misc_parameters_2 .metadata_reg_c_1 , ESW_TUN_MASK );
1122
+ MLX5_SET (fte_match_param , spec -> match_value , misc_parameters_2 .metadata_reg_c_1 ,
1123
+ ESW_TUN_SLOW_TABLE_GOTO_VPORT_MARK );
1124
+
1125
+ spec -> match_criteria_enable = MLX5_MATCH_MISC_PARAMETERS_2 ;
1126
+ dest .type = MLX5_FLOW_DESTINATION_TYPE_VPORT ;
1127
+ flow_act .action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST ;
1128
+
1129
+ mlx5_esw_for_each_vf_vport_num (esw , vport_num , num_vfs ) {
1130
+ MLX5_SET (fte_match_param , spec -> match_value , misc_parameters_2 .metadata_reg_c_0 ,
1131
+ mlx5_eswitch_get_vport_metadata_for_match (esw , vport_num ));
1132
+ dest .vport .num = vport_num ;
1133
+
1134
+ flow_rule = mlx5_add_flow_rules (esw -> fdb_table .offloads .slow_fdb ,
1135
+ spec , & flow_act , & dest , 1 );
1136
+ if (IS_ERR (flow_rule )) {
1137
+ err = PTR_ERR (flow_rule );
1138
+ esw_warn (esw -> dev , "FDB: Failed to add send to vport meta rule idx %d, err %ld\n" ,
1139
+ rule_idx , PTR_ERR (flow_rule ));
1140
+ goto rule_err ;
1141
+ }
1142
+ flows [rule_idx ++ ] = flow_rule ;
1143
+ }
1144
+
1145
+ esw -> fdb_table .offloads .send_to_vport_meta_rules = flows ;
1146
+ kvfree (spec );
1147
+ return 0 ;
1148
+
1149
+ rule_err :
1150
+ while (-- rule_idx >= 0 )
1151
+ mlx5_del_flow_rules (flows [rule_idx ]);
1152
+ kvfree (spec );
1153
+ alloc_err :
1154
+ kvfree (flows );
1155
+ return err ;
1156
+ }
1157
+
1083
1158
static bool mlx5_eswitch_reg_c1_loopback_supported (struct mlx5_eswitch * esw )
1084
1159
{
1085
1160
return MLX5_CAP_ESW_FLOWTABLE (esw -> dev , fdb_to_vport_reg_c_id ) &
@@ -1562,11 +1637,11 @@ static int esw_create_offloads_fdb_tables(struct mlx5_eswitch *esw)
1562
1637
{
1563
1638
int inlen = MLX5_ST_SZ_BYTES (create_flow_group_in );
1564
1639
struct mlx5_flow_table_attr ft_attr = {};
1640
+ int num_vfs , table_size , ix , err = 0 ;
1565
1641
struct mlx5_core_dev * dev = esw -> dev ;
1566
1642
struct mlx5_flow_namespace * root_ns ;
1567
1643
struct mlx5_flow_table * fdb = NULL ;
1568
1644
u32 flags = 0 , * flow_group_in ;
1569
- int table_size , ix , err = 0 ;
1570
1645
struct mlx5_flow_group * g ;
1571
1646
void * match_criteria ;
1572
1647
u8 * dmac ;
@@ -1592,7 +1667,7 @@ static int esw_create_offloads_fdb_tables(struct mlx5_eswitch *esw)
1592
1667
}
1593
1668
1594
1669
table_size = esw -> total_vports * MAX_SQ_NVPORTS + MAX_PF_SQ +
1595
- MLX5_ESW_MISS_FLOWS + esw -> total_vports ;
1670
+ MLX5_ESW_MISS_FLOWS + esw -> total_vports + esw -> esw_funcs . num_vfs ;
1596
1671
1597
1672
/* create the slow path fdb with encap set, so further table instances
1598
1673
* can be created at run time while VFs are probed if the FW allows that.
@@ -1640,6 +1715,38 @@ static int esw_create_offloads_fdb_tables(struct mlx5_eswitch *esw)
1640
1715
}
1641
1716
esw -> fdb_table .offloads .send_to_vport_grp = g ;
1642
1717
1718
+ /* meta send to vport */
1719
+ memset (flow_group_in , 0 , inlen );
1720
+ MLX5_SET (create_flow_group_in , flow_group_in , match_criteria_enable ,
1721
+ MLX5_MATCH_MISC_PARAMETERS_2 );
1722
+
1723
+ match_criteria = MLX5_ADDR_OF (create_flow_group_in , flow_group_in , match_criteria );
1724
+
1725
+ MLX5_SET (fte_match_param , match_criteria ,
1726
+ misc_parameters_2 .metadata_reg_c_0 , mlx5_eswitch_get_vport_metadata_mask ());
1727
+ MLX5_SET (fte_match_param , match_criteria ,
1728
+ misc_parameters_2 .metadata_reg_c_1 , ESW_TUN_MASK );
1729
+
1730
+ num_vfs = esw -> esw_funcs .num_vfs ;
1731
+ if (num_vfs ) {
1732
+ MLX5_SET (create_flow_group_in , flow_group_in , start_flow_index , ix );
1733
+ MLX5_SET (create_flow_group_in , flow_group_in , end_flow_index , ix + num_vfs - 1 );
1734
+ ix += num_vfs ;
1735
+
1736
+ g = mlx5_create_flow_group (fdb , flow_group_in );
1737
+ if (IS_ERR (g )) {
1738
+ err = PTR_ERR (g );
1739
+ esw_warn (dev , "Failed to create send-to-vport meta flow group err(%d)\n" ,
1740
+ err );
1741
+ goto send_vport_meta_err ;
1742
+ }
1743
+ esw -> fdb_table .offloads .send_to_vport_meta_grp = g ;
1744
+
1745
+ err = mlx5_eswitch_add_send_to_vport_meta_rules (esw );
1746
+ if (err )
1747
+ goto meta_rule_err ;
1748
+ }
1749
+
1643
1750
if (MLX5_CAP_ESW (esw -> dev , merged_eswitch )) {
1644
1751
/* create peer esw miss group */
1645
1752
memset (flow_group_in , 0 , inlen );
@@ -1707,6 +1814,11 @@ static int esw_create_offloads_fdb_tables(struct mlx5_eswitch *esw)
1707
1814
if (MLX5_CAP_ESW (esw -> dev , merged_eswitch ))
1708
1815
mlx5_destroy_flow_group (esw -> fdb_table .offloads .peer_miss_grp );
1709
1816
peer_miss_err :
1817
+ mlx5_eswitch_del_send_to_vport_meta_rules (esw );
1818
+ meta_rule_err :
1819
+ if (esw -> fdb_table .offloads .send_to_vport_meta_grp )
1820
+ mlx5_destroy_flow_group (esw -> fdb_table .offloads .send_to_vport_meta_grp );
1821
+ send_vport_meta_err :
1710
1822
mlx5_destroy_flow_group (esw -> fdb_table .offloads .send_to_vport_grp );
1711
1823
send_vport_err :
1712
1824
esw_chains_destroy (esw , esw_chains (esw ));
@@ -1728,7 +1840,10 @@ static void esw_destroy_offloads_fdb_tables(struct mlx5_eswitch *esw)
1728
1840
esw_debug (esw -> dev , "Destroy offloads FDB Tables\n" );
1729
1841
mlx5_del_flow_rules (esw -> fdb_table .offloads .miss_rule_multi );
1730
1842
mlx5_del_flow_rules (esw -> fdb_table .offloads .miss_rule_uni );
1843
+ mlx5_eswitch_del_send_to_vport_meta_rules (esw );
1731
1844
mlx5_destroy_flow_group (esw -> fdb_table .offloads .send_to_vport_grp );
1845
+ if (esw -> fdb_table .offloads .send_to_vport_meta_grp )
1846
+ mlx5_destroy_flow_group (esw -> fdb_table .offloads .send_to_vport_meta_grp );
1732
1847
if (MLX5_CAP_ESW (esw -> dev , merged_eswitch ))
1733
1848
mlx5_destroy_flow_group (esw -> fdb_table .offloads .peer_miss_grp );
1734
1849
mlx5_destroy_flow_group (esw -> fdb_table .offloads .miss_grp );
0 commit comments