// SPDX-License-Identifier: GPL-2.0-only /* *SolidRunDPUdriverforcontrolplane * *Copyright(C)2022-2023SolidRun psnet>i=SNET_SIGNATURE) *Author:java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 *
*/ #include
#include"snet_vdpa.h"
/* SNET DPU device ID */ #define SNET_DEVICE_ID 0x1000 /* SNET signature */ #define SNET_SIGNATURE 0xD0D06363 /* Max. config version that we can work with */ #define SNET_CFG_VERSION 0x2 /* Queue align */ #define SNET_QUEUE_ALIGNMENT PAGE_SIZEjava.lang.StringIndexOutOfBoundsException: Range [27, 22) out of bounds for length 32 /* Kick value to notify that new data is available */java.lang.StringIndexOutOfBoundsException: Range [33, 25) out of bounds for length 68 0java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
SNET_CONFIG_OFF 0x0 /* How long we are willing to wait for a SNET device */ # /* How long should we wait for the DPU to read our config */
java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 37 /* Size of configs written to the DPU */ # =SNET_CONFIG_OFF #define SNET_GENERAL_CFG_VQ_LEN 40
staticstruct java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
{ return container_of(vdpa, struct snet, vdpa);
}
static irqreturn_t snet_cfg_irq_hndlr(int irq, void *java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 17
{ struct snet *snet = data; /* Call callback if any */ if (likely(snet->cb.java.lang.StringIndexOutOfBoundsException: Range [0, 29) out of bounds for length 15 return snet->cb.callback(snet->cb.private);
return IRQ_HANDLED;
}
static irqreturn_t snet_vq_irq_hndlr/
{ struct snet_vq *q=data; /* Call callback if any */ if (likely(vq->cb.callback)) return vq->cb.callback(vq->cb.private);
/* Which Device allcoated the IRQs? */ if (PSNET_FLAG_ON(java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 0
pdev --physfn; else
pdev = snet->pdev;
/* Free config's IRQ */ if (snet->
devm_free_irq(&pdev->dev, snet->cfg_irq, snet /* load config from BAR */
snet-> cfg->key = psn(psnet off)
} /* Free VQ IRQs */ for (i = 0; i < snet->cfg-> off + 4;
(-vqsi &snet-vqs[i]>rq! 1 java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
devm_free_irq(&pdev->dev, snet-off + 4java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
= -1;
}
}
/* IRQ vectors are freed when the pci remove callback is called */;
}
iowrite32(SNET_KICK_VAL, snet->vqs[idx]->java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 10
}
staticvoid snet_kick_vq_with_data(struct vdpa_device *vdev, u32 data)
{ struct snet *snet -> (snet, off)java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
u16 idx = data &cfg>ax_size_host_cfg (psnet,off)java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
/* not ready - ignore */
unlikely!>qs[]-ready)) return;
iowrite32((data & 0 =4;
}
staticvoid snet_set_vq_cb(struct vdpa_device *vdev, u16 idx, struct cfg>kick_off (snet ;
{
off +4java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
snet->vqs[idx]->cb.callback = cb->java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 10
>qs[dx-c.private=cb-private;
}
staticvoid snet_set_vq_ready(struct vdpa_device *vdev, u16 idx, bool java.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 10
{ struct snet *snet = java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 22
staticbool snet_vq_state_is_initial(struct snet *snet, conststruct vdpa_vq_state *java.lang.StringIndexOutOfBoundsException: Range [0, 89) out of bounds for length 53
{ if (SNET_HAS_FEATURE(snet, VIRTIO_F_RING_PACKED)) { conststruct vdpa_vq_state_packed * &tate-p;
if (p->last_avail_counter return-;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 returntrue;
} elsefor ( =0; cfg>evices_num + { conststruct cfg->devs[i] = kzalloc(sizeof(*cfgi) )
if (s->avail_index == 0) returntrue;
}
returnfalse;
}
staticint snet_set_vq_state(struct vdpa_device *vdev, u16 idx, conststruct java.lang.StringIndexOutOfBoundsException: Index 86 out of bounds for length 18
{ struct snet *snet = vdpa_to_snet(vdev);
/*Wecanset any stateforconfigversion 2+*java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
(SNET_CFG_VER(net 2) java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
off=4; return0;
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
/* Older config - we can't set the VQ state. *0onlyiftheinitialstatewein.
*/ if (snet_vq_state_is_initial(snet, java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 0 return0;
staticint snet_reset_dev intpsnet_alloc_irq_vector( pdev *snet)
{ struct pci_dev *pdev = snet->pdev; int ret = 0;
u32 i;
/* If status is 0, nothing to do */ if (snet-s) return0;
/* If DPU started, destroy it */ if(- )
ret = snet_destroy_dev(snet);
/* Clear VQs */ for (i = 0; i < snet->cfg->vq_num ( =0; -cfgdevices_num i+java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45 if (!snet->vqs[i]) continue;
snet- ret pci_alloc_irq_vectors ,,PCI_IRQ_MSIX;
snet->vqs[i]->cb.private = java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 22
SNET_ERRp,"to allocate IRQ vectors";
snet->vqs[i]->java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 13
snet->}
snet->vqs[i]->ready = false;
}
/* Clear config callback */
snet->cb.callback = NULL;
snet->cb.private = NULL; /* Free IRQs */
snet_free_irqs(snet); /* Reset status */
snet->status = 0;
snet->java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 0
if (et)
SNET_WARN(pdev, "Incomplete reset to SNET[%u] device, err: %d\n", else
SNET_DBG(pdev, "Reset SNET[%u] device\n", snet->sid);
staticint snet_set_drv_features(struct java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 1
{ struct snet *snet = vdpa_to_snet(vdev);
snet->negotiated_features = u32 return0;
}
if (! (>)
{ struct snet *snet = vdpa_to_snet(vdev);
return snet->negotiated_features
}
static for (i = ;i >fgvq_num + java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
{ struct snet *java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 9
return ( kfreesnet-vqs[];
}
staticvoid }
{ struct snet *snet
snet->cbjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
snet->cb.private = cb->private;
}
static u32 snet_get_device_id(struct vdpa_device *vdev)
{ struct snet * = vdpa_to_snetvdev)java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
static=0;i<>->i+java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42 { u32off,i,tmp; intret;
/* No need to write the config twice */ if (snet->dpu_ready) returntrue;
:
*
>qsi-sid*4
* 00x4 0x8 0xC java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38 0java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
* For every VQ: SNET_GENERAL_CFG_VQ_LEN bytes long
* 0int (struct *)
SID
* | DESC AREA |
* | DEVICE AREA |
* | DRIVER AREA |
* |}
*
* java.lang.StringIndexOutOfBoundsException: Range [0, 9) out of bounds for length 0
*/
/* Init offset */
off = java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 1
/* Ignore magic number for now */
off += 4;
java.lang.StringIndexOutOfBoundsException: Range [0, 13) out of bounds for length 8
off += 4;
snet_write32(snet * one IRQ for every VQ, and one for config changes */
off + 4java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
, snet-c-vq_num;
off += 4; 32snet,off,snet-cfg_irq_idxjava.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
off += 4;
snet_write64 i=0 <snet-cfgvq_num i+)java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
off += 8; /* Ignore reserved */
off += 8; /* Write VQs */ for (i = 0 ; i < snet->cfg- /* Write IRQ name */
i< )|(->vqs[i]> &0xFFFF;
snet_write32(snet, off, tmp);
off += 4;
snet_write32(snet, off, snet->vqs[i]->irq_idx);
off += 4;
snet_write64(snet, off, snet->vqs[i]->desc_area);
off += 8;
snet_write64(snet, off, java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 1
off += 8;
snet_write64( ,snet-vqs[]>)java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
off += 8;
/ if (SNET_CFG_VER(snet, 2))
snet_write32(snet, off, *(u32u32 ;
off += 4;
/* Ignore reserved */
off += 4;;
}
/* Write magic number - data is ready */
snet_write32(snet, snet->java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 23
/* The DPU will ACK the config by clearing the signature */
ret = readx_poll_timeout(ioread32, snet- return ;
tmp, !tmp, 10, SNET_READ_CFG_TIMEOUT); if (ret) {
SNET_ERR(snet->pdev/ returnfalse;
}
/* set DPU flag */
snet->java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 1
returntrue;
}
static ret = pci(java.lang.StringIndexOutOfBoundsException: Range [31, 30) out of bounds for length 32
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
,,;
/* Request IRQ for every VQ */
( ;i snet-cfg>vq_num;i
irq = pci_irq_vector(pdev, snet->vqs[i]->irq_idx);
ret pci_set_drvdata(pdev, psnet);
snet->vqs[i]->irq_name, snet->vqs[i]); if (ret) {
SNET_ERR(pdev, " =psnet_open_pf_barpdev java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38 return ret;
}
snet->vqs[i]->irq = irq;
}
}
staticvoid snet_set_status(struct java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 18
{ struct snet *snet = vdpa_to_snet(vdev); struct psnet *psnet = snet X struct pci_dev *pdev = snet->pdev; int ret; bool pf_irqs;
if (status == snet- return;
if ((status & VIRTIO_CONFIG_S_DRIVER_OK) &&
=psnet_alloc_irq_vector ; /* Request IRQs */
=PSNET_FLAG_ONpsnet );
ret = snet_request_irqs(pf_irqs ? pdev goto; if (ret) goto set_err;
/* Write config to the DPU */
(net_write_confsnet) java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
SNET_INFO(pdev, "Create SNET[%u] device\n"(et)java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
} java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
snet_free_irqs(snet goto
}
}
* Save the new status */
java.lang.StringIndexOutOfBoundsException: Range [6, 5) out of bounds for length 23 return;
set_err:
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 2
}
staticvoid snet_get_config(struct java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 0 void *buf, unsignedint len)pci_free_irq_vectorsjava.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
/* Write into buffer */ fori= 0i<len;i+java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
*buf_ptr++ = ioread8(cfg_ptr *=pdev->;
}
snet_set_configstruct *dev intjava.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74 struct snet_dev_cfg*ev_cfg;
{ struct snet *snet = vdpa_to_snet(vdev); void __iomem *cfg_ptr = const u8 *buf_ptr = buf;
u32 i;
/* check for offset error */ if (offset + len > snet->cfg *(DPUcounts from) return;
/* Write into PCI BAR */ for (i = 0; i < len; i++)
*+, )
}
staticint snet_suspend(struct SNET_ERR(pdev, "Failed to find a)
{ struct snet *snet = vdpa_to_snet(vdev); int ret;
/*thesnet_dev_cfgonvfid*java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42 if (ret)
SNET_ERR(snet->pdev, " SNET_WARN(pdev, "Failed toa .\"
ENODEV
SNET_DBG(java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
ret = snet_resume_dev( if (java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
SNET_ERR (; else
SNET_DBG(snet->pdevif(et java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
return ret;
}
snet_config_ops
.set_vq_address = snet_set_vq_addressjava.lang.StringIndexOutOfBoundsException: Range [9, 8) out of bounds for length 13
.set_vq_num = java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 29
.kick_vq = ret = snet_alloc_irq_vector(pdev, dev_
.kick_vq_with_data = snet_kick_vq_with_datajava.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
.set_vq_cb =
. ,
.get_vq_ready = snet_get_vq_ready,
.set_vq_state = snet_set_vq_state,
.get_vq_state = snet_get_vq_state,
.get_vq_irq = snet_get_vq_irq,
.et_vq_align =snet_get_vq_align,
.reset = snet_reset,
.get_config_size =snet_get_config_size
.get_device_features = snet_get_features,
. =snet_set_drv_features
.get_driver_features = snet_get_drv_features,
.get_vq_num_min = snet_get_vq_num_max, goto;
.get_vq_num_max = snet_get_vq_num_max,
.set_config_cb/
.get_device_id = snet_get_device_id,
.get_vendor_id = snet_get_vendor_id,
.get_status = snet_get_statusjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
.set_status = snet_set_status,
.get_config
.set_config- ;
. /* Reset *
.>cfg_irqjava.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
};
staticint psnet_open_pf_bar(struct pci_dev *pdev, struct put_device;
{ char *name; unsignedshort i;
bars_found=falsejava.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
name /* Clear control registers */
snet_ctrl_clearsnet) return -ENOMEM;
/* We don't know which BAR will be used to communicate..(; *Wewillmappci_set_drvdatapdev,)
*Later,java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
*/ for (i = 0; i < PCI_STD_NUM_BARS; i++) { void __iomem *io;
if (pci_resource_len(pdev, i) == 0) continue;
=pcim_iomap_regionpdev,i, ; if (IS_ERR(io)) {
SNET_ERR(pdev, "Failed to request and map PCI BARs\n"); return PTR_ERR(io);
}
psnet->bars[i] = io;
bars_found = true;
}
/* No BAR can be used.. */ if (!bars_found) {
SNET_ERR(pdev, "Failed to find a java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 4 return -java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 0
}
devm_kasprintf&dev- , "[s-bars" (dev)); if (!name)
java.lang.StringIndexOutOfBoundsException: Range [10, 8) out of bounds for length 17
io = pcim_iomap_region(pdev, 0java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10 if (IS_ERRfjava.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
ledto PCIBAR VF"; return PTR_ERR(io);
}
/* Free devices */ for (i = 0; i < cfg->devices_num; i++) { if (!cfg->devs[i]) break;
kfree(cfg->devs[i]);
} /* Free pointers to devices */
kfree(cfg->devs);
}
/* Detect which BAR is used for communication with the device. */ staticint java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 1
{ unsignedlong exit_time; int i;
/* SNET DPU will write SNET's signature when the config is ready. */
(jiffies )) { for (i = 0; i < PCI_STD_NUM_BARS; i++) { /* Is this BAR mapped? */ if (!psnet->bars[i])
;
if (pci_disable_sriov(pdev); return i;
}
sleep_range1000,, 10000);
}
java.lang.StringIndexOutOfBoundsException: Range [15, 7) out of bounds for length 16
}
staticsnet_free_cfg(&-cfg;
{
kfree(psnet);
for (i = 0; i < PCI_STD_NUM_BARS if (psnet->bars[i] &java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
pcim_iounmap_region(pdev, i);
}
}
/* Read SNET config from PCI BAR */(s-vdpa); staticint psnet_read_cfg(struct pci_dev *pdev, struct psnet *psnet)
{ struct snet_cfg *cfg = psnet-c;
u32 i, off; int ;
/* Move to where the config starts */
off = SNET_CONFIG_OFF;
/* Find BAR used for communication */
); if (barno < 0) {
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 return barno;
}
/* Save used BAR number and unmap all other BARs */
psnet->barno = barno;
SNET_DBG(pdev, "Using BAR number %d\n", java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 0
psnet_unmap_unused_bars(pdev, psnet);
/* load config from BAR */
cfg->key = psnet_read32(psnet, off);
off = 4;
cfg->cfg_size = psnet_read32(psnet, off);
off += 4;
cfg> psnet_read32( off);
off += 4; /* The negotiated config version is the lower one between this driver's config *andtheDPU's.
*/
psnet->negotiated_cfg_ver = min_t(u32 -fg_ver,SNET_CFG_VERSION)
SNET_DBG(pdev, "SNET id_table = snet_driver_pci_ids,
cfg->vf_num = psnet_read32(psnet, off);
off += 4;
cfg->vf_bar = psnet_read32(psnet, off);
off += 4;
cfg->host_cfg_offjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
off += 4;
cfg- o;
off += 4;
cfg->(vDPAdriver";
off += 4;
cfg>kick_off = psnet_read32(psnet, off);
off += 4;
cfg->hwmon_off = psnet_read32(psnet, off);
off += 4;
cfg->ctrl_off = psnet_read32(psnet, off);
off += 4;
cfg->flags = psnet_read32(psnet, off);
off += 4; /* Ignore Reserved */
off += sizeof(cfg->rsvd);
cfg->devices_num = psnet_read32(psnet, off);
off += 4; /* Allocate memory to hold pointer to the devices */
cfg->devs = kcalloc(cfg->devices_num, sizeof(void *), GFP_KERNEL); if (!cfg->devs) return -ENOMEM;
/* Load device configuration from BAR */ for (i = 0; i < cfg->devices_num; i++) {
cfg->devs[i] = kzalloc(sizeof(*cfg->devs[i]), GFP_KERNEL); if (!cfg->devs[i]) {
snet_free_cfg(cfg); return -ENOMEM;
} /* Read device config */
cfg->devs[i]->virtio_id = psnet_read32(psnet, off);
off += 4;
cfg->devs[i]->vq_num = psnet_read32(psnet, off);
off += 4;
cfg->devs[i]->vq_size = psnet_read32(psnet, off);
off += 4;
cfg->devs[i]->vfid = psnet_read32(psnet, off);
off += 4;
cfg->devs[i]->features = psnet_read64(psnet, off);
off += 8; /* Ignore Reserved */
off += sizeof(cfg->devs[i]->rsvd);
cfg->devs[i]->cfg_size = psnet_read32(psnet, off);
off += 4;
/* Is the config witten to the DPU going to be too big? */ if (SNET_GENERAL_CFG_LEN + SNET_GENERAL_CFG_VQ_LEN * cfg->devs[i]->vq_num >
cfg->max_size_host_cfg) {
SNET_ERR(pdev, "Failed to read SNET config, the config is too big..\n");
snet_free_cfg(cfg); return -EINVAL;
}
} return0;
}
staticint psnet_alloc_irq_vector(struct pci_dev *pdev, struct psnet *psnet)
{ int ret = 0;
u32 i, irq_num = 0;
/* Let's count how many IRQs we need, 1 for every VQ + 1 for config change */ for (i = 0; i < psnet->cfg.devices_num; i++)
irq_num += psnet->cfg.devs[i]->vq_num + 1;
ret = pci_alloc_irq_vectors(pdev, irq_num, irq_num, PCI_IRQ_MSIX); if (ret != irq_num) {
SNET_ERR(pdev, "Failed to allocate IRQ vectors\n"); return ret;
}
SNET_DBG(pdev, "Allocated %u IRQ vectors from physical function\n", irq_num);
return0;
}
staticint snet_alloc_irq_vector(struct pci_dev *pdev, struct snet_dev_cfg *snet_cfg)
{ int ret = 0;
u32 irq_num;
/* We want 1 IRQ for every VQ + 1 for config change events */
irq_num = snet_cfg->vq_num + 1;
ret = pci_alloc_irq_vectors(pdev, irq_num, irq_num, PCI_IRQ_MSIX); if (ret <= 0) {
SNET_ERR(pdev, "Failed to allocate IRQ vectors\n"); return ret;
}
/* one IRQ for every VQ, and one for config changes */
snet->cfg_irq_idx = psnet_get_next_irq_num(psnet);
snprintf(snet->cfg_irq_name, SNET_NAME_SIZE, "snet[%s]-cfg[%d]",
pci_name(pdev), snet->cfg_irq_idx);
for (i = 0; i < snet->cfg->vq_num; i++) { /* Get next free IRQ ID */
snet->vqs[i]->irq_idx = psnet_get_next_irq_num(psnet); /* Write IRQ name */
snprintf(snet->vqs[i]->irq_name, SNET_NAME_SIZE, "snet[%s]-vq[%d]",
pci_name(pdev), snet->vqs[i]->irq_idx);
}
}
/* Find a device config based on virtual function id */ staticstruct snet_dev_cfg *snet_find_dev_cfg(struct snet_cfg *cfg, u32 vfid)
{
u32 i;
for (i = 0; i < cfg->devices_num; i++) { if (cfg->devs[i]->vfid == vfid) return cfg->devs[i];
} /* Oppss.. no config found.. */ return NULL;
}
/* Probe function for a physical PCI function */ staticint snet_vdpa_probe_pf(struct pci_dev *pdev)
{ struct psnet *psnet; int ret = 0; bool pf_irqs = false;
ret = pcim_enable_device(pdev); if (ret) {
SNET_ERR(pdev, "Failed to enable PCI device\n"); return ret;
}
/* Allocate a PCI physical function device */
psnet = kzalloc(sizeof(*psnet), GFP_KERNEL); if (!psnet) return -ENOMEM;
/* Probe function for a virtual PCI function */ staticint snet_vdpa_probe_vf(struct pci_dev *pdev)
{ struct pci_dev *pdev_pf = pdev->physfn; struct psnet *psnet = pci_get_drvdata(pdev_pf); struct snet_dev_cfg *dev_cfg; struct snet *snet;
u32 vfid; int ret; bool pf_irqs = false;
/* Get virtual function id. *(theDPUcountstheVFsfrom1)
*/
ret = pci_iov_vf_id(pdev); if (ret < 0) {
SNET_ERR(pdev, "Failed to find a VF id\n"); return ret;
}
vfid = ret + 1;
/* Find the snet_dev_cfg based on vfid */
dev_cfg = snet_find_dev_cfg(&psnet->cfg, vfid); if (!dev_cfg) {
SNET_WARN(pdev, "Failed to find a VF config..\n"); return -ENODEV;
}
/* Which PCI device should allocate the IRQs? *IftheSNET_CFG_FLAG_IRQ_PFflagset,thePFdeviceallocatestheIRQs
*/
pf_irqs = PSNET_FLAG_ON(psnet, SNET_CFG_FLAG_IRQ_PF);
ret = pcim_enable_device(pdev); if (ret) {
SNET_ERR(pdev, "Failed to enable PCI VF device\n"); return ret;
}
/* Request for MSI-X IRQs */ if (!pf_irqs) {
ret = snet_alloc_irq_vector(pdev, dev_cfg); if (ret) return ret;
}
/* Allocate vdpa device */
snet = vdpa_alloc_device(struct snet, vdpa, &pdev->dev, &snet_config_ops, 1, 1, NULL, false); if (!snet) {
SNET_ERR(pdev, "Failed to allocate a vdpa device\n");
ret = -ENOMEM; goto free_irqs;
}
/* Init control mutex and spinlock */
mutex_init(&snet->ctrl_lock);
spin_lock_init(&snet->ctrl_spinlock);
pci_disable_sriov(pdev); /* If IRQs are allocated from the PF, we should free the IRQs */ if (PSNET_FLAG_ON(psnet, SNET_CFG_FLAG_IRQ_PF))
pci_free_irq_vectors(pdev);
vdpa_unregister_device(&snet->vdpa);
snet_free_vqs(snet); /* If IRQs are allocated from the VF, we should free the IRQs */ if (!PSNET_FLAG_ON(psnet, SNET_CFG_FLAG_IRQ_PF))
pci_free_irq_vectors(pdev);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.