// SPDX-License-Identifier: GPL-2.0-only /* * ISHTP client logic * * Copyright (c) 2003-2016, Intel Corporation. */ #include <linux/slab.h> #include <linux/sched.h> #include <linux/wait.h> #include <linux/delay.h> #include <linux/dma-mapping.h> #include <asm/cacheflush.h> #include "hbm.h" #include "client.h" int ishtp_cl_get_tx_free_buffer_size(struct ishtp_cl *cl) { … } EXPORT_SYMBOL(…); int ishtp_cl_get_tx_free_rings(struct ishtp_cl *cl) { … } EXPORT_SYMBOL(…); /** * ishtp_read_list_flush() - Flush read queue * @cl: ishtp client instance * * Used to remove all entries from read queue for a client */ static void ishtp_read_list_flush(struct ishtp_cl *cl) { … } /** * ishtp_cl_flush_queues() - Flush all queues for a client * @cl: ishtp client instance * * Used to remove all queues for a client. This is called when a client device * needs reset due to error, S3 resume or during module removal * * Return: 0 on success else -EINVAL if device is NULL */ int ishtp_cl_flush_queues(struct ishtp_cl *cl) { … } EXPORT_SYMBOL(…); /** * ishtp_cl_init() - Initialize all fields of a client device * @cl: ishtp client instance * @dev: ishtp device * * Initializes a client device fields: Init spinlocks, init queues etc. * This function is called during new client creation */ static void ishtp_cl_init(struct ishtp_cl *cl, struct ishtp_device *dev) { … } /** * ishtp_cl_allocate() - allocates client structure and sets it up. * @cl_device: ishtp client device * * Allocate memory for new client device and call to initialize each field. * * Return: The allocated client instance or NULL on failure */ struct ishtp_cl *ishtp_cl_allocate(struct ishtp_cl_device *cl_device) { … } EXPORT_SYMBOL(…); /** * ishtp_cl_free() - Frees a client device * @cl: client device instance * * Frees a client device */ void ishtp_cl_free(struct ishtp_cl *cl) { … } EXPORT_SYMBOL(…); /** * ishtp_cl_link() - Reserve a host id and link the client instance * @cl: client device instance * * This allocates a single bit in the hostmap. This function will make sure * that not many client sessions are opened at the same time. Once allocated * the client device instance is added to the ishtp device in the current * client list * * Return: 0 or error code on failure */ int ishtp_cl_link(struct ishtp_cl *cl) { … } EXPORT_SYMBOL(…); /** * ishtp_cl_unlink() - remove fw_cl from the client device list * @cl: client device instance * * Remove a previously linked device to a ishtp device */ void ishtp_cl_unlink(struct ishtp_cl *cl) { … } EXPORT_SYMBOL(…); /** * ishtp_cl_disconnect() - Send disconnect request to firmware * @cl: client device instance * * Send a disconnect request for a client to firmware. * * Return: 0 if successful disconnect response from the firmware or error * code on failure */ int ishtp_cl_disconnect(struct ishtp_cl *cl) { … } EXPORT_SYMBOL(…); /** * ishtp_cl_is_other_connecting() - Check other client is connecting * @cl: client device instance * * Checks if other client with the same fw client id is connecting * * Return: true if other client is connected else false */ static bool ishtp_cl_is_other_connecting(struct ishtp_cl *cl) { … } /** * ishtp_cl_connect_to_fw() - Send connect request to firmware * @cl: client device instance * * Send a connect request to the firmware and wait for firmware response. * If there is successful connection response from the firmware, change * client state to ISHTP_CL_CONNECTED, and bind client to related * firmware client_id. * * Return: 0 for success and error code on failure */ static int ishtp_cl_connect_to_fw(struct ishtp_cl *cl) { … } /** * ishtp_cl_connect() - Build connection with firmware * @cl: client device instance * * Call ishtp_cl_connect_to_fw() to connect and bind to firmware. If successful, * allocate RX and TX ring buffers, and start flow control with firmware to * start communication. * * Return: 0 if there is successful connection to the firmware, allocate * ring buffers. */ int ishtp_cl_connect(struct ishtp_cl *cl) { … } EXPORT_SYMBOL(…); /** * ishtp_cl_establish_connection() - Establish connection with the firmware * @cl: client device instance * @uuid: uuid of the client to search * @tx_size: TX ring buffer size * @rx_size: RX ring buffer size * @reset: true if called for reset connection, otherwise for first connection * * This is a helper function for client driver to build connection with firmware. * If it's first time connecting to the firmware, set reset to false, this * function will link client to bus, find client id and send connect request to * the firmware. * * If it's called for reset handler where client lost connection after * firmware reset, set reset to true, this function will reinit client state and * establish connection again. In this case, this function reuses current client * structure and ring buffers to avoid allocation failure and memory fragments. * * Return: 0 for successful connection with the firmware, * or error code on failure */ int ishtp_cl_establish_connection(struct ishtp_cl *cl, const guid_t *uuid, int tx_size, int rx_size, bool reset) { … } EXPORT_SYMBOL(…); /** * ishtp_cl_destroy_connection() - Disconnect with the firmware * @cl: client device instance * @reset: true if called for firmware reset, false for normal disconnection * * This is a helper function for client driver to disconnect with firmware, * unlink to bus and flush message queue. */ void ishtp_cl_destroy_connection(struct ishtp_cl *cl, bool reset) { … } EXPORT_SYMBOL(…); /** * ishtp_cl_read_start() - Prepare to read client message * @cl: client device instance * * Get a free buffer from pool of free read buffers and add to read buffer * pool to add contents. Send a flow control request to firmware to be able * send next message. * * Return: 0 if successful or error code on failure */ int ishtp_cl_read_start(struct ishtp_cl *cl) { … } /** * ishtp_cl_send() - Send a message to firmware * @cl: client device instance * @buf: message buffer * @length: length of message * * If the client is correct state to send message, this function gets a buffer * from tx ring buffers, copy the message data and call to send the message * using ishtp_cl_send_msg() * * Return: 0 if successful or error code on failure */ int ishtp_cl_send(struct ishtp_cl *cl, uint8_t *buf, size_t length) { … } EXPORT_SYMBOL(…); /** * ishtp_cl_read_complete() - read complete * @rb: Pointer to client request block * * If the message is completely received call ishtp_cl_bus_rx_event() * to process message */ static void ishtp_cl_read_complete(struct ishtp_cl_rb *rb) { … } /** * ipc_tx_send() - IPC tx send function * @prm: Pointer to client device instance * * Send message over IPC. Message will be split into fragments * if message size is bigger than IPC FIFO size, and all * fragments will be sent one by one. */ static void ipc_tx_send(void *prm) { … } /** * ishtp_cl_send_msg_ipc() -Send message using IPC * @dev: ISHTP device instance * @cl: Pointer to client device instance * * Send message over IPC not using DMA */ static void ishtp_cl_send_msg_ipc(struct ishtp_device *dev, struct ishtp_cl *cl) { … } /** * ishtp_cl_send_msg_dma() -Send message using DMA * @dev: ISHTP device instance * @cl: Pointer to client device instance * * Send message using DMA */ static void ishtp_cl_send_msg_dma(struct ishtp_device *dev, struct ishtp_cl *cl) { … } /** * ishtp_cl_send_msg() -Send message using DMA or IPC * @dev: ISHTP device instance * @cl: Pointer to client device instance * * Send message using DMA or IPC based on transfer_path */ void ishtp_cl_send_msg(struct ishtp_device *dev, struct ishtp_cl *cl) { … } /** * recv_ishtp_cl_msg() -Receive client message * @dev: ISHTP device instance * @ishtp_hdr: Pointer to message header * * Receive and dispatch ISHTP client messages. This function executes in ISR * or work queue context */ void recv_ishtp_cl_msg(struct ishtp_device *dev, struct ishtp_msg_hdr *ishtp_hdr) { … } /** * recv_ishtp_cl_msg_dma() -Receive client message * @dev: ISHTP device instance * @msg: message pointer * @hbm: hbm buffer * * Receive and dispatch ISHTP client messages using DMA. This function executes * in ISR or work queue context */ void recv_ishtp_cl_msg_dma(struct ishtp_device *dev, void *msg, struct dma_xfer_hbm *hbm) { … } void *ishtp_get_client_data(struct ishtp_cl *cl) { … } EXPORT_SYMBOL(…); void ishtp_set_client_data(struct ishtp_cl *cl, void *data) { … } EXPORT_SYMBOL(…); struct ishtp_device *ishtp_get_ishtp_device(struct ishtp_cl *cl) { … } EXPORT_SYMBOL(…); void ishtp_set_tx_ring_size(struct ishtp_cl *cl, int size) { … } EXPORT_SYMBOL(…); void ishtp_set_rx_ring_size(struct ishtp_cl *cl, int size) { … } EXPORT_SYMBOL(…); void ishtp_set_connection_state(struct ishtp_cl *cl, int state) { … } EXPORT_SYMBOL(…); void ishtp_cl_set_fw_client_id(struct ishtp_cl *cl, int fw_client_id) { … } EXPORT_SYMBOL(…);