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
psnet_read32(struct psnet * psnet,u32 off)159 static inline u32 psnet_read32(struct psnet *psnet, u32 off)
160 {
161 return ioread32(psnet->bars[psnet->barno] + off);
162 }
163
snet_read32(struct snet * snet,u32 off)164 static inline u32 snet_read32(struct snet *snet, u32 off)
165 {
166 return ioread32(snet->bar + off);
167 }
168
snet_write32(struct snet * snet,u32 off,u32 val)169 static inline void snet_write32(struct snet *snet, u32 off, u32 val)
170 {
171 iowrite32(val, snet->bar + off);
172 }
173
psnet_read64(struct psnet * psnet,u32 off)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
snet_write64(struct snet * snet,u32 off,u64 val)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