1c31af68aSBrett Creeley // SPDX-License-Identifier: GPL-2.0 2c31af68aSBrett Creeley /* Copyright (C) 2019-2021, Intel Corporation. */ 3c31af68aSBrett Creeley 4c31af68aSBrett Creeley #include "ice_vsi_vlan_ops.h" 5c31af68aSBrett Creeley #include "ice_vsi_vlan_lib.h" 6a1ffafb0SBrett Creeley #include "ice_vlan_mode.h" 7c31af68aSBrett Creeley #include "ice.h" 8c31af68aSBrett Creeley #include "ice_vf_vsi_vlan_ops.h" 9c31af68aSBrett Creeley #include "ice_virtchnl_pf.h" 10c31af68aSBrett Creeley 11c31af68aSBrett Creeley static int 12c31af68aSBrett Creeley noop_vlan_arg(struct ice_vsi __always_unused *vsi, 13c31af68aSBrett Creeley struct ice_vlan __always_unused *vlan) 14c31af68aSBrett Creeley { 15c31af68aSBrett Creeley return 0; 16c31af68aSBrett Creeley } 17c31af68aSBrett Creeley 18cc71de8fSBrett Creeley static int 19cc71de8fSBrett Creeley noop_vlan(struct ice_vsi __always_unused *vsi) 20cc71de8fSBrett Creeley { 21cc71de8fSBrett Creeley return 0; 22cc71de8fSBrett Creeley } 23cc71de8fSBrett Creeley 24c31af68aSBrett Creeley /** 25c31af68aSBrett Creeley * ice_vf_vsi_init_vlan_ops - Initialize default VSI VLAN ops for VF VSI 26c31af68aSBrett Creeley * @vsi: VF's VSI being configured 27cc71de8fSBrett Creeley * 28cc71de8fSBrett Creeley * If Double VLAN Mode (DVM) is enabled, assume that the VF supports the new 29cc71de8fSBrett Creeley * VIRTCHNL_VF_VLAN_OFFLOAD_V2 capability and set up the VLAN ops accordingly. 30cc71de8fSBrett Creeley * If SVM is enabled maintain the same level of VLAN support previous to 31cc71de8fSBrett Creeley * VIRTCHNL_VF_VLAN_OFFLOAD_V2. 32c31af68aSBrett Creeley */ 33c31af68aSBrett Creeley void ice_vf_vsi_init_vlan_ops(struct ice_vsi *vsi) 34c31af68aSBrett Creeley { 35c31af68aSBrett Creeley struct ice_vsi_vlan_ops *vlan_ops; 36c31af68aSBrett Creeley struct ice_pf *pf = vsi->back; 37c31af68aSBrett Creeley struct ice_vf *vf; 38c31af68aSBrett Creeley 39c31af68aSBrett Creeley vf = &pf->vf[vsi->vf_id]; 40c31af68aSBrett Creeley 41c31af68aSBrett Creeley if (ice_is_dvm_ena(&pf->hw)) { 42c31af68aSBrett Creeley vlan_ops = &vsi->outer_vlan_ops; 43c31af68aSBrett Creeley 44c31af68aSBrett Creeley /* outer VLAN ops regardless of port VLAN config */ 45c31af68aSBrett Creeley vlan_ops->add_vlan = ice_vsi_add_vlan; 46c31af68aSBrett Creeley vlan_ops->dis_rx_filtering = ice_vsi_dis_rx_vlan_filtering; 47c31af68aSBrett Creeley vlan_ops->ena_tx_filtering = ice_vsi_ena_tx_vlan_filtering; 48c31af68aSBrett Creeley vlan_ops->dis_tx_filtering = ice_vsi_dis_tx_vlan_filtering; 49c31af68aSBrett Creeley 50c31af68aSBrett Creeley if (ice_vf_is_port_vlan_ena(vf)) { 51c31af68aSBrett Creeley /* setup outer VLAN ops */ 52c31af68aSBrett Creeley vlan_ops->set_port_vlan = ice_vsi_set_outer_port_vlan; 53*f1da5a08SBrett Creeley vlan_ops->ena_rx_filtering = 54*f1da5a08SBrett Creeley ice_vsi_ena_rx_vlan_filtering; 55c31af68aSBrett Creeley 56c31af68aSBrett Creeley /* setup inner VLAN ops */ 57c31af68aSBrett Creeley vlan_ops = &vsi->inner_vlan_ops; 58c31af68aSBrett Creeley vlan_ops->add_vlan = noop_vlan_arg; 59c31af68aSBrett Creeley vlan_ops->del_vlan = noop_vlan_arg; 60c31af68aSBrett Creeley vlan_ops->ena_stripping = ice_vsi_ena_inner_stripping; 61c31af68aSBrett Creeley vlan_ops->dis_stripping = ice_vsi_dis_inner_stripping; 62c31af68aSBrett Creeley vlan_ops->ena_insertion = ice_vsi_ena_inner_insertion; 63c31af68aSBrett Creeley vlan_ops->dis_insertion = ice_vsi_dis_inner_insertion; 64cc71de8fSBrett Creeley } else { 65*f1da5a08SBrett Creeley if (!test_bit(ICE_FLAG_VF_VLAN_PRUNING, pf->flags)) 66*f1da5a08SBrett Creeley vlan_ops->ena_rx_filtering = noop_vlan; 67*f1da5a08SBrett Creeley else 68*f1da5a08SBrett Creeley vlan_ops->ena_rx_filtering = 69*f1da5a08SBrett Creeley ice_vsi_ena_rx_vlan_filtering; 70*f1da5a08SBrett Creeley 71cc71de8fSBrett Creeley vlan_ops->del_vlan = ice_vsi_del_vlan; 72cc71de8fSBrett Creeley vlan_ops->ena_stripping = ice_vsi_ena_outer_stripping; 73cc71de8fSBrett Creeley vlan_ops->dis_stripping = ice_vsi_dis_outer_stripping; 74cc71de8fSBrett Creeley vlan_ops->ena_insertion = ice_vsi_ena_outer_insertion; 75cc71de8fSBrett Creeley vlan_ops->dis_insertion = ice_vsi_dis_outer_insertion; 76cc71de8fSBrett Creeley 77cc71de8fSBrett Creeley /* setup inner VLAN ops */ 78cc71de8fSBrett Creeley vlan_ops = &vsi->inner_vlan_ops; 79cc71de8fSBrett Creeley 80cc71de8fSBrett Creeley vlan_ops->ena_stripping = ice_vsi_ena_inner_stripping; 81cc71de8fSBrett Creeley vlan_ops->dis_stripping = ice_vsi_dis_inner_stripping; 82cc71de8fSBrett Creeley vlan_ops->ena_insertion = ice_vsi_ena_inner_insertion; 83cc71de8fSBrett Creeley vlan_ops->dis_insertion = ice_vsi_dis_inner_insertion; 84c31af68aSBrett Creeley } 85c31af68aSBrett Creeley } else { 86c31af68aSBrett Creeley vlan_ops = &vsi->inner_vlan_ops; 87c31af68aSBrett Creeley 88c31af68aSBrett Creeley /* inner VLAN ops regardless of port VLAN config */ 89c31af68aSBrett Creeley vlan_ops->add_vlan = ice_vsi_add_vlan; 90c31af68aSBrett Creeley vlan_ops->dis_rx_filtering = ice_vsi_dis_rx_vlan_filtering; 91c31af68aSBrett Creeley vlan_ops->ena_tx_filtering = ice_vsi_ena_tx_vlan_filtering; 92c31af68aSBrett Creeley vlan_ops->dis_tx_filtering = ice_vsi_dis_tx_vlan_filtering; 93c31af68aSBrett Creeley 94c31af68aSBrett Creeley if (ice_vf_is_port_vlan_ena(vf)) { 95c31af68aSBrett Creeley vlan_ops->set_port_vlan = ice_vsi_set_inner_port_vlan; 96*f1da5a08SBrett Creeley vlan_ops->ena_rx_filtering = 97*f1da5a08SBrett Creeley ice_vsi_ena_rx_vlan_filtering; 98c31af68aSBrett Creeley } else { 99*f1da5a08SBrett Creeley if (!test_bit(ICE_FLAG_VF_VLAN_PRUNING, pf->flags)) 100*f1da5a08SBrett Creeley vlan_ops->ena_rx_filtering = noop_vlan; 101*f1da5a08SBrett Creeley else 102*f1da5a08SBrett Creeley vlan_ops->ena_rx_filtering = 103*f1da5a08SBrett Creeley ice_vsi_ena_rx_vlan_filtering; 104*f1da5a08SBrett Creeley 105c31af68aSBrett Creeley vlan_ops->del_vlan = ice_vsi_del_vlan; 106c31af68aSBrett Creeley vlan_ops->ena_stripping = ice_vsi_ena_inner_stripping; 107c31af68aSBrett Creeley vlan_ops->dis_stripping = ice_vsi_dis_inner_stripping; 108c31af68aSBrett Creeley vlan_ops->ena_insertion = ice_vsi_ena_inner_insertion; 109c31af68aSBrett Creeley vlan_ops->dis_insertion = ice_vsi_dis_inner_insertion; 110c31af68aSBrett Creeley } 111c31af68aSBrett Creeley } 112c31af68aSBrett Creeley } 113cc71de8fSBrett Creeley 114cc71de8fSBrett Creeley /** 115cc71de8fSBrett Creeley * ice_vf_vsi_cfg_dvm_legacy_vlan_mode - Config VLAN mode for old VFs in DVM 116cc71de8fSBrett Creeley * @vsi: VF's VSI being configured 117cc71de8fSBrett Creeley * 118cc71de8fSBrett Creeley * This should only be called when Double VLAN Mode (DVM) is enabled, there 119cc71de8fSBrett Creeley * is not a port VLAN enabled on this VF, and the VF negotiates 120cc71de8fSBrett Creeley * VIRTCHNL_VF_OFFLOAD_VLAN. 121cc71de8fSBrett Creeley * 122cc71de8fSBrett Creeley * This function sets up the VF VSI's inner and outer ice_vsi_vlan_ops and also 123cc71de8fSBrett Creeley * initializes software only VLAN mode (i.e. allow all VLANs). Also, use no-op 124cc71de8fSBrett Creeley * implementations for any functions that may be called during the lifetime of 125cc71de8fSBrett Creeley * the VF so these methods do nothing and succeed. 126cc71de8fSBrett Creeley */ 127cc71de8fSBrett Creeley void ice_vf_vsi_cfg_dvm_legacy_vlan_mode(struct ice_vsi *vsi) 128cc71de8fSBrett Creeley { 129cc71de8fSBrett Creeley struct ice_vf *vf = &vsi->back->vf[vsi->vf_id]; 130cc71de8fSBrett Creeley struct device *dev = ice_pf_to_dev(vf->pf); 131cc71de8fSBrett Creeley struct ice_vsi_vlan_ops *vlan_ops; 132cc71de8fSBrett Creeley 133cc71de8fSBrett Creeley if (!ice_is_dvm_ena(&vsi->back->hw) || ice_vf_is_port_vlan_ena(vf)) 134cc71de8fSBrett Creeley return; 135cc71de8fSBrett Creeley 136cc71de8fSBrett Creeley vlan_ops = &vsi->outer_vlan_ops; 137cc71de8fSBrett Creeley 138cc71de8fSBrett Creeley /* Rx VLAN filtering always disabled to allow software offloaded VLANs 139cc71de8fSBrett Creeley * for VFs that only support VIRTCHNL_VF_OFFLOAD_VLAN and don't have a 140cc71de8fSBrett Creeley * port VLAN configured 141cc71de8fSBrett Creeley */ 142cc71de8fSBrett Creeley vlan_ops->dis_rx_filtering = ice_vsi_dis_rx_vlan_filtering; 143cc71de8fSBrett Creeley /* Don't fail when attempting to enable Rx VLAN filtering */ 144cc71de8fSBrett Creeley vlan_ops->ena_rx_filtering = noop_vlan; 145cc71de8fSBrett Creeley 146cc71de8fSBrett Creeley /* Tx VLAN filtering always disabled to allow software offloaded VLANs 147cc71de8fSBrett Creeley * for VFs that only support VIRTCHNL_VF_OFFLOAD_VLAN and don't have a 148cc71de8fSBrett Creeley * port VLAN configured 149cc71de8fSBrett Creeley */ 150cc71de8fSBrett Creeley vlan_ops->dis_tx_filtering = ice_vsi_dis_tx_vlan_filtering; 151cc71de8fSBrett Creeley /* Don't fail when attempting to enable Tx VLAN filtering */ 152cc71de8fSBrett Creeley vlan_ops->ena_tx_filtering = noop_vlan; 153cc71de8fSBrett Creeley 154cc71de8fSBrett Creeley if (vlan_ops->dis_rx_filtering(vsi)) 155cc71de8fSBrett Creeley dev_dbg(dev, "Failed to disable Rx VLAN filtering for old VF without VIRTCHNL_VF_OFFLOAD_VLAN_V2 support\n"); 156cc71de8fSBrett Creeley if (vlan_ops->dis_tx_filtering(vsi)) 157cc71de8fSBrett Creeley dev_dbg(dev, "Failed to disable Tx VLAN filtering for old VF without VIRTHCNL_VF_OFFLOAD_VLAN_V2 support\n"); 158cc71de8fSBrett Creeley 159cc71de8fSBrett Creeley /* All outer VLAN offloads must be disabled */ 160cc71de8fSBrett Creeley vlan_ops->dis_stripping = ice_vsi_dis_outer_stripping; 161cc71de8fSBrett Creeley vlan_ops->dis_insertion = ice_vsi_dis_outer_insertion; 162cc71de8fSBrett Creeley 163cc71de8fSBrett Creeley if (vlan_ops->dis_stripping(vsi)) 164cc71de8fSBrett Creeley dev_dbg(dev, "Failed to disable outer VLAN stripping for old VF without VIRTCHNL_VF_OFFLOAD_VLAN_V2 support\n"); 165cc71de8fSBrett Creeley 166cc71de8fSBrett Creeley if (vlan_ops->dis_insertion(vsi)) 167cc71de8fSBrett Creeley dev_dbg(dev, "Failed to disable outer VLAN insertion for old VF without VIRTCHNL_VF_OFFLOAD_VLAN_V2 support\n"); 168cc71de8fSBrett Creeley 169cc71de8fSBrett Creeley /* All inner VLAN offloads must be disabled */ 170cc71de8fSBrett Creeley vlan_ops = &vsi->inner_vlan_ops; 171cc71de8fSBrett Creeley 172cc71de8fSBrett Creeley vlan_ops->dis_stripping = ice_vsi_dis_outer_stripping; 173cc71de8fSBrett Creeley vlan_ops->dis_insertion = ice_vsi_dis_outer_insertion; 174cc71de8fSBrett Creeley 175cc71de8fSBrett Creeley if (vlan_ops->dis_stripping(vsi)) 176cc71de8fSBrett Creeley dev_dbg(dev, "Failed to disable inner VLAN stripping for old VF without VIRTCHNL_VF_OFFLOAD_VLAN_V2 support\n"); 177cc71de8fSBrett Creeley 178cc71de8fSBrett Creeley if (vlan_ops->dis_insertion(vsi)) 179cc71de8fSBrett Creeley dev_dbg(dev, "Failed to disable inner VLAN insertion for old VF without VIRTCHNL_VF_OFFLOAD_VLAN_V2 support\n"); 180cc71de8fSBrett Creeley } 181cc71de8fSBrett Creeley 182cc71de8fSBrett Creeley /** 183cc71de8fSBrett Creeley * ice_vf_vsi_cfg_svm_legacy_vlan_mode - Config VLAN mode for old VFs in SVM 184cc71de8fSBrett Creeley * @vsi: VF's VSI being configured 185cc71de8fSBrett Creeley * 186cc71de8fSBrett Creeley * This should only be called when Single VLAN Mode (SVM) is enabled, there is 187cc71de8fSBrett Creeley * not a port VLAN enabled on this VF, and the VF negotiates 188cc71de8fSBrett Creeley * VIRTCHNL_VF_OFFLOAD_VLAN. 189cc71de8fSBrett Creeley * 190cc71de8fSBrett Creeley * All of the normal SVM VLAN ops are identical for this case. However, by 191cc71de8fSBrett Creeley * default Rx VLAN filtering should be turned off by default in this case. 192cc71de8fSBrett Creeley */ 193cc71de8fSBrett Creeley void ice_vf_vsi_cfg_svm_legacy_vlan_mode(struct ice_vsi *vsi) 194cc71de8fSBrett Creeley { 195cc71de8fSBrett Creeley struct ice_vf *vf = &vsi->back->vf[vsi->vf_id]; 196cc71de8fSBrett Creeley 197cc71de8fSBrett Creeley if (ice_is_dvm_ena(&vsi->back->hw) || ice_vf_is_port_vlan_ena(vf)) 198cc71de8fSBrett Creeley return; 199cc71de8fSBrett Creeley 200cc71de8fSBrett Creeley if (vsi->inner_vlan_ops.dis_rx_filtering(vsi)) 201cc71de8fSBrett Creeley dev_dbg(ice_pf_to_dev(vf->pf), "Failed to disable Rx VLAN filtering for old VF with VIRTCHNL_VF_OFFLOAD_VLAN support\n"); 202cc71de8fSBrett Creeley } 203