* 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 _DEVDRV_PCI_H_
#define _DEVDRV_PCI_H_
#include "ka_base_pub.h"
#include "ka_pci_pub.h"
#include "ka_system_pub.h"
#include "ka_common_pub.h"
#include "ka_task_pub.h"
#include "ka_memory_pub.h"
#include "devdrv_device_load.h"
#include "devdrv_atu.h"
#include "devdrv_dma.h"
#include "securec.h"
#define PCI_VENDOR_ID_HUAWEI 0x19e5
#define PCI_VENDOR_ID_HX 0x2092
#define CLOUD_V1_DEVICE 0xd801
#define MINI_V2_DEVICE 0xd500
#define MINI_V2_2P_DEVICE 0xd501
#define CLOUD_V2_DEVICE 0xd802
#define CLOUD_V2_2P_DEVICE 0xd804
#define CLOUD_V2_HCCS_IEP_DEVICE 0xd803
#define CLOUD_V2_VF_DEVICE 0xd805
#define MINI_V3_DEVICE 0xd105
#define CLOUD_V4_DEVICE 0xd806
#define CLOUD_V5_DEVICE 0xd807
#define DEVDRV_RC_MSI_ADDR 0x820
#define DEVDRV_RC_MSI_UPPER_ADDR 0x824
#define DEVDRV_RC_MSI_EN 0x828
#define DEVDRV_RC_MSI_MASK 0x82C
#define DEVDRV_RC_MSI_STATUS 0x830
#define DEVDRV_MINI_MSI_X_OFFSET 0x10000
#define DEVDRV_DMA_TEST_SIZE 0x100000
#define DEVDRV_REMOVE_CALLED_BY_PRERESET 0
#define DEVDRV_REMOVE_CALLED_BY_MODULE_EXIT 1
#define DEVDRV_DEVICE_DEAD 1
#define DEVDRV_DEVICE_REMOVE 2
#define DEVDRV_DEVICE_ALIVE 3
#define DEVDRV_DEVICE_SUSPEND 4
#define DEVDRV_DEVICE_RESUME 5
#define DEVDRV_DEVICE_UDA_RM 6
#define DEVDRV_NORMAL_STARTUP_STATUS 0
#define DEVDRV_SUSPEND_STATUS 1
#define DEVDRV_RESUME_STATUS 2
#define DEVDRV_SUSPEND_STARTUP_STATUS 3
#define DEVDRV_REMOVE_STATUS 4
#define DEVDRV_WAIT_STATE_STATUS_DELAY 10
#define DEVDRV_WAIT_STATE_STATUS_TIMEOUT 100
#define DEVDRV_DEVICE_RAM_INFO_MAX_NUM 256
#define DEVDRV_DEVICE_RAM_INFO_DATA_SIZE 48
#define DEVDRV_DEVICE_RAM_INFO_NUM_ONE_TIME 4
#define DEVDRV_BBOX_RESVED_MEM_ALLOC_PAGES_ORDER 9
#define DEVDRV_BBOX_RESVED_MEM_SIZE (2 * 1024 * 1024)
#define DEVDRV_BIOS_VERSION_ARR_LEN 4
#define DEVDRV_HOST_RECV_INTERRUPT_FLAG 1
#define DEVDRV_ADDR_ADD 4
#define DEVDRV_ADDR_MOVE_32 32
#define DEVDRV_MSIX_TABLE_SPAN 0x10
#define DEVDRV_MSIX_TABLE_ADDRH 0x4
#define DEVDRV_MSIX_TABLE_NUM 0x8
#define DEVDRV_MSIX_TABLE_MASK 0xC
#define DEVDRV_MSIX_ADDR_BIT 0xFFFFFFFFU
#define DEVDRV_DMA_BIT_MASK_64 64
#define DEVDRV_DMA_BIT_MASK_48 48
#define DEVDRV_DMA_BIT_MASK_32 32
#define DEVDRV_FREE_PAGE_PARA 9
#define DEVDRV_REVISION_TYPE_DEFAULT 0x20
#define DEVDRV_REVISION_TYPE_MDEV_SRIOV_VF 0x71
#define DEVDRV_PCI_SUBSYS_DEV 0X0100UL
#define DEVDRV_1PF2P_PCI_SUBSYS_DEV 0X0110UL
#define DEVDRV_PCI_SUBSYS_VENDOR 0X0200UL
#define DEVDRV_PCI_SUBSYS_PRIVATE_VENDOR 0X19E5UL
#define DEVDRV_PCI_SUBSYS_PRIVATE_VENDOR_HX 0X2092UL
#define DEVDRV_PCI_SUBSYS_PRIVATE_VENDOR_HK 0X20C6UL
#define DEVDRV_PCI_SUBSYS_PRIVATE_VENDOR_KL 0X203FUL
#define DEVDRV_PCI_SUBSYS_PRIVATE_VENDOR_CJ 0X20E9UL
#define DEVDRV_PCI_SUBSYS_DEV_MASK_BIT 4
#define DEVDRV_DAVINCI_DEV_NUM_1PF1P 1
#define DEVDRV_DAVINCI_DEV_NUM_1PF2P 2
#define DEVDRV_SYSFS_ENABLE 1
#define DEVDRV_SYSFS_DISABLE 0
struct devdrv_pgtab_info;
#define MSI_X_MAX_VECTORS 2048
#define DEVDRV_MSI_MAX_VECTORS 32
#define DEVDRV_WAIT_BOOT_MODE_MAX 1000
#define DEVDRV_WAIT_BOOT_MODE_SLEEP_TIME 20
#define DEVDRV_GUARD_WORK_DELAY_MIN 1
#define DEVDRV_GUARD_WORK_DELAY_MAX 1000
#define DEVDRV_GUARD_WORK_DELAY_MULTI 2
#define DEVDRV_DMA_DONE_GUARD_WORK_DELAY 100
#define DEVDRV_CHECK_MODULE_TIMEOUT 1000
#define CACHE_INVALID 1
#define CACHE_CLEAN 2
#define DEVDRV_INVALID_PHY_ID 0xFFFFFFFFU
struct devdrv_msix_ctrl {
u32 next_entry;
ka_msix_entry_t entries[MSI_X_MAX_VECTORS];
};
struct devdrv_msi_info {
void *data;
ka_irqreturn_t (*callback_func)(int, void *);
};
struct devdrv_device_mem_info {
u64 start_addr;
u64 offset;
u32 mem_type;
u32 node_id;
};
struct devdrv_dma_test {
u32 flag;
ka_timer_list_t test_timer;
int timer_remain;
int timer_expires;
};
#define DEVDRV_STARTUP_STATUS_INIT 0
#define DEVDRV_STARTUP_STATUS_TIMEOUT 1
#define DEVDRV_STARTUP_STATUS_FINISH 2
#define DEVDRV_MODULE_INIT_TIMEOUT 300000
#define DEVDRV_MODULE_FINISH_TIMEOUT 60000
#define DEVDRV_PCIE_HOT_RESET_ALL_DEVICE_MASK (~0x0ULL)
#define DEVDRV_LOAD_INIT_STATUS 1
#define DEVDRV_LOAD_SUCCESS_STATUS 2
#define DEVDRV_LOAD_HALF_PROBE_STATUS 3
#define DEVDRV_LOAD_HALF_WAIT_COUNT 300
struct devdrv_startup_status {
int status;
u32 module_bit_map;
unsigned long timestamp;
};
struct devdrv_bar_dma_info {
u64 io_dma_addr;
u64 io_phy_size;
u64 io_txatu_base;
u64 mem_dma_addr;
u64 mem_phy_size;
u64 mem_txatu_base;
u64 db_dma_addr;
u64 db_phy_size;
u64 msg_mem_dma_addr;
u64 msg_mem_phy_size;
u64 rsv_mem_dma_addr;
u64 rsv_mem_phy_size;
};
struct devdrv_bar_addr {
u64 addr;
size_t size;
};
struct devdrv_intr_info {
int min_vector;
int max_vector;
int device_os_load_irq;
msg chan 0 is used to admin(chan 0) role */
int msg_irq_base;
int msg_irq_num;
host support x dma chan witch is related to enum devdrv_dma_data_type */
int dma_irq_base;
int dma_irq_num;
int tsdrv_irq_base;
int tsdrv_irq_num;
int topic_sched_irq_base;
int topic_sched_irq_num;
int cdqm_irq_base;
int cdqm_irq_num;
allocate the second segment of interrupts to the msg and tsdrv. */
int msg_irq_vector2_base;
int msg_irq_vector2_num;
int tsdrv_irq_vector2_base;
int tsdrv_irq_vector2_num;
};
#define DEVDRV_IRQ_GEAR_INFO_INVALID 0
#define DEVDRV_IRQ_GEAR_INFO_VALID 1
struct devdrv_irq_gear_info {
int flag;
struct devdrv_intr_info intr;
};
#define DEVDRV_RES_GEAR_MAX_VAL 6
#define DEVDRV_RES_GEAR_VAL_CNT (DEVDRV_RES_GEAR_MAX_VAL + 1)
struct devdrv_load_file_info {
struct devdrv_load_file_cfg *load_file_cfg;
int load_file_num;
};
#define DEVDRV_MODULE_UNPROBED 0
#define DEVDRV_MODULE_ONLINE 1
struct devdrv_depend_module {
char *module_name;
u32 status;
};
struct devdrv_depend_info {
struct devdrv_depend_module *module_list;
u32 module_num;
};
struct devdrv_link_info {
u64 bandwidth;
u64 packspeed;
u32 bandwidth_ratio;
u32 packspeed_ratio;
};
struct devdrv_res_info {
void __ka_mm_iomem *phy_match_flag_addr;
void __ka_mm_iomem *nvme_db_base;
void __ka_mm_iomem *nvme_pf_ctrl_base;
void __ka_mm_iomem *load_sram_base;
phys_addr_t rsv_phy_addr;
struct devdrv_dma_res dma_res;
struct devdrv_bar_addr msg_db;
struct devdrv_bar_addr msg_mem;
struct devdrv_bar_addr s2s_msg;
struct devdrv_bar_addr ts_db;
struct devdrv_bar_addr ts_sram;
struct devdrv_bar_addr ts_sq;
struct devdrv_bar_addr test;
struct devdrv_bar_addr load_sram;
struct devdrv_bar_addr hwts;
struct devdrv_bar_addr imu_log;
struct devdrv_bar_addr hdr;
struct devdrv_bar_addr bbox;
struct devdrv_bar_addr kdump;
struct devdrv_bar_addr vmcore;
struct devdrv_bar_addr bbox_ddr_dump;
struct devdrv_bar_addr ts_log;
struct devdrv_bar_addr chip_dfx;
struct devdrv_bar_addr reg_sram;
struct devdrv_bar_addr tsdrv_resv;
struct devdrv_bar_addr devmng_resv;
struct devdrv_bar_addr devmng_info_mem;
struct devdrv_bar_addr hbm_ecc_mem;
struct devdrv_bar_addr vf_bandwidth;
struct devdrv_bar_addr ts_share_mem;
struct devdrv_bar_addr ts_notify;
struct devdrv_bar_addr ts_event;
struct devdrv_bar_addr l3d_sram;
struct devdrv_bar_addr stars_sqcq;
struct devdrv_bar_addr stars_sqcq_intr;
struct devdrv_bar_addr stars_topic_sched;
struct devdrv_bar_addr stars_topic_sched_cqe;
struct devdrv_bar_addr stars_topic_sched_rsv_mem;
struct devdrv_bar_addr stars_cdqm;
struct devdrv_bar_addr stars_intr;
struct devdrv_bar_addr vpc;
struct devdrv_bar_addr dvpp;
struct devdrv_intr_info intr;
struct devdrv_load_file_info load_file;
struct devdrv_depend_info depend_info;
int msg_chan_cnt[devdrv_msg_client_max];
struct devdrv_link_info link_info;
};
#define DEVDRV_VDAVINCI_VIRTUAL_RESERVE_BYTES 40
struct devdrv_priv {
ka_device_t *dev;
void *dvt;
void *ops;
char reserve[DEVDRV_VDAVINCI_VIRTUAL_RESERVE_BYTES];
};
struct devdrv_dev_ops {
void (*shr_para_rebuild)(struct devdrv_pci_ctrl *pci_ctrl);
int (*alloc_devid)(struct devdrv_ctrl *ctrl_this);
int (*is_p2p_access_cap)(struct devdrv_pci_ctrl *pci_ctrl, struct devdrv_pci_ctrl *peer_pci_ctrl);
void (*probe_wait)(int devid);
void (*bind_irq)(struct devdrv_pci_ctrl *pci_ctrl);
void (*unbind_irq)(struct devdrv_pci_ctrl *pci_ctrl);
enum devdrv_load_wait_mode (*get_load_wait_mode)(struct devdrv_pci_ctrl *pci_ctrl);
int (*get_pf_max_msg_chan_cnt)(void);
int (*get_vf_max_msg_chan_cnt)(void);
u32 (*get_p2p_support_max_devnum)(void);
void (*get_vf_dma_info)(struct devdrv_pci_ctrl *pci_ctrl);
void (*get_hccs_link_info)(struct devdrv_pci_ctrl *pci_ctrl);
bool (*is_mdev_vm_full_spec)(struct devdrv_pci_ctrl *pci_ctrl);
int (*devdrv_deal_suspend_handshake)(struct devdrv_pci_ctrl *pci_ctrl);
bool (*is_all_dev_unified_addr)(void);
void (*flush_cache)(u64 base, size_t len, u32 mode);
int (*get_peh_link_info)(ka_pci_dev_t *pdev, u32 *link_speed, u32 *link_width, u32 *link_status);
void (*set_dev_shr_info)(struct devdrv_pci_ctrl *pci_ctrl);
void (*link_speed_slow_to_normal)(struct devdrv_pci_ctrl *pci_ctrl);
int (*get_p2p_addr)(struct devdrv_pci_ctrl *pci_ctrl, u32 remote_dev_id, enum devdrv_p2p_addr_type type,
phys_addr_t *phy_addr, size_t *size);
unsigned int (*get_server_id)(struct devdrv_pci_ctrl *pci_ctrl);
unsigned int (*get_max_server_num)(struct devdrv_pci_ctrl *pci_ctrl);
int (*check_ep_suspend_status)(struct devdrv_pci_ctrl *pci_ctrl);
int (*single_fault_init)(struct devdrv_pci_ctrl *pci_ctrl);
int (*single_fault_uninit)(struct devdrv_pci_ctrl *pci_ctrl);
void (*init_virt_info)(struct devdrv_pci_ctrl *pci_ctrl);
int (*set_udevid_reorder_para)(struct devdrv_pci_ctrl *pci_ctrl);
u32 (*get_nvme_low_level_db_irq_num)(void);
u32 (*get_nvme_db_irq_strde)(void);
void (*pre_cfg)(struct devdrv_pci_ctrl *pci_ctrl);
};
#define DEVDRV_MAX_MSG_CHAN_NUM 101
struct devdrv_pci_ctrl {
struct devdrv_agent_load *agent_loader;
struct devdrv_msg_dev *msg_dev;
ka_workqueue_struct_t *work_queue[DEVDRV_MAX_MSG_CHAN_NUM];
struct devdrv_dma_dev *dma_dev;
struct devdrv_load_work load_work;
struct devdrv_dma_test *dma_test;
ka_pci_dev_t *pdev;
struct devdrv_pgtab_info *pgtab_info;
struct devdrv_shr_para __ka_mm_iomem *shr_para;
struct devdrv_res_info res;
struct devdrv_dev_ops ops;
void __ka_mm_iomem *io_base;
void __ka_mm_iomem *msi_base;
void __ka_mm_iomem *mem_base;
void __ka_mm_iomem *local_reserve_mem_base;
void __ka_mm_iomem *rc_reg_base;
phys_addr_t io_phy_base;
u64 io_phy_size;
phys_addr_t mem_phy_base;
u64 mem_phy_size;
phys_addr_t rsv_mem_phy_base;
u64 rsv_mem_phy_size;
phys_addr_t mdev_rsv_mem_phy_base;
u64 mdev_rsv_mem_phy_size;
u64 host_mem_dma_addr;
u64 host_mem_phy_size;
struct devdrv_bar_dma_info target_bar[DEVDRV_P2P_SUPPORT_MAX_DEVNUM];
phys_addr_t mem_base_paddr;
u32 dev_id;
u32 remote_dev_id;
u32 slot_id;
u32 func_id;
u32 os_load_flag;
u32 chip_type;
u32 virtfn_flag;
int env_boot_mode;
int connect_protocol;
int addr_mode;
int multi_die;
u32 load_half_probe;
u32 add_davinci_flag;
int load_vector;
ka_work_struct_t half_probe_work;
u32 device_boot_status;
u32 module_exit_flag;
u32 load_status_flag;
device is alive or dead
if dead, no need to send admin msg for save time
*/
u32 device_status;
struct devdrv_startup_status startup_status;
int msix_irq_num;
struct devdrv_msix_ctrl msix_ctrl;
void *msi_addr;
ka_dma_addr_t msi_dma_addr;
struct devdrv_msi_info msi_info[DEVDRV_MSI_MAX_VECTORS];
u32 mem_bar_id;
struct devdrv_iob_atu mem_rx_atu[DEVDRV_MAX_RX_ATU_NUM];
u32 bbox_resv_size;
u64 bbox_resv_dmaAddr;
ka_page_t *bbox_resv_dmaPages;
ka_delayed_work_t guard_work;
u32 guard_work_delay;
u32 dev_id_in_pdev;
int vector_num;
u32 msix_offset;
phys_addr_t mem_bar_offset;
phys_addr_t rsv_mem_bar_offset;
phys_addr_t io_bar_offset;
ka_atomic_t ref_cnt;
struct devdrv_dma_iova_addr_range *iova_range;
ka_rb_root_t dma_desc_rbtree;
ka_task_spinlock_t dma_desc_rblock;
u32 hccs_status;
u32 hccs_group_id[HCCS_GROUP_SUPPORT_MAX_CHIPNUM];
u32 bar_wc_flag;
u32 ep_pf_index;
u32 is_sriov_enabled;
};
#define PDEV_MAX_DEV_NUM 2
struct devdrv_pdev_ctrl {
struct devdrv_priv vdavinci_priv;
int dev_num;
struct devdrv_pci_ctrl *pci_ctrl[PDEV_MAX_DEV_NUM];
u32 main_dev_id;
u32 sysfs_flag;
};
void devdrv_set_pcie_info_to_dbl(struct devdrv_pci_ctrl *pci_ctrl);
void devdrv_set_resmng_hccs_link_status_and_group_id(struct devdrv_pci_ctrl *pci_ctrl);
void devdrv_set_resmng_pdev_by_devid(struct devdrv_pci_ctrl *pci_ctrl);
void devdrv_set_resmng_host_phy_match_flag(struct devdrv_pci_ctrl *pci_ctrl);
bool devdrv_is_tsdrv_irq(const struct devdrv_intr_info *intr, int irq);
void devdrv_bind_irq(struct devdrv_pci_ctrl *pci_ctrl);
void devdrv_unbind_irq(struct devdrv_pci_ctrl *pci_ctrl);
void devdrv_load_half_probe(struct devdrv_pci_ctrl *pci_ctrl);
void devdrv_load_half_free(struct devdrv_pci_ctrl *pci_ctrl);
void devdrv_init_dev_num(void);
int devdrv_get_dev_num(void);
void devdrv_notify_dev_init_status(struct devdrv_pci_ctrl *pci_ctrl);
void devdrv_guard_work_sched_immediate(struct devdrv_pci_ctrl *pci_ctrl);
extern int devdrv_sysfs_init(ka_pci_dev_t *pdev);
extern void devdrv_sysfs_exit(ka_pci_dev_t *pdev);
bool devdrv_is_pdev_main_davinci_dev(struct devdrv_pci_ctrl *pci_ctrl);
struct devdrv_pci_ctrl *devdrv_get_dev_by_index_in_pdev(ka_pci_dev_t *pdev, int dev_index);
struct devdrv_pci_ctrl *devdrv_get_pdev_main_davinci_dev(ka_pci_dev_t *pdev);
int devdrv_get_davinci_dev_num_by_pdev(ka_pci_dev_t *pdev);
u32 devdrv_get_main_davinci_devid_by_pdev(ka_pci_dev_t *pdev);
int devdrv_init_interrupt_normal(struct devdrv_pci_ctrl *pci_ctrl);
int devdrv_uninit_interrupt(struct devdrv_pci_ctrl *pci_ctrl);
int devdrv_vf_half_probe(u32 index_id);
int devdrv_vf_half_free(u32 index_id);
void devdrv_init_shr_info_after_half_probe(struct devdrv_pci_ctrl *pci_ctrl);
void devdrv_pcictrl_shr_para_init(struct devdrv_pci_ctrl *pci_ctrl);
int devdrv_get_product(void);
extern ka_pci_driver_t g_devdrv_driver_ver;
int devdrv_get_pdev_davinci_dev_num(u32 device, u16 subsystem_device);
void devdrv_guard_work_uninit(struct devdrv_pci_ctrl *pci_ctrl);
void devdrv_guard_work_init(struct devdrv_pci_ctrl *pci_ctrl);
ka_irqreturn_t devdrv_half_probe_irq(int irq, void *data);
int devdrv_cfg_pdev(ka_pci_dev_t *pdev);
void devdrv_uncfg_pdev(ka_pci_dev_t *pdev);
void drv_pcie_remove(ka_pci_dev_t *pdev);
#endif