Linux Audio

Check our new training course

Loading...
  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 */
 27struct 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
 54struct 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
 89struct 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
108struct 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 */
142struct 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
159enum 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
168static inline u32 psnet_read32(struct psnet *psnet, u32 off)
169{
170	return ioread32(psnet->bars[psnet->barno] + off);
171}
172
173static inline u32 snet_read32(struct snet *snet, u32 off)
174{
175	return ioread32(snet->bar + off);
176}
177
178static inline void snet_write32(struct snet *snet, u32 off, u32 val)
179{
180	iowrite32(val, snet->bar + off);
181}
182
183static 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
192static 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)
200void psnet_create_hwmon(struct pci_dev *pdev);
201#endif
202
203void snet_ctrl_clear(struct snet *snet);
204int snet_destroy_dev(struct snet *snet);
205int snet_read_vq_state(struct snet *snet, u16 idx, struct vdpa_vq_state *state);
206int snet_suspend_dev(struct snet *snet);
207int snet_resume_dev(struct snet *snet);
208
209#endif //_SNET_VDPA_H_