aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/hw/mlx5/main.c14
-rw-r--r--drivers/infiniband/hw/mlx5/mlx5_ib.h2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en.h14
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c38
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_fs.c49
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c19
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_rep.c6
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_tc.c32
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eswitch.c68
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eswitch.h22
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c42
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fs_core.c289
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fs_core.h5
-rw-r--r--include/linux/mlx5/fs.h28
14 files changed, 374 insertions, 254 deletions
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
index d02341eebddb..8e0dbd51944e 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -1771,13 +1771,13 @@ static int mlx5_ib_destroy_flow(struct ib_flow *flow_id)
1771 mutex_lock(&dev->flow_db.lock); 1771 mutex_lock(&dev->flow_db.lock);
1772 1772
1773 list_for_each_entry_safe(iter, tmp, &handler->list, list) { 1773 list_for_each_entry_safe(iter, tmp, &handler->list, list) {
1774 mlx5_del_flow_rule(iter->rule); 1774 mlx5_del_flow_rules(iter->rule);
1775 put_flow_table(dev, iter->prio, true); 1775 put_flow_table(dev, iter->prio, true);
1776 list_del(&iter->list); 1776 list_del(&iter->list);
1777 kfree(iter); 1777 kfree(iter);
1778 } 1778 }
1779 1779
1780 mlx5_del_flow_rule(handler->rule); 1780 mlx5_del_flow_rules(handler->rule);
1781 put_flow_table(dev, handler->prio, true); 1781 put_flow_table(dev, handler->prio, true);
1782 mutex_unlock(&dev->flow_db.lock); 1782 mutex_unlock(&dev->flow_db.lock);
1783 1783
@@ -1907,10 +1907,10 @@ static struct mlx5_ib_flow_handler *create_flow_rule(struct mlx5_ib_dev *dev,
1907 spec->match_criteria_enable = get_match_criteria_enable(spec->match_criteria); 1907 spec->match_criteria_enable = get_match_criteria_enable(spec->match_criteria);
1908 action = dst ? MLX5_FLOW_CONTEXT_ACTION_FWD_DEST : 1908 action = dst ? MLX5_FLOW_CONTEXT_ACTION_FWD_DEST :
1909 MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO; 1909 MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO;
1910 handler->rule = mlx5_add_flow_rule(ft, spec, 1910 handler->rule = mlx5_add_flow_rules(ft, spec,
1911 action, 1911 action,
1912 MLX5_FS_DEFAULT_FLOW_TAG, 1912 MLX5_FS_DEFAULT_FLOW_TAG,
1913 dst); 1913 dst, 1);
1914 1914
1915 if (IS_ERR(handler->rule)) { 1915 if (IS_ERR(handler->rule)) {
1916 err = PTR_ERR(handler->rule); 1916 err = PTR_ERR(handler->rule);
@@ -1941,7 +1941,7 @@ static struct mlx5_ib_flow_handler *create_dont_trap_rule(struct mlx5_ib_dev *de
1941 handler_dst = create_flow_rule(dev, ft_prio, 1941 handler_dst = create_flow_rule(dev, ft_prio,
1942 flow_attr, dst); 1942 flow_attr, dst);
1943 if (IS_ERR(handler_dst)) { 1943 if (IS_ERR(handler_dst)) {
1944 mlx5_del_flow_rule(handler->rule); 1944 mlx5_del_flow_rules(handler->rule);
1945 ft_prio->refcount--; 1945 ft_prio->refcount--;
1946 kfree(handler); 1946 kfree(handler);
1947 handler = handler_dst; 1947 handler = handler_dst;
@@ -2004,7 +2004,7 @@ static struct mlx5_ib_flow_handler *create_leftovers_rule(struct mlx5_ib_dev *de
2004 &leftovers_specs[LEFTOVERS_UC].flow_attr, 2004 &leftovers_specs[LEFTOVERS_UC].flow_attr,
2005 dst); 2005 dst);
2006 if (IS_ERR(handler_ucast)) { 2006 if (IS_ERR(handler_ucast)) {
2007 mlx5_del_flow_rule(handler->rule); 2007 mlx5_del_flow_rules(handler->rule);
2008 ft_prio->refcount--; 2008 ft_prio->refcount--;
2009 kfree(handler); 2009 kfree(handler);
2010 handler = handler_ucast; 2010 handler = handler_ucast;
@@ -2046,7 +2046,7 @@ static struct mlx5_ib_flow_handler *create_sniffer_rule(struct mlx5_ib_dev *dev,
2046 return handler_rx; 2046 return handler_rx;
2047 2047
2048err_tx: 2048err_tx:
2049 mlx5_del_flow_rule(handler_rx->rule); 2049 mlx5_del_flow_rules(handler_rx->rule);
2050 ft_rx->refcount--; 2050 ft_rx->refcount--;
2051 kfree(handler_rx); 2051 kfree(handler_rx);
2052err: 2052err:
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h
index dcdcd195fe53..d5d007740159 100644
--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
@@ -153,7 +153,7 @@ struct mlx5_ib_flow_handler {
153 struct list_head list; 153 struct list_head list;
154 struct ib_flow ibflow; 154 struct ib_flow ibflow;
155 struct mlx5_ib_flow_prio *prio; 155 struct mlx5_ib_flow_prio *prio;
156 struct mlx5_flow_rule *rule; 156 struct mlx5_flow_handle *rule;
157}; 157};
158 158
159struct mlx5_ib_flow_db { 159struct mlx5_ib_flow_db {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index 460363b66cb1..47ee8ffe987f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -520,7 +520,7 @@ struct mlx5e_vxlan_db {
520 520
521struct mlx5e_l2_rule { 521struct mlx5e_l2_rule {
522 u8 addr[ETH_ALEN + 2]; 522 u8 addr[ETH_ALEN + 2];
523 struct mlx5_flow_rule *rule; 523 struct mlx5_flow_handle *rule;
524}; 524};
525 525
526struct mlx5e_flow_table { 526struct mlx5e_flow_table {
@@ -541,10 +541,10 @@ struct mlx5e_tc_table {
541struct mlx5e_vlan_table { 541struct mlx5e_vlan_table {
542 struct mlx5e_flow_table ft; 542 struct mlx5e_flow_table ft;
543 unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; 543 unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
544 struct mlx5_flow_rule *active_vlans_rule[VLAN_N_VID]; 544 struct mlx5_flow_handle *active_vlans_rule[VLAN_N_VID];
545 struct mlx5_flow_rule *untagged_rule; 545 struct mlx5_flow_handle *untagged_rule;
546 struct mlx5_flow_rule *any_vlan_rule; 546 struct mlx5_flow_handle *any_vlan_rule;
547 bool filter_disabled; 547 bool filter_disabled;
548}; 548};
549 549
550struct mlx5e_l2_table { 550struct mlx5e_l2_table {
@@ -562,14 +562,14 @@ struct mlx5e_l2_table {
562/* L3/L4 traffic type classifier */ 562/* L3/L4 traffic type classifier */
563struct mlx5e_ttc_table { 563struct mlx5e_ttc_table {
564 struct mlx5e_flow_table ft; 564 struct mlx5e_flow_table ft;
565 struct mlx5_flow_rule *rules[MLX5E_NUM_TT]; 565 struct mlx5_flow_handle *rules[MLX5E_NUM_TT];
566}; 566};
567 567
568#define ARFS_HASH_SHIFT BITS_PER_BYTE 568#define ARFS_HASH_SHIFT BITS_PER_BYTE
569#define ARFS_HASH_SIZE BIT(BITS_PER_BYTE) 569#define ARFS_HASH_SIZE BIT(BITS_PER_BYTE)
570struct arfs_table { 570struct arfs_table {
571 struct mlx5e_flow_table ft; 571 struct mlx5e_flow_table ft;
572 struct mlx5_flow_rule *default_rule; 572 struct mlx5_flow_handle *default_rule;
573 struct hlist_head rules_hash[ARFS_HASH_SIZE]; 573 struct hlist_head rules_hash[ARFS_HASH_SIZE];
574}; 574};
575 575
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c
index a8cb38789774..8ff22e83e1dd 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c
@@ -56,7 +56,7 @@ struct arfs_tuple {
56struct arfs_rule { 56struct arfs_rule {
57 struct mlx5e_priv *priv; 57 struct mlx5e_priv *priv;
58 struct work_struct arfs_work; 58 struct work_struct arfs_work;
59 struct mlx5_flow_rule *rule; 59 struct mlx5_flow_handle *rule;
60 struct hlist_node hlist; 60 struct hlist_node hlist;
61 int rxq; 61 int rxq;
62 /* Flow ID passed to ndo_rx_flow_steer */ 62 /* Flow ID passed to ndo_rx_flow_steer */
@@ -104,7 +104,7 @@ static int arfs_disable(struct mlx5e_priv *priv)
104 tt = arfs_get_tt(i); 104 tt = arfs_get_tt(i);
105 /* Modify ttc rules destination to bypass the aRFS tables*/ 105 /* Modify ttc rules destination to bypass the aRFS tables*/
106 err = mlx5_modify_rule_destination(priv->fs.ttc.rules[tt], 106 err = mlx5_modify_rule_destination(priv->fs.ttc.rules[tt],
107 &dest); 107 &dest, NULL);
108 if (err) { 108 if (err) {
109 netdev_err(priv->netdev, 109 netdev_err(priv->netdev,
110 "%s: modify ttc destination failed\n", 110 "%s: modify ttc destination failed\n",
@@ -137,7 +137,7 @@ int mlx5e_arfs_enable(struct mlx5e_priv *priv)
137 tt = arfs_get_tt(i); 137 tt = arfs_get_tt(i);
138 /* Modify ttc rules destination to point on the aRFS FTs */ 138 /* Modify ttc rules destination to point on the aRFS FTs */
139 err = mlx5_modify_rule_destination(priv->fs.ttc.rules[tt], 139 err = mlx5_modify_rule_destination(priv->fs.ttc.rules[tt],
140 &dest); 140 &dest, NULL);
141 if (err) { 141 if (err) {
142 netdev_err(priv->netdev, 142 netdev_err(priv->netdev,
143 "%s: modify ttc destination failed err=%d\n", 143 "%s: modify ttc destination failed err=%d\n",
@@ -151,7 +151,7 @@ int mlx5e_arfs_enable(struct mlx5e_priv *priv)
151 151
152static void arfs_destroy_table(struct arfs_table *arfs_t) 152static void arfs_destroy_table(struct arfs_table *arfs_t)
153{ 153{
154 mlx5_del_flow_rule(arfs_t->default_rule); 154 mlx5_del_flow_rules(arfs_t->default_rule);
155 mlx5e_destroy_flow_table(&arfs_t->ft); 155 mlx5e_destroy_flow_table(&arfs_t->ft);
156} 156}
157 157
@@ -205,10 +205,10 @@ static int arfs_add_default_rule(struct mlx5e_priv *priv,
205 goto out; 205 goto out;
206 } 206 }
207 207
208 arfs_t->default_rule = mlx5_add_flow_rule(arfs_t->ft.t, spec, 208 arfs_t->default_rule = mlx5_add_flow_rules(arfs_t->ft.t, spec,
209 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST, 209 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST,
210 MLX5_FS_DEFAULT_FLOW_TAG, 210 MLX5_FS_DEFAULT_FLOW_TAG,
211 &dest); 211 &dest, 1);
212 if (IS_ERR(arfs_t->default_rule)) { 212 if (IS_ERR(arfs_t->default_rule)) {
213 err = PTR_ERR(arfs_t->default_rule); 213 err = PTR_ERR(arfs_t->default_rule);
214 arfs_t->default_rule = NULL; 214 arfs_t->default_rule = NULL;
@@ -396,7 +396,7 @@ static void arfs_may_expire_flow(struct mlx5e_priv *priv)
396 spin_unlock_bh(&priv->fs.arfs.arfs_lock); 396 spin_unlock_bh(&priv->fs.arfs.arfs_lock);
397 hlist_for_each_entry_safe(arfs_rule, htmp, &del_list, hlist) { 397 hlist_for_each_entry_safe(arfs_rule, htmp, &del_list, hlist) {
398 if (arfs_rule->rule) 398 if (arfs_rule->rule)
399 mlx5_del_flow_rule(arfs_rule->rule); 399 mlx5_del_flow_rules(arfs_rule->rule);
400 hlist_del(&arfs_rule->hlist); 400 hlist_del(&arfs_rule->hlist);
401 kfree(arfs_rule); 401 kfree(arfs_rule);
402 } 402 }
@@ -420,7 +420,7 @@ static void arfs_del_rules(struct mlx5e_priv *priv)
420 hlist_for_each_entry_safe(rule, htmp, &del_list, hlist) { 420 hlist_for_each_entry_safe(rule, htmp, &del_list, hlist) {
421 cancel_work_sync(&rule->arfs_work); 421 cancel_work_sync(&rule->arfs_work);
422 if (rule->rule) 422 if (rule->rule)
423 mlx5_del_flow_rule(rule->rule); 423 mlx5_del_flow_rules(rule->rule);
424 hlist_del(&rule->hlist); 424 hlist_del(&rule->hlist);
425 kfree(rule); 425 kfree(rule);
426 } 426 }
@@ -462,12 +462,12 @@ static struct arfs_table *arfs_get_table(struct mlx5e_arfs_tables *arfs,
462 return NULL; 462 return NULL;
463} 463}
464 464
465static struct mlx5_flow_rule *arfs_add_rule(struct mlx5e_priv *priv, 465static struct mlx5_flow_handle *arfs_add_rule(struct mlx5e_priv *priv,
466 struct arfs_rule *arfs_rule) 466 struct arfs_rule *arfs_rule)
467{ 467{
468 struct mlx5e_arfs_tables *arfs = &priv->fs.arfs; 468 struct mlx5e_arfs_tables *arfs = &priv->fs.arfs;
469 struct arfs_tuple *tuple = &arfs_rule->tuple; 469 struct arfs_tuple *tuple = &arfs_rule->tuple;
470 struct mlx5_flow_rule *rule = NULL; 470 struct mlx5_flow_handle *rule = NULL;
471 struct mlx5_flow_destination dest; 471 struct mlx5_flow_destination dest;
472 struct arfs_table *arfs_table; 472 struct arfs_table *arfs_table;
473 struct mlx5_flow_spec *spec; 473 struct mlx5_flow_spec *spec;
@@ -544,9 +544,9 @@ static struct mlx5_flow_rule *arfs_add_rule(struct mlx5e_priv *priv,
544 } 544 }
545 dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR; 545 dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
546 dest.tir_num = priv->direct_tir[arfs_rule->rxq].tirn; 546 dest.tir_num = priv->direct_tir[arfs_rule->rxq].tirn;
547 rule = mlx5_add_flow_rule(ft, spec, MLX5_FLOW_CONTEXT_ACTION_FWD_DEST, 547 rule = mlx5_add_flow_rules(ft, spec, MLX5_FLOW_CONTEXT_ACTION_FWD_DEST,
548 MLX5_FS_DEFAULT_FLOW_TAG, 548 MLX5_FS_DEFAULT_FLOW_TAG,
549 &dest); 549 &dest, 1);
550 if (IS_ERR(rule)) { 550 if (IS_ERR(rule)) {
551 err = PTR_ERR(rule); 551 err = PTR_ERR(rule);
552 netdev_err(priv->netdev, "%s: add rule(filter id=%d, rq idx=%d) failed, err=%d\n", 552 netdev_err(priv->netdev, "%s: add rule(filter id=%d, rq idx=%d) failed, err=%d\n",
@@ -559,14 +559,14 @@ out:
559} 559}
560 560
561static void arfs_modify_rule_rq(struct mlx5e_priv *priv, 561static void arfs_modify_rule_rq(struct mlx5e_priv *priv,
562 struct mlx5_flow_rule *rule, u16 rxq) 562 struct mlx5_flow_handle *rule, u16 rxq)
563{ 563{
564 struct mlx5_flow_destination dst; 564 struct mlx5_flow_destination dst;
565 int err = 0; 565 int err = 0;
566 566
567 dst.type = MLX5_FLOW_DESTINATION_TYPE_TIR; 567 dst.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
568 dst.tir_num = priv->direct_tir[rxq].tirn; 568 dst.tir_num = priv->direct_tir[rxq].tirn;
569 err = mlx5_modify_rule_destination(rule, &dst); 569 err = mlx5_modify_rule_destination(rule, &dst, NULL);
570 if (err) 570 if (err)
571 netdev_warn(priv->netdev, 571 netdev_warn(priv->netdev,
572 "Failed to modfiy aRFS rule destination to rq=%d\n", rxq); 572 "Failed to modfiy aRFS rule destination to rq=%d\n", rxq);
@@ -578,7 +578,7 @@ static void arfs_handle_work(struct work_struct *work)
578 struct arfs_rule, 578 struct arfs_rule,
579 arfs_work); 579 arfs_work);
580 struct mlx5e_priv *priv = arfs_rule->priv; 580 struct mlx5e_priv *priv = arfs_rule->priv;
581 struct mlx5_flow_rule *rule; 581 struct mlx5_flow_handle *rule;
582 582
583 mutex_lock(&priv->state_lock); 583 mutex_lock(&priv->state_lock);
584 if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) { 584 if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
index 36fbc6b21a33..bed544d47ba1 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
@@ -160,7 +160,7 @@ static int __mlx5e_add_vlan_rule(struct mlx5e_priv *priv,
160{ 160{
161 struct mlx5_flow_table *ft = priv->fs.vlan.ft.t; 161 struct mlx5_flow_table *ft = priv->fs.vlan.ft.t;
162 struct mlx5_flow_destination dest; 162 struct mlx5_flow_destination dest;
163 struct mlx5_flow_rule **rule_p; 163 struct mlx5_flow_handle **rule_p;
164 int err = 0; 164 int err = 0;
165 165
166 dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; 166 dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
@@ -187,10 +187,10 @@ static int __mlx5e_add_vlan_rule(struct mlx5e_priv *priv,
187 break; 187 break;
188 } 188 }
189 189
190 *rule_p = mlx5_add_flow_rule(ft, spec, 190 *rule_p = mlx5_add_flow_rules(ft, spec,
191 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST, 191 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST,
192 MLX5_FS_DEFAULT_FLOW_TAG, 192 MLX5_FS_DEFAULT_FLOW_TAG,
193 &dest); 193 &dest, 1);
194 194
195 if (IS_ERR(*rule_p)) { 195 if (IS_ERR(*rule_p)) {
196 err = PTR_ERR(*rule_p); 196 err = PTR_ERR(*rule_p);
@@ -229,20 +229,20 @@ static void mlx5e_del_vlan_rule(struct mlx5e_priv *priv,
229 switch (rule_type) { 229 switch (rule_type) {
230 case MLX5E_VLAN_RULE_TYPE_UNTAGGED: 230 case MLX5E_VLAN_RULE_TYPE_UNTAGGED:
231 if (priv->fs.vlan.untagged_rule) { 231 if (priv->fs.vlan.untagged_rule) {
232 mlx5_del_flow_rule(priv->fs.vlan.untagged_rule); 232 mlx5_del_flow_rules(priv->fs.vlan.untagged_rule);
233 priv->fs.vlan.untagged_rule = NULL; 233 priv->fs.vlan.untagged_rule = NULL;
234 } 234 }
235 break; 235 break;
236 case MLX5E_VLAN_RULE_TYPE_ANY_VID: 236 case MLX5E_VLAN_RULE_TYPE_ANY_VID:
237 if (priv->fs.vlan.any_vlan_rule) { 237 if (priv->fs.vlan.any_vlan_rule) {
238 mlx5_del_flow_rule(priv->fs.vlan.any_vlan_rule); 238 mlx5_del_flow_rules(priv->fs.vlan.any_vlan_rule);
239 priv->fs.vlan.any_vlan_rule = NULL; 239 priv->fs.vlan.any_vlan_rule = NULL;
240 } 240 }
241 break; 241 break;
242 case MLX5E_VLAN_RULE_TYPE_MATCH_VID: 242 case MLX5E_VLAN_RULE_TYPE_MATCH_VID:
243 mlx5e_vport_context_update_vlans(priv); 243 mlx5e_vport_context_update_vlans(priv);
244 if (priv->fs.vlan.active_vlans_rule[vid]) { 244 if (priv->fs.vlan.active_vlans_rule[vid]) {
245 mlx5_del_flow_rule(priv->fs.vlan.active_vlans_rule[vid]); 245 mlx5_del_flow_rules(priv->fs.vlan.active_vlans_rule[vid]);
246 priv->fs.vlan.active_vlans_rule[vid] = NULL; 246 priv->fs.vlan.active_vlans_rule[vid] = NULL;
247 } 247 }
248 mlx5e_vport_context_update_vlans(priv); 248 mlx5e_vport_context_update_vlans(priv);
@@ -560,7 +560,7 @@ static void mlx5e_cleanup_ttc_rules(struct mlx5e_ttc_table *ttc)
560 560
561 for (i = 0; i < MLX5E_NUM_TT; i++) { 561 for (i = 0; i < MLX5E_NUM_TT; i++) {
562 if (!IS_ERR_OR_NULL(ttc->rules[i])) { 562 if (!IS_ERR_OR_NULL(ttc->rules[i])) {
563 mlx5_del_flow_rule(ttc->rules[i]); 563 mlx5_del_flow_rules(ttc->rules[i]);
564 ttc->rules[i] = NULL; 564 ttc->rules[i] = NULL;
565 } 565 }
566 } 566 }
@@ -616,13 +616,14 @@ static struct {
616 }, 616 },
617}; 617};
618 618
619static struct mlx5_flow_rule *mlx5e_generate_ttc_rule(struct mlx5e_priv *priv, 619static struct mlx5_flow_handle *
620 struct mlx5_flow_table *ft, 620mlx5e_generate_ttc_rule(struct mlx5e_priv *priv,
621 struct mlx5_flow_destination *dest, 621 struct mlx5_flow_table *ft,
622 u16 etype, 622 struct mlx5_flow_destination *dest,
623 u8 proto) 623 u16 etype,
624 u8 proto)
624{ 625{
625 struct mlx5_flow_rule *rule; 626 struct mlx5_flow_handle *rule;
626 struct mlx5_flow_spec *spec; 627 struct mlx5_flow_spec *spec;
627 int err = 0; 628 int err = 0;
628 629
@@ -643,10 +644,10 @@ static struct mlx5_flow_rule *mlx5e_generate_ttc_rule(struct mlx5e_priv *priv,
643 MLX5_SET(fte_match_param, spec->match_value, outer_headers.ethertype, etype); 644 MLX5_SET(fte_match_param, spec->match_value, outer_headers.ethertype, etype);
644 } 645 }
645 646
646 rule = mlx5_add_flow_rule(ft, spec, 647 rule = mlx5_add_flow_rules(ft, spec,
647 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST, 648 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST,
648 MLX5_FS_DEFAULT_FLOW_TAG, 649 MLX5_FS_DEFAULT_FLOW_TAG,
649 dest); 650 dest, 1);
650 if (IS_ERR(rule)) { 651 if (IS_ERR(rule)) {
651 err = PTR_ERR(rule); 652 err = PTR_ERR(rule);
652 netdev_err(priv->netdev, "%s: add rule failed\n", __func__); 653 netdev_err(priv->netdev, "%s: add rule failed\n", __func__);
@@ -660,7 +661,7 @@ static int mlx5e_generate_ttc_table_rules(struct mlx5e_priv *priv)
660{ 661{
661 struct mlx5_flow_destination dest; 662 struct mlx5_flow_destination dest;
662 struct mlx5e_ttc_table *ttc; 663 struct mlx5e_ttc_table *ttc;
663 struct mlx5_flow_rule **rules; 664 struct mlx5_flow_handle **rules;
664 struct mlx5_flow_table *ft; 665 struct mlx5_flow_table *ft;
665 int tt; 666 int tt;
666 int err; 667 int err;
@@ -801,7 +802,7 @@ static void mlx5e_del_l2_flow_rule(struct mlx5e_priv *priv,
801 struct mlx5e_l2_rule *ai) 802 struct mlx5e_l2_rule *ai)
802{ 803{
803 if (!IS_ERR_OR_NULL(ai->rule)) { 804 if (!IS_ERR_OR_NULL(ai->rule)) {
804 mlx5_del_flow_rule(ai->rule); 805 mlx5_del_flow_rules(ai->rule);
805 ai->rule = NULL; 806 ai->rule = NULL;
806 } 807 }
807} 808}
@@ -847,9 +848,9 @@ static int mlx5e_add_l2_flow_rule(struct mlx5e_priv *priv,
847 break; 848 break;
848 } 849 }
849 850
850 ai->rule = mlx5_add_flow_rule(ft, spec, 851 ai->rule = mlx5_add_flow_rules(ft, spec,
851 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST, 852 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST,
852 MLX5_FS_DEFAULT_FLOW_TAG, &dest); 853 MLX5_FS_DEFAULT_FLOW_TAG, &dest, 1);
853 if (IS_ERR(ai->rule)) { 854 if (IS_ERR(ai->rule)) {
854 netdev_err(priv->netdev, "%s: add l2 rule(mac:%pM) failed\n", 855 netdev_err(priv->netdev, "%s: add l2 rule(mac:%pM) failed\n",
855 __func__, mv_dmac); 856 __func__, mv_dmac);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c
index d17c24227900..cf52c06377f2 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c
@@ -36,7 +36,7 @@
36struct mlx5e_ethtool_rule { 36struct mlx5e_ethtool_rule {
37 struct list_head list; 37 struct list_head list;
38 struct ethtool_rx_flow_spec flow_spec; 38 struct ethtool_rx_flow_spec flow_spec;
39 struct mlx5_flow_rule *rule; 39 struct mlx5_flow_handle *rule;
40 struct mlx5e_ethtool_table *eth_ft; 40 struct mlx5e_ethtool_table *eth_ft;
41}; 41};
42 42
@@ -284,13 +284,14 @@ static bool outer_header_zero(u32 *match_criteria)
284 size - 1); 284 size - 1);
285} 285}
286 286
287static struct mlx5_flow_rule *add_ethtool_flow_rule(struct mlx5e_priv *priv, 287static struct mlx5_flow_handle *
288 struct mlx5_flow_table *ft, 288add_ethtool_flow_rule(struct mlx5e_priv *priv,
289 struct ethtool_rx_flow_spec *fs) 289 struct mlx5_flow_table *ft,
290 struct ethtool_rx_flow_spec *fs)
290{ 291{
291 struct mlx5_flow_destination *dst = NULL; 292 struct mlx5_flow_destination *dst = NULL;
292 struct mlx5_flow_spec *spec; 293 struct mlx5_flow_spec *spec;
293 struct mlx5_flow_rule *rule; 294 struct mlx5_flow_handle *rule;
294 int err = 0; 295 int err = 0;
295 u32 action; 296 u32 action;
296 297
@@ -317,8 +318,8 @@ static struct mlx5_flow_rule *add_ethtool_flow_rule(struct mlx5e_priv *priv,
317 } 318 }
318 319
319 spec->match_criteria_enable = (!outer_header_zero(spec->match_criteria)); 320 spec->match_criteria_enable = (!outer_header_zero(spec->match_criteria));
320 rule = mlx5_add_flow_rule(ft, spec, action, 321 rule = mlx5_add_flow_rules(ft, spec, action,
321 MLX5_FS_DEFAULT_FLOW_TAG, dst); 322 MLX5_FS_DEFAULT_FLOW_TAG, dst, 1);
322 if (IS_ERR(rule)) { 323 if (IS_ERR(rule)) {
323 err = PTR_ERR(rule); 324 err = PTR_ERR(rule);
324 netdev_err(priv->netdev, "%s: failed to add ethtool steering rule: %d\n", 325 netdev_err(priv->netdev, "%s: failed to add ethtool steering rule: %d\n",
@@ -335,7 +336,7 @@ static void del_ethtool_rule(struct mlx5e_priv *priv,
335 struct mlx5e_ethtool_rule *eth_rule) 336 struct mlx5e_ethtool_rule *eth_rule)
336{ 337{
337 if (eth_rule->rule) 338 if (eth_rule->rule)
338 mlx5_del_flow_rule(eth_rule->rule); 339 mlx5_del_flow_rules(eth_rule->rule);
339 list_del(&eth_rule->list); 340 list_del(&eth_rule->list);
340 priv->fs.ethtool.tot_num_rules--; 341 priv->fs.ethtool.tot_num_rules--;
341 put_flow_table(eth_rule->eth_ft); 342 put_flow_table(eth_rule->eth_ft);
@@ -475,7 +476,7 @@ int mlx5e_ethtool_flow_replace(struct mlx5e_priv *priv,
475{ 476{
476 struct mlx5e_ethtool_table *eth_ft; 477 struct mlx5e_ethtool_table *eth_ft;
477 struct mlx5e_ethtool_rule *eth_rule; 478 struct mlx5e_ethtool_rule *eth_rule;
478 struct mlx5_flow_rule *rule; 479 struct mlx5_flow_handle *rule;
479 int num_tuples; 480 int num_tuples;
480 int err; 481 int err;
481 482
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
index 3c97da103d30..88d3fd132d63 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
@@ -328,7 +328,7 @@ static int mlx5e_init_rep_rx(struct mlx5e_priv *priv)
328 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; 328 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
329 struct mlx5_eswitch_rep *rep = priv->ppriv; 329 struct mlx5_eswitch_rep *rep = priv->ppriv;
330 struct mlx5_core_dev *mdev = priv->mdev; 330 struct mlx5_core_dev *mdev = priv->mdev;
331 struct mlx5_flow_rule *flow_rule; 331 struct mlx5_flow_handle *flow_rule;
332 int err; 332 int err;
333 int i; 333 int i;
334 334
@@ -360,7 +360,7 @@ static int mlx5e_init_rep_rx(struct mlx5e_priv *priv)
360 return 0; 360 return 0;
361 361
362err_del_flow_rule: 362err_del_flow_rule:
363 mlx5_del_flow_rule(rep->vport_rx_rule); 363 mlx5_del_flow_rules(rep->vport_rx_rule);
364err_destroy_direct_tirs: 364err_destroy_direct_tirs:
365 mlx5e_destroy_direct_tirs(priv); 365 mlx5e_destroy_direct_tirs(priv);
366err_destroy_direct_rqts: 366err_destroy_direct_rqts:
@@ -375,7 +375,7 @@ static void mlx5e_cleanup_rep_rx(struct mlx5e_priv *priv)
375 int i; 375 int i;
376 376
377 mlx5e_tc_cleanup(priv); 377 mlx5e_tc_cleanup(priv);
378 mlx5_del_flow_rule(rep->vport_rx_rule); 378 mlx5_del_flow_rules(rep->vport_rx_rule);
379 mlx5e_destroy_direct_tirs(priv); 379 mlx5e_destroy_direct_tirs(priv);
380 for (i = 0; i < priv->params.num_channels; i++) 380 for (i = 0; i < priv->params.num_channels; i++)
381 mlx5e_destroy_rqt(priv, &priv->direct_tir[i].rqt); 381 mlx5e_destroy_rqt(priv, &priv->direct_tir[i].rqt);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index ce8c54d18906..5d9ac0dbf3bf 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -47,21 +47,22 @@
47struct mlx5e_tc_flow { 47struct mlx5e_tc_flow {
48 struct rhash_head node; 48 struct rhash_head node;
49 u64 cookie; 49 u64 cookie;
50 struct mlx5_flow_rule *rule; 50 struct mlx5_flow_handle *rule;
51 struct mlx5_esw_flow_attr *attr; 51 struct mlx5_esw_flow_attr *attr;
52}; 52};
53 53
54#define MLX5E_TC_TABLE_NUM_ENTRIES 1024 54#define MLX5E_TC_TABLE_NUM_ENTRIES 1024
55#define MLX5E_TC_TABLE_NUM_GROUPS 4 55#define MLX5E_TC_TABLE_NUM_GROUPS 4
56 56
57static struct mlx5_flow_rule *mlx5e_tc_add_nic_flow(struct mlx5e_priv *priv, 57static struct mlx5_flow_handle *
58 struct mlx5_flow_spec *spec, 58mlx5e_tc_add_nic_flow(struct mlx5e_priv *priv,
59 u32 action, u32 flow_tag) 59 struct mlx5_flow_spec *spec,
60 u32 action, u32 flow_tag)
60{ 61{
61 struct mlx5_core_dev *dev = priv->mdev; 62 struct mlx5_core_dev *dev = priv->mdev;
62 struct mlx5_flow_destination dest = { 0 }; 63 struct mlx5_flow_destination dest = { 0 };
63 struct mlx5_fc *counter = NULL; 64 struct mlx5_fc *counter = NULL;
64 struct mlx5_flow_rule *rule; 65 struct mlx5_flow_handle *rule;
65 bool table_created = false; 66 bool table_created = false;
66 67
67 if (action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) { 68 if (action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) {
@@ -94,9 +95,9 @@ static struct mlx5_flow_rule *mlx5e_tc_add_nic_flow(struct mlx5e_priv *priv,
94 } 95 }
95 96
96 spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS; 97 spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
97 rule = mlx5_add_flow_rule(priv->fs.tc.t, spec, 98 rule = mlx5_add_flow_rules(priv->fs.tc.t, spec,
98 action, flow_tag, 99 action, flow_tag,
99 &dest); 100 &dest, 1);
100 101
101 if (IS_ERR(rule)) 102 if (IS_ERR(rule))
102 goto err_add_rule; 103 goto err_add_rule;
@@ -114,9 +115,10 @@ err_create_ft:
114 return rule; 115 return rule;
115} 116}
116 117
117static struct mlx5_flow_rule *mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv, 118static struct mlx5_flow_handle *
118 struct mlx5_flow_spec *spec, 119mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
119 struct mlx5_esw_flow_attr *attr) 120 struct mlx5_flow_spec *spec,
121 struct mlx5_esw_flow_attr *attr)
120{ 122{
121 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; 123 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
122 int err; 124 int err;
@@ -129,7 +131,7 @@ static struct mlx5_flow_rule *mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
129} 131}
130 132
131static void mlx5e_tc_del_flow(struct mlx5e_priv *priv, 133static void mlx5e_tc_del_flow(struct mlx5e_priv *priv,
132 struct mlx5_flow_rule *rule, 134 struct mlx5_flow_handle *rule,
133 struct mlx5_esw_flow_attr *attr) 135 struct mlx5_esw_flow_attr *attr)
134{ 136{
135 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; 137 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
@@ -140,7 +142,7 @@ static void mlx5e_tc_del_flow(struct mlx5e_priv *priv,
140 if (esw && esw->mode == SRIOV_OFFLOADS) 142 if (esw && esw->mode == SRIOV_OFFLOADS)
141 mlx5_eswitch_del_vlan_action(esw, attr); 143 mlx5_eswitch_del_vlan_action(esw, attr);
142 144
143 mlx5_del_flow_rule(rule); 145 mlx5_del_flow_rules(rule);
144 146
145 mlx5_fc_destroy(priv->mdev, counter); 147 mlx5_fc_destroy(priv->mdev, counter);
146 148
@@ -450,7 +452,7 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv, __be16 protocol,
450 u32 flow_tag, action; 452 u32 flow_tag, action;
451 struct mlx5e_tc_flow *flow; 453 struct mlx5e_tc_flow *flow;
452 struct mlx5_flow_spec *spec; 454 struct mlx5_flow_spec *spec;
453 struct mlx5_flow_rule *old = NULL; 455 struct mlx5_flow_handle *old = NULL;
454 struct mlx5_esw_flow_attr *old_attr = NULL; 456 struct mlx5_esw_flow_attr *old_attr = NULL;
455 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; 457 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
456 458
@@ -511,7 +513,7 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv, __be16 protocol,
511 goto out; 513 goto out;
512 514
513err_del_rule: 515err_del_rule:
514 mlx5_del_flow_rule(flow->rule); 516 mlx5_del_flow_rules(flow->rule);
515 517
516err_free: 518err_free:
517 if (!old) 519 if (!old)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
index 9ef01d1bea06..fcd8b15f6625 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
@@ -56,7 +56,7 @@ struct esw_uc_addr {
56/* E-Switch MC FDB table hash node */ 56/* E-Switch MC FDB table hash node */
57struct esw_mc_addr { /* SRIOV only */ 57struct esw_mc_addr { /* SRIOV only */
58 struct l2addr_node node; 58 struct l2addr_node node;
59 struct mlx5_flow_rule *uplink_rule; /* Forward to uplink rule */ 59 struct mlx5_flow_handle *uplink_rule; /* Forward to uplink rule */
60 u32 refcnt; 60 u32 refcnt;
61}; 61};
62 62
@@ -65,7 +65,7 @@ struct vport_addr {
65 struct l2addr_node node; 65 struct l2addr_node node;
66 u8 action; 66 u8 action;
67 u32 vport; 67 u32 vport;
68 struct mlx5_flow_rule *flow_rule; /* SRIOV only */ 68 struct mlx5_flow_handle *flow_rule; /* SRIOV only */
69 /* A flag indicating that mac was added due to mc promiscuous vport */ 69 /* A flag indicating that mac was added due to mc promiscuous vport */
70 bool mc_promisc; 70 bool mc_promisc;
71}; 71};
@@ -237,13 +237,13 @@ static void del_l2_table_entry(struct mlx5_core_dev *dev, u32 index)
237} 237}
238 238
239/* E-Switch FDB */ 239/* E-Switch FDB */
240static struct mlx5_flow_rule * 240static struct mlx5_flow_handle *
241__esw_fdb_set_vport_rule(struct mlx5_eswitch *esw, u32 vport, bool rx_rule, 241__esw_fdb_set_vport_rule(struct mlx5_eswitch *esw, u32 vport, bool rx_rule,
242 u8 mac_c[ETH_ALEN], u8 mac_v[ETH_ALEN]) 242 u8 mac_c[ETH_ALEN], u8 mac_v[ETH_ALEN])
243{ 243{
244 int match_header = (is_zero_ether_addr(mac_c) ? 0 : 244 int match_header = (is_zero_ether_addr(mac_c) ? 0 :
245 MLX5_MATCH_OUTER_HEADERS); 245 MLX5_MATCH_OUTER_HEADERS);
246 struct mlx5_flow_rule *flow_rule = NULL; 246 struct mlx5_flow_handle *flow_rule = NULL;
247 struct mlx5_flow_destination dest; 247 struct mlx5_flow_destination dest;
248 struct mlx5_flow_spec *spec; 248 struct mlx5_flow_spec *spec;
249 void *mv_misc = NULL; 249 void *mv_misc = NULL;
@@ -286,9 +286,9 @@ __esw_fdb_set_vport_rule(struct mlx5_eswitch *esw, u32 vport, bool rx_rule,
286 dmac_v, dmac_c, vport); 286 dmac_v, dmac_c, vport);
287 spec->match_criteria_enable = match_header; 287 spec->match_criteria_enable = match_header;
288 flow_rule = 288 flow_rule =
289 mlx5_add_flow_rule(esw->fdb_table.fdb, spec, 289 mlx5_add_flow_rules(esw->fdb_table.fdb, spec,
290 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST, 290 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST,
291 0, &dest); 291 0, &dest, 1);
292 if (IS_ERR(flow_rule)) { 292 if (IS_ERR(flow_rule)) {
293 esw_warn(esw->dev, 293 esw_warn(esw->dev,
294 "FDB: Failed to add flow rule: dmac_v(%pM) dmac_c(%pM) -> vport(%d), err(%ld)\n", 294 "FDB: Failed to add flow rule: dmac_v(%pM) dmac_c(%pM) -> vport(%d), err(%ld)\n",
@@ -300,7 +300,7 @@ __esw_fdb_set_vport_rule(struct mlx5_eswitch *esw, u32 vport, bool rx_rule,
300 return flow_rule; 300 return flow_rule;
301} 301}
302 302
303static struct mlx5_flow_rule * 303static struct mlx5_flow_handle *
304esw_fdb_set_vport_rule(struct mlx5_eswitch *esw, u8 mac[ETH_ALEN], u32 vport) 304esw_fdb_set_vport_rule(struct mlx5_eswitch *esw, u8 mac[ETH_ALEN], u32 vport)
305{ 305{
306 u8 mac_c[ETH_ALEN]; 306 u8 mac_c[ETH_ALEN];
@@ -309,7 +309,7 @@ esw_fdb_set_vport_rule(struct mlx5_eswitch *esw, u8 mac[ETH_ALEN], u32 vport)
309 return __esw_fdb_set_vport_rule(esw, vport, false, mac_c, mac); 309 return __esw_fdb_set_vport_rule(esw, vport, false, mac_c, mac);
310} 310}
311 311
312static struct mlx5_flow_rule * 312static struct mlx5_flow_handle *
313esw_fdb_set_vport_allmulti_rule(struct mlx5_eswitch *esw, u32 vport) 313esw_fdb_set_vport_allmulti_rule(struct mlx5_eswitch *esw, u32 vport)
314{ 314{
315 u8 mac_c[ETH_ALEN]; 315 u8 mac_c[ETH_ALEN];
@@ -322,7 +322,7 @@ esw_fdb_set_vport_allmulti_rule(struct mlx5_eswitch *esw, u32 vport)
322 return __esw_fdb_set_vport_rule(esw, vport, false, mac_c, mac_v); 322 return __esw_fdb_set_vport_rule(esw, vport, false, mac_c, mac_v);
323} 323}
324 324
325static struct mlx5_flow_rule * 325static struct mlx5_flow_handle *
326esw_fdb_set_vport_promisc_rule(struct mlx5_eswitch *esw, u32 vport) 326esw_fdb_set_vport_promisc_rule(struct mlx5_eswitch *esw, u32 vport)
327{ 327{
328 u8 mac_c[ETH_ALEN]; 328 u8 mac_c[ETH_ALEN];
@@ -515,7 +515,7 @@ static int esw_del_uc_addr(struct mlx5_eswitch *esw, struct vport_addr *vaddr)
515 del_l2_table_entry(esw->dev, esw_uc->table_index); 515 del_l2_table_entry(esw->dev, esw_uc->table_index);
516 516
517 if (vaddr->flow_rule) 517 if (vaddr->flow_rule)
518 mlx5_del_flow_rule(vaddr->flow_rule); 518 mlx5_del_flow_rules(vaddr->flow_rule);
519 vaddr->flow_rule = NULL; 519 vaddr->flow_rule = NULL;
520 520
521 l2addr_hash_del(esw_uc); 521 l2addr_hash_del(esw_uc);
@@ -562,7 +562,7 @@ static void update_allmulti_vports(struct mlx5_eswitch *esw,
562 case MLX5_ACTION_DEL: 562 case MLX5_ACTION_DEL:
563 if (!iter_vaddr) 563 if (!iter_vaddr)
564 continue; 564 continue;
565 mlx5_del_flow_rule(iter_vaddr->flow_rule); 565 mlx5_del_flow_rules(iter_vaddr->flow_rule);
566 l2addr_hash_del(iter_vaddr); 566 l2addr_hash_del(iter_vaddr);
567 break; 567 break;
568 } 568 }
@@ -632,7 +632,7 @@ static int esw_del_mc_addr(struct mlx5_eswitch *esw, struct vport_addr *vaddr)
632 esw_mc->uplink_rule); 632 esw_mc->uplink_rule);
633 633
634 if (vaddr->flow_rule) 634 if (vaddr->flow_rule)
635 mlx5_del_flow_rule(vaddr->flow_rule); 635 mlx5_del_flow_rules(vaddr->flow_rule);
636 vaddr->flow_rule = NULL; 636 vaddr->flow_rule = NULL;
637 637
638 /* If the multicast mac is added as a result of mc promiscuous vport, 638 /* If the multicast mac is added as a result of mc promiscuous vport,
@@ -645,7 +645,7 @@ static int esw_del_mc_addr(struct mlx5_eswitch *esw, struct vport_addr *vaddr)
645 update_allmulti_vports(esw, vaddr, esw_mc); 645 update_allmulti_vports(esw, vaddr, esw_mc);
646 646
647 if (esw_mc->uplink_rule) 647 if (esw_mc->uplink_rule)
648 mlx5_del_flow_rule(esw_mc->uplink_rule); 648 mlx5_del_flow_rules(esw_mc->uplink_rule);
649 649
650 l2addr_hash_del(esw_mc); 650 l2addr_hash_del(esw_mc);
651 return 0; 651 return 0;
@@ -828,14 +828,14 @@ static void esw_apply_vport_rx_mode(struct mlx5_eswitch *esw, u32 vport_num,
828 UPLINK_VPORT); 828 UPLINK_VPORT);
829 allmulti_addr->refcnt++; 829 allmulti_addr->refcnt++;
830 } else if (vport->allmulti_rule) { 830 } else if (vport->allmulti_rule) {
831 mlx5_del_flow_rule(vport->allmulti_rule); 831 mlx5_del_flow_rules(vport->allmulti_rule);
832 vport->allmulti_rule = NULL; 832 vport->allmulti_rule = NULL;
833 833
834 if (--allmulti_addr->refcnt > 0) 834 if (--allmulti_addr->refcnt > 0)
835 goto promisc; 835 goto promisc;
836 836
837 if (allmulti_addr->uplink_rule) 837 if (allmulti_addr->uplink_rule)
838 mlx5_del_flow_rule(allmulti_addr->uplink_rule); 838 mlx5_del_flow_rules(allmulti_addr->uplink_rule);
839 allmulti_addr->uplink_rule = NULL; 839 allmulti_addr->uplink_rule = NULL;
840 } 840 }
841 841
@@ -847,7 +847,7 @@ promisc:
847 vport->promisc_rule = esw_fdb_set_vport_promisc_rule(esw, 847 vport->promisc_rule = esw_fdb_set_vport_promisc_rule(esw,
848 vport_num); 848 vport_num);
849 } else if (vport->promisc_rule) { 849 } else if (vport->promisc_rule) {
850 mlx5_del_flow_rule(vport->promisc_rule); 850 mlx5_del_flow_rules(vport->promisc_rule);
851 vport->promisc_rule = NULL; 851 vport->promisc_rule = NULL;
852 } 852 }
853} 853}
@@ -1015,10 +1015,10 @@ static void esw_vport_cleanup_egress_rules(struct mlx5_eswitch *esw,
1015 struct mlx5_vport *vport) 1015 struct mlx5_vport *vport)
1016{ 1016{
1017 if (!IS_ERR_OR_NULL(vport->egress.allowed_vlan)) 1017 if (!IS_ERR_OR_NULL(vport->egress.allowed_vlan))
1018 mlx5_del_flow_rule(vport->egress.allowed_vlan); 1018 mlx5_del_flow_rules(vport->egress.allowed_vlan);
1019 1019
1020 if (!IS_ERR_OR_NULL(vport->egress.drop_rule)) 1020 if (!IS_ERR_OR_NULL(vport->egress.drop_rule))
1021 mlx5_del_flow_rule(vport->egress.drop_rule); 1021 mlx5_del_flow_rules(vport->egress.drop_rule);
1022 1022
1023 vport->egress.allowed_vlan = NULL; 1023 vport->egress.allowed_vlan = NULL;
1024 vport->egress.drop_rule = NULL; 1024 vport->egress.drop_rule = NULL;
@@ -1173,10 +1173,10 @@ static void esw_vport_cleanup_ingress_rules(struct mlx5_eswitch *esw,
1173 struct mlx5_vport *vport) 1173 struct mlx5_vport *vport)
1174{ 1174{
1175 if (!IS_ERR_OR_NULL(vport->ingress.drop_rule)) 1175 if (!IS_ERR_OR_NULL(vport->ingress.drop_rule))
1176 mlx5_del_flow_rule(vport->ingress.drop_rule); 1176 mlx5_del_flow_rules(vport->ingress.drop_rule);
1177 1177
1178 if (!IS_ERR_OR_NULL(vport->ingress.allow_rule)) 1178 if (!IS_ERR_OR_NULL(vport->ingress.allow_rule))
1179 mlx5_del_flow_rule(vport->ingress.allow_rule); 1179 mlx5_del_flow_rules(vport->ingress.allow_rule);
1180 1180
1181 vport->ingress.drop_rule = NULL; 1181 vport->ingress.drop_rule = NULL;
1182 vport->ingress.allow_rule = NULL; 1182 vport->ingress.allow_rule = NULL;
@@ -1253,9 +1253,9 @@ static int esw_vport_ingress_config(struct mlx5_eswitch *esw,
1253 1253
1254 spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS; 1254 spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
1255 vport->ingress.allow_rule = 1255 vport->ingress.allow_rule =
1256 mlx5_add_flow_rule(vport->ingress.acl, spec, 1256 mlx5_add_flow_rules(vport->ingress.acl, spec,
1257 MLX5_FLOW_CONTEXT_ACTION_ALLOW, 1257 MLX5_FLOW_CONTEXT_ACTION_ALLOW,
1258 0, NULL); 1258 0, NULL, 0);
1259 if (IS_ERR(vport->ingress.allow_rule)) { 1259 if (IS_ERR(vport->ingress.allow_rule)) {
1260 err = PTR_ERR(vport->ingress.allow_rule); 1260 err = PTR_ERR(vport->ingress.allow_rule);
1261 esw_warn(esw->dev, 1261 esw_warn(esw->dev,
@@ -1267,9 +1267,9 @@ static int esw_vport_ingress_config(struct mlx5_eswitch *esw,
1267 1267
1268 memset(spec, 0, sizeof(*spec)); 1268 memset(spec, 0, sizeof(*spec));
1269 vport->ingress.drop_rule = 1269 vport->ingress.drop_rule =
1270 mlx5_add_flow_rule(vport->ingress.acl, spec, 1270 mlx5_add_flow_rules(vport->ingress.acl, spec,
1271 MLX5_FLOW_CONTEXT_ACTION_DROP, 1271 MLX5_FLOW_CONTEXT_ACTION_DROP,
1272 0, NULL); 1272 0, NULL, 0);
1273 if (IS_ERR(vport->ingress.drop_rule)) { 1273 if (IS_ERR(vport->ingress.drop_rule)) {
1274 err = PTR_ERR(vport->ingress.drop_rule); 1274 err = PTR_ERR(vport->ingress.drop_rule);
1275 esw_warn(esw->dev, 1275 esw_warn(esw->dev,
@@ -1321,9 +1321,9 @@ static int esw_vport_egress_config(struct mlx5_eswitch *esw,
1321 1321
1322 spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS; 1322 spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
1323 vport->egress.allowed_vlan = 1323 vport->egress.allowed_vlan =
1324 mlx5_add_flow_rule(vport->egress.acl, spec, 1324 mlx5_add_flow_rules(vport->egress.acl, spec,
1325 MLX5_FLOW_CONTEXT_ACTION_ALLOW, 1325 MLX5_FLOW_CONTEXT_ACTION_ALLOW,
1326 0, NULL); 1326 0, NULL, 0);
1327 if (IS_ERR(vport->egress.allowed_vlan)) { 1327 if (IS_ERR(vport->egress.allowed_vlan)) {
1328 err = PTR_ERR(vport->egress.allowed_vlan); 1328 err = PTR_ERR(vport->egress.allowed_vlan);
1329 esw_warn(esw->dev, 1329 esw_warn(esw->dev,
@@ -1336,9 +1336,9 @@ static int esw_vport_egress_config(struct mlx5_eswitch *esw,
1336 /* Drop others rule (star rule) */ 1336 /* Drop others rule (star rule) */
1337 memset(spec, 0, sizeof(*spec)); 1337 memset(spec, 0, sizeof(*spec));
1338 vport->egress.drop_rule = 1338 vport->egress.drop_rule =
1339 mlx5_add_flow_rule(vport->egress.acl, spec, 1339 mlx5_add_flow_rules(vport->egress.acl, spec,
1340 MLX5_FLOW_CONTEXT_ACTION_DROP, 1340 MLX5_FLOW_CONTEXT_ACTION_DROP,
1341 0, NULL); 1341 0, NULL, 0);
1342 if (IS_ERR(vport->egress.drop_rule)) { 1342 if (IS_ERR(vport->egress.drop_rule)) {
1343 err = PTR_ERR(vport->egress.drop_rule); 1343 err = PTR_ERR(vport->egress.drop_rule);
1344 esw_warn(esw->dev, 1344 esw_warn(esw->dev,
@@ -1667,7 +1667,7 @@ void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw)
1667 esw_disable_vport(esw, i); 1667 esw_disable_vport(esw, i);
1668 1668
1669 if (mc_promisc && mc_promisc->uplink_rule) 1669 if (mc_promisc && mc_promisc->uplink_rule)
1670 mlx5_del_flow_rule(mc_promisc->uplink_rule); 1670 mlx5_del_flow_rules(mc_promisc->uplink_rule);
1671 1671
1672 esw_destroy_tsar(esw); 1672 esw_destroy_tsar(esw);
1673 1673
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
index ddae90c1f15b..6d414cb1b75f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
@@ -97,16 +97,16 @@ struct vport_ingress {
97 struct mlx5_flow_group *allow_spoofchk_only_grp; 97 struct mlx5_flow_group *allow_spoofchk_only_grp;
98 struct mlx5_flow_group *allow_untagged_only_grp; 98 struct mlx5_flow_group *allow_untagged_only_grp;
99 struct mlx5_flow_group *drop_grp; 99 struct mlx5_flow_group *drop_grp;
100 struct mlx5_flow_rule *allow_rule; 100 struct mlx5_flow_handle *allow_rule;
101 struct mlx5_flow_rule *drop_rule; 101 struct mlx5_flow_handle *drop_rule;
102}; 102};
103 103
104struct vport_egress { 104struct vport_egress {
105 struct mlx5_flow_table *acl; 105 struct mlx5_flow_table *acl;
106 struct mlx5_flow_group *allowed_vlans_grp; 106 struct mlx5_flow_group *allowed_vlans_grp;
107 struct mlx5_flow_group *drop_grp; 107 struct mlx5_flow_group *drop_grp;
108 struct mlx5_flow_rule *allowed_vlan; 108 struct mlx5_flow_handle *allowed_vlan;
109 struct mlx5_flow_rule *drop_rule; 109 struct mlx5_flow_handle *drop_rule;
110}; 110};
111 111
112struct mlx5_vport_info { 112struct mlx5_vport_info {
@@ -125,8 +125,8 @@ struct mlx5_vport {
125 int vport; 125 int vport;
126 struct hlist_head uc_list[MLX5_L2_ADDR_HASH_SIZE]; 126 struct hlist_head uc_list[MLX5_L2_ADDR_HASH_SIZE];
127 struct hlist_head mc_list[MLX5_L2_ADDR_HASH_SIZE]; 127 struct hlist_head mc_list[MLX5_L2_ADDR_HASH_SIZE];
128 struct mlx5_flow_rule *promisc_rule; 128 struct mlx5_flow_handle *promisc_rule;
129 struct mlx5_flow_rule *allmulti_rule; 129 struct mlx5_flow_handle *allmulti_rule;
130 struct work_struct vport_change_handler; 130 struct work_struct vport_change_handler;
131 131
132 struct vport_ingress ingress; 132 struct vport_ingress ingress;
@@ -162,7 +162,7 @@ struct mlx5_eswitch_fdb {
162 struct mlx5_flow_table *fdb; 162 struct mlx5_flow_table *fdb;
163 struct mlx5_flow_group *send_to_vport_grp; 163 struct mlx5_flow_group *send_to_vport_grp;
164 struct mlx5_flow_group *miss_grp; 164 struct mlx5_flow_group *miss_grp;
165 struct mlx5_flow_rule *miss_rule; 165 struct mlx5_flow_handle *miss_rule;
166 int vlan_push_pop_refcount; 166 int vlan_push_pop_refcount;
167 } offloads; 167 } offloads;
168 }; 168 };
@@ -175,7 +175,7 @@ enum {
175}; 175};
176 176
177struct mlx5_esw_sq { 177struct mlx5_esw_sq {
178 struct mlx5_flow_rule *send_to_vport_rule; 178 struct mlx5_flow_handle *send_to_vport_rule;
179 struct list_head list; 179 struct list_head list;
180}; 180};
181 181
@@ -188,7 +188,7 @@ struct mlx5_eswitch_rep {
188 u8 hw_id[ETH_ALEN]; 188 u8 hw_id[ETH_ALEN];
189 void *priv_data; 189 void *priv_data;
190 190
191 struct mlx5_flow_rule *vport_rx_rule; 191 struct mlx5_flow_handle *vport_rx_rule;
192 struct list_head vport_sqs_list; 192 struct list_head vport_sqs_list;
193 u16 vlan; 193 u16 vlan;
194 u32 vlan_refcount; 194 u32 vlan_refcount;
@@ -257,11 +257,11 @@ int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw,
257struct mlx5_flow_spec; 257struct mlx5_flow_spec;
258struct mlx5_esw_flow_attr; 258struct mlx5_esw_flow_attr;
259 259
260struct mlx5_flow_rule * 260struct mlx5_flow_handle *
261mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw, 261mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
262 struct mlx5_flow_spec *spec, 262 struct mlx5_flow_spec *spec,
263 struct mlx5_esw_flow_attr *attr); 263 struct mlx5_esw_flow_attr *attr);
264struct mlx5_flow_rule * 264struct mlx5_flow_handle *
265mlx5_eswitch_create_vport_rx_rule(struct mlx5_eswitch *esw, int vport, u32 tirn); 265mlx5_eswitch_create_vport_rx_rule(struct mlx5_eswitch *esw, int vport, u32 tirn);
266 266
267enum { 267enum {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
index c55ad8d00c05..8b2a3832cd0a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
@@ -43,14 +43,14 @@ enum {
43 FDB_SLOW_PATH 43 FDB_SLOW_PATH
44}; 44};
45 45
46struct mlx5_flow_rule * 46struct mlx5_flow_handle *
47mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw, 47mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
48 struct mlx5_flow_spec *spec, 48 struct mlx5_flow_spec *spec,
49 struct mlx5_esw_flow_attr *attr) 49 struct mlx5_esw_flow_attr *attr)
50{ 50{
51 struct mlx5_flow_destination dest = { 0 }; 51 struct mlx5_flow_destination dest = { 0 };
52 struct mlx5_fc *counter = NULL; 52 struct mlx5_fc *counter = NULL;
53 struct mlx5_flow_rule *rule; 53 struct mlx5_flow_handle *rule;
54 void *misc; 54 void *misc;
55 int action; 55 int action;
56 56
@@ -80,8 +80,8 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
80 spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS | 80 spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS |
81 MLX5_MATCH_MISC_PARAMETERS; 81 MLX5_MATCH_MISC_PARAMETERS;
82 82
83 rule = mlx5_add_flow_rule((struct mlx5_flow_table *)esw->fdb_table.fdb, 83 rule = mlx5_add_flow_rules((struct mlx5_flow_table *)esw->fdb_table.fdb,
84 spec, action, 0, &dest); 84 spec, action, 0, &dest, 1);
85 85
86 if (IS_ERR(rule)) 86 if (IS_ERR(rule))
87 mlx5_fc_destroy(esw->dev, counter); 87 mlx5_fc_destroy(esw->dev, counter);
@@ -269,11 +269,11 @@ out:
269 return err; 269 return err;
270} 270}
271 271
272static struct mlx5_flow_rule * 272static struct mlx5_flow_handle *
273mlx5_eswitch_add_send_to_vport_rule(struct mlx5_eswitch *esw, int vport, u32 sqn) 273mlx5_eswitch_add_send_to_vport_rule(struct mlx5_eswitch *esw, int vport, u32 sqn)
274{ 274{
275 struct mlx5_flow_destination dest; 275 struct mlx5_flow_destination dest;
276 struct mlx5_flow_rule *flow_rule; 276 struct mlx5_flow_handle *flow_rule;
277 struct mlx5_flow_spec *spec; 277 struct mlx5_flow_spec *spec;
278 void *misc; 278 void *misc;
279 279
@@ -296,9 +296,9 @@ mlx5_eswitch_add_send_to_vport_rule(struct mlx5_eswitch *esw, int vport, u32 sqn
296 dest.type = MLX5_FLOW_DESTINATION_TYPE_VPORT; 296 dest.type = MLX5_FLOW_DESTINATION_TYPE_VPORT;
297 dest.vport_num = vport; 297 dest.vport_num = vport;
298 298
299 flow_rule = mlx5_add_flow_rule(esw->fdb_table.offloads.fdb, spec, 299 flow_rule = mlx5_add_flow_rules(esw->fdb_table.offloads.fdb, spec,
300 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST, 300 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST,
301 0, &dest); 301 0, &dest, 1);
302 if (IS_ERR(flow_rule)) 302 if (IS_ERR(flow_rule))
303 esw_warn(esw->dev, "FDB: Failed to add send to vport rule err %ld\n", PTR_ERR(flow_rule)); 303 esw_warn(esw->dev, "FDB: Failed to add send to vport rule err %ld\n", PTR_ERR(flow_rule));
304out: 304out:
@@ -315,7 +315,7 @@ void mlx5_eswitch_sqs2vport_stop(struct mlx5_eswitch *esw,
315 return; 315 return;
316 316
317 list_for_each_entry_safe(esw_sq, tmp, &rep->vport_sqs_list, list) { 317 list_for_each_entry_safe(esw_sq, tmp, &rep->vport_sqs_list, list) {
318 mlx5_del_flow_rule(esw_sq->send_to_vport_rule); 318 mlx5_del_flow_rules(esw_sq->send_to_vport_rule);
319 list_del(&esw_sq->list); 319 list_del(&esw_sq->list);
320 kfree(esw_sq); 320 kfree(esw_sq);
321 } 321 }
@@ -325,7 +325,7 @@ int mlx5_eswitch_sqs2vport_start(struct mlx5_eswitch *esw,
325 struct mlx5_eswitch_rep *rep, 325 struct mlx5_eswitch_rep *rep,
326 u16 *sqns_array, int sqns_num) 326 u16 *sqns_array, int sqns_num)
327{ 327{
328 struct mlx5_flow_rule *flow_rule; 328 struct mlx5_flow_handle *flow_rule;
329 struct mlx5_esw_sq *esw_sq; 329 struct mlx5_esw_sq *esw_sq;
330 int err; 330 int err;
331 int i; 331 int i;
@@ -362,7 +362,7 @@ out_err:
362static int esw_add_fdb_miss_rule(struct mlx5_eswitch *esw) 362static int esw_add_fdb_miss_rule(struct mlx5_eswitch *esw)
363{ 363{
364 struct mlx5_flow_destination dest; 364 struct mlx5_flow_destination dest;
365 struct mlx5_flow_rule *flow_rule = NULL; 365 struct mlx5_flow_handle *flow_rule = NULL;
366 struct mlx5_flow_spec *spec; 366 struct mlx5_flow_spec *spec;
367 int err = 0; 367 int err = 0;
368 368
@@ -376,9 +376,9 @@ static int esw_add_fdb_miss_rule(struct mlx5_eswitch *esw)
376 dest.type = MLX5_FLOW_DESTINATION_TYPE_VPORT; 376 dest.type = MLX5_FLOW_DESTINATION_TYPE_VPORT;
377 dest.vport_num = 0; 377 dest.vport_num = 0;
378 378
379 flow_rule = mlx5_add_flow_rule(esw->fdb_table.offloads.fdb, spec, 379 flow_rule = mlx5_add_flow_rules(esw->fdb_table.offloads.fdb, spec,
380 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST, 380 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST,
381 0, &dest); 381 0, &dest, 1);
382 if (IS_ERR(flow_rule)) { 382 if (IS_ERR(flow_rule)) {
383 err = PTR_ERR(flow_rule); 383 err = PTR_ERR(flow_rule);
384 esw_warn(esw->dev, "FDB: Failed to add miss flow rule err %d\n", err); 384 esw_warn(esw->dev, "FDB: Failed to add miss flow rule err %d\n", err);
@@ -501,7 +501,7 @@ static void esw_destroy_offloads_fdb_table(struct mlx5_eswitch *esw)
501 return; 501 return;
502 502
503 esw_debug(esw->dev, "Destroy offloads FDB Table\n"); 503 esw_debug(esw->dev, "Destroy offloads FDB Table\n");
504 mlx5_del_flow_rule(esw->fdb_table.offloads.miss_rule); 504 mlx5_del_flow_rules(esw->fdb_table.offloads.miss_rule);
505 mlx5_destroy_flow_group(esw->fdb_table.offloads.send_to_vport_grp); 505 mlx5_destroy_flow_group(esw->fdb_table.offloads.send_to_vport_grp);
506 mlx5_destroy_flow_group(esw->fdb_table.offloads.miss_grp); 506 mlx5_destroy_flow_group(esw->fdb_table.offloads.miss_grp);
507 507
@@ -585,11 +585,11 @@ static void esw_destroy_vport_rx_group(struct mlx5_eswitch *esw)
585 mlx5_destroy_flow_group(esw->offloads.vport_rx_group); 585 mlx5_destroy_flow_group(esw->offloads.vport_rx_group);
586} 586}
587 587
588struct mlx5_flow_rule * 588struct mlx5_flow_handle *
589mlx5_eswitch_create_vport_rx_rule(struct mlx5_eswitch *esw, int vport, u32 tirn) 589mlx5_eswitch_create_vport_rx_rule(struct mlx5_eswitch *esw, int vport, u32 tirn)
590{ 590{
591 struct mlx5_flow_destination dest; 591 struct mlx5_flow_destination dest;
592 struct mlx5_flow_rule *flow_rule; 592 struct mlx5_flow_handle *flow_rule;
593 struct mlx5_flow_spec *spec; 593 struct mlx5_flow_spec *spec;
594 void *misc; 594 void *misc;
595 595
@@ -610,9 +610,9 @@ mlx5_eswitch_create_vport_rx_rule(struct mlx5_eswitch *esw, int vport, u32 tirn)
610 dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR; 610 dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
611 dest.tir_num = tirn; 611 dest.tir_num = tirn;
612 612
613 flow_rule = mlx5_add_flow_rule(esw->offloads.ft_offloads, spec, 613 flow_rule = mlx5_add_flow_rules(esw->offloads.ft_offloads, spec,
614 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST, 614 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST,
615 0, &dest); 615 0, &dest, 1);
616 if (IS_ERR(flow_rule)) { 616 if (IS_ERR(flow_rule)) {
617 esw_warn(esw->dev, "fs offloads: Failed to add vport rx rule err %ld\n", PTR_ERR(flow_rule)); 617 esw_warn(esw->dev, "fs offloads: Failed to add vport rx rule err %ld\n", PTR_ERR(flow_rule));
618 goto out; 618 goto out;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
index 43d7052c76fc..6732287a98c8 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
@@ -155,6 +155,9 @@ static void del_flow_group(struct fs_node *node);
155static void del_fte(struct fs_node *node); 155static void del_fte(struct fs_node *node);
156static bool mlx5_flow_dests_cmp(struct mlx5_flow_destination *d1, 156static bool mlx5_flow_dests_cmp(struct mlx5_flow_destination *d1,
157 struct mlx5_flow_destination *d2); 157 struct mlx5_flow_destination *d2);
158static struct mlx5_flow_rule *
159find_flow_rule(struct fs_fte *fte,
160 struct mlx5_flow_destination *dest);
158 161
159static void tree_init_node(struct fs_node *node, 162static void tree_init_node(struct fs_node *node,
160 unsigned int refcount, 163 unsigned int refcount,
@@ -640,8 +643,8 @@ static int update_root_ft_create(struct mlx5_flow_table *ft, struct fs_prio
640 return err; 643 return err;
641} 644}
642 645
643int mlx5_modify_rule_destination(struct mlx5_flow_rule *rule, 646static int _mlx5_modify_rule_destination(struct mlx5_flow_rule *rule,
644 struct mlx5_flow_destination *dest) 647 struct mlx5_flow_destination *dest)
645{ 648{
646 struct mlx5_flow_table *ft; 649 struct mlx5_flow_table *ft;
647 struct mlx5_flow_group *fg; 650 struct mlx5_flow_group *fg;
@@ -666,6 +669,28 @@ int mlx5_modify_rule_destination(struct mlx5_flow_rule *rule,
666 return err; 669 return err;
667} 670}
668 671
672int mlx5_modify_rule_destination(struct mlx5_flow_handle *handle,
673 struct mlx5_flow_destination *new_dest,
674 struct mlx5_flow_destination *old_dest)
675{
676 int i;
677
678 if (!old_dest) {
679 if (handle->num_rules != 1)
680 return -EINVAL;
681 return _mlx5_modify_rule_destination(handle->rule[0],
682 new_dest);
683 }
684
685 for (i = 0; i < handle->num_rules; i++) {
686 if (mlx5_flow_dests_cmp(new_dest, &handle->rule[i]->dest_attr))
687 return _mlx5_modify_rule_destination(handle->rule[i],
688 new_dest);
689 }
690
691 return -EINVAL;
692}
693
669/* Modify/set FWD rules that point on old_next_ft to point on new_next_ft */ 694/* Modify/set FWD rules that point on old_next_ft to point on new_next_ft */
670static int connect_fwd_rules(struct mlx5_core_dev *dev, 695static int connect_fwd_rules(struct mlx5_core_dev *dev,
671 struct mlx5_flow_table *new_next_ft, 696 struct mlx5_flow_table *new_next_ft,
@@ -688,7 +713,7 @@ static int connect_fwd_rules(struct mlx5_core_dev *dev,
688 list_splice_init(&old_next_ft->fwd_rules, &new_next_ft->fwd_rules); 713 list_splice_init(&old_next_ft->fwd_rules, &new_next_ft->fwd_rules);
689 mutex_unlock(&old_next_ft->lock); 714 mutex_unlock(&old_next_ft->lock);
690 list_for_each_entry(iter, &new_next_ft->fwd_rules, next_ft) { 715 list_for_each_entry(iter, &new_next_ft->fwd_rules, next_ft) {
691 err = mlx5_modify_rule_destination(iter, &dest); 716 err = _mlx5_modify_rule_destination(iter, &dest);
692 if (err) 717 if (err)
693 pr_err("mlx5_core: failed to modify rule to point on flow table %d\n", 718 pr_err("mlx5_core: failed to modify rule to point on flow table %d\n",
694 new_next_ft->id); 719 new_next_ft->id);
@@ -917,41 +942,117 @@ static struct mlx5_flow_rule *alloc_rule(struct mlx5_flow_destination *dest)
917 return rule; 942 return rule;
918} 943}
919 944
920/* fte should not be deleted while calling this function */ 945static struct mlx5_flow_handle *alloc_handle(int num_rules)
921static struct mlx5_flow_rule *add_rule_fte(struct fs_fte *fte,
922 struct mlx5_flow_group *fg,
923 struct mlx5_flow_destination *dest,
924 bool update_action)
925{ 946{
947 struct mlx5_flow_handle *handle;
948
949 handle = kzalloc(sizeof(*handle) + sizeof(handle->rule[0]) *
950 num_rules, GFP_KERNEL);
951 if (!handle)
952 return NULL;
953
954 handle->num_rules = num_rules;
955
956 return handle;
957}
958
959static void destroy_flow_handle(struct fs_fte *fte,
960 struct mlx5_flow_handle *handle,
961 struct mlx5_flow_destination *dest,
962 int i)
963{
964 for (; --i >= 0;) {
965 if (atomic_dec_and_test(&handle->rule[i]->node.refcount)) {
966 fte->dests_size--;
967 list_del(&handle->rule[i]->node.list);
968 kfree(handle->rule[i]);
969 }
970 }
971 kfree(handle);
972}
973
974static struct mlx5_flow_handle *
975create_flow_handle(struct fs_fte *fte,
976 struct mlx5_flow_destination *dest,
977 int dest_num,
978 int *modify_mask,
979 bool *new_rule)
980{
981 struct mlx5_flow_handle *handle;
982 struct mlx5_flow_rule *rule = NULL;
983 static int count = BIT(MLX5_SET_FTE_MODIFY_ENABLE_MASK_FLOW_COUNTERS);
984 static int dst = BIT(MLX5_SET_FTE_MODIFY_ENABLE_MASK_DESTINATION_LIST);
985 int type;
986 int i = 0;
987
988 handle = alloc_handle((dest_num) ? dest_num : 1);
989 if (!handle)
990 return ERR_PTR(-ENOMEM);
991
992 do {
993 if (dest) {
994 rule = find_flow_rule(fte, dest + i);
995 if (rule) {
996 atomic_inc(&rule->node.refcount);
997 goto rule_found;
998 }
999 }
1000
1001 *new_rule = true;
1002 rule = alloc_rule(dest + i);
1003 if (!rule)
1004 goto free_rules;
1005
1006 /* Add dest to dests list- we need flow tables to be in the
1007 * end of the list for forward to next prio rules.
1008 */
1009 tree_init_node(&rule->node, 1, del_rule);
1010 if (dest &&
1011 dest[i].type != MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE)
1012 list_add(&rule->node.list, &fte->node.children);
1013 else
1014 list_add_tail(&rule->node.list, &fte->node.children);
1015 if (dest) {
1016 fte->dests_size++;
1017
1018 type = dest[i].type ==
1019 MLX5_FLOW_DESTINATION_TYPE_COUNTER;
1020 *modify_mask |= type ? count : dst;
1021 }
1022rule_found:
1023 handle->rule[i] = rule;
1024 } while (++i < dest_num);
1025
1026 return handle;
1027
1028free_rules:
1029 destroy_flow_handle(fte, handle, dest, i);
1030 return ERR_PTR(-ENOMEM);
1031}
1032
1033/* fte should not be deleted while calling this function */
1034static struct mlx5_flow_handle *
1035add_rule_fte(struct fs_fte *fte,
1036 struct mlx5_flow_group *fg,
1037 struct mlx5_flow_destination *dest,
1038 int dest_num,
1039 bool update_action)
1040{
1041 struct mlx5_flow_handle *handle;
926 struct mlx5_flow_table *ft; 1042 struct mlx5_flow_table *ft;
927 struct mlx5_flow_rule *rule;
928 int modify_mask = 0; 1043 int modify_mask = 0;
929 int err; 1044 int err;
1045 bool new_rule = false;
930 1046
931 rule = alloc_rule(dest); 1047 handle = create_flow_handle(fte, dest, dest_num, &modify_mask,
932 if (!rule) 1048 &new_rule);
933 return ERR_PTR(-ENOMEM); 1049 if (IS_ERR(handle) || !new_rule)
1050 goto out;
934 1051
935 if (update_action) 1052 if (update_action)
936 modify_mask |= BIT(MLX5_SET_FTE_MODIFY_ENABLE_MASK_ACTION); 1053 modify_mask |= BIT(MLX5_SET_FTE_MODIFY_ENABLE_MASK_ACTION);
937 1054
938 fs_get_obj(ft, fg->node.parent); 1055 fs_get_obj(ft, fg->node.parent);
939 /* Add dest to dests list- we need flow tables to be in the
940 * end of the list for forward to next prio rules.
941 */
942 tree_init_node(&rule->node, 1, del_rule);
943 if (dest && dest->type != MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE)
944 list_add(&rule->node.list, &fte->node.children);
945 else
946 list_add_tail(&rule->node.list, &fte->node.children);
947 if (dest) {
948 fte->dests_size++;
949
950 modify_mask |= dest->type == MLX5_FLOW_DESTINATION_TYPE_COUNTER ?
951 BIT(MLX5_SET_FTE_MODIFY_ENABLE_MASK_FLOW_COUNTERS) :
952 BIT(MLX5_SET_FTE_MODIFY_ENABLE_MASK_DESTINATION_LIST);
953 }
954
955 if (!(fte->status & FS_FTE_STATUS_EXISTING)) 1056 if (!(fte->status & FS_FTE_STATUS_EXISTING))
956 err = mlx5_cmd_create_fte(get_dev(&ft->node), 1057 err = mlx5_cmd_create_fte(get_dev(&ft->node),
957 ft, fg->id, fte); 1058 ft, fg->id, fte);
@@ -959,17 +1060,15 @@ static struct mlx5_flow_rule *add_rule_fte(struct fs_fte *fte,
959 err = mlx5_cmd_update_fte(get_dev(&ft->node), 1060 err = mlx5_cmd_update_fte(get_dev(&ft->node),
960 ft, fg->id, modify_mask, fte); 1061 ft, fg->id, modify_mask, fte);
961 if (err) 1062 if (err)
962 goto free_rule; 1063 goto free_handle;
963 1064
964 fte->status |= FS_FTE_STATUS_EXISTING; 1065 fte->status |= FS_FTE_STATUS_EXISTING;
965 1066
966 return rule; 1067out:
1068 return handle;
967 1069
968free_rule: 1070free_handle:
969 list_del(&rule->node.list); 1071 destroy_flow_handle(fte, handle, dest, handle->num_rules);
970 kfree(rule);
971 if (dest)
972 fte->dests_size--;
973 return ERR_PTR(err); 1072 return ERR_PTR(err);
974} 1073}
975 1074
@@ -1098,16 +1197,18 @@ static struct mlx5_flow_rule *find_flow_rule(struct fs_fte *fte,
1098 return NULL; 1197 return NULL;
1099} 1198}
1100 1199
1101static struct mlx5_flow_rule *add_rule_fg(struct mlx5_flow_group *fg, 1200static struct mlx5_flow_handle *add_rule_fg(struct mlx5_flow_group *fg,
1102 u32 *match_value, 1201 u32 *match_value,
1103 u8 action, 1202 u8 action,
1104 u32 flow_tag, 1203 u32 flow_tag,
1105 struct mlx5_flow_destination *dest) 1204 struct mlx5_flow_destination *dest,
1205 int dest_num)
1106{ 1206{
1107 struct fs_fte *fte; 1207 struct mlx5_flow_handle *handle;
1108 struct mlx5_flow_rule *rule;
1109 struct mlx5_flow_table *ft; 1208 struct mlx5_flow_table *ft;
1110 struct list_head *prev; 1209 struct list_head *prev;
1210 struct fs_fte *fte;
1211 int i;
1111 1212
1112 nested_lock_ref_node(&fg->node, FS_MUTEX_PARENT); 1213 nested_lock_ref_node(&fg->node, FS_MUTEX_PARENT);
1113 fs_for_each_fte(fte, fg) { 1214 fs_for_each_fte(fte, fg) {
@@ -1116,40 +1217,33 @@ static struct mlx5_flow_rule *add_rule_fg(struct mlx5_flow_group *fg,
1116 (action & fte->action) && flow_tag == fte->flow_tag) { 1217 (action & fte->action) && flow_tag == fte->flow_tag) {
1117 int old_action = fte->action; 1218 int old_action = fte->action;
1118 1219
1119 rule = find_flow_rule(fte, dest);
1120 if (rule) {
1121 atomic_inc(&rule->node.refcount);
1122 unlock_ref_node(&fte->node);
1123 unlock_ref_node(&fg->node);
1124 return rule;
1125 }
1126 fte->action |= action; 1220 fte->action |= action;
1127 rule = add_rule_fte(fte, fg, dest, 1221 handle = add_rule_fte(fte, fg, dest, dest_num,
1128 old_action != action); 1222 old_action != action);
1129 if (IS_ERR(rule)) { 1223 if (IS_ERR(handle)) {
1130 fte->action = old_action; 1224 fte->action = old_action;
1131 goto unlock_fte; 1225 goto unlock_fte;
1132 } else { 1226 } else {
1133 goto add_rule; 1227 goto add_rules;
1134 } 1228 }
1135 } 1229 }
1136 unlock_ref_node(&fte->node); 1230 unlock_ref_node(&fte->node);
1137 } 1231 }
1138 fs_get_obj(ft, fg->node.parent); 1232 fs_get_obj(ft, fg->node.parent);
1139 if (fg->num_ftes >= fg->max_ftes) { 1233 if (fg->num_ftes >= fg->max_ftes) {
1140 rule = ERR_PTR(-ENOSPC); 1234 handle = ERR_PTR(-ENOSPC);
1141 goto unlock_fg; 1235 goto unlock_fg;
1142 } 1236 }
1143 1237
1144 fte = create_fte(fg, match_value, action, flow_tag, &prev); 1238 fte = create_fte(fg, match_value, action, flow_tag, &prev);
1145 if (IS_ERR(fte)) { 1239 if (IS_ERR(fte)) {
1146 rule = (void *)fte; 1240 handle = (void *)fte;
1147 goto unlock_fg; 1241 goto unlock_fg;
1148 } 1242 }
1149 tree_init_node(&fte->node, 0, del_fte); 1243 tree_init_node(&fte->node, 0, del_fte);
1150 nested_lock_ref_node(&fte->node, FS_MUTEX_CHILD); 1244 nested_lock_ref_node(&fte->node, FS_MUTEX_CHILD);
1151 rule = add_rule_fte(fte, fg, dest, false); 1245 handle = add_rule_fte(fte, fg, dest, dest_num, false);
1152 if (IS_ERR(rule)) { 1246 if (IS_ERR(handle)) {
1153 kfree(fte); 1247 kfree(fte);
1154 goto unlock_fg; 1248 goto unlock_fg;
1155 } 1249 }
@@ -1158,21 +1252,24 @@ static struct mlx5_flow_rule *add_rule_fg(struct mlx5_flow_group *fg,
1158 1252
1159 tree_add_node(&fte->node, &fg->node); 1253 tree_add_node(&fte->node, &fg->node);
1160 list_add(&fte->node.list, prev); 1254 list_add(&fte->node.list, prev);
1161add_rule: 1255add_rules:
1162 tree_add_node(&rule->node, &fte->node); 1256 for (i = 0; i < handle->num_rules; i++) {
1257 if (atomic_read(&handle->rule[i]->node.refcount) == 1)
1258 tree_add_node(&handle->rule[i]->node, &fte->node);
1259 }
1163unlock_fte: 1260unlock_fte:
1164 unlock_ref_node(&fte->node); 1261 unlock_ref_node(&fte->node);
1165unlock_fg: 1262unlock_fg:
1166 unlock_ref_node(&fg->node); 1263 unlock_ref_node(&fg->node);
1167 return rule; 1264 return handle;
1168} 1265}
1169 1266
1170struct mlx5_fc *mlx5_flow_rule_counter(struct mlx5_flow_rule *rule) 1267struct mlx5_fc *mlx5_flow_rule_counter(struct mlx5_flow_handle *handle)
1171{ 1268{
1172 struct mlx5_flow_rule *dst; 1269 struct mlx5_flow_rule *dst;
1173 struct fs_fte *fte; 1270 struct fs_fte *fte;
1174 1271
1175 fs_get_obj(fte, rule->node.parent); 1272 fs_get_obj(fte, handle->rule[0]->node.parent);
1176 1273
1177 fs_for_each_dst(dst, fte) { 1274 fs_for_each_dst(dst, fte) {
1178 if (dst->dest_attr.type == MLX5_FLOW_DESTINATION_TYPE_COUNTER) 1275 if (dst->dest_attr.type == MLX5_FLOW_DESTINATION_TYPE_COUNTER)
@@ -1211,18 +1308,22 @@ static bool dest_is_valid(struct mlx5_flow_destination *dest,
1211 return true; 1308 return true;
1212} 1309}
1213 1310
1214static struct mlx5_flow_rule * 1311static struct mlx5_flow_handle *
1215_mlx5_add_flow_rule(struct mlx5_flow_table *ft, 1312_mlx5_add_flow_rules(struct mlx5_flow_table *ft,
1216 struct mlx5_flow_spec *spec, 1313 struct mlx5_flow_spec *spec,
1217 u32 action, 1314 u32 action,
1218 u32 flow_tag, 1315 u32 flow_tag,
1219 struct mlx5_flow_destination *dest) 1316 struct mlx5_flow_destination *dest,
1317 int dest_num)
1220{ 1318{
1221 struct mlx5_flow_group *g; 1319 struct mlx5_flow_group *g;
1222 struct mlx5_flow_rule *rule; 1320 struct mlx5_flow_handle *rule;
1321 int i;
1223 1322
1224 if (!dest_is_valid(dest, action, ft)) 1323 for (i = 0; i < dest_num; i++) {
1225 return ERR_PTR(-EINVAL); 1324 if (!dest_is_valid(&dest[i], action, ft))
1325 return ERR_PTR(-EINVAL);
1326 }
1226 1327
1227 nested_lock_ref_node(&ft->node, FS_MUTEX_GRANDPARENT); 1328 nested_lock_ref_node(&ft->node, FS_MUTEX_GRANDPARENT);
1228 fs_for_each_fg(g, ft) 1329 fs_for_each_fg(g, ft)
@@ -1231,7 +1332,7 @@ _mlx5_add_flow_rule(struct mlx5_flow_table *ft,
1231 g->mask.match_criteria, 1332 g->mask.match_criteria,
1232 spec->match_criteria)) { 1333 spec->match_criteria)) {
1233 rule = add_rule_fg(g, spec->match_value, 1334 rule = add_rule_fg(g, spec->match_value,
1234 action, flow_tag, dest); 1335 action, flow_tag, dest, dest_num);
1235 if (!IS_ERR(rule) || PTR_ERR(rule) != -ENOSPC) 1336 if (!IS_ERR(rule) || PTR_ERR(rule) != -ENOSPC)
1236 goto unlock; 1337 goto unlock;
1237 } 1338 }
@@ -1244,7 +1345,7 @@ _mlx5_add_flow_rule(struct mlx5_flow_table *ft,
1244 } 1345 }
1245 1346
1246 rule = add_rule_fg(g, spec->match_value, 1347 rule = add_rule_fg(g, spec->match_value,
1247 action, flow_tag, dest); 1348 action, flow_tag, dest, dest_num);
1248 if (IS_ERR(rule)) { 1349 if (IS_ERR(rule)) {
1249 /* Remove assumes refcount > 0 and autogroup creates a group 1350 /* Remove assumes refcount > 0 and autogroup creates a group
1250 * with a refcount = 0. 1351 * with a refcount = 0.
@@ -1265,17 +1366,18 @@ static bool fwd_next_prio_supported(struct mlx5_flow_table *ft)
1265 (MLX5_CAP_FLOWTABLE(get_dev(&ft->node), nic_rx_multi_path_tirs))); 1366 (MLX5_CAP_FLOWTABLE(get_dev(&ft->node), nic_rx_multi_path_tirs)));
1266} 1367}
1267 1368
1268struct mlx5_flow_rule * 1369struct mlx5_flow_handle *
1269mlx5_add_flow_rule(struct mlx5_flow_table *ft, 1370mlx5_add_flow_rules(struct mlx5_flow_table *ft,
1270 struct mlx5_flow_spec *spec, 1371 struct mlx5_flow_spec *spec,
1271 u32 action, 1372 u32 action,
1272 u32 flow_tag, 1373 u32 flow_tag,
1273 struct mlx5_flow_destination *dest) 1374 struct mlx5_flow_destination *dest,
1375 int dest_num)
1274{ 1376{
1275 struct mlx5_flow_root_namespace *root = find_root(&ft->node); 1377 struct mlx5_flow_root_namespace *root = find_root(&ft->node);
1276 struct mlx5_flow_destination gen_dest; 1378 struct mlx5_flow_destination gen_dest;
1277 struct mlx5_flow_table *next_ft = NULL; 1379 struct mlx5_flow_table *next_ft = NULL;
1278 struct mlx5_flow_rule *rule = NULL; 1380 struct mlx5_flow_handle *handle = NULL;
1279 u32 sw_action = action; 1381 u32 sw_action = action;
1280 struct fs_prio *prio; 1382 struct fs_prio *prio;
1281 1383
@@ -1291,6 +1393,7 @@ mlx5_add_flow_rule(struct mlx5_flow_table *ft,
1291 gen_dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; 1393 gen_dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
1292 gen_dest.ft = next_ft; 1394 gen_dest.ft = next_ft;
1293 dest = &gen_dest; 1395 dest = &gen_dest;
1396 dest_num = 1;
1294 action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST; 1397 action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
1295 } else { 1398 } else {
1296 mutex_unlock(&root->chain_lock); 1399 mutex_unlock(&root->chain_lock);
@@ -1298,27 +1401,33 @@ mlx5_add_flow_rule(struct mlx5_flow_table *ft,
1298 } 1401 }
1299 } 1402 }
1300 1403
1301 rule = _mlx5_add_flow_rule(ft, spec, action, flow_tag, dest); 1404 handle = _mlx5_add_flow_rules(ft, spec, action, flow_tag, dest,
1405 dest_num);
1302 1406
1303 if (sw_action == MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO) { 1407 if (sw_action == MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO) {
1304 if (!IS_ERR_OR_NULL(rule) && 1408 if (!IS_ERR_OR_NULL(handle) &&
1305 (list_empty(&rule->next_ft))) { 1409 (list_empty(&handle->rule[0]->next_ft))) {
1306 mutex_lock(&next_ft->lock); 1410 mutex_lock(&next_ft->lock);
1307 list_add(&rule->next_ft, &next_ft->fwd_rules); 1411 list_add(&handle->rule[0]->next_ft,
1412 &next_ft->fwd_rules);
1308 mutex_unlock(&next_ft->lock); 1413 mutex_unlock(&next_ft->lock);
1309 rule->sw_action = MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO; 1414 handle->rule[0]->sw_action = MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO;
1310 } 1415 }
1311 mutex_unlock(&root->chain_lock); 1416 mutex_unlock(&root->chain_lock);
1312 } 1417 }
1313 return rule; 1418 return handle;
1314} 1419}
1315EXPORT_SYMBOL(mlx5_add_flow_rule); 1420EXPORT_SYMBOL(mlx5_add_flow_rules);
1316 1421
1317void mlx5_del_flow_rule(struct mlx5_flow_rule *rule) 1422void mlx5_del_flow_rules(struct mlx5_flow_handle *handle)
1318{ 1423{
1319 tree_remove_node(&rule->node); 1424 int i;
1425
1426 for (i = handle->num_rules - 1; i >= 0; i--)
1427 tree_remove_node(&handle->rule[i]->node);
1428 kfree(handle);
1320} 1429}
1321EXPORT_SYMBOL(mlx5_del_flow_rule); 1430EXPORT_SYMBOL(mlx5_del_flow_rules);
1322 1431
1323/* Assuming prio->node.children(flow tables) is sorted by level */ 1432/* Assuming prio->node.children(flow tables) is sorted by level */
1324static struct mlx5_flow_table *find_next_ft(struct mlx5_flow_table *ft) 1433static struct mlx5_flow_table *find_next_ft(struct mlx5_flow_table *ft)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h
index 71ff03bceabb..d5150888645c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h
@@ -94,6 +94,11 @@ struct mlx5_flow_rule {
94 u32 sw_action; 94 u32 sw_action;
95}; 95};
96 96
97struct mlx5_flow_handle {
98 int num_rules;
99 struct mlx5_flow_rule *rule[];
100};
101
97/* Type of children is mlx5_flow_group */ 102/* Type of children is mlx5_flow_group */
98struct mlx5_flow_table { 103struct mlx5_flow_table {
99 struct fs_node node; 104 struct fs_node node;
diff --git a/include/linux/mlx5/fs.h b/include/linux/mlx5/fs.h
index 93ebc5e21334..0dcd287f4bd0 100644
--- a/include/linux/mlx5/fs.h
+++ b/include/linux/mlx5/fs.h
@@ -69,8 +69,8 @@ enum mlx5_flow_namespace_type {
69 69
70struct mlx5_flow_table; 70struct mlx5_flow_table;
71struct mlx5_flow_group; 71struct mlx5_flow_group;
72struct mlx5_flow_rule;
73struct mlx5_flow_namespace; 72struct mlx5_flow_namespace;
73struct mlx5_flow_handle;
74 74
75struct mlx5_flow_spec { 75struct mlx5_flow_spec {
76 u8 match_criteria_enable; 76 u8 match_criteria_enable;
@@ -127,18 +127,20 @@ void mlx5_destroy_flow_group(struct mlx5_flow_group *fg);
127/* Single destination per rule. 127/* Single destination per rule.
128 * Group ID is implied by the match criteria. 128 * Group ID is implied by the match criteria.
129 */ 129 */
130struct mlx5_flow_rule * 130struct mlx5_flow_handle *
131mlx5_add_flow_rule(struct mlx5_flow_table *ft, 131mlx5_add_flow_rules(struct mlx5_flow_table *ft,
132 struct mlx5_flow_spec *spec, 132 struct mlx5_flow_spec *spec,
133 u32 action, 133 u32 action,
134 u32 flow_tag, 134 u32 flow_tag,
135 struct mlx5_flow_destination *dest); 135 struct mlx5_flow_destination *dest,
136void mlx5_del_flow_rule(struct mlx5_flow_rule *fr); 136 int dest_num);
137 137void mlx5_del_flow_rules(struct mlx5_flow_handle *fr);
138int mlx5_modify_rule_destination(struct mlx5_flow_rule *rule, 138
139 struct mlx5_flow_destination *dest); 139int mlx5_modify_rule_destination(struct mlx5_flow_handle *handler,
140 140 struct mlx5_flow_destination *new_dest,
141struct mlx5_fc *mlx5_flow_rule_counter(struct mlx5_flow_rule *rule); 141 struct mlx5_flow_destination *old_dest);
142
143struct mlx5_fc *mlx5_flow_rule_counter(struct mlx5_flow_handle *handler);
142struct mlx5_fc *mlx5_fc_create(struct mlx5_core_dev *dev, bool aging); 144struct mlx5_fc *mlx5_fc_create(struct mlx5_core_dev *dev, bool aging);
143void mlx5_fc_destroy(struct mlx5_core_dev *dev, struct mlx5_fc *counter); 145void mlx5_fc_destroy(struct mlx5_core_dev *dev, struct mlx5_fc *counter);
144void mlx5_fc_query_cached(struct mlx5_fc *counter, 146void mlx5_fc_query_cached(struct mlx5_fc *counter,