1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * SolidRun DPU driver for control plane 4 * 5 * Copyright (C) 2022-2023 SolidRun 6 * 7 * Author: Alvaro Karsz <alvaro.karsz@solid-run.com> 8 * 9 */ 10 #ifndef _SNET_VDPA_H_ 11 #define _SNET_VDPA_H_ 12 13 #include <linux/vdpa.h> 14 #include <linux/pci.h> 15 16 #define SNET_NAME_SIZE 256 17 18 #define SNET_ERR(pdev, fmt, ...) dev_err(&(pdev)->dev, "%s"fmt, "snet_vdpa: ", ##__VA_ARGS__) 19 #define SNET_WARN(pdev, fmt, ...) dev_warn(&(pdev)->dev, "%s"fmt, "snet_vdpa: ", ##__VA_ARGS__) 20 #define SNET_INFO(pdev, fmt, ...) dev_info(&(pdev)->dev, "%s"fmt, "snet_vdpa: ", ##__VA_ARGS__) 21 #define SNET_DBG(pdev, fmt, ...) dev_dbg(&(pdev)->dev, "%s"fmt, "snet_vdpa: ", ##__VA_ARGS__) 22 #define SNET_HAS_FEATURE(s, f) ((s)->negotiated_features & BIT_ULL(f)) 23 /* Check if negotiated config version is at least @ver */ 24 #define SNET_CFG_VER(snet, ver) ((snet)->psnet->negotiated_cfg_ver >= (ver)) 25 26 /* VQ struct */ 27 struct snet_vq { 28 /* VQ callback */ 29 struct vdpa_callback cb; 30 /* VQ state received from bus */ 31 struct vdpa_vq_state vq_state; 32 /* desc base address */ 33 u64 desc_area; 34 /* device base address */ 35 u64 device_area; 36 /* driver base address */ 37 u64 driver_area; 38 /* Queue size */ 39 u32 num; 40 /* Serial ID for VQ */ 41 u32 sid; 42 /* is ready flag */ 43 bool ready; 44 /* IRQ number */ 45 u32 irq; 46 /* IRQ index, DPU uses this to parse data from MSI-X table */ 47 u32 irq_idx; 48 /* IRQ name */ 49 char irq_name[SNET_NAME_SIZE]; 50 /* pointer to mapped PCI BAR register used by this VQ to kick */ 51 void __iomem *kick_ptr; 52 }; 53 54 struct snet { 55 /* vdpa device */ 56 struct vdpa_device vdpa; 57 /* Config callback */ 58 struct vdpa_callback cb; 59 /* To lock the control mechanism */ 60 struct mutex ctrl_lock; 61 /* Spinlock to protect critical parts in the control mechanism */ 62 spinlock_t ctrl_spinlock; 63 /* array of virqueues */ 64 struct snet_vq **vqs; 65 /* Used features */ 66 u64 negotiated_features; 67 /* Device serial ID */ 68 u32 sid; 69 /* device status */ 70 u8 status; 71 /* boolean indicating if snet config was passed to the device */ 72 bool dpu_ready; 73 /* IRQ number */ 74 u32 cfg_irq; 75 /* IRQ index, DPU uses this to parse data from MSI-X table */ 76 u32 cfg_irq_idx; 77 /* IRQ name */ 78 char cfg_irq_name[SNET_NAME_SIZE]; 79 /* BAR to access the VF */ 80 void __iomem *bar; 81 /* PCI device */ 82 struct pci_dev *pdev; 83 /* Pointer to snet pdev parent device */ 84 struct psnet *psnet; 85 /* Pointer to snet config device */ 86 struct snet_dev_cfg *cfg; 87 }; 88 89 struct snet_dev_cfg { 90 /* Device ID following VirtIO spec. */ 91 u32 virtio_id; 92 /* Number of VQs for this device */ 93 u32 vq_num; 94 /* Size of every VQ */ 95 u32 vq_size; 96 /* Virtual Function id */ 97 u32 vfid; 98 /* Device features, following VirtIO spec */ 99 u64 features; 100 /* Reserved for future usage */ 101 u32 rsvd[6]; 102 /* VirtIO device specific config size */ 103 u32 cfg_size; 104 /* VirtIO device specific config address */ 105 void __iomem *virtio_cfg; 106 } __packed; 107 108 struct snet_cfg { 109 /* Magic key */ 110 u32 key; 111 /* Size of total config in bytes */ 112 u32 cfg_size; 113 /* Config version */ 114 u32 cfg_ver; 115 /* Number of Virtual Functions to create */ 116 u32 vf_num; 117 /* BAR to use for the VFs */ 118 u32 vf_bar; 119 /* Where should we write the SNET's config */ 120 u32 host_cfg_off; 121 /* Max. allowed size for a SNET's config */ 122 u32 max_size_host_cfg; 123 /* VirtIO config offset in BAR */ 124 u32 virtio_cfg_off; 125 /* Offset in PCI BAR for VQ kicks */ 126 u32 kick_off; 127 /* Offset in PCI BAR for HW monitoring */ 128 u32 hwmon_off; 129 /* Offset in PCI BAR for Control mechanism */ 130 u32 ctrl_off; 131 /* Config general flags - enum snet_cfg_flags */ 132 u32 flags; 133 /* Reserved for future usage */ 134 u32 rsvd[6]; 135 /* Number of snet devices */ 136 u32 devices_num; 137 /* The actual devices */ 138 struct snet_dev_cfg **devs; 139 } __packed; 140 141 /* SolidNET PCIe device, one device per PCIe physical function */ 142 struct psnet { 143 /* PCI BARs */ 144 void __iomem *bars[PCI_STD_NUM_BARS]; 145 /* Negotiated config version */ 146 u32 negotiated_cfg_ver; 147 /* Next IRQ index to use in case when the IRQs are allocated from this device */ 148 u32 next_irq; 149 /* BAR number used to communicate with the device */ 150 u8 barno; 151 /* spinlock to protect data that can be changed by SNET devices */ 152 spinlock_t lock; 153 /* Pointer to the device's config read from BAR */ 154 struct snet_cfg cfg; 155 /* Name of monitor device */ 156 char hwmon_name[SNET_NAME_SIZE]; 157 }; 158 159 enum snet_cfg_flags { 160 /* Create a HWMON device */ 161 SNET_CFG_FLAG_HWMON = BIT(0), 162 /* USE IRQs from the physical function */ 163 SNET_CFG_FLAG_IRQ_PF = BIT(1), 164 }; 165 166 #define PSNET_FLAG_ON(p, f) ((p)->cfg.flags & (f)) 167 168 static inline u32 psnet_read32(struct psnet *psnet, u32 off) 169 { 170 return ioread32(psnet->bars[psnet->barno] + off); 171 } 172 173 static inline u32 snet_read32(struct snet *snet, u32 off) 174 { 175 return ioread32(snet->bar + off); 176 } 177 178 static inline void snet_write32(struct snet *snet, u32 off, u32 val) 179 { 180 iowrite32(val, snet->bar + off); 181 } 182 183 static inline u64 psnet_read64(struct psnet *psnet, u32 off) 184 { 185 u64 val; 186 /* 64bits are written in 2 halves, low part first */ 187 val = (u64)psnet_read32(psnet, off); 188 val |= ((u64)psnet_read32(psnet, off + 4) << 32); 189 return val; 190 } 191 192 static inline void snet_write64(struct snet *snet, u32 off, u64 val) 193 { 194 /* The DPU expects a 64bit integer in 2 halves, the low part first */ 195 snet_write32(snet, off, (u32)val); 196 snet_write32(snet, off + 4, (u32)(val >> 32)); 197 } 198 199 #if IS_ENABLED(CONFIG_HWMON) 200 void psnet_create_hwmon(struct pci_dev *pdev); 201 #endif 202 203 void snet_ctrl_clear(struct snet *snet); 204 int snet_destroy_dev(struct snet *snet); 205 int snet_read_vq_state(struct snet *snet, u16 idx, struct vdpa_vq_state *state); 206 int snet_suspend_dev(struct snet *snet); 207 208 #endif //_SNET_VDPA_H_ 209