1 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
2 /*
3 * Copyright (C) 2021, 2025 Intel Corporation
4 */
5 #ifndef __iwl_fw_dhc_utils_h__
6 #define __iwl_fw_dhc_utils_h__
7
8 #include <linux/types.h>
9 #include "fw/img.h"
10 #include "api/commands.h"
11 #include "api/dhc.h"
12
13 /**
14 * iwl_dhc_resp_status - return status of DHC response
15 * @fw: firwmware image information
16 * @pkt: response packet, must not be %NULL
17 *
18 * Returns: the status value of the DHC command or (u32)-1 if the
19 * response was too short.
20 */
iwl_dhc_resp_status(const struct iwl_fw * fw,struct iwl_rx_packet * pkt)21 static inline u32 iwl_dhc_resp_status(const struct iwl_fw *fw,
22 struct iwl_rx_packet *pkt)
23 {
24 if (iwl_fw_lookup_notif_ver(fw, IWL_ALWAYS_LONG_GROUP,
25 DEBUG_HOST_COMMAND, 1) >= 2) {
26 struct iwl_dhc_cmd_resp *resp = (void *)pkt->data;
27
28 if (iwl_rx_packet_payload_len(pkt) < sizeof(*resp))
29 return (u32)-1;
30
31 return le32_to_cpu(resp->status);
32 } else {
33 struct iwl_dhc_cmd_resp_v1 *resp = (void *)pkt->data;
34
35 if (iwl_rx_packet_payload_len(pkt) < sizeof(*resp))
36 return (u32)-1;
37
38 return le32_to_cpu(resp->status);
39 }
40 }
41
42 /**
43 * iwl_dhc_resp_data - return data pointer of DHC response
44 * @fw: firwmware image information
45 * @pkt: response packet, must not be %NULL
46 * @len: where to store the length
47 *
48 * Returns: The data pointer, or an ERR_PTR() if the data was
49 * not valid (too short).
50 */
iwl_dhc_resp_data(const struct iwl_fw * fw,struct iwl_rx_packet * pkt,unsigned int * len)51 static inline void *iwl_dhc_resp_data(const struct iwl_fw *fw,
52 struct iwl_rx_packet *pkt,
53 unsigned int *len)
54 {
55 if (iwl_fw_lookup_notif_ver(fw, IWL_ALWAYS_LONG_GROUP,
56 DEBUG_HOST_COMMAND, 1) >= 2) {
57 struct iwl_dhc_cmd_resp *resp = (void *)pkt->data;
58
59 if (iwl_rx_packet_payload_len(pkt) < sizeof(*resp))
60 return ERR_PTR(-EINVAL);
61
62 *len = iwl_rx_packet_payload_len(pkt) - sizeof(*resp);
63 return (void *)&resp->data;
64 } else {
65 struct iwl_dhc_cmd_resp_v1 *resp = (void *)pkt->data;
66
67 if (iwl_rx_packet_payload_len(pkt) < sizeof(*resp))
68 return ERR_PTR(-EINVAL);
69
70 *len = iwl_rx_packet_payload_len(pkt) - sizeof(*resp);
71 return (void *)&resp->data;
72 }
73 }
74
75 #endif /* __iwl_fw_dhc_utils_h__ */
76