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