net/ice/base: update add scheduler node counter
[dpdk.git] / drivers / net / ice / base / ice_vlan_mode.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2001-2020 Intel Corporation
3  */
4
5 #include "ice_vlan_mode.h"
6 #include "ice_common.h"
7
8 /**
9  * ice_pkg_supports_dvm - determine if DDP supports Double VLAN mode (DVM)
10  * @hw: pointer to the HW struct
11  * @dvm: output variable to determine if DDP supports DVM(true) or SVM(false)
12  */
13 static enum ice_status
14 ice_pkg_get_supported_vlan_mode(struct ice_hw *hw, bool *dvm)
15 {
16         u16 meta_init_size = sizeof(struct ice_meta_init_section);
17         struct ice_meta_init_section *sect;
18         struct ice_buf_build *bld;
19         enum ice_status status;
20
21         /* if anything fails, we assume there is no DVM support */
22         *dvm = false;
23
24         bld = ice_pkg_buf_alloc_single_section(hw,
25                                                ICE_SID_RXPARSER_METADATA_INIT,
26                                                meta_init_size, (void **)&sect);
27         if (!bld)
28                 return ICE_ERR_NO_MEMORY;
29
30         /* only need to read a single section */
31         sect->count = CPU_TO_LE16(1);
32         sect->offset = CPU_TO_LE16(ICE_META_VLAN_MODE_ENTRY);
33
34         status = ice_aq_upload_section(hw,
35                                        (struct ice_buf_hdr *)ice_pkg_buf(bld),
36                                        ICE_PKG_BUF_SIZE, NULL);
37         if (!status) {
38                 ice_declare_bitmap(entry, ICE_META_INIT_BITS);
39                 u32 arr[ICE_META_INIT_DW_CNT];
40                 u16 i;
41
42                 /* convert to host bitmap format */
43                 for (i = 0; i < ICE_META_INIT_DW_CNT; i++)
44                         arr[i] = LE32_TO_CPU(sect->entry[0].bm[i]);
45
46                 ice_bitmap_from_array32(entry, arr, (u16)ICE_META_INIT_BITS);
47
48                 /* check if DVM is supported */
49                 *dvm = ice_is_bit_set(entry, ICE_META_VLAN_MODE_BIT);
50         }
51
52         ice_pkg_buf_free(hw, bld);
53
54         return status;
55 }
56
57 /**
58  * ice_is_dvm_supported - check if double VLAN mode is supported based on DDP
59  * @hw: pointer to the hardware structure
60  *
61  * Returns true if DVM is supported and false if only SVM is supported. This
62  * function should only be called while the global config lock is held and after
63  * the package has been successfully downloaded.
64  */
65 static bool ice_is_dvm_supported(struct ice_hw *hw)
66 {
67         enum ice_status status;
68         bool pkg_supports_dvm;
69
70         status = ice_pkg_get_supported_vlan_mode(hw, &pkg_supports_dvm);
71         if (status) {
72                 ice_debug(hw, ICE_DBG_PKG, "Failed to get supported VLAN mode, err %d\n",
73                           status);
74                 return false;
75         }
76
77         if (!pkg_supports_dvm)
78                 return false;
79
80         return true;
81 }
82
83 /**
84  * ice_set_svm - set single VLAN mode
85  * @hw: pointer to the HW structure
86  */
87 static enum ice_status ice_set_svm_dflt(struct ice_hw *hw)
88 {
89         ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
90
91         return ice_aq_set_port_params(hw->port_info, 0, false, false, false, NULL);
92 }
93
94 /**
95  * ice_init_vlan_mode_ops - initialize VLAN mode configuration ops
96  * @hw: pointer to the HW structure
97  */
98 void ice_init_vlan_mode_ops(struct ice_hw *hw)
99 {
100         hw->vlan_mode_ops.set_dvm = NULL;
101         hw->vlan_mode_ops.set_svm = ice_set_svm_dflt;
102 }
103
104 /**
105  * ice_set_vlan_mode
106  * @hw: pointer to the HW structure
107  */
108 enum ice_status ice_set_vlan_mode(struct ice_hw *hw)
109 {
110         enum ice_status status = ICE_ERR_NOT_IMPL;
111
112         if (!ice_is_dvm_supported(hw))
113                 return ICE_SUCCESS;
114
115         if (hw->vlan_mode_ops.set_dvm)
116                 status = hw->vlan_mode_ops.set_dvm(hw);
117
118         if (status)
119                 return hw->vlan_mode_ops.set_svm(hw);
120
121         return ICE_SUCCESS;
122 }