blob: cef81f7ceefd2cf49b0c6c3c8c950af41dde2663 [file] [log] [blame]
// SPDX-License-Identifier: GPL-2.0 OR Apache-2.0
/*
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef AOC_IPC_CORE_H
#define AOC_IPC_CORE_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __KERNEL__
#include <linux/kernel.h>
#else
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#endif
typedef void aoc_service;
/**
* Direction indicates Tx/Rx for each side of the link
* AOC UP FW -> AP communication
* AOC_DOWN AP -> FW communication
*/
typedef enum {
AOC_UP = 0,
AOC_DOWN = 1,
} aoc_direction;
/**
* Check if a passed in service is a queue
*
* \param[in] service pointer to a service
*
* \return true if service is a message queue, otherwise false
*/
bool aoc_service_is_queue(aoc_service *service);
/**
* Check if a passed in service is a ring
*
* \param[in] service pointer to a service
*
* \return true if service is a ring service, otherwise false
*/
bool aoc_service_is_ring(aoc_service *service);
/**
* Check if a passed in service is a buffer
*
* \param[in] service pointer to a service
*
* \return true if service is a named buffer, otherwise false
*/
bool aoc_service_is_buffer(aoc_service *service);
/**
* Return the interrupt index for a service
*
* \param[in] service pointer to a service
*
* \return interrupt index for the service
*/
int aoc_service_irq_index(aoc_service *service);
/**
* Return the name of a service
*
* \param[in] service pointer to a service
*
* \return the name of the service, or NULL on error
*/
const char *aoc_service_name(aoc_service *service);
/**
* Return the size of a message slot
*
* \param[in] service pointer to a service
* \param[in] dir direction for the message
*
* \return the size of a message slot, or 0 on error
*/
size_t aoc_service_message_size(aoc_service *service, aoc_direction dir);
/**
* Return the total number of message slots
*
* \param[in] service pointer to a service
* \param[in] dir direction for the message
*
* \return total number of message slots, or 0 on error
*/
size_t aoc_service_message_slots(aoc_service *service, aoc_direction dir);
/**
* Return the total size of the IPC region
*
* \param[in] service pointer to a service
* \param[in] dir direction for the message
*
* \return total size for all messages on a service
*/
size_t aoc_service_total_size(aoc_service *service, aoc_direction dir);
/**
* Return the number of pending messages to be read
*
* \param[in] service pointer to a service
* \param[in] dir direction for the message
*
* \return number of pending messages
*/
size_t aoc_service_slots_available_to_read(aoc_service *service,
aoc_direction dir);
/**
* Return the number of free slots available to write
*
* \param[in] service pointer to a service
* \param[in] dir direction for the message
*
* \return number of slots available to write
*/
size_t aoc_service_slots_available_to_write(aoc_service *service,
aoc_direction dir);
/**
* Check if any messages are available to read
*
* \param[in] service pointer to a service
* \param[in] dir direction for the message
*
* \return true if there are pending messages, otherwise false
*/
bool aoc_service_can_read_message(aoc_service *service, aoc_direction dir);
/**
* Check if there is a free message slot
*
* \param[in] service pointer to a service
* \param[in] dir direction for the message
*
* \return true if a message can be written, otherwise false
*/
bool aoc_service_can_write_message(aoc_service *service, aoc_direction dir);
/**
* Read one message out of the queue
*
* \param[in] service pointer to a service
* \param[in] base pointer to the base of IPC memory
* \param[in] dir direction for the message
* \param[out] dst memory to copy the message to
* \param[inout] size size of the buffer, then size of the outgoing message
*
* \return true if a message was read, otherwise false
*/
bool aoc_service_read_message(aoc_service *service, void *base,
aoc_direction dir, void *dst, size_t *size);
/**
* Write a message to the queue
*
* \param[in] service pointer to a service
* \param[in] base pointer to the base of IPC memory
* \param[in] dir direction for the message
* \param[in] dst memory to copy the message from
* \param[in] size size of the incoming message
*
* \return true if a message was read, otherwise false
*/
bool aoc_service_write_message(aoc_service *service, void *base,
aoc_direction dir, const void *dst, size_t size);
/**
* Total number of bytes read from a ring service
*
* \param[in] service pointer to a service
* \param[in] dir direction for the message
*
* \return total number of bytes read from the service, up to UINT32_MAX
*/
size_t aoc_ring_bytes_read(aoc_service *service, aoc_direction dir);
/**
* Total number of bytes written to a ring service
*
* \param[in] service pointer to a service
* \param[in] dir direction for the message
*
* \return total number of bytes written to the service, up to UINT32_MAX
*/
size_t aoc_ring_bytes_written(aoc_service *service, aoc_direction dir);
/**
* Tells if more data has been written to the ring than it's capacity
*
* \param[in] service pointer to a service
* \param[in] dir direction for the message
*
* \return true if data has been overflowed, otherwise false
*/
bool aoc_ring_did_overflow(aoc_service *service, aoc_direction dir);
/**
* Tells if notifications should be sent after writing data into the ring
*
* \param[in] service pointer to a service
*
* \return true if the receiver expects a notification after writes
*/
bool aoc_ring_is_push(aoc_service *service);
#ifdef __cplusplus
}
#endif
#endif /* AOC_IPC_CORE_H */