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