1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35#define pr_fmt(fmt) "MFA2: " fmt
36
37#include "mlxfw_mfa2_tlv_multi.h"
38#include <uapi/linux/netlink.h>
39
40#define MLXFW_MFA2_TLV_TOTAL_SIZE(tlv) \
41 NLA_ALIGN(sizeof(*(tlv)) + be16_to_cpu((tlv)->len))
42
43const struct mlxfw_mfa2_tlv *
44mlxfw_mfa2_tlv_multi_child(const struct mlxfw_mfa2_file *mfa2_file,
45 const struct mlxfw_mfa2_tlv_multi *multi)
46{
47 size_t multi_len;
48
49 multi_len = NLA_ALIGN(sizeof(struct mlxfw_mfa2_tlv_multi));
50 return mlxfw_mfa2_tlv_get(mfa2_file, (void *) multi + multi_len);
51}
52
53const struct mlxfw_mfa2_tlv *
54mlxfw_mfa2_tlv_next(const struct mlxfw_mfa2_file *mfa2_file,
55 const struct mlxfw_mfa2_tlv *tlv)
56{
57 const struct mlxfw_mfa2_tlv_multi *multi;
58 u16 tlv_len;
59 void *next;
60
61 tlv_len = MLXFW_MFA2_TLV_TOTAL_SIZE(tlv);
62
63 if (tlv->type == MLXFW_MFA2_TLV_MULTI_PART) {
64 multi = mlxfw_mfa2_tlv_multi_get(mfa2_file, tlv);
65 tlv_len = NLA_ALIGN(tlv_len + be16_to_cpu(multi->total_len));
66 }
67
68 next = (void *) tlv + tlv_len;
69 return mlxfw_mfa2_tlv_get(mfa2_file, next);
70}
71
72const struct mlxfw_mfa2_tlv *
73mlxfw_mfa2_tlv_advance(const struct mlxfw_mfa2_file *mfa2_file,
74 const struct mlxfw_mfa2_tlv *from_tlv, u16 count)
75{
76 const struct mlxfw_mfa2_tlv *tlv;
77 u16 idx;
78
79 mlxfw_mfa2_tlv_foreach(mfa2_file, tlv, idx, from_tlv, count)
80 if (!tlv)
81 return NULL;
82 return tlv;
83}
84
85const struct mlxfw_mfa2_tlv *
86mlxfw_mfa2_tlv_multi_child_find(const struct mlxfw_mfa2_file *mfa2_file,
87 const struct mlxfw_mfa2_tlv_multi *multi,
88 enum mlxfw_mfa2_tlv_type type, u16 index)
89{
90 const struct mlxfw_mfa2_tlv *tlv;
91 u16 skip = 0;
92 u16 idx;
93
94 mlxfw_mfa2_tlv_multi_foreach(mfa2_file, tlv, idx, multi) {
95 if (!tlv) {
96 pr_err("TLV parsing error\n");
97 return NULL;
98 }
99 if (tlv->type == type)
100 if (skip++ == index)
101 return tlv;
102 }
103 return NULL;
104}
105
106int mlxfw_mfa2_tlv_multi_child_count(const struct mlxfw_mfa2_file *mfa2_file,
107 const struct mlxfw_mfa2_tlv_multi *multi,
108 enum mlxfw_mfa2_tlv_type type,
109 u16 *p_count)
110{
111 const struct mlxfw_mfa2_tlv *tlv;
112 u16 count = 0;
113 u16 idx;
114
115 mlxfw_mfa2_tlv_multi_foreach(mfa2_file, tlv, idx, multi) {
116 if (!tlv) {
117 pr_err("TLV parsing error\n");
118 return -EINVAL;
119 }
120
121 if (tlv->type == type)
122 count++;
123 }
124 *p_count = count;
125 return 0;
126}
127