return (ice_vf_get_port_vlan_id(vf) || ice_vf_get_port_vlan_prio(vf));
}
+static u16 ice_vf_get_port_vlan_tpid(struct ice_vf *vf)
+{
+ return vf->port_vlan_info.tpid;
+}
+
/**
* ice_vf_rebuild_host_vlan_cfg - add VLAN 0 filter or rebuild the Port VLAN
* @vf: VF to add MAC filters for
v_ret, (u8 *)vfres, sizeof(*vfres));
}
+/**
+ * ice_is_supported_port_vlan_proto - make sure the vlan_proto is supported
+ * @hw: hardware structure used to check the VLAN mode
+ * @vlan_proto: VLAN TPID being checked
+ *
+ * If the device is configured in Double VLAN Mode (DVM), then both ETH_P_8021Q
+ * and ETH_P_8021AD are supported. If the device is configured in Single VLAN
+ * Mode (SVM), then only ETH_P_8021Q is supported.
+ */
+static bool
+ice_is_supported_port_vlan_proto(struct ice_hw *hw, u16 vlan_proto)
+{
+ bool is_supported = false;
+
+ switch (vlan_proto) {
+ case ETH_P_8021Q:
+ is_supported = true;
+ break;
+ case ETH_P_8021AD:
+ if (ice_is_dvm_ena(hw))
+ is_supported = true;
+ break;
+ }
+
+ return is_supported;
+}
+
/**
* ice_set_vf_port_vlan
* @netdev: network interface device structure
__be16 vlan_proto)
{
struct ice_pf *pf = ice_netdev_to_pf(netdev);
+ u16 local_vlan_proto = ntohs(vlan_proto);
struct device *dev;
struct ice_vf *vf;
int ret;
return -EINVAL;
}
- if (vlan_proto != htons(ETH_P_8021Q)) {
- dev_err(dev, "VF VLAN protocol is not supported\n");
+ if (!ice_is_supported_port_vlan_proto(&pf->hw, local_vlan_proto)) {
+ dev_err(dev, "VF VLAN protocol 0x%04x is not supported\n",
+ local_vlan_proto);
return -EPROTONOSUPPORT;
}
return ret;
if (ice_vf_get_port_vlan_prio(vf) == qos &&
+ ice_vf_get_port_vlan_tpid(vf) == local_vlan_proto &&
ice_vf_get_port_vlan_id(vf) == vlan_id) {
/* duplicate request, so just return success */
- dev_dbg(dev, "Duplicate port VLAN %u, QoS %u request\n",
- vlan_id, qos);
+ dev_dbg(dev, "Duplicate port VLAN %u, QoS %u, TPID 0x%04x request\n",
+ vlan_id, qos, local_vlan_proto);
return 0;
}
mutex_lock(&vf->cfg_lock);
- vf->port_vlan_info = ICE_VLAN(ETH_P_8021Q, vlan_id, qos);
+ vf->port_vlan_info = ICE_VLAN(local_vlan_proto, vlan_id, qos);
if (ice_vf_is_port_vlan_ena(vf))
- dev_info(dev, "Setting VLAN %u, QoS %u on VF %d\n",
- vlan_id, qos, vf_id);
+ dev_info(dev, "Setting VLAN %u, QoS %u, TPID 0x%04x on VF %d\n",
+ vlan_id, qos, local_vlan_proto, vf_id);
else
dev_info(dev, "Clearing port VLAN on VF %d\n", vf_id);
/* VF configuration for VLAN and applicable QoS */
ivi->vlan = ice_vf_get_port_vlan_id(vf);
ivi->qos = ice_vf_get_port_vlan_prio(vf);
+ if (ice_vf_is_port_vlan_ena(vf))
+ ivi->vlan_proto = cpu_to_be16(ice_vf_get_port_vlan_tpid(vf));
ivi->trusted = vf->trusted;
ivi->spoofchk = vf->spoofchk;