1102ac20eSJunlong Wang /* SPDX-License-Identifier: BSD-3-Clause 2102ac20eSJunlong Wang * Copyright(c) 2024 ZTE Corporation 3102ac20eSJunlong Wang */ 4102ac20eSJunlong Wang 5102ac20eSJunlong Wang #ifndef ZXDH_PCI_H 6102ac20eSJunlong Wang #define ZXDH_PCI_H 7102ac20eSJunlong Wang 8102ac20eSJunlong Wang #include <stdint.h> 9102ac20eSJunlong Wang #include <stdbool.h> 10102ac20eSJunlong Wang 11102ac20eSJunlong Wang #include <bus_pci_driver.h> 12102ac20eSJunlong Wang 13102ac20eSJunlong Wang #include "zxdh_ethdev.h" 14102ac20eSJunlong Wang 15102ac20eSJunlong Wang enum zxdh_msix_status { 16102ac20eSJunlong Wang ZXDH_MSIX_NONE = 0, 17102ac20eSJunlong Wang ZXDH_MSIX_DISABLED = 1, 18102ac20eSJunlong Wang ZXDH_MSIX_ENABLED = 2 19102ac20eSJunlong Wang }; 20102ac20eSJunlong Wang 213630ac8bSJunlong Wang /* The bit of the ISR which indicates a device has an interrupt. */ 223630ac8bSJunlong Wang #define ZXDH_PCI_ISR_INTR 0x1 233630ac8bSJunlong Wang /* The bit of the ISR which indicates a device configuration change. */ 243630ac8bSJunlong Wang #define ZXDH_PCI_ISR_CONFIG 0x2 253630ac8bSJunlong Wang /* Vector value used to disable MSI for queue. */ 263630ac8bSJunlong Wang #define ZXDH_MSI_NO_VECTOR 0x7F 273630ac8bSJunlong Wang 2870d49e4bSJunlong Wang #define ZXDH_PCI_VRING_ALIGN 4096 2970d49e4bSJunlong Wang 3070d49e4bSJunlong Wang #define ZXDH_NET_F_CSUM 0 /* Host handles pkts w/ partial csum */ 3170d49e4bSJunlong Wang #define ZXDH_NET_F_GUEST_CSUM 1 /* Guest handles pkts w/ partial csum */ 3270d49e4bSJunlong Wang #define ZXDH_NET_F_MTU 3 /* Initial MTU advice. */ 33102ac20eSJunlong Wang #define ZXDH_NET_F_MAC 5 /* Host has given MAC address. */ 3470d49e4bSJunlong Wang #define ZXDH_NET_F_GUEST_TSO4 7 /* Guest can handle TSOv4 in. */ 3570d49e4bSJunlong Wang #define ZXDH_NET_F_GUEST_TSO6 8 /* Guest can handle TSOv6 in. */ 3670d49e4bSJunlong Wang #define ZXDH_NET_F_GUEST_ECN 9 /* Guest can handle TSO[6] w/ ECN in. */ 3770d49e4bSJunlong Wang #define ZXDH_NET_F_GUEST_UFO 10 /* Guest can handle UFO in. */ 3870d49e4bSJunlong Wang 3970d49e4bSJunlong Wang #define ZXDH_NET_F_HOST_UFO 14 /* Host can handle UFO in. */ 4070d49e4bSJunlong Wang #define ZXDH_NET_F_HOST_TSO4 11 /* Host can handle TSOv4 in. */ 4170d49e4bSJunlong Wang #define ZXDH_NET_F_HOST_TSO6 12 /* Host can handle TSOv6 in. */ 42102ac20eSJunlong Wang #define ZXDH_NET_F_MRG_RXBUF 15 /* Host can merge receive buffers. */ 43102ac20eSJunlong Wang #define ZXDH_NET_F_STATUS 16 /* zxdh_net_config.status available */ 44102ac20eSJunlong Wang #define ZXDH_NET_F_MQ 22 /* Device supports Receive Flow Steering */ 45102ac20eSJunlong Wang #define ZXDH_F_ANY_LAYOUT 27 /* Can the device handle any descriptor layout */ 46102ac20eSJunlong Wang #define ZXDH_F_VERSION_1 32 47102ac20eSJunlong Wang #define ZXDH_F_RING_PACKED 34 48102ac20eSJunlong Wang #define ZXDH_F_IN_ORDER 35 49102ac20eSJunlong Wang #define ZXDH_F_NOTIFICATION_DATA 38 50102ac20eSJunlong Wang 51102ac20eSJunlong Wang #define ZXDH_PCI_CAP_COMMON_CFG 1 /* Common configuration */ 52102ac20eSJunlong Wang #define ZXDH_PCI_CAP_NOTIFY_CFG 2 /* Notifications */ 53102ac20eSJunlong Wang #define ZXDH_PCI_CAP_ISR_CFG 3 /* ISR Status */ 54102ac20eSJunlong Wang #define ZXDH_PCI_CAP_DEVICE_CFG 4 /* Device specific configuration */ 55102ac20eSJunlong Wang #define ZXDH_PCI_CAP_PCI_CFG 5 /* PCI configuration access */ 56102ac20eSJunlong Wang 57102ac20eSJunlong Wang /* Status byte for guest to report progress. */ 58102ac20eSJunlong Wang #define ZXDH_CONFIG_STATUS_RESET 0x00 59102ac20eSJunlong Wang #define ZXDH_CONFIG_STATUS_ACK 0x01 60102ac20eSJunlong Wang #define ZXDH_CONFIG_STATUS_DRIVER 0x02 61102ac20eSJunlong Wang #define ZXDH_CONFIG_STATUS_DRIVER_OK 0x04 62102ac20eSJunlong Wang #define ZXDH_CONFIG_STATUS_FEATURES_OK 0x08 63102ac20eSJunlong Wang #define ZXDH_CONFIG_STATUS_DEV_NEED_RESET 0x40 64102ac20eSJunlong Wang #define ZXDH_CONFIG_STATUS_FAILED 0x80 6570d49e4bSJunlong Wang #define ZXDH_PCI_QUEUE_ADDR_SHIFT 12 66102ac20eSJunlong Wang 67*e7750639SAndre Muezerie struct __rte_packed_begin zxdh_net_config { 68102ac20eSJunlong Wang /* The config defining mac address (if ZXDH_NET_F_MAC) */ 69102ac20eSJunlong Wang uint8_t mac[RTE_ETHER_ADDR_LEN]; 70102ac20eSJunlong Wang /* See ZXDH_NET_F_STATUS and ZXDH_NET_S_* above */ 71102ac20eSJunlong Wang uint16_t status; 72102ac20eSJunlong Wang uint16_t max_virtqueue_pairs; 73102ac20eSJunlong Wang uint16_t mtu; 74102ac20eSJunlong Wang uint32_t speed; 75102ac20eSJunlong Wang uint8_t duplex; 76*e7750639SAndre Muezerie } __rte_packed_end; 77102ac20eSJunlong Wang 78102ac20eSJunlong Wang /* This is the PCI capability header: */ 79102ac20eSJunlong Wang struct zxdh_pci_cap { 80102ac20eSJunlong Wang uint8_t cap_vndr; /* Generic PCI field: PCI_CAP_ID_VNDR */ 81102ac20eSJunlong Wang uint8_t cap_next; /* Generic PCI field: next ptr. */ 82102ac20eSJunlong Wang uint8_t cap_len; /* Generic PCI field: capability length */ 83102ac20eSJunlong Wang uint8_t cfg_type; /* Identifies the structure. */ 84102ac20eSJunlong Wang uint8_t bar; /* Where to find it. */ 85102ac20eSJunlong Wang uint8_t padding[3]; /* Pad to full dword. */ 86102ac20eSJunlong Wang uint32_t offset; /* Offset within bar. */ 87102ac20eSJunlong Wang uint32_t length; /* Length of the structure, in bytes. */ 88102ac20eSJunlong Wang }; 89102ac20eSJunlong Wang 90102ac20eSJunlong Wang /* Fields in ZXDH_PCI_CAP_COMMON_CFG: */ 91102ac20eSJunlong Wang struct zxdh_pci_common_cfg { 92102ac20eSJunlong Wang /* About the whole device. */ 93102ac20eSJunlong Wang uint32_t device_feature_select; /* read-write */ 94102ac20eSJunlong Wang uint32_t device_feature; /* read-only */ 95102ac20eSJunlong Wang uint32_t guest_feature_select; /* read-write */ 96102ac20eSJunlong Wang uint32_t guest_feature; /* read-write */ 97102ac20eSJunlong Wang uint16_t msix_config; /* read-write */ 98102ac20eSJunlong Wang uint16_t num_queues; /* read-only */ 99102ac20eSJunlong Wang uint8_t device_status; /* read-write */ 100102ac20eSJunlong Wang uint8_t config_generation; /* read-only */ 101102ac20eSJunlong Wang 102102ac20eSJunlong Wang /* About a specific virtqueue. */ 103102ac20eSJunlong Wang uint16_t queue_select; /* read-write */ 104102ac20eSJunlong Wang uint16_t queue_size; /* read-write, power of 2. */ 105102ac20eSJunlong Wang uint16_t queue_msix_vector; /* read-write */ 106102ac20eSJunlong Wang uint16_t queue_enable; /* read-write */ 107102ac20eSJunlong Wang uint16_t queue_notify_off; /* read-only */ 108102ac20eSJunlong Wang uint32_t queue_desc_lo; /* read-write */ 109102ac20eSJunlong Wang uint32_t queue_desc_hi; /* read-write */ 110102ac20eSJunlong Wang uint32_t queue_avail_lo; /* read-write */ 111102ac20eSJunlong Wang uint32_t queue_avail_hi; /* read-write */ 112102ac20eSJunlong Wang uint32_t queue_used_lo; /* read-write */ 113102ac20eSJunlong Wang uint32_t queue_used_hi; /* read-write */ 114102ac20eSJunlong Wang }; 115102ac20eSJunlong Wang 11670d49e4bSJunlong Wang static inline int32_t 11770d49e4bSJunlong Wang vtpci_with_feature(struct zxdh_hw *hw, uint64_t bit) 118102ac20eSJunlong Wang { 119102ac20eSJunlong Wang return (hw->guest_features & (1ULL << bit)) != 0; 120102ac20eSJunlong Wang } 121102ac20eSJunlong Wang 12270d49e4bSJunlong Wang static inline int32_t 12370d49e4bSJunlong Wang vtpci_packed_queue(struct zxdh_hw *hw) 12470d49e4bSJunlong Wang { 12570d49e4bSJunlong Wang return vtpci_with_feature(hw, ZXDH_F_RING_PACKED); 12670d49e4bSJunlong Wang } 12770d49e4bSJunlong Wang 128102ac20eSJunlong Wang struct zxdh_pci_ops { 129102ac20eSJunlong Wang void (*read_dev_cfg)(struct zxdh_hw *hw, size_t offset, void *dst, int32_t len); 130102ac20eSJunlong Wang void (*write_dev_cfg)(struct zxdh_hw *hw, size_t offset, const void *src, int32_t len); 131102ac20eSJunlong Wang 132102ac20eSJunlong Wang uint8_t (*get_status)(struct zxdh_hw *hw); 133102ac20eSJunlong Wang void (*set_status)(struct zxdh_hw *hw, uint8_t status); 134102ac20eSJunlong Wang 135102ac20eSJunlong Wang uint64_t (*get_features)(struct zxdh_hw *hw); 136102ac20eSJunlong Wang void (*set_features)(struct zxdh_hw *hw, uint64_t features); 1373630ac8bSJunlong Wang uint16_t (*set_queue_irq)(struct zxdh_hw *hw, struct zxdh_virtqueue *vq, uint16_t vec); 1383630ac8bSJunlong Wang uint16_t (*set_config_irq)(struct zxdh_hw *hw, uint16_t vec); 1393630ac8bSJunlong Wang uint8_t (*get_isr)(struct zxdh_hw *hw); 14070d49e4bSJunlong Wang uint16_t (*get_queue_num)(struct zxdh_hw *hw, uint16_t queue_id); 14170d49e4bSJunlong Wang void (*set_queue_num)(struct zxdh_hw *hw, uint16_t queue_id, uint16_t vq_size); 14270d49e4bSJunlong Wang 14370d49e4bSJunlong Wang int32_t (*setup_queue)(struct zxdh_hw *hw, struct zxdh_virtqueue *vq); 14470d49e4bSJunlong Wang void (*del_queue)(struct zxdh_hw *hw, struct zxdh_virtqueue *vq); 145102ac20eSJunlong Wang }; 146102ac20eSJunlong Wang 147102ac20eSJunlong Wang struct zxdh_hw_internal { 148102ac20eSJunlong Wang const struct zxdh_pci_ops *zxdh_vtpci_ops; 149102ac20eSJunlong Wang }; 150102ac20eSJunlong Wang 151102ac20eSJunlong Wang #define ZXDH_VTPCI_OPS(hw) (zxdh_hw_internal[(hw)->port_id].zxdh_vtpci_ops) 152102ac20eSJunlong Wang 153102ac20eSJunlong Wang extern struct zxdh_hw_internal zxdh_hw_internal[RTE_MAX_ETHPORTS]; 154102ac20eSJunlong Wang extern const struct zxdh_pci_ops zxdh_dev_pci_ops; 155102ac20eSJunlong Wang 156102ac20eSJunlong Wang void zxdh_pci_reset(struct zxdh_hw *hw); 157102ac20eSJunlong Wang void zxdh_pci_read_dev_config(struct zxdh_hw *hw, size_t offset, 158102ac20eSJunlong Wang void *dst, int32_t length); 159102ac20eSJunlong Wang 160102ac20eSJunlong Wang int32_t zxdh_read_pci_caps(struct rte_pci_device *dev, struct zxdh_hw *hw); 161102ac20eSJunlong Wang void zxdh_get_pci_dev_config(struct zxdh_hw *hw); 162102ac20eSJunlong Wang 163102ac20eSJunlong Wang uint16_t zxdh_pci_get_features(struct zxdh_hw *hw); 164102ac20eSJunlong Wang enum zxdh_msix_status zxdh_pci_msix_detect(struct rte_pci_device *dev); 1653630ac8bSJunlong Wang uint8_t zxdh_pci_isr(struct zxdh_hw *hw); 16670d49e4bSJunlong Wang void zxdh_pci_reinit_complete(struct zxdh_hw *hw); 16770d49e4bSJunlong Wang void zxdh_pci_set_status(struct zxdh_hw *hw, uint8_t status); 168102ac20eSJunlong Wang 169102ac20eSJunlong Wang #endif /* ZXDH_PCI_H */ 170