1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) 2019-2021, Intel Corporation. */
3 
4 #include "ice_pf_vsi_vlan_ops.h"
5 #include "ice_vf_vsi_vlan_ops.h"
6 #include "ice_lib.h"
7 #include "ice.h"
8 
9 static int
op_unsupported_vlan_arg(struct ice_vsi * __always_unused vsi,struct ice_vlan * __always_unused vlan)10 op_unsupported_vlan_arg(struct ice_vsi * __always_unused vsi,
11 			struct ice_vlan * __always_unused vlan)
12 {
13 	return -EOPNOTSUPP;
14 }
15 
16 static int
op_unsupported_tpid_arg(struct ice_vsi * __always_unused vsi,u16 __always_unused tpid)17 op_unsupported_tpid_arg(struct ice_vsi *__always_unused vsi,
18 			u16 __always_unused tpid)
19 {
20 	return -EOPNOTSUPP;
21 }
22 
op_unsupported(struct ice_vsi * __always_unused vsi)23 static int op_unsupported(struct ice_vsi *__always_unused vsi)
24 {
25 	return -EOPNOTSUPP;
26 }
27 
28 /* If any new ops are added to the VSI VLAN ops interface then an unsupported
29  * implementation should be set here.
30  */
31 static struct ice_vsi_vlan_ops ops_unsupported = {
32 	.add_vlan = op_unsupported_vlan_arg,
33 	.del_vlan = op_unsupported_vlan_arg,
34 	.ena_stripping = op_unsupported_tpid_arg,
35 	.dis_stripping = op_unsupported,
36 	.ena_insertion = op_unsupported_tpid_arg,
37 	.dis_insertion = op_unsupported,
38 	.ena_rx_filtering = op_unsupported,
39 	.dis_rx_filtering = op_unsupported,
40 	.ena_tx_filtering = op_unsupported,
41 	.dis_tx_filtering = op_unsupported,
42 	.set_port_vlan = op_unsupported_vlan_arg,
43 };
44 
45 /**
46  * ice_vsi_init_unsupported_vlan_ops - init all VSI VLAN ops to unsupported
47  * @vsi: VSI to initialize VSI VLAN ops to unsupported for
48  *
49  * By default all inner and outer VSI VLAN ops return -EOPNOTSUPP. This was done
50  * as oppsed to leaving the ops null to prevent unexpected crashes. Instead if
51  * an unsupported VSI VLAN op is called it will just return -EOPNOTSUPP.
52  *
53  */
ice_vsi_init_unsupported_vlan_ops(struct ice_vsi * vsi)54 static void ice_vsi_init_unsupported_vlan_ops(struct ice_vsi *vsi)
55 {
56 	vsi->outer_vlan_ops = ops_unsupported;
57 	vsi->inner_vlan_ops = ops_unsupported;
58 }
59 
60 /**
61  * ice_vsi_init_vlan_ops - initialize type specific VSI VLAN ops
62  * @vsi: VSI to initialize ops for
63  *
64  * If any VSI types are added and/or require different ops than the PF or VF VSI
65  * then they will have to add a case here to handle that. Also, VSI type
66  * specific files should be added in the same manner that was done for PF VSI.
67  */
ice_vsi_init_vlan_ops(struct ice_vsi * vsi)68 void ice_vsi_init_vlan_ops(struct ice_vsi *vsi)
69 {
70 	/* Initialize all VSI types to have unsupported VSI VLAN ops */
71 	ice_vsi_init_unsupported_vlan_ops(vsi);
72 
73 	switch (vsi->type) {
74 	case ICE_VSI_PF:
75 	case ICE_VSI_SWITCHDEV_CTRL:
76 		ice_pf_vsi_init_vlan_ops(vsi);
77 		break;
78 	case ICE_VSI_VF:
79 		ice_vf_vsi_init_vlan_ops(vsi);
80 		break;
81 	default:
82 		dev_dbg(ice_pf_to_dev(vsi->back), "%s does not support VLAN operations\n",
83 			ice_vsi_type_str(vsi->type));
84 		break;
85 	}
86 }
87 
88 /**
89  * ice_get_compat_vsi_vlan_ops - Get VSI VLAN ops based on VLAN mode
90  * @vsi: VSI used to get the VSI VLAN ops
91  *
92  * This function is meant to be used when the caller doesn't know which VLAN ops
93  * to use (i.e. inner or outer). This allows backward compatibility for VLANs
94  * since most of the Outer VSI VLAN functins are not supported when
95  * the device is configured in Single VLAN Mode (SVM).
96  */
ice_get_compat_vsi_vlan_ops(struct ice_vsi * vsi)97 struct ice_vsi_vlan_ops *ice_get_compat_vsi_vlan_ops(struct ice_vsi *vsi)
98 {
99 	if (ice_is_dvm_ena(&vsi->back->hw))
100 		return &vsi->outer_vlan_ops;
101 	else
102 		return &vsi->inner_vlan_ops;
103 }
104