/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright(c) 2007-2022 Intel Corporation */ #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 #include #include #include #include #include #include #include #define ADF_CONST_TABLE_VERSION_BYTE (0) /* Keep version number in range 0-255 */ #define ADF_CONST_TABLE_VERSION (1) /* Admin Messages Registers */ #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; } /** * adf_send_admin_init() - Function sends init message to FW * @accel_dev: Pointer to acceleration device. * * Function sends admin init message to the FW * * Return: 0 on success, error code otherwise. */ 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; } /* DMA ARAM address map */ 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; }