|
8 | 8 | #include "ice_fltr.h" |
9 | 9 | #include "ice_dcb_lib.h" |
10 | 10 | #include "ice_devlink.h" |
| 11 | +#include "ice_vsi_vlan_ops.h" |
11 | 12 |
|
12 | 13 | /** |
13 | 14 | * 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, |
2458 | 2459 | if (ret) |
2459 | 2460 | goto unroll_vector_base; |
2460 | 2461 |
|
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 | | - |
2472 | 2462 | ice_vsi_map_rings_to_vectors(vsi); |
2473 | 2463 |
|
2474 | 2464 | /* 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) |
3918 | 3908 | /** |
3919 | 3909 | * ice_vsi_add_vlan_zero - add VLAN 0 filter(s) for this VSI |
3920 | 3910 | * @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. |
3921 | 3924 | */ |
3922 | 3925 | int ice_vsi_add_vlan_zero(struct ice_vsi *vsi) |
3923 | 3926 | { |
| 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); |
3924 | 3958 | struct ice_vlan vlan; |
| 3959 | + int err; |
3925 | 3960 |
|
3926 | 3961 | 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)); |
3928 | 4015 | } |
3929 | 4016 |
|
3930 | 4017 | /** |
|
0 commit comments