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