diff --git a/include/rogue/hardware/drivers/AxisDriver.h b/include/rogue/hardware/drivers/AxisDriver.h index cefe829b0..104b98289 100644 --- a/include/rogue/hardware/drivers/AxisDriver.h +++ b/include/rogue/hardware/drivers/AxisDriver.h @@ -1,9 +1,14 @@ /** *----------------------------------------------------------------------------- - * Title : AXIS DMA Driver, Shared Header + * Company : SLAC National Accelerator Laboratory * ---------------------------------------------------------------------------- * Description: - * Definitions and inline functions for interacting with AXIS driver. + * This file contains definitions and inline functions for interacting + * with the AXIS driver as part of the aes_stream_drivers package. + * + * It includes functionalities for setting flags within the AXIS protocol + * and performing specific actions such as acknowledging reads and indicating + * missed write requests. * ---------------------------------------------------------------------------- * This file is part of the aes_stream_drivers package. It is subject to * the license terms in the LICENSE.txt file found in the top-level directory @@ -14,46 +19,88 @@ * contained in the LICENSE.txt file. * ---------------------------------------------------------------------------- **/ + #ifndef __ASIS_DRIVER_H__ #define __ASIS_DRIVER_H__ #include "DmaDriver.h" -// Commands -#define AXIS_Read_Ack 0x2001 +// Command definitions +#define AXIS_Read_Ack 0x2001 // Command to acknowledge read +#define AXIS_Write_ReqMissed 0x2002 // Command to indicate a missed write request -// Everything below is hidden during kernel module compile +// Only define the following if not compiling for kernel space #ifndef DMA_IN_KERNEL -// Set flags -// static constexpr inline uint32_t axisSetFlags(uint32_t fuser, uint32_t luser, uint32_t cont) { -// return ( ((cont & 0x1) << 16) | ((luser & 0xFF) << 8) | ((fuser & 0xFF) << 0) ); -//} - +/** + * Set flags for AXIS transactions. + * + * @param fuser First user-defined flag. + * @param luser Last user-defined flag. + * @param cont Continuation flag. + * + * @return The combined flags value. + */ static inline uint32_t axisSetFlags(uint32_t fuser, uint32_t luser, uint32_t cont) { - uint32_t flags; + uint32_t flags; - flags = fuser & 0xFF; - flags += (luser << 8) & 0xFF00; - flags += (cont << 16) & 0x10000; - return (flags); + // Set flags based on input parameters, ensuring each is in its correct position + flags = fuser & 0xFF; // First user-defined flag + flags |= (luser << 8) & 0xFF00; // Last user-defined flag + flags |= (cont << 16) & 0x10000; // Continuation flag + + return flags; } +/** + * Extract the first user-defined flag from the combined flags. + * + * @param flags The combined flags value. + * + * @return The first user-defined flag. + */ static inline uint32_t axisGetFuser(uint32_t flags) { - return (flags & 0xFF); + return flags & 0xFF; } +/** + * Extract the last user-defined flag from the combined flags. + * + * @param flags The combined flags value. + * + * @return The last user-defined flag. + */ static inline uint32_t axisGetLuser(uint32_t flags) { - return ((flags >> 8) & 0xFF); + return (flags >> 8) & 0xFF; } +/** + * Extract the continuation flag from the combined flags. + * + * @param flags The combined flags value. + * + * @return The continuation flag. + */ static inline uint32_t axisGetCont(uint32_t flags) { - return ((flags >> 16) & 0x1); + return (flags >> 16) & 0x1; } -// Read ACK +/** + * Acknowledge a read operation. + * + * @param fd File descriptor for the AXIS device. + */ static inline void axisReadAck(int32_t fd) { - ioctl(fd, AXIS_Read_Ack, 0); + ioctl(fd, AXIS_Read_Ack, 0); +} + +/** + * Indicate a missed write request. + * + * @param fd File descriptor for the AXIS device. + */ +static inline void axisWriteReqMissed(int32_t fd) { + ioctl(fd, AXIS_Write_ReqMissed, 0); } -#endif -#endif +#endif // !DMA_IN_KERNEL +#endif // __ASIS_DRIVER_H__ diff --git a/include/rogue/hardware/drivers/DmaDriver.h b/include/rogue/hardware/drivers/DmaDriver.h index b16bdeba6..eddd022c6 100644 --- a/include/rogue/hardware/drivers/DmaDriver.h +++ b/include/rogue/hardware/drivers/DmaDriver.h @@ -1,12 +1,13 @@ /** *----------------------------------------------------------------------------- - * Title : DMA Driver, Common Header - * ---------------------------------------------------------------------------- - * File : DmaDriver.h - * Created : 2016-08-08 - * ---------------------------------------------------------------------------- + * Company: SLAC National Accelerator Laboratory + *----------------------------------------------------------------------------- * Description: - * Defintions and inline functions for interacting drivers. + * This header file defines the interfaces and data structures used by + * DMA (Direct Memory Access) drivers in the aes_stream_drivers package. + * These drivers facilitate efficient data transfer between memory and + * devices without requiring CPU intervention, improving throughput and + * reducing latency for I/O operations. * ---------------------------------------------------------------------------- * This file is part of the aes_stream_drivers package. It is subject to * the license terms in the LICENSE.txt file found in the top-level directory @@ -16,449 +17,730 @@ * copied, modified, propagated, or distributed except according to the terms * contained in the LICENSE.txt file. * ---------------------------------------------------------------------------- - **/ +**/ + #ifndef __DMA_DRIVER_H__ #define __DMA_DRIVER_H__ #ifdef DMA_IN_KERNEL -#include + #include #else -#include + #include #endif -// API Version -#define DMA_VERSION 0x06 +/* API Version */ +#define DMA_VERSION 0x06 -// Error values +/* Error values */ #define DMA_ERR_FIFO 0x01 #define DMA_ERR_LEN 0x02 #define DMA_ERR_MAX 0x04 #define DMA_ERR_BUS 0x08 -// Commands -#define DMA_Get_Buff_Count 0x1001 -#define DMA_Get_Buff_Size 0x1002 -#define DMA_Set_Debug 0x1003 -#define DMA_Set_Mask 0x1004 -#define DMA_Ret_Index 0x1005 -#define DMA_Get_Index 0x1006 -#define DMA_Read_Ready 0x1007 -#define DMA_Set_MaskBytes 0x1008 -#define DMA_Get_Version 0x1009 -#define DMA_Write_Register 0x100A -#define DMA_Read_Register 0x100B -#define DMA_Get_RxBuff_Count 0x100C -#define DMA_Get_TxBuff_Count 0x100D -#define DMA_Get_TxBuffinUser_Count 0x100F -#define DMA_Get_TxBuffinHW_Count 0x1010 +/* Commands */ +#define DMA_Get_Buff_Count 0x1001 +#define DMA_Get_Buff_Size 0x1002 +#define DMA_Set_Debug 0x1003 +#define DMA_Set_Mask 0x1004 +#define DMA_Ret_Index 0x1005 +#define DMA_Get_Index 0x1006 +#define DMA_Read_Ready 0x1007 +#define DMA_Set_MaskBytes 0x1008 +#define DMA_Get_Version 0x1009 +#define DMA_Write_Register 0x100A +#define DMA_Read_Register 0x100B +#define DMA_Get_RxBuff_Count 0x100C +#define DMA_Get_TxBuff_Count 0x100D +#define DMA_Get_TxBuffinUser_Count 0x100F +#define DMA_Get_TxBuffinHW_Count 0x1010 #define DMA_Get_TxBuffinPreHWQ_Count 0x1011 -#define DMA_Get_TxBuffinSWQ_Count 0x1012 -#define DMA_Get_TxBuffMiss_Count 0x1013 +#define DMA_Get_TxBuffinSWQ_Count 0x1012 +#define DMA_Get_TxBuffMiss_Count 0x1013 -// Mask size +/* Mask size */ #define DMA_MASK_SIZE 512 -// TX Structure -// Size = 0 for return index +/** + * struct DmaWriteData - Structure representing a DMA write operation. + * @data: Physical address of the data to be written. + * @dest: Destination address within the device. + * @flags: Flags to control the write operation. + * @index: Index of the buffer to be used for the write operation. + * @size: Size of the data to be written. + * @is32: Flag indicating whether the system uses 32-bit addressing. + * @pad: Padding to align the structure to 64 bits. + * + * This structure is used to initiate a DMA write operation. It contains + * information about the data to be written, the destination, and various + * control flags. + */ struct DmaWriteData { - uint64_t data; - uint32_t dest; - uint32_t flags; - uint32_t index; - uint32_t size; - uint32_t is32; - uint32_t pad; + uint64_t data; + uint32_t dest; + uint32_t flags; + uint32_t index; + uint32_t size; + uint32_t is32; + uint32_t pad; }; -// RX Structure -// Data = 0 for read index +/** + * struct DmaReadData - Structure representing a DMA read operation. + * @data: Physical address where the read data will be stored. + * @dest: Source address within the device. + * @flags: Flags to control the read operation. + * @index: Index of the buffer to be used for the read operation. + * @error: Error code returned by the read operation. + * @size: Size of the data to be read. + * @is32: Flag indicating whether the system uses 32-bit addressing. + * @ret: The return value of the read operation, typically the size of the data read. + * + * This structure is used to initiate a DMA read operation. It contains + * information about where to store the read data, the source of the data, + * and various control flags. + */ struct DmaReadData { - uint64_t data; - uint32_t dest; - uint32_t flags; - uint32_t index; - uint32_t error; - uint32_t size; - uint32_t is32; - int32_t ret; + uint64_t data; + uint32_t dest; + uint32_t flags; + uint32_t index; + uint32_t error; + uint32_t size; + uint32_t is32; + int32_t ret; }; -// Register data +/** + * struct DmaRegisterData - Register data structure. + * @address: Memory address. + * @data: Data to be written. + * + * This structure holds the data necessary to perform a register write operation + * within a DMA context. + */ struct DmaRegisterData { - uint64_t address; - uint32_t data; + uint64_t address; + uint32_t data; }; -// Everything below is hidden during kernel module compile +// Conditional inclusion for non-kernel environments #ifndef DMA_IN_KERNEL -#include -#include #include #include -#include -#include #include +#include +#include +#include +#include #include +#include #include -#include - -// Write Frame -static inline ssize_t dmaWrite(int32_t fd, const void* buf, size_t size, uint32_t flags, uint32_t dest) { - struct DmaWriteData w; - memset(&w, 0, sizeof(struct DmaWriteData)); - w.dest = dest; - w.flags = flags; - w.size = size; - w.is32 = (sizeof(void*) == 4); - w.data = (uint64_t)buf; - - return (write(fd, &w, sizeof(struct DmaWriteData))); +/** + * dmaWrite - Writes data to a DMA channel. + * @fd: File descriptor for the DMA device. + * @buf: Pointer to the data buffer. + * @size: Size of the data to write. + * @flags: Flags for the write operation. + * @dest: Destination address for the write. + * + * This function writes a single frame of data to a DMA channel, specified by the + * file descriptor @fd. The data to be written is pointed to by @buf, with a specified + * size of @size. Additional parameters include flags (@flags) and a destination address + * (@dest). + * + * Return: Number of bytes written, or a negative error code on failure. + */ +static inline ssize_t dmaWrite(int32_t fd, const void *buf, size_t size, uint32_t flags, uint32_t dest) { + struct DmaWriteData w; + + memset(&w, 0, sizeof(struct DmaWriteData)); + w.dest = dest; + w.flags = flags; + w.size = size; + w.is32 = (sizeof(void *) == 4); + w.data = (uint64_t)buf; + + return(write(fd, &w, sizeof(struct DmaWriteData))); } -// Write Frame, memory mapped +/** + * dmaWriteIndex - Writes data to a DMA channel using an index. + * @fd: File descriptor for the DMA device. + * @index: Index of the data buffer. + * @size: Size of the data to write. + * @flags: Flags for the write operation. + * @dest: Destination address for the write. + * + * Similar to dmaWrite, but uses an index (@index) to specify the data buffer + * instead of a direct pointer. This is useful for memory-mapped I/O operations + * where data buffers are identified by indexes. + * + * Return: Number of bytes written, or a negative error code on failure. + */ static inline ssize_t dmaWriteIndex(int32_t fd, uint32_t index, size_t size, uint32_t flags, uint32_t dest) { - struct DmaWriteData w; + struct DmaWriteData w; - memset(&w, 0, sizeof(struct DmaWriteData)); - w.dest = dest; - w.flags = flags; - w.size = size; - w.is32 = (sizeof(void*) == 4); - w.index = index; + memset(&w, 0, sizeof(struct DmaWriteData)); + w.dest = dest; + w.flags = flags; + w.size = size; + w.is32 = (sizeof(void *) == 4); + w.index = index; - return (write(fd, &w, sizeof(struct DmaWriteData))); + return(write(fd, &w, sizeof(struct DmaWriteData))); } -// Write frame from iovector -static inline ssize_t dmaWriteVector(int32_t fd, - struct iovec* iov, - size_t iovlen, - uint32_t begFlags, - uint32_t midFlags, - uint32_t endFlags, - uint32_t dest) { - uint32_t x; - ssize_t ret; - ssize_t res; - struct DmaWriteData w; - - ret = 0; - - for (x = 0; x < iovlen; x++) { - memset(&w, 0, sizeof(struct DmaWriteData)); - w.dest = dest; - w.flags = (x == 0) ? begFlags : ((x == (iovlen - 1)) ? endFlags : midFlags); - w.size = iov[x].iov_len; - w.is32 = (sizeof(void*) == 4); - w.data = (uint64_t)iov[x].iov_base; - - do { - res = write(fd, &w, sizeof(struct DmaWriteData)); - - if (res < 0) - return (res); - else if (res == 0) - usleep(10); - else - ret += res; - } while (res == 0); - } - return (ret); +/** + * dmaWriteVector - Writes an array of data frames to a DMA channel. + * @fd: File descriptor for the DMA device. + * @iov: Pointer to the array of iovec structures. + * @iovlen: Number of elements in the iov array. + * @begFlags: Flags for the beginning of the data stream. + * @midFlags: Flags for the middle of the data stream. + * @endFlags: Flags for the end of the data stream. + * @dest: Destination address for the write. + * + * This function writes multiple data frames to a DMA channel, where each frame is + * specified by an iovec structure in the array pointed to by @iov. The number of + * frames to write is specified by @iovlen. Flags for the beginning, middle, and end + * of the data stream are specified by @begFlags, @midFlags, and @endFlags, respectively. + * The destination address for the write operation is specified by @dest. + * + * Return: Total number of bytes written, or a negative error code on failure. + */ +static inline ssize_t dmaWriteVector(int32_t fd, struct iovec *iov, size_t iovlen, + uint32_t begFlags, uint32_t midFlags, uint32_t endFlags, uint32_t dest) { + uint32_t x; + ssize_t ret; + ssize_t res; + struct DmaWriteData w; + + ret = 0; + + for (x=0; x < iovlen; x++) { + memset(&w,0,sizeof(struct DmaWriteData)); + w.dest = dest; + w.flags = (x==0)?begFlags:((x==(iovlen-1))?endFlags:midFlags); + w.size = iov[x].iov_len; + w.is32 = (sizeof(void *)==4); + w.data = (uint64_t)iov[x].iov_base; + + do { + res = write(fd,&w,sizeof(struct DmaWriteData)); + + if ( res < 0 ) return(res); + else if ( res == 0 ) usleep(10); + else ret += res; + } while (res == 0); + } + return(ret); } -// Write Frame, memory mapped from iovector -static inline ssize_t dmaWriteIndexVector(int32_t fd, - struct iovec* iov, - size_t iovlen, - uint32_t begFlags, - uint32_t midFlags, - uint32_t endFlags, - uint32_t dest) { - uint32_t x; - ssize_t ret; - ssize_t res; - struct DmaWriteData w; - - ret = 0; - - for (x = 0; x < iovlen; x++) { - memset(&w, 0, sizeof(struct DmaWriteData)); - w.dest = dest; - w.flags = (x == 0) ? begFlags : ((x == (iovlen - 1)) ? endFlags : midFlags); - w.size = iov[x].iov_len; - w.is32 = (sizeof(void*) == 4); - w.index = (uint32_t)(((uint64_t)iov[x].iov_base) & 0xFFFFFFFF); - - do { - res = write(fd, &w, sizeof(struct DmaWriteData)); - - if (res < 0) - return (res); - else if (res == 0) - usleep(10); - else - ret += res; - } while (res == 0); - } - return (ret); +/** + * dmaWriteIndexVector - Write Frame, memory mapped from iovector. + * @fd: File descriptor for DMA operation. + * @iov: Pointer to array of iovec structures. + * @iovlen: Length of the iov array. + * @begFlags: Flags to use for the beginning of the DMA transaction. + * @midFlags: Flags to use for the middle of the DMA transaction. + * @endFlags: Flags to use for the end of the DMA transaction. + * @dest: Destination address for the DMA write. + * + * This function writes a frame to a device, using DMA, where the frame data + * is described by an array of iovec structures. + * + * Return: Total number of bytes written, or negative on failure. + */ +static inline ssize_t dmaWriteIndexVector(int32_t fd, struct iovec *iov, size_t iovlen, + uint32_t begFlags, uint32_t midFlags, uint32_t endFlags, uint32_t dest) { + uint32_t x; + ssize_t ret; + ssize_t res; + struct DmaWriteData w; + + ret = 0; + + for (x = 0; x < iovlen; x++) { + memset(&w, 0, sizeof(struct DmaWriteData)); + w.dest = dest; + w.flags = (x == 0) ? begFlags : ((x == (iovlen - 1)) ? endFlags : midFlags); + w.size = iov[x].iov_len; + w.is32 = (sizeof(void *) == 4); + w.index = (uint32_t)(((uint64_t)iov[x].iov_base) & 0xFFFFFFFF); + + do { + res = write(fd, &w, sizeof(struct DmaWriteData)); + + if (res < 0) return(res); + else if (res == 0) usleep(10); + else ret += res; + } while (res == 0); + } + return(ret); } -// Receive Frame -static inline ssize_t dmaRead(int32_t fd, void* buf, size_t maxSize, uint32_t* flags, uint32_t* error, uint32_t* dest) { - struct DmaReadData r; - ssize_t ret; - - memset(&r, 0, sizeof(struct DmaReadData)); - r.size = maxSize; - r.is32 = (sizeof(void*) == 4); - r.data = (uint64_t)buf; - - ret = read(fd, &r, sizeof(struct DmaReadData)); - - if (ret <= 0) return (ret); - - if (dest != NULL) *dest = r.dest; - if (flags != NULL) *flags = r.flags; - if (error != NULL) *error = r.error; - - return (r.ret); +/** + * dmaRead - Receive Frame. + * @fd: File descriptor for DMA operation. + * @buf: Buffer to store received data. + * @maxSize: Maximum size to read. + * @flags: Pointer to store flags after reading. + * @error: Pointer to store error code if any. + * @dest: Pointer to store destination address. + * + * This function reads a frame from a device using DMA. + * + * Return: Size of the data received, or negative on failure. + */ +static inline ssize_t dmaRead(int32_t fd, void *buf, size_t maxSize, uint32_t *flags, uint32_t *error, uint32_t *dest) { + struct DmaReadData r; + ssize_t ret; + + memset(&r, 0, sizeof(struct DmaReadData)); + r.size = maxSize; + r.is32 = (sizeof(void *) == 4); + r.data = (uint64_t)buf; + + ret = read(fd, &r, sizeof(struct DmaReadData)); + + if (ret <= 0) return(ret); + + if (dest != NULL) *dest = r.dest; + if (flags != NULL) *flags = r.flags; + if (error != NULL) *error = r.error; + + return(r.ret); } -// Receive Frame, access memory mapped buffer -// Returns receive size -static inline ssize_t dmaReadIndex(int32_t fd, uint32_t* index, uint32_t* flags, uint32_t* error, uint32_t* dest) { - struct DmaReadData r; - size_t ret; - - memset(&r, 0, sizeof(struct DmaReadData)); - - ret = read(fd, &r, sizeof(struct DmaReadData)); - - if (ret <= 0) return (ret); - - if (dest != NULL) *dest = r.dest; - if (flags != NULL) *flags = r.flags; - if (error != NULL) *error = r.error; - - *index = r.index; - return (r.ret); +/** + * dmaReadIndex - Receive Frame, access memory mapped buffer. + * @fd: File descriptor for DMA operation. + * @index: Pointer to store the index of the received data. + * @flags: Pointer to store flags after reading. + * @error: Pointer to store error code if any. + * @dest: Pointer to store destination address. + * + * This function reads a frame from a device using DMA, specifically accessing + * the memory-mapped buffer and retrieves the index of the received data. + * + * Return: Size of the data received, or negative on failure. + */ +static inline ssize_t dmaReadIndex(int32_t fd, uint32_t *index, uint32_t *flags, uint32_t *error, uint32_t *dest) { + struct DmaReadData r; + size_t ret; + + memset(&r, 0, sizeof(struct DmaReadData)); + + ret = read(fd, &r, sizeof(struct DmaReadData)); + + if (ret <= 0) return(ret); + + if (dest != NULL) *dest = r.dest; + if (flags != NULL) *flags = r.flags; + if (error != NULL) *error = r.error; + + *index = r.index; + return(r.ret); } -// Receive Frame, access memory mapped buffer -// Returns receive size -static inline ssize_t dmaReadBulkIndex(int32_t fd, - uint32_t count, - int32_t* ret, - uint32_t* index, - uint32_t* flags, - uint32_t* error, - uint32_t* dest) { - struct DmaReadData r[count]; - size_t res; - size_t x; - - memset(r, 0, count * sizeof(struct DmaReadData)); - - res = read(fd, r, count * sizeof(struct DmaReadData)); - - for (x = 0; x < res; ++x) { - if (dest != NULL) dest[x] = r[x].dest; - if (flags != NULL) flags[x] = r[x].flags; - if (error != NULL) error[x] = r[x].error; - - index[x] = r[x].index; - ret[x] = r[x].ret; - } - return (res); +/** + * dmaReadBulkIndex - Receive frame and access memory-mapped buffer. + * @fd: File descriptor to read from. + * @count: Number of elements in the buffers. + * @ret: Pointer to store the return values. + * @index: Buffer to store the indices of the DMA read operations. + * @flags: Buffer to store flags of the DMA read operations. + * @error: Buffer to store error codes of the DMA read operations. + * @dest: Buffer to store destination addresses of the DMA read operations. + * + * This function reads bulk data from a DMA channel and extracts the metadata + * associated with each read operation, including return values, indices, + * flags, error codes, and destination addresses. + * + * Returns: The number of bytes read. + */ +static inline ssize_t dmaReadBulkIndex(int32_t fd, uint32_t count, int32_t *ret, uint32_t *index, + uint32_t *flags, uint32_t *error, uint32_t *dest) { + struct DmaReadData r[count]; + size_t res; + size_t x; + + memset(r, 0, count * sizeof(struct DmaReadData)); + + res = read(fd, r, count * sizeof(struct DmaReadData)); + + for (x = 0; x < res; ++x) { + if (dest != NULL) dest[x] = r[x].dest; + if (flags != NULL) flags[x] = r[x].flags; + if (error != NULL) error[x] = r[x].error; + + index[x] = r[x].index; + ret[x] = r[x].ret; + } + return(res); } -// Post Index +/** + * dmaRetIndex - Post an index back to the DMA. + * @fd: File descriptor to use. + * @index: Index to be returned. + * + * This function posts a single index back to the DMA, indicating that + * the buffer associated with this index can be reused. + * + * Returns: Result of the IOCTL operation. + */ static inline ssize_t dmaRetIndex(int32_t fd, uint32_t index) { - uint32_t cmd = DMA_Ret_Index | 0x10000; + uint32_t cmd = DMA_Ret_Index | 0x10000; - return (ioctl(fd, cmd, &index)); + return(ioctl(fd, cmd, &index)); } -// Post Index List -static inline ssize_t dmaRetIndexes(int32_t fd, uint32_t count, uint32_t* indexes) { - uint32_t cmd = DMA_Ret_Index | ((count << 16) & 0xFFFF0000); - - return (ioctl(fd, cmd, indexes)); +/** + * dmaRetIndexes - Post multiple indices back to the DMA. + * @fd: File descriptor to use. + * @count: Number of indices to be returned. + * @indexes: Array of indices to be returned. + * + * This function posts multiple indices back to the DMA, indicating that + * the buffers associated with these indices can be reused. + * + * Returns: Result of the IOCTL operation. + */ +static inline ssize_t dmaRetIndexes(int32_t fd, uint32_t count, uint32_t *indexes) { + uint32_t cmd = DMA_Ret_Index | ((count << 16) & 0xFFFF0000); + + return(ioctl(fd, cmd, indexes)); } -// Get write buffer index +/** + * dmaGetIndex - Get the current write buffer index. + * @fd: File descriptor to use. + * + * This function retrieves the current index for writing to the DMA buffer. + * + * Returns: The current write buffer index. + */ static inline uint32_t dmaGetIndex(int32_t fd) { - return (ioctl(fd, DMA_Get_Index, 0)); + return(ioctl(fd, DMA_Get_Index, 0)); } -// Get read ready status +/** + * dmaReadReady - Check if read is ready. + * @fd: File descriptor to use. + * + * This function checks if the DMA is ready for reading. + * + * Returns: Result of the IOCTL operation, indicating read readiness. + */ static inline ssize_t dmaReadReady(int32_t fd) { - return (ioctl(fd, DMA_Read_Ready, 0)); + return(ioctl(fd, DMA_Read_Ready, 0)); } -// get rx buffer count +/** + * dmaGetRxBuffCount - Get the receive buffer count. + * @fd: File descriptor to use. + * + * This function retrieves the count of receive buffers available. + * + * Returns: The count of receive buffers. + */ static inline ssize_t dmaGetRxBuffCount(int32_t fd) { - return (ioctl(fd, DMA_Get_RxBuff_Count, 0)); + return(ioctl(fd, DMA_Get_RxBuff_Count, 0)); } -// get tx buffer count +/** + * dmaGetTxBuffCount - Get the transmit buffer count. + * @fd: File descriptor to use. + * + * This function retrieves the count of transmit buffers available. + * + * Returns: The count of transmit buffers. + */ static inline ssize_t dmaGetTxBuffCount(int32_t fd) { - return (ioctl(fd, DMA_Get_TxBuff_Count, 0)); + return(ioctl(fd, DMA_Get_TxBuff_Count, 0)); } -// get buffer size +/** + * dmaGetBuffSize - Get the buffer size. + * @fd: File descriptor to use. + * + * This function retrieves the size of DMA buffers. + * + * Returns: The size of DMA buffers. + */ static inline ssize_t dmaGetBuffSize(int32_t fd) { - return (ioctl(fd, DMA_Get_Buff_Size, 0)); + return(ioctl(fd, DMA_Get_Buff_Size, 0)); } -// Return user space mapping to dma buffers -static inline void** dmaMapDma(int32_t fd, uint32_t* count, uint32_t* size) { - void* temp; - void** ret; - uint32_t bCount; - uint32_t gCount; - uint32_t bSize; - off_t offset; - - bSize = ioctl(fd, DMA_Get_Buff_Size, 0); - bCount = ioctl(fd, DMA_Get_Buff_Count, 0); - - if (count != NULL) *count = bCount; - if (size != NULL) *size = bSize; - - if ((ret = (void**)malloc(sizeof(void*) * bCount)) == 0) return (NULL); - - // Attempt to map - gCount = 0; - while (gCount < bCount) { - offset = (off_t)bSize * (off_t)gCount; - - if ((temp = mmap(0, bSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset)) == MAP_FAILED) break; - ret[gCount++] = temp; - } - - // Map failed - if (gCount != bCount) { - while (gCount != 0) munmap(ret[--gCount], bSize); - free(ret); - ret = NULL; - } - return (ret); +/** + * dmaMapDma - Map user space to DMA buffers. + * @fd: File descriptor to use. + * @count: Pointer to store the count of buffers. + * @size: Pointer to store the size of each buffer. + * + * This function maps DMA buffers into user space, allowing direct access. + * + * Returns: Pointer to an array of pointers to the mapped buffers, or NULL on failure. + */ +static inline void **dmaMapDma(int32_t fd, uint32_t *count, uint32_t *size) { + void *temp; + void **ret; + uint32_t bCount; + uint32_t gCount; + uint32_t bSize; + off_t offset; + + bSize = ioctl(fd, DMA_Get_Buff_Size, 0); + bCount = ioctl(fd, DMA_Get_Buff_Count, 0); + + if (count != NULL) *count = bCount; + if (size != NULL) *size = bSize; + + if ( (ret = (void **)malloc(sizeof(void *) * bCount)) == 0 ) return(NULL); + + // Attempt to map + gCount = 0; + while (gCount < bCount) { + offset = (off_t)bSize * (off_t)gCount; + + if ((temp = mmap(0, bSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset)) == MAP_FAILED) break; + ret[gCount++] = temp; + } + + // Map failed + if (gCount != bCount) { + while (gCount != 0) munmap(ret[--gCount], bSize); + free(ret); + ret = NULL; + } + return(ret); } -// Free space mapping to dma buffers -static inline ssize_t dmaUnMapDma(int32_t fd, void** buffer) { - uint32_t bCount; - uint32_t bSize; - uint32_t x; - - bCount = ioctl(fd, DMA_Get_Buff_Count, 0); - bSize = ioctl(fd, DMA_Get_Buff_Size, 0); - - for (x = 0; x < bCount; x++) munmap(buffer[x], bSize); - - free(buffer); - return (0); +/** + * dmaUnMapDma - Unmap user space from DMA buffers. + * @fd: File descriptor to use. + * @buffer: Array of pointers to the mapped buffers. + * + * This function unmaps DMA buffers from user space, releasing the resources. + * + * Returns: 0 on success. + */ +static inline ssize_t dmaUnMapDma(int32_t fd, void **buffer) { + uint32_t bCount; + uint32_t bSize; + uint32_t x; + + bCount = ioctl(fd, DMA_Get_Buff_Count, 0); + bSize = ioctl(fd, DMA_Get_Buff_Size, 0); + + for (x = 0; x < bCount; x++) munmap(buffer[x], bSize); + + free(buffer); + return(0); } -// Set debug +/** + * dmaSetDebug - Set debugging level for DMA operations. + * @fd: File descriptor for the DMA device. + * @level: Debugging level to be set. + * + * This function sets the specified debugging level for DMA operations + * using an IOCTL command. + * + * Return: Result from the IOCTL call. + */ static inline ssize_t dmaSetDebug(int32_t fd, uint32_t level) { - return (ioctl(fd, DMA_Set_Debug, level)); + return(ioctl(fd, DMA_Set_Debug, level)); } -// Assign interrupt handler +/** + * dmaAssignHandler - Assign a signal handler for asynchronous DMA operations. + * @fd: File descriptor for the DMA device. + * @handler: Function pointer to the signal handler. + * + * This function sets up a signal action structure to handle SIGIO signals + * with the specified handler function. It also sets the file descriptor to + * receive signals for asynchronous I/O. + */ static inline void dmaAssignHandler(int32_t fd, void (*handler)(int32_t)) { - struct sigaction act; - int32_t oflags; + struct sigaction act; + int32_t oflags; - act.sa_handler = handler; - sigemptyset(&act.sa_mask); - act.sa_flags = 0; + act.sa_handler = handler; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; - sigaction(SIGIO, &act, NULL); - fcntl(fd, F_SETOWN, getpid()); - oflags = fcntl(fd, F_GETFL); - fcntl(fd, F_SETFL, oflags | FASYNC); + sigaction(SIGIO, &act, NULL); + fcntl(fd, F_SETOWN, getpid()); + oflags = fcntl(fd, F_GETFL); + fcntl(fd, F_SETFL, oflags | FASYNC); } -// set mask +/** + * dmaSetMask - Set DMA mask. + * @fd: File descriptor for the DMA device. + * @mask: DMA mask to be set. + * + * Sets a DMA mask using an IOCTL command. + * + * Return: Result from the IOCTL call. + */ static inline ssize_t dmaSetMask(int32_t fd, uint32_t mask) { - return (ioctl(fd, DMA_Set_Mask, mask)); + return(ioctl(fd, DMA_Set_Mask, mask)); } -// Init mask byte array -static inline void dmaInitMaskBytes(uint8_t* mask) { - memset(mask, 0, DMA_MASK_SIZE); +/** + * dmaInitMaskBytes - Initialize DMA mask byte array. + * @mask: Pointer to the DMA mask byte array. + * + * Initializes the DMA mask byte array to zeros. + */ +static inline void dmaInitMaskBytes(uint8_t *mask) { + memset(mask, 0, DMA_MASK_SIZE); } -// Add destination to mask byte array -static inline void dmaAddMaskBytes(uint8_t* mask, uint32_t dest) { - uint32_t byte; - uint32_t bit; - - if (dest < 8 * (DMA_MASK_SIZE)) { - byte = dest / 8; - bit = dest % 8; - mask[byte] += (1 << bit); - } +/** + * dmaAddMaskBytes - Add a destination to the DMA mask byte array. + * @mask: Pointer to the DMA mask byte array. + * @dest: Destination index to set in the mask. + * + * Adds a destination to the DMA mask byte array by setting the appropriate + * bit based on the destination index. + */ +static inline void dmaAddMaskBytes(uint8_t *mask, uint32_t dest) { + uint32_t byte; + uint32_t bit; + + if (dest < 8 * (DMA_MASK_SIZE)) { + byte = dest / 8; + bit = dest % 8; + mask[byte] += (1 << bit); + } } -// set mask byte array to driver -static inline ssize_t dmaSetMaskBytes(int32_t fd, uint8_t* mask) { - return (ioctl(fd, DMA_Set_MaskBytes, mask)); +/** + * dmaSetMaskBytes - Set mask byte array to the driver. + * @fd: File descriptor for the DMA device. + * @mask: Pointer to the DMA mask byte array. + * + * Sets the DMA mask byte array using an IOCTL command. + * + * Return: Result from the IOCTL call. + */ +static inline ssize_t dmaSetMaskBytes(int32_t fd, uint8_t *mask) { + return(ioctl(fd, DMA_Set_MaskBytes, mask)); } -// Check API version, return negative on error +/** + * dmaCheckVersion - Check API version of the DMA driver. + * @fd: File descriptor for the DMA device. + * + * Checks the API version of the DMA driver to ensure compatibility. + * + * Return: 0 if the version matches, -1 otherwise. + */ static inline ssize_t dmaCheckVersion(int32_t fd) { - int32_t version; - version = ioctl(fd, DMA_Get_Version); - return ((version == DMA_VERSION) ? -0 : -1); + int32_t version; + version = ioctl(fd, DMA_Get_Version); + return((version == DMA_VERSION) ? 0 : -1); } -// Write Register +/** + * dmaWriteRegister - Write to a DMA register. + * @fd: File descriptor for the DMA device. + * @address: Register address. + * @data: Data to write. + * + * Writes data to a specified register address using an IOCTL command. + * + * Return: Result from the IOCTL call. + */ static inline ssize_t dmaWriteRegister(int32_t fd, uint64_t address, uint32_t data) { - struct DmaRegisterData reg; + struct DmaRegisterData reg; - reg.address = address; - reg.data = data; - return (ioctl(fd, DMA_Write_Register, ®)); + reg.address = address; + reg.data = data; + return(ioctl(fd, DMA_Write_Register, ®)); } -// Read Register -static inline ssize_t dmaReadRegister(int32_t fd, uint64_t address, uint32_t* data) { - struct DmaRegisterData reg; - ssize_t res; - - reg.address = address; - reg.data = 0; - res = ioctl(fd, DMA_Read_Register, ®); - - if (data != NULL) *data = reg.data; - - return (res); +/** + * dmaReadRegister - Read a value from a DMA register. + * @fd: File descriptor for the DMA device. + * @address: The address of the register to be read. + * @data: Pointer to store the read data. + * + * This function reads a 32-bit value from a specified DMA register address. + * The read value is stored in the location pointed to by @data if @data is not NULL. + * + * Return: The result of the ioctl operation, indicating success or failure. + */ +static inline ssize_t dmaReadRegister(int32_t fd, uint64_t address, uint32_t *data) +{ + struct DmaRegisterData reg; + ssize_t res; + + // Initialize register data structure + reg.address = address; + reg.data = 0; + + // Perform ioctl to read the register + res = ioctl(fd, DMA_Read_Register, ®); + + // If data pointer is valid, update it with the read value + if (data != NULL) + *data = reg.data; + + return res; } -// Return user space mapping to a relative register space -static inline void* dmaMapRegister(int32_t fd, off_t offset, uint32_t size) { - uint32_t bCount; - uint32_t bSize; - off_t intOffset; - - bSize = ioctl(fd, DMA_Get_Buff_Size, 0); - bCount = ioctl(fd, DMA_Get_Buff_Count, 0); - - intOffset = (bSize * bCount) + offset; - - // Attempt to map - return (mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, intOffset)); +/** + * dmaMapRegister - Map a DMA register space to user space. + * @fd: File descriptor for the DMA device. + * @offset: Offset from the start of the register space to be mapped. + * @size: Size of the memory region to map. + * + * This function calculates an internal offset based on the buffer size and count + * obtained from the DMA device. It then attempts to map a region of memory into + * the user space corresponding to this calculated offset plus the specified @offset. + * + * Return: A pointer to the mapped memory region in user space, or MAP_FAILED on failure. + */ +static inline void *dmaMapRegister(int32_t fd, off_t offset, uint32_t size) +{ + uint32_t bSize; + uint32_t bCount; + off_t intOffset; + + // Obtain buffer size and count from the DMA device + bSize = ioctl(fd, DMA_Get_Buff_Size, 0); + bCount = ioctl(fd, DMA_Get_Buff_Count, 0); + + // Calculate internal offset + intOffset = (bSize * bCount) + offset; + + // Attempt to map the memory region into user space + return mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, intOffset); } -// Free space mapping to dma buffers -static inline ssize_t dmaUnMapRegister(int32_t fd, void* ptr, uint32_t size) { - munmap(ptr, size); - return (0); +/** + * dmaUnMapRegister - Unmap a DMA register space from user space. + * @fd: File descriptor for the DMA device. (Unused in this function, but kept for symmetry with map function) + * @ptr: Pointer to the start of the mapped memory region. + * @size: Size of the memory region to unmap. + * + * This function unmaps a previously mapped region of memory from the user space. + * The @fd parameter is not used but is included for symmetry with the dmaMapRegister function. + * + * Return: Always returns 0 indicating success. + */ +static inline ssize_t dmaUnMapRegister(int32_t fd, void *ptr, uint32_t size) +{ + // Unmap the memory region + munmap(ptr, size); + return 0; } -#endif -#endif +#endif // !DMA_IN_KERNEL +#endif // __DMA_DRIVER_H__ diff --git a/include/rogue/hardware/drivers/PgpDriver.h b/include/rogue/hardware/drivers/PgpDriver.h deleted file mode 100644 index 575d48b27..000000000 --- a/include/rogue/hardware/drivers/PgpDriver.h +++ /dev/null @@ -1,329 +0,0 @@ -/** - *----------------------------------------------------------------------------- - * Title : PGP Card Driver, Shared Header - * ---------------------------------------------------------------------------- - * Description: - * Definitions and inline functions for interacting with PGP driver. - * ---------------------------------------------------------------------------- - * This file is part of the aes_stream_drivers package. It is subject to - * the license terms in the LICENSE.txt file found in the top-level directory - * of this distribution and at: - * https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. - * No part of the aes_stream_drivers package, including this file, may be - * copied, modified, propagated, or distributed except according to the terms - * contained in the LICENSE.txt file. - * ---------------------------------------------------------------------------- - **/ -#ifndef __PGP_DRIVER_H__ -#define __PGP_DRIVER_H__ -#include "DmaDriver.h" - -//! PGP Card Info -struct PgpInfo { - //! PGP Card Serial # - uint64_t serial; - - //! PGP Card Type - uint32_t type; - - //! PGP Card Version - uint32_t version; - - //! PGP Card Lane Mask - uint32_t laneMask; - - //! PGP Card VCs per Lane Mask - uint32_t vcPerMask; - - //! PGP Card Line Rate - uint32_t pgpRate; - - //! PGP Card Prom Programming Support Flag - uint32_t promPrgEn; - - //! PGP Card EVR Support Flag - uint32_t evrSupport; - - uint32_t pad; - - char buildStamp[256]; -}; - -//! PCI Status -struct PciStatus { - //! PCI Express Command Field - uint32_t pciCommand; - - //! PCI Express Status Field - uint32_t pciStatus; - - //! PCI Express D Command Field - uint32_t pciDCommand; - - //! PCI Express D Status Field - uint32_t pciDStatus; - - //! PCI Express L Command Field - uint32_t pciLCommand; - - //! PCI Express L Status Field - uint32_t pciLStatus; - - //! PCI Express Link State - uint32_t pciLinkState; - - //! PCI Express Function Number - uint32_t pciFunction; - - //! PCI Express Device Number - uint32_t pciDevice; - - //! PCI Express Bus Number - uint32_t pciBus; - - //! Number Of PCI Lanes - uint32_t pciLanes; - - uint32_t pad; -}; - -//! PGP Lane Status -struct PgpStatus { - //! Lane number associated with this record - uint32_t lane; - - //! Lane loopback status - uint32_t loopBack; - - //! Lane local link ready status - uint32_t locLinkReady; - - //! Lane remote link ready status - uint32_t remLinkReady; - - //! Lane receive PLL ready status - uint32_t rxReady; - - //! Lane transmit PLL ready status - uint32_t txReady; - - //! Lane receive frame counter - uint32_t rxCount; - - //! Lane cell error counter - uint32_t cellErrCnt; - - //! Lane link lost transition counter - uint32_t linkDownCnt; - - //! Lane link error counter - uint32_t linkErrCnt; - - //! Lane FIFO error counter - uint32_t fifoErr; - - //! Lane current received remote sideband data - uint32_t remData; - - //! Lane remote buffer status - uint32_t remBuffStatus; - - uint32_t pad; -}; - -//! EVR Control, one per lane -struct PgpEvrControl { - //! Lane number associated with this record - uint32_t lane; - - //! Global EVR enable for all lanes, 1 = enable, 0 = disabled - uint32_t evrEnable; // Global flag - - //! Run trigger enable for this lane, 1 = enable, 0 = disable - uint32_t laneRunMask; // 1 = Run trigger enable - - //! EVR Sync enable, 1 = start, 0 = stop - uint32_t evrSyncEn; // 1 = Start, 0 = Stop - - //! Sync select, 0 = async, 1 = sync for start/stop - uint32_t evrSyncSel; // 0 = async, 1 = sync for start/stop - - //! Header checking mask, 1 enable bit for each of 4 virtual channels. - uint32_t headerMask; // 1 = Enable header data checking, one bit per VC (4 bits) - - //! EVR Sync word, 32-bit timing fidicial to transition start/stop on - uint32_t evrSyncWord; // fiducial to transition start stop - - //! 8-bit timing code to assert run trigger - uint32_t runCode; // Run code - - //! Delay between timing code reception and assertion of run trigger - uint32_t runDelay; // Run delay - - //! 8-bit timing code to assert accept trigger - uint32_t acceptCode; // Accept code - - //! Delay between timing code reception and assertion of accept trigger - uint32_t acceptDelay; // Accept delay - - uint32_t pad; -}; - -//! EVR Status, one per lane -struct PgpEvrStatus { - //! Lane number associated with this record - uint32_t lane; - - //! EVR link error counter - uint32_t linkErrors; - - //! EVR link up state, 0 = down, 1 = up - uint32_t linkUp; - - //! EVR running status, 0 = stopped, 1 = running - uint32_t runStatus; // 1 = Running, 0 = Stopped - - //! Current distributed timing seconds value - uint32_t evrSeconds; - - //! Number of run triggers received - uint32_t runCounter; - - //! Number of accepts triggers received - uint32_t acceptCounter; - - uint32_t pad; -}; - -// Card Types -#define PGP_NONE 0x00 -#define PGP_GEN1 0x01 -#define PGP_GEN2 0x02 -#define PGP_GEN2_VCI 0x12 -#define PGP_GEN3 0x03 -#define PGP_GEN3_VCI 0x13 - -// Error values -#define PGP_ERR_EOFE 0x10 - -// Commands -#define PGP_Read_Info 0x2001 -#define PGP_Read_Pci 0x2002 -#define PGP_Read_Status 0x2003 -#define PGP_Set_Loop 0x2004 -#define PGP_Count_Reset 0x2005 -#define PGP_Send_OpCode 0x2006 -#define PGP_Set_Data 0x2007 -#define PGP_Set_Evr_Cntrl 0x3001 -#define PGP_Get_Evr_Cntrl 0x3002 -#define PGP_Get_Evr_Status 0x3003 -#define PGP_Rst_Evr_Count 0x3004 - -// Everything below is hidden during kernel module compile -#ifndef DMA_IN_KERNEL - -static inline uint32_t pgpSetDest(uint32_t lane, uint32_t vc) { - uint32_t dest; - - dest = lane * 4; - dest += vc; - return (dest); -} - -static inline uint32_t pgpSetFlags(uint32_t cont) { - return (cont & 0x1); -} - -static inline uint32_t pgpGetLane(uint32_t dest) { - return (dest / 4); -} - -static inline uint32_t pgpGetVc(uint32_t dest) { - return (dest % 4); -} - -static inline uint32_t pgpGetCont(uint32_t flags) { - return (flags & 0x1); -} - -// Read Card Info -static inline ssize_t pgpGetInfo(int32_t fd, struct PgpInfo* info) { - return (ioctl(fd, PGP_Read_Info, info)); -} - -// Read PCI Status -static inline ssize_t pgpGetPci(int32_t fd, struct PciStatus* status) { - return (ioctl(fd, PGP_Read_Pci, status)); -} - -// Read Lane Status -static inline ssize_t pgpGetStatus(int32_t fd, uint32_t lane, struct PgpStatus* status) { - status->lane = lane; - return (ioctl(fd, PGP_Read_Status, status)); -} - -// Set Loopback State For Lane -static inline ssize_t pgpSetLoop(int32_t fd, uint32_t lane, uint32_t state) { - uint32_t temp; - - temp = lane & 0xFF; - temp |= ((state << 8) & 0x100); - - return (ioctl(fd, PGP_Set_Loop, temp)); -} - -// Reset counters -static inline ssize_t pgpCountReset(int32_t fd) { - return (ioctl(fd, PGP_Count_Reset, 0)); -} - -// Set Sideband Data -static inline ssize_t pgpSetData(int32_t fd, uint32_t lane, uint32_t data) { - uint32_t temp; - - temp = lane & 0xFF; - temp |= ((data << 8) & 0xFF00); - - return (ioctl(fd, PGP_Set_Data, temp)); -} - -// Send OpCode -static inline ssize_t pgpSendOpCode(int32_t fd, uint32_t code) { - return (ioctl(fd, PGP_Send_OpCode, code)); -} - -// Set EVR Control -static inline ssize_t pgpSetEvrControl(int32_t fd, uint32_t lane, struct PgpEvrControl* control) { - control->lane = lane; - return (ioctl(fd, PGP_Set_Evr_Cntrl, control)); -} - -// Get EVR Control -static inline ssize_t pgpGetEvrControl(int32_t fd, uint32_t lane, struct PgpEvrControl* control) { - control->lane = lane; - return (ioctl(fd, PGP_Get_Evr_Cntrl, control)); -} - -// Get EVR Status -static inline ssize_t pgpGetEvrStatus(int32_t fd, uint32_t lane, struct PgpEvrStatus* status) { - status->lane = lane; - return (ioctl(fd, PGP_Get_Evr_Status, status)); -} - -// Reset EVR Counters -static inline ssize_t pgpResetEvrCount(int32_t fd, uint32_t lane) { - return (ioctl(fd, PGP_Rst_Evr_Count, lane)); -} - -// Add destination to mask byte array -static inline void pgpAddMaskBytes(uint8_t* mask, uint32_t lane, uint32_t vc) { - dmaAddMaskBytes(mask, lane * 4 + vc); -} - -// set lane/vc rx mask, one bit per vc -static inline ssize_t pgpSetMask(int32_t fd, uint32_t lane, uint32_t vc) { - return (dmaSetMask(fd, lane * 4 + vc)); -} - -#endif -#endif