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 |
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 |
17 | op_unsupported_tpid_arg(struct ice_vsi *__always_unused vsi, |
18 | u16 __always_unused tpid) |
19 | { |
20 | return -EOPNOTSUPP; |
21 | } |
22 | |
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 | */ |
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 | */ |
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 | */ |
97 | struct ice_vsi_vlan_ops *ice_get_compat_vsi_vlan_ops(struct ice_vsi *vsi) |
98 | { |
99 | if (ice_is_dvm_ena(hw: &vsi->back->hw)) |
100 | return &vsi->outer_vlan_ops; |
101 | else |
102 | return &vsi->inner_vlan_ops; |
103 | } |
104 | |