162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/****************************************************************************** 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci AudioScience HPI driver 562306a36Sopenharmony_ci Copyright (C) 1997-2014 AudioScience Inc. <support@audioscience.com> 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci Hardware Programming Interface (HPI) Utility functions. 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci (C) Copyright AudioScience Inc. 2007 1162306a36Sopenharmony_ci*******************************************************************************/ 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include "hpi_internal.h" 1462306a36Sopenharmony_ci#include "hpimsginit.h" 1562306a36Sopenharmony_ci#include <linux/nospec.h> 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci/* The actual message size for each object type */ 1862306a36Sopenharmony_cistatic u16 msg_size[HPI_OBJ_MAXINDEX + 1] = HPI_MESSAGE_SIZE_BY_OBJECT; 1962306a36Sopenharmony_ci/* The actual response size for each object type */ 2062306a36Sopenharmony_cistatic u16 res_size[HPI_OBJ_MAXINDEX + 1] = HPI_RESPONSE_SIZE_BY_OBJECT; 2162306a36Sopenharmony_ci/* Flag to enable alternate message type for SSX2 bypass. */ 2262306a36Sopenharmony_cistatic u16 gwSSX2_bypass; 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci/** \internal 2562306a36Sopenharmony_ci * initialize the HPI message structure 2662306a36Sopenharmony_ci */ 2762306a36Sopenharmony_cistatic void hpi_init_message(struct hpi_message *phm, u16 object, 2862306a36Sopenharmony_ci u16 function) 2962306a36Sopenharmony_ci{ 3062306a36Sopenharmony_ci u16 size; 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) { 3362306a36Sopenharmony_ci object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1); 3462306a36Sopenharmony_ci size = msg_size[object]; 3562306a36Sopenharmony_ci } else { 3662306a36Sopenharmony_ci size = sizeof(*phm); 3762306a36Sopenharmony_ci } 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci memset(phm, 0, size); 4062306a36Sopenharmony_ci phm->size = size; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci if (gwSSX2_bypass) 4362306a36Sopenharmony_ci phm->type = HPI_TYPE_SSX2BYPASS_MESSAGE; 4462306a36Sopenharmony_ci else 4562306a36Sopenharmony_ci phm->type = HPI_TYPE_REQUEST; 4662306a36Sopenharmony_ci phm->object = object; 4762306a36Sopenharmony_ci phm->function = function; 4862306a36Sopenharmony_ci phm->version = 0; 4962306a36Sopenharmony_ci phm->adapter_index = HPI_ADAPTER_INDEX_INVALID; 5062306a36Sopenharmony_ci /* Expect actual adapter index to be set by caller */ 5162306a36Sopenharmony_ci} 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci/** \internal 5462306a36Sopenharmony_ci * initialize the HPI response structure 5562306a36Sopenharmony_ci */ 5662306a36Sopenharmony_civoid hpi_init_response(struct hpi_response *phr, u16 object, u16 function, 5762306a36Sopenharmony_ci u16 error) 5862306a36Sopenharmony_ci{ 5962306a36Sopenharmony_ci u16 size; 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) { 6262306a36Sopenharmony_ci object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1); 6362306a36Sopenharmony_ci size = res_size[object]; 6462306a36Sopenharmony_ci } else { 6562306a36Sopenharmony_ci size = sizeof(*phr); 6662306a36Sopenharmony_ci } 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci memset(phr, 0, sizeof(*phr)); 6962306a36Sopenharmony_ci phr->size = size; 7062306a36Sopenharmony_ci phr->type = HPI_TYPE_RESPONSE; 7162306a36Sopenharmony_ci phr->object = object; 7262306a36Sopenharmony_ci phr->function = function; 7362306a36Sopenharmony_ci phr->error = error; 7462306a36Sopenharmony_ci phr->specific_error = 0; 7562306a36Sopenharmony_ci phr->version = 0; 7662306a36Sopenharmony_ci} 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_civoid hpi_init_message_response(struct hpi_message *phm, 7962306a36Sopenharmony_ci struct hpi_response *phr, u16 object, u16 function) 8062306a36Sopenharmony_ci{ 8162306a36Sopenharmony_ci hpi_init_message(phm, object, function); 8262306a36Sopenharmony_ci /* default error return if the response is 8362306a36Sopenharmony_ci not filled in by the callee */ 8462306a36Sopenharmony_ci hpi_init_response(phr, object, function, 8562306a36Sopenharmony_ci HPI_ERROR_PROCESSING_MESSAGE); 8662306a36Sopenharmony_ci} 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_cistatic void hpi_init_messageV1(struct hpi_message_header *phm, u16 size, 8962306a36Sopenharmony_ci u16 object, u16 function) 9062306a36Sopenharmony_ci{ 9162306a36Sopenharmony_ci memset(phm, 0, size); 9262306a36Sopenharmony_ci if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) { 9362306a36Sopenharmony_ci phm->size = size; 9462306a36Sopenharmony_ci phm->type = HPI_TYPE_REQUEST; 9562306a36Sopenharmony_ci phm->object = object; 9662306a36Sopenharmony_ci phm->function = function; 9762306a36Sopenharmony_ci phm->version = 1; 9862306a36Sopenharmony_ci /* Expect adapter index to be set by caller */ 9962306a36Sopenharmony_ci } 10062306a36Sopenharmony_ci} 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_civoid hpi_init_responseV1(struct hpi_response_header *phr, u16 size, 10362306a36Sopenharmony_ci u16 object, u16 function) 10462306a36Sopenharmony_ci{ 10562306a36Sopenharmony_ci (void)object; 10662306a36Sopenharmony_ci (void)function; 10762306a36Sopenharmony_ci memset(phr, 0, size); 10862306a36Sopenharmony_ci phr->size = size; 10962306a36Sopenharmony_ci phr->version = 1; 11062306a36Sopenharmony_ci phr->type = HPI_TYPE_RESPONSE; 11162306a36Sopenharmony_ci phr->error = HPI_ERROR_PROCESSING_MESSAGE; 11262306a36Sopenharmony_ci} 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_civoid hpi_init_message_responseV1(struct hpi_message_header *phm, u16 msg_size, 11562306a36Sopenharmony_ci struct hpi_response_header *phr, u16 res_size, u16 object, 11662306a36Sopenharmony_ci u16 function) 11762306a36Sopenharmony_ci{ 11862306a36Sopenharmony_ci hpi_init_messageV1(phm, msg_size, object, function); 11962306a36Sopenharmony_ci hpi_init_responseV1(phr, res_size, object, function); 12062306a36Sopenharmony_ci} 121