#include "qat_freebsd.h"
#include "adf_cfg.h"
#include "adf_common_drv.h"
#include "adf_accel_devices.h"
#include "icp_qat_uclo.h"
#include "icp_qat_fw.h"
#include "icp_qat_fw_init_admin.h"
#include "adf_cfg_strings.h"
#include "adf_transport_access_macros.h"
#include "adf_transport_internal.h"
#include "adf_heartbeat.h"
#include <sys/types.h>
#include <sys/lock.h>
#include <sys/sx.h>
#include <sys/malloc.h>
#include <sys/systm.h>
#include <dev/pci/pcivar.h>
#include <machine/bus_dma.h>
#include <linux/delay.h>
#define ADF_CONST_TABLE_VERSION_BYTE (0)
#define ADF_CONST_TABLE_VERSION (1)
#define ADF_MAILBOX_STRIDE 0x1000
#define ADF_ADMINMSG_LEN 32
#define FREEBSD_ALLIGNMENT_SIZE 64
#define ADF_INIT_CONFIG_SIZE 1024
static u8 const_tab[1024] __aligned(1024) = {
ADF_CONST_TABLE_VERSION,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76,
0x54, 0x32, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab,
0x89, 0x98, 0xba, 0xdc, 0xfe, 0x10, 0x32, 0x54, 0x76, 0xc3, 0xd2, 0xe1, 0xf0,
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x05, 0x9e,
0xd8, 0x36, 0x7c, 0xd5, 0x07, 0x30, 0x70, 0xdd, 0x17, 0xf7, 0x0e, 0x59, 0x39,
0xff, 0xc0, 0x0b, 0x31, 0x68, 0x58, 0x15, 0x11, 0x64, 0xf9, 0x8f, 0xa7, 0xbe,
0xfa, 0x4f, 0xa4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x09, 0xe6, 0x67, 0xbb, 0x67, 0xae,
0x85, 0x3c, 0x6e, 0xf3, 0x72, 0xa5, 0x4f, 0xf5, 0x3a, 0x51, 0x0e, 0x52, 0x7f,
0x9b, 0x05, 0x68, 0x8c, 0x1f, 0x83, 0xd9, 0xab, 0x5b, 0xe0, 0xcd, 0x19, 0x05,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xcb, 0xbb, 0x9d, 0x5d, 0xc1, 0x05, 0x9e, 0xd8, 0x62, 0x9a, 0x29,
0x2a, 0x36, 0x7c, 0xd5, 0x07, 0x91, 0x59, 0x01, 0x5a, 0x30, 0x70, 0xdd, 0x17,
0x15, 0x2f, 0xec, 0xd8, 0xf7, 0x0e, 0x59, 0x39, 0x67, 0x33, 0x26, 0x67, 0xff,
0xc0, 0x0b, 0x31, 0x8e, 0xb4, 0x4a, 0x87, 0x68, 0x58, 0x15, 0x11, 0xdb, 0x0c,
0x2e, 0x0d, 0x64, 0xf9, 0x8f, 0xa7, 0x47, 0xb5, 0x48, 0x1d, 0xbe, 0xfa, 0x4f,
0xa4, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08, 0xbb,
0x67, 0xae, 0x85, 0x84, 0xca, 0xa7, 0x3b, 0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94,
0xf8, 0x2b, 0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1, 0x51, 0x0e, 0x52,
0x7f, 0xad, 0xe6, 0x82, 0xd1, 0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f,
0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b, 0x5b, 0xe0, 0xcd, 0x19, 0x13,
0x7e, 0x21, 0x79, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x15, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x14, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x24, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x12, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
#define ADF_ADMIN_POLL_INTERVAL_US 20
#define ADF_ADMIN_POLL_RETRIES 5000
static void
dma_callback(void *arg, bus_dma_segment_t *segs, int nseg, int error)
{
bus_addr_t *addr;
addr = arg;
if (error == 0 && nseg == 1)
*addr = segs[0].ds_addr;
else
*addr = 0;
}
int
adf_put_admin_msg_sync(struct adf_accel_dev *accel_dev,
u32 ae,
void *in,
void *out)
{
struct adf_admin_comms *admin = accel_dev->admin;
struct adf_hw_device_data *hw_data = accel_dev->hw_device;
struct resource *mailbox = admin->mailbox_addr;
struct admin_info admin_csrs_info;
hw_data->get_admin_info(&admin_csrs_info);
int offset = ae * ADF_ADMINMSG_LEN * 2;
int mb_offset =
ae * ADF_MAILBOX_STRIDE + admin_csrs_info.mailbox_offset;
int times, received;
struct icp_qat_fw_init_admin_req *request = in;
sx_xlock(&admin->lock);
if (ADF_CSR_RD(mailbox, mb_offset) == 1) {
sx_xunlock(&admin->lock);
return EAGAIN;
}
memcpy(admin->virt_addr + offset, in, ADF_ADMINMSG_LEN);
ADF_CSR_WR(mailbox, mb_offset, 1);
received = 0;
for (times = 0; times < ADF_ADMIN_POLL_RETRIES; times++) {
usleep_range(ADF_ADMIN_POLL_INTERVAL_US,
ADF_ADMIN_POLL_INTERVAL_US * 2);
if (ADF_CSR_RD(mailbox, mb_offset) == 0) {
received = 1;
break;
}
}
if (received)
memcpy(out,
admin->virt_addr + offset + ADF_ADMINMSG_LEN,
ADF_ADMINMSG_LEN);
else
device_printf(GET_DEV(accel_dev),
"Failed to send admin msg %d to accelerator %d\n",
request->cmd_id,
ae);
sx_xunlock(&admin->lock);
return received ? 0 : EFAULT;
}
static inline int
adf_set_dc_ibuf(struct adf_accel_dev *accel_dev,
struct icp_qat_fw_init_admin_req *req)
{
char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
unsigned long ibuf_size = 0;
if (!adf_cfg_get_param_value(
accel_dev, ADF_GENERAL_SEC, ADF_INTER_BUF_SIZE, val)) {
if (compat_strtoul(val, 0, &ibuf_size))
return EFAULT;
}
if (ibuf_size != 32 && ibuf_size != 64)
ibuf_size = 64;
req->ibuf_size_in_kb = ibuf_size;
return 0;
}
int
adf_send_admin(struct adf_accel_dev *accel_dev,
struct icp_qat_fw_init_admin_req *req,
struct icp_qat_fw_init_admin_resp *resp,
u32 ae_mask)
{
int i;
unsigned int mask;
for (i = 0, mask = ae_mask; mask; i++, mask >>= 1) {
if (!(mask & 1))
continue;
if (adf_put_admin_msg_sync(accel_dev, i, req, resp) ||
resp->status)
return EFAULT;
}
return 0;
}
static int
adf_init_me(struct adf_accel_dev *accel_dev)
{
struct icp_qat_fw_init_admin_req req;
struct icp_qat_fw_init_admin_resp resp;
struct adf_hw_device_data *hw_device = accel_dev->hw_device;
u32 ae_mask = hw_device->ae_mask;
explicit_bzero(&req, sizeof(req));
explicit_bzero(&resp, sizeof(resp));
req.cmd_id = ICP_QAT_FW_INIT_ME;
if (adf_set_dc_ibuf(accel_dev, &req))
return EFAULT;
if (accel_dev->aram_info) {
req.init_cfg_sz = sizeof(*accel_dev->aram_info);
req.init_cfg_ptr = (u64)accel_dev->admin->aram_map_phys_addr;
}
if (adf_send_admin(accel_dev, &req, &resp, ae_mask))
return EFAULT;
return 0;
}
static int
adf_set_heartbeat_timer(struct adf_accel_dev *accel_dev)
{
struct icp_qat_fw_init_admin_req req;
struct icp_qat_fw_init_admin_resp resp;
struct adf_hw_device_data *hw_device = accel_dev->hw_device;
u32 ae_mask = hw_device->ae_mask;
u32 heartbeat_ticks;
explicit_bzero(&req, sizeof(req));
req.cmd_id = ICP_QAT_FW_HEARTBEAT_TIMER_SET;
req.hb_cfg_ptr = accel_dev->admin->phy_hb_addr;
if (adf_get_hb_timer(accel_dev, &heartbeat_ticks))
return EINVAL;
req.heartbeat_ticks = heartbeat_ticks;
if (adf_send_admin(accel_dev, &req, &resp, ae_mask))
return EFAULT;
return 0;
}
static int
adf_get_dc_capabilities(struct adf_accel_dev *accel_dev, u32 *capabilities)
{
struct icp_qat_fw_init_admin_req req;
struct icp_qat_fw_init_admin_resp resp;
u32 ae_mask = 1;
explicit_bzero(&req, sizeof(req));
req.cmd_id = ICP_QAT_FW_COMP_CAPABILITY_GET;
if (adf_send_admin(accel_dev, &req, &resp, ae_mask))
return EFAULT;
*capabilities = resp.extended_features;
return 0;
}
static int
adf_set_fw_constants(struct adf_accel_dev *accel_dev)
{
struct icp_qat_fw_init_admin_req req;
struct icp_qat_fw_init_admin_resp resp;
struct adf_hw_device_data *hw_device = accel_dev->hw_device;
u32 ae_mask = hw_device->admin_ae_mask;
explicit_bzero(&req, sizeof(req));
req.cmd_id = ICP_QAT_FW_CONSTANTS_CFG;
req.init_cfg_sz = sizeof(const_tab);
req.init_cfg_ptr = accel_dev->admin->const_tbl_addr;
if (adf_send_admin(accel_dev, &req, &resp, ae_mask))
return EFAULT;
return 0;
}
static int
adf_get_fw_status(struct adf_accel_dev *accel_dev,
u8 *major,
u8 *minor,
u8 *patch)
{
struct icp_qat_fw_init_admin_req req;
struct icp_qat_fw_init_admin_resp resp;
u32 ae_mask = 1;
explicit_bzero(&req, sizeof(req));
req.cmd_id = ICP_QAT_FW_STATUS_GET;
if (adf_send_admin(accel_dev, &req, &resp, ae_mask))
return EFAULT;
*major = resp.version_major_num;
*minor = resp.version_minor_num;
*patch = resp.version_patch_num;
return 0;
}
int
adf_get_fw_timestamp(struct adf_accel_dev *accel_dev, u64 *timestamp)
{
struct icp_qat_fw_init_admin_req req;
struct icp_qat_fw_init_admin_resp rsp;
unsigned int ae_mask = 1;
if (!accel_dev || !timestamp)
return EFAULT;
explicit_bzero(&req, sizeof(req));
req.cmd_id = ICP_QAT_FW_TIMER_GET;
if (adf_send_admin(accel_dev, &req, &rsp, ae_mask))
return EFAULT;
*timestamp = rsp.timestamp;
return 0;
}
int
adf_get_fw_pke_stats(struct adf_accel_dev *accel_dev,
u64 *suc_count,
u64 *unsuc_count)
{
struct icp_qat_fw_init_admin_req req = { 0 };
struct icp_qat_fw_init_admin_resp resp = { 0 };
unsigned long sym_ae_msk = 0;
u8 sym_ae_msk_size = 0;
u8 i = 0;
if (!suc_count || !unsuc_count)
return EFAULT;
sym_ae_msk = accel_dev->au_info->sym_ae_msk;
sym_ae_msk_size =
sizeof(accel_dev->au_info->sym_ae_msk) * BITS_PER_BYTE;
req.cmd_id = ICP_QAT_FW_PKE_REPLAY_STATS_GET;
for_each_set_bit(i, &sym_ae_msk, sym_ae_msk_size)
{
memset(&resp, 0, sizeof(struct icp_qat_fw_init_admin_resp));
if (adf_put_admin_msg_sync(accel_dev, i, &req, &resp) ||
resp.status) {
return EFAULT;
}
*suc_count += resp.successful_count;
*unsuc_count += resp.unsuccessful_count;
}
return 0;
}
int
adf_send_admin_init(struct adf_accel_dev *accel_dev)
{
int ret;
u32 dc_capabilities = 0;
unsigned int storage_enabled = 0;
if (GET_HW_DATA(accel_dev)->query_storage_cap) {
ret = adf_get_dc_capabilities(accel_dev, &dc_capabilities);
if (ret) {
device_printf(GET_DEV(accel_dev),
"Cannot get dc capabilities\n");
return ret;
}
accel_dev->hw_device->extended_dc_capabilities =
dc_capabilities;
} else {
ret = GET_HW_DATA(accel_dev)->get_storage_enabled(
accel_dev, &storage_enabled);
if (ret) {
device_printf(GET_DEV(accel_dev),
"Cannot get storage enabled\n");
return ret;
}
}
ret = adf_set_heartbeat_timer(accel_dev);
if (ret) {
if (ret == EINVAL) {
device_printf(GET_DEV(accel_dev),
"Cannot set heartbeat timer\n");
return ret;
}
device_printf(GET_DEV(accel_dev),
"Heartbeat is not supported\n");
}
ret = adf_get_fw_status(accel_dev,
&accel_dev->fw_versions.fw_version_major,
&accel_dev->fw_versions.fw_version_minor,
&accel_dev->fw_versions.fw_version_patch);
if (ret) {
device_printf(GET_DEV(accel_dev), "Cannot get fw version\n");
return ret;
}
device_printf(GET_DEV(accel_dev),
"FW version: %d.%d.%d\n",
accel_dev->fw_versions.fw_version_major,
accel_dev->fw_versions.fw_version_minor,
accel_dev->fw_versions.fw_version_patch);
ret = adf_set_fw_constants(accel_dev);
if (ret) {
device_printf(GET_DEV(accel_dev), "Cannot set fw constants\n");
return ret;
}
ret = adf_init_me(accel_dev);
if (ret)
device_printf(GET_DEV(accel_dev), "Cannot init AE\n");
return ret;
}
int
adf_init_admin_comms(struct adf_accel_dev *accel_dev)
{
struct adf_admin_comms *admin = NULL;
struct adf_hw_device_data *hw_data = NULL;
struct adf_bar *pmisc = NULL;
struct resource *csr = NULL;
struct admin_info admin_csrs_info;
unsigned int adminmsg_u, adminmsg_l;
u64 reg_val = 0;
int ret = 0;
admin = kzalloc_node(sizeof(*accel_dev->admin),
M_WAITOK | M_ZERO,
dev_to_node(GET_DEV(accel_dev)));
hw_data = accel_dev->hw_device;
pmisc = &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)];
csr = pmisc->virt_addr;
ret = bus_dma_mem_create(&admin->dma_mem,
accel_dev->dma_tag,
FREEBSD_ALLIGNMENT_SIZE,
BUS_SPACE_MAXADDR,
PAGE_SIZE,
0);
if (ret != 0) {
device_printf(GET_DEV(accel_dev),
"Failed to allocate dma buff\n");
kfree(admin);
return ret;
}
admin->virt_addr = admin->dma_mem.dma_vaddr;
admin->phy_addr = admin->dma_mem.dma_baddr;
bzero(admin->virt_addr, PAGE_SIZE);
ret = bus_dmamap_create(accel_dev->dma_tag, 0, &admin->const_tbl_map);
if (ret != 0) {
device_printf(GET_DEV(accel_dev), "Failed to create DMA map\n");
bus_dma_mem_free(&admin->dma_mem);
kfree(admin);
return ret;
}
ret = bus_dmamap_load(accel_dev->dma_tag,
admin->const_tbl_map,
(void *)const_tab,
1024,
dma_callback,
&admin->const_tbl_addr,
BUS_DMA_NOWAIT);
if (ret == 0 && admin->const_tbl_addr == 0)
ret = EFBIG;
if (ret != 0) {
device_printf(GET_DEV(accel_dev),
"Failed to map const table for DMA\n");
bus_dmamap_destroy(accel_dev->dma_tag, admin->const_tbl_map);
bus_dma_mem_free(&admin->dma_mem);
kfree(admin);
return ret;
}
if (accel_dev->aram_info) {
ret =
bus_dmamap_create(accel_dev->dma_tag, 0, &admin->aram_map);
if (ret != 0) {
device_printf(GET_DEV(accel_dev),
"Failed to create DMA map\n");
bus_dma_mem_free(&admin->dma_mem);
kfree(admin);
return ret;
}
ret = bus_dmamap_load(accel_dev->dma_tag,
admin->aram_map,
(void *)accel_dev->aram_info,
sizeof(*accel_dev->aram_info),
dma_callback,
&admin->aram_map_phys_addr,
BUS_DMA_NOWAIT);
if (ret == 0 && admin->aram_map_phys_addr == 0)
ret = EFBIG;
if (ret != 0) {
device_printf(GET_DEV(accel_dev),
"Failed to map aram phys addr for DMA\n");
bus_dmamap_destroy(accel_dev->dma_tag, admin->aram_map);
bus_dma_mem_free(&admin->dma_mem);
kfree(admin);
return ret;
}
}
ret = bus_dma_mem_create(&admin->dma_hb,
accel_dev->dma_tag,
FREEBSD_ALLIGNMENT_SIZE,
BUS_SPACE_MAXADDR,
PAGE_SIZE,
0);
if (ret != 0) {
device_printf(GET_DEV(accel_dev),
"Failed to allocate dma buff\n");
bus_dmamap_unload(accel_dev->dma_tag, admin->const_tbl_map);
bus_dmamap_destroy(accel_dev->dma_tag, admin->const_tbl_map);
bus_dma_mem_free(&admin->dma_mem);
kfree(admin);
return ret;
}
admin->virt_hb_addr = admin->dma_hb.dma_vaddr;
admin->phy_hb_addr = admin->dma_hb.dma_baddr;
bzero(admin->virt_hb_addr, PAGE_SIZE);
hw_data->get_admin_info(&admin_csrs_info);
adminmsg_u = admin_csrs_info.admin_msg_ur;
adminmsg_l = admin_csrs_info.admin_msg_lr;
reg_val = (u64)admin->phy_addr;
ADF_CSR_WR(csr, adminmsg_u, reg_val >> 32);
ADF_CSR_WR(csr, adminmsg_l, reg_val);
sx_init(&admin->lock, "qat admin");
admin->mailbox_addr = csr;
accel_dev->admin = admin;
return 0;
}
void
adf_exit_admin_comms(struct adf_accel_dev *accel_dev)
{
struct adf_admin_comms *admin = accel_dev->admin;
if (!admin)
return;
if (admin->virt_addr)
bus_dma_mem_free(&admin->dma_mem);
if (admin->virt_hb_addr)
bus_dma_mem_free(&admin->dma_hb);
bus_dmamap_unload(accel_dev->dma_tag, admin->const_tbl_map);
bus_dmamap_destroy(accel_dev->dma_tag, admin->const_tbl_map);
sx_destroy(&admin->lock);
kfree(admin);
accel_dev->admin = NULL;
}