brintos

brintos / linux-shallow public Read only

0
0
Text · 5.5 KiB · 36ac285 Raw
210 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * SolidRun DPU driver for control plane4 *5 * Copyright (C) 2022-2023 SolidRun6 *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 25617 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#endif202 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_210