2026-01-21 18:59:54 +08:00

244 lines
7.8 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
/* Huawei Hifc PCI Express Linux driver
* Copyright(c) 2017 Huawei Technologies Co., Ltd
*
*/
#ifndef HIFC_HWIF_H
#define HIFC_HWIF_H
#include "hifc_hwdev.h"
#define HIFC_WAIT_DOORBELL_AND_OUTBOUND_TIMEOUT 60000
#define HIFC_CSR_GLOBAL_BASE_ADDR 0x4000
/* HW interface registers */
#define HIFC_CSR_FUNC_ATTR0_ADDR 0x0
#define HIFC_CSR_FUNC_ATTR1_ADDR 0x4
#define HIFC_CSR_FUNC_ATTR2_ADDR 0x8
#define HIFC_CSR_FUNC_ATTR4_ADDR 0x10
#define HIFC_CSR_FUNC_ATTR5_ADDR 0x14
#define HIFC_PCI_MSIX_ENTRY_SIZE 16
#define HIFC_PCI_MSIX_ENTRY_VECTOR_CTRL 12
#define HIFC_PCI_MSIX_ENTRY_CTRL_MASKBIT 1
/* total doorbell or direct wqe size is 512kB, db num: 128, dwqe: 128*/
#define HIFC_DB_DWQE_SIZE 0x00080000
/* db/dwqe page size: 4K */
#define HIFC_DB_PAGE_SIZE 0x00001000ULL
#define HIFC_DB_MAX_AREAS (HIFC_DB_DWQE_SIZE / HIFC_DB_PAGE_SIZE)
#define HIFC_ELECTION_BASE 0x200
#define HIFC_PPF_ELECTION_STRIDE 0x4
#define HIFC_CSR_MAX_PORTS 4
#define HIFC_CSR_PPF_ELECTION_ADDR \
(HIFC_CSR_GLOBAL_BASE_ADDR + HIFC_ELECTION_BASE)
#define HIFC_CSR_GLOBAL_MPF_ELECTION_ADDR \
(HIFC_CSR_GLOBAL_BASE_ADDR + HIFC_ELECTION_BASE + \
HIFC_CSR_MAX_PORTS * HIFC_PPF_ELECTION_STRIDE)
#define DB_IDX(db, db_base) \
((u32)(((ulong)(db) - (ulong)(db_base)) / \
HIFC_DB_PAGE_SIZE))
#define HIFC_AF0_FUNC_GLOBAL_IDX_SHIFT 0
#define HIFC_AF0_P2P_IDX_SHIFT 10
#define HIFC_AF0_PCI_INTF_IDX_SHIFT 14
#define HIFC_AF0_VF_IN_PF_SHIFT 16
#define HIFC_AF0_FUNC_TYPE_SHIFT 24
#define HIFC_AF0_FUNC_GLOBAL_IDX_MASK 0x3FF
#define HIFC_AF0_P2P_IDX_MASK 0xF
#define HIFC_AF0_PCI_INTF_IDX_MASK 0x3
#define HIFC_AF0_VF_IN_PF_MASK 0xFF
#define HIFC_AF0_FUNC_TYPE_MASK 0x1
#define HIFC_AF0_GET(val, member) \
(((val) >> HIFC_AF0_##member##_SHIFT) & HIFC_AF0_##member##_MASK)
#define HIFC_AF1_PPF_IDX_SHIFT 0
#define HIFC_AF1_AEQS_PER_FUNC_SHIFT 8
#define HIFC_AF1_CEQS_PER_FUNC_SHIFT 12
#define HIFC_AF1_IRQS_PER_FUNC_SHIFT 20
#define HIFC_AF1_DMA_ATTR_PER_FUNC_SHIFT 24
#define HIFC_AF1_MGMT_INIT_STATUS_SHIFT 30
#define HIFC_AF1_PF_INIT_STATUS_SHIFT 31
#define HIFC_AF1_PPF_IDX_MASK 0x1F
#define HIFC_AF1_AEQS_PER_FUNC_MASK 0x3
#define HIFC_AF1_CEQS_PER_FUNC_MASK 0x7
#define HIFC_AF1_IRQS_PER_FUNC_MASK 0xF
#define HIFC_AF1_DMA_ATTR_PER_FUNC_MASK 0x7
#define HIFC_AF1_MGMT_INIT_STATUS_MASK 0x1
#define HIFC_AF1_PF_INIT_STATUS_MASK 0x1
#define HIFC_AF1_GET(val, member) \
(((val) >> HIFC_AF1_##member##_SHIFT) & HIFC_AF1_##member##_MASK)
#define HIFC_AF4_OUTBOUND_CTRL_SHIFT 0
#define HIFC_AF4_DOORBELL_CTRL_SHIFT 1
#define HIFC_AF4_OUTBOUND_CTRL_MASK 0x1
#define HIFC_AF4_DOORBELL_CTRL_MASK 0x1
#define HIFC_AF4_GET(val, member) \
(((val) >> HIFC_AF4_##member##_SHIFT) & HIFC_AF4_##member##_MASK)
#define HIFC_AF4_SET(val, member) \
(((val) & HIFC_AF4_##member##_MASK) << HIFC_AF4_##member##_SHIFT)
#define HIFC_AF4_CLEAR(val, member) \
((val) & (~(HIFC_AF4_##member##_MASK << \
HIFC_AF4_##member##_SHIFT)))
#define HIFC_AF5_PF_STATUS_SHIFT 0
#define HIFC_AF5_PF_STATUS_MASK 0xFFFF
#define HIFC_AF5_SET(val, member) \
(((val) & HIFC_AF5_##member##_MASK) << HIFC_AF5_##member##_SHIFT)
#define HIFC_AF5_GET(val, member) \
(((val) >> HIFC_AF5_##member##_SHIFT) & HIFC_AF5_##member##_MASK)
#define HIFC_PPF_ELECTION_IDX_SHIFT 0
#define HIFC_PPF_ELECTION_IDX_MASK 0x1F
#define HIFC_PPF_ELECTION_SET(val, member) \
(((val) & HIFC_PPF_ELECTION_##member##_MASK) << \
HIFC_PPF_ELECTION_##member##_SHIFT)
#define HIFC_PPF_ELECTION_GET(val, member) \
(((val) >> HIFC_PPF_ELECTION_##member##_SHIFT) & \
HIFC_PPF_ELECTION_##member##_MASK)
#define HIFC_PPF_ELECTION_CLEAR(val, member) \
((val) & (~(HIFC_PPF_ELECTION_##member##_MASK \
<< HIFC_PPF_ELECTION_##member##_SHIFT)))
#define HIFC_MPF_ELECTION_IDX_SHIFT 0
#define HIFC_MPF_ELECTION_IDX_MASK 0x1F
#define HIFC_MPF_ELECTION_SET(val, member) \
(((val) & HIFC_MPF_ELECTION_##member##_MASK) << \
HIFC_MPF_ELECTION_##member##_SHIFT)
#define HIFC_MPF_ELECTION_GET(val, member) \
(((val) >> HIFC_MPF_ELECTION_##member##_SHIFT) & \
HIFC_MPF_ELECTION_##member##_MASK)
#define HIFC_MPF_ELECTION_CLEAR(val, member) \
((val) & (~(HIFC_MPF_ELECTION_##member##_MASK \
<< HIFC_MPF_ELECTION_##member##_SHIFT)))
#define HIFC_HWIF_NUM_AEQS(hwif) ((hwif)->attr.num_aeqs)
#define HIFC_HWIF_NUM_CEQS(hwif) ((hwif)->attr.num_ceqs)
#define HIFC_HWIF_PPF_IDX(hwif) ((hwif)->attr.ppf_idx)
#define HIFC_PCI_INTF_IDX(hwif) ((hwif)->attr.pci_intf_idx)
#define HIFC_FUNC_TYPE(dev) ((dev)->hwif->attr.func_type)
#define HIFC_IS_PPF(dev) (HIFC_FUNC_TYPE(dev) == TYPE_PPF)
enum hifc_pcie_nosnoop {
HIFC_PCIE_SNOOP = 0,
HIFC_PCIE_NO_SNOOP = 1,
};
enum hifc_pcie_tph {
HIFC_PCIE_TPH_DISABLE = 0,
HIFC_PCIE_TPH_ENABLE = 1,
};
enum hifc_pf_status {
HIFC_PF_STATUS_INIT = 0X0,
HIFC_PF_STATUS_ACTIVE_FLAG = 0x11,
HIFC_PF_STATUS_FLR_START_FLAG = 0x12,
HIFC_PF_STATUS_FLR_FINISH_FLAG = 0x13,
};
enum hifc_outbound_ctrl {
ENABLE_OUTBOUND = 0x0,
DISABLE_OUTBOUND = 0x1,
};
enum hifc_doorbell_ctrl {
ENABLE_DOORBELL = 0x0,
DISABLE_DOORBELL = 0x1,
};
struct hifc_free_db_area {
u32 db_idx[HIFC_DB_MAX_AREAS];
u32 num_free;
u32 alloc_pos;
u32 return_pos;
/* spinlock for allocating doorbell area */
spinlock_t idx_lock;
};
enum func_type {
TYPE_PF,
TYPE_VF,
TYPE_PPF,
TYPE_UNKNOWN,
};
struct hifc_func_attr {
u16 func_global_idx;
u8 port_to_port_idx;
u8 pci_intf_idx;
u8 vf_in_pf;
enum func_type func_type;
u8 mpf_idx;
u8 ppf_idx;
u16 num_irqs; /* max: 2 ^ 15 */
u8 num_aeqs; /* max: 2 ^ 3 */
u8 num_ceqs; /* max: 2 ^ 7 */
u8 num_dma_attr; /* max: 2 ^ 6 */
};
struct hifc_hwif {
u8 __iomem *cfg_regs_base;
u8 __iomem *intr_regs_base;
u64 db_base_phy;
u8 __iomem *db_base;
#if defined(__aarch64__)
void __iomem *dwqe_mapping;
#else
struct io_mapping *dwqe_mapping;
#endif
struct hifc_free_db_area free_db_area;
struct hifc_func_attr attr;
void *pdev;
};
struct hifc_dma_addr_align {
u32 real_size;
void *ori_vaddr;
dma_addr_t ori_paddr;
void *align_vaddr;
dma_addr_t align_paddr;
};
u32 hifc_hwif_read_reg(struct hifc_hwif *hwif, u32 reg);
void hifc_hwif_write_reg(struct hifc_hwif *hwif, u32 reg, u32 val);
void hifc_set_pf_status(struct hifc_hwif *hwif, enum hifc_pf_status status);
enum hifc_pf_status hifc_get_pf_status(struct hifc_hwif *hwif);
enum hifc_doorbell_ctrl
hifc_get_doorbell_ctrl_status(struct hifc_hwif *hwif);
enum hifc_outbound_ctrl
hifc_get_outbound_ctrl_status(struct hifc_hwif *hwif);
void hifc_enable_doorbell(struct hifc_hwif *hwif);
void hifc_disable_doorbell(struct hifc_hwif *hwif);
int hifc_init_hwif(struct hifc_hwdev *hwdev, void *cfg_reg_base,
void *intr_reg_base, u64 db_base_phy,
void *db_base, void *dwqe_mapping);
void hifc_free_hwif(struct hifc_hwdev *hwdev);
int hifc_dma_alloc_coherent_align(void *dev_hdl, u64 size, u64 align,
unsigned flag,
struct hifc_dma_addr_align *mem_align);
void hifc_dma_free_coherent_align(void *dev_hdl,
struct hifc_dma_addr_align *mem_align);
#endif