1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2001-2020 Intel Corporation
5 #include "ice_vlan_mode.h"
6 #include "ice_common.h"
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)
13 static enum ice_status
14 ice_pkg_get_supported_vlan_mode(struct ice_hw *hw, bool *dvm)
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;
21 /* if anything fails, we assume there is no DVM support */
24 bld = ice_pkg_buf_alloc_single_section(hw,
25 ICE_SID_RXPARSER_METADATA_INIT,
26 meta_init_size, (void **)§);
28 return ICE_ERR_NO_MEMORY;
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);
34 status = ice_aq_upload_section(hw,
35 (struct ice_buf_hdr *)ice_pkg_buf(bld),
36 ICE_PKG_BUF_SIZE, NULL);
38 ice_declare_bitmap(entry, ICE_META_INIT_BITS);
39 u32 arr[ICE_META_INIT_DW_CNT];
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]);
46 ice_bitmap_from_array32(entry, arr, (u16)ICE_META_INIT_BITS);
48 /* check if DVM is supported */
49 *dvm = ice_is_bit_set(entry, ICE_META_VLAN_MODE_BIT);
52 ice_pkg_buf_free(hw, bld);
58 * ice_is_dvm_supported - check if double VLAN mode is supported based on DDP
59 * @hw: pointer to the hardware structure
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.
65 static bool ice_is_dvm_supported(struct ice_hw *hw)
67 enum ice_status status;
68 bool pkg_supports_dvm;
70 status = ice_pkg_get_supported_vlan_mode(hw, &pkg_supports_dvm);
72 ice_debug(hw, ICE_DBG_PKG, "Failed to get supported VLAN mode, err %d\n",
77 if (!pkg_supports_dvm)
84 * ice_set_svm - set single VLAN mode
85 * @hw: pointer to the HW structure
87 static enum ice_status ice_set_svm_dflt(struct ice_hw *hw)
89 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
91 return ice_aq_set_port_params(hw->port_info, 0, false, false, false, NULL);
95 * ice_init_vlan_mode_ops - initialize VLAN mode configuration ops
96 * @hw: pointer to the HW structure
98 void ice_init_vlan_mode_ops(struct ice_hw *hw)
100 hw->vlan_mode_ops.set_dvm = NULL;
101 hw->vlan_mode_ops.set_svm = ice_set_svm_dflt;
106 * @hw: pointer to the HW structure
108 enum ice_status ice_set_vlan_mode(struct ice_hw *hw)
110 enum ice_status status = ICE_ERR_NOT_IMPL;
112 if (!ice_is_dvm_supported(hw))
115 if (hw->vlan_mode_ops.set_dvm)
116 status = hw->vlan_mode_ops.set_dvm(hw);
119 return hw->vlan_mode_ops.set_svm(hw);