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; 37*b03d519dSJacob Keller struct ice_vf *vf = vsi->vf; 38c31af68aSBrett Creeley 39*b03d519dSJacob Keller if (WARN_ON(!vf)) 40*b03d519dSJacob Keller return; 41c31af68aSBrett Creeley 42c31af68aSBrett Creeley if (ice_is_dvm_ena(&pf->hw)) { 43c31af68aSBrett Creeley vlan_ops = &vsi->outer_vlan_ops; 44c31af68aSBrett Creeley 45c31af68aSBrett Creeley /* outer VLAN ops regardless of port VLAN config */ 46c31af68aSBrett Creeley vlan_ops->add_vlan = ice_vsi_add_vlan; 47c31af68aSBrett Creeley vlan_ops->dis_rx_filtering = ice_vsi_dis_rx_vlan_filtering; 48c31af68aSBrett Creeley vlan_ops->ena_tx_filtering = ice_vsi_ena_tx_vlan_filtering; 49c31af68aSBrett Creeley vlan_ops->dis_tx_filtering = ice_vsi_dis_tx_vlan_filtering; 50c31af68aSBrett Creeley 51c31af68aSBrett Creeley if (ice_vf_is_port_vlan_ena(vf)) { 52c31af68aSBrett Creeley /* setup outer VLAN ops */ 53c31af68aSBrett Creeley vlan_ops->set_port_vlan = ice_vsi_set_outer_port_vlan; 54f1da5a08SBrett Creeley vlan_ops->ena_rx_filtering = 55f1da5a08SBrett Creeley ice_vsi_ena_rx_vlan_filtering; 56c31af68aSBrett Creeley 57c31af68aSBrett Creeley /* setup inner VLAN ops */ 58c31af68aSBrett Creeley vlan_ops = &vsi->inner_vlan_ops; 59c31af68aSBrett Creeley vlan_ops->add_vlan = noop_vlan_arg; 60c31af68aSBrett Creeley vlan_ops->del_vlan = noop_vlan_arg; 61c31af68aSBrett Creeley vlan_ops->ena_stripping = ice_vsi_ena_inner_stripping; 62c31af68aSBrett Creeley vlan_ops->dis_stripping = ice_vsi_dis_inner_stripping; 63c31af68aSBrett Creeley vlan_ops->ena_insertion = ice_vsi_ena_inner_insertion; 64c31af68aSBrett Creeley vlan_ops->dis_insertion = ice_vsi_dis_inner_insertion; 65cc71de8fSBrett Creeley } else { 66f1da5a08SBrett Creeley if (!test_bit(ICE_FLAG_VF_VLAN_PRUNING, pf->flags)) 67f1da5a08SBrett Creeley vlan_ops->ena_rx_filtering = noop_vlan; 68f1da5a08SBrett Creeley else 69f1da5a08SBrett Creeley vlan_ops->ena_rx_filtering = 70f1da5a08SBrett Creeley ice_vsi_ena_rx_vlan_filtering; 71f1da5a08SBrett Creeley 72cc71de8fSBrett Creeley vlan_ops->del_vlan = ice_vsi_del_vlan; 73cc71de8fSBrett Creeley vlan_ops->ena_stripping = ice_vsi_ena_outer_stripping; 74cc71de8fSBrett Creeley vlan_ops->dis_stripping = ice_vsi_dis_outer_stripping; 75cc71de8fSBrett Creeley vlan_ops->ena_insertion = ice_vsi_ena_outer_insertion; 76cc71de8fSBrett Creeley vlan_ops->dis_insertion = ice_vsi_dis_outer_insertion; 77cc71de8fSBrett Creeley 78cc71de8fSBrett Creeley /* setup inner VLAN ops */ 79cc71de8fSBrett Creeley vlan_ops = &vsi->inner_vlan_ops; 80cc71de8fSBrett Creeley 81cc71de8fSBrett Creeley vlan_ops->ena_stripping = ice_vsi_ena_inner_stripping; 82cc71de8fSBrett Creeley vlan_ops->dis_stripping = ice_vsi_dis_inner_stripping; 83cc71de8fSBrett Creeley vlan_ops->ena_insertion = ice_vsi_ena_inner_insertion; 84cc71de8fSBrett Creeley vlan_ops->dis_insertion = ice_vsi_dis_inner_insertion; 85c31af68aSBrett Creeley } 86c31af68aSBrett Creeley } else { 87c31af68aSBrett Creeley vlan_ops = &vsi->inner_vlan_ops; 88c31af68aSBrett Creeley 89c31af68aSBrett Creeley /* inner VLAN ops regardless of port VLAN config */ 90c31af68aSBrett Creeley vlan_ops->add_vlan = ice_vsi_add_vlan; 91c31af68aSBrett Creeley vlan_ops->dis_rx_filtering = ice_vsi_dis_rx_vlan_filtering; 92c31af68aSBrett Creeley vlan_ops->ena_tx_filtering = ice_vsi_ena_tx_vlan_filtering; 93c31af68aSBrett Creeley vlan_ops->dis_tx_filtering = ice_vsi_dis_tx_vlan_filtering; 94c31af68aSBrett Creeley 95c31af68aSBrett Creeley if (ice_vf_is_port_vlan_ena(vf)) { 96c31af68aSBrett Creeley vlan_ops->set_port_vlan = ice_vsi_set_inner_port_vlan; 97f1da5a08SBrett Creeley vlan_ops->ena_rx_filtering = 98f1da5a08SBrett Creeley ice_vsi_ena_rx_vlan_filtering; 99c31af68aSBrett Creeley } else { 100f1da5a08SBrett Creeley if (!test_bit(ICE_FLAG_VF_VLAN_PRUNING, pf->flags)) 101f1da5a08SBrett Creeley vlan_ops->ena_rx_filtering = noop_vlan; 102f1da5a08SBrett Creeley else 103f1da5a08SBrett Creeley vlan_ops->ena_rx_filtering = 104f1da5a08SBrett Creeley ice_vsi_ena_rx_vlan_filtering; 105f1da5a08SBrett Creeley 106c31af68aSBrett Creeley vlan_ops->del_vlan = ice_vsi_del_vlan; 107c31af68aSBrett Creeley vlan_ops->ena_stripping = ice_vsi_ena_inner_stripping; 108c31af68aSBrett Creeley vlan_ops->dis_stripping = ice_vsi_dis_inner_stripping; 109c31af68aSBrett Creeley vlan_ops->ena_insertion = ice_vsi_ena_inner_insertion; 110c31af68aSBrett Creeley vlan_ops->dis_insertion = ice_vsi_dis_inner_insertion; 111c31af68aSBrett Creeley } 112c31af68aSBrett Creeley } 113c31af68aSBrett Creeley } 114cc71de8fSBrett Creeley 115cc71de8fSBrett Creeley /** 116cc71de8fSBrett Creeley * ice_vf_vsi_cfg_dvm_legacy_vlan_mode - Config VLAN mode for old VFs in DVM 117cc71de8fSBrett Creeley * @vsi: VF's VSI being configured 118cc71de8fSBrett Creeley * 119cc71de8fSBrett Creeley * This should only be called when Double VLAN Mode (DVM) is enabled, there 120cc71de8fSBrett Creeley * is not a port VLAN enabled on this VF, and the VF negotiates 121cc71de8fSBrett Creeley * VIRTCHNL_VF_OFFLOAD_VLAN. 122cc71de8fSBrett Creeley * 123cc71de8fSBrett Creeley * This function sets up the VF VSI's inner and outer ice_vsi_vlan_ops and also 124cc71de8fSBrett Creeley * initializes software only VLAN mode (i.e. allow all VLANs). Also, use no-op 125cc71de8fSBrett Creeley * implementations for any functions that may be called during the lifetime of 126cc71de8fSBrett Creeley * the VF so these methods do nothing and succeed. 127cc71de8fSBrett Creeley */ 128cc71de8fSBrett Creeley void ice_vf_vsi_cfg_dvm_legacy_vlan_mode(struct ice_vsi *vsi) 129cc71de8fSBrett Creeley { 130cc71de8fSBrett Creeley struct ice_vsi_vlan_ops *vlan_ops; 131*b03d519dSJacob Keller struct ice_vf *vf = vsi->vf; 132*b03d519dSJacob Keller struct device *dev; 133*b03d519dSJacob Keller 134*b03d519dSJacob Keller if (WARN_ON(!vf)) 135*b03d519dSJacob Keller return; 136*b03d519dSJacob Keller 137*b03d519dSJacob Keller dev = ice_pf_to_dev(vf->pf); 138cc71de8fSBrett Creeley 139cc71de8fSBrett Creeley if (!ice_is_dvm_ena(&vsi->back->hw) || ice_vf_is_port_vlan_ena(vf)) 140cc71de8fSBrett Creeley return; 141cc71de8fSBrett Creeley 142cc71de8fSBrett Creeley vlan_ops = &vsi->outer_vlan_ops; 143cc71de8fSBrett Creeley 144cc71de8fSBrett Creeley /* Rx VLAN filtering always disabled to allow software offloaded VLANs 145cc71de8fSBrett Creeley * for VFs that only support VIRTCHNL_VF_OFFLOAD_VLAN and don't have a 146cc71de8fSBrett Creeley * port VLAN configured 147cc71de8fSBrett Creeley */ 148cc71de8fSBrett Creeley vlan_ops->dis_rx_filtering = ice_vsi_dis_rx_vlan_filtering; 149cc71de8fSBrett Creeley /* Don't fail when attempting to enable Rx VLAN filtering */ 150cc71de8fSBrett Creeley vlan_ops->ena_rx_filtering = noop_vlan; 151cc71de8fSBrett Creeley 152cc71de8fSBrett Creeley /* Tx VLAN filtering always disabled to allow software offloaded VLANs 153cc71de8fSBrett Creeley * for VFs that only support VIRTCHNL_VF_OFFLOAD_VLAN and don't have a 154cc71de8fSBrett Creeley * port VLAN configured 155cc71de8fSBrett Creeley */ 156cc71de8fSBrett Creeley vlan_ops->dis_tx_filtering = ice_vsi_dis_tx_vlan_filtering; 157cc71de8fSBrett Creeley /* Don't fail when attempting to enable Tx VLAN filtering */ 158cc71de8fSBrett Creeley vlan_ops->ena_tx_filtering = noop_vlan; 159cc71de8fSBrett Creeley 160cc71de8fSBrett Creeley if (vlan_ops->dis_rx_filtering(vsi)) 161cc71de8fSBrett Creeley dev_dbg(dev, "Failed to disable Rx VLAN filtering for old VF without VIRTCHNL_VF_OFFLOAD_VLAN_V2 support\n"); 162cc71de8fSBrett Creeley if (vlan_ops->dis_tx_filtering(vsi)) 163cc71de8fSBrett Creeley dev_dbg(dev, "Failed to disable Tx VLAN filtering for old VF without VIRTHCNL_VF_OFFLOAD_VLAN_V2 support\n"); 164cc71de8fSBrett Creeley 165cc71de8fSBrett Creeley /* All outer VLAN offloads must be disabled */ 166cc71de8fSBrett Creeley vlan_ops->dis_stripping = ice_vsi_dis_outer_stripping; 167cc71de8fSBrett Creeley vlan_ops->dis_insertion = ice_vsi_dis_outer_insertion; 168cc71de8fSBrett Creeley 169cc71de8fSBrett Creeley if (vlan_ops->dis_stripping(vsi)) 170cc71de8fSBrett Creeley dev_dbg(dev, "Failed to disable outer VLAN stripping for old VF without VIRTCHNL_VF_OFFLOAD_VLAN_V2 support\n"); 171cc71de8fSBrett Creeley 172cc71de8fSBrett Creeley if (vlan_ops->dis_insertion(vsi)) 173cc71de8fSBrett Creeley dev_dbg(dev, "Failed to disable outer VLAN insertion for old VF without VIRTCHNL_VF_OFFLOAD_VLAN_V2 support\n"); 174cc71de8fSBrett Creeley 175cc71de8fSBrett Creeley /* All inner VLAN offloads must be disabled */ 176cc71de8fSBrett Creeley vlan_ops = &vsi->inner_vlan_ops; 177cc71de8fSBrett Creeley 178cc71de8fSBrett Creeley vlan_ops->dis_stripping = ice_vsi_dis_outer_stripping; 179cc71de8fSBrett Creeley vlan_ops->dis_insertion = ice_vsi_dis_outer_insertion; 180cc71de8fSBrett Creeley 181cc71de8fSBrett Creeley if (vlan_ops->dis_stripping(vsi)) 182cc71de8fSBrett Creeley dev_dbg(dev, "Failed to disable inner VLAN stripping for old VF without VIRTCHNL_VF_OFFLOAD_VLAN_V2 support\n"); 183cc71de8fSBrett Creeley 184cc71de8fSBrett Creeley if (vlan_ops->dis_insertion(vsi)) 185cc71de8fSBrett Creeley dev_dbg(dev, "Failed to disable inner VLAN insertion for old VF without VIRTCHNL_VF_OFFLOAD_VLAN_V2 support\n"); 186cc71de8fSBrett Creeley } 187cc71de8fSBrett Creeley 188cc71de8fSBrett Creeley /** 189cc71de8fSBrett Creeley * ice_vf_vsi_cfg_svm_legacy_vlan_mode - Config VLAN mode for old VFs in SVM 190cc71de8fSBrett Creeley * @vsi: VF's VSI being configured 191cc71de8fSBrett Creeley * 192cc71de8fSBrett Creeley * This should only be called when Single VLAN Mode (SVM) is enabled, there is 193cc71de8fSBrett Creeley * not a port VLAN enabled on this VF, and the VF negotiates 194cc71de8fSBrett Creeley * VIRTCHNL_VF_OFFLOAD_VLAN. 195cc71de8fSBrett Creeley * 196cc71de8fSBrett Creeley * All of the normal SVM VLAN ops are identical for this case. However, by 197cc71de8fSBrett Creeley * default Rx VLAN filtering should be turned off by default in this case. 198cc71de8fSBrett Creeley */ 199cc71de8fSBrett Creeley void ice_vf_vsi_cfg_svm_legacy_vlan_mode(struct ice_vsi *vsi) 200cc71de8fSBrett Creeley { 201*b03d519dSJacob Keller struct ice_vf *vf = vsi->vf; 202*b03d519dSJacob Keller 203*b03d519dSJacob Keller if (WARN_ON(!vf)) 204*b03d519dSJacob Keller return; 205cc71de8fSBrett Creeley 206cc71de8fSBrett Creeley if (ice_is_dvm_ena(&vsi->back->hw) || ice_vf_is_port_vlan_ena(vf)) 207cc71de8fSBrett Creeley return; 208cc71de8fSBrett Creeley 209cc71de8fSBrett Creeley if (vsi->inner_vlan_ops.dis_rx_filtering(vsi)) 210cc71de8fSBrett 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"); 211cc71de8fSBrett Creeley } 212