diff options
Diffstat (limited to 'sys/contrib/dev/iwlwifi/fw/dhc-utils.h')
| -rw-r--r-- | sys/contrib/dev/iwlwifi/fw/dhc-utils.h | 75 | 
1 files changed, 75 insertions, 0 deletions
| diff --git a/sys/contrib/dev/iwlwifi/fw/dhc-utils.h b/sys/contrib/dev/iwlwifi/fw/dhc-utils.h new file mode 100644 index 000000000000..983acee5cd7d --- /dev/null +++ b/sys/contrib/dev/iwlwifi/fw/dhc-utils.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* + * Copyright (C) 2021, 2025 Intel Corporation + */ +#ifndef __iwl_fw_dhc_utils_h__ +#define __iwl_fw_dhc_utils_h__ + +#include <linux/types.h> +#include "fw/img.h" +#include "api/commands.h" +#include "api/dhc.h" + +/** + * iwl_dhc_resp_status - return status of DHC response + * @fw: firwmware image information + * @pkt: response packet, must not be %NULL + * + * Returns: the status value of the DHC command or (u32)-1 if the + *	    response was too short. + */ +static inline u32 iwl_dhc_resp_status(const struct iwl_fw *fw, +				      struct iwl_rx_packet *pkt) +{ +	if (iwl_fw_lookup_notif_ver(fw, IWL_ALWAYS_LONG_GROUP, +				    DEBUG_HOST_COMMAND, 1) >= 2) { +		struct iwl_dhc_cmd_resp *resp = (void *)pkt->data; + +		if (iwl_rx_packet_payload_len(pkt) < sizeof(*resp)) +			return (u32)-1; + +		return le32_to_cpu(resp->status); +	} else { +		struct iwl_dhc_cmd_resp_v1 *resp = (void *)pkt->data; + +		if (iwl_rx_packet_payload_len(pkt) < sizeof(*resp)) +			return (u32)-1; + +		return le32_to_cpu(resp->status); +	} +} + +/** + * iwl_dhc_resp_data - return data pointer of DHC response + * @fw: firwmware image information + * @pkt: response packet, must not be %NULL + * @len: where to store the length + * + * Returns: The data pointer, or an ERR_PTR() if the data was + *	    not valid (too short). + */ +static inline void *iwl_dhc_resp_data(const struct iwl_fw *fw, +				      struct iwl_rx_packet *pkt, +				      unsigned int *len) +{ +	if (iwl_fw_lookup_notif_ver(fw, IWL_ALWAYS_LONG_GROUP, +				    DEBUG_HOST_COMMAND, 1) >= 2) { +		struct iwl_dhc_cmd_resp *resp = (void *)pkt->data; + +		if (iwl_rx_packet_payload_len(pkt) < sizeof(*resp)) +			return ERR_PTR(-EINVAL); + +		*len = iwl_rx_packet_payload_len(pkt) - sizeof(*resp); +		return (void *)&resp->data; +	} else { +		struct iwl_dhc_cmd_resp_v1 *resp = (void *)pkt->data; + +		if (iwl_rx_packet_payload_len(pkt) < sizeof(*resp)) +			return ERR_PTR(-EINVAL); + +		*len = iwl_rx_packet_payload_len(pkt) - sizeof(*resp); +		return (void *)&resp->data; +	} +} + +#endif  /* __iwl_fw_dhc_utils_h__ */ | 
