Skip to content

Commit c31af68

Browse files
bcreeley13anguy11
authored andcommitted
ice: Add outer_vlan_ops and VSI specific VLAN ops implementations
Add a new outer_vlan_ops member to the ice_vsi structure as outer VLAN ops are only available when the device is in Double VLAN Mode (DVM). Depending on the VSI type, the requirements for what operations to use/allow differ. By default all VSI's have unsupported inner and outer VSI VLAN ops. This implementation was chosen to prevent unexpected crashes due to null pointer dereferences. Instead, if a VSI calls an unsupported op, it will just return -EOPNOTSUPP. Add implementations to support modifying outer VLAN fields for VSI context. This includes the ability to modify VLAN stripping, insertion, and the port VLAN based on the outer VLAN handling fields of the VSI context. These functions should only ever be used if DVM is enabled because that means the firmware supports the outer VLAN fields in the VSI context. If the device is in DVM, then always use the outer_vlan_ops, else use the vlan_ops since the device is in Single VLAN Mode (SVM). Also, move adding the untagged VLAN 0 filter from ice_vsi_setup() to ice_vsi_vlan_setup() as the latter function is specific to the PF and all other VSI types that need an untagged VLAN 0 filter already do this in their specific flows. Without this change, Flow Director is failing to initialize because it does not implement any VSI VLAN ops. Signed-off-by: Brett Creeley <[email protected]> Tested-by: Gurucharan G <[email protected]> Signed-off-by: Tony Nguyen <[email protected]>
1 parent 7bd527a commit c31af68

16 files changed

+813
-86
lines changed

drivers/net/ethernet/intel/ice/Makefile

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ ice-y := ice_main.o \
1818
ice_txrx_lib.o \
1919
ice_txrx.o \
2020
ice_fltr.o \
21+
ice_pf_vsi_vlan_ops.o \
2122
ice_vsi_vlan_ops.o \
2223
ice_vsi_vlan_lib.o \
2324
ice_fdir.o \
@@ -31,8 +32,12 @@ ice-y := ice_main.o \
3132
ice_ethtool.o \
3233
ice_repr.o \
3334
ice_tc_lib.o
34-
ice-$(CONFIG_PCI_IOV) += ice_virtchnl_allowlist.o
35-
ice-$(CONFIG_PCI_IOV) += ice_virtchnl_pf.o ice_sriov.o ice_virtchnl_fdir.o
35+
ice-$(CONFIG_PCI_IOV) += \
36+
ice_virtchnl_allowlist.o \
37+
ice_virtchnl_fdir.o \
38+
ice_sriov.o \
39+
ice_vf_vsi_vlan_ops.o \
40+
ice_virtchnl_pf.o
3641
ice-$(CONFIG_PTP_1588_CLOCK) += ice_ptp.o ice_ptp_hw.o
3742
ice-$(CONFIG_DCB) += ice_dcb.o ice_dcb_nl.o ice_dcb_lib.o
3843
ice-$(CONFIG_RFS_ACCEL) += ice_arfs.o

