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