psnet
return snet->bar + snet->psnet->cfg.ctrl_off;
snet_hwmon_read_reg(psnet, SNET_MON_TMP0_MAX_OFF, val);
snet_hwmon_read_reg(psnet, SNET_MON_TMP0_CRIT_OFF, val);
snet_hwmon_read_reg(psnet, SNET_MON_TMP1_CRIT_OFF, val);
struct psnet *psnet = pci_get_drvdata(pdev);
snprintf(psnet->hwmon_name, SNET_NAME_SIZE, "snet_%s", pci_name(pdev));
hwmon = devm_hwmon_device_register_with_info(&pdev->dev, psnet->hwmon_name, psnet,
static void snet_hwmon_read_reg(struct psnet *psnet, u32 reg, long *out)
*out = psnet_read64(psnet, psnet->cfg.hwmon_off + reg);
struct psnet *psnet = dev_get_drvdata(dev);
snet_hwmon_read_reg(psnet, SNET_MON_VOLT_LCRIT_OFF, val);
snet_hwmon_read_reg(psnet, SNET_MON_VOLT_CRIT_OFF, val);
snet_hwmon_read_reg(psnet, SNET_MON_VOLT_IN_OFF, val);
snet_hwmon_read_reg(psnet, SNET_MON_PWR_IN_OFF, val);
snet_hwmon_read_reg(psnet, SNET_MON_CURR_IN_OFF, val);
snet_hwmon_read_reg(psnet, SNET_MON_CURR_MAX_OFF, val);
snet_hwmon_read_reg(psnet, SNET_MON_CURR_CRIT_OFF, val);
snet_hwmon_read_reg(psnet, SNET_MON_TMP0_IN_OFF, val);
snet_hwmon_read_reg(psnet, SNET_MON_TMP1_IN_OFF, val);
snet->psnet = psnet;
snet->cfg->virtio_cfg = snet->bar + snet->psnet->cfg.virtio_cfg_off;
struct psnet *psnet = pci_get_drvdata(pdev);
if (PSNET_FLAG_ON(psnet, SNET_CFG_FLAG_IRQ_PF))
snet_free_cfg(&psnet->cfg);
kfree(psnet);
struct psnet *psnet = snet->psnet;
if (!PSNET_FLAG_ON(psnet, SNET_CFG_FLAG_IRQ_PF))
off = snet->psnet->cfg.host_cfg_off;
snet_write32(snet, off, snet->psnet->negotiated_cfg_ver);
snet_write32(snet, snet->psnet->cfg.host_cfg_off, SNET_SIGNATURE);
ret = readx_poll_timeout(ioread32, snet->bar + snet->psnet->cfg.host_cfg_off,
struct psnet *psnet = snet->psnet;
pf_irqs = PSNET_FLAG_ON(psnet, SNET_CFG_FLAG_IRQ_PF);
static int psnet_open_pf_bar(struct pci_dev *pdev, struct psnet *psnet)
psnet->bars[i] = io;
struct psnet *psnet = snet->psnet;
io = pcim_iomap_region(pdev, snet->psnet->cfg.vf_bar, name);
static int psnet_detect_bar(struct psnet *psnet, u32 off)
if (!psnet->bars[i])
if (PSNET_FLAG_ON(psnet, SNET_CFG_FLAG_IRQ_PF))
if (ioread32(psnet->bars[i] + off) == SNET_SIGNATURE)
static void psnet_unmap_unused_bars(struct pci_dev *pdev, struct psnet *psnet)
if (psnet->bars[i] && i != psnet->barno)
static int psnet_read_cfg(struct pci_dev *pdev, struct psnet *psnet)
struct snet_cfg *cfg = &psnet->cfg;
barno = psnet_detect_bar(psnet, off);
psnet->barno = barno;
psnet_unmap_unused_bars(pdev, psnet);
cfg->key = psnet_read32(psnet, off);
cfg->cfg_size = psnet_read32(psnet, off);
cfg->cfg_ver = psnet_read32(psnet, off);
psnet->negotiated_cfg_ver = min_t(u32, cfg->cfg_ver, SNET_CFG_VERSION);
SNET_DBG(pdev, "SNET config version %u\n", psnet->negotiated_cfg_ver);
cfg->vf_num = psnet_read32(psnet, off);
cfg->vf_bar = psnet_read32(psnet, off);
cfg->host_cfg_off = psnet_read32(psnet, off);
cfg->max_size_host_cfg = psnet_read32(psnet, off);
cfg->virtio_cfg_off = psnet_read32(psnet, off);
cfg->kick_off = psnet_read32(psnet, off);
cfg->hwmon_off = psnet_read32(psnet, off);
cfg->ctrl_off = psnet_read32(psnet, off);
cfg->flags = psnet_read32(psnet, off);
cfg->devices_num = psnet_read32(psnet, off);
cfg->devs[i]->virtio_id = psnet_read32(psnet, off);
cfg->devs[i]->vq_num = psnet_read32(psnet, off);
cfg->devs[i]->vq_size = psnet_read32(psnet, off);
cfg->devs[i]->vfid = psnet_read32(psnet, off);
cfg->devs[i]->features = psnet_read64(psnet, off);
cfg->devs[i]->cfg_size = psnet_read32(psnet, off);
static int psnet_alloc_irq_vector(struct pci_dev *pdev, struct psnet *psnet)
for (i = 0; i < psnet->cfg.devices_num; i++)
irq_num += psnet->cfg.devs[i]->vq_num + 1;
snet->vqs[i]->kick_ptr = snet->bar + snet->psnet->cfg.kick_off +
static int psnet_get_next_irq_num(struct psnet *psnet)
spin_lock(&psnet->lock);
irq = psnet->next_irq++;
spin_unlock(&psnet->lock);
struct psnet *psnet = snet->psnet;
snet->cfg_irq_idx = psnet_get_next_irq_num(psnet);
snet->vqs[i]->irq_idx = psnet_get_next_irq_num(psnet);
struct psnet *psnet;
psnet = kzalloc_obj(*psnet);
if (!psnet)
spin_lock_init(&psnet->lock);
pci_set_drvdata(pdev, psnet);
ret = psnet_open_pf_bar(pdev, psnet);
ret = psnet_read_cfg(pdev, psnet);
pf_irqs = PSNET_FLAG_ON(psnet, SNET_CFG_FLAG_IRQ_PF);
ret = psnet_alloc_irq_vector(pdev, psnet);
SNET_DBG(pdev, "Enable %u virtual functions\n", psnet->cfg.vf_num);
ret = pci_enable_sriov(pdev, psnet->cfg.vf_num);
if (PSNET_FLAG_ON(psnet, SNET_CFG_FLAG_HWMON)) {
snet_free_cfg(&psnet->cfg);
kfree(psnet);
struct psnet *psnet = pci_get_drvdata(pdev_pf);
dev_cfg = snet_find_dev_cfg(&psnet->cfg, vfid);
pf_irqs = PSNET_FLAG_ON(psnet, SNET_CFG_FLAG_IRQ_PF);
static inline u32 psnet_read32(struct psnet *psnet, u32 off)
return ioread32(psnet->bars[psnet->barno] + off);
static inline u64 psnet_read64(struct psnet *psnet, u32 off)
val = (u64)psnet_read32(psnet, off);
val |= ((u64)psnet_read32(psnet, off + 4) << 32);
#define SNET_CFG_VER(snet, ver) ((snet)->psnet->negotiated_cfg_ver >= (ver))
struct psnet *psnet;