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