From: Ian Stokes <ian.sto...@intel.com>

Currently for unicast promiscuous, the driver is adding a LOOKUP_RX filter rule
using recipe 3. The direction bit in this recipe is the pkt_is_from_network
flag, so the filter only matches on packets from the network, not loopback
packets. To match loopback packets without replicating all Tx packets, LOOKUP_TX
(where source is the VSI) filter with LB_EN bit set to 0 is needed. This would
be equivalent to the rx-only promiscuous mode used in E700 cards.

Extended promiscuous mask by additional UCAST_RX_LB entry, added another flag
pointing to RX_LB to distinguish filter from the TX, aligned unittests.

Signed-off-by: Mateusz Pacuszka <mateuszx.pacus...@intel.com>
Signed-off-by: Ian Stokes <ian.sto...@intel.com>
---
 drivers/net/ice/base/ice_switch.c | 30 ++++++++++++++++++++++++++----
 drivers/net/ice/base/ice_switch.h |  7 +++++--
 2 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ice/base/ice_switch.c 
b/drivers/net/ice/base/ice_switch.c
index 9cb5b67699..1a851e4d0e 100644
--- a/drivers/net/ice/base/ice_switch.c
+++ b/drivers/net/ice/base/ice_switch.c
@@ -3966,6 +3966,13 @@ static void ice_fill_sw_info(struct ice_hw *hw, struct 
ice_fltr_info *fi)
                        fi->lan_en = true;
                }
        }
+       /* To be able to receive packets coming from the VF on the same PF,
+        * unicast filter needs to be added without LB_EN bit
+        */
+       if (fi->flag & ICE_FLTR_RX_LB) {
+               fi->lb_en = false;
+               fi->lan_en = true;
+       }
 }
 
 /**
@@ -4796,7 +4803,7 @@ ice_add_rule_internal(struct ice_hw *hw, struct 
ice_sw_recipe *recp_list,
        new_fltr = &f_entry->fltr_info;
        if (new_fltr->flag & ICE_FLTR_RX)
                new_fltr->src = lport;
-       else if (new_fltr->flag & ICE_FLTR_TX)
+       else if (new_fltr->flag & (ICE_FLTR_TX | ICE_FLTR_RX_LB))
                new_fltr->src =
                        ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
 
@@ -6162,12 +6169,15 @@ static void ice_determine_promisc_mask(struct 
ice_fltr_info *fi,
 {
        u16 vid = fi->l_data.mac_vlan.vlan_id;
        u8 *macaddr = fi->l_data.mac.mac_addr;
+       bool is_rx_lb_fltr = false;
        bool is_tx_fltr = false;
 
        ice_zero_bitmap(promisc_mask, ICE_PROMISC_MAX);
 
        if (fi->flag == ICE_FLTR_TX)
                is_tx_fltr = true;
+       if (fi->flag == ICE_FLTR_RX_LB)
+               is_rx_lb_fltr = true;
 
        if (IS_BROADCAST_ETHER_ADDR(macaddr)) {
                ice_set_bit(is_tx_fltr ? ICE_PROMISC_BCAST_TX
@@ -6176,8 +6186,12 @@ static void ice_determine_promisc_mask(struct 
ice_fltr_info *fi,
                ice_set_bit(is_tx_fltr ? ICE_PROMISC_MCAST_TX
                                       : ICE_PROMISC_MCAST_RX, promisc_mask);
        } else if (IS_UNICAST_ETHER_ADDR(macaddr)) {
-               ice_set_bit(is_tx_fltr ? ICE_PROMISC_UCAST_TX
-                                      : ICE_PROMISC_UCAST_RX, promisc_mask);
+               if (is_tx_fltr)
+                       ice_set_bit(ICE_PROMISC_UCAST_TX, promisc_mask);
+               else if (is_rx_lb_fltr)
+                       ice_set_bit(ICE_PROMISC_UCAST_RX_LB, promisc_mask);
+               else
+                       ice_set_bit(ICE_PROMISC_UCAST_RX, promisc_mask);
        }
 
        if (vid) {
@@ -6407,7 +6421,7 @@ _ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle,
        enum { UCAST_FLTR = 1, MCAST_FLTR, BCAST_FLTR };
        ice_declare_bitmap(p_mask, ICE_PROMISC_MAX);
        struct ice_fltr_list_entry f_list_entry;
-       bool is_tx_fltr;
+       bool is_tx_fltr, is_rx_lb_fltr;
        struct ice_fltr_info new_fltr;
        int status = 0;
        u16 hw_vsi_id;
@@ -6446,6 +6460,7 @@ _ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle,
 
                pkt_type = 0;
                is_tx_fltr = false;
+               is_rx_lb_fltr = false;
 
                if (ice_test_and_clear_bit(ICE_PROMISC_UCAST_RX,
                                           p_mask)) {
@@ -6468,6 +6483,10 @@ _ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle,
                                                  p_mask)) {
                        pkt_type = BCAST_FLTR;
                        is_tx_fltr = true;
+               } else if (ice_test_and_clear_bit(ICE_PROMISC_UCAST_RX_LB,
+                                                 p_mask)) {
+                       pkt_type = UCAST_FLTR;
+                       is_rx_lb_fltr = true;
                }
 
                /* Check for VLAN promiscuous flag */
@@ -6495,6 +6514,9 @@ _ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle,
                if (is_tx_fltr) {
                        new_fltr.flag |= ICE_FLTR_TX;
                        new_fltr.src = hw_vsi_id;
+               } else if (is_rx_lb_fltr) {
+                       new_fltr.flag |= ICE_FLTR_RX_LB;
+                       new_fltr.src = hw_vsi_id;
                } else {
                        new_fltr.flag |= ICE_FLTR_RX;
                        new_fltr.src = lport;
diff --git a/drivers/net/ice/base/ice_switch.h 
b/drivers/net/ice/base/ice_switch.h
index 473784dc30..184e30f226 100644
--- a/drivers/net/ice/base/ice_switch.h
+++ b/drivers/net/ice/base/ice_switch.h
@@ -11,8 +11,10 @@
 #define ICE_SW_CFG_MAX_BUF_LEN 2048
 #define ICE_MAX_SW 256
 #define ICE_DFLT_VSI_INVAL 0xff
-#define ICE_FLTR_RX BIT(0)
-#define ICE_FLTR_TX BIT(1)
+
+#define ICE_FLTR_RX    BIT(0)
+#define ICE_FLTR_TX    BIT(1)
+#define ICE_FLTR_RX_LB BIT(2)
 #define ICE_FLTR_TX_RX (ICE_FLTR_RX | ICE_FLTR_TX)
 
 /* Switch Profile IDs for Profile related switch rules */
@@ -426,6 +428,7 @@ enum ice_promisc_flags {
        ICE_PROMISC_BCAST_TX,
        ICE_PROMISC_VLAN_RX,
        ICE_PROMISC_VLAN_TX,
+       ICE_PROMISC_UCAST_RX_LB,
        /* Max value */
        ICE_PROMISC_MAX,
 };
-- 
2.43.0

Reply via email to