Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /* Copyright (c) 2017-2019 Mellanox Technologies. All rights reserved */
0003 
0004 #define pr_fmt(fmt) "MFA2: " fmt
0005 
0006 #include "mlxfw_mfa2_tlv_multi.h"
0007 #include <uapi/linux/netlink.h>
0008 
0009 #define MLXFW_MFA2_TLV_TOTAL_SIZE(tlv) \
0010     NLA_ALIGN(sizeof(*(tlv)) + be16_to_cpu((tlv)->len))
0011 
0012 const struct mlxfw_mfa2_tlv *
0013 mlxfw_mfa2_tlv_multi_child(const struct mlxfw_mfa2_file *mfa2_file,
0014                const struct mlxfw_mfa2_tlv_multi *multi)
0015 {
0016     size_t multi_len;
0017 
0018     multi_len = NLA_ALIGN(sizeof(struct mlxfw_mfa2_tlv_multi));
0019     return mlxfw_mfa2_tlv_get(mfa2_file, (void *) multi + multi_len);
0020 }
0021 
0022 const struct mlxfw_mfa2_tlv *
0023 mlxfw_mfa2_tlv_next(const struct mlxfw_mfa2_file *mfa2_file,
0024             const struct mlxfw_mfa2_tlv *tlv)
0025 {
0026     const struct mlxfw_mfa2_tlv_multi *multi;
0027     u16 tlv_len;
0028     void *next;
0029 
0030     tlv_len = MLXFW_MFA2_TLV_TOTAL_SIZE(tlv);
0031 
0032     if (tlv->type == MLXFW_MFA2_TLV_MULTI_PART) {
0033         multi = mlxfw_mfa2_tlv_multi_get(mfa2_file, tlv);
0034         tlv_len = NLA_ALIGN(tlv_len + be16_to_cpu(multi->total_len));
0035     }
0036 
0037     next = (void *) tlv + tlv_len;
0038     return mlxfw_mfa2_tlv_get(mfa2_file, next);
0039 }
0040 
0041 const struct mlxfw_mfa2_tlv *
0042 mlxfw_mfa2_tlv_advance(const struct mlxfw_mfa2_file *mfa2_file,
0043                const struct mlxfw_mfa2_tlv *from_tlv, u16 count)
0044 {
0045     const struct mlxfw_mfa2_tlv *tlv;
0046     u16 idx;
0047 
0048     mlxfw_mfa2_tlv_foreach(mfa2_file, tlv, idx, from_tlv, count)
0049         if (!tlv)
0050             return NULL;
0051     return tlv;
0052 }
0053 
0054 const struct mlxfw_mfa2_tlv *
0055 mlxfw_mfa2_tlv_multi_child_find(const struct mlxfw_mfa2_file *mfa2_file,
0056                 const struct mlxfw_mfa2_tlv_multi *multi,
0057                 enum mlxfw_mfa2_tlv_type type, u16 index)
0058 {
0059     const struct mlxfw_mfa2_tlv *tlv;
0060     u16 skip = 0;
0061     u16 idx;
0062 
0063     mlxfw_mfa2_tlv_multi_foreach(mfa2_file, tlv, idx, multi) {
0064         if (!tlv) {
0065             pr_err("TLV parsing error\n");
0066             return NULL;
0067         }
0068         if (tlv->type == type)
0069             if (skip++ == index)
0070                 return tlv;
0071     }
0072     return NULL;
0073 }
0074 
0075 int mlxfw_mfa2_tlv_multi_child_count(const struct mlxfw_mfa2_file *mfa2_file,
0076                      const struct mlxfw_mfa2_tlv_multi *multi,
0077                      enum mlxfw_mfa2_tlv_type type,
0078                      u16 *p_count)
0079 {
0080     const struct mlxfw_mfa2_tlv *tlv;
0081     u16 count = 0;
0082     u16 idx;
0083 
0084     mlxfw_mfa2_tlv_multi_foreach(mfa2_file, tlv, idx, multi) {
0085         if (!tlv) {
0086             pr_err("TLV parsing error\n");
0087             return -EINVAL;
0088         }
0089 
0090         if (tlv->type == type)
0091             count++;
0092     }
0093     *p_count = count;
0094     return 0;
0095 }