18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/******************************************************************************
38c2ecf20Sopenharmony_ci
48c2ecf20Sopenharmony_ci    AudioScience HPI driver
58c2ecf20Sopenharmony_ci    Copyright (C) 1997-2014  AudioScience Inc. <support@audioscience.com>
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci Hardware Programming Interface (HPI) Utility functions.
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci (C) Copyright AudioScience Inc. 2007
118c2ecf20Sopenharmony_ci*******************************************************************************/
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#include "hpi_internal.h"
148c2ecf20Sopenharmony_ci#include "hpimsginit.h"
158c2ecf20Sopenharmony_ci#include <linux/nospec.h>
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci/* The actual message size for each object type */
188c2ecf20Sopenharmony_cistatic u16 msg_size[HPI_OBJ_MAXINDEX + 1] = HPI_MESSAGE_SIZE_BY_OBJECT;
198c2ecf20Sopenharmony_ci/* The actual response size for each object type */
208c2ecf20Sopenharmony_cistatic u16 res_size[HPI_OBJ_MAXINDEX + 1] = HPI_RESPONSE_SIZE_BY_OBJECT;
218c2ecf20Sopenharmony_ci/* Flag to enable alternate message type for SSX2 bypass. */
228c2ecf20Sopenharmony_cistatic u16 gwSSX2_bypass;
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci/** \internal
258c2ecf20Sopenharmony_ci  * initialize the HPI message structure
268c2ecf20Sopenharmony_ci  */
278c2ecf20Sopenharmony_cistatic void hpi_init_message(struct hpi_message *phm, u16 object,
288c2ecf20Sopenharmony_ci	u16 function)
298c2ecf20Sopenharmony_ci{
308c2ecf20Sopenharmony_ci	u16 size;
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci	if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
338c2ecf20Sopenharmony_ci		object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1);
348c2ecf20Sopenharmony_ci		size = msg_size[object];
358c2ecf20Sopenharmony_ci	} else {
368c2ecf20Sopenharmony_ci		size = sizeof(*phm);
378c2ecf20Sopenharmony_ci	}
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci	memset(phm, 0, size);
408c2ecf20Sopenharmony_ci	phm->size = size;
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci	if (gwSSX2_bypass)
438c2ecf20Sopenharmony_ci		phm->type = HPI_TYPE_SSX2BYPASS_MESSAGE;
448c2ecf20Sopenharmony_ci	else
458c2ecf20Sopenharmony_ci		phm->type = HPI_TYPE_REQUEST;
468c2ecf20Sopenharmony_ci	phm->object = object;
478c2ecf20Sopenharmony_ci	phm->function = function;
488c2ecf20Sopenharmony_ci	phm->version = 0;
498c2ecf20Sopenharmony_ci	phm->adapter_index = HPI_ADAPTER_INDEX_INVALID;
508c2ecf20Sopenharmony_ci	/* Expect actual adapter index to be set by caller */
518c2ecf20Sopenharmony_ci}
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci/** \internal
548c2ecf20Sopenharmony_ci  * initialize the HPI response structure
558c2ecf20Sopenharmony_ci  */
568c2ecf20Sopenharmony_civoid hpi_init_response(struct hpi_response *phr, u16 object, u16 function,
578c2ecf20Sopenharmony_ci	u16 error)
588c2ecf20Sopenharmony_ci{
598c2ecf20Sopenharmony_ci	u16 size;
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci	if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
628c2ecf20Sopenharmony_ci		object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1);
638c2ecf20Sopenharmony_ci		size = res_size[object];
648c2ecf20Sopenharmony_ci	} else {
658c2ecf20Sopenharmony_ci		size = sizeof(*phr);
668c2ecf20Sopenharmony_ci	}
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	memset(phr, 0, sizeof(*phr));
698c2ecf20Sopenharmony_ci	phr->size = size;
708c2ecf20Sopenharmony_ci	phr->type = HPI_TYPE_RESPONSE;
718c2ecf20Sopenharmony_ci	phr->object = object;
728c2ecf20Sopenharmony_ci	phr->function = function;
738c2ecf20Sopenharmony_ci	phr->error = error;
748c2ecf20Sopenharmony_ci	phr->specific_error = 0;
758c2ecf20Sopenharmony_ci	phr->version = 0;
768c2ecf20Sopenharmony_ci}
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_civoid hpi_init_message_response(struct hpi_message *phm,
798c2ecf20Sopenharmony_ci	struct hpi_response *phr, u16 object, u16 function)
808c2ecf20Sopenharmony_ci{
818c2ecf20Sopenharmony_ci	hpi_init_message(phm, object, function);
828c2ecf20Sopenharmony_ci	/* default error return if the response is
838c2ecf20Sopenharmony_ci	   not filled in by the callee */
848c2ecf20Sopenharmony_ci	hpi_init_response(phr, object, function,
858c2ecf20Sopenharmony_ci		HPI_ERROR_PROCESSING_MESSAGE);
868c2ecf20Sopenharmony_ci}
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_cistatic void hpi_init_messageV1(struct hpi_message_header *phm, u16 size,
898c2ecf20Sopenharmony_ci	u16 object, u16 function)
908c2ecf20Sopenharmony_ci{
918c2ecf20Sopenharmony_ci	memset(phm, 0, size);
928c2ecf20Sopenharmony_ci	if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
938c2ecf20Sopenharmony_ci		phm->size = size;
948c2ecf20Sopenharmony_ci		phm->type = HPI_TYPE_REQUEST;
958c2ecf20Sopenharmony_ci		phm->object = object;
968c2ecf20Sopenharmony_ci		phm->function = function;
978c2ecf20Sopenharmony_ci		phm->version = 1;
988c2ecf20Sopenharmony_ci		/* Expect adapter index to be set by caller */
998c2ecf20Sopenharmony_ci	}
1008c2ecf20Sopenharmony_ci}
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_civoid hpi_init_responseV1(struct hpi_response_header *phr, u16 size,
1038c2ecf20Sopenharmony_ci	u16 object, u16 function)
1048c2ecf20Sopenharmony_ci{
1058c2ecf20Sopenharmony_ci	(void)object;
1068c2ecf20Sopenharmony_ci	(void)function;
1078c2ecf20Sopenharmony_ci	memset(phr, 0, size);
1088c2ecf20Sopenharmony_ci	phr->size = size;
1098c2ecf20Sopenharmony_ci	phr->version = 1;
1108c2ecf20Sopenharmony_ci	phr->type = HPI_TYPE_RESPONSE;
1118c2ecf20Sopenharmony_ci	phr->error = HPI_ERROR_PROCESSING_MESSAGE;
1128c2ecf20Sopenharmony_ci}
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_civoid hpi_init_message_responseV1(struct hpi_message_header *phm, u16 msg_size,
1158c2ecf20Sopenharmony_ci	struct hpi_response_header *phr, u16 res_size, u16 object,
1168c2ecf20Sopenharmony_ci	u16 function)
1178c2ecf20Sopenharmony_ci{
1188c2ecf20Sopenharmony_ci	hpi_init_messageV1(phm, msg_size, object, function);
1198c2ecf20Sopenharmony_ci	hpi_init_responseV1(phr, res_size, object, function);
1208c2ecf20Sopenharmony_ci}
121