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