[v2,027/148] net/ice/base: fix rx-only unicast promiscuous mode

Message ID c295509b9cc80b86242bfcd361eb04c6817eb343.1718204528.git.anatoly.burakov@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Bruce Richardson
Headers
Series Update net/ice base driver to latest upstream snapshot |

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

Burakov, Anatoly June 12, 2024, 3 p.m. UTC
From: Ian Stokes <ian.stokes@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.pacuszka@intel.com>
Signed-off-by: Ian Stokes <ian.stokes@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(-)
  

Patch

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,
 };