| /* 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__ */ |