* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __VMNG_KERNEL_INTERFACE_H__
#define __VMNG_KERNEL_INTERFACE_H__
#include "ka_task_pub.h"
#include "ka_pci_pub.h"
#include "ka_memory_pub.h"
#include "vpc_kernel_interface.h"
#include "pbl/pbl_soc_res_attr.h"
#include "vmng_kernel_interface_cmd.h"
#define VMNG_PDEV_MAX 64U
#define VMNG_VDEV_MAX_PER_PDEV 17
#define VMNG_VF_MAX_PER_PF 12
#define VMNG_VDEV_FIRST_VFID 1
#define VMNG_VM_MAX 128
#define VMNG_AICORE_MAX_NUM 32
#define VMNGH_VM 1
#define VMNGH_CONTAINER 2
#define VMNG_PCIE_FLOW_H2D 0
#define VMNG_PCIE_FLOW_D2H 1
#define VMNG_NOT_SUPPORT_BW_CTRL (-1)
#define VMNG_BW_BANDWIDTH_RENEW_CNT 10
#define VMNG_BW_BANDWIDTH_CHECK_LEN 0x400
#define VMNG_BW_BANDWIDTH_CHECK_WAIT_TIME 5
#define VMNG_BW_BANDWIDTH_CHECK_MAX_CNT 900
#define VMNG_BW_BANDWIDTH_CHECK_SLEEPABLE 0
#define VMNG_BW_BANDWIDTH_CHECK_NON_SLEEP 1
#define VMNG_BANDW_DUPLEX_PERCENTAGE 140
#define VMNG_BANDW_PERCENTAGE_BASE 100
#define VMNGD_TYPE_PF 0
#define VMNGD_TYPE_VF 1
enum vmng_vdev_status {
VMNG_VDEV_STATUS_FREE = 0,
VMNG_VDEV_STATUS_ALLOC,
VMNG_VDEV_STATUS_CLIENT_INIT,
VMNG_VDEV_STATUS_CLIENT_UNINIT,
VMNG_VDEV_STATUS_REFRESH,
VMNG_VDEV_STATUS_RESET,
VMNG_VDEV_STATUS_MAX
};
enum vmng_client_type {
VMNG_CLIENT_TYPE_DEVMNG = 0,
VMNG_CLIENT_TYPE_HDC,
VMNG_CLIENT_TYPE_DEVMM,
VMNG_CLIENT_TYPE_TSDRV,
VMNG_CLIENT_TYPE_DVPP,
VMNG_CLIENT_TYPE_ESCHED,
VMNG_CLIENT_TYPE_MAX
};
enum vmng_startup_flag_type {
VMNG_STARTUP_UNPROBED = 0,
VMNG_STARTUP_PROBED,
VMNG_STARTUP_TOP_HALF_OK,
VMNG_STARTUP_BOTTOM_HALF_OK
};
enum VMNG_TYPE {
VMNG_TYPE_C1,
VMNG_TYPE_C2,
VMNG_TYPE_C4,
VMNG_TYPE_C8,
VMNG_TYPE_C16,
VMNG_TYPE_MAX
};
enum VMNG_HW_TYPE {
VMNG_HW_TYPE_C1,
VMNG_HW_TYPE_C2,
VMNG_HW_TYPE_C4,
VMNG_HW_TYPE_C6,
VMNG_HW_TYPE_C12,
VMNG_HW_TYPE_C24,
VMNG_HW_TYPE_MAX
};
enum VMNG_HW_TYPE_EXTRA {
VMNG_HW_TYPE_C1_4 = 10,
VMNG_HW_TYPE_C2_4,
VMNG_HW_TYPE_EXTRA_MAX
};
enum vmng_vf_group_type {
VMNG_VF_GROUP_TYPE_NORMAL = 0,
VMNG_VF_GROUP_TYPE_VIP,
VMNG_VF_GROUP_TYPE_SHARE,
VMNG_VF_GROUP_TYPE_MAX
};
enum vmng_vf_group_mode {
VMNG_VF_GROUP_MODE_STRICT = 0,
VMNG_VF_GROUP_MODE_RELAX,
VMNG_VF_GROUP_MODE_MAX
};
#pragma pack(push)
#pragma pack (1)
typedef struct vf_id_info {
u8 vf_id;
u8 vfg_mode;
u8 vfg_id;
u8 vip;
u32 reserved0;
u64 token;
u64 token_max;
u64 task_timeout;
u32 reserved[4];
} vf_id_info_t;
typedef struct vf_ac_info {
u64 aiv_bitmap;
u32 aic_bitmap;
u32 c_core_bitmap;
u32 dsa_bitmap;
u32 ffts_bitmap;
u32 sdma_bitmap;
u32 pcie_dma_bitmap;
u32 acsq_slice_bitmap;
u32 rtsq_slice_bitmap;
u32 event_slice_bitmap;
u32 notify_slice_bitmap;
u32 cdq_slice_bitmap;
u32 cmo_slice_bitmap;
u32 reserved[3];
} vf_ac_info_t;
typedef struct vf_dvpp_info {
u32 jpegd_bitmap;
u32 jpege_bitmap;
u32 vpc_bitmap;
u32 vdec_bitmap;
u32 pngd_bitmap;
u32 venc_bitmap;
u32 reserved[4];
} vf_dvpp_info_t;
typedef struct vf_cpu_info {
u32 topic_aicpu_slot_bitmap;
u32 topic_ctrl_cpu_slot_bitmap;
u32 host_ctrl_cpu_bitmap;
u32 device_aicpu_bitmap;
u64 host_aicpu_bitmap;
u32 reserved[4];
} vf_cpu_info_t;
typedef struct vmng_vf_cfg {
u32 capbility;
vf_id_info_t id;
vf_ac_info_t accelerator;
vf_cpu_info_t cpu;
vf_dvpp_info_t dvpp;
u32 reserved[4];
} vmng_vf_cfg_t;
#pragma pack(pop)
#pragma pack(push)
#pragma pack(1)
typedef struct {
u8 flag;
u8 totalNum;
u8 minNum;
u8 reserved;
u32 freq;
u64 bitMap;
} vmng_common_pg_info;
typedef struct {
vmng_common_pg_info cpuPara;
vmng_common_pg_info aicPara;
vmng_common_pg_info aivPara;
vmng_common_pg_info hbmPara;
vmng_common_pg_info vpcPara;
vmng_common_pg_info jpegdPara;
vmng_common_pg_info dvppPara;
vmng_common_pg_info sioPara;
vmng_common_pg_info hccsPara;
vmng_common_pg_info mataPara;
vmng_common_pg_info l2Para;
vmng_common_pg_info gpuPara;
} vmng_common_pg;
#pragma pack(pop)
struct vmng_vdev_ctrl {
u32 status;
u32 dev_id;
u32 vfid;
u32 vm_devid;
u32 vm_id;
u32 dtype;
u32 core_num;
u32 total_core_num;
u64 ddr_size;
u64 hbm_size;
u64 mem_size;
u64 bar0_size;
u64 bar2_size;
u64 bar4_size;
vmng_vf_cfg_t vf_cfg;
};
struct vf_bandwidth_ctrl_remote {
u64 flow_limit;
u64 hostcpu_flow_cnt[2];
u64 ctrlcpu_flow_cnt[2];
u64 tscpu_flow_cnt[2];
u64 pack_limit;
u64 hostcpu_pack_cnt[2];
u64 ctrlcpu_pack_cnt[2];
u64 tscpu_pack_cnt[2];
u64 reserved[2];
};
struct vf_bandwidth_ctrl_local {
u64 hostcpu_flow_cnt[2];
u64 ctrlcpu_flow_cnt[2];
u64 tscpu_flow_cnt[2];
u64 hostcpu_pack_cnt[2];
u64 ctrlcpu_pack_cnt[2];
u64 tscpu_pack_cnt[2];
u32 read_cnt;
u32 write_cnt;
};
struct vmng_bandwith_ctrl {
struct vf_bandwidth_ctrl_remote *io_base_bwctrl;
u64 bandwidth;
u64 packspeed;
u64 flow_limit[VMNG_VDEV_MAX_PER_PDEV];
u64 pack_limit[VMNG_VDEV_MAX_PER_PDEV];
struct vf_bandwidth_ctrl_local local_data[VMNG_VDEV_MAX_PER_PDEV];
};
struct vmng_bandwidth_check_info {
u32 dev_id;
u32 vfid;
u32 dir;
u32 data_len;
u32 node_cnt;
u32 handle_mode;
};
struct vmngh_client_instance {
void *priv;
struct vmng_vdev_ctrl *dev_ctrl;
ka_mutex_t flag_mutex;
enum vmng_client_type type;
u32 flag;
u32 vdev_type;
};
struct vmngh_bar_map {
size_t offset;
u64 paddr;
size_t size;
};
struct vmngh_map_info {
u64 num;
struct vmngh_bar_map *map_info;
};
enum vmng_pf_sriov_status {
VMNGH_PF_SRIOV_DISABLE = 0,
VMNGH_PF_SRIOV_ENABLE,
VMNGH_PF_STATUS_MAX
};
struct vmng_sriov_info {
unsigned int dev_id;
enum vmng_pf_sriov_status sriov_status;
};
struct vmngh_client {
enum vmng_client_type type;
int (*init_instance)(struct vmngh_client_instance *instance);
int (*uninit_instance)(struct vmngh_client_instance *instance);
int (*init_container_instance)(struct vmngh_client_instance *instance);
int (*uninit_container_instance)(struct vmngh_client_instance *instance);
int (*suspend)(struct vmngh_client_instance *instance);
int (*sriov_instance)(struct vmng_sriov_info *sriov_info);
};
int vmngh_register_client(struct vmngh_client *client);
int vmngh_unregister_client(struct vmngh_client *client);
struct vmngh_vascend_client {
enum vmng_client_type type;
int (*get_map_info)(struct vmngh_client_instance *instance, struct vmngh_map_info *map_info);
int (*put_map_info)(struct vmngh_client_instance *instance);
};
int vmngh_register_vascend_client(struct vmngh_vascend_client *client);
int vmngh_unregister_vascend_client(struct vmngh_vascend_client *client);
enum vmng_split_mode {
VMNG_NORMAL_NONE_SPLIT_MODE = 0,
VMNG_VIRTUAL_SPLIT_MODE,
VMNG_CONTAINER_SPLIT_MODE,
VMNG_INVALID_SPLIT_MODE
};
* @Description: get device runtime environment
* @Returun: 0: normal, none split 1: virtual split 2: container split
*/
enum vmng_split_mode vmng_get_device_split_mode(u32 dev_id);
struct vmnga_ctrl {
ka_device_t *dev;
ka_pci_bus_t *bus;
ka_pci_dev_t *pdev;
void *unit;
enum vmng_startup_flag_type startup_flag;
u32 dev_id;
u32 dtype;
u32 core_num;
u64 ddr_size;
u64 hbm_size;
};
struct vmnga_client_instance {
void *priv;
struct vmnga_ctrl *dev_ctrl;
ka_mutex_t flag_mutex;
enum vmng_client_type type;
u32 flag;
};
struct vmnga_client {
enum vmng_client_type type;
int (*init_instance)(struct vmnga_client_instance *instance);
int (*uninit_instance)(struct vmnga_client_instance *instance);
int (*suspend)(struct vmnga_client_instance *instance);
};
int vmnga_register_client(struct vmnga_client *client);
int vmnga_unregister_client(struct vmnga_client *client);
typedef enum {
VMNG_GOING_TO_S0 = 0,
VMNG_GOING_TO_SUSPEND,
VMNG_GOING_TO_S3,
VMNG_GOING_TO_S4,
VMNG_GOING_TO_D0,
VMNG_GOING_TO_D3,
VMNG_GOING_TO_DISABLE_DEV,
VMNG_GOING_TO_ENABLE_DEV,
VMNG_STATE_MAX
} vmnga_dev_state;
typedef int (*vmnga_dev_startup_notify)(u32 probe_num, const u32 dev_ids[], u32 array_len, u32 dev_num);
typedef int (*vmnga_dev_state_notify)(u32 dev_id, vmnga_dev_state state);
void vmnga_register_dev_startup_callback(vmnga_dev_startup_notify startup_notify);
void vmnga_register_dev_state_callback(vmnga_dev_state_notify state_notify);
enum vmng_get_irq_type {
VMNG_GET_IRQ_TYPE_TSDRV = 0,
VMNG_IRQ_TYPE_MAX
};
typedef int (*db_handler_t)(int, void *);
int vmngh_get_local_db(u32 dev_id, u32 fid, enum vmng_get_irq_type type, u32 *db_base, u32 *db_num);
int vmngh_register_local_db(u32 dev_id, u32 fid, u32 db_index, db_handler_t handler, void *data);
int vmngh_unregister_local_db(u32 dev_id, u32 fid, u32 db_index, const void *data);
int vmnga_get_remote_db(u32 dev_id, enum vmng_get_irq_type type, u32 *db_base, u32 *db_num);
int vmnga_trigger_remote_db(u32 dev_id, u32 db_index);
int vmngh_get_remote_msix(u32 dev_id, u32 fid, enum vmng_get_irq_type type, u32 *msix_base, u32 *msix_num);
int vmngh_trigger_remote_msix(u32 dev_id, u32 fid, u32 msix_index);
int vmnga_get_local_msix(u32 dev_id, enum vmng_get_irq_type type, u32 *msix_base, u32 *msix_num);
int vmnga_register_local_msix(u32 dev_id, u32 msix_index, ka_irq_handler_t handler, void *data, const char *name);
int vmnga_unregister_local_msix(u32 dev_id, u32 msix_index, void *data);
enum vmng_get_addr_type {
VMNG_GET_ADDR_TYPE_TSDRV = 0,
VMNG_GET_ADDR_TYPE_MAX
};
int vmngh_get_virtual_addr_info(u32 dev_id, u32 fid, enum vmng_get_addr_type type, u64 *addr, u64 *size);
int vmnga_get_physicl_addr_info(u32 dev_id, enum vmng_get_addr_type type, phys_addr_t *addr, u64 *size);
#define DMA_MAP_ERROR (~(ka_dma_addr_t)0)
ka_dma_addr_t vmngh_dma_map_guest_page(u32 dev_id, u32 fid, unsigned long addr, unsigned long size,
ka_sg_table_t **dma_sgt);
void vmngh_dma_unmap_guest_page(u32 dev_id, u32 fid, ka_sg_table_t *dma_sgt);
bool vmngh_dma_pool_active(u32 dev_id, u32 fid);
int vmngh_dma_map_guest_page_batch(u32 dev_id, u32 fid, unsigned long *gfn, unsigned long *dma_addr,
unsigned long count);
void vmngh_dma_unmap_guest_page_batch(u32 dev_id, u32 fid, unsigned long *gfn, unsigned long *dma_addr,
unsigned long count);
void *vmngh_get_vdavinci_by_id(u32 dev_id, u32 fid);
void *vmngh_dma_alloc_coherent(ka_device_t *dev, size_t size, ka_dma_addr_t *dma_handle, ka_gfp_t gfp);
void vmngh_dma_free_coherent(ka_device_t *dev, size_t size, void *cpu_addr, ka_dma_addr_t dma_handle);
int vmngh_hypervisor_inject_msix(unsigned int dev_id, unsigned int irq_vector);
int vmngh_check_vdev_phy_address(unsigned int dev_id, u64 phy_address, u64 length);
int vmng_check_vdev_iova_address(unsigned int dev_id, ka_dma_addr_t iova_addr, size_t size);
* @Description: get vm id
* @Returun: 0~31: normal -1: error
*/
#define VMNGH_VM_ID_DEFAULT (-1)
int vmngh_ctrl_get_vm_id(u32 dev_id, u32 fid);
int vmngh_ctrl_get_devid_fid(u32 vm_id, u32 vm_devid, u32 *dev_id, u32 *fid);
int vmngh_enable_sriov(u32 dev_id);
int vmngh_disable_sriov(u32 dev_id);
struct vmng_para {
u32 devid;
u32 fid;
void *para1;
void *para2;
void *para3;
void *para4;
};
enum vmngh_dev_info_type {
VMNGH_DEV_CORE_NUM = 0,
VMNGH_DEV_DDR_SIZE,
VMNGH_DEV_HBM_SIZE,
VMNGH_DEV_TYPE_MAX
};
void vmngh_set_dev_info(u32 dev_id, enum vmngh_dev_info_type type, u64 val);
void vmngh_set_total_core_num(u32 dev_id, u32 total_core_num);
struct vmnga_pci_dev_info {
u8 bus_no;
u8 device_no;
u8 function_no;
};
struct vmnga_pcie_id_info {
unsigned int venderid;
unsigned int subvenderid;
unsigned int deviceid;
unsigned int subdeviceid;
unsigned int bus;
unsigned int device;
unsigned int fn;
};
int vmnga_get_pci_dev_info(u32 dev_id, struct vmnga_pci_dev_info *dev_info);
int vmnga_get_pcie_id_info(u32 dev_id, struct vmnga_pcie_id_info *dev_info);
enum vmngd_client_type {
VMNGD_CLIENT_TYPE_DEVMNG = 0,
VMNGD_CLIENT_TYPE_TSDRV,
VMNGD_CLIENT_TYPE_ESCHED,
VMNGD_CLIENT_TYPE_DEVMM,
VMNGD_CLIENT_TYPE_DVPP,
VMNGD_CLIENT_TYPE_TSD,
VMNGD_CLIENT_TYPE_QOS,
VMNGD_CLIENT_TYPE_PROFILING,
VMNGD_CLIENT_TYPE_HDC,
VMNGD_CLIENT_TYPE_QUEUE,
VMNGD_CLIENT_TYPE_VRESOURCE_MGR,
VMNGD_CLIENT_TYPE_MAX
};
static const char *vmngd_client_name[VMNGD_CLIENT_TYPE_MAX] = {
[VMNGD_CLIENT_TYPE_DEVMNG] = "devmng",
[VMNGD_CLIENT_TYPE_TSDRV] = "tsdrv",
[VMNGD_CLIENT_TYPE_ESCHED] = "esched",
[VMNGD_CLIENT_TYPE_DEVMM] = "devmm",
[VMNGD_CLIENT_TYPE_DVPP] = "dvpp",
[VMNGD_CLIENT_TYPE_TSD] = "tsd",
[VMNGD_CLIENT_TYPE_QOS] = "qos",
[VMNGD_CLIENT_TYPE_PROFILING] = "profiling",
[VMNGD_CLIENT_TYPE_HDC] = "hdc",
[VMNGD_CLIENT_TYPE_QUEUE] = "queue",
[VMNGD_CLIENT_TYPE_VRESOURCE_MGR] = "resource_mgr"
};
static inline const char *get_client_name(enum vmngd_client_type type)
{
if (type >= VMNGD_CLIENT_TYPE_MAX) {
return "Invalid type";
}
return vmngd_client_name[type];
}
struct vmngd_client_instance {
enum vmngd_client_type type;
u32 flag;
ka_mutex_t mutex;
struct vmng_vdev_ctrl vdev_ctrl;
};
struct vmngd_client {
enum vmngd_client_type type;
int (*init_instance)(struct vmngd_client_instance *instance);
int (*uninit_instance)(struct vmngd_client_instance *instance);
int (*update_vfg)(struct vmng_soc_resource_enquire *vf_info);
int (*reset_instance)(struct vmngd_client_instance *instance);
int (*sriov_instance)(struct vmng_sriov_info *sriov_info);
};
int vmngd_register_client(struct vmngd_client *client);
int vmngd_unregister_client(struct vmngd_client *client);
int vmngd_get_dtype(u32 dev_id, u32 vfid, u32 *dtype);
int vmngd_register_vmng_client(void);
int vmngd_get_pfvf_id_by_devid(u32 dev_id, u32 *pf_id, u32 *vf_id);
int vmngd_get_devid_by_pfvf_id(u32 pf_id, u32 vf_id, u32 *dev_id);
int vmngd_get_pfvf_type_by_devid(u32 dev_id);
int vmngh_create_container_vdev(u32 dev_id, u32 dtype, u32 *vfid, struct vmng_vf_res_info *vf_resource);
int vmngh_destory_container_vdev(u32 dev_id, u32 vfid);
int vmng_bandwidth_limit_check(struct vmng_bandwidth_check_info *info);
int vmngd_get_device_vf_max(u32 dev_id, u32 *vf_max_num);
int vmngd_get_device_vf_list(u32 dev_id, u32 *vf_list, u32 list_len, u32 *vf_num);
int vmngh_enquire_soc_resource(u32 dev_id, u32 vfid, struct vmng_soc_resource_enquire *info);
int vmngd_enquire_soc_resource(u32 dev_id, u32 vfid, struct vmng_soc_resource_enquire *info);
int vmngd_enquire_vfg_resource(u32 dev_id, u32 vfid, struct vmng_soc_res_info *vfg_info);
int vmngh_refresh_vdev_resource(u32 dev_id, u32 vfid, struct vmng_soc_resource_refresh *info);
int vmngh_sriov_reset_vdev(u32 dev_id, u32 vfid);
int vmngd_get_device_vf_core_info(u32 dev_id, u32 vf_id,
u32 *total_core, u32 *core_count, u64 *mem_size);
#if (defined CFG_FEATURE_VFIO) && (defined CFG_FEATURE_RC_MODE)
int vmng_create_container_vdev(u32 dev_id, u32 dtype, u32 *vfid, struct vmng_vf_res_info *vf_resource);
int vmng_destory_container_vdev(u32 dev_id, u32 vfid);
#endif
#endif