Skip to content

Commit d9c8390

Browse files
alewi-westermoandersson
authored andcommitted
soc: qcom: fix QMI encoding/decoding for basic elements
Extend the QMI byte encoding and decoding logic to support multiple basic data type sizes (u8, u16, u32, u64) using differnet macros for each type. Ensure correct handling of data sizes and proper byte order conversion on big-endian platforms by consistently applying these macros during encoding and decoding of basic elements. Signed-off-by: Alexander Wilhelm <alexander.wilhelm@westermo.com> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Link: https://lore.kernel.org/r/20251119104008.3505152-3-alexander.wilhelm@westermo.com Signed-off-by: Bjorn Andersson <andersson@kernel.org>
1 parent 5a6d033 commit d9c8390

1 file changed

Lines changed: 90 additions & 12 deletions

File tree

drivers/soc/qcom/qmi_encdec.c

Lines changed: 90 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,60 @@
2323
*p_length |= ((u8)*p_src) << 8; \
2424
} while (0)
2525

26-
#define QMI_ENCDEC_ENCODE_N_BYTES(p_dst, p_src, size) \
26+
#define QMI_ENCDEC_ENCODE_U8(p_dst, p_src) \
2727
do { \
28-
memcpy(p_dst, p_src, size); \
29-
p_dst = (u8 *)p_dst + size; \
30-
p_src = (u8 *)p_src + size; \
28+
memcpy(p_dst, p_src, sizeof(u8)); \
29+
p_dst = (u8 *)p_dst + sizeof(u8); \
30+
p_src = (u8 *)p_src + sizeof(u8); \
3131
} while (0)
3232

33-
#define QMI_ENCDEC_DECODE_N_BYTES(p_dst, p_src, size) \
33+
#define QMI_ENCDEC_ENCODE_U16(p_dst, p_src) \
3434
do { \
35-
memcpy(p_dst, p_src, size); \
36-
p_dst = (u8 *)p_dst + size; \
37-
p_src = (u8 *)p_src + size; \
35+
*(__le16 *)p_dst = __cpu_to_le16(*(u16 *)p_src); \
36+
p_dst = (u8 *)p_dst + sizeof(u16); \
37+
p_src = (u8 *)p_src + sizeof(u16); \
38+
} while (0)
39+
40+
#define QMI_ENCDEC_ENCODE_U32(p_dst, p_src) \
41+
do { \
42+
*(__le32 *)p_dst = __cpu_to_le32(*(u32 *)p_src); \
43+
p_dst = (u8 *)p_dst + sizeof(u32); \
44+
p_src = (u8 *)p_src + sizeof(u32); \
45+
} while (0)
46+
47+
#define QMI_ENCDEC_ENCODE_U64(p_dst, p_src) \
48+
do { \
49+
*(__le64 *)p_dst = __cpu_to_le64(*(u64 *)p_src); \
50+
p_dst = (u8 *)p_dst + sizeof(u64); \
51+
p_src = (u8 *)p_src + sizeof(u64); \
52+
} while (0)
53+
54+
#define QMI_ENCDEC_DECODE_U8(p_dst, p_src) \
55+
do { \
56+
memcpy(p_dst, p_src, sizeof(u8)); \
57+
p_dst = (u8 *)p_dst + sizeof(u8); \
58+
p_src = (u8 *)p_src + sizeof(u8); \
59+
} while (0)
60+
61+
#define QMI_ENCDEC_DECODE_U16(p_dst, p_src) \
62+
do { \
63+
*(u16 *)p_dst = __le16_to_cpu(*(__le16 *)p_src); \
64+
p_dst = (u8 *)p_dst + sizeof(u16); \
65+
p_src = (u8 *)p_src + sizeof(u16); \
66+
} while (0)
67+
68+
#define QMI_ENCDEC_DECODE_U32(p_dst, p_src) \
69+
do { \
70+
*(u32 *)p_dst = __le32_to_cpu(*(__le32 *)p_src); \
71+
p_dst = (u8 *)p_dst + sizeof(u32); \
72+
p_src = (u8 *)p_src + sizeof(u32); \
73+
} while (0)
74+
75+
#define QMI_ENCDEC_DECODE_U64(p_dst, p_src) \
76+
do { \
77+
*(u64 *)p_dst = __le64_to_cpu(*(__le64 *)p_src); \
78+
p_dst = (u8 *)p_dst + sizeof(u64); \
79+
p_src = (u8 *)p_src + sizeof(u64); \
3880
} while (0)
3981

4082
#define UPDATE_ENCODE_VARIABLES(temp_si, buf_dst, \
@@ -161,15 +203,33 @@ static int qmi_calc_min_msg_len(const struct qmi_elem_info *ei_array,
161203
* of primary data type which include u8 - u64 or similar. This
162204
* function returns the number of bytes of encoded information.
163205
*
164-
* Return: The number of bytes of encoded information.
206+
* Return: The number of bytes of encoded information on success or negative
207+
* errno on error.
165208
*/
166209
static int qmi_encode_basic_elem(void *buf_dst, const void *buf_src,
167210
u32 elem_len, u32 elem_size)
168211
{
169212
u32 i, rc = 0;
170213

171214
for (i = 0; i < elem_len; i++) {
172-
QMI_ENCDEC_ENCODE_N_BYTES(buf_dst, buf_src, elem_size);
215+
switch (elem_size) {
216+
case sizeof(u8):
217+
QMI_ENCDEC_ENCODE_U8(buf_dst, buf_src);
218+
break;
219+
case sizeof(u16):
220+
QMI_ENCDEC_ENCODE_U16(buf_dst, buf_src);
221+
break;
222+
case sizeof(u32):
223+
QMI_ENCDEC_ENCODE_U32(buf_dst, buf_src);
224+
break;
225+
case sizeof(u64):
226+
QMI_ENCDEC_ENCODE_U64(buf_dst, buf_src);
227+
break;
228+
default:
229+
pr_err("%s: Unrecognized element size\n", __func__);
230+
return -EINVAL;
231+
}
232+
173233
rc += elem_size;
174234
}
175235

@@ -456,15 +516,33 @@ static int qmi_encode(const struct qmi_elem_info *ei_array, void *out_buf,
456516
* of primary data type which include u8 - u64 or similar. This
457517
* function returns the number of bytes of decoded information.
458518
*
459-
* Return: The total size of the decoded data elements, in bytes.
519+
* Return: The total size of the decoded data elements, in bytes, on success or
520+
* negative errno on error.
460521
*/
461522
static int qmi_decode_basic_elem(void *buf_dst, const void *buf_src,
462523
u32 elem_len, u32 elem_size)
463524
{
464525
u32 i, rc = 0;
465526

466527
for (i = 0; i < elem_len; i++) {
467-
QMI_ENCDEC_DECODE_N_BYTES(buf_dst, buf_src, elem_size);
528+
switch (elem_size) {
529+
case sizeof(u8):
530+
QMI_ENCDEC_DECODE_U8(buf_dst, buf_src);
531+
break;
532+
case sizeof(u16):
533+
QMI_ENCDEC_DECODE_U16(buf_dst, buf_src);
534+
break;
535+
case sizeof(u32):
536+
QMI_ENCDEC_DECODE_U32(buf_dst, buf_src);
537+
break;
538+
case sizeof(u64):
539+
QMI_ENCDEC_DECODE_U64(buf_dst, buf_src);
540+
break;
541+
default:
542+
pr_err("%s: Unrecognized element size\n", __func__);
543+
return -EINVAL;
544+
}
545+
468546
rc += elem_size;
469547
}
470548

0 commit comments

Comments
 (0)