drivers/net/ethernet/intel/ice/ice.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,8 @@ struct ice_vsi {
369369
u8 irqs_ready:1;
370370
u8 current_isup:1; /* Sync 'link up' logging */
371371
u8 stat_offsets_loaded:1;
372-
struct ice_vsi_vlan_ops vlan_ops;
372+
struct ice_vsi_vlan_ops inner_vlan_ops;
373+
struct ice_vsi_vlan_ops outer_vlan_ops;
373374
u16 num_vlan;
374375

375376
/* queue information */

drivers/net/ethernet/intel/ice/ice_eswitch.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,12 @@ static int ice_eswitch_setup_env(struct ice_pf *pf)
115115
struct ice_vsi *uplink_vsi = pf->switchdev.uplink_vsi;
116116
struct net_device *uplink_netdev = uplink_vsi->netdev;
117117
struct ice_vsi *ctrl_vsi = pf->switchdev.control_vsi;
118+
struct ice_vsi_vlan_ops *vlan_ops;
118119
bool rule_added = false;
119120

120-
ctrl_vsi->vlan_ops.dis_stripping(ctrl_vsi);
121+
vlan_ops = ice_get_compat_vsi_vlan_ops(ctrl_vsi);
122+
if (vlan_ops->dis_stripping(ctrl_vsi))
123+
return -ENODEV;
121124

122125
ice_remove_vsi_fltr(&pf->hw, uplink_vsi->idx);
123126

drivers/net/ethernet/intel/ice/ice_lib.c

Lines changed: 99 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "ice_fltr.h"
99
#include "ice_dcb_lib.h"
1010
#include "ice_devlink.h"
11+
#include "ice_vsi_vlan_ops.h"
1112

1213
/**
1314
* ice_vsi_type_str - maps VSI type enum to string equivalents
@@ -2458,17 +2459,6 @@ ice_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi,
24582459
if (ret)
24592460
goto unroll_vector_base;
24602461

2461-
/* Always add VLAN ID 0 switch rule by default. This is needed
2462-
* in order to allow all untagged and 0 tagged priority traffic
2463-
* if Rx VLAN pruning is enabled. Also there are cases where we
2464-
* don't get the call to add VLAN 0 via ice_vlan_rx_add_vid()
2465-
* so this handles those cases (i.e. adding the PF to a bridge
2466-
* without the 8021q module loaded).
2467-
*/
2468-
ret = ice_vsi_add_vlan_zero(vsi);
2469-
if (ret)
2470-
goto unroll_clear_rings;
2471-
24722462
ice_vsi_map_rings_to_vectors(vsi);
24732463

24742464
/* ICE_VSI_CTRL does not need RSS so skip RSS processing */
@@ -3918,13 +3908,110 @@ int ice_set_link(struct ice_vsi *vsi, bool ena)
39183908
/**
39193909
* ice_vsi_add_vlan_zero - add VLAN 0 filter(s) for this VSI
39203910
* @vsi: VSI used to add VLAN filters
3911+
*
3912+
* In Single VLAN Mode (SVM), single VLAN filters via ICE_SW_LKUP_VLAN are based
3913+
* on the inner VLAN ID, so the VLAN TPID (i.e. 0x8100 or 0x888a8) doesn't
3914+
* matter. In Double VLAN Mode (DVM), outer/single VLAN filters via
3915+
* ICE_SW_LKUP_VLAN are based on the outer/single VLAN ID + VLAN TPID.
3916+
*
3917+
* For both modes add a VLAN 0 + no VLAN TPID filter to handle untagged traffic
3918+
* when VLAN pruning is enabled. Also, this handles VLAN 0 priority tagged
3919+
* traffic in SVM, since the VLAN TPID isn't part of filtering.
3920+
*
3921+
* If DVM is enabled then an explicit VLAN 0 + VLAN TPID filter needs to be
3922+
* added to allow VLAN 0 priority tagged traffic in DVM, since the VLAN TPID is
3923+
* part of filtering.
39213924
*/
39223925
int ice_vsi_add_vlan_zero(struct ice_vsi *vsi)
39233926
{
3927+
struct ice_vsi_vlan_ops *vlan_ops = ice_get_compat_vsi_vlan_ops(vsi);
3928+
struct ice_vlan vlan;
3929+
int err;
3930+
3931+
vlan = ICE_VLAN(0, 0, 0);
3932+
err = vlan_ops->add_vlan(vsi, &vlan);
3933+
if (err && err != -EEXIST)
3934+
return err;
3935+
3936+
/* in SVM both VLAN 0 filters are identical */
3937+
if (!ice_is_dvm_ena(&vsi->back->hw))
3938+
return 0;
3939+
3940+
vlan = ICE_VLAN(ETH_P_8021Q, 0, 0);
3941+
err = vlan_ops->add_vlan(vsi, &vlan);
3942+
if (err && err != -EEXIST)
3943+
return err;
3944+
3945+
return 0;
3946+
}
3947+
3948+
/**
3949+
* ice_vsi_del_vlan_zero - delete VLAN 0 filter(s) for this VSI
3950+
* @vsi: VSI used to add VLAN filters
3951+
*
3952+
* Delete the VLAN 0 filters in the same manner that they were added in
3953+
* ice_vsi_add_vlan_zero.
3954+
*/
3955+
int ice_vsi_del_vlan_zero(struct ice_vsi *vsi)
3956+
{
3957+
struct ice_vsi_vlan_ops *vlan_ops = ice_get_compat_vsi_vlan_ops(vsi);
39243958
struct ice_vlan vlan;
3959+
int err;
39253960

39263961
vlan = ICE_VLAN(0, 0, 0);
3927-
return vsi->vlan_ops.add_vlan(vsi, &vlan);
3962+
err = vlan_ops->del_vlan(vsi, &vlan);
3963+
if (err && err != -EEXIST)
3964+
return err;
3965+
3966+
/* in SVM both VLAN 0 filters are identical */
3967+
if (!ice_is_dvm_ena(&vsi->back->hw))
3968+
return 0;
3969+
3970+
vlan = ICE_VLAN(ETH_P_8021Q, 0, 0);
3971+
err = vlan_ops->del_vlan(vsi, &vlan);
3972+
if (err && err != -EEXIST)
3973+
return err;
3974+
3975+
return 0;
3976+
}
3977+
3978+
/**
3979+
* ice_vsi_num_zero_vlans - get number of VLAN 0 filters based on VLAN mode
3980+
* @vsi: VSI used to get the VLAN mode
3981+
*
3982+
* If DVM is enabled then 2 VLAN 0 filters are added, else if SVM is enabled
3983+
* then 1 VLAN 0 filter is added. See ice_vsi_add_vlan_zero for more details.
3984+
*/
3985+
static u16 ice_vsi_num_zero_vlans(struct ice_vsi *vsi)
3986+
{
3987+
#define ICE_DVM_NUM_ZERO_VLAN_FLTRS 2
3988+
#define ICE_SVM_NUM_ZERO_VLAN_FLTRS 1
3989+
/* no VLAN 0 filter is created when a port VLAN is active */
3990+
if (vsi->type == ICE_VSI_VF &&
3991+
ice_vf_is_port_vlan_ena(&vsi->back->vf[vsi->vf_id]))
3992+
return 0;
3993+
if (ice_is_dvm_ena(&vsi->back->hw))
3994+
return ICE_DVM_NUM_ZERO_VLAN_FLTRS;
3995+
else
3996+
return ICE_SVM_NUM_ZERO_VLAN_FLTRS;
3997+
}
3998+
3999+
/**
4000+
* ice_vsi_has_non_zero_vlans - check if VSI has any non-zero VLANs
4001+
* @vsi: VSI used to determine if any non-zero VLANs have been added
4002+
*/
4003+
bool ice_vsi_has_non_zero_vlans(struct ice_vsi *vsi)
4004+
{
4005+
return (vsi->num_vlan > ice_vsi_num_zero_vlans(vsi));
4006+
}
4007+
4008+
/**
4009+
* ice_vsi_num_non_zero_vlans - get the number of non-zero VLANs for this VSI
4010+
* @vsi: VSI used to get the number of non-zero VLANs added
4011+
*/
4012+
u16 ice_vsi_num_non_zero_vlans(struct ice_vsi *vsi)
4013+
{
4014+
return (vsi->num_vlan - ice_vsi_num_zero_vlans(vsi));
39284015
}
39294016

39304017
/**

drivers/net/ethernet/intel/ice/ice_lib.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ void ice_vsi_ctx_set_allow_override(struct ice_vsi_ctx *ctx);
123123

124124
void ice_vsi_ctx_clear_allow_override(struct ice_vsi_ctx *ctx);
125125
int ice_vsi_add_vlan_zero(struct ice_vsi *vsi);
126+
int ice_vsi_del_vlan_zero(struct ice_vsi *vsi);
127+
bool ice_vsi_has_non_zero_vlans(struct ice_vsi *vsi);
128+
u16 ice_vsi_num_non_zero_vlans(struct ice_vsi *vsi);
126129
bool ice_is_feature_supported(struct ice_pf *pf, enum ice_feature f);
127130
void ice_clear_feature_support(struct ice_pf *pf, enum ice_feature f);
128131
void ice_init_feature_support(struct ice_pf *pf);

0 commit comments

Comments
 (0)