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(-)
@@ -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;
@@ -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,
};