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