Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags   |
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright IBM Corp. 2020
*
* Author(s):
* Niklas Schnelle <schnelle@linux.ibm.com>
*
*/
#define KMSG_COMPONENT "zpci"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <linux/kernel.h>
#include <linux/pci.h>
#include "pci_iov.h"
static struct resource iov_res = {
<------>.name = "PCI IOV res",
<------>.start = 0,
<------>.end = -1,
<------>.flags = IORESOURCE_MEM,
};
void zpci_iov_map_resources(struct pci_dev *pdev)
{
<------>resource_size_t len;
<------>int i;
<------>for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
<------><------>int bar = i + PCI_IOV_RESOURCES;
<------><------>len = pci_resource_len(pdev, bar);
<------><------>if (!len)
<------><------><------>continue;
<------><------>pdev->resource[bar].parent = &iov_res;
<------>}
}
void zpci_iov_remove_virtfn(struct pci_dev *pdev, int vfn)
{
<------>pci_lock_rescan_remove();
<------>/* Linux' vfid's start at 0 vfn at 1 */
<------>pci_iov_remove_virtfn(pdev->physfn, vfn - 1);
<------>pci_unlock_rescan_remove();
}
static int zpci_iov_link_virtfn(struct pci_dev *pdev, struct pci_dev *virtfn, int vfid)
{
<------>int rc;
<------>rc = pci_iov_sysfs_link(pdev, virtfn, vfid);
<------>if (rc)
<------><------>return rc;
<------>virtfn->is_virtfn = 1;
<------>virtfn->multifunction = 0;
<------>virtfn->physfn = pci_dev_get(pdev);
<------>return 0;
}
int zpci_iov_setup_virtfn(struct zpci_bus *zbus, struct pci_dev *virtfn, int vfn)
{
<------>int i, cand_devfn;
<------>struct zpci_dev *zdev;
<------>struct pci_dev *pdev;
<------>int vfid = vfn - 1; /* Linux' vfid's start at 0 vfn at 1*/
<------>int rc = 0;
<------>if (!zbus->multifunction)
<------><------>return 0;
<------>/* If the parent PF for the given VF is also configured in the
<------> * instance, it must be on the same zbus.
<------> * We can then identify the parent PF by checking what
<------> * devfn the VF would have if it belonged to that PF using the PF's
<------> * stride and offset. Only if this candidate devfn matches the
<------> * actual devfn will we link both functions.
<------> */
<------>for (i = 0; i < ZPCI_FUNCTIONS_PER_BUS; i++) {
<------><------>zdev = zbus->function[i];
<------><------>if (zdev && zdev->is_physfn) {
<------><------><------>pdev = pci_get_slot(zbus->bus, zdev->devfn);
<------><------><------>if (!pdev)
<------><------><------><------>continue;
<------><------><------>cand_devfn = pci_iov_virtfn_devfn(pdev, vfid);
<------><------><------>if (cand_devfn == virtfn->devfn) {
<------><------><------><------>rc = zpci_iov_link_virtfn(pdev, virtfn, vfid);
<------><------><------><------>/* balance pci_get_slot() */
<------><------><------><------>pci_dev_put(pdev);
<------><------><------><------>break;
<------><------><------>}
<------><------><------>/* balance pci_get_slot() */
<------><------><------>pci_dev_put(pdev);
<------><------>}
<------>}
<------>return rc;
}