Commit 5f12009e authored by Sujatha Banoth's avatar Sujatha Banoth

2020.2 QDMA Windows Driver Release

2020.2 QDMA Windows Driver Release
parent 1fe2bd02
Release: 2020.1
Release: 2020.2
================
This release is validated on QDMA4.0 2020.1 based example design,
This release is validated on QDMA4.0 2020.2 based example design and
QDMA3.1 2019.2 patch based example design.
QDMA Windows driver is supported in poll mode by default
......@@ -53,12 +53,19 @@ SUPPORTED FEATURES:
- Updated and validated the example design with marker changes for QDMA4.0 and without marker changes for QDMA3.1
- Support multiple bus numbers on single card
2020.2 Updates
--------------
- Support larger MM & ST packet transfer support
- Added support for detailed register dump
- Added support for post processing HW error messages
- Added support for Debug mode and Internal only mode
KNOWN ISSUES:
=============
- Driver installation gives warning due to test signature.
- In interrupt mode, Sometimes completions are not received when C2H PIDX updates are held for 64 descriptors
- On QDMA4.0 2020.1 design, HW errors are observed in trace logs while validating the MM only design.
- On QDMA4.0 2020.1 design, User logic fails to generate C2H streaming packets when multiple threads try
- On QDMA4.0 2020.2 design, User logic fails to generate C2H streaming packets when multiple threads try
to generate packets on multiple active queues.
DRIVER LIMITATIONS:
......
......@@ -20,7 +20,7 @@
#define __QDMARW_VERSION_H
#define PROGNAME "dma-arw"
#define VERSION "2020.1.0"
#define VERSION "2020.2.0"
#define COPYRIGHT "Copyright (c) 2020 Xilinx Inc."
#endif /*__QDMARW_VERSION_H*/
......@@ -26,9 +26,11 @@
#define MAX_VALID_GLBL_IDX 15
#define MAX_VALID_CMPT_SZ 3
#define MAX_VALID_INTR_RING_VEC 8
#define MAX_VALID_BAR_NUM 5
#define MAX_CMPT_DESC_SZ 64
#define MAX_INTR_RING_ENTRY_SZ 32
#define MAX_DUMP_BUFF_SZ 64 * 1024
#define MAX_REG_INFO_SZ 1024
#pragma comment(lib, "setupapi.lib")
......@@ -38,6 +40,13 @@ using std::runtime_error;
using std::cout;
using namespace std;
const char *desc_engine_mode[] = {
"Internal and Bypass mode",
"Bypass only mode"
"Inernal only mode",
};
static void help(void);
static bool open_device(const char *dev_name, device_file& device)
......@@ -231,6 +240,14 @@ static int handle_devinfo(const char *dev_name)
printf("%-35s : %s\n", "MM enabled", cmd.dev_info.out->mm_en ? "yes" : "no");
printf("%-35s : %s\n", "Mailbox enabled", cmd.dev_info.out->mailbox_en ? "yes" : "no");
printf("%-35s : %s\n", "MM completion enabled", cmd.dev_info.out->mm_cmpl_en ? "yes" : "no");
printf("%-35s : %s\n", "Debug Mode enabled", cmd.dev_info.out->debug_mode ? "yes" : "no");
if (cmd.dev_info.out->desc_eng_mode < sizeof(desc_engine_mode) / sizeof(desc_engine_mode[0])) {
printf("%-35s : %s\n", "Desc Engine Mode", desc_engine_mode[cmd.dev_info.out->desc_eng_mode]);
}
else {
printf("%-35s : %s\n", "Desc Engine Mode", "Invalid");
}
printf("\n");
delete cmd.dev_info.out;
......@@ -1107,27 +1124,120 @@ static int handle_reg_dump(const char *dev_name, const int argc, char* argv[])
unsigned int size = MAX_DUMP_BUFF_SZ;
unsigned int out_size = sizeof(struct regdump_info_out) + size;
cmd.reg_info.out = (struct regdump_info_out *)new char[out_size];
cmd.reg_info.out->ret_len = 0;
cmd.reg_dump_info.out = (struct regdump_info_out *)new char[out_size];
cmd.reg_dump_info.out->ret_len = 0;
ioctl_code = IOCTL_QDMA_REG_DUMP;
device.ioctl(ioctl_code, NULL, 0, cmd.reg_info.out, out_size);
device.ioctl(ioctl_code, NULL, 0, cmd.reg_dump_info.out, out_size);
if (!cmd.reg_info.out->ret_len) {
if (!cmd.reg_dump_info.out->ret_len) {
printf("Failed to dump the registers\n");
}
else {
char *addr = (char *)&cmd.reg_info.out->pbuffer[0];
for (auto i = 0; ((i < (int)cmd.reg_info.out->ret_len) && (addr[i] != '\0')); i++) {
char *addr = (char *)&cmd.reg_dump_info.out->pbuffer[0];
for (auto i = 0; ((i < (int)cmd.reg_dump_info.out->ret_len) && (addr[i] != '\0')); i++) {
printf("%c", addr[i]);
}
}
delete[] cmd.reg_dump_info.out;
}
catch (const std::exception& e) {
delete[] cmd.reg_dump_info.out;
cout << "Failed to execute reg dump command.\n" << e.what() << '\n';
}
return 0;
}
static int handle_reg_info(const char* dev_name, const int argc, char* argv[])
{
UNREFERENCED_PARAMETER(dev_name);
UNREFERENCED_PARAMETER(argc);
UNREFERENCED_PARAMETER(argv);
auto i = 0;
bool bar_valid = false;
ioctl_cmd cmd = {};
DWORD ioctl_code = 0x0;
if (i == argc) {
cout << "insufficient arguments\n";
return 1;
}
while (i < argc) {
if (strcmp(argv[i], "bar") == 0) {
if ((argv[i + 1] == NULL) || (argv[i + 2] == NULL)) {
cout << "Insufficient options provided\n";
cout << "bar option needs atleast two arguments : <bar_num> <address> [num_regs <M>]\n";
return 1;
}
++i;
cmd.reg_info.in.bar_no = strtoul(argv[i], NULL, 0);
if ((MAX_VALID_BAR_NUM < cmd.reg_info.in.bar_no) &&
((cmd.reg_info.in.bar_no % 2) != 0)) {
cout << "Invalid BAR number provided : " << argv[i] << endl;
break;
}
cmd.reg_info.in.bar_no = cmd.reg_info.in.bar_no / 2;
bar_valid = true;
++i;
cmd.reg_info.in.address = strtoul(argv[i], NULL, 0);
++i;
if ((argv[i] != NULL) && (strcmp(argv[i], "num_regs")) == 0) {
cmd.reg_info.in.reg_cnt = strtoul(argv[i + 1], NULL, 0);
++i;
}
else {
cmd.reg_info.in.reg_cnt = 1;
}
}
else {
cout << "Unknown command " << argv[i] << endl;
return 1;
}
++i;
}
if (!bar_valid) {
return 1;
}
try {
device_file device;
auto ret = open_device(dev_name, device);
if (ret == false)
return 0;
unsigned int size = (cmd.reg_info.in.reg_cnt * MAX_REG_INFO_SZ);
unsigned int out_size = sizeof(struct reg_info_out) + size;
cmd.reg_info.out = (struct reg_info_out *)new char[out_size];
cmd.reg_info.out->ret_len = 0;
ioctl_code = IOCTL_QDMA_REG_INFO;
device.ioctl(ioctl_code, &cmd.reg_info.in, sizeof(cmd.reg_info.in),
cmd.reg_info.out, out_size);
if (!cmd.reg_info.out->ret_len) {
printf("Failed to dump the registers\n");
}
else {
char* data = (char*)&cmd.reg_info.out->pbuffer[0];
for (i = 0; ((i < (int)cmd.reg_info.out->ret_len) &&
(data[i] != '\0')); i++) {
printf("%c", data[i]);
}
}
delete[] cmd.reg_info.out;
}
catch (const std::exception& e) {
delete[] cmd.reg_info.out;
cout << "Failed to execute reg dump command.\n" << e.what() << '\n';
cout << "Failed to execute reg info command.\n" << e.what() << '\n';
}
return 0;
......@@ -1205,6 +1315,10 @@ static int handle_reg_cmds(const char *dev_name, const int argc, char* argv[])
++i;
return handle_reg_dump(dev_name, argc - i, argv + i);
}
else if (strcmp(argv[i], "info") == 0) {
++i;
return handle_reg_info(dev_name, argc - i, argv + i);
}
else {
cout << "Unknown command " << argv[i] << endl;
return 1;
......@@ -1304,6 +1418,7 @@ static void help(void)
cout << " intring dump vector <N> <start_idx> <end_idx> - interrupt ring dump for vector number <N>\n";
cout << " for intrrupt entries :<start_idx> --- <end_idx>\n";
cout << " reg dump - register dump\n";
cout << " reg info bar <N> addr [num_regs <M>] - dump detailed fields information of a register\n";
}
int __cdecl main(const int argc, char* argv[])
......
......@@ -20,7 +20,7 @@
#define __QDMATOOL_VERSION_H
#define PROGNAME "dma-ctl"
#define VERSION "2020.1.0"
#define VERSION "2020.2.0"
#define COPYRIGHT "Copyright (c) 2020 Xilinx Inc."
#endif /* __QDMATOOL_VERSION_H */
......@@ -20,7 +20,7 @@
#define __QDMARW_VERSION_H
#define PROGNAME "dma-rw"
#define VERSION "2020.1.0"
#define VERSION "2020.2.0"
#define COPYRIGHT "Copyright (c) 2020 Xilinx Inc."
#endif /*__QDMARW_VERSION_H*/
......@@ -105,6 +105,7 @@ enum commands {
CMD_QUEUE_NO_COPY,
CMD_SET_QMAX,
CMD_GET_QSTATS,
CMD_REG_INFO,
CMD_OP_MAX
};
......@@ -180,6 +181,8 @@ struct device_info_out {
BOOL mm_en;
BOOL mm_cmpl_en;
BOOL mailbox_en;
BOOL debug_mode;
UINT8 desc_eng_mode;
UINT32 num_mm_channels;
};
......@@ -307,6 +310,25 @@ struct qstat_out {
UINT32 active_cmpt_queues;
};
/** Structure to be passed as input parameter for
* IOCTL Command :
* IOCTL_QDMA_REG_INFO
*/
struct reg_info_in {
UINT32 bar_no;
UINT32 address;
UINT32 reg_cnt;
};
/** Structure to be passed as output parameter for
* IOCTL Command :
* IOCTL_QDMA_REG_INFO
*/
struct reg_info_out {
size_t ret_len;
char pbuffer[1];
};
struct csr_conf_data {
struct csr_conf_out *out;
};
......@@ -361,6 +383,11 @@ struct qstats_info {
struct qstat_out *out;
};
struct reg_info {
struct reg_info_in in;
struct reg_info_out* out;
};
/** Union that consolidates parameters for all ioctl commands */
union ioctl_cmd {
struct csr_conf_data csr;
......@@ -372,9 +399,10 @@ union ioctl_cmd {
struct ctx_dump_info ctx_info;
struct cmpt_data_info cmpt_info;
struct intring_info int_ring_info;
struct regdump_info reg_info;
struct regdump_info reg_dump_info;
struct qmax_info qmax_info;
struct qstats_info qstats_info;
struct reg_info reg_info;
};
#define QDMA_IOCTL(index) CTL_CODE(FILE_DEVICE_UNKNOWN, index, METHOD_BUFFERED, FILE_ANY_ACCESS)
......@@ -395,6 +423,7 @@ union ioctl_cmd {
#define IOCTL_QDMA_QUEUE_NO_COPY QDMA_IOCTL(CMD_QUEUE_NO_COPY)
#define IOCTL_QDMA_SET_QMAX QDMA_IOCTL(CMD_SET_QMAX)
#define IOCTL_QDMA_GET_QSTATS QDMA_IOCTL(CMD_GET_QSTATS)
#define IOCTL_QDMA_REG_INFO QDMA_IOCTL(CMD_REG_INFO)
#include <poppack.h>
......
......@@ -23,7 +23,7 @@ Class = %ClassName%
ClassGuid = {a3a4c1ce-5a80-452c-9b51-a98edd3378d1}
Provider = %ManufacturerName%
CatalogFile = QDMA.cat
DriverVer = 08/01/2019, 2019.2.5.9 ;Format : year.quarter_no.drv_ver.libqdma_ver
DriverVer = 10/15/2020, 2020.2.0.0 ;Format : year.quarter_no.drv_ver.libqdma_ver
DriverPackageType = PlugAndPlay
[DestinationDirs]
......
......@@ -148,6 +148,39 @@ ErrExit:
return status;
}
//_Use_decl_annotations_
static void
qdma_user_isr_handler(
ULONG event_id,
void *user_data)
{
UNREFERENCED_PARAMETER(event_id);
UNREFERENCED_PARAMETER(user_data);
TraceInfo(TRACE_DEVICE, "In %s", __func__);
}
//_Use_decl_annotations_
static void
qdma_user_interrupt_enable(
ULONG event_id,
void *user_data)
{
UNREFERENCED_PARAMETER(event_id);
UNREFERENCED_PARAMETER(user_data);
TraceInfo(TRACE_DEVICE, "In %s", __func__);
}
//_Use_decl_annotations_
static void
qdma_user_interrupt_disable(
ULONG event_id,
void *user_data)
{
UNREFERENCED_PARAMETER(event_id);
UNREFERENCED_PARAMETER(user_data);
TraceInfo(TRACE_DEVICE, "In %s", __func__);
}
NTSTATUS qdma_evt_device_prepare_hardware(
const WDFDEVICE device,
const WDFCMRESLIST resources,
......@@ -155,26 +188,42 @@ NTSTATUS qdma_evt_device_prepare_hardware(
{
PAGED_CODE();
device_context* ctx = get_device_context(device);
qdma_drv_config drv_conf = {};
device_context *ctx = get_device_context(device);
ctx->qdma = qdma_interface::create_qdma_device();
if (ctx->qdma == nullptr) {
TraceError(TRACE_DEVICE, "qdma device memory allocation failed");
return STATUS_INSUFFICIENT_RESOURCES;
}
NTSTATUS status = read_reg_params(ctx->config.op_mode, ctx->config.config_bar);
if (!NT_SUCCESS(status)) {
TraceError(TRACE_DEVICE, "failed to read registry params %!STATUS!", status);
return STATUS_INTERNAL_ERROR;
return status;
}
status = ctx->qdma->init(ctx->config.op_mode, ctx->config.config_bar, QDMA_MAX_QUEUES_PER_PF);
drv_conf.operation_mode = ctx->config.op_mode;
drv_conf.cfg_bar = ctx->config.config_bar;
drv_conf.qsets_max = QDMA_MAX_QUEUES_PER_PF;
drv_conf.user_msix_max = QDMA_MAX_USER_INTR;
drv_conf.data_msix_max = QDMA_MAX_DATA_INTR;
drv_conf.user_data = (void*)device;
drv_conf.user_isr_handler = qdma_user_isr_handler;
drv_conf.user_interrupt_enable_handler = qdma_user_interrupt_enable;
drv_conf.user_interrupt_disable_handler = qdma_user_interrupt_disable;
status = ctx->qdma->init(drv_conf);
if (!NT_SUCCESS(status)) {
TraceError(TRACE_DEVICE, "qdma.init() failed! %!STATUS!", status);
return STATUS_INTERNAL_ERROR;
return status;
}
status = ctx->qdma->open(device, resources, resources_translated);
if (!NT_SUCCESS(status)) {
TraceError(TRACE_DEVICE, "qdma.open() failed! %!STATUS!", status);
return STATUS_INTERNAL_ERROR;
return status;
}
return STATUS_SUCCESS;
......
......@@ -22,6 +22,8 @@
EXTERN_C_START
#define QDMA_MAX_QUEUES_PER_PF 512
#define QDMA_MAX_USER_INTR 1
#define QDMA_MAX_DATA_INTR 7
struct device_context {
struct {
......
......@@ -60,7 +60,7 @@ DriverEntry(
return status;
}
TraceInfo(TRACE_DRIVER, "%!FUNC! Exit");
TraceVerbose(TRACE_DRIVER, "%!FUNC! Exit");
return status;
}
......@@ -92,7 +92,7 @@ qdma_evt_driver_context_cleanup(
UNREFERENCED_PARAMETER(driver_object);
#endif
TraceInfo(TRACE_DRIVER, "%!FUNC! Entry");
TraceVerbose(TRACE_DRIVER, "%!FUNC! Entry");
/** Stop WPP Tracing */
WPP_CLEANUP(WdfDriverWdmGetDriverObject(static_cast<WDFDRIVER>(driver_object)));
}
This diff is collapsed.
......@@ -23,6 +23,8 @@ EXTERN_C_START
using namespace xlnx;
static constexpr ULONG IO_QUEUE_TAG = 'UQOI';
NTSTATUS qdma_io_queue_initialize(WDFDEVICE wdf_device);
struct DMA_TXN_CONTEXT {
......@@ -32,6 +34,12 @@ struct DMA_TXN_CONTEXT {
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DMA_TXN_CONTEXT, get_dma_txn_context)
struct ST_DMA_ZERO_TX_PRIV {
WDFREQUEST request;
PVOID sg_list;
};
EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL qdma_evt_ioctl;
EVT_WDF_IO_QUEUE_IO_STOP qdma_evt_io_stop;
EVT_WDF_IO_QUEUE_IO_READ qdma_evt_io_read;
......
......@@ -44,6 +44,20 @@ enum qdma_q_type {
QDMA_Q_TYPE_MAX
};
/** queue_state - State of the QDMA queue */
enum queue_state {
/** Queue is available to configure */
QUEUE_AVAILABLE,
/** Queue is added with resources */
QUEUE_ADDED,
/** Queue is programmed and started */
QUEUE_STARTED,
/** Queue critical operation is in progress */
QUEUE_BUSY,
/** Invalid Queue State */
QUEUE_INVALID_STATE
};
/** Streaming card to host packet type */
enum class st_c2h_pkt_type {
/** C2H DATA Packet MACRO */
......@@ -116,11 +130,11 @@ enum class qdma_bar_type {
* (Contains all QDMA configuration Registers)
*/
CONFIG_BAR,
/** QDMA User BAR
/** QDMA AXI Master Lite BAR
* (Contains User Logic Registers)
*/
USER_BAR,
/** QDMA Bypass BAR
/** QDMA AXI Bridge Master BAR
* (Contains Bypass Registers to bypass QDMA)
*/
BYPASS_BAR
......@@ -178,6 +192,68 @@ using st_rx_completion_cb = void(*)(const st_c2h_pkt_fragment *rx_frags, size_t
*/
using proc_st_udd_only_cb = void(*)(UINT16 qid, void *udd_addr, void *priv);
/**
* fp_user_isr_handler() - User defined user ISR handler
*
* @param[in] event_id: Event identifier
* @param[in] user_data: Driver provided user data
*
* @return void
*/
using fp_user_isr_handler = void(*)(ULONG event_id, void *user_data);
/**
* fp_user_interrupt_enable_handler() - User defined user ISR handler
*
* @param[in] event_id: Event identifier
* @param[in] user_data: Driver provided user data
*
* @return void
*/
using fp_user_interrupt_enable_handler = void(*)(ULONG event_id, void *user_data);
/**
* fp_user_interrupt_disable_handler() - User defined user ISR handler
*
* @param[in] event_id: Event identifier
* @param[in] user_data: Driver provided user data
*
* @return void
*/
using fp_user_interrupt_disable_handler = void(*)(ULONG event_id, void *user_data);
/** dev_config - qdma device configuration
* needed to initialize the device
*/
struct qdma_drv_config {
/* Queue operation mode */
queue_op_mode operation_mode;
/* Config BAR index */
UINT8 cfg_bar;
/* Maximum queues for the device */
UINT32 qsets_max;
/* Maximum user MSIx vector to use */
UINT16 user_msix_max;
/* Maximum data MSIx vector to use */
UINT16 data_msix_max;
/* User data for user interrupt callback functions */
void *user_data;
/* User ISR handler */
fp_user_isr_handler user_isr_handler;
/* User interrupt enable handler */
fp_user_interrupt_enable_handler user_interrupt_enable_handler;
/* User interrupt disable handler */
fp_user_interrupt_disable_handler user_interrupt_disable_handler;
};
/** queue_config - qdma queue configuration
* needed to add a queue
*/
......@@ -248,6 +324,12 @@ struct qdma_device_attributes_info {
bool mm_cmpl_en;
/** Mailbox Feature enabled */
bool mailbox_en;
/** Debug mode is enabled/disabled for IP */
bool debug_mode;
/** Descriptor Engine mode:
* Internal only/Bypass only/Internal & Bypass
*/
UINT8 desc_eng_mode;
/** Number of MM channels supported */
UINT16 num_mm_channels;
};
......@@ -429,6 +511,24 @@ struct qdma_qstat_info {
UINT32 active_cmpt_queues;
};
/** qdma_reg_info - Structure contains required members to
* retrieve requested qdma registers information
*/
struct qdma_reg_info {
/** PCIe bar number */
UINT32 bar_no;
/** Register address offset */
UINT32 address;
/** number of registers to retrieve */
UINT32 reg_cnt;
/** Length of the buffer pointed by pbuffer */
size_t buf_len;
/** Length of the data present in pbuffer */
size_t ret_len;
/** output buffer to copy the register info */
char *pbuffer;
};
/**
* qdma_interface - libqdma interface class
*
......@@ -445,14 +545,11 @@ public:
* init() - Initializes the qdma device with operation mode and
* config bar number to use
*
* @param[in] operation_mode: queue oper mode (poll, intr, aggr)
* @param[in] cfg_bar: config bar number for qdma device
* @param[in] qsets_max: Maximum number of queues requested for this
* device
* @param[in] conf: Device operation configuration
*
* @return STATUS_SUCCESS for success else error
*****************************************************************************/
virtual NTSTATUS init(queue_op_mode operation_mode, UINT8 cfg_bar, UINT16 qsets_max) = 0;
virtual NTSTATUS init(qdma_drv_config conf) = 0;
/*****************************************************************************/
/**
......@@ -517,17 +614,31 @@ public:
*****************************************************************************/
virtual NTSTATUS write_bar(qdma_bar_type bar_type, size_t offset, void* data, size_t size) = 0;
/*****************************************************************************/
/**
* write_bar() - Performs PCIe write operation on specified BAR number at
* requested offset of requested size
*
* @param[in] bar_type: BAR Type
* @param[out] bar_base: BAR base mapped address
* @param[out] bar_lenght: Bar length(in bytes)
*
* @return STATUS_SUCCESS for success else error
*****************************************************************************/
virtual NTSTATUS get_bar_info(qdma_bar_type bar_type, PVOID &bar_base, size_t &bar_length) = 0;
/*****************************************************************************/
/**
* qdma_get_queues_state() - Retrieves the state of the specified queue
*
* @param[in] qid: queue id relative to this QDMA device
* @param[out] qstate: state of the queue specified as enumeration
* @param[out] state: state of the queue specified as character string
* @param[in] sz: size of the state character array
*
* @return STATUS_SUCCESS for success else error
*****************************************************************************/
virtual NTSTATUS qdma_get_queues_state(UINT16 qid, char *state, size_t sz) = 0;
virtual NTSTATUS qdma_get_queues_state(UINT16 qid, enum queue_state *qstate, char *state, size_t sz) = 0;
/*****************************************************************************/
/**
......@@ -595,12 +706,10 @@ public:
* @param[in] compl_cb: completion call back function
* @param[in] priv: private data that gets passed to
* compl_cb function
* @param[out] xfered_len: If status is NT_SUCCESS, then number
* of bytes for a request successfully enqueued
*
* @return STATUS_SUCCESS for success else error
*****************************************************************************/
virtual NTSTATUS qdma_enqueue_mm_request(UINT16 qid, WDF_DMA_DIRECTION direction, PSCATTER_GATHER_LIST sg_list, LONGLONG device_offset, dma_completion_cb compl_cb, VOID *priv, size_t &xfered_len) = 0;
virtual NTSTATUS qdma_enqueue_mm_request(UINT16 qid, WDF_DMA_DIRECTION direction, PSCATTER_GATHER_LIST sg_list, LONGLONG device_offset, dma_completion_cb compl_cb, VOID *priv) = 0;
/*****************************************************************************/
/**
......@@ -612,12 +721,10 @@ public:
* to indicate write operation is completed
* @param[in,out] priv: private data that gets passed to
* compl_cb function
* @param[out] xfered_len: If status is NT_SUCCESS, then number
* of bytes for a request successfully enqueued.
*
* @return STATUS_SUCCESS for success else error
*****************************************************************************/
virtual NTSTATUS qdma_enqueue_st_tx_request(UINT16 qid, PSCATTER_GATHER_LIST sg_list, dma_completion_cb compl_cb, VOID *priv, size_t &xfered_len) = 0;
virtual NTSTATUS qdma_enqueue_st_tx_request(UINT16 qid, PSCATTER_GATHER_LIST sg_list, dma_completion_cb compl_cb, VOID *priv) = 0;
/*****************************************************************************/
/**
......@@ -768,6 +875,16 @@ public:
*****************************************************************************/
virtual NTSTATUS qdma_get_qstats_info(qdma_qstat_info &qstats) = 0;
/*****************************************************************************/
/**
* qdma_get_reg_info() - Retrieves the requested QDMA registers information
*
* @param[out] reg_info: Register information (Address, Len, etc.,)
*
* @return STATUS_SUCCESS for success else error
*****************************************************************************/
virtual NTSTATUS qdma_get_reg_info(qdma_reg_info* reg_info) = 0;
/*****************************************************************************/
/**
* create_qdma_device() - Allocates an instance for qdma device
......
......@@ -21,7 +21,7 @@
#undef VER_PRODUCTMAJORVERSION
#define VER_PRODUCTMAJORVERSION (2020)
#undef VER_PRODUCTMINORVERSION
#define VER_PRODUCTMINORVERSION (1)
#define VER_PRODUCTMINORVERSION (2)
#undef VER_PRODUCTREVISION
#define VER_PRODUCTREVISION (0)
#undef VER_PRODUCTBUILD
......@@ -56,11 +56,11 @@
// Version number (in format needed for version resources)
#undef VER_PRODUCTVERSION
#define VER_PRODUCTVERSION 2020,1,0,0
#define VER_PRODUCTVERSION 2020,2,0,0
// Version number string
#undef VER_PRODUCTVERSION_STR
#define VER_PRODUCTVERSION_STR "2020.1.0.0"
#define VER_PRODUCTVERSION_STR "2020.2.0.0"
/** File Details ************************************************************/
......
......@@ -212,10 +212,12 @@
<ClCompile Include="source\interrupts.cpp" />
<ClCompile Include="source\qdma.cpp" />
<ClCompile Include="source\qdma_access\eqdma_soft_access\eqdma_soft_access.c" />
<ClCompile Include="source\qdma_access\eqdma_soft_access\eqdma_soft_reg_dump.c" />
<ClCompile Include="source\qdma_access\qdma_access_common.c" />
<ClCompile Include="source\qdma_access\qdma_list.c" />
<ClCompile Include="source\qdma_access\qdma_resource_mgmt.c" />
<ClCompile Include="source\qdma_access\qdma_s80_hard_access\qdma_s80_hard_access.c" />
<ClCompile Include="source\qdma_access\qdma_s80_hard_access\qdma_s80_hard_reg_dump.c" />
<ClCompile Include="source\qdma_access\qdma_soft_access\qdma_soft_access.c" />
<ClCompile Include="source\qdma_platform.cpp" />
<ClCompile Include="source\thread.cpp" />
......
......@@ -119,5 +119,11 @@
<ClCompile Include="source\xpcie.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source\qdma_access\eqdma_soft_access\eqdma_soft_reg_dump.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source\qdma_access\qdma_s80_hard_access\qdma_s80_hard_reg_dump.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
\ No newline at end of file
......@@ -63,12 +63,15 @@ struct intr_queue {
NTSTATUS intring_dump(qdma_intr_ring_info *intring_info);
};
typedef struct IRQ_CONTEXT {
typedef struct QDMA_IRQ_CONTEXT {
bool is_coal;
interrupt_type intr_type = interrupt_type::NONE;
ULONG vector_id;
UINT32 weight;
/* For user interrupt handling */
void *user_data;
/* For Error interrupt handling */
qdma_device *qdma_dev = nullptr;
......@@ -79,21 +82,21 @@ typedef struct IRQ_CONTEXT {
intr_queue *intr_q = nullptr;
/* Interrupt handler function */
void (*interrupt_handler)(IRQ_CONTEXT *);
}*PIRQ_CONTEXT;
void (*interrupt_handler)(QDMA_IRQ_CONTEXT *);
}*PQDMA_IRQ_CONTEXT;
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(IRQ_CONTEXT, get_irq_context);
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(QDMA_IRQ_CONTEXT, get_qdma_irq_context);
struct interrupt_manager {
interrupt_type intr_type = interrupt_type::NONE;
ULONG err_vector_id = 0;
ULONG user_vector_id = 0;
ULONG user_vector_id_start = 0;
ULONG user_vector_id_end = 0;
ULONG data_vector_id_end = 0;
ULONG data_vector_id_start = 0;
WDFSPINLOCK lock = nullptr;
UINT32 irq_weight[qdma_max_msix_vectors_per_pf];
WDFINTERRUPT irq[qdma_max_msix_vectors_per_pf];
intr_queue intr_q[qdma_max_msix_vectors_per_pf];
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -87,6 +87,18 @@ static constexpr unsigned int mm_c2h_completion_weight = 2048;
static constexpr unsigned int st_h2c_completion_weight = 2048;
static constexpr unsigned int st_c2h_completion_weight = 2048;
static constexpr unsigned int max_req_service_cnt = 10;
/**
* Structure to hold the driver name and mode
*/
struct drv_mode_name {
/** Mode of the function */
queue_op_mode mode;
/** Driver Name */
char name[20];
};
class qdma_device;
struct queue_pair;
......@@ -111,6 +123,9 @@ struct queue_pair;
#define LIST_FOR_EACH_ENTRY_SAFE(list_head, n, entry) \
for ((entry) = (list_head)->Flink, (n) = (entry)->Flink; (entry) != (list_head); (entry) = (n), (n) = (entry)->Flink)
#define LIST_GET_ENTRY(entry, type, member) \
CONTAINING_RECORD(entry, type, member)
/** queue_type - QDMA queue type */
enum class queue_type {
/** Memory mapped queue type */
......@@ -121,24 +136,14 @@ enum class queue_type {
NONE
};
/** queue_state - State of the QDMA queue */
enum queue_state {
/** Queue is available to configure */
QUEUE_AVAILABLE,
/** Queue is added with resources */
QUEUE_ADDED,
/** Queue is programmed and started */
QUEUE_STARTED,
/** Queue critical operation is in progress */
QUEUE_BUSY
};
/** device_state - State of the QDMA device */
enum device_state {
/** Device is online */
DEVICE_ONLINE,
/** Device is in Init State */
DEVICE_INIT,
/** Device is offline */
DEVICE_OFFLINE,
/** Device is online */
DEVICE_ONLINE,
};
/**
......@@ -146,6 +151,11 @@ enum device_state {
*/
#define QDMA_DEV_NAME_MAXLEN 32
/**
* QDMA_QUEUE_NAME_MAXLEN - Maximum queue name length
*/
#define QDMA_QUEUE_NAME_MAXLEN 32
/**
* qdma_dev_conf - defines the per-device qdma property.
*/
......@@ -200,7 +210,6 @@ struct ring_buffer {
struct {
UINT32 tot_desc_accepted;
UINT32 tot_desc_processed;
UINT32 tot_desc_dropped;
}stats;
PFORCEINLINE void advance_idx(volatile UINT32& idx);
......@@ -312,6 +321,31 @@ struct st_c2h_pkt_buffer {
PVOID get_va(void);
};
struct dma_request {
/** Linked list entry to form request queue */
LIST_ENTRY list_entry;
/** DMA Mode (ST/MM) */
bool is_st;
/** Direction of DMA */
WDF_DMA_DIRECTION direction;
/** SG list of request */
PSCATTER_GATHER_LIST sg_list;
/** Completion callback handler */
dma_completion_cb compl_cb;
/** Private data to pass during completion callback */
VOID *priv;
/** The device address to/from DMA
* (Only Valid for MM transfers) */
LONGLONG device_offset;
/** Holds the next index to resume
* request transfer for split request */
UINT32 sg_index;
/** Holds the next device offset to resume
* request transfer for split request
* (Only valid for MM transfers ) */
LONGLONG offset_idx;
};
struct h2c_queue {
queue_config user_conf;
libqdma_queue_config lib_config;
......@@ -319,6 +353,9 @@ struct h2c_queue {
ring_buffer desc_ring;
dma_req_tracker req_tracker;
/** This forms a chain of h2c requests */
LIST_ENTRY req_list_head;
/* This lock is to ensure enqueueing/adding
the requests to the descriptor ring properly
......@@ -326,6 +363,7 @@ struct h2c_queue {
request tracker design will make sure proper execution
*/
WDFSPINLOCK lock = nullptr;
poll_operation_entry *req_proc_entry;
poll_operation_entry *poll_entry;
qdma_q_pidx_reg_info csr_pidx_info;
......@@ -341,6 +379,9 @@ struct c2h_queue {
ring_buffer desc_ring;
dma_req_tracker req_tracker;
/** This forms a chain of c2h requests */
LIST_ENTRY req_list_head;
/* This lock is to ensure MM enqueueing/adding
the requests to the descriptor ring properly
......@@ -348,7 +389,8 @@ struct c2h_queue {
request tracker design takes care
*/
WDFSPINLOCK lock = nullptr;
poll_operation_entry * poll_entry;
poll_operation_entry *req_proc_entry;
poll_operation_entry *poll_entry;
qdma_q_pidx_reg_info csr_pidx_info;
qdma_q_cmpt_cidx_reg_info csr_cmpt_cidx_info;
bool is_cmpt_valid = false;
......@@ -380,6 +422,7 @@ struct queue_pair {
qdma_device *qdma = nullptr;
queue_type type;
char name[QDMA_QUEUE_NAME_MAXLEN];
volatile LONG state;
UINT16 idx = 0; /* queue index - relative to this PF */
......@@ -399,14 +442,18 @@ struct queue_pair {
PFORCEINLINE void update_sw_index_with_csr_c2h_pidx(UINT32 new_pidx);
/** Transfer initiate functions */
NTSTATUS enqueue_mm_request(const WDF_DMA_DIRECTION direction, PSCATTER_GATHER_LIST sg_list, LONGLONG device_offset, dma_completion_cb compl_cb, VOID *priv, size_t &xfered_len);
NTSTATUS enqueue_st_tx_request(PSCATTER_GATHER_LIST sg_list, dma_completion_cb compl_cb, VOID *priv, size_t &xfered_len);
NTSTATUS enqueue_st_rx_request(size_t length, st_rx_completion_cb compl_cb, void *priv);
NTSTATUS enqueue_dma_request(dma_request *request);
NTSTATUS enqueue_dma_request(size_t length, st_rx_completion_cb compl_cb, void *priv);
/** Transfer processing functions */
service_status process_mm_request(dma_request* request, size_t* xfer_len);
service_status process_st_h2c_request(dma_request* request, size_t* xfer_len);
NTSTATUS process_st_c2h_data_pkt(void* udd_ptr, const UINT32 length);
/** Transfer completion functions */
service_status service_mm_st_h2c_completions(ring_buffer *desc_ring, dma_req_tracker *tracker, UINT32 budget);
service_status service_mm_st_h2c_completions(ring_buffer *desc_ring, dma_req_tracker *tracker, UINT32 budget, UINT32& proc_desc_cnt);
service_status st_service_c2h_queue(UINT32 budget);
NTSTATUS process_st_c2h_data_pkt(void *udd_ptr, const UINT32 length);
PFORCEINLINE void update_c2h_pidx_in_batch(UINT32 processed_desc_cnt);
NTSTATUS check_cmpt_error(c2h_wb_header_8B *cmpt_data);
......@@ -443,9 +490,11 @@ public:
qdma_dev_conf dev_conf;
/** Structure that contains QDMA global CSR registers information */
qdma_glbl_csr_conf csr_conf;
/** Structure that contains QDMA driver configuration */
qdma_drv_config drv_conf;
/** DMA Initialization/Teardown APIs */
NTSTATUS init(queue_op_mode operation_mode, UINT8 cfg_bar, UINT16 qsets_max);
NTSTATUS init(qdma_drv_config conf);
NTSTATUS open(WDFDEVICE device, WDFCMRESLIST resources, WDFCMRESLIST resources_translated);
void close(void);
bool qdma_is_device_online(void);
......@@ -455,6 +504,7 @@ public:
NTSTATUS write_bar(qdma_bar_type bar_type, size_t offset, void* data, size_t size);
ULONG qdma_conf_reg_read(size_t offset);
void qdma_conf_reg_write(size_t offset, ULONG data);
NTSTATUS get_bar_info(qdma_bar_type bar_type, PVOID &bar_base, size_t &bar_length);
/** Queue Configuration APIs (Add, Start Stop, Delete, state) */
NTSTATUS qdma_add_queue(UINT16 qid, queue_config& conf);
......@@ -462,12 +512,12 @@ public:
NTSTATUS qdma_stop_queue(UINT16 qid);
NTSTATUS qdma_remove_queue(UINT16 qid);
NTSTATUS qdma_is_queue_in_range(UINT16 qid);
NTSTATUS qdma_get_queues_state(UINT16 qid, CHAR *str, size_t str_maxlen);
NTSTATUS qdma_get_queues_state(UINT16 qid, enum queue_state *qstate, CHAR *str, size_t str_maxlen);
NTSTATUS qdma_set_qmax(UINT32 queue_max);
/** DMA transfer APIs (From Device and To Device) */
NTSTATUS qdma_enqueue_mm_request(UINT16 qid, WDF_DMA_DIRECTION direction, PSCATTER_GATHER_LIST sg_list, LONGLONG device_offset, dma_completion_cb compl_cb, VOID *priv, size_t &xfered_len);
NTSTATUS qdma_enqueue_st_tx_request(UINT16 qid, PSCATTER_GATHER_LIST sg_list, dma_completion_cb compl_cb, VOID *priv, size_t &xfered_len);
NTSTATUS qdma_enqueue_mm_request(UINT16 qid, WDF_DMA_DIRECTION direction, PSCATTER_GATHER_LIST sg_list, LONGLONG device_offset, dma_completion_cb compl_cb, VOID *priv);
NTSTATUS qdma_enqueue_st_tx_request(UINT16 qid, PSCATTER_GATHER_LIST sg_list, dma_completion_cb compl_cb, VOID *priv);
NTSTATUS qdma_enqueue_st_rx_request(UINT16 qid, size_t length, st_rx_completion_cb compl_cb, VOID *priv);
/** DMA Completion ring APIs */
......@@ -486,6 +536,7 @@ public:
NTSTATUS qdma_intring_dump(qdma_intr_ring_info *intring_info);
NTSTATUS qdma_regdump(qdma_reg_dump_info *regdump_info);
NTSTATUS qdma_get_qstats_info(qdma_qstat_info &qstats);
NTSTATUS qdma_get_reg_info(qdma_reg_info *reg_info);
/** DMA Versioning APIs */
NTSTATUS qdma_device_version_info(qdma_version_info &version_info);
......@@ -497,8 +548,6 @@ private:
LIST_ENTRY list_entry;
/** Identifier returned by resource manager */
UINT32 dma_dev_index = 0;
/** Maximum number of queues for this device */
UINT32 qmax;
/** Start/base queue number for this device */
INT32 qbase = -1;
/** Device state */
......@@ -506,8 +555,6 @@ private:
xpcie_device pcie;
WDFDEVICE wdf_dev = nullptr;
queue_op_mode op_mode;
UINT8 config_bar = 0;
qdma_hw_version_info hw_version_info;
queue_pair *queue_pairs = nullptr;
interrupt_manager irq_mgr;
......@@ -544,7 +591,7 @@ private:
void destroy_func(void);
void destroy_resource_manager(void);
NTSTATUS configure_irq(PIRQ_CONTEXT irq_context, ULONG vec);
NTSTATUS configure_irq(PQDMA_IRQ_CONTEXT irq_context, ULONG vec);
NTSTATUS intr_setup(WDFCMRESLIST resources, const WDFCMRESLIST resources_translated);
void intr_teardown(void);
NTSTATUS setup_legacy_interrupt(WDFCMRESLIST resources, const WDFCMRESLIST resources_translated);
......
......@@ -14,15 +14,15 @@
* under the License.
*/
#ifndef EQDMA_ACCESS_H_
#define EQDMA_ACCESS_H_
#include "qdma_access_common.h"
#ifndef __EQDMA_SOFT_ACCESS_H_
#define __EQDMA_SOFT_ACCESS_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "qdma_platform.h"
/**
* enum qdma_error_idx - qdma errors
*/
......@@ -191,8 +191,18 @@ struct eqdma_hw_err_info {
uint32_t stat_reg_addr;
uint32_t leaf_err_mask;
uint32_t global_err_mask;
void (*eqdma_hw_err_process)(void *dev_hndl);
};
#define EQDMA_OFFSET_VF_VERSION 0x5014
#define EQDMA_OFFSET_VF_USER_BAR 0x5018
#define EQDMA_OFFSET_MBOX_BASE_PF 0x22400
#define EQDMA_OFFSET_MBOX_BASE_VF 0x5000
#define EQDMA_COMPL_CTXT_BADDR_HIGH_H_MASK GENMASK_ULL(63, 38)
#define EQDMA_COMPL_CTXT_BADDR_HIGH_L_MASK GENMASK_ULL(37, 6)
#define EQDMA_COMPL_CTXT_BADDR_LOW_MASK GENMASK_ULL(5, 2)
int eqdma_init_ctxt_memory(void *dev_hndl);
......@@ -243,7 +253,8 @@ int eqdma_context_buf_len(uint8_t st,
enum qdma_dev_q_type q_type, uint32_t *buflen);
int eqdma_hw_error_process(void *dev_hndl);
const char *eqdma_hw_get_error_name(enum qdma_error_idx err_idx);
const char *eqdma_hw_get_error_name(uint32_t err_idx);
int eqdma_hw_error_enable(void *dev_hndl, uint32_t err_idx);
int eqdma_read_dump_queue_context(void *dev_hndl,
uint16_t qid_hw,
......@@ -258,19 +269,38 @@ int eqdma_get_user_bar(void *dev_hndl, uint8_t is_vf,
uint8_t func_id, uint8_t *user_bar);
int eqdma_dump_config_reg_list(void *dev_hndl,
uint32_t num_regs,
uint32_t total_regs,
struct qdma_reg_data *reg_list,
char *buf, uint32_t buflen);
int eqdma_read_reg_list(void *dev_hndl, uint8_t is_vf,
uint16_t reg_rd_slot,
uint16_t reg_rd_group,
uint16_t *total_regs,
struct qdma_reg_data *reg_list);
int eqdma_set_default_global_csr(void *dev_hndl);
int eqdma_global_csr_conf(void *dev_hndl, uint8_t index, uint8_t count,
uint32_t *csr_val,
enum qdma_global_csr_type csr_type,
enum qdma_hw_access_type access_type);
int eqdma_global_writeback_interval_conf(void *dev_hndl,
enum qdma_wrb_interval *wb_int,
enum qdma_hw_access_type access_type);
int eqdma_mm_channel_conf(void *dev_hndl, uint8_t channel, uint8_t is_c2h,
uint8_t enable);
int eqdma_dump_reg_info(void *dev_hndl, uint32_t reg_addr,
uint32_t num_regs, char *buf, uint32_t buflen);
uint32_t eqdma_get_config_num_regs(void);
struct xreg_info *eqdma_get_config_regs(void);
#ifdef __cplusplus
}
#endif
#endif /* EQDMA_ACCESS_H_ */
#endif /* __EQDMA_SOFT_ACCESS_H_ */
......@@ -14,21 +14,65 @@
* under the License.
*/
#ifndef QDMA_ACCESS_COMMON_H_
#define QDMA_ACCESS_COMMON_H_
#include "qdma_access_export.h"
#include "qdma_access_errors.h"
#ifndef __QDMA_ACCESS_COMMON_H_
#define __QDMA_ACCESS_COMMON_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "qdma_access_export.h"
#include "qdma_access_errors.h"
/* QDMA HW version string array length */
#define QDMA_HW_VERSION_STRING_LEN 32
#define ENABLE_INIT_CTXT_MEMORY 1
#ifdef GCC_COMPILER
static inline uint32_t get_trailing_zeros(uint64_t x)
{
uint32_t rv =
__builtin_ffsll(x) - 1;
return rv;
}
#else
static inline uint32_t get_trailing_zeros(uint64_t value)
{
uint32_t pos = 0;
if ((value & 0xffffffff) == 0) {
pos += 32;
value >>= 32;
}
if ((value & 0xffff) == 0) {
pos += 16;
value >>= 16;
}
if ((value & 0xff) == 0) {
pos += 8;
value >>= 8;
}
if ((value & 0xf) == 0) {
pos += 4;
value >>= 4;
}
if ((value & 0x3) == 0) {
pos += 2;
value >>= 2;
}
if ((value & 0x1) == 0)
pos += 1;
return pos;
}
#endif
#define FIELD_SHIFT(mask) get_trailing_zeros(mask)
#define FIELD_SET(mask, val) ((val << FIELD_SHIFT(mask)) & mask)
#define FIELD_GET(mask, reg) ((reg & mask) >> FIELD_SHIFT(mask))
/* CSR Default values */
#define DEFAULT_MAX_DSC_FETCH 6
#define DEFAULT_WRB_INT QDMA_WRB_INTERVAL_128
......@@ -50,6 +94,66 @@ extern "C" {
*/
#define QDMA_NUM_DATA_VEC_FOR_INTR_CXT 1
enum ind_ctxt_cmd_op {
QDMA_CTXT_CMD_CLR,
QDMA_CTXT_CMD_WR,
QDMA_CTXT_CMD_RD,
QDMA_CTXT_CMD_INV
};
enum ind_ctxt_cmd_sel {
QDMA_CTXT_SEL_SW_C2H,
QDMA_CTXT_SEL_SW_H2C,
QDMA_CTXT_SEL_HW_C2H,
QDMA_CTXT_SEL_HW_H2C,
QDMA_CTXT_SEL_CR_C2H,
QDMA_CTXT_SEL_CR_H2C,
QDMA_CTXT_SEL_CMPT,
QDMA_CTXT_SEL_PFTCH,
QDMA_CTXT_SEL_INT_COAL,
QDMA_CTXT_SEL_PASID_RAM_LOW,
QDMA_CTXT_SEL_PASID_RAM_HIGH,
QDMA_CTXT_SEL_TIMER,
QDMA_CTXT_SEL_FMAP,
};
/* polling a register */
#define QDMA_REG_POLL_DFLT_INTERVAL_US 10 /* 10us per poll */
#define QDMA_REG_POLL_DFLT_TIMEOUT_US (500*1000) /* 500ms */
/** Constants */
#define QDMA_NUM_RING_SIZES 16
#define QDMA_NUM_C2H_TIMERS 16
#define QDMA_NUM_C2H_BUFFER_SIZES 16
#define QDMA_NUM_C2H_COUNTERS 16
#define QDMA_MM_CONTROL_RUN 0x1
#define QDMA_MM_CONTROL_STEP 0x100
#define QDMA_MAGIC_NUMBER 0x1fd3
#define QDMA_PIDX_STEP 0x10
#define QDMA_CMPT_CIDX_STEP 0x10
#define QDMA_INT_CIDX_STEP 0x10
/** QDMA_IND_REG_SEL_PFTCH */
#define QDMA_PFTCH_CTXT_SW_CRDT_GET_H_MASK GENMASK(15, 3)
#define QDMA_PFTCH_CTXT_SW_CRDT_GET_L_MASK GENMASK(2, 0)
/** QDMA_IND_REG_SEL_CMPT */
#define QDMA_COMPL_CTXT_BADDR_GET_H_MASK GENMASK_ULL(63, 38)
#define QDMA_COMPL_CTXT_BADDR_GET_L_MASK GENMASK_ULL(37, 12)
#define QDMA_COMPL_CTXT_PIDX_GET_H_MASK GENMASK(15, 4)
#define QDMA_COMPL_CTXT_PIDX_GET_L_MASK GENMASK(3, 0)
#define QDMA_INTR_CTXT_BADDR_GET_H_MASK GENMASK_ULL(63, 61)
#define QDMA_INTR_CTXT_BADDR_GET_M_MASK GENMASK_ULL(60, 29)
#define QDMA_INTR_CTXT_BADDR_GET_L_MASK GENMASK_ULL(28, 12)
#define QDMA_GLBL2_MM_CMPT_EN_MASK BIT(2)
#define QDMA_GLBL2_FLR_PRESENT_MASK BIT(1)
#define QDMA_GLBL2_MAILBOX_EN_MASK BIT(0)
#define QDMA_REG_IND_CTXT_REG_COUNT 8
/* ------------------------ indirect register context fields -----------*/
union qdma_ind_ctxt_cmd {
uint32_t word;
......@@ -294,8 +398,6 @@ struct qdma_descq_cmpt_ctxt {
uint32_t pasid;
/** @pasid_en - PASID Enable */
uint8_t pasid_en;
/** @virtio_dsc_base - Virtio Desc Base Address */
uint8_t base_addr;
/** @vio_eop - Virtio End-of-packet */
uint8_t vio_eop;
/** @sh_cmpt - Shared Completion Queue */
......@@ -518,11 +620,16 @@ void qdma_memset(void *to, uint8_t val, uint32_t size);
int qdma_acc_reg_dump_buf_len(void *dev_hndl,
enum qdma_ip_type ip_type, int *buflen);
int qdma_acc_reg_info_len(void *dev_hndl,
enum qdma_ip_type ip_type, int *buflen, int *num_regs);
int qdma_acc_context_buf_len(void *dev_hndl,
enum qdma_ip_type ip_type, uint8_t st,
enum qdma_dev_q_type q_type, uint32_t *buflen);
int qdma_acc_get_num_config_regs(void *dev_hndl,
enum qdma_ip_type ip_type, uint32_t *num_regs);
/*
* struct qdma_hw_access - Structure to hold HW access function pointers
*/
......@@ -587,11 +694,15 @@ struct qdma_hw_access {
uint8_t err_intr_index);
int (*qdma_hw_error_intr_rearm)(void *dev_hndl);
int (*qdma_hw_error_enable)(void *dev_hndl,
enum qdma_error_idx err_idx);
const char *(*qdma_hw_get_error_name)(enum qdma_error_idx err_idx);
uint32_t err_idx);
const char *(*qdma_hw_get_error_name)(uint32_t err_idx);
int (*qdma_hw_error_process)(void *dev_hndl);
int (*qdma_dump_config_regs)(void *dev_hndl, uint8_t is_vf, char *buf,
uint32_t buflen);
int (*qdma_dump_reg_info)(void *dev_hndl, uint32_t reg_addr,
uint32_t num_regs,
char *buf,
uint32_t buflen);
int (*qdma_dump_queue_context)(void *dev_hndl,
uint8_t st,
enum qdma_dev_q_type q_type,
......@@ -622,6 +733,7 @@ struct qdma_hw_access {
char *buf, uint32_t buflen);
uint32_t mbox_base_pf;
uint32_t mbox_base_vf;
uint32_t qdma_max_errors;
};
/*****************************************************************************/
......@@ -643,6 +755,21 @@ struct qdma_hw_access {
int qdma_hw_access_init(void *dev_hndl, uint8_t is_vf,
struct qdma_hw_access *hw_access);
/*****************************************************************************/
/**
* qdma_acc_dump_config_regs() - Function to get qdma config registers
*
* @dev_hndl: device handle
* @is_vf: Whether PF or VF
* @ip_type: QDMA IP Type
* @reg_data: pointer to register data to be filled
*
* Return: Length up-till the buffer is filled -success and < 0 - failure
*****************************************************************************/
int qdma_acc_get_config_regs(void *dev_hndl, uint8_t is_vf,
enum qdma_ip_type ip_type,
uint32_t *reg_data);
/*****************************************************************************/
/**
* qdma_acc_dump_config_regs() - Function to get qdma config register dump in a
......@@ -660,6 +787,23 @@ int qdma_acc_dump_config_regs(void *dev_hndl, uint8_t is_vf,
enum qdma_ip_type ip_type,
char *buf, uint32_t buflen);
/*****************************************************************************/
/**
* qdma_acc_dump_reg_info() - Function to get qdma reg info in a buffer
*
* @dev_hndl: device handle
* @ip_type: QDMA IP Type
* @reg_addr: Register Address
* @num_regs: Number of Registers
* @buf : pointer to buffer to be filled
* @buflen : Length of the buffer
*
* Return: Length up-till the buffer is filled -success and < 0 - failure
*****************************************************************************/
int qdma_acc_dump_reg_info(void *dev_hndl,
enum qdma_ip_type ip_type, uint32_t reg_addr,
uint32_t num_regs, char *buf, uint32_t buflen);
/*****************************************************************************/
/**
* qdma_acc_dump_queue_context() - Function to dump qdma queue context data in a
......
......@@ -14,9 +14,12 @@
* under the License.
*/
#ifndef QDMA_ACCESS_ERRORS_H_
#define QDMA_ACCESS_ERRORS_H_
#ifndef __QDMA_ACCESS_ERRORS_H_
#define __QDMA_ACCESS_ERRORS_H_
#ifdef __cplusplus
extern "C" {
#endif
/**
* DOC: QDMA common library error codes definitions
......@@ -62,4 +65,8 @@ enum qdma_access_error_codes {
QDMA_ERR_MBOX_ALL_ZERO_MSG, /* 25 */
};
#endif /* QDMA_ACCESS_H_ */
#ifdef __cplusplus
}
#endif
#endif /* __QDMA_ACCESS_ERRORS_H_ */
......@@ -14,15 +14,15 @@
* under the License.
*/
#ifndef QDMA_ACCESS_EXPORT_H_
#define QDMA_ACCESS_EXPORT_H_
#include "qdma_platform_env.h"
#ifndef __QDMA_ACCESS_EXPORT_H_
#define __QDMA_ACCESS_EXPORT_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "qdma_platform_env.h"
/** QDMA Global CSR array size */
#define QDMA_GLOBAL_CSR_ARRAY_SZ 16
......@@ -44,6 +44,12 @@ struct qdma_dev_attributes {
uint8_t mm_cmpt_en:1;
/** @mailbox_en - Mailbox supported or not? */
uint8_t mailbox_en:1;
/** @debug_mode - Debug mode is enabled/disabled for IP */
uint8_t debug_mode:1;
/** @desc_eng_mode - Descriptor Engine mode:
* Internal only/Bypass only/Internal & Bypass
*/
uint8_t desc_eng_mode:2;
/** @mm_channel_max - Num of MM channels */
uint8_t mm_channel_max;
......@@ -202,6 +208,8 @@ enum qdma_vivado_release_id {
QDMA_VIVADO_2019_2,
/** @QDMA_VIVADO_2020_1 - Vivado version 2020.1 */
QDMA_VIVADO_2020_1,
/** @QDMA_VIVADO_2020_2 - Vivado version 2020.2 */
QDMA_VIVADO_2020_2,
/** @QDMA_VIVADO_NONE - Not a valid Vivado version*/
QDMA_VIVADO_NONE
};
......@@ -229,137 +237,19 @@ enum qdma_device_type {
QDMA_DEVICE_NONE
};
/**
* enum qdma_error_idx - qdma errors
*/
enum qdma_error_idx {
/* Descriptor errors */
QDMA_DSC_ERR_POISON,
QDMA_DSC_ERR_UR_CA,
QDMA_DSC_ERR_PARAM,
QDMA_DSC_ERR_ADDR,
QDMA_DSC_ERR_TAG,
QDMA_DSC_ERR_FLR,
QDMA_DSC_ERR_TIMEOUT,
QDMA_DSC_ERR_DAT_POISON,
QDMA_DSC_ERR_FLR_CANCEL,
QDMA_DSC_ERR_DMA,
QDMA_DSC_ERR_DSC,
QDMA_DSC_ERR_RQ_CANCEL,
QDMA_DSC_ERR_DBE,
QDMA_DSC_ERR_SBE,
QDMA_DSC_ERR_ALL,
/* TRQ Errors */
QDMA_TRQ_ERR_UNMAPPED,
QDMA_TRQ_ERR_QID_RANGE,
QDMA_TRQ_ERR_VF_ACCESS,
QDMA_TRQ_ERR_TCP_TIMEOUT,
QDMA_TRQ_ERR_ALL,
/* C2H Errors */
QDMA_ST_C2H_ERR_MTY_MISMATCH,
QDMA_ST_C2H_ERR_LEN_MISMATCH,
QDMA_ST_C2H_ERR_QID_MISMATCH,
QDMA_ST_C2H_ERR_DESC_RSP_ERR,
QDMA_ST_C2H_ERR_ENG_WPL_DATA_PAR_ERR,
QDMA_ST_C2H_ERR_MSI_INT_FAIL,
QDMA_ST_C2H_ERR_ERR_DESC_CNT,
QDMA_ST_C2H_ERR_PORTID_CTXT_MISMATCH,
QDMA_ST_C2H_ERR_PORTID_BYP_IN_MISMATCH,
QDMA_ST_C2H_ERR_CMPT_INV_Q_ERR,
QDMA_ST_C2H_ERR_CMPT_QFULL_ERR,
QDMA_ST_C2H_ERR_CMPT_CIDX_ERR,
QDMA_ST_C2H_ERR_CMPT_PRTY_ERR,
QDMA_ST_C2H_ERR_ALL,
/* Fatal Errors */
QDMA_ST_FATAL_ERR_MTY_MISMATCH,
QDMA_ST_FATAL_ERR_LEN_MISMATCH,
QDMA_ST_FATAL_ERR_QID_MISMATCH,
QDMA_ST_FATAL_ERR_TIMER_FIFO_RAM_RDBE,
QDMA_ST_FATAL_ERR_PFCH_II_RAM_RDBE,
QDMA_ST_FATAL_ERR_CMPT_CTXT_RAM_RDBE,
QDMA_ST_FATAL_ERR_PFCH_CTXT_RAM_RDBE,
QDMA_ST_FATAL_ERR_DESC_REQ_FIFO_RAM_RDBE,
QDMA_ST_FATAL_ERR_INT_CTXT_RAM_RDBE,
QDMA_ST_FATAL_ERR_CMPT_COAL_DATA_RAM_RDBE,
QDMA_ST_FATAL_ERR_TUSER_FIFO_RAM_RDBE,
QDMA_ST_FATAL_ERR_QID_FIFO_RAM_RDBE,
QDMA_ST_FATAL_ERR_PAYLOAD_FIFO_RAM_RDBE,
QDMA_ST_FATAL_ERR_WPL_DATA_PAR,
QDMA_ST_FATAL_ERR_ALL,
/* H2C Errors */
QDMA_ST_H2C_ERR_ZERO_LEN_DESC,
QDMA_ST_H2C_ERR_CSI_MOP,
QDMA_ST_H2C_ERR_NO_DMA_DSC,
QDMA_ST_H2C_ERR_SBE,
QDMA_ST_H2C_ERR_DBE,
QDMA_ST_H2C_ERR_ALL,
/* Single bit errors */
QDMA_SBE_ERR_MI_H2C0_DAT,
QDMA_SBE_ERR_MI_C2H0_DAT,
QDMA_SBE_ERR_H2C_RD_BRG_DAT,
QDMA_SBE_ERR_H2C_WR_BRG_DAT,
QDMA_SBE_ERR_C2H_RD_BRG_DAT,
QDMA_SBE_ERR_C2H_WR_BRG_DAT,
QDMA_SBE_ERR_FUNC_MAP,
QDMA_SBE_ERR_DSC_HW_CTXT,
QDMA_SBE_ERR_DSC_CRD_RCV,
QDMA_SBE_ERR_DSC_SW_CTXT,
QDMA_SBE_ERR_DSC_CPLI,
QDMA_SBE_ERR_DSC_CPLD,
QDMA_SBE_ERR_PASID_CTXT_RAM,
QDMA_SBE_ERR_TIMER_FIFO_RAM,
QDMA_SBE_ERR_PAYLOAD_FIFO_RAM,
QDMA_SBE_ERR_QID_FIFO_RAM,
QDMA_SBE_ERR_TUSER_FIFO_RAM,
QDMA_SBE_ERR_WRB_COAL_DATA_RAM,
QDMA_SBE_ERR_INT_QID2VEC_RAM,
QDMA_SBE_ERR_INT_CTXT_RAM,
QDMA_SBE_ERR_DESC_REQ_FIFO_RAM,
QDMA_SBE_ERR_PFCH_CTXT_RAM,
QDMA_SBE_ERR_WRB_CTXT_RAM,
QDMA_SBE_ERR_PFCH_LL_RAM,
QDMA_SBE_ERR_H2C_PEND_FIFO,
QDMA_SBE_ERR_ALL,
/* Double bit Errors */
QDMA_DBE_ERR_MI_H2C0_DAT,
QDMA_DBE_ERR_MI_C2H0_DAT,
QDMA_DBE_ERR_H2C_RD_BRG_DAT,
QDMA_DBE_ERR_H2C_WR_BRG_DAT,
QDMA_DBE_ERR_C2H_RD_BRG_DAT,
QDMA_DBE_ERR_C2H_WR_BRG_DAT,
QDMA_DBE_ERR_FUNC_MAP,
QDMA_DBE_ERR_DSC_HW_CTXT,
QDMA_DBE_ERR_DSC_CRD_RCV,
QDMA_DBE_ERR_DSC_SW_CTXT,
QDMA_DBE_ERR_DSC_CPLI,
QDMA_DBE_ERR_DSC_CPLD,
QDMA_DBE_ERR_PASID_CTXT_RAM,
QDMA_DBE_ERR_TIMER_FIFO_RAM,
QDMA_DBE_ERR_PAYLOAD_FIFO_RAM,
QDMA_DBE_ERR_QID_FIFO_RAM,
QDMA_DBE_ERR_TUSER_FIFO_RAM,
QDMA_DBE_ERR_WRB_COAL_DATA_RAM,
QDMA_DBE_ERR_INT_QID2VEC_RAM,
QDMA_DBE_ERR_INT_CTXT_RAM,
QDMA_DBE_ERR_DESC_REQ_FIFO_RAM,
QDMA_DBE_ERR_PFCH_CTXT_RAM,
QDMA_DBE_ERR_WRB_CTXT_RAM,
QDMA_DBE_ERR_PFCH_LL_RAM,
QDMA_DBE_ERR_H2C_PEND_FIFO,
QDMA_DBE_ERR_ALL,
QDMA_ERRS_ALL
enum qdma_desc_eng_mode {
/** @QDMA_DESC_ENG_INTERNAL_BYPASS - Internal and Bypass mode */
QDMA_DESC_ENG_INTERNAL_BYPASS,
/** @QDMA_DESC_ENG_BYPASS_ONLY - Only Bypass mode */
QDMA_DESC_ENG_BYPASS_ONLY,
/** @QDMA_DESC_ENG_INTERNAL_ONLY - Only Internal mode */
QDMA_DESC_ENG_INTERNAL_ONLY,
/** @QDMA_DESC_ENG_MODE_MAX - Max of desc engine modes */
QDMA_DESC_ENG_MODE_MAX
};
#ifdef __cplusplus
}
#endif
#endif /* QDMA_ACCESS_EXPORT_H_ */
#endif /* __QDMA_ACCESS_EXPORT_H_ */
......@@ -14,12 +14,12 @@
* under the License.
*/
#ifndef QDMA_VERSION_H_
#define QDMA_VERSION_H_
#ifndef __QDMA_ACCESS_VERSION_H_
#define __QDMA_ACCESS_VERSION_H_
#define QDMA_VERSION_MAJOR 2020
#define QDMA_VERSION_MINOR 1
#define QDMA_VERSION_MINOR 2
#define QDMA_VERSION_PATCH 0
#define QDMA_VERSION_STR \
......@@ -33,4 +33,4 @@
QDMA_VERSION_PATCH)
#endif /* COMMON_QDMA_VERSION_H_ */
#endif /* __QDMA_ACCESS_VERSION_H_ */
......@@ -14,8 +14,12 @@
* under the License.
*/
#ifndef QDMA_LIST_H_
#define QDMA_LIST_H_
#ifndef __QDMA_LIST_H_
#define __QDMA_LIST_H_
#ifdef __cplusplus
extern "C" {
#endif
/**
* DOC: QDMA common library provided list implementation definitions
......@@ -114,4 +118,8 @@ void qdma_list_insert_after(struct qdma_list_head *new_node,
*****************************************************************************/
void qdma_list_del(struct qdma_list_head *node);
#endif /* QDMA_LIST_H_ */
#ifdef __cplusplus
}
#endif
#endif /* __QDMA_LIST_H_ */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment