X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fice%2Fbase%2Fice_vlan_mode.c;h=363354ff3f4f381128822285c262b3834d730a78;hb=553be3ed18543fc7fe0beb3c62c5ec764c945eef;hp=603de74e250bc110c7cf59d22e21fa56ff3f0a3f;hpb=4e4dc21e450b5860da650d255abb6e17c3e637a9;p=dpdk.git diff --git a/drivers/net/ice/base/ice_vlan_mode.c b/drivers/net/ice/base/ice_vlan_mode.c index 603de74e25..363354ff3f 100644 --- a/drivers/net/ice/base/ice_vlan_mode.c +++ b/drivers/net/ice/base/ice_vlan_mode.c @@ -5,6 +5,81 @@ #include "ice_vlan_mode.h" #include "ice_common.h" +/** + * ice_pkg_supports_dvm - determine if DDP supports Double VLAN mode (DVM) + * @hw: pointer to the HW struct + * @dvm: output variable to determine if DDP supports DVM(true) or SVM(false) + */ +static enum ice_status +ice_pkg_get_supported_vlan_mode(struct ice_hw *hw, bool *dvm) +{ + u16 meta_init_size = sizeof(struct ice_meta_init_section); + struct ice_meta_init_section *sect; + struct ice_buf_build *bld; + enum ice_status status; + + /* if anything fails, we assume there is no DVM support */ + *dvm = false; + + bld = ice_pkg_buf_alloc_single_section(hw, + ICE_SID_RXPARSER_METADATA_INIT, + meta_init_size, (void **)§); + if (!bld) + return ICE_ERR_NO_MEMORY; + + /* only need to read a single section */ + sect->count = CPU_TO_LE16(1); + sect->offset = CPU_TO_LE16(ICE_META_VLAN_MODE_ENTRY); + + status = ice_aq_upload_section(hw, + (struct ice_buf_hdr *)ice_pkg_buf(bld), + ICE_PKG_BUF_SIZE, NULL); + if (!status) { + ice_declare_bitmap(entry, ICE_META_INIT_BITS); + u32 arr[ICE_META_INIT_DW_CNT]; + u16 i; + + /* convert to host bitmap format */ + for (i = 0; i < ICE_META_INIT_DW_CNT; i++) + arr[i] = LE32_TO_CPU(sect->entry[0].bm[i]); + + ice_bitmap_from_array32(entry, arr, (u16)ICE_META_INIT_BITS); + + /* check if DVM is supported */ + *dvm = ice_is_bit_set(entry, ICE_META_VLAN_MODE_BIT); + } + + ice_pkg_buf_free(hw, bld); + + return status; +} + +/** + * ice_is_dvm_supported - check if double VLAN mode is supported based on DDP + * @hw: pointer to the hardware structure + * + * Returns true if DVM is supported and false if only SVM is supported. This + * function should only be called while the global config lock is held and after + * the package has been successfully downloaded. + */ +static bool ice_is_dvm_supported(struct ice_hw *hw) +{ + enum ice_status status; + bool pkg_supports_dvm; + + status = ice_pkg_get_supported_vlan_mode(hw, &pkg_supports_dvm); + if (status) { + ice_debug(hw, ICE_DBG_PKG, "Failed to get supported VLAN mode, err %d\n", + status); + return false; + } + + if (!pkg_supports_dvm) + return false; + + return true; +} + /** * ice_set_svm - set single VLAN mode * @hw: pointer to the HW structure @@ -34,6 +109,9 @@ enum ice_status ice_set_vlan_mode(struct ice_hw *hw) { enum ice_status status = ICE_ERR_NOT_IMPL; + if (!ice_is_dvm_supported(hw)) + return ICE_SUCCESS; + if (hw->vlan_mode_ops.set_dvm) status = hw->vlan_mode_ops.set_dvm(hw);