1// SPDX-License-Identifier: GPL-2.0-only
2/******************************************************************************
3
4    AudioScience HPI driver
5    Copyright (C) 1997-2014  AudioScience Inc. <support@audioscience.com>
6
7
8 Hardware Programming Interface (HPI) Utility functions.
9
10 (C) Copyright AudioScience Inc. 2007
11*******************************************************************************/
12
13#include "hpi_internal.h"
14#include "hpimsginit.h"
15#include <linux/nospec.h>
16
17/* The actual message size for each object type */
18static u16 msg_size[HPI_OBJ_MAXINDEX + 1] = HPI_MESSAGE_SIZE_BY_OBJECT;
19/* The actual response size for each object type */
20static u16 res_size[HPI_OBJ_MAXINDEX + 1] = HPI_RESPONSE_SIZE_BY_OBJECT;
21/* Flag to enable alternate message type for SSX2 bypass. */
22static u16 gwSSX2_bypass;
23
24/** \internal
25  * initialize the HPI message structure
26  */
27static void hpi_init_message(struct hpi_message *phm, u16 object,
28	u16 function)
29{
30	u16 size;
31
32	if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
33		object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1);
34		size = msg_size[object];
35	} else {
36		size = sizeof(*phm);
37	}
38
39	memset(phm, 0, size);
40	phm->size = size;
41
42	if (gwSSX2_bypass)
43		phm->type = HPI_TYPE_SSX2BYPASS_MESSAGE;
44	else
45		phm->type = HPI_TYPE_REQUEST;
46	phm->object = object;
47	phm->function = function;
48	phm->version = 0;
49	phm->adapter_index = HPI_ADAPTER_INDEX_INVALID;
50	/* Expect actual adapter index to be set by caller */
51}
52
53/** \internal
54  * initialize the HPI response structure
55  */
56void hpi_init_response(struct hpi_response *phr, u16 object, u16 function,
57	u16 error)
58{
59	u16 size;
60
61	if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
62		object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1);
63		size = res_size[object];
64	} else {
65		size = sizeof(*phr);
66	}
67
68	memset(phr, 0, sizeof(*phr));
69	phr->size = size;
70	phr->type = HPI_TYPE_RESPONSE;
71	phr->object = object;
72	phr->function = function;
73	phr->error = error;
74	phr->specific_error = 0;
75	phr->version = 0;
76}
77
78void hpi_init_message_response(struct hpi_message *phm,
79	struct hpi_response *phr, u16 object, u16 function)
80{
81	hpi_init_message(phm, object, function);
82	/* default error return if the response is
83	   not filled in by the callee */
84	hpi_init_response(phr, object, function,
85		HPI_ERROR_PROCESSING_MESSAGE);
86}
87
88static void hpi_init_messageV1(struct hpi_message_header *phm, u16 size,
89	u16 object, u16 function)
90{
91	memset(phm, 0, size);
92	if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
93		phm->size = size;
94		phm->type = HPI_TYPE_REQUEST;
95		phm->object = object;
96		phm->function = function;
97		phm->version = 1;
98		/* Expect adapter index to be set by caller */
99	}
100}
101
102void hpi_init_responseV1(struct hpi_response_header *phr, u16 size,
103	u16 object, u16 function)
104{
105	(void)object;
106	(void)function;
107	memset(phr, 0, size);
108	phr->size = size;
109	phr->version = 1;
110	phr->type = HPI_TYPE_RESPONSE;
111	phr->error = HPI_ERROR_PROCESSING_MESSAGE;
112}
113
114void hpi_init_message_responseV1(struct hpi_message_header *phm, u16 msg_size,
115	struct hpi_response_header *phr, u16 res_size, u16 object,
116	u16 function)
117{
118	hpi_init_messageV1(phm, msg_size, object, function);
119	hpi_init_responseV1(phr, res_size, object, function);
120}
121