/* Copyright (C) 2018 RDA Technologies Limited and/or its affiliates("RDA"). * All rights reserved. * * This software is supplied "AS IS" without any warranties. * RDA assumes no responsibility or liability for the use of the software, * conveys no license or title under any patent, copyright, or mask work * right to the product. RDA reserves the right to make changes in the * software without notification. RDA also make no representation or * warranty that such application will be suitable for the specified use * without further testing or modification. */ #ifndef _DRV_IPC_FIFO_H_ #define _DRV_IPC_FIFO_H_ #include #ifdef __cplusplus extern "C" { #endif /** * \brief flag to indicate the fifo is ready */ #define DRV_IPC_FIFO_READY (1 << 0) /** * \brief forward declaration */ struct osiFifo; /** * \brief IPC fifo from the point of view of master * * There are 2 fifos for each IPC channel, one for send and the other * for receive. The fifo control data struct is located in the shared * memory. So, the fields of send for one side is the fields of receive * for the other side. This is the data struct for master. * * The data struct in shared memory should be 32 bytes aligned. * * For master side, it is recommened to define: * \code{.cpp} * typedef drvIpcFifoMasterCtrl_t drvIpcFifoCtrl_t; * \endcode */ typedef struct { struct { uint32_t status; ///< status uint32_t send_base; ///< send fifo base address uint32_t recv_base; ///< receive fifo base address uint32_t send_size; ///< send fifo size uint32_t recv_size; ///< receive fifo size uint32_t send_wr; ///< send fifo write position uint32_t recv_rd; ///< receive fifo read position uint32_t reserved[1]; ///< reserved } th; ///< this side (master) writable struct struct { uint32_t status; ///< status uint32_t send_base; ///< send fifo base address uint32_t recv_base; ///< receive fifo base address uint32_t send_size; ///< send fifo size uint32_t recv_size; ///< receive fifo size uint32_t send_rd; ///< send fifo read position uint32_t recv_wr; ///< receive fifo write position uint32_t reserved[1]; ///< reserved } peer; ///< peer side (slave) writable struct } drvIpcFifoMasterCtrl_t; /** * \brief IPC fifo from the point of view of slave * * For slave side, it is recommened to define: * \code{.cpp} * typedef drvIpcFifoSlaveCtrl_t drvIpcFifoCtrl_t; * \endcode * * Based on \p drvIpcFifoCtrl_t, the source codes for master and slave * are identical. */ typedef struct { struct { uint32_t status; ///< status uint32_t recv_base; ///< receive fifo base address uint32_t send_base; ///< send fifo base address uint32_t recv_size; ///< receive fifo size uint32_t send_size; ///< send fifo size uint32_t recv_wr; ///< receive fifo write position uint32_t send_rd; ///< send fifo read position uint32_t reserved[1]; ///< reserved } peer; ///< peer side (master) writable struct struct { uint32_t status; ///< status uint32_t recv_base; ///< receive fifo base address uint32_t send_base; ///< send fifo base address uint32_t recv_size; ///< receive fifo size uint32_t send_size; ///< send fifo size uint32_t recv_rd; ///< receive fifo write position uint32_t send_wr; ///< send fifo read position uint32_t reserved[1]; ///< reserved } th; ///< peer side (slave) writable struct } drvIpcFifoSlaveCtrl_t; /** * \brief ipc command header * * Usually, channel 0 is the control channel. And the data in control * channel is command packets. * * The command packet header is compatible with RPC packet. And \p opcode * shouldn't conflict with RPC when it is used for other purpose. Also, * multiple purposes can be mixed in one channel. * * \p size is required to be aligned to 8 bytes. When needed, the memory * in shared memory can be casted to \p drvIpcCmdHeader_t data struct. */ typedef struct { uint32_t opcode; ///< operation in command header uint32_t size; ///< the whole command packet size, including header } drvIpcCmdHeader_t; /** * \brief initialze ipc fifo (master) * * \param pctrl ipc fifo control * \param send_base send fifo base address * \param send_size send fifo size * \param recv_base receive fifo base address * \param recv_size receive fifo size */ void drvIpcFifoMasterInit(drvIpcFifoMasterCtrl_t *pctrl, unsigned send_base, unsigned send_size, unsigned recv_base, unsigned recv_size); /** * \brief ipc fifo read available byte count (master) * * \param pctrl ipc fifo control */ unsigned drvIpcFifoMasterAvail(drvIpcFifoMasterCtrl_t *pctrl); /** * \brief ipc fifo write space byte count (master) * * \param pctrl ipc fifo control */ unsigned drvIpcFifoMasterSpace(drvIpcFifoMasterCtrl_t *pctrl); /** * \brief read from ipc fifo (master) * * The returned real read size may be smaller than \p size. * * It is not thread safe. Thread safe shall be considered by caller. * * \param pctrl ipc fifo control * \param data memory for read * \param size memory size * \return real read size */ int drvIpcFifoMasterRead(drvIpcFifoMasterCtrl_t *pctrl, void *data, unsigned size); /** * \brief write to ipc fifo (master) * * The returned real written size may be smaller than \p size. * * It is not thread safe. Thread safe shall be considered by caller. * * \param pctrl ipc fifo control * \param data data to be written * \param size data size * \return real written size */ int drvIpcFifoMasterWrite(drvIpcFifoMasterCtrl_t *pctrl, const void *data, unsigned size); /** * \brief read from ipc fifo and write to local fifo (master) * * It is not thread safe. Thread safe shall be considered by caller. * * \param pctrl ipc fifo control * \param fifo local fifo * \return real read size */ int drvIpcFifoMasterReadToFifo(drvIpcFifoMasterCtrl_t *pctrl, struct osiFifo *fifo); /** * \brief write to ipc fifo and read from local fifo (master) * * It is not thread safe. Thread safe shall be considered by caller. * * \param pctrl ipc fifo control * \param fifo local fifo * \return real written size */ int drvIpcFifoMasterWriteFromFifo(drvIpcFifoMasterCtrl_t *pctrl, struct osiFifo *fifo); /** * \brief initialze ipc fifo (slave) * * \param pctrl ipc fifo control */ void drvIpcFifoSlaveInit(drvIpcFifoSlaveCtrl_t *pctrl); /** * \brief ipc fifo read available byte count (slave) * * \param pctrl ipc fifo control */ unsigned drvIpcFifoSlaveAvail(drvIpcFifoSlaveCtrl_t *pctrl); /** * \brief ipc fifo write space byte count (slave) * * \param pctrl ipc fifo control */ unsigned drvIpcFifoSlaveSpace(drvIpcFifoSlaveCtrl_t *pctrl); /** * \brief read from ipc fifo (slave) * * It is similar to \p drvIpcFifoMasterRead, just the fifo control is * interpreted as slave. * * \param pctrl ipc fifo control * \param data memory for read * \param size memory size * \return real read size */ int drvIpcFifoSlaveRead(drvIpcFifoSlaveCtrl_t *pctrl, void *data, unsigned size); /** * \brief write to ipc fifo (slave) * * It is similar to \p drvIpcFifoMasterWrite, just the fifo control is * interpreted as slave. * * \param pctrl ipc fifo control * \param data data to be written * \param size data size * \return real written size */ int drvIpcFifoSlaveWrite(drvIpcFifoSlaveCtrl_t *pctrl, const void *data, unsigned size); /** * \brief read from ipc fifo and write to local fifo (slave) * * It is similar to \p drvIpcFifoMasterReadToFifo, just the fifo control is * interpreted as slave. * * \param pctrl ipc fifo control * \param fifo local fifo * \return real read size */ int drvIpcFifoSlaveReadToFifo(drvIpcFifoSlaveCtrl_t *pctrl, struct osiFifo *fifo); /** * \brief write to ipc fifo and read from local fifo (slave) * * It is not thread safe. Thread safe shall be considered by caller. * * \param pctrl ipc fifo control * \param fifo local fifo * \return real written size */ int drvIpcFifoSlaveWriteFromFifo(drvIpcFifoSlaveCtrl_t *pctrl, struct osiFifo *fifo); #ifdef __cplusplus } #endif #endif