GNU Linux-libre 6.8.7-gnu
[releases.git] / drivers / vdpa / solidrun / snet_vdpa.h
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 int snet_resume_dev(struct snet *snet);
208
209 #endif //_SNET_VDPA_H_